source: lib/protocols.c @ 85a79b0

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 85a79b0 was 85a79b0, checked in by Perry Lorier <perry@…>, 15 years ago

Fixed lots of warnings

  • Property mode set to 100644
File size: 16.8 KB
Line 
1/* This file has the various helper functions used to decode various protocols
2 *
3 * $Id$
4 */ 
5#include "libtrace.h"
6#include "libtrace_int.h"
7#include "wag.h"
8#include <assert.h>
9#include <stdio.h>
10
11#ifndef WIN32
12#include <net/if_arp.h>
13#endif
14
15#ifndef ARPHRD_ETHER
16#define ARPHRD_ETHER    1               /* Ethernet 10/100Mbps.  */
17#endif
18
19#ifndef ARPHRD_PPP
20#define ARPHRD_PPP      512
21#endif
22
23
24/* Returns the payload from 802.3 ethernet.  Type optionally returned in
25 * "type" in host byte order.  This will return a vlan header.
26 */
27static void *trace_get_payload_from_ethernet(void *ethernet, 
28                uint16_t *type,
29                uint32_t *remaining)
30{
31        libtrace_ether_t *eth = (libtrace_ether_t*)ethernet;
32
33        if (remaining) {
34                if (*remaining < sizeof(*eth))
35                        return NULL;
36                *remaining-=sizeof(*eth);
37        }
38
39        if (type)
40                *type = ntohs(eth->ether_type);
41
42        return (void*)((char *)eth + sizeof(*eth));
43}
44
45/* skip any 802.1q headers if necessary
46 * type is input/output
47 */
48static void *trace_get_vlan_payload_from_ethernet_payload(void *ethernet, uint16_t *type,
49                uint32_t *remaining)
50{
51        assert(type && "You must pass a type in!");
52
53        if (*type == 0x8100) {
54                libtrace_8021q_t *vlanhdr = (libtrace_8021q_t *)ethernet;
55
56                if (remaining) {
57                        if (*remaining < sizeof(libtrace_8021q_t))
58                                return NULL;
59
60                        *remaining=*remaining-sizeof(libtrace_8021q_t);
61                }
62
63                *type = ntohs(vlanhdr->vlan_ether_type);
64
65                return (void*)((char *)ethernet + sizeof(*vlanhdr));
66        }
67
68        return ethernet;
69}
70
71static void *trace_get_payload_from_80211(void *link, uint16_t *type, uint32_t *remaining)
72{
73        libtrace_80211_t *wifi;
74        libtrace_802_11_payload_t *eth;
75
76        if (remaining && *remaining < sizeof(libtrace_80211_t))
77                return NULL;
78
79        wifi=(libtrace_80211_t*)link;
80
81        /* Data packet? */
82        if (wifi->type != 2) {
83                return NULL;
84        }
85
86        if (remaining && *remaining < sizeof(*eth))
87                return NULL;
88
89        eth=(libtrace_802_11_payload_t *)((char*)wifi+sizeof(*wifi));
90
91        if (type) *type=ntohs(eth->type);
92
93        return (void*)((char*)eth+sizeof(*eth));
94}
95
96static void *trace_get_payload_from_linux_sll(void *link,
97                uint16_t *type, uint32_t *remaining) 
98{
99        libtrace_sll_header_t *sll;
100        void *ret;
101
102        sll = (libtrace_sll_header_t*) link;
103
104        if (remaining) {
105                if (*remaining < sizeof(*sll))
106                        return NULL;
107                *remaining-=sizeof(*sll);
108        }
109
110        /* What kind of wacked out header, has this in host order?! */
111        if (type) *type = htons(sll->protocol); 
112
113        ret=(void*)((char*)sll+sizeof(*sll));
114
115        switch(sll->hatype) {
116                case ARPHRD_PPP:
117                        break;
118                case ARPHRD_ETHER:
119                        ret=trace_get_payload_from_ethernet(ret,type,remaining);
120                        break;
121                default:
122                        /* Unknown hardware type */
123                        return NULL;
124        }
125
126        return ret;
127}
128
129static void *trace_get_payload_from_atm(void *link,
130                uint16_t *type, uint32_t *remaining)
131{
132        /* 64 byte capture. */
133        libtrace_llcsnap_t *llc = (libtrace_llcsnap_t*)link;
134
135        if (remaining) {
136                if (*remaining < sizeof(libtrace_llcsnap_t)+4)
137                        return NULL;
138                *remaining-=(sizeof(libtrace_llcsnap_t)+4);
139        }
140
141        /* advance the llc ptr +4 into the link layer.
142         * TODO: need to check what is in these 4 bytes.
143         * don't have time!
144         */
145        llc = (libtrace_llcsnap_t*)((char *)llc + 4);
146
147        if (type) *type = ntohs(llc->type);
148
149        return (void*)((char*)llc+sizeof(*llc));
150}
151
152static void *trace_get_payload_from_pos(void *link, 
153                uint16_t *type, uint32_t *remaining)
154{
155        /* 64 byte capture. */
156        libtrace_pos_t *pos = (libtrace_pos_t*)link;
157
158        if (remaining) {
159                if (*remaining < sizeof(libtrace_pos_t))
160                        return NULL;
161                *remaining-=sizeof(libtrace_pos_t);
162        }
163
164        if (type) *type = ntohs(pos->ether_type);
165
166        return (void*)((char *)pos+sizeof(*pos));
167}
168
169static void *trace_get_payload_from_pflog(void *link,
170                uint16_t *type, uint32_t *remaining)
171{
172        libtrace_pflog_header_t *pflog = (libtrace_pflog_header_t*)link;
173        if (remaining) {
174                if (*remaining<sizeof(*pflog)) 
175                        return NULL;
176                *remaining-=sizeof(*pflog);
177        }
178        if (type) {
179                switch(pflog->af) {
180                        case AF_INET6: *type=0x86DD; break;
181                        case AF_INET:  *type=0x0800; break;
182                        default:
183                                      /* Unknown */
184                                      return NULL;
185                }
186        }
187        return (void*)((char*)pflog+ sizeof(*pflog));
188}
189
190void *trace_get_payload_from_link(void *link, libtrace_linktype_t linktype, 
191                uint16_t *type, uint32_t *remaining)
192{
193        switch(linktype) {
194                case TRACE_TYPE_80211_PRISM:
195                        return trace_get_payload_from_80211((char*)link+144,
196                                        type,remaining);
197                case TRACE_TYPE_80211:
198                        return trace_get_payload_from_80211(link,type,remaining);
199                case TRACE_TYPE_ETH:
200                        return trace_get_payload_from_ethernet(link,type,remaining);
201                case TRACE_TYPE_NONE:
202                        if ((*(char*)link&0xF0) == 0x40)
203                                *type=0x0800;
204                        else if ((*(char*)link&0xF0) == 0x60)
205                                *type=0x86DD;
206                        return link; /* I love the simplicity */
207                case TRACE_TYPE_LINUX_SLL:
208                        return trace_get_payload_from_linux_sll(link,type,remaining);
209                case TRACE_TYPE_PFLOG:
210                        return trace_get_payload_from_pflog(link,type,remaining);
211                case TRACE_TYPE_POS:
212                        return trace_get_payload_from_pos(link,type,remaining);
213                case TRACE_TYPE_ATM:
214                        return trace_get_payload_from_atm(link,type,remaining);
215                case TRACE_TYPE_DUCK:
216                        return NULL; /* duck packets have no payload! */
217        }
218        fprintf(stderr,"Don't understand link layer type %i in trace_get_payload_from_link()\n",
219                linktype);
220        return NULL;
221}
222
223libtrace_ip_t *trace_get_ip(libtrace_packet_t *packet) 
224{
225        uint16_t type;
226        void *link = trace_get_link(packet);
227        void *ret;
228
229        if (!link)
230                return NULL;
231       
232        ret=trace_get_payload_from_link(
233                        link,
234                        trace_get_link_type(packet),
235                        &type, NULL);
236
237        if (!ret)
238                return NULL;
239
240        ret=trace_get_vlan_payload_from_ethernet_payload(ret,&type,NULL);
241
242        if (!ret || type!=0x0800)
243                return NULL;
244
245        /* Not an IPv4 packet */
246        if (((libtrace_ip_t*)ret)->ip_v != 4)
247                return NULL;
248
249        return (libtrace_ip_t*)ret;
250}
251
252libtrace_ip6_t *trace_get_ip6(libtrace_packet_t *packet) 
253{
254        uint16_t type;
255        void *link=trace_get_link(packet);
256        void *ret;
257       
258        if (!link)
259                return NULL;
260
261        ret=trace_get_payload_from_link(
262                        link,
263                        trace_get_link_type(packet),
264                        &type,NULL);
265
266        if (!ret)
267                return NULL;
268
269        ret=trace_get_vlan_payload_from_ethernet_payload(ret,&type,NULL);
270
271        if (!ret || type!=0x86DD)
272                return NULL;
273
274        return (libtrace_ip6_t*)ret;
275}
276
277#define SW_IP_OFFMASK 0xff1f
278
279DLLEXPORT void *trace_get_payload_from_ip(libtrace_ip_t *ipptr, uint8_t *prot,
280                uint32_t *remaining) 
281{
282        void *trans_ptr = 0;
283
284        if ((ipptr->ip_off & SW_IP_OFFMASK) != 0)
285                return NULL;
286
287        if (remaining) {
288                if (*remaining<(ipptr->ip_hl*4U)) {
289                        return NULL;
290                }
291                *remaining-=(ipptr->ip_hl * 4);
292        }
293
294        trans_ptr = (void *)((char *)ipptr + (ipptr->ip_hl * 4));
295
296        if (prot) *prot = ipptr->ip_p;
297
298        return trans_ptr;
299}
300
301void *trace_get_payload_from_ip6(libtrace_ip6_t *ipptr, uint8_t *prot,
302                uint32_t *remaining) 
303{
304        void *payload = (char*)ipptr+sizeof(libtrace_ip6_t);
305        uint8_t nxt = ipptr->nxt;
306
307        if (remaining) {
308                if (*remaining<sizeof(libtrace_ip6_t))
309                        return NULL;
310                *remaining-=sizeof(libtrace_ip6_t);
311        }
312
313        while(1) {
314                switch (nxt) {
315                        case 0: /* hop by hop options */
316                        case 43: /* routing */
317                        case 44: /* fragment */
318                        case 50: /* ESP */
319                        case 51: /* AH */
320                        case 60: /* Destination options */
321                                {
322                                        uint16_t len=((libtrace_ip6_ext_t*)payload)->len
323                                        +sizeof(libtrace_ip6_ext_t);
324
325                                        if (remaining) {
326                                                if (*remaining < len) {
327                                                        /* Snap too short */
328                                                        return NULL;
329                                                }
330                                                *remaining-=len;
331                                        }
332
333                                        payload=(char*)payload+len;
334                                        nxt=((libtrace_ip6_ext_t*)payload)->nxt;
335                                        continue;
336                                }
337                        default:
338                                if (prot) *prot=nxt;
339                                return payload;
340                }
341        }
342}
343
344DLLEXPORT void *trace_get_transport(libtrace_packet_t *packet, 
345                uint8_t *proto,
346                uint32_t *remaining
347                ) 
348{
349        void *transport;
350        uint8_t dummy_proto;
351        uint16_t ethertype;
352        void *link;
353        uint32_t dummy_remaining;
354
355        if (!proto) proto=&dummy_proto;
356
357        if (!remaining) remaining=&dummy_remaining;
358
359        *remaining = trace_get_capture_length(packet);
360
361        link=trace_get_link(packet);
362
363        if (!link)
364                return NULL;
365
366        transport = trace_get_payload_from_link(
367                        link,
368                        trace_get_link_type(packet),
369                        &ethertype,
370                        remaining);
371
372        if (!transport)
373                return NULL;
374
375        transport = trace_get_vlan_payload_from_ethernet_payload(transport,
376                        &ethertype,
377                        remaining);
378
379        if (!transport)
380                return NULL;
381
382        switch (ethertype) {
383                case 0x0800: /* IPv4 */
384                        transport=trace_get_payload_from_ip(
385                                (libtrace_ip_t*)transport, proto, remaining);
386                        /* IPv6 */
387                        if (transport && *proto == 41) {
388                                transport=trace_get_payload_from_ip6(
389                                 (libtrace_ip6_t*)transport, proto,remaining);
390                        }
391                        return transport;
392                case 0x86DD: /* IPv6 */
393                        return trace_get_payload_from_ip6(
394                                (libtrace_ip6_t*)transport, proto, remaining);
395                       
396                default:
397                        *proto=0;
398                        return NULL;
399        }
400
401}
402
403DLLEXPORT libtrace_tcp_t *trace_get_tcp(libtrace_packet_t *packet) {
404        uint8_t proto;
405        libtrace_tcp_t *tcp;
406
407        tcp=(libtrace_tcp_t*)trace_get_transport(packet,&proto,NULL);
408
409        if (!tcp || proto != 6)
410                return NULL;
411
412        return (libtrace_tcp_t*)tcp;
413}
414
415DLLEXPORT libtrace_tcp_t *trace_get_tcp_from_ip(libtrace_ip_t *ip, uint32_t *remaining)
416{
417        libtrace_tcp_t *tcpptr = 0;
418
419        if (ip->ip_p == 6)  {
420                tcpptr = (libtrace_tcp_t *)
421                        trace_get_payload_from_ip(ip, NULL, remaining);
422        }
423
424        return tcpptr;
425}
426
427DLLEXPORT libtrace_udp_t *trace_get_udp(libtrace_packet_t *packet) {
428        uint8_t proto;
429        libtrace_udp_t *udp;
430
431        udp=(libtrace_udp_t*)trace_get_transport(packet,&proto,NULL);
432
433        if (!udp || proto != 17)
434                return NULL;
435
436        return udp;
437}
438
439DLLEXPORT libtrace_udp_t *trace_get_udp_from_ip(libtrace_ip_t *ip, uint32_t *remaining)
440{
441        libtrace_udp_t *udpptr = 0;
442
443        if (ip->ip_p == 17) {
444                udpptr = (libtrace_udp_t *)
445                        trace_get_payload_from_ip(ip, NULL, remaining);
446        }
447
448        return udpptr;
449}
450
451DLLEXPORT libtrace_icmp_t *trace_get_icmp(libtrace_packet_t *packet) {
452        uint8_t proto;
453        libtrace_icmp_t *icmp;
454
455        icmp=(libtrace_icmp_t*)trace_get_transport(packet,&proto,NULL);
456
457        if (!icmp || proto != 1)
458                return NULL;
459
460        return icmp;
461}
462
463DLLEXPORT libtrace_icmp_t *trace_get_icmp_from_ip(libtrace_ip_t *ip, uint32_t *remaining)
464{
465        libtrace_icmp_t *icmpptr = 0;
466
467        if (ip->ip_p == 1)  {
468                icmpptr = (libtrace_icmp_t *)trace_get_payload_from_ip(ip, 
469                                NULL, remaining);
470        }
471
472        return icmpptr;
473}
474
475DLLEXPORT void *trace_get_payload_from_udp(libtrace_udp_t *udp, uint32_t *remaining)
476{
477        if (remaining) {
478                if (*remaining < sizeof(libtrace_udp_t))
479                        return NULL;
480                *remaining-=sizeof(libtrace_udp_t);
481        }
482        return (void*)((char*)udp+sizeof(libtrace_udp_t));
483}
484
485DLLEXPORT void *trace_get_payload_from_tcp(libtrace_tcp_t *tcp, uint32_t *remaining)
486{
487        unsigned int dlen = tcp->doff*4;
488        if (remaining) {
489                if (*remaining < dlen)
490                        return NULL;
491                *remaining-=dlen;
492        }
493        return (void *)((char *)tcp+dlen);
494}
495
496DLLEXPORT void *trace_get_payload_from_icmp(libtrace_icmp_t *icmp, uint32_t *remaining)
497{
498        if (remaining) {
499                if (*remaining < sizeof(libtrace_icmp_t))
500                        return NULL;
501                *remaining-=sizeof(libtrace_icmp_t);
502        }
503        return (char*)icmp+sizeof(libtrace_icmp_t);
504}
505
506struct ports_t {
507        uint16_t src;
508        uint16_t dst;
509};
510
511/* Return the client port
512 */
513DLLEXPORT uint16_t trace_get_source_port(const libtrace_packet_t *packet)
514{
515        uint32_t remaining;
516        struct ports_t *port = 
517                (struct ports_t*)trace_get_transport((libtrace_packet_t*)packet,
518                        NULL, &remaining);
519
520        /* snapped too early */
521        if (remaining<2)
522                return 0;
523
524        if (port)
525                return ntohs(port->src);
526        else
527                return 0;
528}
529
530/* Same as get_source_port except use the destination port */
531DLLEXPORT uint16_t trace_get_destination_port(const libtrace_packet_t *packet)
532{
533        uint32_t remaining;
534        struct ports_t *port = 
535                (struct ports_t*)trace_get_transport((libtrace_packet_t*)packet,
536                        NULL, &remaining);
537        /* snapped to early */
538        if (remaining<4)
539                return 0;
540
541        if (port)
542                return ntohs(port->dst);
543        else
544                return 0;
545}
546
547
548uint8_t *trace_get_source_mac(libtrace_packet_t *packet) {
549        void *link = trace_get_link(packet);
550        libtrace_80211_t *wifi;
551        libtrace_ether_t *ethptr = (libtrace_ether_t*)link;
552        if (!link)
553                return NULL;
554        switch (trace_get_link_type(packet)) {
555                case TRACE_TYPE_80211:
556                        wifi=(libtrace_80211_t*)link;
557                        return (uint8_t*)&wifi->mac2;
558                case TRACE_TYPE_80211_PRISM:
559                        wifi=(libtrace_80211_t*)((char*)link+144);
560                        return (uint8_t*)&wifi->mac2;
561                case TRACE_TYPE_ETH:
562                        return (uint8_t*)&ethptr->ether_shost;
563                case TRACE_TYPE_POS:
564                case TRACE_TYPE_NONE:
565                case TRACE_TYPE_HDLC_POS:
566                case TRACE_TYPE_LINUX_SLL:
567                case TRACE_TYPE_PFLOG:
568                case TRACE_TYPE_ATM:
569                case TRACE_TYPE_DUCK:
570                        return NULL;
571        }
572        fprintf(stderr,"Not implemented\n");
573        assert(0);
574        return NULL;
575}
576
577DLLEXPORT uint8_t *trace_get_destination_mac(libtrace_packet_t *packet) {
578        void *link = trace_get_link(packet);
579        libtrace_80211_t *wifi;
580        libtrace_ether_t *ethptr = (libtrace_ether_t*)link;
581        if (!link)
582                return NULL;
583        switch (trace_get_link_type(packet)) {
584                case TRACE_TYPE_80211:
585                        wifi=(libtrace_80211_t*)link;
586                        return (uint8_t*)&wifi->mac1;
587                case TRACE_TYPE_80211_PRISM:
588                        wifi=(libtrace_80211_t*)((char*)link+144);
589                        return (uint8_t*)&wifi->mac1;
590                case TRACE_TYPE_ETH:
591                        return (uint8_t*)&ethptr->ether_dhost;
592                case TRACE_TYPE_POS:
593                case TRACE_TYPE_NONE:
594                case TRACE_TYPE_ATM:
595                case TRACE_TYPE_HDLC_POS:
596                case TRACE_TYPE_LINUX_SLL:
597                case TRACE_TYPE_PFLOG:
598                case TRACE_TYPE_DUCK:
599                        /* No MAC address */
600                        return NULL;
601        }
602        fprintf(stderr,"Not implemented\n");
603        assert(0);
604        return NULL;
605}
606
607DLLEXPORT struct sockaddr *trace_get_source_address(const libtrace_packet_t *packet, 
608                struct sockaddr *addr)
609{
610        uint16_t proto;
611        uint32_t remaining;
612        void *l3;
613        struct ports_t *ports;
614        static struct sockaddr_storage dummy;
615
616        if (!addr)
617                addr=(struct sockaddr*)&dummy;
618
619        remaining = trace_get_capture_length(packet);
620
621        l3 = trace_get_payload_from_link(
622                        trace_get_link(packet),
623                        trace_get_link_type(packet),
624                        &proto,
625                        &remaining);
626
627        if (!l3)
628                return false;
629
630        l3 = trace_get_vlan_payload_from_ethernet_payload(l3,
631                        &proto,
632                        &remaining);
633
634        if (!l3)
635                return NULL;
636
637        switch (proto) {
638                case 0x0800: /* IPv4 */
639                {
640                        struct sockaddr_in *addr4=(struct sockaddr_in*)addr;
641                        libtrace_ip_t *ip = (libtrace_ip_t*)l3;
642                        ports = (struct ports_t*)
643                                trace_get_payload_from_ip(ip,NULL,&remaining);
644                        addr4->sin_family=AF_INET;
645                        if (ports && remaining>=sizeof(*ports))
646                                addr4->sin_port=ports->src;
647                        else
648                                addr4->sin_port=0;
649                        addr4->sin_addr=ip->ip_src;
650                        return addr;
651                }
652                case 0x86DD: /* IPv6 */
653                {
654                        struct sockaddr_in6 *addr6=(struct sockaddr_in6*)addr;
655                        libtrace_ip6_t *ip6 = (libtrace_ip6_t*)l3;
656                        ports = (struct ports_t*)
657                                trace_get_payload_from_ip6(ip6,NULL,&remaining);
658                        addr6->sin6_family=AF_INET6;
659                        if (ports && remaining>=sizeof(*ports))
660                                addr6->sin6_port=ports->dst;
661                        else
662                                addr6->sin6_port=0;
663                        addr6->sin6_flowinfo=0;
664                        addr6->sin6_addr=ip6->ip_src;
665                        return addr;
666                }
667                default:
668                        return NULL;
669        }
670}
671
672DLLEXPORT struct sockaddr *trace_get_destination_address(const libtrace_packet_t *packet, 
673                struct sockaddr *addr)
674{
675        uint16_t proto;
676        uint32_t remaining;
677        void *transport;
678        static struct sockaddr_storage dummy;
679
680        if (!addr)
681                addr=(struct sockaddr*)&dummy;
682
683        remaining = trace_get_capture_length(packet);
684
685        transport = trace_get_payload_from_link(
686                        trace_get_link(packet),
687                        trace_get_link_type(packet),
688                        &proto,
689                        &remaining);
690
691        if (!transport)
692                return false;
693
694        transport = trace_get_vlan_payload_from_ethernet_payload(transport,
695                        &proto,
696                        &remaining);
697
698        if (!transport)
699                return false;
700
701        switch (proto) {
702                case 0x0800: /* IPv4 */
703                {
704                        struct sockaddr_in *addr4=(struct sockaddr_in*)addr;
705                        libtrace_ip_t *ip = (libtrace_ip_t*)transport;
706                        addr4->sin_family=AF_INET;
707                        addr4->sin_port=0;
708                        addr4->sin_addr=ip->ip_dst;
709                        return addr;
710                }
711                case 0x86DD: /* IPv6 */
712                {
713                        struct sockaddr_in6 *addr6=(struct sockaddr_in6*)addr;
714                        libtrace_ip6_t *ip6 = (libtrace_ip6_t*)transport;
715                        addr6->sin6_family=AF_INET6;
716                        addr6->sin6_port=0;
717                        addr6->sin6_flowinfo=0;
718                        addr6->sin6_addr=ip6->ip_dst;
719                        return addr;
720                }
721                default:
722                        return NULL;
723        }
724}
725
726/* parse an ip or tcp option
727 * @param[in,out] ptr   the pointer to the current option
728 * @param[in,out] len   the length of the remaining buffer
729 * @param[out] type     the type of the option
730 * @param[out] optlen   the length of the option
731 * @param[out] data     the data of the option
732 *
733 * @returns bool true if there is another option (and the fields are filled in)
734 *               or false if this was the last option.
735 *
736 * This updates ptr to point to the next option after this one, and updates
737 * len to be the number of bytes remaining in the options area.  Type is updated
738 * to be the code of this option, and data points to the data of this option,
739 * with optlen saying how many bytes there are.
740 *
741 * @note Beware of fragmented packets.
742 * @author Perry Lorier
743 */
744DLLEXPORT int trace_get_next_option(unsigned char **ptr,int *len,
745                        unsigned char *type,
746                        unsigned char *optlen,
747                        unsigned char **data)
748{
749        if (*len<=0)
750                return 0;
751        *type=**ptr;
752        switch(*type) {
753                case 0: /* End of options */
754                        return 0;
755                case 1: /* Pad */
756                        (*ptr)++;
757                        (*len)--;
758                        return 1;
759                default:
760                        *optlen = *(*ptr+1);
761                        if (*optlen<2)
762                                return 0; /* I have no idea wtf is going on
763                                           * with these packets
764                                           */
765                        (*len)-=*optlen;
766                        (*data)=(*ptr+2);
767                        (*ptr)+=*optlen;
768                        if (*len<0)
769                                return 0;
770                        return 1;
771        }
772        assert(0);
773}
774
775
Note: See TracBrowser for help on using the repository browser.