예제 #1
0
    def start_dhcp(self, subnets):
        """Start a DHCP server for the specified subnets.

        This allows consumers of the access point objects to control DHCP.

        Args:
            subnets: A list of Subnets.
        """
        return self._dhcp.start(config=dhcp_config.DhcpConfig(subnets))
예제 #2
0
    def stop_ap(self, identifier):
        """Stops a running ap on this controller.

        Args:
            identifier: The identify of the ap that should be taken down.
        """

        if identifier not in self._aps:
            raise ValueError('Invalid identifer %s given' % identifier)

        instance = self._aps.get(identifier)

        instance.hostapd.stop()
        self._dhcp.stop()
        self._ip_cmd.clear_ipv4_addresses(identifier)

        # DHCP server needs to refresh in order to tear down the subnet no
        # longer being used. In the event that all interfaces are torn down
        # then an exception gets thrown. We need to catch this exception and
        # check that all interfaces should actually be down.
        configured_subnets = [x.subnet for x in self._aps.values()]
        if configured_subnets:
            self._dhcp.start(dhcp_config.DhcpConfig(configured_subnets))
예제 #3
0
    def start_ap(self, hostapd_config, additional_parameters=None):
        """Starts as an ap using a set of configurations.

        This will start an ap on this host. To start an ap the controller
        selects a network interface to use based on the configs given. It then
        will start up hostapd on that interface. Next a subnet is created for
        the network interface and dhcp server is refreshed to give out ips
        for that subnet for any device that connects through that interface.

        Args:
            hostapd_config: hostapd_config.HostapdConfig, The configurations
                            to use when starting up the ap.
            additional_parameters: A dictionary of parameters that can sent
                                   directly into the hostapd config file.  This
                                   can be used for debugging and or adding one
                                   off parameters into the config.

        Returns:
            An identifier for the ap being run. This identifier can be used
            later by this controller to control the ap.

        Raises:
            Error: When the ap can't be brought up.
        """

        if hostapd_config.frequency < 5000:
            interface = self.wlan_2g
            subnet = self._AP_2G_SUBNET
        else:
            interface = self.wlan_5g
            subnet = self._AP_5G_SUBNET

        # In order to handle dhcp servers on any interface, the initiation of
        # the dhcp server must be done after the wlan interfaces are figured
        # out as opposed to being in __init__
        self._dhcp = dhcp_server.DhcpServer(self.ssh, interface=interface)

        # For multi bssid configurations the mac address
        # of the wireless interface needs to have enough space to mask out
        # up to 8 different mac addresses.  The easiest way to do this
        # is to set the last byte to 0.  While technically this could
        # cause a duplicate mac address it is unlikely and will allow for
        # one radio to have up to 8 APs on the interface.
        interface_mac_orig = None
        cmd = "ifconfig %s|grep ether|awk -F' ' '{print $2}'" % interface
        interface_mac_orig = self.ssh.run(cmd)
        hostapd_config.bssid = interface_mac_orig.stdout[:-1] + '0'

        if interface in self._aps:
            raise ValueError('No WiFi interface available for AP on '
                             'channel %d' % hostapd_config.channel)

        apd = hostapd.Hostapd(self.ssh, interface)
        new_instance = _ApInstance(hostapd=apd, subnet=subnet)
        self._aps[interface] = new_instance

        # Turn off the DHCP server, we're going to change its settings.
        self._dhcp.stop()
        # Clear all routes to prevent old routes from interfering.
        self._route_cmd.clear_routes(net_interface=interface)

        if hostapd_config.bss_lookup:
            # The dhcp_bss dictionary is created to hold the key/value
            # pair of the interface name and the ip scope that will be
            # used for the particular interface.  The a, b, c, d
            # variables below are the octets for the ip address.  The
            # third octet is then incremented for each interface that
            # is requested.  This part is designed to bring up the
            # hostapd interfaces and not the DHCP servers for each
            # interface.
            dhcp_bss = {}
            counter = 1
            for bss in hostapd_config.bss_lookup:
                if interface_mac_orig:
                    hostapd_config.bss_lookup[
                        bss].bssid = interface_mac_orig.stdout[:-1] + str(
                            counter)
                self._route_cmd.clear_routes(net_interface=str(bss))
                if interface is self.wlan_2g:
                    starting_ip_range = self._AP_2G_SUBNET_STR
                else:
                    starting_ip_range = self._AP_5G_SUBNET_STR
                a, b, c, d = starting_ip_range.split('.')
                dhcp_bss[bss] = dhcp_config.Subnet(
                    ipaddress.ip_network('%s.%s.%s.%s' %
                                         (a, b, str(int(c) + counter), d)))
                counter = counter + 1

        apd.start(hostapd_config, additional_parameters=additional_parameters)

        # The DHCP serer requires interfaces to have ips and routes before
        # the server will come up.
        interface_ip = ipaddress.ip_interface(
            '%s/%s' % (subnet.router, subnet.network.netmask))
        self._ip_cmd.set_ipv4_address(interface, interface_ip)
        if hostapd_config.bss_lookup:
            # This loop goes through each interface that was setup for
            # hostapd and assigns the DHCP scopes that were defined but
            # not used during the hostapd loop above.  The k and v
            # variables represent the interface name, k, and dhcp info, v.
            for k, v in dhcp_bss.items():
                bss_interface_ip = ipaddress.ip_interface(
                    '%s/%s' %
                    (dhcp_bss[k].router, dhcp_bss[k].network.netmask))
                self._ip_cmd.set_ipv4_address(str(k), bss_interface_ip)

        # Restart the DHCP server with our updated list of subnets.
        configured_subnets = [x.subnet for x in self._aps.values()]
        if hostapd_config.bss_lookup:
            for k, v in dhcp_bss.items():
                configured_subnets.append(v)

        self._dhcp.start(config=dhcp_config.DhcpConfig(configured_subnets))

        # The following three commands are needed to enable bridging between
        # the WAN and LAN/WLAN ports.  This means anyone connecting to the
        # WLAN/LAN ports will be able to access the internet if the WAN port
        # is connected to the internet.
        self.ssh.run('iptables -t nat -F')
        self.ssh.run('iptables -t nat -A POSTROUTING -o %s -j MASQUERADE' %
                     self.wan)
        self.ssh.run('echo 1 > /proc/sys/net/ipv4/ip_forward')

        return interface