http://gimel.esc.cam.ac.uk/james/rpld/src/rpld-1.8-beta-1.tar.gz
[rpld.git] / llc-nit.c
1 /*************************************************
2 *     rpld - an IBM style RIPL server            *
3 *************************************************/
4
5 /* Copyright (c) 1999,2000,2001 James McKenzie.
6  *                      All rights reserved
7  * Copyright (c) 1998,2000,2001 Christopher Lightfoot.
8  *                      All rights reserved
9  *
10  * By using this file, you agree to the terms and conditions set
11  * forth in the LICENCE file which can be found at the top level of
12  * the rpld distribution.
13  *
14  * IBM is a trademark of IBM corp.
15  *
16  */
17
18
19 static char rcsid[] = "$Id: llc-nit.c,v 1.8 2001/11/01 15:30:29 root Exp $";
20
21 /*
22  * $Log: llc-nit.c,v $
23  * Revision 1.8  2001/11/01 15:30:29  root
24  * #
25  *
26  * Revision 1.7  2001/11/01 15:28:23  root
27  * #
28  *
29  * Revision 1.6  2001/11/01 15:26:45  root
30  * #
31  *
32  * Revision 1.5  2001/11/01 15:26:29  root
33  * #
34  *
35  * Revision 1.4  2001/11/01 15:23:59  root
36  * #
37  *
38  * Revision 1.3  2000/09/26 04:06:07  root
39  * #
40  *
41  * Revision 1.2  2000/09/26 03:48:23  root
42  * #
43  *
44  * Revision 1.1  2000/09/26 03:44:29  root
45  * #
46  *
47  * Revision 1.10  2000/07/17 11:59:45  root
48  * #
49  *
50  * Revision 1.9  2000/07/17 10:43:34  root
51  * #
52  *
53  * Revision 1.8  2000/07/16 14:05:28  root
54  * #
55  *
56  * Revision 1.7  2000/07/16 13:18:10  root
57  * #
58  *
59  * Revision 1.1  2000/07/16 13:16:33  root
60  * #
61  *
62  * Revision 1.6  1999/09/13 11:17:35  root
63  * \#
64  *
65  * Revision 1.5  1999/09/13 11:05:27  root
66  * \#
67  *
68  * Revision 1.4  1999/09/13 11:04:13  root
69  * \#
70  *
71  */
72
73
74
75 #include "project.h"
76
77 #include "llc.h"
78 #include "nit.h"
79
80 #define LLC_HDR_LEN 3
81
82 #define LLC_UIC     0x3
83
84 /* The LLC-1 headers as it comes off the wire */
85 struct llchdr
86 {
87   unsigned char h_dsap;
88   unsigned char h_ssap;
89   unsigned char h_flags;
90 };
91
92 struct llcdrv_nit
93 {
94   LLCDRV;
95   struct nit *n;
96   int sap;
97 };
98
99 #ifdef DEBUG
100 static void
101 hexdump (char *p, unsigned char *buf, int l)
102 {
103   int i;
104
105   for (i = 0; i < l; ++i)
106     {
107       if ((i % 16) == 0)
108         {
109           printf ("%s: ", p);
110         }
111       printf ("%02x ", buf[i]);
112       if ((i % 16) == 15)
113         {
114           printf ("\n");
115         }
116     }
117
118   printf ("\n");
119
120
121 }
122
123 #endif
124
125 static int
126 llc_nit_send (struct llcdrv *llc, unsigned char *dmac, unsigned char dsap,
127               unsigned char *buf, int len)
128 {
129   struct llcdrv_nit *llc_nit = (struct llcdrv_nit *) llc;
130
131   unsigned char mybuf[MAX_FRAME_LEN];
132   struct llchdr *h = (struct llchdr *) mybuf;
133   int llclen;
134
135 #ifdef DEBUG
136   printf ("Got %d bytes from upper layer\n", len);
137 //  hexdump("write",buf,len);
138 #endif
139
140 /*
141   bcopy (dmac, h->h_dest, ETH_ALEN);
142   bcopy (nit_mac(llc_nit->n), h->h_source, ETH_ALEN);
143
144   h->h_len = htons (len + LLC_SAP_LEN);
145 */
146
147
148   h->h_ssap = llc_nit->sap;
149   h->h_dsap = dsap;
150   h->h_flags = LLC_UIC;
151
152   bcopy (buf, mybuf + LLC_HDR_LEN, len);
153
154   llclen = len + LLC_HDR_LEN;
155   if (nit_send (llc_nit->n, mybuf, llclen, dmac) == llclen)
156     {
157       return len;
158     }
159
160   return -1;
161 }
162
163
164 static int
165 llc_nit_recv (struct llcdrv *llc, unsigned char *buf, int blen,
166               unsigned char *smac, unsigned char *ssap, struct timeval *tv)
167 {
168   struct llcdrv_nit *llc_nit = (struct llcdrv_nit *) llc;
169
170   unsigned char mybuf[MAX_FRAME_LEN + 20];
171   unsigned char *myptr = &mybuf[20];
172 #define       mylen (MAX_FRAME_LEN-20)
173
174   struct llchdr *h = (struct llchdr *) myptr;
175
176   int llclen;
177   int len;
178
179   do
180     {
181       do
182         {
183           len = nit_recv (llc_nit->n, myptr, mylen, smac, tv);
184           if (len <= 0)
185             {
186               return len;
187             }
188         }
189       while ((len <= LLC_HDR_LEN) || (len > MAX_FRAME_LEN));
190
191       llclen = len;
192
193 #ifdef DEBUG
194       if (smac)
195         printf ("llc-nit-recv: source: %s ", ethtoa (smac));
196       printf ("len: 0x%04x ", llclen);
197       printf ("dsap:%02x ssap:%02x flags:%02x \n", h->h_dsap, h->h_ssap,
198               h->h_flags);
199 #endif
200
201     }
202   while (h->h_dsap != llc_nit->sap);
203 #ifdef DEBUG
204   hexdump ("read", myptr, len);
205 #endif
206
207   if (ssap)
208     *ssap = h->h_ssap;
209
210   llclen -= LLC_HDR_LEN;
211
212   bcopy (myptr + LLC_HDR_LEN, buf, llclen);
213
214 #ifdef DEBUG
215   printf ("Returning %d bytes to upper layer\n", llclen);
216   hexdump ("read", buf, llclen);
217 #endif
218
219
220
221   return llclen;
222
223 }
224
225 static int
226 llc_nit_add_multicast (struct llcdrv *llc, unsigned char *mac)
227 {
228   struct llcdrv_nit *llc_nit = (struct llcdrv_nit *) llc;
229
230   return nit_multicast (llc_nit->n, mac);
231 }
232
233 static unsigned char *
234 llc_nit_mac (struct llcdrv *llc)
235 {
236   struct llcdrv_nit *llc_nit = (struct llcdrv_nit *) llc;
237   return nit_mac (llc_nit->n);
238 }
239
240 static void
241 llc_nit_close (struct llcdrv *llc)
242 {
243   struct llcdrv_nit *llc_nit = (struct llcdrv_nit *) llc;
244   nit_close (llc_nit->n);
245   free (llc_nit);
246 }
247
248 struct llcdrv *
249 llc_open (unsigned char sap, char *name)
250 {
251   struct llcdrv_nit *llc;
252
253   syslog (LOG_ERR, "RPLD LLC 802.2 over NIT support %s", rcsid);
254
255   llc = malloc (sizeof (struct llcdrv_nit));
256   bzero (llc, sizeof (struct llcdrv_nit));
257
258   llc->n = nit_open (name);
259
260   if (!llc->n)
261     {
262       free (llc);
263       return NULL;
264     }
265
266   llc->sap = sap;
267
268   llc->recv = llc_nit_recv;
269   llc->send = llc_nit_send;
270   llc->mac = llc_nit_mac;
271   llc->add_multicast = llc_nit_add_multicast;
272   llc->close = llc_nit_close;
273
274
275   return (struct llcdrv *) llc;
276 }