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.9 2019/10/01 16:06:16 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 if (caplen < hdrlen + 1) { 2067 ND_PRINT((ndo, "%s", tstr)); 2068 return hdrlen; 2069 } 2070 meshdrlen = extract_mesh_header_length(p+hdrlen); 2071 hdrlen += meshdrlen; 2072 } else 2073 meshdrlen = 0; 2074 2075 if (caplen < hdrlen) { 2076 ND_PRINT((ndo, "%s", tstr)); 2077 return hdrlen; 2078 } 2079 2080 if (ndo->ndo_eflag) 2081 ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen); 2082 2083 /* 2084 * Go past the 802.11 header. 2085 */ 2086 length -= hdrlen; 2087 caplen -= hdrlen; 2088 p += hdrlen; 2089 2090 src.addr_string = etheraddr_string; 2091 dst.addr_string = etheraddr_string; 2092 switch (FC_TYPE(fc)) { 2093 case T_MGMT: 2094 get_mgmt_src_dst_mac(p - hdrlen, &src.addr, &dst.addr); 2095 if (!mgmt_body_print(ndo, fc, src.addr, p, length)) { 2096 ND_PRINT((ndo, "%s", tstr)); 2097 return hdrlen; 2098 } 2099 break; 2100 case T_CTRL: 2101 if (!ctrl_body_print(ndo, fc, p - hdrlen)) { 2102 ND_PRINT((ndo, "%s", tstr)); 2103 return hdrlen; 2104 } 2105 break; 2106 case T_DATA: 2107 if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc))) 2108 return hdrlen; /* no-data frame */ 2109 /* There may be a problem w/ AP not having this bit set */ 2110 if (FC_PROTECTED(fc)) { 2111 ND_PRINT((ndo, "Data")); 2112 if (!wep_print(ndo, p)) { 2113 ND_PRINT((ndo, "%s", tstr)); 2114 return hdrlen; 2115 } 2116 } else { 2117 get_data_src_dst_mac(fc, p - hdrlen, &src.addr, &dst.addr); 2118 llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst); 2119 if (llc_hdrlen < 0) { 2120 /* 2121 * Some kinds of LLC packet we cannot 2122 * handle intelligently 2123 */ 2124 if (!ndo->ndo_suppress_default_print) 2125 ND_DEFAULTPRINT(p, caplen); 2126 llc_hdrlen = -llc_hdrlen; 2127 } 2128 hdrlen += llc_hdrlen; 2129 } 2130 break; 2131 default: 2132 /* We shouldn't get here - we should already have quit */ 2133 break; 2134 } 2135 2136 return hdrlen; 2137 } 2138 2139 /* 2140 * This is the top level routine of the printer. 'p' points 2141 * to the 802.11 header of the packet, 'h->ts' is the timestamp, 2142 * 'h->len' is the length of the packet off the wire, and 'h->caplen' 2143 * is the number of bytes actually captured. 2144 */ 2145 u_int 2146 ieee802_11_if_print(netdissect_options *ndo, 2147 const struct pcap_pkthdr *h, const u_char *p) 2148 { 2149 return ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0); 2150 } 2151 2152 2153 /* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */ 2154 /* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp */ 2155 2156 /*- 2157 * Copyright (c) 2003, 2004 David Young. All rights reserved. 2158 * 2159 * Redistribution and use in source and binary forms, with or without 2160 * modification, are permitted provided that the following conditions 2161 * are met: 2162 * 1. Redistributions of source code must retain the above copyright 2163 * notice, this list of conditions and the following disclaimer. 2164 * 2. Redistributions in binary form must reproduce the above copyright 2165 * notice, this list of conditions and the following disclaimer in the 2166 * documentation and/or other materials provided with the distribution. 2167 * 3. The name of David Young may not be used to endorse or promote 2168 * products derived from this software without specific prior 2169 * written permission. 2170 * 2171 * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY 2172 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 2173 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 2174 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID 2175 * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2176 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2177 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2178 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 2179 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2180 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2181 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 2182 * OF SUCH DAMAGE. 2183 */ 2184 2185 /* A generic radio capture format is desirable. It must be 2186 * rigidly defined (e.g., units for fields should be given), 2187 * and easily extensible. 2188 * 2189 * The following is an extensible radio capture format. It is 2190 * based on a bitmap indicating which fields are present. 2191 * 2192 * I am trying to describe precisely what the application programmer 2193 * should expect in the following, and for that reason I tell the 2194 * units and origin of each measurement (where it applies), or else I 2195 * use sufficiently weaselly language ("is a monotonically nondecreasing 2196 * function of...") that I cannot set false expectations for lawyerly 2197 * readers. 2198 */ 2199 2200 /* 2201 * The radio capture header precedes the 802.11 header. 2202 * 2203 * Note well: all radiotap fields are little-endian. 2204 */ 2205 struct ieee80211_radiotap_header { 2206 uint8_t it_version; /* Version 0. Only increases 2207 * for drastic changes, 2208 * introduction of compatible 2209 * new fields does not count. 2210 */ 2211 uint8_t it_pad; 2212 uint16_t it_len; /* length of the whole 2213 * header in bytes, including 2214 * it_version, it_pad, 2215 * it_len, and data fields. 2216 */ 2217 uint32_t it_present; /* A bitmap telling which 2218 * fields are present. Set bit 31 2219 * (0x80000000) to extend the 2220 * bitmap by another 32 bits. 2221 * Additional extensions are made 2222 * by setting bit 31. 2223 */ 2224 }; 2225 2226 /* Name Data type Units 2227 * ---- --------- ----- 2228 * 2229 * IEEE80211_RADIOTAP_TSFT uint64_t microseconds 2230 * 2231 * Value in microseconds of the MAC's 64-bit 802.11 Time 2232 * Synchronization Function timer when the first bit of the 2233 * MPDU arrived at the MAC. For received frames, only. 2234 * 2235 * IEEE80211_RADIOTAP_CHANNEL 2 x uint16_t MHz, bitmap 2236 * 2237 * Tx/Rx frequency in MHz, followed by flags (see below). 2238 * Note that IEEE80211_RADIOTAP_XCHANNEL must be used to 2239 * represent an HT channel as there is not enough room in 2240 * the flags word. 2241 * 2242 * IEEE80211_RADIOTAP_FHSS uint16_t see below 2243 * 2244 * For frequency-hopping radios, the hop set (first byte) 2245 * and pattern (second byte). 2246 * 2247 * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s or index 2248 * 2249 * Tx/Rx data rate. If bit 0x80 is set then it represents an 2250 * an MCS index and not an IEEE rate. 2251 * 2252 * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from 2253 * one milliwatt (dBm) 2254 * 2255 * RF signal power at the antenna, decibel difference from 2256 * one milliwatt. 2257 * 2258 * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from 2259 * one milliwatt (dBm) 2260 * 2261 * RF noise power at the antenna, decibel difference from one 2262 * milliwatt. 2263 * 2264 * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB) 2265 * 2266 * RF signal power at the antenna, decibel difference from an 2267 * arbitrary, fixed reference. 2268 * 2269 * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB) 2270 * 2271 * RF noise power at the antenna, decibel difference from an 2272 * arbitrary, fixed reference point. 2273 * 2274 * IEEE80211_RADIOTAP_LOCK_QUALITY uint16_t unitless 2275 * 2276 * Quality of Barker code lock. Unitless. Monotonically 2277 * nondecreasing with "better" lock strength. Called "Signal 2278 * Quality" in datasheets. (Is there a standard way to measure 2279 * this?) 2280 * 2281 * IEEE80211_RADIOTAP_TX_ATTENUATION uint16_t unitless 2282 * 2283 * Transmit power expressed as unitless distance from max 2284 * power set at factory calibration. 0 is max power. 2285 * Monotonically nondecreasing with lower power levels. 2286 * 2287 * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t decibels (dB) 2288 * 2289 * Transmit power expressed as decibel distance from max power 2290 * set at factory calibration. 0 is max power. Monotonically 2291 * nondecreasing with lower power levels. 2292 * 2293 * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from 2294 * one milliwatt (dBm) 2295 * 2296 * Transmit power expressed as dBm (decibels from a 1 milliwatt 2297 * reference). This is the absolute power level measured at 2298 * the antenna port. 2299 * 2300 * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap 2301 * 2302 * Properties of transmitted and received frames. See flags 2303 * defined below. 2304 * 2305 * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index 2306 * 2307 * Unitless indication of the Rx/Tx antenna for this packet. 2308 * The first antenna is antenna 0. 2309 * 2310 * IEEE80211_RADIOTAP_RX_FLAGS uint16_t bitmap 2311 * 2312 * Properties of received frames. See flags defined below. 2313 * 2314 * IEEE80211_RADIOTAP_XCHANNEL uint32_t bitmap 2315 * uint16_t MHz 2316 * uint8_t channel number 2317 * uint8_t .5 dBm 2318 * 2319 * Extended channel specification: flags (see below) followed by 2320 * frequency in MHz, the corresponding IEEE channel number, and 2321 * finally the maximum regulatory transmit power cap in .5 dBm 2322 * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL 2323 * and only one of the two should be present. 2324 * 2325 * IEEE80211_RADIOTAP_MCS uint8_t known 2326 * uint8_t flags 2327 * uint8_t mcs 2328 * 2329 * Bitset indicating which fields have known values, followed 2330 * by bitset of flag values, followed by the MCS rate index as 2331 * in IEEE 802.11n. 2332 * 2333 * 2334 * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless 2335 * 2336 * Contains the AMPDU information for the subframe. 2337 * 2338 * IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16 2339 * 2340 * Contains VHT information about this frame. 2341 * 2342 * IEEE80211_RADIOTAP_VENDOR_NAMESPACE 2343 * uint8_t OUI[3] 2344 * uint8_t subspace 2345 * uint16_t length 2346 * 2347 * The Vendor Namespace Field contains three sub-fields. The first 2348 * sub-field is 3 bytes long. It contains the vendor's IEEE 802 2349 * Organizationally Unique Identifier (OUI). The fourth byte is a 2350 * vendor-specific "namespace selector." 2351 * 2352 */ 2353 enum ieee80211_radiotap_type { 2354 IEEE80211_RADIOTAP_TSFT = 0, 2355 IEEE80211_RADIOTAP_FLAGS = 1, 2356 IEEE80211_RADIOTAP_RATE = 2, 2357 IEEE80211_RADIOTAP_CHANNEL = 3, 2358 IEEE80211_RADIOTAP_FHSS = 4, 2359 IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, 2360 IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, 2361 IEEE80211_RADIOTAP_LOCK_QUALITY = 7, 2362 IEEE80211_RADIOTAP_TX_ATTENUATION = 8, 2363 IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, 2364 IEEE80211_RADIOTAP_DBM_TX_POWER = 10, 2365 IEEE80211_RADIOTAP_ANTENNA = 11, 2366 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, 2367 IEEE80211_RADIOTAP_DB_ANTNOISE = 13, 2368 IEEE80211_RADIOTAP_RX_FLAGS = 14, 2369 /* NB: gap for netbsd definitions */ 2370 IEEE80211_RADIOTAP_XCHANNEL = 18, 2371 IEEE80211_RADIOTAP_MCS = 19, 2372 IEEE80211_RADIOTAP_AMPDU_STATUS = 20, 2373 IEEE80211_RADIOTAP_VHT = 21, 2374 IEEE80211_RADIOTAP_NAMESPACE = 29, 2375 IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30, 2376 IEEE80211_RADIOTAP_EXT = 31 2377 }; 2378 2379 /* channel attributes */ 2380 #define IEEE80211_CHAN_TURBO 0x00010 /* Turbo channel */ 2381 #define IEEE80211_CHAN_CCK 0x00020 /* CCK channel */ 2382 #define IEEE80211_CHAN_OFDM 0x00040 /* OFDM channel */ 2383 #define IEEE80211_CHAN_2GHZ 0x00080 /* 2 GHz spectrum channel. */ 2384 #define IEEE80211_CHAN_5GHZ 0x00100 /* 5 GHz spectrum channel */ 2385 #define IEEE80211_CHAN_PASSIVE 0x00200 /* Only passive scan allowed */ 2386 #define IEEE80211_CHAN_DYN 0x00400 /* Dynamic CCK-OFDM channel */ 2387 #define IEEE80211_CHAN_GFSK 0x00800 /* GFSK channel (FHSS PHY) */ 2388 #define IEEE80211_CHAN_GSM 0x01000 /* 900 MHz spectrum channel */ 2389 #define IEEE80211_CHAN_STURBO 0x02000 /* 11a static turbo channel only */ 2390 #define IEEE80211_CHAN_HALF 0x04000 /* Half rate channel */ 2391 #define IEEE80211_CHAN_QUARTER 0x08000 /* Quarter rate channel */ 2392 #define IEEE80211_CHAN_HT20 0x10000 /* HT 20 channel */ 2393 #define IEEE80211_CHAN_HT40U 0x20000 /* HT 40 channel w/ ext above */ 2394 #define IEEE80211_CHAN_HT40D 0x40000 /* HT 40 channel w/ ext below */ 2395 2396 /* Useful combinations of channel characteristics, borrowed from Ethereal */ 2397 #define IEEE80211_CHAN_A \ 2398 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) 2399 #define IEEE80211_CHAN_B \ 2400 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) 2401 #define IEEE80211_CHAN_G \ 2402 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) 2403 #define IEEE80211_CHAN_TA \ 2404 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO) 2405 #define IEEE80211_CHAN_TG \ 2406 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN | IEEE80211_CHAN_TURBO) 2407 2408 2409 /* For IEEE80211_RADIOTAP_FLAGS */ 2410 #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received 2411 * during CFP 2412 */ 2413 #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received 2414 * with short 2415 * preamble 2416 */ 2417 #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received 2418 * with WEP encryption 2419 */ 2420 #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received 2421 * with fragmentation 2422 */ 2423 #define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ 2424 #define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between 2425 * 802.11 header and payload 2426 * (to 32-bit boundary) 2427 */ 2428 #define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */ 2429 2430 /* For IEEE80211_RADIOTAP_RX_FLAGS */ 2431 #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ 2432 #define IEEE80211_RADIOTAP_F_RX_PLCP_CRC 0x0002 /* frame failed PLCP CRC check */ 2433 2434 /* For IEEE80211_RADIOTAP_MCS known */ 2435 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN 0x01 2436 #define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN 0x02 /* MCS index field */ 2437 #define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN 0x04 2438 #define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN 0x08 2439 #define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN 0x10 2440 #define IEEE80211_RADIOTAP_MCS_STBC_KNOWN 0x20 2441 #define IEEE80211_RADIOTAP_MCS_NESS_KNOWN 0x40 2442 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_1 0x80 2443 2444 /* For IEEE80211_RADIOTAP_MCS flags */ 2445 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK 0x03 2446 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20 0 2447 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 1 2448 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L 2 2449 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U 3 2450 #define IEEE80211_RADIOTAP_MCS_SHORT_GI 0x04 /* short guard interval */ 2451 #define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD 0x08 2452 #define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 2453 #define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60 2454 #define IEEE80211_RADIOTAP_MCS_STBC_1 1 2455 #define IEEE80211_RADIOTAP_MCS_STBC_2 2 2456 #define IEEE80211_RADIOTAP_MCS_STBC_3 3 2457 #define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5 2458 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_0 0x80 2459 2460 /* For IEEE80211_RADIOTAP_AMPDU_STATUS */ 2461 #define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001 2462 #define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN 0x0002 2463 #define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN 0x0004 2464 #define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008 2465 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 2466 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 2467 2468 /* For IEEE80211_RADIOTAP_VHT known */ 2469 #define IEEE80211_RADIOTAP_VHT_STBC_KNOWN 0x0001 2470 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA_KNOWN 0x0002 2471 #define IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN 0x0004 2472 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_DIS_KNOWN 0x0008 2473 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM_KNOWN 0x0010 2474 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED_KNOWN 0x0020 2475 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN 0x0040 2476 #define IEEE80211_RADIOTAP_VHT_GROUP_ID_KNOWN 0x0080 2477 #define IEEE80211_RADIOTAP_VHT_PARTIAL_AID_KNOWN 0x0100 2478 2479 /* For IEEE80211_RADIOTAP_VHT flags */ 2480 #define IEEE80211_RADIOTAP_VHT_STBC 0x01 2481 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA 0x02 2482 #define IEEE80211_RADIOTAP_VHT_SHORT_GI 0x04 2483 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_M10_9 0x08 2484 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM 0x10 2485 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED 0x20 2486 2487 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK 0x1f 2488 2489 #define IEEE80211_RADIOTAP_VHT_NSS_MASK 0x0f 2490 #define IEEE80211_RADIOTAP_VHT_MCS_MASK 0xf0 2491 #define IEEE80211_RADIOTAP_VHT_MCS_SHIFT 4 2492 2493 #define IEEE80211_RADIOTAP_CODING_LDPC_USERn 0x01 2494 2495 #define IEEE80211_CHAN_FHSS \ 2496 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK) 2497 #define IEEE80211_CHAN_A \ 2498 (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) 2499 #define IEEE80211_CHAN_B \ 2500 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) 2501 #define IEEE80211_CHAN_PUREG \ 2502 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM) 2503 #define IEEE80211_CHAN_G \ 2504 (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) 2505 2506 #define IS_CHAN_FHSS(flags) \ 2507 ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS) 2508 #define IS_CHAN_A(flags) \ 2509 ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A) 2510 #define IS_CHAN_B(flags) \ 2511 ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B) 2512 #define IS_CHAN_PUREG(flags) \ 2513 ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG) 2514 #define IS_CHAN_G(flags) \ 2515 ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G) 2516 #define IS_CHAN_ANYG(flags) \ 2517 (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags)) 2518 2519 static void 2520 print_chaninfo(netdissect_options *ndo, 2521 uint16_t freq, int flags, int presentflags) 2522 { 2523 ND_PRINT((ndo, "%u MHz", freq)); 2524 if (presentflags & (1 << IEEE80211_RADIOTAP_MCS)) { 2525 /* 2526 * We have the MCS field, so this is 11n, regardless 2527 * of what the channel flags say. 2528 */ 2529 ND_PRINT((ndo, " 11n")); 2530 } else { 2531 if (IS_CHAN_FHSS(flags)) 2532 ND_PRINT((ndo, " FHSS")); 2533 if (IS_CHAN_A(flags)) { 2534 if (flags & IEEE80211_CHAN_HALF) 2535 ND_PRINT((ndo, " 11a/10Mhz")); 2536 else if (flags & IEEE80211_CHAN_QUARTER) 2537 ND_PRINT((ndo, " 11a/5Mhz")); 2538 else 2539 ND_PRINT((ndo, " 11a")); 2540 } 2541 if (IS_CHAN_ANYG(flags)) { 2542 if (flags & IEEE80211_CHAN_HALF) 2543 ND_PRINT((ndo, " 11g/10Mhz")); 2544 else if (flags & IEEE80211_CHAN_QUARTER) 2545 ND_PRINT((ndo, " 11g/5Mhz")); 2546 else 2547 ND_PRINT((ndo, " 11g")); 2548 } else if (IS_CHAN_B(flags)) 2549 ND_PRINT((ndo, " 11b")); 2550 if (flags & IEEE80211_CHAN_TURBO) 2551 ND_PRINT((ndo, " Turbo")); 2552 } 2553 /* 2554 * These apply to 11n. 2555 */ 2556 if (flags & IEEE80211_CHAN_HT20) 2557 ND_PRINT((ndo, " ht/20")); 2558 else if (flags & IEEE80211_CHAN_HT40D) 2559 ND_PRINT((ndo, " ht/40-")); 2560 else if (flags & IEEE80211_CHAN_HT40U) 2561 ND_PRINT((ndo, " ht/40+")); 2562 ND_PRINT((ndo, " ")); 2563 } 2564 2565 static int 2566 print_radiotap_field(netdissect_options *ndo, 2567 struct cpack_state *s, uint32_t bit, uint8_t *flagsp, 2568 uint32_t presentflags) 2569 { 2570 u_int i; 2571 int rc; 2572 2573 switch (bit) { 2574 2575 case IEEE80211_RADIOTAP_TSFT: { 2576 uint64_t tsft; 2577 2578 rc = cpack_uint64(s, &tsft); 2579 if (rc != 0) 2580 goto trunc; 2581 ND_PRINT((ndo, "%" PRIu64 "us tsft ", tsft)); 2582 break; 2583 } 2584 2585 case IEEE80211_RADIOTAP_FLAGS: { 2586 uint8_t flagsval; 2587 2588 rc = cpack_uint8(s, &flagsval); 2589 if (rc != 0) 2590 goto trunc; 2591 *flagsp = flagsval; 2592 if (flagsval & IEEE80211_RADIOTAP_F_CFP) 2593 ND_PRINT((ndo, "cfp ")); 2594 if (flagsval & IEEE80211_RADIOTAP_F_SHORTPRE) 2595 ND_PRINT((ndo, "short preamble ")); 2596 if (flagsval & IEEE80211_RADIOTAP_F_WEP) 2597 ND_PRINT((ndo, "wep ")); 2598 if (flagsval & IEEE80211_RADIOTAP_F_FRAG) 2599 ND_PRINT((ndo, "fragmented ")); 2600 if (flagsval & IEEE80211_RADIOTAP_F_BADFCS) 2601 ND_PRINT((ndo, "bad-fcs ")); 2602 break; 2603 } 2604 2605 case IEEE80211_RADIOTAP_RATE: { 2606 uint8_t rate; 2607 2608 rc = cpack_uint8(s, &rate); 2609 if (rc != 0) 2610 goto trunc; 2611 /* 2612 * XXX On FreeBSD rate & 0x80 means we have an MCS. On 2613 * Linux and AirPcap it does not. (What about 2614 * Mac OS X, NetBSD, OpenBSD, and DragonFly BSD?) 2615 * 2616 * This is an issue either for proprietary extensions 2617 * to 11a or 11g, which do exist, or for 11n 2618 * implementations that stuff a rate value into 2619 * this field, which also appear to exist. 2620 * 2621 * We currently handle that by assuming that 2622 * if the 0x80 bit is set *and* the remaining 2623 * bits have a value between 0 and 15 it's 2624 * an MCS value, otherwise it's a rate. If 2625 * there are cases where systems that use 2626 * "0x80 + MCS index" for MCS indices > 15, 2627 * or stuff a rate value here between 64 and 2628 * 71.5 Mb/s in here, we'll need a preference 2629 * setting. Such rates do exist, e.g. 11n 2630 * MCS 7 at 20 MHz with a long guard interval. 2631 */ 2632 if (rate >= 0x80 && rate <= 0x8f) { 2633 /* 2634 * XXX - we don't know the channel width 2635 * or guard interval length, so we can't 2636 * convert this to a data rate. 2637 * 2638 * If you want us to show a data rate, 2639 * use the MCS field, not the Rate field; 2640 * the MCS field includes not only the 2641 * MCS index, it also includes bandwidth 2642 * and guard interval information. 2643 * 2644 * XXX - can we get the channel width 2645 * from XChannel and the guard interval 2646 * information from Flags, at least on 2647 * FreeBSD? 2648 */ 2649 ND_PRINT((ndo, "MCS %u ", rate & 0x7f)); 2650 } else 2651 ND_PRINT((ndo, "%2.1f Mb/s ", .5 * rate)); 2652 break; 2653 } 2654 2655 case IEEE80211_RADIOTAP_CHANNEL: { 2656 uint16_t frequency; 2657 uint16_t flags; 2658 2659 rc = cpack_uint16(s, &frequency); 2660 if (rc != 0) 2661 goto trunc; 2662 rc = cpack_uint16(s, &flags); 2663 if (rc != 0) 2664 goto trunc; 2665 /* 2666 * If CHANNEL and XCHANNEL are both present, skip 2667 * CHANNEL. 2668 */ 2669 if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL)) 2670 break; 2671 print_chaninfo(ndo, frequency, flags, presentflags); 2672 break; 2673 } 2674 2675 case IEEE80211_RADIOTAP_FHSS: { 2676 uint8_t hopset; 2677 uint8_t hoppat; 2678 2679 rc = cpack_uint8(s, &hopset); 2680 if (rc != 0) 2681 goto trunc; 2682 rc = cpack_uint8(s, &hoppat); 2683 if (rc != 0) 2684 goto trunc; 2685 ND_PRINT((ndo, "fhset %d fhpat %d ", hopset, hoppat)); 2686 break; 2687 } 2688 2689 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: { 2690 int8_t dbm_antsignal; 2691 2692 rc = cpack_int8(s, &dbm_antsignal); 2693 if (rc != 0) 2694 goto trunc; 2695 ND_PRINT((ndo, "%ddBm signal ", dbm_antsignal)); 2696 break; 2697 } 2698 2699 case IEEE80211_RADIOTAP_DBM_ANTNOISE: { 2700 int8_t dbm_antnoise; 2701 2702 rc = cpack_int8(s, &dbm_antnoise); 2703 if (rc != 0) 2704 goto trunc; 2705 ND_PRINT((ndo, "%ddBm noise ", dbm_antnoise)); 2706 break; 2707 } 2708 2709 case IEEE80211_RADIOTAP_LOCK_QUALITY: { 2710 uint16_t lock_quality; 2711 2712 rc = cpack_uint16(s, &lock_quality); 2713 if (rc != 0) 2714 goto trunc; 2715 ND_PRINT((ndo, "%u sq ", lock_quality)); 2716 break; 2717 } 2718 2719 case IEEE80211_RADIOTAP_TX_ATTENUATION: { 2720 uint16_t tx_attenuation; 2721 2722 rc = cpack_uint16(s, &tx_attenuation); 2723 if (rc != 0) 2724 goto trunc; 2725 ND_PRINT((ndo, "%d tx power ", -(int)tx_attenuation)); 2726 break; 2727 } 2728 2729 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: { 2730 uint8_t db_tx_attenuation; 2731 2732 rc = cpack_uint8(s, &db_tx_attenuation); 2733 if (rc != 0) 2734 goto trunc; 2735 ND_PRINT((ndo, "%ddB tx attenuation ", -(int)db_tx_attenuation)); 2736 break; 2737 } 2738 2739 case IEEE80211_RADIOTAP_DBM_TX_POWER: { 2740 int8_t dbm_tx_power; 2741 2742 rc = cpack_int8(s, &dbm_tx_power); 2743 if (rc != 0) 2744 goto trunc; 2745 ND_PRINT((ndo, "%ddBm tx power ", dbm_tx_power)); 2746 break; 2747 } 2748 2749 case IEEE80211_RADIOTAP_ANTENNA: { 2750 uint8_t antenna; 2751 2752 rc = cpack_uint8(s, &antenna); 2753 if (rc != 0) 2754 goto trunc; 2755 ND_PRINT((ndo, "antenna %u ", antenna)); 2756 break; 2757 } 2758 2759 case IEEE80211_RADIOTAP_DB_ANTSIGNAL: { 2760 uint8_t db_antsignal; 2761 2762 rc = cpack_uint8(s, &db_antsignal); 2763 if (rc != 0) 2764 goto trunc; 2765 ND_PRINT((ndo, "%ddB signal ", db_antsignal)); 2766 break; 2767 } 2768 2769 case IEEE80211_RADIOTAP_DB_ANTNOISE: { 2770 uint8_t db_antnoise; 2771 2772 rc = cpack_uint8(s, &db_antnoise); 2773 if (rc != 0) 2774 goto trunc; 2775 ND_PRINT((ndo, "%ddB noise ", db_antnoise)); 2776 break; 2777 } 2778 2779 case IEEE80211_RADIOTAP_RX_FLAGS: { 2780 uint16_t rx_flags; 2781 2782 rc = cpack_uint16(s, &rx_flags); 2783 if (rc != 0) 2784 goto trunc; 2785 /* Do nothing for now */ 2786 break; 2787 } 2788 2789 case IEEE80211_RADIOTAP_XCHANNEL: { 2790 uint32_t flags; 2791 uint16_t frequency; 2792 uint8_t channel; 2793 uint8_t maxpower; 2794 2795 rc = cpack_uint32(s, &flags); 2796 if (rc != 0) 2797 goto trunc; 2798 rc = cpack_uint16(s, &frequency); 2799 if (rc != 0) 2800 goto trunc; 2801 rc = cpack_uint8(s, &channel); 2802 if (rc != 0) 2803 goto trunc; 2804 rc = cpack_uint8(s, &maxpower); 2805 if (rc != 0) 2806 goto trunc; 2807 print_chaninfo(ndo, frequency, flags, presentflags); 2808 break; 2809 } 2810 2811 case IEEE80211_RADIOTAP_MCS: { 2812 uint8_t known; 2813 uint8_t flags; 2814 uint8_t mcs_index; 2815 static const char *ht_bandwidth[4] = { 2816 "20 MHz", 2817 "40 MHz", 2818 "20 MHz (L)", 2819 "20 MHz (U)" 2820 }; 2821 float htrate; 2822 2823 rc = cpack_uint8(s, &known); 2824 if (rc != 0) 2825 goto trunc; 2826 rc = cpack_uint8(s, &flags); 2827 if (rc != 0) 2828 goto trunc; 2829 rc = cpack_uint8(s, &mcs_index); 2830 if (rc != 0) 2831 goto trunc; 2832 if (known & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) { 2833 /* 2834 * We know the MCS index. 2835 */ 2836 if (mcs_index <= MAX_MCS_INDEX) { 2837 /* 2838 * And it's in-range. 2839 */ 2840 if (known & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) { 2841 /* 2842 * And we know both the bandwidth and 2843 * the guard interval, so we can look 2844 * up the rate. 2845 */ 2846 htrate = 2847 ieee80211_float_htrates \ 2848 [mcs_index] \ 2849 [((flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \ 2850 [((flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)]; 2851 } else { 2852 /* 2853 * We don't know both the bandwidth 2854 * and the guard interval, so we can 2855 * only report the MCS index. 2856 */ 2857 htrate = 0.0; 2858 } 2859 } else { 2860 /* 2861 * The MCS value is out of range. 2862 */ 2863 htrate = 0.0; 2864 } 2865 if (htrate != 0.0) { 2866 /* 2867 * We have the rate. 2868 * Print it. 2869 */ 2870 ND_PRINT((ndo, "%.1f Mb/s MCS %u ", htrate, mcs_index)); 2871 } else { 2872 /* 2873 * We at least have the MCS index. 2874 * Print it. 2875 */ 2876 ND_PRINT((ndo, "MCS %u ", mcs_index)); 2877 } 2878 } 2879 if (known & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) { 2880 ND_PRINT((ndo, "%s ", 2881 ht_bandwidth[flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK])); 2882 } 2883 if (known & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) { 2884 ND_PRINT((ndo, "%s GI ", 2885 (flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 2886 "short" : "long")); 2887 } 2888 if (known & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) { 2889 ND_PRINT((ndo, "%s ", 2890 (flags & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ? 2891 "greenfield" : "mixed")); 2892 } 2893 if (known & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) { 2894 ND_PRINT((ndo, "%s FEC ", 2895 (flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ? 2896 "LDPC" : "BCC")); 2897 } 2898 if (known & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) { 2899 ND_PRINT((ndo, "RX-STBC%u ", 2900 (flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT)); 2901 } 2902 break; 2903 } 2904 2905 case IEEE80211_RADIOTAP_AMPDU_STATUS: { 2906 uint32_t reference_num; 2907 uint16_t flags; 2908 uint8_t delim_crc; 2909 uint8_t reserved; 2910 2911 rc = cpack_uint32(s, &reference_num); 2912 if (rc != 0) 2913 goto trunc; 2914 rc = cpack_uint16(s, &flags); 2915 if (rc != 0) 2916 goto trunc; 2917 rc = cpack_uint8(s, &delim_crc); 2918 if (rc != 0) 2919 goto trunc; 2920 rc = cpack_uint8(s, &reserved); 2921 if (rc != 0) 2922 goto trunc; 2923 /* Do nothing for now */ 2924 break; 2925 } 2926 2927 case IEEE80211_RADIOTAP_VHT: { 2928 uint16_t known; 2929 uint8_t flags; 2930 uint8_t bandwidth; 2931 uint8_t mcs_nss[4]; 2932 uint8_t coding; 2933 uint8_t group_id; 2934 uint16_t partial_aid; 2935 static const char *vht_bandwidth[32] = { 2936 "20 MHz", 2937 "40 MHz", 2938 "20 MHz (L)", 2939 "20 MHz (U)", 2940 "80 MHz", 2941 "80 MHz (L)", 2942 "80 MHz (U)", 2943 "80 MHz (LL)", 2944 "80 MHz (LU)", 2945 "80 MHz (UL)", 2946 "80 MHz (UU)", 2947 "160 MHz", 2948 "160 MHz (L)", 2949 "160 MHz (U)", 2950 "160 MHz (LL)", 2951 "160 MHz (LU)", 2952 "160 MHz (UL)", 2953 "160 MHz (UU)", 2954 "160 MHz (LLL)", 2955 "160 MHz (LLU)", 2956 "160 MHz (LUL)", 2957 "160 MHz (UUU)", 2958 "160 MHz (ULL)", 2959 "160 MHz (ULU)", 2960 "160 MHz (UUL)", 2961 "160 MHz (UUU)", 2962 "unknown (26)", 2963 "unknown (27)", 2964 "unknown (28)", 2965 "unknown (29)", 2966 "unknown (30)", 2967 "unknown (31)" 2968 }; 2969 2970 rc = cpack_uint16(s, &known); 2971 if (rc != 0) 2972 goto trunc; 2973 rc = cpack_uint8(s, &flags); 2974 if (rc != 0) 2975 goto trunc; 2976 rc = cpack_uint8(s, &bandwidth); 2977 if (rc != 0) 2978 goto trunc; 2979 for (i = 0; i < 4; i++) { 2980 rc = cpack_uint8(s, &mcs_nss[i]); 2981 if (rc != 0) 2982 goto trunc; 2983 } 2984 rc = cpack_uint8(s, &coding); 2985 if (rc != 0) 2986 goto trunc; 2987 rc = cpack_uint8(s, &group_id); 2988 if (rc != 0) 2989 goto trunc; 2990 rc = cpack_uint16(s, &partial_aid); 2991 if (rc != 0) 2992 goto trunc; 2993 for (i = 0; i < 4; i++) { 2994 u_int nss, mcs; 2995 nss = mcs_nss[i] & IEEE80211_RADIOTAP_VHT_NSS_MASK; 2996 mcs = (mcs_nss[i] & IEEE80211_RADIOTAP_VHT_MCS_MASK) >> IEEE80211_RADIOTAP_VHT_MCS_SHIFT; 2997 2998 if (nss == 0) 2999 continue; 3000 3001 ND_PRINT((ndo, "User %u MCS %u ", i, mcs)); 3002 ND_PRINT((ndo, "%s FEC ", 3003 (coding & (IEEE80211_RADIOTAP_CODING_LDPC_USERn << i)) ? 3004 "LDPC" : "BCC")); 3005 } 3006 if (known & IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN) { 3007 ND_PRINT((ndo, "%s ", 3008 vht_bandwidth[bandwidth & IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK])); 3009 } 3010 if (known & IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN) { 3011 ND_PRINT((ndo, "%s GI ", 3012 (flags & IEEE80211_RADIOTAP_VHT_SHORT_GI) ? 3013 "short" : "long")); 3014 } 3015 break; 3016 } 3017 3018 default: 3019 /* this bit indicates a field whose 3020 * size we do not know, so we cannot 3021 * proceed. Just print the bit number. 3022 */ 3023 ND_PRINT((ndo, "[bit %u] ", bit)); 3024 return -1; 3025 } 3026 3027 return 0; 3028 3029 trunc: 3030 ND_PRINT((ndo, "%s", tstr)); 3031 return rc; 3032 } 3033 3034 3035 static int 3036 print_in_radiotap_namespace(netdissect_options *ndo, 3037 struct cpack_state *s, uint8_t *flags, 3038 uint32_t presentflags, int bit0) 3039 { 3040 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x))) 3041 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x))) 3042 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x))) 3043 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x))) 3044 #define BITNO_2(x) (((x) & 2) ? 1 : 0) 3045 uint32_t present, next_present; 3046 int bitno; 3047 enum ieee80211_radiotap_type bit; 3048 int rc; 3049 3050 for (present = presentflags; present; present = next_present) { 3051 /* 3052 * Clear the least significant bit that is set. 3053 */ 3054 next_present = present & (present - 1); 3055 3056 /* 3057 * Get the bit number, within this presence word, 3058 * of the remaining least significant bit that 3059 * is set. 3060 */ 3061 bitno = BITNO_32(present ^ next_present); 3062 3063 /* 3064 * Stop if this is one of the "same meaning 3065 * in all presence flags" bits. 3066 */ 3067 if (bitno >= IEEE80211_RADIOTAP_NAMESPACE) 3068 break; 3069 3070 /* 3071 * Get the radiotap bit number of that bit. 3072 */ 3073 bit = (enum ieee80211_radiotap_type)(bit0 + bitno); 3074 3075 rc = print_radiotap_field(ndo, s, bit, flags, presentflags); 3076 if (rc != 0) 3077 return rc; 3078 } 3079 3080 return 0; 3081 } 3082 3083 u_int 3084 ieee802_11_radio_print(netdissect_options *ndo, 3085 const u_char *p, u_int length, u_int caplen) 3086 { 3087 #define BIT(n) (1U << n) 3088 #define IS_EXTENDED(__p) \ 3089 (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0 3090 3091 struct cpack_state cpacker; 3092 const struct ieee80211_radiotap_header *hdr; 3093 uint32_t presentflags; 3094 const uint32_t *presentp, *last_presentp; 3095 int vendor_namespace; 3096 uint8_t vendor_oui[3]; 3097 uint8_t vendor_subnamespace; 3098 uint16_t skip_length; 3099 int bit0; 3100 u_int len; 3101 uint8_t flags; 3102 int pad; 3103 u_int fcslen; 3104 3105 if (caplen < sizeof(*hdr)) { 3106 ND_PRINT((ndo, "%s", tstr)); 3107 return caplen; 3108 } 3109 3110 hdr = (const struct ieee80211_radiotap_header *)p; 3111 3112 len = EXTRACT_LE_16BITS(&hdr->it_len); 3113 if (len < sizeof(*hdr)) { 3114 /* 3115 * The length is the length of the entire header, so 3116 * it must be as large as the fixed-length part of 3117 * the header. 3118 */ 3119 ND_PRINT((ndo, "%s", tstr)); 3120 return caplen; 3121 } 3122 3123 /* 3124 * If we don't have the entire radiotap header, just give up. 3125 */ 3126 if (caplen < len) { 3127 ND_PRINT((ndo, "%s", tstr)); 3128 return caplen; 3129 } 3130 cpack_init(&cpacker, (const uint8_t *)hdr, len); /* align against header start */ 3131 cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */ 3132 for (last_presentp = &hdr->it_present; 3133 (const u_char*)(last_presentp + 1) <= p + len && 3134 IS_EXTENDED(last_presentp); 3135 last_presentp++) 3136 cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */ 3137 3138 /* are there more bitmap extensions than bytes in header? */ 3139 if ((const u_char*)(last_presentp + 1) > p + len) { 3140 ND_PRINT((ndo, "%s", tstr)); 3141 return caplen; 3142 } 3143 3144 /* 3145 * Start out at the beginning of the default radiotap namespace. 3146 */ 3147 bit0 = 0; 3148 vendor_namespace = 0; 3149 memset(vendor_oui, 0, 3); 3150 vendor_subnamespace = 0; 3151 skip_length = 0; 3152 /* Assume no flags */ 3153 flags = 0; 3154 /* Assume no Atheros padding between 802.11 header and body */ 3155 pad = 0; 3156 /* Assume no FCS at end of frame */ 3157 fcslen = 0; 3158 for (presentp = &hdr->it_present; presentp <= last_presentp; 3159 presentp++) { 3160 presentflags = EXTRACT_LE_32BITS(presentp); 3161 3162 /* 3163 * If this is a vendor namespace, we don't handle it. 3164 */ 3165 if (vendor_namespace) { 3166 /* 3167 * Skip past the stuff we don't understand. 3168 * If we add support for any vendor namespaces, 3169 * it'd be added here; use vendor_oui and 3170 * vendor_subnamespace to interpret the fields. 3171 */ 3172 if (cpack_advance(&cpacker, skip_length) != 0) { 3173 /* 3174 * Ran out of space in the packet. 3175 */ 3176 break; 3177 } 3178 3179 /* 3180 * We've skipped it all; nothing more to 3181 * skip. 3182 */ 3183 skip_length = 0; 3184 } else { 3185 if (print_in_radiotap_namespace(ndo, &cpacker, 3186 &flags, presentflags, bit0) != 0) { 3187 /* 3188 * Fatal error - can't process anything 3189 * more in the radiotap header. 3190 */ 3191 break; 3192 } 3193 } 3194 3195 /* 3196 * Handle the namespace switch bits; we've already handled 3197 * the extension bit in all but the last word above. 3198 */ 3199 switch (presentflags & 3200 (BIT(IEEE80211_RADIOTAP_NAMESPACE)|BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE))) { 3201 3202 case 0: 3203 /* 3204 * We're not changing namespaces. 3205 * advance to the next 32 bits in the current 3206 * namespace. 3207 */ 3208 bit0 += 32; 3209 break; 3210 3211 case BIT(IEEE80211_RADIOTAP_NAMESPACE): 3212 /* 3213 * We're switching to the radiotap namespace. 3214 * Reset the presence-bitmap index to 0, and 3215 * reset the namespace to the default radiotap 3216 * namespace. 3217 */ 3218 bit0 = 0; 3219 vendor_namespace = 0; 3220 memset(vendor_oui, 0, 3); 3221 vendor_subnamespace = 0; 3222 skip_length = 0; 3223 break; 3224 3225 case BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE): 3226 /* 3227 * We're switching to a vendor namespace. 3228 * Reset the presence-bitmap index to 0, 3229 * note that we're in a vendor namespace, 3230 * and fetch the fields of the Vendor Namespace 3231 * item. 3232 */ 3233 bit0 = 0; 3234 vendor_namespace = 1; 3235 if ((cpack_align_and_reserve(&cpacker, 2)) == NULL) { 3236 ND_PRINT((ndo, "%s", tstr)); 3237 break; 3238 } 3239 if (cpack_uint8(&cpacker, &vendor_oui[0]) != 0) { 3240 ND_PRINT((ndo, "%s", tstr)); 3241 break; 3242 } 3243 if (cpack_uint8(&cpacker, &vendor_oui[1]) != 0) { 3244 ND_PRINT((ndo, "%s", tstr)); 3245 break; 3246 } 3247 if (cpack_uint8(&cpacker, &vendor_oui[2]) != 0) { 3248 ND_PRINT((ndo, "%s", tstr)); 3249 break; 3250 } 3251 if (cpack_uint8(&cpacker, &vendor_subnamespace) != 0) { 3252 ND_PRINT((ndo, "%s", tstr)); 3253 break; 3254 } 3255 if (cpack_uint16(&cpacker, &skip_length) != 0) { 3256 ND_PRINT((ndo, "%s", tstr)); 3257 break; 3258 } 3259 break; 3260 3261 default: 3262 /* 3263 * Illegal combination. The behavior in this 3264 * case is undefined by the radiotap spec; we 3265 * just ignore both bits. 3266 */ 3267 break; 3268 } 3269 } 3270 3271 if (flags & IEEE80211_RADIOTAP_F_DATAPAD) 3272 pad = 1; /* Atheros padding */ 3273 if (flags & IEEE80211_RADIOTAP_F_FCS) 3274 fcslen = 4; /* FCS at end of packet */ 3275 return len + ieee802_11_print(ndo, p + len, length - len, caplen - len, pad, 3276 fcslen); 3277 #undef BITNO_32 3278 #undef BITNO_16 3279 #undef BITNO_8 3280 #undef BITNO_4 3281 #undef BITNO_2 3282 #undef BIT 3283 } 3284 3285 static u_int 3286 ieee802_11_avs_radio_print(netdissect_options *ndo, 3287 const u_char *p, u_int length, u_int caplen) 3288 { 3289 uint32_t caphdr_len; 3290 3291 if (caplen < 8) { 3292 ND_PRINT((ndo, "%s", tstr)); 3293 return caplen; 3294 } 3295 3296 caphdr_len = EXTRACT_32BITS(p + 4); 3297 if (caphdr_len < 8) { 3298 /* 3299 * Yow! The capture header length is claimed not 3300 * to be large enough to include even the version 3301 * cookie or capture header length! 3302 */ 3303 ND_PRINT((ndo, "%s", tstr)); 3304 return caplen; 3305 } 3306 3307 if (caplen < caphdr_len) { 3308 ND_PRINT((ndo, "%s", tstr)); 3309 return caplen; 3310 } 3311 3312 return caphdr_len + ieee802_11_print(ndo, p + caphdr_len, 3313 length - caphdr_len, caplen - caphdr_len, 0, 0); 3314 } 3315 3316 #define PRISM_HDR_LEN 144 3317 3318 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000 3319 #define WLANCAP_MAGIC_COOKIE_V1 0x80211001 3320 #define WLANCAP_MAGIC_COOKIE_V2 0x80211002 3321 3322 /* 3323 * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header, 3324 * containing information such as radio information, which we 3325 * currently ignore. 3326 * 3327 * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or 3328 * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS 3329 * (currently, on Linux, there's no ARPHRD_ type for 3330 * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM 3331 * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for 3332 * the AVS header, and the first 4 bytes of the header are used to 3333 * indicate whether it's a Prism header or an AVS header). 3334 */ 3335 u_int 3336 prism_if_print(netdissect_options *ndo, 3337 const struct pcap_pkthdr *h, const u_char *p) 3338 { 3339 u_int caplen = h->caplen; 3340 u_int length = h->len; 3341 uint32_t msgcode; 3342 3343 if (caplen < 4) { 3344 ND_PRINT((ndo, "%s", tstr)); 3345 return caplen; 3346 } 3347 3348 msgcode = EXTRACT_32BITS(p); 3349 if (msgcode == WLANCAP_MAGIC_COOKIE_V1 || 3350 msgcode == WLANCAP_MAGIC_COOKIE_V2) 3351 return ieee802_11_avs_radio_print(ndo, p, length, caplen); 3352 3353 if (caplen < PRISM_HDR_LEN) { 3354 ND_PRINT((ndo, "%s", tstr)); 3355 return caplen; 3356 } 3357 3358 return PRISM_HDR_LEN + ieee802_11_print(ndo, p + PRISM_HDR_LEN, 3359 length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0); 3360 } 3361 3362 /* 3363 * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra 3364 * header, containing information such as radio information. 3365 */ 3366 u_int 3367 ieee802_11_radio_if_print(netdissect_options *ndo, 3368 const struct pcap_pkthdr *h, const u_char *p) 3369 { 3370 return ieee802_11_radio_print(ndo, p, h->len, h->caplen); 3371 } 3372 3373 /* 3374 * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an 3375 * extra header, containing information such as radio information, 3376 * which we currently ignore. 3377 */ 3378 u_int 3379 ieee802_11_radio_avs_if_print(netdissect_options *ndo, 3380 const struct pcap_pkthdr *h, const u_char *p) 3381 { 3382 return ieee802_11_avs_radio_print(ndo, p, h->len, h->caplen); 3383 } 3384