source: lib/protocols_pktmeta.c @ a81d2fc

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since a81d2fc was a81d2fc, checked in by Perry Lorier <perry@…>, 14 years ago

Split the protocol API's up into seperate files

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