def build_nx_match(self,switch,inport,pred,table_id): ### BUILD NX MATCH match = nx.nx_match() if inport: if table_id == 0: match.of_in_port = inport else: """NXM_NX_REG2 is the per-packet metadata register where we store the current port value of the packet, including actions from previous tables' forwarding actions. """ match.reg2 = inport if 'srcmac' in pred: match.of_eth_src = packetaddr.EthAddr(pred['srcmac']) if 'dstmac' in pred: match.of_eth_dst = packetaddr.EthAddr(pred['dstmac']) if 'vlan_id' in pred: assert 'vlan_pcp' in pred # Setting the 16-bit TCI: (from highest to least significant bits): # 3 bits vlan_pcp # 1 bit CFI forced to 1 # 12 bits vlan_id # Ref: manpages.ubuntu.com/manpages/trusty/man8/ovs-ofctl.8.html vlan_16bit = ((int(pred['vlan_pcp']) << 13) | 0x1000 | (int(pred['vlan_id']))) match.of_vlan_tci = vlan_16bit if 'ethtype' in pred: match.of_eth_type = pred['ethtype'] if 'srcip' in pred: assert 'ethtype' in pred if pred['ethtype'] == IP_TYPE: match.of_ip_src = packetaddr.IPAddr(pred['srcip']) elif pred['ethtype'] == ARP_TYPE: match.arp_spa = packetaddr.IPAddr(pred['srcip']) else: raise RuntimeError("Unknown ethtype for srcip match!") if 'dstip' in pred: assert 'ethtype' in pred if pred['ethtype'] == IP_TYPE: match.of_ip_dst = packetaddr.IPAddr(pred['dstip']) elif pred['ethtype'] == ARP_TYPE: match.arp_tpa = packetaddr.IPAddr(pred['dstip']) else: raise RuntimeError("Unknown ethtype for dstip match!") if 'tos' in pred: match.of_ip_tos = pred['tos'] if 'protocol' in pred: match.of_ip_proto = pred['protocol'] if 'srcport' in pred: assert 'protocol' in pred match.append(nx.NXM_OF_TCP_SRC(pred['srcport'])) if 'dstport' in pred: assert 'protocol' in pred match.append(nx.NXM_OF_TCP_DST(pred['dstport'])) return match
def ARP_Request_handler(self, packet, packet_in): ARP_Dst = self.route_table.get(str(packet.payload.protodst)) if ARP_Dst[2] == 'H': packet.dst = adr.EthAddr(ARP_Dst[0]) self.send_Packet(frame=packet, out_port=ARP_Dst[3]) #host -> router elif ARP_Dst[2] == 'R': if str(packet.payload.protodst) == '10.0.1.1': arp_reply = pkt.arp() arp_reply.hwsrc = adr.EthAddr('00:00:00:00:11:05') arp_reply.hwdst = packet.payload.hwsrc arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = packet.payload.protodst arp_reply.protodst = packet.payload.protosrc #make ARP packet -> Frame ether = pkt.ethernet() ether.type = pkt.ethernet.ARP_TYPE ether.dst = packet.src ether.src = packet.dst ether.payload = arp_reply #send Frame self.send_Packet(frame=ether, out_port=packet_in.in_port) elif str(packet.payload.protodst) == '10.0.2.1': arp_reply = pkt.arp() arp_reply.hwsrc = adr.EthAddr('00:00:00:00:11:06') arp_reply.hwdst = packet.payload.hwsrc arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = packet.payload.protodst arp_reply.protodst = packet.payload.protosrc #make ARP packet -> Frame ether = pkt.ethernet() ether.type = pkt.ethernet.ARP_TYPE ether.dst = packet.src ether.src = packet.dst ether.payload = arp_reply #send Frame self.send_Packet(frame=ether, out_port=packet_in.in_port) elif str(packet.payload.protodst) == '10.0.3.1': arp_reply = pkt.arp() arp_reply.hwsrc = adr.EthAddr('00:00:00:00:11:07') arp_reply.hwdst = packet.payload.hwsrc arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = packet.payload.protodst arp_reply.protodst = packet.payload.protosrc #make ARP packet -> Frame ether = pkt.ethernet() ether.type = pkt.ethernet.ARP_TYPE ether.dst = packet.src ether.src = packet.dst ether.payload = arp_reply #send Frame self.send_Packet(frame=ether, out_port=packet_in.in_port)
def arp_send1(self, packet, packet_in): arpPacketProtocol = packet.payload if arpPacketProtocol.opcode == pkt.arp.REPLY: log.debug("ARP reply reveived") self.mac_to_port1[packet.src] = packet_in.in_port log.debug("Display the mac_to_port dictionary)(REPLY)") #log.debug(self.mac_to_port) self.act_like_switch1(packet, packet_in) elif arpPacketProtocol.opcode == pkt.arp.REQUEST: if str(arpPacketProtocol.protodst) == "10.0.1.1": # ARP reply arpResponse = pkt.arp() arpResponse.hwsrc = adr.EthAddr("10:10:10:10:10:10") arpResponse.hwdst = arpPacketProtocol.hwsrc arpResponse.opcode = pkt.arp.REPLY arpResponse.protosrc = arpPacketProtocol.protodst arpResponse.protodst = arpPacketProtocol.protosrc #add header to the arp packet, usign the ethernet frame arpFrame = pkt.ethernet() arpFrame.type = pkt.ethernet.ARP_TYPE arpFrame.dst = packet.src arpFrame.src = adr.EthAddr("10:10:10:10:10:10") arpFrame.payload = arpResponse #send the packet msg = of.ofp_packet_out() msg.data = arpFrame.pack() action = of.ofp_action_output(port=packet_in.in_port) msg.actions.append(action) self.connection.send(msg) #add the mac address to the port table## self.mac_to_port1[packet.src] = packet_in.in_port log.debug("Display the mac_to_port dictionary(REQUEST)") log.debug(self.mac_to_port1) else: find_ip = 0 for ip in self.network1.keys(): if ip == str(arpPacketProtocol.protodst): find_ip = ip if find_ip == 0: log.debug( "ARP: The dst ip is not in the network, we can't find it's mac address" ) else: self.act_like_switch1(packet, packet_in) else: pass
def _handle_arp(event): eth_pkt = event.parsed arp_pkt = event.parsed.payload org_mac = eth_pkt.src.toStr() pmac_src = adrs.EthAddr(actual_pmac[org_mac]) #gratituos arp is when the src and dst ip in arp are same. check it and update tables in case of new host. or else return if arp_pkt.opcode == arp_pkt.REQUEST: dst_ip = arp_pkt.protodst.toStr() #print 'ARP request : ip:{0}'.format(dst_ip) if dst_ip in arp_table: #we know the mapping. respond back to inp port OFPP_IN_PORT. arp_reply = pkt.arp() arp_reply.hwsrc = adrs.EthAddr(arp_table[dst_ip]) arp_reply.hwdst = eth_pkt.src arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = arp_pkt.protodst arp_reply.protodst = arp_pkt.protosrc ether = pkt.ethernet() ether.type = pkt.ethernet.ARP_TYPE ether.dst = eth_pkt.src ether.src = arp_reply.hwsrc ether.payload = arp_reply msg = of.ofp_packet_out() #msg.in_port = event.port #msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.actions.append(of.ofp_action_output(port = event.port)) msg.data = ether.pack() event.connection.send(msg) else: #bcast with src changed to sources pmac. also if its this switch, put inport as the it came from, so that it wont go to it #print 'Broadcasting since we dont have ARP mapping' arp_pkt.hwsrc = pmac_src eth_pkt.src = pmac_src #edge bcast: msg = of.ofp_packet_out() for i in range(half_num_pods + 1, num_pods + 1):#pkt out to host ports msg.actions.append(of.ofp_action_output(port = i)) msg.data = eth_pkt.pack() other_switches = edge_switches - set([event.dpid]) for es in other_switches: core.openflow.connections[es].send(msg) msg.actions.pop(event.port - half_num_pods - 1) event.connection.send(msg) elif arp_pkt.opcode == arp_pkt.REPLY: #print 'ARP reply : src ip:{0}, dst ip:{1}'.format(arp_pkt.protosrc.toStr(), arp_pkt.protodst.toStr()) arp_pkt.hwdst = adrs.EthAddr(pmac_actual[arp_pkt.hwdst.toStr()]) arp_pkt.hwsrc = pmac_src eth_pkt.src = pmac_src msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_TABLE)) msg.data = eth_pkt.pack() core.openflow.connections[cs[0]].send(msg)
def ICMP_Reply_handler(self, packet, packet_in): #log.debug("----------ICMP reply----------") ip_packet = packet.payload ipDstAdd = self.route_table.get(str(ip_packet.dstip)) if ipDstAdd != None: packet.src = packet.dst packet.dst = adr.EthAddr(ipDstAdd[0]) self.send_Packet(frame=packet, out_port=ipDstAdd[1])
def packet_forward(self, event): ''' Manually mangle a packet and forward it to its destination. Kick off an ARP request and enqueue the packet if the destination HW address is not known yet. Returns true if the packet will be output on this port. ''' eth_fwd = event.parsed ip_fwd = eth_fwd.payload addr_dst = ip_fwd.dstip if not self.match_ip(ip_fwd.dstip): return False if addr_dst in self.neigh_by_ip: # The HW address of the peer is known: # Perform the forwarding eth_fwd.src = self.my_mac eth_fwd.dst = self.neigh_by_ip[addr_dst] self._packet_send(eth_fwd) else: # The HW address of the peer is not known: # Kick of an ARP request and store the packet in # a queue to be processed when the address is known. arp_out = Arp(hwsrc=self.my_mac, hwdst=addresses.EthAddr("ff:ff:ff:ff:ff:ff"), opcode=Arp.REQUEST, protosrc=self.my_ip, protodst=ip_fwd.dstip) eth_out = Ethernet(dst=addresses.EthAddr("ff:ff:ff:ff:ff:ff"), src=self.my_mac, type=Ethernet.ARP_TYPE, next=arp_out) self._packet_send(eth_out) self.packet_queue.append(event) return True
def _handle_new_host(org_mac, ip, dpid, port): con = core.openflow.connections[dpid] pmac = _assign_pmac(dpid, port - 1, org_mac) #i guess nothing more to do here. in multi table, the switch would have sent here and replied to the host. msg = nx.nx_flow_mod(table_id = 0) msg.priority = 5000 msg.match.NXM_OF_IN_PORT = port msg.match.eth_src = org_mac msg.actions.append(of.ofp_action_dl_addr.set_src(adrs.EthAddr(pmac))) msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1)) con.send(msg) msg = nx.nx_flow_mod(table_id = 1) msg.priority = 5000 msg.match.eth_dst = pmac msg.actions.append(of.ofp_action_dl_addr.set_dst(adrs.EthAddr(org_mac))) msg.actions.append(of.ofp_action_output(port = port)) con.send(msg) return pmac
def send_packet_broadcast(self, port_num, packet, dpid): message = of.ofp_packet_out() action = of.ofp_action_output(port = port_num) packet.src = adr.EthAddr('EF:EF:EF:EF:EF:EF') packet.dst = ETHER_BROADCAST message.data = packet.pack() message.actions.append(action) self.connection.send(message) log.debug("IPv4: sent")
def convert(h, val): if h in ['srcmac', 'dstmac']: return packetaddr.EthAddr(val) elif h in ['srcip', 'dstip']: return packetaddr.IPAddr(val) elif h in ['vlan_id', 'vlan_pcp'] and val == 'None': return None else: return val
def generate_arp_response(self, a, packet_in,dpid): r = pkt.arp(hwtype = a.hwtype, prototype = a.prototype, hwlen = a.hwlen, protolen = a.protolen, opcode = pkt.arp.REPLY, hwdst = a.hwsrc, protodst = a.protosrc, protosrc = a.protodst, hwsrc = adr.EthAddr('EF:EF:EF:EF:EF:EF')) e = ethernet(type = pkt.ethernet.ARP_TYPE, src = adr.EthAddr('EF:EF:EF:EF:EF:EF'), dst=a.hwsrc, payload = r) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port = packet_in.in_port)) log.debug(" answering for arp from %s: MAC for %s is %s", str(a.protosrc), str(r.protosrc), str(r.hwsrc)) self.connection.send(msg) log.debug('ARP Reply Sent...')
def generate_arp_response(self, a, packet_in): r = pkt.arp(hwtype=a.hwtype, prototype=a.prototype, hwlen=a.hwlen, protolen=a.protolen, opcode=pkt.arp.REPLY, hwdst=a.hwsrc, protodst=a.protosrc, protosrc=a.protodst, hwsrc=adr.EthAddr('EF:EF:EF:EF:EF:EF')) e = ethernet(type=pkt.ethernet.ARP_TYPE, src=adr.EthAddr('EF:EF:EF:EF:EF:EF'), dst=a.hwsrc) e.payload = r msg = of.ofp_packet_out() msg.data = e.pack() action = of.ofp_action_output(port=packet_in.in_port) msg.actions.append(action) self.connection.send(msg) log.debug('ARP Reply Sent...')
def IP_handler(self, packet, packet_in): ip_packet = packet.payload ipDstAdd = self.route_table.get(str(ip_packet.dstip)) if ipDstAdd != None: msg = of.ofp_flow_mod() msg.match.in_port = packet_in.in_port msg.match = of.ofp_match.from_packet(packet) msg.actions.append( of.ofp_action_dl_addr.set_dst(adr.EthAddr(ipDstAdd[0]))) msg.actions.append(of.ofp_action_dl_addr.set_src(packet.dst)) msg.actions.append(of.ofp_action_output(port=ipDstAdd[1])) self.connection.send(msg)
def send_packet(self, packet, dpid): port_num = self.routing_table[dpid][str(packet.payload.dstip)][3] message = of.ofp_packet_out() action = of.ofp_action_output(port = port_num) packet.src = adr.EthAddr('EF:EF:EF:EF:EF:EF') packet.dst = self.arpTable[packet.payload.dstip] message.data = packet.pack() message.actions.append(action) self.connection.send(message) log.debug("IPv4: sent")
def arp_request1(self, packet, packet_in): arp_packet = packet.payload if arp_packet.opcode == pkt.arp.REQUEST: if str(arp_packet.protodst) == "10.0.1.1": # network1 # packet: arp packet arp_reply = pkt.arp() arp_reply.hwsrc = adr.EthAddr("11:11:11:11:11:11") arp_reply.hwdst = arp_packet.hwsrc arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = arp_packet.protodst arp_reply.protodst = arp_packet.protosrc # ethernet packet eth_packet = pkt.ethernet() eth_packet.type = pkt.ethernet.ARP_TYPE eth_packet.dst = packet.src eth_packet.src = adr.EthAddr("11:11:11:11:11:11") eth_packet.payload = arp_reply msg = of.ofp_packet_out() msg.data = eth_packet.pack() action = of.ofp_action_output(port=packet_in.in_port) msg.actions.append(action) self.connection.send(msg) self.mac_to_port1[packet.src] = packet_in.in_port log.debug(self.mac_to_port1) else: find_ip = 0 for ip in self.routing_table1.keys(): if ip == str(arp_packet.protodst): find_ip = ip if find_ip != 0: self.switch1(packet, packet_in) elif arp_packet.opcode == pkt.arp.REPLY: log.debug("Received arp REPLY") self.mac_to_port1[packet.src] = packet_in.in_port self.switch1(packet, packet_in)
def arp_send(self, packet, packet_in): arpPacketProtocol = packet.payload # ARP reply if arpPacketProtocol.opcode == pkt.arp.REQUEST: arpResponse = pkt.arp() arpResponse.hwsrc = adr.EthAddr("10:10:10:10:10:10") arpResponse.hwdst = arpPacketProtocol.hwsrc arpResponse.opcode = pkt.arp.REPLY arpResponse.protosrc = arpPacketProtocol.protodst arpResponse.protodst = arpPacketProtocol.protosrc #add header to the arp packet, sign the ethernet frame arpFrame = pkt.ethernet() arpFrame.type = pkt.ethernet.ARP_TYPE arpFrame.dst = packet.src arpFrame.src = adr.EthAddr("10:10:10:10:10:10") arpFrame.payload = arpResponse #send the packet msg = of.ofp_packet_out() msg.data = arpFrame.pack() action = of.ofp_action_output(port=packet_in.in_port) msg.actions.append(action) self.connection.send(msg) #add the mac address to the port table# self.mac_to_port[packet.src] = packet_in.in_port log.debug("Display the mac_to_port dictionary(REQUEST)") log.debug(self.mac_to_port) elif arpPacketProtocol.opcode == pkt.arp.REPLY: log.debug("ARP reply reveived") self.mac_to_port[packet.src] = packet_in.in_port log.debug("Display the mac_to_port dictionary(REPLY)") log.debug(self.mac_to_port) else: log.debug("Other arp")
def send_arp_request(self, port_num, packet, packet_in): arp_data = arp(hwlen=6, hwdst=ETHER_BROADCAST, protodst=packet.payload.dstip, hwsrc=adr.EthAddr('EF:EF:EF:EF:EF:EF'), protosrc=packet.next.srcip) arp_data.hwtype = arp_data.HW_TYPE_ETHERNET arp_data.prototype = arp_data.PROTO_TYPE_IP arp_data.protolen = arp_data.protolen arp_data.opcode = arp_data.REQUEST e = ethernet(type=ethernet.ARP_TYPE, src=adr.EthAddr('EF:EF:EF:EF:EF:EF'), dst=ETHER_BROADCAST) e.set_payload(arp_data) message = of.ofp_packet_out() message.data = e.pack() message.actions.append(of.ofp_action_output(port=port_num)) message.in_port = packet_in.in_port self.connection.send(message) log.debug("ARP: request sent")
def __init__(self, backplane, my_ip, my_netmask, my_mac, my_ofport): self.backbone = backplane self.my_ip = addresses.IPAddr(my_ip) self.my_netmask = addresses.IPAddr(my_netmask) self.my_mac = addresses.EthAddr(my_mac) self.my_ofport = my_ofport # A list of packets that could not yet be delivered # due to ARP resolution being in progress. self.packet_queue = list() # IP->MAC mappings learned using ARP self.neigh_by_ip = dict()
def send_ipv4(self, network, packet): dst_port = self.routing_table[network][3] dst_mac = adr.EthAddr('EF:EF:EF:EF:EF:EF') message = of.ofp_packet_out() packet.dst = dst_mac packet.src = adr.EthAddr('EF:EF:EF:EF:EF:EF') message.data = packet.pack() message.actions.append(of.ofp_action_output(port=dst_port)) self.connection.send(message) log.debug("IPv4: sent") message = of.ofp_flow_mod() message.match.nw_dst = packet.payload.dstip message.match.dl_type = 0x800 message.actions.append( of.ofp_action_dl_addr.set_src(adr.EthAddr('EF:EF:EF:EF:EF:EF'))) message.actions.append(of.ofp_action_dl_addr.set_dst(dst_mac)) message.actions.append(of.ofp_action_output(port=dst_port)) log.debug("Flow Mode install Successfully") self.connection.send(message)
def ICMP_Reply_handler(self, packet, packet_in): ip_packet = packet.payload ipSrcAdd = self.route_table.get(str(ip_packet.srcip)) ipDstAdd = self.route_table.get(str(ip_packet.dstip)) if ipDstAdd != None: if str(packet.dst) == '00:00:00:00:00:11': if ipDstAdd[1] == '10.0.1.0/24': ether_pack = pkt.ethernet() ether_pack.type = pkt.ethernet.IP_TYPE ether_pack.src = packet.dst ether_pack.dst = adr.EthAddr(ipDstAdd[0]) ether_pack.payload = packet.payload self.send_Packet(frame=ether_pack, out_port=ipDstAdd[3]) elif ipDstAdd[1] == '10.0.2.0/24': ether_pack = pkt.ethernet() ether_pack.type = pkt.ethernet.IP_TYPE ether_pack.src = packet.dst ether_pack.dst = adr.EthAddr('00:00:00:00:00:22') ether_pack.payload = packet.payload self.send_Packet(frame=ether_pack, out_port=3) elif str(packet.dst) == '00:00:00:00:00:22': if ipDstAdd[1] == '10.0.2.0/24': ether_pack = pkt.ethernet() ether_pack.type = pkt.ethernet.IP_TYPE ether_pack.src = packet.dst ether_pack.dst = adr.EthAddr(ipDstAdd[0]) ether_pack.payload = packet.payload self.send_Packet(frame=ether_pack, out_port=ipDstAdd[3]) elif ipDstAdd[1] == '10.0.1.0/24': ether_pack = pkt.ethernet() ether_pack.type = pkt.ethernet.IP_TYPE ether_pack.src = packet.dst ether_pack.dst = adr.EthAddr('00:00:00:00:00:11') ether_pack.payload = packet.payload self.send_Packet(frame=ether_pack, out_port=1) else: self.send_Packet(frame=packet, out_port=ipDstAdd[3])
def ipv4pkt_send1(self, packet, packet_in): log.debug("ipv4 function pkt send src ip %r dst ip %r"%(packet.payload.srcip,packet.payload.dstip)) dstip_pkt = packet.payload.dstip srcip_pkt = packet.payload.srcip if str(dstip_pkt) in self.network1: if str(srcip_pkt) in self.network1: msg = of.ofp_flow_mod() msg.match.dl_type = pkt.ethernet.IP_TYPE msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.match.nw_src = packet.payload.srcip msg.match.nw_dst = packet.payload.dstip msg.match.in_port = packet_in.in_port msg.data = packet_in msg.actions.append(of.ofp_action_output(port = self.network1[str(dstip_pkt)][0])) self.connection.send(msg) elif str(srcip_pkt) in self.network2: packet.src = packet.dst packet.dst = EthAddr(self.network1[str(dstPktIP)][1]) msg = of.ofp_packet_out() msg.data = packet.pack() action = of.ofp_action_output(port = self.network1[str(dstPktIP)][0]) msg.actions.append(action) self.connection.send(msg) else: pass elif str(dstip_pkt) in self.network2: log.debug("forward the packet from %r to %r"%(packet.payload.srcip, packet.payload.dstip)) packet.src = packet.dst packet.dst = adr.EthAddr("20:20:20:20:20:20") msg = of.ofp_packet_out() msg.data = packet.pack() action = of.ofp_action_output(port = 3) msg.actions.append(action) self.connection.send(msg) else: pass
def ARP_Request_handler(self, packet, packet_in): #make ARP reply arp_reply = pkt.arp() arp_reply.hwsrc = adr.EthAddr('00:00:00:00:00:10') arp_reply.hwdst = packet.payload.hwsrc arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = packet.payload.protodst arp_reply.protodst = packet.payload.protosrc #make ARP packet -> Frame ether = pkt.ethernet() ether.type = pkt.ethernet.ARP_TYPE ether.dst = packet.src ether.src = packet.dst ether.payload = arp_reply #send Frame self.send_Packet(frame=ether, out_port=packet_in.in_port)
def handleThreat(): log.info("Packet received from %s" % packet.src) f = open('block.list', 'rb') s1 = f.read() log.info(s1) macList = s1.split(',') log.info(str(macList)) if s1 != "": for m in macList: log.info("m = %s" % m) match = of.ofp_match() match.dl_src = addr.EthAddr(m) msg = of.ofp_flow_mod(command=of.OFPFC_ADD, actions=[], match=match) self.connection.send(msg)
def broadcast_routing_table(self): rip_msg = pkt.rip() rip_msg.version = 2 rip_msg.command = pkt.RIP_RESPONSE for entry in self.routing_table: rip_entry = pkt.RIPEntry() rip_entry.ip = adr.IPAddr(entry.split("/")[0]) rip_entry.netmask = int(entry.split("/")[1]) rip_entry.metric = self.routing_table[entry][-1] rip_msg.entries.append(rip_entry) if entry[1] != forever_ttl: --self.routing_table[entry][1] if self.routing_table[entry][1] == 0: del self.routing_table[entry] udp = pkt.udp() udp.srcport = 520 udp.dstport = 520 # log.debug( "Created rip msg of len: %d", len(rip_msg) ) udp.len = len(rip_msg) udp.payload = rip_msg ipv4 = pkt.ipv4() ipv4.protocol = pkt.ipv4.UDP_PROTOCOL ipv4.srcip = pkt.IP_ANY ipv4.dstip = pkt.rip.RIP2_ADDRESS ipv4.payload = udp ether = pkt.ethernet() ether.type = pkt.ethernet.IP_TYPE ether.dst = adr.EthAddr('ff:ff:ff:ff:ff:ff') ether.payload = ipv4 for port in self.port_to_hwaddr.keys()[0:-1]: ether.src = self.port_to_hwaddr[port] # log.debug( "Broadcasting routing table" ) msg = of.ofp_packet_out() msg.data = ether.pack() # Add an action to send to the specified port action = of.ofp_action_output(port=port) msg.actions.append(action) self.connection.send(msg)
def generate_flow(self, packet, network): message = of.ofp_packet_out(data=packet.pack()) message.actions.append( of.ofp_action_output(port=self.routing_table[network][3])) self.connection.send(message) log.debug("ICMP: sent") message = of.ofp_flow_mod() message.match.nw_dst = packet.payload.dstip message.match.dl_type = 0x800 message.actions.append( of.ofp_action_dl_addr.set_src(adr.EthAddr('EF:EF:EF:EF:EF:EF'))) message.actions.append( of.ofp_action_dl_addr.set_dst(self.arpTable[packet.payload.dstip])) message.actions.append( of.ofp_action_output(port=self.routing_table[network][3])) log.debug("Flow Mode install Successfully") self.connection.send(message)
def _handle_migration(event): eth_pkt = event.parsed arp_pkt = event.parsed.payload org_mac = eth_pkt.src.toStr() dst_ip = arp_pkt.protodst.toStr() #old_pmac = arp_table[dst_ip] old_pmac = actual_pmac[org_mac] sw, port = pmac_pos(old_pmac) if (sw != event.dpid) or (port+1 != event.port): ''' this host has migrated. assign new pmac. add trans in new switch. remove prev trans tabbles from old switch. add entry in old switch to frwrd to some agg switch replacing old pmac with new pmac update our internal tables change the assigned mac string - not assign the old pmac for the timeout period of time ''' new_pmac = _handle_new_host(org_mac, dst_ip, event.dpid, event.port) msg = nx.nx_flow_mod(table_id = 0, command=of.OFPFC_DELETE) msg.priority = 5000 msg.match.eth_src = org_mac event.connection.send(msg) msg = nx.nx_flow_mod(table_id = 1, command=of.OFPFC_DELETE) msg.priority = 5000 msg.match.eth_dst = old_pmac event.connection.send(msg) msg = nx.nx_flow_mod(table_id = 0) msg.priority = 8000 msg.hard_timeout = arp_timeout msg.match.eth_dst = old_pmac msg.actions.append(of.ofp_action_dl_addr.set_dst(adrs.EthAddr(new_pmac))) msg.actions.append(of.ofp_action_output(port = switch_pos(event.dpid)[1] + 1 ))#simple hashing. edge switch x sends to agg switch x event.connection.send(msg) arp_table[dst_ip] = new_pmac actual_pmac.pop(pmac_actual[old_pmac]) pmac_actual.pop(old_pmac) #this nxt 2 lines should be in a fn called after the timeout. we dont want to assing old pmac to anyone until then vmid = int(s[-5:].replace(':',''),16) assigned_pmac[event.dpid][event.port] = assigned_pmac[event.dpid][event.port][:vmid] + '0' + assigned_pmac[event.dpid][event.port][vmid + 1:]
def addNode(self, ip, mac, port=None): """ Construct a new Node from the given argument, keep it in self.nodes, and perform active OVS port discovery. If there is already a node with the same IP and MAC, no new node will be created """ ipaddr = libaddr.IPAddr(ip) macaddr = libaddr.EthAddr(mac) node = self.nodes.get(ipaddr, None) if node and node.mac == macaddr: return node newNode = Node(ipaddr, macaddr, port=port) self.nodes[ipaddr] = newNode self.sendArpRequest(newNode) log.debug('New Node object created with IP %s' % ipaddr) return newNode
def act_like_router(self, packet, packet_in): # handle ARP type packet table_num = self.get_table_num(packet) if packet.type == pkt.ethernet.ARP_TYPE: if packet.payload.opcode == pkt.arp.REQUEST: log.debug("ARP request received") # create a ARP type packet arp_reply = pkt.arp() if table_num == 1: arp_reply.hwsrc = adr.EthAddr("10:00:00:00:00:00") elif table_num == 2: arp_reply.hwsrc = adr.EthAddr("20:00:00:00:00:00") log.debug("ARP received from %s" % packet.payload.hwsrc) arp_reply.hwdst = packet.payload.hwsrc arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = packet.payload.protodst arp_reply.protodst = packet.payload.protosrc # create a ETHERNET type packet # wrap ARP as the payload of the ETHERNET packet eth_p = self.create_Ether_packet(pkt.ethernet.ARP_TYPE, packet.dst, packet.src, arp_reply) # Send the ETHERNET packet self.send_EtherNet_packet(eth_p, packet_in.in_port) log.debug("ARP reply sent") elif packet.payload.opcode == pkt.arp.REPLY: log.debug("It's a reply!") self.mac_to_port[packet.src] = packet_in.in_port else: log.debug("Some other ARP opcode") # Handle IP type packet elif packet.type == pkt.ethernet.IP_TYPE: # Parse IP_packet information ip_packet = packet.payload src_ip = ip_packet.srcip dst_ip = ip_packet.dstip subnet = self.find_subnet(dst_ip, table_num) # Handle ICMP type packet if ip_packet.protocol == pkt.ipv4.ICMP_PROTOCOL: icmp_packet = ip_packet.payload if icmp_packet.type == pkt.TYPE_ECHO_REQUEST: log.debug("ICMP request received + table_num = %d" % table_num) log.debug("\t\t subnet = %s" % subnet) # When subnet is found in the routing table if subnet != None: log.debug("ICMP reply sent") log.debug("network containing host: " + subnet) ech = pkt.echo() ech.seq = icmp_packet.payload.seq + 1 ech.id = icmp_packet.payload.id ip_p = self.create_icmp_packet(src_ip, dst_ip, pkt.TYPE_ECHO_REPLY, ech) eth_p = self.create_Ether_packet( pkt.ethernet.IP_TYPE, packet.dst, packet.src, ip_p) self.send_EtherNet_packet(eth_p, packet_in.in_port) # Subnet is not fount, return an unreachable message else: log.debug("ICMP destination unreachable") unr = pkt.unreach() unr.payload = ip_packet ip_p = self.create_icmp_packet(src_ip, dst_ip, pkt.TYPE_DEST_UNREACH, unr) eth_p = self.create_Ether_packet( pkt.ethernet.IP_TYPE, packet.dst, packet.src, ip_p) self.send_EtherNet_packet(eth_p, packet_in.in_port) # Handle normal IP type packet else: if subnet != None: packet.src = packet.dst if table_num == 1: packet.dst = adr.EthAddr( self.routing_table1[subnet][4]) self.send_EtherNet_packet( packet, self.routing_table1[subnet][3]) elif table_num == 2: packet.dst = adr.EthAddr( self.routing_table2[subnet][4]) self.send_EtherNet_packet( packet, self.routing_table2[subnet][3])
def act_like_router(self, frame, packet_in): if frame.type == 0x0806: packet = frame.payload network = 0 if packet.opcode == 1 and packet.protodst in self.routerip: # arp request and ip dst in routing table arp_data = arp(hwtype=packet.hwtype, prototype=packet.prototype, hwlen=packet.hwlen, protolen=packet.protolen, opcode=2, hwdst=packet.hwsrc, protodst=packet.protosrc, protosrc=packet.protodst, hwsrc=addresses.EthAddr('FA:DE:DD:ED:AF:AA')) e_frame = ethernet(type=0x0806, src=addresses.EthAddr('FA:DE:DD:ED:AF:AA'), dst=packet.hwsrc) e_frame.payload = arp_data out_packet = of.ofp_packet_out() out_packet.data = e_frame.pack() action = of.ofp_action_output(port=packet_in.in_port) out_packet.actions.append(action) self.connection.send(out_packet) elif (packet.opcode == 2): self.arp_cache[packet.protosrc] = packet.hwsrc to_send = self.store.payload for nw in self.routing_table: nw1 = self.routing_table[nw] if str(to_send.dstip) in nw1: network = nw break message = of.ofp_packet_out() action = of.ofp_action_output( port=self.routing_table[network][3]) self.store.src = addresses.EthAddr('FA:DE:DD:ED:AF:AA') self.store.dst = self.arp_cache[to_send.dstip] message.data = self.store.pack() message.actions.append(action) self.connection.send(message) log.debug("ICMP: sent from router to host") message = of.ofp_flow_mod() message.match.nw_dst = to_send.dstip message.match.dl_type = 0x0800 message.actions.append( of.ofp_action_dl_addr.set_src(self.store.src)) message.actions.append( of.ofp_action_dl_addr.set_dst(self.store.dst)) message.actions.append( of.ofp_action_output(port=self.routing_table[network][3])) log.debug("Flow Mode install Successfully") self.connection.send(message) self.store = None elif frame.type == 0x0800: network = 0 for nw in self.routing_table.keys(): nw1 = self.routing_table[nw] if str(frame.payload.dstip) in nw1: network = nw break packet = frame.payload if network == 0: unreachable_type = pocket.unreach() unreachable_type.payload = frame.payload icmp_type = pocket.icmp() icmp_type.type = 3 icmp_type.payload = unreachable_type ip_type = pocket.ipv4(srcip=frame.payload.dstip, dstip=frame.payload.srcip, protocol=1, payload=icmp_type) ethernet_type = pocket.ethernet(type=0x0800, src=frame.dst, dst=frame.src, payload=ip_type) message = of.ofp_packet_out() message.data = ethernet_type.pack() message.actions.append( of.ofp_action_output(port=packet_in.in_port)) self.connection.send(message) elif packet.protocol == 1: data_icmp = packet.payload if data_icmp.type == 8 and packet.dstip in self.routerip: echo_type = pocket.echo(seq=data_icmp.payload.seq + 1, id=data_icmp.payload.id) icmp_type = pocket.icmp(type=0, payload=echo_type) ip_type = pocket.ipv4(srcip=packet.dstip, dstip=packet.srcip, protocol=1, payload=icmp_type) ethernet_type = pocket.ethernet(type=0x0800, src=frame.dst, dst=frame.src, payload=ip_type) message = of.ofp_packet_out() message.data = ethernet_type.pack() message.actions.append( of.ofp_action_output(port=packet_in.in_port)) self.connection.send(message) elif packet.dstip not in self.arp_cache: self.store = frame arp_type = arp( hwlen=6, hwdst=ETHER_BROADCAST, protodst=packet.dstip, hwsrc=addresses.EthAddr('FA:DE:DD:ED:AF:AA'), protosrc=packet.srcip) arp_type.opcode = 1 ethernet_type = ethernet( type=0x0806, src=addresses.EthAddr('FA:DE:DD:ED:AF:AA'), dst=ETHER_BROADCAST) ethernet_type.set_payload(arp_type) message = of.ofp_packet_out() message.data = ethernet_type.pack() message.actions.append( of.ofp_action_output( port=self.routing_table[network][3])) message.in_port = packet_in.in_port self.connection.send(message) elif packet.dstip in self.arp_cache: message = of.ofp_packet_out() action = of.ofp_action_output( port=self.routing_table[network][3]) frame.src = addresses.EthAddr('FA:DE:DD:ED:AF:AA') frame.dst = self.arp_cache[packet.dstip] message.data = frame.pack() message.actions.append(action) self.connection.send(message) message = of.ofp_flow_mod() message.match.nw_dst = packet.dstip message.match.dl_type = 0x0800 message.actions.append( of.ofp_action_dl_addr.set_src(frame.src)) message.actions.append( of.ofp_action_dl_addr.set_dst(frame.dst)) message.actions.append( of.ofp_action_output( port=self.routing_table[network][3])) self.connection.send(message)
def act_like_router(self, packet, packet_in): #handle arp if packet.type == pkt.ethernet.ARP_TYPE: if packet.payload.opcode == pkt.arp.REQUEST: log.debug("ARP request received") arp_reply = pkt.arp() arp_reply.hwsrc = adr.EthAddr("40:10:40:10:40:10") #fake MAC arp_reply.hwdst = packet.payload.hwsrc arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = packet.payload.protodst arp_reply.protodst = packet.payload.protosrc ether = pkt.ethernet() ether.type = pkt.ethernet.ARP_TYPE ether.dst = packet.src ether.src = packet.dst ether.payload = arp_reply msg = of.ofp_packet_out() msg.data = ether.pack() # Add an action to send to the specified port action = of.ofp_action_output(port=packet_in.in_port) msg.actions.append(action) #msg.in_port = event.port # Send message to switch self.connection.send(msg) log.debug("ARP reply sent") elif packet.payload.opcode == pkt.arp.REPLY: log.debug("It's a reply!") self.mac_to_port[packet.src] = packet_in.in_port else: log.debug("Some other ARP opcode") elif packet.type == pkt.ethernet.IP_TYPE: ip_packet = packet.payload if ip_packet.protocol == pkt.ipv4.ICMP_PROTOCOL: icmp_packet = ip_packet.payload if icmp_packet.type == pkt.TYPE_ECHO_REQUEST: log.debug("ICMP request received") src_ip = ip_packet.srcip dst_ip = ip_packet.dstip k = 0 for key in self.routing_table.keys(): if dst_ip.inNetwork(key): k = key break if k != 0: log.debug("ICMP reply sent") log.debug("network containing host: " + k) ech = pkt.echo() ech.seq = icmp_packet.payload.seq + 1 ech.id = icmp_packet.payload.id icmp_reply = pkt.icmp() icmp_reply.type = pkt.TYPE_ECHO_REPLY icmp_reply.payload = ech ip_p = pkt.ipv4() ip_p.srcip = dst_ip ip_p.dstip = src_ip ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL ip_p.payload = icmp_reply eth_p = pkt.ethernet() eth_p.type = pkt.ethernet.IP_TYPE eth_p.dst = packet.src eth_p.src = packet.dst eth_p.payload = ip_p msg = of.ofp_packet_out() msg.data = eth_p.pack() # Add an action to send to the specified port action = of.ofp_action_output(port=packet_in.in_port) #fl2.actions.append(action) msg.actions.append(action) #msg.in_port = event.port # Send message to switch self.connection.send(msg) else: log.debug("ICMP destination unreachable") unr = pkt.unreach() unr.payload = ip_packet icmp_reply = pkt.icmp() icmp_reply.type = pkt.TYPE_DEST_UNREACH icmp_reply.payload = unr ip_p = pkt.ipv4() ip_p.srcip = dst_ip ip_p.dstip = src_ip ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL ip_p.payload = icmp_reply eth_p = pkt.ethernet() eth_p.type = pkt.ethernet.IP_TYPE eth_p.dst = packet.src eth_p.src = packet.dst eth_p.payload = ip_p msg = of.ofp_packet_out() msg.data = eth_p.pack() # Add an action to send to the specified port action = of.ofp_action_output(port=packet_in.in_port) #fl2.actions.append(action) msg.actions.append(action) #msg.in_port = event.port # Send message to switch self.connection.send(msg) else: src_ip = ip_packet.srcip dst_ip = ip_packet.dstip k = 0 for key in self.routing_table.keys(): if dst_ip.inNetwork(key): k = key break if k != 0: port1 = self.routing_table[k][3] dsteth = adr.EthAddr(self.routing_table[k][4]) msg = of.ofp_packet_out() action = of.ofp_action_output(port=port1) packet.src = packet.dst packet.dst = dsteth msg.data = packet.pack() msg.actions.append(action) self.connection.send(msg) self.FlowMode(packet_in, packet_in.in_port)
def act_like_router(self, packet, packet_in): #handle arp if packet.type == pkt.ethernet.IP_TYPE: ip_packet = packet.payload if ip_packet.protocol == pkt.ipv4.UDP_PROTOCOL: udp_packet = ip_packet.payload if udp_packet.dstport == 520: rip_packet = udp_packet.payload self.port_to_mac[packet_in.in_port] = packet.src # log.debug("got rip packet form port: %s", packet_in.in_port) for entry in rip_packet.entries: key = entry.ip.toStr() + '/' + str(entry.network_bits) if key in self.routing_table.keys(): if self.routing_table[key][-1] - 1 > entry.metric: self.routing_table[key][0] = packet_in.in_port self.routing_table[key][-1] = entry.metric + 1 self.routing_table[key][1] = basic_ttl else: self.routing_table[key] = [packet_in.in_port, basic_ttl,\ entry.metric+1] return if packet.type == pkt.ethernet.ARP_TYPE: dst_ip = packet.payload.protodst.toStr() if packet.payload.opcode == pkt.arp.REQUEST \ and dst_ip.split(".")[3] == "1": log.debug("ARP request received") log.debug("%s, port: %d", dst_ip, packet_in.in_port) # self.ip_to_port[dst_ip] = packet_in.in_port # self.routing_table[packet_in.in_port].append([ \ # packet.payload.protosrc.toStr(),\ # packet.payload.hwsrc.toStr()]) # log.debug("%s", packet.payload.protodst.toStr().split(".")[3]) self.routing_table[ip_to_subnet[packet.payload.protosrc.toStr()][0]] = \ [packet_in.in_port, forever_ttl, 0] self.port_to_mac[packet_in.in_port] = packet.src print(self.port_to_mac) arp_reply = pkt.arp() arp_reply.hwsrc = adr.EthAddr( self.port_to_hwaddr[packet_in.in_port]) arp_reply.hwdst = packet.payload.hwsrc arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = packet.payload.protodst arp_reply.protodst = packet.payload.protosrc ether = pkt.ethernet() ether.type = pkt.ethernet.ARP_TYPE ether.dst = packet.src ether.src = packet.dst ether.payload = arp_reply msg = of.ofp_packet_out() msg.data = ether.pack() # Add an action to send to the specified port action = of.ofp_action_output(port=packet_in.in_port) msg.actions.append(action) #msg.in_port = event.port # Send message to switch self.connection.send(msg) print(self.routing_table) print(self.ip_to_port) print(self.port_to_hwaddr) log.debug("ARP reply sent") elif packet.payload.opcode == pkt.arp.REPLY: log.debug("It's a reply!") self.port_to_mac[packet_in.in_port] = packet.src else: log.debug("Some other ARP opcode") # elif packet.type == pkt.ethernet.IP_TYPE: # ip_packet = packet.payload # if ip_packet.protocol == pkt.ipv4.ICMP_PROTOCOL: # icmp_packet = ip_packet.payload # if icmp_packet.type == pkt.TYPE_ECHO_REQUEST: # log.debug("ICMP request received") # src_ip = ip_packet.srcip # dst_ip = ip_packet.dstip # k = 0 # log.debug(self.routing_table.keys()) # for key in self.routing_table.keys(): # if dst_ip.inNetwork(key): # k = key # break # if k!=0: # log.debug("ICMP reply sent") # log.debug("network containing host: "+k) # ech = pkt.echo() # ech.seq = icmp_packet.payload.seq + 1 # ech.id = icmp_packet.payload.id # icmp_reply = pkt.icmp() # icmp_reply.type = pkt.TYPE_ECHO_REPLY # icmp_reply.payload = ech # ip_p = pkt.ipv4() # ip_p.srcip = dst_ip # ip_p.dstip = src_ip # ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL # ip_p.payload = icmp_reply # eth_p = pkt.ethernet() # eth_p.type = pkt.ethernet.IP_TYPE # eth_p.dst = packet.src # eth_p.src = packet.dst # eth_p.payload = ip_p # msg = of.ofp_packet_out() # msg.data = eth_p.pack() # # Add an action to send to the specified port # action = of.ofp_action_output(port = packet_in.in_port) # #fl2.actions.append(action) # msg.actions.append(action) # #msg.in_port = event.port # # Send message to switch # self.connection.send(msg) # else: # log.debug("ICMP destination unreachable") # unr = pkt.unreach() # unr.payload = ip_packet # icmp_reply = pkt.icmp() # icmp_reply.type = pkt.TYPE_DEST_UNREACH # icmp_reply.payload = unr # ip_p = pkt.ipv4() # ip_p.srcip = dst_ip # ip_p.dstip = src_ip # ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL # ip_p.payload = icmp_reply # eth_p = pkt.ethernet() # eth_p.type = pkt.ethernet.IP_TYPE # eth_p.dst = packet.src # eth_p.src = packet.dst # eth_p.payload = ip_p # msg = of.ofp_packet_out() # msg.data = eth_p.pack() # # Add an action to send to the specified port # action = of.ofp_action_output(port = packet_in.in_port) # #fl2.actions.append(action) # msg.actions.append(action) # #msg.in_port = event.port # # Send message to switch # self.connection.send(msg) # if ip_packet.protocol == pkt.ipv4.UDP_PROTOCOL: # udp_packet = ip_packet.payload # if udp_packet.dstport == 520: # rip_packet = udp_packet.payload # # log.debug("got rip packet form port: %s", packet_in.in_port) # for entry in rip_packet.entries: # key = entry.ip.toStr()+'/'+str(entry.network_bits) # if key in self.routing_table.keys(): # if self.routing_table[key][-1]-1 > entry.metric: # self.routing_table[key][0] = packet_in.in_port # self.routing_table[key][-1] = entry.metric+1 # self.routing_table[key][1] = basic_ttl # else: # self.routing_table[key] = [packet_in.in_port, basic_ttl,\ # entry.metric+1] else: src_ip = ip_packet.srcip dst_ip = ip_packet.dstip k = 0 for key in self.routing_table.keys(): if dst_ip.inNetwork(key): k = key break if k != 0: out_port = self.routing_table[k][0] print(out_port) print(k) print(self.routing_table) print(packet.dst) print(self.port_to_mac) print(self.port_to_mac[out_port]) print(dst_ip) # packet.dst = adr.EthAddr(self.port_to_mac[out_port]) # print(packet.dst) # msg = of.ofp_packet_out() match = of.ofp_match.from_packet(packet) action = of.ofp_action_output(port=out_port) msg = of.ofp_flow_mod() msg.match = match msg.match.in_port = packet_in.in_port # msg.out_port = out_port msg.idle_timeout = FLOW_IDLE_TIMEOUT msg.hard_timeout = FLOW_HARD_TIMEOUT # packet.src = packet.dst # packet.dst = dsteth # msg.data = packet.pack() msg.actions.append( of.ofp_action_dl_addr.set_dst( adr.EthAddr(self.port_to_mac[out_port]))) msg.actions.append(action) self.connection.send(msg) # self.FlowMode( packet_in, packet_in.in_port) else: log.debug("ICMP destination unreachable") unr = pkt.unreach() unr.payload = ip_packet icmp_reply = pkt.icmp() icmp_reply.type = pkt.TYPE_DEST_UNREACH icmp_reply.payload = unr ip_p = pkt.ipv4() ip_p.srcip = dst_ip ip_p.dstip = src_ip ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL ip_p.payload = icmp_reply eth_p = pkt.ethernet() eth_p.type = pkt.ethernet.IP_TYPE eth_p.dst = packet.src eth_p.src = packet.dst eth_p.payload = ip_p msg = of.ofp_packet_out() msg.data = eth_p.pack() # Add an action to send to the specified port action = of.ofp_action_output(port=packet_in.in_port) #fl2.actions.append(action) msg.actions.append(action) #msg.in_port = event.port # Send message to switch self.connection.send(msg)