wiphy.py 4.7 KB

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