source: lib/protocols_pktmeta.c @ 8b98289

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

pflog is a pktmeta header

  • 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
93        assert(packet != NULL);
94        assert(linktype != NULL);
95       
96        if (remaining == NULL) 
97                remaining = &dummyrem;
98       
99        void *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        if (wifi == NULL) return NULL;
185        struct libtrace_80211_t *w = (struct libtrace_80211_t *) wifi;
186       
187        /* If the frame is of type CTRL */
188        if (w->type == 0x1) 
189                /* If bit 2 of the subtype field is zero, this indicates that
190                 * there is no transmitter address, i.e. the frame is either an
191                 * ACK or a CTS frame */
192                if ((w->subtype & 0x2) == 0)
193                        return NULL;
194
195        /* Always return the address of the transmitter, i.e. address 2 */
196        return (uint8_t *) &w->mac2;
197}
198
199DLLEXPORT uint8_t *trace_get_source_mac(libtrace_packet_t *packet) {
200        void *link;
201        uint32_t remaining;
202        libtrace_linktype_t linktype;
203        assert(packet);
204        link = trace_get_layer2(packet,&linktype,&remaining);
205
206        if (!link)
207                return NULL;
208       
209        switch (linktype) {
210                case TRACE_TYPE_ETH:
211                        return (uint8_t *)&(((libtrace_ether_t*)link)->ether_shost);
212                case TRACE_TYPE_80211:
213                        return get_source_mac_from_wifi(link);
214                /* These packets don't have MAC addresses */
215                case TRACE_TYPE_POS:
216                case TRACE_TYPE_NONE:
217                case TRACE_TYPE_HDLC_POS:
218                case TRACE_TYPE_PFLOG:
219                case TRACE_TYPE_ATM:
220                case TRACE_TYPE_DUCK:
221                case TRACE_TYPE_METADATA:
222                case TRACE_TYPE_AAL5:
223                case TRACE_TYPE_LLCSNAP:
224                case TRACE_TYPE_PPP:
225                        return NULL;
226
227                /* Metadata headers should already be skipped */
228                case TRACE_TYPE_LINUX_SLL:
229                case TRACE_TYPE_80211_PRISM:
230                case TRACE_TYPE_80211_RADIO:
231                        assert(!"Metadata headers should already be skipped");
232                        break;
233        }
234        fprintf(stderr,"%s not implemented for linktype %i\n", __func__, linktype);
235        assert(0);
236        return NULL;
237}
238
239DLLEXPORT uint8_t *trace_get_destination_mac(libtrace_packet_t *packet) 
240{
241        void *link;
242        libtrace_linktype_t linktype;
243        uint32_t remaining;
244
245        link = trace_get_layer2(packet,&linktype,&remaining);
246
247        libtrace_80211_t *wifi;
248        libtrace_ether_t *ethptr = (libtrace_ether_t*)link;
249
250
251        if (!link)
252                return NULL;
253
254        switch (linktype) {
255                case TRACE_TYPE_80211:
256                        wifi=(libtrace_80211_t*)link;
257                        return (uint8_t*)&wifi->mac1;
258                case TRACE_TYPE_80211_RADIO:
259                        wifi=(libtrace_80211_t*)trace_get_payload_from_radiotap(
260                                        link,NULL,NULL);
261                        return (uint8_t*)&wifi->mac1;
262                case TRACE_TYPE_80211_PRISM:
263                        wifi=(libtrace_80211_t*)((char*)link+144);
264                        return (uint8_t*)&wifi->mac1;
265                case TRACE_TYPE_ETH:
266                        return (uint8_t*)&ethptr->ether_dhost;
267                case TRACE_TYPE_POS:
268                case TRACE_TYPE_NONE:
269                case TRACE_TYPE_ATM:
270                case TRACE_TYPE_HDLC_POS:
271                case TRACE_TYPE_LINUX_SLL:
272                case TRACE_TYPE_PFLOG:
273                case TRACE_TYPE_DUCK:
274                case TRACE_TYPE_METADATA:
275                        /* No MAC address */
276                        return NULL;
277                default:
278                        break;
279        }
280        fprintf(stderr,"Not implemented\n");
281        assert(0);
282        return NULL;
283}
284
285
Note: See TracBrowser for help on using the repository browser.