source: lib/protocols_pktmeta.c @ ab25522

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since ab25522 was ab25522, checked in by Scott Raynel <smr26@…>, 13 years ago

Revert r1361. My bad, the SLL header seems to have a static 8 byte
address field.

  • Property mode set to 100644
File size: 7.1 KB
Line 
1/* Protocol decodes for packet metadata headers */
2#include "libtrace.h"
3#include "libtrace_int.h"
4#include "protocols.h"
5#include <assert.h>
6
7#ifndef WIN32
8#include <net/if_arp.h>
9#endif
10
11#ifndef ARPHRD_ETHER
12#define ARPHRD_ETHER    1               /* Ethernet 10/100Mbps.  */
13#endif
14
15#ifndef ARPHRD_PPP
16#define ARPHRD_PPP      512
17#endif
18
19/* NB: type is returned as an ARPHRD_ type for SLL*/
20void *trace_get_payload_from_linux_sll(const void *link,
21                uint16_t *type, uint32_t *remaining) 
22{
23        libtrace_sll_header_t *sll;
24
25        sll = (libtrace_sll_header_t*) link;
26
27        if (remaining) {
28                if (*remaining <= sizeof(*sll)) {
29                        *remaining = 0;
30                        return NULL;
31                }
32                *remaining-=sizeof(*sll);
33        }
34
35        if (type) *type = ntohs(sll->hatype);
36
37        return (void*)((char*)sll+sizeof(*sll));
38
39}
40
41/* NB: type is returned as an ethertype */
42static void *trace_get_payload_from_pflog(const void *link,
43                libtrace_linktype_t *type, uint32_t *remaining)
44{
45        libtrace_pflog_header_t *pflog = (libtrace_pflog_header_t*)link;
46        if (remaining) {
47                if (*remaining<=sizeof(*pflog)) {
48                        *remaining = 0;
49                        return NULL;
50                }
51                *remaining-=sizeof(*pflog);
52        }
53        if (type) {
54                *type = TRACE_TYPE_NONE;
55        }
56        return (void*)((char*)pflog+ sizeof(*pflog));
57}
58
59/* Returns the 'payload' of the prism header, which is the 802.11 frame */
60static void *trace_get_payload_from_prism (const void *link,
61                libtrace_linktype_t *type, uint32_t *remaining)
62{
63        if (remaining) {
64                if (*remaining<=144) {
65                        *remaining = 0;
66                        return NULL;
67                }
68                *remaining-=144;
69        }
70
71        if (type) *type = TRACE_TYPE_80211;
72
73        return (void *) ((char*)link+144);
74}
75
76/* Returns the 'payload' of the radiotap header, which is the 802.11 frame */
77static void *trace_get_payload_from_radiotap (const void *link, 
78                libtrace_linktype_t *type, uint32_t *remaining)
79{
80        struct libtrace_radiotap_t *rtap = (struct libtrace_radiotap_t*)link;
81        uint16_t rtaplen = bswap_le_to_host16(rtap->it_len);
82        if (remaining) {
83                if (*remaining <= rtaplen) {
84                        *remaining = 0;
85                        return NULL;
86                }
87                *remaining -= rtaplen;
88        }
89
90        if (type) *type = TRACE_TYPE_80211;
91
92        return (void*) ((char*)link + rtaplen);
93}
94
95DLLEXPORT void *trace_get_packet_meta(const libtrace_packet_t *packet, 
96                libtrace_linktype_t *linktype,
97                uint32_t *remaining)
98{
99        uint32_t dummyrem;
100        void *pktbuf = NULL;
101        assert(packet != NULL);
102        assert(linktype != NULL);
103       
104        if (remaining == NULL) 
105                remaining = &dummyrem;
106       
107        pktbuf = trace_get_packet_buffer(packet, linktype, remaining);
108        switch (*linktype) {
109                case TRACE_TYPE_LINUX_SLL:
110                case TRACE_TYPE_80211_RADIO:
111                case TRACE_TYPE_80211_PRISM:
112                        return pktbuf;
113                /* Non metadata packets */
114                case TRACE_TYPE_HDLC_POS:
115                case TRACE_TYPE_ETH:
116                case TRACE_TYPE_ATM:
117                case TRACE_TYPE_80211:
118                case TRACE_TYPE_NONE:
119                case TRACE_TYPE_PFLOG:
120                case TRACE_TYPE_POS:
121                case TRACE_TYPE_AAL5:
122                case TRACE_TYPE_DUCK:
123                case TRACE_TYPE_LLCSNAP:
124                case TRACE_TYPE_PPP:
125                case TRACE_TYPE_METADATA:
126                        return NULL;
127        }
128
129        /* Shouldn't get here */
130        return NULL;
131}
132
133DLLEXPORT void *trace_get_payload_from_meta(const void *meta,
134                libtrace_linktype_t *linktype,
135                uint32_t *remaining)
136{
137        void *nexthdr; 
138        uint16_t arphrd;
139       
140        assert(meta != NULL);
141        assert(linktype != NULL);
142        assert(remaining != NULL);
143       
144        switch(*linktype) {
145                case TRACE_TYPE_LINUX_SLL:
146                        nexthdr = trace_get_payload_from_linux_sll(meta,
147                                        &arphrd, remaining);
148                        *linktype = arphrd_type_to_libtrace(arphrd);
149                        return nexthdr;
150                case TRACE_TYPE_80211_RADIO:
151                        nexthdr = trace_get_payload_from_radiotap(meta,
152                                        linktype, remaining);
153                        return nexthdr;
154                case TRACE_TYPE_80211_PRISM:
155                        nexthdr = trace_get_payload_from_prism(meta,
156                                        linktype, remaining);
157                        return nexthdr;
158                case TRACE_TYPE_PFLOG:
159                        nexthdr = trace_get_payload_from_pflog(meta,
160                                        linktype, remaining);
161                        return nexthdr;
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_POS:
168                case TRACE_TYPE_AAL5:
169                case TRACE_TYPE_DUCK:
170                case TRACE_TYPE_LLCSNAP:
171                case TRACE_TYPE_PPP:
172                case TRACE_TYPE_METADATA:
173                        /* In this case, the pointer passed in does not point
174                         * to a metadata header and so we cannot get the
175                         * payload.
176                         */
177                        return NULL;
178        }
179        /* Shouldn't get here */
180        return NULL;
181}
182
183/* Take a pointer to the start of an IEEE 802.11 MAC frame and return a pointer
184 * to the source MAC address. 
185 * If the frame does not contain a sender address, e.g. ACK frame, return NULL.
186 * If the frame is a 4-address WDS frame, return TA, i.e. addr2.
187 * NB: This function decodes the 802.11 header, so it assumes that there are no
188 * bit-errors. If there are, all bets are off.
189 */
190static
191uint8_t *get_source_mac_from_wifi(void *wifi) {
192        struct libtrace_80211_t *w;
193        if (wifi == NULL) return NULL;
194        w = (struct libtrace_80211_t *) wifi;
195       
196        /* If the frame is of type CTRL */
197        if (w->type == 0x1) 
198                /* If bit 2 of the subtype field is zero, this indicates that
199                 * there is no transmitter address, i.e. the frame is either an
200                 * ACK or a CTS frame */
201                if ((w->subtype & 0x2) == 0)
202                        return NULL;
203
204        /* Always return the address of the transmitter, i.e. address 2 */
205        return (uint8_t *) &w->mac2;
206}
207
208DLLEXPORT uint8_t *trace_get_source_mac(libtrace_packet_t *packet) {
209        void *link;
210        uint32_t remaining;
211        libtrace_linktype_t linktype;
212        assert(packet);
213        link = trace_get_layer2(packet,&linktype,&remaining);
214
215        if (!link)
216                return NULL;
217       
218        switch (linktype) {
219                case TRACE_TYPE_ETH:
220                        return (uint8_t *)&(((libtrace_ether_t*)link)->ether_shost);
221                case TRACE_TYPE_80211:
222                        return get_source_mac_from_wifi(link);
223                /* These packets don't have MAC addresses */
224                case TRACE_TYPE_POS:
225                case TRACE_TYPE_NONE:
226                case TRACE_TYPE_HDLC_POS:
227                case TRACE_TYPE_PFLOG:
228                case TRACE_TYPE_ATM:
229                case TRACE_TYPE_DUCK:
230                case TRACE_TYPE_METADATA:
231                case TRACE_TYPE_AAL5:
232                case TRACE_TYPE_LLCSNAP:
233                case TRACE_TYPE_PPP:
234                        return NULL;
235
236                /* Metadata headers should already be skipped */
237                case TRACE_TYPE_LINUX_SLL:
238                case TRACE_TYPE_80211_PRISM:
239                case TRACE_TYPE_80211_RADIO:
240                        assert(!"Metadata headers should already be skipped");
241                        break;
242        }
243        fprintf(stderr,"%s not implemented for linktype %i\n", __func__, linktype);
244        assert(0);
245        return NULL;
246}
247
248DLLEXPORT uint8_t *trace_get_destination_mac(libtrace_packet_t *packet) 
249{
250        void *link;
251        libtrace_linktype_t linktype;
252        uint32_t remaining;
253        libtrace_80211_t *wifi;
254        libtrace_ether_t *ethptr;
255       
256        link = trace_get_layer2(packet,&linktype,&remaining);
257
258        ethptr = (libtrace_ether_t*)link;
259
260
261        if (!link)
262                return NULL;
263
264        switch (linktype) {
265                case TRACE_TYPE_80211:
266                        wifi=(libtrace_80211_t*)link;
267                        return (uint8_t*)&wifi->mac1;
268                case TRACE_TYPE_80211_RADIO:
269                        wifi=(libtrace_80211_t*)trace_get_payload_from_radiotap(
270                                        link,NULL,NULL);
271                        return (uint8_t*)&wifi->mac1;
272                case TRACE_TYPE_80211_PRISM:
273                        wifi=(libtrace_80211_t*)((char*)link+144);
274                        return (uint8_t*)&wifi->mac1;
275                case TRACE_TYPE_ETH:
276                        return (uint8_t*)&ethptr->ether_dhost;
277                case TRACE_TYPE_POS:
278                case TRACE_TYPE_NONE:
279                case TRACE_TYPE_ATM:
280                case TRACE_TYPE_HDLC_POS:
281                case TRACE_TYPE_LINUX_SLL:
282                case TRACE_TYPE_PFLOG:
283                case TRACE_TYPE_DUCK:
284                case TRACE_TYPE_METADATA:
285                        /* No MAC address */
286                        return NULL;
287                default:
288                        break;
289        }
290        fprintf(stderr,"Not implemented\n");
291        assert(0);
292        return NULL;
293}
294
295
Note: See TracBrowser for help on using the repository browser.