def handle_reachable(self, packet, packet_in): # echo echo = pkt.echo() echo.seq = packet.payload.payload.payload.seq + 1 echo.id = packet.payload.payload.payload.id # icmp pakcet icmp_packet = pkt.icmp() icmp_packet.type = pkt.TYPE_ECHO_REPLY icmp_packet.payload = echo # ip packet 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 # ethernet 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 reachable_send(self, packet, packet_in): msgEcho = pkt.echo() msgEcho.seq = packet.payload.payload.payload.seq + 1 msgEcho.id = packet.payload.payload.payload.id #encapsulate the reachable ICMP packet icmpReachable = pkt.icmp() icmpReachable.type = pkt.TYPE_ECHO_REPLY icmpReachable.payload = msgEcho icmpPkt = pkt.ipv4() icmpPkt.srcip = packet.payload.dstip icmpPkt.dstip = packet.payload.srcip icmpPkt.protocol = pkt.ipv4.ICMP_PROTOCOL icmpPkt.payload = icmpReachable #encapsulate the packet into frame icmpFrame2 = pkt.ethernet() icmpFrame2.type = pkt.ethernet.IP_TYPE icmpFrame2.dst = packet.src icmpFrame2.src = packet.dst icmpFrame2.payload = icmpPkt msg = of.ofp_packet_out() msg.data = icmpFrame2.pack() action = of.ofp_action_output(port=packet_in.in_port) msg.actions.append(action) self.connection.send(msg)
def icmp_echo_reply(self, icmp_data, packet, packet_in): log.debug("ICMP: router get request") icmp_echo = pkt.echo(seq=icmp_data.payload.seq + 1, id=icmp_data.payload.id) icmp_reply = pkt.icmp(type=pkt.TYPE_ECHO_REPLY, payload=icmp_echo) self.send_icmp_packet(icmp_reply, packet, packet_in)
def tests(): f = Firewall() ip1 = ipv4() ip1.srcip = IPAddr("172.16.42.1") ip1.dstip = IPAddr("10.0.0.2") ip1.protocol = 17 xudp1 = udp() xudp1.srcport = 53 xudp1.dstport = 53 xudp1.payload = "Hello, world" xudp1.len = 8 + len(xudp1.payload) ip1.payload = xudp1 ip2 = ipv4() ip2.srcip = IPAddr("172.16.40.1") ip2.dstip = IPAddr("10.0.0.1") ip2.protocol = ip2.ICMP_PROTOCOL icmppkt = icmp() icmppkt.type = pktlib.TYPE_ECHO_REQUEST ping = pktlib.echo() ping.id = 5 ping.seq = 10 icmppkt.payload = ping ip2.payload = icmppkt ip3 = ipv4() ip3.srcip = IPAddr("172.16.38.0") ip3.dstip = IPAddr("10.0.0.5") ip3.protocol = ip2.ICMP_PROTOCOL icmppkt = icmp() icmppkt.type = pktlib.TYPE_ECHO_REQUEST ping = pktlib.echo() ping.id = 5 ping.seq = 10 icmppkt.payload = ping ip3.payload = icmppkt i=0 while i<10: print "+"*70 f.update_token_buckets() f.allow(ip2) f.allow(ip3) time.sleep(0.5) i+=1
def makeEcho(self, request): icmppkt = pktlib.icmp() icmppkt.type = pktlib.TYPE_ECHO_REPLY reply = pktlib.echo() reply.id = request.id reply.seq = request.seq reply.payload = request.payload icmppkt.payload = reply return icmppkt
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 __echo_request(srcip, dstip, srcmac, participant, idseq, seq, switch=1, payload="dummy payload"): """Constructs an icmp echo request packet and injects into network""" pport = participant.phys_ports[0] r = echo(id=idseq, seq=seq) r.set_payload(payload) i = icmp(type=8, code=0) i.set_payload(r) ip = ipv4(protocol=ICMP, srcip=IPAddr(srcip), dstip=IPAddr(dstip)) ip.set_payload(i) e = ethernet(type=IP_TYPE, src=srcmac, dst=str(pport.mac)) e.set_payload(ip) pkt = Packet() d = dict(protocol=ICMP, ethtype=IP_TYPE, switch=switch, inport=-1, outport=pport.id_, srcport=8, dstport=0, srcip=srcip, srcmac=srcmac, dstip=dstip, dstmac=str(pport.mac), tos=0, raw=e.pack()) pkt = pkt.modifymany(d) EchoSender.net.inject_packet(pkt)
def _do_ctl2(event): def errf(msg, *args): raise RuntimeError(msg % args) args = event.args def ra(low, high=None): if high is None: high = low if len(args) < low or len(args) > high: raise RuntimeError("Wrong number of arguments") return False def get_sw(arg, fail=True): r = _switches.get(arg) if r is not None: return r try: dpid = str_to_dpid(arg) except Exception: raise RuntimeError("No such switch as %s" % (arg, )) r = core.datapaths.get(dpid) if r is None and fail: raise RuntimeError("No such switch as %s" % (dpid_to_str(dpid), )) return r try: if event.first == "add-port": ra(1, 2) if len(event.args) == 1 and len(_switches) == 1: sw = _switches[_switches.keys()[0]] p = args[0] else: ra(2) sw = get_sw(args[0]) p = args[1] sw.add_interface(p, start=True, on_error=errf) elif event.first == "del-port": ra(1, 2) if len(event.args) == 1: for sw in _switches.values(): for p in sw.ports.values(): if p.name == event.args[0]: sw.remove_interface(event.args[0]) return raise RuntimeError("No such interface") sw = _switches[event.args[0]] sw.remove_interface(args[1]) elif event.first == "show": ra(0) s = [] for sw in _switches.values(): s.append("Switch %s" % (sw.name, )) for no, p in sw.ports.iteritems(): stats = sw.port_stats[no] s.append(" %3s %-16s rx:%-20s tx:%-20s" % (no, p.name, "%s (%s)" % (stats.rx_packets, stats.rx_bytes), "%s (%s)" % (stats.tx_packets, stats.tx_bytes))) return "\n".join(s) elif event.first == "show-table": ra(0, 1) sw = None if len(args) == 1: sw = get_sw(args[0]) s = [] for switch in _switches.values(): if sw is None or switch is sw: s.append("== " + switch.name + " ==") for entry in switch.table.entries: s.append(entry.show()) return "\n".join(s) elif event.first == "wire-port": # Wire a virtual port to a channel: wire-port [sw] port channel ra(2, 3) if len(event.args) == 2 and len(_switches) == 1: sw = _switches[_switches.keys()[0]] p = args[0] c = args[1] else: ra(3) sw = get_sw(args[0]) p = args[1] c = args[2] for port in sw.ports.values(): if port.name == p: px = sw.px.get(port.port_no) if not isinstance(px, VirtualPort): raise RuntimeError("Port is not a virtual port") px.channel = c return raise RuntimeError("No such interface") elif event.first == "unwire-port": # Unhook the virtual port: unwire-port [sw] port ra(1, 2) if len(event.args) == 1 and len(_switches) == 1: sw = _switches[_switches.keys()[0]] p = args[0] else: ra(2) sw = get_sw(args[0]) p = args[1] for port in sw.ports.values(): if port.name == p: px = sw.px.get(port.port_no) if not isinstance(px, VirtualPort): raise RuntimeError("Port is not a virtual port") px.channel = None return raise RuntimeError("No such interface") elif event.first == "sendraw": # sendraw sw src-port <raw hex bytes> if len(args) < 3: ra(3) sw = get_sw(args[0]) p = args[1] data = [] for x in args[2:]: x = x.strip() #print "<",x,">" if len(x) < 2: data.append(int(x, 16)) else: assert len(x) & 1 == 0 for y, z in zip(x[::2], x[1::2]): data.append(int(y + z, 16)) data = "".join(chr(x) for x in data) for port in sw.ports.values(): if port.name == p: px = sw.px.get(port.port_no) sw._pcap_rx(px, data, 0, 0, len(data)) return raise RuntimeError("No such interface") elif event.first == "ping": # ping [sw] dst-mac dst-ip [-I src-ip] [--port src-port] # [-s byte-count] [-p pad] [-t ttl] from pox.lib.addresses import EthAddr, IPAddr kvs = dict(s=(int, 56), p=(str, chr(0x42)), port=(str, ""), I=(IPAddr, IPAddr("1.1.1.1")), t=(int, 64)) ai = list(event.args) ai.append(None) args[:] = [] skip = False for k, v in zip(ai[:-1], ai[1:]): if skip: skip = False continue if not k.startswith("-"): args.append(k) continue k = k.lstrip("-").replace("-", "_") if "=" in k: k, v = k.split("=", 1) else: if v is None: raise RuntimeError("Expected argument for '%s'" % (k, )) skip = True if k not in kvs: raise RuntimeError("Unknown option '%s'" % (k, )) kvs[k] = (kvs[k][0], kvs[k][0](v)) kvs = {k: v[1] for k, v in kvs.items()} ra(2, 3) pad = (kvs['p'] * kvs['s'])[:kvs['s']] if len(args) == 2 and len(_switches) == 1: sw = _switches[_switches.keys()[0]] mac, ip = args else: ra(3) sw = get_sw(args[0]) mac, ip = args[1:] mac = EthAddr(mac) ip = IPAddr(ip) srcport = kvs['port'] for p in sw.ports.values(): if srcport == "" or p.name == srcport: echo = pkt.echo() echo.payload = pad icmp = pkt.icmp() icmp.type = pkt.TYPE_ECHO_REQUEST icmp.payload = echo # Make the IP packet around it ipp = pkt.ipv4() ipp.protocol = ipp.ICMP_PROTOCOL ipp.srcip = kvs['I'] ipp.dstip = ip ipp.ttl = kvs['t'] ipp.payload = icmp # Ethernet around that... e = pkt.ethernet() e.src = p.hw_addr e.dst = mac e.type = e.IP_TYPE e.payload = ipp data = e.pack() px = sw.px.get(p.port_no) sw._pcap_rx(px, data, 0, 0, len(data)) return raise RuntimeError("No such interface") else: raise RuntimeError("Unknown command") except Exception as e: log.exception("While processing command") return "Error: " + str(e)
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 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 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, 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 create_echo_reply(self, icmp_payload): echo = pkt.echo() echo.seq = icmp_payload.seq + 1 echo.id = icmp_payload.id return echo
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 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, 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 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)