source: lib/protocols_pktmeta.c @ a857389

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

Initial support for ERF provenance records

Update erftypes.h with TYPE_META (27).
Check for ERF_TYPE_MAX rather than some arbitrary type in ERF sanity checks. In Wireshark we recently completely removed these checks as there are only a few types before TYPE_PAD/ERF_TYPE_MAX, but leave them in for now.
Add TRACE_TYPE_ERF_META for provenance record payload.
Continue to use TRACE_RT_DATA_ERF as provenance is a valid ERF record. Note: this means that LIBTRACE_IS_META_PACKET() will currently return FALSE which may confuse some tools. Other places in the code also tend to check for TRACE_TYPE_NONDATA which isn't true here either.
Return zero for wire length of provenance records.
Don't allow snapping them (just return the same value).
Skip provenance records in l2 parsers and trace_get_payload_from_meta().
Return provenance payload for trace_get_packet_meta().

Also add support for a couple of missing ERF_TYPE_ETH_COLOR variants.

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