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()
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()
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 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()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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()
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()