X-Git-Url: http://xvm.mit.edu/gitweb/invirt/packages/invirt-dhcp.git/blobdiff_plain/4ac9701f4fd2847f00970f3b1447de95a8a6d655..2b38e5c8b077cc03612388daf1c9c34f08688fef:/code/dhcpserver.py diff --git a/code/dhcpserver.py b/code/dhcpserver.py index 3133643..d5f35eb 100755 --- a/code/dhcpserver.py +++ b/code/dhcpserver.py @@ -1,6 +1,5 @@ #!/usr/bin/python import sys -sys.path.append('pydhcplib/') import pydhcplib import pydhcplib.dhcp_network from pydhcplib.dhcp_packet import * @@ -10,37 +9,32 @@ from pydhcplib.type_strlist import strlist import socket import IN -import event_logger -if '__main__' == __name__: - event_logger.init("stdout", 'DEBUG', {}) -from event_logger import Log +import syslog as s import psycopg2 import time -import sipb_xen_database -from sqlalchemy import create_engine +from invirt import database +from invirt.config import structs as config -dhcp_options = {'subnet_mask': '255.255.0.0', - 'router': '18.181.0.1', - 'domain_name_server': '18.70.0.160,18.71.0.151,18.72.0.3', - 'domain_name': 'mit.edu', +dhcp_options = {'subnet_mask': config.dhcp.netmask, + 'router': config.dhcp.gateway, + 'domain_name_server': ','.join(config.dhcp.dns), 'ip_address_lease_time': 60*60*24} class DhcpBackend: - def __init__(self, database=None): - if database is not None: - self.database = database - sipb_xen_database.connect(create_engine(database)) + def __init__(self): + database.connect() def findNIC(self, mac): + database.clear_cache() for i in range(3): try: - value = sipb_xen_database.NIC.get_by(mac_addr=mac) + value = database.NIC.query().filter_by(mac_addr=mac).one() except psycopg2.OperationalError: time.sleep(0.5) if i == 2: #Try twice to reconnect. raise #Sigh. SQLAlchemy should do this itself. - sipb_xen_database.connect(create_engine(self.database)) + database.connect() else: break return value @@ -48,14 +42,14 @@ class DhcpBackend: chaddr = hwmac(packet.GetHardwareAddress()) nic = self.findNIC(str(chaddr)) if nic is None or nic.ip is None: - return ("18.181.0.60", None) + return ipstr = ''.join(reversed(['%02X' % i for i in ipv4(nic.ip).list()])) for line in open('/proc/net/route'): parts = line.split() if parts[1] == ipstr: - Log.Output(Log.debug, "find_interface found "+str(nic.ip)+" on "+parts[0]) - return ("18.181.0.60", parts[0]) - return ("18.181.0.60", None) + s.syslog(s.LOG_DEBUG, "find_interface found "+str(nic.ip)+" on "+parts[0]) + return parts[0] + return def getParameters(self, **extra): all_options=dict(dhcp_options) @@ -95,13 +89,22 @@ class DhcpBackend: elif option_type == "string" : options[parameter] = strlist(value).list() + + elif option_type == "RFC3397" : + parsed_value = "" + for item in value: + components = item.split('.') + item_fmt = "".join(chr(len(elt)) + elt for elt in components) + "\x00" + parsed_value += item_fmt + options[parameter] = strlist(parsed_value).list() + else : options[parameter] = strlist(value).list() return options def Discover(self, packet): - Log.Output(Log.debug,"dhcp_backend : Discover ") + s.syslog(s.LOG_DEBUG, "dhcp_backend : Discover ") chaddr = hwmac(packet.GetHardwareAddress()) nic = self.findNIC(str(chaddr)) if nic is None or nic.machine is None: @@ -109,16 +112,23 @@ class DhcpBackend: ip = nic.ip if ip is None: #Deactivated? return False + + options = {} if nic.hostname and '.' in nic.hostname: - hostname = nic.hostname + options['host_name'], options['domain_name'] = nic.hostname.split('.', 1) elif nic.machine.name: - hostname = nic.machine.name + '.servers.csail.mit.edu' + options['host_name'] = nic.machine.name + options['domain_name'] = config.dns.domains[0] else: hostname = None + if DhcpOptions['domain_search'] in packet.GetOption('parameter_request_list'): + options['host_name'] += '.' + options['domain_name'] + del options['domain_name'] + options['domain_search'] = [config.dhcp.search_domain] if ip is not None: ip = ipv4(ip) - Log.Output(Log.debug,"dhcp_backend : Discover result = "+str(ip)) - packet_parameters = self.getParameters(host_name=hostname) + s.syslog(s.LOG_DEBUG,"dhcp_backend : Discover result = "+str(ip)) + packet_parameters = self.getParameters(**options) # FIXME: Other offer parameters go here packet_parameters["yiaddr"] = ip.list() @@ -128,7 +138,7 @@ class DhcpBackend: return False def Request(self, packet): - Log.Output(Log.debug, "dhcp_backend : Request") + s.syslog(s.LOG_DEBUG, "dhcp_backend : Request") discover = self.Discover(packet) @@ -139,14 +149,14 @@ class DhcpBackend: yiaddr = packet.GetOption("yiaddr") if not discover: - Log.Output(Log.info,"Unknown MAC address: "+str(chaddr)) + s.syslog(s.LOG_INFO,"Unknown MAC address: "+str(chaddr)) return False if yiaddr!="0.0.0.0" and yiaddr == request : - Log.Output(Log.info,"Ack ip "+str(yiaddr)+" for "+str(chaddr)) + s.syslog(s.LOG_INFO,"Ack ip "+str(yiaddr)+" for "+str(chaddr)) return True else: - Log.Output(Log.info,"Requested ip "+str(request)+" not available for "+str(chaddr)) + s.syslog(s.LOG_INFO,"Requested ip "+str(request)+" not available for "+str(chaddr)) return False def Decline(self, packet): @@ -159,10 +169,10 @@ class DhcpServer(pydhcplib.dhcp_network.DhcpServer): def __init__(self, backend, options = {'client_listenport':68,'server_listenport':67}): pydhcplib.dhcp_network.DhcpServer.__init__(self,"0.0.0.0",options["client_listen_port"],options["server_listen_port"],) self.backend = backend - Log.Output(Log.debug, "__init__ DhcpServer") + s.syslog(s.LOG_DEBUG, "__init__ DhcpServer") def SendDhcpPacketTo(self, To, packet): - (ip, intf) = self.backend.find_interface(packet) + intf = self.backend.find_interface(packet) if intf: out_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) out_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST,1) @@ -184,12 +194,12 @@ class DhcpServer(pydhcplib.dhcp_network.DhcpServer): if giaddr!=[0,0,0,0] : agent_ip = ".".join(map(str,giaddr)) self.SendDhcpPacketTo(agent_ip,packet) - Log.Output(Log.debug, "SendPacket to agent : "+agent_ip) + s.syslog(s.LOG_DEBUG, "SendPacket to agent : "+agent_ip) # FIXME: This shouldn't broadcast if it has an IP address to send # it to instead. See RFC2131 part 4.1 for full details else : - Log.Output(Log.debug, "No agent, broadcast packet.") + s.syslog(s.LOG_DEBUG, "No agent, broadcast packet.") self.SendDhcpPacketTo("255.255.255.255",packet) @@ -199,7 +209,7 @@ class DhcpServer(pydhcplib.dhcp_network.DhcpServer): logmsg = "Get DHCPDISCOVER packet from " + hwmac(packet.GetHardwareAddress()).str() - Log.Output(Log.info, logmsg) + s.syslog(s.LOG_INFO, logmsg) offer = DhcpPacket() offer.CreateDhcpOfferPacketFrom(packet) @@ -219,15 +229,15 @@ class DhcpServer(pydhcplib.dhcp_network.DhcpServer): #packet.PrintOptions() if sid != [0,0,0,0] and ciaddr == [0,0,0,0] : - Log.Output(Log.info, "Get DHCPREQUEST_SELECTING_STATE packet") + s.syslog(s.LOG_INFO, "Get DHCPREQUEST_SELECTING_STATE packet") elif sid == [0,0,0,0] and ciaddr == [0,0,0,0] and ip : - Log.Output(Log.info, "Get DHCPREQUEST_INITREBOOT_STATE packet") + s.syslog(s.LOG_INFO, "Get DHCPREQUEST_INITREBOOT_STATE packet") elif sid == [0,0,0,0] and ciaddr != [0,0,0,0] and not ip : - Log.Output(Log.info,"Get DHCPREQUEST_INITREBOOT_STATE packet") + s.syslog(s.LOG_INFO,"Get DHCPREQUEST_INITREBOOT_STATE packet") - else : Log.Output(Log.info,"Get DHCPREQUEST_UNKNOWN_STATE packet : not implemented") + else : s.syslog(s.LOG_INFO,"Get DHCPREQUEST_UNKNOWN_STATE packet : not implemented") if self.backend.Request(packet) : packet.TransformToDhcpAckPacket() else : packet.TransformToDhcpNackPacket() @@ -238,15 +248,15 @@ class DhcpServer(pydhcplib.dhcp_network.DhcpServer): # FIXME: These are not yet implemented. def HandleDhcpDecline(self, packet): - Log.Output(Log.info, "Get DHCPDECLINE packet") + s.syslog(s.LOG_INFO, "Get DHCPDECLINE packet") self.backend.Decline(packet) def HandleDhcpRelease(self, packet): - Log.Output(Log.info,"Get DHCPRELEASE packet") + s.syslog(s.LOG_INFO,"Get DHCPRELEASE packet") self.backend.Release(packet) def HandleDhcpInform(self, packet): - Log.Output(Log.info, "Get DHCPINFORM packet") + s.syslog(s.LOG_INFO, "Get DHCPINFORM packet") if self.backend.Request(packet) : packet.TransformToDhcpAckPacket() @@ -259,7 +269,7 @@ if '__main__' == __name__: options = { "server_listen_port":67, "client_listen_port":68, "listen_address":"0.0.0.0"} - backend = DhcpBackend('postgres://sipb-xen@sipb-xen-dev/sipb_xen') + backend = DhcpBackend() server = DhcpServer(backend, options) while True : server.GetNextDhcpPacket()