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_bss_load
{
293 struct element_edca_ps
{
303 struct element_tspec
{
307 #if defined(__LITTLE_ENDIAN_BITFIELD)
308 /* Correct order here ... */
309 __extension__ u32 len
:8,
320 #elif defined(__BIG_ENDIAN_BITFIELD)
321 __extension__ u32 len
:8,
333 # error "Adjust your <asm/byteorder.h> defines"
350 u16 surplus_bandw_allow
;
354 struct element_tclas
{
365 struct element_ext_supp_rates
{
370 struct element_vend_spec
{
376 static int8_t len_neq_error(u8 len
, u8 intended
)
378 if(intended
!= len
) {
379 tprintf("Length should be %u Bytes", intended
);
386 static int8_t len_gt_error(u8 len
, u8 intended
)
389 tprintf("Length should be greater %u Bytes", intended
);
396 static float data_rates(u8 id
)
398 /* XXX Why not (id / 2.f)? */
406 case 11: return 5.5f
;
407 case 12: return 6.0f
;
408 case 18: return 9.0f
;
409 case 22: return 11.0f
;
410 case 24: return 12.0f
;
411 case 27: return 13.5f
;
412 case 36: return 18.0f
;
413 case 44: return 22.0f
;
414 case 48: return 24.0f
;
415 case 54: return 27.0f
;
416 case 66: return 33.0f
;
417 case 72: return 36.0f
;
418 case 96: return 48.0f
;
419 case 108: return 54.0f
;
425 static int8_t inf_reserved(struct pkt_buff
*pkt
, u8
*id
)
429 struct element_reserved
*reserved
;
431 reserved
= (struct element_reserved
*) pkt_pull(pkt
, sizeof(*reserved
));
432 if (reserved
== NULL
)
435 tprintf("Reserved (%u, Len (%u)): ", *id
, reserved
->len
);
437 data
= pkt_pull(pkt
, reserved
->len
);
442 for (i
= 0; i
< reserved
->len
; i
++)
443 tprintf("%.2x", data
[i
]);
448 static int8_t inf_ssid(struct pkt_buff
*pkt
, u8
*id
)
451 struct element_ssid
*ssid
;
454 ssid
= (struct element_ssid
*) pkt_pull(pkt
, sizeof(*ssid
));
458 tprintf(" SSID (%u, Len (%u)): ", *id
, ssid
->len
);
460 if ((ssid
->len
- sizeof(*ssid
) + 1) > 0) {
461 ssid_name
= (char *) pkt_pull(pkt
, ssid
->len
);
462 if (ssid_name
== NULL
)
465 for (i
= 0; i
< ssid
->len
; i
++)
466 tprintf("%c",ssid_name
[i
]);
468 tprintf("Wildcard SSID");
474 static int8_t inf_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
478 struct element_supp_rates
*supp_rates
;
480 supp_rates
= (struct element_supp_rates
*)
481 pkt_pull(pkt
, sizeof(*supp_rates
));
482 if (supp_rates
== NULL
)
485 tprintf("Rates (%u, Len (%u)): ", *id
, supp_rates
->len
);
486 if (len_gt_error(supp_rates
->len
, 1))
489 if ((supp_rates
->len
- sizeof(*supp_rates
) + 1) > 0) {
490 rates
= pkt_pull(pkt
, supp_rates
->len
);
494 for (i
= 0; i
< supp_rates
->len
; i
++)
495 tprintf("%g ", (rates
[i
] & 0x80) ?
496 ((rates
[i
] & 0x3f) * 0.5) :
497 data_rates(rates
[i
]));
504 static int8_t inf_fh_ps(struct pkt_buff
*pkt
, u8
*id
)
506 struct element_fh_ps
*fh_ps
;
508 fh_ps
= (struct element_fh_ps
*) pkt_pull(pkt
, sizeof(*fh_ps
));
512 tprintf("FH Param Set (%u, Len(%u)): ", *id
, fh_ps
->len
);
513 if (len_neq_error(fh_ps
->len
, 5))
515 tprintf("Dwell Time: %fs, ", le16_to_cpu(fh_ps
->dwell_time
) * TU
);
516 tprintf("HopSet: %u, ", fh_ps
->hop_set
);
517 tprintf("HopPattern: %u, ", fh_ps
->hop_pattern
);
518 tprintf("HopIndex: %u", fh_ps
->hop_index
);
523 static int8_t inf_dsss_ps(struct pkt_buff
*pkt
, u8
*id
)
525 struct element_dsss_ps
*dsss_ps
;
527 dsss_ps
= (struct element_dsss_ps
*) pkt_pull(pkt
, sizeof(*dsss_ps
));
531 tprintf("DSSS Param Set (%u, Len(%u)): ", *id
, dsss_ps
->len
);
532 if (len_neq_error(dsss_ps
->len
, 1))
534 tprintf("Current Channel: %u", dsss_ps
->curr_ch
);
539 static int8_t inf_cf_ps(struct pkt_buff
*pkt
, u8
*id
)
541 struct element_cf_ps
*cf_ps
;
543 cf_ps
= (struct element_cf_ps
*) pkt_pull(pkt
, sizeof(*cf_ps
));
547 tprintf("CF Param Set (%u, Len(%u)): ", *id
, cf_ps
->len
);
548 if (len_neq_error(cf_ps
->len
, 6))
550 tprintf("CFP Count: %u, ", cf_ps
->cfp_cnt
);
551 tprintf("CFP Period: %u, ", cf_ps
->cfp_period
);
552 tprintf("CFP MaxDur: %fs, ", le16_to_cpu(cf_ps
->cfp_max_dur
) * TU
);
553 tprintf("CFP DurRem: %fs", le16_to_cpu(cf_ps
->cfp_dur_rem
) * TU
);
558 static int8_t inf_tim(struct pkt_buff
*pkt
, u8
*id
)
560 struct element_tim
*tim
;
562 tim
= (struct element_tim
*) pkt_pull(pkt
, sizeof(*tim
));
566 tprintf("TIM (%u, Len(%u)): ", *id
, tim
->len
);
567 if (len_gt_error(tim
->len
, 3))
569 tprintf("DTIM Count: %u, ", tim
->dtim_cnt
);
570 tprintf("DTIM Period: %u, ", tim
->dtim_period
);
571 tprintf("Bitmap Control: %u, ", tim
->bmp_cntrl
);
572 if ((tim
->len
- sizeof(*tim
) + 1) > 0) {
573 u8
*bmp
= pkt_pull(pkt
, (tim
->len
- sizeof(*tim
) + 1));
577 tprintf("Partial Virtual Bitmap: 0x");
578 for(u8 i
=0; i
< (tim
->len
- sizeof(*tim
) + 1); i
++)
579 tprintf("%.2x ", bmp
[i
]);
585 static int8_t inf_ibss_ps(struct pkt_buff
*pkt
, u8
*id
)
587 struct element_ibss_ps
*ibss_ps
;
589 ibss_ps
= (struct element_ibss_ps
*) pkt_pull(pkt
, sizeof(*ibss_ps
));
593 tprintf("IBSS Param Set (%u, Len(%u)): ", *id
, ibss_ps
->len
);
594 if (len_neq_error(ibss_ps
->len
, 2))
596 tprintf("ATIM Window: %fs", le16_to_cpu(ibss_ps
->atim_win
) * TU
);
601 static int8_t inf_country(struct pkt_buff
*pkt
, u8
*id
)
605 struct element_country
*country
;
607 country
= (struct element_country
*) pkt_pull(pkt
, sizeof(*country
));
611 tprintf("Country (%u, Len(%u)): ", *id
, country
->len
);
612 if (len_gt_error(country
->len
, 6))
614 tprintf("Country String: %c%c%c", country
->country_first
,
615 country
->country_sec
, country
->country_third
);
617 for (i
= 0; i
< (country
->len
- 3); i
+= 3) {
618 struct element_country_tripled
*country_tripled
;
620 country_tripled
= (struct element_country_tripled
*)
621 pkt_pull(pkt
, sizeof(*country_tripled
));
622 if (country_tripled
== NULL
)
625 if(country_tripled
->frst_ch
>= 201) {
626 tprintf("Oper Ext ID: %u, ", country_tripled
->frst_ch
);
627 tprintf("Operating Class: %u, ", country_tripled
->nr_ch
);
628 tprintf("Coverage Class: %u", country_tripled
->max_trans
);
630 tprintf("First Ch Nr: %u, ", country_tripled
->frst_ch
);
631 tprintf("Nr of Ch: %u, ", country_tripled
->nr_ch
);
632 tprintf("Max Transmit Pwr Lvl: %u", country_tripled
->max_trans
);
636 if(country
->len
% 2) {
637 pad
= pkt_pull(pkt
, 1);
641 tprintf(", Pad: 0x%x", *pad
);
647 static int8_t inf_hop_pp(struct pkt_buff
*pkt
, u8
*id
)
649 struct element_hop_pp
*hop_pp
;
651 hop_pp
= (struct element_hop_pp
*) pkt_pull(pkt
, sizeof(*hop_pp
));
655 tprintf("Hopping Pattern Param (%u, Len(%u)): ", *id
, hop_pp
->len
);
656 if (len_neq_error(hop_pp
->len
, 2))
658 tprintf("Nr of Ch: %u", hop_pp
->nr_ch
);
663 static int8_t inf_hop_pt(struct pkt_buff
*pkt
, u8
*id
)
667 struct element_hop_pt
*hop_pt
;
669 hop_pt
= (struct element_hop_pt
*) pkt_pull(pkt
, sizeof(*hop_pt
));
673 tprintf("Hopping Pattern Table (%u, Len(%u)): ", *id
, hop_pt
->len
);
674 if (len_gt_error(hop_pt
->len
, 4))
676 tprintf("Flag: %u, ", hop_pt
->flag
);
677 tprintf("Nr of Sets: %u, ", hop_pt
->nr_sets
);
678 tprintf("Modules: %u, ", hop_pt
->modules
);
679 tprintf("Offs: %u", hop_pt
->offs
);
681 if ((hop_pt
->len
- sizeof(*hop_pt
) + 1) > 0) {
682 rand_tabl
= pkt_pull(pkt
, (hop_pt
->len
- sizeof(*hop_pt
) + 1));
683 if (rand_tabl
== NULL
)
686 tprintf(", Rand table: 0x");
687 for (i
= 0; i
< (hop_pt
->len
- sizeof(*hop_pt
) + 1); i
++)
688 tprintf("%.2x ", rand_tabl
[i
]);
694 static int8_t inf_req(struct pkt_buff
*pkt
, u8
*id
)
697 struct element_req
*req
;
700 req
= (struct element_req
*) pkt_pull(pkt
, sizeof(*req
));
704 tprintf("Request Element (%u, Len(%u)): ", *id
, req
->len
);
705 if ((req
->len
- sizeof(*req
) + 1) > 0) {
706 req_ids
= pkt_pull(pkt
, (req
->len
- sizeof(*req
) + 1));
710 tprintf(", Requested Element IDs: ");
711 for (i
= 0; i
< (req
->len
- sizeof(*req
) + 1); i
++)
712 tprintf("%u ", req_ids
[i
]);
718 static int8_t inf_bss_load(struct pkt_buff
*pkt
, u8
*id
)
720 struct element_bss_load
*bss_load
;
722 bss_load
= (struct element_bss_load
*) pkt_pull(pkt
, sizeof(*bss_load
));
723 if (bss_load
== NULL
)
726 tprintf("BSS Load element (%u, Len(%u)): ", *id
, bss_load
->len
);
727 if (len_neq_error(bss_load
->len
, 5))
729 tprintf("Station Count: %u, ", le16_to_cpu(bss_load
->station_cnt
));
730 tprintf("Channel Utilization: %u, ", bss_load
->ch_util
);
731 tprintf("Available Admission Capacity: %uus",
732 bss_load
->avlb_adm_cap
* 32);
737 static int8_t inf_edca_ps(struct pkt_buff
*pkt
, u8
*id
)
739 u32 ac_be
, ac_bk
, ac_vi
, ac_vo
;
740 struct element_edca_ps
*edca_ps
;
742 edca_ps
= (struct element_edca_ps
*) pkt_pull(pkt
, sizeof(*edca_ps
));
746 ac_be
= le32_to_cpu(edca_ps
->ac_be
);
747 ac_bk
= le32_to_cpu(edca_ps
->ac_bk
);
748 ac_vi
= le32_to_cpu(edca_ps
->ac_vi
);
749 ac_vo
= le32_to_cpu(edca_ps
->ac_vo
);
751 tprintf("EDCA Param Set (%u, Len(%u)): ", *id
, edca_ps
->len
);
752 if (len_neq_error(edca_ps
->len
, 18))
754 tprintf("QoS Info: 0x%x (-> EDCA Param Set Update Count (%u),"
755 "Q-Ack (%u), Queue Re (%u), TXOP Req(%u), Res(%u)), ",
756 edca_ps
->qos_inf
, edca_ps
->qos_inf
>> 4,
757 (edca_ps
->qos_inf
>> 3) & 1, (edca_ps
->qos_inf
>> 2) & 1,
758 (edca_ps
->qos_inf
>> 1) & 1, edca_ps
->qos_inf
& 1);
759 tprintf("Reserved: 0x%x, ", edca_ps
->res
);
760 tprintf("AC_BE Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
761 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_be
,
762 ac_be
>> 28, (ac_be
>> 27) & 1, (ac_be
>> 25) & 3,
763 (ac_be
>> 24) & 1, (ac_be
>> 20) & 15, (ac_be
>> 16) & 15,
764 bswap_16(ac_be
& 0xFFFF) * 32);
765 tprintf("AC_BK Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
766 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_bk
,
767 ac_bk
>> 28, (ac_bk
>> 27) & 1, (ac_bk
>> 25) & 3,
768 (ac_bk
>> 24) & 1, (ac_bk
>> 20) & 15, (ac_bk
>> 16) & 15,
769 bswap_16(ac_bk
& 0xFFFF) * 32);
770 tprintf("AC_VI Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
771 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_vi
,
772 ac_vi
>> 28, (ac_vi
>> 27) & 1, (ac_vi
>> 25) & 3,
773 (ac_vi
>> 24) & 1, (ac_vi
>> 20) & 15, (ac_vi
>> 16) & 15,
774 bswap_16(ac_vi
& 0xFFFF) * 32);
775 tprintf("AC_VO Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
776 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)", ac_vo
,
777 ac_vo
>> 28, (ac_vo
>> 27) & 1, (ac_vo
>> 25) & 3,
778 (ac_vo
>> 24) & 1, (ac_vo
>> 20) & 15, (ac_vo
>> 16) & 15,
779 bswap_16(ac_vo
& 0xFFFF) * 32);
784 static int8_t inf_tspec(struct pkt_buff
*pkt
, u8
*id
)
786 u16 nom_msdu_size
, surplus_bandw_allow
;
787 struct element_tspec
*tspec
;
789 tspec
= (struct element_tspec
*) pkt_pull(pkt
, sizeof(*tspec
));
793 nom_msdu_size
= le16_to_cpu(tspec
->nom_msdu_size
);
794 surplus_bandw_allow
= le16_to_cpu(tspec
->surplus_bandw_allow
);
796 tprintf("TSPEC (%u, Len(%u)): ", *id
, tspec
->len
);
797 if (len_neq_error(tspec
->len
, 55))
799 tprintf("Traffic Type: %u, ", tspec
->traffic_type
);
800 tprintf("TSID: %u, ", tspec
->tsid
);
801 tprintf("Direction: %u, ", tspec
->direction
);
802 tprintf("Access Policy: %u, ", tspec
->access_policy
);
803 tprintf("Aggregation: %u, ", tspec
->aggr
);
804 tprintf("User Priority: %u, ", tspec
->user_prior
);
805 tprintf("TSinfo Ack Policy: %u, ", tspec
->tsinfo_ack_pol
);
806 tprintf("Schedule: %u, ", tspec
->schedule
);
807 tprintf("Reserved: 0x%x, ", tspec
->res
);
808 tprintf("Nominal MSDU Size: %uB (Fixed (%u)), ",
809 nom_msdu_size
>> 1, nom_msdu_size
& 1);
810 tprintf("Maximum MSDU Size: %uB, ", le16_to_cpu(tspec
->max_msdu_size
));
811 tprintf("Minimum Service Interval: %uus, ",
812 le32_to_cpu(tspec
->min_srv_intv
));
813 tprintf("Maximum Service Interval: %uus, ",
814 le32_to_cpu(tspec
->max_srv_intv
));
815 tprintf("Inactivity Interval: %uus, ",
816 le32_to_cpu(tspec
->inactive_intv
));
817 tprintf("Suspension Interval: %uus, ", le32_to_cpu(tspec
->susp_intv
));
818 tprintf("Service Start Time: %uus, ",
819 le32_to_cpu(tspec
->srv_start_time
));
820 tprintf("Minimum Data Rate: %ub/s, ",le32_to_cpu(tspec
->min_data_rate
));
821 tprintf("Mean Data Rate: %ub/s, ", le32_to_cpu(tspec
->mean_data_rate
));
822 tprintf("Peak Data Rate: %ub/s, ",le32_to_cpu(tspec
->peak_data_rate
));
823 tprintf("Burst Size: %uB, ", le32_to_cpu(tspec
->burst_size
));
824 tprintf("Delay Bound: %uus, ", le32_to_cpu(tspec
->delay_bound
));
825 tprintf("Minimum PHY Rate: %ub/s, ", le32_to_cpu(tspec
->min_phy_rate
));
826 tprintf("Surplus Bandwidth: %u.%u, ", surplus_bandw_allow
>> 13,
827 surplus_bandw_allow
& 0x1FFF);
828 tprintf("Medium Time: %uus, ", le16_to_cpu(tspec
->med_time
) * 32);
833 static int8_t inf_tclas(struct pkt_buff
*pkt
, u8
*id
)
835 struct element_tclas
*tclas
;
837 tclas
= (struct element_tclas
*) pkt_pull(pkt
, sizeof(*tclas
));
841 tprintf("TCLAS (%u, Len(%u)): ", *id
, tclas
->len
);
842 if (len_gt_error(tclas
->len
, 1))
844 tprintf("User Priority: %u, ", tclas
->user_priority
);
846 /*TODO add Classifier p.574*/
851 static int8_t inf_sched(struct pkt_buff
*pkt
, u8
*id
)
856 static int8_t inf_chall_txt(struct pkt_buff
*pkt
, u8
*id
)
861 static int8_t inf_pwr_constr(struct pkt_buff
*pkt
, u8
*id
)
866 static int8_t inf_pwr_cap(struct pkt_buff
*pkt
, u8
*id
)
871 static int8_t inf_tpc_req(struct pkt_buff
*pkt
, u8
*id
)
876 static int8_t inf_tpc_rep(struct pkt_buff
*pkt
, u8
*id
)
881 static int8_t inf_supp_ch(struct pkt_buff
*pkt
, u8
*id
)
886 static int8_t inf_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
)
891 static int8_t inf_meas_req(struct pkt_buff
*pkt
, u8
*id
)
896 static int8_t inf_meas_rep(struct pkt_buff
*pkt
, u8
*id
)
901 static int8_t inf_quiet(struct pkt_buff
*pkt
, u8
*id
)
906 static int8_t inf_ibss_dfs(struct pkt_buff
*pkt
, u8
*id
)
911 static int8_t inf_erp(struct pkt_buff
*pkt
, u8
*id
)
913 struct element_erp
*erp
;
915 erp
= (struct element_erp
*) pkt_pull(pkt
, sizeof(*erp
));
919 tprintf("ERP (%u, Len(%u)): ", *id
, erp
->len
);
920 if (len_neq_error(erp
->len
, 1))
922 tprintf("Non ERP Present (%u), ", erp
->param
& 0x1);
923 tprintf("Use Protection (%u), ", (erp
->param
>> 1) & 0x1);
924 tprintf("Barker Preamble Mode (%u), ", (erp
->param
>> 2) & 0x1);
925 tprintf("Reserved (0x%.5x)", erp
->param
>> 3);
930 static int8_t inf_ts_del(struct pkt_buff
*pkt
, u8
*id
)
935 static int8_t inf_tclas_proc(struct pkt_buff
*pkt
, u8
*id
)
940 static int8_t inf_ht_cap(struct pkt_buff
*pkt
, u8
*id
)
945 static int8_t inf_qos_cap(struct pkt_buff
*pkt
, u8
*id
)
950 static int8_t inf_rsn(struct pkt_buff
*pkt
, u8
*id
)
955 static int8_t inf_ext_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
959 struct element_ext_supp_rates
*ext_supp_rates
;
961 ext_supp_rates
= (struct element_ext_supp_rates
*)
962 pkt_pull(pkt
, sizeof(*ext_supp_rates
));
963 if (ext_supp_rates
== NULL
)
966 tprintf("Ext Support Rates (%u, Len(%u)): ", *id
, ext_supp_rates
->len
);
968 if ((ext_supp_rates
->len
- sizeof(*ext_supp_rates
) + 1) > 0) {
969 rates
= pkt_pull(pkt
, ext_supp_rates
->len
);
973 for (i
= 0; i
< ext_supp_rates
->len
; i
++)
974 tprintf("%g ", (rates
[i
] & 0x80) ?
975 ((rates
[i
] & 0x3f) * 0.5) :
976 data_rates(rates
[i
]));
983 static int8_t inf_ap_ch_exp(struct pkt_buff
*pkt
, u8
*id
) {
987 static int8_t inf_neighb_rep(struct pkt_buff
*pkt
, u8
*id
) {
991 static int8_t inf_rcpi(struct pkt_buff
*pkt
, u8
*id
) {
995 static int8_t inf_mde(struct pkt_buff
*pkt
, u8
*id
) {
999 static int8_t inf_fte(struct pkt_buff
*pkt
, u8
*id
) {
1003 static int8_t inf_time_out_int(struct pkt_buff
*pkt
, u8
*id
) {
1007 static int8_t inf_rde(struct pkt_buff
*pkt
, u8
*id
) {
1011 static int8_t inf_dse_reg_loc(struct pkt_buff
*pkt
, u8
*id
) {
1015 static int8_t inf_supp_op_class(struct pkt_buff
*pkt
, u8
*id
) {
1019 static int8_t inf_ext_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
) {
1023 static int8_t inf_ht_op(struct pkt_buff
*pkt
, u8
*id
) {
1027 static int8_t inf_sec_ch_offs(struct pkt_buff
*pkt
, u8
*id
) {
1031 static int8_t inf_bss_avg_acc_del(struct pkt_buff
*pkt
, u8
*id
) {
1035 static int8_t inf_ant(struct pkt_buff
*pkt
, u8
*id
) {
1039 static int8_t inf_rsni(struct pkt_buff
*pkt
, u8
*id
) {
1043 static int8_t inf_meas_pilot_trans(struct pkt_buff
*pkt
, u8
*id
) {
1047 static int8_t inf_bss_avl_adm_cap(struct pkt_buff
*pkt
, u8
*id
) {
1051 static int8_t inf_bss_ac_acc_del(struct pkt_buff
*pkt
, u8
*id
) {
1055 static int8_t inf_time_adv(struct pkt_buff
*pkt
, u8
*id
) {
1059 static int8_t inf_rm_ena_cap(struct pkt_buff
*pkt
, u8
*id
) {
1063 static int8_t inf_mult_bssid(struct pkt_buff
*pkt
, u8
*id
) {
1067 static int8_t inf_20_40_bss_coex(struct pkt_buff
*pkt
, u8
*id
) {
1071 static int8_t inf_20_40_bss_int_ch_rep(struct pkt_buff
*pkt
, u8
*id
) {
1075 static int8_t inf_overl_bss_scan_para(struct pkt_buff
*pkt
, u8
*id
) {
1079 static int8_t inf_ric_desc(struct pkt_buff
*pkt
, u8
*id
) {
1083 static int8_t inf_mgmt_mic(struct pkt_buff
*pkt
, u8
*id
) {
1087 static int8_t inf_ev_req(struct pkt_buff
*pkt
, u8
*id
) {
1091 static int8_t inf_ev_rep(struct pkt_buff
*pkt
, u8
*id
) {
1095 static int8_t inf_diagn_req(struct pkt_buff
*pkt
, u8
*id
) {
1099 static int8_t inf_diagn_rep(struct pkt_buff
*pkt
, u8
*id
) {
1103 static int8_t inf_loc_para(struct pkt_buff
*pkt
, u8
*id
) {
1107 static int8_t inf_nontr_bssid_cap(struct pkt_buff
*pkt
, u8
*id
) {
1111 static int8_t inf_ssid_list(struct pkt_buff
*pkt
, u8
*id
) {
1115 static int8_t inf_mult_bssid_index(struct pkt_buff
*pkt
, u8
*id
) {
1119 static int8_t inf_fms_desc(struct pkt_buff
*pkt
, u8
*id
) {
1123 static int8_t inf_fms_req(struct pkt_buff
*pkt
, u8
*id
) {
1127 static int8_t inf_fms_resp(struct pkt_buff
*pkt
, u8
*id
) {
1131 static int8_t inf_qos_tfc_cap(struct pkt_buff
*pkt
, u8
*id
) {
1135 static int8_t inf_bss_max_idle_per(struct pkt_buff
*pkt
, u8
*id
) {
1139 static int8_t inf_tfs_req(struct pkt_buff
*pkt
, u8
*id
) {
1143 static int8_t inf_tfs_resp(struct pkt_buff
*pkt
, u8
*id
) {
1147 static int8_t inf_wnm_sleep_mod(struct pkt_buff
*pkt
, u8
*id
) {
1151 static int8_t inf_tim_bcst_req(struct pkt_buff
*pkt
, u8
*id
) {
1155 static int8_t inf_tim_bcst_resp(struct pkt_buff
*pkt
, u8
*id
) {
1159 static int8_t inf_coll_interf_rep(struct pkt_buff
*pkt
, u8
*id
) {
1163 static int8_t inf_ch_usage(struct pkt_buff
*pkt
, u8
*id
) {
1167 static int8_t inf_time_zone(struct pkt_buff
*pkt
, u8
*id
) {
1171 static int8_t inf_dms_req(struct pkt_buff
*pkt
, u8
*id
) {
1175 static int8_t inf_dms_resp(struct pkt_buff
*pkt
, u8
*id
) {
1179 static int8_t inf_link_id(struct pkt_buff
*pkt
, u8
*id
) {
1183 static int8_t inf_wakeup_sched(struct pkt_buff
*pkt
, u8
*id
) {
1187 static int8_t inf_ch_sw_timing(struct pkt_buff
*pkt
, u8
*id
) {
1191 static int8_t inf_pti_ctrl(struct pkt_buff
*pkt
, u8
*id
) {
1195 static int8_t inf_tpu_buff_status(struct pkt_buff
*pkt
, u8
*id
) {
1199 static int8_t inf_interw(struct pkt_buff
*pkt
, u8
*id
) {
1203 static int8_t inf_adv_proto(struct pkt_buff
*pkt
, u8
*id
) {
1207 static int8_t inf_exp_bandw_req(struct pkt_buff
*pkt
, u8
*id
) {
1211 static int8_t inf_qos_map_set(struct pkt_buff
*pkt
, u8
*id
) {
1215 static int8_t inf_roam_cons(struct pkt_buff
*pkt
, u8
*id
) {
1219 static int8_t inf_emer_alert_id(struct pkt_buff
*pkt
, u8
*id
) {
1223 static int8_t inf_mesh_conf(struct pkt_buff
*pkt
, u8
*id
) {
1227 static int8_t inf_mesh_id(struct pkt_buff
*pkt
, u8
*id
) {
1231 static int8_t inf_mesh_link_metr_rep(struct pkt_buff
*pkt
, u8
*id
) {
1235 static int8_t inf_cong_notif(struct pkt_buff
*pkt
, u8
*id
) {
1239 static int8_t inf_mesh_peer_mgmt(struct pkt_buff
*pkt
, u8
*id
) {
1243 static int8_t inf_mesh_ch_sw_para(struct pkt_buff
*pkt
, u8
*id
) {
1247 static int8_t inf_mesh_awake_win(struct pkt_buff
*pkt
, u8
*id
) {
1251 static int8_t inf_beacon_timing(struct pkt_buff
*pkt
, u8
*id
) {
1255 static int8_t inf_mccaop_setup_req(struct pkt_buff
*pkt
, u8
*id
) {
1259 static int8_t inf_mccaop_setup_rep(struct pkt_buff
*pkt
, u8
*id
) {
1263 static int8_t inf_mccaop_adv(struct pkt_buff
*pkt
, u8
*id
) {
1267 static int8_t inf_mccaop_teardwn(struct pkt_buff
*pkt
, u8
*id
) {
1271 static int8_t inf_gann(struct pkt_buff
*pkt
, u8
*id
) {
1275 static int8_t inf_rann(struct pkt_buff
*pkt
, u8
*id
) {
1279 static int8_t inf_ext_cap(struct pkt_buff
*pkt
, u8
*id
) {
1283 static int8_t inf_preq(struct pkt_buff
*pkt
, u8
*id
) {
1287 static int8_t inf_prep(struct pkt_buff
*pkt
, u8
*id
) {
1291 static int8_t inf_perr(struct pkt_buff
*pkt
, u8
*id
) {
1295 static int8_t inf_pxu(struct pkt_buff
*pkt
, u8
*id
) {
1299 static int8_t inf_pxuc(struct pkt_buff
*pkt
, u8
*id
) {
1303 static int8_t inf_auth_mesh_peer_exch(struct pkt_buff
*pkt
, u8
*id
) {
1307 static int8_t inf_mic(struct pkt_buff
*pkt
, u8
*id
) {
1311 static int8_t inf_dest_uri(struct pkt_buff
*pkt
, u8
*id
) {
1315 static int8_t inf_u_apsd_coex(struct pkt_buff
*pkt
, u8
*id
) {
1319 static int8_t inf_mccaop_adv_overv(struct pkt_buff
*pkt
, u8
*id
) {
1323 static int8_t inf_vend_spec(struct pkt_buff
*pkt
, u8
*id
)
1327 struct element_vend_spec
*vend_spec
;
1329 vend_spec
= (struct element_vend_spec
*)
1330 pkt_pull(pkt
, sizeof(*vend_spec
));
1331 if (vend_spec
== NULL
)
1334 tprintf("Vendor Specific (%u, Len (%u)): ", *id
, vend_spec
->len
);
1336 data
= pkt_pull(pkt
, vend_spec
->len
);
1341 for (i
= 0; i
< vend_spec
->len
; i
++)
1342 tprintf("%.2x", data
[i
]);
1347 static int8_t inf_elements(struct pkt_buff
*pkt
)
1349 u8
*id
= pkt_pull(pkt
, 1);
1354 case 0: return inf_ssid(pkt
, id
);
1355 case 1: return inf_supp_rates(pkt
, id
);
1356 case 2: return inf_fh_ps(pkt
, id
);
1357 case 3: return inf_dsss_ps(pkt
, id
);
1358 case 4: return inf_cf_ps(pkt
, id
);
1359 case 5: return inf_tim(pkt
, id
);
1360 case 6: return inf_ibss_ps(pkt
, id
);
1361 case 7: return inf_country(pkt
, id
);
1362 case 8: return inf_hop_pp(pkt
, id
);
1363 case 9: return inf_hop_pt(pkt
, id
);
1364 case 10: return inf_req(pkt
, id
);
1365 case 11: return inf_bss_load(pkt
, id
);
1366 case 12: return inf_edca_ps(pkt
, id
);
1367 case 13: return inf_tspec(pkt
, id
);
1368 case 14: return inf_tclas(pkt
, id
);
1369 case 15: return inf_sched(pkt
, id
);
1370 case 16: return inf_chall_txt(pkt
, id
);
1371 case 17 ... 31: return inf_reserved(pkt
, id
);
1372 case 32: return inf_pwr_constr(pkt
, id
);
1373 case 33: return inf_pwr_cap(pkt
, id
);
1374 case 34: return inf_tpc_req(pkt
, id
);
1375 case 35: return inf_tpc_rep(pkt
, id
);
1376 case 36: return inf_supp_ch(pkt
, id
);
1377 case 37: return inf_ch_sw_ann(pkt
, id
);
1378 case 38: return inf_meas_req(pkt
, id
);
1379 case 39: return inf_meas_rep(pkt
, id
);
1380 case 40: return inf_quiet(pkt
, id
);
1381 case 41: return inf_ibss_dfs(pkt
, id
);
1382 case 42: return inf_erp(pkt
, id
);
1383 case 43: return inf_ts_del(pkt
, id
);
1384 case 44: return inf_tclas_proc(pkt
, id
);
1385 case 45: return inf_ht_cap(pkt
, id
);
1386 case 46: return inf_qos_cap(pkt
, id
);
1387 case 47: return inf_reserved(pkt
, id
);
1388 case 48: return inf_rsn(pkt
, id
);
1389 case 49: return inf_rsn(pkt
, id
);
1390 case 50: return inf_ext_supp_rates(pkt
, id
);
1391 case 51: return inf_ap_ch_exp(pkt
, id
);
1392 case 52: return inf_neighb_rep(pkt
, id
);
1393 case 53: return inf_rcpi(pkt
, id
);
1394 case 54: return inf_mde(pkt
, id
);
1395 case 55: return inf_fte(pkt
, id
);
1396 case 56: return inf_time_out_int(pkt
, id
);
1397 case 57: return inf_rde(pkt
, id
);
1398 case 58: return inf_dse_reg_loc(pkt
, id
);
1399 case 59: return inf_supp_op_class(pkt
, id
);
1400 case 60: return inf_ext_ch_sw_ann(pkt
, id
);
1401 case 61: return inf_ht_op(pkt
, id
);
1402 case 62: return inf_sec_ch_offs(pkt
, id
);
1403 case 63: return inf_bss_avg_acc_del(pkt
, id
);
1404 case 64: return inf_ant(pkt
, id
);
1405 case 65: return inf_rsni(pkt
, id
);
1406 case 66: return inf_meas_pilot_trans(pkt
, id
);
1407 case 67: return inf_bss_avl_adm_cap(pkt
, id
);
1408 case 68: return inf_bss_ac_acc_del(pkt
, id
);
1409 case 69: return inf_time_adv(pkt
, id
);
1410 case 70: return inf_rm_ena_cap(pkt
, id
);
1411 case 71: return inf_mult_bssid(pkt
, id
);
1412 case 72: return inf_20_40_bss_coex(pkt
, id
);
1413 case 73: return inf_20_40_bss_int_ch_rep(pkt
, id
);
1414 case 74: return inf_overl_bss_scan_para(pkt
, id
);
1415 case 75: return inf_ric_desc(pkt
, id
);
1416 case 76: return inf_mgmt_mic(pkt
, id
);
1417 case 78: return inf_ev_req(pkt
, id
);
1418 case 79: return inf_ev_rep(pkt
, id
);
1419 case 80: return inf_diagn_req(pkt
, id
);
1420 case 81: return inf_diagn_rep(pkt
, id
);
1421 case 82: return inf_loc_para(pkt
, id
);
1422 case 83: return inf_nontr_bssid_cap(pkt
, id
);
1423 case 84: return inf_ssid_list(pkt
, id
);
1424 case 85: return inf_mult_bssid_index(pkt
, id
);
1425 case 86: return inf_fms_desc(pkt
, id
);
1426 case 87: return inf_fms_req(pkt
, id
);
1427 case 88: return inf_fms_resp(pkt
, id
);
1428 case 89: return inf_qos_tfc_cap(pkt
, id
);
1429 case 90: return inf_bss_max_idle_per(pkt
, id
);
1430 case 91: return inf_tfs_req(pkt
, id
);
1431 case 92: return inf_tfs_resp(pkt
, id
);
1432 case 93: return inf_wnm_sleep_mod(pkt
, id
);
1433 case 94: return inf_tim_bcst_req(pkt
, id
);
1434 case 95: return inf_tim_bcst_resp(pkt
, id
);
1435 case 96: return inf_coll_interf_rep(pkt
, id
);
1436 case 97: return inf_ch_usage(pkt
, id
);
1437 case 98: return inf_time_zone(pkt
, id
);
1438 case 99: return inf_dms_req(pkt
, id
);
1439 case 100: return inf_dms_resp(pkt
, id
);
1440 case 101: return inf_link_id(pkt
, id
);
1441 case 102: return inf_wakeup_sched(pkt
, id
);
1442 case 104: return inf_ch_sw_timing(pkt
, id
);
1443 case 105: return inf_pti_ctrl(pkt
, id
);
1444 case 106: return inf_tpu_buff_status(pkt
, id
);
1445 case 107: return inf_interw(pkt
, id
);
1446 case 108: return inf_adv_proto(pkt
, id
);
1447 case 109: return inf_exp_bandw_req(pkt
, id
);
1448 case 110: return inf_qos_map_set(pkt
, id
);
1449 case 111: return inf_roam_cons(pkt
, id
);
1450 case 112: return inf_emer_alert_id(pkt
, id
);
1451 case 113: return inf_mesh_conf(pkt
, id
);
1452 case 114: return inf_mesh_id(pkt
, id
);
1453 case 115: return inf_mesh_link_metr_rep(pkt
, id
);
1454 case 116: return inf_cong_notif(pkt
, id
);
1455 case 117: return inf_mesh_peer_mgmt(pkt
, id
);
1456 case 118: return inf_mesh_ch_sw_para(pkt
, id
);
1457 case 119: return inf_mesh_awake_win(pkt
, id
);
1458 case 120: return inf_beacon_timing(pkt
, id
);
1459 case 121: return inf_mccaop_setup_req(pkt
, id
);
1460 case 122: return inf_mccaop_setup_rep(pkt
, id
);
1461 case 123: return inf_mccaop_adv(pkt
, id
);
1462 case 124: return inf_mccaop_teardwn(pkt
, id
);
1463 case 125: return inf_gann(pkt
, id
);
1464 case 126: return inf_rann(pkt
, id
);
1465 case 127: return inf_ext_cap(pkt
, id
);
1466 case 128: return inf_reserved(pkt
, id
);
1467 case 129: return inf_reserved(pkt
, id
);
1468 case 130: return inf_preq(pkt
, id
);
1469 case 131: return inf_prep(pkt
, id
);
1470 case 132: return inf_perr(pkt
, id
);
1471 case 133: return inf_reserved(pkt
, id
);
1472 case 134: return inf_reserved(pkt
, id
);
1473 case 135: return inf_reserved(pkt
, id
);
1474 case 136: return inf_reserved(pkt
, id
);
1475 case 137: return inf_pxu(pkt
, id
);
1476 case 138: return inf_pxuc(pkt
, id
);
1477 case 139: return inf_auth_mesh_peer_exch(pkt
, id
);
1478 case 140: return inf_mic(pkt
, id
);
1479 case 141: return inf_dest_uri(pkt
, id
);
1480 case 142: return inf_u_apsd_coex(pkt
, id
);
1481 case 143 ... 173: return inf_reserved(pkt
, id
);
1482 case 174: return inf_mccaop_adv_overv(pkt
, id
);
1483 case 221: return inf_vend_spec(pkt
, id
);
1489 #define ESS 0b0000000000000001
1490 #define IBSS 0b0000000000000010
1491 #define CF_Pollable 0b0000000000000100
1492 #define CF_Poll_Req 0b0000000000001000
1493 #define Privacy 0b0000000000010000
1494 #define Short_Pre 0b0000000000100000
1495 #define PBCC 0b0000000001000000
1496 #define Ch_Agility 0b0000000010000000
1497 #define Spec_Mgmt 0b0000000100000000
1498 #define QoS 0b0000001000000000
1499 #define Short_Slot_t 0b0000010000000000
1500 #define APSD 0b0000100000000000
1501 #define Radio_Meas 0b0001000000000000
1502 #define DSSS_OFDM 0b0010000000000000
1503 #define Del_Block_ACK 0b0100000000000000
1504 #define Imm_Block_ACK 0b1000000000000000
1506 static int8_t cap_field(u16 cap_inf
)
1512 if (CF_Pollable
& cap_inf
)
1513 tprintf(" CF Pollable;");
1514 if (CF_Poll_Req
& cap_inf
)
1515 tprintf(" CF-Poll Request;");
1516 if (Privacy
& cap_inf
)
1517 tprintf(" Privacy;");
1518 if (Short_Pre
& cap_inf
)
1519 tprintf(" Short Preamble;");
1522 if (Ch_Agility
& cap_inf
)
1523 tprintf(" Channel Agility;");
1524 if (Spec_Mgmt
& cap_inf
)
1525 tprintf(" Spectrum Management;");
1528 if (Short_Slot_t
& cap_inf
)
1529 tprintf(" Short Slot Time;");
1532 if (Radio_Meas
& cap_inf
)
1533 tprintf(" Radio Measurement;");
1534 if (DSSS_OFDM
& cap_inf
)
1535 tprintf(" DSSS-OFDM;");
1536 if (Del_Block_ACK
& cap_inf
)
1537 tprintf(" Delayed Block Ack;");
1538 if (Imm_Block_ACK
& cap_inf
)
1539 tprintf(" Immediate Block Ack;");
1544 /* Management Dissectors */
1545 static int8_t assoc_req(struct pkt_buff
*pkt
) {
1549 static int8_t assoc_resp(struct pkt_buff
*pkt
) {
1553 static int8_t reassoc_req(struct pkt_buff
*pkt
) {
1557 static int8_t reassoc_resp(struct pkt_buff
*pkt
) {
1561 static int8_t probe_req(struct pkt_buff
*pkt
) {
1565 static int8_t probe_resp(struct pkt_buff
*pkt
) {
1569 static int8_t beacon(struct pkt_buff
*pkt
)
1571 struct ieee80211_mgmt_beacon
*beacon
;
1573 beacon
= (struct ieee80211_mgmt_beacon
*)
1574 pkt_pull(pkt
, sizeof(*beacon
));
1578 tprintf("Timestamp 0x%.16lx, ", le64_to_cpu(beacon
->timestamp
));
1579 tprintf("Beacon Interval (%fs), ", le16_to_cpu(beacon
->beacon_int
)*TU
);
1580 tprintf("Capabilities (0x%x <->", le16_to_cpu(beacon
->capab_info
));
1581 cap_field(le16_to_cpu(beacon
->capab_info
));
1585 tprintf("\n\tParameters:");
1586 while (inf_elements(pkt
)) {
1596 static int8_t atim(struct pkt_buff
*pkt
) {
1600 static int8_t disassoc(struct pkt_buff
*pkt
) {
1604 static int8_t auth(struct pkt_buff
*pkt
) {
1608 static int8_t deauth(struct pkt_buff
*pkt
) {
1611 /* End Management Dissectors */
1613 /* Control Dissectors */
1614 static int8_t ps_poll(struct pkt_buff
*pkt
) {
1618 static int8_t rts(struct pkt_buff
*pkt
) {
1622 static int8_t cts(struct pkt_buff
*pkt
) {
1626 static int8_t ack(struct pkt_buff
*pkt
) {
1630 static int8_t cf_end(struct pkt_buff
*pkt
) {
1634 static int8_t cf_end_ack(struct pkt_buff
*pkt
) {
1637 /* End Control Dissectors */
1639 /* Data Dissectors */
1640 static int8_t data(struct pkt_buff
*pkt
) {
1644 static int8_t data_cf_ack(struct pkt_buff
*pkt
) {
1648 static int8_t data_cf_poll(struct pkt_buff
*pkt
) {
1652 static int8_t data_cf_ack_poll(struct pkt_buff
*pkt
) {
1656 static int8_t null(struct pkt_buff
*pkt
) {
1660 static int8_t cf_ack(struct pkt_buff
*pkt
) {
1664 static int8_t cf_poll(struct pkt_buff
*pkt
) {
1668 static int8_t cf_ack_poll(struct pkt_buff
*pkt
) {
1671 /* End Data Dissectors */
1673 static const char *mgt_sub(u8 subtype
, struct pkt_buff
*pkt
,
1674 int8_t (**get_content
)(struct pkt_buff
*pkt
))
1677 struct ieee80211_mgmt
*mgmt
;
1678 const char *dst
, *src
, *bssid
;
1680 mgmt
= (struct ieee80211_mgmt
*) pkt_pull(pkt
, sizeof(*mgmt
));
1684 dst
= lookup_vendor((mgmt
->da
[0] << 16) |
1685 (mgmt
->da
[1] << 8) |
1687 src
= lookup_vendor((mgmt
->sa
[0] << 16) |
1688 (mgmt
->sa
[1] << 8) |
1691 bssid
= lookup_vendor((mgmt
->bssid
[0] << 16) |
1692 (mgmt
->bssid
[1] << 8) |
1694 seq_ctrl
= le16_to_cpu(mgmt
->seq_ctrl
);
1696 tprintf("Duration (%u),", le16_to_cpu(mgmt
->duration
));
1697 tprintf("\n\tDestination (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1698 mgmt
->da
[0], mgmt
->da
[1], mgmt
->da
[2],
1699 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
1701 tprintf("=> (%s:%.2x:%.2x:%.2x)", dst
,
1702 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
1705 tprintf("\n\tSource (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1706 mgmt
->sa
[0], mgmt
->sa
[1], mgmt
->sa
[2],
1707 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
1709 tprintf("=> (%s:%.2x:%.2x:%.2x)", src
,
1710 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
1713 tprintf("\n\tBSSID (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1714 mgmt
->bssid
[0], mgmt
->bssid
[1], mgmt
->bssid
[2],
1715 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
1717 tprintf("=> (%s:%.2x:%.2x:%.2x)", bssid
,
1718 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
1721 tprintf("\n\tFragmentnr. (%u), Seqnr. (%u). ",
1722 seq_ctrl
& 0xf, seq_ctrl
>> 4);
1726 *get_content
= assoc_req
;
1727 return "Association Request";
1729 *get_content
= assoc_resp
;
1730 return "Association Response";
1732 *get_content
= reassoc_req
;
1733 return "Reassociation Request";
1735 *get_content
= reassoc_resp
;
1736 return "Reassociation Response";
1738 *get_content
= probe_req
;
1739 return "Probe Request";
1741 *get_content
= probe_resp
;
1742 return "Probe Response";
1744 *get_content
= beacon
;
1747 *get_content
= atim
;
1750 *get_content
= disassoc
;
1751 return "Disassociation";
1753 *get_content
= auth
;
1754 return "Authentication";
1756 *get_content
= deauth
;
1757 return "Deauthentication";
1758 case 0b0110 ... 0b0111:
1759 case 0b1101 ... 0b1111:
1760 *get_content
= NULL
;
1763 *get_content
= NULL
;
1764 return "Management SubType unknown";
1768 static const char *ctrl_sub(u8 subtype
, struct pkt_buff
*pkt
,
1769 int8_t (**get_content
)(struct pkt_buff
*pkt
))
1773 *get_content
= ps_poll
;
1785 *get_content
= cf_end
;
1788 *get_content
= cf_end_ack
;
1789 return "CF End + CF-ACK";
1790 case 0b0000 ... 0b1001:
1791 *get_content
= NULL
;
1794 return "Control SubType unkown";
1798 static const char *data_sub(u8 subtype
, struct pkt_buff
*pkt
,
1799 int8_t (**get_content
)(struct pkt_buff
*pkt
))
1803 *get_content
= data
;
1806 *get_content
= data_cf_ack
;
1807 return "Data + CF-ACK";
1809 *get_content
= data_cf_poll
;
1810 return "Data + CF-Poll";
1812 *get_content
= data_cf_ack_poll
;
1813 return "Data + CF-ACK + CF-Poll";
1815 *get_content
= null
;
1818 *get_content
= cf_ack
;
1821 *get_content
= cf_poll
;
1824 *get_content
= cf_ack_poll
;
1825 return "CF-ACK + CF-Poll";
1826 case 0b1000 ... 0b1111:
1827 *get_content
= NULL
;
1830 *get_content
= NULL
;
1831 return "Data SubType unkown";
1836 frame_control_type(u8 type
, const char *(**get_subtype
)(u8 subtype
,
1837 struct pkt_buff
*pkt
, int8_t (**get_content
)(struct pkt_buff
*pkt
)))
1841 *get_subtype
= mgt_sub
;
1842 return "Management";
1844 *get_subtype
= ctrl_sub
;
1847 *get_subtype
= data_sub
;
1850 *get_subtype
= NULL
;
1853 *get_subtype
= NULL
;
1854 return "Control Type unkown";
1858 static void ieee80211(struct pkt_buff
*pkt
)
1860 int8_t (*get_content
)(struct pkt_buff
*pkt
) = NULL
;
1861 const char *(*get_subtype
)(u8 subtype
, struct pkt_buff
*pkt
,
1862 int8_t (**get_content
)(struct pkt_buff
*pkt
)) = NULL
;
1863 const char *subtype
= NULL
;
1864 struct ieee80211_frm_ctrl
*frm_ctrl
;
1866 frm_ctrl
= (struct ieee80211_frm_ctrl
*)
1867 pkt_pull(pkt
, sizeof(*frm_ctrl
));
1868 if (frm_ctrl
== NULL
)
1871 tprintf(" [ 802.11 Frame Control (0x%04x)]\n",
1872 le16_to_cpu(frm_ctrl
->frame_control
));
1874 tprintf(" [ Proto Version (%u), ", frm_ctrl
->proto_version
);
1875 tprintf("Type (%u, %s), ", frm_ctrl
->type
,
1876 frame_control_type(frm_ctrl
->type
, &get_subtype
));
1878 subtype
= (*get_subtype
)(frm_ctrl
->subtype
, pkt
, &get_content
);
1879 tprintf("Subtype (%u, %s)", frm_ctrl
->subtype
, subtype
);
1881 tprintf("%s%s%s", colorize_start_full(black
, red
),
1882 "No SubType Data available", colorize_end());
1885 tprintf("%s%s", frm_ctrl
->to_ds
? ", Frame goes to DS" : "",
1886 frm_ctrl
->from_ds
? ", Frame comes from DS" : "");
1887 tprintf("%s", frm_ctrl
->more_frags
? ", More Fragments" : "");
1888 tprintf("%s", frm_ctrl
->retry
? ", Frame is retransmitted" : "");
1889 tprintf("%s", frm_ctrl
->power_mgmt
? ", In Power Saving Mode" : "");
1890 tprintf("%s", frm_ctrl
->more_data
? ", More Data" : "");
1891 tprintf("%s", frm_ctrl
->wep
? ", Needs WEP" : "");
1892 tprintf("%s", frm_ctrl
->order
? ", Order" : "");
1896 tprintf(" [ Subtype %s: ", subtype
);
1897 if (!((*get_content
) (pkt
)))
1898 tprintf("%s%s%s", colorize_start_full(black
, red
),
1899 "Failed to dissect Subtype", colorize_end());
1902 tprintf("%s%s%s", colorize_start_full(black
, red
),
1903 "No SubType Data available", colorize_end());
1908 // pkt_set_proto(pkt, &ieee802_lay2, ntohs(eth->h_proto));
1911 static void ieee80211_less(struct pkt_buff
*pkt
)
1913 tprintf("802.11 frame (more on todo)");
1916 struct protocol ieee80211_ops
= {
1918 .print_full
= ieee80211
,
1919 .print_less
= ieee80211_less
,
1922 EXPORT_SYMBOL(ieee80211_ops
);