source: libpacketdump/link_4.c @ b852fd2

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

Fix minor formatting problem in 802.11 libpacketdump decoder
Hexdump rest of packet when 802.11 decoder does not recognise frame type.

  • Property mode set to 100644
File size: 23.0 KB
RevLine 
[d0aa87c]1/*
2 * 802.11 libpacketdump decoder
3 *
[41b7eab]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>
[d0aa87c]22 */
23
[ace188a]24#include <sys/types.h>
[09d3bef]25#include <netinet/in.h>
26#include <stdio.h>
27#include "libpacketdump.h"
28#include "libtrace.h"
29
[41b7eab]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;
[09d3bef]52        uint16_t     duration;
[41b7eab]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];
[d0aa87c]76        uint16_t        qos;
[41b7eab]77} __attribute__ ((__packed__)) ieee80211_qos_data_frame;
[09d3bef]78
[41b7eab]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;
[d0aa87c]87
[41b7eab]88typedef struct ieee80211_payload {
89        uint16_t        ethertype;
90        uint8_t         payload[1];
91} __attribute__ ((__packed__)) ieee80211_payload;
[d0aa87c]92
[41b7eab]93char *macaddr(uint8_t mac[]) {
[d0aa87c]94        static char ether_buf[18] = {0, };
95        trace_ether_ntoa(mac, ether_buf);
96        return ether_buf;
97}
[09d3bef]98
[41b7eab]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                                }               
[b852fd2]247                                printf("\n");
[41b7eab]248                                               
249                                break;
250                        case 7:
251                                printf("  802.11d Country Information:\n");
252                                printf("   ISO 3166 Country Code: %c%c\n", data[0], data[1]);
253                                printf("   Regulatory Operating Environment: ");
254                                if (data[2] == ' ') printf("Indoor/Outdoor\n");
255                                else if (data[2] == 'O') printf("Outdoor only\n");
256                                else if (data[2] == 'I') printf("Indoor only\n");
257                                else printf("Unknown, code = %c\n", data[2]);
258                                data += sizeof(uint8_t) * 3;
259                                for (i = 0; i < ((ie->length - 3) / 3); i++) {
260                                        printf("   First Channel: %u, Num Channels: %u, Max Tx Power %idBm\n",
261                                                        data[0], data[1], (int8_t) data[2]);
262                                        data += sizeof(uint8_t) * 3;
263                                }
264                               
265                                break;
266                        case 11:
267                                printf("  802.11e QBSS Load\n");
268                                break;
269                        case 12:
270                                printf("  802.11e EDCA Parameter\n");
271                                break;
272                        case 13:
273                                printf("  802.11e TSPEC\n");
274                                break;
275                        case 14:
276                                printf("  802.11e TCLAS\n");
277                                break;
278                        case 15:
279                                printf("  802.11e Schedule\n");
280                                break;
281                        case 16:
282                                printf("  Authentication Challenge Text\n");
283                                break;
284                        case 32:
285                                printf("  802.11h Power Contraint\n");
286                                printf("   Local Power Contraint = %udB\n", data[0]);
287                                break;
288                        case 33:
289                                printf("  802.11h Power Capability\n");
290                                printf("   Minimum Transmit Power Capability = %idBm\n", (int8_t)data[0]);
291                                printf("   Maximum Transmit Power Capability = %idBm\n", (int8_t)data[1]);
292                                break;
293                        case 34:
294                                printf("  802.11h Transmit Power Control Request\n");
295                                break;
296                        case 35:
297                                printf("  802.11h Transmit Power Control Report\n");
298                                printf("   Transmit Power = %idBm\n", (int8_t)data[0]);
299                                printf("   Link Margin = %idB\n", (int8_t)data[1]);
300                                break;
301                        case 36:
302                                printf("  802.11h Supported Channels\n");
303                                for(i = 0; i < (ie->length / 2); i++) {
304                                        printf("   First Channel = %u, Num Channels = %u\n", data[0], data[1]);
305                                        data += 2;
306                                }
307                                break;
308                        case 37:
309                                printf("  802.11h Channel Switch Announcement\n");
310                                printf("   New Channel Number = %u\n", data[1]);
311                                printf("   Target Beacon Transmission Times untill switch = %u\n", data[2]);
312                                if (data[0]) printf("   Don't transmit more frames until switch occurs\n");
313                                break;
314                        case 38:
315                                printf("  802.11h Measurement Request\n");
316                                break;
317                        case 39:
318                                printf("  802.11h Measurement Report\n");
319                                break;
320                        case 40:
321                                printf("  802.11h Quiet\n");
322                                break;
323                        case 41:
324                                printf("  802.11h IBSS DFS\n");
325                                break;
326                        case 42:
327                                printf("  802.11g ERP Information\n");
328                                if(data[0] & 0x80) printf("   NonERP STAs are present in this BSS\n");
329                                if(data[0] & 0x40) printf("   Use Protection Mechanism\n");
330                                if(data[0] & 0x20) printf("   Do not use short preamble\n");
331                                break;
332                        case 43:
333                                printf("  802.11e TS Delay\n");
334                                break;
335                        case 44:
336                                printf("  802.11e TCLAS Processing\n");
337                                break;
338                        case 46:
339                                printf("  802.11e QoS Capability\n");
340                                break;
341                        case 48:
342                                printf("  802.11i RSN:\n");
343                                break;
344                        case 50:
345                                printf("  802.11g Extended Supported Rates (Kbit/s)\n   ");
346                                for(i = 0; i < ie->length; i++) 
347                                        printf("%u, ", data[i] * 500);
348                                printf("%c%c\n", (char) 8, (char) 8);           
349                                break;
350                               
351                        case 221:
352                                decode_80211_vendor_ie(ie);
353                                break;
354                        default:
355                                printf("  Unknown IE Element ID, 0x%02x\n", ie->id);
356                }
357                len -= sizeof(ieee80211_ie) + ie->length;
358                pkt = ((char *)pkt + sizeof(ieee80211_ie) + ie->length);
359        }
360}
361
362static
363void ieee80211_print_reason_code(uint16_t code) {
364        switch (code) {
365                case 0: printf("Reserved"); break;
366                case 1: printf("Unspecified Reason"); break;
367                case 2: printf("Previous authentication no longer valid"); break;
368                case 3: printf("Deauthenticated because sending station is leaving or has left IBSS or BSS"); break;
369                case 4: printf("Disassociated due to inactivity"); break;
370                case 5: printf("Disassociated because AP is unable to handle all currently associated stations"); break;
371                case 6: printf("Class 2 frame received from nonauthenticated station"); break;
372                case 7: printf("Class 3 frame received from nonassociated station"); break;
373                case 8: printf("Disassociated because AP is leaving (or has left) BSS"); break;
374                case 9: printf("Station requesting (re)association is not authenticated with responding station"); break;
375                default: printf("Unknown reason code: %u\n", code);
376        }
377}
[d0aa87c]378
[41b7eab]379static 
380void ieee80211_print_status_code(uint16_t code) {
381        switch (code) {
382                case 0: printf("Successful"); break;
383                case 1: printf("Unspecified failure"); break;
384                case 10: printf("Cannot support all requested capabilities in the Capability Information field"); break;
385                case 11: printf("Reassociation denied due to inablity to confirm that association exists"); break;
386                case 12: printf("Association denied due to reason outside the scope of this standard"); break;
387                case 13: printf("Responding station does not support the specified authentication algorithm"); break;
388                case 14: printf("Received an Authentication frame with authentication transaction sequence number outside of expected sequence"); break;
389                case 15: printf("Authentication rejected because of channege failure"); break;
390                case 16: printf("Authentication rejected due to timeout waiting for next frame in sequence"); break;
391                case 17: printf("Association denied because AP is unable to handle additional associated stations"); break;
392                case 18: printf("Association denied due to requesting station not supporting all of the data rates in the BSSBasicRates parameter"); break;
393                default: printf("Unknown status code: %u", code);
394        }
395}
396
397/* Decodes a capability info field */
398void decode_80211_capinfo(ieee80211_capinfo *c) {
399        printf(" 802.11MAC: Capability Info:");
400        if (c->ess) printf(" ESS");
401        if (c->ibss) printf(" IBSS");
402        if (c->cf_pollable) printf(" CF-POLLABLE");
403        if (c->cf_poll_req) printf(" CF-POLL-REQ");
404        if (c->privacy) printf(" PRIVACY");
405        if (c->short_preamble) printf(" SHORT-PREAMBLE");
406        if (c->pbcc) printf (" PBCC");
407        if (c->channel_agility) printf (" CHANNEL-AGILITY");
408        if (c->spectrum_mgmt) printf( " SPECTRUM-MGMT");
409        if (c->qos) printf(" QoS");
410        if (c->short_slot_time) printf (" SHORT-SLOT-TIME");
411        if (c->apsd) printf(" APSD");
412        if (c->dsss_ofdm) printf (" DSSS-OFDM");
413        if (c->delayed_block_ack) printf(" DELAYED-BLK-ACK");
414        if (c->immediate_block_ack) printf(" IMMEDIATE-BLK-ACK");
415        printf("\n");
416}
417       
418/* Decodes a beacon (or a probe response) */
419void decode_80211_beacon(char *pkt, int len) {
420        ieee80211_beacon *b = (ieee80211_beacon *)pkt;
421        if (len < sizeof(ieee80211_beacon)) {
422                printf(" 802.11MAC: [Truncated]\n");
423                return;
424        }
425       
426        printf(" 802.11MAC: Timestamp = %llu\n", b->ts);
427        printf(" 802.11MAC: Beacon Interval = %u\n", b->interval);
428        decode_80211_capinfo(&b->capinfo);
429        printf(" 802.11MAC: Information Elements:\n");
430        decode_80211_information_elements((char *) pkt + sizeof(ieee80211_beacon), len - sizeof(ieee80211_beacon));             
431}
432
433void decode_80211_assoc_request(char *pkt, int len) {
434        ieee80211_assoc_req *a = (ieee80211_assoc_req *) pkt;
435       
436        if (len < sizeof(ieee80211_assoc_req)) {
437                printf(" [Truncated association request]\n");
[d0aa87c]438                return;
439        }
440
[41b7eab]441        decode_80211_capinfo(&a->capinfo);
442        printf(" 802.11MAC: Listen Interval = %u beacon intervals\n", a->listen_interval);
443        printf(" 802.11MAC: Information Elements:\n");
444        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_assoc_req), len - sizeof(ieee80211_assoc_req));
445}
[d0aa87c]446
[41b7eab]447void decode_80211_assoc_response(char *pkt, int len) {
448        ieee80211_assoc_resp *r = (ieee80211_assoc_resp *) pkt;
[d0aa87c]449
[41b7eab]450        if (len < sizeof(ieee80211_assoc_resp)) {
451                printf(" [Truncated association response]\n");
452                return;
453        }
454        decode_80211_capinfo(&r->capinfo);
455        printf(" 802.11MAC: Status Code = ");
[e0184a5]456        ieee80211_print_status_code(r->status_code);
[41b7eab]457        /* AID has two most significant bits set to 1 */
458        printf("\n 802.11MAC: Association ID = %u\n", r->assoc_id & 0x3FFF);
459        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_assoc_resp), len-sizeof(ieee80211_assoc_resp));
460}
461       
462void decode_80211_reassoc_request(char *pkt, int len) {
463        ieee80211_reassoc_req *r = (ieee80211_reassoc_req *) pkt;
[d0aa87c]464
[41b7eab]465        if (len < sizeof(ieee80211_reassoc_req)) {
466                printf(" [Truncated reassociation request]\n");
467                return;
468        }
469        decode_80211_capinfo(&r->capinfo);
470        printf(" 802.11MAC: Listen Interval = %u beacon intervals\n", r->listen_interval);
471        printf(" 802.11MAC: Current AP address = %s\n", macaddr(r->current_address));
472        printf(" 802.11MAC: Information Elements:\n");
473        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_reassoc_req), len - sizeof(ieee80211_reassoc_req));
474
475}
476void decode_80211_authentication_frame(char *pkt, int len) {
477        ieee80211_auth *auth = (ieee80211_auth *)pkt;
478        if(len < sizeof(ieee80211_auth)) {
479                printf(" [Truncated authentication frame]\n");
480                return;
481        }
482        printf(" 802.11MAC: Authentication algorithm number = %u\n", auth->auth_algo_num);
483        printf(" 802.11MAC: Authentication transaction sequence number = %u\n", auth->auth_trans_seq_num);
484        printf(" 802.11MAC: Status Code = ");
[e0184a5]485        ieee80211_print_status_code(auth->status_code);
[41b7eab]486        printf("\n 802.11MAC: Information Elements:\n");
487        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_auth), len - sizeof(ieee80211_auth));
488
489}
490
491void decode_80211_mgmt(char *pkt, int len) {
492        ieee80211_mgmt_frame *mgmt = (ieee80211_mgmt_frame *)pkt;
493        uint8_t *data;
494       
495        printf(" 802.11MAC: Management frame: ");
496       
497        if (len < sizeof(ieee80211_mgmt_frame)) {
498                printf("[Truncated]\n");
499                return;
500        }
501
502        switch (mgmt->ctl.subtype) {
503                case 0: printf("association request"); break;
504                case 1: printf("association response"); break;
505                case 2: printf("reassociation request"); break;
506                case 3: printf("reassociation response"); break;
507                case 4: printf("probe request"); break;
508                case 5: printf("probe response"); break;
509                case 8: printf("beacon"); break;
510                case 9: printf("ATIM"); break;
511                case 10: printf("disassociation"); break;
512                case 11: printf("authentication"); break;
513                case 12: printf("deauthentication"); break;
514                case 13: printf("action"); break;
515                default: printf("RESERVED"); break;
516        }
517       
518        printf("\n 802.11MAC: Duration = %u us\n", mgmt->duration);
519        printf(" 802.11MAC: DA       = %s\n", macaddr(mgmt->addr1));
520        printf(" 802.11MAC: SA       = %s\n", macaddr(mgmt->addr2));
521        printf(" 802.11MAC: BSSID    = %s\n", macaddr(mgmt->addr3));
522        printf(" 802.11MAC: fragment no. = %u, sequence no. = %u\n",
523                        (mgmt->seq_ctrl & 0x000F) ,
524                        (mgmt->seq_ctrl & 0xFFF0) >> 4);
525
526        switch (mgmt->ctl.subtype) {
[d0aa87c]527                case 0:
[41b7eab]528                        decode_80211_assoc_request(pkt, len);
529                        break; 
[d0aa87c]530                case 1:
[41b7eab]531                        decode_80211_assoc_response(pkt, len);
[d0aa87c]532                        break;
533                case 2:
[41b7eab]534                        decode_80211_reassoc_request(pkt, len);
[d0aa87c]535                        break;
536                case 3:
[41b7eab]537                        /* Reassoc response == assoc response */
538                        decode_80211_assoc_response(pkt, len);
539                        break;
540                case 4:
541                        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_mgmt_frame), len - sizeof(ieee80211_mgmt_frame));
542                        break;
543                case 5:
544                        /* Probe response == beacon frame */
545                        decode_80211_beacon(pkt, len);
546                        break;
547                case 8:
548                        decode_80211_beacon(pkt, len);
549                        break;
550                case 10:
551                        data = ((char *)pkt + sizeof(ieee80211_mgmt_frame));
552                        printf(" 802.11MAC: Reason Code = ");
[e0184a5]553                        ieee80211_print_reason_code((uint16_t) ((data[0] << 8) | (data[1])));
[41b7eab]554                        printf("\n");
555                        break;
556                                                   
557                case 11:
558                        decode_80211_authentication_frame(pkt, len);
559                        break;
560                case 12:
561                        data = ((char *)pkt + sizeof(ieee80211_mgmt_frame));
562                        printf(" 802.11MAC: Reason Code = ");
[e0184a5]563                        ieee80211_print_reason_code((uint16_t) ((data[0] << 8) | (data[1])));
[41b7eab]564                        printf("\n");
[d0aa87c]565                        break;
[41b7eab]566                default:
567                        printf(" 802.11MAC: Subtype %u decoder not implemented\n", mgmt->ctl.subtype);
[d0aa87c]568        }
569
[41b7eab]570        printf("\n");
[d0aa87c]571
[41b7eab]572}
573
574void decode_80211_ctrl(char *pkt, int len) {
575        ieee80211_ctrl_frame_1addr *ctrl1 = (ieee80211_ctrl_frame_1addr *) pkt;
576        ieee80211_ctrl_frame_2addr *ctrl2 = (ieee80211_ctrl_frame_2addr *) pkt;
577        printf(" 802.11MAC: Control frame: ");
578       
579        if (len < sizeof(ieee80211_ctrl_frame_1addr)) {
580                printf("[Truncated]\n");
581                return;
582        }
583       
584        switch (ctrl1->ctl.subtype) {
585                case 8:
586                        printf("BlockAckReq\n"); 
[d0aa87c]587                        break;
[41b7eab]588                case 9:
589                        printf("BlockAck\n"); 
590                        break;
591                case 10:
592                        printf("PS-Poll\n"); 
593                        printf(" 802.11MAC: AID = 0x%04x\n", ntohs(ctrl1->duration));
594                        printf(" 802.11MAC: BSSID = %s\n", macaddr(ctrl1->addr1));
595                        break;
596                case 11:
597                        printf("RTS\n");
598 
599                        if (len < sizeof(ieee80211_ctrl_frame_2addr)) {
600                                printf("[Truncated]\n");
601                                return;
[d0aa87c]602                        }
[41b7eab]603
604                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl2->addr1));
605                        printf(" 802.11MAC: TA = %s\n", macaddr(ctrl2->addr2));
606                        break;
607                case 12:
608                        printf("CTS\n"); 
609                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl1->addr1));
610                        break;
611                case 13:
612                        printf("ACK\n"); 
613                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl1->addr1));
614                        break;
615                case 14:
616                        printf("CF-End\n"); 
617
618                        if (len < sizeof(ieee80211_ctrl_frame_2addr)) {
619                                printf("[Truncated]\n");
620                                return;
621                        }
622
623                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl2->addr1));
624                        printf(" 802.11MAC: BSSID = %s\n", macaddr(ctrl2->addr2));
625                        break;
626                case 15:
627                        printf("CF-End + CF-Ack\n"); 
628
629                        if (len < sizeof(ieee80211_ctrl_frame_2addr)) {
630                                printf("[Truncated]\n");
631                                return;
[d0aa87c]632                        }
[41b7eab]633
634                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl2->addr1));
635                        printf(" 802.11MAC: BSSID = %s\n", macaddr(ctrl2->addr2));
636                        break;
637                default:
638                        printf("RESERVED"); 
[d0aa87c]639                        break;
640        }
641
[41b7eab]642}
643
644void decode_80211_data(char *pkt, int len) {
645        ieee80211_data_frame *data = (ieee80211_data_frame *) pkt;
646        ieee80211_qos_data_frame *qos = (ieee80211_qos_data_frame *)pkt;
647        ieee80211_payload *pld; 
648        uint32_t hdrlen = 0;
649       
650        printf(" 802.11MAC: Data frame: ");
[d0aa87c]651       
[41b7eab]652        if (len < sizeof(ieee80211_data_frame)) {
653                printf("[Truncated]\n");
654                return;
655        }
656
657        switch (data->ctl.subtype) {
658                case 0: printf("Data"); break;
659                case 1: printf("Data + CF-Ack"); break;
660                case 2: printf("Data + CF-Poll"); break;
661                case 3: printf("Data + CF-Ack + CF-Poll"); break;
662                case 4: printf("Null (no data)"); break;
663                case 5: printf("CF-Ack (no data)"); break;
664                case 6: printf("CF-Poll (no data)"); break;
665                case 7: printf("CF-Ack + CF-Poll (no data)"); break;
666                case 8: printf("QoS Data"); break;
667                case 9: printf("QoS Data + CF-Ack"); break;
668                case 10: printf("QoS Data + CF-Poll"); break;
669                case 11: printf("QoS Data + CF-Ack + CF-Poll"); break;
670                case 12: printf("QoS Null (no data)"); break;
671                         /* subtype 13 is reserved */
672                case 14: printf("QoS CF-Poll (no data)"); break;
673                case 15: printf("Qos CF-Ack + CF-Poll (no data)"); break;
674
675                default: printf("RESERVED"); break;
676        }
677
678        printf("\n 802.11MAC: duration = %u us\n", data->duration);
679        printf(" 802.11MAC: fragment no. = %u, sequence no. = %u\n",
680                        (data->seq_ctrl & 0x000F) ,
681                        (data->seq_ctrl & 0xFFF0) >> 4);
682
683        if (! data->ctl.from_ds && ! data->ctl.to_ds) {
684                printf(" 802.11MAC: DA      = %s\n", macaddr(data->addr1));
685                printf(" 802.11MAC: SA      = %s\n", macaddr(data->addr2));
686                printf(" 802.11MAC: BSSID   = %s\n", macaddr(data->addr3));
687        } else if ( ! data->ctl.from_ds && data->ctl.to_ds) {
688                printf(" 802.11MAC: DA      = %s\n", macaddr(data->addr3));
689                printf(" 802.11MAC: SA      = %s\n", macaddr(data->addr2));
690                printf(" 802.11MAC: BSSID   = %s\n", macaddr(data->addr1));
691        } else if ( data->ctl.from_ds && ! data->ctl.to_ds) {
692                printf(" 802.11MAC: DA      = %s\n", macaddr(data->addr1));
693                printf(" 802.11MAC: SA      = %s\n", macaddr(data->addr3));
694                printf(" 802.11MAC: BSSID   = %s\n", macaddr(data->addr2));
695        } else {
696                printf(" 802.11MAC: DA      = %s\n", macaddr(data->addr3));
697                printf(" 802.11MAC: SA      = %s\n", macaddr(data->addr4));
698                printf(" 802.11MAC: TA      = %s\n", macaddr(data->addr2));
699                printf(" 802.11MAC: RA      = %s\n", macaddr(data->addr1));
700        }
701
702        hdrlen = 0;
703
704        if (data->ctl.subtype >= 8) { 
705                printf(" 802.11e: QoS = 0x%04x\n", qos->qos);
706                if (len > sizeof(ieee80211_qos_data_frame)) 
707                        hdrlen = sizeof(ieee80211_qos_data_frame);
[d0aa87c]708        } else {
[41b7eab]709                if (len > sizeof(ieee80211_data_frame)) 
710                        hdrlen = sizeof(ieee80211_data_frame);
[d0aa87c]711        }
712       
[41b7eab]713        /* hdrlen will be zero if there wasn't a payload */
714        if (hdrlen > 0) {
715                pld = (ieee80211_payload *) ((char *)pkt + hdrlen) ;
716                printf(" 802.11MAC: Payload ethertype = 0x%04x\n", ntohs(pld->ethertype));
717                decode_next((char *) pld->payload, len - hdrlen - 2, "eth", ntohs(pld->ethertype));
718        }
719
720       
721}
722
723void decode(int link_type, char *pkt, int len) 
724{
725        ieee80211_frame_control *fc;
[d0aa87c]726       
[41b7eab]727        if (len < sizeof(ieee80211_frame_control)) {
728                printf(" 802.11MAC: Truncated at frame control field\n");
729                return;
730        }
731
732        fc = (ieee80211_frame_control *) pkt;   
733
734        printf(" 802.11MAC: ");
735
736        printf("proto = %d, type = %d, subtype = %d, ", fc->version, fc->type, fc->subtype);
737
738        printf("flags =");
739        if (fc->to_ds) printf(" toDS");
740        if (fc->from_ds) printf(" fromDS");
741        if (fc->more_frag) printf(" moreFrag");
742        if (fc->retry) printf(" retry");
743        if (fc->power) printf(" pwrMgmt");
744        if (fc->more_data) printf(" moreData");
745        if (fc->wep) printf(" WEP");
746        if (fc->order) printf(" order");
747
748        printf("\n");
749        switch (fc->type) {
750                case 0:
751                        decode_80211_mgmt(pkt, len);
752                        break;
753                case 1:
754                        decode_80211_ctrl(pkt, len);
755                        break;
756                case 2:
757                        decode_80211_data(pkt, len);
758                        break;
759                case 3:
[b852fd2]760                        printf(" Unable to decode frame type %u, dumping rest of packet\n", fc->type);
761                        decode_next(pkt + sizeof(ieee80211_frame_control), len - sizeof(ieee80211_frame_control), "eth", 0);
762                       
[41b7eab]763                        break;
764        }
[d0aa87c]765
[09d3bef]766}
[d0aa87c]767
768
Note: See TracBrowser for help on using the repository browser.