source: lib/protocols_pktmeta.c @ 00365c6

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

Update to use new libwandder_etsili API

The new API should be more thread-safe than the original, at the
cost of being a bit more awkward to use.

  • Property mode set to 100644
File size: 6.8 KB
RevLine 
[f6730d8]1/*
2 *
[ee6e802]3 * Copyright (c) 2007-2016 The University of Waikato, Hamilton, New Zealand.
[f6730d8]4 * All rights reserved.
5 *
[ee6e802]6 * This file is part of libtrace.
7 *
8 * This code has been developed by the University of Waikato WAND
[f6730d8]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
[ee6e802]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
[f6730d8]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
[ee6e802]19 * GNU Lesser General Public License for more details.
[f6730d8]20 *
[ee6e802]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/>.
[f6730d8]23 *
24 *
25 */
[a81d2fc]26#include "libtrace_int.h"
[1326d5f]27#include "libtrace.h"
[a81d2fc]28#include "protocols.h"
29#include <assert.h>
30
[b663d33]31#ifdef HAVE_WANDDER
32#include <libwandder_etsili.h>
33#endif
34
[f6730d8]35/* This file contains all the protocol decoding functions for the meta-data
36 * headers that may be prepended to captured packets.
37 *
38 * Supported protocols include (but are not limited to):
39 *      Linux SLL
40 *      PFLOG
41 *      RadioTap
42 *      Prism
43 */
44
[a81d2fc]45/* NB: type is returned as an ARPHRD_ type for SLL*/
46void *trace_get_payload_from_linux_sll(const void *link,
[9cc1266]47                uint16_t *arphrd_type, uint16_t *next, 
48                uint32_t *remaining) 
[a81d2fc]49{
[ab25522]50        libtrace_sll_header_t *sll;
[a81d2fc]51
[ab25522]52        sll = (libtrace_sll_header_t*) link;
[a81d2fc]53
54        if (remaining) {
[aa22b5b]55                if (*remaining < sizeof(*sll)) {
[35782f6]56                        *remaining = 0;
[a81d2fc]57                        return NULL;
[35782f6]58                }
[ab25522]59                *remaining-=sizeof(*sll);
[a81d2fc]60        }
61
[9cc1266]62        /* The SLL header is actually in place of a link layer header, so
63         * we want to use the protocol field to tell our caller what the
64         * next header is going to be */
65        if (next) *next = (libtrace_linktype_t)(ntohs(sll->protocol));
66        if (arphrd_type) *arphrd_type = ntohs(sll->hatype);
[a81d2fc]67
[ab25522]68        return (void*)((char*)sll+sizeof(*sll));
[a81d2fc]69
70}
71
[8b98289]72/* NB: type is returned as an ethertype */
73static void *trace_get_payload_from_pflog(const void *link,
74                libtrace_linktype_t *type, uint32_t *remaining)
[a81d2fc]75{
76        libtrace_pflog_header_t *pflog = (libtrace_pflog_header_t*)link;
[8b98289]77        if (remaining) {
[aa22b5b]78                if (*remaining<sizeof(*pflog)) {
[35782f6]79                        *remaining = 0;
[a81d2fc]80                        return NULL;
[35782f6]81                }
[a81d2fc]82                *remaining-=sizeof(*pflog);
83        }
84        if (type) {
[8b98289]85                *type = TRACE_TYPE_NONE;
[a81d2fc]86        }
87        return (void*)((char*)pflog+ sizeof(*pflog));
88}
89
90/* Returns the 'payload' of the prism header, which is the 802.11 frame */
[8b98289]91static void *trace_get_payload_from_prism (const void *link,
[a81d2fc]92                libtrace_linktype_t *type, uint32_t *remaining)
93{
94        if (remaining) {
[aa22b5b]95                /* Prism header is 144 bytes long */
96                if (*remaining<144) {
[35782f6]97                        *remaining = 0;
[a81d2fc]98                        return NULL;
[35782f6]99                }
[a81d2fc]100                *remaining-=144;
101        }
102
103        if (type) *type = TRACE_TYPE_80211;
104
105        return (void *) ((char*)link+144);
106}
107
108/* Returns the 'payload' of the radiotap header, which is the 802.11 frame */
[8b98289]109static void *trace_get_payload_from_radiotap (const void *link, 
[a81d2fc]110                libtrace_linktype_t *type, uint32_t *remaining)
111{
112        struct libtrace_radiotap_t *rtap = (struct libtrace_radiotap_t*)link;
113        uint16_t rtaplen = bswap_le_to_host16(rtap->it_len);
114        if (remaining) {
[aa22b5b]115                if (*remaining < rtaplen) {
[35782f6]116                        *remaining = 0;
[a81d2fc]117                        return NULL;
[35782f6]118                }
[a81d2fc]119                *remaining -= rtaplen;
120        }
121
122        if (type) *type = TRACE_TYPE_80211;
123
124        return (void*) ((char*)link + rtaplen);
125}
126
[b663d33]127static void *trace_get_payload_from_etsili(const void *link,
128                libtrace_linktype_t *type, uint32_t *remaining) {
129
130#ifdef HAVE_WANDDER
[00365c6]131        wandder_etsispec_t *dec;
[b663d33]132        uint8_t *ccptr;
133
[00365c6]134        /* XXX Bit annoying to be creating and freeing this every time */
135        dec = wandder_create_etsili_decoder();
136        wandder_attach_etsili_buffer(dec, (uint8_t *)link, *remaining, false);
137        ccptr = wandder_etsili_get_cc_contents(dec, remaining);
[b663d33]138        /* Assuming all CCs are IP for now */
139        *type = TRACE_TYPE_NONE;
[00365c6]140        wandder_free_etsili_decoder(dec);
[b663d33]141        return ccptr;
142
143#else
144        *remaining = NULL;
145        return NULL;
146#endif
147
148}
149
[a81d2fc]150DLLEXPORT void *trace_get_packet_meta(const libtrace_packet_t *packet, 
151                libtrace_linktype_t *linktype,
152                uint32_t *remaining)
153{
154        uint32_t dummyrem;
[3ac4bf7]155        void *pktbuf = NULL;
[a81d2fc]156        assert(packet != NULL);
157        assert(linktype != NULL);
158       
159        if (remaining == NULL) 
160                remaining = &dummyrem;
161       
[3ac4bf7]162        pktbuf = trace_get_packet_buffer(packet, linktype, remaining);
[a81d2fc]163        switch (*linktype) {
164                case TRACE_TYPE_LINUX_SLL:
165                case TRACE_TYPE_80211_RADIO:
166                case TRACE_TYPE_80211_PRISM:
[a857389]167                case TRACE_TYPE_ERF_META:
[b663d33]168                case TRACE_TYPE_ETSILI:
[a81d2fc]169                        return pktbuf;
170                /* Non metadata packets */
171                case TRACE_TYPE_HDLC_POS:
172                case TRACE_TYPE_ETH:
173                case TRACE_TYPE_ATM:
174                case TRACE_TYPE_80211:
175                case TRACE_TYPE_NONE:
176                case TRACE_TYPE_PFLOG:
177                case TRACE_TYPE_POS:
178                case TRACE_TYPE_AAL5:
179                case TRACE_TYPE_DUCK:
180                case TRACE_TYPE_LLCSNAP:
181                case TRACE_TYPE_PPP:
182                case TRACE_TYPE_METADATA:
[307892f]183                case TRACE_TYPE_NONDATA:
[77f79c7]184                case TRACE_TYPE_OPENBSD_LOOP:
[f7bcbfb]185                case TRACE_TYPE_UNKNOWN:
[a81d2fc]186                        return NULL;
187        }
188
189        /* Shouldn't get here */
190        return NULL;
191}
192
193DLLEXPORT void *trace_get_payload_from_meta(const void *meta,
194                libtrace_linktype_t *linktype,
195                uint32_t *remaining)
196{
197        void *nexthdr; 
[26c2d4c]198        uint16_t arphrd = 0;
199        uint16_t next = 0;
[a81d2fc]200       
201        assert(meta != NULL);
202        assert(linktype != NULL);
203        assert(remaining != NULL);
204       
205        switch(*linktype) {
206                case TRACE_TYPE_LINUX_SLL:
207                        nexthdr = trace_get_payload_from_linux_sll(meta,
[8ccb7897]208                                        &arphrd, &next, remaining);
[9cc1266]209
210                        /* Ethernet header is usually absent in SLL captures,
211                         * so we don't want to skip it just yet */
[8ccb7897]212                        if (arphrd_type_to_libtrace(arphrd) == TRACE_TYPE_ETH && next != 0x0060) 
[9cc1266]213                                *linktype = TRACE_TYPE_NONE; 
214                        else 
215                                *linktype = arphrd_type_to_libtrace(arphrd);
[a81d2fc]216                        return nexthdr;
217                case TRACE_TYPE_80211_RADIO:
218                        nexthdr = trace_get_payload_from_radiotap(meta,
219                                        linktype, remaining);
220                        return nexthdr;
221                case TRACE_TYPE_80211_PRISM:
222                        nexthdr = trace_get_payload_from_prism(meta,
223                                        linktype, remaining);
224                        return nexthdr;
[8b98289]225                case TRACE_TYPE_PFLOG:
226                        nexthdr = trace_get_payload_from_pflog(meta,
227                                        linktype, remaining);
228                        return nexthdr;
[b663d33]229                case TRACE_TYPE_ETSILI:
230                        nexthdr = trace_get_payload_from_etsili(meta,
231                                        linktype, remaining);
232                        return nexthdr;
233
[a81d2fc]234                case TRACE_TYPE_HDLC_POS:
235                case TRACE_TYPE_ETH:
236                case TRACE_TYPE_ATM:
237                case TRACE_TYPE_80211:
238                case TRACE_TYPE_NONE:
239                case TRACE_TYPE_POS:
240                case TRACE_TYPE_AAL5:
241                case TRACE_TYPE_DUCK:
242                case TRACE_TYPE_LLCSNAP:
243                case TRACE_TYPE_PPP:
244                case TRACE_TYPE_METADATA:
[307892f]245                case TRACE_TYPE_NONDATA:
[77f79c7]246                case TRACE_TYPE_OPENBSD_LOOP:
[a857389]247                case TRACE_TYPE_ERF_META:
[f7bcbfb]248                case TRACE_TYPE_UNKNOWN:
[a81d2fc]249                        /* In this case, the pointer passed in does not point
250                         * to a metadata header and so we cannot get the
251                         * payload.
252                         */
253                        return NULL;
254        }
255        /* Shouldn't get here */
256        return NULL;
257}
258
Note: See TracBrowser for help on using the repository browser.