2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Daniel Borkmann <borkmann@iogearbox.net>
4 * Copyright 2012 Markus Amend <markus@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"
20 /* Note: Fields are encoded in little-endian! */
21 struct ieee80211_frm_ctrl
{
25 #if defined(__LITTLE_ENDIAN_BITFIELD)
26 /* Correct order here ... */
27 __extension__ u16 proto_version
:2,
38 #elif defined(__BIG_ENDIAN_BITFIELD)
39 __extension__ u16 subtype
:4,
51 # error "Adjust your <asm/byteorder.h> defines"
57 /* Management Frame start */
58 /* Note: Fields are encoded in little-endian! */
59 struct ieee80211_mgmt
{
67 struct ieee80211_mgmt_auth
{
71 /* possibly followed by Challenge text */
75 struct ieee80211_mgmt_deauth
{
79 struct ieee80211_mgmt_assoc_req
{
82 /* followed by SSID and Supported rates */
86 struct ieee80211_mgmt_assoc_resp
{
90 /* followed by Supported rates */
94 struct ieee80211_mgmt_reassoc_resp
{
98 /* followed by Supported rates */
102 struct ieee80211_mgmt_reassoc_req
{
106 /* followed by SSID and Supported rates */
110 struct ieee80211_mgmt_disassoc
{
114 struct ieee80211_mgmt_probe_req
{
117 struct ieee80211_mgmt_beacon
{
121 /* followed by some of SSID, Supported rates,
122 * FH Params, DS Params, CF Params, IBSS Params, TIM */
126 struct ieee80211_mgmt_probe_resp
{
130 /* followed by some of SSID, Supported rates,
131 * FH Params, DS Params, CF Params, IBSS Params, TIM */
134 /* Management Frame end */
136 /* Control Frame start */
137 /* Note: Fields are encoded in little-endian! */
138 struct ieee80211_ctrl
{
141 struct ieee80211_ctrl_rts
{
147 struct ieee80211_ctrl_cts
{
152 struct ieee80211_ctrl_ack
{
157 struct ieee80211_ctrl_ps_poll
{
163 struct ieee80211_ctrl_cf_end
{
169 struct ieee80211_ctrl_cf_end_ack
{
174 /* Control Frame end */
176 /* Data Frame start */
177 /* Note: Fields are encoded in little-endian! */
178 struct ieee80211_data
{
185 /* http://www.sss-mag.com/pdf/802_11tut.pdf
186 * http://www.scribd.com/doc/78443651/111/Management-Frames
187 * http://www.wildpackets.com/resources/compendium/wireless_lan/wlan_packets
188 * http://www.rhyshaden.com/wireless.htm
191 struct element_reserved
{
195 struct element_ssid
{
200 struct element_supp_rates
{
205 struct element_fh_ps
{
213 struct element_dsss_ps
{
218 struct element_cf_ps
{
245 struct element_ext_supp_rates
{
251 struct element_vend_spec
{
257 static float data_rates(u8 id
) {
304 static int8_t inf_reserved(struct pkt_buff
*pkt
, u8
*id
) {
305 struct element_reserved
*reserved
=
306 (struct element_reserved
*) pkt_pull(pkt
, sizeof(*reserved
));
307 if (reserved
== NULL
)
310 tprintf(" Reserved (%u, Len (%u)): ", *id
, reserved
->len
);
312 if (!pkt_pull(pkt
, reserved
->len
))
318 static int8_t inf_ssid(struct pkt_buff
*pkt
, u8
*id
) {
319 struct element_ssid
*ssid
=
320 (struct element_ssid
*) pkt_pull(pkt
, sizeof(*ssid
));
324 tprintf(" SSID (%u, Len (%u)): ", *id
, ssid
->len
);
327 char *ssid_name
= (char *) pkt_pull(pkt
, ssid
->len
);
328 if (ssid_name
== NULL
)
330 for(u8 i
=0; i
< ssid
->len
; i
++)
331 tprintf("%c",ssid_name
[i
]);
334 tprintf("Wildcard SSID");
339 static int8_t inf_supp_rates(struct pkt_buff
*pkt
, u8
*id
) {
340 struct element_supp_rates
*supp_rates
=
341 (struct element_supp_rates
*) pkt_pull(pkt
, sizeof(*supp_rates
));
342 if (supp_rates
== NULL
)
345 tprintf("Rates (%u, Len (%u)): ", *id
, supp_rates
->len
);
347 if (supp_rates
->len
) {
348 u8
*rates
= pkt_pull(pkt
, supp_rates
->len
);
351 for(u8 i
=0; i
< supp_rates
->len
; i
++)
352 tprintf("%g ",(rates
[i
] & 0x80) ? ((rates
[i
] & 0x3f) * 0.5) : data_rates(rates
[i
]));
360 static int8_t inf_fh_ps(struct pkt_buff
*pkt
, u8
*id
) {
361 struct element_fh_ps
*fh_ps
=
362 (struct element_fh_ps
*) pkt_pull(pkt
, sizeof(*fh_ps
));
366 tprintf("FH Param Set (%u, Len(%u)): ", *id
, fh_ps
->len
);
367 tprintf("Dwell Time: %fs, ", le16_to_cpu(fh_ps
->dwell_time
) * 0.001024);
368 tprintf("HopSet: %u, ", fh_ps
->hop_set
);
369 tprintf("HopPattern: %u, ", fh_ps
->hop_pattern
);
370 tprintf("HopIndex: %u", fh_ps
->hop_index
);
375 static int8_t inf_dsss_ps(struct pkt_buff
*pkt
, u8
*id
) {
376 struct element_dsss_ps
*dsss_ps
=
377 (struct element_dsss_ps
*) pkt_pull(pkt
, sizeof(*dsss_ps
));
381 tprintf("DSSS Param Set (%u, Len(%u)): ", *id
, dsss_ps
->len
);
382 tprintf("Current Channel: %u", dsss_ps
->curr_ch
);
387 static int8_t inf_cf_ps(struct pkt_buff
*pkt
, u8
*id
) {
388 struct element_cf_ps
*cf_ps
=
389 (struct element_cf_ps
*) pkt_pull(pkt
, sizeof(*cf_ps
));
393 tprintf("CF Param Set (%u, Len(%u)): ", *id
, cf_ps
->len
);
394 tprintf("CFP Count: %u, ", cf_ps
->cfp_cnt
);
395 tprintf("CFP Period: %u, ", cf_ps
->cfp_period
);
396 tprintf("CFP MaxDur: %fs, ", le16_to_cpu(cf_ps
->cfp_max_dur
) * 0.001024);
397 tprintf("CFP DurRem: %fs", le16_to_cpu(cf_ps
->cfp_dur_rem
) * 0.001024);
402 static int8_t inf_tim(struct pkt_buff
*pkt
, u8
*id
) {
403 struct element_tim
*tim
=
404 (struct element_tim
*) pkt_pull(pkt
, sizeof(*tim
));
408 tprintf("TIM (%u, Len(%u)): ", *id
, tim
->len
);
409 tprintf("DTIM Count: %u, ", tim
->dtim_cnt
);
410 tprintf("DTIM Period: %u, ", tim
->dtim_period
);
411 tprintf("Bitmap Control: %u, ", tim
->bmp_cntrl
);
412 if ((tim
->len
- sizeof(*tim
) + 1) > 0) {
413 u8
*bmp
= pkt_pull(pkt
, (tim
->len
- sizeof(*tim
) + 1));
416 tprintf("Partial Virtual Bitmap: 0x");
417 for(u8 i
=0; i
< (tim
->len
- sizeof(*tim
) + 1); i
++)
418 tprintf("%.2x ", bmp
[i
]);
424 static int8_t inf_ibss_ps(struct pkt_buff
*pkt
, u8
*id
) {
428 static int8_t inf_country(struct pkt_buff
*pkt
, u8
*id
) {
432 static int8_t inf_hop_pp(struct pkt_buff
*pkt
, u8
*id
) {
436 static int8_t inf_hop_pt(struct pkt_buff
*pkt
, u8
*id
) {
440 static int8_t inf_req(struct pkt_buff
*pkt
, u8
*id
) {
444 static int8_t inf_bss_load(struct pkt_buff
*pkt
, u8
*id
) {
448 static int8_t inf_edca_ps(struct pkt_buff
*pkt
, u8
*id
) {
452 static int8_t inf_tspec(struct pkt_buff
*pkt
, u8
*id
) {
456 static int8_t inf_tclas(struct pkt_buff
*pkt
, u8
*id
) {
460 static int8_t inf_sched(struct pkt_buff
*pkt
, u8
*id
) {
464 static int8_t inf_chall_txt(struct pkt_buff
*pkt
, u8
*id
) {
468 static int8_t inf_pwr_constr(struct pkt_buff
*pkt
, u8
*id
) {
472 static int8_t inf_pwr_cap(struct pkt_buff
*pkt
, u8
*id
) {
476 static int8_t inf_tpc_req(struct pkt_buff
*pkt
, u8
*id
) {
480 static int8_t inf_tpc_rep(struct pkt_buff
*pkt
, u8
*id
) {
484 static int8_t inf_supp_ch(struct pkt_buff
*pkt
, u8
*id
) {
488 static int8_t inf_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
) {
492 static int8_t inf_meas_req(struct pkt_buff
*pkt
, u8
*id
) {
496 static int8_t inf_meas_rep(struct pkt_buff
*pkt
, u8
*id
) {
500 static int8_t inf_quiet(struct pkt_buff
*pkt
, u8
*id
) {
504 static int8_t inf_ibss_dfs(struct pkt_buff
*pkt
, u8
*id
) {
508 static int8_t inf_erp(struct pkt_buff
*pkt
, u8
*id
) {
509 struct element_erp
*erp
=
510 (struct element_erp
*) pkt_pull(pkt
, sizeof(*erp
));
514 tprintf("ERP (%u, Len(%u)): ", *id
, erp
->len
);
515 tprintf("Non ERP Present (%u), ", erp
->param
& 0x1);
516 tprintf("Use Protection (%u), ", (erp
->param
>> 1) & 0x1);
517 tprintf("Barker Preamble Mode (%u), ", (erp
->param
>> 2) & 0x1);
518 tprintf("Reserved (0x%.5x)", erp
->param
>> 3);
523 static int8_t inf_ts_del(struct pkt_buff
*pkt
, u8
*id
) {
527 static int8_t inf_tclas_proc(struct pkt_buff
*pkt
, u8
*id
) {
531 static int8_t inf_ht_cap(struct pkt_buff
*pkt
, u8
*id
) {
535 static int8_t inf_qos_cap(struct pkt_buff
*pkt
, u8
*id
) {
539 static int8_t inf_rsn(struct pkt_buff
*pkt
, u8
*id
) {
543 static int8_t inf_ext_supp_rates(struct pkt_buff
*pkt
, u8
*id
) {
544 struct element_ext_supp_rates
*ext_supp_rates
=
545 (struct element_ext_supp_rates
*) pkt_pull(pkt
, sizeof(*ext_supp_rates
));
546 if (ext_supp_rates
== NULL
)
549 tprintf("Ext Support Rates (%u, Len(%u)): ", *id
, ext_supp_rates
->len
);
551 if (ext_supp_rates
->len
) {
552 u8
*rates
= pkt_pull(pkt
, ext_supp_rates
->len
);
555 for(u8 i
=0; i
< ext_supp_rates
->len
; i
++)
556 tprintf("%g ",(rates
[i
] & 0x80) ? ((rates
[i
] & 0x3f) * 0.5) : data_rates(rates
[i
]));
564 static int8_t inf_ap_ch_exp(struct pkt_buff
*pkt
, u8
*id
) {
568 static int8_t inf_neighb_rep(struct pkt_buff
*pkt
, u8
*id
) {
572 static int8_t inf_rcpi(struct pkt_buff
*pkt
, u8
*id
) {
576 static int8_t inf_mde(struct pkt_buff
*pkt
, u8
*id
) {
580 static int8_t inf_fte(struct pkt_buff
*pkt
, u8
*id
) {
584 static int8_t inf_time_out_int(struct pkt_buff
*pkt
, u8
*id
) {
588 static int8_t inf_rde(struct pkt_buff
*pkt
, u8
*id
) {
592 static int8_t inf_dse_reg_loc(struct pkt_buff
*pkt
, u8
*id
) {
596 static int8_t inf_supp_op_class(struct pkt_buff
*pkt
, u8
*id
) {
600 static int8_t inf_ext_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
) {
604 static int8_t inf_ht_op(struct pkt_buff
*pkt
, u8
*id
) {
608 static int8_t inf_sec_ch_offs(struct pkt_buff
*pkt
, u8
*id
) {
612 static int8_t inf_bss_avg_acc_del(struct pkt_buff
*pkt
, u8
*id
) {
616 static int8_t inf_ant(struct pkt_buff
*pkt
, u8
*id
) {
620 static int8_t inf_rsni(struct pkt_buff
*pkt
, u8
*id
) {
624 static int8_t inf_meas_pilot_trans(struct pkt_buff
*pkt
, u8
*id
) {
628 static int8_t inf_bss_avl_adm_cap(struct pkt_buff
*pkt
, u8
*id
) {
632 static int8_t inf_bss_ac_acc_del(struct pkt_buff
*pkt
, u8
*id
) {
636 static int8_t inf_time_adv(struct pkt_buff
*pkt
, u8
*id
) {
640 static int8_t inf_rm_ena_cap(struct pkt_buff
*pkt
, u8
*id
) {
644 static int8_t inf_mult_bssid(struct pkt_buff
*pkt
, u8
*id
) {
648 static int8_t inf_20_40_bss_coex(struct pkt_buff
*pkt
, u8
*id
) {
652 static int8_t inf_20_40_bss_int_ch_rep(struct pkt_buff
*pkt
, u8
*id
) {
656 static int8_t inf_overl_bss_scan_para(struct pkt_buff
*pkt
, u8
*id
) {
660 static int8_t inf_ric_desc(struct pkt_buff
*pkt
, u8
*id
) {
664 static int8_t inf_mgmt_mic(struct pkt_buff
*pkt
, u8
*id
) {
668 static int8_t inf_ev_req(struct pkt_buff
*pkt
, u8
*id
) {
672 static int8_t inf_ev_rep(struct pkt_buff
*pkt
, u8
*id
) {
676 static int8_t inf_diagn_req(struct pkt_buff
*pkt
, u8
*id
) {
680 static int8_t inf_diagn_rep(struct pkt_buff
*pkt
, u8
*id
) {
684 static int8_t inf_loc_para(struct pkt_buff
*pkt
, u8
*id
) {
688 static int8_t inf_nontr_bssid_cap(struct pkt_buff
*pkt
, u8
*id
) {
692 static int8_t inf_ssid_list(struct pkt_buff
*pkt
, u8
*id
) {
696 static int8_t inf_mult_bssid_index(struct pkt_buff
*pkt
, u8
*id
) {
700 static int8_t inf_fms_desc(struct pkt_buff
*pkt
, u8
*id
) {
704 static int8_t inf_fms_req(struct pkt_buff
*pkt
, u8
*id
) {
708 static int8_t inf_fms_resp(struct pkt_buff
*pkt
, u8
*id
) {
712 static int8_t inf_qos_tfc_cap(struct pkt_buff
*pkt
, u8
*id
) {
716 static int8_t inf_bss_max_idle_per(struct pkt_buff
*pkt
, u8
*id
) {
720 static int8_t inf_tfs_req(struct pkt_buff
*pkt
, u8
*id
) {
724 static int8_t inf_tfs_resp(struct pkt_buff
*pkt
, u8
*id
) {
728 static int8_t inf_wnm_sleep_mod(struct pkt_buff
*pkt
, u8
*id
) {
732 static int8_t inf_tim_bcst_req(struct pkt_buff
*pkt
, u8
*id
) {
736 static int8_t inf_tim_bcst_resp(struct pkt_buff
*pkt
, u8
*id
) {
740 static int8_t inf_coll_interf_rep(struct pkt_buff
*pkt
, u8
*id
) {
744 static int8_t inf_ch_usage(struct pkt_buff
*pkt
, u8
*id
) {
748 static int8_t inf_time_zone(struct pkt_buff
*pkt
, u8
*id
) {
752 static int8_t inf_dms_req(struct pkt_buff
*pkt
, u8
*id
) {
756 static int8_t inf_dms_resp(struct pkt_buff
*pkt
, u8
*id
) {
760 static int8_t inf_link_id(struct pkt_buff
*pkt
, u8
*id
) {
764 static int8_t inf_wakeup_sched(struct pkt_buff
*pkt
, u8
*id
) {
768 static int8_t inf_ch_sw_timing(struct pkt_buff
*pkt
, u8
*id
) {
772 static int8_t inf_pti_ctrl(struct pkt_buff
*pkt
, u8
*id
) {
776 static int8_t inf_tpu_buff_status(struct pkt_buff
*pkt
, u8
*id
) {
780 static int8_t inf_interw(struct pkt_buff
*pkt
, u8
*id
) {
784 static int8_t inf_adv_proto(struct pkt_buff
*pkt
, u8
*id
) {
788 static int8_t inf_exp_bandw_req(struct pkt_buff
*pkt
, u8
*id
) {
792 static int8_t inf_qos_map_set(struct pkt_buff
*pkt
, u8
*id
) {
796 static int8_t inf_roam_cons(struct pkt_buff
*pkt
, u8
*id
) {
800 static int8_t inf_emer_alert_id(struct pkt_buff
*pkt
, u8
*id
) {
804 static int8_t inf_mesh_conf(struct pkt_buff
*pkt
, u8
*id
) {
808 static int8_t inf_mesh_id(struct pkt_buff
*pkt
, u8
*id
) {
812 static int8_t inf_mesh_link_metr_rep(struct pkt_buff
*pkt
, u8
*id
) {
816 static int8_t inf_cong_notif(struct pkt_buff
*pkt
, u8
*id
) {
820 static int8_t inf_mesh_peer_mgmt(struct pkt_buff
*pkt
, u8
*id
) {
824 static int8_t inf_mesh_ch_sw_para(struct pkt_buff
*pkt
, u8
*id
) {
828 static int8_t inf_mesh_awake_win(struct pkt_buff
*pkt
, u8
*id
) {
832 static int8_t inf_beacon_timing(struct pkt_buff
*pkt
, u8
*id
) {
836 static int8_t inf_mccaop_setup_req(struct pkt_buff
*pkt
, u8
*id
) {
840 static int8_t inf_mccaop_setup_rep(struct pkt_buff
*pkt
, u8
*id
) {
844 static int8_t inf_mccaop_adv(struct pkt_buff
*pkt
, u8
*id
) {
848 static int8_t inf_mccaop_teardwn(struct pkt_buff
*pkt
, u8
*id
) {
852 static int8_t inf_gann(struct pkt_buff
*pkt
, u8
*id
) {
856 static int8_t inf_rann(struct pkt_buff
*pkt
, u8
*id
) {
860 static int8_t inf_ext_cap(struct pkt_buff
*pkt
, u8
*id
) {
864 static int8_t inf_preq(struct pkt_buff
*pkt
, u8
*id
) {
868 static int8_t inf_prep(struct pkt_buff
*pkt
, u8
*id
) {
872 static int8_t inf_perr(struct pkt_buff
*pkt
, u8
*id
) {
876 static int8_t inf_pxu(struct pkt_buff
*pkt
, u8
*id
) {
880 static int8_t inf_pxuc(struct pkt_buff
*pkt
, u8
*id
) {
884 static int8_t inf_auth_mesh_peer_exch(struct pkt_buff
*pkt
, u8
*id
) {
888 static int8_t inf_mic(struct pkt_buff
*pkt
, u8
*id
) {
892 static int8_t inf_dest_uri(struct pkt_buff
*pkt
, u8
*id
) {
896 static int8_t inf_u_apsd_coex(struct pkt_buff
*pkt
, u8
*id
) {
900 static int8_t inf_mccaop_adv_overv(struct pkt_buff
*pkt
, u8
*id
) {
904 static int8_t inf_vend_spec(struct pkt_buff
*pkt
, u8
*id
) {
905 struct element_vend_spec
*vend_spec
=
906 (struct element_vend_spec
*) pkt_pull(pkt
, sizeof(*vend_spec
));
907 if (vend_spec
== NULL
)
910 tprintf("Vendor Specific (%u, Len (%u)): ", *id
, vend_spec
->len
);
912 u8
*data
= pkt_pull(pkt
, vend_spec
->len
);
917 for(u8 i
=0; i
< vend_spec
->len
; i
++)
918 tprintf("%.2x", data
[i
]);
923 static int8_t inf_elements(struct pkt_buff
*pkt
) {
924 u8
*id
= pkt_pull(pkt
, 1);
931 return inf_ssid(pkt
, id
);
933 return inf_supp_rates(pkt
, id
);
935 return inf_fh_ps(pkt
, id
);
937 return inf_dsss_ps(pkt
, id
);
939 return inf_cf_ps(pkt
, id
);
941 return inf_tim(pkt
, id
);
943 return inf_ibss_ps(pkt
, id
);
945 return inf_country(pkt
, id
);
947 return inf_hop_pp(pkt
, id
);
949 return inf_hop_pt(pkt
, id
);
951 return inf_req(pkt
, id
);
953 return inf_bss_load(pkt
, id
);
955 return inf_edca_ps(pkt
, id
);
957 return inf_tspec(pkt
, id
);
959 return inf_tclas(pkt
, id
);
961 return inf_sched(pkt
, id
);
963 return inf_chall_txt(pkt
, id
);
965 return inf_pwr_constr(pkt
, id
);
967 return inf_pwr_cap(pkt
, id
);
969 return inf_tpc_req(pkt
, id
);
971 return inf_tpc_rep(pkt
, id
);
973 return inf_supp_ch(pkt
, id
);
975 return inf_ch_sw_ann(pkt
, id
);
977 return inf_meas_req(pkt
, id
);
979 return inf_meas_rep(pkt
, id
);
981 return inf_quiet(pkt
, id
);
983 return inf_ibss_dfs(pkt
, id
);
985 return inf_erp(pkt
, id
);
987 return inf_ts_del(pkt
, id
);
989 return inf_tclas_proc(pkt
, id
);
991 return inf_ht_cap(pkt
, id
);
993 return inf_qos_cap(pkt
, id
);
995 return inf_reserved(pkt
, id
);
997 return inf_rsn(pkt
, id
);
999 return inf_rsn(pkt
, id
);
1001 return inf_ext_supp_rates(pkt
, id
);
1003 return inf_ap_ch_exp(pkt
, id
);
1005 return inf_neighb_rep(pkt
, id
);
1007 return inf_rcpi(pkt
, id
);
1009 return inf_mde(pkt
, id
);
1011 return inf_fte(pkt
, id
);
1013 return inf_time_out_int(pkt
, id
);
1015 return inf_rde(pkt
, id
);
1017 return inf_dse_reg_loc(pkt
, id
);
1019 return inf_supp_op_class(pkt
, id
);
1021 return inf_ext_ch_sw_ann(pkt
, id
);
1023 return inf_ht_op(pkt
, id
);
1025 return inf_sec_ch_offs(pkt
, id
);
1027 return inf_bss_avg_acc_del(pkt
, id
);
1029 return inf_ant(pkt
, id
);
1031 return inf_rsni(pkt
, id
);
1033 return inf_meas_pilot_trans(pkt
, id
);
1035 return inf_bss_avl_adm_cap(pkt
, id
);
1037 return inf_bss_ac_acc_del(pkt
, id
);
1039 return inf_time_adv(pkt
, id
);
1041 return inf_rm_ena_cap(pkt
, id
);
1043 return inf_mult_bssid(pkt
, id
);
1045 return inf_20_40_bss_coex(pkt
, id
);
1047 return inf_20_40_bss_int_ch_rep(pkt
, id
);
1049 return inf_overl_bss_scan_para(pkt
, id
);
1051 return inf_ric_desc(pkt
, id
);
1053 return inf_mgmt_mic(pkt
, id
);
1055 return inf_ev_req(pkt
, id
);
1057 return inf_ev_rep(pkt
, id
);
1059 return inf_diagn_req(pkt
, id
);
1061 return inf_diagn_rep(pkt
, id
);
1063 return inf_loc_para(pkt
, id
);
1065 return inf_nontr_bssid_cap(pkt
, id
);
1067 return inf_ssid_list(pkt
, id
);
1069 return inf_mult_bssid_index(pkt
, id
);
1071 return inf_fms_desc(pkt
, id
);
1073 return inf_fms_req(pkt
, id
);
1075 return inf_fms_resp(pkt
, id
);
1077 return inf_qos_tfc_cap(pkt
, id
);
1079 return inf_bss_max_idle_per(pkt
, id
);
1081 return inf_tfs_req(pkt
, id
);
1083 return inf_tfs_resp(pkt
, id
);
1085 return inf_wnm_sleep_mod(pkt
, id
);
1087 return inf_tim_bcst_req(pkt
, id
);
1089 return inf_tim_bcst_resp(pkt
, id
);
1091 return inf_coll_interf_rep(pkt
, id
);
1093 return inf_ch_usage(pkt
, id
);
1095 return inf_time_zone(pkt
, id
);
1097 return inf_dms_req(pkt
, id
);
1099 return inf_dms_resp(pkt
, id
);
1101 return inf_link_id(pkt
, id
);
1103 return inf_wakeup_sched(pkt
, id
);
1105 return inf_ch_sw_timing(pkt
, id
);
1107 return inf_pti_ctrl(pkt
, id
);
1109 return inf_tpu_buff_status(pkt
, id
);
1111 return inf_interw(pkt
, id
);
1113 return inf_adv_proto(pkt
, id
);
1115 return inf_exp_bandw_req(pkt
, id
);
1117 return inf_qos_map_set(pkt
, id
);
1119 return inf_roam_cons(pkt
, id
);
1121 return inf_emer_alert_id(pkt
, id
);
1123 return inf_mesh_conf(pkt
, id
);
1125 return inf_mesh_id(pkt
, id
);
1127 return inf_mesh_link_metr_rep(pkt
, id
);
1129 return inf_cong_notif(pkt
, id
);
1131 return inf_mesh_peer_mgmt(pkt
, id
);
1133 return inf_mesh_ch_sw_para(pkt
, id
);
1135 return inf_mesh_awake_win(pkt
, id
);
1137 return inf_beacon_timing(pkt
, id
);
1139 return inf_mccaop_setup_req(pkt
, id
);
1141 return inf_mccaop_setup_rep(pkt
, id
);
1143 return inf_mccaop_adv(pkt
, id
);
1145 return inf_mccaop_teardwn(pkt
, id
);
1147 return inf_gann(pkt
, id
);
1149 return inf_rann(pkt
, id
);
1151 return inf_ext_cap(pkt
, id
);
1153 return inf_reserved(pkt
, id
);
1155 return inf_reserved(pkt
, id
);
1157 return inf_preq(pkt
, id
);
1159 return inf_prep(pkt
, id
);
1161 return inf_perr(pkt
, id
);
1163 return inf_reserved(pkt
, id
);
1165 return inf_reserved(pkt
, id
);
1167 return inf_reserved(pkt
, id
);
1169 return inf_reserved(pkt
, id
);
1171 return inf_pxu(pkt
, id
);
1173 return inf_pxuc(pkt
, id
);
1175 return inf_auth_mesh_peer_exch(pkt
, id
);
1177 return inf_mic(pkt
, id
);
1179 return inf_dest_uri(pkt
, id
);
1181 return inf_u_apsd_coex(pkt
, id
);
1183 return inf_mccaop_adv_overv(pkt
, id
);
1185 return inf_vend_spec(pkt
, id
);
1188 if((*id
>= 17 && *id
<= 31) || (*id
>= 143 && *id
<= 173))
1189 return inf_reserved(pkt
, id
);
1194 static int8_t cap_field(u16 cap_inf
) {
1196 #define ESS 0b0000000000000001
1197 #define IBSS 0b0000000000000010
1198 #define CF_Pollable 0b0000000000000100
1199 #define CF_Poll_Req 0b0000000000001000
1200 #define Privacy 0b0000000000010000
1201 #define Short_Pre 0b0000000000100000
1202 #define PBCC 0b0000000001000000
1203 #define Ch_Agility 0b0000000010000000
1204 #define Spec_Mgmt 0b0000000100000000
1205 #define QoS 0b0000001000000000
1206 #define Short_Slot_t 0b0000010000000000
1207 #define APSD 0b0000100000000000
1208 #define Radio_Meas 0b0001000000000000
1209 #define DSSS_OFDM 0b0010000000000000
1210 #define Del_Block_ACK 0b0100000000000000
1211 #define Imm_Block_ACK 0b1000000000000000
1217 if(CF_Pollable
& cap_inf
)
1218 tprintf(" CF Pollable;");
1219 if(CF_Poll_Req
& cap_inf
)
1220 tprintf(" CF-Poll Request;");
1221 if(Privacy
& cap_inf
)
1222 tprintf(" Privacy;");
1223 if(Short_Pre
& cap_inf
)
1224 tprintf(" Short Preamble;");
1227 if(Ch_Agility
& cap_inf
)
1228 tprintf(" Channel Agility;");
1229 if(Spec_Mgmt
& cap_inf
)
1230 tprintf(" Spectrum Management;");
1233 if(Short_Slot_t
& cap_inf
)
1234 tprintf(" Short Slot Time;");
1237 if(Radio_Meas
& cap_inf
)
1238 tprintf(" Radio Measurement;");
1239 if(DSSS_OFDM
& cap_inf
)
1240 tprintf(" DSSS-OFDM;");
1241 if(Del_Block_ACK
& cap_inf
)
1242 tprintf(" Delayed Block Ack;");
1243 if(Imm_Block_ACK
& cap_inf
)
1244 tprintf(" Immediate Block Ack;");
1249 /* Management Dissectors */
1250 static int8_t assoc_req(struct pkt_buff
*pkt
) {
1254 static int8_t assoc_resp(struct pkt_buff
*pkt
) {
1258 static int8_t reassoc_req(struct pkt_buff
*pkt
) {
1262 static int8_t reassoc_resp(struct pkt_buff
*pkt
) {
1266 static int8_t probe_req(struct pkt_buff
*pkt
) {
1270 static int8_t probe_resp(struct pkt_buff
*pkt
) {
1274 static int8_t beacon(struct pkt_buff
*pkt
) {
1275 struct ieee80211_mgmt_beacon
*beacon
=
1276 (struct ieee80211_mgmt_beacon
*) pkt_pull(pkt
, sizeof(*beacon
));
1279 tprintf("Timestamp 0x%.16lx, ", le64_to_cpu(beacon
->timestamp
));
1280 tprintf("Beacon Interval (%fs), ",
1281 le16_to_cpu(beacon
->beacon_int
) * 0.001024);
1282 tprintf("Capabilities (0x%x <->",
1283 le16_to_cpu(beacon
->capab_info
));
1284 cap_field(le16_to_cpu(beacon
->capab_info
));
1288 tprintf("\n\tParameters:");
1289 while (inf_elements(pkt
)) {
1300 static int8_t atim(struct pkt_buff
*pkt
) {
1304 static int8_t disassoc(struct pkt_buff
*pkt
) {
1308 static int8_t auth(struct pkt_buff
*pkt
) {
1312 static int8_t deauth(struct pkt_buff
*pkt
) {
1315 /* End Management Dissectors */
1317 /* Control Dissectors */
1318 static int8_t ps_poll(struct pkt_buff
*pkt
) {
1322 static int8_t rts(struct pkt_buff
*pkt
) {
1326 static int8_t cts(struct pkt_buff
*pkt
) {
1330 static int8_t ack(struct pkt_buff
*pkt
) {
1334 static int8_t cf_end(struct pkt_buff
*pkt
) {
1338 static int8_t cf_end_ack(struct pkt_buff
*pkt
) {
1341 /* End Control Dissectors */
1343 /* Data Dissectors */
1344 static int8_t data(struct pkt_buff
*pkt
) {
1348 static int8_t data_cf_ack(struct pkt_buff
*pkt
) {
1352 static int8_t data_cf_poll(struct pkt_buff
*pkt
) {
1356 static int8_t data_cf_ack_poll(struct pkt_buff
*pkt
) {
1360 static int8_t null(struct pkt_buff
*pkt
) {
1364 static int8_t cf_ack(struct pkt_buff
*pkt
) {
1368 static int8_t cf_poll(struct pkt_buff
*pkt
) {
1372 static int8_t cf_ack_poll(struct pkt_buff
*pkt
) {
1375 /* End Data Dissectors */
1377 static char *mgt_sub(u8 subtype
, struct pkt_buff
*pkt
, int8_t (**get_content
)(struct pkt_buff
*pkt
)) {
1379 struct ieee80211_mgmt
*mgmt
=
1380 (struct ieee80211_mgmt
*) pkt_pull(pkt
, sizeof(*mgmt
));
1384 const char *dst
= lookup_vendor((mgmt
->da
[0] << 16) | (mgmt
->da
[1] << 8) | mgmt
->da
[2]);
1385 const char *src
= lookup_vendor((mgmt
->sa
[0] << 16) | (mgmt
->sa
[1] << 8) | mgmt
->sa
[2]);
1386 const char *bssid
= lookup_vendor((mgmt
->bssid
[0] << 16) | (mgmt
->bssid
[1] << 8) | mgmt
->bssid
[2]);
1387 u16 seq_ctrl
= le16_to_cpu(mgmt
->seq_ctrl
);
1389 tprintf("Duration (%u),", le16_to_cpu(mgmt
->duration
));
1390 tprintf("\n\tDestination (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1391 mgmt
->da
[0], mgmt
->da
[1], mgmt
->da
[2], mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
1393 tprintf("=> (%s:%.2x:%.2x:%.2x)", dst
, mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
1394 tprintf("\n\tSource (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1395 mgmt
->sa
[0], mgmt
->sa
[1], mgmt
->sa
[2], mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
1397 tprintf("=> (%s:%.2x:%.2x:%.2x)", src
, mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
1398 tprintf("\n\tBSSID (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1399 mgmt
->bssid
[0], mgmt
->bssid
[1], mgmt
->bssid
[2], mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
1401 tprintf("=> (%s:%.2x:%.2x:%.2x)", bssid
, mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
1402 tprintf("\n\tFragmentnr. (%u), Seqnr. (%u). ", seq_ctrl
& 0xf, seq_ctrl
>> 4);
1406 *get_content
= assoc_req
;
1407 return "Association Request";
1409 *get_content
= assoc_resp
;
1410 return "Association Response";
1412 *get_content
= reassoc_req
;
1413 return "Reassociation Request";
1415 *get_content
= reassoc_resp
;
1416 return "Reassociation Response";
1418 *get_content
= probe_req
;
1419 return "Probe Request";
1421 *get_content
= probe_resp
;
1422 return "Probe Response";
1424 *get_content
= beacon
;
1427 *get_content
= atim
;
1430 *get_content
= disassoc
;
1431 return "Disassociation";
1433 *get_content
= auth
;
1434 return "Authentication";
1436 *get_content
= deauth
;
1437 return "Deauthentication";
1440 if ((subtype
>= 0b0110 && subtype
<= 0b0111) || (subtype
>= 0b1101 && subtype
<= 0b1111))
1443 return "Management SubType not supported";
1446 static char *ctrl_sub(u8 subtype
, struct pkt_buff
*pkt
, int8_t (**get_content
)(struct pkt_buff
*pkt
)) {
1450 *get_content
= ps_poll
;
1462 *get_content
= cf_end
;
1465 *get_content
= cf_end_ack
;
1466 return "CF End + CF-ACK";
1469 if (subtype
<= 0b1001)
1472 return "Control SubType not supported";
1475 static char *data_sub(u8 subtype
, struct pkt_buff
*pkt
, int8_t (**get_content
)(struct pkt_buff
*pkt
)) {
1479 *get_content
= data
;
1482 *get_content
= data_cf_ack
;
1483 return "Data + CF-ACK";
1485 *get_content
= data_cf_poll
;
1486 return "Data + CF-Poll";
1488 *get_content
= data_cf_ack_poll
;
1489 return "Data + CF-ACK + CF-Poll";
1491 *get_content
= null
;
1494 *get_content
= cf_ack
;
1497 *get_content
= cf_poll
;
1500 *get_content
= cf_ack_poll
;
1501 return "CF-ACK + CF-Poll";
1504 if (subtype
>= 0b1000 && subtype
<= 0b1111)
1507 return "Data SubType not supported";
1510 static char *frame_control_type(u8 type
, char *(**get_subtype
)(u8 subtype
, struct pkt_buff
*pkt
, int8_t (**get_content
)(struct pkt_buff
*pkt
))) {
1513 *get_subtype
= mgt_sub
;
1514 return "Management";
1516 *get_subtype
= ctrl_sub
;
1519 *get_subtype
= data_sub
;
1521 case 0b11: return "Reserved";
1524 return "Control Type not supported";
1528 static void ieee80211(struct pkt_buff
*pkt
)
1530 int8_t (*get_content
)(struct pkt_buff
*pkt
) = NULL
;
1531 char *(*get_subtype
)(u8 subtype
, struct pkt_buff
*pkt
, int8_t (**get_content
)(struct pkt_buff
*pkt
)) = NULL
;
1532 char *subtype
= NULL
;
1534 struct ieee80211_frm_ctrl
*frm_ctrl
=
1535 (struct ieee80211_frm_ctrl
*) pkt_pull(pkt
, sizeof(*frm_ctrl
));
1536 if (frm_ctrl
== NULL
)
1539 tprintf(" [ 802.11 Frame Control (0x%04x)]\n",
1540 le16_to_cpu(frm_ctrl
->frame_control
));
1541 tprintf("\t [ Proto Version (%u), ", frm_ctrl
->proto_version
);
1542 tprintf("Type (%u, %s), ", frm_ctrl
->type
, frame_control_type(frm_ctrl
->type
, &get_subtype
));
1544 subtype
= (*get_subtype
)(frm_ctrl
->subtype
, pkt
, &get_content
);
1545 tprintf("Subtype (%u, %s)", frm_ctrl
->subtype
, subtype
);
1548 tprintf("\n%s%s%s", colorize_start_full(black
, red
),
1549 "No SubType Data available", colorize_end());
1551 frm_ctrl
->to_ds
? ", Frame goes to DS" : "",
1552 frm_ctrl
->from_ds
? ", Frame comes from DS" : "");
1553 tprintf("%s", frm_ctrl
->more_frags
? ", More Fragments" : "");
1554 tprintf("%s", frm_ctrl
->retry
? ", Frame is retransmitted" : "");
1555 tprintf("%s", frm_ctrl
->power_mgmt
? ", In Power Saving Mode" : "");
1556 tprintf("%s", frm_ctrl
->more_data
? ", More Data" : "");
1557 tprintf("%s", frm_ctrl
->wep
? ", Needs WEP" : "");
1558 tprintf("%s", frm_ctrl
->order
? ", Order" : "");
1562 tprintf(" [ Subtype %s: ", subtype
);
1563 if (!((*get_content
) (pkt
)))
1564 tprintf("\n%s%s%s", colorize_start_full(black
, red
),
1565 "Failed to dissect Subtype", colorize_end());
1569 tprintf("\n%s%s%s", colorize_start_full(black
, red
),
1570 "No SubType Data available", colorize_end());
1572 // pkt_set_proto(pkt, &ieee802_lay2, ntohs(eth->h_proto));
1575 static void ieee80211_less(struct pkt_buff
*pkt
)
1577 tprintf("802.11 frame (more on todo)");
1580 struct protocol ieee80211_ops
= {
1582 .print_full
= ieee80211
,
1583 .print_less
= ieee80211_less
,
1586 EXPORT_SYMBOL(ieee80211_ops
);