Changeset 41b7eab
- Timestamp:
- 09/27/06 15:43:45 (15 years ago)
- Branches:
- 4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, getfragoff, help, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
- Children:
- a7d1914
- Parents:
- fc2078d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libpacketdump/link_4.c
rd0aa87c r41b7eab 2 2 * 802.11 libpacketdump decoder 3 3 * 4 * Based on "wagdump" (c) 2005 Dean Armstrong 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> 5 22 */ 6 23 … … 11 28 #include "libtrace.h" 12 29 13 /* NB: this struct is just used for length */ 14 struct ieee_802_11_header { 15 uint8_t protocol:2; 16 uint8_t type:2; 17 uint8_t subtype:4; 18 uint8_t to_ds:1; 19 uint8_t from_ds:1; 20 uint8_t more_frag:1; 21 uint8_t retry:1; 22 uint8_t power:1; 23 uint8_t more_data:1; 24 uint8_t wep:1; 25 uint8_t order:1; 30 typedef 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 44 typedef struct ieee80211_ctrl_frame_1addr { 45 ieee80211_frame_control ctl; 26 46 uint16_t duration; 27 uint8_t mac1[6]; 28 uint8_t mac2[6]; 29 uint8_t mac3[6]; 30 uint16_t SeqCtl; 31 uint8_t mac4[6]; 32 }__attribute__ ((__packed__)); 33 34 struct ieee_802_11_e_payload { 47 uint8_t addr1[6]; 48 } __attribute__ ((__packed__)) ieee80211_ctrl_frame_1addr; 49 50 typedef 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 58 typedef 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 68 typedef 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]; 35 76 uint16_t qos; 36 uint16_t type; 37 uint8_t data[1]; 38 }__attribute__ ((__packed__)); 39 40 struct ieee_802_11_payload { 41 uint16_t type; 42 uint8_t data[1]; 43 }__attribute__ ((__packed__)); 44 45 46 char *macaddr(uint8_t *mac) { 77 } __attribute__ ((__packed__)) ieee80211_qos_data_frame; 78 79 typedef 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 88 typedef struct ieee80211_payload { 89 uint16_t ethertype; 90 uint8_t payload[1]; 91 } __attribute__ ((__packed__)) ieee80211_payload; 92 93 char *macaddr(uint8_t mac[]) { 47 94 static char ether_buf[18] = {0, }; 48 95 trace_ether_ntoa(mac, ether_buf); … … 50 97 } 51 98 99 typedef 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 118 typedef 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 125 typedef 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 131 typedef 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 138 typedef 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 145 typedef 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 153 typedef 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 */ 161 void 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 */ 185 void 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 361 static 362 void 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 378 static 379 void 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 */ 397 void 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) */ 418 void 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 432 void 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 446 void 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 461 void 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 } 475 void 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 490 void 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 573 void 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 643 void 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 52 722 void decode(int link_type, char *pkt, int len) 53 723 { 54 int version, type, subtype, flags, duration, seq_ctrl; 55 bool is_wme = false; 56 57 if (len == 0) { 58 printf("Zero length packet!\n"); 59 return; 60 } 61 62 version = (pkt[0] & 0x3); 63 type = (pkt[0] & 0x0c) >> 2; 64 subtype = (pkt[0] & 0xf0) >> 4; 65 flags = pkt[1]; 66 seq_ctrl = *(uint16_t *)&pkt[22]; 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; 67 732 68 733 printf(" 802.11MAC: "); 69 734 70 printf("proto = %d, type = %d, subtype = %d, ", version, type,subtype);735 printf("proto = %d, type = %d, subtype = %d, ", fc->version, fc->type, fc->subtype); 71 736 72 737 printf("flags ="); 73 if (flags == 0) 74 printf(" 0"); 75 if (flags & 0x01) printf(" toDS"); 76 if (flags & 0x02) printf(" fromDS"); 77 if (flags & 0x04) printf(" moreFrag"); 78 if (flags & 0x08) printf(" retry"); 79 if (flags & 0x10) printf(" pwrMgmt"); 80 if (flags & 0x20) printf(" moreData"); 81 if (flags & 0x40) printf(" WEP"); 82 if (flags & 0x80) printf(" order"); 83 84 if (type == 2) 85 printf(", seq_ctrl = %d", seq_ctrl); 86 87 printf("\n 802.11MAC: "); 88 switch (type) { 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) { 89 749 case 0: 90 printf("Management frame: "); 91 switch (subtype) { 92 case 0: printf("association request"); break; 93 case 1: printf("association response"); break; 94 case 2: printf("reassociation request"); break; 95 case 3: printf("reassociation response"); break; 96 case 4: printf("probe request"); break; 97 case 5: printf("probe response"); break; 98 case 8: printf("beacon"); break; 99 case 9: printf("ATIM"); break; 100 case 10: printf("disassociation"); break; 101 case 11: printf("authentication"); break; 102 case 12: printf("deauthentication"); break; 103 case 13: printf("action"); break; 104 default: printf("RESERVED"); break; 105 } 750 decode_80211_mgmt(pkt, len); 106 751 break; 107 752 case 1: 108 printf("Control frame: "); 109 switch (subtype) { 110 case 8: printf("BlockAckReq"); break; 111 case 9: printf("BlockAck"); break; 112 case 10: printf("PS-Poll"); break; 113 case 11: printf("RTS"); break; 114 case 12: printf("CTS"); break; 115 case 13: printf("ACK"); break; 116 case 14: printf("CF-End"); break; 117 case 15: printf("CF-End + CF-Ack"); break; 118 default: printf("RESERVED"); break; 119 } 753 decode_80211_ctrl(pkt, len); 120 754 break; 121 755 case 2: 122 printf("Data frame: "); 123 /* Check to see if the frame has WME QoS bits */ 124 if (subtype >= 8) is_wme = true; 125 126 switch (subtype) { 127 case 0: printf("Data"); break; 128 case 1: printf("Data + CF-Ack"); break; 129 case 2: printf("Data + CF-Poll"); break; 130 case 3: printf("Data + CF-Ack + CF-Poll"); break; 131 case 4: printf("Null (no data)"); break; 132 case 5: printf("CF-Ack (no data)"); break; 133 case 6: printf("CF-Poll (no data)"); break; 134 case 7: printf("CF-Ack + CF-Poll (no data)"); break; 135 case 8: printf("QoS Data"); break; 136 case 9: printf("QoS Data + CF-Ack"); break; 137 case 10: printf("QoS Data + CF-Poll"); break; 138 case 11: printf("QoS Data + CF-Ack + CF-Poll"); break; 139 case 12: printf("QoS Null (no data)"); break; 140 /* subtype 13 is reserved */ 141 case 14: printf("QoS CF-Poll (no data)"); break; 142 case 15: printf("Qos CF-Ack + CF-Poll (no data)"); break; 143 144 default: printf("RESERVED"); break; 145 } 756 decode_80211_data(pkt, len); 146 757 break; 147 758 case 3: 148 printf("BAD FRAME TYPE!"); 149 break; 150 } 151 152 duration = ((uint32_t)pkt[2] << 8) + pkt[3]; 153 printf(" (duration = %d)\n", duration); 154 155 switch (type) { 156 case 0: 157 printf(" 802.11MAC: DA = %s\n", macaddr(&pkt[4])); 158 printf(" 802.11MAC: SA = %s\n", macaddr(&pkt[10])); 159 printf(" 802.11MAC: BSSID = %s\n", macaddr(&pkt[16])); 160 break; 161 case 1: 162 switch (subtype) { 163 case 11: 164 printf(" 802.11MAC: SA = %s\n", macaddr(&pkt[10])); 165 case 12: 166 case 13: 167 printf(" 802.11MAC: RA = %s\n", macaddr(&pkt[4])); 168 break; 169 } 170 case 2: // Data packet 171 if (subtype == 0 || subtype == 8) { 172 switch (pkt[1] & 0x3) { 173 case 0x0: 174 printf(" 802.11MAC: DA = %s\n", macaddr(&pkt[4])); 175 printf(" 802.11MAC: SA = %s\n", macaddr(&pkt[10])); 176 printf(" 802.11MAC: BSSID = %s\n", macaddr(&pkt[16])); 177 break; 178 case 0x1: // To DS 179 printf(" 802.11MAC: DA = %s\n", macaddr(&pkt[16])); 180 printf(" 802.11MAC: SA = %s\n", macaddr(&pkt[10])); 181 printf(" 802.11MAC: BSSID = %s\n", macaddr(&pkt[4])); 182 break; 183 case 0x2: // From DS 184 printf(" 802.11MAC: DA = %s\n", macaddr(&pkt[4])); 185 printf(" 802.11MAC: SA = %s\n", macaddr(&pkt[16])); 186 printf(" 802.11MAC: BSSID = %s\n", macaddr(&pkt[10])); 187 break; 188 case 0x3: // To DS + From DS 189 printf(" 802.11MAC: DA = %s\n", macaddr(&pkt[16])); 190 printf(" 802.11MAC: SA = %s\n", macaddr(&pkt[24])); 191 printf(" 802.11MAC: TA = %s\n", macaddr(&pkt[10])); 192 printf(" 802.11MAC: RA = %s\n", macaddr(&pkt[4])); 193 break; 194 } 195 } 196 break; 197 } 198 199 char *data; 200 int extra = 0; 201 uint16_t ethtype = 0; 202 if (is_wme) { 203 struct ieee_802_11_e_payload *pld = (struct ieee_802_11_e_payload *) ((char*)pkt + sizeof(struct ieee_802_11_header)); 204 205 printf(" 802.11e: QoS = 0x%04x\n", pld->qos); 206 207 ethtype = htons(pld->type); 208 data = (char *) pld->data; 209 extra = 2; 210 } else { 211 struct ieee_802_11_payload *pld = (struct ieee_802_11_payload *) ((char *)pkt + sizeof(struct ieee_802_11_header)); 212 ethtype = htons(pld->type); 213 data = (char *) pld->data; 214 } 215 216 printf(" 802.11MAC: Payload Type = %04x\n",ethtype); 217 decode_next(data,len-(sizeof(struct ieee_802_11_header))-extra,"eth",ethtype); 218 219 220 } 221 222 759 printf("BAD FRAME TYPE!\n"); 760 break; 761 } 762 763 } 764 765
Note: See TracChangeset
for help on using the changeset viewer.