Home | History | Annotate | Download | only in examples
      1 import netlink.capi as nl
      2 import netlink.genl.capi as genl
      3 import nl80211
      4 import sys
      5 import traceback
      6 
      7 class test_class:
      8 	def __init__(self):
      9 		self.done = 1;
     10 
     11 def 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 
     27 def 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 
     38 def 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 
     45 def 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 
     64 def 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 
    105 def error_handler(err, a):
    106 	a.done = err.error
    107 	return nl.NL_STOP
    108 
    109 def finish_handler(m, a):
    110 	return nl.NL_SKIP
    111 
    112 def ack_handler(m, a):
    113 	a.done = 0
    114 	return nl.NL_STOP
    115 
    116 try:
    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)
    138 except Exception as e:
    139 	(t, v, tb) = sys.exc_info()
    140 	print v.message
    141 	traceback.print_tb(tb)
    142