source: lib/protocols_l2.c @ 322c516

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 322c516 was 461582b, checked in by Shane Alcock <salcock@…>, 6 years ago

Ethertype and linktype are not the same thing!

  • Property mode set to 100644
File size: 20.4 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007,2008,2009,2010 The University of Waikato, Hamilton,
5 * New Zealand.
6 *
7 * Authors: Daniel Lawson
8 *          Perry Lorier
9 *          Shane Alcock
10 *         
11 * All rights reserved.
12 *
13 * This code has been developed by the University of Waikato WAND
14 * research group. For further information please see http://www.wand.net.nz/
15 *
16 * libtrace is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * libtrace is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with libtrace; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 *
30 * $Id$
31 *
32 */
33
34#include "libtrace_int.h"
35#include "libtrace.h"
36#include "protocols.h"
37#include <assert.h>
38#include <stdlib.h>
39#include <string.h>
40
41
42/* This file contains all the protocol decoding functions for layer 2
43 * (and 2.5) protocols. This includes functions for accessing MAC addresses.
44 *
45 * Supported protocols include (but are not limited to):
46 *      Ethernet
47 *      802.11
48 *      802.1q (vlan)
49 *      MPLS
50 *      PPPoE
51 *      LLCSnap
52 *      ATM
53 */
54
55
56/* Returns the payload from 802.3 ethernet.  Type optionally returned in
57 * "type" in host byte order.  This will return a vlan header.
58 */
59void *trace_get_payload_from_ethernet(void *ethernet, 
60                uint16_t *type,
61                uint32_t *remaining)
62{
63        libtrace_ether_t *eth = (libtrace_ether_t*)ethernet;
64
65        if (remaining) {
66                if (*remaining < sizeof(*eth)) {
67                        *remaining = 0;
68                        return NULL;
69                }
70                *remaining-=sizeof(*eth);
71        }
72
73        if (type)
74                *type = ntohs(eth->ether_type);
75
76        return (void*)((char *)eth + sizeof(*eth));
77}
78
79/* Skip any 802.1q headers if necessary
80 * type is now output only (why check it if we don't need to?)
81 */
82void *trace_get_payload_from_vlan(void *ethernet, uint16_t *type,
83                uint32_t *remaining)
84{
85        libtrace_8021q_t *vlanhdr = (libtrace_8021q_t *)ethernet;
86
87        if (remaining) {
88                if (*remaining < sizeof(libtrace_8021q_t)) {
89                        *remaining = 0;
90                        return NULL;
91                }
92
93                *remaining=*remaining-sizeof(libtrace_8021q_t);
94        }
95
96        if (type)
97                *type = ntohs(vlanhdr->vlan_ether_type);
98
99        return (void*)((char *)ethernet + sizeof(*vlanhdr));
100
101}
102
103libtrace_packet_t *trace_strip_packet(libtrace_packet_t *packet) {
104
105        libtrace_ether_t *ethernet;
106        libtrace_linktype_t linktype;
107        uint16_t ethertype;
108        uint32_t remaining;
109        char *nextpayload;
110        uint16_t finalethertype = 0;
111        uint16_t caplen, removed = 0;
112        char *dest;
113        uint8_t done = 0;
114        uint32_t oldrem;
115
116        /* For now, this will just work for Ethernet packets. */
117        ethernet = (libtrace_ether_t *)trace_get_layer2(packet, 
118                        &linktype, &remaining);
119
120        if (linktype != TRACE_TYPE_ETH) {
121                return packet;
122        }
123
124        /* No headers to strip, return the original packet */
125        if (ethernet->ether_type == TRACE_ETHERTYPE_IP ||
126                        ethernet->ether_type == TRACE_ETHERTYPE_IPV6) {
127                return packet;
128        }
129
130        if (remaining <= sizeof(libtrace_ether_t))
131                return packet;
132
133        caplen = trace_get_capture_length(packet);
134        ethertype = ntohs(ethernet->ether_type);
135        dest = ((char *)ethernet) + sizeof(libtrace_ether_t);
136        nextpayload = dest;
137        remaining -= sizeof(libtrace_ether_t);
138
139        /* I'd normally use trace_get_layer3 here, but it works out faster
140         * to do it this way (mostly less function call overhead).
141         *
142         * XXX This approach is going to just strip everything between the
143         * Ethernet and IP headers -- is there a use case where someone
144         * might want to selectively strip headers?
145         */
146        while (!done) {
147
148                if (nextpayload == NULL || remaining == 0)
149                        break;
150
151                oldrem = remaining;
152                switch (ethertype) {
153
154                case TRACE_ETHERTYPE_8021Q:
155                        nextpayload = (char *)trace_get_payload_from_vlan(
156                                        nextpayload,
157                                        &ethertype, &remaining);
158                        removed += (oldrem - remaining);
159                        break;
160
161                case TRACE_ETHERTYPE_MPLS:
162                        nextpayload = (char *)trace_get_payload_from_mpls(
163                                        nextpayload,
164                                        &ethertype, &remaining);
165                        removed += (oldrem - remaining);
166                        break;
167                case TRACE_ETHERTYPE_PPP_SES:
168                        nextpayload = (char *)trace_get_payload_from_pppoe(
169                                        nextpayload,
170                                        &ethertype, &remaining);
171                        removed += (oldrem - remaining);
172                        break;
173
174                case TRACE_ETHERTYPE_IP:
175                case TRACE_ETHERTYPE_IPV6:
176                default:
177                        if (finalethertype == 0)
178                                finalethertype = ethertype;
179                        done = true;
180                        break;
181                }
182        }
183
184        if (nextpayload != NULL) {
185
186                ethernet->ether_type = ntohs(finalethertype);
187                trace_set_capture_length(packet, caplen - removed);
188                memmove(nextpayload - (dest - (char *)packet->payload), 
189                        packet->payload, 
190                        (dest - (char *)packet->payload));
191                packet->payload = nextpayload - (dest - (char *)packet->payload);
192                packet->l2_header = NULL;
193        }
194       
195        return packet;
196
197}
198
199/* Skip any MPLS headers if necessary, guessing what the next type is
200 * type is input/output.  If the next type is "ethernet" this will
201 * return a type of 0x0000.
202 */
203void *trace_get_payload_from_mpls(void *ethernet, uint16_t *type, 
204                uint32_t *remaining)
205{
206       
207        assert(type);
208        if ((((char*)ethernet)[2]&0x01)==0) {
209                /* The MPLS Stack bit is set */
210                *type = TRACE_ETHERTYPE_MPLS;
211        }
212        else {
213                if (!remaining || *remaining>=5) {
214                        switch (((char*)ethernet)[4]&0xF0) {
215                                case 0x40:      /* IPv4 */
216                                        *type = TRACE_ETHERTYPE_IP;
217                                        break;
218                                case 0x60:      /* IPv6 */
219                                        *type = TRACE_ETHERTYPE_IPV6;
220                                        break;
221                                default:        /* VPLS */
222                                        /* Ethernet */
223                                        *type = 0;
224                        }
225                }
226        }
227        ethernet=(char*)ethernet+4;
228        if (remaining) {
229                if (*remaining<4)
230                        return NULL;
231                else
232                        *remaining-=4;
233        }
234
235
236        return ethernet;
237}
238
239static void *trace_get_payload_from_llcsnap(void *link,
240                uint16_t *type, uint32_t *remaining)
241{
242        /* 64 byte capture. */
243        libtrace_llcsnap_t *llc = (libtrace_llcsnap_t*)link;
244
245        if (remaining) {
246                if (*remaining < sizeof(libtrace_llcsnap_t)) {
247                        *remaining = 0;
248                        return NULL;
249                }
250                *remaining-=(sizeof(libtrace_llcsnap_t));
251        }
252
253        llc = (libtrace_llcsnap_t*)((char *)llc);
254
255        if (type) *type = ntohs(llc->type);
256
257        return (void*)((char*)llc+sizeof(*llc));
258}
259
260
261static void *trace_get_payload_from_80211(void *link, uint16_t *type, uint32_t *remaining)
262{
263        libtrace_80211_t *wifi;
264        uint16_t *eth; /* ethertype */
265        int8_t extra = 0; /* how many QoS bytes to skip */
266       
267        if (remaining && *remaining < sizeof(libtrace_80211_t)) {
268                *remaining = 0;
269                return NULL;
270        }
271
272        wifi=(libtrace_80211_t*)link;
273
274        /* Data packet? */
275        if (wifi->type != 2) {
276                return NULL;
277        }
278
279        /* If FromDS and ToDS are both set then we have a four-address
280         * frame. Otherwise we have a three-address frame */
281        if (!(wifi->to_ds && wifi->from_ds)) 
282                extra -= 6; 
283       
284        /* Indicates QoS field present, see IEEE802.11e-2005 pg 21 */
285        if (wifi->subtype & 0x8) 
286                extra += 2;
287
288        if (remaining && *remaining < sizeof(*eth)) {
289                *remaining = 0;
290                return NULL;
291        }
292
293        eth=(uint16_t *)((char*)wifi+sizeof(*wifi)+extra);
294       
295        if (*eth == 0xaaaa)
296                /* Payload contains an 802.2 LLC/SNAP frame */
297                return trace_get_payload_from_llcsnap((void *)eth, type, remaining);
298                       
299        /* Otherwise we assume an Ethernet II frame */
300        if (type) *type=ntohs(*eth);
301        if (remaining) *remaining = *remaining - sizeof(libtrace_80211_t) - extra - sizeof(*eth);
302       
303        return (void*)((char*)eth+sizeof(*eth));
304}
305
306static void *trace_get_payload_from_ppp(void *link, 
307                uint16_t *type, uint32_t *remaining)
308{
309        /* 64 byte capture. */
310        libtrace_ppp_t *ppp = (libtrace_ppp_t*)link;
311
312        if (remaining) {
313                if (*remaining < sizeof(libtrace_ppp_t)) {
314                        *remaining = 0;
315                        return NULL;
316                }
317                *remaining-=sizeof(libtrace_ppp_t);
318        }
319
320        if (type) {
321                switch(ntohs(ppp->protocol)) {
322                        case 0x0021: *type = TRACE_ETHERTYPE_IP; break;
323                        /* If it isn't IP, then it is probably PPP control and
324                         * I can't imagine anyone caring about that too much
325                         */
326                        default: *type = 0; break;
327                }
328        }
329
330
331        return (void*)((char *)ppp+sizeof(*ppp));
332}
333
334void *trace_get_payload_from_pppoe(void *link, uint16_t *type, 
335                uint32_t *remaining) {
336        assert(type);
337       
338        if (remaining) {
339                if (*remaining < sizeof(libtrace_pppoe_t)) {
340                        *remaining = 0;
341                        return NULL;
342                }
343                *remaining -= sizeof(libtrace_pppoe_t);
344        }
345       
346        /* PPPoE is always followed by PPP */
347        return trace_get_payload_from_ppp(link + sizeof(libtrace_pppoe_t),
348                        type, remaining);
349}
350       
351/* Header for CHDLC framing */
352typedef struct libtrace_chdlc_t {
353        uint8_t address;        /** 0xF0 for unicast, 0xF8 for multicast */
354        uint8_t control;        /** Always 0x00 */
355        uint16_t ethertype;
356} libtrace_chdlc_t;
357
358/* Header for PPP in HDLC-like framing */
359typedef struct libtrace_ppp_hdlc_t {
360        uint8_t address;        /** Always should be 0xff */
361        uint8_t control;        /** Always should be 0x03 */
362        uint16_t protocol;     
363} libtrace_ppp_hdlc_t;
364
365static void *trace_get_payload_from_chdlc(void *link, uint16_t *type,
366                uint32_t *remaining) {
367
368        libtrace_chdlc_t *chdlc = (libtrace_chdlc_t *)link;
369
370        if (remaining) {
371                if (*remaining < sizeof(libtrace_chdlc_t)) {
372                        *remaining = 0;
373                        return NULL;
374                }
375                *remaining -= sizeof(libtrace_chdlc_t);
376        }
377
378        if (type) {
379                *type = ntohs(chdlc->ethertype);
380        }
381
382        return (void *)((char *)chdlc + sizeof(*chdlc));
383
384}
385
386static void *trace_get_payload_from_ppp_hdlc(void *link, 
387                uint16_t *type, uint32_t *remaining)
388{
389        libtrace_ppp_hdlc_t *ppp_hdlc = (libtrace_ppp_hdlc_t*)link;
390
391        if (remaining) {
392                if (*remaining < sizeof(libtrace_ppp_hdlc_t)) {
393                        *remaining = 0;
394                        return NULL;
395                }
396                *remaining-=sizeof(libtrace_ppp_hdlc_t);
397        }
398
399        if (type) {
400                /* http://www.iana.org/assignments/ppp-numbers */
401
402                switch(ntohs(ppp_hdlc->protocol)) {
403                        case 0x0021: /* IP */
404                                *type = TRACE_ETHERTYPE_IP;
405                                break;
406                        case 0xc021: /* Link Control Protocol */
407                                *type = 0; /* No ethertype for this */
408                                break;
409
410                        default:
411                                printf("Unknown chdlc type: %04x\n",
412                                                ntohs(ppp_hdlc->protocol));
413                                *type = 0; /* Unknown */
414                }
415        }
416
417
418        return (void*)((char *)ppp_hdlc+sizeof(*ppp_hdlc));
419}
420
421void *trace_get_payload_from_link(void *link, libtrace_linktype_t linktype, 
422                uint16_t *ethertype, uint32_t *remaining)
423{
424        void *l = NULL;
425
426        do {
427                l = trace_get_payload_from_meta(link, &linktype, remaining);
428                if (l != NULL) {
429                        link=l;
430                }
431        } while (l != NULL);
432
433        return trace_get_payload_from_layer2(link,linktype,ethertype,remaining);
434       
435}
436
437DLLEXPORT void *trace_get_layer2(const libtrace_packet_t *packet,
438                libtrace_linktype_t *linktype,
439                uint32_t *remaining) 
440{
441        uint32_t dummyrem;
442        void *meta = NULL;
443       
444        assert(packet != NULL);
445        assert(linktype != NULL);
446
447        if (remaining == NULL)
448                remaining = &dummyrem;
449
450        if (packet->l2_header) {
451                /* Use cached values */
452                *linktype = packet->link_type;
453                *remaining = packet->l2_remaining;
454                return packet->l2_header;
455        }
456
457        /* Code looks a bit inefficient, but I'm actually trying to avoid
458         * calling trace_get_packet_buffer more than once like we used to.
459         */
460       
461        meta = trace_get_packet_buffer(packet, linktype, remaining);
462
463        /* If there are no meta-data headers, we just return the start of the
464         * packet buffer, along with the linktype, etc.
465         */
466        switch(*linktype) {
467                /* meta points to a layer 2 header! */
468                case TRACE_TYPE_HDLC_POS:
469                case TRACE_TYPE_ETH:
470                case TRACE_TYPE_ATM:
471                case TRACE_TYPE_80211:
472                case TRACE_TYPE_NONE:
473                case TRACE_TYPE_POS:
474                case TRACE_TYPE_AAL5:
475                case TRACE_TYPE_DUCK:
476                case TRACE_TYPE_LLCSNAP:
477                case TRACE_TYPE_PPP:
478                case TRACE_TYPE_METADATA:
479                case TRACE_TYPE_NONDATA:
480                case TRACE_TYPE_OPENBSD_LOOP:
481                        ((libtrace_packet_t*)packet)->l2_header = meta;
482                        ((libtrace_packet_t*)packet)->l2_remaining = *remaining;
483                        return meta;
484                case TRACE_TYPE_LINUX_SLL:
485                case TRACE_TYPE_80211_RADIO:
486                case TRACE_TYPE_80211_PRISM:
487                case TRACE_TYPE_PFLOG:
488                        break;
489                case TRACE_TYPE_UNKNOWN:
490                        return NULL;
491        }
492
493        /* If there are meta-data headers, we need to skip over them until we
494         * find a non-meta data header and return that.
495         */
496        for(;;) {
497                void *nexthdr = trace_get_payload_from_meta(meta, 
498                                linktype, remaining);
499               
500                if (nexthdr == NULL) {
501                        switch (*linktype) {
502                                /* meta points to a layer 2 header! */
503                                case TRACE_TYPE_HDLC_POS:
504                                case TRACE_TYPE_ETH:
505                                case TRACE_TYPE_ATM:
506                                case TRACE_TYPE_80211:
507                                case TRACE_TYPE_NONE:
508                                case TRACE_TYPE_POS:
509                                case TRACE_TYPE_AAL5:
510                                case TRACE_TYPE_DUCK:
511                                case TRACE_TYPE_LLCSNAP:
512                                case TRACE_TYPE_PPP:
513                                case TRACE_TYPE_METADATA:
514                                case TRACE_TYPE_NONDATA:
515                                case TRACE_TYPE_OPENBSD_LOOP:
516                                        ((libtrace_packet_t*)packet)->l2_header = meta;
517                                        ((libtrace_packet_t*)packet)->l2_remaining = *remaining;
518                                        return meta;
519                                case TRACE_TYPE_LINUX_SLL:
520                                case TRACE_TYPE_80211_RADIO:
521                                case TRACE_TYPE_80211_PRISM:
522                                case TRACE_TYPE_PFLOG:
523                                        break;
524                                case TRACE_TYPE_UNKNOWN:
525                                        return NULL;
526                        }
527                       
528                        /* Otherwise, we must have hit the end of the packet */
529                        return NULL;
530                }
531         
532               
533                meta = nexthdr;
534        }
535
536}
537
538DLLEXPORT
539void *trace_get_payload_from_atm(void *link,
540                uint8_t *type, uint32_t *remaining)
541{
542        libtrace_atm_capture_cell_t *cell;
543        if (remaining && *remaining<sizeof(libtrace_atm_capture_cell_t)) {
544                *remaining = 0;
545                return NULL;
546        }
547        cell=(libtrace_atm_capture_cell_t*)link;
548
549        if (type)
550                *type=cell->pt;
551
552        if (remaining)
553                *remaining-=sizeof(libtrace_atm_capture_cell_t);
554
555        return ((char*)link)+sizeof(libtrace_atm_capture_cell_t);
556}
557
558
559
560DLLEXPORT void *trace_get_payload_from_layer2(void *link,
561                libtrace_linktype_t linktype,
562                uint16_t *ethertype,
563                uint32_t *remaining)
564{
565        void *l;
566
567        if (linktype == TRACE_TYPE_UNKNOWN) {
568                fprintf(stderr, "Unable to determine linktype for packet\n");
569                return NULL;
570        }
571       
572        switch(linktype) {
573                /* Packet Metadata headers, not layer2 headers */
574                case TRACE_TYPE_80211_PRISM:
575                case TRACE_TYPE_80211_RADIO:
576                case TRACE_TYPE_PFLOG:
577                case TRACE_TYPE_LINUX_SLL:
578                        return NULL;
579
580                /* duck packets have no payload! */
581                case TRACE_TYPE_DUCK:
582                        return NULL;
583
584                /* The payload is in these packets does
585                   not correspond to a genuine link-layer
586                   */
587                case TRACE_TYPE_METADATA:
588                case TRACE_TYPE_NONDATA:
589                case TRACE_TYPE_UNKNOWN:
590                        return NULL;
591
592                case TRACE_TYPE_80211:
593                        return trace_get_payload_from_80211(link,ethertype,remaining);
594                case TRACE_TYPE_ETH:
595                        return trace_get_payload_from_ethernet(link,ethertype,remaining);
596                case TRACE_TYPE_NONE:
597                        if ((*(char*)link&0xF0) == 0x40)
598                                *ethertype=TRACE_ETHERTYPE_IP;   /* IPv4 */
599                        else if ((*(char*)link&0xF0) == 0x60)
600                                *ethertype=TRACE_ETHERTYPE_IPV6; /* IPv6 */
601                        return link; /* I love the simplicity */
602                case TRACE_TYPE_PPP:
603                        return trace_get_payload_from_ppp(link,ethertype,remaining);
604                case TRACE_TYPE_ATM:
605                        l=trace_get_payload_from_atm(link,NULL,remaining);
606                        /* FIXME: We shouldn't skip llcsnap here, we should
607                         * return an ethertype for it (somehow)
608                         */
609                        return (l ? trace_get_payload_from_llcsnap(l,
610                                                ethertype, remaining):NULL);
611                case TRACE_TYPE_LLCSNAP:
612                        return trace_get_payload_from_llcsnap(link,ethertype,remaining);
613
614                case TRACE_TYPE_HDLC_POS:
615                        return trace_get_payload_from_chdlc(link,ethertype,
616                                        remaining);
617                case TRACE_TYPE_POS:
618                        return trace_get_payload_from_ppp_hdlc(link,ethertype,
619                                        remaining);
620                /* TODO: Unsupported */
621                case TRACE_TYPE_AAL5:
622                        return NULL;
623
624                case TRACE_TYPE_OPENBSD_LOOP:
625                        link = link + 4; /* Loopback header is 4 bytes */
626                        if ((*(char*)link&0xF0) == 0x40)
627                                *ethertype=TRACE_ETHERTYPE_IP;   /* IPv4 */
628                        else if ((*(char*)link&0xF0) == 0x60)
629                                *ethertype=TRACE_ETHERTYPE_IPV6; /* IPv6 */
630                        return link; /* I love the simplicity */
631               
632
633        }
634        return NULL;
635
636}
637
638/* Take a pointer to the start of an IEEE 802.11 MAC frame and return a pointer
639 * to the source MAC address. 
640 * If the frame does not contain a sender address, e.g. ACK frame, return NULL.
641 * If the frame is a 4-address WDS frame, return TA, i.e. addr2.
642 * NB: This function decodes the 802.11 header, so it assumes that there are no
643 * bit-errors. If there are, all bets are off.
644 */
645static
646uint8_t *get_source_mac_from_wifi(void *wifi) {
647        struct libtrace_80211_t *w;
648        if (wifi == NULL) return NULL;
649        w = (struct libtrace_80211_t *) wifi;
650
651        /* If the frame is of type CTRL */
652        if (w->type == 0x1)
653                /* If bit 2 of the subtype field is zero, this indicates that
654                 * there is no transmitter address, i.e. the frame is either an
655                 * ACK or a CTS frame */
656                if ((w->subtype & 0x2) == 0)
657                        return NULL;
658
659        /* Always return the address of the transmitter, i.e. address 2 */
660        return (uint8_t *) &w->mac2;
661}
662
663DLLEXPORT uint8_t *trace_get_source_mac(libtrace_packet_t *packet) {
664        void *link;
665        uint32_t remaining;
666        libtrace_linktype_t linktype;
667        assert(packet);
668        link = trace_get_layer2(packet,&linktype,&remaining);
669
670        if (!link)
671                return NULL;
672
673        switch (linktype) {
674                case TRACE_TYPE_ETH:
675                        return (uint8_t *)&(((libtrace_ether_t*)link)->ether_shost);
676                case TRACE_TYPE_80211:
677                        return get_source_mac_from_wifi(link);
678                /* These packets don't have MAC addresses */
679                case TRACE_TYPE_POS:
680                case TRACE_TYPE_NONE:
681                case TRACE_TYPE_HDLC_POS:
682                case TRACE_TYPE_PFLOG:
683                case TRACE_TYPE_ATM:
684                case TRACE_TYPE_DUCK:
685                case TRACE_TYPE_METADATA:
686                case TRACE_TYPE_AAL5:
687                case TRACE_TYPE_LLCSNAP:
688                case TRACE_TYPE_PPP:
689                case TRACE_TYPE_NONDATA:
690                case TRACE_TYPE_OPENBSD_LOOP:
691                case TRACE_TYPE_UNKNOWN:
692                        return NULL;
693
694                /* Metadata headers should already be skipped */
695                case TRACE_TYPE_LINUX_SLL:
696                case TRACE_TYPE_80211_PRISM:
697                case TRACE_TYPE_80211_RADIO:
698                        assert(!"Metadata headers should already be skipped");
699                        break;
700        }
701        fprintf(stderr,"%s not implemented for linktype %i\n", __func__, linktype);
702        assert(0);
703        return NULL;
704}
705
706DLLEXPORT uint8_t *trace_get_destination_mac(libtrace_packet_t *packet)
707{
708        void *link;
709        libtrace_linktype_t linktype;
710        uint32_t remaining;
711        libtrace_80211_t *wifi;
712        libtrace_ether_t *ethptr;
713
714        link = trace_get_layer2(packet,&linktype,&remaining);
715
716        ethptr = (libtrace_ether_t*)link;
717
718
719        if (!link)
720                return NULL;
721
722        switch (linktype) {
723                case TRACE_TYPE_80211:
724                        wifi=(libtrace_80211_t*)link;
725                        return (uint8_t*)&wifi->mac1;
726                case TRACE_TYPE_ETH:
727                        return (uint8_t*)&ethptr->ether_dhost;
728                case TRACE_TYPE_POS:
729                case TRACE_TYPE_NONE:
730                case TRACE_TYPE_ATM:
731                case TRACE_TYPE_HDLC_POS:
732                case TRACE_TYPE_PFLOG:
733                case TRACE_TYPE_DUCK:
734                case TRACE_TYPE_METADATA:
735                case TRACE_TYPE_AAL5:
736                case TRACE_TYPE_LLCSNAP:
737                case TRACE_TYPE_PPP:   
738                case TRACE_TYPE_NONDATA:
739                case TRACE_TYPE_OPENBSD_LOOP:
740                case TRACE_TYPE_UNKNOWN:
741                        /* No MAC address */
742                        return NULL;
743                /* Metadata headers should already be skipped */
744                case TRACE_TYPE_LINUX_SLL:
745                case TRACE_TYPE_80211_PRISM:
746                case TRACE_TYPE_80211_RADIO:
747                        assert(!"Metadata headers should already be skipped");
748                        break;
749        }
750        fprintf(stderr,"Not implemented\n");
751        assert(0);
752        return NULL;
753}
754
Note: See TracBrowser for help on using the repository browser.