def arp_request(self, datapath, ip, port): p = Packet() (port_ip, port_mask, port_mac) = self.ports.get_port(port) p.add_protocol(ethernet.ethernet(src=port_mac, dst='ff:ff:ff:ff:ff:ff', ethertype=ether.ETH_TYPE_ARP)) p.add_protocol(arp.arp(opcode=arp.ARP_REQUEST, src_mac=port_mac,src_ip=port_ip, dst_ip=ip)) self.send_packet(datapath,port,p)
def packet_in_handler(self, ev): """ Routing simplified for prototyping!!! Only works with Topology of testbed0/mininet_multi_switches_ipv4.py :param ev: :return: """ msg = ev.msg datapath = msg.datapath inPort = msg.match['in_port'] packet = Packet(msg.data) etherFrame = packet.get_protocol(ethernet) if etherFrame.ethertype == ether.ETH_TYPE_LLDP: # ignore lldp packet return if etherFrame.ethertype == ether.ETH_TYPE_ARP: self.receive_arp(datapath, packet, etherFrame, inPort) elif etherFrame.ethertype == ether.ETH_TYPE_IP: self.receive_ip(datapath, packet, etherFrame, inPort) else: LOG.debug("receive Unknown packet %s => %s (port%d)" % (etherFrame.src, etherFrame.dst, inPort)) self.print_etherFrame(etherFrame) LOG.debug("Drop packet") return 1 return 0
def receive_icmp(self, datapath, packet, port): ip_packet = packet.get_protocol(ipv4.ipv4) icmp_packet = packet.get_protocol(icmp.icmp) if icmp_packet.type == 8: # Echo request dst_mac = self.arpcache.get_mac(ip_packet.src, port) ip_data = self.ports.get_ip(ip_packet.dst) if (ip_data == None): LOG.debug("ICMP not for router") return 0 (ip_addr,mask,mac_addr) = self.ports.get_port(port) # Routing e = ethernet.ethernet(dst_mac, mac_addr, ether.ETH_TYPE_IP) ip = ipv4.ipv4(src= ip_packet.dst, dst=ip_packet.src, proto= inet.IPPROTO_ICMP,ttl=64) echo_new = icmp.echo(icmp_packet.data.id, icmp_packet.data.seq, icmp_packet.data.data) icmp_new = icmp.icmp(type_=0, code=0, data=echo_new) p = Packet() p.add_protocol(e) p.add_protocol(ip) p.add_protocol(icmp_new) self.send_packet(datapath,port, p) LOG.debug("ICMP for router") return 1 return 0
def test_Packet_in_2_icmpEcho1(self): print "*** Case2: HOST2のMAC未学習の時、HOST1からICMP Echoを受信 ***" sr = SimpleForward() dstMac = ROUTER_MACADDR1 srcMac = HOST_MACADDR1 srcIp = HOST_IPADDR1 dstIp = HOST_IPADDR2 targetMac = dstMac targetIp = dstIp ttl = 64 datapath = _Datapath() e = ethernet(dstMac, srcMac, ether.ETH_TYPE_IP) iph = ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, srcIp, dstIp) echo = icmp.echo(1, 1, 'unit test') icmph = icmp.icmp(8, 0, 0, echo) p = Packet() p.add_protocol(e) p.add_protocol(iph) p.add_protocol(icmph) p.serialize() packetIn = OFPPacketIn(datapath, match=OFPMatch(in_port=1), data=buffer(p.data)) ev = ofp_event.EventOFPPacketIn(packetIn) result = sr.packet_in_handler(ev) self.assertEqual(result, 1) print ""
def packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto inPort = msg.match['in_port'] packet = Packet(msg.data) etherFrame = packet.get_protocol(ethernet) if etherFrame.ethertype == ether.ETH_TYPE_ARP: arpPacket = packet.get_protocol(arp) if arpPacket.dst_ip != OUTER_IPADDR and arpPacket.dst_ip != INNER_IPADDR: LOG.debug("Miss: This ARP packet is not for me.") return 1 arpPacket = packet.get_protocol(arp) self.receive_arp(datapath, packet, etherFrame, inPort) return 0 elif etherFrame.ethertype == ether.ETH_TYPE_IP: ipPacket = packet.get_protocol(ipv4) if ipPacket.dst != OUTER_IPADDR: LOG.debug("Miss: This IP packet is not for me.") return 1 self.receive_ip(datapath, packet, etherFrame, inPort) return 1 else: LOG.debug("receive Unknown packet %s => %s (port%d)" % (etherFrame.src, etherFrame.dst, inPort)) self.print_etherFrame(etherFrame) LOG.debug("Drop packet") return 2
def send_arp(self, datapath, opcode, srcMac, srcIp, dstMac, dstIp, outPort, RouteDist=None): if opcode == 1: self.portInfo[outPort] = PortTable(outPort, srcIp, srcMac, RouteDist) targetMac = "00:00:00:00:00:00" targetIp = dstIp elif opcode == 2: targetMac = dstMac targetIp = dstIp e = ethernet(dstMac, srcMac, ether.ETH_TYPE_ARP) a = arp(1, 0x0800, 6, 4, opcode, srcMac, srcIp, targetMac, targetIp) p = Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() actions = [datapath.ofproto_parser.OFPActionOutput(outPort, 0)] out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=p.data) datapath.send_msg(out) return 0
def send_arp(datapath, opcode, source_mac, source_ip, destination_mac, destination_ip, out_port): in_port = datapath.ofproto.OFPP_CONTROLLER e = ethernet(destination_mac, source_mac, ether.ETH_TYPE_ARP) a = arp( ARP_HW_TYPE_ETHERNET, ether.ETH_TYPE_IP, 6, # ethernet mac address length 4, # ipv4 address length opcode, source_mac, source_ip, destination_mac, destination_ip) p = Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() actions = [datapath.ofproto_parser.OFPActionOutput(out_port, 0)] out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=0xffffffff, in_port=in_port, actions=actions, data=p.data) datapath.send_msg(out)
def find_mac(self, datapath, etherFrame, msg): #Almacena el puerto y el siguiente salto (next_hop, port) = self.find_in_routingTable(ipPacket.dst) if next_hop in self.ipToMac.keys(): #Si está dentro de la tabla de ips y macs se envía. match = datapath.ofproto_parser.OFPMatch(eth_dst=self.ipToMac[next_hop]) actions = [datapath.ofproto_parser.OFPActionOutput(port)] self.add_flow(datapath, 0, match, actions) self.insertar_flujo(msg=msg, mac=self.ipToMac[next_hop], port=port, mod=1) else: #Si no está dentro de la tabla se construye un paquete ARP para averiguar su MAC # print "---- NEXT_HOP -----", next_hop e = ethernet.ethernet(src=etherFrame.dst, ethertype=ether.ETH_TYPE_ARP) a = arp.arp(opcode=arp.ARP_REQUEST, src_ip=self.ports_to_ips[port-1][0], src_mac=etherFrame.src, dst_ip=next_hop) puerto = etherFrame.src p = Packet() p.add_protocol(e) p.add_protocol(a) if next_hop not in self.dict_pendientes: self.dict_pendientes[next_hop] = [] self.dict_pendientes[next_hop] = self.dict_pendientes[next_hop] + [(msg, port, None, None)] self.send_packet(datapath=datapath, port=port, packet=p)
def packet_in(self, event): """ Handles packets sent to the controller.""" msg = event.msg packet = Packet(msg.data) self.packet_in_events.append(packet) # self.logger.info("packet: {}".format(msg)) # Let's keep some counts on the types of packets received ether = packet.get_protocol(ryu.lib.packet.ethernet.ethernet) ipv4 = packet.get_protocol(ryu.lib.packet.ipv4.ipv4) udp = packet.get_protocol(ryu.lib.packet.udp.udp) icmp = packet.get_protocol(ryu.lib.packet.icmp.icmp) if not ether: return ether_type = ether.ethertype self.packet_in_types[ether_type] = self.packet_in_types.get(ether_type) + 1 # Might want to add code here to extract more info from packets # Now let's see if we intercepted a UDP packet if ipv4: self.logger.info("Intercepted a packet from: {} to {}".format( ipv4.src, ipv4.dst)) if udp: self.logger.info("Intercepted UDP packet with source port {} and dest port {}".format( udp.src_port, udp.dst_port)) if icmp: self.logger.info("Intercepted ICMP packet from {} to {}".format(ipv4.src, ipv4.dst))
def test_Packet_in_1_arpRequest(self): print "*** Case1: HOST1からARP Request受信 ***" sr = SimpleForward() dstMac = "ff:ff:ff:ff:ff:ff" srcMac = HOST_MACADDR1 srcIp = HOST_IPADDR1 dstIp = ROUTER_IPADDR1 targetMac = dstMac targetIp = dstIp datapath = _Datapath() e = ethernet(dstMac, srcMac, ether.ETH_TYPE_ARP) a = arp(1, 0x0800, 6, 4, 1, srcMac, srcIp, targetMac, targetIp) p = Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() packetIn = OFPPacketIn(datapath, match=OFPMatch(in_port=1), data=buffer(p.data)) ev = ofp_event.EventOFPPacketIn(packetIn) result = sr.packet_in_handler(ev) self.assertEqual(result, 0) print ""
def packet_in_handler(self, ev): #Qué hace el router cuando le llegua un paquete #print('ENTRO EN LA RUTINA') msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto in_port = msg.match['in_port'] packet = Packet(msg.data) eth = packet.get_protocol(ethernet.ethernet) ethertype = packet.get_protocol(ethernet.ethernet) print "PAQUETE: \n", packet src = eth.src #print(src) dst = eth.dst #sdgsa self.mac_to_port[src] = in_port #print(1) if eth.ethertype == ether.ETH_TYPE_ARP: #Si se trata de un paquete ARPÇ self.receive_arp(datapath, packet, ethertype, in_port) elif eth.ethertype == ether.ETH_TYPE_IP: #Si se trata de un paquete IP #print('paquete ip') self.receive_ip(datapath, packet, ethertype, in_port, msg)
def test_Packet_in_3_arpReply2(self): print "*** Case3: HOST1のMAC学習済の時、HOST2からARP Replyを受信 ***" sr = SimpleForward() sr.HOST_MACADDR1 = HOST_MACADDR1 sr.HOST_MACADDR2 = HOST_MACADDR2 dstMac = ROUTER_MACADDR2 srcMac = HOST_MACADDR2 srcIp = HOST_IPADDR2 dstIp = ROUTER_IPADDR2 targetMac = dstMac targetIp = dstIp datapath = _Datapath() e = ethernet(dstMac, srcMac, ether.ETH_TYPE_ARP) a = arp(1, 0x0800, 6, 4, 2, srcMac, srcIp, targetMac, targetIp) p = Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() packetIn = OFPPacketIn(datapath, match=OFPMatch(in_port=2), data=buffer(p.data)) ev = ofp_event.EventOFPPacketIn(packetIn) result = sr.packet_in_handler(ev) self.assertEqual(result, 0) print ""
def test_20_check_withdrawal_2(self): g1 = self.gobgp g2 = self.quaggas['g2'] dumpfile = g2.start_tcpdump() g1.add_route('10.40.0.0/24') time.sleep(1) paths = g2.get_global_rib('10.40.0.0/24') self.assertTrue(len(paths) == 1) g1.local('gobgp global rib del 10.40.0.0/24') time.sleep(1) paths = g2.get_global_rib('10.40.0.0/24') self.assertTrue(len(paths) == 0) g2.stop_tcpdump() time.sleep(1) cnt = 0 for pkt in pcap.Reader(open(dumpfile)): last = Packet(pkt[1]).protocols[-1] if type(last) == str: pkt = BGPMessage.parser(last)[0] if type(pkt) == BGPUpdate: cnt += len(pkt.withdrawn_routes) self.assertTrue(cnt == 1)
def send_arp(self, datapath, opcode, src_mac, src_ip, dst_mac, dst_ip, out_port): if opcode == 1: # ARP request target_mac = "00:00:00:00:00:00" target_ip = dst_ip elif opcode == 2: # ARP reply target_mac = dst_mac target_ip = dst_ip e = ethernet.ethernet(dst_mac, src_mac, ether.ETH_TYPE_ARP) a = arp.arp(1, 0x0800, 6, 4, opcode, src_mac, src_ip, target_mac, target_ip) p = Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() actions = [datapath.ofproto_parser.OFPActionOutput(out_port, 0)] out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=p.data) datapath.send_msg(out)
def _build_vlan(self): src_mac = mac.haddr_to_bin('00:07:0d:af:f4:54') dst_mac = mac.haddr_to_bin('00:00:00:00:00:00') ethertype = ether.ETH_TYPE_8021Q e = ethernet(dst_mac, src_mac, ethertype) version = 4 header_length = 20 tos = 0 total_length = 24 identification = 0x8a5d flags = 0 offset = 1480 ttl = 64 proto = inet.IPPROTO_ICMP csum = 0xa7f2 src = int(netaddr.IPAddress('131.151.32.21')) dst = int(netaddr.IPAddress('131.151.32.129')) option = 'TEST' ip = ipv4(version, header_length, tos, total_length, identification, flags, offset, ttl, proto, csum, src, dst, option) p = Packet() p.add_protocol(e) p.add_protocol(self.v) p.add_protocol(ip) p.serialize() return p
def packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto inPort = msg.match['in_port'] dpid = datapath.id self.ip_to_mac.setdefault(dpid, {}) packet = Packet(msg.data) etherFrame = packet.get_protocol(ethernet) srcMAC = etherFrame.src if etherFrame.ethertype == ether.ETH_TYPE_ARP: self.receive_arp(datapath, packet, etherFrame, inPort) return 0 elif etherFrame.ethertype == ether.ETH_TYPE_IP: ipPacket = packet.get_protocol(ipv4) srcIp = ipPacket.src if (ipPacket.proto == IPPROTO_ICMP) & (self.ip_to_mac[dpid][srcIp] == srcMAC): self.receive_icmp(datapath, packet, etherFrame, inPort) return 0 elif (ipPacket.proto == IPPROTO_ICMP): self.send_arp(datapath, ARP_REQUEST, ROUTER_MACADDR1, ROUTER_IPADDR1, "ff:ff:ff:ff:ff:ff", srcIp, inPort) else: LOG.debug("Drop packet") return 1
def send_icmp(self, datapath, etherFrame, ipPacket, icmpPacket, inPort): e = ethernet(dst=etherFrame.src, src=etherFrame.dst, ethertype=ether.ETH_TYPE_IP) a = ipv4(version=ipPacket.version, header_length=ipPacket.header_length, tos=ipPacket.tos, total_length=ipPacket.total_length, identification=ipPacket.identification, flags=ipPacket.flags, offset=ipPacket.offset, ttl=ipPacket.ttl, proto=ipPacket.proto, csum=ipPacket.csum, src=ipPacket.dst, dst=ipPacket.src, option=None) b = icmp(type_=ICMP_ECHO_REPLY, code=icmpPacket.code, csum=icmpPacket.csum, data=icmpPacket.data) p = Packet() p.add_protocol(e) p.add_protocol(a) p.add_protocol(b) p.serialize() actions = [datapath.ofproto_parser.OFPActionOutput(inPort, 0)] out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=p.data) datapath.send_msg(out)
def _send_packet(self, ev): """ First install drop flows if they are not there yet. Then send the packet through the switch :param ev: EventSendPacket """ self.install_drop_flows() pkt = ev.packet imsi = ev.imsi if isinstance(pkt, (bytes, bytearray)): data = bytearray(pkt) elif isinstance(pkt, Packet): pkt.serialize() data = pkt.data else: raise ValueError('Could not handle packet of type: ' '{}'.format(type(pkt))) self.logger.debug('Tracer sending packet: %s', str(Packet(data))) datapath = get_datapath(self, dpid=self._datapath.id) ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser actions = [ # Turn on test-packet as we're just tracing it ofp_parser.NXActionRegLoad2(dst=TEST_PACKET_REG, value=TestPacket.ON.value), # Add IMSI metadata ofp_parser.NXActionRegLoad2(dst=IMSI_REG, value=encode_imsi(imsi)), # Submit to table=0 because otherwise the packet will be dropped! ofp_parser.NXActionResubmitTable(table_id=0), ] datapath.send_packet_out(in_port=ofp.OFPP_LOCAL, actions=actions, data=data)
def _packet_in_handler(self, ev): self.logger.debug("my_arp: _packet_in_handler:") # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath # ofproto = datapath.ofproto inPort = msg.match['in_port'] packets = Packet(msg.data) dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) eth = packets.get_protocols(ethernet)[0] src = eth.src self.mac_to_port[dpid][src] = inPort data = msg.data # print "packets: ", packets # print "packets.get_protocols(ethernet): ", packets.get_protocols(ethernet) if etherFrame.ethertype == ether.ETH_TYPE_ARP: # print "packets: ", packets # print "packets.get_protocols(ethernet): ", packets.get_protocols(ethernet) self.receive_arp(datapath, packets, etherFrame, inPort, data) return 0 else: self.logger.debug("Drop packet") return 1
def test_Packet_in_4_icmpEcho2(self): print "*** Case4: HOST2からHOST1以外の宛先IPへのIPパケットを受信 ***" sr = SimpleForward() sr.HOST_MACADDR1 = HOST_MACADDR1 sr.HOST_MACADDR2 = HOST_MACADDR2 dstMac = ROUTER_MACADDR2 srcMac = HOST_MACADDR2 srcIp = HOST_IPADDR2 dstIp = "91.189.89.22" ttl = 64 datapath = _Datapath() e = ethernet(dstMac, srcMac, ether.ETH_TYPE_IP) iph = ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, srcIp, dstIp) p = Packet() p.add_protocol(e) p.add_protocol(iph) p.serialize() packetIn = OFPPacketIn(datapath, match=OFPMatch(in_port=2), data=buffer(p.data)) ev = ofp_event.EventOFPPacketIn(packetIn) result = sr.packet_in_handler(ev) self.assertEqual(result, 1) print ""
def _packet_in_handler(self, ev): self.logger.debug("my_arp: _packet_in_handler:") # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath # ofproto = datapath.ofproto inPort = msg.match['in_port'] packets = Packet(msg.data) dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) eth = packets.get_protocols(ethernet)[0] src = eth.src dst = eth.dst self.mac_to_port[dpid][src] = inPort data = msg.data self.arp_learning.setdefault(dpid, []) self.packetToport.setdefault(dpid, []) etherFrame = packets.get_protocol(ethernet) # if dst == LLDP_MAC_NEAREST_BRIDGE: # return # print "packets: ", packets # print "packets.get_protocols(ethernet): ", packets.get_protocols(ethernet) # print "etherFrame######", etherFrame # etherFrame = packets.get_protocol(ethernet) etherFrame = packets.get_protocol(ethernet) # print etherFrame # print ether # print hex(etherFrame.ethertype) # print hex(ether.ETH_TYPE_ARP) if etherFrame.ethertype == ether.ETH_TYPE_ARP: arpPacket = packets.get_protocol(arp) arpArriveTime = time.time() srcMac = etherFrame.src arp_dstIP = arpPacket.dst_ip self.packetToport[datapath.id] = [srcMac, arp_dstIP, inPort, arpArriveTime] # print "arp" # print "packets: ", packets # print "packets.get_protocols(ethernet): ", packets.get_protocols(ethernet) # print "ARP: %s" % arpPacket.opcode # # self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # if arpPacket.opcode == 1: # print "ARP Requst" # self.logger.info("packet in %s %s %s %s", datapath.id, srcMac, dst, inPort) # elif arpPacket.opcode == 2: # print "ARP Reply" # self.logger.info("packet in %s %s %s %s", datapath.id, srcMac, dst, inPort) self.receive_arp(datapath, packets, etherFrame, inPort, data) return 0 else: self.logger.debug("Drop packet") return 1
def test_20_check_withdrawal_2(self): g1 = self.gobgp g2 = self.quaggas['g2'] dumpfile = g2.start_tcpdump() g1.add_route('10.40.0.0/24') time.sleep(1) paths = g2.get_global_rib('10.40.0.0/24') self.assertTrue(len(paths) == 1) g1.local('gobgp global rib del 10.40.0.0/24') time.sleep(1) paths = g2.get_global_rib('10.40.0.0/24') self.assertTrue(len(paths) == 0) g2.stop_tcpdump() time.sleep(1) cnt = 0 for _, buf in pcap.Reader(open(dumpfile)): pkt = Packet(buf).get_protocol(BGPMessage) if isinstance(pkt, BGPUpdate): cnt += len(pkt.withdrawn_routes) self.assertTrue(cnt == 1)
def receive_ip(self, datapath, packet, etherFrame, inPort, msg): #Función que se usa cuando se recibe un paquete IP ipPacket = packet.get_protocol(ipv4.ipv4) if ipPacket.dst == self.ports_to_ips[0][0]: #Si va destinado al router if ipPacket.proto == inet.IPPROTO_ICMP: icmpPacket = packet.get_protocol(icmp.icmp) self.check_icmp(datapath, etherFrame, ipPacket, icmpPacket, inPort) #Se usa una función que trata un paquete ICMP return 0 else: send_packet(datapath=datapath,port=inPort,packet=packet) #Se envía el paquete return 1 else: #Si no va destinado al router (next_hop, port) = self.find_in_routingTable(ipPacket.dst) #Almacena el puerto y el siguiente salto #en port y en next_hop if next_hop in self.ipToMac.keys(): #Si está dentro de la tabla de ips y macs se envía. match = datapath.ofproto_parser.OFPMatch(eth_dst=self.ipToMac[next_hop]) actions = [datapath.ofproto_parser.OFPActionOutput(port)] #self.add_flow(datapath, 0, match, actions) self.insertar_flujo(msg=msg, mac=self.ipToMac[next_hop], port=port, mod=1) else: #Si no está dentro de la tabla se construye un paquete ARP para averiguar su MAC # print "---- NEXT_HOP -----", next_hop e = ethernet.ethernet(src=etherFrame.dst, ethertype=ether.ETH_TYPE_ARP) a = arp.arp(opcode=arp.ARP_REQUEST, src_ip=self.ports_to_ips[port-1][0], src_mac=etherFrame.src, dst_ip=next_hop) puerto = etherFrame.src p = Packet() p.add_protocol(e) p.add_protocol(a) if next_hop not in self.dict_pendientes: self.dict_pendientes[next_hop] = [] self.dict_pendientes[next_hop] = self.dict_pendientes[next_hop] + [(msg, port,None,None)] self.send_packet(datapath=datapath, port=port, packet=p)
def send_icmp(self, datapath, srcMac, srcIp, dstMac, dstIp, outPort, seq, data, id=1, type=8, ttl=64): e = ethernet(dstMac, srcMac, ether.ETH_TYPE_IP) iph = ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, srcIp, dstIp) echo = icmp.echo(id, seq, data) icmph = icmp.icmp(type, 0, 0, echo) p = Packet() p.add_protocol(e) p.add_protocol(iph) p.add_protocol(icmph) p.serialize() actions = [datapath.ofproto_parser.OFPActionOutput(outPort, 0)] out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=p.data) datapath.send_msg(out) return 0
def trace_packet(self, packet, imsi, timeout=2): """ Send a packet and wait until it is processed and the dropped_table dict shows which table caused a drop. Important: trace_packet initiates a packet-send through self.send_event_to_observers() because trace_packet could be called from a different thread than the one Ryu app is running on, which will cause the datapath to reconnect. To avoid that we initiate an EventSendPacket which will be handled on the Ryu event-loop thread. :param packet: bytes of the packet :param imsi: IMSI string (like 001010000000013 or IMSI001010000000013) :param timeout: timeout after which to stop waiting for a packet :return: table_id which caused the drop or -1 if it wasn't dropped """ assert isinstance(packet, bytes) self.logger.debug('Trace packet: %s', str(Packet(packet))) self.send_event_to_observers(EventSendPacket(pkt=packet, imsi=imsi)) start = time.time() while packet not in self.dropped_table: if time.time() > start + timeout: raise Exception('Timeout while waiting for the packet') time.sleep(0.1) table_id = self.dropped_table[packet] del self.dropped_table[packet] # If the table was returned to the user space after the last table => # It wasn't dropped in the process if table_id == self._service_manager.get_table_num(EGRESS): return -1 return table_id
def receive_arp(self, datapath, packet, etherFrame, inPort): arp_msg = packet.get_protocol(arp.arp) if arp_msg.opcode == arp.ARP_REQUEST: if arp_msg.dst_ip == self.ports_to_ips[inPort-1][0]: e = ethernet.ethernet(dst=etherFrame.src, src=self.ports_to_ips[inPort-1][2], ethertype=ether.ETH_TYPE_ARP) a = arp.arp(opcode=arp.ARP_REPLY, src_mac=self.ports_to_ips[inPort-1][2], src_ip=arp_msg.dst_ip, dst_mac=etherFrame.src, dst_ip=arp_msg.src_ip) puerto=inPort p = Packet() p.add_protocol(e) p.add_protocol(a) self.send_packet(datapath, puerto, p) elif arp_msg.opcode == arp.ARP_REPLY: self.ipToMac[arp_msg.src_ip] = arp_msg.src_mac for (msg,port,nat,puertoNat) in self.dict_pendientes[arp_msg.src_ip]: if nat == None and puertoNat == None: self.insertar_flujo(msg=msg, mac=arp_msg.src_mac, port=port, mod=1) elif nat == 1: self.insertar_flujo(msg=msg, mod=0, puerto_origen=puertoNat, ip_origen=ip_publica, sentido=1, protoc=1, port=port, mac=arp_msg.src_mac) self.dict_pendientes[arp_msg.src_ip] = []
def _handle_packet_in_user_space(self, ev): """ Receive the table_id which caused the packet to be dropped """ if ev.msg.match[TEST_PACKET_REG] != TestPacket.ON.value: return pkt = Packet(data=ev.msg.data) self.logger.debug('Tracer received packet %s', str(pkt)) self.dropped_table[pkt.data] = ev.msg.table_id
def arp_response(self, datapath, pkt, ether_frame, ofp_parser, ofp, in_port): arp_packet = pkt.get_protocol(arp.arp) dst_ip = arp_packet.src_ip src_ip = arp_packet.dst_ip dst_mac = ether_frame.src # If the ARP request isn't from one of the two servers, # choose the target/source MAC address from one of the servers; # else the target MAC address is set to the one corresponding # to the target host's IP. if dst_ip != self.H1_ip and dst_ip != self.H2_ip: src_mac = self.VIRTUAL_MAC # if self.next_server == self.H1_ip: # src_mac = self.H1_mac # self.next_server = self.H2_ip # else: # src_mac = self.H2_mac # self.next_server = self.H1_ip else: src_mac = self.ip_to_mac[src_ip] print "arp_response -> src_mac : %s" % src_mac eth_header = ethernet.ethernet(dst_mac, src_mac, ether_types.ETH_TYPE_ARP) arp_reply_packet = arp.arp(hwtype=ARP_HW_TYPE_ETHERNET, proto=ETH_TYPE_IP, hlen=6, plen=4, opcode=ARP_REPLY, src_mac=src_mac, src_ip=src_ip, dst_mac=dst_mac, dst_ip=dst_ip) print "arp_response -> src_mac : %s" % src_mac print "arp_response -> src_ip : %s" % src_ip print "arp_response -> dst_mac : %s" % dst_mac print "arp_response -> dst_ip : %s" % dst_ip pkt = Packet(protocols=[eth_header, arp_reply_packet]) pkt.serialize() # ARP action list actions = [ofp_parser.OFPActionOutput(ofp.OFPP_IN_PORT)] # ARP output message out = ofp_parser.OFPPacketOut(datapath=datapath, buffer_id=ofp.OFP_NO_BUFFER, in_port=in_port, actions=actions, data=pkt.data) datapath.send_msg(out) # Send out ARP reply
def receive_ip(self, datapath, packet, etherFrame, inPort, msg): #Función que se usa cuando se recibe un paquete IP ipPacket = packet.get_protocol(ipv4.ipv4) #print packet.get_protocol(ipv4.ipv4) print "LLEGÓ UN PAQUETE IP" if ipPacket.dst == self.ports_to_ips[0][0]: #Si va destinado al router print "VA DESTINADO AL ROUTER" if ipPacket.proto == inet.IPPROTO_ICMP: print "Y ES ICMP" icmpPacket = packet.get_protocol(icmp.icmp) self.check_icmp( datapath, etherFrame, ipPacket, icmpPacket, inPort) #Se usa una función que trata un paquete ICMP return 0 else: send_packet(datapath=datapath, port=inPort, packet=packet) #Se envía el paquete return 1 else: #Si no va destinado al router print "NO VA DESTINADO AL ROUTER" (next_hop, port) = self.find_in_routingTable( ipPacket.dst) #Almacena el puerto y el siguiente salto #en port y en next_hop print "¿Está dentro de la tabla ", next_hop, " ?" if next_hop in self.ipToMac.keys( ): #Si está dentro de la tabla de ips y macs se envía. print "ESTÁ DENTRO DE LA TABLA##################################################" print "ipToMac[next_hop] = ", self.ipToMac[next_hop] match = datapath.ofproto_parser.OFPMatch( eth_dst=self.ipToMac[next_hop]) actions = [datapath.ofproto_parser.OFPActionOutput(port)] self.add_flow(datapath, 0, match, actions) self.insertar_flujo(msg, self.ipToMac[next_hop], port) else: #Si no está dentro de la tabla se construye un paquete ARP para averiguar su MAC print "NO ESTÁ DENTRO DE LA TABLA" print "---- NEXT_HOP -----", next_hop e = ethernet.ethernet( #dst=etherFrame.dst, src=etherFrame.dst, ethertype=ether.ETH_TYPE_ARP) a = arp.arp(opcode=arp.ARP_REQUEST, src_ip=self.ports_to_ips[port - 1][0], src_mac=etherFrame.src, dst_ip=next_hop) puerto = etherFrame.src p = Packet() p.add_protocol(e) p.add_protocol(a) if next_hop not in self.dict_pendientes: self.dict_pendientes[next_hop] = [] self.dict_pendientes[ next_hop] = self.dict_pendientes[next_hop] + [(msg, port)] #def send_packet(self, datapath, port, packet): print "llegó por el PUERTO: ", inPort, "Sale por el puerto: ", port self.send_packet(datapath=datapath, port=port, packet=p)
def _packet_in_handler(self, ev): """Handle packet_in events.""" if not self.link_discovery: return msg = ev.msg in_port = msg.match['in_port'] packet = Packet(msg.data) efm = packet.get_protocol(ethernet.ethernet) if efm.ethertype == ether.ETH_TYPE_ARP: self.send_event_to_observers(event.EventArpReceived(ev)) try: src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data) except LLDPPacket.LLDPUnknownFormat as e: # This handler can receive all the packtes which can be # not-LLDP packet. Ignore it silently return else: dst_dpid = msg.datapath.id dst_port_no = in_port src = self._get_port(src_dpid, src_port_no) if not src or src.dpid == dst_dpid: return dst = self._get_port(dst_dpid, dst_port_no) if not dst: return old_peer = self.links.get_peer(src) #LOG.debug("Packet-In") #LOG.debug(" src=%s", src) #LOG.debug(" dst=%s", dst) #LOG.debug(" old_peer=%s", old_peer) if old_peer and old_peer != dst: old_link = Link(src, old_peer) self.send_event_to_observers(event.EventLinkDelete(old_link)) link = Link(src, dst) if not link in self.links: self.send_event_to_observers(event.EventLinkAdd(link)) if not self.links.update_link(src, dst): # reverse link is not detected yet. # So schedule the check early because it's very likely it's up try: self.ports.lldp_received(dst) except KeyError as e: # There are races between EventOFPPacketIn and # EventDPPortAdd. So packet-in event can happend before # port add event. In that case key error can happend. # LOG.debug('lldp_received: KeyError %s', e) pass else: self.ports.move_front(dst) self.lldp_event.set()