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