source: libpacketdump/link_4.c @ dc6dc11

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

Fix a bug in the previous commit

  • Property mode set to 100644
File size: 24.2 KB
Line 
1/*
2 * 802.11 libpacketdump decoder
3 *
4 * Originally based on "wagdump" (c) 2005 Dean Armstrong
5 *
6 * This decoder will attempt to do it's best at decoding the frame formats
7 * defined in the following standards. Not all fields are decoded, but they
8 * are at least acknowledged as being present.
9 *
10 *  802.11
11 *  802.11b
12 *  802.11d - operation in multiple regulatory domains
13 *  802.11e - wireless multimedia extensions
14 *  802.11g
15 *  802.11h - power management
16 *  802.11i - MAC security enhancements
17 *
18 *  It will also attempt to decode vendor specific Information Elements
19 *  if possible.
20 *
21 *  (c) 2006 Scott Raynel <scottraynel@gmail.com>
22 */
23
24#include <sys/types.h>
25#include <netinet/in.h>
26#include <stdio.h>
27#include "libpacketdump.h"
28#include "libtrace.h"
29
30typedef struct ieee80211_frame_control {
31        uint8_t         version:2;
32        uint8_t         type:2;
33        uint8_t         subtype:4;
34        uint8_t         to_ds:1;
35        uint8_t         from_ds:1;
36        uint8_t         more_frag:1;
37        uint8_t         retry:1;
38        uint8_t         power:1;
39        uint8_t         more_data:1;
40        uint8_t         wep:1;
41        uint8_t         order:1;
42} __attribute__ ((__packed__)) ieee80211_frame_control;
43
44typedef struct ieee80211_ctrl_frame_1addr {
45        ieee80211_frame_control ctl;
46        uint16_t     duration;
47        uint8_t      addr1[6];
48} __attribute__ ((__packed__)) ieee80211_ctrl_frame_1addr;
49
50typedef struct ieee80211_ctrl_frame_2addr {
51        ieee80211_frame_control ctl;
52        uint16_t     duration;
53        uint8_t      addr1[6];
54        uint8_t      addr2[6];
55} __attribute__ ((__packed__)) ieee80211_ctrl_frame_2addr;
56
57typedef struct ieee80211_data_frame_3 {
58        ieee80211_frame_control ctl;
59        uint16_t        duration;
60        uint8_t         addr1[6];
61        uint8_t         addr2[6];
62        uint8_t         addr3[6];
63        uint16_t        seq_ctrl;
64} __attribute__ ((__packed__)) ieee80211_data_frame_3;
65
66typedef struct ieee80211_data_frame {
67        ieee80211_frame_control ctl;
68        uint16_t        duration;
69        uint8_t         addr1[6];
70        uint8_t         addr2[6];
71        uint8_t         addr3[6];
72        uint16_t        seq_ctrl;
73        uint8_t         addr4[6];
74} __attribute__ ((__packed__)) ieee80211_data_frame;
75
76typedef struct ieee80211_qos_data_frame {
77        ieee80211_frame_control ctl;
78        uint16_t        duration;
79        uint8_t         addr1[6];
80        uint8_t         addr2[6];
81        uint8_t         addr3[6];
82        uint16_t        seq_ctrl;
83        uint8_t         addr4[6];
84        uint16_t        qos;
85} __attribute__ ((__packed__)) ieee80211_qos_data_frame;
86
87typedef struct ieee80211_mgmt_frame {
88        ieee80211_frame_control ctl;
89        uint16_t        duration;
90        uint8_t         addr1[6];
91        uint8_t         addr2[6];
92        uint8_t         addr3[6];
93        uint16_t        seq_ctrl;
94} __attribute__ ((__packed__)) ieee80211_mgmt_frame;
95
96typedef struct ieee80211_payload {
97        uint16_t        ethertype;
98        uint8_t         payload[1];
99} __attribute__ ((__packed__)) ieee80211_payload;
100
101char *macaddr(uint8_t mac[]) {
102        static char ether_buf[18] = {0, };
103        trace_ether_ntoa(mac, ether_buf);
104        return ether_buf;
105}
106
107typedef struct ieee80211_capinfo {
108        uint16_t        ess:1;
109        uint16_t        ibss:1;
110        uint16_t        cf_pollable:1;
111        uint16_t        cf_poll_req:1;
112        uint16_t        privacy:1;
113        uint16_t        short_preamble:1;
114        uint16_t        pbcc:1;
115        uint16_t        channel_agility:1;
116        uint16_t        spectrum_mgmt:1;
117        uint16_t        qos:1;
118        uint16_t        short_slot_time:1;
119        uint16_t        apsd:1;
120        uint16_t        res1:1;
121        uint16_t        dsss_ofdm:1;
122        uint16_t        delayed_block_ack:1;
123        uint16_t        immediate_block_ack:1;
124} __attribute__ ((__packed__)) ieee80211_capinfo;
125
126typedef struct ieee80211_beacon {
127        ieee80211_mgmt_frame mgmt;
128        uint64_t        ts;
129        uint16_t        interval;
130        ieee80211_capinfo capinfo;
131} __attribute__ ((__packed__)) ieee80211_beacon;
132
133typedef struct ieee80211_assoc_req { 
134        ieee80211_mgmt_frame mgmt;
135        ieee80211_capinfo capinfo;
136        uint16_t        listen_interval;
137} __attribute__ ((__packed__)) ieee80211_assoc_req;
138
139typedef struct ieee80211_assoc_resp {
140        ieee80211_mgmt_frame mgmt;
141        ieee80211_capinfo capinfo;
142        uint16_t        status_code;
143        uint16_t        assoc_id;
144} __attribute__ ((__packed__)) ieee80211_assoc_resp;
145
146typedef struct ieee80211_reassoc_req {
147        ieee80211_mgmt_frame mgmt;
148        ieee80211_capinfo capinfo;
149        uint16_t        listen_interval;
150        uint8_t         current_address[6];
151} __attribute__ ((__packed__)) ieee80211_reassoc_req;
152
153typedef struct ieee80211_auth {
154        ieee80211_mgmt_frame mgmt;
155        uint16_t        auth_algo_num;
156        uint16_t        auth_trans_seq_num;
157        uint16_t        status_code;
158} __attribute__ ((__packed__)) ieee80211_auth;
159
160
161typedef struct ieee80211_ie {
162        uint8_t         id;
163        uint8_t         length;
164} __attribute__ ((__packed__)) ieee80211_ie;
165
166/*
167 * Takes a vendor IE and decodes it
168 */
169static void decode_80211_vendor_ie(ieee80211_ie *ie) {
170        uint8_t *data = (uint8_t *) ((char *)ie + sizeof(ieee80211_ie));
171        uint32_t ie_oui;       
172        printf("  Vendor Private Information Element\n");
173        if (ie->length <= 3) return;
174        ie_oui = (data[0] << 16) | (data[1] << 8) | data[2];
175        switch(ie_oui) {
176                case 0x0050f2:
177                        printf("   Atheros 802.11i/WPA IE\n");
178                        break;
179                case 0x00037f:
180                        printf("   Atheros Advanced Capability IE\n");
181                        break;
182                default:
183                        printf("   Unknown Vendor OUI (0x%06x)\n", ie_oui);
184                        break;
185        }
186
187}
188
189/*
190 * Takes a pointer to the start of the IEs in a beacon and the
191 * length remaining and decodes the IEs.
192 */
193static void decode_80211_information_elements(char *pkt, unsigned len) {
194        ieee80211_ie *ie;
195        int i = 0;
196        uint8_t * data;
197        uint8_t bmap_offset;
198        while (len >= sizeof(ieee80211_ie)) {
199                ie = (ieee80211_ie *) pkt;
200               
201                if ( len < ( sizeof(ieee80211_ie) + ie->length)) {
202                        printf("  [Truncated]\n");
203                        printf("  len = %u, sizeof_ie = %u, ie->len = %u\n",
204                                        len, sizeof(ieee80211_ie), ie->length);
205                        return;
206                }
207               
208                data = (( char *)pkt + sizeof (ieee80211_ie));
209               
210                switch (ie->id) {
211                        case 0:
212                                printf("  SSID = ");
213                                for (i = 0; i < ie->length; i++) 
214                                        printf("%c", data[i]);
215                                printf("\n");
216                                break;
217                        case 1:
218                                printf("  Supported Rates (Kbit/s):\n   ");
219                                /* NB: the MSB of each field will be set
220                                 * if the rate it describes is part of the
221                                 * basic rate set, hence the AND */
222                                for (i = 0; i < ie->length; i++) {
223                                        printf("%u, ", 
224                                                ( (data[i]&0x7F) * 500));
225
226                                }
227                                printf("%c%c\n", 0x8, 0x8);
228                                break;
229                        case 3:
230                                printf("  DSSS Channel = ");
231                                printf("%u\n", *data);
232                                break;
233                        case 5:
234                                printf("  Traffic Indication Message:\n");
235                                printf("   DTIM Count = %u, ", *data);
236                                data++;
237                                printf("DTIM Period = %u\n", *data);
238                                data++;
239                                printf("   Broadcast/Multicast waiting = %s\n", 
240                                        (*data) & 0x01 ? "Yes\0" : "No\0");
241                                bmap_offset = ((*data) & 0xFE) >> 1;
242                                data++;
243                                if ((ie->length == 4) && ( *data == 0)) {
244                                        printf("   No traffic waiting for stations\n");
245                                        break;
246                                }
247                               
248                                printf("   Traffic waiting for AssocIDs: ");
249                                for (i = 0; i < (ie->length - 3); i++) {
250                                        int j;
251                                        for (j = 0; j < 8; j++) {
252                                                if (data[i] & (1 << j)) {
253                                                        printf("%u ", (bmap_offset + i + 1) * 8 + j);
254                                                }
255                                        }
256                                }               
257                                printf("\n");
258                                               
259                                break;
260                        case 7:
261                                printf("  802.11d Country Information:\n");
262                                printf("   ISO 3166 Country Code: %c%c\n", data[0], data[1]);
263                                printf("   Regulatory Operating Environment: ");
264                                if (data[2] == ' ') printf("Indoor/Outdoor\n");
265                                else if (data[2] == 'O') printf("Outdoor only\n");
266                                else if (data[2] == 'I') printf("Indoor only\n");
267                                else printf("Unknown, code = %c\n", data[2]);
268                                data += sizeof(uint8_t) * 3;
269                                for (i = 0; i < ((ie->length - 3) / 3); i++) {
270                                        printf("   First Channel: %u, Num Channels: %u, Max Tx Power %idBm\n",
271                                                        data[0], data[1], (int8_t) data[2]);
272                                        data += sizeof(uint8_t) * 3;
273                                }
274                               
275                                break;
276                        case 11:
277                                printf("  802.11e QBSS Load\n");
278                                break;
279                        case 12:
280                                printf("  802.11e EDCA Parameter\n");
281                                break;
282                        case 13:
283                                printf("  802.11e TSPEC\n");
284                                break;
285                        case 14:
286                                printf("  802.11e TCLAS\n");
287                                break;
288                        case 15:
289                                printf("  802.11e Schedule\n");
290                                break;
291                        case 16:
292                                printf("  Authentication Challenge Text\n");
293                                break;
294                        case 32:
295                                printf("  802.11h Power Contraint\n");
296                                printf("   Local Power Contraint = %udB\n", data[0]);
297                                break;
298                        case 33:
299                                printf("  802.11h Power Capability\n");
300                                printf("   Minimum Transmit Power Capability = %idBm\n", (int8_t)data[0]);
301                                printf("   Maximum Transmit Power Capability = %idBm\n", (int8_t)data[1]);
302                                break;
303                        case 34:
304                                printf("  802.11h Transmit Power Control Request\n");
305                                break;
306                        case 35:
307                                printf("  802.11h Transmit Power Control Report\n");
308                                printf("   Transmit Power = %idBm\n", (int8_t)data[0]);
309                                printf("   Link Margin = %idB\n", (int8_t)data[1]);
310                                break;
311                        case 36:
312                                printf("  802.11h Supported Channels\n");
313                                for(i = 0; i < (ie->length / 2); i++) {
314                                        printf("   First Channel = %u, Num Channels = %u\n", data[0], data[1]);
315                                        data += 2;
316                                }
317                                break;
318                        case 37:
319                                printf("  802.11h Channel Switch Announcement\n");
320                                printf("   New Channel Number = %u\n", data[1]);
321                                printf("   Target Beacon Transmission Times untill switch = %u\n", data[2]);
322                                if (data[0]) printf("   Don't transmit more frames until switch occurs\n");
323                                break;
324                        case 38:
325                                printf("  802.11h Measurement Request\n");
326                                break;
327                        case 39:
328                                printf("  802.11h Measurement Report\n");
329                                break;
330                        case 40:
331                                printf("  802.11h Quiet\n");
332                                break;
333                        case 41:
334                                printf("  802.11h IBSS DFS\n");
335                                break;
336                        case 42:
337                                printf("  802.11g ERP Information\n");
338                                if(data[0] & 0x80) printf("   NonERP STAs are present in this BSS\n");
339                                if(data[0] & 0x40) printf("   Use Protection Mechanism\n");
340                                if(data[0] & 0x20) printf("   Do not use short preamble\n");
341                                break;
342                        case 43:
343                                printf("  802.11e TS Delay\n");
344                                break;
345                        case 44:
346                                printf("  802.11e TCLAS Processing\n");
347                                break;
348                        case 46:
349                                printf("  802.11e QoS Capability\n");
350                                break;
351                        case 48:
352                                printf("  802.11i RSN:\n");
353                                break;
354                        case 50:
355                                printf("  802.11g Extended Supported Rates (Kbit/s)\n   ");
356                                for(i = 0; i < ie->length; i++) 
357                                        printf("%u, ", data[i] * 500);
358                                printf("%c%c\n", (char) 8, (char) 8);           
359                                break;
360                               
361                        case 221:
362                                decode_80211_vendor_ie(ie);
363                                break;
364                        default:
365                                printf("  Unknown IE Element ID, 0x%02x\n", ie->id);
366                }
367                len -= (sizeof(ieee80211_ie) + ie->length);
368                pkt = ((char *)pkt + sizeof(ieee80211_ie) + ie->length);
369        }
370}
371
372static
373void ieee80211_print_reason_code(uint16_t code) {
374        switch (code) {
375                case 0: printf("Reserved"); break;
376                case 1: printf("Unspecified Reason"); break;
377                case 2: printf("Previous authentication no longer valid"); break;
378                case 3: printf("Deauthenticated because sending station is leaving or has left IBSS or BSS"); break;
379                case 4: printf("Disassociated due to inactivity"); break;
380                case 5: printf("Disassociated because AP is unable to handle all currently associated stations"); break;
381                case 6: printf("Class 2 frame received from nonauthenticated station"); break;
382                case 7: printf("Class 3 frame received from nonassociated station"); break;
383                case 8: printf("Disassociated because AP is leaving (or has left) BSS"); break;
384                case 9: printf("Station requesting (re)association is not authenticated with responding station"); break;
385                default: printf("Unknown reason code: %u\n", code);
386        }
387}
388
389static 
390void ieee80211_print_status_code(uint16_t code) {
391        switch (code) {
392                case 0: printf("Successful"); break;
393                case 1: printf("Unspecified failure"); break;
394                case 10: printf("Cannot support all requested capabilities in the Capability Information field"); break;
395                case 11: printf("Reassociation denied due to inablity to confirm that association exists"); break;
396                case 12: printf("Association denied due to reason outside the scope of this standard"); break;
397                case 13: printf("Responding station does not support the specified authentication algorithm"); break;
398                case 14: printf("Received an Authentication frame with authentication transaction sequence number outside of expected sequence"); break;
399                case 15: printf("Authentication rejected because of channege failure"); break;
400                case 16: printf("Authentication rejected due to timeout waiting for next frame in sequence"); break;
401                case 17: printf("Association denied because AP is unable to handle additional associated stations"); break;
402                case 18: printf("Association denied due to requesting station not supporting all of the data rates in the BSSBasicRates parameter"); break;
403                default: printf("Unknown status code: %u", code);
404        }
405}
406
407/* Decodes a capability info field */
408static void decode_80211_capinfo(ieee80211_capinfo *c) {
409        printf(" 802.11MAC: Capability Info:");
410        if (c->ess) printf(" ESS");
411        if (c->ibss) printf(" IBSS");
412        if (c->cf_pollable) printf(" CF-POLLABLE");
413        if (c->cf_poll_req) printf(" CF-POLL-REQ");
414        if (c->privacy) printf(" PRIVACY");
415        if (c->short_preamble) printf(" SHORT-PREAMBLE");
416        if (c->pbcc) printf (" PBCC");
417        if (c->channel_agility) printf (" CHANNEL-AGILITY");
418        if (c->spectrum_mgmt) printf( " SPECTRUM-MGMT");
419        if (c->qos) printf(" QoS");
420        if (c->short_slot_time) printf (" SHORT-SLOT-TIME");
421        if (c->apsd) printf(" APSD");
422        if (c->dsss_ofdm) printf (" DSSS-OFDM");
423        if (c->delayed_block_ack) printf(" DELAYED-BLK-ACK");
424        if (c->immediate_block_ack) printf(" IMMEDIATE-BLK-ACK");
425        printf("\n");
426}
427       
428/* Decodes a beacon (or a probe response) */
429static void decode_80211_beacon(char *pkt, unsigned len) {
430        ieee80211_beacon *b = (ieee80211_beacon *)pkt;
431        if (len < sizeof(ieee80211_beacon)) {
432                printf(" 802.11MAC: [Truncated]\n");
433                return;
434        }
435       
436        printf(" 802.11MAC: Timestamp = %llu\n", b->ts);
437        printf(" 802.11MAC: Beacon Interval = %u\n", b->interval);
438        decode_80211_capinfo(&b->capinfo);
439        printf(" 802.11MAC: Information Elements:\n");
440        decode_80211_information_elements((char *) pkt + sizeof(ieee80211_beacon), len - sizeof(ieee80211_beacon));             
441}
442
443static void decode_80211_assoc_request(char *pkt, unsigned len) {
444        ieee80211_assoc_req *a = (ieee80211_assoc_req *) pkt;
445       
446        if (len < sizeof(ieee80211_assoc_req)) {
447                printf(" [Truncated association request]\n");
448                return;
449        }
450
451        decode_80211_capinfo(&a->capinfo);
452        printf(" 802.11MAC: Listen Interval = %u beacon intervals\n", a->listen_interval);
453        printf(" 802.11MAC: Information Elements:\n");
454        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_assoc_req), len - sizeof(ieee80211_assoc_req));
455}
456
457static void decode_80211_assoc_response(char *pkt, unsigned len) {
458        ieee80211_assoc_resp *r = (ieee80211_assoc_resp *) pkt;
459
460        if (len < sizeof(ieee80211_assoc_resp)) {
461                printf(" [Truncated association response]\n");
462                return;
463        }
464        decode_80211_capinfo(&r->capinfo);
465        printf(" 802.11MAC: Status Code = ");
466        ieee80211_print_status_code(r->status_code);
467        /* AID has two most significant bits set to 1 */
468        printf("\n 802.11MAC: Association ID = %u\n", r->assoc_id & 0x3FFF);
469        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_assoc_resp), len-sizeof(ieee80211_assoc_resp));
470}
471       
472static void decode_80211_reassoc_request(char *pkt, unsigned len) {
473        ieee80211_reassoc_req *r = (ieee80211_reassoc_req *) pkt;
474
475        if (len < sizeof(ieee80211_reassoc_req)) {
476                printf(" [Truncated reassociation request]\n");
477                return;
478        }
479        decode_80211_capinfo(&r->capinfo);
480        printf(" 802.11MAC: Listen Interval = %u beacon intervals\n", r->listen_interval);
481        printf(" 802.11MAC: Current AP address = %s\n", macaddr(r->current_address));
482        printf(" 802.11MAC: Information Elements:\n");
483        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_reassoc_req), len - sizeof(ieee80211_reassoc_req));
484}
485
486static void decode_80211_authentication_frame(char *pkt, unsigned len) {
487        ieee80211_auth *auth = (ieee80211_auth *)pkt;
488        if(len < sizeof(ieee80211_auth)) {
489                printf(" [Truncated authentication frame]\n");
490                return;
491        }
492        printf(" 802.11MAC: Authentication algorithm number = %u\n", auth->auth_algo_num);
493        printf(" 802.11MAC: Authentication transaction sequence number = %u\n", auth->auth_trans_seq_num);
494        printf(" 802.11MAC: Status Code = ");
495        ieee80211_print_status_code(auth->status_code);
496        printf("\n 802.11MAC: Information Elements:\n");
497        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_auth), len - sizeof(ieee80211_auth));
498
499}
500
501static void decode_80211_mgmt(char *pkt, unsigned len) {
502        ieee80211_mgmt_frame *mgmt = (ieee80211_mgmt_frame *)pkt;
503        uint8_t *data;
504       
505        printf(" 802.11MAC: Management frame: ");
506       
507        if (len < sizeof(ieee80211_mgmt_frame)) {
508                printf("[Truncated]\n");
509                return;
510        }
511
512        switch (mgmt->ctl.subtype) {
513                case 0: printf("association request"); break;
514                case 1: printf("association response"); break;
515                case 2: printf("reassociation request"); break;
516                case 3: printf("reassociation response"); break;
517                case 4: printf("probe request"); break;
518                case 5: printf("probe response"); break;
519                case 8: printf("beacon"); break;
520                case 9: printf("ATIM"); break;
521                case 10: printf("disassociation"); break;
522                case 11: printf("authentication"); break;
523                case 12: printf("deauthentication"); break;
524                case 13: printf("action"); break;
525                default: printf("RESERVED"); break;
526        }
527       
528        printf("\n 802.11MAC: Duration = %u us\n", mgmt->duration);
529        printf(" 802.11MAC: DA       = %s\n", macaddr(mgmt->addr1));
530        printf(" 802.11MAC: SA       = %s\n", macaddr(mgmt->addr2));
531        printf(" 802.11MAC: BSSID    = %s\n", macaddr(mgmt->addr3));
532        printf(" 802.11MAC: fragment no. = %u, sequence no. = %u\n",
533                        (mgmt->seq_ctrl & 0x000F) ,
534                        (mgmt->seq_ctrl & 0xFFF0) >> 4);
535
536        switch (mgmt->ctl.subtype) {
537                case 0:
538                        decode_80211_assoc_request(pkt, len);
539                        break; 
540                case 1:
541                        decode_80211_assoc_response(pkt, len);
542                        break;
543                case 2:
544                        decode_80211_reassoc_request(pkt, len);
545                        break;
546                case 3:
547                        /* Reassoc response == assoc response */
548                        decode_80211_assoc_response(pkt, len);
549                        break;
550                case 4:
551                        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_mgmt_frame), len - sizeof(ieee80211_mgmt_frame));
552                        break;
553                case 5:
554                        /* Probe response == beacon frame */
555                        decode_80211_beacon(pkt, len);
556                        break;
557                case 8:
558                        decode_80211_beacon(pkt, len);
559                        break;
560                case 10:
561                        data = ((char *)pkt + sizeof(ieee80211_mgmt_frame));
562                        printf(" 802.11MAC: Reason Code = ");
563                        ieee80211_print_reason_code((uint16_t) ((data[0] << 8) | (data[1])));
564                        printf("\n");
565                        break;
566                                                   
567                case 11:
568                        decode_80211_authentication_frame(pkt, len);
569                        break;
570                case 12:
571                        data = ((char *)pkt + sizeof(ieee80211_mgmt_frame));
572                        printf(" 802.11MAC: Reason Code = ");
573                        ieee80211_print_reason_code((uint16_t) ((data[0] << 8) | (data[1])));
574                        printf("\n");
575                        break;
576                default:
577                        printf(" 802.11MAC: Subtype %u decoder not implemented\n", mgmt->ctl.subtype);
578        }
579
580        printf("\n");
581
582}
583
584static void decode_80211_ctrl(char *pkt, unsigned len) {
585        ieee80211_ctrl_frame_1addr *ctrl1 = (ieee80211_ctrl_frame_1addr *) pkt;
586        ieee80211_ctrl_frame_2addr *ctrl2 = (ieee80211_ctrl_frame_2addr *) pkt;
587        printf(" 802.11MAC: Control frame: ");
588       
589        if (len < sizeof(ieee80211_ctrl_frame_1addr)) {
590                printf("[Truncated]\n");
591                return;
592        }
593       
594        switch (ctrl1->ctl.subtype) {
595                case 8:
596                        printf("BlockAckReq\n"); 
597                        break;
598                case 9:
599                        printf("BlockAck\n"); 
600                        break;
601                case 10:
602                        printf("PS-Poll\n"); 
603                        printf(" 802.11MAC: AID = 0x%04x\n", ntohs(ctrl1->duration));
604                        printf(" 802.11MAC: BSSID = %s\n", macaddr(ctrl1->addr1));
605                        break;
606                case 11:
607                        printf("RTS\n");
608 
609                        if (len < sizeof(ieee80211_ctrl_frame_2addr)) {
610                                printf("[Truncated]\n");
611                                return;
612                        }
613
614                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl2->addr1));
615                        printf(" 802.11MAC: TA = %s\n", macaddr(ctrl2->addr2));
616                        break;
617                case 12:
618                        printf("CTS\n"); 
619                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl1->addr1));
620                        break;
621                case 13:
622                        printf("ACK\n"); 
623                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl1->addr1));
624                        break;
625                case 14:
626                        printf("CF-End\n"); 
627
628                        if (len < sizeof(ieee80211_ctrl_frame_2addr)) {
629                                printf("[Truncated]\n");
630                                return;
631                        }
632
633                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl2->addr1));
634                        printf(" 802.11MAC: BSSID = %s\n", macaddr(ctrl2->addr2));
635                        break;
636                case 15:
637                        printf("CF-End + CF-Ack\n"); 
638
639                        if (len < sizeof(ieee80211_ctrl_frame_2addr)) {
640                                printf("[Truncated]\n");
641                                return;
642                        }
643
644                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl2->addr1));
645                        printf(" 802.11MAC: BSSID = %s\n", macaddr(ctrl2->addr2));
646                        break;
647                default:
648                        printf("RESERVED"); 
649                        break;
650        }
651
652}
653
654static void decode_80211_data(char *pkt, unsigned len) {
655        ieee80211_data_frame *data = (ieee80211_data_frame *) pkt;
656        ieee80211_qos_data_frame *qos = (ieee80211_qos_data_frame *)pkt;
657        ieee80211_payload *pld; 
658        uint32_t hdrlen = 0;
659       
660        printf(" 802.11MAC: Data frame: ");
661       
662        if (len < sizeof(ieee80211_data_frame_3)) {
663                printf("[Truncated]\n");
664                return;
665        }
666
667        switch (data->ctl.subtype) {
668                case 0: printf("Data"); break;
669                case 1: printf("Data + CF-Ack"); break;
670                case 2: printf("Data + CF-Poll"); break;
671                case 3: printf("Data + CF-Ack + CF-Poll"); break;
672                case 4: printf("Null (no data)"); break;
673                case 5: printf("CF-Ack (no data)"); break;
674                case 6: printf("CF-Poll (no data)"); break;
675                case 7: printf("CF-Ack + CF-Poll (no data)"); break;
676                case 8: printf("QoS Data"); break;
677                case 9: printf("QoS Data + CF-Ack"); break;
678                case 10: printf("QoS Data + CF-Poll"); break;
679                case 11: printf("QoS Data + CF-Ack + CF-Poll"); break;
680                case 12: printf("QoS Null (no data)"); break;
681                         /* subtype 13 is reserved */
682                case 14: printf("QoS CF-Poll (no data)"); break;
683                case 15: printf("Qos CF-Ack + CF-Poll (no data)"); break;
684
685                default: printf("RESERVED"); break;
686        }
687
688        printf("\n 802.11MAC: duration = %u us\n", data->duration);
689        printf(" 802.11MAC: fragment no. = %u, sequence no. = %u\n",
690                        (data->seq_ctrl & 0x000F) ,
691                        (data->seq_ctrl & 0xFFF0) >> 4);
692
693        hdrlen = sizeof(ieee80211_data_frame_3);
694       
695        if (! data->ctl.from_ds && ! data->ctl.to_ds) {
696                printf(" 802.11MAC: DA      = %s\n", macaddr(data->addr1));
697                printf(" 802.11MAC: SA      = %s\n", macaddr(data->addr2));
698                printf(" 802.11MAC: BSSID   = %s\n", macaddr(data->addr3));
699        } else if ( ! data->ctl.from_ds && data->ctl.to_ds) {
700                printf(" 802.11MAC: DA      = %s\n", macaddr(data->addr3));
701                printf(" 802.11MAC: SA      = %s\n", macaddr(data->addr2));
702                printf(" 802.11MAC: BSSID   = %s\n", macaddr(data->addr1));
703        } else if ( data->ctl.from_ds && ! data->ctl.to_ds) {
704                printf(" 802.11MAC: DA      = %s\n", macaddr(data->addr1));
705                printf(" 802.11MAC: SA      = %s\n", macaddr(data->addr3));
706                printf(" 802.11MAC: BSSID   = %s\n", macaddr(data->addr2));
707        } else {
708                /* Check to make sure we have a four-address frame first */
709                if (len < sizeof(ieee80211_data_frame)) {
710                        printf(" 802.11MAC: [Truncated]\n");
711                        return;
712                }
713                printf(" 802.11MAC: DA      = %s\n", macaddr(data->addr3));
714                printf(" 802.11MAC: SA      = %s\n", macaddr(data->addr4));
715                printf(" 802.11MAC: TA      = %s\n", macaddr(data->addr2));
716                printf(" 802.11MAC: RA      = %s\n", macaddr(data->addr1));
717                hdrlen = sizeof(ieee80211_data_frame); /* 4 addr header */
718        }
719
720
721        if (data->ctl.subtype >= 8) { 
722                printf(" 802.11e: QoS = 0x%04x\n", qos->qos);
723                if (len > sizeof(ieee80211_qos_data_frame)) 
724                        hdrlen = sizeof(ieee80211_qos_data_frame);
725        }
726       
727        if (len > hdrlen) {
728                pld = (ieee80211_payload *) ((char *)pkt + hdrlen) ;
729                int payload_offset = 0;
730                uint16_t ethertype = 0;
731                if (ntohs(pld->ethertype) == 0xaaaa) {
732                        /* 802.11 payload contains an 802.2 LLC/SNAP header */
733                        libtrace_llcsnap_t *llcsnap = (libtrace_llcsnap_t *) pld;
734                        printf(" 802.2: DSAP = 0x%x, SSAP = 0x%x, OUI = 0x%x, Type = 0x%x\n", 
735                                        llcsnap->dsap, llcsnap->ssap, llcsnap->oui, ntohs(llcsnap->type));
736                        payload_offset = sizeof(libtrace_llcsnap_t);
737                        ethertype = ntohs(llcsnap->type);
738                } else {
739                        /* 802.11 payload contains an Ethernet II frame */
740                        printf(" 802.11MAC: Payload ethertype = 0x%04x\n", ntohs(pld->ethertype));
741                        payload_offset = sizeof(pld->ethertype);
742                        ethertype = ntohs(pld->ethertype);
743                }
744                decode_next((char *) pkt + hdrlen + payload_offset, 
745                                len - hdrlen - payload_offset, "eth", ethertype);
746        }
747
748       
749}
750
751void decode(int link_type, char *pkt, unsigned len) 
752{
753        ieee80211_frame_control *fc;
754       
755        if (len < sizeof(ieee80211_frame_control)) {
756                printf(" 802.11MAC: Truncated at frame control field\n");
757                return;
758        }
759
760        fc = (ieee80211_frame_control *) pkt;   
761
762        printf(" 802.11MAC: ");
763
764        printf("proto = %d, type = %d, subtype = %d, ", fc->version, fc->type, fc->subtype);
765
766        printf("flags =");
767        if (fc->to_ds) printf(" toDS");
768        if (fc->from_ds) printf(" fromDS");
769        if (fc->more_frag) printf(" moreFrag");
770        if (fc->retry) printf(" retry");
771        if (fc->power) printf(" pwrMgmt");
772        if (fc->more_data) printf(" moreData");
773        if (fc->wep) printf(" WEP");
774        if (fc->order) printf(" order");
775
776        printf("\n");
777        switch (fc->type) {
778                case 0:
779                        decode_80211_mgmt(pkt, len);
780                        break;
781                case 1:
782                        decode_80211_ctrl(pkt, len);
783                        break;
784                case 2:
785                        decode_80211_data(pkt, len);
786                        break;
787                case 3:
788                        printf(" Unable to decode frame type %u, dumping rest of packet\n", fc->type);
789                        decode_next(pkt + sizeof(ieee80211_frame_control), len - sizeof(ieee80211_frame_control), "eth", 0);
790                       
791                        break;
792        }
793
794}
795
796
Note: See TracBrowser for help on using the repository browser.