source: lib/protocols_pktmeta.c @ c0506ea

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since c0506ea was 8ccb7897, checked in by Shane Alcock <salcock@…>, 11 years ago
  • Fixed bug where the packet buffer can be freed twice following a trace termination event
  • Fixed bug with processing SLL traces that have actually retained the Ethernet header
  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007,2008,2009,2010 The University of Waikato, Hamilton,
5 * New Zealand.
6 *
7 * Authors: Daniel Lawson
8 *          Perry Lorier
9 *          Shane Alcock
10 *         
11 * All rights reserved.
12 *
13 * This code has been developed by the University of Waikato WAND
14 * research group. For further information please see http://www.wand.net.nz/
15 *
16 * libtrace is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * libtrace is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with libtrace; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 *
30 * $Id$
31 *
32 */
33
34#include "libtrace_int.h"
35#include "libtrace.h"
36#include "protocols.h"
37#include <assert.h>
38
39#include "arphrd.h"
40
41/* This file contains all the protocol decoding functions for the meta-data
42 * headers that may be prepended to captured packets.
43 *
44 * Supported protocols include (but are not limited to):
45 *      Linux SLL
46 *      PFLOG
47 *      RadioTap
48 *      Prism
49 */
50
51/* NB: type is returned as an ARPHRD_ type for SLL*/
52void *trace_get_payload_from_linux_sll(const void *link,
53                uint16_t *arphrd_type, uint16_t *next, 
54                uint32_t *remaining) 
55{
56        libtrace_sll_header_t *sll;
57
58        sll = (libtrace_sll_header_t*) link;
59
60        if (remaining) {
61                if (*remaining < sizeof(*sll)) {
62                        *remaining = 0;
63                        return NULL;
64                }
65                *remaining-=sizeof(*sll);
66        }
67
68        /* The SLL header is actually in place of a link layer header, so
69         * we want to use the protocol field to tell our caller what the
70         * next header is going to be */
71        if (next) *next = (libtrace_linktype_t)(ntohs(sll->protocol));
72        if (arphrd_type) *arphrd_type = ntohs(sll->hatype);
73
74        return (void*)((char*)sll+sizeof(*sll));
75
76}
77
78/* NB: type is returned as an ethertype */
79static void *trace_get_payload_from_pflog(const void *link,
80                libtrace_linktype_t *type, uint32_t *remaining)
81{
82        libtrace_pflog_header_t *pflog = (libtrace_pflog_header_t*)link;
83        if (remaining) {
84                if (*remaining<sizeof(*pflog)) {
85                        *remaining = 0;
86                        return NULL;
87                }
88                *remaining-=sizeof(*pflog);
89        }
90        if (type) {
91                *type = TRACE_TYPE_NONE;
92        }
93        return (void*)((char*)pflog+ sizeof(*pflog));
94}
95
96/* Returns the 'payload' of the prism header, which is the 802.11 frame */
97static void *trace_get_payload_from_prism (const void *link,
98                libtrace_linktype_t *type, uint32_t *remaining)
99{
100        if (remaining) {
101                /* Prism header is 144 bytes long */
102                if (*remaining<144) {
103                        *remaining = 0;
104                        return NULL;
105                }
106                *remaining-=144;
107        }
108
109        if (type) *type = TRACE_TYPE_80211;
110
111        return (void *) ((char*)link+144);
112}
113
114/* Returns the 'payload' of the radiotap header, which is the 802.11 frame */
115static void *trace_get_payload_from_radiotap (const void *link, 
116                libtrace_linktype_t *type, uint32_t *remaining)
117{
118        struct libtrace_radiotap_t *rtap = (struct libtrace_radiotap_t*)link;
119        uint16_t rtaplen = bswap_le_to_host16(rtap->it_len);
120        if (remaining) {
121                if (*remaining < rtaplen) {
122                        *remaining = 0;
123                        return NULL;
124                }
125                *remaining -= rtaplen;
126        }
127
128        if (type) *type = TRACE_TYPE_80211;
129
130        return (void*) ((char*)link + rtaplen);
131}
132
133DLLEXPORT void *trace_get_packet_meta(const libtrace_packet_t *packet, 
134                libtrace_linktype_t *linktype,
135                uint32_t *remaining)
136{
137        uint32_t dummyrem;
138        void *pktbuf = NULL;
139        assert(packet != NULL);
140        assert(linktype != NULL);
141       
142        if (remaining == NULL) 
143                remaining = &dummyrem;
144       
145        pktbuf = trace_get_packet_buffer(packet, linktype, remaining);
146        switch (*linktype) {
147                case TRACE_TYPE_LINUX_SLL:
148                case TRACE_TYPE_80211_RADIO:
149                case TRACE_TYPE_80211_PRISM:
150                        return pktbuf;
151                /* Non metadata packets */
152                case TRACE_TYPE_HDLC_POS:
153                case TRACE_TYPE_ETH:
154                case TRACE_TYPE_ATM:
155                case TRACE_TYPE_80211:
156                case TRACE_TYPE_NONE:
157                case TRACE_TYPE_PFLOG:
158                case TRACE_TYPE_POS:
159                case TRACE_TYPE_AAL5:
160                case TRACE_TYPE_DUCK:
161                case TRACE_TYPE_LLCSNAP:
162                case TRACE_TYPE_PPP:
163                case TRACE_TYPE_METADATA:
164                case TRACE_TYPE_NONDATA:
165                        return NULL;
166        }
167
168        /* Shouldn't get here */
169        return NULL;
170}
171
172DLLEXPORT void *trace_get_payload_from_meta(const void *meta,
173                libtrace_linktype_t *linktype,
174                uint32_t *remaining)
175{
176        void *nexthdr; 
177        uint16_t arphrd;
178        uint16_t next;
179       
180        assert(meta != NULL);
181        assert(linktype != NULL);
182        assert(remaining != NULL);
183       
184        switch(*linktype) {
185                case TRACE_TYPE_LINUX_SLL:
186                        nexthdr = trace_get_payload_from_linux_sll(meta,
187                                        &arphrd, &next, remaining);
188
189                        /* Ethernet header is usually absent in SLL captures,
190                         * so we don't want to skip it just yet */
191                        if (arphrd_type_to_libtrace(arphrd) == TRACE_TYPE_ETH && next != 0x0060) 
192                                *linktype = TRACE_TYPE_NONE; 
193                        else 
194                                *linktype = arphrd_type_to_libtrace(arphrd);
195                        return nexthdr;
196                case TRACE_TYPE_80211_RADIO:
197                        nexthdr = trace_get_payload_from_radiotap(meta,
198                                        linktype, remaining);
199                        return nexthdr;
200                case TRACE_TYPE_80211_PRISM:
201                        nexthdr = trace_get_payload_from_prism(meta,
202                                        linktype, remaining);
203                        return nexthdr;
204                case TRACE_TYPE_PFLOG:
205                        nexthdr = trace_get_payload_from_pflog(meta,
206                                        linktype, remaining);
207                        return nexthdr;
208                case TRACE_TYPE_HDLC_POS:
209                case TRACE_TYPE_ETH:
210                case TRACE_TYPE_ATM:
211                case TRACE_TYPE_80211:
212                case TRACE_TYPE_NONE:
213                case TRACE_TYPE_POS:
214                case TRACE_TYPE_AAL5:
215                case TRACE_TYPE_DUCK:
216                case TRACE_TYPE_LLCSNAP:
217                case TRACE_TYPE_PPP:
218                case TRACE_TYPE_METADATA:
219                case TRACE_TYPE_NONDATA:
220                        /* In this case, the pointer passed in does not point
221                         * to a metadata header and so we cannot get the
222                         * payload.
223                         */
224                        return NULL;
225        }
226        /* Shouldn't get here */
227        return NULL;
228}
229
Note: See TracBrowser for help on using the repository browser.