1from __future__ import print_function 2import netlink.capi as nl 3import netlink.genl.capi as genl 4import nl80211 5import sys 6import traceback 7 8 9class test_class: 10 def __init__(self): 11 self.done = 1 12 13 14def freq_to_ch(freq): 15 if freq == 2484: 16 return 14 17 18 if freq < 2484: 19 return (freq - 2407) / 5 20 21 # FIXME: dot11ChannelStartingFactor (802.11-2007 17.3.8.3.2) 22 if freq < 45000: 23 return freq / 5 - 1000 24 25 if freq >= 58320 and freq <= 64800: 26 return (freq - 56160) / 2160 27 28 return 0 29 30 31def handle_freq(attr, pol): 32 e, fattr = nl.py_nla_parse_nested(nl80211.NL80211_FREQUENCY_ATTR_MAX, attr, pol) 33 if nl80211.NL80211_FREQUENCY_ATTR_FREQ in fattr: 34 freq = nl.nla_get_u32(fattr[nl80211.NL80211_FREQUENCY_ATTR_FREQ]) 35 sys.stdout.write("\t\tfreq %d MHz [%d]" % (freq, freq_to_ch(freq))) 36 if nl80211.NL80211_FREQUENCY_ATTR_MAX_TX_POWER in fattr and not ( 37 nl80211.NL80211_FREQUENCY_ATTR_DISABLED in fattr 38 ): 39 sys.stdout.write( 40 " (%.1f dBm)" 41 % ( 42 0.01 43 * nl.nla_get_u32(fattr[nl80211.NL80211_FREQUENCY_ATTR_MAX_TX_POWER]) 44 ) 45 ) 46 if nl80211.NL80211_FREQUENCY_ATTR_DISABLED in fattr: 47 sys.stdout.write(" (disabled)") 48 sys.stdout.write("\n") 49 50 51def handle_band(attr, fpol): 52 e, battr = nl.py_nla_parse_nested(nl80211.NL80211_BAND_ATTR_MAX, attr, None) 53 print("\tband %d:" % nl.nla_type(attr)) 54 if nl80211.NL80211_BAND_ATTR_FREQS in battr: 55 for fattr in nl.nla_get_nested(battr[nl80211.NL80211_BAND_ATTR_FREQS]): 56 handle_freq(fattr, fpol) 57 58 59def cipher_name(suite): 60 suite_val = "%02x%02x%02x%02x" % tuple(reversed(suite)) 61 if suite_val == "000fac01": 62 return "WEP40 (00-0f-ac:1)" 63 elif suite_val == "000fac05": 64 return "WEP104 (00-0f-ac:5)" 65 elif suite_val == "000fac02": 66 return "TKIP (00-0f-ac:2)" 67 elif suite_val == "000fac04": 68 return "CCMP (00-0f-ac:4)" 69 elif suite_val == "000fac06": 70 return "CMAC (00-0f-ac:6)" 71 elif suite_val == "000fac08": 72 return "GCMP (00-0f-ac:8)" 73 elif suite_val == "00147201": 74 return "WPI-SMS4 (00-14-72:1)" 75 else: 76 return suite_val 77 78 79def msg_handler(m, a): 80 try: 81 e, attr = genl.py_genlmsg_parse( 82 nl.nlmsg_hdr(m), 0, nl80211.NL80211_ATTR_MAX, None 83 ) 84 if nl80211.NL80211_ATTR_WIPHY_NAME in attr: 85 print("wiphy %s" % nl.nla_get_string(attr[nl80211.NL80211_ATTR_WIPHY_NAME])) 86 if nl80211.NL80211_ATTR_WIPHY_BANDS in attr: 87 fpol = nl.nla_policy_array(nl80211.NL80211_FREQUENCY_ATTR_MAX + 1) 88 fpol[nl80211.NL80211_FREQUENCY_ATTR_FREQ].type = nl.NLA_U32 89 fpol[nl80211.NL80211_FREQUENCY_ATTR_DISABLED].type = nl.NLA_FLAG 90 fpol[nl80211.NL80211_FREQUENCY_ATTR_PASSIVE_SCAN].type = nl.NLA_FLAG 91 fpol[nl80211.NL80211_FREQUENCY_ATTR_NO_IBSS].type = nl.NLA_FLAG 92 fpol[nl80211.NL80211_FREQUENCY_ATTR_RADAR].type = nl.NLA_FLAG 93 fpol[nl80211.NL80211_FREQUENCY_ATTR_MAX_TX_POWER].type = nl.NLA_U32 94 95 nattrs = nl.nla_get_nested(attr[nl80211.NL80211_ATTR_WIPHY_BANDS]) 96 for nattr in nattrs: 97 handle_band(nattr, fpol) 98 if nl80211.NL80211_ATTR_CIPHER_SUITES in attr: 99 ciphers = nl.nla_data(attr[nl80211.NL80211_ATTR_CIPHER_SUITES]) 100 num = len(ciphers) / 4 101 if num > 0: 102 print("\tSupported Ciphers:") 103 for i in range(0, num, 4): 104 print("\t\t* %s" % cipher_name(ciphers[i : i + 4])) 105 if nl80211.NL80211_ATTR_SUPPORTED_IFTYPES in attr: 106 print("\tSupported interface modes:") 107 ifattr = nl.nla_get_nested(attr[nl80211.NL80211_ATTR_SUPPORTED_IFTYPES]) 108 for nl_mode in ifattr: 109 print("\t\t* %s" % nl80211.nl80211_iftype2str[nl.nla_type(nl_mode)]) 110 if nl80211.NL80211_ATTR_SOFTWARE_IFTYPES in attr: 111 print("\tsoftware interface modes (can always be added):") 112 ifattr = nl.nla_get_nested(attr[nl80211.NL80211_ATTR_SOFTWARE_IFTYPES]) 113 for nl_mode in ifattr: 114 print("\t\t* %s" % nl80211.nl80211_iftype2str[nl.nla_type(nl_mode)]) 115 return nl.NL_SKIP 116 except Exception: 117 (t, v, tb) = sys.exc_info() 118 print(v.message) 119 traceback.print_tb(tb) 120 121 122def error_handler(err, a): 123 a.done = err.error 124 return nl.NL_STOP 125 126 127def finish_handler(m, a): 128 return nl.NL_SKIP 129 130 131def ack_handler(m, a): 132 a.done = 0 133 return nl.NL_STOP 134 135 136try: 137 cbd = test_class() 138 tx_cb = nl.nl_cb_alloc(nl.NL_CB_DEFAULT) 139 rx_cb = nl.nl_cb_clone(tx_cb) 140 s = nl.nl_socket_alloc_cb(tx_cb) 141 nl.py_nl_cb_err(rx_cb, nl.NL_CB_CUSTOM, error_handler, cbd) 142 nl.py_nl_cb_set(rx_cb, nl.NL_CB_FINISH, nl.NL_CB_CUSTOM, finish_handler, cbd) 143 nl.py_nl_cb_set(rx_cb, nl.NL_CB_ACK, nl.NL_CB_CUSTOM, ack_handler, cbd) 144 nl.py_nl_cb_set(rx_cb, nl.NL_CB_VALID, nl.NL_CB_CUSTOM, msg_handler, cbd) 145 146 genl.genl_connect(s) 147 family = genl.genl_ctrl_resolve(s, "nl80211") 148 m = nl.nlmsg_alloc() 149 genl.genlmsg_put(m, 0, 0, family, 0, 0, nl80211.NL80211_CMD_GET_WIPHY, 0) 150 nl.nla_put_u32(m, nl80211.NL80211_ATTR_WIPHY, 7) 151 152 err = nl.nl_send_auto_complete(s, m) 153 if err < 0: 154 nl.nlmsg_free(m) 155 156 while cbd.done > 0 and not err < 0: 157 err = nl.nl_recvmsgs(s, rx_cb) 158except Exception: 159 (t, v, tb) = sys.exc_info() 160 print(v.message) 161 traceback.print_tb(tb) 162