def handle_unreachable(self, packet, packet_in): packet_unreachable = pkt.unreach() packet_unreachable.payload = packet.payload icmp_packet = pkt.icmp() icmp_packet.type = pkt.TYPE_DEST_UNREACH icmp_packet.payload = packet_unreachable ip_packet = pkt.ipv4() ip_packet.srcip = packet.payload.dstip ip_packet.dstip = packet.payload.srcip ip_packet.protocol = pkt.ipv4.ICMP_PROTOCOL ip_packet.payload = icmp_packet ether_packet = pkt.ethernet() ether_packet.type = pkt.ethernet.IP_TYPE ether_packet.dst = packet.src ether_packet.src = packet.dst ether_packet.payload = ip_packet msg = of.ofp_packet_out() msg.data = ether_packet.pack() action = of.ofp_action_output(port=packet_in.in_port) msg.actions.append(action) self.connection.send(msg)
def unreachable_send(self, packet, packet_in): msgUnreachable = pkt.unreach() msgUnreachable.payload = packet.payload icmpReachable = pkt.icmp() icmpReachable.type = pkt.TYPE_DEST_UNREACH icmpReachable.payload = msgUnreachable #encapsulate reachable ICMP packet icmpPkt = pkt.ipv4() icmpPkt.srcip = packet.payload.dstip #change the source ip to router's ip icmpPkt.dstip = packet.payload.srcip icmpPkt.protocol = pkt.ipv4.ICMP_PROTOCOL icmpPkt.payload = icmpReachable #encapsulate packet into frame icmpFrame = pkt.ethernet() icmpFrame.type = pkt.ethernet.IP_TYPE icmpFrame.dst = packet.src icmpFrame.src = packet.dst icmpFrame.payload = icmpPkt msg = of.ofp_packet_out() msg.data = icmpFrame.pack() action = of.ofp_action_output(port=packet_in.in_port) msg.actions.append(action) self.connection.send(msg)
def makeICMP(self, errorType, codeType, ippkt): icmppkt = pktlib.icmp() icmppkt.type = errorType icmppkt.code = codeType icmppkt.payload = pktlib.unreach() icmppkt.payload.payload = ippkt.dump()[:28] return icmppkt
def destination_unreachable_icmp(self, packet, packet_in): data = packet.payload log.debug("ICMP: destination unreachable") dst_unreach = pkt.unreach() dst_unreach.payload = data icmp_reply = pkt.icmp() icmp_reply.type = pkt.TYPE_DEST_UNREACH icmp_reply.payload = dst_unreach self.send_icmp_packet(icmp_reply, packet, packet_in)
def make_ICMP(self, TYPE, pkt, dev): icmppkt = pktlib.icmp() if(TYPE=='PING'): #if ping type print 'ping reply' icmppkt.type = pktlib.TYPE_ECHO_REPLY ping = pktlib.echo() ping.id = pkt.payload.payload.id ping.seq = pkt.payload.payload.seq ping.payload = pkt.payload.payload.payload #It's like christmas, so much unwrapping icmppkt.payload = ping else: #if error message if(TYPE=='TIMEEXCEED'): print 'time exceed' icmppkt.type = pktlib.TYPE_TIME_EXCEED else: icmppkt.type = pktlib.TYPE_DEST_UNREACH if(TYPE=='UNREACH_NET'): #if table lookup failed print 'net unreach' icmppkt.code = pktlib.CODE_UNREACH_NET elif(TYPE=='UNREACH_HOST'): #if sent 5 arps and no reply from host print 'host unreach' icmppkt.code = pktlib.CODE_UNREACH_HOST elif(TYPE=='UNREACH_PORT'): #sent to us, but not an ICMP PING print 'port unreach' icmppkt.code = pktlib.CODE_UNREACH_PORT else: print 'wtf? if it wasnt one of these errors, something REALLY went wrong' icmppkt.payload = pktlib.unreach() icmppkt.payload.payload = pkt.dump()[:28] #wrap up in IP then ethernet ipreply = pktlib.ipv4() ipreply.protocol = ipreply.ICMP_PROTOCOL ipreply.dstip = pkt.srcip ipreply.ttl = 65 #make this bigger, because it gets decremented when we send it ipreply.payload = icmppkt ipreply.srcip = self.net.interface_by_name(dev).ipaddr match = self.FT_lookup(ipreply, dev) intf = self.net.interface_by_name(match[3]) prefix = match[1] nexthop = match[2] if nexthop not in self.macaddrs: self.queue.append([match, floor(time()), ipreply, 0]) self.send_arp_request(match) else: self.send_packet(match, ipreply) '''
def _send_icmp_reply(self, dpid, p, srcip, dstip, icmpType, event): pktIcmp = pkt.icmp() # TYPE_ECHO_REQUEST = 8, TYPE_DEST_UNREACH = 3, TYPE_ECHO_REPLY = 0 if icmpType == pkt.TYPE_ECHO_REPLY: pktIcmp.payload = p.find('icmp').payload elif icmpType == pkt.TYPE_DEST_UNREACH: pktIcmp.type = pkt.TYPE_DEST_UNREACH unreachMsg = pkt.unreach() unreachMsg.payload = p.payload pktIcmp.payload = unreachMsg # Make IP header pktIp = ipv4() pktIp.protocol = pktIp.ICMP_PROTOCOL pktIp.srcip = dstip pktIp.dstip = srcip # Ethernet header eth = ethernet() eth.src = p.dst eth.dst = p.src eth.type = eth.IP_TYPE # Hook them up pktIp.payload = pktIcmp # ICMP encapsulated in IP packet eth.payload = pktIp # IP packet encapsulated in ethernet frame # Send it back to the input port msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.data = eth.pack() msg.in_port = self.routingTable[dpid][srcip] event.connection.send(msg) log.debug('DPID %d: IP %s pings %s, icmp reply with type %d', dpid, str(srcip), str(dstip), icmpType) log.debug('(type 0: reply, type 3: unreach, type 8: request)')
def unreachable_send(self, packet, packet_in): msgUnreachable = pkt.unreach() msgUnreachable.payload = packet.payload #encapsulate unreachable msg into icmp packet icmpReachable = pkt.icmp() icmpReachable.type = pkt.TYPE_DEST_UNREACH icmpReachable.payload = msgUnreachable #encapsulate icmp into ipv4 packet icmpPkt = pkt.ipv4() for netIP in self.routingTable.keys(): if packet.payload.srcip.inNetwork(netIP): dstSubnet = netIP dstIP = self.routingTable[dstSubnet][2] #change the source ip to router's ip icmpPkt.srcip = IPAddr(dstIP) icmpPkt.dstip = packet.payload.srcip icmpPkt.protocol = pkt.ipv4.ICMP_PROTOCOL icmpPkt.payload = icmpReachable #encapsulate packet into ethernet frame icmpFrame = pkt.ethernet() icmpFrame.type = pkt.ethernet.IP_TYPE icmpFrame.dst = packet.src icmpFrame.src = packet.dst icmpFrame.payload = icmpPkt msg = of.ofp_packet_out() msg.data = icmpFrame.pack() action = of.ofp_action_output(port=packet_in.in_port) msg.actions.append(action) self.connection.send(msg)
def _send_icmp_reply(self, dpid, p, srcip, dstip, icmpType, event): pktIcmp = pkt.icmp() # TYPE_ECHO_REQUEST = 8, TYPE_DEST_UNREACH = 3, TYPE_ECHO_REPLY = 0 if icmpType == pkt.TYPE_ECHO_REPLY: pktIcmp.payload = p.find('icmp').payload elif icmpType == pkt.TYPE_DEST_UNREACH: pktIcmp.type = pkt.TYPE_DEST_UNREACH unreachMsg = pkt.unreach() unreachMsg.payload = p.payload pktIcmp.payload = unreachMsg # Make IP header pktIp = ipv4() pktIp.protocol = pktIp.ICMP_PROTOCOL pktIp.srcip = dstip pktIp.dstip = srcip # Ethernet header eth = ethernet() eth.src = p.dst eth.dst = p.src eth.type = eth.IP_TYPE # Hook them up pktIp.payload = pktIcmp # ICMP encapsulated in IP packet eth.payload = pktIp # IP packet encapsulated in ethernet frame # Send it back to the input port msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.data = eth.pack() msg.in_port = self.routingTable[dpid][srcip] event.connection.send(msg) log.debug('DPID %d: IP %s pings %s, icmp reply with type %d', dpid, str(srcip), str(dstip), icmpType) log.debug('(type 0: reply, type 3: unreach, type 8: request)')
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)
def act_like_switch (self, event, packet, packet_in): """ Implement router-like behavior. """ # handle ARP if packet.type == myPkt.ethernet.ARP_TYPE: # ref: pox/pox/proto/arp_helper.py && arp_responder.py && pong.py a = packet.payload if a.opcode == myPkt.arp.REQUEST: log.debug("port %s ARP request %s => %s", str(packet_in.in_port), str(a.protosrc), str(a.protodst)) r = myPkt.arp() r.hwtype = a.hwtype r.prototype = a.prototype r.hwlen = a.hwlen r.protolen = a.protolen r.opcode = myPkt.arp.REPLY r.hwdst = a.hwsrc if str(a.protodst) == '10.0.1.1' or str(a.protodst) == '10.0.2.1' or str(a.protodst) == '10.0.3.1': r.hwsrc = myAddr.EthAddr("12:12:12:12:12:12") else: return r.protodst = a.protosrc r.protosrc = a.protodst e = myPkt.ethernet() e.type = myPkt.ethernet.ARP_TYPE e.dst = a.hwsrc e.src = r.hwsrc e.payload = r log.debug("Answer ARP for " + str(r.protosrc)) msg = of.ofp_packet_out() msg.data = e.pack() msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT)) msg.in_port = event.port event.connection.send(msg) elif packet.payload.opcode == myPkt.arp.REPLY: log.debug("port %s ARP reply %s => %s", str(packet_in.in_port), str(a.protosrc), str(a.hwsrc)) else: log.debug("Router receive Other ARP packet") # handle ICMP elif packet.type == myPkt.ethernet.IP_TYPE: src_ip = packet.payload.srcip dst_ip = packet.payload.dstip if packet.payload.protocol == myPkt.ipv4.ICMP_PROTOCOL: #ref: pox/pox/proto/pong.py && pox/pox/lib/packet/icmp.py if self.arp_cache.get(dst_ip): #log.debug("packet.src = %s, packet.dst = %s", str(packet.src), str(packet.dst)) icmp_reply = myPkt.icmp() icmp_reply.type = myPkt.TYPE_ECHO_REPLY icmp_reply.payload = packet.find("icmp").payload ip_pkt = myPkt.ipv4() ip_pkt.protocol = myPkt.ipv4.ICMP_PROTOCOL ip_pkt.srcip = packet.find("ipv4").dstip ip_pkt.dstip = packet.find("ipv4").srcip icmp_frame = myPkt.ethernet() icmp_frame.type = myPkt.ethernet.IP_TYPE icmp_frame.dst = packet.src icmp_frame.src = packet.dst ip_pkt.payload = icmp_reply icmp_frame.payload = ip_pkt msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.data = icmp_frame.pack() msg.in_port = event.port event.connection.send(msg) log.debug("%s pinged %s", str(ip_pkt.dstip), str(ip_pkt.srcip)) else: icmp_reply = myPkt.icmp() icmp_reply.type = myPkt.TYPE_DEST_UNREACH unreach_msg = myPkt.unreach() unreach_msg.payload = packet.payload icmp_reply.payload = unreach_msg ip_pkt = myPkt.ipv4() ip_pkt.protocol = myPkt.ipv4.ICMP_PROTOCOL ip_pkt.srcip = packet.find("ipv4").dstip ip_pkt.dstip = packet.find("ipv4").srcip icmp_frame = myPkt.ethernet() icmp_frame.type = myPkt.ethernet.IP_TYPE icmp_frame.dst = packet.src icmp_frame.src = packet.dst ip_pkt.payload = icmp_reply icmp_frame.payload = ip_pkt msg = of.ofp_packet_out() msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg.data = icmp_frame.pack() msg.in_port = event.port event.connection.send(msg) log.debug("%s pinged %s failed", str(ip_pkt.dstip), str(ip_pkt.srcip))
def destination_unreachable_icmp(self, packet, packet_in): log.debug("ICMP: destination unreachable") dst_unreach = pkt.unreach(payload=packet.payload) icmp_reply = pkt.icmp(type=pkt.TYPE_DEST_UNREACH, payload=dst_unreach) self.send_icmp_packet(icmp_reply, packet, packet_in)
def router_main(self): self.readfile() self.interfaces() firewallrules.import_rules() while True: try: dev,ts,pkt = self.net.recv_packet(timeout=0.5) except SrpyNoPackets: #log_debug("Timeout waiting for packets") update_token_bucket() toDel = [] icmpError = False for key in self.queue: #iterate packetObjects in the queue packetObject = self.queue[key] if (time.time() - packetObject.lastSend) > 1: if packetObject.retries != 0: #if retries are 0 packetObject.retries -= 1 #decrement retries by self.net.send_packet(packetObject.dev, packetObject.ARP_request) packetObject.lastSend = time.time() else: pkt = packetObject.pkt ipreply = pktlib.ipv4() interface = self.net.interface_by_name(dev) devIP = interface.ipaddr ipreply.srcip = devIP ipreply.dstip = pkt.payload.srcip # send back to source of packet that had TTL of 1 ipreply.ttl = 65 #create ICMPpkt icmppkt = pktlib.icmp() icmppkt.type = pktlib.TYPE_DEST_UNREACH icmppkt.code = pktlib.CODE_UNREACH_HOST icmppkt.payload = pktlib.unreach() icmppkt.payload.payload = pkt.dump()[:28] #link the two ipreply.protocol = ipreply.ICMP_PROTOCOL ipreply.set_payload(icmppkt) icmpError = True #link the two ipreply.protocol = ipreply.ICMP_PROTOCOL ipreply.set_payload(icmppkt) toDel.append(key) if icmpError: self.icmpError(ipreply, packetObject.pkt, packetObject.dev, self.net,packetObject.ip_header) for item in toDel: #print "deleting item" del self.queue[item] continue except SrpyShutdown: return #if ARP-packet (REQ or REPLY)------------------------------ arp_header = pkt.find("arp") if arp_header != None: #checks if ARP-packet if arp_header.opcode == pktlib.arp.REQUEST: #checks if is an ARP request if addr_check(): #fvalid address packet = self.create_arp_reply(arp_header, pkt) #creates reply self.net.send_packet(dev,packet) #sends reply elif arp_header.opcode == pktlib.arp.REPLY: #checks if is an ARP reply dstIP = arp_header.protodst interface = self.net.interface_by_name(dev) devIP = interface.ipaddr devMAC = interface.ethaddr srcMAC = arp_header.hwsrc srcIP = arp_header.protosrc if dstIP == devIP: #is this ARP reply meant for me dstMAC = srcMAC #flip because you now want to send it back srcMAC = devMAC self.MACaddresses[srcIP] = dstMAC #add newly MAC address to mac dictionary packetObject = self.queue[srcIP] #temporarily store packet ] if packetObject.ICMP == False: #if the packet is an IPv4 packet pkt = packetObject.pkt packet = self.create_eth_header(pkt, dstMAC, srcMAC) #add ethernet header to packet packet.payload.dstip = ipreply.dstip packet.payload.srcip = ipreply.srcip self.net.send_packet(dev,packet) elif packetObject.ICMP == True: #if packet is a ICMP packet packet = self.create_eth_header(packetObject.ip_header, dstMAC, srcMAC) #add ethernet header to packet packet.payload = packetObject.ip_header self.net.send_packet(dev,packet) del self.queue[srcIP] #delte packeet from queue else: print "Error." #drop packet since not valid ARP-packet else: x = firewallrules.allow(pkt) if x== True: #if IPv4 packet---------------------------------- ip_header = pkt.find("ipv4") icmpError = False if ip_header != None: #if IPv4packet! if ip_header.ttl == 1: #AF: if TTL value is 0 #create IP reply ipreply = pktlib.ipv4() interface = self.net.interface_by_name(dev) devIP = interface.ipaddr ipreply.srcip = devIP ipreply.dstip = pkt.payload.srcip ipreply.ttl = 64 #create ICMPpkt icmppkt = pktlib.icmp() icmppkt.type = pktlib.TYPE_TIME_EXCEED icmppkt.payload = pktlib.unreach() icmppkt.payload.payload = pkt.dump()[:28] #link the two ipreply.protocol = ipreply.ICMP_PROTOCOL ipreply.payload = icmppkt icmpError = True ip_header.ttl -= 1 dstIP = ip_header.dstip #destination IP addr of IPheader srcIP = ip_header.srcip interface = self.net.interface_by_name(dev) devIP = interface.ipaddr #packet sent to me------------------------------------- sentToMe = False for intf in self.net.interfaces(): if dstIP == intf.ipaddr: sentToMe = True if sentToMe: #if packet is for me icmp_header = pkt.find("icmp") if icmp_header != None: #need this to check if ping...not just ICMP oldPing = icmp_header.payload #creat ICMP reply to send out icmppkt = pktlib.icmp() #create ICMP header icmppkt.type = pktlib.TYPE_ECHO_REPLY ping = pktlib.echo() ping.id = oldPing.id ping.seq = oldPing.seq ping.payload = oldPing.payload icmppkt.payload = ping #create IP header ipreply = pktlib.ipv4() ipreply.srcip = devIP ipreply.dstip = srcIP ipreply.ttl = 64 ipreply.payload = icmppkt ipreply.protocol = 1 self.icmpError(ipreply, pkt, dev, self.net, ip_header) else: ipreply = pktlib.ipv4() interface = self.net.interface_by_name(dev) devIP = interface.ipaddr ipreply.srcip = devIP ipreply.dstip = ip_header.srcip ipreply.ttl = 65 #create ICMPpkt icmppkt = pktlib.icmp() icmppkt.type = pktlib.TYPE_DEST_UNREACH icmppkt.code = pktlib.CODE_UNREACH_PORT icmppkt.payload = pktlib.unreach() icmppkt.payload.payload = pkt.dump()[:28] #link the two ipreply.protocol = ipreply.ICMP_PROTOCOL ipreply.set_payload(icmppkt) self.icmpError(ipreply, pkt, dev, self.net,ip_header) #print packet not sent to me------------------------------------------ else: #if packet is not for me bestKey = self.in_forwarding_table(ip_header) if bestKey != None: #checks if a match in forwarding table if self.forwardingTable[bestKey][1]==None: #checks if nextHop none-directly reachable if dstIP in self.MACaddresses: #checks if already know MAC addr srcINTR = self.forwardingTable[bestKey][2] #get own mac address with ^ interface = self.net.interface_by_name(srcINTR) #get own mac address srcMAC = interface.ethaddr dstMAC = self.MACaddresses[dstIP] #gets MACaddr for dstIP packet = self.create_eth_header(pkt, dstMAC, srcMAC) #creates new packet to send dev = self.forwardingTable[bestKey][2] #gets net interface name for dstIP self.net.send_packet(dev,packet) #sends IPv4packet else: #if don't know mac addr IPinfo = self.forwardingTable[bestKey] packetObject = packets() packetObject.pkt = pkt packetObject.ip_header = ip_header packetObject.lastSend = time.time() self.queue[dstIP] = packetObject packet = self.create_arp_request(ip_header, packetObject, IPinfo, dstIP) #creates packet dev = IPinfo[2] #dev is the interface to send on packetObject.dev = dev self.net.send_packet(dev,packet) #send request else: #if next HOP is not None IPinfo = self.forwardingTable[bestKey] nextHopIP = self.forwardingTable[bestKey][1] nextHopDev = self.forwardingTable[bestKey][2] if nextHopIP in self.MACaddresses: #if already know MAC address srcINTR = self.forwardingTable[bestKey][2] #get own mac address with ^ interface = self.net.interface_by_name(srcINTR) #get own mac address srcMAC = interface.ethaddr dstMAC = self.MACaddresses[dstIP] #gets MACaddr for dstIP packet = self.create_eth_header(pkt, dstMAC, srcMAC) #creates new packet to send dev = self.forwardingTable[bestKey][2] #gets netinterface name for dstIP self.net.send_packet(packetObject.dev, packetObject.ARP_request) #sends IPv4packet else: #If don't know MAC address if icmpError: self.icmpError(ipreply, pkt, dev, self.net,ip_header) #send else: packetObject = packets() packetObject.pkt = pkt packetObject.ip_header = ip_header packetObject.lastSend = time.time() self.queue[ip_header.srcip] = packetObject packet = self.create_arp_request(ip_header, packetObject, IPinfo, nextHopIP) packetObject.dev = dev packet.payload.protosrc = ipreply.srcip packet.payload.protodst = ip_header.srcip packet.src = pkt.dst packet.payload.hwsrc = pkt.dst self.net.send_packet(dev, packetObject.ARP_request) #send request else: ipreply = pktlib.ipv4() interface = self.net.interface_by_name(dev) devIP = interface.ipaddr ipreply.srcip = devIP ipreply.dstip = ip_header.srcip #send back to source of packet that had TTL of 1 ipreply.ttl = 65 #create ICMPpkt icmppkt = pktlib.icmp() icmppkt.type = pktlib.TYPE_DEST_UNREACH icmppkt.code = pktlib.CODE_UNREACH_NET icmppkt.payload = pktlib.unreach() icmppkt.payload.payload = pkt.dump()[:28] #link the two ipreply.protocol = ipreply.ICMP_PROTOCOL ipreply.set_payload(icmppkt) #print "entering ICMP Error area" self.icmpError(ipreply, pkt, dev, self.net,ip_header)
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 log.debug(str(icmp_packet)+str(icmp_packet.payload.seq)) 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("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: 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)
def create_router(self, packet, packeti): if packet.type == pk.ethernet.ARP_TYPE: if packet.payload.opcode == pk.arp.REQUEST: log.debug('ARP REQUEST RECEIVED') reply = pk.arp() reply.opcode = pk.arp.REPLY reply.hwdst = packet.payload.hwsrc if str(packet.payload.protosrc) == '10.0.1.2' or str(packet.payload.protosrc) == '10.0.1.3': reply.hwsrc = adr.EthAddr('ac:ac:ac:ac:ac:bd') elif str(packet.payload.protosrc) == '10.0.2.2' or str(packet.payload.protosrc) == '10.0.2.3' or str(packet.payload.protosrc) == '10.0.2.4': reply.hwsrc = adr.EthAddr('13:13:13:13:13:66') reply.protosrc = packet.payload.protodst reply.protodst = packet.payload.protosrc e = pk.ethernet(type=pk.ethernet.ARP_TYPE,src=packet.dst,dst=packet.src) e.set_payload(reply) self.open_flow_func(packeti,0,e) log.debug('ARP REPLY SENT') else: log.debug('ARP REPLY') elif packet.type == pk.ethernet.IP_TYPE: ip_u = packet.payload if ip_u.protocol == pk.ipv4.ICMP_PROTOCOL: icmp_p = ip_u.payload log.debug(packet.dst) if str(packet.dst) == "ac:ac:ac:ac:ac:bd": #Find whether the host is available in the routing table if icmp_p.type == pk.TYPE_ECHO_REQUEST: log.debug('ICMP REQUEST RECEIVED') log.debug(ip_u.dstip) i = self.find_key(ip_u,1) if i!=None: log.debug('ICMP Reply Sent') #Get the payload from echo request ec = pk.echo() ec.seq = icmp_p.payload.seq + 1 ec.id = icmp_p.payload.id #Create an echo reply packet icmp_r = pk.icmp() icmp_r.type = pk.TYPE_ECHO_REPLY #Insert the echo payload into the reply packet icmp_r.set_payload(packet.find("icmp").payload) #Create an ipv4 packet and insert the ICMP ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip = ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL) ip_encap.set_payload(icmp_r) #Create an Ethernet packet and insert the IPV4 in it eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE,src =packet.dst,dst = packet.src) eth_encap.set_payload(ip_encap) self.open_flow_func(packeti,0,eth_encap) else: log.debug('ICMP DESTINATION UNREACHABLE') #Get the payload from echo request u = pk.unreach() u.payload = ip_u #Create an echo reply packet icmp_r = pk.icmp() icmp_r.type = pk.TYPE_DEST_UNREACH #Insert the echo payload into the reply packet icmp_r.payload = u #Create an ipv4 packet and insert the ICMP ip_encap = pk.ipv4() ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip=ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL) ip_encap.set_payload(icmp_r) #Create an Ethernet packet and insert the IPV4 in it eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE, src = packet.dst, dst = packet.src) eth_encap.set_payload(ip_encap) self.open_flow_func(packeti,0,eth_encap) elif str(packet.dst) == "13:13:13:13:13:66": #if icmp_p.type == pk.TYPE_ECHO_REQUEST: log.debug('ICMP REQUEST RECEIVED') i = self.find_key(ip_u,0) if i!=None: log.debug('ICMP Reply Sent') #Get the payload from echo request ec = pk.echo() ec.seq = icmp_p.payload.seq + 1 ec.id = icmp_p.payload.id #Create an echo reply packet icmp_r = pk.icmp() icmp_r.type = pk.TYPE_ECHO_REPLY #Insert the echo payload into the reply packet icmp_r.set_payload(packet.find("icmp").payload) #Create an ipv4 packet and insert the ICMP ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip = ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL) ip_encap.set_payload(icmp_r) #Create an Ethernet packet and insert the IPV4 in it eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE,src =packet.dst,dst = packet.src) eth_encap.set_payload(ip_encap) self.open_flow_func(packeti,0,eth_encap) else: log.debug('ICMP DESTINATION UNREACHABLE') #Get the payload from echo request u = pk.unreach() u.payload = ip_u #Create an echo reply packet icmp_r = pk.icmp() icmp_r.type = pk.TYPE_DEST_UNREACH #Insert the echo payload into the reply packet icmp_r.payload = u #Create an ipv4 packet and insert the ICMP ip_encap = pk.ipv4() ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip=ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL) ip_encap.set_payload(icmp_r) #Create an Ethernet packet and insert the IPV4 in it eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE, src = packet.dst, dst = packet.src) eth_encap.set_payload(ip_encap) self.open_flow_func(packeti,0,eth_encap) else: log.debug('ICMP DESTINATION UNREACHABLE') #Get the payload from echo request u = pk.unreach() u.payload = ip_u #Create an echo reply packet icmp_r = pk.icmp() icmp_r.type = pk.TYPE_DEST_UNREACH #Insert the echo payload into the reply packet icmp_r.payload = u #Create an ipv4 packet and insert the ICMP ip_encap = pk.ipv4() ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip=ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL) ip_encap.set_payload(icmp_r) #Create an Ethernet packet and insert the IPV4 in it eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE, src = packet.dst, dst = packet.src) eth_encap.set_payload(ip_encap) self.open_flow_func(packeti,0,eth_encap) else: j=0 #log.debug(packet.dst) if str(packet.dst) == "ac:ac:ac:ac:ac:bd": j = self.find_key(ip_u,1) if j!=None: p = self.rtable1[j][3] dsthw = self.rtable1[j][2] dsthw1 = adr.EthAddr(dsthw) packet.src = packet.dst packet.dst = dsthw1 self.open_flow_func(0,p,packet) elif str(packet.dst) == "13:13:13:13:13:66": j = self.find_key(ip_u,0) if j!=None: p = self.rtable2[j][3] dsthw = self.rtable2[j][2] dsthw1 = adr.EthAddr(dsthw) packet.src = packet.dst packet.dst = dsthw1 self.open_flow_func(0,p,packet) else: j = self.find_key(ip_u,2) if j!=None: p = self.rtable[j][3] dsthw = self.rtable2[j][2] dsthw1 = adr.EthAddr(dsthw) packet.src = packet.dst packet.dst = dsthw1 self.open_flow_func(0,p,packet) self.FlowMode( packeti, packeti.in_port)
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 ICMP_Request_handler(self, packet, packet_in): ip_packet = packet.payload icmp_segment = ip_packet.payload ipSrcAdd = self.route_table.get(str(ip_packet.srcip)) ipDstAdd = self.route_table.get(str(ip_packet.dstip)) if ipDstAdd != None: # router if str(packet.dst) == '00:00:00:00:00:11': if str(ip_packet.dstip) == '10.0.1.1': echo_segment = pkt.echo() echo_segment.seq = icmp_segment.payload.seq + 1 echo_segment.id = icmp_segment.payload.id #icmp packt|echo icmp_reply = pkt.icmp() icmp_reply.type = pkt.TYPE_ECHO_REPLY icmp_reply.payload = echo_segment #ip packet|icmp|echo ip_pack = pkt.ipv4() ip_pack.srcip = ip_packet.dstip ip_pack.dstip = ip_packet.srcip ip_pack.protocol = pkt.ipv4.ICMP_PROTOCOL ip_pack.payload = icmp_reply #frame|ip|icmp|echo ether_pack = pkt.ethernet() ether_pack.dst = packet.src ether_pack.src = packet.dst ether_pack.type = pkt.ethernet.IP_TYPE ether_pack.payload = ip_pack self.send_Packet(frame=ether_pack, out_port=packet_in.in_port) 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(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': #echo rely to source Router -> H5 if str(ip_packet.dstip) == '10.0.2.1': echo_segment = pkt.echo() echo_segment.seq = icmp_segment.payload.seq + 1 echo_segment.id = icmp_segment.payload.id #icmp packt|echo icmp_reply = pkt.icmp() icmp_reply.type = pkt.TYPE_ECHO_REPLY icmp_reply.payload = echo_segment #ip packet|icmp|echo ip_pack = pkt.ipv4() ip_pack.srcip = ip_packet.dstip ip_pack.dstip = ip_packet.srcip ip_pack.protocol = pkt.ipv4.ICMP_PROTOCOL ip_pack.payload = icmp_reply #frame|ip|icmp|echo ether_pack = pkt.ethernet() ether_pack.dst = packet.src ether_pack.src = packet.dst ether_pack.type = pkt.ethernet.IP_TYPE ether_pack.payload = ip_pack self.send_Packet(frame=ether_pack, out_port=packet_in.in_port) 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(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]) else: #unreach ICMP packet unreachPacket = pkt.unreach() unreachPacket.payload = packet.payload icmp_unreReply = pkt.icmp() icmp_unreReply.type = pkt.TYPE_DEST_UNREACH icmp_unreReply.payload = unreachPacket ip_unrePack = pkt.ipv4() ip_unrePack.srcip = ip_packet.dstip ip_unrePack.dstip = ip_packet.srcip ip_unrePack.protocol = pkt.ipv4.ICMP_PROTOCOL ip_unrePack.payload = icmp_unreReply ether_unrePack = pkt.ethernet() ether_unrePack.src = packet.dst ether_unrePack.dst = packet.src ether_unrePack.type = pkt.ethernet.IP_TYPE ether_unrePack.payload = ip_unrePack self.send_Packet(frame=ether_unrePack, out_port=packet_in.in_port)
def act_like_router(self, frame, packet_in, dpid): if frame.type == 0x0806: # ARP type packet = frame.payload network = 0 # arp request and in /30 subnet if packet.opcode == 1 and str(packet.protodst) in self.exterior: arp_data = pocket.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) log.debug("arp...") # arp reply and in /30 subnet elif (packet.opcode == 2) and str( packet.protodst) in self.exterior: self.arp_cache[packet.protosrc] = packet.hwsrc to_send = self.store.payload """ for nw in self.routing_table[dpid]: nw1 = self.routing_table[dpid][nw] if str(to_send.dstip) in nw1: network = nw break """ message = of.ofp_packet_out() my_port = self.routing_table[dpid][str(to_send.dstip)][3] action = of.ofp_action_output(port=my_port) 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[dpid][network][3])) log.debug("Flow Mode install Successfully") self.connection.send(message) """ self.store = None elif packet.protodst in self.interior: """ msg = of.ofp_packet_out() msg.data = frame.pack() my_port = self.routing_table[dpid][str(packet.protodst)][3] action = of.ofp_action_output(port = my_port) msg.actions.append(action) self.connection.send(msg) """ msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(frame) msg.data = packet_in action = of.ofp_action_output( port=self.routing_table[dpid][str(packet.protodst)][3]) msg.actions.append(action) self.connection.send(msg) elif frame.type == 0x0800: # IP type """ network = 0 for nw in self.interior: nw1 = nw if str(frame.payload.dstip) in nw1: network = nw break """ packet = frame.payload if str(packet.dstip) not in self.interior: # dst unreachable log.debug("dst %s is unreachable" % (frame.payload.dstip)) 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) # if ICMP type elif packet.protocol == 1 and packet.payload.type == 8 and str( packet.dstip) == self.exterior[dpid - 1]: data_icmp = packet.payload # if data_icmp.type == 8 and str(packet.dstip) in self.exterior: #if echo_request and dstip is in exterior 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 in self.dirconnex[dpid]: port_num = self.routing_table[dpid][str(packet.dstip)][3] if packet.dstip not in self.arp_cache: # mapping of dstip not present self.store = frame arp_type = arp( hwlen=6, hwdst=ETHER_BROADCAST, protodst=packet.dstip, hwsrc=addresses.EthAddr('FA:DE:DD:ED:AF:AA'), protosrc=addresses.IPAddr(self.routing_table[dpid][str( packet.dstip)][2])) 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[dpid][str( packet.dstip)][3])) message.in_port = packet_in.in_port self.connection.send(message) elif packet.dstip in self.arp_cache: # mapping present in arp cache message = of.ofp_packet_out() action = of.ofp_action_output( port=self.routing_table[dpid][str(packet.dstip)][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) """ else: # route to the next hop log.debug("the packet proceeds to the next hop") port_to_send = self.routing_table[dpid][str(packet.dstip)][3] next_ip = self.routing_table[dpid][str(packet.dstip)][0] msg = of.ofp_packet_out() action = of.ofp_action_output(port=port_to_send) frame.dst = ETHER_BROADCAST frame.src = addresses.EthAddr('FA:DE:DD:ED:AF:AA') msg.data = frame.pack() msg.actions.append(action) self.connection.send(msg) log.debug("IPv4 has been sent")
def create_echo_unreach(self, icmp_payload): echo = pkt.unreach() echo.payload = icmp_payload return echo
def ICMP_Request_handler(self, packet, packet_in): ip_packet = packet.payload icmp_segment = ip_packet.payload ipDstAdd = self.route_table.get(str(ip_packet.dstip)) #ICMP reach if ipDstAdd != None: #ICMP -> router if ipDstAdd[2] == 'R': log.debug("----------ICMP echo packet----------") #echo packet echo_segment = pkt.echo() echo_segment.seq = icmp_segment.payload.seq + 1 echo_segment.id = icmp_segment.payload.id #icmp packt|echo icmp_reply = pkt.icmp() icmp_reply.type = pkt.TYPE_ECHO_REQUEST icmp_reply.payload = echo_segment #ip packet|icmp|echo ip_pack = pkt.ipv4() ip_pack.srcip = ip_packet.dstip ip_pack.dstip = ip_packet.srcip ip_pack.protocol = pkt.ipv4.ICMP_PROTOCOL ip_pack.payload = icmp_reply #frame|ip|icmp|echo ether_pack = pkt.ethernet() ether_pack.dst = packet.src ether_pack.src = packet.dst ether_pack.type = pkt.ethernet.IP_TYPE ether_pack.payload = ip_pack self.send_Packet(frame=ether_pack, out_port=packet_in.in_port) elif ipDstAdd[2] == 'H': #router -> can reache ipadd #frame|original packet send to dst 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[1]) #ICMP unreach else: #log.debug("----------ICMP unreach----------") unreachPacket = pkt.unreach() unreachPacket.payload = packet.payload icmp_unreReply = pkt.icmp() icmp_unreReply.type = pkt.TYPE_DEST_UNREACH icmp_unreReply.payload = unreachPacket ip_unrePack = pkt.ipv4() ip_unrePack.srcip = ip_packet.dstip ip_unrePack.dstip = ip_packet.srcip ip_unrePack.protocol = pkt.ipv4.ICMP_PROTOCOL ip_unrePack.payload = icmp_unreReply ether_unrePack = pkt.ethernet() ether_unrePack.src = packet.dst ether_unrePack.dst = packet.src ether_unrePack.type = pkt.ethernet.IP_TYPE ether_unrePack.payload = ip_unrePack self.send_Packet(frame=ether_unrePack, out_port=packet_in.in_port)
def act_like_router (self, event, packet_in): """ Implement router-like behavior """ packet = event.parsed ipPacket = packet.payload icmpPacket = packet.payload.payload #self.IP_to_port[ipPacket.srcip] = packet_in.in_port self.mac_to_port[packet.src] = packet_in.in_port self.mac_to_port[EthAddr("00:00:00:00:00:01")] = 1 self.mac_to_port[EthAddr("00:00:00:00:00:02")] = 2 self.mac_to_port[EthAddr("12:12:12:12:12:12")] = 3 self.mac_to_port[EthAddr("00:00:00:00:00:03")] = 1 self.mac_to_port[EthAddr("00:00:00:00:00:04")] = 2 self.mac_to_port[EthAddr("12:12:12:12:12:12")] = 3 self.ARP_cache[IPAddr('10.0.1.100')] = EthAddr("00:00:00:00:00:01") self.ARP_cache[IPAddr('10.0.1.200')] = EthAddr("00:00:00:00:00:02") self.ARP_cache[IPAddr('10.0.2.100')] = EthAddr("00:00:00:00:00:03") self.ARP_cache[IPAddr('10.0.2.200')] = EthAddr("00:00:00:00:00:04") # self.rt_table["10.0.1.100/24"] =['10.0.1.100', 's1-eth1', '10.0.1.1', 1] # self.rt_table["10.0.2.100/24"] =['10.0.2.100', 's1-eth2', '10.0.2.1', 3] # self.rt_table["10.0.3.100/24"] =['10.0.3.100', 's1-eth3', '10.0.3.1', 2] self.IP_to_port[IPAddr('10.0.1.1')]=1 self.IP_to_port[IPAddr('10.0.1.1')]=2 self.IP_to_port[IPAddr('10.0.2.1')]=1 self.IP_to_port[IPAddr('10.0.2.1')]=2 self.s1_to_s2[IPAddr('10.0.1.100')] = IPAddr('10.0.1.1') self.s1_to_s2[IPAddr('10.0.1.200')] = IPAddr('10.0.1.1') self.s2_to_s1[IPAddr('10.0.2.100')] = IPAddr('10.0.2.1') self.s2_to_s1[IPAddr('10.0.2.200')] = IPAddr('10.0.2.1') if packet.type == pck.ethernet.ARP_TYPE: ip_add = ipPacket.protodst log.debug("arp packet: %s" % (ip_add)) else: ip_add = ipPacket.dstip log.debug("ip packet: %s" % (ip_add)) if ip_add in self.IP_to_port or ip_add in self.ARP_cache: if packet.type == pck.ethernet.ARP_TYPE: log.debug("Received an ARP packet") if ipPacket.opcode == pck.arp.REQUEST: log.debug(" ARP request packet with MAC: %s" % (packet.src)) log.debug(" ARP request packet with iP: %s" % (ipPacket.protosrc)) pck_ARP = pck.arp() pck_ARP.hwtype = ipPacket.hwtype pck_ARP.protype = ipPacket.prototype pck_ARP.hwlen = ipPacket.hwlen pck_ARP.protolen = ipPacket.protolen pck_ARP.hwsrc = EthAddr("12:12:12:12:12:12") pck_ARP.protosrc = ipPacket.protodst pck_ARP.protodst = ipPacket.protosrc pck_ARP.hwdst = ipPacket.hwsrc pck_ARP.opcode = pck.arp.REPLY pck_MAC = pck.ethernet() pck_MAC.type = pck.ethernet.ARP_TYPE pck_MAC.dst = ipPacket.hwsrc pck_MAC.src = EthAddr("12:12:12:12:12:12") pck_MAC.payload = pck_ARP log.debug(" Sending ARP reply with MAC: %s" % (pck_MAC.dst)) log.debug(" Sending ARP reply with IP: %s" % (pck_ARP.protodst)) msg_to_send = of.ofp_packet_out() msg_to_send.data = pck_MAC.pack() msg_to_send.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg_to_send.in_port = event.port event.connection.send(msg_to_send) elif packet.type == pck.ethernet.IP_TYPE: log.debug("Relaying ipv4 packet") log.debug(" Received packet from MAC: %s" % (packet.src)) log.debug(" Received packet from IP: %s" % (ipPacket.srcip)) pck_IP = pck.ipv4() pck_IP.protocol = ipPacket.protocol pck_IP.srcip = ipPacket.srcip pck_IP.dstip = ipPacket.dstip #pck_IP.srcip = self.int_to_ip[ipPacket.srcip] #pck_IP.dstip = self.int_to_ip[ipPacket.dstip] pck_IP.payload = packet.payload.payload pck_MAC = pck.ethernet() pck_MAC.type = pck.ethernet.IP_TYPE pck_MAC.dst = self.ARP_cache[ipPacket.dstip] pck_MAC.src = EthAddr("12:12:12:12:12:12") pck_MAC.payload = pck_IP # if ipPacket.dstip in self.IP_to_port: #self.resend_packet(pck_MAC, self.IP_to_port[ipPacket.dstip ]) log.debug(" Relaying packet to MAC: %s" % (pck_MAC.dst)) log.debug(" Relaying packet to IP: %s" % (pck_IP.dstip)) if packet_in.in_port == 3: port_out = self.mac_to_port[pck_MAC.dst] else: if ipPacket.dstip in self.s1_to_s2 and ipPacket.srcip in self.s1_to_s2 or ipPacket.dstip in self.s2_to_s1 and ipPacket.srcip in self.s2_to_s1: port_out = self.mac_to_port[pck_MAC.dst] log.debug("we got 1") else: port_out = 3 log.debug("we got 2") msg_to_send = of.ofp_packet_out() msg_to_send.data = pck_MAC.pack() msg_to_send.actions.append(of.ofp_action_output(port = port_out)) msg_to_send.in_port = event.port event.connection.send(msg_to_send) log.debug(" Relaying to Port: %s" % port_out) else: log.debug("Send host unavailable message") log.debug("Received packet with IP: %s" % ipPacket.srcip) log.debug("MAC: %s" % packet.src) log.debug(" RCVD IP packet with MAC source: %s" % (packet.src)) log.debug(" IP packet with iP source: %s" % (ipPacket.srcip)) log.debug(" IP packet with MAC dest: %s" % (packet.dst)) log.debug(" IP packet with iP dest: %s" % (ipPacket.dstip)) pck_pay = pck.unreach() pck_pay.payload = ipPacket pck_ICMP = pck.icmp() pck_ICMP.type = pck.TYPE_DEST_UNREACH pck_ICMP.code = pck.CODE_UNREACH_HOST pck_ICMP.payload = pck_pay pck_IP = pck.ipv4() pck_IP.protocol = pck.ipv4.ICMP_PROTOCOL pck_IP.srcip = ipPacket.dstip pck_IP.dstip = ipPacket.srcip pck_IP.payload = pck_ICMP pck_MAC = pck.ethernet() pck_MAC.type = pck.ethernet.IP_TYPE pck_MAC.dst = packet.src pck_MAC.src = packet.dst pck_MAC.payload = pck_IP msg_to_send = of.ofp_packet_out() msg_to_send.data = pck_MAC.pack() msg_to_send.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT)) msg_to_send.in_port = event.port event.connection.send(msg_to_send)
def act_like_router(self, packet, packet_in): #handle ARP Requests and replies etherPayload = packet.payload #the stripped ethFrame, contains ipv4 or arp packet src_mac = packet.src dst_mac = packet.dst if packet.type == pkt.ethernet.ARP_TYPE: src_ip = etherPayload.protosrc dst_ip = etherPayload.protodst if etherPayload.opcode == pkt.arp.REQUEST: print( "received ARP REQUEST checking if i have info on sender: " + str(src_mac)) if src_mac not in self.mac_to_port: print("sender mac unknown, adding to mac table...") self.mac_to_port[src_mac] = packet_in.in_port if src_ip not in self.arp_table: print("sender ip unknown, adding to arp table...") self.arp_table[src_ip] = src_mac if src_ip not in self.ip_to_port: print("sender ip unknown, adding to ip table...") self.ip_to_port[src_ip] = packet_in.in_port self.displayTables() #creating arp reply to send back arp_reply = pkt.arp() arp_reply.hwsrc = adr.EthAddr( "11:12:13:14:15:16") # fake mac in response arp_reply.hwdst = etherPayload.hwsrc arp_reply.opcode = pkt.arp.REPLY arp_reply.protosrc = etherPayload.protodst arp_reply.protodst = etherPayload.protosrc # encapsulate in ethernet frame now ether = pkt.ethernet() ether.type = pkt.ethernet.ARP_TYPE ether.dst = packet.src ether.src = packet.dst ether.payload = arp_reply #sending packet to switch self.resend_packet(ether, packet_in.in_port) elif packet.type == pkt.ethernet.IP_TYPE: if etherPayload.protocol == pkt.ipv4.ICMP_PROTOCOL: icmp_packet = etherPayload.payload src_ip = etherPayload.srcip dst_ip = etherPayload.dstip k = 0 #subnet holder if icmp_packet.type == pkt.TYPE_ECHO_REQUEST: if src_mac not in self.mac_to_port: print("sender mac unknown, adding to mac table...") self.mac_to_port[src_mac] = packet_in.in_port if src_ip not in self.arp_table: print("sender ip unknown, adding to arp table...") self.arp_table[src_ip] = src_mac if src_ip not in self.ip_to_port: print("sender ip unknown, adding to ip table...") self.ip_to_port[src_ip] = packet_in.in_port self.displayTables() for subnet in self.routing_table: if dst_ip.inNetwork(subnet): k = subnet if k != 0: #create ping reply # create echo fields ech = pkt.echo() # echo contained in pkt.icmp ech.id = icmp_packet.payload.id ech.seq = icmp_packet.payload.seq + 1 # encapsulates in icmp icmp_reply = pkt.icmp() icmp_reply.type = pkt.TYPE_ECHO_REPLY # code 0 icmp_reply.payload = ech # encapsulates in ipv4 ip_p = pkt.ipv4() ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL ip_p.srcip = dst_ip ip_p.dstip = src_ip ip_p.payload = icmp_reply # encapsulates in ethernet eth_p = pkt.ethernet() eth_p.type = pkt.ethernet.IP_TYPE eth_p.src = packet.dst eth_p.dst = packet.src eth_p.payload = ip_p msg = of.ofp_packet_out() msg.data = eth_p.pack() action = of.ofp_action_output(port=packet_in.in_port) msg.actions.append(action) self.connection.send(msg) print("echo Reply sent!") self.createflow(packet_in, eth_p, packet_in.in_port) else: print("ICMP destination unreachable") unr = pkt.unreach() unr.payload = etherPayload 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() action = of.ofp_action_output(port=packet_in.in_port) msg.actions.append(action) self.connection.send(msg) print("echo Unreachable Reply sent!") self.createflow(packet_in, eth_p, packet_in.in_port) #other type of ip packet maybe udp or tcp else: src_ip = etherPayload.srcip dst_ip = etherPayload.dstip if dst_ip in self.ip_to_port and dst_ip in self.arp_table: print("received other type of packet sending reply...") out_port = self.ip_to_port[dst_ip] eth_dest = self.arp_table[dst_ip] msg = of.ofp_packet_out() packet.src = packet.dst #since who received the packet is sending the reply set src = dst packet.dst = adr.EthAddr(eth_dest) msg.data = packet.pack() action = of.ofp_action_output(port=out_port) msg.actions.append(action) self.connection.send(msg) self.createflow(packet_in, packet, out_port) else: print("who do i send this to I am switch: " + str(self.connection.dpid)) print("packet src ip: " + str(src_ip) + " to: " + str(dst_ip)) self.resend_packet(packet, of.OFPP_ALL) self.createflow(packet_in, packet, of.OFPP_ALL)
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 create_router(self, packet, packeti): if packet.type == pk.ethernet.ARP_TYPE: if packet.payload.opcode == pk.arp.REQUEST: log.debug('ARP REQUEST RECEIVED') reply = pk.arp() reply.opcode = pk.arp.REPLY reply.hwdst = packet.payload.hwsrc reply.hwsrc = adr.EthAddr('AC:AC:AC:AC:AC:BD') reply.protosrc = packet.payload.protodst reply.protodst = packet.payload.protosrc e = pk.ethernet(type=pk.ethernet.ARP_TYPE,src=packet.dst,dst=packet.src) e.set_payload(reply) self.open_flow_func(packeti,0,e) log.debug('ARP REPLY SENT') else: log.debug('ARP REPLY') elif packet.type == pk.ethernet.IP_TYPE: ip_u = packet.payload if ip_u.protocol == pk.ipv4.ICMP_PROTOCOL: icmp_p = ip_u.payload #Find whether the host is available in the routing table if icmp_p.type == pk.TYPE_ECHO_REQUEST: log.debug('ICMP REQUEST RECEIVED') n = self.find_key(ip_u) log.debug(n) if n!=None: log.debug('ICMP Reply Sent') icmp_r = pk.icmp() icmp_r.type = pk.TYPE_ECHO_REPLY #Insert the echo payload into the reply packet icmp_r.set_payload(packet.find("icmp").payload) #Create an ipv4 packet and insert the ICMP ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip = ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL) ip_encap.set_payload(icmp_r) #Create an Ethernet packet and insert the IPV4 in it eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE,src =packet.dst,dst = packet.src) eth_encap.set_payload(ip_encap) self.open_flow_func(packeti,0,eth_encap) #Get the payload from echo request else: u = pk.unreach() u.payload = ip_u log.debug("Destination Unreachable") #Create an echo reply packet icmp_r = pk.icmp() icmp_r.type = pk.TYPE_DEST_UNREACH icmp_r.code = pk.CODE_UNREACH_HOST #Insert the echo payload into the reply packet icmp_r.payload = u #Create an ipv4 packet and insert the ICMP ip_encap = pk.ipv4() ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip=ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL) ip_encap.set_payload(icmp_r) #Create an Ethernet packet and insert the IPV4 in it eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE, src = packet.dst, dst = packet.src) eth_encap.set_payload(ip_encap) self.open_flow_func(packeti,0,eth_encap) else: j=0 j = self.find_key(ip_u) if j!=0: dsthw = self.rtable[j][3] p = self.rtable[j][4] dsthw1 = adr.EthAddr(dsthw) packet.src = packet.dst packet.dst = dsthw1 self.open_flow_func(0,p,packet) self.FlowMode( packeti, packeti.in_port)