source: lib/protocols_l2.c @ a857389

cachetimestampsdevelopetsiliverc-4.0.3rc-4.0.4ringdecrementfixringperformance
Last change on this file since a857389 was a857389, checked in by Shane Alcock <salcock@…>, 3 years ago

Initial support for ERF provenance records

Update erftypes.h with TYPE_META (27).
Check for ERF_TYPE_MAX rather than some arbitrary type in ERF sanity checks. In Wireshark we recently completely removed these checks as there are only a few types before TYPE_PAD/ERF_TYPE_MAX, but leave them in for now.
Add TRACE_TYPE_ERF_META for provenance record payload.
Continue to use TRACE_RT_DATA_ERF as provenance is a valid ERF record. Note: this means that LIBTRACE_IS_META_PACKET() will currently return FALSE which may confuse some tools. Other places in the code also tend to check for TRACE_TYPE_NONDATA which isn't true here either.
Return zero for wire length of provenance records.
Don't allow snapping them (just return the same value).
Skip provenance records in l2 parsers and trace_get_payload_from_meta().
Return provenance payload for trace_get_packet_meta().

Also add support for a couple of missing ERF_TYPE_ETH_COLOR variants.

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