source: libpacketdump/link_4.c @ 11a7f9c

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

Constification

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