source: lib/protocols_pktmeta.c @ 2193905

develop
Last change on this file since 2193905 was 2193905, checked in by Jacob Van Walraven <jcv9@…>, 23 months ago

Apply changes required for pull request #81

  • Property mode set to 100644
File size: 7.3 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
30#ifdef HAVE_WANDDER
31#include <libwandder_etsili.h>
32#endif
33
34/* This file contains all the protocol decoding functions for the meta-data
35 * headers that may be prepended to captured packets.
36 *
37 * Supported protocols include (but are not limited to):
38 *      Linux SLL
39 *      PFLOG
40 *      RadioTap
41 *      Prism
42 */
43
44/* NB: type is returned as an ARPHRD_ type for SLL*/
45void *trace_get_payload_from_linux_sll(const void *link,
46                uint16_t *arphrd_type, uint16_t *next, 
47                uint32_t *remaining) 
48{
49        libtrace_sll_header_t *sll;
50
51        sll = (libtrace_sll_header_t*) link;
52
53        if (remaining) {
54                if (*remaining < sizeof(*sll)) {
55                        *remaining = 0;
56                        return NULL;
57                }
58                *remaining-=sizeof(*sll);
59        }
60
61        /* The SLL header is actually in place of a link layer header, so
62         * we want to use the protocol field to tell our caller what the
63         * next header is going to be */
64        if (next) *next = (libtrace_linktype_t)(ntohs(sll->protocol));
65        if (arphrd_type) *arphrd_type = ntohs(sll->hatype);
66
67        return (void*)((char*)sll+sizeof(*sll));
68
69}
70
71/* NB: type is returned as an ethertype */
72static void *trace_get_payload_from_pflog(const void *link,
73                libtrace_linktype_t *type, uint32_t *remaining)
74{
75        libtrace_pflog_header_t *pflog = (libtrace_pflog_header_t*)link;
76        if (remaining) {
77                if (*remaining<sizeof(*pflog)) {
78                        *remaining = 0;
79                        return NULL;
80                }
81                *remaining-=sizeof(*pflog);
82        }
83        if (type) {
84                *type = TRACE_TYPE_NONE;
85        }
86        return (void*)((char*)pflog+ sizeof(*pflog));
87}
88
89/* Returns the 'payload' of the prism header, which is the 802.11 frame */
90static void *trace_get_payload_from_prism (const void *link,
91                libtrace_linktype_t *type, uint32_t *remaining)
92{
93        if (remaining) {
94                /* Prism header is 144 bytes long */
95                if (*remaining<144) {
96                        *remaining = 0;
97                        return NULL;
98                }
99                *remaining-=144;
100        }
101
102        if (type) *type = TRACE_TYPE_80211;
103
104        return (void *) ((char*)link+144);
105}
106
107/* Returns the 'payload' of the radiotap header, which is the 802.11 frame */
108static void *trace_get_payload_from_radiotap (const void *link, 
109                libtrace_linktype_t *type, uint32_t *remaining)
110{
111        struct libtrace_radiotap_t *rtap = (struct libtrace_radiotap_t*)link;
112        uint16_t rtaplen = bswap_le_to_host16(rtap->it_len);
113        if (remaining) {
114                if (*remaining < rtaplen) {
115                        *remaining = 0;
116                        return NULL;
117                }
118                *remaining -= rtaplen;
119        }
120
121        if (type) *type = TRACE_TYPE_80211;
122
123        return (void*) ((char*)link + rtaplen);
124}
125
126static void *trace_get_payload_from_etsili(const void *link,
127                libtrace_linktype_t *type, uint32_t *remaining) {
128
129#ifdef HAVE_WANDDER
130        wandder_etsispec_t *dec;
131        uint8_t *ccptr;
132
133        /* XXX Bit annoying to be creating and freeing this every time */
134        dec = wandder_create_etsili_decoder();
135        wandder_attach_etsili_buffer(dec, (uint8_t *)link, *remaining, false);
136        ccptr = wandder_etsili_get_cc_contents(dec, remaining, NULL, 0);
137        /* Assuming all CCs are IP for now */
138        *type = TRACE_TYPE_NONE;
139        wandder_free_etsili_decoder(dec);
140        return ccptr;
141
142#else
143        (void)link;
144        (void)type;
145        *remaining = 0;
146        return NULL;
147#endif
148
149}
150
151DLLEXPORT void *trace_get_packet_meta(const libtrace_packet_t *packet, 
152                libtrace_linktype_t *linktype,
153                uint32_t *remaining)
154{
155        uint32_t dummyrem;
156        void *pktbuf = NULL;
157        if (!packet) {
158                fprintf(stderr, "NULL packet passed into trace_get_packet_meta()");
159                return NULL;
160        }
161        if (!linktype) {
162                fprintf(stderr, "NULL linkype passed into trace_get_packet_meta()");
163                return NULL;
164        }
165
166        if (remaining == NULL)
167                remaining = &dummyrem;
168
169        pktbuf = trace_get_packet_buffer(packet, linktype, remaining);
170        switch (*linktype) {
171                case TRACE_TYPE_LINUX_SLL:
172                case TRACE_TYPE_80211_RADIO:
173                case TRACE_TYPE_80211_PRISM:
174                case TRACE_TYPE_ERF_META:
175                case TRACE_TYPE_ETSILI:
176                        return pktbuf;
177                /* Non metadata packets */
178                case TRACE_TYPE_HDLC_POS:
179                case TRACE_TYPE_ETH:
180                case TRACE_TYPE_ATM:
181                case TRACE_TYPE_80211:
182                case TRACE_TYPE_NONE:
183                case TRACE_TYPE_PFLOG:
184                case TRACE_TYPE_POS:
185                case TRACE_TYPE_AAL5:
186                case TRACE_TYPE_DUCK:
187                case TRACE_TYPE_LLCSNAP:
188                case TRACE_TYPE_PPP:
189                case TRACE_TYPE_METADATA:
190                case TRACE_TYPE_NONDATA:
191                case TRACE_TYPE_OPENBSD_LOOP:
192                case TRACE_TYPE_UNKNOWN:
193                case TRACE_TYPE_CONTENT_INVALID:
194                        return NULL;
195        }
196
197        /* Shouldn't get here */
198        return NULL;
199}
200
201DLLEXPORT void *trace_get_payload_from_meta(const void *meta,
202                libtrace_linktype_t *linktype,
203                uint32_t *remaining)
204{
205        void *nexthdr;
206        uint16_t arphrd = 0;
207        uint16_t next = 0;
208
209        if (!meta) {
210                fprintf(stderr, "NULL meta passed into trace_get_payload_from_meta()");
211                return NULL;
212        }
213        if (!linktype) {
214                fprintf(stderr, "NULL linktype passed into trace_get_payload_from_meta()");
215                return NULL;
216        }
217        if (!remaining) {
218                fprintf(stderr, "NULL remaining passed into trace_get_payload_from_meta()");
219                return NULL;
220        }
221
222        switch(*linktype) {
223                case TRACE_TYPE_LINUX_SLL:
224                        nexthdr = trace_get_payload_from_linux_sll(meta,
225                                        &arphrd, &next, remaining);
226
227                        /* Ethernet header is usually absent in SLL captures,
228                         * so we don't want to skip it just yet */
229                        if (arphrd_type_to_libtrace(arphrd) == TRACE_TYPE_ETH && next != 0x0060) 
230                                *linktype = TRACE_TYPE_NONE; 
231                        else 
232                                *linktype = arphrd_type_to_libtrace(arphrd);
233                        return nexthdr;
234                case TRACE_TYPE_80211_RADIO:
235                        nexthdr = trace_get_payload_from_radiotap(meta,
236                                        linktype, remaining);
237                        return nexthdr;
238                case TRACE_TYPE_80211_PRISM:
239                        nexthdr = trace_get_payload_from_prism(meta,
240                                        linktype, remaining);
241                        return nexthdr;
242                case TRACE_TYPE_PFLOG:
243                        nexthdr = trace_get_payload_from_pflog(meta,
244                                        linktype, remaining);
245                        return nexthdr;
246                case TRACE_TYPE_ETSILI:
247                        nexthdr = trace_get_payload_from_etsili(meta,
248                                        linktype, remaining);
249                        return nexthdr;
250
251                case TRACE_TYPE_HDLC_POS:
252                case TRACE_TYPE_ETH:
253                case TRACE_TYPE_ATM:
254                case TRACE_TYPE_80211:
255                case TRACE_TYPE_NONE:
256                case TRACE_TYPE_POS:
257                case TRACE_TYPE_AAL5:
258                case TRACE_TYPE_DUCK:
259                case TRACE_TYPE_LLCSNAP:
260                case TRACE_TYPE_PPP:
261                case TRACE_TYPE_METADATA:
262                case TRACE_TYPE_NONDATA:
263                case TRACE_TYPE_OPENBSD_LOOP:
264                case TRACE_TYPE_ERF_META:
265                case TRACE_TYPE_UNKNOWN:
266                case TRACE_TYPE_CONTENT_INVALID:
267                        /* In this case, the pointer passed in does not point
268                         * to a metadata header and so we cannot get the
269                         * payload.
270                         */
271                        return NULL;
272        }
273        /* Shouldn't get here */
274        return NULL;
275}
276
Note: See TracBrowser for help on using the repository browser.