source: lib/protocols_pktmeta.c @ b663d33

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

etsilive format is now functional (for single-threaded only).

Packets are decoded using libwandder. The ETSI headers are treated
as a meta-data layer.

Libpacketdump support has also been added for all fields and
structures that libwandder understands.

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