def host_discovery_packet_in_handler(self, ev): msg = ev.msg eth, pkt_type, pkt_data = ethernet.ethernet.parser(msg.data) # ignore lldp and cfm packets if eth.ethertype in (ETH_TYPE_LLDP, ETH_TYPE_CFM): return datapath = msg.datapath dpid = datapath.id port_no = -1 if msg.datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: port_no = msg.in_port else: port_no = msg.match['in_port'] port = self._get_port(dpid, port_no) # can't find this port(ex: logic port) if not port: return # ignore switch-to-switch port if not self._is_edge_port(port): return host_mac = eth.src host = Host(host_mac, port) if host_mac not in self.hosts: self.hosts.add(host) ev = event.EventHostAdd(host) self.send_event_to_observers(ev) elif self.hosts[host_mac].port != port: # assumes the host is moved to another port ev = event.EventHostMove(src=self.hosts[host_mac], dst=host) self.hosts[host_mac] = host self.send_event_to_observers(ev) # arp packet, update ip address if eth.ethertype == ether_types.ETH_TYPE_ARP: arp_pkt, _, _ = pkt_type.parser(pkt_data) self.hosts.update_ip(host, ip_v4=arp_pkt.src_ip) # ipv4 packet, update ipv4 address elif eth.ethertype == ether_types.ETH_TYPE_IP: ipv4_pkt, _, _ = pkt_type.parser(pkt_data) self.hosts.update_ip(host, ip_v4=ipv4_pkt.src) # ipv6 packet, update ipv6 address elif eth.ethertype == ether_types.ETH_TYPE_IPV6: # TODO: need to handle NDP ipv6_pkt, _, _ = pkt_type.parser(pkt_data) self.hosts.update_ip(host, ip_v6=ipv6_pkt.src)
def host_discovery_packet_in_handler(self, ev): msg = ev.msg pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] # ignore lldp packet if eth.ethertype == ETH_TYPE_LLDP: return datapath = msg.datapath dpid = datapath.id port_no = -1 if msg.datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: port_no = msg.in_port else: port_no = msg.match['in_port'] port = self._get_port(dpid, port_no) # can't find this port(ex: logic port) if not port: return # ignore switch-to-switch port if not self._is_edge_port(port): return host_mac = eth.src host = Host(host_mac, port) if host_mac not in self.hosts: self.hosts.add(host) ev = event.EventHostAdd(host) self.send_event_to_observers(ev) # arp packet, update ip address if eth.ethertype == ether_types.ETH_TYPE_ARP: arp_pkt = pkt.get_protocols(arp.arp)[0] self.hosts.update_ip(host, ip_v4=arp_pkt.src_ip) # ipv4 packet, update ipv4 address elif eth.ethertype == ether_types.ETH_TYPE_IP: ipv4_pkt = pkt.get_protocols(ipv4.ipv4)[0] self.hosts.update_ip(host, ip_v4=ipv4_pkt.src) # ipv6 packet, update ipv6 address elif eth.ethertype == ether_types.ETH_TYPE_IPV6: # TODO: need to handle NDP ipv6_pkt = pkt.get_protocols(ipv6.ipv6)[0] self.hosts.update_ip(host, ip_v6=ipv6_pkt.src)
def assemble_offer(self, port, pkt): #self.semaphore.acquire() disc_eth = pkt.get_protocol(ethernet.ethernet) disc_ipv4 = pkt.get_protocol(ipv4.ipv4) disc_udp = pkt.get_protocol(udp.udp) disc = pkt.get_protocol(dhcp.dhcp) try: disc.options.option_list.remove( next(opt for opt in disc.options.option_list if opt.tag == 50)) except: pass disc.options.option_list.remove( next(opt for opt in disc.options.option_list if opt.tag == 55)) disc.options.option_list.remove( next(opt for opt in disc.options.option_list if opt.tag == 53)) disc.options.option_list.remove( next(opt for opt in disc.options.option_list if opt.tag == 12)) disc.options.option_list.insert( 0, dhcp.option(tag=1, value=self.bin_netmask)) disc.options.option_list.insert( 0, dhcp.option(tag=3, value=self.bin_server)) disc.options.option_list.insert(0, dhcp.option(tag=6, value=self.bin_dns)) # disc.options.option_list.insert( # 0, dhcp.option(tag=12, value=self.hostname)) disc.options.option_list.insert( 0, dhcp.option(tag=51, value=struct.pack('!I', self.release_time))) disc.options.option_list.insert( 0, dhcp.option(tag=53, value=struct.pack('!B', 2))) # disc.options.option_list.insert( # 0, dhcp.option(tag=54, value=self.hostname)) disc.options.option_list.insert( 0, dhcp.option(tag=58, value=struct.pack('!I', self.release_time // 2))) disc.options.option_list.insert( 0, dhcp.option(tag=59, value=struct.pack('!I', self.release_time * 7 // 8))) if disc_eth.src not in self.ip_pool: nid = random.choice(self.usable_id) nip = self.ip_addr + str(nid) #print("new host in,mac:" + disc_eth.src + ",ip:" + nip) self.usable_id.remove(nid) self.ip_pool[disc_eth.src] = [nip, time.perf_counter()] else: self.ip_pool[disc_eth.src][1] = time.perf_counter() #print(disc_eth.src, str(self.mac_port[disc_eth.src][1])+":"+str(self.mac_port[disc_eth.src][1])) h = switches.Host( disc_eth.src, str(self.mac_port[disc_eth.src][0]) + ":" + str(self.mac_port[disc_eth.src][1])) h.ipv4.append(self.ip_pool[disc_eth.src][0]) self.send_event_to_observers(event.EventHostAdd(h)) nip = self.ip_pool[disc_eth.src][0] offer_pkt = packet.Packet() offer_pkt.add_protocol( ethernet.ethernet(ethertype=disc_eth.ethertype, dst=disc_eth.src, src=self.hw_addr)) offer_pkt.add_protocol( ipv4.ipv4(dst=disc_ipv4.dst, src=self.dhcp_server, proto=disc_ipv4.proto)) offer_pkt.add_protocol(udp.udp(src_port=67, dst_port=68)) offer_pkt.add_protocol( dhcp.dhcp(op=2, chaddr=disc_eth.src, siaddr=self.dhcp_server, boot_file=disc.boot_file, yiaddr=nip, xid=disc.xid, options=disc.options)) return offer_pkt