1 /*
2 NETWIB
3 Network library
4 Copyright(c) 1999-2010 Laurent Constantin
5 -----
6
7 Main server : http://www.laurentconstantin.com/
8 Backup server : http://laurentconstantin.free.fr/
9 [my current email address is on the web servers]
10
11 -----
12 This file is part of Netwib.
13
14 Netwib is free software: you can redistribute it and/or modify
15 it under the terms of the GNU General Public License version 3
16 as published by the Free Software Foundation.
17
18 Netwib is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details (http://www.gnu.org/).
22
23 ------------------------------------------------------------------------
24 */
25
26 #include <netwib/inc/maininc.h>
27
28 /*-------------------------------------------------------------*/
netwib_linkhdr_initdefault(netwib_device_dlttype type,netwib_linkhdr * plinkhdr)29 netwib_err netwib_linkhdr_initdefault(netwib_device_dlttype type,
30 netwib_linkhdr *plinkhdr)
31 {
32
33 if (plinkhdr != NULL) {
34 plinkhdr->type = type;
35 switch(type) {
36 case NETWIB_DEVICE_DLTTYPE_ETHER :
37 case NETWIB_DEVICE_DLTTYPE_NULL :
38 case NETWIB_DEVICE_DLTTYPE_LOOP :
39 case NETWIB_DEVICE_DLTTYPE_RAW :
40 case NETWIB_DEVICE_DLTTYPE_RAW4 :
41 case NETWIB_DEVICE_DLTTYPE_RAW6 :
42 break;
43 case NETWIB_DEVICE_DLTTYPE_PPP :
44 /* is this correct to set nothing ??? */
45 break;
46 case NETWIB_DEVICE_DLTTYPE_LINUX_SLL :
47 plinkhdr->hdr.linuxsll.pkttype = NETWIB_LINUXSLLHDRPKTTYPE_HOST;
48 plinkhdr->hdr.linuxsll.hatype = NETWIB_LINUXSLLHDRHATYPE_ETHER;
49 plinkhdr->hdr.linuxsll.halen = NETWIB_ETH_LEN;
50 break;
51 default :
52 return(NETWIB_ERR_LONOTIMPLEMENTED);
53 break;
54 }
55 }
56
57 return(NETWIB_ERR_OK);
58 }
59
60 /*-------------------------------------------------------------*/
netwib_pkt_append_etherhdr(netwib_constetherhdr * petherhdr,netwib_buf * ppkt)61 static netwib_err netwib_pkt_append_etherhdr(netwib_constetherhdr *petherhdr,
62 netwib_buf *ppkt)
63 {
64 netwib_data data;
65
66 netwib_er(netwib_buf_wantspace(ppkt, NETWIB_ETHERHDR_LEN, &data));
67
68 netwib_c_memcpy(data, petherhdr->dst.b, NETWIB_ETH_LEN);
69 data += NETWIB_ETH_LEN;
70 netwib_c_memcpy(data, petherhdr->src.b, NETWIB_ETH_LEN);
71 data += NETWIB_ETH_LEN;
72 netwib__data_append_uint16(data, petherhdr->type);
73
74 ppkt->endoffset += NETWIB_ETHERHDR_LEN;
75
76 return(NETWIB_ERR_OK);
77 }
78
79 /*-------------------------------------------------------------*/
netwib_pkt_decode_etherhdr(netwib_constbuf * ppkt,netwib_etherhdr * petherhdr,netwib_uint32 * pskipsize)80 static netwib_err netwib_pkt_decode_etherhdr(netwib_constbuf *ppkt,
81 netwib_etherhdr *petherhdr,
82 netwib_uint32 *pskipsize)
83 {
84 netwib_data data;
85 netwib_uint32 datasize;
86
87 if (pskipsize != NULL) *pskipsize = NETWIB_ETHERHDR_LEN;
88
89 datasize = netwib__buf_ref_data_size(ppkt);
90 if (datasize < NETWIB_ETHERHDR_LEN) {
91 return(NETWIB_ERR_DATAMISSING);
92 }
93
94 if (petherhdr != NULL) {
95 data = netwib__buf_ref_data_ptr(ppkt);
96 netwib_c_memcpy(petherhdr->dst.b, data, NETWIB_ETH_LEN);
97 data += NETWIB_ETH_LEN;
98 netwib_c_memcpy(petherhdr->src.b, data, NETWIB_ETH_LEN);
99 data += NETWIB_ETH_LEN;
100 netwib__data_decode_uint16t(data, petherhdr->type, netwib_etherhdrtype);
101 }
102
103 return(NETWIB_ERR_OK);
104 }
105
106 /*-------------------------------------------------------------*/
107 /*-------------------------------------------------------------*/
netwib_pkt_append_nullhdr(netwib_constnullhdr * pnullhdr,netwib_buf * ppkt)108 static netwib_err netwib_pkt_append_nullhdr(netwib_constnullhdr *pnullhdr,
109 netwib_buf *ppkt)
110 {
111 netwib_data data;
112
113 netwib_er(netwib_buf_wantspace(ppkt, NETWIB_NULLHDR_LEN, &data));
114
115 netwib__data_append_uint32(data, pnullhdr->type);
116
117 ppkt->endoffset += NETWIB_NULLHDR_LEN;
118 return(NETWIB_ERR_OK);
119 }
120
121 /*-------------------------------------------------------------*/
netwib_pkt_decode_nullhdr(netwib_constbuf * ppkt,netwib_nullhdr * pnullhdr,netwib_uint32 * pskipsize)122 static netwib_err netwib_pkt_decode_nullhdr(netwib_constbuf *ppkt,
123 netwib_nullhdr *pnullhdr,
124 netwib_uint32 *pskipsize)
125 {
126 netwib_data data;
127 netwib_uint32 datasize;
128
129 if (pskipsize != NULL) *pskipsize = NETWIB_NULLHDR_LEN;
130
131 datasize = netwib__buf_ref_data_size(ppkt);
132 if (datasize < NETWIB_NULLHDR_LEN) {
133 return(NETWIB_ERR_DATAMISSING);
134 }
135
136 if (pnullhdr != NULL) {
137 data = netwib__buf_ref_data_ptr(ppkt);
138 netwib__data_decode_uint32t(data, pnullhdr->type, netwib_etherhdrtype);
139 if ((pnullhdr->type & 0xFFFF) == 0) {
140 /* swap */
141 pnullhdr->type = (netwib_etherhdrtype)(((pnullhdr->type>>8)&0xFFFF) |
142 (pnullhdr->type>>24));
143 }
144 /* under BSD, this field can also contain AF_xyz */
145 switch(pnullhdr->type) {
146 case AF_INET :
147 pnullhdr->type = NETWIB_ETHERHDRTYPE_IP4;
148 break;
149 #if NETWIBDEF_HAVEVAR_AF_INET6 == 1
150 case AF_INET6 :
151 pnullhdr->type = NETWIB_ETHERHDRTYPE_IP6;
152 break;
153 #endif
154 default :
155 /* do not change */
156 break;
157 }
158 }
159
160 return(NETWIB_ERR_OK);
161 }
162
163 /*-------------------------------------------------------------*/
164 /*-------------------------------------------------------------*/
netwib_pkt_append_loophdr(netwib_constloophdr * ploophdr,netwib_buf * ppkt)165 static netwib_err netwib_pkt_append_loophdr(netwib_constloophdr *ploophdr,
166 netwib_buf *ppkt)
167 {
168 netwib_data data;
169
170 netwib_er(netwib_buf_wantspace(ppkt, NETWIB_LOOPHDR_LEN, &data));
171
172 netwib__data_append_uint32(data, ploophdr->type);
173
174 ppkt->endoffset += NETWIB_LOOPHDR_LEN;
175
176 return(NETWIB_ERR_OK);
177 }
178
179 /*-------------------------------------------------------------*/
netwib_pkt_decode_loophdr(netwib_constbuf * ppkt,netwib_loophdr * ploophdr,netwib_uint32 * pskipsize)180 static netwib_err netwib_pkt_decode_loophdr(netwib_constbuf *ppkt,
181 netwib_loophdr *ploophdr,
182 netwib_uint32 *pskipsize)
183 {
184 netwib_data data;
185 netwib_uint32 datasize;
186
187 if (pskipsize != NULL) *pskipsize = NETWIB_LOOPHDR_LEN;
188
189 datasize = netwib__buf_ref_data_size(ppkt);
190 if (datasize < NETWIB_LOOPHDR_LEN) {
191 return(NETWIB_ERR_DATAMISSING);
192 }
193
194 if (ploophdr != NULL) {
195 data = netwib__buf_ref_data_ptr(ppkt);
196 netwib__data_decode_uint32t(data, ploophdr->type, netwib_etherhdrtype);
197 /* under BSD, this field can contain AF_xyz */
198 switch(ploophdr->type) {
199 case AF_INET :
200 ploophdr->type = NETWIB_ETHERHDRTYPE_IP4;
201 break;
202 #if NETWIBDEF_HAVEVAR_AF_INET6 == 1
203 case AF_INET6 :
204 ploophdr->type = NETWIB_ETHERHDRTYPE_IP6;
205 break;
206 #endif
207 default :
208 /* do not change */
209 break;
210 }
211 }
212
213 return(NETWIB_ERR_OK);
214 }
215
216
217 /*-------------------------------------------------------------*/
218 /*-------------------------------------------------------------*/
netwib_pkt_append_ppphdr(netwib_constppphdr * pppphdr,netwib_buf * ppkt)219 static netwib_err netwib_pkt_append_ppphdr(netwib_constppphdr *pppphdr,
220 netwib_buf *ppkt)
221 {
222 netwib_data data;
223
224 netwib_er(netwib_buf_wantspace(ppkt, NETWIB_PPPHDR_LEN, &data));
225
226 netwib__data_append_uint8(data, pppphdr->address);
227 netwib__data_append_uint8(data, pppphdr->control);
228 netwib__data_append_uint16(data, pppphdr->protocol);
229
230 ppkt->endoffset += NETWIB_PPPHDR_LEN;
231
232 return(NETWIB_ERR_OK);
233 }
234
235 /*-------------------------------------------------------------*/
netwib_pkt_decode_ppphdr(netwib_constbuf * ppkt,netwib_ppphdr * pppphdr,netwib_uint32 * pskipsize)236 static netwib_err netwib_pkt_decode_ppphdr(netwib_constbuf *ppkt,
237 netwib_ppphdr *pppphdr,
238 netwib_uint32 *pskipsize)
239 {
240 netwib_data data;
241 netwib_uint32 datasize;
242
243 if (pskipsize != NULL) *pskipsize = NETWIB_PPPHDR_LEN;
244
245 datasize = netwib__buf_ref_data_size(ppkt);
246 if (datasize < NETWIB_PPPHDR_LEN) {
247 return(NETWIB_ERR_DATAMISSING);
248 }
249
250 if (pppphdr != NULL) {
251 data = netwib__buf_ref_data_ptr(ppkt);
252 netwib__data_decode_uint8(data, pppphdr->address);
253 netwib__data_decode_uint8(data, pppphdr->control);
254 netwib__data_decode_uint16t(data, pppphdr->protocol, netwib_ppphdrproto);
255 }
256
257 return(NETWIB_ERR_OK);
258 }
259
260 /*-------------------------------------------------------------*/
261 /*-------------------------------------------------------------*/
netwib_pkt_append_linuxsllhdr(netwib_constlinuxsllhdr * plinuxsllhdr,netwib_buf * ppkt)262 static netwib_err netwib_pkt_append_linuxsllhdr(netwib_constlinuxsllhdr *plinuxsllhdr,
263 netwib_buf *ppkt)
264 {
265 netwib_data data;
266
267 netwib_er(netwib_buf_wantspace(ppkt, NETWIB_LINUXSLLHDR_LEN, &data));
268
269 netwib__data_append_uint16(data, plinuxsllhdr->pkttype);
270 netwib__data_append_uint16(data, plinuxsllhdr->hatype);
271 netwib__data_append_uint16(data, plinuxsllhdr->halen);
272 if (plinuxsllhdr->halen >= 8 ) {
273 netwib_c_memcpy(data, plinuxsllhdr->srcaddr, 8);
274 data += 8;
275 } else {
276 netwib_c_memcpy(data, plinuxsllhdr->srcaddr, plinuxsllhdr->halen);
277 data += plinuxsllhdr->halen;
278 netwib_c_memset(data, 0, 8-plinuxsllhdr->halen);
279 data += 8-plinuxsllhdr->halen;
280 }
281 netwib__data_append_uint16(data, plinuxsllhdr->protocol);
282
283 ppkt->endoffset += NETWIB_LINUXSLLHDR_LEN;
284
285 return(NETWIB_ERR_OK);
286 }
287
288 /*-------------------------------------------------------------*/
netwib_pkt_decode_linuxsllhdr(netwib_constbuf * ppkt,netwib_linuxsllhdr * plinuxsllhdr,netwib_uint32 * pskipsize)289 static netwib_err netwib_pkt_decode_linuxsllhdr(netwib_constbuf *ppkt,
290 netwib_linuxsllhdr *plinuxsllhdr,
291 netwib_uint32 *pskipsize)
292 {
293 netwib_data data;
294 netwib_uint32 datasize;
295
296 if (pskipsize != NULL) *pskipsize = NETWIB_LINUXSLLHDR_LEN;
297
298 datasize = netwib__buf_ref_data_size(ppkt);
299 if (datasize < NETWIB_LINUXSLLHDR_LEN) {
300 return(NETWIB_ERR_DATAMISSING);
301 }
302
303 if (plinuxsllhdr != NULL) {
304 data = netwib__buf_ref_data_ptr(ppkt);
305 netwib__data_decode_uint16t(data, plinuxsllhdr->pkttype,
306 netwib_linuxsllhdrpkttype);
307 netwib__data_decode_uint16t(data, plinuxsllhdr->hatype,
308 netwib_linuxsllhdrhatype);
309 netwib__data_decode_uint16(data, plinuxsllhdr->halen);
310 if (plinuxsllhdr->halen >= 8 ) {
311 netwib_c_memcpy(plinuxsllhdr->srcaddr, data, 8);
312 } else {
313 netwib_c_memcpy(plinuxsllhdr->srcaddr, data, plinuxsllhdr->halen);
314 netwib_c_memset(plinuxsllhdr->srcaddr+plinuxsllhdr->halen, 0,
315 8-plinuxsllhdr->halen);
316 }
317 data += 8;
318 netwib__data_decode_uint16t(data, plinuxsllhdr->protocol,
319 netwib_etherhdrtype);
320 }
321
322 return(NETWIB_ERR_OK);
323 }
324
325
326 /*-------------------------------------------------------------*/
327 /*-------------------------------------------------------------*/
328
329 /*-------------------------------------------------------------*/
netwib_pkt_append_linkhdr(netwib_constlinkhdr * plinkhdr,netwib_buf * ppkt)330 netwib_err netwib_pkt_append_linkhdr(netwib_constlinkhdr *plinkhdr,
331 netwib_buf *ppkt)
332 {
333 switch(plinkhdr->type) {
334 case NETWIB_DEVICE_DLTTYPE_EN10MB :
335 netwib_er(netwib_pkt_append_etherhdr(&plinkhdr->hdr.ether, ppkt));
336 break;
337 case NETWIB_DEVICE_DLTTYPE_NULL :
338 netwib_er(netwib_pkt_append_nullhdr(&plinkhdr->hdr.null, ppkt));
339 break;
340 case NETWIB_DEVICE_DLTTYPE_LOOP :
341 netwib_er(netwib_pkt_append_loophdr(&plinkhdr->hdr.loop, ppkt));
342 break;
343 case NETWIB_DEVICE_DLTTYPE_RAW :
344 case NETWIB_DEVICE_DLTTYPE_RAW4 :
345 case NETWIB_DEVICE_DLTTYPE_RAW6 :
346 /* nothing to append */
347 break;
348 case NETWIB_DEVICE_DLTTYPE_PPP :
349 netwib_er(netwib_pkt_append_ppphdr(&plinkhdr->hdr.ppp, ppkt));
350 break;
351 case NETWIB_DEVICE_DLTTYPE_LINUX_SLL :
352 netwib_er(netwib_pkt_append_linuxsllhdr(&plinkhdr->hdr.linuxsll, ppkt));
353 break;
354 default :
355 return(NETWIB_ERR_LONOTIMPLEMENTED);
356 break;
357 }
358 return(NETWIB_ERR_OK);
359 }
360
361 /*-------------------------------------------------------------*/
netwib_pkt_prepend_linkhdr(netwib_constlinkhdr * plinkhdr,netwib_buf * ppkt)362 netwib_err netwib_pkt_prepend_linkhdr(netwib_constlinkhdr *plinkhdr,
363 netwib_buf *ppkt)
364 {
365 netwib_byte array[NETWIB_LINKHDR_MAXLEN];
366 netwib_buf buf;
367 netwib_err ret;
368
369 netwib_er(netwib_buf_init_ext_arrayempty(array, NETWIB_LINKHDR_MAXLEN,
370 &buf));
371 ret = netwib_pkt_append_linkhdr(plinkhdr, &buf);
372 if (ret == NETWIB_ERR_OK) {
373 ret = netwib_buf_prepend_buf(&buf, ppkt);
374 }
375
376 return(ret);
377 }
378
379 /*-------------------------------------------------------------*/
netwib_pkt_decode_linkhdr(netwib_device_dlttype dlttype,netwib_constbuf * ppkt,netwib_linkhdr * plinkhdr,netwib_uint32 * pskipsize)380 netwib_err netwib_pkt_decode_linkhdr(netwib_device_dlttype dlttype,
381 netwib_constbuf *ppkt,
382 netwib_linkhdr *plinkhdr,
383 netwib_uint32 *pskipsize)
384 {
385 netwib_iptype iptype;
386
387 switch(dlttype) {
388 case NETWIB_DEVICE_DLTTYPE_EN10MB :
389 netwib_er(netwib_pkt_decode_etherhdr(ppkt,
390 (plinkhdr==NULL)?NULL:&plinkhdr->hdr.ether,
391 pskipsize));
392 break;
393 case NETWIB_DEVICE_DLTTYPE_NULL :
394 netwib_er(netwib_pkt_decode_nullhdr(ppkt,
395 (plinkhdr==NULL)?NULL:&plinkhdr->hdr.null,
396 pskipsize));
397 break;
398 case NETWIB_DEVICE_DLTTYPE_LOOP :
399 netwib_er(netwib_pkt_decode_loophdr(ppkt,
400 (plinkhdr==NULL)?NULL:&plinkhdr->hdr.loop,
401 pskipsize));
402 break;
403 case NETWIB_DEVICE_DLTTYPE_RAW :
404 netwib_er(netwib_priv_ippkt_decode_iptype(ppkt, &iptype));
405 switch(iptype) {
406 case NETWIB_IPTYPE_IP4 :
407 dlttype = NETWIB_DEVICE_DLTTYPE_RAW4;
408 break;
409 case NETWIB_IPTYPE_IP6 :
410 dlttype = NETWIB_DEVICE_DLTTYPE_RAW6;
411 break;
412 default :
413 break;
414 }
415 /* no break */
416 case NETWIB_DEVICE_DLTTYPE_RAW4 :
417 case NETWIB_DEVICE_DLTTYPE_RAW6 :
418 if (pskipsize != NULL) *pskipsize = NETWIB_RAWHDR_LEN;
419 break;
420 case NETWIB_DEVICE_DLTTYPE_PPP :
421 netwib_er(netwib_pkt_decode_ppphdr(ppkt,
422 (plinkhdr==NULL)?NULL:&plinkhdr->hdr.ppp,
423 pskipsize));
424 break;
425 case NETWIB_DEVICE_DLTTYPE_LINUX_SLL :
426 netwib_er(netwib_pkt_decode_linuxsllhdr(ppkt,
427 (plinkhdr==NULL)?NULL:&plinkhdr->hdr.linuxsll,
428 pskipsize));
429 break;
430 default :
431 return(NETWIB_ERR_LONOTIMPLEMENTED);
432 break;
433 }
434
435 if (plinkhdr != NULL) plinkhdr->type = dlttype;
436
437 return(NETWIB_ERR_OK);
438 }
439
440 /*-------------------------------------------------------------*/
netwib_linkhdr_set_proto(netwib_linkhdr * plinkhdr,netwib_linkhdrproto linkhdrproto)441 netwib_err netwib_linkhdr_set_proto(netwib_linkhdr *plinkhdr,
442 netwib_linkhdrproto linkhdrproto)
443 {
444 netwib_etherhdrtype etherhdrtype = (netwib_etherhdrtype)0;
445 netwib_ppphdrproto ppphdrproto = (netwib_ppphdrproto)0;
446
447 switch(linkhdrproto) {
448 case NETWIB_LINKHDRPROTO_IP4 :
449 etherhdrtype = NETWIB_ETHERHDRTYPE_IP4;
450 ppphdrproto = NETWIB_PPPHDRPROTO_IP4;
451 break;
452 case NETWIB_LINKHDRPROTO_IP6 :
453 etherhdrtype = NETWIB_ETHERHDRTYPE_IP6;
454 ppphdrproto = NETWIB_PPPHDRPROTO_IP6;
455 break;
456 case NETWIB_LINKHDRPROTO_ARP :
457 etherhdrtype = NETWIB_ETHERHDRTYPE_ARP;
458 ppphdrproto = (netwib_ppphdrproto)0;
459 break;
460 case NETWIB_LINKHDRPROTO_RARP :
461 etherhdrtype = NETWIB_ETHERHDRTYPE_RARP;
462 ppphdrproto = (netwib_ppphdrproto)0;
463 break;
464 case NETWIB_LINKHDRPROTO_IPX :
465 etherhdrtype = NETWIB_ETHERHDRTYPE_IPX;
466 ppphdrproto = NETWIB_PPPHDRPROTO_IPX;
467 break;
468 default :
469 return(NETWIB_ERR_LONOTIMPLEMENTED);
470 break;
471 }
472
473 switch(plinkhdr->type) {
474 case NETWIB_DEVICE_DLTTYPE_EN10MB :
475 plinkhdr->hdr.ether.type = etherhdrtype;
476 break;
477 case NETWIB_DEVICE_DLTTYPE_NULL :
478 plinkhdr->hdr.null.type = etherhdrtype;
479 break;
480 case NETWIB_DEVICE_DLTTYPE_LOOP :
481 plinkhdr->hdr.loop.type = etherhdrtype;
482 break;
483 case NETWIB_DEVICE_DLTTYPE_RAW :
484 case NETWIB_DEVICE_DLTTYPE_RAW4 :
485 case NETWIB_DEVICE_DLTTYPE_RAW6 :
486 /* nothing to store */
487 break;
488 case NETWIB_DEVICE_DLTTYPE_PPP :
489 if (ppphdrproto == 0) {
490 return(NETWIB_ERR_LONOTIMPLEMENTED);
491 }
492 plinkhdr->hdr.ppp.protocol = ppphdrproto;
493 break;
494 case NETWIB_DEVICE_DLTTYPE_LINUX_SLL :
495 plinkhdr->hdr.linuxsll.protocol = etherhdrtype;
496 break;
497 default :
498 return(NETWIB_ERR_LONOTIMPLEMENTED);
499 break;
500 }
501 return(NETWIB_ERR_OK);
502 }
503
504 /*-------------------------------------------------------------*/
netwib_linkhdr_get_proto(netwib_constlinkhdr * plinkhdr,netwib_linkhdrproto * plinkhdrproto)505 netwib_err netwib_linkhdr_get_proto(netwib_constlinkhdr *plinkhdr,
506 netwib_linkhdrproto *plinkhdrproto)
507 {
508 netwib_etherhdrtype etherhdrtype = (netwib_etherhdrtype)0;
509 netwib_ppphdrproto ppphdrproto = (netwib_ppphdrproto)0;
510 netwib_linkhdrproto linkhdrproto = (netwib_linkhdrproto)0;
511 netwib_bool etherset;
512
513 etherset = NETWIB_TRUE;
514
515 switch(plinkhdr->type) {
516 case NETWIB_DEVICE_DLTTYPE_EN10MB :
517 etherhdrtype = plinkhdr->hdr.ether.type;
518 break;
519 case NETWIB_DEVICE_DLTTYPE_NULL :
520 etherhdrtype = plinkhdr->hdr.null.type;
521 break;
522 case NETWIB_DEVICE_DLTTYPE_LOOP :
523 etherhdrtype = plinkhdr->hdr.loop.type;
524 break;
525 case NETWIB_DEVICE_DLTTYPE_RAW :
526 /* IPv4 or IPv6, but don't know which one */
527 return(NETWIB_ERR_NOTCONVERTED);
528 break;
529 case NETWIB_DEVICE_DLTTYPE_RAW4 :
530 etherhdrtype = NETWIB_ETHERHDRTYPE_IP4;
531 break;
532 case NETWIB_DEVICE_DLTTYPE_RAW6 :
533 etherhdrtype = NETWIB_ETHERHDRTYPE_IP6;
534 break;
535 case NETWIB_DEVICE_DLTTYPE_PPP :
536 ppphdrproto = plinkhdr->hdr.ppp.protocol;
537 etherset = NETWIB_FALSE;
538 break;
539 case NETWIB_DEVICE_DLTTYPE_LINUX_SLL :
540 etherhdrtype = plinkhdr->hdr.linuxsll.protocol;
541 break;
542 default :
543 return(NETWIB_ERR_LONOTIMPLEMENTED);
544 break;
545 }
546
547 if (etherset) {
548 switch(etherhdrtype) {
549 case NETWIB_ETHERHDRTYPE_IP4 :
550 linkhdrproto = NETWIB_LINKHDRPROTO_IP4;
551 break;
552 case NETWIB_ETHERHDRTYPE_IP6 :
553 linkhdrproto = NETWIB_LINKHDRPROTO_IP6;
554 break;
555 case NETWIB_ETHERHDRTYPE_ARP :
556 linkhdrproto = NETWIB_LINKHDRPROTO_ARP;
557 break;
558 case NETWIB_ETHERHDRTYPE_RARP :
559 linkhdrproto = NETWIB_LINKHDRPROTO_RARP;
560 break;
561 case NETWIB_ETHERHDRTYPE_IPX :
562 linkhdrproto = NETWIB_LINKHDRPROTO_IPX;
563 break;
564 default :
565 linkhdrproto = NETWIB_LINKHDRPROTO_UNKNOWN;
566 break;
567 }
568 } else {
569 switch(ppphdrproto) {
570 case NETWIB_PPPHDRPROTO_IP4 :
571 linkhdrproto = NETWIB_LINKHDRPROTO_IP4;
572 case NETWIB_PPPHDRPROTO_IP6 :
573 linkhdrproto = NETWIB_LINKHDRPROTO_IP6;
574 break;
575 case NETWIB_PPPHDRPROTO_IPX :
576 linkhdrproto = NETWIB_LINKHDRPROTO_IPX;
577 break;
578 default :
579 linkhdrproto = NETWIB_LINKHDRPROTO_UNKNOWN;
580 break;
581 }
582 }
583
584 if (plinkhdrproto != NULL) *plinkhdrproto = linkhdrproto;
585 return(NETWIB_ERR_OK);
586 }
587