Beispiel #1
0
    def wireless(self, interface=None):
        # Store the name of the interface in question in a class attribute for
        # use later.
        self.interface = interface

        # Set up variables to hold the ESSID and channel of the wireless
        # uplink.
        channel = 0
        essid = ''

        channel, essid, warning = _utils.check_for_configured_interface(
            self.netconfdb, interface, channel, essid)

        # The forms in the HTML template do everything here, as well.  This
        # method only accepts input for use later.
        try:
            page = self.templatelookup.get_template("/gateways/wireless.html")
            return page.render(
                title="Configure wireless uplink.",
                purpose_of_page="Set wireless uplink parameters.",
                warning=warning,
                interface=interface,
                channel=channel,
                essid=essid)
        except:
            _utils.output_error_data()
Beispiel #2
0
    def wireless(self, interface=None):
        logging.debug("Entered NetworkConfiguration.wireless().")

        # Store the name of the network interface chosen by the user in the
        # object's attribute set and then generate the name of the client
        # interface.
        self.mesh_interface = interface
        self.client_interface = interface + ':1'

        # Default settings for /network/wireless.html page.
        channel = 3
        essid = 'Byzantium'

        # This is a hidden class attribute setting, used for sanity checking
        # later in the configuration process.
        self.frequency = frequencies[channel - 1]

        channel, essid, warning = _utils.check_for_configured_interface(
            self.netconfdb, interface, channel, essid)

        # The forms in the HTML template do everything here, as well.  This
        # method only accepts input for use later.
        try:
            page = self.templatelookup.get_template("/network/wireless.html")
            return page.render(
                title="Configure wireless for Byzantium node.",
                purpose_of_page="Set wireless network parameters.",
                warning=warning,
                interface=self.mesh_interface,
                channel=channel,
                essid=essid)
        except:
            _utils.output_error_data()
Beispiel #3
0
    def tcpip(self, interface=None, essid=None, channel=None):
        logging.debug("Entered Gateways.tcpip().")

        # Define this variable in case wireless configuration information is
        # passed into this method.
        iwconfigs = ''

        # Test to see if the interface argument has been passed.  If it hasn't
        # then this method is being called from Gateways.wireless(), so
        # populate it from the class attribute variable.
        if interface is None:
            interface = self.interface

        # If an ESSID and channel were passed to this method, store them in
        # class attributes.
        if essid:
            self.essid = essid
            iwconfigs = '<p>Wireless network configuration:</p>\n'
            iwconfigs = iwconfigs + '<p>ESSID: ' + essid + '</p>\n'
        if channel:
            self.channel = channel
            iwconfigs = iwconfigs + '<p>Channel: ' + channel + '</p>\n'

        # Run the "Are you sure?" page through the template interpeter.
        try:
            page = self.templatelookup.get_template("/gateways/confirm.html")
            return page.render(title="Enable gateway?",
                               purpose_of_page="Confirm gateway mode.",
                               interface=interface,
                               iwconfigs=iwconfigs)
        except:
            _utils.output_error_data()
Beispiel #4
0
    def tcpip(self, interface=None, essid=None, channel=None):
        logging.debug("Entered Gateways.tcpip().")

        # Define this variable in case wireless configuration information is
        # passed into this method.
        iwconfigs = ''

        # Test to see if the interface argument has been passed.  If it hasn't
        # then this method is being called from Gateways.wireless(), so
        # populate it from the class attribute variable.
        if interface is None:
            interface = self.interface

        # If an ESSID and channel were passed to this method, store them in
        # class attributes.
        if essid:
            self.essid = essid
            iwconfigs = '<p>Wireless network configuration:</p>\n'
            iwconfigs = iwconfigs + '<p>ESSID: ' + essid + '</p>\n'
        if channel:
            self.channel = channel
            iwconfigs = iwconfigs + '<p>Channel: ' + channel + '</p>\n'

        # Run the "Are you sure?" page through the template interpeter.
        try:
            page = self.templatelookup.get_template("/gateways/confirm.html")
            return page.render(title = "Enable gateway?",
                               purpose_of_page = "Confirm gateway mode.",
                               interface = interface, iwconfigs = iwconfigs)
        except:
            _utils.output_error_data()
    def wireless(self, interface=None):
        logging.debug("Entered NetworkConfiguration.wireless().")

        # Store the name of the network interface chosen by the user in the
        # object's attribute set and then generate the name of the client
        # interface.
        self.mesh_interface = interface
        self.client_interface = interface + ':1'

        # Default settings for /network/wireless.html page.
        channel = 3
        essid = 'Byzantium'

        # This is a hidden class attribute setting, used for sanity checking
        # later in the configuration process.
        self.frequency = frequencies[channel - 1]

        channel, essid, warning = _utils.check_for_configured_interface(self.netconfdb, interface, channel, essid)

        # The forms in the HTML template do everything here, as well.  This
        # method only accepts input for use later.
        try:
            page = self.templatelookup.get_template("/network/wireless.html")
            return page.render(title = "Configure wireless for Byzantium node.",
                           purpose_of_page = "Set wireless network parameters.",
                           warning = warning, interface = self.mesh_interface,
                           channel = channel, essid = essid)
        except:
            _utils.output_error_data()
Beispiel #6
0
    def enable(self):
        # Set up the error and successful output messages.
        error = ''
        output = ''

        # Set up a default set of command line options for babeld.  Some of
        # these are redundant but are present in case an older version of
        # babeld is used on the node.  See the following file to see why:
        # http://www.pps.jussieu.fr/~jch/software/babel/CHANGES.text
        common_babeld_opts = [
            '-m', 'ff02:0:0:0:0:0:1:6', '-p', '6696', '-D', '-g', '33123',
            '-c', '/etc/babeld.conf'
        ]

        # Create a set of unique command line options for babeld.  Right now,
        # this variable is empty but it might be used in the future.  Maybe
        # it'll be populated from a config file or something.
        unique_babeld_opts = []

        # Set up a list of mesh interfaces for which babeld is already running.
        interfaces = []
        query = "SELECT interface, enabled, protocol FROM meshes WHERE enabled='yes' AND protocol='babel';"
        connection, cursor = _utils.execute_query(self.meshconfdb, query)
        results = cursor.fetchall()
        for i in results:
            logging.debug("Adding interface: %s", i[0])
            interfaces.append(i[0])

        # By definition, if we're in this method the new interface hasn't been
        # added yet.
        interfaces.append(self.interface)

        self.update_babeld(common_babeld_opts, unique_babeld_opts, interfaces)

        # Get the PID of babeld, then test to see if that pid exists and
        # corresponds to a running babeld process.  If there is no match,
        # babeld isn't running.
        pid = self.pid_check()
        if pid:
            error, output = self._pid_helper(pid,
                                             error,
                                             output,
                                             cursor,
                                             connection,
                                             commit=True)
        cursor.close()

        # Render the HTML page.
        try:
            page = self.templatelookup.get_template("/mesh/enabled.html")
            return page.render(title="Byzantium Node Mesh Configuration",
                               purpose_of_page="Mesh Interface Enabled",
                               protocol=self.protocol,
                               interface=self.interface,
                               error=error,
                               output=output)
        except:
            _utils.output_error_data()
Beispiel #7
0
    def activate(self, interface=None):
        logging.debug("Entered Gateways.activate().")

        # Test to see if wireless configuration attributes are set, and if they
        # are, use iwconfig to set up the interface.
        if self.essid:
            command = ['/sbin/iwconfig', interface, 'essid', self.essid]
            logging.debug("Setting ESSID to %s.", self.essid)
            if self.test:
                logging.debug("Command to set ESSID:\n%s", ' '.join(command))
            else:
                subprocess.Popen(command)
        if self.channel:
            command = ['/sbin/iwconfig', interface, 'channel', self.channel]
            logging.debug("Setting channel %s.", self.channel)
            if self.test:
                logging.debug("Command to set channel:\n%s", ' '.join(command))
            else:
                subprocess.Popen(command)

        # If we have to configure layers 1 and 2, then it's a safe bet that we
        # should use DHCP to set up layer 3.  This is wrapped in a shell script
        # because of a timing conflict between the time dhcpcd starts, the
        # time dhcpcd gets IP configuration information (or not) and when
        # avahi-daemon is bounced.
        command = ['/usr/local/sbin/gateway.sh', interface]
        logging.debug("Preparing to configure interface %s.", interface)
        if self.test:
            logging.debug("Pretending to run gateway.sh on interface %s.",
                          interface)
            logging.debug("Command that would be run:\n%s", ' '.join(command))
        else:
            subprocess.Popen(command)

        # See what value was returned by the script.

        # Set up a list of mesh interfaces for which babeld is already running.
        #
        # NOTE: the interfaces variable doesn't seem to ever get used anywhere :/
        #
        interfaces = self._get_mesh_interfaces(interface)

        # Update the network configuration database to reflect the fact that
        # the interface is now a gateway.  Search the table of Ethernet
        # interfaces first.
        self._update_netconfdb(interface)

        # Display the confirmation of the operation to the user.
        try:
            page = self.templatelookup.get_template("/gateways/done.html")
            return page.render(title="Enable gateway?",
                               purpose_of_page="Confirm gateway mode.",
                               interface=interface)
        except:
            _utils.output_error_data()
Beispiel #8
0
    def activate(self, interface=None):
        logging.debug("Entered Gateways.activate().")

        # Test to see if wireless configuration attributes are set, and if they
        # are, use iwconfig to set up the interface.
        if self.essid:
            command = ['/sbin/iwconfig', interface, 'essid', self.essid]
            logging.debug("Setting ESSID to %s.", self.essid)
            if self.test:
                logging.debug("Command to set ESSID:\n%s", ' '.join(command))
            else:
                subprocess.Popen(command)
        if self.channel:
            command = ['/sbin/iwconfig', interface, 'channel', self.channel]
            logging.debug("Setting channel %s.", self.channel)
            if self.test:
                logging.debug("Command to set channel:\n%s", ' '.join(command))
            else:
                subprocess.Popen(command)

        # If we have to configure layers 1 and 2, then it's a safe bet that we
        # should use DHCP to set up layer 3.  This is wrapped in a shell script
        # because of a timing conflict between the time dhcpcd starts, the
        # time dhcpcd gets IP configuration information (or not) and when
        # avahi-daemon is bounced.
        command = ['/usr/local/sbin/gateway.sh', interface]
        logging.debug("Preparing to configure interface %s.", interface)
        if self.test:
            logging.debug("Pretending to run gateway.sh on interface %s.", interface)
            logging.debug("Command that would be run:\n%s", ' '.join(command))
        else:
            subprocess.Popen(command)

        # See what value was returned by the script.

        # Set up a list of mesh interfaces for which babeld is already running.
        #
        # NOTE: the interfaces variable doesn't seem to ever get used anywhere :/
        #
        interfaces = self._get_mesh_interfaces(interface)

        # Update the network configuration database to reflect the fact that
        # the interface is now a gateway.  Search the table of Ethernet
        # interfaces first.
        self._update_netconfdb(interface)

        # Display the confirmation of the operation to the user.
        try:
            page = self.templatelookup.get_template("/gateways/done.html")
            return page.render(title = "Enable gateway?",
                               purpose_of_page = "Confirm gateway mode.",
                               interface = interface)
        except:
            _utils.output_error_data()
Beispiel #9
0
    def enable(self):
        # Set up the error and successful output messages.
        error = ""
        output = ""

        # Set up a default set of command line options for babeld.  Some of
        # these are redundant but are present in case an older version of
        # babeld is used on the node.  See the following file to see why:
        # http://www.pps.jussieu.fr/~jch/software/babel/CHANGES.text
        common_babeld_opts = ["-m", "ff02:0:0:0:0:0:1:6", "-p", "6696", "-D", "-g", "33123", "-c", "/etc/babeld.conf"]

        # Create a set of unique command line options for babeld.  Right now,
        # this variable is empty but it might be used in the future.  Maybe
        # it'll be populated from a config file or something.
        unique_babeld_opts = []

        # Set up a list of mesh interfaces for which babeld is already running.
        interfaces = []
        query = "SELECT interface, enabled, protocol FROM meshes WHERE enabled='yes' AND protocol='babel';"
        connection, cursor = _utils.execute_query(self.meshconfdb, query)
        results = cursor.fetchall()
        for i in results:
            logging.debug("Adding interface: %s", i[0])
            interfaces.append(i[0])

        # By definition, if we're in this method the new interface hasn't been
        # added yet.
        interfaces.append(self.interface)

        self.update_babeld(common_babeld_opts, unique_babeld_opts, interfaces)

        # Get the PID of babeld, then test to see if that pid exists and
        # corresponds to a running babeld process.  If there is no match,
        # babeld isn't running.
        pid = self.pid_check()
        if pid:
            error, output = self._pid_helper(pid, error, output, cursor, connection, commit=True)
        cursor.close()

        # Render the HTML page.
        try:
            page = self.templatelookup.get_template("/mesh/enabled.html")
            return page.render(
                title="Byzantium Node Mesh Configuration",
                purpose_of_page="Mesh Interface Enabled",
                protocol=self.protocol,
                interface=self.interface,
                error=error,
                output=output,
            )
        except:
            _utils.output_error_data()
Beispiel #10
0
    def removefrommesh(self, interface=None):
        logging.debug("Entered MeshConfiguration.removefrommesh().")

        # Configure this instance of the object for the interface the user
        # wants to remove from the mesh.
        self.interface = interface
        self.protocol = "babel"
        self.enabled = "yes"

        # Render the HTML page.
        try:
            page = self.templatelookup.get_template("/mesh/removefrommesh.html")
            return page.render(
                title="Byzantium Node Mesh Configuration", purpose_of_page="Disable Mesh Interface", interface=interface
            )
        except:
            _utils.output_error_data()
Beispiel #11
0
    def removefrommesh(self, interface=None):
        logging.debug("Entered MeshConfiguration.removefrommesh().")

        # Configure this instance of the object for the interface the user
        # wants to remove from the mesh.
        self.interface = interface
        self.protocol = 'babel'
        self.enabled = 'yes'

        # Render the HTML page.
        try:
            page = self.templatelookup.get_template(
                "/mesh/removefrommesh.html")
            return page.render(title="Byzantium Node Mesh Configuration",
                               purpose_of_page="Disable Mesh Interface",
                               interface=interface)
        except:
            _utils.output_error_data()
Beispiel #12
0
    def addtomesh(self, interface=None):
        # Store the name of the network interface and whether or not it's
        # enabled in the object's attributes.  Right now only the Babel
        # protocol is supported, so that's hardcoded for the moment (but it
        # could change in later releases).
        self.interface = interface
        self.protocol = 'babel'
        self.enabled = 'no'

        # Render the HTML page.
        try:
            page = self.templatelookup.get_template("/mesh/addtomesh.html")
            return page.render(title="Byzantium Node Mesh Configuration",
                               purpose_of_page="Enable Mesh Interfaces",
                               interface=self.interface,
                               protocol=self.protocol)
        except:
            _utils.output_error_data()
Beispiel #13
0
    def addtomesh(self, interface=None):
        # Store the name of the network interface and whether or not it's
        # enabled in the object's attributes.  Right now only the Babel
        # protocol is supported, so that's hardcoded for the moment (but it
        # could change in later releases).
        self.interface = interface
        self.protocol = "babel"
        self.enabled = "no"

        # Render the HTML page.
        try:
            page = self.templatelookup.get_template("/mesh/addtomesh.html")
            return page.render(
                title="Byzantium Node Mesh Configuration",
                purpose_of_page="Enable Mesh Interfaces",
                interface=self.interface,
                protocol=self.protocol,
            )
        except:
            _utils.output_error_data()
Beispiel #14
0
    def index(self):
        ethernet_buttons = ""
        wireless_buttons = ""

        # To find any new network interfaces, rescan the network interfaces on
        # the node.
        self.update_network_interfaces()

        query = "SELECT interface FROM wired WHERE gateway='no';"
        _, cursor = _utils.execute_query(self.netconfdb, query)
        results = cursor.fetchall()
        if results:
            for interface in results:
                ethernet_buttons = ethernet_buttons + "<td><input type='submit' name='interface' value='" + interface[
                    0] + "' /></td>\n"

        # Generate a list of wireless interfaces on the node that are not
        # enabled but are known.  As before, each button gets is own button
        # in a table.
        cursor.execute(
            "SELECT mesh_interface FROM wireless WHERE gateway='no';")
        results = cursor.fetchall()
        if results:
            for interface in results:
                wireless_buttons = wireless_buttons + "<td><input type='submit' name='interface' value='" + interface[
                    0] + "' /></td>\n"

        # Close the connection to the database.
        cursor.close()

        # Render the HTML page.
        try:
            page = self.templatelookup.get_template("/gateways/index.html")
            return page.render(title="Network Gateway",
                               purpose_of_page="Configure Network Gateway",
                               ethernet_buttons=ethernet_buttons,
                               wireless_buttons=wireless_buttons)
        except:
            _utils.output_error_data()
Beispiel #15
0
    def wireless(self, interface=None):
        # Store the name of the interface in question in a class attribute for
        # use later.
        self.interface = interface

        # Set up variables to hold the ESSID and channel of the wireless
        # uplink.
        channel = 0
        essid = ''

        channel, essid, warning = _utils.check_for_configured_interface(self.netconfdb, interface, channel, essid)

        # The forms in the HTML template do everything here, as well.  This
        # method only accepts input for use later.
        try:
            page = self.templatelookup.get_template("/gateways/wireless.html")
            return page.render(title = "Configure wireless uplink.",
                           purpose_of_page = "Set wireless uplink parameters.",
                           warning = warning, interface = interface,
                           channel = channel, essid = essid)
        except:
            _utils.output_error_data()
Beispiel #16
0
    def index(self):
        ethernet_buttons = ""
        wireless_buttons = ""

        # To find any new network interfaces, rescan the network interfaces on
        # the node.
        self.update_network_interfaces()

        query = "SELECT interface FROM wired WHERE gateway='no';"
        _, cursor = _utils.execute_query(self.netconfdb, query)
        results = cursor.fetchall()
        if results:
            for interface in results:
                ethernet_buttons = ethernet_buttons + "<td><input type='submit' name='interface' value='" + interface[0] + "' /></td>\n"

        # Generate a list of wireless interfaces on the node that are not
        # enabled but are known.  As before, each button gets is own button
        # in a table.
        cursor.execute("SELECT mesh_interface FROM wireless WHERE gateway='no';")
        results = cursor.fetchall()
        if results:
            for interface in results:
                wireless_buttons = wireless_buttons + "<td><input type='submit' name='interface' value='" + interface[0] + "' /></td>\n"

        # Close the connection to the database.
        cursor.close()

        # Render the HTML page.
        try:
            page = self.templatelookup.get_template("/gateways/index.html")
            return page.render(title = "Network Gateway",
                               purpose_of_page = "Configure Network Gateway",
                               ethernet_buttons = ethernet_buttons,
                               wireless_buttons = wireless_buttons)
        except:
            _utils.output_error_data()
Beispiel #17
0
    def set_ip(self):
        # If we've made it this far, the user's decided to (re)configure a
        # network interface.  Full steam ahead, damn the torpedoes!

        # First, take the wireless NIC offline so its mode can be changed.
        command = ['/sbin/ifconfig', self.mesh_interface, 'down']
        output = subprocess.Popen(command)
        time.sleep(5)

        # Wrap this whole process in a loop to ensure that stubborn wireless
        # interfaces are configured reliably.  The wireless NIC has to make it
        # all the way through one iteration of the loop without errors before
        # we can go on.
        while True:
            # Set the mode, ESSID and channel.
            command = ['/sbin/iwconfig', self.mesh_interface, 'mode ad-hoc']
            output = subprocess.Popen(command)
            command = [
                '/sbin/iwconfig', self.mesh_interface, 'essid', self.essid
            ]
            output = subprocess.Popen(command)
            command = [
                '/sbin/iwconfig', self.mesh_interface, 'channel', self.channel
            ]
            output = subprocess.Popen(command)

            # Run iwconfig again and capture the current wireless configuration.
            command = ['/sbin/iwconfig', self.mesh_interface]
            output = subprocess.Popen(command).stdout
            configuration = output.readlines()

            # Test the interface by going through the captured text to see if
            # it's in ad-hoc mode.  If it's not, put it in ad-hoc mode and go
            # back to the top of the loop to try again.
            for line in configuration:
                if 'Mode' in line:
                    line = line.strip()
                    mode = line.split(' ')[0].split(':')[1]
                    if mode != 'Ad-Hoc':
                        continue

            # Test the ESSID to see if it's been set properly.
            for line in configuration:
                if 'ESSID' in line:
                    line = line.strip()
                    essid = line.split(' ')[-1].split(':')[1]
                    if essid != self.essid:
                        continue

            # Check the wireless channel to see if it's been set properly.
            for line in configuration:
                if 'Frequency' in line:
                    line = line.strip()
                    frequency = line.split(' ')[2].split(':')[1]
                    if frequency != self.frequency:
                        continue

            # "Victory is mine!"
            # --Stewie, _Family Guy_
            break

        # Call ifconfig and set up the network configuration information.
        command = [
            '/sbin/ifconfig', self.mesh_interface, self.mesh_ip, 'netmask',
            self.mesh_netmask, 'up'
        ]
        output = subprocess.Popen(command)
        time.sleep(5)

        # Add the client interface.
        command = [
            '/sbin/ifconfig', self.client_interface, self.client_ip, 'up'
        ]
        output = subprocess.Popen(command)

        template = ('yes', self.channel, self.essid, self.mesh_interface,
                    self.client_interface, self.mesh_interface)
        _utils.set_wireless_db_entry(self.netconfdb, template)

        # Send this information to the methods that write the /etc/hosts and
        # dnsmasq config files.
        networkconfiguration.make_hosts(self.hosts_file,
                                        self.test,
                                        starting_ip=self.client_ip)
        networkconfiguration.configure_dnsmasq(self.dnsmasq_include_file,
                                               self.test,
                                               starting_ip=self.client_ip)

        # Render and display the page.
        try:
            page = self.templatelookup.get_template("/network/done.html")
            return page.render(title="Network interface configured.",
                               purpose_of_page="Configured!",
                               interface=self.mesh_interface,
                               ip_address=self.mesh_ip,
                               netmask=self.mesh_netmask,
                               client_ip=self.client_ip,
                               client_netmask=self.client_netmask)
        except:
            _utils.output_error_data()
    def tcpip(self, essid=None, channel=None):
        logging.debug("Entered NetworkConfiguration.tcpip().")

        # Store the ESSID and wireless channel in the class' attribute set if
        # they were passed as args.
        if essid:
            self.essid = essid
        if channel:
            self.channel = channel

        # Initialize the Python environment's randomizer.
        random.seed()

        # Connect to the network configuration database.
        connection = sqlite3.connect(self.netconfdb)
        cursor = connection.cursor()

        # To run arping, the interface has to be up.  Check the database to
        # see if it's up, and if not flip it on for a few seconds to test.
        template = (self.mesh_interface, 'yes', )
        cursor.execute("SELECT mesh_interface, enabled FROM wireless WHERE mesh_interface=? AND enabled=?;", template)
        result = cursor.fetchall()
        if not result:
            self.update_mesh_interface_status('up')

            # Sleep five seconds to give the hardware a chance to catch up.
            time.sleep(5)

        # First pick an IP address for the mesh interface on the node.
        # Go into a loop in which pseudorandom IP addresses are chosen and
        # tested to see if they have been taken already or not.  Loop until we
        # have a winner.
        logging.debug("Probing for an IP address for the mesh interface.")
        # Pick a random IP address in a 192.168/24.
        addr = '192.168.'
        addr = addr + str(random.randint(0, 254)) + '.'
        addr = addr + str(random.randint(1, 254))
        self.mesh_ip = self.get_unused_ip(self.mesh_interface, addr, kind="mesh")
    
        # Next pick a distinct IP address for the client interface and its
        # netblock.  This is potentially trickier depending on how large the
        # mesh gets.
        logging.debug("Probing for an IP address for the client interface.")
        # Pick a random IP address in a 10/24.
        addr = '10.'
        addr = addr + str(random.randint(0, 254)) + '.'
        addr = addr + str(random.randint(0, 254)) + '.1'
        self.mesh_ip = self.get_unused_ip(self.client_interface, addr, kind="client")

        # For testing, hardcode some IP addresses so the rest of the code has
        # something to work with.
        if self.test:
            self.mesh_ip = '192.168.1.1'
            self.client_ip = '10.0.0.1'

        # Deactivate the interface as if it was down to begin with.
        if not result:
            self.update_mesh_interface_status('down')

        # Close the database connection.
        connection.close()

        # Run the "Are you sure?" page through the template interpeter.
        try:
            page = self.templatelookup.get_template("/network/confirm.html")
            return page.render(title = "Confirm network address for interface.",
                               purpose_of_page = "Confirm IP configuration.",
                               interface = self.mesh_interface,
                               mesh_ip = self.mesh_ip,
                               mesh_netmask = self.mesh_netmask,
                               client_ip = self.client_ip,
                               client_netmask = self.client_netmask)
        except:
            _utils.output_error_data()
Beispiel #19
0
    def set_ip(self):
        logging.debug("Entered NetworkConfiguration.set_ip().")

        # Set up the error catcher variable.
        error = []

        # Define the PID of the captive portal daemon in the topmost context
        # of this method.
        portal_pid = 0

        # If we've made it this far, the user's decided to (re)configure a
        # network interface.  Full steam ahead, damn the torpedoes!
        # First, take the wireless NIC offline so its mode can be changed.
        self.update_mesh_interface_status('down')
        time.sleep(5)

        # Wrap this whole process in a loop to ensure that stubborn wireless
        # interfaces are configured reliably.  The wireless NIC has to make it
        # all the way through one iteration of the loop without errors before
        # we can go on.
        while True:
            logging.debug("At top of wireless configuration loop.")

            chunks = {
                "mode": ("mode", "ad-hoc"),
                "ESSID": ("essid", self.essid),
                "BSSID": ("ap", self.bssid),
                "channel": ("channel", self.channel)
            }
            for k, v in chunks.iteritems():
                logging.debug("Configuring wireless interface: %s = %s", k, v)
                command = ['/sbin/iwconfig', self.mesh_interface]
                command.extend(v)
                if self.test:
                    logging.debug(
                        "NetworkConfiguration.set_ip() command to set the %s: %s",
                        k, ' '.join(command))
                else:
                    subprocess.Popen(command)
                    time.sleep(1)

            # Run iwconfig again and capture the current wireless configuration.
            command = ['/sbin/iwconfig', self.mesh_interface]
            configuration = ''
            if self.test:
                logging.debug(
                    "NetworkConfiguration.set_ip()command to capture the current state of a network interface: %s",
                    command)
            else:
                output = subprocess.Popen(command,
                                          stdout=subprocess.PIPE).stdout
                configuration = output.readlines()

            break_flag = False
            # Test the interface by going through the captured text to see if
            # it's in ad-hoc mode.  If it's not, go back to the top of the
            # loop to try again.
            for line in configuration:
                if re.search("Mode|ESSID|Cell|Frequency", line):
                    line = line.split(' ')
                else:
                    continue

                if 'Mode' in line:
                    mode = line[0].split(':')[1]
                    if mode != 'Ad-Hoc':
                        logging.debug(
                            "Uh-oh!  Not in ad-hoc mode!  Starting over.")
                        break_flag = True
                        break

                # Test the ESSID to see if it's been set properly.
                if 'ESSID' in line:
                    essid = line[-1].split(':')[1]
                    if essid != self.essid:
                        logging.debug(
                            "Uh-oh!  ESSID wasn't set!  Starting over.")
                        break_flag = True
                        break

                # Test the BSSID to see if it's been set properly.
                if 'Cell' in line:
                    bssid = line[-1]
                    if bssid != self.bssid:
                        logging.debug(
                            "Uh-oh!  BSSID wasn't set!  Starting over.")
                        break_flag = True
                        break

                # Check the wireless channel to see if it's been set properly.
                if 'Frequency' in line:
                    frequency = line[2].split(':')[1]
                    if frequency != self.frequency:
                        logging.debug(
                            "Uh-oh!  Wireless channel wasn't set!  starting over."
                        )
                        break_flag = True
                        break

            logging.debug("Hit bottom of the wireless configuration loop.")

            # For the purpose of testing, exit after one iteration so we don't
            # get stuck in an infinite loop.
            if self.test:
                break

            # "Victory is mine!"
            #     --Stewie, _Family Guy_
            if not (break_flag):
                break

        logging.debug("Wireless interface configured successfully.")

        # Call ifconfig and set up the network configuration information.
        logging.debug(
            "Setting IP configuration information on wireless interface.")
        command = [
            '/sbin/ifconfig', self.mesh_interface, self.mesh_ip, 'netmask',
            self.mesh_netmask, 'up'
        ]
        if self.test:
            logging.debug(
                "NetworkConfiguration.set_ip()command to set the IP configuration of the mesh interface: %s",
                command)
        else:
            subprocess.Popen(command)
        time.sleep(5)

        # Add the client interface.
        logging.debug("Adding client interface.")
        command = [
            '/sbin/ifconfig', self.client_interface, self.client_ip, 'up'
        ]
        if self.test:
            logging.debug(
                "NetworkConfiguration.set_ip()command to set the IP configuration of the client interface: %s",
                command)
        else:
            subprocess.Popen(command)

        template = ('yes', self.channel, self.essid, self.mesh_interface,
                    self.client_interface, self.mesh_interface)
        _utils.set_wireless_db_entry(self.netconfdb, template)

        # Start the captive portal daemon.  This will also initialize the IP
        # tables ruleset for the client interface.
        logging.debug("Starting captive portal daemon.")
        captive_portal_daemon = [
            '/usr/local/sbin/captive_portal.py', '-i',
            str(self.mesh_interface), '-a', self.client_ip, '-d'
        ]
        captive_portal_return = 0
        if self.test:
            logging.debug(
                "NetworkConfiguration.set_ip() command to start the captive portal daemon: %s",
                captive_portal_daemon)
            captive_portal_return = 6
        else:
            captive_portal_return = subprocess.Popen(captive_portal_daemon)
        logging.debug(
            "Sleeping for 5 seconds to see if a race condition is the reason we can't get the PID of the captive portal daemon."
        )
        time.sleep(5)

        # Now do some error checking.
        warnings = "<p>WARNING!  captive_portal.py exited with code %d - %s!</p>\n"
        if captive_portal_return == 1:
            error.append(
                warnings %
                (captive_portal_return,
                 "insufficient command line arguments passed to daemon"))
        elif captive_portal_return == 2:
            error.append(
                warnings %
                (captive_portal_return, "bad arguments passed to daemon"))
        elif captive_portal_return == 3:
            error.append(
                warnings %
                (captive_portal_return,
                 "bad IP tables commands during firewall initialization"))
        elif captive_portal_return == 4:
            error.append(
                warnings %
                (captive_portal_return, "bad parameters passed to IP tables"))
        elif captive_portal_return == 5:
            error.append(
                warnings %
                (captive_portal_return, "daemon already running on interface"))
        elif captive_portal_return == 6:
            error.append(
                "<p>NOTICE: captive_portal.py started in TEST mode - did not actually start up!</p>\n"
            )
        else:
            logging.debug("Getting PID of captive portal daemon.")

            # If the captive portal daemon started successfully, get its PID.
            # Note that we have to take into account both regular and test mode.
            captive_portal_pidfile = 'captive_portal.' + self.mesh_interface

            if os.path.exists('/var/run/' + captive_portal_pidfile):
                captive_portal_pidfile = '/var/run/' + captive_portal_pidfile
            elif os.path.exists('/tmp/' + captive_portal_pidfile):
                captive_portal_pidfile = '/tmp/' + captive_portal_pidfile
            else:
                error.append(
                    "<p>WARNING: Unable to open captive portal PID file " +
                    captive_portal_pidfile + "</p>\n")
                logging.debug(
                    "Unable to find PID file %s of captive portal daemon.",
                    captive_portal_pidfile)

            # Try to open the PID file.
            logging.debug("Trying to open %s.", captive_portal_pidfile)
            portal_pid = 0
            try:
                pidfile = open(str(captive_portal_pidfile), 'r')
                portal_pid = pidfile.readline()
                pidfile.close()
            except:
                error.append(
                    "<p>WARNING: Unable to open captive portal PID file " +
                    captive_portal_pidfile + "</p>\n")

            logging.debug("value of portal_pid is %s.", portal_pid)
            if self.test:
                logging.debug("Faking PID of captive_portal.py.")
                portal_pid = "Insert clever PID for captive_portal.py here."

            if not portal_pid:
                portal_pid = "ERROR: captive_portal.py failed, returned code " + str(
                    captive_portal_return) + "."
                logging.debug(
                    "Captive portal daemon failed to start.  Exited with code %s.",
                    str(captive_portal_return))

        # Send this information to the methods that write the /etc/hosts and
        # dnsmasq config files.
        logging.debug("Generating dnsmasq configuration files.")

        problem = make_hosts(self.hosts_file,
                             self.test,
                             starting_ip=self.client_ip)
        if problem:
            error.append(
                "<p>WARNING!  /etc/hosts.mesh not generated!  Something went wrong!</p>"
            )
            logging.debug("Couldn't generate /etc/hosts.mesh!")
        configure_dnsmasq(self.dnsmasq_include_file,
                          self.test,
                          starting_ip=self.client_ip)

        # Render and display the page.
        try:
            page = self.templatelookup.get_template("/network/done.html")
            return page.render(title="Network interface configured.",
                               purpose_of_page="Configured!",
                               error=''.join(error),
                               interface=self.mesh_interface,
                               ip_address=self.mesh_ip,
                               netmask=self.mesh_netmask,
                               portal_pid=portal_pid,
                               client_ip=self.client_ip,
                               client_netmask=self.client_netmask)
        except:
            _utils.output_error_data()
    def set_ip(self):
        logging.debug("Entered NetworkConfiguration.set_ip().")

        # Set up the error catcher variable.
        error = []

        # Define the PID of the captive portal daemon in the topmost context
        # of this method.
        portal_pid = 0

        # If we've made it this far, the user's decided to (re)configure a
        # network interface.  Full steam ahead, damn the torpedoes!
        # First, take the wireless NIC offline so its mode can be changed.
        self.update_mesh_interface_status('down')
        time.sleep(5)

        # Wrap this whole process in a loop to ensure that stubborn wireless
        # interfaces are configured reliably.  The wireless NIC has to make it
        # all the way through one iteration of the loop without errors before
        # we can go on.
        while True:
            logging.debug("At top of wireless configuration loop.")

            chunks = {"mode": ("mode", "ad-hoc"),
                      "ESSID": ("essid", self.essid),
                      "BSSID": ("ap", self.bssid),
                      "channel": ("channel", self.channel)}
            for k, v in chunks.iteritems():
                logging.debug("Configuring wireless interface: %s = %s", k, v)
                command = ['/sbin/iwconfig', self.mesh_interface]
                command.extend(v)
                if self.test:
                    logging.debug("NetworkConfiguration.set_ip() command to set the %s: %s", k, ' '.join(command))
                else:
                    subprocess.Popen(command)
                    time.sleep(1)

            # Run iwconfig again and capture the current wireless configuration.
            command = ['/sbin/iwconfig', self.mesh_interface]
            configuration = ''
            if self.test:
                logging.debug("NetworkConfiguration.set_ip()command to capture the current state of a network interface: %s", command)
            else:
                output = subprocess.Popen(command, stdout=subprocess.PIPE).stdout
                configuration = output.readlines()

            break_flag = False
            # Test the interface by going through the captured text to see if
            # it's in ad-hoc mode.  If it's not, go back to the top of the
            # loop to try again.
            for line in configuration:
                if re.search("Mode|ESSID|Cell|Frequency", line):
                    line = line.split(' ')
                else:
                    continue

                if 'Mode' in line:
                    mode = line[0].split(':')[1]
                    if mode != 'Ad-Hoc':
                        logging.debug("Uh-oh!  Not in ad-hoc mode!  Starting over.")
                        break_flag = True
                        break

                # Test the ESSID to see if it's been set properly.
                if 'ESSID' in line:
                    essid = line[-1].split(':')[1]
                    if essid != self.essid:
                        logging.debug("Uh-oh!  ESSID wasn't set!  Starting over.")
                        break_flag = True
                        break

                # Test the BSSID to see if it's been set properly.
                if 'Cell' in line:
                    bssid = line[-1]
                    if bssid != self.bssid:
                        logging.debug("Uh-oh!  BSSID wasn't set!  Starting over.")
                        break_flag = True
                        break

                # Check the wireless channel to see if it's been set properly.
                if 'Frequency' in line:
                    frequency = line[2].split(':')[1]
                    if frequency != self.frequency:
                        logging.debug("Uh-oh!  Wireless channel wasn't set!  starting over.")
                        break_flag = True
                        break

            logging.debug("Hit bottom of the wireless configuration loop.")

            # For the purpose of testing, exit after one iteration so we don't
            # get stuck in an infinite loop.
            if self.test:
                break

            # "Victory is mine!"
            #     --Stewie, _Family Guy_
            if not(break_flag):
                break

        logging.debug("Wireless interface configured successfully.")

        # Call ifconfig and set up the network configuration information.
        logging.debug("Setting IP configuration information on wireless interface.")
        command = ['/sbin/ifconfig', self.mesh_interface, self.mesh_ip,
                   'netmask', self.mesh_netmask, 'up']
        if self.test:
            logging.debug("NetworkConfiguration.set_ip()command to set the IP configuration of the mesh interface: %s", command)
        else:
            subprocess.Popen(command)
        time.sleep(5)

        # Add the client interface.
        logging.debug("Adding client interface.")
        command = ['/sbin/ifconfig', self.client_interface, self.client_ip, 'up']
        if self.test:
            logging.debug("NetworkConfiguration.set_ip()command to set the IP configuration of the client interface: %s", command)
        else:
            subprocess.Popen(command)

        template = ('yes', self.channel, self.essid, self.mesh_interface, self.client_interface, self.mesh_interface)
        _utils.set_wireless_db_entry(self.netconfdb, template)

        # Start the captive portal daemon.  This will also initialize the IP
        # tables ruleset for the client interface.
        logging.debug("Starting captive portal daemon.")
        captive_portal_daemon = ['/usr/local/sbin/captive_portal.py', '-i',
                                 str(self.mesh_interface), '-a', self.client_ip,
                                 '-d' ]
        captive_portal_return = 0
        if self.test:
            logging.debug("NetworkConfiguration.set_ip() command to start the captive portal daemon: %s", captive_portal_daemon)
            captive_portal_return = 6
        else:
            captive_portal_return = subprocess.Popen(captive_portal_daemon)
        logging.debug("Sleeping for 5 seconds to see if a race condition is the reason we can't get the PID of the captive portal daemon.")
        time.sleep(5)

        # Now do some error checking.
        warnings = "<p>WARNING!  captive_portal.py exited with code %d - %s!</p>\n"
        if captive_portal_return == 1:
            error.append(warnings % (captive_portal_return, "insufficient command line arguments passed to daemon"))
        elif captive_portal_return == 2:
            error.append(warnings % (captive_portal_return, "bad arguments passed to daemon"))
        elif captive_portal_return == 3:
            error.append(warnings % (captive_portal_return, "bad IP tables commands during firewall initialization"))
        elif captive_portal_return == 4:
            error.append(warnings % (captive_portal_return, "bad parameters passed to IP tables"))
        elif captive_portal_return == 5:
            error.append(warnings % (captive_portal_return, "daemon already running on interface"))
        elif captive_portal_return == 6:
            error.append("<p>NOTICE: captive_portal.py started in TEST mode - did not actually start up!</p>\n")
        else:
            logging.debug("Getting PID of captive portal daemon.")

            # If the captive portal daemon started successfully, get its PID.
            # Note that we have to take into account both regular and test mode.
            captive_portal_pidfile = 'captive_portal.' + self.mesh_interface

            if os.path.exists('/var/run/' + captive_portal_pidfile):
                captive_portal_pidfile = '/var/run/' + captive_portal_pidfile
            elif os.path.exists('/tmp/' + captive_portal_pidfile):
                captive_portal_pidfile = '/tmp/' + captive_portal_pidfile
            else:
                error.append("<p>WARNING: Unable to open captive portal PID file " + captive_portal_pidfile + "</p>\n")
                logging.debug("Unable to find PID file %s of captive portal daemon.", captive_portal_pidfile)

            # Try to open the PID file.
            logging.debug("Trying to open %s.", captive_portal_pidfile)
            portal_pid = 0
            try:
                pidfile = open(str(captive_portal_pidfile), 'r')
                portal_pid = pidfile.readline()
                pidfile.close()
            except:
                error.append("<p>WARNING: Unable to open captive portal PID file " + captive_portal_pidfile + "</p>\n")

            logging.debug("value of portal_pid is %s.", portal_pid)
            if self.test:
                logging.debug("Faking PID of captive_portal.py.")
                portal_pid = "Insert clever PID for captive_portal.py here."

            if not portal_pid:
                portal_pid = "ERROR: captive_portal.py failed, returned code " + str(captive_portal_return) + "."
                logging.debug("Captive portal daemon failed to start.  Exited with code %s.", str(captive_portal_return))

        # Send this information to the methods that write the /etc/hosts and
        # dnsmasq config files.
        logging.debug("Generating dnsmasq configuration files.")

        problem = make_hosts(self.hosts_file, self.test, starting_ip=self.client_ip)
        if problem:
            error.append("<p>WARNING!  /etc/hosts.mesh not generated!  Something went wrong!</p>")
            logging.debug("Couldn't generate /etc/hosts.mesh!")
        configure_dnsmasq(self.dnsmasq_include_file, self.test, starting_ip=self.client_ip)

        # Render and display the page.
        try:
            page = self.templatelookup.get_template("/network/done.html")
            return page.render(title = "Network interface configured.",
                               purpose_of_page = "Configured!",
                               error = ''.join(error), interface = self.mesh_interface,
                               ip_address = self.mesh_ip,
                               netmask = self.mesh_netmask,
                               portal_pid = portal_pid,
                               client_ip = self.client_ip,
                               client_netmask = self.client_netmask)
        except:
            _utils.output_error_data()
Beispiel #21
0
    def tcpip(self, essid=None, channel=None):
        logging.debug("Entered NetworkConfiguration.tcpip().")

        # Store the ESSID and wireless channel in the class' attribute set if
        # they were passed as args.
        if essid:
            self.essid = essid
        if channel:
            self.channel = channel

        # Initialize the Python environment's randomizer.
        random.seed()

        # Connect to the network configuration database.
        connection = sqlite3.connect(self.netconfdb)
        cursor = connection.cursor()

        # To run arping, the interface has to be up.  Check the database to
        # see if it's up, and if not flip it on for a few seconds to test.
        template = (
            self.mesh_interface,
            'yes',
        )
        cursor.execute(
            "SELECT mesh_interface, enabled FROM wireless WHERE mesh_interface=? AND enabled=?;",
            template)
        result = cursor.fetchall()
        if not result:
            self.update_mesh_interface_status('up')

            # Sleep five seconds to give the hardware a chance to catch up.
            time.sleep(5)

        # First pick an IP address for the mesh interface on the node.
        # Go into a loop in which pseudorandom IP addresses are chosen and
        # tested to see if they have been taken already or not.  Loop until we
        # have a winner.
        logging.debug("Probing for an IP address for the mesh interface.")
        # Pick a random IP address in a 192.168/24.
        addr = '192.168.'
        addr = addr + str(random.randint(0, 254)) + '.'
        addr = addr + str(random.randint(1, 254))
        self.mesh_ip = self.get_unused_ip(self.mesh_interface,
                                          addr,
                                          kind="mesh")

        # Next pick a distinct IP address for the client interface and its
        # netblock.  This is potentially trickier depending on how large the
        # mesh gets.
        logging.debug("Probing for an IP address for the client interface.")
        # Pick a random IP address in a 10/24.
        addr = '10.'
        addr = addr + str(random.randint(0, 254)) + '.'
        addr = addr + str(random.randint(0, 254)) + '.1'
        self.mesh_ip = self.get_unused_ip(self.client_interface,
                                          addr,
                                          kind="client")

        # For testing, hardcode some IP addresses so the rest of the code has
        # something to work with.
        if self.test:
            self.mesh_ip = '192.168.1.1'
            self.client_ip = '10.0.0.1'

        # Deactivate the interface as if it was down to begin with.
        if not result:
            self.update_mesh_interface_status('down')

        # Close the database connection.
        connection.close()

        # Run the "Are you sure?" page through the template interpeter.
        try:
            page = self.templatelookup.get_template("/network/confirm.html")
            return page.render(title="Confirm network address for interface.",
                               purpose_of_page="Confirm IP configuration.",
                               interface=self.mesh_interface,
                               mesh_ip=self.mesh_ip,
                               mesh_netmask=self.mesh_netmask,
                               client_ip=self.client_ip,
                               client_netmask=self.client_netmask)
        except:
            _utils.output_error_data()
Beispiel #22
0
    def index(self):
        logging.debug("Entering NetworkConfiguration.index().")

        # Reinitialize this class' attributes in case the user wants to
        # reconfigure an interface.  It'll be used to set the default values
        # of the HTML fields.
        self.reinitialize_attributes()

        # Get a list of all network interfaces on the node (sans loopback).
        wired, wireless = enumerate_network_interfaces()
        logging.debug("Contents of wired[]: %s", wired)
        logging.debug("Contents of wireless[]: %s", wireless)

        # MOOF MOOF MOOF - call to stub implementation.  We can use the list
        # immediately above (interfaces) as the list to compare the database
        # against.
        # Test to see if any network interfaces have gone away.
        #logging.debug("Pruning missing network interfaces.")
        #self.prune(interfaces)

        # Build tables containing the interfaces extant.  At the same time,
        # search the network configuration databases for interfaces that are
        # already configured and give them a different color.  If they're up
        # and running give them yet another color.
        connection = sqlite3.connect(self.netconfdb)
        cursor = connection.cursor()
        wireless_buttons = ""
        ethernet_buttons = ""

        interface_tag_start = "<input type='submit' name='interface' value='"

        # Start with wireless interfaces.
        for i in wireless:
            logging.debug("Checking to see if %s is in the database.", i)
            cursor.execute(
                "SELECT mesh_interface, enabled FROM wireless WHERE mesh_interface=?",
                (i, ))
            result = cursor.fetchall()

            # If the interface is not found in database, add it.
            if not result:
                logging.debug("Adding %s to table 'wireless'.", i)

                # gateway, client_interface, enabled, channel, essid,
                # mesh_interface
                template = (
                    'no',
                    (i + ':1'),
                    'no',
                    '0',
                    '',
                    i,
                )

                cursor.execute("INSERT INTO wireless VALUES (?,?,?,?,?,?);",
                               template)
                connection.commit()
                wireless_buttons += "%s%s' />\n" % (interface_tag_start, i)
                continue

            # If it is there test to see if it's been configured or not.  If it
            # has, use a CSS hack to make its button a different color.
            if result[0][1] == "yes":
                wireless_buttons += "%s%s' style='background-color:red' />\n" % (
                    interface_tag_start, i)
                continue

            # If all else fails, just add the button without any extra
            # decoration.
            wireless_buttons += "%s%s' />\n" % (interface_tag_start, i)

        # Wired interfaces.
        for i in wired:
            logging.debug("Checking to see if %s is in the database.", i)
            cursor.execute(
                "SELECT interface, enabled FROM wired WHERE interface=?",
                (i, ))
            result = cursor.fetchall()

            # If the interface is not found in database, add it.
            if not result:
                logging.debug("Adding %s to table 'wired'.", i)

                # enabled, gateway, interface
                template = (
                    'no',
                    'no',
                    i,
                )
                cursor.execute("INSERT INTO wired VALUES (?,?,?);", template)
                connection.commit()
                ethernet_buttons += "%s%s' />\n" % (interface_tag_start, i)
                continue

            # If it is found test to see if it's been configured or not.  If it
            # has, use a CSS hack to make its button a different color.
            if result[0][1] == "yes":
                ethernet_buttons += "%s%s' style='background-color:red' />\n" % (
                    interface_tag_start, i)
                continue

            # If all else fails, just add the button without any extra
            # decoration.
            ethernet_buttons += "%s%s' />\n" % (interface_tag_start, i)

        # Render the HTML page.
        cursor.close()
        try:
            page = self.templatelookup.get_template("/network/index.html")
            return page.render(title="Byzantium Node Network Interfaces",
                               purpose_of_page="Configure Network Interfaces",
                               wireless_buttons=wireless_buttons,
                               ethernet_buttons=ethernet_buttons)
        except:
            _utils.output_error_data()
Beispiel #23
0
    def index(self):
        # This is technically irrelevant because the class' attributes are blank
        # when instantiated, but it's useful for setting up the HTML fields.
        self.reinitialize_attributes()

        # Populate the database of mesh interfaces using the network interface
        # database as a template.  Start by pulling a list of interfaces out of
        # the network configuration database.
        error = []
        netconfconn = sqlite3.connect(self.netconfdb)
        netconfcursor = netconfconn.cursor()
        interfaces = []
        netconfcursor.execute("SELECT mesh_interface, enabled FROM wireless;")
        results = netconfcursor.fetchall()
        active_interfaces = []
        if not results:
            # Display an error page which says that no wireless interfaces have
            # been configured yet.
            error.append(
                "<p>ERROR: No wireless network interfaces have been configured yet.  <a href='/network'>You need to do that first!</a></p>"
            )
        else:
            # Open a connection to the mesh configuration database.
            meshconfconn = sqlite3.connect(self.meshconfdb)
            meshconfcursor = meshconfconn.cursor()

            # Walk through the list of results.
            for i in results:
                # Is the network interface already configured?
                if i[1] == "yes":
                    # See if the interface is already in the mesh configuration
                    # database, and if it's not insert it.
                    template = (i[0],)
                    meshconfcursor.execute("SELECT interface, enabled FROM meshes WHERE interface=?;", template)
                    interface_found = meshconfcursor.fetchall()
                    interface_tag = "<input type='submit' name='interface' value='"
                    if not interface_found:
                        template = ("no", i[0], "babel")
                        meshconfcursor.execute("INSERT INTO meshes VALUES (?, ?, ?);", template)
                        meshconfconn.commit()

                        # This is a network interface that's ready to configure,
                        # so add it to the HTML template as a button.
                        interfaces.append("%s%s' style='background-color:white;' />\n" % (interface_tag, i[0]))
                    else:
                        # If the interface is enabled, add it to the row of
                        # active interfaces with a different color.
                        if interface_found[0][1] == "yes":
                            active_interfaces.append(
                                "%s%s' style='background-color:green;' />\n" % (interface_tag, i[0])
                            )
                        else:
                            # The mesh interface hasn't been configured.
                            interfaces.append("%s%s' />\n" % (interface_tag, i[0]))

                else:
                    # This interface isn't configured but it's in the database,
                    # so add it to the template as an unclickable button.
                    # While it might not be a good idea to put unusable buttons
                    # into the page, it would tell the user that the interfaces
                    # were detected.
                    interfaces.append("%s%s' style='background-color:orange;' />\n" % (interface_tag, i[0]))
            meshconfcursor.close()

        # Clean up our connections to the configuration databases.
        netconfcursor.close()

        # Render the HTML page.
        try:
            page = self.templatelookup.get_template("/mesh/index.html")
            return page.render(
                title="Byzantium Node Mesh Configuration",
                purpose_of_page="Configure Mesh Interfaces",
                error="".join(error),
                interfaces="".join(interfaces),
                active_interfaces="".join(active_interfaces),
            )
        except:
            _utils.output_error_data()
Beispiel #24
0
    def disable(self):
        logging.debug("Entered MeshConfiguration.disable().")

        # Set up the error and successful output messages.
        error = ""
        output = ""

        # Set up a default set of command line options for babeld.  Some of
        # these are redundant but are present in case an older version of
        # babeld is used on the node.  See the following file to see why:
        # http://www.pps.jussieu.fr/~jch/software/babel/CHANGES.text
        common_babeld_opts = ["-m", "ff02:0:0:0:0:0:1:6", "-p", "6696", "-D"]

        # Create a set of unique command line options for babeld.  Right now,
        # this variable is empty but it might be used in the future.  Maybe
        # it'll be populated from a config file or something.
        unique_babeld_opts = []

        # Set up a list of mesh interfaces for which babeld is already running
        # but omit self.interface.
        interfaces = []
        query = "SELECT interface FROM meshes WHERE enabled='yes' AND protocol='babel';"
        connection, cursor = _utils.execute_query(self.meshconfdb, query)
        results = cursor.fetchall()
        for i in results:
            if i[0] != self.interface:
                interfaces.append(i[0])

        # If there are no mesh interfaces configured anymore, then the node
        # is offline.
        if not interfaces:
            output = "Byzantium node offline."

        babeld_command = self.update_babeld(common_babeld_opts, unique_babeld_opts, interfaces)

        # If there is at least one wireless network interface still configured,
        # then re-run babeld.
        if interfaces:
            logging.debug("value of babeld_command is %s", babeld_command)
            if self.test:
                logging.debug("Pretending to restart babeld.")
            else:
                subprocess.Popen(babeld_command)
            time.sleep(self.babeld_timeout)

        # Get the PID of babeld, then test to see if that pid exists and
        # corresponds to a running babeld process.  If there is no match,
        # babeld isn't running, in which case something went wrong.
        pid = self.pid_check()
        if pid:
            error, output = self._pid_helper(pid, error, output, cursor, connection)
        else:
            # There are no mesh interfaces left, so update the database to
            # deconfigure self.interface.
            template = ("no", self.interface)
            cursor.execute("UPDATE meshes SET enabled=? WHERE interface=?;", template)
        connection.commit()
        cursor.close()

        # Render the HTML page.
        try:
            page = self.templatelookup.get_template("/mesh/disabled.html")
            return page.render(
                title="Byzantium Node Mesh Configuration",
                purpose_of_page="Disable Mesh Interface",
                error=error,
                output=output,
            )
        except:
            _utils.output_error_data()
Beispiel #25
0
    def disable(self):
        logging.debug("Entered MeshConfiguration.disable().")

        # Set up the error and successful output messages.
        error = ''
        output = ''

        # Set up a default set of command line options for babeld.  Some of
        # these are redundant but are present in case an older version of
        # babeld is used on the node.  See the following file to see why:
        # http://www.pps.jussieu.fr/~jch/software/babel/CHANGES.text
        common_babeld_opts = ['-m', 'ff02:0:0:0:0:0:1:6', '-p', '6696', '-D']

        # Create a set of unique command line options for babeld.  Right now,
        # this variable is empty but it might be used in the future.  Maybe
        # it'll be populated from a config file or something.
        unique_babeld_opts = []

        # Set up a list of mesh interfaces for which babeld is already running
        # but omit self.interface.
        interfaces = []
        query = "SELECT interface FROM meshes WHERE enabled='yes' AND protocol='babel';"
        connection, cursor = _utils.execute_query(self.meshconfdb, query)
        results = cursor.fetchall()
        for i in results:
            if i[0] != self.interface:
                interfaces.append(i[0])

        # If there are no mesh interfaces configured anymore, then the node
        # is offline.
        if not interfaces:
            output = 'Byzantium node offline.'

        babeld_command = self.update_babeld(common_babeld_opts,
                                            unique_babeld_opts, interfaces)

        # If there is at least one wireless network interface still configured,
        # then re-run babeld.
        if interfaces:
            logging.debug("value of babeld_command is %s", babeld_command)
            if self.test:
                logging.debug("Pretending to restart babeld.")
            else:
                subprocess.Popen(babeld_command)
            time.sleep(self.babeld_timeout)

        # Get the PID of babeld, then test to see if that pid exists and
        # corresponds to a running babeld process.  If there is no match,
        # babeld isn't running, in which case something went wrong.
        pid = self.pid_check()
        if pid:
            error, output = self._pid_helper(pid, error, output, cursor,
                                             connection)
        else:
            # There are no mesh interfaces left, so update the database to
            # deconfigure self.interface.
            template = (
                'no',
                self.interface,
            )
            cursor.execute("UPDATE meshes SET enabled=? WHERE interface=?;",
                           template)
        connection.commit()
        cursor.close()

        # Render the HTML page.
        try:
            page = self.templatelookup.get_template("/mesh/disabled.html")
            return page.render(title="Byzantium Node Mesh Configuration",
                               purpose_of_page="Disable Mesh Interface",
                               error=error,
                               output=output)
        except:
            _utils.output_error_data()
Beispiel #26
0
    def index(self):
        # This is technically irrelevant because the class' attributes are blank
        # when instantiated, but it's useful for setting up the HTML fields.
        self.reinitialize_attributes()

        # Populate the database of mesh interfaces using the network interface
        # database as a template.  Start by pulling a list of interfaces out of
        # the network configuration database.
        error = []
        netconfconn = sqlite3.connect(self.netconfdb)
        netconfcursor = netconfconn.cursor()
        interfaces = []
        netconfcursor.execute("SELECT mesh_interface, enabled FROM wireless;")
        results = netconfcursor.fetchall()
        active_interfaces = []
        if not results:
            # Display an error page which says that no wireless interfaces have
            # been configured yet.
            error.append(
                "<p>ERROR: No wireless network interfaces have been configured yet.  <a href='/network'>You need to do that first!</a></p>"
            )
        else:
            # Open a connection to the mesh configuration database.
            meshconfconn = sqlite3.connect(self.meshconfdb)
            meshconfcursor = meshconfconn.cursor()

            # Walk through the list of results.
            for i in results:
                # Is the network interface already configured?
                if i[1] == 'yes':
                    # See if the interface is already in the mesh configuration
                    # database, and if it's not insert it.
                    template = (i[0], )
                    meshconfcursor.execute(
                        "SELECT interface, enabled FROM meshes WHERE interface=?;",
                        template)
                    interface_found = meshconfcursor.fetchall()
                    interface_tag = "<input type='submit' name='interface' value='"
                    if not interface_found:
                        template = (
                            'no',
                            i[0],
                            'babel',
                        )
                        meshconfcursor.execute(
                            "INSERT INTO meshes VALUES (?, ?, ?);", template)
                        meshconfconn.commit()

                        # This is a network interface that's ready to configure,
                        # so add it to the HTML template as a button.
                        interfaces.append(
                            "%s%s' style='background-color:white;' />\n" %
                            (interface_tag, i[0]))
                    else:
                        # If the interface is enabled, add it to the row of
                        # active interfaces with a different color.
                        if interface_found[0][1] == 'yes':
                            active_interfaces.append(
                                "%s%s' style='background-color:green;' />\n" %
                                (interface_tag, i[0]))
                        else:
                            # The mesh interface hasn't been configured.
                            interfaces.append("%s%s' />\n" %
                                              (interface_tag, i[0]))

                else:
                    # This interface isn't configured but it's in the database,
                    # so add it to the template as an unclickable button.
                    # While it might not be a good idea to put unusable buttons
                    # into the page, it would tell the user that the interfaces
                    # were detected.
                    interfaces.append(
                        "%s%s' style='background-color:orange;' />\n" %
                        (interface_tag, i[0]))
            meshconfcursor.close()

        # Clean up our connections to the configuration databases.
        netconfcursor.close()

        # Render the HTML page.
        try:
            page = self.templatelookup.get_template("/mesh/index.html")
            return page.render(title="Byzantium Node Mesh Configuration",
                               purpose_of_page="Configure Mesh Interfaces",
                               error=''.join(error),
                               interfaces=''.join(interfaces),
                               active_interfaces=''.join(active_interfaces))
        except:
            _utils.output_error_data()
Beispiel #27
0
    def set_ip(self):
        # If we've made it this far, the user's decided to (re)configure a
        # network interface.  Full steam ahead, damn the torpedoes!

        # First, take the wireless NIC offline so its mode can be changed.
        command = ['/sbin/ifconfig', self.mesh_interface, 'down']
        output = subprocess.Popen(command)
        time.sleep(5)

        # Wrap this whole process in a loop to ensure that stubborn wireless
        # interfaces are configured reliably.  The wireless NIC has to make it
        # all the way through one iteration of the loop without errors before
        # we can go on.
        while True:
            # Set the mode, ESSID and channel.
            command = ['/sbin/iwconfig', self.mesh_interface, 'mode ad-hoc']
            output = subprocess.Popen(command)
            command = ['/sbin/iwconfig', self.mesh_interface, 'essid', self.essid]
            output = subprocess.Popen(command)
            command = ['/sbin/iwconfig', self.mesh_interface, 'channel',  self.channel]
            output = subprocess.Popen(command)

            # Run iwconfig again and capture the current wireless configuration.
            command = ['/sbin/iwconfig', self.mesh_interface]
            output = subprocess.Popen(command).stdout
            configuration = output.readlines()

            # Test the interface by going through the captured text to see if
            # it's in ad-hoc mode.  If it's not, put it in ad-hoc mode and go
            # back to the top of the loop to try again.
            for line in configuration:
                if 'Mode' in line:
                    line = line.strip()
                    mode = line.split(' ')[0].split(':')[1]
                    if mode != 'Ad-Hoc':
                        continue

            # Test the ESSID to see if it's been set properly.
            for line in configuration:
                if 'ESSID' in line:
                    line = line.strip()
                    essid = line.split(' ')[-1].split(':')[1]
                    if essid != self.essid:
                        continue

            # Check the wireless channel to see if it's been set properly.
            for line in configuration:
                if 'Frequency' in line:
                    line = line.strip()
                    frequency = line.split(' ')[2].split(':')[1]
                    if frequency != self.frequency:
                        continue

            # "Victory is mine!"
            # --Stewie, _Family Guy_
            break

        # Call ifconfig and set up the network configuration information.
        command = ['/sbin/ifconfig', self.mesh_interface, self.mesh_ip,
                   'netmask', self.mesh_netmask, 'up']
        output = subprocess.Popen(command)
        time.sleep(5)

        # Add the client interface.
        command = ['/sbin/ifconfig', self.client_interface, self.client_ip, 'up']
        output = subprocess.Popen(command)

        template = ('yes', self.channel, self.essid, self.mesh_interface, self.client_interface, self.mesh_interface)
        _utils.set_wireless_db_entry(self.netconfdb, template)

        # Send this information to the methods that write the /etc/hosts and
        # dnsmasq config files.
        networkconfiguration.make_hosts(self.hosts_file, self.test, starting_ip=self.client_ip)
        networkconfiguration.configure_dnsmasq(self.dnsmasq_include_file, self.test, starting_ip=self.client_ip)

        # Render and display the page.
        try:
            page = self.templatelookup.get_template("/network/done.html")
            return page.render(title = "Network interface configured.",
                               purpose_of_page = "Configured!",
                               interface = self.mesh_interface,
                               ip_address = self.mesh_ip,
                               netmask = self.mesh_netmask,
                               client_ip = self.client_ip,
                               client_netmask = self.client_netmask)
        except:
            _utils.output_error_data()
    def index(self):
        logging.debug("Entering NetworkConfiguration.index().")

        # Reinitialize this class' attributes in case the user wants to
        # reconfigure an interface.  It'll be used to set the default values
        # of the HTML fields.
        self.reinitialize_attributes()

        # Get a list of all network interfaces on the node (sans loopback).
        wired, wireless = enumerate_network_interfaces()
        logging.debug("Contents of wired[]: %s", wired)
        logging.debug("Contents of wireless[]: %s", wireless)

        # MOOF MOOF MOOF - call to stub implementation.  We can use the list
        # immediately above (interfaces) as the list to compare the database
        # against.
        # Test to see if any network interfaces have gone away.
        #logging.debug("Pruning missing network interfaces.")
        #self.prune(interfaces)

        # Build tables containing the interfaces extant.  At the same time,
        # search the network configuration databases for interfaces that are
        # already configured and give them a different color.  If they're up
        # and running give them yet another color.
        connection = sqlite3.connect(self.netconfdb)
        cursor = connection.cursor()
        wireless_buttons = ""
        ethernet_buttons = ""

        interface_tag_start = "<input type='submit' name='interface' value='"

        # Start with wireless interfaces.
        for i in wireless:
            logging.debug("Checking to see if %s is in the database.", i)
            cursor.execute("SELECT mesh_interface, enabled FROM wireless WHERE mesh_interface=?", (i, ))
            result = cursor.fetchall()

            # If the interface is not found in database, add it.
            if not result:
                logging.debug("Adding %s to table 'wireless'.", i)

                # gateway, client_interface, enabled, channel, essid,
                # mesh_interface
                template = ('no', (i + ':1'), 'no', '0', '', i, )

                cursor.execute("INSERT INTO wireless VALUES (?,?,?,?,?,?);", template)
                connection.commit()
                wireless_buttons += "%s%s' />\n" % (interface_tag_start, i)
                continue

            # If it is there test to see if it's been configured or not.  If it
            # has, use a CSS hack to make its button a different color.
            if result[0][1] == "yes":
                wireless_buttons += "%s%s' style='background-color:red' />\n" % (interface_tag_start, i)
                continue

            # If all else fails, just add the button without any extra
            # decoration.
            wireless_buttons += "%s%s' />\n" % (interface_tag_start, i)

        # Wired interfaces.
        for i in wired:
            logging.debug("Checking to see if %s is in the database.", i)
            cursor.execute("SELECT interface, enabled FROM wired WHERE interface=?", (i, ))
            result = cursor.fetchall()

            # If the interface is not found in database, add it.
            if not result:
                logging.debug("Adding %s to table 'wired'.", i)

                # enabled, gateway, interface
                template = ('no', 'no', i, )
                cursor.execute("INSERT INTO wired VALUES (?,?,?);", template)
                connection.commit()
                ethernet_buttons += "%s%s' />\n" % (interface_tag_start, i)
                continue

            # If it is found test to see if it's been configured or not.  If it
            # has, use a CSS hack to make its button a different color.
            if result[0][1] == "yes":
                ethernet_buttons += "%s%s' style='background-color:red' />\n" % (interface_tag_start, i)
                continue

            # If all else fails, just add the button without any extra
            # decoration.
            ethernet_buttons += "%s%s' />\n" % (interface_tag_start, i)

        # Render the HTML page.
        cursor.close()
        try:
            page = self.templatelookup.get_template("/network/index.html")
            return page.render(title = "Byzantium Node Network Interfaces",
                               purpose_of_page = "Configure Network Interfaces",
                               wireless_buttons = wireless_buttons,
                               ethernet_buttons = ethernet_buttons)
        except:
            _utils.output_error_data()