source: lib/protocols_pktmeta.c @ 3ac4bf7

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