source: lib/protocols_pktmeta.c @ 59b2ed8

cachetimestampsdeveloprc-4.0.4ringdecrementfixringperformance
Last change on this file since 59b2ed8 was 59b2ed8, checked in by Shane Alcock <salcock@…>, 2 years ago

Fix warnings when building without libwandder.

  • 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        (void)link;
145        (void)type;
146        *remaining = 0;
147        return NULL;
148#endif
149
150}
151
152DLLEXPORT void *trace_get_packet_meta(const libtrace_packet_t *packet, 
153                libtrace_linktype_t *linktype,
154                uint32_t *remaining)
155{
156        uint32_t dummyrem;
157        void *pktbuf = NULL;
158        assert(packet != NULL);
159        assert(linktype != NULL);
160       
161        if (remaining == NULL) 
162                remaining = &dummyrem;
163       
164        pktbuf = trace_get_packet_buffer(packet, linktype, remaining);
165        switch (*linktype) {
166                case TRACE_TYPE_LINUX_SLL:
167                case TRACE_TYPE_80211_RADIO:
168                case TRACE_TYPE_80211_PRISM:
169                case TRACE_TYPE_ERF_META:
170                case TRACE_TYPE_ETSILI:
171                        return pktbuf;
172                /* Non metadata packets */
173                case TRACE_TYPE_HDLC_POS:
174                case TRACE_TYPE_ETH:
175                case TRACE_TYPE_ATM:
176                case TRACE_TYPE_80211:
177                case TRACE_TYPE_NONE:
178                case TRACE_TYPE_PFLOG:
179                case TRACE_TYPE_POS:
180                case TRACE_TYPE_AAL5:
181                case TRACE_TYPE_DUCK:
182                case TRACE_TYPE_LLCSNAP:
183                case TRACE_TYPE_PPP:
184                case TRACE_TYPE_METADATA:
185                case TRACE_TYPE_NONDATA:
186                case TRACE_TYPE_OPENBSD_LOOP:
187                case TRACE_TYPE_UNKNOWN:
188                        return NULL;
189        }
190
191        /* Shouldn't get here */
192        return NULL;
193}
194
195DLLEXPORT void *trace_get_payload_from_meta(const void *meta,
196                libtrace_linktype_t *linktype,
197                uint32_t *remaining)
198{
199        void *nexthdr; 
200        uint16_t arphrd = 0;
201        uint16_t next = 0;
202       
203        assert(meta != NULL);
204        assert(linktype != NULL);
205        assert(remaining != NULL);
206       
207        switch(*linktype) {
208                case TRACE_TYPE_LINUX_SLL:
209                        nexthdr = trace_get_payload_from_linux_sll(meta,
210                                        &arphrd, &next, remaining);
211
212                        /* Ethernet header is usually absent in SLL captures,
213                         * so we don't want to skip it just yet */
214                        if (arphrd_type_to_libtrace(arphrd) == TRACE_TYPE_ETH && next != 0x0060) 
215                                *linktype = TRACE_TYPE_NONE; 
216                        else 
217                                *linktype = arphrd_type_to_libtrace(arphrd);
218                        return nexthdr;
219                case TRACE_TYPE_80211_RADIO:
220                        nexthdr = trace_get_payload_from_radiotap(meta,
221                                        linktype, remaining);
222                        return nexthdr;
223                case TRACE_TYPE_80211_PRISM:
224                        nexthdr = trace_get_payload_from_prism(meta,
225                                        linktype, remaining);
226                        return nexthdr;
227                case TRACE_TYPE_PFLOG:
228                        nexthdr = trace_get_payload_from_pflog(meta,
229                                        linktype, remaining);
230                        return nexthdr;
231                case TRACE_TYPE_ETSILI:
232                        nexthdr = trace_get_payload_from_etsili(meta,
233                                        linktype, remaining);
234                        return nexthdr;
235
236                case TRACE_TYPE_HDLC_POS:
237                case TRACE_TYPE_ETH:
238                case TRACE_TYPE_ATM:
239                case TRACE_TYPE_80211:
240                case TRACE_TYPE_NONE:
241                case TRACE_TYPE_POS:
242                case TRACE_TYPE_AAL5:
243                case TRACE_TYPE_DUCK:
244                case TRACE_TYPE_LLCSNAP:
245                case TRACE_TYPE_PPP:
246                case TRACE_TYPE_METADATA:
247                case TRACE_TYPE_NONDATA:
248                case TRACE_TYPE_OPENBSD_LOOP:
249                case TRACE_TYPE_ERF_META:
250                case TRACE_TYPE_UNKNOWN:
251                        /* In this case, the pointer passed in does not point
252                         * to a metadata header and so we cannot get the
253                         * payload.
254                         */
255                        return NULL;
256        }
257        /* Shouldn't get here */
258        return NULL;
259}
260
Note: See TracBrowser for help on using the repository browser.