Example #1
0
    def scan(self, ifindex, ssids=None, flush_cache=False):
        '''
        Trigger scan and get results.

        Triggering scan usually requires root, and can take a
        couple of seconds.
        '''
        # Prepare a second netlink socket to get the scan results.
        # The issue is that the kernel can send the results notification
        # before we get answer for the NL80211_CMD_TRIGGER_SCAN
        nsock = NL80211()
        nsock.bind()
        nsock.add_membership('scan')

        # send scan request
        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_TRIGGER_SCAN']
        msg['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex]]

        # If a list of SSIDs is provided, active scanning should be performed
        if ssids is not None:
            if isinstance(ssids, list):
                msg['attrs'].append(['NL80211_ATTR_SCAN_SSIDS', ssids])

        scan_flags = 0
        if flush_cache:
            # Flush the cache before scanning
            scan_flags |= SCAN_FLAGS_NAMES['NL80211_SCAN_FLAG_FLUSH']
            msg['attrs'].append(['NL80211_ATTR_SCAN_FLAGS', scan_flags])

        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)

        # monitor the results notification on the secondary socket
        scanResultNotFound = True
        while scanResultNotFound:
            listMsg = nsock.get()
            for msg in listMsg:
                if msg["event"] == "NL80211_CMD_NEW_SCAN_RESULTS":
                    scanResultNotFound = False
                    break
        # close the secondary socket
        nsock.close()

        # request the results
        msg2 = nl80211cmd()
        msg2['cmd'] = NL80211_NAMES['NL80211_CMD_GET_SCAN']
        msg2['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex]]
        return self.nlm_request(msg2,
                                msg_type=self.prid,
                                msg_flags=NLM_F_REQUEST | NLM_F_DUMP)
Example #2
0
    def get_associated_bss(self, ifindex):
        '''
        Returns the same info like scan() does, but only about the
        currently associated BSS.

        Unlike scan(), it returns immediately and doesn't require root.
        '''
        # When getting scan results without triggering scan first,
        # you'll always get the information about currently associated BSS
        #
        # However, it may return other BSS, if last scan wasn't very
        # long time go

        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_GET_SCAN']
        msg['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex]]

        res = self.nlm_request(msg,
                               msg_type=self.prid,
                               msg_flags=NLM_F_REQUEST | NLM_F_DUMP)

        for x in res:
            attr_bss = x.get_attr('NL80211_ATTR_BSS')
            if attr_bss is not None:
                status = attr_bss.get_attr('NL80211_BSS_STATUS')
                if status in (
                        BSS_STATUS_NAMES['associated'],
                        BSS_STATUS_NAMES['ibss_joined'],
                ):

                    return x

        return None
Example #3
0
 def list_wiphy(self):
     '''
     Get list of all phy devices
     '''
     msg = nl80211cmd()
     msg['cmd'] = NL80211_NAMES['NL80211_CMD_GET_WIPHY']
     return self.nlm_request(msg,
                             msg_type=self.prid,
                             msg_flags=NLM_F_REQUEST | NLM_F_DUMP)
Example #4
0
 def get_interfaces_dump(self):
     '''
     Get interfaces dump
     '''
     msg = nl80211cmd()
     msg['cmd'] = NL80211_NAMES['NL80211_CMD_GET_INTERFACE']
     return self.nlm_request(msg,
                             msg_type=self.prid,
                             msg_flags=NLM_F_REQUEST | NLM_F_DUMP)
Example #5
0
 def survey(self, ifindex):
     '''
     Return the survey info.
     '''
     msg = nl80211cmd()
     msg['cmd'] = NL80211_NAMES['NL80211_CMD_GET_SURVEY']
     msg['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex]]
     return self.nlm_request(msg,
                             msg_type=self.prid,
                             msg_flags=NLM_F_REQUEST | NLM_F_DUMP)
Example #6
0
 def disconnect(self, ifindex):
     '''
     Disconnect the device
     '''
     msg = nl80211cmd()
     msg['cmd'] = NL80211_NAMES['NL80211_CMD_DISCONNECT']
     msg['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex]]
     self.nlm_request(msg,
                      msg_type=self.prid,
                      msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #7
0
 def get_interface_by_ifindex(self, ifindex):
     '''
     Get interface by ifindex ( use x.get_attr('NL80211_ATTR_IFINDEX')
     '''
     msg = nl80211cmd()
     msg['cmd'] = NL80211_NAMES['NL80211_CMD_GET_INTERFACE']
     msg['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex]]
     return self.nlm_request(msg,
                             msg_type=self.prid,
                             msg_flags=NLM_F_REQUEST)
Example #8
0
 def get_stations(self, ifindex):
     '''
     Get stations by ifindex
     '''
     msg = nl80211cmd()
     msg['cmd'] = NL80211_NAMES['NL80211_CMD_GET_STATION']
     msg['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex]]
     return self.nlm_request(msg,
                             msg_type=self.prid,
                             msg_flags=NLM_F_REQUEST | NLM_F_DUMP)
Example #9
0
 def get_interface_by_phy(self, attr):
     '''
     Get interface by phy ( use x.get_attr('NL80211_ATTR_WIPHY') )
     '''
     msg = nl80211cmd()
     msg['cmd'] = NL80211_NAMES['NL80211_CMD_GET_INTERFACE']
     msg['attrs'] = [['NL80211_ATTR_WIPHY', attr]]
     return self.nlm_request(msg,
                             msg_type=self.prid,
                             msg_flags=NLM_F_REQUEST | NLM_F_DUMP)
Example #10
0
    def leave_ibss(self, ifindex):
        '''
        Leave the IBSS -- the IBSS is determined by the network interface
        '''
        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_LEAVE_IBSS']
        msg['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex]]

        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #11
0
    def set_regulatory_domain(self, alpha2):
        '''
        Set regulatory domain.
        '''
        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_REQ_SET_REG']
        msg['attrs'] = [['NL80211_ATTR_REG_ALPHA2', alpha2]]

        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #12
0
    def set_wiphy_netns_by_pid(self, wiphy, pid):
        '''
        Set wiphy network namespace to process network namespace.
        '''
        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_SET_WIPHY_NETNS']
        msg['attrs'] = [['NL80211_ATTR_WIPHY', wiphy],
                        ['NL80211_ATTR_PID', pid]]

        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #13
0
    def del_interface(self, dev):
        '''
        Delete a virtual interface

            - dev — device index
        '''
        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_DEL_INTERFACE']
        msg['attrs'] = [['NL80211_ATTR_IFINDEX', dev]]
        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #14
0
    def set_wiphy_netns_by_fd(self, wiphy, netns_fd):
        '''
        Set wiphy network namespace to namespace referenced by fd.
        '''
        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_SET_WIPHY_NETNS']
        msg['attrs'] = [['NL80211_ATTR_WIPHY', wiphy],
                        ['NL80211_ATTR_NETNS_FD', netns_fd]]

        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #15
0
    def disassociate(self, ifindex, bssid, reason_code=0x03):
        '''
        Send a Disassociation management frame.
        '''

        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_DISASSOCIATE']
        msg['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex],
                        ['NL80211_ATTR_MAC', bssid],
                        ['NL80211_ATTR_REASON_CODE', reason_code]]

        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #16
0
    def connect(self, ifindex, ssid, bssid=None):
        '''
        Connect to the ap with ssid and bssid
        '''
        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_CONNECT']
        msg['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex],
                        ['NL80211_ATTR_SSID', ssid]]
        if bssid is not None:
            msg['attrs'].append(['NL80211_ATTR_MAC', bssid])

        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #17
0
    def get_regulatory_domain(self, attr=None):
        '''
        Get regulatory domain information. If attr specified, get regulatory
        domain information for this device
        ( use x.get_attr('NL80211_ATTR_WIPHY') ).
        '''
        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_GET_REG']
        flags = NLM_F_REQUEST
        if attr is None:
            flags |= NLM_F_DUMP
        else:
            msg['attrs'] = [['NL80211_ATTR_WIPHY', attr]]

        return self.nlm_request(msg, msg_type=self.prid, msg_flags=flags)
Example #18
0
    def deauthenticate(self, ifindex, bssid, reason_code=0x01):
        '''
        Send a Deauthentication management frame.
        '''

        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_DEAUTHENTICATE']
        msg['attrs'] = [
            ['NL80211_ATTR_IFINDEX', ifindex],
            ['NL80211_ATTR_MAC', bssid],
            ['NL80211_ATTR_REASON_CODE', reason_code],
        ]

        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #19
0
    def authenticate(self, ifindex, bssid, ssid, freq, auth_type=0):
        '''
        Send an Authentication management frame.
        '''

        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_AUTHENTICATE']
        msg['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex],
                        ['NL80211_ATTR_MAC', bssid],
                        ['NL80211_ATTR_SSID', ssid],
                        ['NL80211_ATTR_WIPHY_FREQ', freq],
                        ['NL80211_ATTR_AUTH_TYPE', auth_type]]

        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #20
0
    def add_interface(self, ifname, iftype, dev=None, phy=0):
        '''
        Create a virtual interface

            - ifname — name of the interface to create
            - iftype — interface type to create
            - dev — device index
            - phy — phy index

        One should specify `dev` (device index) or `phy`
        (phy index). If no one specified, phy == 0.

        `iftype` can be integer or string:

        1. adhoc
        2. station
        3. ap
        4. ap_vlan
        5. wds
        6. monitor
        7. mesh_point
        8. p2p_client
        9. p2p_go
        10. p2p_device
        11. ocb
        '''
        # lookup the interface type
        iftype = IFTYPE_NAMES.get(iftype, iftype)
        assert isinstance(iftype, int)

        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_NEW_INTERFACE']
        msg['attrs'] = [
            ['NL80211_ATTR_IFNAME', ifname],
            ['NL80211_ATTR_IFTYPE', iftype],
        ]
        if dev is not None:
            msg['attrs'].append(['NL80211_ATTR_IFINDEX', dev])
        elif phy is not None:
            msg['attrs'].append(['NL80211_ATTR_WIPHY', phy])
        else:
            raise TypeError('no device specified')
        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #21
0
    def associate(self, ifindex, bssid, ssid, freq, info_elements=None):
        '''
        Send an Association request frame.
        '''

        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_ASSOCIATE']
        msg['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex],
                        ['NL80211_ATTR_MAC', bssid],
                        ['NL80211_ATTR_SSID', ssid],
                        ['NL80211_ATTR_WIPHY_FREQ', freq]]

        if info_elements is not None:
            msg['attrs'].append(['NL80211_ATTR_IE', info_elements])

        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #22
0
    def set_tx_power(self, dev, mode, mbm=None):
        '''
        Set TX power of interface.

            - dev — device index
            - mode — TX power setting (0 - auto, 1 - limit, 2 - fixed)
            - mbm — TX power in mBm (dBm * 100)
        '''
        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_SET_WIPHY']
        msg['attrs'] = [
            ['NL80211_ATTR_IFINDEX', dev],
            ['NL80211_ATTR_WIPHY_TX_POWER_SETTING', mode],
        ]
        if mbm is not None:
            msg['attrs'].append(['NL80211_ATTR_WIPHY_TX_POWER_LEVEL', mbm])

        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)
Example #23
0
    def join_ibss(
        self,
        ifindex,
        ssid,
        freq,
        bssid=None,
        channel_fixed=False,
        width=None,
        center=None,
        center2=None,
    ):
        '''
        Connect to network by ssid
            - ifindex - IFINDEX of the interface to perform the connection
            - ssid - Service set identification
            - freq - Frequency in MHz
            - bssid - The MAC address of target interface
            - channel_fixed: Boolean flag
            - width - Channel width
            - center - Central frequency of the 40/80/160 MHz channel
            - center2 - Center frequency of second segment if 80P80

        If the flag of channel_fixed is True, one should specify both the width
        and center of the channel

        `width` can be integer of string:

        0. 20_noht
        1. 20
        2. 40
        3. 80
        4. 80p80
        5. 160
        6. 5
        7. 10
        '''

        msg = nl80211cmd()
        msg['cmd'] = NL80211_NAMES['NL80211_CMD_JOIN_IBSS']
        msg['attrs'] = [
            ['NL80211_ATTR_IFINDEX', ifindex],
            ['NL80211_ATTR_SSID', ssid],
            ['NL80211_ATTR_WIPHY_FREQ', freq],
        ]

        if channel_fixed:
            msg['attrs'].append(['NL80211_ATTR_FREQ_FIXED', None])
            width = CHAN_WIDTH.get(width, width)
            assert isinstance(width, int)
            if width in [2, 3, 5] and center:
                msg['attrs'].append(['NL80211_ATTR_CHANNEL_WIDTH', width])
                msg['attrs'].append(['NL80211_ATTR_CENTER_FREQ1', center])
            elif width == 4 and center and center2:
                msg['attrs'].append(['NL80211_ATTR_CHANNEL_WIDTH', width])
                msg['attrs'].append(['NL80211_ATTR_CENTER_FREQ1', center])
                msg['attrs'].append(['NL80211_ATTR_CENTER_FREQ2', center2])
            elif width in [0, 1, 6, 7]:
                msg['attrs'].append(['NL80211_ATTR_CHANNEL_WIDTH', width])
            else:
                raise TypeError('No channel specified')

        if bssid is not None:
            msg['attrs'].append(['NL80211_ATTR_MAC', bssid])

        self.nlm_request(msg,
                         msg_type=self.prid,
                         msg_flags=NLM_F_REQUEST | NLM_F_ACK)