def _handle_arp(self, datapath, port, pkt_ethernet, pkt_arp): """Handle ARP reply/request packets. When controller get an ARP reply packet, it will write into ARP table. When controller get an ARP request packet, it will reply someone who want to ask NAT's MAC address. (Probably under NAT's LAN or WAN)""" if pkt_arp.opcode != arp.ARP_REQUEST: #it means ARP_REPLY if pkt_arp.dst_ip == self.nat_ip: # 140.92.62.30 is at xx:xx:xx:xx:xx:xx # Got an ARP Reply and parser it. #gw_src_mac = pkt_arp.src_mac #gw_ip = pkt_arp.src_ip ARP_TABLE[pkt_arp.src_ip] = pkt_arp.src_mac print "Get ARP reply" print ARP_TABLE return else: pass # Handle ARP Request and send an ARP Reply if pkt_arp.dst_ip == self.nat_intranet_gateway: # Who has 192.168.9.1 ? # Tell 192.168.9.20(Host), 192.168.9.1's fake MAC address (eth1) pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.fake_mac_eth1)) pkt.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=self.fake_mac_eth1, src_ip=self.nat_intranet_gateway, dst_mac=pkt_arp.src_mac, dst_ip=pkt_arp.src_ip)) #print "Send pkt to %s" % pkt_arp.src_mac self._send_packet(datapath, port, pkt) elif pkt_arp.dst_ip == self.nat_ip: # Who has 140.92.62.235 ? # Tell 140.92.62.1(Extranet Gateway) pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.fake_mac_eth2)) pkt.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=self.fake_mac_eth1, src_ip=self.nat_ip, dst_mac=pkt_arp.src_mac, dst_ip=pkt_arp.src_ip)) self._send_packet(datapath, port, pkt) else: return
def send_arp_reply(self, dpid, datapath, eth, arp_pkt, src_ip, dst_ip, in_port, msg): ofproto = datapath.ofproto out_port = None mac_found = "" for dp, values in self.ip_mac_port.items(): # print values if dst_ip in values: mac_found = values[dst_ip][0] out_port = in_port e = ethernet.ethernet(dst=eth.src, src=CONTROLLER_MAC, ethertype=ether.ETH_TYPE_ARP) a = arp.arp(hwtype=1, proto=0x0800, hlen=6, plen=4, opcode=2, src_mac=mac_found, src_ip=dst_ip, dst_mac=eth.src, dst_ip=src_ip) break if out_port == None: #print "Controller or unknown ARP request" e = ethernet.ethernet(dst=eth.src, src=CONTROLLER_MAC, ethertype=ether.ETH_TYPE_ARP) a = arp.arp(hwtype=1, proto=0x0800, hlen=6, plen=4, opcode=2, src_mac=CONTROLLER_MAC, src_ip=dst_ip, dst_mac=eth.src, dst_ip=src_ip) out_port = in_port p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() data = p.data actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=data) datapath.send_msg(out)
def _handle_arp(self, datapath, port, pkt_ethernet, pkt_arp): """Handle ARP reply/request packets. When controller get an ARP reply packet, it will write into ARP table. When controller get an ARP request packet, it will reply someone who want to ask NAT's MAC address. (Probably under NAT's LAN or WAN)""" if pkt_arp.opcode != arp.ARP_REQUEST: #it means ARP_REPLY if pkt_arp.dst_ip == self.nat_ip: # 140.92.62.30 is at xx:xx:xx:xx:xx:xx # Got an ARP Reply and parser it. #gw_src_mac = pkt_arp.src_mac #gw_ip = pkt_arp.src_ip ARP_TABLE[pkt_arp.src_ip] = pkt_arp.src_mac print "Get ARP reply" print ARP_TABLE return else: pass # Handle ARP Request and send an ARP Reply if pkt_arp.dst_ip == self.nat_intranet_gateway: # Who has 192.168.9.1 ? # Tell 192.168.9.20(Host), 192.168.9.1's fake MAC address (eth1) pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.fake_mac_eth1)) pkt.add_protocol(arp.arp(opcode=arp.ARP_REPLY, src_mac=self.fake_mac_eth1, src_ip=self.nat_intranet_gateway, dst_mac=pkt_arp.src_mac, dst_ip=pkt_arp.src_ip)) #print "Send pkt to %s" % pkt_arp.src_mac self._send_packet(datapath, port, pkt) elif pkt_arp.dst_ip == self.nat_ip: # Who has 140.92.62.235 ? # Tell 140.92.62.1(Extranet Gateway) pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.fake_mac_eth2)) pkt.add_protocol(arp.arp(opcode=arp.ARP_REPLY, src_mac=self.fake_mac_eth1, src_ip=self.nat_ip, dst_mac=pkt_arp.src_mac, dst_ip=pkt_arp.src_ip)) self._send_packet(datapath, port, pkt) else: return
def _packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath in_port = msg.match['in_port'] ofproto = datapath.ofproto parser = datapath.ofproto_parser pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) if eth.ethertype == ether_types.ETH_TYPE_IP: # record host mac address ipv4_header = pkt.get_protocol(ipv4.ipv4) self.arp_table.setdefault(ipv4_header.src, eth.src) return if eth.ethertype != ether_types.ETH_TYPE_ARP: # ignore non-arp packet return arp_header = pkt.get_protocol(arp.arp) src_ip = arp_header.src_ip src_mac = arp_header.src_mac dst_ip = arp_header.dst_ip dst_mac = self.arp_table.get(dst_ip) self.arp_table.setdefault(src_ip, src_mac) if arp_header.opcode != arp.ARP_REQUEST: return if not dst_mac: # can't find distination, drop it return # send arp request to host actions = [parser.OFPActionOutput(in_port)] arp_reply = packet.Packet() arp_reply.add_protocol( ethernet.ethernet( ethertype=ether_types.ETH_TYPE_ARP, src=dst_mac, dst=src_mac ) ) arp_reply.add_protocol( arp.arp( opcode=arp.ARP_REPLY, src_ip=dst_ip, src_mac=dst_mac, dst_ip=src_ip, dst_mac=src_mac ) ) arp_reply.serialize() out = parser.OFPPacketOut( datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=arp_reply.data) datapath.send_msg(out)
def _handle_arp(self, ev, subname): msg = ev.msg datapath = msg.datapath in_port = msg.match['in_port'] pkt = packet.Packet(data=msg.data) pkt_ethernet = pkt.get_protocol(ethernet.ethernet) pkt_arp = pkt.get_protocol(arp.arp) if pkt_arp.opcode == arp.ARP_REPLY: self.subnet[datapath.id][subname]['arp_table'][pkt_arp.src_ip]=pkt_arp.src_mac self.logger.info('arp_table: %s ' % json.dumps(self.subnet)) return elif pkt_arp.opcode == arp.ARP_REQUEST: #ingest arp_table self.subnet[datapath.id][subname]['arp_table'][pkt_arp.src_ip]=pkt_arp.src_mac self.logger.info('arp_table: %s ' % json.dumps(self.subnet)) this_subnet=self.subnet[datapath.id][subname] #generating arp packet pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=this_subnet['mac'])) pkt.add_protocol(arp.arp(opcode=arp.ARP_REPLY, src_mac=this_subnet['mac'], src_ip =this_subnet['ip'], dst_mac=pkt_arp.src_mac, dst_ip=pkt_arp.src_ip)) self._send_packet(datapath, in_port, pkt) self.logger.info("arp reply is sent: %s-%s -> %s-%s via port=%s" % (this_subnet['mac'], this_subnet['ip'], pkt_arp.src_mac, pkt_arp.src_ip, in_port) ) return else: return
def createArpReply(message, ip): if not packetIsARP(message): print("Packet is not ARP") return pkt = packet.Packet(message.data) origarp = pkt.get_protocol(arp.arp) a = arp.arp( hwtype=origarp.hwtype, proto=origarp.proto, src_mac=origarp.src_mac, dst_mac=origarp.dst_mac, hlen=origarp.hlen, opcode=arp.ARP_REPLY, plen=origarp.plen, src_ip=ip, dst_ip=origarp.dst_ip ) e = ethernet.ethernet( dst=origarp.dst_mac, src=origarp.src_mac, ethertype=ether.ETH_TYPE_ARP) p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() return p
def create_arp(dl_src, dl_dst, nl_src, nl_dst): ''' Create an ARP reply packet. :param dl_src: 48bit MAC address :type dl_src: str :param dl_dst: 48bit MAC address :type dl_dst: str :param nl_src: 32bit IP address :type nl_src: str :param nl_dst: 32bit IP address :type nl_dst: str :returns: binary representation of ARP packet :rtype: `bytearray` ''' pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=ethertypes.ETH_TYPE_ARP, dst=dl_dst, src=dl_src)) pkt.add_protocol(arp.arp(opcode=arp.ARP_REPLY, src_mac=dl_src, src_ip=nl_src, dst_mac=dl_dst, dst_ip=nl_dst)) return pkt.serialize()
def function_for_arp_reply( self, dst_ip, dst_mac ): #Function placed here, source MAC and IP passed from below now become the destination for the reply ppacket print( "(((Entered the ARP Reply function to build a packet and reply back appropriately)))" ) arp_target_ip = dst_ip arp_target_mac = dst_mac src_ip = self.virtual_lb_ip #Making the load balancers IP and MAC as source IP and MAC src_mac = self.virtual_lb_mac arp_opcode = 2 #ARP opcode is 2 for ARP reply hardware_type = 1 #1 indicates Ethernet ie 10Mb arp_protocol = 2048 #2048 means IPv4 packet ether_protocol = 2054 #2054 indicates ARP protocol len_of_mac = 6 #Indicates length of MAC in bytes len_of_ip = 4 #Indicates length of IP in bytes pkt = packet.Packet() ether_frame = ethernet.ethernet( dst_mac, src_mac, ether_protocol) #Dealing with only layer 2 arp_reply_pkt = arp.arp( hardware_type, arp_protocol, len_of_mac, len_of_ip, arp_opcode, src_mac, src_ip, arp_target_mac, dst_ip) #Building the ARP reply packet, dealing with layer 3 pkt.add_protocol(ether_frame) pkt.add_protocol(arp_reply_pkt) pkt.serialize() print( "{{{Exiting the ARP Reply Function as done with processing for ARP reply packet}}}" ) return pkt
def _respond_arp(self, datapath, port, arptbl, pkt_ethernet, pkt_vlan, pkt_arp): if pkt_arp.opcode != arp.ARP_REQUEST: LOG.debug("unknown arp op %s", pkt_arp.opcode) return False ip_addr = pkt_arp.dst_ip hw_addr = arptbl.get(ip_addr) if hw_addr is None: LOG.debug("unknown arp request %s", ip_addr) return False LOG.debug("responding arp request %(ip_addr)s -> %(hw_addr)s", { 'ip_addr': ip_addr, 'hw_addr': hw_addr }) pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=hw_addr)) pkt.add_protocol( vlan.vlan(cfi=pkt_vlan.cfi, ethertype=pkt_vlan.ethertype, pcp=pkt_vlan.pcp, vid=pkt_vlan.vid)) pkt.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=hw_addr, src_ip=ip_addr, dst_mac=pkt_arp.src_mac, dst_ip=pkt_arp.src_ip)) self._send_arp_reply(datapath, port, pkt) return True
def request_generator(self,datapath): parser = datapath.ofproto_parser barrier_req = parser.OFPBarrierRequest(datapath) e = ethernet.ethernet(dst='ff:ff:ff:ff:ff:ff', src='08:60:6e:7f:74:e7', ethertype=ether.ETH_TYPE_ARP) a = arp.arp(hwtype=1, proto=0x0800, hlen=6, plen=4, opcode=2, src_mac='08:60:6e:7f:74:e7', src_ip='192.0.2.1', dst_mac='00:00:00:00:00:00', dst_ip='192.0.2.2') p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() msg1=p.data actions = [parser.OFPActionOutput(1, 0)] send_data_req = parser.OFPPacketOut(datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=p.data) print "send empty request" datapath.send_msg(barrier_req) yield print "send 1st datamsg" datapath.send_msg(send_data_req) datapath.send_msg(barrier_req) yield print "send 2nd datamsg" datapath.send_msg(send_data_req) datapath.send_msg(barrier_req) yield print "*** end of request sequence ***" yield
def _arp_request(self, datapath, pkt_ip=None): """Sending an ARP request via broadcast""" # Who has xxx.xxx.xxx.xxx? Tell 140.92.62.235 (NAT's Public IP) if pkt_ip is None: target_ip = self.nat_extranet_gateway else: target_ip = self.subnet(pkt_ip) print "Sending ARP Request..." ofproto = datapath.ofproto parser = datapath.ofproto_parser #target_ip = self.subnet(pkt_ip) pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=ether.ETH_TYPE_ARP, dst='ff:ff:ff:ff:ff:ff', src=self.fake_mac_eth2)) pkt.add_protocol(arp.arp(opcode=arp.ARP_REQUEST, src_mac=self.fake_mac_eth2, src_ip=self.nat_ip, dst_mac='00:00:00:00:00:00', dst_ip=target_ip)) pkt.serialize() data = pkt.data actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)] out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=data) datapath.send_msg(out)
def addARP(pkt_out,fields): pkt_out.add_protocol(arp.arp(opcode=arp.ARP_REPLY, src_mac=fields['srcmac'], src_ip=fields['srcip'], dst_mac=fields['dstmac'], dst_ip=fields['dstip'])) return pkt_out
def _handle_arp_reply(self, pkt_arp, port, dpid): if pkt_arp.opcode == arp.ARP_REPLY and pkt_arp.dst_mac == self.hw_addr: if pkt_arp.src_ip not in self.active_ips: print("ARP from " + pkt_arp.src_ip + "\n") self.active_ips[pkt_arp.src_ip] = [dpid, port] self.arp_table[pkt_arp.src_ip] = pkt_arp.src_mac if self.topology: self.draw_graph(1, draw=True) if pkt_arp.opcode == arp.ARP_REQUEST and pkt_arp.src_ip != self.ip_addr: #print("ARP Reqest from: " + pkt_arp.src_mac + " requesting: " + pkt_arp.dst_ip) if pkt_arp.dst_ip not in self.arp_table: return #construct and send ARP reply reply_pkt = packet.Packet() reply_pkt.add_protocol(ethernet.ethernet(ethertype=0x806,\ dst=pkt_arp.src_mac,\ src=self.arp_table[pkt_arp.dst_ip])) reply_pkt.add_protocol(arp.arp(opcode=arp.ARP_REPLY,\ src_mac=self.arp_table[pkt_arp.dst_ip],\ src_ip=pkt_arp.dst_ip,\ dst_mac=pkt_arp.src_mac,\ dst_ip=pkt_arp.src_ip)) print("Responded to ARP Request: " ) print("Gave [" + pkt_arp.src_mac + "," + pkt_arp.src_ip + "]" +\ "[" + pkt_arp.dst_ip + "," + self.arp_table[pkt_arp.dst_ip] + "]") self._send_packet(reply_pkt, self.dpids[int(dpid, 16)])
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 control_plane_arp_handler(self, in_port, vlan, eth_src, arp_pkt): ofmsgs = [] if arp_pkt.opcode == arp.ARP_REQUEST: pkt = self.build_ethernet_pkt( eth_src, in_port, vlan, ether.ETH_TYPE_ARP) arp_pkt = arp.arp( opcode=arp.ARP_REPLY, src_mac=self.FAUCET_MAC, src_ip=arp_pkt.dst_ip, dst_mac=eth_src, dst_ip=arp_pkt.src_ip) pkt.add_protocol(arp_pkt) pkt.serialize() ofmsgs.append(self.valve_packetout(in_port, pkt.data)) self.logger.info('Responded to ARP request for %s from %s', arp_pkt.src_ip, arp_pkt.dst_ip) elif arp_pkt.opcode == arp.ARP_REPLY: resolved_ip_gw = ipaddr.IPv4Address(arp_pkt.src_ip) for ip_dst, ip_gw in vlan.ipv4_routes.iteritems(): if ip_gw == resolved_ip_gw: self.logger.info('ARP response %s for %s', eth_src, resolved_ip_gw) ofmsgs.extend( self.add_resolved_route( ether.ETH_TYPE_IP, vlan, vlan.arp_cache, ip_gw, ip_dst, eth_src)) return ofmsgs
def _arp_request(self, datapath, pkt_ip=None): """Sending an ARP request via broadcast""" # Who has xxx.xxx.xxx.xxx? Tell 140.92.62.235 (NAT's Public IP) if pkt_ip is None: target_ip = self.nat_extranet_gateway else: target_ip = self.subnet(pkt_ip) print "Sending ARP Request..." ofproto = datapath.ofproto parser = datapath.ofproto_parser #target_ip = self.subnet(pkt_ip) pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=ether.ETH_TYPE_ARP, dst='ff:ff:ff:ff:ff:ff', src=self.fake_mac_eth2)) pkt.add_protocol( arp.arp(opcode=arp.ARP_REQUEST, src_mac=self.fake_mac_eth2, src_ip=self.nat_ip, dst_mac='00:00:00:00:00:00', dst_ip=target_ip)) pkt.serialize() data = pkt.data actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)] out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=data) datapath.send_msg(out)
def discover_router(self, datapath, ofproto, parser): ##arp for the router first, to learn its out port ##form the ARP req a_hwtype = 1 a_proto = ether.ETH_TYPE_IP a_hlen = 6 a_plen = 4 a_opcode = 1 #request1 a_srcMAC = self.CONTROLLER_SPECIAL_MAC a_srcIP = self.CONTROLLER_SPECIAL_IP a_dstMAC = self.ROUTER_MAC a_dstIP = self.ROUTER_IP p = packet.Packet() e = ethernet.ethernet(a_dstMAC,a_srcMAC,ether.ETH_TYPE_ARP) a = arp.arp(a_hwtype,a_proto,a_hlen,a_plen,a_opcode,a_srcMAC,a_srcIP,a_dstMAC,a_dstIP) p.add_protocol(e) p.add_protocol(a) p.serialize() #send packet out actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)] out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER,in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=p.data) datapath.send_msg(out) dpid = datapath.id self.logger.info("packet out dpid:'%s' src:'%s' dst:'%s' out_port:'OFPP_FLOOD'", dpid, self.CONTROLLER_SPECIAL_MAC, self.ROUTER_MAC) self.logger.info("[ADMIN] Attempting to discover WAN router... ")
def build_pkt(pkt): layers = [] if 'arp_target_ip' in pkt: ethertype = 0x806 layers.append(arp.arp(dst_ip=pkt['arp_target_ip'])) elif 'ipv6_src' in pkt: ethertype = 0x86DD layers.append(ipv6.ipv6(src=pkt['ipv6_src'], dst=pkt['ipv6_src'])) else: ethertype = 0x800 if 'ipv4_src' in pkt: net = ipv4.ipv4(src=pkt['ipv4_src'], dst=pkt['ipv4_dst']) else: net = ipv4.ipv4() layers.append(net) if 'vid' in pkt: tpid = 0x8100 layers.append(vlan.vlan(vid=pkt['vid'], ethertype=ethertype)) else: tpid = ethertype eth = ethernet.ethernet( dst=pkt['eth_dst'], src=pkt['eth_src'], ethertype=tpid) layers.append(eth) result = packet.Packet() for layer in layers: result.add_protocol(layer) return result
def handle_arp(self, datapath, in_port, pkt): ofproto = datapath.ofproto parser = datapath.ofproto_parser # parse out the ethernet and arp packet eth_pkt = pkt.get_protocol(ethernet.ethernet) arp_pkt = pkt.get_protocol(arp.arp) # obtain the MAC of dst IP arp_resolv_mac = self.arp_table[arp_pkt.dst_ip] # generate the ARP reply msg # the packet library section ether_hd = ethernet.ethernet(dst = eth_pkt.src, src = arp_resolv_mac, ethertype = ether.ETH_TYPE_ARP); arp_hd = arp.arp(hwtype=1, proto = 2048, hlen = 6, plen = 4, opcode = 2, src_mac = arp_resolv_mac, src_ip = arp_pkt.dst_ip, dst_mac = eth_pkt.src, dst_ip = arp_pkt.src_ip); arp_reply = packet.Packet() arp_reply.add_protocol(ether_hd) arp_reply.add_protocol(arp_hd) arp_reply.serialize() # send the Packet Out mst to back to the host who is initilaizing the ARP actions = [parser.OFPActionOutput(in_port)]; out = parser.OFPPacketOut(datapath, ofproto.OFP_NO_BUFFER, ofproto.OFPP_CONTROLLER, actions, arp_reply.data) datapath.send_msg(out)
def send_arp(self, arp_opcode, src_mac, dst_mac, src_ip, dst_ip, arp_target_mac, in_port, output, ofproto, datapath, msg, parser): # Generate ARP packet ether_proto = ether.ETH_TYPE_ARP hwtype = 1 arp_proto = ether.ETH_TYPE_IP hlen = 6 plen = 4 pkt = packet.Packet() e = ethernet.ethernet(dst_mac, src_mac, ether_proto) a = arp.arp(hwtype, arp_proto, hlen, plen, arp_opcode, src_mac, src_ip, arp_target_mac, dst_ip) pkt.add_protocol(e) pkt.add_protocol(a) pkt.serialize() self.logger.info("send arp pkt:\n%s" % (pkt)) actions = [parser.OFPActionOutput(output, 0)] out = parser.OFPPacketOut(datapath=datapath, buffer_id=0xffffffff, in_port=in_port, actions=actions, data=pkt.data) datapath.send_msg(out)
def arp_handler(self, dp, port, arp_req): if arp_req.dst_ip != self.ip_inside \ and arp_req.dst_ip != self.ip_outside: return if arp_req.opcode == arp.ARP_REQUEST: rep = packet.Packet() eth_rep = ethernet.ethernet(ethertype=ether_types.ETH_TYPE_ARP, dst=arp_req.src_mac, src=dp.ports[port].hw_addr) if self.nat_port[port] == 'outside': _src_ip = self.ip_outside elif self.nat_port[port] == 'inside': _src_ip = self.ip_inside else: raise 'bad ip address' arp_rep = arp.arp(opcode=arp.ARP_REPLY, src_mac=dp.ports[port].hw_addr, src_ip=_src_ip, dst_mac=arp_req.src_mac, dst_ip=arp_req.src_ip) self.arp_table[arp_rep.src_ip] = arp_rep.src_mac self.arp_table[arp_rep.dst_ip] = arp_rep.dst_mac rep.add_protocol(eth_rep) rep.add_protocol(arp_rep) self.send_packet(dp, port, rep) return
def send_arp(self, datapath, eth_dst, eth_src, dst_ip, src_ip, opcode, port): ''' Send ARP Packet. ''' ofproto = datapath.ofproto parser = datapath.ofproto_parser actions = [parser.OFPActionOutput(port)] arp_packet = packet.Packet() arp_packet.add_protocol( ethernet.ethernet(ethertype=ether_types.ETH_TYPE_ARP, dst=eth_dst, src=eth_src)) arp_packet.add_protocol( arp.arp(opcode=opcode, src_mac=eth_src, src_ip=src_ip, dst_mac=eth_dst, dst_ip=dst_ip)) arp_packet.serialize() out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=arp_packet.data) datapath.send_msg(out)
def build_pkt(pkt): layers = [] if 'arp_target_ip' in pkt: ethertype = 0x806 layers.append(arp.arp(dst_ip=pkt['arp_target_ip'])) elif 'ipv6_src' in pkt: ethertype = 0x86DD layers.append(ipv6.ipv6(src=pkt['ipv6_src'], dst=pkt['ipv6_src'])) else: ethertype = 0x800 if 'ipv4_src' in pkt: net = ipv4.ipv4(src=pkt['ipv4_src'], dst=pkt['ipv4_dst']) else: net = ipv4.ipv4() layers.append(net) if 'vid' in pkt: tpid = 0x8100 layers.append(vlan.vlan(vid=pkt['vid'], ethertype=ethertype)) else: tpid = ethertype eth = ethernet.ethernet(dst=pkt['eth_dst'], src=pkt['eth_src'], ethertype=tpid) layers.append(eth) result = packet.Packet() for layer in layers: result.add_protocol(layer) return result
def _arp_request(self, msg, port, data): # ARPリクエストを生成する creste from icmp or v4 packet pkt = packet.Packet(data) src_mac = self.gateway_mac pkt_ipv4 = pkt.get_protocol(ipv4.ipv4) if pkt_ipv4: dst_ip = pkt_ipv4.dst else: return # Buffer IDを控えておく if dst_ip in self.buffer: self.buffer[dst_ip].append(msg.buffer_id) else: self.buffer[dst_ip] = [msg.buffer_id] src_ip = self.gateway_ip print('ARP Request : ', src_ip, ' > ', dst_ip) pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=ether.ETH_TYPE_ARP, dst='ff:ff:ff:ff:ff:ff', src=src_mac)) pkt.add_protocol( arp.arp(opcode=arp.ARP_REQUEST, src_mac=src_mac, src_ip=src_ip, dst_mac='ff:ff:ff:ff:ff:ff', dst_ip=dst_ip)) # パケットを送信する self._send_packet(ofproto_v1_3.OFPP_FLOOD, pkt, self.datapath.ofproto.OFP_NO_BUFFER) self._send_packet(self.gateway_port, pkt, self.datapath.ofproto.OFP_NO_BUFFER)
def envia_pkt_broadcasting(self, datapath, parser, ofproto, in_port, src_mac, src_ip, dst_ip, debug_proto=''): # print(debug_proto) #DEBUG e = ethernet.ethernet(dst=BROADCAST_MAC, src=src_mac, ethertype=ether.ETH_TYPE_ARP) a = arp.arp(hwtype=1, proto=0x800, hlen=6, plen=4, opcode=1, src_mac=src_mac, src_ip=src_ip, dst_mac=ZERO_MAC, dst_ip=dst_ip) p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() actions4 = [parser.OFPActionOutput(ofproto.OFPP_FLOOD, 0)] out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=in_port, actions=actions4, data=p.data) datapath.send_msg(out)
def reply_arp(self, datapath, eth_dst, ip_dst, in_port): ofproto = datapath.ofproto parser = datapath.ofproto_parser actions = [parser.OFPActionOutput(in_port)] ARP_Reply = packet.Packet() ARP_Reply.add_protocol( ethernet.ethernet(ethertype=ether_types.ETH_TYPE_ARP, dst=eth_dst, src=self.controller_mac)) ARP_Reply.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=self.controller_mac, src_ip=self.controller_ip, dst_mac=eth_dst, dst_ip=ip_dst)) ARP_Reply.serialize() out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=ARP_Reply.data) datapath.send_msg(out)
def arp_rep(self, datapath, src, dst, dst_ip, src_ip, eth, msg): ofproto = datapath.ofproto parser = datapath.ofproto_parser # datapath.ofproto_parser object that represent the OpenFlow protocol that Ryu and the switch negotiated pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=eth.ethertype, dst=src, src=dst)) pkt.add_protocol( arp.arp(opcode=2, src_mac=dst, src_ip=dst_ip, dst_mac=src, dst_ip=src_ip)) # opcode=2 for reply pkt.serialize( ) # Generate a corresponding sequence of bytes of the packet(encode the packet) actions = [ parser.OFPActionOutput(port=msg.in_port) ] # OFPActionOutputclass specifies a switchport that you wish to send the packet outof data = pkt.data #The ofp_packet_out message instructs a switch to send a packet. The packet might be one constructed at the controller, #or it might be one that the switch received, buffered, and forwarded to the controller (and is now referenced by a buffer_id) out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=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 crear_y_enviar_paquete(self, id_core): #creamos el paquete e = ethernet.ethernet(dst='ff:ff:ff:ff:ff:ff', src=str(self.mac_switches[id_core][0]), ethertype=0x0806) a = arp.arp(hwtype=1, proto=0x0800, hlen=6, plen=4, opcode=1, src_mac=str(self.mac_switches[id_core][0]), src_ip='0.0.0.0', dst_mac=str(self.mac_switches[id_core][0]), dst_ip='0.0.0.0') p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() #enpaquetamos en PacketIN parser = self.switches[id_core].ofproto_parser actions = [ parser.OFPActionOutput(self.switches[id_core].ofproto.OFPP_ALL) ] out = parser.OFPPacketOut( datapath=self.switches[id_core], buffer_id=self.switches[id_core].ofproto.OFP_NO_BUFFER, in_port=0, actions=actions, data=p.data) self.switches[id_core].send_msg(out) #aumentamos el contador de packet_out self.packet_out = int(self.packet_out) + 1 print "Enviado el mensaje correctamente"
def _handle_arp(self, datapath, port, eth, pkt_arp): ofproto = datapath.ofproto parser = datapath.ofproto_parser if pkt_arp.opcode != arp.ARP_REQUEST: return pkt = packet.Packet() if pkt_arp.dst_ip in self.arptable: fin_src_mac = self.arptable[pkt_arp.dst_ip] pkt.add_protocol( ethernet.ethernet(ethertype=eth.ethertype, dst=eth.src, src=fin_src_mac)) pkt.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=fin_src_mac, src_ip=pkt_arp.dst_ip, dst_mac=eth.src, dst_ip=pkt_arp.src_ip)) pkt.serialize() data = pkt.data actions = [parser.OFPActionOutput(port=port)] self.logger.info("packet out for arp reply %s" % (pkt, )) out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=data) datapath.send_msg(out)
def send_arp(self, dp, arp_opcode, vlan_id, src_mac, dst_mac, src_ip, dst_ip, arp_target_mac, output): # Generate ARP packet if vlan_id != VLANID_NONE: ether_proto = ether.ETH_TYPE_8021Q pcp = 0 cfi = 0 vlan_ether = ether.ETH_TYPE_ARP v = vlan.vlan(pcp, cfi, vlan_id, vlan_ether) else: ether_proto = ether.ETH_TYPE_ARP hwtype = 1 arp_proto = ether.ETH_TYPE_IP hlen = 6 plen = 4 pkt = packet.Packet() e = ethernet.ethernet(dst_mac, src_mac, ether_proto) a = arp.arp(hwtype, arp_proto, hlen, plen, arp_opcode, src_mac, src_ip, arp_target_mac, dst_ip) pkt.add_protocol(e) if vlan_id != VLANID_NONE: pkt.add_protocol(v) pkt.add_protocol(a) pkt.serialize() # Send packet out self.send_packet_out(dp, output, pkt.data)
def arp_reply(self,datapath, src, dst, dst_ip, src_ip, eth, msg): ofproto = datapath.ofproto parser = datapath.ofproto_parser pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=eth.ethertype, dst=src, src=dst)) pkt.add_protocol(arp.arp(opcode=2, src_mac=dst, src_ip=dst_ip, dst_mac=src, dst_ip=src_ip)) pkt.serialize() self.logger.info("packet-out %s", pkt) actions = [parser.OFPActionOutput(port=msg.in_port)] data = pkt.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=data) datapath.send_msg(out)
def get_arp_reply(self, datapath, pkt, eth, parser, ofproto, in_port): arp_pkt = pkt.get_protocol(arp.arp) dst_ip = arp_pkt.src_ip src_ip = arp_pkt.dst_ip dst_mac = eth.src #Determines which MAC address to send. if dst_ip != self.SERVER_IP_SIX and dst_ip != self.SERVER_IP_FIVE: src_mac = self.CURRENT_MAC else: if src_ip == self.SERVER_IP_ONE: src_mac = self.MAC_ONE elif src_ip == self.SERVER_IP_TWO: src_mac = self.MAC_TWO elif src_ip == self.SERVER_IP_THREE: src_mac = self.MAC_THREE elif src_ip == self.SERVER_IP_FOUR: src_mac = self.MAC_FOUR else: return #Creates the packet, adds the protocol, and sends the packet out. e = ethernet.ethernet(dst_mac, src_mac, ether_types.ETH_TYPE_ARP) a = arp.arp(1, 0x0800, 6, 4, 2, src_mac, src_ip, dst_mac, dst_ip) p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() actions = [parser.OFPActionOutput(ofproto.OFPP_IN_PORT)] out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=in_port, actions=actions, data=p.data) datapath.send_msg(out)
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 arp_handler(self, msg): datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] arp_pkt = pkt.get_protocol(arp.arp) if eth: eth_dst = eth.dst eth_src = eth.src # Break the loop for avoiding ARP broadcast storm if eth_dst == mac.BROADCAST_STR and arp_pkt: arp_dst_ip = arp_pkt.dst_ip if (datapath.id, eth_src, arp_dst_ip) in self.sw: if self.sw[(datapath.id, eth_src, arp_dst_ip)] != in_port: datapath.send_packet_out(in_port=in_port, actions=[]) return True else: self.sw[(datapath.id, eth_src, arp_dst_ip)] = in_port # Try to reply arp request if arp_pkt: hwtype = arp_pkt.hwtype proto = arp_pkt.proto hlen = arp_pkt.hlen plen = arp_pkt.plen opcode = arp_pkt.opcode arp_src_ip = arp_pkt.src_ip arp_dst_ip = arp_pkt.dst_ip if opcode == arp.ARP_REQUEST: if arp_dst_ip in self.arp_table: actions = [parser.OFPActionOutput(in_port)] ARP_Reply = packet.Packet() ARP_Reply.add_protocol(ethernet.ethernet( ethertype=eth.ethertype, dst=eth_src, src=self.arp_table[arp_dst_ip])) ARP_Reply.add_protocol(arp.arp( opcode=arp.ARP_REPLY, src_mac=self.arp_table[arp_dst_ip], src_ip=arp_dst_ip, dst_mac=eth_src, dst_ip=arp_src_ip)) ARP_Reply.serialize() out = parser.OFPPacketOut( datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=ARP_Reply.data) datapath.send_msg(out) return True return False
def answer_arp(self, mac, port): pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=self.pkt_eth.ethertype, dst=self.get_mac_src(), src=mac)) pkt.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=mac, src_ip=self.get_arp_ip_dst(), dst_mac=self.pkt_arp.src_mac, dst_ip=self.get_arp_ip_src())) ofproto = self.datapath.ofproto parser = self.datapath.ofproto_parser pkt.serialize() actions = [parser.OFPActionOutput(port=port)] out = parser.OFPPacketOut(datapath=self.ev.msg.datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data) self.datapath.send_msg(out)
def _respond_arp(self, datapath, port, arptbl, pkt_ethernet, pkt_vlan, pkt_arp): if pkt_arp.opcode != arp.ARP_REQUEST: LOG.debug("unknown arp op %s", pkt_arp.opcode) return False ip_addr = pkt_arp.dst_ip hw_addr = arptbl.get(ip_addr) if hw_addr is None: LOG.debug("unknown arp request %s", ip_addr) return False LOG.debug("responding arp request %(ip_addr)s -> %(hw_addr)s", {'ip_addr': ip_addr, 'hw_addr': hw_addr}) pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=hw_addr)) if pkt_vlan: pkt.add_protocol(vlan.vlan(cfi=pkt_vlan.cfi, ethertype=pkt_vlan.ethertype, pcp=pkt_vlan.pcp, vid=pkt_vlan.vid)) pkt.add_protocol(arp.arp(opcode=arp.ARP_REPLY, src_mac=hw_addr, src_ip=ip_addr, dst_mac=pkt_arp.src_mac, dst_ip=pkt_arp.src_ip)) self._send_arp_reply(datapath, port, pkt) return True
def _arp_reply(self, msg, port, data): # ARPリプライを生成する pkt = packet.Packet(data) pkt_ethernet = pkt.get_protocol(ethernet.ethernet) pkt_arp = pkt.get_protocol(arp.arp) if pkt_arp: pass else: return if pkt_arp.opcode != arp.ARP_REQUEST: return # dst_mac, src_mac, dst_ip, src_ip dst_mac = pkt_arp.src_mac src_mac = self.gateway_mac dst_ip = pkt_arp.src_ip src_ip = pkt_arp.dst_ip print('ARP Reply : ', src_ip, ' > ', dst_ip) pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=src_mac)) pkt.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=src_mac, src_ip=src_ip, dst_mac=dst_mac, dst_ip=dst_ip)) # パケットを送信する self._send_packet(port, pkt, self.datapath.ofproto.OFP_NO_BUFFER)
def arp_process(self, datapath, eth, a, in_port): r = arp_table.get(a.dst_ip) if r: self.logger.info("Matched MAC %s ", r) arp_resp = packet.Packet() arp_resp.add_protocol( ethernet.ethernet(ethertype=eth.ethertype, dst=eth.src, src=r)) arp_resp.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=r, src_ip=a.dst_ip, dst_mac=a.src_mac, dst_ip=a.src_ip)) arp_resp.serialize() actions = [] actions.append(datapath.ofproto_parser.OFPActionOutput(in_port)) parser = datapath.ofproto_parser ofproto = datapath.ofproto out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=arp_resp) datapath.send_msg(out) self.logger.info("Proxied ARP Response packet")
def handle_arp(self, dp, port, pkt_ethernet, pkt_arp): if pkt_arp.opcode != arp.ARP_REQUEST: return if self.arp_table.get(pkt_arp.dst_ip) == None: return get_mac = self.arp_table[pkt_arp.dst_ip] pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet( ethertype=ether.ETH_TYPE_ARP, dst = pkt_ethernet.src, src = get_mac ) ) pkt.add_protocol( arp.arp( opcode=arp.ARP_REPLY, src_mac= get_mac, src_ip = pkt_arp.dst_ip, dst_mac= pkt_arp.src_mac, dst_ip = pkt_arp.src_ip ) ) self.send_packet(dp, port, pkt)
def arp_reply(self, datapath, src, dst, dst_ip, src_ip, eth, msg): ofproto = datapath.ofproto parser = datapath.ofproto_parser pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=eth.ethertype, dst=src, src=dst)) pkt.add_protocol( arp.arp(opcode=2, src_mac=dst, src_ip=dst_ip, dst_mac=src, dst_ip=src_ip)) pkt.serialize() self.logger.info("packet-out %s", pkt) actions = [parser.OFPActionOutput(port=msg.in_port)] data = pkt.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=data) datapath.send_msg(out)
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 _handle_arp_overrider(self, datapath, port, pkt_ethernet, pkt_arp): if pkt_arp.opcode != arp.ARP_REQUEST: return #Learn the MAC to IP mac_lst = [] for each_key in GlobalTables.mac_to_port.keys(): x = GlobalTables.mac_to_port[each_key] for mac,port in x.iteritems(): mac_lst.append(mac) if (pkt_arp.src_mac in mac_lst): self.learn_mac_to_ip(datapath.id, pkt_arp.src_mac, pkt_arp.src_ip) self.logger.info("INFO: New MAC_TO_IP: %s", GlobalTables.mac_to_ip) #Generate response pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype = pkt_ethernet.ethertype, dst = pkt_ethernet.src, src = GlobalTables.hw_addr)) pkt.add_protocol(arp.arp(opcode = arp.ARP_REPLY, src_mac = '02:00:00:00:00:01', src_ip = pkt_arp.dst_ip, dst_mac = pkt_arp.src_mac, dst_ip = pkt_arp.src_ip)) self.logger.info("INFO: Sending ARPOverrider response") self._send_packet(datapath, port, pkt)
def send_arp_reply(self, of_packet, data_packet): '''Builds and sends an ARP reply, if the IP corresponds to the switch''' arp_dst_ip = data_packet[1].dst_ip if arp_dst_ip == config.nat_internal_ip: arp_dst_mac = config.nat_internal_mac elif arp_dst_ip == config.nat_external_ip: arp_dst_mac = config.nat_external_mac # Destination ip is one of the internal hosts else: self.switch_forward(of_packet, data_packet) return self.debug('Sending ARP reply: %s -> %s' % (arp_dst_ip, arp_dst_mac)) eth_packet = ethernet.ethernet(dst=data_packet[1].src_mac, src=arp_dst_mac, ethertype=ether.ETH_TYPE_ARP) arp_packet = arp.arp(hwtype=1, proto=ether.ETH_TYPE_IP, hlen=6, plen=4, opcode=arp.ARP_REPLY, src_mac=arp_dst_mac, src_ip=arp_dst_ip, dst_mac=data_packet[1].src_mac, dst_ip=data_packet[1].src_ip) new_packet = packet.Packet() new_packet.add_protocol(eth_packet) new_packet.add_protocol(arp_packet) new_packet.serialize() self.send_packet(new_packet, of_packet, of_packet.datapath.ofproto.OFPP_IN_PORT)
def _arp_proxy_handler(self, ev): msg = ev.msg pkt = ev.pkt datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match["in_port"] eth_protocol = pkt.get_protocol(ethernet.ethernet) eth_src = eth_protocol.src arp_protocol = pkt.get_protocol(arp.arp) src_ip = arp_protocol.src_ip dst_ip = arp_protocol.dst_ip self.arp_table[src_ip] = eth_src self.dp_to_ip[datapath.id].add(src_ip) if arp_protocol.opcode == arp.ARP_REPLY: return dst_mac = self.arp_table.get(dst_ip) if dst_mac is None: # Flood to flood_ports ports = self.wrapper.get_flood_ports() for dpid, out_port in ports: if (dpid, out_port) == (datapath.id, in_port): continue self.logger.info("flood to port:%d:%d", dpid, out_port) dp = self.dpset.get(dpid) actions = [parser.OFPActionOutput(out_port)] out = dp.ofproto_parser.OFPPacketOut(datapath=dp, buffer_id=dp.ofproto.OFP_NO_BUFFER, in_port=dp.ofproto.OFPP_CONTROLLER, actions=actions, data=msg.data) dp.send_msg(out) else: ARP_Reply = packet.Packet() ARP_Reply.add_protocol(ethernet.ethernet(ethertype=eth_protocol.ethertype, dst=eth_src, src=dst_mac)) ARP_Reply.add_protocol(arp.arp(opcode=arp.ARP_REPLY, src_mac=dst_mac, src_ip=dst_ip, dst_mac=eth_src, dst_ip=src_ip)) ARP_Reply.serialize() actions = [parser.OFPActionOutput(in_port)] out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=ARP_Reply.data) datapath.send_msg(out) self.logger.debug("%s - %s" % (dst_ip, dst_mac)) return True
def handle_arp(self, datapath, in_port, pkt): ofproto = datapath.ofproto parser = datapath.ofproto_parser # parse out the ethernet and arp packet eth_pkt = pkt.get_protocol(ethernet.ethernet) arp_pkt = pkt.get_protocol(arp.arp) # obtain the MAC of dst IP arp_resolv_mac = self.arp_table[arp_pkt.dst_ip] ### generate the ARP reply msg, please refer RYU documentation ### the packet library section ether_hd = ethernet.ethernet(dst = eth_pkt.src, src = arp_resolv_mac, ethertype = ether.ETH_TYPE_ARP); arp_hd = arp.arp(hwtype=1, proto = 2048, hlen = 6, plen = 4, opcode = 2, src_mac = arp_resolv_mac, src_ip = arp_pkt.dst_ip, dst_mac = eth_pkt.src, dst_ip = arp_pkt.src_ip); arp_reply = packet.Packet() arp_reply.add_protocol(ether_hd) arp_reply.add_protocol(arp_hd) arp_reply.serialize() # send the Packet Out mst to back to the host who is initilaizing the ARP actions = [parser.OFPActionOutput(in_port)]; out = parser.OFPPacketOut(datapath, ofproto.OFP_NO_BUFFER, ofproto.OFPP_CONTROLLER, actions, arp_reply.data) datapath.send_msg(out)
def request_arp(self, datapath, ip): ofproto = datapath.ofproto parser = datapath.ofproto_parser actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)] ARP_Request = packet.Packet() ARP_Request.add_protocol( ethernet.ethernet(ethertype=ether_types.ETH_TYPE_ARP, dst=mac.BROADCAST_STR, src=self.controller_mac)) ARP_Request.add_protocol( arp.arp(opcode=arp.ARP_REQUEST, src_mac=self.controller_mac, src_ip=self.controller_ip, dst_mac=mac.BROADCAST_STR, dst_ip=ip)) ARP_Request.serialize() out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=ARP_Request.data) datapath.send_msg(out)
def create_arp_reply(self, source_mac, source_ip): #print("Data Received: ", source_mac, source_ip) src_mac = self.service_mac src_ip = self.service_ip dst_mac = source_mac #source(requester) becomes destination dst_ip = source_ip arp_opcode = 2 #opcode for Reply ethertype = 2054 hwtype = 1 proto = 2048 hlen = 6 plen = 4 pkt = packet.Packet() e = ethernet.ethernet(dst_mac, src_mac, ethertype) a = arp.arp(hwtype, proto, hlen, plen, arp_opcode, src_mac, src_ip, dst_mac, dst_ip) pkt.add_protocol(e) pkt.add_protocol(a) pkt.serialize() return pkt
def handle_arp_for_server(self, dmac, dip): self.logger.info("Handling ARP Reply for dummy Server IP") #handle arp request for Dummy Server IP #checked Wireshark for sample pcap for arp-reply #build arp packet - format source web link included in reference hrdw_type = 1 #Hardware Type: ethernet 10mb protocol = 2048 #Layer 3 type: Internet Protocol hrdw_add_len = 6 # length of mac prot_add_len = 4 # lenght of IP opcode = 2 # arp reply sha = self.dummyMAC #sender address spa = self.dummyIP #sender IP tha = dmac #target MAC tpa = dip #target IP ether_type = 2054 #ethertype ARP pack = packet.Packet() eth_frame = ethernet.ethernet(dmac, sha, ether_type) arp_rpl_frame = arp.arp(hrdw_type, protocol, hrdw_add_len, prot_add_len, opcode, sha, spa, tha, tpa) pack.add_protocol(eth_frame) pack.add_protocol(arp_rpl_frame) pack.serialize() self.logger.info("Done handling ARP Reply") return pack
def ARPPacket(self,arp_msg,in_port,datapath): if (self.interfaces_virtuales[self.tabla_vlan[in_port]][2]==arp_msg.dst_ip and arp_msg.opcode==arp.ARP_REQUEST): e = ethernet.ethernet(dst=arp_msg.src_mac, src=self.interfaces_virtuales[self.tabla_vlan[in_port]][0], ethertype=ether.ETH_TYPE_ARP) a = arp.arp(opcode=arp.ARP_REPLY, src_mac=self.interfaces_virtuales[self.tabla_vlan[in_port]][0], src_ip=arp_msg.dst_ip, dst_mac=arp_msg.src_mac, dst_ip=arp_msg.src_ip)
def handle_arp_request(self, msg, pkt, arp_pkt): """ called when receiving ARP request from hosts. when a host send a request first time, it has no MAC address information for its gateway, so it will send a ARP request to the switch. """ print "################## handle arp request #####################" #switch = self.switches[msg.datapath.id] rtr = self.routers[msg.datapath.id] print vars(msg) in_port_no = msg.match["in_port"] req_dst_ip = arp_pkt.dst_ip req_src_ip = arp_pkt.src_ip #port = switch.ports[in_port_no] logger.info('receive ARP request: who has %s? tell %s (dpid=%s)', str(req_dst_ip), str(req_src_ip), dpid_lib.dpid_to_str(msg.datapath.id)) # handle ARP request for gatewayr print type(req_dst_ip) print req_dst_ip print rtr.ports[in_port_no].ip_addr print type(rtr.ports[in_port_no].ip_addr) '''if rtr.ports[in_port_no].ip_addr != req_dst_ip: logger.warning('cannot reply ARP, please check gateway configuration. (dpid=%s)', dpid_lib.dpid_to_str(msg.datapath.id)) return''' port = rtr.ports[in_port_no] datapath = msg.datapath reply_src_mac = str(port.mac_addr) ether_layer = self.find_packet(pkt, 'ethernet') self.update_arp_entry(msg.datapath.id,pkt) print "ip_src :",req_dst_ip print "ip_dst :",req_src_ip print "out_port:",in_port_no # pack a ARP reply packet e = ethernet.ethernet(dst = ether_layer.src, src = reply_src_mac, ethertype = ether.ETH_TYPE_ARP) a = arp.arp(hwtype = arp.ARP_HW_TYPE_ETHERNET, proto = ether.ETH_TYPE_IP, hlen = 6, plen = 4, opcode = arp.ARP_REPLY, src_mac = reply_src_mac, src_ip = req_dst_ip, dst_mac = arp_pkt.src_mac, dst_ip = req_src_ip) p = packet.Packet() p.add_protocol(e) p.add_protocol(a) print vars(p) p.serialize() data = p.data actions = [datapath.ofproto_parser.OFPActionOutput(in_port_no)] out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=datapath.ofproto.OFP_NO_BUFFER, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=data) print "send arp reply" datapath.send_msg(out) logger.info('ARP replied: %s - %s', reply_src_mac, req_dst_ip)
def _handle_arp(self, msg, pkt, arp_pkt): """ 1) handles ARP request from hosts, about their gateways; only works in IPv4 since IPv6 uses NDP(ICMPv6); e.g. when a host need to send a packet to the gateway, it will firstly send an ARP to get the MAC address of the gateway 2) handles ARP reply from hosts, and try to send packets currently stored in switch.msg_buffer 3) brutally forward all ARP packets to the tap port, so the system protocol stack could also handle those MAC addresses """ LOG.debug('Handling ARP packet %s', arp_pkt) # forward ARP packets to the tap port self.write_to_tap(pkt.data) if arp_pkt.opcode == arp.ARP_REPLY: self._handle_arp_reply(msg, pkt, arp_pkt) return if arp_pkt.opcode != arp.ARP_REQUEST: return switch = self.dpid_to_switch[msg.datapath.id] in_port_no = msg.in_port req_dst_ip = arp_pkt.dst_ip req_src_ip = arp_pkt.src_ip port = switch.ports[in_port_no] if port.gateway and netaddr.IPAddress(req_dst_ip) != port.gateway.gw_ip: return datapath = msg.datapath reply_src_mac = str(port.hw_addr) ether_layer = self.find_packet(pkt, 'ethernet') e = ethernet.ethernet(dst = ether_layer.src, src = reply_src_mac, ethertype = ether.ETH_TYPE_ARP) a = arp.arp(hwtype = arp.ARP_HW_TYPE_ETHERNET, proto = ether.ETH_TYPE_IP, hlen = 6, plen = 4, opcode = arp.ARP_REPLY, src_mac = reply_src_mac, src_ip = req_dst_ip, dst_mac = arp_pkt.src_mac, dst_ip = req_src_ip) p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() datapath.send_packet_out(in_port = ofproto_v1_0.OFPP_NONE, actions = [datapath.ofproto_parser.OFPActionOutput(in_port_no)], data = p.data) LOG.debug('ARP replied: %s - %s', reply_src_mac, req_dst_ip)
def _send_arp_req(self, datapath): pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet( ethertype = ETH_TYPE_ARP, src = BROADCAST_STR, dst = BROADCAST_STR) ) pkt.add_protocol( arp.arp( opcode = ARP_REQUEST, src_mac = '01:02:03:04:05:06', src_ip = '192.168.0.1', dst_mac = BROADCAST_STR, dst_ip = '255.255.255.255') ) of_tb_func.ofSendPck(datapath, pkt, ofproto13.OFPP_FLOOD)
def broadcast_arp_request(src_mac, src_ip, target_ip): pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=ETH_TYPE_ARP, dst=BROADCAST, src=src_mac)) pkt.add_protocol( arp.arp(opcode=arp.ARP_REQUEST, src_mac=src_mac, src_ip=src_ip, dst_mac=TARGET_MAC_ADDRESS, dst_ip=target_ip) ) pkt.serialize() data = pkt.data # print 'Built up a broadcast arp request packet:', data return data
def _handle_arp_rq(self, dst_ip): pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=0x806,\ dst='ff:ff:ff:ff:ff:ff',\ src=self.hw_addr)) pkt.add_protocol(arp.arp(opcode=arp.ARP_REQUEST,\ src_mac=self.hw_addr,\ src_ip=self.ip_addr,\ dst_mac='00:00:00:00:00:00',\ dst_ip=dst_ip)) self._flood_packet(pkt)
def build_from_service(service): pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet( ethertype = ETH_TYPE_ARP, src = ServiceDiscoveryPacket.CONTROLLER_MAC, dst = BROADCAST_STR) ) pkt.add_protocol( arp.arp( opcode = ARP_REQUEST, src_mac = ServiceDiscoveryPacket.CONTROLLER_MAC, src_ip = ServiceDiscoveryPacket.src_ip, #TODO change srcmac and src ip dst_mac = BROADCAST_STR, dst_ip = service.ip) ) return pkt