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