1 /* 2 * Copyright (c) 2001 3 * Fortress Technologies, Inc. All rights reserved. 4 * Charlie Lenahan (clenahan@fortresstech.com) 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that: (1) source code distributions 8 * retain the above copyright notice and this paragraph in its entirety, (2) 9 * distributions including binary code include the above copyright notice and 10 * this paragraph in its entirety in the documentation or other materials 11 * provided with the distribution, and (3) all advertising materials mentioning 12 * features or use of this software display the following acknowledgement: 13 * ``This product includes software developed by the University of California, 14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 15 * the University nor the names of its contributors may be used to endorse 16 * or promote products derived from this software without specific prior 17 * written permission. 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 21 */ 22 23 /* \summary: IEEE 802.11 printer */ 24 25 #ifdef HAVE_CONFIG_H 26 #include <config.h> 27 #endif 28 29 #include "netdissect-stdinc.h" 30 31 #include <string.h> 32 33 #include "netdissect.h" 34 #include "addrtoname.h" 35 36 #include "extract.h" 37 38 #include "cpack.h" 39 40 41 /* Lengths of 802.11 header components. */ 42 #define IEEE802_11_FC_LEN 2 43 #define IEEE802_11_DUR_LEN 2 44 #define IEEE802_11_DA_LEN 6 45 #define IEEE802_11_SA_LEN 6 46 #define IEEE802_11_BSSID_LEN 6 47 #define IEEE802_11_RA_LEN 6 48 #define IEEE802_11_TA_LEN 6 49 #define IEEE802_11_ADDR1_LEN 6 50 #define IEEE802_11_SEQ_LEN 2 51 #define IEEE802_11_CTL_LEN 2 52 #define IEEE802_11_CARRIED_FC_LEN 2 53 #define IEEE802_11_HT_CONTROL_LEN 4 54 #define IEEE802_11_IV_LEN 3 55 #define IEEE802_11_KID_LEN 1 56 57 /* Frame check sequence length. */ 58 #define IEEE802_11_FCS_LEN 4 59 60 /* Lengths of beacon components. */ 61 #define IEEE802_11_TSTAMP_LEN 8 62 #define IEEE802_11_BCNINT_LEN 2 63 #define IEEE802_11_CAPINFO_LEN 2 64 #define IEEE802_11_LISTENINT_LEN 2 65 66 #define IEEE802_11_AID_LEN 2 67 #define IEEE802_11_STATUS_LEN 2 68 #define IEEE802_11_REASON_LEN 2 69 70 /* Length of previous AP in reassocation frame */ 71 #define IEEE802_11_AP_LEN 6 72 73 #define T_MGMT 0x0 /* management */ 74 #define T_CTRL 0x1 /* control */ 75 #define T_DATA 0x2 /* data */ 76 #define T_RESV 0x3 /* reserved */ 77 78 #define ST_ASSOC_REQUEST 0x0 79 #define ST_ASSOC_RESPONSE 0x1 80 #define ST_REASSOC_REQUEST 0x2 81 #define ST_REASSOC_RESPONSE 0x3 82 #define ST_PROBE_REQUEST 0x4 83 #define ST_PROBE_RESPONSE 0x5 84 /* RESERVED 0x6 */ 85 /* RESERVED 0x7 */ 86 #define ST_BEACON 0x8 87 #define ST_ATIM 0x9 88 #define ST_DISASSOC 0xA 89 #define ST_AUTH 0xB 90 #define ST_DEAUTH 0xC 91 #define ST_ACTION 0xD 92 /* RESERVED 0xE */ 93 /* RESERVED 0xF */ 94 95 static const struct tok st_str[] = { 96 { ST_ASSOC_REQUEST, "Assoc Request" }, 97 { ST_ASSOC_RESPONSE, "Assoc Response" }, 98 { ST_REASSOC_REQUEST, "ReAssoc Request" }, 99 { ST_REASSOC_RESPONSE, "ReAssoc Response" }, 100 { ST_PROBE_REQUEST, "Probe Request" }, 101 { ST_PROBE_RESPONSE, "Probe Response" }, 102 { ST_BEACON, "Beacon" }, 103 { ST_ATIM, "ATIM" }, 104 { ST_DISASSOC, "Disassociation" }, 105 { ST_AUTH, "Authentication" }, 106 { ST_DEAUTH, "DeAuthentication" }, 107 { ST_ACTION, "Action" }, 108 { 0, NULL } 109 }; 110 111 #define CTRL_CONTROL_WRAPPER 0x7 112 #define CTRL_BAR 0x8 113 #define CTRL_BA 0x9 114 #define CTRL_PS_POLL 0xA 115 #define CTRL_RTS 0xB 116 #define CTRL_CTS 0xC 117 #define CTRL_ACK 0xD 118 #define CTRL_CF_END 0xE 119 #define CTRL_END_ACK 0xF 120 121 static const struct tok ctrl_str[] = { 122 { CTRL_CONTROL_WRAPPER, "Control Wrapper" }, 123 { CTRL_BAR, "BAR" }, 124 { CTRL_BA, "BA" }, 125 { CTRL_PS_POLL, "Power Save-Poll" }, 126 { CTRL_RTS, "Request-To-Send" }, 127 { CTRL_CTS, "Clear-To-Send" }, 128 { CTRL_ACK, "Acknowledgment" }, 129 { CTRL_CF_END, "CF-End" }, 130 { CTRL_END_ACK, "CF-End+CF-Ack" }, 131 { 0, NULL } 132 }; 133 134 #define DATA_DATA 0x0 135 #define DATA_DATA_CF_ACK 0x1 136 #define DATA_DATA_CF_POLL 0x2 137 #define DATA_DATA_CF_ACK_POLL 0x3 138 #define DATA_NODATA 0x4 139 #define DATA_NODATA_CF_ACK 0x5 140 #define DATA_NODATA_CF_POLL 0x6 141 #define DATA_NODATA_CF_ACK_POLL 0x7 142 143 #define DATA_QOS_DATA 0x8 144 #define DATA_QOS_DATA_CF_ACK 0x9 145 #define DATA_QOS_DATA_CF_POLL 0xA 146 #define DATA_QOS_DATA_CF_ACK_POLL 0xB 147 #define DATA_QOS_NODATA 0xC 148 #define DATA_QOS_CF_POLL_NODATA 0xE 149 #define DATA_QOS_CF_ACK_POLL_NODATA 0xF 150 151 /* 152 * The subtype field of a data frame is, in effect, composed of 4 flag 153 * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have 154 * any data), and QoS. 155 */ 156 #define DATA_FRAME_IS_CF_ACK(x) ((x) & 0x01) 157 #define DATA_FRAME_IS_CF_POLL(x) ((x) & 0x02) 158 #define DATA_FRAME_IS_NULL(x) ((x) & 0x04) 159 #define DATA_FRAME_IS_QOS(x) ((x) & 0x08) 160 161 /* 162 * Bits in the frame control field. 163 */ 164 #define FC_VERSION(fc) ((fc) & 0x3) 165 #define FC_TYPE(fc) (((fc) >> 2) & 0x3) 166 #define FC_SUBTYPE(fc) (((fc) >> 4) & 0xF) 167 #define FC_TO_DS(fc) ((fc) & 0x0100) 168 #define FC_FROM_DS(fc) ((fc) & 0x0200) 169 #define FC_MORE_FLAG(fc) ((fc) & 0x0400) 170 #define FC_RETRY(fc) ((fc) & 0x0800) 171 #define FC_POWER_MGMT(fc) ((fc) & 0x1000) 172 #define FC_MORE_DATA(fc) ((fc) & 0x2000) 173 #define FC_PROTECTED(fc) ((fc) & 0x4000) 174 #define FC_ORDER(fc) ((fc) & 0x8000) 175 176 struct mgmt_header_t { 177 nd_uint16_t fc; 178 nd_uint16_t duration; 179 nd_mac_addr da; 180 nd_mac_addr sa; 181 nd_mac_addr bssid; 182 nd_uint16_t seq_ctrl; 183 }; 184 185 #define MGMT_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ 186 IEEE802_11_DA_LEN+IEEE802_11_SA_LEN+\ 187 IEEE802_11_BSSID_LEN+IEEE802_11_SEQ_LEN) 188 189 #define CAPABILITY_ESS(cap) ((cap) & 0x0001) 190 #define CAPABILITY_IBSS(cap) ((cap) & 0x0002) 191 #define CAPABILITY_CFP(cap) ((cap) & 0x0004) 192 #define CAPABILITY_CFP_REQ(cap) ((cap) & 0x0008) 193 #define CAPABILITY_PRIVACY(cap) ((cap) & 0x0010) 194 195 struct ssid_t { 196 uint8_t element_id; 197 uint8_t length; 198 u_char ssid[33]; /* 32 + 1 for null */ 199 }; 200 201 struct rates_t { 202 uint8_t element_id; 203 uint8_t length; 204 uint8_t rate[16]; 205 }; 206 207 struct challenge_t { 208 uint8_t element_id; 209 uint8_t length; 210 uint8_t text[254]; /* 1-253 + 1 for null */ 211 }; 212 213 struct fh_t { 214 uint8_t element_id; 215 uint8_t length; 216 uint16_t dwell_time; 217 uint8_t hop_set; 218 uint8_t hop_pattern; 219 uint8_t hop_index; 220 }; 221 222 struct ds_t { 223 uint8_t element_id; 224 uint8_t length; 225 uint8_t channel; 226 }; 227 228 struct cf_t { 229 uint8_t element_id; 230 uint8_t length; 231 uint8_t count; 232 uint8_t period; 233 uint16_t max_duration; 234 uint16_t dur_remaining; 235 }; 236 237 struct tim_t { 238 uint8_t element_id; 239 uint8_t length; 240 uint8_t count; 241 uint8_t period; 242 uint8_t bitmap_control; 243 uint8_t bitmap[251]; 244 }; 245 246 #define E_SSID 0 247 #define E_RATES 1 248 #define E_FH 2 249 #define E_DS 3 250 #define E_CF 4 251 #define E_TIM 5 252 #define E_IBSS 6 253 /* reserved 7 */ 254 /* reserved 8 */ 255 /* reserved 9 */ 256 /* reserved 10 */ 257 /* reserved 11 */ 258 /* reserved 12 */ 259 /* reserved 13 */ 260 /* reserved 14 */ 261 /* reserved 15 */ 262 /* reserved 16 */ 263 264 #define E_CHALLENGE 16 265 /* reserved 17 */ 266 /* reserved 18 */ 267 /* reserved 19 */ 268 /* reserved 16 */ 269 /* reserved 16 */ 270 271 272 struct mgmt_body_t { 273 uint8_t timestamp[IEEE802_11_TSTAMP_LEN]; 274 uint16_t beacon_interval; 275 uint16_t listen_interval; 276 uint16_t status_code; 277 uint16_t aid; 278 u_char ap[IEEE802_11_AP_LEN]; 279 uint16_t reason_code; 280 uint16_t auth_alg; 281 uint16_t auth_trans_seq_num; 282 int challenge_present; 283 struct challenge_t challenge; 284 uint16_t capability_info; 285 int ssid_present; 286 struct ssid_t ssid; 287 int rates_present; 288 struct rates_t rates; 289 int ds_present; 290 struct ds_t ds; 291 int cf_present; 292 struct cf_t cf; 293 int fh_present; 294 struct fh_t fh; 295 int tim_present; 296 struct tim_t tim; 297 }; 298 299 struct ctrl_control_wrapper_hdr_t { 300 nd_uint16_t fc; 301 nd_uint16_t duration; 302 nd_mac_addr addr1; 303 nd_uint16_t carried_fc[IEEE802_11_CARRIED_FC_LEN]; 304 nd_uint16_t ht_control[IEEE802_11_HT_CONTROL_LEN]; 305 }; 306 307 #define CTRL_CONTROL_WRAPPER_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ 308 IEEE802_11_ADDR1_LEN+\ 309 IEEE802_11_CARRIED_FC_LEN+\ 310 IEEE802_11_HT_CONTROL_LEN) 311 312 struct ctrl_rts_hdr_t { 313 nd_uint16_t fc; 314 nd_uint16_t duration; 315 nd_mac_addr ra; 316 nd_mac_addr ta; 317 }; 318 319 #define CTRL_RTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ 320 IEEE802_11_RA_LEN+IEEE802_11_TA_LEN) 321 322 struct ctrl_cts_hdr_t { 323 nd_uint16_t fc; 324 nd_uint16_t duration; 325 nd_mac_addr ra; 326 }; 327 328 #define CTRL_CTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) 329 330 struct ctrl_ack_hdr_t { 331 nd_uint16_t fc; 332 nd_uint16_t duration; 333 nd_mac_addr ra; 334 }; 335 336 #define CTRL_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) 337 338 struct ctrl_ps_poll_hdr_t { 339 nd_uint16_t fc; 340 nd_uint16_t aid; 341 nd_mac_addr bssid; 342 nd_mac_addr ta; 343 }; 344 345 #define CTRL_PS_POLL_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_AID_LEN+\ 346 IEEE802_11_BSSID_LEN+IEEE802_11_TA_LEN) 347 348 struct ctrl_end_hdr_t { 349 nd_uint16_t fc; 350 nd_uint16_t duration; 351 nd_mac_addr ra; 352 nd_mac_addr bssid; 353 }; 354 355 #define CTRL_END_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ 356 IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN) 357 358 struct ctrl_end_ack_hdr_t { 359 nd_uint16_t fc; 360 nd_uint16_t duration; 361 nd_mac_addr ra; 362 nd_mac_addr bssid; 363 }; 364 365 #define CTRL_END_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ 366 IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN) 367 368 struct ctrl_ba_hdr_t { 369 nd_uint16_t fc; 370 nd_uint16_t duration; 371 nd_mac_addr ra; 372 }; 373 374 #define CTRL_BA_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN) 375 376 struct ctrl_bar_hdr_t { 377 nd_uint16_t fc; 378 nd_uint16_t dur; 379 nd_mac_addr ra; 380 nd_mac_addr ta; 381 nd_uint16_t ctl; 382 nd_uint16_t seq; 383 }; 384 385 #define CTRL_BAR_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\ 386 IEEE802_11_RA_LEN+IEEE802_11_TA_LEN+\ 387 IEEE802_11_CTL_LEN+IEEE802_11_SEQ_LEN) 388 389 struct meshcntl_t { 390 nd_uint8_t flags; 391 nd_uint8_t ttl; 392 nd_uint32_t seq; 393 nd_mac_addr addr4; 394 nd_mac_addr addr5; 395 nd_mac_addr addr6; 396 }; 397 398 #define IV_IV(iv) ((iv) & 0xFFFFFF) 399 #define IV_PAD(iv) (((iv) >> 24) & 0x3F) 400 #define IV_KEYID(iv) (((iv) >> 30) & 0x03) 401 402 #define PRINT_SSID(p) \ 403 if (p.ssid_present) { \ 404 ND_PRINT(" ("); \ 405 fn_print_str(ndo, p.ssid.ssid); \ 406 ND_PRINT(")"); \ 407 } 408 409 #define PRINT_RATE(_sep, _r, _suf) \ 410 ND_PRINT("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf) 411 #define PRINT_RATES(p) \ 412 if (p.rates_present) { \ 413 int z; \ 414 const char *sep = " ["; \ 415 for (z = 0; z < p.rates.length ; z++) { \ 416 PRINT_RATE(sep, p.rates.rate[z], \ 417 (p.rates.rate[z] & 0x80 ? "*" : "")); \ 418 sep = " "; \ 419 } \ 420 if (p.rates.length != 0) \ 421 ND_PRINT(" Mbit]"); \ 422 } 423 424 #define PRINT_DS_CHANNEL(p) \ 425 if (p.ds_present) \ 426 ND_PRINT(" CH: %u", p.ds.channel); \ 427 ND_PRINT("%s", \ 428 CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : ""); 429 430 #define MAX_MCS_INDEX 76 431 432 /* 433 * Indices are: 434 * 435 * the MCS index (0-76); 436 * 437 * 0 for 20 MHz, 1 for 40 MHz; 438 * 439 * 0 for a long guard interval, 1 for a short guard interval. 440 */ 441 static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = { 442 /* MCS 0 */ 443 { /* 20 Mhz */ { 6.5f, /* SGI */ 7.2f, }, 444 /* 40 Mhz */ { 13.5f, /* SGI */ 15.0f, }, 445 }, 446 447 /* MCS 1 */ 448 { /* 20 Mhz */ { 13.0f, /* SGI */ 14.4f, }, 449 /* 40 Mhz */ { 27.0f, /* SGI */ 30.0f, }, 450 }, 451 452 /* MCS 2 */ 453 { /* 20 Mhz */ { 19.5f, /* SGI */ 21.7f, }, 454 /* 40 Mhz */ { 40.5f, /* SGI */ 45.0f, }, 455 }, 456 457 /* MCS 3 */ 458 { /* 20 Mhz */ { 26.0f, /* SGI */ 28.9f, }, 459 /* 40 Mhz */ { 54.0f, /* SGI */ 60.0f, }, 460 }, 461 462 /* MCS 4 */ 463 { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, }, 464 /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, }, 465 }, 466 467 /* MCS 5 */ 468 { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, }, 469 /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, }, 470 }, 471 472 /* MCS 6 */ 473 { /* 20 Mhz */ { 58.5f, /* SGI */ 65.0f, }, 474 /* 40 Mhz */ { 121.5f, /* SGI */ 135.0f, }, 475 }, 476 477 /* MCS 7 */ 478 { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, }, 479 /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, }, 480 }, 481 482 /* MCS 8 */ 483 { /* 20 Mhz */ { 13.0f, /* SGI */ 14.4f, }, 484 /* 40 Mhz */ { 27.0f, /* SGI */ 30.0f, }, 485 }, 486 487 /* MCS 9 */ 488 { /* 20 Mhz */ { 26.0f, /* SGI */ 28.9f, }, 489 /* 40 Mhz */ { 54.0f, /* SGI */ 60.0f, }, 490 }, 491 492 /* MCS 10 */ 493 { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, }, 494 /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, }, 495 }, 496 497 /* MCS 11 */ 498 { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, }, 499 /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, }, 500 }, 501 502 /* MCS 12 */ 503 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, 504 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, 505 }, 506 507 /* MCS 13 */ 508 { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, }, 509 /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, }, 510 }, 511 512 /* MCS 14 */ 513 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, 514 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, 515 }, 516 517 /* MCS 15 */ 518 { /* 20 Mhz */ { 130.0f, /* SGI */ 144.4f, }, 519 /* 40 Mhz */ { 270.0f, /* SGI */ 300.0f, }, 520 }, 521 522 /* MCS 16 */ 523 { /* 20 Mhz */ { 19.5f, /* SGI */ 21.7f, }, 524 /* 40 Mhz */ { 40.5f, /* SGI */ 45.0f, }, 525 }, 526 527 /* MCS 17 */ 528 { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, }, 529 /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, }, 530 }, 531 532 /* MCS 18 */ 533 { /* 20 Mhz */ { 58.5f, /* SGI */ 65.0f, }, 534 /* 40 Mhz */ { 121.5f, /* SGI */ 135.0f, }, 535 }, 536 537 /* MCS 19 */ 538 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, 539 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, 540 }, 541 542 /* MCS 20 */ 543 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, 544 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, 545 }, 546 547 /* MCS 21 */ 548 { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, }, 549 /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, }, 550 }, 551 552 /* MCS 22 */ 553 { /* 20 Mhz */ { 175.5f, /* SGI */ 195.0f, }, 554 /* 40 Mhz */ { 364.5f, /* SGI */ 405.0f, }, 555 }, 556 557 /* MCS 23 */ 558 { /* 20 Mhz */ { 195.0f, /* SGI */ 216.7f, }, 559 /* 40 Mhz */ { 405.0f, /* SGI */ 450.0f, }, 560 }, 561 562 /* MCS 24 */ 563 { /* 20 Mhz */ { 26.0f, /* SGI */ 28.9f, }, 564 /* 40 Mhz */ { 54.0f, /* SGI */ 60.0f, }, 565 }, 566 567 /* MCS 25 */ 568 { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, }, 569 /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, }, 570 }, 571 572 /* MCS 26 */ 573 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, 574 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, 575 }, 576 577 /* MCS 27 */ 578 { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, }, 579 /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, }, 580 }, 581 582 /* MCS 28 */ 583 { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, }, 584 /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, }, 585 }, 586 587 /* MCS 29 */ 588 { /* 20 Mhz */ { 208.0f, /* SGI */ 231.1f, }, 589 /* 40 Mhz */ { 432.0f, /* SGI */ 480.0f, }, 590 }, 591 592 /* MCS 30 */ 593 { /* 20 Mhz */ { 234.0f, /* SGI */ 260.0f, }, 594 /* 40 Mhz */ { 486.0f, /* SGI */ 540.0f, }, 595 }, 596 597 /* MCS 31 */ 598 { /* 20 Mhz */ { 260.0f, /* SGI */ 288.9f, }, 599 /* 40 Mhz */ { 540.0f, /* SGI */ 600.0f, }, 600 }, 601 602 /* MCS 32 */ 603 { /* 20 Mhz */ { 0.0f, /* SGI */ 0.0f, }, /* not valid */ 604 /* 40 Mhz */ { 6.0f, /* SGI */ 6.7f, }, 605 }, 606 607 /* MCS 33 */ 608 { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, }, 609 /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, }, 610 }, 611 612 /* MCS 34 */ 613 { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, }, 614 /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, }, 615 }, 616 617 /* MCS 35 */ 618 { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, }, 619 /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, }, 620 }, 621 622 /* MCS 36 */ 623 { /* 20 Mhz */ { 58.5f, /* SGI */ 65.0f, }, 624 /* 40 Mhz */ { 121.5f, /* SGI */ 135.0f, }, 625 }, 626 627 /* MCS 37 */ 628 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, 629 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, 630 }, 631 632 /* MCS 38 */ 633 { /* 20 Mhz */ { 97.5f, /* SGI */ 108.3f, }, 634 /* 40 Mhz */ { 202.5f, /* SGI */ 225.0f, }, 635 }, 636 637 /* MCS 39 */ 638 { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, }, 639 /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, }, 640 }, 641 642 /* MCS 40 */ 643 { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, }, 644 /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, }, 645 }, 646 647 /* MCS 41 */ 648 { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, }, 649 /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, }, 650 }, 651 652 /* MCS 42 */ 653 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, 654 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, 655 }, 656 657 /* MCS 43 */ 658 { /* 20 Mhz */ { 91.0f, /* SGI */ 101.1f, }, 659 /* 40 Mhz */ { 189.0f, /* SGI */ 210.0f, }, 660 }, 661 662 /* MCS 44 */ 663 { /* 20 Mhz */ { 91.0f, /* SGI */ 101.1f, }, 664 /* 40 Mhz */ { 189.0f, /* SGI */ 210.0f, }, 665 }, 666 667 /* MCS 45 */ 668 { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, }, 669 /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, }, 670 }, 671 672 /* MCS 46 */ 673 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, 674 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, 675 }, 676 677 /* MCS 47 */ 678 { /* 20 Mhz */ { 97.5f, /* SGI */ 108.3f, }, 679 /* 40 Mhz */ { 202.5f, /* SGI */ 225.0f, }, 680 }, 681 682 /* MCS 48 */ 683 { /* 20 Mhz */ { 97.5f, /* SGI */ 108.3f, }, 684 /* 40 Mhz */ { 202.5f, /* SGI */ 225.0f, }, 685 }, 686 687 /* MCS 49 */ 688 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, 689 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, 690 }, 691 692 /* MCS 50 */ 693 { /* 20 Mhz */ { 136.5f, /* SGI */ 151.7f, }, 694 /* 40 Mhz */ { 283.5f, /* SGI */ 315.0f, }, 695 }, 696 697 /* MCS 51 */ 698 { /* 20 Mhz */ { 136.5f, /* SGI */ 151.7f, }, 699 /* 40 Mhz */ { 283.5f, /* SGI */ 315.0f, }, 700 }, 701 702 /* MCS 52 */ 703 { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, }, 704 /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, }, 705 }, 706 707 /* MCS 53 */ 708 { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, }, 709 /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, }, 710 }, 711 712 /* MCS 54 */ 713 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, 714 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, 715 }, 716 717 /* MCS 55 */ 718 { /* 20 Mhz */ { 91.0f, /* SGI */ 101.1f, }, 719 /* 40 Mhz */ { 189.0f, /* SGI */ 210.0f, }, 720 }, 721 722 /* MCS 56 */ 723 { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, }, 724 /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, }, 725 }, 726 727 /* MCS 57 */ 728 { /* 20 Mhz */ { 91.0f, /* SGI */ 101.1f, }, 729 /* 40 Mhz */ { 189.0f, /* SGI */ 210.0f, }, 730 }, 731 732 /* MCS 58 */ 733 { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, }, 734 /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, }, 735 }, 736 737 /* MCS 59 */ 738 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, 739 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, 740 }, 741 742 /* MCS 60 */ 743 { /* 20 Mhz */ { 104.0f, /* SGI */ 115.6f, }, 744 /* 40 Mhz */ { 216.0f, /* SGI */ 240.0f, }, 745 }, 746 747 /* MCS 61 */ 748 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, 749 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, 750 }, 751 752 /* MCS 62 */ 753 { /* 20 Mhz */ { 130.0f, /* SGI */ 144.4f, }, 754 /* 40 Mhz */ { 270.0f, /* SGI */ 300.0f, }, 755 }, 756 757 /* MCS 63 */ 758 { /* 20 Mhz */ { 130.0f, /* SGI */ 144.4f, }, 759 /* 40 Mhz */ { 270.0f, /* SGI */ 300.0f, }, 760 }, 761 762 /* MCS 64 */ 763 { /* 20 Mhz */ { 143.0f, /* SGI */ 158.9f, }, 764 /* 40 Mhz */ { 297.0f, /* SGI */ 330.0f, }, 765 }, 766 767 /* MCS 65 */ 768 { /* 20 Mhz */ { 97.5f, /* SGI */ 108.3f, }, 769 /* 40 Mhz */ { 202.5f, /* SGI */ 225.0f, }, 770 }, 771 772 /* MCS 66 */ 773 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, 774 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, 775 }, 776 777 /* MCS 67 */ 778 { /* 20 Mhz */ { 136.5f, /* SGI */ 151.7f, }, 779 /* 40 Mhz */ { 283.5f, /* SGI */ 315.0f, }, 780 }, 781 782 /* MCS 68 */ 783 { /* 20 Mhz */ { 117.0f, /* SGI */ 130.0f, }, 784 /* 40 Mhz */ { 243.0f, /* SGI */ 270.0f, }, 785 }, 786 787 /* MCS 69 */ 788 { /* 20 Mhz */ { 136.5f, /* SGI */ 151.7f, }, 789 /* 40 Mhz */ { 283.5f, /* SGI */ 315.0f, }, 790 }, 791 792 /* MCS 70 */ 793 { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, }, 794 /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, }, 795 }, 796 797 /* MCS 71 */ 798 { /* 20 Mhz */ { 175.5f, /* SGI */ 195.0f, }, 799 /* 40 Mhz */ { 364.5f, /* SGI */ 405.0f, }, 800 }, 801 802 /* MCS 72 */ 803 { /* 20 Mhz */ { 156.0f, /* SGI */ 173.3f, }, 804 /* 40 Mhz */ { 324.0f, /* SGI */ 360.0f, }, 805 }, 806 807 /* MCS 73 */ 808 { /* 20 Mhz */ { 175.5f, /* SGI */ 195.0f, }, 809 /* 40 Mhz */ { 364.5f, /* SGI */ 405.0f, }, 810 }, 811 812 /* MCS 74 */ 813 { /* 20 Mhz */ { 195.0f, /* SGI */ 216.7f, }, 814 /* 40 Mhz */ { 405.0f, /* SGI */ 450.0f, }, 815 }, 816 817 /* MCS 75 */ 818 { /* 20 Mhz */ { 195.0f, /* SGI */ 216.7f, }, 819 /* 40 Mhz */ { 405.0f, /* SGI */ 450.0f, }, 820 }, 821 822 /* MCS 76 */ 823 { /* 20 Mhz */ { 214.5f, /* SGI */ 238.3f, }, 824 /* 40 Mhz */ { 445.5f, /* SGI */ 495.0f, }, 825 }, 826 }; 827 828 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"}; 829 #define NUM_AUTH_ALGS (sizeof(auth_alg_text) / sizeof(auth_alg_text[0])) 830 831 static const char *status_text[] = { 832 "Successful", /* 0 */ 833 "Unspecified failure", /* 1 */ 834 "TDLS wakeup schedule rejected but alternative schedule " 835 "provided", /* 2 */ 836 "TDLS wakeup schedule rejected",/* 3 */ 837 "Reserved", /* 4 */ 838 "Security disabled", /* 5 */ 839 "Unacceptable lifetime", /* 6 */ 840 "Not in same BSS", /* 7 */ 841 "Reserved", /* 8 */ 842 "Reserved", /* 9 */ 843 "Cannot Support all requested capabilities in the Capability " 844 "Information field", /* 10 */ 845 "Reassociation denied due to inability to confirm that association " 846 "exists", /* 11 */ 847 "Association denied due to reason outside the scope of this " 848 "standard", /* 12 */ 849 "Responding STA does not support the specified authentication " 850 "algorithm", /* 13 */ 851 "Received an Authentication frame with authentication transaction " 852 "sequence number out of expected sequence", /* 14 */ 853 "Authentication rejected because of challenge failure", /* 15 */ 854 "Authentication rejected due to timeout waiting for next frame in " 855 "sequence", /* 16 */ 856 "Association denied because AP is unable to handle " 857 "additional associated STAs", /* 17 */ 858 "Association denied due to requesting STA not supporting " 859 "all of the data rates in the BSSBasicRateSet parameter, " 860 "the Basic HT-MCS Set field of the HT Operation " 861 "parameter, or the Basic VHT-MCS and NSS Set field in " 862 "the VHT Operation parameter", /* 18 */ 863 "Association denied due to requesting STA not supporting " 864 "the short preamble option", /* 19 */ 865 "Reserved", /* 20 */ 866 "Reserved", /* 21 */ 867 "Association request rejected because Spectrum Management " 868 "capability is required", /* 22 */ 869 "Association request rejected because the information in the " 870 "Power Capability element is unacceptable", /* 23 */ 871 "Association request rejected because the information in the " 872 "Supported Channels element is unacceptable", /* 24 */ 873 "Association denied due to requesting STA not supporting " 874 "the Short Slot Time option", /* 25 */ 875 "Reserved", /* 26 */ 876 "Association denied because the requested STA does not support HT " 877 "features", /* 27 */ 878 "R0KH unreachable", /* 28 */ 879 "Association denied because the requesting STA does not " 880 "support the phased coexistence operation (PCO) " 881 "transition time required by the AP", /* 29 */ 882 "Association request rejected temporarily; try again " 883 "later", /* 30 */ 884 "Robust management frame policy violation", /* 31 */ 885 "Unspecified, QoS-related failure", /* 32 */ 886 "Association denied because QoS AP or PCP has " 887 "insufficient bandwidth to handle another QoS " 888 "STA", /* 33 */ 889 "Association denied due to excessive frame loss rates and/or " 890 "poor conditions on current operating channel", /* 34 */ 891 "Association (with QoS BSS) denied because the requesting STA " 892 "does not support the QoS facility", /* 35 */ 893 "Reserved", /* 36 */ 894 "The request has been declined", /* 37 */ 895 "The request has not been successful as one or more parameters " 896 "have invalid values", /* 38 */ 897 "The allocation or TS has not been created because the request " 898 "cannot be honored; however, a suggested TSPEC/DMG TSPEC is " 899 "provided so that the initiating STA can attempt to set " 900 "another allocation or TS with the suggested changes to the " 901 "TSPEC/DMG TSPEC", /* 39 */ 902 "Invalid element, i.e., an element defined in this standard " 903 "for which the content does not meet the specifications in " 904 "Clause 9", /* 40 */ 905 "Invalid group cipher", /* 41 */ 906 "Invalid pairwise cipher", /* 42 */ 907 "Invalid AKMP", /* 43 */ 908 "Unsupported RSNE version", /* 44 */ 909 "Invalid RSNE capabilities", /* 45 */ 910 "Cipher suite rejected because of security policy", /* 46 */ 911 "The TS or allocation has not been created; however, the " 912 "HC or PCP might be capable of creating a TS or " 913 "allocation, in response to a request, after the time " 914 "indicated in the TS Delay element", /* 47 */ 915 "Direct Link is not allowed in the BSS by policy", /* 48 */ 916 "The Destination STA is not present within this BSS", /* 49 */ 917 "The Destination STA is not a QoS STA", /* 50 */ 918 919 "Association denied because the listen interval is " 920 "too large", /* 51 */ 921 "Invalid FT Action frame count", /* 52 */ 922 "Invalid pairwise master key identifier (PMKID)", /* 53 */ 923 "Invalid MDE", /* 54 */ 924 "Invalid FTE", /* 55 */ 925 "Requested TCLAS processing is not supported by the AP " 926 "or PCP", /* 56 */ 927 "The AP or PCP has insufficient TCLAS processing " 928 "resources to satisfy the request", /* 57 */ 929 "The TS has not been created because the request " 930 "cannot be honored; however, the HC or PCP suggests " 931 "that the STA transition to a different BSS to set up " 932 "the TS", /* 58 */ 933 "GAS Advertisement Protocol not supported", /* 59 */ 934 "No outstanding GAS request", /* 60 */ 935 "GAS Response not received from the Advertisement " 936 "Server", /* 61 */ 937 "STA timed out waiting for GAS Query Response", /* 62 */ 938 "LARGE GAS Response is larger than query response " 939 "length limit", /* 63 */ 940 "Request refused because home network does not support " 941 "request", /* 64 */ 942 "Advertisement Server in the network is not currently " 943 "reachable", /* 65 */ 944 "Reserved", /* 66 */ 945 "Request refused due to permissions received via SSPN " 946 "interface", /* 67 */ 947 "Request refused because the AP or PCP does not " 948 "support unauthenticated access", /* 68 */ 949 "Reserved", /* 69 */ 950 "Reserved", /* 70 */ 951 "Reserved", /* 71 */ 952 "Invalid contents of RSNE", /* 72 */ 953 "U-APSD coexistence is not supported", /* 73 */ 954 "Requested U-APSD coexistence mode is not supported", /* 74 */ 955 "Requested Interval/Duration value cannot be " 956 "supported with U-APSD coexistence", /* 75 */ 957 "Authentication is rejected because an Anti-Clogging " 958 "Token is required", /* 76 */ 959 "Authentication is rejected because the offered " 960 "finite cyclic group is not supported", /* 77 */ 961 "The TBTT adjustment request has not been successful " 962 "because the STA could not find an alternative TBTT", /* 78 */ 963 "Transmission failure", /* 79 */ 964 "Requested TCLAS Not Supported", /* 80 */ 965 "TCLAS Resources Exhausted", /* 81 */ 966 "Rejected with Suggested BSS transition", /* 82 */ 967 "Reject with recommended schedule", /* 83 */ 968 "Reject because no wakeup schedule specified", /* 84 */ 969 "Success, the destination STA is in power save mode", /* 85 */ 970 "FST pending, in process of admitting FST session", /* 86 */ 971 "Performing FST now", /* 87 */ 972 "FST pending, gap(s) in block ack window", /* 88 */ 973 "Reject because of U-PID setting", /* 89 */ 974 "Reserved", /* 90 */ 975 "Reserved", /* 91 */ 976 "(Re)Association refused for some external reason", /* 92 */ 977 "(Re)Association refused because of memory limits " 978 "at the AP", /* 93 */ 979 "(Re)Association refused because emergency services " 980 "are not supported at the AP", /* 94 */ 981 "GAS query response not yet received", /* 95 */ 982 "Reject since the request is for transition to a " 983 "frequency band subject to DSE procedures and " 984 "FST Initiator is a dependent STA", /* 96 */ 985 "Requested TCLAS processing has been terminated by " 986 "the AP", /* 97 */ 987 "The TS schedule conflicts with an existing " 988 "schedule; an alternative schedule is provided", /* 98 */ 989 "The association has been denied; however, one or " 990 "more Multi-band elements are included that can " 991 "be used by the receiving STA to join the BSS", /* 99 */ 992 "The request failed due to a reservation conflict", /* 100 */ 993 "The request failed due to exceeded MAF limit", /* 101 */ 994 "The request failed due to exceeded MCCA track " 995 "limit", /* 102 */ 996 "Association denied because the information in the" 997 "Spectrum Management field is unacceptable", /* 103 */ 998 "Association denied because the requesting STA " 999 "does not support VHT features", /* 104 */ 1000 "Enablement denied", /* 105 */ 1001 "Enablement denied due to restriction from an " 1002 "authorized GDB", /* 106 */ 1003 "Authorization deenabled", /* 107 */ 1004 }; 1005 #define NUM_STATUSES (sizeof(status_text) / sizeof(status_text[0])) 1006 1007 static const char *reason_text[] = { 1008 "Reserved", /* 0 */ 1009 "Unspecified reason", /* 1 */ 1010 "Previous authentication no longer valid", /* 2 */ 1011 "Deauthenticated because sending STA is leaving (or has left) " 1012 "IBSS or ESS", /* 3 */ 1013 "Disassociated due to inactivity", /* 4 */ 1014 "Disassociated because AP is unable to handle all currently " 1015 " associated STAs", /* 5 */ 1016 "Class 2 frame received from nonauthenticated STA", /* 6 */ 1017 "Class 3 frame received from nonassociated STA", /* 7 */ 1018 "Disassociated because sending STA is leaving " 1019 "(or has left) BSS", /* 8 */ 1020 "STA requesting (re)association is not authenticated with " 1021 "responding STA", /* 9 */ 1022 "Disassociated because the information in the Power Capability " 1023 "element is unacceptable", /* 10 */ 1024 "Disassociated because the information in the Supported Channels " 1025 "element is unacceptable", /* 11 */ 1026 "Disassociated due to BSS transition management", /* 12 */ 1027 "Invalid element, i.e., an element defined in this standard for " 1028 "which the content does not meet the specifications " 1029 "in Clause 9", /* 13 */ 1030 "Message integrity code (MIC) failure", /* 14 */ 1031 "4-Way Handshake timeout", /* 15 */ 1032 "Group key handshake timeout", /* 16 */ 1033 "Information element in 4-Way Handshake different from (Re)Association" 1034 "Request/Probe Response/Beacon frame", /* 17 */ 1035 "Invalid group cipher", /* 18 */ 1036 "Invalid pairwise cipher", /* 19 */ 1037 "Invalid AKMP", /* 20 */ 1038 "Unsupported RSNE version", /* 21 */ 1039 "Invalid RSNE capabilities", /* 22 */ 1040 "IEEE 802.1X authentication failed", /* 23 */ 1041 "Cipher suite rejected because of the security policy", /* 24 */ 1042 "TDLS direct-link teardown due to TDLS peer STA " 1043 "unreachable via the TDLS direct link", /* 25 */ 1044 "TDLS direct-link teardown for unspecified reason", /* 26 */ 1045 "Disassociated because session terminated by SSP request",/* 27 */ 1046 "Disassociated because of lack of SSP roaming agreement",/* 28 */ 1047 "Requested service rejected because of SSP cipher suite or " 1048 "AKM requirement", /* 29 */ 1049 "Requested service not authorized in this location", /* 30 */ 1050 "TS deleted because QoS AP lacks sufficient bandwidth for this " 1051 "QoS STA due to a change in BSS service characteristics or " 1052 "operational mode (e.g. an HT BSS change from 40 MHz channel " 1053 "to 20 MHz channel)", /* 31 */ 1054 "Disassociated for unspecified, QoS-related reason", /* 32 */ 1055 "Disassociated because QoS AP lacks sufficient bandwidth for this " 1056 "QoS STA", /* 33 */ 1057 "Disassociated because of excessive number of frames that need to be " 1058 "acknowledged, but are not acknowledged due to AP transmissions " 1059 "and/or poor channel conditions", /* 34 */ 1060 "Disassociated because STA is transmitting outside the limits " 1061 "of its TXOPs", /* 35 */ 1062 "Requested from peer STA as the STA is leaving the BSS " 1063 "(or resetting)", /* 36 */ 1064 "Requested from peer STA as it does not want to use the " 1065 "mechanism", /* 37 */ 1066 "Requested from peer STA as the STA received frames using the " 1067 "mechanism for which a set up is required", /* 38 */ 1068 "Requested from peer STA due to time out", /* 39 */ 1069 "Reserved", /* 40 */ 1070 "Reserved", /* 41 */ 1071 "Reserved", /* 42 */ 1072 "Reserved", /* 43 */ 1073 "Reserved", /* 44 */ 1074 "Peer STA does not support the requested cipher suite", /* 45 */ 1075 "In a DLS Teardown frame: The teardown was initiated by the " 1076 "DLS peer. In a Disassociation frame: Disassociated because " 1077 "authorized access limit reached", /* 46 */ 1078 "In a DLS Teardown frame: The teardown was initiated by the " 1079 "AP. In a Disassociation frame: Disassociated due to external " 1080 "service requirements", /* 47 */ 1081 "Invalid FT Action frame count", /* 48 */ 1082 "Invalid pairwise master key identifier (PMKID)", /* 49 */ 1083 "Invalid MDE", /* 50 */ 1084 "Invalid FTE", /* 51 */ 1085 "Mesh peering canceled for unknown reasons", /* 52 */ 1086 "The mesh STA has reached the supported maximum number of " 1087 "peer mesh STAs", /* 53 */ 1088 "The received information violates the Mesh Configuration " 1089 "policy configured in the mesh STA profile", /* 54 */ 1090 "The mesh STA has received a Mesh Peering Close frame " 1091 "requesting to close the mesh peering", /* 55 */ 1092 "The mesh STA has resent dot11MeshMaxRetries Mesh " 1093 "Peering Open frames, without receiving a Mesh Peering " 1094 "Confirm frame", /* 56 */ 1095 "The confirmTimer for the mesh peering instance times out", /* 57 */ 1096 "The mesh STA fails to unwrap the GTK or the values in the " 1097 "wrapped contents do not match", /* 58 */ 1098 "The mesh STA receives inconsistent information about the " 1099 "mesh parameters between mesh peering Management frames", /* 59 */ 1100 "The mesh STA fails the authenticated mesh peering exchange " 1101 "because due to failure in selecting either the pairwise " 1102 "ciphersuite or group ciphersuite", /* 60 */ 1103 "The mesh STA does not have proxy information for this " 1104 "external destination", /* 61 */ 1105 "The mesh STA does not have forwarding information for this " 1106 "destination", /* 62 */ 1107 "The mesh STA determines that the link to the next hop of an " 1108 "active path in its forwarding information is no longer " 1109 "usable", /* 63 */ 1110 "The Deauthentication frame was sent because the MAC " 1111 "address of the STA already exists in the mesh BSS", /* 64 */ 1112 "The mesh STA performs channel switch to meet regulatory " 1113 "requirements", /* 65 */ 1114 "The mesh STA performs channel switching with unspecified " 1115 "reason", /* 66 */ 1116 }; 1117 #define NUM_REASONS (sizeof(reason_text) / sizeof(reason_text[0])) 1118 1119 static int 1120 wep_print(netdissect_options *ndo, 1121 const u_char *p) 1122 { 1123 uint32_t iv; 1124 1125 ND_TCHECK_LEN(p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN); 1126 iv = GET_LE_U_4(p); 1127 1128 ND_PRINT(" IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv), 1129 IV_KEYID(iv)); 1130 1131 return 1; 1132 trunc: 1133 return 0; 1134 } 1135 1136 static int 1137 parse_elements(netdissect_options *ndo, 1138 struct mgmt_body_t *pbody, const u_char *p, int offset, 1139 u_int length) 1140 { 1141 u_int elementlen; 1142 struct ssid_t ssid; 1143 struct challenge_t challenge; 1144 struct rates_t rates; 1145 struct ds_t ds; 1146 struct cf_t cf; 1147 struct tim_t tim; 1148 1149 /* 1150 * We haven't seen any elements yet. 1151 */ 1152 pbody->challenge_present = 0; 1153 pbody->ssid_present = 0; 1154 pbody->rates_present = 0; 1155 pbody->ds_present = 0; 1156 pbody->cf_present = 0; 1157 pbody->tim_present = 0; 1158 1159 while (length != 0) { 1160 /* Make sure we at least have the element ID and length. */ 1161 ND_TCHECK_2(p + offset); 1162 if (length < 2) 1163 goto trunc; 1164 elementlen = GET_U_1(p + offset + 1); 1165 1166 /* Make sure we have the entire element. */ 1167 ND_TCHECK_LEN(p + offset + 2, elementlen); 1168 if (length < elementlen + 2) 1169 goto trunc; 1170 1171 switch (GET_U_1(p + offset)) { 1172 case E_SSID: 1173 memcpy(&ssid, p + offset, 2); 1174 offset += 2; 1175 length -= 2; 1176 if (ssid.length != 0) { 1177 if (ssid.length > sizeof(ssid.ssid) - 1) 1178 return 0; 1179 memcpy(&ssid.ssid, p + offset, ssid.length); 1180 offset += ssid.length; 1181 length -= ssid.length; 1182 } 1183 ssid.ssid[ssid.length] = '\0'; 1184 /* 1185 * Present and not truncated. 1186 * 1187 * If we haven't already seen an SSID IE, 1188 * copy this one, otherwise ignore this one, 1189 * so we later report the first one we saw. 1190 */ 1191 if (!pbody->ssid_present) { 1192 pbody->ssid = ssid; 1193 pbody->ssid_present = 1; 1194 } 1195 break; 1196 case E_CHALLENGE: 1197 memcpy(&challenge, p + offset, 2); 1198 offset += 2; 1199 length -= 2; 1200 if (challenge.length != 0) { 1201 if (challenge.length > 1202 sizeof(challenge.text) - 1) 1203 return 0; 1204 memcpy(&challenge.text, p + offset, 1205 challenge.length); 1206 offset += challenge.length; 1207 length -= challenge.length; 1208 } 1209 challenge.text[challenge.length] = '\0'; 1210 /* 1211 * Present and not truncated. 1212 * 1213 * If we haven't already seen a challenge IE, 1214 * copy this one, otherwise ignore this one, 1215 * so we later report the first one we saw. 1216 */ 1217 if (!pbody->challenge_present) { 1218 pbody->challenge = challenge; 1219 pbody->challenge_present = 1; 1220 } 1221 break; 1222 case E_RATES: 1223 memcpy(&rates, p + offset, 2); 1224 offset += 2; 1225 length -= 2; 1226 if (rates.length != 0) { 1227 if (rates.length > sizeof(rates.rate)) 1228 return 0; 1229 memcpy(&rates.rate, p + offset, rates.length); 1230 offset += rates.length; 1231 length -= rates.length; 1232 } 1233 /* 1234 * Present and not truncated. 1235 * 1236 * If we haven't already seen a rates IE, 1237 * copy this one if it's not zero-length, 1238 * otherwise ignore this one, so we later 1239 * report the first one we saw. 1240 * 1241 * We ignore zero-length rates IEs as some 1242 * devices seem to put a zero-length rates 1243 * IE, followed by an SSID IE, followed by 1244 * a non-zero-length rates IE into frames, 1245 * even though IEEE Std 802.11-2007 doesn't 1246 * seem to indicate that a zero-length rates 1247 * IE is valid. 1248 */ 1249 if (!pbody->rates_present && rates.length != 0) { 1250 pbody->rates = rates; 1251 pbody->rates_present = 1; 1252 } 1253 break; 1254 case E_DS: 1255 memcpy(&ds, p + offset, 2); 1256 offset += 2; 1257 length -= 2; 1258 if (ds.length != 1) { 1259 offset += ds.length; 1260 length -= ds.length; 1261 break; 1262 } 1263 ds.channel = GET_U_1(p + offset); 1264 offset += 1; 1265 length -= 1; 1266 /* 1267 * Present and not truncated. 1268 * 1269 * If we haven't already seen a DS IE, 1270 * copy this one, otherwise ignore this one, 1271 * so we later report the first one we saw. 1272 */ 1273 if (!pbody->ds_present) { 1274 pbody->ds = ds; 1275 pbody->ds_present = 1; 1276 } 1277 break; 1278 case E_CF: 1279 memcpy(&cf, p + offset, 2); 1280 offset += 2; 1281 length -= 2; 1282 if (cf.length != 6) { 1283 offset += cf.length; 1284 length -= cf.length; 1285 break; 1286 } 1287 cf.count = GET_U_1(p + offset); 1288 offset += 1; 1289 length -= 1; 1290 cf.period = GET_U_1(p + offset); 1291 offset += 1; 1292 length -= 1; 1293 cf.max_duration = GET_LE_U_2(p + offset); 1294 offset += 2; 1295 length -= 2; 1296 cf.dur_remaining = GET_LE_U_2(p + offset); 1297 offset += 2; 1298 length -= 2; 1299 /* 1300 * Present and not truncated. 1301 * 1302 * If we haven't already seen a CF IE, 1303 * copy this one, otherwise ignore this one, 1304 * so we later report the first one we saw. 1305 */ 1306 if (!pbody->cf_present) { 1307 pbody->cf = cf; 1308 pbody->cf_present = 1; 1309 } 1310 break; 1311 case E_TIM: 1312 memcpy(&tim, p + offset, 2); 1313 offset += 2; 1314 length -= 2; 1315 if (tim.length <= 3U) { 1316 offset += tim.length; 1317 length -= tim.length; 1318 break; 1319 } 1320 if (tim.length - 3U > sizeof(tim.bitmap)) 1321 return 0; 1322 tim.count = GET_U_1(p + offset); 1323 offset += 1; 1324 length -= 1; 1325 tim.period = GET_U_1(p + offset); 1326 offset += 1; 1327 length -= 1; 1328 tim.bitmap_control = GET_U_1(p + offset); 1329 offset += 1; 1330 length -= 1; 1331 memcpy(tim.bitmap, p + offset, tim.length - 3); 1332 offset += tim.length - 3; 1333 length -= tim.length - 3; 1334 /* 1335 * Present and not truncated. 1336 * 1337 * If we haven't already seen a TIM IE, 1338 * copy this one, otherwise ignore this one, 1339 * so we later report the first one we saw. 1340 */ 1341 if (!pbody->tim_present) { 1342 pbody->tim = tim; 1343 pbody->tim_present = 1; 1344 } 1345 break; 1346 default: 1347 #if 0 1348 ND_PRINT("(1) unhandled element_id (%u) ", 1349 GET_U_1(p + offset)); 1350 #endif 1351 offset += 2 + elementlen; 1352 length -= 2 + elementlen; 1353 break; 1354 } 1355 } 1356 1357 /* No problems found. */ 1358 return 1; 1359 trunc: 1360 return 0; 1361 } 1362 1363 /********************************************************************************* 1364 * Print Handle functions for the management frame types 1365 *********************************************************************************/ 1366 1367 static int 1368 handle_beacon(netdissect_options *ndo, 1369 const u_char *p, u_int length) 1370 { 1371 struct mgmt_body_t pbody; 1372 int offset = 0; 1373 int ret; 1374 1375 memset(&pbody, 0, sizeof(pbody)); 1376 1377 ND_TCHECK_LEN(p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + 1378 IEEE802_11_CAPINFO_LEN); 1379 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + 1380 IEEE802_11_CAPINFO_LEN) 1381 goto trunc; 1382 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN); 1383 offset += IEEE802_11_TSTAMP_LEN; 1384 length -= IEEE802_11_TSTAMP_LEN; 1385 pbody.beacon_interval = GET_LE_U_2(p + offset); 1386 offset += IEEE802_11_BCNINT_LEN; 1387 length -= IEEE802_11_BCNINT_LEN; 1388 pbody.capability_info = GET_LE_U_2(p + offset); 1389 offset += IEEE802_11_CAPINFO_LEN; 1390 length -= IEEE802_11_CAPINFO_LEN; 1391 1392 ret = parse_elements(ndo, &pbody, p, offset, length); 1393 1394 PRINT_SSID(pbody); 1395 PRINT_RATES(pbody); 1396 ND_PRINT(" %s", 1397 CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS"); 1398 PRINT_DS_CHANNEL(pbody); 1399 1400 return ret; 1401 trunc: 1402 return 0; 1403 } 1404 1405 static int 1406 handle_assoc_request(netdissect_options *ndo, 1407 const u_char *p, u_int length) 1408 { 1409 struct mgmt_body_t pbody; 1410 int offset = 0; 1411 int ret; 1412 1413 memset(&pbody, 0, sizeof(pbody)); 1414 1415 ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN); 1416 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN) 1417 goto trunc; 1418 pbody.capability_info = GET_LE_U_2(p); 1419 offset += IEEE802_11_CAPINFO_LEN; 1420 length -= IEEE802_11_CAPINFO_LEN; 1421 pbody.listen_interval = GET_LE_U_2(p + offset); 1422 offset += IEEE802_11_LISTENINT_LEN; 1423 length -= IEEE802_11_LISTENINT_LEN; 1424 1425 ret = parse_elements(ndo, &pbody, p, offset, length); 1426 1427 PRINT_SSID(pbody); 1428 PRINT_RATES(pbody); 1429 return ret; 1430 trunc: 1431 return 0; 1432 } 1433 1434 static int 1435 handle_assoc_response(netdissect_options *ndo, 1436 const u_char *p, u_int length) 1437 { 1438 struct mgmt_body_t pbody; 1439 int offset = 0; 1440 int ret; 1441 1442 memset(&pbody, 0, sizeof(pbody)); 1443 1444 ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN + 1445 IEEE802_11_AID_LEN); 1446 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN + 1447 IEEE802_11_AID_LEN) 1448 goto trunc; 1449 pbody.capability_info = GET_LE_U_2(p); 1450 offset += IEEE802_11_CAPINFO_LEN; 1451 length -= IEEE802_11_CAPINFO_LEN; 1452 pbody.status_code = GET_LE_U_2(p + offset); 1453 offset += IEEE802_11_STATUS_LEN; 1454 length -= IEEE802_11_STATUS_LEN; 1455 pbody.aid = GET_LE_U_2(p + offset); 1456 offset += IEEE802_11_AID_LEN; 1457 length -= IEEE802_11_AID_LEN; 1458 1459 ret = parse_elements(ndo, &pbody, p, offset, length); 1460 1461 ND_PRINT(" AID(%x) :%s: %s", ((uint16_t)(pbody.aid << 2 )) >> 2 , 1462 CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "", 1463 (pbody.status_code < NUM_STATUSES 1464 ? status_text[pbody.status_code] 1465 : "n/a")); 1466 1467 return ret; 1468 trunc: 1469 return 0; 1470 } 1471 1472 static int 1473 handle_reassoc_request(netdissect_options *ndo, 1474 const u_char *p, u_int length) 1475 { 1476 struct mgmt_body_t pbody; 1477 int offset = 0; 1478 int ret; 1479 1480 memset(&pbody, 0, sizeof(pbody)); 1481 1482 ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN + 1483 IEEE802_11_AP_LEN); 1484 if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN + 1485 IEEE802_11_AP_LEN) 1486 goto trunc; 1487 pbody.capability_info = GET_LE_U_2(p); 1488 offset += IEEE802_11_CAPINFO_LEN; 1489 length -= IEEE802_11_CAPINFO_LEN; 1490 pbody.listen_interval = GET_LE_U_2(p + offset); 1491 offset += IEEE802_11_LISTENINT_LEN; 1492 length -= IEEE802_11_LISTENINT_LEN; 1493 memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN); 1494 offset += IEEE802_11_AP_LEN; 1495 length -= IEEE802_11_AP_LEN; 1496 1497 ret = parse_elements(ndo, &pbody, p, offset, length); 1498 1499 PRINT_SSID(pbody); 1500 ND_PRINT(" AP : %s", etheraddr_string(ndo, pbody.ap )); 1501 1502 return ret; 1503 trunc: 1504 return 0; 1505 } 1506 1507 static int 1508 handle_reassoc_response(netdissect_options *ndo, 1509 const u_char *p, u_int length) 1510 { 1511 /* Same as a Association Response */ 1512 return handle_assoc_response(ndo, p, length); 1513 } 1514 1515 static int 1516 handle_probe_request(netdissect_options *ndo, 1517 const u_char *p, u_int length) 1518 { 1519 struct mgmt_body_t pbody; 1520 int offset = 0; 1521 int ret; 1522 1523 memset(&pbody, 0, sizeof(pbody)); 1524 1525 ret = parse_elements(ndo, &pbody, p, offset, length); 1526 1527 PRINT_SSID(pbody); 1528 PRINT_RATES(pbody); 1529 1530 return ret; 1531 } 1532 1533 static int 1534 handle_probe_response(netdissect_options *ndo, 1535 const u_char *p, u_int length) 1536 { 1537 struct mgmt_body_t pbody; 1538 int offset = 0; 1539 int ret; 1540 1541 memset(&pbody, 0, sizeof(pbody)); 1542 1543 ND_TCHECK_LEN(p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + 1544 IEEE802_11_CAPINFO_LEN); 1545 if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + 1546 IEEE802_11_CAPINFO_LEN) 1547 goto trunc; 1548 memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN); 1549 offset += IEEE802_11_TSTAMP_LEN; 1550 length -= IEEE802_11_TSTAMP_LEN; 1551 pbody.beacon_interval = GET_LE_U_2(p + offset); 1552 offset += IEEE802_11_BCNINT_LEN; 1553 length -= IEEE802_11_BCNINT_LEN; 1554 pbody.capability_info = GET_LE_U_2(p + offset); 1555 offset += IEEE802_11_CAPINFO_LEN; 1556 length -= IEEE802_11_CAPINFO_LEN; 1557 1558 ret = parse_elements(ndo, &pbody, p, offset, length); 1559 1560 PRINT_SSID(pbody); 1561 PRINT_RATES(pbody); 1562 PRINT_DS_CHANNEL(pbody); 1563 1564 return ret; 1565 trunc: 1566 return 0; 1567 } 1568 1569 static int 1570 handle_atim(void) 1571 { 1572 /* the frame body for ATIM is null. */ 1573 return 1; 1574 } 1575 1576 static int 1577 handle_disassoc(netdissect_options *ndo, 1578 const u_char *p, u_int length) 1579 { 1580 struct mgmt_body_t pbody; 1581 1582 memset(&pbody, 0, sizeof(pbody)); 1583 1584 ND_TCHECK_LEN(p, IEEE802_11_REASON_LEN); 1585 if (length < IEEE802_11_REASON_LEN) 1586 goto trunc; 1587 pbody.reason_code = GET_LE_U_2(p); 1588 1589 ND_PRINT(": %s", 1590 (pbody.reason_code < NUM_REASONS) 1591 ? reason_text[pbody.reason_code] 1592 : "Reserved"); 1593 1594 return 1; 1595 trunc: 1596 return 0; 1597 } 1598 1599 static int 1600 handle_auth(netdissect_options *ndo, 1601 const u_char *p, u_int length) 1602 { 1603 struct mgmt_body_t pbody; 1604 int offset = 0; 1605 int ret; 1606 1607 memset(&pbody, 0, sizeof(pbody)); 1608 1609 ND_TCHECK_6(p); 1610 if (length < 6) 1611 goto trunc; 1612 pbody.auth_alg = GET_LE_U_2(p); 1613 offset += 2; 1614 length -= 2; 1615 pbody.auth_trans_seq_num = GET_LE_U_2(p + offset); 1616 offset += 2; 1617 length -= 2; 1618 pbody.status_code = GET_LE_U_2(p + offset); 1619 offset += 2; 1620 length -= 2; 1621 1622 ret = parse_elements(ndo, &pbody, p, offset, length); 1623 1624 if ((pbody.auth_alg == 1) && 1625 ((pbody.auth_trans_seq_num == 2) || 1626 (pbody.auth_trans_seq_num == 3))) { 1627 ND_PRINT(" (%s)-%x [Challenge Text] %s", 1628 (pbody.auth_alg < NUM_AUTH_ALGS) 1629 ? auth_alg_text[pbody.auth_alg] 1630 : "Reserved", 1631 pbody.auth_trans_seq_num, 1632 ((pbody.auth_trans_seq_num % 2) 1633 ? ((pbody.status_code < NUM_STATUSES) 1634 ? status_text[pbody.status_code] 1635 : "n/a") : "")); 1636 return ret; 1637 } 1638 ND_PRINT(" (%s)-%x: %s", 1639 (pbody.auth_alg < NUM_AUTH_ALGS) 1640 ? auth_alg_text[pbody.auth_alg] 1641 : "Reserved", 1642 pbody.auth_trans_seq_num, 1643 (pbody.auth_trans_seq_num % 2) 1644 ? ((pbody.status_code < NUM_STATUSES) 1645 ? status_text[pbody.status_code] 1646 : "n/a") 1647 : ""); 1648 1649 return ret; 1650 trunc: 1651 return 0; 1652 } 1653 1654 static int 1655 handle_deauth(netdissect_options *ndo, 1656 const uint8_t *src, const u_char *p, u_int length) 1657 { 1658 struct mgmt_body_t pbody; 1659 const char *reason = NULL; 1660 1661 memset(&pbody, 0, sizeof(pbody)); 1662 1663 ND_TCHECK_LEN(p, IEEE802_11_REASON_LEN); 1664 if (length < IEEE802_11_REASON_LEN) 1665 goto trunc; 1666 pbody.reason_code = GET_LE_U_2(p); 1667 1668 reason = (pbody.reason_code < NUM_REASONS) 1669 ? reason_text[pbody.reason_code] 1670 : "Reserved"; 1671 1672 if (ndo->ndo_eflag) { 1673 ND_PRINT(": %s", reason); 1674 } else { 1675 ND_PRINT(" (%s): %s", GET_ETHERADDR_STRING(src), reason); 1676 } 1677 return 1; 1678 trunc: 1679 return 0; 1680 } 1681 1682 #define PRINT_HT_ACTION(v) (\ 1683 (v) == 0 ? ND_PRINT("TxChWidth"): \ 1684 (v) == 1 ? ND_PRINT("MIMOPwrSave"): \ 1685 ND_PRINT("Act#%u", (v))) 1686 #define PRINT_BA_ACTION(v) (\ 1687 (v) == 0 ? ND_PRINT("ADDBA Request"): \ 1688 (v) == 1 ? ND_PRINT("ADDBA Response"): \ 1689 (v) == 2 ? ND_PRINT("DELBA"): \ 1690 ND_PRINT("Act#%u", (v))) 1691 #define PRINT_MESHLINK_ACTION(v) (\ 1692 (v) == 0 ? ND_PRINT("Request"): \ 1693 (v) == 1 ? ND_PRINT("Report"): \ 1694 ND_PRINT("Act#%u", (v))) 1695 #define PRINT_MESHPEERING_ACTION(v) (\ 1696 (v) == 0 ? ND_PRINT("Open"): \ 1697 (v) == 1 ? ND_PRINT("Confirm"): \ 1698 (v) == 2 ? ND_PRINT("Close"): \ 1699 ND_PRINT("Act#%u", (v))) 1700 #define PRINT_MESHPATH_ACTION(v) (\ 1701 (v) == 0 ? ND_PRINT("Request"): \ 1702 (v) == 1 ? ND_PRINT("Report"): \ 1703 (v) == 2 ? ND_PRINT("Error"): \ 1704 (v) == 3 ? ND_PRINT("RootAnnouncement"): \ 1705 ND_PRINT("Act#%u", (v))) 1706 1707 #define PRINT_MESH_ACTION(v) (\ 1708 (v) == 0 ? ND_PRINT("MeshLink"): \ 1709 (v) == 1 ? ND_PRINT("HWMP"): \ 1710 (v) == 2 ? ND_PRINT("Gate Announcement"): \ 1711 (v) == 3 ? ND_PRINT("Congestion Control"): \ 1712 (v) == 4 ? ND_PRINT("MCCA Setup Request"): \ 1713 (v) == 5 ? ND_PRINT("MCCA Setup Reply"): \ 1714 (v) == 6 ? ND_PRINT("MCCA Advertisement Request"): \ 1715 (v) == 7 ? ND_PRINT("MCCA Advertisement"): \ 1716 (v) == 8 ? ND_PRINT("MCCA Teardown"): \ 1717 (v) == 9 ? ND_PRINT("TBTT Adjustment Request"): \ 1718 (v) == 10 ? ND_PRINT("TBTT Adjustment Response"): \ 1719 ND_PRINT("Act#%u", (v))) 1720 #define PRINT_MULTIHOP_ACTION(v) (\ 1721 (v) == 0 ? ND_PRINT("Proxy Update"): \ 1722 (v) == 1 ? ND_PRINT("Proxy Update Confirmation"): \ 1723 ND_PRINT("Act#%u", (v))) 1724 #define PRINT_SELFPROT_ACTION(v) (\ 1725 (v) == 1 ? ND_PRINT("Peering Open"): \ 1726 (v) == 2 ? ND_PRINT("Peering Confirm"): \ 1727 (v) == 3 ? ND_PRINT("Peering Close"): \ 1728 (v) == 4 ? ND_PRINT("Group Key Inform"): \ 1729 (v) == 5 ? ND_PRINT("Group Key Acknowledge"): \ 1730 ND_PRINT("Act#%u", (v))) 1731 1732 static int 1733 handle_action(netdissect_options *ndo, 1734 const uint8_t *src, const u_char *p, u_int length) 1735 { 1736 ND_TCHECK_2(p); 1737 if (length < 2) 1738 goto trunc; 1739 if (ndo->ndo_eflag) { 1740 ND_PRINT(": "); 1741 } else { 1742 ND_PRINT(" (%s): ", GET_ETHERADDR_STRING(src)); 1743 } 1744 switch (GET_U_1(p)) { 1745 case 0: ND_PRINT("Spectrum Management Act#%u", GET_U_1(p + 1)); break; 1746 case 1: ND_PRINT("QoS Act#%u", GET_U_1(p + 1)); break; 1747 case 2: ND_PRINT("DLS Act#%u", GET_U_1(p + 1)); break; 1748 case 3: ND_PRINT("BA "); PRINT_BA_ACTION(GET_U_1(p + 1)); break; 1749 case 7: ND_PRINT("HT "); PRINT_HT_ACTION(GET_U_1(p + 1)); break; 1750 case 13: ND_PRINT("MeshAction "); PRINT_MESH_ACTION(GET_U_1(p + 1)); break; 1751 case 14: 1752 ND_PRINT("MultiohopAction "); 1753 PRINT_MULTIHOP_ACTION(GET_U_1(p + 1)); break; 1754 case 15: 1755 ND_PRINT("SelfprotectAction "); 1756 PRINT_SELFPROT_ACTION(GET_U_1(p + 1)); break; 1757 case 127: ND_PRINT("Vendor Act#%u", GET_U_1(p + 1)); break; 1758 default: 1759 ND_PRINT("Reserved(%u) Act#%u", GET_U_1(p), GET_U_1(p + 1)); 1760 break; 1761 } 1762 return 1; 1763 trunc: 1764 return 0; 1765 } 1766 1767 1768 /********************************************************************************* 1769 * Print Body funcs 1770 *********************************************************************************/ 1771 1772 1773 static int 1774 mgmt_body_print(netdissect_options *ndo, 1775 uint16_t fc, const uint8_t *src, const u_char *p, u_int length) 1776 { 1777 ND_PRINT("%s", tok2str(st_str, "Unhandled Management subtype(%x)", FC_SUBTYPE(fc))); 1778 1779 /* There may be a problem w/ AP not having this bit set */ 1780 if (FC_PROTECTED(fc)) 1781 return wep_print(ndo, p); 1782 switch (FC_SUBTYPE(fc)) { 1783 case ST_ASSOC_REQUEST: 1784 return handle_assoc_request(ndo, p, length); 1785 case ST_ASSOC_RESPONSE: 1786 return handle_assoc_response(ndo, p, length); 1787 case ST_REASSOC_REQUEST: 1788 return handle_reassoc_request(ndo, p, length); 1789 case ST_REASSOC_RESPONSE: 1790 return handle_reassoc_response(ndo, p, length); 1791 case ST_PROBE_REQUEST: 1792 return handle_probe_request(ndo, p, length); 1793 case ST_PROBE_RESPONSE: 1794 return handle_probe_response(ndo, p, length); 1795 case ST_BEACON: 1796 return handle_beacon(ndo, p, length); 1797 case ST_ATIM: 1798 return handle_atim(); 1799 case ST_DISASSOC: 1800 return handle_disassoc(ndo, p, length); 1801 case ST_AUTH: 1802 return handle_auth(ndo, p, length); 1803 case ST_DEAUTH: 1804 return handle_deauth(ndo, src, p, length); 1805 case ST_ACTION: 1806 return handle_action(ndo, src, p, length); 1807 default: 1808 return 1; 1809 } 1810 } 1811 1812 1813 /********************************************************************************* 1814 * Handles printing all the control frame types 1815 *********************************************************************************/ 1816 1817 static int 1818 ctrl_body_print(netdissect_options *ndo, 1819 uint16_t fc, const u_char *p) 1820 { 1821 ND_PRINT("%s", tok2str(ctrl_str, "Unknown Ctrl Subtype", FC_SUBTYPE(fc))); 1822 switch (FC_SUBTYPE(fc)) { 1823 case CTRL_CONTROL_WRAPPER: 1824 /* XXX - requires special handling */ 1825 break; 1826 case CTRL_BAR: 1827 ND_TCHECK_LEN(p, CTRL_BAR_HDRLEN); 1828 if (!ndo->ndo_eflag) 1829 ND_PRINT(" RA:%s TA:%s CTL(%x) SEQ(%u) ", 1830 GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ra), 1831 GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ta), 1832 GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->ctl), 1833 GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->seq)); 1834 break; 1835 case CTRL_BA: 1836 ND_TCHECK_LEN(p, CTRL_BA_HDRLEN); 1837 if (!ndo->ndo_eflag) 1838 ND_PRINT(" RA:%s ", 1839 GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra)); 1840 break; 1841 case CTRL_PS_POLL: 1842 ND_TCHECK_LEN(p, CTRL_PS_POLL_HDRLEN); 1843 ND_PRINT(" AID(%x)", 1844 GET_LE_U_2(((const struct ctrl_ps_poll_hdr_t *)p)->aid)); 1845 break; 1846 case CTRL_RTS: 1847 ND_TCHECK_LEN(p, CTRL_RTS_HDRLEN); 1848 if (!ndo->ndo_eflag) 1849 ND_PRINT(" TA:%s ", 1850 GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ta)); 1851 break; 1852 case CTRL_CTS: 1853 ND_TCHECK_LEN(p, CTRL_CTS_HDRLEN); 1854 if (!ndo->ndo_eflag) 1855 ND_PRINT(" RA:%s ", 1856 GET_ETHERADDR_STRING(((const struct ctrl_cts_hdr_t *)p)->ra)); 1857 break; 1858 case CTRL_ACK: 1859 ND_TCHECK_LEN(p, CTRL_ACK_HDRLEN); 1860 if (!ndo->ndo_eflag) 1861 ND_PRINT(" RA:%s ", 1862 GET_ETHERADDR_STRING(((const struct ctrl_ack_hdr_t *)p)->ra)); 1863 break; 1864 case CTRL_CF_END: 1865 ND_TCHECK_LEN(p, CTRL_END_HDRLEN); 1866 if (!ndo->ndo_eflag) 1867 ND_PRINT(" RA:%s ", 1868 GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->ra)); 1869 break; 1870 case CTRL_END_ACK: 1871 ND_TCHECK_LEN(p, CTRL_END_ACK_HDRLEN); 1872 if (!ndo->ndo_eflag) 1873 ND_PRINT(" RA:%s ", 1874 GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra)); 1875 break; 1876 } 1877 return 1; 1878 trunc: 1879 return 0; 1880 } 1881 1882 /* 1883 * Data Frame - Address field contents 1884 * 1885 * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4 1886 * 0 | 0 | DA | SA | BSSID | n/a 1887 * 0 | 1 | DA | BSSID | SA | n/a 1888 * 1 | 0 | BSSID | SA | DA | n/a 1889 * 1 | 1 | RA | TA | DA | SA 1890 */ 1891 1892 /* 1893 * Function to get source and destination MAC addresses for a data frame. 1894 */ 1895 static void 1896 get_data_src_dst_mac(uint16_t fc, const u_char *p, const uint8_t **srcp, 1897 const uint8_t **dstp) 1898 { 1899 #define ADDR1 (p + 4) 1900 #define ADDR2 (p + 10) 1901 #define ADDR3 (p + 16) 1902 #define ADDR4 (p + 24) 1903 1904 if (!FC_TO_DS(fc)) { 1905 if (!FC_FROM_DS(fc)) { 1906 /* not To DS and not From DS */ 1907 *srcp = ADDR2; 1908 *dstp = ADDR1; 1909 } else { 1910 /* not To DS and From DS */ 1911 *srcp = ADDR3; 1912 *dstp = ADDR1; 1913 } 1914 } else { 1915 if (!FC_FROM_DS(fc)) { 1916 /* To DS and not From DS */ 1917 *srcp = ADDR2; 1918 *dstp = ADDR3; 1919 } else { 1920 /* To DS and From DS */ 1921 *srcp = ADDR4; 1922 *dstp = ADDR3; 1923 } 1924 } 1925 1926 #undef ADDR1 1927 #undef ADDR2 1928 #undef ADDR3 1929 #undef ADDR4 1930 } 1931 1932 static void 1933 get_mgmt_src_dst_mac(const u_char *p, const uint8_t **srcp, const uint8_t **dstp) 1934 { 1935 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p; 1936 1937 if (srcp != NULL) 1938 *srcp = hp->sa; 1939 if (dstp != NULL) 1940 *dstp = hp->da; 1941 } 1942 1943 /* 1944 * Print Header funcs 1945 */ 1946 1947 static void 1948 data_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p) 1949 { 1950 u_int subtype = FC_SUBTYPE(fc); 1951 1952 if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) || 1953 DATA_FRAME_IS_QOS(subtype)) { 1954 ND_PRINT("CF "); 1955 if (DATA_FRAME_IS_CF_ACK(subtype)) { 1956 if (DATA_FRAME_IS_CF_POLL(subtype)) 1957 ND_PRINT("Ack/Poll"); 1958 else 1959 ND_PRINT("Ack"); 1960 } else { 1961 if (DATA_FRAME_IS_CF_POLL(subtype)) 1962 ND_PRINT("Poll"); 1963 } 1964 if (DATA_FRAME_IS_QOS(subtype)) 1965 ND_PRINT("+QoS"); 1966 ND_PRINT(" "); 1967 } 1968 1969 #define ADDR1 (p + 4) 1970 #define ADDR2 (p + 10) 1971 #define ADDR3 (p + 16) 1972 #define ADDR4 (p + 24) 1973 1974 if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { 1975 ND_PRINT("DA:%s SA:%s BSSID:%s ", 1976 GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2), 1977 GET_ETHERADDR_STRING(ADDR3)); 1978 } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { 1979 ND_PRINT("DA:%s BSSID:%s SA:%s ", 1980 GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2), 1981 GET_ETHERADDR_STRING(ADDR3)); 1982 } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { 1983 ND_PRINT("BSSID:%s SA:%s DA:%s ", 1984 GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2), 1985 GET_ETHERADDR_STRING(ADDR3)); 1986 } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { 1987 ND_PRINT("RA:%s TA:%s DA:%s SA:%s ", 1988 GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2), 1989 GET_ETHERADDR_STRING(ADDR3), GET_ETHERADDR_STRING(ADDR4)); 1990 } 1991 1992 #undef ADDR1 1993 #undef ADDR2 1994 #undef ADDR3 1995 #undef ADDR4 1996 } 1997 1998 static void 1999 mgmt_header_print(netdissect_options *ndo, const u_char *p) 2000 { 2001 const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p; 2002 2003 ND_PRINT("BSSID:%s DA:%s SA:%s ", 2004 GET_ETHERADDR_STRING((hp)->bssid), GET_ETHERADDR_STRING((hp)->da), 2005 GET_ETHERADDR_STRING((hp)->sa)); 2006 } 2007 2008 static void 2009 ctrl_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p) 2010 { 2011 switch (FC_SUBTYPE(fc)) { 2012 case CTRL_BAR: 2013 ND_PRINT(" RA:%s TA:%s CTL(%x) SEQ(%u) ", 2014 GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ra), 2015 GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ta), 2016 GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->ctl), 2017 GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->seq)); 2018 break; 2019 case CTRL_BA: 2020 ND_PRINT("RA:%s ", 2021 GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra)); 2022 break; 2023 case CTRL_PS_POLL: 2024 ND_PRINT("BSSID:%s TA:%s ", 2025 GET_ETHERADDR_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->bssid), 2026 GET_ETHERADDR_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->ta)); 2027 break; 2028 case CTRL_RTS: 2029 ND_PRINT("RA:%s TA:%s ", 2030 GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ra), 2031 GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ta)); 2032 break; 2033 case CTRL_CTS: 2034 ND_PRINT("RA:%s ", 2035 GET_ETHERADDR_STRING(((const struct ctrl_cts_hdr_t *)p)->ra)); 2036 break; 2037 case CTRL_ACK: 2038 ND_PRINT("RA:%s ", 2039 GET_ETHERADDR_STRING(((const struct ctrl_ack_hdr_t *)p)->ra)); 2040 break; 2041 case CTRL_CF_END: 2042 ND_PRINT("RA:%s BSSID:%s ", 2043 GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->ra), 2044 GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->bssid)); 2045 break; 2046 case CTRL_END_ACK: 2047 ND_PRINT("RA:%s BSSID:%s ", 2048 GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra), 2049 GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->bssid)); 2050 break; 2051 default: 2052 /* We shouldn't get here - we should already have quit */ 2053 break; 2054 } 2055 } 2056 2057 static int 2058 extract_header_length(netdissect_options *ndo, 2059 uint16_t fc) 2060 { 2061 int len; 2062 2063 switch (FC_TYPE(fc)) { 2064 case T_MGMT: 2065 return MGMT_HDRLEN; 2066 case T_CTRL: 2067 switch (FC_SUBTYPE(fc)) { 2068 case CTRL_CONTROL_WRAPPER: 2069 return CTRL_CONTROL_WRAPPER_HDRLEN; 2070 case CTRL_BAR: 2071 return CTRL_BAR_HDRLEN; 2072 case CTRL_BA: 2073 return CTRL_BA_HDRLEN; 2074 case CTRL_PS_POLL: 2075 return CTRL_PS_POLL_HDRLEN; 2076 case CTRL_RTS: 2077 return CTRL_RTS_HDRLEN; 2078 case CTRL_CTS: 2079 return CTRL_CTS_HDRLEN; 2080 case CTRL_ACK: 2081 return CTRL_ACK_HDRLEN; 2082 case CTRL_CF_END: 2083 return CTRL_END_HDRLEN; 2084 case CTRL_END_ACK: 2085 return CTRL_END_ACK_HDRLEN; 2086 default: 2087 ND_PRINT("unknown 802.11 ctrl frame subtype (%u)", FC_SUBTYPE(fc)); 2088 return 0; 2089 } 2090 case T_DATA: 2091 len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24; 2092 if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) 2093 len += 2; 2094 return len; 2095 default: 2096 ND_PRINT("unknown 802.11 frame type (%u)", FC_TYPE(fc)); 2097 return 0; 2098 } 2099 } 2100 2101 static int 2102 extract_mesh_header_length(netdissect_options *ndo, const u_char *p) 2103 { 2104 return (GET_U_1(p) &~ 3) ? 0 : 6*(1 + (GET_U_1(p) & 3)); 2105 } 2106 2107 /* 2108 * Print the 802.11 MAC header. 2109 */ 2110 static void 2111 ieee_802_11_hdr_print(netdissect_options *ndo, 2112 uint16_t fc, const u_char *p, u_int hdrlen, 2113 u_int meshdrlen) 2114 { 2115 if (ndo->ndo_vflag) { 2116 if (FC_MORE_DATA(fc)) 2117 ND_PRINT("More Data "); 2118 if (FC_MORE_FLAG(fc)) 2119 ND_PRINT("More Fragments "); 2120 if (FC_POWER_MGMT(fc)) 2121 ND_PRINT("Pwr Mgmt "); 2122 if (FC_RETRY(fc)) 2123 ND_PRINT("Retry "); 2124 if (FC_ORDER(fc)) 2125 ND_PRINT("Strictly Ordered "); 2126 if (FC_PROTECTED(fc)) 2127 ND_PRINT("Protected "); 2128 if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL) 2129 ND_PRINT("%uus ", 2130 GET_LE_U_2(((const struct mgmt_header_t *)p)->duration)); 2131 } 2132 if (meshdrlen != 0) { 2133 const struct meshcntl_t *mc = 2134 (const struct meshcntl_t *)(p + hdrlen - meshdrlen); 2135 u_int ae = GET_U_1(mc->flags) & 3; 2136 2137 ND_PRINT("MeshData (AE %u TTL %u seq %u", ae, 2138 GET_U_1(mc->ttl), GET_LE_U_4(mc->seq)); 2139 if (ae > 0) 2140 ND_PRINT(" A4:%s", GET_ETHERADDR_STRING(mc->addr4)); 2141 if (ae > 1) 2142 ND_PRINT(" A5:%s", GET_ETHERADDR_STRING(mc->addr5)); 2143 if (ae > 2) 2144 ND_PRINT(" A6:%s", GET_ETHERADDR_STRING(mc->addr6)); 2145 ND_PRINT(") "); 2146 } 2147 2148 switch (FC_TYPE(fc)) { 2149 case T_MGMT: 2150 mgmt_header_print(ndo, p); 2151 break; 2152 case T_CTRL: 2153 ctrl_header_print(ndo, fc, p); 2154 break; 2155 case T_DATA: 2156 data_header_print(ndo, fc, p); 2157 break; 2158 default: 2159 break; 2160 } 2161 } 2162 2163 static u_int 2164 ieee802_11_print(netdissect_options *ndo, 2165 const u_char *p, u_int length, u_int orig_caplen, int pad, 2166 u_int fcslen) 2167 { 2168 uint16_t fc; 2169 u_int caplen, hdrlen, meshdrlen; 2170 struct lladdr_info src, dst; 2171 int llc_hdrlen; 2172 2173 ndo->ndo_protocol = "802.11"; 2174 caplen = orig_caplen; 2175 /* Remove FCS, if present */ 2176 if (length < fcslen) { 2177 nd_print_trunc(ndo); 2178 return caplen; 2179 } 2180 length -= fcslen; 2181 if (caplen > length) { 2182 /* Amount of FCS in actual packet data, if any */ 2183 fcslen = caplen - length; 2184 caplen -= fcslen; 2185 ndo->ndo_snapend -= fcslen; 2186 } 2187 2188 if (caplen < IEEE802_11_FC_LEN) { 2189 nd_print_trunc(ndo); 2190 return orig_caplen; 2191 } 2192 2193 fc = GET_LE_U_2(p); 2194 hdrlen = extract_header_length(ndo, fc); 2195 if (hdrlen == 0) { 2196 /* Unknown frame type or control frame subtype; quit. */ 2197 return (0); 2198 } 2199 if (pad) 2200 hdrlen = roundup2(hdrlen, 4); 2201 if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA && 2202 DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) { 2203 if(!ND_TTEST_1(p + hdrlen)) { 2204 nd_print_trunc(ndo); 2205 return hdrlen; 2206 } 2207 meshdrlen = extract_mesh_header_length(ndo, p + hdrlen); 2208 hdrlen += meshdrlen; 2209 } else 2210 meshdrlen = 0; 2211 2212 if (caplen < hdrlen) { 2213 nd_print_trunc(ndo); 2214 return hdrlen; 2215 } 2216 2217 if (ndo->ndo_eflag) 2218 ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen); 2219 2220 /* 2221 * Go past the 802.11 header. 2222 */ 2223 length -= hdrlen; 2224 caplen -= hdrlen; 2225 p += hdrlen; 2226 2227 src.addr_string = etheraddr_string; 2228 dst.addr_string = etheraddr_string; 2229 switch (FC_TYPE(fc)) { 2230 case T_MGMT: 2231 get_mgmt_src_dst_mac(p - hdrlen, &src.addr, &dst.addr); 2232 if (!mgmt_body_print(ndo, fc, src.addr, p, length)) { 2233 nd_print_trunc(ndo); 2234 return hdrlen; 2235 } 2236 break; 2237 case T_CTRL: 2238 if (!ctrl_body_print(ndo, fc, p - hdrlen)) { 2239 nd_print_trunc(ndo); 2240 return hdrlen; 2241 } 2242 break; 2243 case T_DATA: 2244 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc))) 2245 return hdrlen; /* no-data frame */ 2246 /* There may be a problem w/ AP not having this bit set */ 2247 if (FC_PROTECTED(fc)) { 2248 ND_PRINT("Data"); 2249 if (!wep_print(ndo, p)) { 2250 nd_print_trunc(ndo); 2251 return hdrlen; 2252 } 2253 } else { 2254 get_data_src_dst_mac(fc, p - hdrlen, &src.addr, &dst.addr); 2255 llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); 2256 if (llc_hdrlen < 0) { 2257 /* 2258 * Some kinds of LLC packet we cannot 2259 * handle intelligently 2260 */ 2261 if (!ndo->ndo_suppress_default_print) 2262 ND_DEFAULTPRINT(p, caplen); 2263 llc_hdrlen = -llc_hdrlen; 2264 } 2265 hdrlen += llc_hdrlen; 2266 } 2267 break; 2268 default: 2269 /* We shouldn't get here - we should already have quit */ 2270 break; 2271 } 2272 2273 return hdrlen; 2274 } 2275 2276 /* 2277 * This is the top level routine of the printer. 'p' points 2278 * to the 802.11 header of the packet, 'h->ts' is the timestamp, 2279 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 2280 * is the number of bytes actually captured. 2281 */ 2282 void 2283 ieee802_11_if_print(netdissect_options *ndo, 2284 const struct pcap_pkthdr *h, const u_char *p) 2285 { 2286 ndo->ndo_protocol = "802.11"; 2287 ndo->ndo_ll_hdr_len += ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0); 2288 } 2289 2290 2291 /* $FreeBSD: projects/clang400-import/contrib/tcpdump/print-802_11.c 276788 2015-01-07 19:55:18Z delphij $ */ 2292 /* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp */ 2293 2294 /*- 2295 * Copyright (c) 2003, 2004 David Young. All rights reserved. 2296 * 2297 * Redistribution and use in source and binary forms, with or without 2298 * modification, are permitted provided that the following conditions 2299 * are met: 2300 * 1. Redistributions of source code must retain the above copyright 2301 * notice, this list of conditions and the following disclaimer. 2302 * 2. Redistributions in binary form must reproduce the above copyright 2303 * notice, this list of conditions and the following disclaimer in the 2304 * documentation and/or other materials provided with the distribution. 2305 * 3. The name of David Young may not be used to endorse or promote 2306 * products derived from this software without specific prior 2307 * written permission. 2308 * 2309 * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY 2310 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 2311 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 2312 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID 2313 * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2314 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2315 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2316 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 2317 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2318 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2319 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 2320 * OF SUCH DAMAGE. 2321 */ 2322 2323 /* A generic radio capture format is desirable. It must be 2324 * rigidly defined (e.g., units for fields should be given), 2325 * and easily extensible. 2326 * 2327 * The following is an extensible radio capture format. It is 2328 * based on a bitmap indicating which fields are present. 2329 * 2330 * I am trying to describe precisely what the application programmer 2331 * should expect in the following, and for that reason I tell the 2332 * units and origin of each measurement (where it applies), or else I 2333 * use sufficiently weaselly language ("is a monotonically nondecreasing 2334 * function of...") that I cannot set false expectations for lawyerly 2335 * readers. 2336 */ 2337 2338 /* 2339 * The radio capture header precedes the 802.11 header. 2340 * 2341 * Note well: all radiotap fields are little-endian. 2342 */ 2343 struct ieee80211_radiotap_header { 2344 nd_uint8_t it_version; /* Version 0. Only increases 2345 * for drastic changes, 2346 * introduction of compatible 2347 * new fields does not count. 2348 */ 2349 nd_uint8_t it_pad; 2350 nd_uint16_t it_len; /* length of the whole 2351 * header in bytes, including 2352 * it_version, it_pad, 2353 * it_len, and data fields. 2354 */ 2355 nd_uint32_t it_present; /* A bitmap telling which 2356 * fields are present. Set bit 31 2357 * (0x80000000) to extend the 2358 * bitmap by another 32 bits. 2359 * Additional extensions are made 2360 * by setting bit 31. 2361 */ 2362 }; 2363 2364 /* Name Data type Units 2365 * ---- --------- ----- 2366 * 2367 * IEEE80211_RADIOTAP_TSFT uint64_t microseconds 2368 * 2369 * Value in microseconds of the MAC's 64-bit 802.11 Time 2370 * Synchronization Function timer when the first bit of the 2371 * MPDU arrived at the MAC. For received frames, only. 2372 * 2373 * IEEE80211_RADIOTAP_CHANNEL 2 x uint16_t MHz, bitmap 2374 * 2375 * Tx/Rx frequency in MHz, followed by flags (see below). 2376 * Note that IEEE80211_RADIOTAP_XCHANNEL must be used to 2377 * represent an HT channel as there is not enough room in 2378 * the flags word. 2379 * 2380 * IEEE80211_RADIOTAP_FHSS uint16_t see below 2381 * 2382 * For frequency-hopping radios, the hop set (first byte) 2383 * and pattern (second byte). 2384 * 2385 * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s or index 2386 * 2387 * Tx/Rx data rate. If bit 0x80 is set then it represents an 2388 * an MCS index and not an IEEE rate. 2389 * 2390 * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from 2391 * one milliwatt (dBm) 2392 * 2393 * RF signal power at the antenna, decibel difference from 2394 * one milliwatt. 2395 * 2396 * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from 2397 * one milliwatt (dBm) 2398 * 2399 * RF noise power at the antenna, decibel difference from one 2400 * milliwatt. 2401 * 2402 * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB) 2403 * 2404 * RF signal power at the antenna, decibel difference from an 2405 * arbitrary, fixed reference. 2406 * 2407 * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB) 2408 * 2409 * RF noise power at the antenna, decibel difference from an 2410 * arbitrary, fixed reference point. 2411 * 2412 * IEEE80211_RADIOTAP_LOCK_QUALITY uint16_t unitless 2413 * 2414 * Quality of Barker code lock. Unitless. Monotonically 2415 * nondecreasing with "better" lock strength. Called "Signal 2416 * Quality" in datasheets. (Is there a standard way to measure 2417 * this?) 2418 * 2419 * IEEE80211_RADIOTAP_TX_ATTENUATION uint16_t unitless 2420 * 2421 * Transmit power expressed as unitless distance from max 2422 * power set at factory calibration. 0 is max power. 2423 * Monotonically nondecreasing with lower power levels. 2424 * 2425 * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t decibels (dB) 2426 * 2427 * Transmit power expressed as decibel distance from max power 2428 * set at factory calibration. 0 is max power. Monotonically 2429 * nondecreasing with lower power levels. 2430 * 2431 * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from 2432 * one milliwatt (dBm) 2433 * 2434 * Transmit power expressed as dBm (decibels from a 1 milliwatt 2435 * reference). This is the absolute power level measured at 2436 * the antenna port. 2437 * 2438 * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap 2439 * 2440 * Properties of transmitted and received frames. See flags 2441 * defined below. 2442 * 2443 * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index 2444 * 2445 * Unitless indication of the Rx/Tx antenna for this packet. 2446 * The first antenna is antenna 0. 2447 * 2448 * IEEE80211_RADIOTAP_RX_FLAGS uint16_t bitmap 2449 * 2450 * Properties of received frames. See flags defined below. 2451 * 2452 * IEEE80211_RADIOTAP_XCHANNEL uint32_t bitmap 2453 * uint16_t MHz 2454 * uint8_t channel number 2455 * uint8_t .5 dBm 2456 * 2457 * Extended channel specification: flags (see below) followed by 2458 * frequency in MHz, the corresponding IEEE channel number, and 2459 * finally the maximum regulatory transmit power cap in .5 dBm 2460 * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL 2461 * and only one of the two should be present. 2462 * 2463 * IEEE80211_RADIOTAP_MCS uint8_t known 2464 * uint8_t flags 2465 * uint8_t mcs 2466 * 2467 * Bitset indicating which fields have known values, followed 2468 * by bitset of flag values, followed by the MCS rate index as 2469 * in IEEE 802.11n. 2470 * 2471 * 2472 * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless 2473 * 2474 * Contains the AMPDU information for the subframe. 2475 * 2476 * IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16 2477 * 2478 * Contains VHT information about this frame. 2479 * 2480 * IEEE80211_RADIOTAP_VENDOR_NAMESPACE 2481 * uint8_t OUI[3] 2482 * uint8_t subspace 2483 * uint16_t length 2484 * 2485 * The Vendor Namespace Field contains three sub-fields. The first 2486 * sub-field is 3 bytes long. It contains the vendor's IEEE 802 2487 * Organizationally Unique Identifier (OUI). The fourth byte is a 2488 * vendor-specific "namespace selector." 2489 * 2490 */ 2491 enum ieee80211_radiotap_type { 2492 IEEE80211_RADIOTAP_TSFT = 0, 2493 IEEE80211_RADIOTAP_FLAGS = 1, 2494 IEEE80211_RADIOTAP_RATE = 2, 2495 IEEE80211_RADIOTAP_CHANNEL = 3, 2496 IEEE80211_RADIOTAP_FHSS = 4, 2497 IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, 2498 IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, 2499 IEEE80211_RADIOTAP_LOCK_QUALITY = 7, 2500 IEEE80211_RADIOTAP_TX_ATTENUATION = 8, 2501 IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, 2502 IEEE80211_RADIOTAP_DBM_TX_POWER = 10, 2503 IEEE80211_RADIOTAP_ANTENNA = 11, 2504 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, 2505 IEEE80211_RADIOTAP_DB_ANTNOISE = 13, 2506 IEEE80211_RADIOTAP_RX_FLAGS = 14, 2507 /* NB: gap for netbsd definitions */ 2508 IEEE80211_RADIOTAP_XCHANNEL = 18, 2509 IEEE80211_RADIOTAP_MCS = 19, 2510 IEEE80211_RADIOTAP_AMPDU_STATUS = 20, 2511 IEEE80211_RADIOTAP_VHT = 21, 2512 IEEE80211_RADIOTAP_NAMESPACE = 29, 2513 IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30, 2514 IEEE80211_RADIOTAP_EXT = 31 2515 }; 2516 2517 /* channel attributes */ 2518 #define IEEE80211_CHAN_TURBO 0x00010 /* Turbo channel */ 2519 #define IEEE80211_CHAN_CCK 0x00020 /* CCK channel */ 2520 #define IEEE80211_CHAN_OFDM 0x00040 /* OFDM channel */ 2521 #define IEEE80211_CHAN_2GHZ 0x00080 /* 2 GHz spectrum channel. */ 2522 #define IEEE80211_CHAN_5GHZ 0x00100 /* 5 GHz spectrum channel */ 2523 #define IEEE80211_CHAN_PASSIVE 0x00200 /* Only passive scan allowed */ 2524 #define IEEE80211_CHAN_DYN 0x00400 /* Dynamic CCK-OFDM channel */ 2525 #define IEEE80211_CHAN_GFSK 0x00800 /* GFSK channel (FHSS PHY) */ 2526 #define IEEE80211_CHAN_GSM 0x01000 /* 900 MHz spectrum channel */ 2527 #define IEEE80211_CHAN_STURBO 0x02000 /* 11a static turbo channel only */ 2528 #define IEEE80211_CHAN_HALF 0x04000 /* Half rate channel */ 2529 #define IEEE80211_CHAN_QUARTER 0x08000 /* Quarter rate channel */ 2530 #define IEEE80211_CHAN_HT20 0x10000 /* HT 20 channel */ 2531 #define IEEE80211_CHAN_HT40U 0x20000 /* HT 40 channel w/ ext above */ 2532 #define IEEE80211_CHAN_HT40D 0x40000 /* HT 40 channel w/ ext below */ 2533 2534 /* Useful combinations of channel characteristics, borrowed from Ethereal */ 2535 #define IEEE80211_CHAN_A \ 2536 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) 2537 #define IEEE80211_CHAN_B \ 2538 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) 2539 #define IEEE80211_CHAN_G \ 2540 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) 2541 #define IEEE80211_CHAN_TA \ 2542 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO) 2543 #define IEEE80211_CHAN_TG \ 2544 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN | IEEE80211_CHAN_TURBO) 2545 2546 2547 /* For IEEE80211_RADIOTAP_FLAGS */ 2548 #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received 2549 * during CFP 2550 */ 2551 #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received 2552 * with short 2553 * preamble 2554 */ 2555 #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received 2556 * with WEP encryption 2557 */ 2558 #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received 2559 * with fragmentation 2560 */ 2561 #define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ 2562 #define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between 2563 * 802.11 header and payload 2564 * (to 32-bit boundary) 2565 */ 2566 #define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */ 2567 2568 /* For IEEE80211_RADIOTAP_RX_FLAGS */ 2569 #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ 2570 #define IEEE80211_RADIOTAP_F_RX_PLCP_CRC 0x0002 /* frame failed PLCP CRC check */ 2571 2572 /* For IEEE80211_RADIOTAP_MCS known */ 2573 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN 0x01 2574 #define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN 0x02 /* MCS index field */ 2575 #define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN 0x04 2576 #define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN 0x08 2577 #define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN 0x10 2578 #define IEEE80211_RADIOTAP_MCS_STBC_KNOWN 0x20 2579 #define IEEE80211_RADIOTAP_MCS_NESS_KNOWN 0x40 2580 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_1 0x80 2581 2582 /* For IEEE80211_RADIOTAP_MCS flags */ 2583 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK 0x03 2584 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20 0 2585 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 1 2586 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L 2 2587 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U 3 2588 #define IEEE80211_RADIOTAP_MCS_SHORT_GI 0x04 /* short guard interval */ 2589 #define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD 0x08 2590 #define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 2591 #define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60 2592 #define IEEE80211_RADIOTAP_MCS_STBC_1 1 2593 #define IEEE80211_RADIOTAP_MCS_STBC_2 2 2594 #define IEEE80211_RADIOTAP_MCS_STBC_3 3 2595 #define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5 2596 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_0 0x80 2597 2598 /* For IEEE80211_RADIOTAP_AMPDU_STATUS */ 2599 #define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001 2600 #define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN 0x0002 2601 #define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN 0x0004 2602 #define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008 2603 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 2604 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 2605 2606 /* For IEEE80211_RADIOTAP_VHT known */ 2607 #define IEEE80211_RADIOTAP_VHT_STBC_KNOWN 0x0001 2608 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA_KNOWN 0x0002 2609 #define IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN 0x0004 2610 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_DIS_KNOWN 0x0008 2611 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM_KNOWN 0x0010 2612 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED_KNOWN 0x0020 2613 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN 0x0040 2614 #define IEEE80211_RADIOTAP_VHT_GROUP_ID_KNOWN 0x0080 2615 #define IEEE80211_RADIOTAP_VHT_PARTIAL_AID_KNOWN 0x0100 2616 2617 /* For IEEE80211_RADIOTAP_VHT flags */ 2618 #define IEEE80211_RADIOTAP_VHT_STBC 0x01 2619 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA 0x02 2620 #define IEEE80211_RADIOTAP_VHT_SHORT_GI 0x04 2621 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_M10_9 0x08 2622 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM 0x10 2623 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED 0x20 2624 2625 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK 0x1f 2626 2627 #define IEEE80211_RADIOTAP_VHT_NSS_MASK 0x0f 2628 #define IEEE80211_RADIOTAP_VHT_MCS_MASK 0xf0 2629 #define IEEE80211_RADIOTAP_VHT_MCS_SHIFT 4 2630 2631 #define IEEE80211_RADIOTAP_CODING_LDPC_USERn 0x01 2632 2633 #define IEEE80211_CHAN_FHSS \ 2634 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK) 2635 #define IEEE80211_CHAN_A \ 2636 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) 2637 #define IEEE80211_CHAN_B \ 2638 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) 2639 #define IEEE80211_CHAN_PUREG \ 2640 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM) 2641 #define IEEE80211_CHAN_G \ 2642 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) 2643 2644 #define IS_CHAN_FHSS(flags) \ 2645 ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS) 2646 #define IS_CHAN_A(flags) \ 2647 ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A) 2648 #define IS_CHAN_B(flags) \ 2649 ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B) 2650 #define IS_CHAN_PUREG(flags) \ 2651 ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG) 2652 #define IS_CHAN_G(flags) \ 2653 ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G) 2654 #define IS_CHAN_ANYG(flags) \ 2655 (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags)) 2656 2657 static void 2658 print_chaninfo(netdissect_options *ndo, 2659 uint16_t freq, uint32_t flags, uint32_t presentflags) 2660 { 2661 ND_PRINT("%u MHz", freq); 2662 if (presentflags & (1 << IEEE80211_RADIOTAP_MCS)) { 2663 /* 2664 * We have the MCS field, so this is 11n, regardless 2665 * of what the channel flags say. 2666 */ 2667 ND_PRINT(" 11n"); 2668 } else { 2669 if (IS_CHAN_FHSS(flags)) 2670 ND_PRINT(" FHSS"); 2671 if (IS_CHAN_A(flags)) { 2672 if (flags & IEEE80211_CHAN_HALF) 2673 ND_PRINT(" 11a/10Mhz"); 2674 else if (flags & IEEE80211_CHAN_QUARTER) 2675 ND_PRINT(" 11a/5Mhz"); 2676 else 2677 ND_PRINT(" 11a"); 2678 } 2679 if (IS_CHAN_ANYG(flags)) { 2680 if (flags & IEEE80211_CHAN_HALF) 2681 ND_PRINT(" 11g/10Mhz"); 2682 else if (flags & IEEE80211_CHAN_QUARTER) 2683 ND_PRINT(" 11g/5Mhz"); 2684 else 2685 ND_PRINT(" 11g"); 2686 } else if (IS_CHAN_B(flags)) 2687 ND_PRINT(" 11b"); 2688 if (flags & IEEE80211_CHAN_TURBO) 2689 ND_PRINT(" Turbo"); 2690 } 2691 /* 2692 * These apply to 11n. 2693 */ 2694 if (flags & IEEE80211_CHAN_HT20) 2695 ND_PRINT(" ht/20"); 2696 else if (flags & IEEE80211_CHAN_HT40D) 2697 ND_PRINT(" ht/40-"); 2698 else if (flags & IEEE80211_CHAN_HT40U) 2699 ND_PRINT(" ht/40+"); 2700 ND_PRINT(" "); 2701 } 2702 2703 static int 2704 print_radiotap_field(netdissect_options *ndo, 2705 struct cpack_state *s, uint32_t bit, uint8_t *flagsp, 2706 uint32_t presentflags) 2707 { 2708 u_int i; 2709 int rc; 2710 2711 switch (bit) { 2712 2713 case IEEE80211_RADIOTAP_TSFT: { 2714 uint64_t tsft; 2715 2716 rc = nd_cpack_uint64(ndo, s, &tsft); 2717 if (rc != 0) 2718 goto trunc; 2719 ND_PRINT("%" PRIu64 "us tsft ", tsft); 2720 break; 2721 } 2722 2723 case IEEE80211_RADIOTAP_FLAGS: { 2724 uint8_t flagsval; 2725 2726 rc = nd_cpack_uint8(ndo, s, &flagsval); 2727 if (rc != 0) 2728 goto trunc; 2729 *flagsp = flagsval; 2730 if (flagsval & IEEE80211_RADIOTAP_F_CFP) 2731 ND_PRINT("cfp "); 2732 if (flagsval & IEEE80211_RADIOTAP_F_SHORTPRE) 2733 ND_PRINT("short preamble "); 2734 if (flagsval & IEEE80211_RADIOTAP_F_WEP) 2735 ND_PRINT("wep "); 2736 if (flagsval & IEEE80211_RADIOTAP_F_FRAG) 2737 ND_PRINT("fragmented "); 2738 if (flagsval & IEEE80211_RADIOTAP_F_BADFCS) 2739 ND_PRINT("bad-fcs "); 2740 break; 2741 } 2742 2743 case IEEE80211_RADIOTAP_RATE: { 2744 uint8_t rate; 2745 2746 rc = nd_cpack_uint8(ndo, s, &rate); 2747 if (rc != 0) 2748 goto trunc; 2749 /* 2750 * XXX On FreeBSD rate & 0x80 means we have an MCS. On 2751 * Linux and AirPcap it does not. (What about 2752 * macOS, NetBSD, OpenBSD, and DragonFly BSD?) 2753 * 2754 * This is an issue either for proprietary extensions 2755 * to 11a or 11g, which do exist, or for 11n 2756 * implementations that stuff a rate value into 2757 * this field, which also appear to exist. 2758 * 2759 * We currently handle that by assuming that 2760 * if the 0x80 bit is set *and* the remaining 2761 * bits have a value between 0 and 15 it's 2762 * an MCS value, otherwise it's a rate. If 2763 * there are cases where systems that use 2764 * "0x80 + MCS index" for MCS indices > 15, 2765 * or stuff a rate value here between 64 and 2766 * 71.5 Mb/s in here, we'll need a preference 2767 * setting. Such rates do exist, e.g. 11n 2768 * MCS 7 at 20 MHz with a long guard interval. 2769 */ 2770 if (rate >= 0x80 && rate <= 0x8f) { 2771 /* 2772 * XXX - we don't know the channel width 2773 * or guard interval length, so we can't 2774 * convert this to a data rate. 2775 * 2776 * If you want us to show a data rate, 2777 * use the MCS field, not the Rate field; 2778 * the MCS field includes not only the 2779 * MCS index, it also includes bandwidth 2780 * and guard interval information. 2781 * 2782 * XXX - can we get the channel width 2783 * from XChannel and the guard interval 2784 * information from Flags, at least on 2785 * FreeBSD? 2786 */ 2787 ND_PRINT("MCS %u ", rate & 0x7f); 2788 } else 2789 ND_PRINT("%2.1f Mb/s ", .5 * rate); 2790 break; 2791 } 2792 2793 case IEEE80211_RADIOTAP_CHANNEL: { 2794 uint16_t frequency; 2795 uint16_t flags; 2796 2797 rc = nd_cpack_uint16(ndo, s, &frequency); 2798 if (rc != 0) 2799 goto trunc; 2800 rc = nd_cpack_uint16(ndo, s, &flags); 2801 if (rc != 0) 2802 goto trunc; 2803 /* 2804 * If CHANNEL and XCHANNEL are both present, skip 2805 * CHANNEL. 2806 */ 2807 if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL)) 2808 break; 2809 print_chaninfo(ndo, frequency, flags, presentflags); 2810 break; 2811 } 2812 2813 case IEEE80211_RADIOTAP_FHSS: { 2814 uint8_t hopset; 2815 uint8_t hoppat; 2816 2817 rc = nd_cpack_uint8(ndo, s, &hopset); 2818 if (rc != 0) 2819 goto trunc; 2820 rc = nd_cpack_uint8(ndo, s, &hoppat); 2821 if (rc != 0) 2822 goto trunc; 2823 ND_PRINT("fhset %u fhpat %u ", hopset, hoppat); 2824 break; 2825 } 2826 2827 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: { 2828 int8_t dbm_antsignal; 2829 2830 rc = nd_cpack_int8(ndo, s, &dbm_antsignal); 2831 if (rc != 0) 2832 goto trunc; 2833 ND_PRINT("%ddBm signal ", dbm_antsignal); 2834 break; 2835 } 2836 2837 case IEEE80211_RADIOTAP_DBM_ANTNOISE: { 2838 int8_t dbm_antnoise; 2839 2840 rc = nd_cpack_int8(ndo, s, &dbm_antnoise); 2841 if (rc != 0) 2842 goto trunc; 2843 ND_PRINT("%ddBm noise ", dbm_antnoise); 2844 break; 2845 } 2846 2847 case IEEE80211_RADIOTAP_LOCK_QUALITY: { 2848 uint16_t lock_quality; 2849 2850 rc = nd_cpack_uint16(ndo, s, &lock_quality); 2851 if (rc != 0) 2852 goto trunc; 2853 ND_PRINT("%u sq ", lock_quality); 2854 break; 2855 } 2856 2857 case IEEE80211_RADIOTAP_TX_ATTENUATION: { 2858 int16_t tx_attenuation; 2859 2860 rc = nd_cpack_int16(ndo, s, &tx_attenuation); 2861 if (rc != 0) 2862 goto trunc; 2863 ND_PRINT("%d tx power ", -tx_attenuation); 2864 break; 2865 } 2866 2867 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: { 2868 int8_t db_tx_attenuation; 2869 2870 rc = nd_cpack_int8(ndo, s, &db_tx_attenuation); 2871 if (rc != 0) 2872 goto trunc; 2873 ND_PRINT("%ddB tx attenuation ", -db_tx_attenuation); 2874 break; 2875 } 2876 2877 case IEEE80211_RADIOTAP_DBM_TX_POWER: { 2878 int8_t dbm_tx_power; 2879 2880 rc = nd_cpack_int8(ndo, s, &dbm_tx_power); 2881 if (rc != 0) 2882 goto trunc; 2883 ND_PRINT("%ddBm tx power ", dbm_tx_power); 2884 break; 2885 } 2886 2887 case IEEE80211_RADIOTAP_ANTENNA: { 2888 uint8_t antenna; 2889 2890 rc = nd_cpack_uint8(ndo, s, &antenna); 2891 if (rc != 0) 2892 goto trunc; 2893 ND_PRINT("antenna %u ", antenna); 2894 break; 2895 } 2896 2897 case IEEE80211_RADIOTAP_DB_ANTSIGNAL: { 2898 uint8_t db_antsignal; 2899 2900 rc = nd_cpack_uint8(ndo, s, &db_antsignal); 2901 if (rc != 0) 2902 goto trunc; 2903 ND_PRINT("%udB signal ", db_antsignal); 2904 break; 2905 } 2906 2907 case IEEE80211_RADIOTAP_DB_ANTNOISE: { 2908 uint8_t db_antnoise; 2909 2910 rc = nd_cpack_uint8(ndo, s, &db_antnoise); 2911 if (rc != 0) 2912 goto trunc; 2913 ND_PRINT("%udB noise ", db_antnoise); 2914 break; 2915 } 2916 2917 case IEEE80211_RADIOTAP_RX_FLAGS: { 2918 uint16_t rx_flags; 2919 2920 rc = nd_cpack_uint16(ndo, s, &rx_flags); 2921 if (rc != 0) 2922 goto trunc; 2923 /* Do nothing for now */ 2924 break; 2925 } 2926 2927 case IEEE80211_RADIOTAP_XCHANNEL: { 2928 uint32_t flags; 2929 uint16_t frequency; 2930 uint8_t channel; 2931 uint8_t maxpower; 2932 2933 rc = nd_cpack_uint32(ndo, s, &flags); 2934 if (rc != 0) 2935 goto trunc; 2936 rc = nd_cpack_uint16(ndo, s, &frequency); 2937 if (rc != 0) 2938 goto trunc; 2939 rc = nd_cpack_uint8(ndo, s, &channel); 2940 if (rc != 0) 2941 goto trunc; 2942 rc = nd_cpack_uint8(ndo, s, &maxpower); 2943 if (rc != 0) 2944 goto trunc; 2945 print_chaninfo(ndo, frequency, flags, presentflags); 2946 break; 2947 } 2948 2949 case IEEE80211_RADIOTAP_MCS: { 2950 uint8_t known; 2951 uint8_t flags; 2952 uint8_t mcs_index; 2953 static const char *ht_bandwidth[4] = { 2954 "20 MHz", 2955 "40 MHz", 2956 "20 MHz (L)", 2957 "20 MHz (U)" 2958 }; 2959 float htrate; 2960 2961 rc = nd_cpack_uint8(ndo, s, &known); 2962 if (rc != 0) 2963 goto trunc; 2964 rc = nd_cpack_uint8(ndo, s, &flags); 2965 if (rc != 0) 2966 goto trunc; 2967 rc = nd_cpack_uint8(ndo, s, &mcs_index); 2968 if (rc != 0) 2969 goto trunc; 2970 if (known & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) { 2971 /* 2972 * We know the MCS index. 2973 */ 2974 if (mcs_index <= MAX_MCS_INDEX) { 2975 /* 2976 * And it's in-range. 2977 */ 2978 if (known & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) { 2979 /* 2980 * And we know both the bandwidth and 2981 * the guard interval, so we can look 2982 * up the rate. 2983 */ 2984 htrate = 2985 ieee80211_float_htrates 2986 [mcs_index] 2987 [((flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] 2988 [((flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)]; 2989 } else { 2990 /* 2991 * We don't know both the bandwidth 2992 * and the guard interval, so we can 2993 * only report the MCS index. 2994 */ 2995 htrate = 0.0; 2996 } 2997 } else { 2998 /* 2999 * The MCS value is out of range. 3000 */ 3001 htrate = 0.0; 3002 } 3003 if (htrate != 0.0) { 3004 /* 3005 * We have the rate. 3006 * Print it. 3007 */ 3008 ND_PRINT("%.1f Mb/s MCS %u ", htrate, mcs_index); 3009 } else { 3010 /* 3011 * We at least have the MCS index. 3012 * Print it. 3013 */ 3014 ND_PRINT("MCS %u ", mcs_index); 3015 } 3016 } 3017 if (known & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) { 3018 ND_PRINT("%s ", 3019 ht_bandwidth[flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]); 3020 } 3021 if (known & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) { 3022 ND_PRINT("%s GI ", 3023 (flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 3024 "short" : "long"); 3025 } 3026 if (known & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) { 3027 ND_PRINT("%s ", 3028 (flags & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ? 3029 "greenfield" : "mixed"); 3030 } 3031 if (known & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) { 3032 ND_PRINT("%s FEC ", 3033 (flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ? 3034 "LDPC" : "BCC"); 3035 } 3036 if (known & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) { 3037 ND_PRINT("RX-STBC%u ", 3038 (flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT); 3039 } 3040 break; 3041 } 3042 3043 case IEEE80211_RADIOTAP_AMPDU_STATUS: { 3044 uint32_t reference_num; 3045 uint16_t flags; 3046 uint8_t delim_crc; 3047 uint8_t reserved; 3048 3049 rc = nd_cpack_uint32(ndo, s, &reference_num); 3050 if (rc != 0) 3051 goto trunc; 3052 rc = nd_cpack_uint16(ndo, s, &flags); 3053 if (rc != 0) 3054 goto trunc; 3055 rc = nd_cpack_uint8(ndo, s, &delim_crc); 3056 if (rc != 0) 3057 goto trunc; 3058 rc = nd_cpack_uint8(ndo, s, &reserved); 3059 if (rc != 0) 3060 goto trunc; 3061 /* Do nothing for now */ 3062 break; 3063 } 3064 3065 case IEEE80211_RADIOTAP_VHT: { 3066 uint16_t known; 3067 uint8_t flags; 3068 uint8_t bandwidth; 3069 uint8_t mcs_nss[4]; 3070 uint8_t coding; 3071 uint8_t group_id; 3072 uint16_t partial_aid; 3073 static const char *vht_bandwidth[32] = { 3074 "20 MHz", 3075 "40 MHz", 3076 "20 MHz (L)", 3077 "20 MHz (U)", 3078 "80 MHz", 3079 "80 MHz (L)", 3080 "80 MHz (U)", 3081 "80 MHz (LL)", 3082 "80 MHz (LU)", 3083 "80 MHz (UL)", 3084 "80 MHz (UU)", 3085 "160 MHz", 3086 "160 MHz (L)", 3087 "160 MHz (U)", 3088 "160 MHz (LL)", 3089 "160 MHz (LU)", 3090 "160 MHz (UL)", 3091 "160 MHz (UU)", 3092 "160 MHz (LLL)", 3093 "160 MHz (LLU)", 3094 "160 MHz (LUL)", 3095 "160 MHz (UUU)", 3096 "160 MHz (ULL)", 3097 "160 MHz (ULU)", 3098 "160 MHz (UUL)", 3099 "160 MHz (UUU)", 3100 "unknown (26)", 3101 "unknown (27)", 3102 "unknown (28)", 3103 "unknown (29)", 3104 "unknown (30)", 3105 "unknown (31)" 3106 }; 3107 3108 rc = nd_cpack_uint16(ndo, s, &known); 3109 if (rc != 0) 3110 goto trunc; 3111 rc = nd_cpack_uint8(ndo, s, &flags); 3112 if (rc != 0) 3113 goto trunc; 3114 rc = nd_cpack_uint8(ndo, s, &bandwidth); 3115 if (rc != 0) 3116 goto trunc; 3117 for (i = 0; i < 4; i++) { 3118 rc = nd_cpack_uint8(ndo, s, &mcs_nss[i]); 3119 if (rc != 0) 3120 goto trunc; 3121 } 3122 rc = nd_cpack_uint8(ndo, s, &coding); 3123 if (rc != 0) 3124 goto trunc; 3125 rc = nd_cpack_uint8(ndo, s, &group_id); 3126 if (rc != 0) 3127 goto trunc; 3128 rc = nd_cpack_uint16(ndo, s, &partial_aid); 3129 if (rc != 0) 3130 goto trunc; 3131 for (i = 0; i < 4; i++) { 3132 u_int nss, mcs; 3133 nss = mcs_nss[i] & IEEE80211_RADIOTAP_VHT_NSS_MASK; 3134 mcs = (mcs_nss[i] & IEEE80211_RADIOTAP_VHT_MCS_MASK) >> IEEE80211_RADIOTAP_VHT_MCS_SHIFT; 3135 3136 if (nss == 0) 3137 continue; 3138 3139 ND_PRINT("User %u MCS %u ", i, mcs); 3140 ND_PRINT("%s FEC ", 3141 (coding & (IEEE80211_RADIOTAP_CODING_LDPC_USERn << i)) ? 3142 "LDPC" : "BCC"); 3143 } 3144 if (known & IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN) { 3145 ND_PRINT("%s ", 3146 vht_bandwidth[bandwidth & IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK]); 3147 } 3148 if (known & IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN) { 3149 ND_PRINT("%s GI ", 3150 (flags & IEEE80211_RADIOTAP_VHT_SHORT_GI) ? 3151 "short" : "long"); 3152 } 3153 break; 3154 } 3155 3156 default: 3157 /* this bit indicates a field whose 3158 * size we do not know, so we cannot 3159 * proceed. Just print the bit number. 3160 */ 3161 ND_PRINT("[bit %u] ", bit); 3162 return -1; 3163 } 3164 3165 return 0; 3166 3167 trunc: 3168 nd_print_trunc(ndo); 3169 return rc; 3170 } 3171 3172 3173 static int 3174 print_in_radiotap_namespace(netdissect_options *ndo, 3175 struct cpack_state *s, uint8_t *flags, 3176 uint32_t presentflags, int bit0) 3177 { 3178 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x))) 3179 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x))) 3180 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x))) 3181 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x))) 3182 #define BITNO_2(x) (((x) & 2) ? 1 : 0) 3183 uint32_t present, next_present; 3184 int bitno; 3185 enum ieee80211_radiotap_type bit; 3186 int rc; 3187 3188 for (present = presentflags; present; present = next_present) { 3189 /* 3190 * Clear the least significant bit that is set. 3191 */ 3192 next_present = present & (present - 1); 3193 3194 /* 3195 * Get the bit number, within this presence word, 3196 * of the remaining least significant bit that 3197 * is set. 3198 */ 3199 bitno = BITNO_32(present ^ next_present); 3200 3201 /* 3202 * Stop if this is one of the "same meaning 3203 * in all presence flags" bits. 3204 */ 3205 if (bitno >= IEEE80211_RADIOTAP_NAMESPACE) 3206 break; 3207 3208 /* 3209 * Get the radiotap bit number of that bit. 3210 */ 3211 bit = (enum ieee80211_radiotap_type)(bit0 + bitno); 3212 3213 rc = print_radiotap_field(ndo, s, bit, flags, presentflags); 3214 if (rc != 0) 3215 return rc; 3216 } 3217 3218 return 0; 3219 } 3220 3221 u_int 3222 ieee802_11_radio_print(netdissect_options *ndo, 3223 const u_char *p, u_int length, u_int caplen) 3224 { 3225 #define BIT(n) (1U << n) 3226 #define IS_EXTENDED(__p) \ 3227 (GET_LE_U_4(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0 3228 3229 struct cpack_state cpacker; 3230 const struct ieee80211_radiotap_header *hdr; 3231 uint32_t presentflags; 3232 const nd_uint32_t *presentp, *last_presentp; 3233 int vendor_namespace; 3234 uint8_t vendor_oui[3]; 3235 uint8_t vendor_subnamespace; 3236 uint16_t skip_length; 3237 int bit0; 3238 u_int len; 3239 uint8_t flags; 3240 int pad; 3241 u_int fcslen; 3242 3243 ndo->ndo_protocol = "802.11_radio"; 3244 if (caplen < sizeof(*hdr)) { 3245 nd_print_trunc(ndo); 3246 return caplen; 3247 } 3248 3249 hdr = (const struct ieee80211_radiotap_header *)p; 3250 3251 len = GET_LE_U_2(hdr->it_len); 3252 if (len < sizeof(*hdr)) { 3253 /* 3254 * The length is the length of the entire header, so 3255 * it must be as large as the fixed-length part of 3256 * the header. 3257 */ 3258 nd_print_trunc(ndo); 3259 return caplen; 3260 } 3261 3262 /* 3263 * If we don't have the entire radiotap header, just give up. 3264 */ 3265 if (caplen < len) { 3266 nd_print_trunc(ndo); 3267 return caplen; 3268 } 3269 nd_cpack_init(&cpacker, (const uint8_t *)hdr, len); /* align against header start */ 3270 nd_cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */ 3271 for (last_presentp = &hdr->it_present; 3272 (const u_char*)(last_presentp + 1) <= p + len && 3273 IS_EXTENDED(last_presentp); 3274 last_presentp++) 3275 nd_cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */ 3276 3277 /* are there more bitmap extensions than bytes in header? */ 3278 if ((const u_char*)(last_presentp + 1) > p + len) { 3279 nd_print_trunc(ndo); 3280 return caplen; 3281 } 3282 3283 /* 3284 * Start out at the beginning of the default radiotap namespace. 3285 */ 3286 bit0 = 0; 3287 vendor_namespace = 0; 3288 memset(vendor_oui, 0, 3); 3289 vendor_subnamespace = 0; 3290 skip_length = 0; 3291 /* Assume no flags */ 3292 flags = 0; 3293 /* Assume no Atheros padding between 802.11 header and body */ 3294 pad = 0; 3295 /* Assume no FCS at end of frame */ 3296 fcslen = 0; 3297 for (presentp = &hdr->it_present; presentp <= last_presentp; 3298 presentp++) { 3299 presentflags = GET_LE_U_4(presentp); 3300 3301 /* 3302 * If this is a vendor namespace, we don't handle it. 3303 */ 3304 if (vendor_namespace) { 3305 /* 3306 * Skip past the stuff we don't understand. 3307 * If we add support for any vendor namespaces, 3308 * it'd be added here; use vendor_oui and 3309 * vendor_subnamespace to interpret the fields. 3310 */ 3311 if (nd_cpack_advance(&cpacker, skip_length) != 0) { 3312 /* 3313 * Ran out of space in the packet. 3314 */ 3315 break; 3316 } 3317 3318 /* 3319 * We've skipped it all; nothing more to 3320 * skip. 3321 */ 3322 skip_length = 0; 3323 } else { 3324 if (print_in_radiotap_namespace(ndo, &cpacker, 3325 &flags, presentflags, bit0) != 0) { 3326 /* 3327 * Fatal error - can't process anything 3328 * more in the radiotap header. 3329 */ 3330 break; 3331 } 3332 } 3333 3334 /* 3335 * Handle the namespace switch bits; we've already handled 3336 * the extension bit in all but the last word above. 3337 */ 3338 switch (presentflags & 3339 (BIT(IEEE80211_RADIOTAP_NAMESPACE)|BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE))) { 3340 3341 case 0: 3342 /* 3343 * We're not changing namespaces. 3344 * advance to the next 32 bits in the current 3345 * namespace. 3346 */ 3347 bit0 += 32; 3348 break; 3349 3350 case BIT(IEEE80211_RADIOTAP_NAMESPACE): 3351 /* 3352 * We're switching to the radiotap namespace. 3353 * Reset the presence-bitmap index to 0, and 3354 * reset the namespace to the default radiotap 3355 * namespace. 3356 */ 3357 bit0 = 0; 3358 vendor_namespace = 0; 3359 memset(vendor_oui, 0, 3); 3360 vendor_subnamespace = 0; 3361 skip_length = 0; 3362 break; 3363 3364 case BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE): 3365 /* 3366 * We're switching to a vendor namespace. 3367 * Reset the presence-bitmap index to 0, 3368 * note that we're in a vendor namespace, 3369 * and fetch the fields of the Vendor Namespace 3370 * item. 3371 */ 3372 bit0 = 0; 3373 vendor_namespace = 1; 3374 if ((nd_cpack_align_and_reserve(&cpacker, 2)) == NULL) { 3375 nd_print_trunc(ndo); 3376 break; 3377 } 3378 if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[0]) != 0) { 3379 nd_print_trunc(ndo); 3380 break; 3381 } 3382 if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[1]) != 0) { 3383 nd_print_trunc(ndo); 3384 break; 3385 } 3386 if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[2]) != 0) { 3387 nd_print_trunc(ndo); 3388 break; 3389 } 3390 if (nd_cpack_uint8(ndo, &cpacker, &vendor_subnamespace) != 0) { 3391 nd_print_trunc(ndo); 3392 break; 3393 } 3394 if (nd_cpack_uint16(ndo, &cpacker, &skip_length) != 0) { 3395 nd_print_trunc(ndo); 3396 break; 3397 } 3398 break; 3399 3400 default: 3401 /* 3402 * Illegal combination. The behavior in this 3403 * case is undefined by the radiotap spec; we 3404 * just ignore both bits. 3405 */ 3406 break; 3407 } 3408 } 3409 3410 if (flags & IEEE80211_RADIOTAP_F_DATAPAD) 3411 pad = 1; /* Atheros padding */ 3412 if (flags & IEEE80211_RADIOTAP_F_FCS) 3413 fcslen = 4; /* FCS at end of packet */ 3414 return len + ieee802_11_print(ndo, p + len, length - len, caplen - len, pad, 3415 fcslen); 3416 #undef BITNO_32 3417 #undef BITNO_16 3418 #undef BITNO_8 3419 #undef BITNO_4 3420 #undef BITNO_2 3421 #undef BIT 3422 } 3423 3424 static u_int 3425 ieee802_11_radio_avs_print(netdissect_options *ndo, 3426 const u_char *p, u_int length, u_int caplen) 3427 { 3428 uint32_t caphdr_len; 3429 3430 ndo->ndo_protocol = "802.11_radio_avs"; 3431 if (caplen < 8) { 3432 nd_print_trunc(ndo); 3433 return caplen; 3434 } 3435 3436 caphdr_len = GET_BE_U_4(p + 4); 3437 if (caphdr_len < 8) { 3438 /* 3439 * Yow! The capture header length is claimed not 3440 * to be large enough to include even the version 3441 * cookie or capture header length! 3442 */ 3443 nd_print_trunc(ndo); 3444 return caplen; 3445 } 3446 3447 if (caplen < caphdr_len) { 3448 nd_print_trunc(ndo); 3449 return caplen; 3450 } 3451 3452 return caphdr_len + ieee802_11_print(ndo, p + caphdr_len, 3453 length - caphdr_len, caplen - caphdr_len, 0, 0); 3454 } 3455 3456 #define PRISM_HDR_LEN 144 3457 3458 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000 3459 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001 3460 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002 3461 3462 /* 3463 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header, 3464 * containing information such as radio information, which we 3465 * currently ignore. 3466 * 3467 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or 3468 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS 3469 * (currently, on Linux, there's no ARPHRD_ type for 3470 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM 3471 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for 3472 * the AVS header, and the first 4 bytes of the header are used to 3473 * indicate whether it's a Prism header or an AVS header). 3474 */ 3475 void 3476 prism_if_print(netdissect_options *ndo, 3477 const struct pcap_pkthdr *h, const u_char *p) 3478 { 3479 u_int caplen = h->caplen; 3480 u_int length = h->len; 3481 uint32_t msgcode; 3482 3483 ndo->ndo_protocol = "prism"; 3484 if (caplen < 4) { 3485 nd_print_trunc(ndo); 3486 ndo->ndo_ll_hdr_len += caplen; 3487 return; 3488 } 3489 3490 msgcode = GET_BE_U_4(p); 3491 if (msgcode == WLANCAP_MAGIC_COOKIE_V1 || 3492 msgcode == WLANCAP_MAGIC_COOKIE_V2) { 3493 ndo->ndo_ll_hdr_len += ieee802_11_radio_avs_print(ndo, p, length, caplen); 3494 return; 3495 } 3496 3497 if (caplen < PRISM_HDR_LEN) { 3498 nd_print_trunc(ndo); 3499 ndo->ndo_ll_hdr_len += caplen; 3500 return; 3501 } 3502 3503 p += PRISM_HDR_LEN; 3504 length -= PRISM_HDR_LEN; 3505 caplen -= PRISM_HDR_LEN; 3506 ndo->ndo_ll_hdr_len += PRISM_HDR_LEN; 3507 ndo->ndo_ll_hdr_len += ieee802_11_print(ndo, p, length, caplen, 0, 0); 3508 } 3509 3510 /* 3511 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra 3512 * header, containing information such as radio information. 3513 */ 3514 void 3515 ieee802_11_radio_if_print(netdissect_options *ndo, 3516 const struct pcap_pkthdr *h, const u_char *p) 3517 { 3518 ndo->ndo_protocol = "802.11_radio"; 3519 ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, h->len, h->caplen); 3520 } 3521 3522 /* 3523 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an 3524 * extra header, containing information such as radio information, 3525 * which we currently ignore. 3526 */ 3527 void 3528 ieee802_11_radio_avs_if_print(netdissect_options *ndo, 3529 const struct pcap_pkthdr *h, const u_char *p) 3530 { 3531 ndo->ndo_protocol = "802.11_radio_avs"; 3532 ndo->ndo_ll_hdr_len += ieee802_11_radio_avs_print(ndo, p, h->len, h->caplen); 3533 } 3534