source: lib/protocols_pktmeta.c @ 9cc1266

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 9cc1266 was 9cc1266, checked in by Shane Alcock <salcock@…>, 10 years ago
  • Fixed poor performance of the event API by greatly reducing the amount of packets created, copied and freed
  • We now cache the transport header and payload length for each packet
  • We now deal with Linux SLL Ethernet captures taken using tcpdump with -i any correctly.
  • Changed parameters for internal function trace_get_payload_from_sll - it now sets both the arphrd type and the next protocol
  • Moved ARPHRD definitions into a separate header file, as they come in handy anywhere we deal with SLL headers
  • Property mode set to 100644
File size: 6.0 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#ifndef WIN32
40#include <net/if_arp.h>
41#endif
42
43#ifndef ARPHRD_ETHER
44#define ARPHRD_ETHER    1               /* Ethernet 10/100Mbps.  */
45#endif
46
47#ifndef ARPHRD_PPP
48#define ARPHRD_PPP      512
49#endif
50
51/* This file contains all the protocol decoding functions for the meta-data
52 * headers that may be prepended to captured packets.
53 *
54 * Supported protocols include (but are not limited to):
55 *      Linux SLL
56 *      PFLOG
57 *      RadioTap
58 *      Prism
59 */
60
61/* NB: type is returned as an ARPHRD_ type for SLL*/
62void *trace_get_payload_from_linux_sll(const void *link,
63                uint16_t *arphrd_type, uint16_t *next, 
64                uint32_t *remaining) 
65{
66        libtrace_sll_header_t *sll;
67
68        sll = (libtrace_sll_header_t*) link;
69
70        if (remaining) {
71                if (*remaining < sizeof(*sll)) {
72                        *remaining = 0;
73                        return NULL;
74                }
75                *remaining-=sizeof(*sll);
76        }
77
78        /* The SLL header is actually in place of a link layer header, so
79         * we want to use the protocol field to tell our caller what the
80         * next header is going to be */
81        if (next) *next = (libtrace_linktype_t)(ntohs(sll->protocol));
82        if (arphrd_type) *arphrd_type = ntohs(sll->hatype);
83
84        return (void*)((char*)sll+sizeof(*sll));
85
86}
87
88/* NB: type is returned as an ethertype */
89static void *trace_get_payload_from_pflog(const void *link,
90                libtrace_linktype_t *type, uint32_t *remaining)
91{
92        libtrace_pflog_header_t *pflog = (libtrace_pflog_header_t*)link;
93        if (remaining) {
94                if (*remaining<sizeof(*pflog)) {
95                        *remaining = 0;
96                        return NULL;
97                }
98                *remaining-=sizeof(*pflog);
99        }
100        if (type) {
101                *type = TRACE_TYPE_NONE;
102        }
103        return (void*)((char*)pflog+ sizeof(*pflog));
104}
105
106/* Returns the 'payload' of the prism header, which is the 802.11 frame */
107static void *trace_get_payload_from_prism (const void *link,
108                libtrace_linktype_t *type, uint32_t *remaining)
109{
110        if (remaining) {
111                /* Prism header is 144 bytes long */
112                if (*remaining<144) {
113                        *remaining = 0;
114                        return NULL;
115                }
116                *remaining-=144;
117        }
118
119        if (type) *type = TRACE_TYPE_80211;
120
121        return (void *) ((char*)link+144);
122}
123
124/* Returns the 'payload' of the radiotap header, which is the 802.11 frame */
125static void *trace_get_payload_from_radiotap (const void *link, 
126                libtrace_linktype_t *type, uint32_t *remaining)
127{
128        struct libtrace_radiotap_t *rtap = (struct libtrace_radiotap_t*)link;
129        uint16_t rtaplen = bswap_le_to_host16(rtap->it_len);
130        if (remaining) {
131                if (*remaining < rtaplen) {
132                        *remaining = 0;
133                        return NULL;
134                }
135                *remaining -= rtaplen;
136        }
137
138        if (type) *type = TRACE_TYPE_80211;
139
140        return (void*) ((char*)link + rtaplen);
141}
142
143DLLEXPORT void *trace_get_packet_meta(const libtrace_packet_t *packet, 
144                libtrace_linktype_t *linktype,
145                uint32_t *remaining)
146{
147        uint32_t dummyrem;
148        void *pktbuf = NULL;
149        assert(packet != NULL);
150        assert(linktype != NULL);
151       
152        if (remaining == NULL) 
153                remaining = &dummyrem;
154       
155        pktbuf = trace_get_packet_buffer(packet, linktype, remaining);
156        switch (*linktype) {
157                case TRACE_TYPE_LINUX_SLL:
158                case TRACE_TYPE_80211_RADIO:
159                case TRACE_TYPE_80211_PRISM:
160                        return pktbuf;
161                /* Non metadata packets */
162                case TRACE_TYPE_HDLC_POS:
163                case TRACE_TYPE_ETH:
164                case TRACE_TYPE_ATM:
165                case TRACE_TYPE_80211:
166                case TRACE_TYPE_NONE:
167                case TRACE_TYPE_PFLOG:
168                case TRACE_TYPE_POS:
169                case TRACE_TYPE_AAL5:
170                case TRACE_TYPE_DUCK:
171                case TRACE_TYPE_LLCSNAP:
172                case TRACE_TYPE_PPP:
173                case TRACE_TYPE_METADATA:
174                case TRACE_TYPE_NONDATA:
175                        return NULL;
176        }
177
178        /* Shouldn't get here */
179        return NULL;
180}
181
182DLLEXPORT void *trace_get_payload_from_meta(const void *meta,
183                libtrace_linktype_t *linktype,
184                uint32_t *remaining)
185{
186        void *nexthdr; 
187        uint16_t arphrd;
188       
189        assert(meta != NULL);
190        assert(linktype != NULL);
191        assert(remaining != NULL);
192       
193        switch(*linktype) {
194                case TRACE_TYPE_LINUX_SLL:
195                        nexthdr = trace_get_payload_from_linux_sll(meta,
196                                        &arphrd, NULL, remaining);
197
198                        /* Ethernet header is usually absent in SLL captures,
199                         * so we don't want to skip it just yet */
200                        if (arphrd_type_to_libtrace(arphrd) == TRACE_TYPE_ETH) 
201                                *linktype = TRACE_TYPE_NONE; 
202                        else 
203                                *linktype = arphrd_type_to_libtrace(arphrd);
204                        return nexthdr;
205                case TRACE_TYPE_80211_RADIO:
206                        nexthdr = trace_get_payload_from_radiotap(meta,
207                                        linktype, remaining);
208                        return nexthdr;
209                case TRACE_TYPE_80211_PRISM:
210                        nexthdr = trace_get_payload_from_prism(meta,
211                                        linktype, remaining);
212                        return nexthdr;
213                case TRACE_TYPE_PFLOG:
214                        nexthdr = trace_get_payload_from_pflog(meta,
215                                        linktype, remaining);
216                        return nexthdr;
217                case TRACE_TYPE_HDLC_POS:
218                case TRACE_TYPE_ETH:
219                case TRACE_TYPE_ATM:
220                case TRACE_TYPE_80211:
221                case TRACE_TYPE_NONE:
222                case TRACE_TYPE_POS:
223                case TRACE_TYPE_AAL5:
224                case TRACE_TYPE_DUCK:
225                case TRACE_TYPE_LLCSNAP:
226                case TRACE_TYPE_PPP:
227                case TRACE_TYPE_METADATA:
228                case TRACE_TYPE_NONDATA:
229                        /* In this case, the pointer passed in does not point
230                         * to a metadata header and so we cannot get the
231                         * payload.
232                         */
233                        return NULL;
234        }
235        /* Shouldn't get here */
236        return NULL;
237}
238
Note: See TracBrowser for help on using the repository browser.