source: lib/protocols_pktmeta.c @ 95ca714

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

Update protocols_pktmeta.c to include libwandder API change

  • Property mode set to 100644
File size: 6.8 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
31#ifdef HAVE_WANDDER
32#include <libwandder_etsili.h>
33#endif
34
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
45/* NB: type is returned as an ARPHRD_ type for SLL*/
46void *trace_get_payload_from_linux_sll(const void *link,
47                uint16_t *arphrd_type, uint16_t *next, 
48                uint32_t *remaining) 
49{
50        libtrace_sll_header_t *sll;
51
52        sll = (libtrace_sll_header_t*) link;
53
54        if (remaining) {
55                if (*remaining < sizeof(*sll)) {
56                        *remaining = 0;
57                        return NULL;
58                }
59                *remaining-=sizeof(*sll);
60        }
61
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);
67
68        return (void*)((char*)sll+sizeof(*sll));
69
70}
71
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)
75{
76        libtrace_pflog_header_t *pflog = (libtrace_pflog_header_t*)link;
77        if (remaining) {
78                if (*remaining<sizeof(*pflog)) {
79                        *remaining = 0;
80                        return NULL;
81                }
82                *remaining-=sizeof(*pflog);
83        }
84        if (type) {
85                *type = TRACE_TYPE_NONE;
86        }
87        return (void*)((char*)pflog+ sizeof(*pflog));
88}
89
90/* Returns the 'payload' of the prism header, which is the 802.11 frame */
91static void *trace_get_payload_from_prism (const void *link,
92                libtrace_linktype_t *type, uint32_t *remaining)
93{
94        if (remaining) {
95                /* Prism header is 144 bytes long */
96                if (*remaining<144) {
97                        *remaining = 0;
98                        return NULL;
99                }
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 */
109static void *trace_get_payload_from_radiotap (const void *link, 
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) {
115                if (*remaining < rtaplen) {
116                        *remaining = 0;
117                        return NULL;
118                }
119                *remaining -= rtaplen;
120        }
121
122        if (type) *type = TRACE_TYPE_80211;
123
124        return (void*) ((char*)link + rtaplen);
125}
126
127static void *trace_get_payload_from_etsili(const void *link,
128                libtrace_linktype_t *type, uint32_t *remaining) {
129
130#ifdef HAVE_WANDDER
131        wandder_etsispec_t *dec;
132        uint8_t *ccptr;
133
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, NULL, 0);
138        /* Assuming all CCs are IP for now */
139        *type = TRACE_TYPE_NONE;
140        wandder_free_etsili_decoder(dec);
141        return ccptr;
142
143#else
144        *remaining = NULL;
145        return NULL;
146#endif
147
148}
149
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;
155        void *pktbuf = NULL;
156        assert(packet != NULL);
157        assert(linktype != NULL);
158       
159        if (remaining == NULL) 
160                remaining = &dummyrem;
161       
162        pktbuf = trace_get_packet_buffer(packet, linktype, remaining);
163        switch (*linktype) {
164                case TRACE_TYPE_LINUX_SLL:
165                case TRACE_TYPE_80211_RADIO:
166                case TRACE_TYPE_80211_PRISM:
167                case TRACE_TYPE_ERF_META:
168                case TRACE_TYPE_ETSILI:
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:
183                case TRACE_TYPE_NONDATA:
184                case TRACE_TYPE_OPENBSD_LOOP:
185                case TRACE_TYPE_UNKNOWN:
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; 
198        uint16_t arphrd = 0;
199        uint16_t next = 0;
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,
208                                        &arphrd, &next, remaining);
209
210                        /* Ethernet header is usually absent in SLL captures,
211                         * so we don't want to skip it just yet */
212                        if (arphrd_type_to_libtrace(arphrd) == TRACE_TYPE_ETH && next != 0x0060) 
213                                *linktype = TRACE_TYPE_NONE; 
214                        else 
215                                *linktype = arphrd_type_to_libtrace(arphrd);
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;
225                case TRACE_TYPE_PFLOG:
226                        nexthdr = trace_get_payload_from_pflog(meta,
227                                        linktype, remaining);
228                        return nexthdr;
229                case TRACE_TYPE_ETSILI:
230                        nexthdr = trace_get_payload_from_etsili(meta,
231                                        linktype, remaining);
232                        return nexthdr;
233
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:
245                case TRACE_TYPE_NONDATA:
246                case TRACE_TYPE_OPENBSD_LOOP:
247                case TRACE_TYPE_ERF_META:
248                case TRACE_TYPE_UNKNOWN:
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.