2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>
4 * Copyright 2012 Daniel Borkmann <daniel@netsniff-ng.org>
5 * Subject to the GPL, version 2.
10 #include <netinet/in.h> /* for ntohs() */
11 #include <asm/byteorder.h>
15 #include "dissector_80211.h"
22 /* Note: Fields are encoded in little-endian! */
23 struct ieee80211_frm_ctrl
{
27 #if defined(__LITTLE_ENDIAN_BITFIELD)
28 /* Correct order here ... */
29 __extension__ u16 proto_version
:2,
40 #elif defined(__BIG_ENDIAN_BITFIELD)
41 __extension__ u16 subtype
:4,
53 # error "Adjust your <asm/byteorder.h> defines"
59 /* Management Frame start */
60 /* Note: Fields are encoded in little-endian! */
61 struct ieee80211_mgmt
{
69 struct ieee80211_mgmt_auth
{
73 /* possibly followed by Challenge text */
77 struct ieee80211_mgmt_deauth
{
81 struct ieee80211_mgmt_assoc_req
{
84 /* followed by SSID and Supported rates */
88 struct ieee80211_mgmt_assoc_resp
{
92 /* followed by Supported rates */
96 struct ieee80211_mgmt_reassoc_resp
{
100 /* followed by Supported rates */
104 struct ieee80211_mgmt_reassoc_req
{
108 /* followed by SSID and Supported rates */
112 struct ieee80211_mgmt_disassoc
{
116 struct ieee80211_mgmt_probe_req
{
119 struct ieee80211_mgmt_beacon
{
123 /* followed by some of SSID, Supported rates,
124 * FH Params, DS Params, CF Params, IBSS Params, TIM */
128 struct ieee80211_mgmt_probe_resp
{
132 /* followed by some of SSID, Supported rates,
133 * FH Params, DS Params, CF Params, IBSS Params, TIM */
136 /* Management Frame end */
138 /* Control Frame start */
139 /* Note: Fields are encoded in little-endian! */
140 struct ieee80211_ctrl
{
143 struct ieee80211_ctrl_rts
{
149 struct ieee80211_ctrl_cts
{
154 struct ieee80211_ctrl_ack
{
159 struct ieee80211_ctrl_ps_poll
{
165 struct ieee80211_ctrl_cf_end
{
171 struct ieee80211_ctrl_cf_end_ack
{
176 /* Control Frame end */
178 /* Data Frame start */
179 /* Note: Fields are encoded in little-endian! */
180 struct ieee80211_data
{
186 /* http://www.sss-mag.com/pdf/802_11tut.pdf
187 * http://www.scribd.com/doc/78443651/111/Management-Frames
188 * http://www.wildpackets.com/resources/compendium/wireless_lan/wlan_packets
189 * http://www.rhyshaden.com/wireless.htm
192 struct element_reserved
{
196 struct element_ssid
{
201 struct element_supp_rates
{
206 struct element_fh_ps
{
214 struct element_dsss_ps
{
219 struct element_cf_ps
{
235 struct element_ibss_ps
{
240 struct element_country_tripled
{
246 struct element_country
{
248 #if defined(__LITTLE_ENDIAN_BITFIELD)
249 /* Correct order here ... */
253 #elif defined(__BIG_ENDIAN_BITFIELD)
258 # error "Adjust your <asm/byteorder.h> defines"
260 /* triplet may repeat */
261 struct element_country_tripled tripled
[0];
266 struct element_hop_pp
{
272 struct element_hop_pt
{
286 struct element_ext_supp_rates
{
291 struct element_vend_spec
{
297 static float data_rates(u8 id
)
299 /* XXX Why not (id / 2.f)? */
307 case 11: return 5.5f
;
308 case 12: return 6.0f
;
309 case 18: return 9.0f
;
310 case 22: return 11.0f
;
311 case 24: return 12.0f
;
312 case 27: return 13.5f
;
313 case 36: return 18.0f
;
314 case 44: return 22.0f
;
315 case 48: return 24.0f
;
316 case 54: return 27.0f
;
317 case 66: return 33.0f
;
318 case 72: return 36.0f
;
319 case 96: return 48.0f
;
320 case 108: return 54.0f
;
326 static int8_t inf_reserved(struct pkt_buff
*pkt
, u8
*id
)
330 struct element_reserved
*reserved
;
332 reserved
= (struct element_reserved
*) pkt_pull(pkt
, sizeof(*reserved
));
333 if (reserved
== NULL
)
336 tprintf("Reserved (%u, Len (%u)): ", *id
, reserved
->len
);
338 data
= pkt_pull(pkt
, reserved
->len
);
343 for (i
= 0; i
< reserved
->len
; i
++)
344 tprintf("%.2x", data
[i
]);
349 static int8_t inf_ssid(struct pkt_buff
*pkt
, u8
*id
)
352 struct element_ssid
*ssid
;
355 ssid
= (struct element_ssid
*) pkt_pull(pkt
, sizeof(*ssid
));
359 tprintf(" SSID (%u, Len (%u)): ", *id
, ssid
->len
);
362 ssid_name
= (char *) pkt_pull(pkt
, ssid
->len
);
363 if (ssid_name
== NULL
)
366 for (i
= 0; i
< ssid
->len
; i
++)
367 tprintf("%c",ssid_name
[i
]);
369 tprintf("Wildcard SSID");
375 static int8_t inf_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
379 struct element_supp_rates
*supp_rates
;
381 supp_rates
= (struct element_supp_rates
*)
382 pkt_pull(pkt
, sizeof(*supp_rates
));
383 if (supp_rates
== NULL
)
386 tprintf("Rates (%u, Len (%u)): ", *id
, supp_rates
->len
);
388 if (supp_rates
->len
) {
389 rates
= pkt_pull(pkt
, supp_rates
->len
);
393 for (i
= 0; i
< supp_rates
->len
; i
++)
394 tprintf("%g ", (rates
[i
] & 0x80) ?
395 ((rates
[i
] & 0x3f) * 0.5) :
396 data_rates(rates
[i
]));
403 static int8_t inf_fh_ps(struct pkt_buff
*pkt
, u8
*id
)
405 struct element_fh_ps
*fh_ps
;
407 fh_ps
= (struct element_fh_ps
*) pkt_pull(pkt
, sizeof(*fh_ps
));
411 tprintf("FH Param Set (%u, Len(%u)): ", *id
, fh_ps
->len
);
412 tprintf("Dwell Time: %fs, ", le16_to_cpu(fh_ps
->dwell_time
) * TU
);
413 tprintf("HopSet: %u, ", fh_ps
->hop_set
);
414 tprintf("HopPattern: %u, ", fh_ps
->hop_pattern
);
415 tprintf("HopIndex: %u", fh_ps
->hop_index
);
420 static int8_t inf_dsss_ps(struct pkt_buff
*pkt
, u8
*id
)
422 struct element_dsss_ps
*dsss_ps
;
424 dsss_ps
= (struct element_dsss_ps
*) pkt_pull(pkt
, sizeof(*dsss_ps
));
428 tprintf("DSSS Param Set (%u, Len(%u)): ", *id
, dsss_ps
->len
);
429 tprintf("Current Channel: %u", dsss_ps
->curr_ch
);
434 static int8_t inf_cf_ps(struct pkt_buff
*pkt
, u8
*id
)
436 struct element_cf_ps
*cf_ps
;
438 cf_ps
= (struct element_cf_ps
*) pkt_pull(pkt
, sizeof(*cf_ps
));
442 tprintf("CF Param Set (%u, Len(%u)): ", *id
, cf_ps
->len
);
443 tprintf("CFP Count: %u, ", cf_ps
->cfp_cnt
);
444 tprintf("CFP Period: %u, ", cf_ps
->cfp_period
);
445 tprintf("CFP MaxDur: %fs, ", le16_to_cpu(cf_ps
->cfp_max_dur
) * TU
);
446 tprintf("CFP DurRem: %fs", le16_to_cpu(cf_ps
->cfp_dur_rem
) * TU
);
451 static int8_t inf_tim(struct pkt_buff
*pkt
, u8
*id
)
453 struct element_tim
*tim
;
455 tim
= (struct element_tim
*) pkt_pull(pkt
, sizeof(*tim
));
459 tprintf("TIM (%u, Len(%u)): ", *id
, tim
->len
);
460 tprintf("DTIM Count: %u, ", tim
->dtim_cnt
);
461 tprintf("DTIM Period: %u, ", tim
->dtim_period
);
462 tprintf("Bitmap Control: %u, ", tim
->bmp_cntrl
);
463 if ((tim
->len
- sizeof(*tim
) + 1) > 0) {
464 u8
*bmp
= pkt_pull(pkt
, (tim
->len
- sizeof(*tim
) + 1));
468 tprintf("Partial Virtual Bitmap: 0x");
469 for(u8 i
=0; i
< (tim
->len
- sizeof(*tim
) + 1); i
++)
470 tprintf("%.2x ", bmp
[i
]);
476 static int8_t inf_ibss_ps(struct pkt_buff
*pkt
, u8
*id
)
478 struct element_ibss_ps
*ibss_ps
;
480 ibss_ps
= (struct element_ibss_ps
*) pkt_pull(pkt
, sizeof(*ibss_ps
));
484 tprintf("IBSS Param Set (%u, Len(%u)): ", *id
, ibss_ps
->len
);
485 tprintf("ATIM Window: %fs", le16_to_cpu(ibss_ps
->atim_win
) * TU
);
490 static int8_t inf_country(struct pkt_buff
*pkt
, u8
*id
)
494 struct element_country
*country
;
496 country
= (struct element_country
*) pkt_pull(pkt
, sizeof(*country
));
500 tprintf("Country (%u, Len(%u)): ", *id
, country
->len
);
501 tprintf("Country String: %c%c%c", country
->country_first
,
502 country
->country_sec
, country
->country_third
);
504 for (i
= 0; i
< (country
->len
- 3); i
+= 3) {
505 struct element_country_tripled
*country_tripled
;
507 country_tripled
= (struct element_country_tripled
*)
508 pkt_pull(pkt
, sizeof(*country_tripled
));
509 if (country_tripled
== NULL
)
512 if(country_tripled
->frst_ch
>= 201) {
513 tprintf("Oper Ext ID: %u, ", country_tripled
->frst_ch
);
514 tprintf("Operating Class: %u, ", country_tripled
->nr_ch
);
515 tprintf("Coverage Class: %u", country_tripled
->max_trans
);
517 tprintf("First Ch Nr: %u, ", country_tripled
->frst_ch
);
518 tprintf("Nr of Ch: %u, ", country_tripled
->nr_ch
);
519 tprintf("Max Transmit Pwr Lvl: %u", country_tripled
->max_trans
);
523 if(country
->len
% 2) {
524 pad
= pkt_pull(pkt
, 1);
528 tprintf(", Pad: 0x%x", *pad
);
534 static int8_t inf_hop_pp(struct pkt_buff
*pkt
, u8
*id
)
536 struct element_hop_pp
*hop_pp
;
538 hop_pp
= (struct element_hop_pp
*) pkt_pull(pkt
, sizeof(*hop_pp
));
542 tprintf("Hopping Pattern Param (%u, Len(%u)): ", *id
, hop_pp
->len
);
543 tprintf("Nr of Ch: %u", hop_pp
->nr_ch
);
548 static int8_t inf_hop_pt(struct pkt_buff
*pkt
, u8
*id
)
552 struct element_hop_pt
*hop_pt
;
554 hop_pt
= (struct element_hop_pt
*) pkt_pull(pkt
, sizeof(*hop_pt
));
558 tprintf("Hopping Pattern Table (%u, Len(%u)): ", *id
, hop_pt
->len
);
559 tprintf("Flag: %u, ", hop_pt
->flag
);
560 tprintf("Nr of Sets: %u, ", hop_pt
->nr_sets
);
561 tprintf("Modules: %u, ", hop_pt
->modules
);
562 tprintf("Offs: %u", hop_pt
->offs
);
564 if ((hop_pt
->len
- sizeof(*hop_pt
) + 1) > 0) {
565 rand_tabl
= pkt_pull(pkt
, (hop_pt
->len
- sizeof(*hop_pt
) + 1));
566 if (rand_tabl
== NULL
)
569 tprintf(", Rand table: 0x");
570 for (i
= 0; i
< (hop_pt
->len
- sizeof(*hop_pt
) + 1); i
++)
571 tprintf("%.2x ", rand_tabl
[i
]);
577 static int8_t inf_req(struct pkt_buff
*pkt
, u8
*id
)
582 static int8_t inf_bss_load(struct pkt_buff
*pkt
, u8
*id
)
587 static int8_t inf_edca_ps(struct pkt_buff
*pkt
, u8
*id
)
592 static int8_t inf_tspec(struct pkt_buff
*pkt
, u8
*id
)
597 static int8_t inf_tclas(struct pkt_buff
*pkt
, u8
*id
)
602 static int8_t inf_sched(struct pkt_buff
*pkt
, u8
*id
)
607 static int8_t inf_chall_txt(struct pkt_buff
*pkt
, u8
*id
)
612 static int8_t inf_pwr_constr(struct pkt_buff
*pkt
, u8
*id
)
617 static int8_t inf_pwr_cap(struct pkt_buff
*pkt
, u8
*id
)
622 static int8_t inf_tpc_req(struct pkt_buff
*pkt
, u8
*id
)
627 static int8_t inf_tpc_rep(struct pkt_buff
*pkt
, u8
*id
)
632 static int8_t inf_supp_ch(struct pkt_buff
*pkt
, u8
*id
)
637 static int8_t inf_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
)
642 static int8_t inf_meas_req(struct pkt_buff
*pkt
, u8
*id
)
647 static int8_t inf_meas_rep(struct pkt_buff
*pkt
, u8
*id
)
652 static int8_t inf_quiet(struct pkt_buff
*pkt
, u8
*id
)
657 static int8_t inf_ibss_dfs(struct pkt_buff
*pkt
, u8
*id
)
662 static int8_t inf_erp(struct pkt_buff
*pkt
, u8
*id
)
664 struct element_erp
*erp
;
666 erp
= (struct element_erp
*) pkt_pull(pkt
, sizeof(*erp
));
670 tprintf("ERP (%u, Len(%u)): ", *id
, erp
->len
);
671 tprintf("Non ERP Present (%u), ", erp
->param
& 0x1);
672 tprintf("Use Protection (%u), ", (erp
->param
>> 1) & 0x1);
673 tprintf("Barker Preamble Mode (%u), ", (erp
->param
>> 2) & 0x1);
674 tprintf("Reserved (0x%.5x)", erp
->param
>> 3);
679 static int8_t inf_ts_del(struct pkt_buff
*pkt
, u8
*id
)
684 static int8_t inf_tclas_proc(struct pkt_buff
*pkt
, u8
*id
)
689 static int8_t inf_ht_cap(struct pkt_buff
*pkt
, u8
*id
)
694 static int8_t inf_qos_cap(struct pkt_buff
*pkt
, u8
*id
)
699 static int8_t inf_rsn(struct pkt_buff
*pkt
, u8
*id
)
704 static int8_t inf_ext_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
708 struct element_ext_supp_rates
*ext_supp_rates
;
710 ext_supp_rates
= (struct element_ext_supp_rates
*)
711 pkt_pull(pkt
, sizeof(*ext_supp_rates
));
712 if (ext_supp_rates
== NULL
)
715 tprintf("Ext Support Rates (%u, Len(%u)): ", *id
, ext_supp_rates
->len
);
717 if (ext_supp_rates
->len
) {
718 rates
= pkt_pull(pkt
, ext_supp_rates
->len
);
722 for (i
= 0; i
< ext_supp_rates
->len
; i
++)
723 tprintf("%g ", (rates
[i
] & 0x80) ?
724 ((rates
[i
] & 0x3f) * 0.5) :
725 data_rates(rates
[i
]));
732 static int8_t inf_ap_ch_exp(struct pkt_buff
*pkt
, u8
*id
) {
736 static int8_t inf_neighb_rep(struct pkt_buff
*pkt
, u8
*id
) {
740 static int8_t inf_rcpi(struct pkt_buff
*pkt
, u8
*id
) {
744 static int8_t inf_mde(struct pkt_buff
*pkt
, u8
*id
) {
748 static int8_t inf_fte(struct pkt_buff
*pkt
, u8
*id
) {
752 static int8_t inf_time_out_int(struct pkt_buff
*pkt
, u8
*id
) {
756 static int8_t inf_rde(struct pkt_buff
*pkt
, u8
*id
) {
760 static int8_t inf_dse_reg_loc(struct pkt_buff
*pkt
, u8
*id
) {
764 static int8_t inf_supp_op_class(struct pkt_buff
*pkt
, u8
*id
) {
768 static int8_t inf_ext_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
) {
772 static int8_t inf_ht_op(struct pkt_buff
*pkt
, u8
*id
) {
776 static int8_t inf_sec_ch_offs(struct pkt_buff
*pkt
, u8
*id
) {
780 static int8_t inf_bss_avg_acc_del(struct pkt_buff
*pkt
, u8
*id
) {
784 static int8_t inf_ant(struct pkt_buff
*pkt
, u8
*id
) {
788 static int8_t inf_rsni(struct pkt_buff
*pkt
, u8
*id
) {
792 static int8_t inf_meas_pilot_trans(struct pkt_buff
*pkt
, u8
*id
) {
796 static int8_t inf_bss_avl_adm_cap(struct pkt_buff
*pkt
, u8
*id
) {
800 static int8_t inf_bss_ac_acc_del(struct pkt_buff
*pkt
, u8
*id
) {
804 static int8_t inf_time_adv(struct pkt_buff
*pkt
, u8
*id
) {
808 static int8_t inf_rm_ena_cap(struct pkt_buff
*pkt
, u8
*id
) {
812 static int8_t inf_mult_bssid(struct pkt_buff
*pkt
, u8
*id
) {
816 static int8_t inf_20_40_bss_coex(struct pkt_buff
*pkt
, u8
*id
) {
820 static int8_t inf_20_40_bss_int_ch_rep(struct pkt_buff
*pkt
, u8
*id
) {
824 static int8_t inf_overl_bss_scan_para(struct pkt_buff
*pkt
, u8
*id
) {
828 static int8_t inf_ric_desc(struct pkt_buff
*pkt
, u8
*id
) {
832 static int8_t inf_mgmt_mic(struct pkt_buff
*pkt
, u8
*id
) {
836 static int8_t inf_ev_req(struct pkt_buff
*pkt
, u8
*id
) {
840 static int8_t inf_ev_rep(struct pkt_buff
*pkt
, u8
*id
) {
844 static int8_t inf_diagn_req(struct pkt_buff
*pkt
, u8
*id
) {
848 static int8_t inf_diagn_rep(struct pkt_buff
*pkt
, u8
*id
) {
852 static int8_t inf_loc_para(struct pkt_buff
*pkt
, u8
*id
) {
856 static int8_t inf_nontr_bssid_cap(struct pkt_buff
*pkt
, u8
*id
) {
860 static int8_t inf_ssid_list(struct pkt_buff
*pkt
, u8
*id
) {
864 static int8_t inf_mult_bssid_index(struct pkt_buff
*pkt
, u8
*id
) {
868 static int8_t inf_fms_desc(struct pkt_buff
*pkt
, u8
*id
) {
872 static int8_t inf_fms_req(struct pkt_buff
*pkt
, u8
*id
) {
876 static int8_t inf_fms_resp(struct pkt_buff
*pkt
, u8
*id
) {
880 static int8_t inf_qos_tfc_cap(struct pkt_buff
*pkt
, u8
*id
) {
884 static int8_t inf_bss_max_idle_per(struct pkt_buff
*pkt
, u8
*id
) {
888 static int8_t inf_tfs_req(struct pkt_buff
*pkt
, u8
*id
) {
892 static int8_t inf_tfs_resp(struct pkt_buff
*pkt
, u8
*id
) {
896 static int8_t inf_wnm_sleep_mod(struct pkt_buff
*pkt
, u8
*id
) {
900 static int8_t inf_tim_bcst_req(struct pkt_buff
*pkt
, u8
*id
) {
904 static int8_t inf_tim_bcst_resp(struct pkt_buff
*pkt
, u8
*id
) {
908 static int8_t inf_coll_interf_rep(struct pkt_buff
*pkt
, u8
*id
) {
912 static int8_t inf_ch_usage(struct pkt_buff
*pkt
, u8
*id
) {
916 static int8_t inf_time_zone(struct pkt_buff
*pkt
, u8
*id
) {
920 static int8_t inf_dms_req(struct pkt_buff
*pkt
, u8
*id
) {
924 static int8_t inf_dms_resp(struct pkt_buff
*pkt
, u8
*id
) {
928 static int8_t inf_link_id(struct pkt_buff
*pkt
, u8
*id
) {
932 static int8_t inf_wakeup_sched(struct pkt_buff
*pkt
, u8
*id
) {
936 static int8_t inf_ch_sw_timing(struct pkt_buff
*pkt
, u8
*id
) {
940 static int8_t inf_pti_ctrl(struct pkt_buff
*pkt
, u8
*id
) {
944 static int8_t inf_tpu_buff_status(struct pkt_buff
*pkt
, u8
*id
) {
948 static int8_t inf_interw(struct pkt_buff
*pkt
, u8
*id
) {
952 static int8_t inf_adv_proto(struct pkt_buff
*pkt
, u8
*id
) {
956 static int8_t inf_exp_bandw_req(struct pkt_buff
*pkt
, u8
*id
) {
960 static int8_t inf_qos_map_set(struct pkt_buff
*pkt
, u8
*id
) {
964 static int8_t inf_roam_cons(struct pkt_buff
*pkt
, u8
*id
) {
968 static int8_t inf_emer_alert_id(struct pkt_buff
*pkt
, u8
*id
) {
972 static int8_t inf_mesh_conf(struct pkt_buff
*pkt
, u8
*id
) {
976 static int8_t inf_mesh_id(struct pkt_buff
*pkt
, u8
*id
) {
980 static int8_t inf_mesh_link_metr_rep(struct pkt_buff
*pkt
, u8
*id
) {
984 static int8_t inf_cong_notif(struct pkt_buff
*pkt
, u8
*id
) {
988 static int8_t inf_mesh_peer_mgmt(struct pkt_buff
*pkt
, u8
*id
) {
992 static int8_t inf_mesh_ch_sw_para(struct pkt_buff
*pkt
, u8
*id
) {
996 static int8_t inf_mesh_awake_win(struct pkt_buff
*pkt
, u8
*id
) {
1000 static int8_t inf_beacon_timing(struct pkt_buff
*pkt
, u8
*id
) {
1004 static int8_t inf_mccaop_setup_req(struct pkt_buff
*pkt
, u8
*id
) {
1008 static int8_t inf_mccaop_setup_rep(struct pkt_buff
*pkt
, u8
*id
) {
1012 static int8_t inf_mccaop_adv(struct pkt_buff
*pkt
, u8
*id
) {
1016 static int8_t inf_mccaop_teardwn(struct pkt_buff
*pkt
, u8
*id
) {
1020 static int8_t inf_gann(struct pkt_buff
*pkt
, u8
*id
) {
1024 static int8_t inf_rann(struct pkt_buff
*pkt
, u8
*id
) {
1028 static int8_t inf_ext_cap(struct pkt_buff
*pkt
, u8
*id
) {
1032 static int8_t inf_preq(struct pkt_buff
*pkt
, u8
*id
) {
1036 static int8_t inf_prep(struct pkt_buff
*pkt
, u8
*id
) {
1040 static int8_t inf_perr(struct pkt_buff
*pkt
, u8
*id
) {
1044 static int8_t inf_pxu(struct pkt_buff
*pkt
, u8
*id
) {
1048 static int8_t inf_pxuc(struct pkt_buff
*pkt
, u8
*id
) {
1052 static int8_t inf_auth_mesh_peer_exch(struct pkt_buff
*pkt
, u8
*id
) {
1056 static int8_t inf_mic(struct pkt_buff
*pkt
, u8
*id
) {
1060 static int8_t inf_dest_uri(struct pkt_buff
*pkt
, u8
*id
) {
1064 static int8_t inf_u_apsd_coex(struct pkt_buff
*pkt
, u8
*id
) {
1068 static int8_t inf_mccaop_adv_overv(struct pkt_buff
*pkt
, u8
*id
) {
1072 static int8_t inf_vend_spec(struct pkt_buff
*pkt
, u8
*id
)
1076 struct element_vend_spec
*vend_spec
;
1078 vend_spec
= (struct element_vend_spec
*)
1079 pkt_pull(pkt
, sizeof(*vend_spec
));
1080 if (vend_spec
== NULL
)
1083 tprintf("Vendor Specific (%u, Len (%u)): ", *id
, vend_spec
->len
);
1085 data
= pkt_pull(pkt
, vend_spec
->len
);
1090 for (i
= 0; i
< vend_spec
->len
; i
++)
1091 tprintf("%.2x", data
[i
]);
1096 static int8_t inf_elements(struct pkt_buff
*pkt
)
1098 u8
*id
= pkt_pull(pkt
, 1);
1103 case 0: return inf_ssid(pkt
, id
);
1104 case 1: return inf_supp_rates(pkt
, id
);
1105 case 2: return inf_fh_ps(pkt
, id
);
1106 case 3: return inf_dsss_ps(pkt
, id
);
1107 case 4: return inf_cf_ps(pkt
, id
);
1108 case 5: return inf_tim(pkt
, id
);
1109 case 6: return inf_ibss_ps(pkt
, id
);
1110 case 7: return inf_country(pkt
, id
);
1111 case 8: return inf_hop_pp(pkt
, id
);
1112 case 9: return inf_hop_pt(pkt
, id
);
1113 case 10: return inf_req(pkt
, id
);
1114 case 11: return inf_bss_load(pkt
, id
);
1115 case 12: return inf_edca_ps(pkt
, id
);
1116 case 13: return inf_tspec(pkt
, id
);
1117 case 14: return inf_tclas(pkt
, id
);
1118 case 15: return inf_sched(pkt
, id
);
1119 case 16: return inf_chall_txt(pkt
, id
);
1120 case 17 ... 31: return inf_reserved(pkt
, id
);
1121 case 32: return inf_pwr_constr(pkt
, id
);
1122 case 33: return inf_pwr_cap(pkt
, id
);
1123 case 34: return inf_tpc_req(pkt
, id
);
1124 case 35: return inf_tpc_rep(pkt
, id
);
1125 case 36: return inf_supp_ch(pkt
, id
);
1126 case 37: return inf_ch_sw_ann(pkt
, id
);
1127 case 38: return inf_meas_req(pkt
, id
);
1128 case 39: return inf_meas_rep(pkt
, id
);
1129 case 40: return inf_quiet(pkt
, id
);
1130 case 41: return inf_ibss_dfs(pkt
, id
);
1131 case 42: return inf_erp(pkt
, id
);
1132 case 43: return inf_ts_del(pkt
, id
);
1133 case 44: return inf_tclas_proc(pkt
, id
);
1134 case 45: return inf_ht_cap(pkt
, id
);
1135 case 46: return inf_qos_cap(pkt
, id
);
1136 case 47: return inf_reserved(pkt
, id
);
1137 case 48: return inf_rsn(pkt
, id
);
1138 case 49: return inf_rsn(pkt
, id
);
1139 case 50: return inf_ext_supp_rates(pkt
, id
);
1140 case 51: return inf_ap_ch_exp(pkt
, id
);
1141 case 52: return inf_neighb_rep(pkt
, id
);
1142 case 53: return inf_rcpi(pkt
, id
);
1143 case 54: return inf_mde(pkt
, id
);
1144 case 55: return inf_fte(pkt
, id
);
1145 case 56: return inf_time_out_int(pkt
, id
);
1146 case 57: return inf_rde(pkt
, id
);
1147 case 58: return inf_dse_reg_loc(pkt
, id
);
1148 case 59: return inf_supp_op_class(pkt
, id
);
1149 case 60: return inf_ext_ch_sw_ann(pkt
, id
);
1150 case 61: return inf_ht_op(pkt
, id
);
1151 case 62: return inf_sec_ch_offs(pkt
, id
);
1152 case 63: return inf_bss_avg_acc_del(pkt
, id
);
1153 case 64: return inf_ant(pkt
, id
);
1154 case 65: return inf_rsni(pkt
, id
);
1155 case 66: return inf_meas_pilot_trans(pkt
, id
);
1156 case 67: return inf_bss_avl_adm_cap(pkt
, id
);
1157 case 68: return inf_bss_ac_acc_del(pkt
, id
);
1158 case 69: return inf_time_adv(pkt
, id
);
1159 case 70: return inf_rm_ena_cap(pkt
, id
);
1160 case 71: return inf_mult_bssid(pkt
, id
);
1161 case 72: return inf_20_40_bss_coex(pkt
, id
);
1162 case 73: return inf_20_40_bss_int_ch_rep(pkt
, id
);
1163 case 74: return inf_overl_bss_scan_para(pkt
, id
);
1164 case 75: return inf_ric_desc(pkt
, id
);
1165 case 76: return inf_mgmt_mic(pkt
, id
);
1166 case 78: return inf_ev_req(pkt
, id
);
1167 case 79: return inf_ev_rep(pkt
, id
);
1168 case 80: return inf_diagn_req(pkt
, id
);
1169 case 81: return inf_diagn_rep(pkt
, id
);
1170 case 82: return inf_loc_para(pkt
, id
);
1171 case 83: return inf_nontr_bssid_cap(pkt
, id
);
1172 case 84: return inf_ssid_list(pkt
, id
);
1173 case 85: return inf_mult_bssid_index(pkt
, id
);
1174 case 86: return inf_fms_desc(pkt
, id
);
1175 case 87: return inf_fms_req(pkt
, id
);
1176 case 88: return inf_fms_resp(pkt
, id
);
1177 case 89: return inf_qos_tfc_cap(pkt
, id
);
1178 case 90: return inf_bss_max_idle_per(pkt
, id
);
1179 case 91: return inf_tfs_req(pkt
, id
);
1180 case 92: return inf_tfs_resp(pkt
, id
);
1181 case 93: return inf_wnm_sleep_mod(pkt
, id
);
1182 case 94: return inf_tim_bcst_req(pkt
, id
);
1183 case 95: return inf_tim_bcst_resp(pkt
, id
);
1184 case 96: return inf_coll_interf_rep(pkt
, id
);
1185 case 97: return inf_ch_usage(pkt
, id
);
1186 case 98: return inf_time_zone(pkt
, id
);
1187 case 99: return inf_dms_req(pkt
, id
);
1188 case 100: return inf_dms_resp(pkt
, id
);
1189 case 101: return inf_link_id(pkt
, id
);
1190 case 102: return inf_wakeup_sched(pkt
, id
);
1191 case 104: return inf_ch_sw_timing(pkt
, id
);
1192 case 105: return inf_pti_ctrl(pkt
, id
);
1193 case 106: return inf_tpu_buff_status(pkt
, id
);
1194 case 107: return inf_interw(pkt
, id
);
1195 case 108: return inf_adv_proto(pkt
, id
);
1196 case 109: return inf_exp_bandw_req(pkt
, id
);
1197 case 110: return inf_qos_map_set(pkt
, id
);
1198 case 111: return inf_roam_cons(pkt
, id
);
1199 case 112: return inf_emer_alert_id(pkt
, id
);
1200 case 113: return inf_mesh_conf(pkt
, id
);
1201 case 114: return inf_mesh_id(pkt
, id
);
1202 case 115: return inf_mesh_link_metr_rep(pkt
, id
);
1203 case 116: return inf_cong_notif(pkt
, id
);
1204 case 117: return inf_mesh_peer_mgmt(pkt
, id
);
1205 case 118: return inf_mesh_ch_sw_para(pkt
, id
);
1206 case 119: return inf_mesh_awake_win(pkt
, id
);
1207 case 120: return inf_beacon_timing(pkt
, id
);
1208 case 121: return inf_mccaop_setup_req(pkt
, id
);
1209 case 122: return inf_mccaop_setup_rep(pkt
, id
);
1210 case 123: return inf_mccaop_adv(pkt
, id
);
1211 case 124: return inf_mccaop_teardwn(pkt
, id
);
1212 case 125: return inf_gann(pkt
, id
);
1213 case 126: return inf_rann(pkt
, id
);
1214 case 127: return inf_ext_cap(pkt
, id
);
1215 case 128: return inf_reserved(pkt
, id
);
1216 case 129: return inf_reserved(pkt
, id
);
1217 case 130: return inf_preq(pkt
, id
);
1218 case 131: return inf_prep(pkt
, id
);
1219 case 132: return inf_perr(pkt
, id
);
1220 case 133: return inf_reserved(pkt
, id
);
1221 case 134: return inf_reserved(pkt
, id
);
1222 case 135: return inf_reserved(pkt
, id
);
1223 case 136: return inf_reserved(pkt
, id
);
1224 case 137: return inf_pxu(pkt
, id
);
1225 case 138: return inf_pxuc(pkt
, id
);
1226 case 139: return inf_auth_mesh_peer_exch(pkt
, id
);
1227 case 140: return inf_mic(pkt
, id
);
1228 case 141: return inf_dest_uri(pkt
, id
);
1229 case 142: return inf_u_apsd_coex(pkt
, id
);
1230 case 143 ... 173: return inf_reserved(pkt
, id
);
1231 case 174: return inf_mccaop_adv_overv(pkt
, id
);
1232 case 221: return inf_vend_spec(pkt
, id
);
1238 #define ESS 0b0000000000000001
1239 #define IBSS 0b0000000000000010
1240 #define CF_Pollable 0b0000000000000100
1241 #define CF_Poll_Req 0b0000000000001000
1242 #define Privacy 0b0000000000010000
1243 #define Short_Pre 0b0000000000100000
1244 #define PBCC 0b0000000001000000
1245 #define Ch_Agility 0b0000000010000000
1246 #define Spec_Mgmt 0b0000000100000000
1247 #define QoS 0b0000001000000000
1248 #define Short_Slot_t 0b0000010000000000
1249 #define APSD 0b0000100000000000
1250 #define Radio_Meas 0b0001000000000000
1251 #define DSSS_OFDM 0b0010000000000000
1252 #define Del_Block_ACK 0b0100000000000000
1253 #define Imm_Block_ACK 0b1000000000000000
1255 static int8_t cap_field(u16 cap_inf
)
1261 if (CF_Pollable
& cap_inf
)
1262 tprintf(" CF Pollable;");
1263 if (CF_Poll_Req
& cap_inf
)
1264 tprintf(" CF-Poll Request;");
1265 if (Privacy
& cap_inf
)
1266 tprintf(" Privacy;");
1267 if (Short_Pre
& cap_inf
)
1268 tprintf(" Short Preamble;");
1271 if (Ch_Agility
& cap_inf
)
1272 tprintf(" Channel Agility;");
1273 if (Spec_Mgmt
& cap_inf
)
1274 tprintf(" Spectrum Management;");
1277 if (Short_Slot_t
& cap_inf
)
1278 tprintf(" Short Slot Time;");
1281 if (Radio_Meas
& cap_inf
)
1282 tprintf(" Radio Measurement;");
1283 if (DSSS_OFDM
& cap_inf
)
1284 tprintf(" DSSS-OFDM;");
1285 if (Del_Block_ACK
& cap_inf
)
1286 tprintf(" Delayed Block Ack;");
1287 if (Imm_Block_ACK
& cap_inf
)
1288 tprintf(" Immediate Block Ack;");
1293 /* Management Dissectors */
1294 static int8_t assoc_req(struct pkt_buff
*pkt
) {
1298 static int8_t assoc_resp(struct pkt_buff
*pkt
) {
1302 static int8_t reassoc_req(struct pkt_buff
*pkt
) {
1306 static int8_t reassoc_resp(struct pkt_buff
*pkt
) {
1310 static int8_t probe_req(struct pkt_buff
*pkt
) {
1314 static int8_t probe_resp(struct pkt_buff
*pkt
) {
1318 static int8_t beacon(struct pkt_buff
*pkt
)
1320 struct ieee80211_mgmt_beacon
*beacon
;
1322 beacon
= (struct ieee80211_mgmt_beacon
*)
1323 pkt_pull(pkt
, sizeof(*beacon
));
1327 tprintf("Timestamp 0x%.16lx, ", le64_to_cpu(beacon
->timestamp
));
1328 tprintf("Beacon Interval (%fs), ", le16_to_cpu(beacon
->beacon_int
)*TU
);
1329 tprintf("Capabilities (0x%x <->", le16_to_cpu(beacon
->capab_info
));
1330 cap_field(le16_to_cpu(beacon
->capab_info
));
1334 tprintf("\n\tParameters:");
1335 while (inf_elements(pkt
)) {
1345 static int8_t atim(struct pkt_buff
*pkt
) {
1349 static int8_t disassoc(struct pkt_buff
*pkt
) {
1353 static int8_t auth(struct pkt_buff
*pkt
) {
1357 static int8_t deauth(struct pkt_buff
*pkt
) {
1360 /* End Management Dissectors */
1362 /* Control Dissectors */
1363 static int8_t ps_poll(struct pkt_buff
*pkt
) {
1367 static int8_t rts(struct pkt_buff
*pkt
) {
1371 static int8_t cts(struct pkt_buff
*pkt
) {
1375 static int8_t ack(struct pkt_buff
*pkt
) {
1379 static int8_t cf_end(struct pkt_buff
*pkt
) {
1383 static int8_t cf_end_ack(struct pkt_buff
*pkt
) {
1386 /* End Control Dissectors */
1388 /* Data Dissectors */
1389 static int8_t data(struct pkt_buff
*pkt
) {
1393 static int8_t data_cf_ack(struct pkt_buff
*pkt
) {
1397 static int8_t data_cf_poll(struct pkt_buff
*pkt
) {
1401 static int8_t data_cf_ack_poll(struct pkt_buff
*pkt
) {
1405 static int8_t null(struct pkt_buff
*pkt
) {
1409 static int8_t cf_ack(struct pkt_buff
*pkt
) {
1413 static int8_t cf_poll(struct pkt_buff
*pkt
) {
1417 static int8_t cf_ack_poll(struct pkt_buff
*pkt
) {
1420 /* End Data Dissectors */
1422 static const char *mgt_sub(u8 subtype
, struct pkt_buff
*pkt
,
1423 int8_t (**get_content
)(struct pkt_buff
*pkt
))
1426 struct ieee80211_mgmt
*mgmt
;
1427 const char *dst
, *src
, *bssid
;
1429 mgmt
= (struct ieee80211_mgmt
*) pkt_pull(pkt
, sizeof(*mgmt
));
1433 dst
= lookup_vendor((mgmt
->da
[0] << 16) |
1434 (mgmt
->da
[1] << 8) |
1436 src
= lookup_vendor((mgmt
->sa
[0] << 16) |
1437 (mgmt
->sa
[1] << 8) |
1440 bssid
= lookup_vendor((mgmt
->bssid
[0] << 16) |
1441 (mgmt
->bssid
[1] << 8) |
1443 seq_ctrl
= le16_to_cpu(mgmt
->seq_ctrl
);
1445 tprintf("Duration (%u),", le16_to_cpu(mgmt
->duration
));
1446 tprintf("\n\tDestination (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1447 mgmt
->da
[0], mgmt
->da
[1], mgmt
->da
[2],
1448 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
1450 tprintf("=> (%s:%.2x:%.2x:%.2x)", dst
,
1451 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
1454 tprintf("\n\tSource (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1455 mgmt
->sa
[0], mgmt
->sa
[1], mgmt
->sa
[2],
1456 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
1458 tprintf("=> (%s:%.2x:%.2x:%.2x)", src
,
1459 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
1462 tprintf("\n\tBSSID (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1463 mgmt
->bssid
[0], mgmt
->bssid
[1], mgmt
->bssid
[2],
1464 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
1466 tprintf("=> (%s:%.2x:%.2x:%.2x)", bssid
,
1467 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
1470 tprintf("\n\tFragmentnr. (%u), Seqnr. (%u). ",
1471 seq_ctrl
& 0xf, seq_ctrl
>> 4);
1475 *get_content
= assoc_req
;
1476 return "Association Request";
1478 *get_content
= assoc_resp
;
1479 return "Association Response";
1481 *get_content
= reassoc_req
;
1482 return "Reassociation Request";
1484 *get_content
= reassoc_resp
;
1485 return "Reassociation Response";
1487 *get_content
= probe_req
;
1488 return "Probe Request";
1490 *get_content
= probe_resp
;
1491 return "Probe Response";
1493 *get_content
= beacon
;
1496 *get_content
= atim
;
1499 *get_content
= disassoc
;
1500 return "Disassociation";
1502 *get_content
= auth
;
1503 return "Authentication";
1505 *get_content
= deauth
;
1506 return "Deauthentication";
1507 case 0b0110 ... 0b0111:
1508 case 0b1101 ... 0b1111:
1509 *get_content
= NULL
;
1512 *get_content
= NULL
;
1513 return "Management SubType unknown";
1517 static const char *ctrl_sub(u8 subtype
, struct pkt_buff
*pkt
,
1518 int8_t (**get_content
)(struct pkt_buff
*pkt
))
1522 *get_content
= ps_poll
;
1534 *get_content
= cf_end
;
1537 *get_content
= cf_end_ack
;
1538 return "CF End + CF-ACK";
1539 case 0b0000 ... 0b1001:
1540 *get_content
= NULL
;
1543 return "Control SubType unkown";
1547 static const char *data_sub(u8 subtype
, struct pkt_buff
*pkt
,
1548 int8_t (**get_content
)(struct pkt_buff
*pkt
))
1552 *get_content
= data
;
1555 *get_content
= data_cf_ack
;
1556 return "Data + CF-ACK";
1558 *get_content
= data_cf_poll
;
1559 return "Data + CF-Poll";
1561 *get_content
= data_cf_ack_poll
;
1562 return "Data + CF-ACK + CF-Poll";
1564 *get_content
= null
;
1567 *get_content
= cf_ack
;
1570 *get_content
= cf_poll
;
1573 *get_content
= cf_ack_poll
;
1574 return "CF-ACK + CF-Poll";
1575 case 0b1000 ... 0b1111:
1576 *get_content
= NULL
;
1579 *get_content
= NULL
;
1580 return "Data SubType unkown";
1585 frame_control_type(u8 type
, const char *(**get_subtype
)(u8 subtype
,
1586 struct pkt_buff
*pkt
, int8_t (**get_content
)(struct pkt_buff
*pkt
)))
1590 *get_subtype
= mgt_sub
;
1591 return "Management";
1593 *get_subtype
= ctrl_sub
;
1596 *get_subtype
= data_sub
;
1599 *get_subtype
= NULL
;
1602 *get_subtype
= NULL
;
1603 return "Control Type unkown";
1607 static void ieee80211(struct pkt_buff
*pkt
)
1609 int8_t (*get_content
)(struct pkt_buff
*pkt
) = NULL
;
1610 const char *(*get_subtype
)(u8 subtype
, struct pkt_buff
*pkt
,
1611 int8_t (**get_content
)(struct pkt_buff
*pkt
)) = NULL
;
1612 const char *subtype
= NULL
;
1613 struct ieee80211_frm_ctrl
*frm_ctrl
;
1615 frm_ctrl
= (struct ieee80211_frm_ctrl
*)
1616 pkt_pull(pkt
, sizeof(*frm_ctrl
));
1617 if (frm_ctrl
== NULL
)
1620 tprintf(" [ 802.11 Frame Control (0x%04x)]\n",
1621 le16_to_cpu(frm_ctrl
->frame_control
));
1623 tprintf(" [ Proto Version (%u), ", frm_ctrl
->proto_version
);
1624 tprintf("Type (%u, %s), ", frm_ctrl
->type
,
1625 frame_control_type(frm_ctrl
->type
, &get_subtype
));
1627 subtype
= (*get_subtype
)(frm_ctrl
->subtype
, pkt
, &get_content
);
1628 tprintf("Subtype (%u, %s)", frm_ctrl
->subtype
, subtype
);
1630 tprintf("\n%s%s%s", colorize_start_full(black
, red
),
1631 "No SubType Data available", colorize_end());
1634 tprintf("%s%s", frm_ctrl
->to_ds
? ", Frame goes to DS" : "",
1635 frm_ctrl
->from_ds
? ", Frame comes from DS" : "");
1636 tprintf("%s", frm_ctrl
->more_frags
? ", More Fragments" : "");
1637 tprintf("%s", frm_ctrl
->retry
? ", Frame is retransmitted" : "");
1638 tprintf("%s", frm_ctrl
->power_mgmt
? ", In Power Saving Mode" : "");
1639 tprintf("%s", frm_ctrl
->more_data
? ", More Data" : "");
1640 tprintf("%s", frm_ctrl
->wep
? ", Needs WEP" : "");
1641 tprintf("%s", frm_ctrl
->order
? ", Order" : "");
1645 tprintf(" [ Subtype %s: ", subtype
);
1646 if (!((*get_content
) (pkt
)))
1647 tprintf("\n%s%s%s", colorize_start_full(black
, red
),
1648 "Failed to dissect Subtype", colorize_end());
1651 tprintf("\n%s%s%s", colorize_start_full(black
, red
),
1652 "No SubType Data available", colorize_end());
1655 // pkt_set_proto(pkt, &ieee802_lay2, ntohs(eth->h_proto));
1658 static void ieee80211_less(struct pkt_buff
*pkt
)
1660 tprintf("802.11 frame (more on todo)");
1663 struct protocol ieee80211_ops
= {
1665 .print_full
= ieee80211
,
1666 .print_less
= ieee80211_less
,
1669 EXPORT_SYMBOL(ieee80211_ops
);