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