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