source: lib/protocols_l2.c @ 0277ab8

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 0277ab8 was 0277ab8, checked in by Shane Alcock <salcock@…>, 5 years ago

Completed improvement of trace_strip_packet()

  • Removed the trace_copy_packet() if the packet is not totally owned by libtrace. I think we can get away without it and we really don't want the performance hit when dealing with live captures.
  • Replaced call to trace_get_layer3 with the old header parsing code from the previous version of trace_strip_packet(). The overhead of calling trace_get_layer3 was outweighing the performance gain from the change in memmove strategy.
  • Removed ability to selectively strip VLAN or MPLS headers only -- this was not that useful and supporting it would make the code much more complex.
  • Updated trace_get_layer3 to use the cached layer 2 header if available rather than making a call to trace_get_layer2 and getting it from there. This saves us a bit of function call overhead.
  • Make sure we reset the layer 2 cached info if we shift the Ethernet header.
  • Strip PPPoE in addition to MPLS and VLAN.
  • Property mode set to 100644
File size: 20.5 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                packet->link_type = finalethertype;
194        }
195       
196        return packet;
197
198}
199
200/* Skip any MPLS headers if necessary, guessing what the next type is
201 * type is input/output.  If the next type is "ethernet" this will
202 * return a type of 0x0000.
203 */
204void *trace_get_payload_from_mpls(void *ethernet, uint16_t *type, 
205                uint32_t *remaining)
206{
207       
208        assert(type);
209        if ((((char*)ethernet)[2]&0x01)==0) {
210                /* The MPLS Stack bit is set */
211                *type = TRACE_ETHERTYPE_MPLS;
212        }
213        else {
214                if (!remaining || *remaining>=5) {
215                        switch (((char*)ethernet)[4]&0xF0) {
216                                case 0x40:      /* IPv4 */
217                                        *type = TRACE_ETHERTYPE_IP;
218                                        break;
219                                case 0x60:      /* IPv6 */
220                                        *type = TRACE_ETHERTYPE_IPV6;
221                                        break;
222                                default:        /* VPLS */
223                                        /* Ethernet */
224                                        *type = 0;
225                        }
226                }
227        }
228        ethernet=(char*)ethernet+4;
229        if (remaining) {
230                if (*remaining<4)
231                        return NULL;
232                else
233                        *remaining-=4;
234        }
235
236
237        return ethernet;
238}
239
240static void *trace_get_payload_from_llcsnap(void *link,
241                uint16_t *type, uint32_t *remaining)
242{
243        /* 64 byte capture. */
244        libtrace_llcsnap_t *llc = (libtrace_llcsnap_t*)link;
245
246        if (remaining) {
247                if (*remaining < sizeof(libtrace_llcsnap_t)) {
248                        *remaining = 0;
249                        return NULL;
250                }
251                *remaining-=(sizeof(libtrace_llcsnap_t));
252        }
253
254        llc = (libtrace_llcsnap_t*)((char *)llc);
255
256        if (type) *type = ntohs(llc->type);
257
258        return (void*)((char*)llc+sizeof(*llc));
259}
260
261
262static void *trace_get_payload_from_80211(void *link, uint16_t *type, uint32_t *remaining)
263{
264        libtrace_80211_t *wifi;
265        uint16_t *eth; /* ethertype */
266        int8_t extra = 0; /* how many QoS bytes to skip */
267       
268        if (remaining && *remaining < sizeof(libtrace_80211_t)) {
269                *remaining = 0;
270                return NULL;
271        }
272
273        wifi=(libtrace_80211_t*)link;
274
275        /* Data packet? */
276        if (wifi->type != 2) {
277                return NULL;
278        }
279
280        /* If FromDS and ToDS are both set then we have a four-address
281         * frame. Otherwise we have a three-address frame */
282        if (!(wifi->to_ds && wifi->from_ds)) 
283                extra -= 6; 
284       
285        /* Indicates QoS field present, see IEEE802.11e-2005 pg 21 */
286        if (wifi->subtype & 0x8) 
287                extra += 2;
288
289        if (remaining && *remaining < sizeof(*eth)) {
290                *remaining = 0;
291                return NULL;
292        }
293
294        eth=(uint16_t *)((char*)wifi+sizeof(*wifi)+extra);
295       
296        if (*eth == 0xaaaa)
297                /* Payload contains an 802.2 LLC/SNAP frame */
298                return trace_get_payload_from_llcsnap((void *)eth, type, remaining);
299                       
300        /* Otherwise we assume an Ethernet II frame */
301        if (type) *type=ntohs(*eth);
302        if (remaining) *remaining = *remaining - sizeof(libtrace_80211_t) - extra - sizeof(*eth);
303       
304        return (void*)((char*)eth+sizeof(*eth));
305}
306
307static void *trace_get_payload_from_ppp(void *link, 
308                uint16_t *type, uint32_t *remaining)
309{
310        /* 64 byte capture. */
311        libtrace_ppp_t *ppp = (libtrace_ppp_t*)link;
312
313        if (remaining) {
314                if (*remaining < sizeof(libtrace_ppp_t)) {
315                        *remaining = 0;
316                        return NULL;
317                }
318                *remaining-=sizeof(libtrace_ppp_t);
319        }
320
321        if (type) {
322                switch(ntohs(ppp->protocol)) {
323                        case 0x0021: *type = TRACE_ETHERTYPE_IP; break;
324                        /* If it isn't IP, then it is probably PPP control and
325                         * I can't imagine anyone caring about that too much
326                         */
327                        default: *type = 0; break;
328                }
329        }
330
331
332        return (void*)((char *)ppp+sizeof(*ppp));
333}
334
335void *trace_get_payload_from_pppoe(void *link, uint16_t *type, 
336                uint32_t *remaining) {
337        assert(type);
338       
339        if (remaining) {
340                if (*remaining < sizeof(libtrace_pppoe_t)) {
341                        *remaining = 0;
342                        return NULL;
343                }
344                *remaining -= sizeof(libtrace_pppoe_t);
345        }
346       
347        /* PPPoE is always followed by PPP */
348        return trace_get_payload_from_ppp(link + sizeof(libtrace_pppoe_t),
349                        type, remaining);
350}
351       
352/* Header for CHDLC framing */
353typedef struct libtrace_chdlc_t {
354        uint8_t address;        /** 0xF0 for unicast, 0xF8 for multicast */
355        uint8_t control;        /** Always 0x00 */
356        uint16_t ethertype;
357} libtrace_chdlc_t;
358
359/* Header for PPP in HDLC-like framing */
360typedef struct libtrace_ppp_hdlc_t {
361        uint8_t address;        /** Always should be 0xff */
362        uint8_t control;        /** Always should be 0x03 */
363        uint16_t protocol;     
364} libtrace_ppp_hdlc_t;
365
366static void *trace_get_payload_from_chdlc(void *link, uint16_t *type,
367                uint32_t *remaining) {
368
369        libtrace_chdlc_t *chdlc = (libtrace_chdlc_t *)link;
370
371        if (remaining) {
372                if (*remaining < sizeof(libtrace_chdlc_t)) {
373                        *remaining = 0;
374                        return NULL;
375                }
376                *remaining -= sizeof(libtrace_chdlc_t);
377        }
378
379        if (type) {
380                *type = ntohs(chdlc->ethertype);
381        }
382
383        return (void *)((char *)chdlc + sizeof(*chdlc));
384
385}
386
387static void *trace_get_payload_from_ppp_hdlc(void *link, 
388                uint16_t *type, uint32_t *remaining)
389{
390        libtrace_ppp_hdlc_t *ppp_hdlc = (libtrace_ppp_hdlc_t*)link;
391
392        if (remaining) {
393                if (*remaining < sizeof(libtrace_ppp_hdlc_t)) {
394                        *remaining = 0;
395                        return NULL;
396                }
397                *remaining-=sizeof(libtrace_ppp_hdlc_t);
398        }
399
400        if (type) {
401                /* http://www.iana.org/assignments/ppp-numbers */
402
403                switch(ntohs(ppp_hdlc->protocol)) {
404                        case 0x0021: /* IP */
405                                *type = TRACE_ETHERTYPE_IP;
406                                break;
407                        case 0xc021: /* Link Control Protocol */
408                                *type = 0; /* No ethertype for this */
409                                break;
410
411                        default:
412                                printf("Unknown chdlc type: %04x\n",
413                                                ntohs(ppp_hdlc->protocol));
414                                *type = 0; /* Unknown */
415                }
416        }
417
418
419        return (void*)((char *)ppp_hdlc+sizeof(*ppp_hdlc));
420}
421
422void *trace_get_payload_from_link(void *link, libtrace_linktype_t linktype, 
423                uint16_t *ethertype, uint32_t *remaining)
424{
425        void *l = NULL;
426
427        do {
428                l = trace_get_payload_from_meta(link, &linktype, remaining);
429                if (l != NULL) {
430                        link=l;
431                }
432        } while (l != NULL);
433
434        return trace_get_payload_from_layer2(link,linktype,ethertype,remaining);
435       
436}
437
438DLLEXPORT void *trace_get_layer2(const libtrace_packet_t *packet,
439                libtrace_linktype_t *linktype,
440                uint32_t *remaining) 
441{
442        uint32_t dummyrem;
443        void *meta = NULL;
444       
445        assert(packet != NULL);
446        assert(linktype != NULL);
447
448        if (remaining == NULL)
449                remaining = &dummyrem;
450
451        if (packet->l2_header) {
452                /* Use cached values */
453                *linktype = packet->link_type;
454                *remaining = packet->l2_remaining;
455                return packet->l2_header;
456        }
457
458        /* Code looks a bit inefficient, but I'm actually trying to avoid
459         * calling trace_get_packet_buffer more than once like we used to.
460         */
461       
462        meta = trace_get_packet_buffer(packet, linktype, remaining);
463
464        /* If there are no meta-data headers, we just return the start of the
465         * packet buffer, along with the linktype, etc.
466         */
467        switch(*linktype) {
468                /* meta points to a layer 2 header! */
469                case TRACE_TYPE_HDLC_POS:
470                case TRACE_TYPE_ETH:
471                case TRACE_TYPE_ATM:
472                case TRACE_TYPE_80211:
473                case TRACE_TYPE_NONE:
474                case TRACE_TYPE_POS:
475                case TRACE_TYPE_AAL5:
476                case TRACE_TYPE_DUCK:
477                case TRACE_TYPE_LLCSNAP:
478                case TRACE_TYPE_PPP:
479                case TRACE_TYPE_METADATA:
480                case TRACE_TYPE_NONDATA:
481                case TRACE_TYPE_OPENBSD_LOOP:
482                        ((libtrace_packet_t*)packet)->l2_header = meta;
483                        ((libtrace_packet_t*)packet)->l2_remaining = *remaining;
484                        return meta;
485                case TRACE_TYPE_LINUX_SLL:
486                case TRACE_TYPE_80211_RADIO:
487                case TRACE_TYPE_80211_PRISM:
488                case TRACE_TYPE_PFLOG:
489                        break;
490                case TRACE_TYPE_UNKNOWN:
491                        return NULL;
492        }
493
494        /* If there are meta-data headers, we need to skip over them until we
495         * find a non-meta data header and return that.
496         */
497        for(;;) {
498                void *nexthdr = trace_get_payload_from_meta(meta, 
499                                linktype, remaining);
500               
501                if (nexthdr == NULL) {
502                        switch (*linktype) {
503                                /* meta points to a layer 2 header! */
504                                case TRACE_TYPE_HDLC_POS:
505                                case TRACE_TYPE_ETH:
506                                case TRACE_TYPE_ATM:
507                                case TRACE_TYPE_80211:
508                                case TRACE_TYPE_NONE:
509                                case TRACE_TYPE_POS:
510                                case TRACE_TYPE_AAL5:
511                                case TRACE_TYPE_DUCK:
512                                case TRACE_TYPE_LLCSNAP:
513                                case TRACE_TYPE_PPP:
514                                case TRACE_TYPE_METADATA:
515                                case TRACE_TYPE_NONDATA:
516                                case TRACE_TYPE_OPENBSD_LOOP:
517                                        ((libtrace_packet_t*)packet)->l2_header = meta;
518                                        ((libtrace_packet_t*)packet)->l2_remaining = *remaining;
519                                        return meta;
520                                case TRACE_TYPE_LINUX_SLL:
521                                case TRACE_TYPE_80211_RADIO:
522                                case TRACE_TYPE_80211_PRISM:
523                                case TRACE_TYPE_PFLOG:
524                                        break;
525                                case TRACE_TYPE_UNKNOWN:
526                                        return NULL;
527                        }
528                       
529                        /* Otherwise, we must have hit the end of the packet */
530                        return NULL;
531                }
532         
533               
534                meta = nexthdr;
535        }
536
537}
538
539DLLEXPORT
540void *trace_get_payload_from_atm(void *link,
541                uint8_t *type, uint32_t *remaining)
542{
543        libtrace_atm_capture_cell_t *cell;
544        if (remaining && *remaining<sizeof(libtrace_atm_capture_cell_t)) {
545                *remaining = 0;
546                return NULL;
547        }
548        cell=(libtrace_atm_capture_cell_t*)link;
549
550        if (type)
551                *type=cell->pt;
552
553        if (remaining)
554                *remaining-=sizeof(libtrace_atm_capture_cell_t);
555
556        return ((char*)link)+sizeof(libtrace_atm_capture_cell_t);
557}
558
559
560
561DLLEXPORT void *trace_get_payload_from_layer2(void *link,
562                libtrace_linktype_t linktype,
563                uint16_t *ethertype,
564                uint32_t *remaining)
565{
566        void *l;
567
568        if (linktype == TRACE_TYPE_UNKNOWN) {
569                fprintf(stderr, "Unable to determine linktype for packet\n");
570                return NULL;
571        }
572       
573        switch(linktype) {
574                /* Packet Metadata headers, not layer2 headers */
575                case TRACE_TYPE_80211_PRISM:
576                case TRACE_TYPE_80211_RADIO:
577                case TRACE_TYPE_PFLOG:
578                case TRACE_TYPE_LINUX_SLL:
579                        return NULL;
580
581                /* duck packets have no payload! */
582                case TRACE_TYPE_DUCK:
583                        return NULL;
584
585                /* The payload is in these packets does
586                   not correspond to a genuine link-layer
587                   */
588                case TRACE_TYPE_METADATA:
589                case TRACE_TYPE_NONDATA:
590                case TRACE_TYPE_UNKNOWN:
591                        return NULL;
592
593                case TRACE_TYPE_80211:
594                        return trace_get_payload_from_80211(link,ethertype,remaining);
595                case TRACE_TYPE_ETH:
596                        return trace_get_payload_from_ethernet(link,ethertype,remaining);
597                case TRACE_TYPE_NONE:
598                        if ((*(char*)link&0xF0) == 0x40)
599                                *ethertype=TRACE_ETHERTYPE_IP;   /* IPv4 */
600                        else if ((*(char*)link&0xF0) == 0x60)
601                                *ethertype=TRACE_ETHERTYPE_IPV6; /* IPv6 */
602                        return link; /* I love the simplicity */
603                case TRACE_TYPE_PPP:
604                        return trace_get_payload_from_ppp(link,ethertype,remaining);
605                case TRACE_TYPE_ATM:
606                        l=trace_get_payload_from_atm(link,NULL,remaining);
607                        /* FIXME: We shouldn't skip llcsnap here, we should
608                         * return an ethertype for it (somehow)
609                         */
610                        return (l ? trace_get_payload_from_llcsnap(l,
611                                                ethertype, remaining):NULL);
612                case TRACE_TYPE_LLCSNAP:
613                        return trace_get_payload_from_llcsnap(link,ethertype,remaining);
614
615                case TRACE_TYPE_HDLC_POS:
616                        return trace_get_payload_from_chdlc(link,ethertype,
617                                        remaining);
618                case TRACE_TYPE_POS:
619                        return trace_get_payload_from_ppp_hdlc(link,ethertype,
620                                        remaining);
621                /* TODO: Unsupported */
622                case TRACE_TYPE_AAL5:
623                        return NULL;
624
625                case TRACE_TYPE_OPENBSD_LOOP:
626                        link = link + 4; /* Loopback header is 4 bytes */
627                        if ((*(char*)link&0xF0) == 0x40)
628                                *ethertype=TRACE_ETHERTYPE_IP;   /* IPv4 */
629                        else if ((*(char*)link&0xF0) == 0x60)
630                                *ethertype=TRACE_ETHERTYPE_IPV6; /* IPv6 */
631                        return link; /* I love the simplicity */
632               
633
634        }
635        return NULL;
636
637}
638
639/* Take a pointer to the start of an IEEE 802.11 MAC frame and return a pointer
640 * to the source MAC address. 
641 * If the frame does not contain a sender address, e.g. ACK frame, return NULL.
642 * If the frame is a 4-address WDS frame, return TA, i.e. addr2.
643 * NB: This function decodes the 802.11 header, so it assumes that there are no
644 * bit-errors. If there are, all bets are off.
645 */
646static
647uint8_t *get_source_mac_from_wifi(void *wifi) {
648        struct libtrace_80211_t *w;
649        if (wifi == NULL) return NULL;
650        w = (struct libtrace_80211_t *) wifi;
651
652        /* If the frame is of type CTRL */
653        if (w->type == 0x1)
654                /* If bit 2 of the subtype field is zero, this indicates that
655                 * there is no transmitter address, i.e. the frame is either an
656                 * ACK or a CTS frame */
657                if ((w->subtype & 0x2) == 0)
658                        return NULL;
659
660        /* Always return the address of the transmitter, i.e. address 2 */
661        return (uint8_t *) &w->mac2;
662}
663
664DLLEXPORT uint8_t *trace_get_source_mac(libtrace_packet_t *packet) {
665        void *link;
666        uint32_t remaining;
667        libtrace_linktype_t linktype;
668        assert(packet);
669        link = trace_get_layer2(packet,&linktype,&remaining);
670
671        if (!link)
672                return NULL;
673
674        switch (linktype) {
675                case TRACE_TYPE_ETH:
676                        return (uint8_t *)&(((libtrace_ether_t*)link)->ether_shost);
677                case TRACE_TYPE_80211:
678                        return get_source_mac_from_wifi(link);
679                /* These packets don't have MAC addresses */
680                case TRACE_TYPE_POS:
681                case TRACE_TYPE_NONE:
682                case TRACE_TYPE_HDLC_POS:
683                case TRACE_TYPE_PFLOG:
684                case TRACE_TYPE_ATM:
685                case TRACE_TYPE_DUCK:
686                case TRACE_TYPE_METADATA:
687                case TRACE_TYPE_AAL5:
688                case TRACE_TYPE_LLCSNAP:
689                case TRACE_TYPE_PPP:
690                case TRACE_TYPE_NONDATA:
691                case TRACE_TYPE_OPENBSD_LOOP:
692                case TRACE_TYPE_UNKNOWN:
693                        return NULL;
694
695                /* Metadata headers should already be skipped */
696                case TRACE_TYPE_LINUX_SLL:
697                case TRACE_TYPE_80211_PRISM:
698                case TRACE_TYPE_80211_RADIO:
699                        assert(!"Metadata headers should already be skipped");
700                        break;
701        }
702        fprintf(stderr,"%s not implemented for linktype %i\n", __func__, linktype);
703        assert(0);
704        return NULL;
705}
706
707DLLEXPORT uint8_t *trace_get_destination_mac(libtrace_packet_t *packet)
708{
709        void *link;
710        libtrace_linktype_t linktype;
711        uint32_t remaining;
712        libtrace_80211_t *wifi;
713        libtrace_ether_t *ethptr;
714
715        link = trace_get_layer2(packet,&linktype,&remaining);
716
717        ethptr = (libtrace_ether_t*)link;
718
719
720        if (!link)
721                return NULL;
722
723        switch (linktype) {
724                case TRACE_TYPE_80211:
725                        wifi=(libtrace_80211_t*)link;
726                        return (uint8_t*)&wifi->mac1;
727                case TRACE_TYPE_ETH:
728                        return (uint8_t*)&ethptr->ether_dhost;
729                case TRACE_TYPE_POS:
730                case TRACE_TYPE_NONE:
731                case TRACE_TYPE_ATM:
732                case TRACE_TYPE_HDLC_POS:
733                case TRACE_TYPE_PFLOG:
734                case TRACE_TYPE_DUCK:
735                case TRACE_TYPE_METADATA:
736                case TRACE_TYPE_AAL5:
737                case TRACE_TYPE_LLCSNAP:
738                case TRACE_TYPE_PPP:   
739                case TRACE_TYPE_NONDATA:
740                case TRACE_TYPE_OPENBSD_LOOP:
741                case TRACE_TYPE_UNKNOWN:
742                        /* No MAC address */
743                        return NULL;
744                /* Metadata headers should already be skipped */
745                case TRACE_TYPE_LINUX_SLL:
746                case TRACE_TYPE_80211_PRISM:
747                case TRACE_TYPE_80211_RADIO:
748                        assert(!"Metadata headers should already be skipped");
749                        break;
750        }
751        fprintf(stderr,"Not implemented\n");
752        assert(0);
753        return NULL;
754}
755
Note: See TracBrowser for help on using the repository browser.