Browse Source

separate supported channels into their respective bands

master
Brad Parker 11 years ago
parent
commit
30cc86a458
  1. 294
      ieee80211.h
  2. 60
      iptest/iptest.cpp
  3. 2
      libip.pro
  4. 211
      wireless.cpp
  5. 44
      wireless.h

294
ieee80211.h

@ -0,0 +1,294 @@
#define FCS_LEN 4
#define IEEE80211_FCTL_VERS 0x0003
#define IEEE80211_FCTL_FTYPE 0x000c
#define IEEE80211_FCTL_STYPE 0x00f0
#define IEEE80211_FCTL_TODS 0x0100
#define IEEE80211_FCTL_FROMDS 0x0200
#define IEEE80211_FCTL_MOREFRAGS 0x0400
#define IEEE80211_FCTL_RETRY 0x0800
#define IEEE80211_FCTL_PM 0x1000
#define IEEE80211_FCTL_MOREDATA 0x2000
#define IEEE80211_FCTL_PROTECTED 0x4000
#define IEEE80211_FCTL_ORDER 0x8000
#define IEEE80211_FCTL_CTL_EXT 0x0f00
#define IEEE80211_SCTL_FRAG 0x000F
#define IEEE80211_SCTL_SEQ 0xFFF0
#define IEEE80211_FTYPE_MGMT 0x0000
#define IEEE80211_FTYPE_CTL 0x0004
#define IEEE80211_FTYPE_DATA 0x0008
#define IEEE80211_FTYPE_EXT 0x000c
#define IEEE80211_STYPE_ASSOC_REQ 0x0000
#define IEEE80211_STYPE_ASSOC_RESP 0x0010
#define IEEE80211_STYPE_REASSOC_REQ 0x0020
#define IEEE80211_STYPE_REASSOC_RESP 0x0030
#define IEEE80211_STYPE_PROBE_REQ 0x0040
#define IEEE80211_STYPE_PROBE_RESP 0x0050
#define IEEE80211_STYPE_BEACON 0x0080
#define IEEE80211_STYPE_ATIM 0x0090
#define IEEE80211_STYPE_DISASSOC 0x00A0
#define IEEE80211_STYPE_AUTH 0x00B0
#define IEEE80211_STYPE_DEAUTH 0x00C0
#define IEEE80211_STYPE_ACTION 0x00D0
#define IEEE80211_STYPE_CTL_EXT 0x0060
#define IEEE80211_STYPE_BACK_REQ 0x0080
#define IEEE80211_STYPE_BACK 0x0090
#define IEEE80211_STYPE_PSPOLL 0x00A0
#define IEEE80211_STYPE_RTS 0x00B0
#define IEEE80211_STYPE_CTS 0x00C0
#define IEEE80211_STYPE_ACK 0x00D0
#define IEEE80211_STYPE_CFEND 0x00E0
#define IEEE80211_STYPE_CFENDACK 0x00F0
#define IEEE80211_STYPE_DATA 0x0000
#define IEEE80211_STYPE_DATA_CFACK 0x0010
#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
#define IEEE80211_STYPE_NULLFUNC 0x0040
#define IEEE80211_STYPE_CFACK 0x0050
#define IEEE80211_STYPE_CFPOLL 0x0060
#define IEEE80211_STYPE_CFACKPOLL 0x0070
#define IEEE80211_STYPE_QOS_DATA 0x0080
#define IEEE80211_STYPE_QOS_DATA_CFACK 0x0090
#define IEEE80211_STYPE_QOS_DATA_CFPOLL 0x00A0
#define IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0
#define IEEE80211_STYPE_QOS_NULLFUNC 0x00C0
#define IEEE80211_STYPE_QOS_CFACK 0x00D0
#define IEEE80211_STYPE_QOS_CFPOLL 0x00E0
#define IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0
#define IEEE80211_STYPE_DMG_BEACON 0x0000
#define IEEE80211_CTL_EXT_POLL 0x2000
#define IEEE80211_CTL_EXT_SPR 0x3000
#define IEEE80211_CTL_EXT_GRANT 0x4000
#define IEEE80211_CTL_EXT_DMG_CTS 0x5000
#define IEEE80211_CTL_EXT_DMG_DTS 0x6000
#define IEEE80211_CTL_EXT_SSW 0x8000
#define IEEE80211_CTL_EXT_SSW_FBACK 0x9000
#define IEEE80211_CTL_EXT_SSW_ACK 0xa000
#define IEEE80211_SN_MASK ((IEEE80211_SCTL_SEQ) >> 4)
#define IEEE80211_MAX_SN IEEE80211_SN_MASK
#define IEEE80211_SN_MODULO (IEEE80211_MAX_SN + 1)
#define IEEE80211_SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
#define IEEE80211_SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
#define IEEE80211_MAX_FRAG_THRESHOLD 2352
#define IEEE80211_MAX_RTS_THRESHOLD 2353
#define IEEE80211_MAX_AID 2007
#define IEEE80211_MAX_TIM_LEN 251
#define IEEE80211_MAX_DATA_LEN 2304
#define IEEE80211_MAX_FRAME_LEN 2352
#define IEEE80211_MAX_SSID_LEN 32
#define IEEE80211_MAX_MESH_ID_LEN 32
#define IEEE80211_NUM_TIDS 16
#define IEEE80211_QOS_CTL_LEN 2
#define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007
#define IEEE80211_QOS_CTL_TID_MASK 0x000f
#define IEEE80211_QOS_CTL_EOSP 0x0010
#define IEEE80211_QOS_CTL_ACK_POLICY_NORMAL 0x0000
#define IEEE80211_QOS_CTL_ACK_POLICY_NOACK 0x0020
#define IEEE80211_QOS_CTL_ACK_POLICY_NO_EXPL 0x0040
#define IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK 0x0060
#define IEEE80211_QOS_CTL_ACK_POLICY_MASK 0x0060
#define IEEE80211_QOS_CTL_A_MSDU_PRESENT 0x0080
#define IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT 0x0100
#define IEEE80211_QOS_CTL_MESH_PS_LEVEL 0x0200
#define IEEE80211_QOS_CTL_RSPI 0x0400
#define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD (1<<7)
#define IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK 0x0f
#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VO (1<<0)
#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VI (1<<1)
#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BK (1<<2)
#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BE (1<<3)
#define IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK 0x0f
#define IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL 0x00
#define IEEE80211_WMM_IE_STA_QOSINFO_SP_2 0x01
#define IEEE80211_WMM_IE_STA_QOSINFO_SP_4 0x02
#define IEEE80211_WMM_IE_STA_QOSINFO_SP_6 0x03
#define IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK 0x03
#define IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT 5
#define IEEE80211_HT_CTL_LEN 4
#define MESH_FLAGS_AE_A4 0x1
#define MESH_FLAGS_AE_A5_A6 0x2
#define MESH_FLAGS_AE 0x3
#define MESH_FLAGS_PS_DEEP 0x4
#define WLAN_SA_QUERY_TR_ID_LEN 2
#define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127
#define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u)
#define IEEE80211_P2P_NOA_DESC_MAX 4
#define IEEE80211_P2P_OPPPS_ENABLE_BIT BIT(7)
#define IEEE80211_P2P_OPPPS_CTWINDOW_MASK 0x7F
#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000
#define IEEE80211_BAR_CTRL_MULTI_TID 0x0002
#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004
#define IEEE80211_BAR_CTRL_TID_INFO_MASK 0xf000
#define IEEE80211_BAR_CTRL_TID_INFO_SHIFT 12
#define IEEE80211_HT_MCS_MASK_LEN 10
#define IEEE80211_HT_MCS_RX_HIGHEST_MASK 0x3ff
#define IEEE80211_HT_MCS_TX_DEFINED 0x01
#define IEEE80211_HT_MCS_TX_RX_DIFF 0x02
#define IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK 0x0C
#define IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT 2
#define IEEE80211_HT_MCS_TX_MAX_STREAMS 4
#define IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION 0x10
#define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START 33
#define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE \
#define IEEE80211_HT_CAP_LDPC_CODING 0x0001
#define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002
#define IEEE80211_HT_CAP_SM_PS 0x000C
#define IEEE80211_HT_CAP_SM_PS_SHIFT 2
#define IEEE80211_HT_CAP_GRN_FLD 0x0010
#define IEEE80211_HT_CAP_SGI_20 0x0020
#define IEEE80211_HT_CAP_SGI_40 0x0040
#define IEEE80211_HT_CAP_TX_STBC 0x0080
#define IEEE80211_HT_CAP_RX_STBC 0x0300
#define IEEE80211_HT_CAP_RX_STBC_SHIFT 8
#define IEEE80211_HT_CAP_DELAY_BA 0x0400
#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800
#define IEEE80211_HT_CAP_DSSSCCK40 0x1000
#define IEEE80211_HT_CAP_RESERVED 0x2000
#define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000
#define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000
#define IEEE80211_HT_EXT_CAP_PCO 0x0001
#define IEEE80211_HT_EXT_CAP_PCO_TIME 0x0006
#define IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT 1
#define IEEE80211_HT_EXT_CAP_MCS_FB 0x0300
#define IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT 8
#define IEEE80211_HT_EXT_CAP_HTC_SUP 0x0400
#define IEEE80211_HT_EXT_CAP_RD_RESPONDER 0x0800
#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03
#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C
#define IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT 2
#define IEEE80211_HT_MAX_AMPDU_FACTOR 13
#define IEEE80211_HT_PARAM_CHA_SEC_OFFSET 0x03
#define IEEE80211_HT_PARAM_CHA_SEC_NONE 0x00
#define IEEE80211_HT_PARAM_CHA_SEC_ABOVE 0x01
#define IEEE80211_HT_PARAM_CHA_SEC_BELOW 0x03
#define IEEE80211_HT_PARAM_CHAN_WIDTH_ANY 0x04
#define IEEE80211_HT_PARAM_RIFS_MODE 0x08
#define IEEE80211_HT_OP_MODE_PROTECTION 0x0003
#define IEEE80211_HT_OP_MODE_PROTECTION_NONE 0
#define IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER 1
#define IEEE80211_HT_OP_MODE_PROTECTION_20MHZ 2
#define IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED 3
#define IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT 0x0004
#define IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT 0x0010
#define IEEE80211_HT_STBC_PARAM_DUAL_BEACON 0x0040
#define IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT 0x0080
#define IEEE80211_HT_STBC_PARAM_STBC_BEACON 0x0100
#define IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT 0x0200
#define IEEE80211_HT_STBC_PARAM_PCO_ACTIVE 0x0400
#define IEEE80211_HT_STBC_PARAM_PCO_PHASE 0x0800
#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0
#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
#define IEEE80211_MIN_AMPDU_BUF 0x8
#define IEEE80211_MAX_AMPDU_BUF 0x40
#define WLAN_HT_CAP_SM_PS_STATIC 0
#define WLAN_HT_CAP_SM_PS_DYNAMIC 1
#define WLAN_HT_CAP_SM_PS_INVALID 2
#define WLAN_HT_CAP_SM_PS_DISABLED 3
#define WLAN_HT_SMPS_CONTROL_DISABLED 0
#define WLAN_HT_SMPS_CONTROL_STATIC 1
#define WLAN_HT_SMPS_CONTROL_DYNAMIC 3
#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 0x00000000
#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 0x00000001
#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 0x00000002
#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ 0x00000004
#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ 0x00000008
#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK 0x0000000C
#define IEEE80211_VHT_CAP_RXLDPC 0x00000010
#define IEEE80211_VHT_CAP_SHORT_GI_80 0x00000020
#define IEEE80211_VHT_CAP_SHORT_GI_160 0x00000040
#define IEEE80211_VHT_CAP_TXSTBC 0x00000080
#define IEEE80211_VHT_CAP_RXSTBC_1 0x00000100
#define IEEE80211_VHT_CAP_RXSTBC_2 0x00000200
#define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300
#define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400
#define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700
#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800
#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000
#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000
#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX 0x00030000
#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000
#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000
#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000
#define IEEE80211_VHT_CAP_HTC_VHT 0x00400000
#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT 23
#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK \
#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB 0x08000000
#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB 0x0c000000
#define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN 0x10000000
#define IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN 0x20000000
#define WLAN_AUTH_OPEN 0
#define WLAN_AUTH_SHARED_KEY 1
#define WLAN_AUTH_FT 2
#define WLAN_AUTH_SAE 3
#define WLAN_AUTH_LEAP 128
#define WLAN_AUTH_CHALLENGE_LEN 128
#define WLAN_CAPABILITY_ESS (1<<0)
#define WLAN_CAPABILITY_IBSS (1<<1)
#define WLAN_CAPABILITY_IS_STA_BSS(cap) (!((cap) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)))
#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
#define WLAN_CAPABILITY_PRIVACY (1<<4)
#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
#define WLAN_CAPABILITY_PBCC (1<<6)
#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
#define WLAN_CAPABILITY_QOS (1<<9)
#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10)
#define WLAN_CAPABILITY_APSD (1<<11)
#define WLAN_CAPABILITY_RADIO_MEASURE (1<<12)
#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
#define WLAN_CAPABILITY_DEL_BACK (1<<14)
#define WLAN_CAPABILITY_IMM_BACK (1<<15)
#define WLAN_CAPABILITY_DMG_TYPE_MASK (3<<0)
#define WLAN_CAPABILITY_DMG_TYPE_IBSS (1<<0) /* Tx by: STA */
#define WLAN_CAPABILITY_DMG_TYPE_PBSS (2<<0) /* Tx by: PCP */
#define WLAN_CAPABILITY_DMG_TYPE_AP (3<<0) /* Tx by: AP */
#define WLAN_CAPABILITY_DMG_CBAP_ONLY (1<<2)
#define WLAN_CAPABILITY_DMG_CBAP_SOURCE (1<<3)
#define WLAN_CAPABILITY_DMG_PRIVACY (1<<4)
#define WLAN_CAPABILITY_DMG_ECPAC (1<<5)
#define WLAN_CAPABILITY_DMG_SPECTRUM_MGMT (1<<8)
#define WLAN_CAPABILITY_DMG_RADIO_MEASURE (1<<12)
#define IEEE80211_SPCT_MSR_RPRT_MODE_LATE (1<<0)
#define IEEE80211_SPCT_MSR_RPRT_MODE_INCAPABLE (1<<1)
#define IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED (1<<2)
#define IEEE80211_SPCT_MSR_RPRT_TYPE_BASIC 0
#define IEEE80211_SPCT_MSR_RPRT_TYPE_CCA 1
#define IEEE80211_SPCT_MSR_RPRT_TYPE_RPI 2
#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
#define WLAN_ERP_USE_PROTECTION (1<<1)
#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
#define WLAN_EXT_CAPA5_TDLS_ENABLED BIT(5)
#define WLAN_EXT_CAPA5_TDLS_PROHIBITED BIT(6)
#define WLAN_EXT_CAPA8_OPMODE_NOTIF BIT(6)
#define WLAN_TDLS_SNAP_RFTYPE 0x2
#define IEEE80211_COUNTRY_IE_MIN_LEN 6
#define IEEE80211_COUNTRY_STRING_LEN 3
#define IEEE80211_COUNTRY_EXTENSION_ID 201
#define WLAN_CIPHER_SUITE_USE_GROUP 0x000FAC00
#define WLAN_CIPHER_SUITE_WEP40 0x000FAC01
#define WLAN_CIPHER_SUITE_TKIP 0x000FAC02
#define WLAN_CIPHER_SUITE_CCMP 0x000FAC04
#define WLAN_CIPHER_SUITE_WEP104 0x000FAC05
#define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06
#define WLAN_CIPHER_SUITE_GCMP 0x000FAC08
#define WLAN_CIPHER_SUITE_SMS4 0x00147201
#define WLAN_AKM_SUITE_8021X 0x000FAC01
#define WLAN_AKM_SUITE_PSK 0x000FAC02
#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
#define WLAN_AKM_SUITE_TDLS 0x000FAC07
#define WLAN_AKM_SUITE_SAE 0x000FAC08
#define WLAN_AKM_SUITE_FT_OVER_SAE 0x000FAC09
#define WLAN_MAX_KEY_LEN 32
#define WLAN_PMKID_LEN 16
#define WLAN_OUI_WFA 0x506f9a
#define WLAN_OUI_TYPE_WFA_P2P 9
#define WLAN_OUI_MICROSOFT 0x0050f2
#define WLAN_OUI_TYPE_MICROSOFT_WPA 1
#define WLAN_OUI_TYPE_MICROSOFT_WMM 2
#define WLAN_OUI_TYPE_MICROSOFT_WPS 4
#define IEEE80211_WMM_IE_TSPEC_TID_MASK 0x0F
#define IEEE80211_WMM_IE_TSPEC_TID_SHIFT 1

60
iptest/iptest.cpp

@ -44,27 +44,49 @@ int main(int argc, char *argv[]) {
Wireless wi("wlp0s11u1");
QList<ChannelInfo> channels = wi.channelMap();
foreach(ChannelInfo info, channels) {
std::cout << "found channel " << info.chan << " (" << info.freq << "): " <<
"Disabled?: " << (info.disabled ? "yes" : "no") << " " <<
"Passive?: " << (info.passive ? "yes" : "no") << " " <<
"Radar?: " << (info.radar ? "yes" : "no") << " " <<
"Max TX Power: " << info.max_txpower <<
std::endl;
QList<BandInfo> bands = wi.bandMap();
foreach(BandInfo band, bands) {
std::cout << "found band" <<
(((band.band & Wireless::BAND_2GHZ) == Wireless::BAND_2GHZ) ? " 2GHz" : "") <<
(((band.band & Wireless::BAND_5GHZ) == Wireless::BAND_5GHZ) ? " 5GHz" : "") <<
(((band.protocols & Wireless::PROTOCOL_80211_A) == Wireless::PROTOCOL_80211_A) ? " (802.11a)" : "") <<
(((band.protocols & Wireless::PROTOCOL_80211_B) == Wireless::PROTOCOL_80211_B) ? " (802.11b)" : "") <<
(((band.protocols & Wireless::PROTOCOL_80211_G) == Wireless::PROTOCOL_80211_G) ? " (802.11g)" : "") <<
(((band.protocols & Wireless::PROTOCOL_80211_N) == Wireless::PROTOCOL_80211_N) ? " (802.11n)" : "");
if((band.width & Wireless::WIDTH_20MHZ) == Wireless::WIDTH_20MHZ) {
std::cout << " (20MHz)";
}
if((band.width & Wireless::WIDTH_40MHZ) == Wireless::WIDTH_40MHZ) {
std::cout << " (40MHz)";
}
std::cout << std::endl;
if(band.channels.count() > 0) {
foreach(ChannelInfo info, band.channels) {
std::cout << " found channel " << info.chan << " (" << info.freq << "): " <<
"Disabled?: " << (info.disabled ? "yes" : "no") << " " <<
"Passive?: " << (info.passive ? "yes" : "no") << " " <<
"Radar?: " << (info.radar ? "yes" : "no") << " " <<
"Max TX Power: " << info.max_txpower << " " <<
std::endl;
}
std::cout << "converting channel 1 to freq: " << qPrintable(Wireless::ChanToFreq("Channel: 1")) << std::endl;
std::cout << "converting freq 5200 to channel: " << qPrintable(Wireless::FreqToChan("Frequency: 5.2GHz")) << std::endl;
std::cout << "is channel 11 supported? " << (wi.channelSupported(11) ? "yes" : "no") << std::endl;
std::cout << "is channel 165 supported? " << (wi.channelSupported(165) ? "yes" : "no") << std::endl;
std::cout << "is frequency 2.437GHz supported? " << (wi.frequencySupported(2437) ? "yes" : "no") << std::endl;
std::cout << "is frequency 5.825GHz supported? " << (wi.frequencySupported(5825) ? "yes" : "no") << std::endl;
std::cout << "all channels:";
}else{
std::cout << "no channels supported" << std::endl;
}
}
std::cout << "converting channel 1 to freq: " << qPrintable(Wireless::ChanToFreq("Channel: 1")) << std::endl;
std::cout << "converting freq 5200 to channel: " << qPrintable(Wireless::FreqToChan("Frequency: 5.2GHz")) << std::endl;
std::cout << "is channel 11 supported? " << (wi.channelSupported(11) ? "yes" : "no") << std::endl;
std::cout << "is channel 165 supported? " << (wi.channelSupported(165) ? "yes" : "no") << std::endl;
std::cout << "is frequency 2.437GHz supported? " << (wi.frequencySupported(2437) ? "yes" : "no") << std::endl;
std::cout << "is frequency 5.825GHz supported? " << (wi.frequencySupported(5825) ? "yes" : "no") << std::endl;
std::cout << "is 802.11a supported? " << (((wi.supportedBands() & Wireless::BAND_80211_A) == Wireless::BAND_80211_A) ? "yes" : "no") << std::endl;
std::cout << "is 802.11b supported? " << (((wi.supportedBands() & Wireless::BAND_80211_B) == Wireless::BAND_80211_B) ? "yes" : "no") << std::endl;
std::cout << "all channels:";
foreach(int chan, wi.allChannels()) {
std::cout << " " << chan;
}

2
libip.pro

@ -14,5 +14,5 @@ QMAKE_CFLAGS += -Wall -Wextra -Werror -fsanitize=address -fPIE
LIBS += -lnl-route-3 -lnl-3 -lnl-genl-3 -lasan
HEADERS += interface.h neighbor.h wireless.h utils.h
HEADERS += interface.h neighbor.h wireless.h utils.h ieee80211.h
SOURCES += interface.cpp neighbor.cpp wireless.cpp utils.cpp

211
wireless.cpp

@ -5,6 +5,7 @@ extern "C" {
#include <pthread.h>
#include <linux/nl80211.h>
#include <dirent.h>
#include "ieee80211.h"
}
#include "wireless.h"
@ -13,17 +14,7 @@ extern "C" {
#include <QStringList>
#include <QRegularExpression>
struct nl80211_channel_block {
char *phyname;
int nfreqs;
int *channel_list;
int *disabled_list;
int *passive_list;
int *radar_list;
int *txpower_list;
};
typedef struct nl80211_channel_block nl80211_channel_block_t;
#define BIT(x) (1ULL<<(x))
int IEEE80211Freq[][2] = {
{1, 2412},
@ -87,10 +78,15 @@ int IEEE80211Freq[][2] = {
{0, 0}
};
struct nl_callback {
char *phyname;
void *bands;
};
Wireless::Wireless(QString interface) :
QObject(0),
m_interface(interface),
m_channels(),
m_bands(),
m_isValid(false),
m_isNL80211(false)
{
@ -99,14 +95,13 @@ m_isNL80211(false)
struct nl_cache *cache = NULL;
struct nl_msg *msg = nlmsg_alloc();
struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
nl80211_channel_block_t cblock;
QByteArray interfaceArray = m_interface.toLatin1();
const char *interfaceStr = interfaceArray.constData();
int err = 1;
cblock.phyname = nl80211_find_parent(interfaceStr);
char *phyname = nl80211_find_parent(interfaceStr);
if(cblock.phyname == NULL) {
if(phyname == NULL) {
if(!(Utils::interfaceIndex(interfaceStr))) {
fprintf(stderr, "Interface %s doesn't exist\n", interfaceStr);
}else{
@ -123,7 +118,9 @@ m_isNL80211(false)
return;
}
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, nl80211_freqlist_cb, &cblock);
struct nl_callback callback = { .phyname = phyname, .bands = &m_bands };
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, nl80211_freqlist_cb, &callback);
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl80211_finish_cb, &err);
nl_cb_err(cb, NL_CB_CUSTOM, nl80211_error_cb, &err);
@ -141,57 +138,22 @@ m_isNL80211(false)
nl80211_disconnect(handle, cache, family);
for(int i = 0; i < cblock.nfreqs; ++i) {
ChannelInfo info;
info.chan = cblock.channel_list[i];
info.freq = ChanToFreq(cblock.channel_list[i]);
info.disabled = cblock.disabled_list[i];
info.passive = cblock.passive_list[i];
info.radar = cblock.radar_list[i];
info.max_txpower = cblock.txpower_list[i];
m_channels.append(info);
// check supported channels to see what bands we support (only makes sense for A and B)
// is there a better way to do this?
if(!((m_supportedBands & BAND_80211_A) == BAND_80211_A)) {
if(cblock.channel_list[i] >= 36) { // first US 5GHz channel
m_supportedBands = static_cast<Bands>(m_supportedBands | BAND_80211_A);
}
}
if(!((m_supportedBands & BAND_80211_B) == BAND_80211_B)) {
if(cblock.channel_list[i] >= 1) { // first 2.4GHz channel
m_supportedBands = static_cast<Bands>(m_supportedBands | BAND_80211_B);
}
}
}
free(cblock.channel_list);
free(cblock.disabled_list);
free(cblock.passive_list);
free(cblock.radar_list);
free(cblock.txpower_list);
free(cblock.phyname);
m_isValid = true;
}
Wireless::~Wireless() {
std::cerr << "del wireless" << std::endl;
m_channels.clear();
}
Wireless::Bands Wireless::supportedBands() {
return m_supportedBands;
m_bands.clear();
}
QList<int> Wireless::allChannels() const {
QList<int> channels;
foreach(ChannelInfo info, m_channels) {
channels.append(info.chan);
foreach(BandInfo info, m_bands) {
foreach(ChannelInfo chan, info.channels) {
channels.append(chan.chan);
}
}
return channels;
@ -200,12 +162,14 @@ QList<int> Wireless::allChannels() const {
QList<int> Wireless::allowedChannels(Direction dir) const {
QList<int> channels;
foreach(ChannelInfo info, m_channels) {
if(!info.disabled) {
if(((dir & Direction_Both) == Direction_Both) && (!info.passive)) {
channels.append(info.chan);
}else if(((dir & Direction_RX) == Direction_RX)) {
channels.append(info.chan);
foreach(BandInfo info, m_bands) {
foreach(ChannelInfo chan, info.channels) {
if(!chan.disabled) {
if(((dir & Direction_Both) == Direction_Both) && (!chan.passive)) {
channels.append(chan.chan);
}else if(((dir & Direction_RX) == Direction_RX)) {
channels.append(chan.chan);
}
}
}
}
@ -216,8 +180,10 @@ QList<int> Wireless::allowedChannels(Direction dir) const {
QList<int> Wireless::allFrequencies() const {
QList<int> freqs;
foreach(ChannelInfo info, m_channels) {
freqs.append(info.freq);
foreach(BandInfo band, m_bands) {
foreach(ChannelInfo info, band.channels) {
freqs.append(info.freq);
}
}
return freqs;
@ -226,12 +192,14 @@ QList<int> Wireless::allFrequencies() const {
QList<int> Wireless::allowedFrequencies(Direction dir) const {
QList<int> freqs;
foreach(ChannelInfo info, m_channels) {
if(!info.disabled) {
if(((dir & Direction_Both) == Direction_Both) && (!info.passive)) {
freqs.append(info.freq);
}else if(((dir & Direction_RX) == Direction_RX)) {
freqs.append(info.freq);
foreach(BandInfo band, m_bands) {
foreach(ChannelInfo info, band.channels) {
if(!info.disabled) {
if(((dir & Direction_Both) == Direction_Both) && (!info.passive)) {
freqs.append(info.freq);
}else if(((dir & Direction_RX) == Direction_RX)) {
freqs.append(info.freq);
}
}
}
}
@ -242,10 +210,12 @@ QList<int> Wireless::allowedFrequencies(Direction dir) const {
bool Wireless::channelSupported(int chan) const {
bool found = false;
foreach(ChannelInfo info, m_channels) {
if(info.chan == chan) {
found = true;
break;
foreach(BandInfo band, m_bands) {
foreach(ChannelInfo info, band.channels) {
if(info.chan == chan) {
found = true;
break;
}
}
}
@ -255,10 +225,12 @@ bool Wireless::channelSupported(int chan) const {
bool Wireless::frequencySupported(int freq) const {
bool found = false;
foreach(ChannelInfo info, m_channels) {
if(info.freq == freq) {
found = true;
break;
foreach(BandInfo band, m_bands) {
foreach(ChannelInfo info, band.channels) {
if(info.freq == freq) {
found = true;
break;
}
}
}
@ -396,9 +368,8 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) {
struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
struct nlattr *nl_band, *nl_freq;
int rem_band, rem_freq, num_freq = 0;
uint32_t freq;
struct nl80211_channel_block *chanb = (struct nl80211_channel_block *) arg;
int rem_band, rem_freq = 0;
struct nl_callback *callback = (struct nl_callback*)arg;
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
@ -409,7 +380,7 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) {
if (tb_msg[NL80211_ATTR_WIPHY_NAME]) {
if (strcmp(nla_get_string(tb_msg[NL80211_ATTR_WIPHY_NAME]),
chanb->phyname) != 0) {
callback->phyname) != 0) {
return NL_SKIP;
}
}
@ -423,38 +394,18 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) {
nla_parse(tb_band, NL80211_BAND_ATTR_MAX, (struct nlattr *) nla_data(nl_band),
nla_len(nl_band), NULL);
for (nl_freq = (struct nlattr *) nla_data(tb_band[NL80211_BAND_ATTR_FREQS]),
rem_freq = nla_len(tb_band[NL80211_BAND_ATTR_FREQS]);
nla_ok(nl_freq, rem_freq);
nl_freq = (struct nlattr *) nla_next(nl_freq, &rem_freq)) {
nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
(struct nlattr *) nla_data(nl_freq),
nla_len(nl_freq), NULL);
QList<BandInfo> *bands = static_cast<QList<BandInfo>*>(callback->bands);
BandInfo band;
if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
continue;
if(tb_band[NL80211_BAND_ATTR_HT_CAPA]) {
__u16 cap = nla_get_u16(tb_band[NL80211_BAND_ATTR_HT_CAPA]);
band.protocols = static_cast<Protocols>(band.protocols | PROTOCOL_80211_N);
band.width |= WIDTH_20MHZ;
num_freq++;
if((cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) { // 40-mhz 802.11n
band.width |= WIDTH_40MHZ;
}
}
}
chanb->nfreqs = num_freq;
chanb->channel_list = (int*)malloc(sizeof(int) * num_freq);
chanb->disabled_list = (int*)malloc(sizeof(int) * num_freq);
chanb->passive_list = (int*)malloc(sizeof(int) * num_freq);
chanb->radar_list = (int*)malloc(sizeof(int) * num_freq);
chanb->txpower_list = (int*)malloc(sizeof(int) * num_freq);
num_freq = 0;
// Assemble a return
for (nl_band = (struct nlattr *) nla_data(tb_msg[NL80211_ATTR_WIPHY_BANDS]),
rem_band = nla_len(tb_msg[NL80211_ATTR_WIPHY_BANDS]);
nla_ok(nl_band, rem_band);
nl_band = (struct nlattr *) nla_next(nl_band, &rem_band)) {
nla_parse(tb_band, NL80211_BAND_ATTR_MAX, (struct nlattr *) nla_data(nl_band),
nla_len(nl_band), NULL);
for (nl_freq = (struct nlattr *) nla_data(tb_band[NL80211_BAND_ATTR_FREQS]),
rem_freq = nla_len(tb_band[NL80211_BAND_ATTR_FREQS]);
@ -468,16 +419,36 @@ int Wireless::nl80211_freqlist_cb(struct nl_msg *msg, void *arg) {
if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
continue;
freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
uint32_t freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
ChannelInfo info;
info.chan = FreqToChan(freq);
info.freq = freq;
info.disabled = (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED]) ? 1 : 0;
info.passive = (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN]) ? 1 : 0;
info.radar = (tb_freq[NL80211_FREQUENCY_ATTR_RADAR]) ? 1 : 0;
info.max_txpower = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]);
// check supported channels to see what bands we support (only makes sense for A and B)
// is there a better way to do this?
if(!((band.protocols & PROTOCOL_80211_A) == PROTOCOL_80211_A)) {
if(info.chan >= 36) { // first US 5GHz channel
band.protocols = static_cast<Protocols>(band.protocols | PROTOCOL_80211_A);
band.band = static_cast<Bands>(band.band | BAND_5GHZ);
}
}
int index = num_freq++;
if(!((band.protocols & PROTOCOL_80211_B) == PROTOCOL_80211_B)) {
if(info.chan >= 1) { // first 2.4GHz channel
band.protocols = static_cast<Protocols>(band.protocols | PROTOCOL_80211_B);
band.band = static_cast<Bands>(band.band | BAND_2GHZ);
}
}
chanb->channel_list[index] = FreqToChan(freq);
chanb->disabled_list[index] = (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED]) ? 1 : 0;
chanb->passive_list[index] = (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN]) ? 1 : 0;
chanb->radar_list[index] = (tb_freq[NL80211_FREQUENCY_ATTR_RADAR]) ? 1 : 0;
chanb->txpower_list[index] = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]);
band.channels.append(info);
}
bands->append(band);
}
return NL_SKIP;
@ -519,6 +490,6 @@ char* Wireless::nl80211_find_parent(const char *interface) const {
return NULL;
}
const QList<ChannelInfo>& Wireless::channelMap() const {
return m_channels;
const QList<BandInfo>& Wireless::bandMap() const {
return m_bands;
}

44
wireless.h

@ -24,6 +24,21 @@ struct ChannelInfo {
}
};
struct BandInfo {
int band;
int width;
int protocols;
QList<ChannelInfo> channels;
BandInfo() :
band(0),
width(0),
protocols(0),
channels()
{
}
};
class LIBIP_EXPORT Wireless : public QObject {
Q_OBJECT
@ -32,19 +47,32 @@ public:
~Wireless();
enum Bands {
BAND_80211_A = (1 << 0),
BAND_80211_B = (1 << 1),
BAND_80211_G = (1 << 2),
BAND_80211_N = (1 << 3)
BAND_2GHZ = (1 << 0),
BAND_5GHZ = (1 << 1),
BAND_60GHZ = (1 << 2)
};
enum Protocols {
PROTOCOL_80211_A = (1 << 0),
PROTOCOL_80211_B = (1 << 1),
PROTOCOL_80211_G = (1 << 2),
PROTOCOL_80211_N = (1 << 3)
};
enum Direction {
Direction_RX = (1 << 0),
Direction_RX = (1 << 0),
Direction_Both = (1 << 1)
};
enum ChannelWidth {
WIDTH_20MHZ = (1 << 0),
WIDTH_40MHZ = (1 << 1),
WIDTH_80MHZ = (1 << 2),
WIDTH_160MHZ = (1 << 3)
};
const QString& name() const;
const QList<ChannelInfo>& channelMap() const;
const QList<BandInfo>& bandMap() const;
QList<int> allChannels() const;
QList<int> allowedChannels(Direction dir) const;
QList<int> allFrequencies() const;
@ -57,14 +85,12 @@ public:
bool isNL80211() const;
bool channelSupported(int chan) const;
bool frequencySupported(int freq) const;
enum Bands supportedBands();
private:
QString m_interface;
QList<ChannelInfo> m_channels;
QList<BandInfo> m_bands;
bool m_isValid;
bool m_isNL80211;
enum Bands m_supportedBands;
static int nl80211_freqlist_cb(struct nl_msg *msg, void *arg);
static int nl80211_error_cb(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);

Loading…
Cancel
Save