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