source: libpacketdump/link_4.c @ 41b7eab

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

Major changes to the libpacketdump decoder for 802.11

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