Java程序辅导

C C++ Java Python Processing编程在线培训 程序编写 软件开发 视频讲解

客服在线QQ:2653320439 微信:ittutor Email:itutor@qq.com
wx: cjtutor
QQ: 2653320439
dhcpserver.py in trunk/packages/sipb-xen-dhcp/code – xvm Please file new bugs on Launchpad: Invirt or XVM (if you're not sure which, just pick one) Search: Login Help/Guide About Trac Preferences Wiki Timeline Roadmap Browse Source View Tickets Search Context Navigation ← Previous Revision Latest Revision Next Revision → Blame Revision Log source: trunk/packages/sipb-xen-dhcp/code/dhcpserver.py @ 302 View diff against: View revision: Visit: trunkbranches/wsgi Last change on this file since 302 was 300, checked in by ecprice, 15 years ago Clear the sql cache for dns and dhcp, fixing #42. Property svn:executable set to * File size: 9.6 KB Line   1 #!/usr/bin/python 2 import sys 3 sys.path.append('pydhcplib/') 4 import 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 9 from pydhcplib.type_strlist import strlist 10 import socket 11 import IN 12 13 import event_logger 14 if '__main__' == __name__: 15     event_logger.init("stdout", 'DEBUG', {}) 16 from event_logger import Log 17 18 import psycopg2 19 import time 20 import sipb_xen_database 21 from sqlalchemy import create_engine 22 23 dhcp_options = {'subnet_mask': '255.255.0.0', 24                 'router': '18.181.0.1', 25                 'domain_name_server': '18.70.0.160,18.71.0.151,18.72.0.3', 26                 'domain_name': 'mit.edu', 27                 'ip_address_lease_time': 60*60*24} 28 29 class DhcpBackend: 30     def __init__(self, database=None): 31         if database is not None: 32             self.database = database 33             sipb_xen_database.connect(create_engine(database)) 34     def findNIC(self, mac): 35         sipb_xen_database.clear_cache() 36         for i in range(3): 37             try: 38                 value = sipb_xen_database.NIC.get_by(mac_addr=mac) 39             except psycopg2.OperationalError: 40                 time.sleep(0.5) 41                 if i == 2:  #Try twice to reconnect. 42                     raise 43                 #Sigh.  SQLAlchemy should do this itself. 44                 sipb_xen_database.connect(create_engine(self.database)) 45             else: 46                 break 47         return value 48     def find_interface(self, packet): 49         chaddr = hwmac(packet.GetHardwareAddress()) 50         nic = self.findNIC(str(chaddr)) 51         if nic is None or nic.ip is None: 52             return ("18.181.0.60", None) 53         ipstr = ''.join(reversed(['%02X' % i for i in ipv4(nic.ip).list()])) 54         for line in open('/proc/net/route'): 55             parts = line.split() 56             if parts[1] == ipstr: 57                 Log.Output(Log.debug, "find_interface found "+str(nic.ip)+" on "+parts[0]) 58                 return ("18.181.0.60", parts[0]) 59         return ("18.181.0.60", None) 60                             61     def getParameters(self, **extra): 62         all_options=dict(dhcp_options) 63         all_options.update(extra) 64         options = {} 65         for parameter, value in all_options.iteritems(): 66             if value is None: 67                 continue 68             option_type = DhcpOptionsTypes[DhcpOptions[parameter]] 69 70             if option_type == "ipv4" : 71                 # this is a single ip address 72                 options[parameter] = map(int,value.split(".")) 73             elif option_type == "ipv4+" : 74                 # this is multiple ip address 75                 iplist = value.split(",") 76                 opt = [] 77                 for single in iplist : 78                     opt.extend(ipv4(single).list()) 79                 options[parameter] = opt 80             elif option_type == "32-bits" : 81                 # This is probably a number... 82                 digit = int(value) 83                 options[parameter] = [digit>>24&0xFF,(digit>>16)&0xFF,(digit>>8)&0xFF,digit&0xFF] 84             elif option_type == "16-bits" : 85                 digit = int(value) 86                 options[parameter] = [(digit>>8)&0xFF,digit&0xFF] 87 88             elif option_type == "char" : 89                 digit = int(value) 90                 options[parameter] = [digit&0xFF] 91 92             elif option_type == "bool" : 93                 if value=="False" or value=="false" or value==0 : 94                     options[parameter] = [0] 95                 else : options[parameter] = [1] 96                     97             elif option_type == "string" : 98                 options[parameter] = strlist(value).list() 99                 100             else : 101                 options[parameter] = strlist(value).list() 102         return options 103 104     def Discover(self, packet): 105         Log.Output(Log.debug,"dhcp_backend : Discover ") 106         chaddr = hwmac(packet.GetHardwareAddress()) 107         nic = self.findNIC(str(chaddr)) 108         if nic is None or nic.machine is None: 109             return False 110         ip = nic.ip 111         if ip is None:  #Deactivated? 112             return False 113         if nic.hostname and '.' in nic.hostname: 114             hostname = nic.hostname 115         elif nic.machine.name: 116             hostname = nic.machine.name + '.servers.csail.mit.edu' 117         else: 118             hostname = None 119         if ip is not None: 120             ip = ipv4(ip) 121             Log.Output(Log.debug,"dhcp_backend : Discover result = "+str(ip)) 122             packet_parameters = self.getParameters(host_name=hostname) 123 124             # FIXME: Other offer parameters go here 125             packet_parameters["yiaddr"] = ip.list() 126             127             packet.SetMultipleOptions(packet_parameters) 128             return True 129         return False 130         131     def Request(self, packet): 132         Log.Output(Log.debug, "dhcp_backend : Request") 133         134         discover = self.Discover(packet) 135         136         chaddr = hwmac(packet.GetHardwareAddress()) 137         request = packet.GetOption("request_ip_address") 138         if not request: 139             request = packet.GetOption("ciaddr") 140         yiaddr = packet.GetOption("yiaddr") 141 142         if not discover: 143             Log.Output(Log.info,"Unknown MAC address: "+str(chaddr)) 144             return False 145         146         if yiaddr!="0.0.0.0" and yiaddr == request : 147             Log.Output(Log.info,"Ack ip "+str(yiaddr)+" for "+str(chaddr)) 148             return True 149         else: 150             Log.Output(Log.info,"Requested ip "+str(request)+" not available for "+str(chaddr)) 151         return False 152 153     def Decline(self, packet): 154         pass 155     def Release(self, packet): 156         pass 157     158 159 class DhcpServer(pydhcplib.dhcp_network.DhcpServer): 160     def __init__(self, backend, options = {'client_listenport':68,'server_listenport':67}): 161         pydhcplib.dhcp_network.DhcpServer.__init__(self,"0.0.0.0",options["client_listen_port"],options["server_listen_port"],) 162         self.backend = backend 163         Log.Output(Log.debug, "__init__ DhcpServer") 164 165     def SendDhcpPacketTo(self, To, packet): 166         (ip, intf) = self.backend.find_interface(packet) 167         if intf: 168             out_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 169             out_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST,1) 170             out_socket.setsockopt(socket.SOL_SOCKET, IN.SO_BINDTODEVICE, intf) 171             #out_socket.bind((ip, self.listen_port)) 172             ret = out_socket.sendto(packet.EncodePacket(), (To,self.emit_port)) 173             out_socket.close() 174             return ret 175         else: 176             return self.dhcp_socket.sendto(packet.EncodePacket(),(To,self.emit_port)) 177 178     def SendPacket(self, packet): 179         """Encode and send the packet.""" 180         181         giaddr = packet.GetOption('giaddr') 182 183         # in all case, if giaddr is set, send packet to relay_agent 184         # network address defines by giaddr 185         if giaddr!=[0,0,0,0] : 186             agent_ip = ".".join(map(str,giaddr)) 187             self.SendDhcpPacketTo(agent_ip,packet) 188             Log.Output(Log.debug, "SendPacket to agent : "+agent_ip) 189 190         # FIXME: This shouldn't broadcast if it has an IP address to send 191         # it to instead. See RFC2131 part 4.1 for full details 192         else : 193             Log.Output(Log.debug, "No agent, broadcast packet.") 194             self.SendDhcpPacketTo("255.255.255.255",packet) 195             196 197     def HandleDhcpDiscover(self, packet): 198         """Build and send DHCPOFFER packet in response to DHCPDISCOVER 199         packet.""" 200 201         logmsg = "Get DHCPDISCOVER packet from " + hwmac(packet.GetHardwareAddress()).str() 202 203         Log.Output(Log.info, logmsg) 204         offer = DhcpPacket() 205         offer.CreateDhcpOfferPacketFrom(packet) 206         207         if self.backend.Discover(offer): 208             self.SendPacket(offer) 209         # FIXME : what if false ? 210 211 212     def HandleDhcpRequest(self, packet): 213         """Build and send DHCPACK or DHCPNACK packet in response to 214         DHCPREQUEST packet. 4 types of DHCPREQUEST exists.""" 215 216         ip = packet.GetOption("request_ip_address") 217         sid = packet.GetOption("server_identifier") 218         ciaddr = packet.GetOption("ciaddr") 219         #packet.PrintHeaders() 220         #packet.PrintOptions() 221 222         if sid != [0,0,0,0] and ciaddr == [0,0,0,0] : 223             Log.Output(Log.info, "Get DHCPREQUEST_SELECTING_STATE packet") 224 225         elif sid == [0,0,0,0] and ciaddr == [0,0,0,0] and ip : 226             Log.Output(Log.info, "Get DHCPREQUEST_INITREBOOT_STATE packet") 227 228         elif sid == [0,0,0,0] and ciaddr != [0,0,0,0] and not ip : 229             Log.Output(Log.info,"Get DHCPREQUEST_INITREBOOT_STATE packet") 230 231         else : Log.Output(Log.info,"Get DHCPREQUEST_UNKNOWN_STATE packet : not implemented") 232 233         if self.backend.Request(packet) : packet.TransformToDhcpAckPacket() 234         else : packet.TransformToDhcpNackPacket() 235 236         self.SendPacket(packet) 237 238 239 240     # FIXME: These are not yet implemented. 241     def HandleDhcpDecline(self, packet): 242         Log.Output(Log.info, "Get DHCPDECLINE packet") 243         self.backend.Decline(packet) 244         245     def HandleDhcpRelease(self, packet): 246         Log.Output(Log.info,"Get DHCPRELEASE packet") 247         self.backend.Release(packet) 248         249     def HandleDhcpInform(self, packet): 250         Log.Output(Log.info, "Get DHCPINFORM packet") 251 252         if self.backend.Request(packet) : 253             packet.TransformToDhcpAckPacket() 254             # FIXME : Remove lease_time from options 255             self.SendPacket(packet) 256 257         # FIXME : what if false ? 258 259 if '__main__' == __name__: 260     options = { "server_listen_port":67, 261                 "client_listen_port":68, 262                 "listen_address":"0.0.0.0"} 263     backend = DhcpBackend('postgres://sipb-xen@sipb-xen-dev/sipb_xen') 264     server = DhcpServer(backend, options) 265 266     while True : server.GetNextDhcpPacket() Note: See TracBrowser for help on using the repository browser. Download in other formats: Plain Text Original Format Powered by Trac 1.0.2 By Edgewall Software. Visit the Trac open source project at http://trac.edgewall.org/