source: lib/protocols_pktmeta.c @ 37ee856

developringdecrementfixringperformance
Last change on this file since 37ee856 was 37ee856, checked in by Shane Alcock <salcock@…>, 2 years ago

Tag each packet with the start iteration of the parent trace.

Traces can be started, paused and then restarted. For some
formats (especially live ones), this will mean that buffers
containing received packets can be destroyed and recreated as
a result of that process. However, in our parallel world we might
also have lingering references to packets that lived in a
now-destroyed buffer and bad things will happen if we try to
operate on it.

To try and avoid this, we keep track of how many times a trace has
been "started" and each packet read is tagged with the start count
at the time it was read. Later processing functions can now check
if the packet was read before the most recent "start" -- if it was,
then it is potentially bogus and should be ignored.

This shouldn't change anything for the vast majority of libtrace
use-cases. Normally, pausing is only used prior to ending an
input without subsequent restarting, i.e. there is only one start
iteration.

  • Property mode set to 100644
File size: 6.9 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                case TRACE_TYPE_CONTENT_INVALID:
189                        return NULL;
190        }
191
192        /* Shouldn't get here */
193        return NULL;
194}
195
196DLLEXPORT void *trace_get_payload_from_meta(const void *meta,
197                libtrace_linktype_t *linktype,
198                uint32_t *remaining)
199{
200        void *nexthdr; 
201        uint16_t arphrd = 0;
202        uint16_t next = 0;
203       
204        assert(meta != NULL);
205        assert(linktype != NULL);
206        assert(remaining != NULL);
207       
208        switch(*linktype) {
209                case TRACE_TYPE_LINUX_SLL:
210                        nexthdr = trace_get_payload_from_linux_sll(meta,
211                                        &arphrd, &next, remaining);
212
213                        /* Ethernet header is usually absent in SLL captures,
214                         * so we don't want to skip it just yet */
215                        if (arphrd_type_to_libtrace(arphrd) == TRACE_TYPE_ETH && next != 0x0060) 
216                                *linktype = TRACE_TYPE_NONE; 
217                        else 
218                                *linktype = arphrd_type_to_libtrace(arphrd);
219                        return nexthdr;
220                case TRACE_TYPE_80211_RADIO:
221                        nexthdr = trace_get_payload_from_radiotap(meta,
222                                        linktype, remaining);
223                        return nexthdr;
224                case TRACE_TYPE_80211_PRISM:
225                        nexthdr = trace_get_payload_from_prism(meta,
226                                        linktype, remaining);
227                        return nexthdr;
228                case TRACE_TYPE_PFLOG:
229                        nexthdr = trace_get_payload_from_pflog(meta,
230                                        linktype, remaining);
231                        return nexthdr;
232                case TRACE_TYPE_ETSILI:
233                        nexthdr = trace_get_payload_from_etsili(meta,
234                                        linktype, remaining);
235                        return nexthdr;
236
237                case TRACE_TYPE_HDLC_POS:
238                case TRACE_TYPE_ETH:
239                case TRACE_TYPE_ATM:
240                case TRACE_TYPE_80211:
241                case TRACE_TYPE_NONE:
242                case TRACE_TYPE_POS:
243                case TRACE_TYPE_AAL5:
244                case TRACE_TYPE_DUCK:
245                case TRACE_TYPE_LLCSNAP:
246                case TRACE_TYPE_PPP:
247                case TRACE_TYPE_METADATA:
248                case TRACE_TYPE_NONDATA:
249                case TRACE_TYPE_OPENBSD_LOOP:
250                case TRACE_TYPE_ERF_META:
251                case TRACE_TYPE_UNKNOWN:
252                case TRACE_TYPE_CONTENT_INVALID:
253                        /* In this case, the pointer passed in does not point
254                         * to a metadata header and so we cannot get the
255                         * payload.
256                         */
257                        return NULL;
258        }
259        /* Shouldn't get here */
260        return NULL;
261}
262
Note: See TracBrowser for help on using the repository browser.