3 from pydhcplib.dhcp_packet import *
4 from pydhcplib.type_hw_addr import hwmac
5 from pydhcplib.type_ipv4 import ipv4
7 from event_logger import Log
9 import sipb_xen_database
12 def __init__(self, database=None):
13 if database is not None:
14 sipb_xen_database.connect(database)
15 def findIP(self, mac):
16 value = sipb_xen_database.NIC.get_by(mac_addr=mac)
20 if ip is None: #Deactivated?
24 def Discover(self, packet):
25 Log.Output(Log.debug,"dhcp_backend : Discover ")
26 chaddr = hwmac(packet.GetHardwareAddress())
27 ip = self.findIP(str(chaddr))
30 Log.Output(Log.debug,"dhcp_backend : Discover result = "+str(ip))
31 packet_parameters = {}
33 # FIXME: Other offer parameters go here
34 packet_parameters["yiaddr"] = ip.list()
36 packet.SetMultipleOptions(packet_parameters)
40 def Request(self, packet):
41 Log.Output(Log.debug, "dhcp_backend : Request")
43 discover = self.Discover(packet)
45 chaddr = hwmac(packet.GetHardwareAddress())
46 request = packet.GetOption("request_ip_address")
47 yiaddr = packet.GetOption("yiaddr")
50 Log.Output(Log.info,"Unknown MAC address: "+str(chaddr))
53 if yiaddr!="0.0.0.0" and yiaddr == request :
54 Log.Output(Log.info,"Ack ip "+str(yiaddr)+" for "+str(chaddr))
57 Log.Output(Log.info,"Requested ip "+str(request)+" not available for "+str(chaddr))
60 def Decline(self, packet):
62 def Release(self, packet):
66 class DhcpServer(pydhcplib.dhcp_network.DhcpServer):
67 def __init__(self, backend, options = {'client_listenport':68,'server_listenport':67}):
68 pydhcplib.dhcp_network.DhcpServer.__init__(self,"0.0.0.0",options["client_listen_port"],options["server_listen_port"],)
69 self.backend = backend
70 Log.Output(Log.debug, "__init__ DhcpServer")
72 def SendPacket(self, packet):
73 """Encode and send the packet."""
75 giaddr = packet.GetOption('giaddr')
77 # in all case, if giaddr is set, send packet to relay_agent
78 # network address defines by giaddr
79 if giaddr!=[0,0,0,0] :
80 agent_ip = ".".join(map(str,giaddr))
81 self.SendDhcpPacketTo(agent_ip,packet)
82 Log.Output(Log.debug, "SendPacket to agent : "+agent_ip)
84 # FIXME: This shouldn't broadcast if it has an IP address to send
85 # it to instead. See RFC2131 part 4.1 for full details
87 Log.Output(Log.debug, "No agent, broadcast packet.")
88 self.SendDhcpPacketTo("255.255.255.255",packet)
91 def HandleDhcpDiscover(self, packet):
92 """Build and send DHCPOFFER packet in response to DHCPDISCOVER
95 logmsg = "Get DHCPDISCOVER packet from " + hwmac(packet.GetHardwareAddress()).str()
97 Log.Output(Log.info, logmsg)
99 offer.CreateDhcpOfferPacketFrom(packet)
101 if self.backend.Discover(offer) :
102 self.SendPacket(offer)
103 # FIXME : what if false ?
106 def HandleDhcpRequest(self, packet):
107 """Build and send DHCPACK or DHCPNACK packet in response to
108 DHCPREQUEST packet. 4 types of DHCPREQUEST exists."""
110 ip = packet.GetOption("request_ip_address")
111 sid = packet.GetOption("server_identifier")
112 ciaddr = packet.GetOption("ciaddr")
114 if sid != [0,0,0,0] and ciaddr == [0,0,0,0] :
115 Log.Output(Log.info, "Get DHCPREQUEST_SELECTING_STATE packet")
117 elif sid == [0,0,0,0] and ciaddr == [0,0,0,0] and ip :
118 Log.Output(Log.info, "Get DHCPREQUEST_INITREBOOT_STATE packet")
120 elif sid == [0,0,0,0] and ciaddr != [0,0,0,0] and not ip :
121 Log.Output(Log.info,"Get DHCPREQUEST_INITREBOOT_STATE packet")
123 else : Log.Output(Log.info,"Get DHCPREQUEST_UNKNOWN_STATE packet : not implemented")
125 if self.backend.Request(packet) : packet.TransformToDhcpAckPacket()
126 else : packet.TransformToDhcpNackPacket()
128 self.SendPacket(packet)
132 # FIXME: These are not yet implemented.
133 def HandleDhcpDecline(self, packet):
134 Log.Output(Log.info, "Get DHCPDECLINE packet")
135 self.backend.Decline(packet)
137 def HandleDhcpRelease(self, packet):
138 Log.Output(Log.info,"Get DHCPRELEASE packet")
139 self.backend.Release(packet)
141 def HandleDhcpInform(self, packet):
142 Log.Output(Log.info, "Get DHCPINFORM packet")
144 if self.backend.Request(packet) :
145 packet.TransformToDhcpAckPacket()
146 # FIXME : Remove lease_time from options
147 self.SendPacket(packet)
149 # FIXME : what if false ?
151 if '__main__' == __name__:
152 event_logger.init("stdout", event_logger.INFO, {})
153 options = { "server_listen_port":67,
154 "client_listen_port":68,
155 "listen_address":"0.0.0.0"}
156 backend = DhcpBackend('postgres://sipb-xen@sipb-xen-dev/sipb_xen')
157 server = DhcpServer(backend, options)
159 while True : server.GetNextDhcpPacket()