3 sys.path.append('pydhcplib/')
5 import pydhcplib.dhcp_network
6 from pydhcplib.dhcp_packet import *
7 from pydhcplib.type_hw_addr import hwmac
8 from pydhcplib.type_ipv4 import ipv4
11 if '__main__' == __name__:
12 event_logger.init("stdout", 'INFO', {})
13 from event_logger import Log
15 import sipb_xen_database
18 def __init__(self, database=None):
19 if database is not None:
20 sipb_xen_database.connect(database)
21 def findIP(self, mac):
22 value = sipb_xen_database.NIC.get_by(mac_addr=mac)
26 if ip is None: #Deactivated?
30 def Discover(self, packet):
31 Log.Output(Log.debug,"dhcp_backend : Discover ")
32 chaddr = hwmac(packet.GetHardwareAddress())
33 ip = self.findIP(str(chaddr))
36 Log.Output(Log.debug,"dhcp_backend : Discover result = "+str(ip))
37 packet_parameters = {}
39 # FIXME: Other offer parameters go here
40 packet_parameters["yiaddr"] = ip.list()
42 packet.SetMultipleOptions(packet_parameters)
46 def Request(self, packet):
47 Log.Output(Log.debug, "dhcp_backend : Request")
49 discover = self.Discover(packet)
51 chaddr = hwmac(packet.GetHardwareAddress())
52 request = packet.GetOption("request_ip_address")
53 yiaddr = packet.GetOption("yiaddr")
56 Log.Output(Log.info,"Unknown MAC address: "+str(chaddr))
59 if yiaddr!="0.0.0.0" and yiaddr == request :
60 Log.Output(Log.info,"Ack ip "+str(yiaddr)+" for "+str(chaddr))
63 Log.Output(Log.info,"Requested ip "+str(request)+" not available for "+str(chaddr))
66 def Decline(self, packet):
68 def Release(self, packet):
72 class DhcpServer(pydhcplib.dhcp_network.DhcpServer):
73 def __init__(self, backend, options = {'client_listenport':68,'server_listenport':67}):
74 pydhcplib.dhcp_network.DhcpServer.__init__(self,"0.0.0.0",options["client_listen_port"],options["server_listen_port"],)
75 self.backend = backend
76 Log.Output(Log.debug, "__init__ DhcpServer")
78 def SendPacket(self, packet):
79 """Encode and send the packet."""
81 giaddr = packet.GetOption('giaddr')
83 # in all case, if giaddr is set, send packet to relay_agent
84 # network address defines by giaddr
85 if giaddr!=[0,0,0,0] :
86 agent_ip = ".".join(map(str,giaddr))
87 self.SendDhcpPacketTo(agent_ip,packet)
88 Log.Output(Log.debug, "SendPacket to agent : "+agent_ip)
90 # FIXME: This shouldn't broadcast if it has an IP address to send
91 # it to instead. See RFC2131 part 4.1 for full details
93 Log.Output(Log.debug, "No agent, broadcast packet.")
94 self.SendDhcpPacketTo("255.255.255.255",packet)
97 def HandleDhcpDiscover(self, packet):
98 """Build and send DHCPOFFER packet in response to DHCPDISCOVER
101 logmsg = "Get DHCPDISCOVER packet from " + hwmac(packet.GetHardwareAddress()).str()
103 Log.Output(Log.info, logmsg)
105 offer.CreateDhcpOfferPacketFrom(packet)
107 if self.backend.Discover(offer) :
108 self.SendPacket(offer)
109 # FIXME : what if false ?
112 def HandleDhcpRequest(self, packet):
113 """Build and send DHCPACK or DHCPNACK packet in response to
114 DHCPREQUEST packet. 4 types of DHCPREQUEST exists."""
116 ip = packet.GetOption("request_ip_address")
117 sid = packet.GetOption("server_identifier")
118 ciaddr = packet.GetOption("ciaddr")
120 if sid != [0,0,0,0] and ciaddr == [0,0,0,0] :
121 Log.Output(Log.info, "Get DHCPREQUEST_SELECTING_STATE packet")
123 elif sid == [0,0,0,0] and ciaddr == [0,0,0,0] and ip :
124 Log.Output(Log.info, "Get DHCPREQUEST_INITREBOOT_STATE packet")
126 elif sid == [0,0,0,0] and ciaddr != [0,0,0,0] and not ip :
127 Log.Output(Log.info,"Get DHCPREQUEST_INITREBOOT_STATE packet")
129 else : Log.Output(Log.info,"Get DHCPREQUEST_UNKNOWN_STATE packet : not implemented")
131 if self.backend.Request(packet) : packet.TransformToDhcpAckPacket()
132 else : packet.TransformToDhcpNackPacket()
134 self.SendPacket(packet)
138 # FIXME: These are not yet implemented.
139 def HandleDhcpDecline(self, packet):
140 Log.Output(Log.info, "Get DHCPDECLINE packet")
141 self.backend.Decline(packet)
143 def HandleDhcpRelease(self, packet):
144 Log.Output(Log.info,"Get DHCPRELEASE packet")
145 self.backend.Release(packet)
147 def HandleDhcpInform(self, packet):
148 Log.Output(Log.info, "Get DHCPINFORM packet")
150 if self.backend.Request(packet) :
151 packet.TransformToDhcpAckPacket()
152 # FIXME : Remove lease_time from options
153 self.SendPacket(packet)
155 # FIXME : what if false ?
157 if '__main__' == __name__:
158 options = { "server_listen_port":67,
159 "client_listen_port":68,
160 "listen_address":"0.0.0.0"}
161 backend = DhcpBackend('postgres://sipb-xen@sipb-xen-dev/sipb_xen')
162 server = DhcpServer(backend, options)
164 while True : server.GetNextDhcpPacket()