def assemble_ack(self, pkt): req_eth = pkt.get_protocol(ethernet.ethernet) req_ipv4 = pkt.get_protocol(ipv4.ipv4) req_udp = pkt.get_protocol(udp.udp) req = dhcp.dhcp.parser(pkt[3]) req[0].options.option_list.remove(next(opt for opt in req[0].options.option_list if opt.tag == 53)) req[0].options.option_list.insert(0, dhcp.option(tag=51, value='8640')) req[0].options.option_list.insert(0, dhcp.option(tag=53, value='05'.decode('hex'))) ack_pkt = packet.Packet() ack_pkt.add_protocol(ethernet.ethernet(ethertype=req_eth.ethertype, dst=req_eth.src, src=self.hw_addr)) ack_pkt.add_protocol(ipv4.ipv4(dst=req_ipv4.dst, src=self.dhcp_server, proto=req_ipv4.proto)) ack_pkt.add_protocol(udp.udp(src_port=67,dst_port=68)) ack_pkt.add_protocol(dhcp.dhcp(op=2, chaddr=req_eth.src, siaddr=self.dhcp_server, boot_file=req[0].boot_file, yiaddr=self.ip_addr, xid=req[0].xid, options=req[0].options)) self.logger.info("ASSEMBLED ACK: %s" % ack_pkt) return ack_pkt
def send_arp_response(self, datapath, arp_opcode, src_mac, dst_mac, src_ip, dst_ip, output): # Generate ARP packet ethertype_ether = ether_types.ETH_TYPE_ARP arp_opcode = arp.ARP_REPLY hwtype = arp.ARP_HW_TYPE_ETHERNET ethertype_arp = ether_types.ETH_TYPE_IP hlen = 6 plen = 4 pkt = packet.Packet() e = ethernet.ethernet(src=dst_mac, dst=src_mac, ethertype=ethertype_ether) a = arp.arp(hwtype=hwtype, proto=ethertype_arp, hlen=hlen, plen=plen, opcode=arp_opcode, src_mac=dst_mac, dst_mac=src_mac, src_ip=dst_ip, dst_ip=src_ip) pkt.add_protocol(e) pkt.add_protocol(a) pkt.serialize() actions = [datapath.ofproto_parser.OFPActionOutput(output, 0)] ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser res = ofp_parser.OFPPacketOut(datapath=datapath, buffer_id=ofp.OFP_NO_BUFFER, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data) LOG.info('Sending ARP response for %s', src_ip) datapath.send_msg(res)
def generateACKtoACKPSHpkt(self): ipv4_p = self.payload_pkt.get_protocol(ipv4.ipv4) tcp_P = self.payload_pkt.get_protocol(tcp.tcp) eth_p = self.payload_pkt.get_protocol(ethernet.ethernet) e = ethernet.ethernet(dst=eth_p.src, src=eth_p.dst) ip = ipv4.ipv4(4, 5, ipv4_p.tos, 0, ipv4_p.identification, ipv4_p.flags, 0, ipv4_p.ttl, ipv4_p.proto, 0, src=ipv4_p.dst, dst=ipv4_p.src, option=ipv4_p.option) bits = 1 << 4 tcpd = tcp.tcp(tcp_P.dst_port, tcp_P.src_port, tcp_P.ack, tcp_P.seq + 1, 0, bits, tcp_P.window_size, 0, tcp_P.urgent, option=tcp_P.option) ack_pkt = packet.Packet() ack_pkt.add_protocol(e) ack_pkt.add_protocol(ip) ack_pkt.add_protocol(tcpd) ack_pkt.serialize() print "ACK packet is generated." return ack_pkt
def report_node_ip(self, req, body, *args, **kwargs): mecId = body['mecId'] if LOCAL_TENANT_MODE: endpoint_id = 'dist' else: endpoint_id = mecId dpid = dpids[endpoint_id] datapath = self.get_datapath(dpid) parser = datapath.ofproto_parser ofproto = datapath.ofproto ofctl = Ofctl(datapath) # SAVE RECEIVED PARAMETERS ipAddr = body['nodeIP'] if mecId not in mecs.keys(): mecs[mecId] = {'ipAddr': ipAddr} LOG.error('Report Node IP: %s, MEC: %s, mecs: %s', mecId, ipAddr, mecs) # BUILD ARP PACKET e = ethernet.ethernet(dst = 'ff:ff:ff:ff:ff:ff', src = ports[endpoint_id][CDN_SIDE_IF]['hwaddr'], ethertype=ether.ETH_TYPE_ARP) a = arp.arp(hwtype=1, proto=0x0800, hlen=6, plen=4, opcode=arp.ARP_REQUEST, src_mac=ports[endpoint_id][CDN_SIDE_IF]['hwaddr'], src_ip=local_ip[endpoint_id], dst_mac='00:00:00:00:00:00', dst_ip=ipAddr) p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() # PACKET OUT actions = [parser.OFPActionOutput(ports[endpoint_id][CDN_SIDE_IF]['port_no'])] out = parser.OFPPacketOut( datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=p) datapath.send_msg(out)
def _handle_arp(self, datapath, in_port, vlan_id, eth_pkt, vlan_pkt, arp_pkt): # check if it is an arp request if arp_pkt.opcode != arp.ARP_REQUEST: return # variable population arp_dst_ip = arp_pkt.dst_ip; arp_src_mac = arp_pkt.src_mac arp_src_ip = arp_pkt.src_ip; vlan_exist = False print (in_port, vlan_id, arp_src_ip, arp_dst_ip, arp_src_mac) # save SRC IP and MAC for later use for i in range(len(self.vlan_src_ip_mac)): if vlan_id == self.vlan_src_ip_mac[i]['vlan']: vlan_exist = True if not vlan_exist: self.vlan_src_ip_mac.append({"vlan": vlan_id, "MAC":arp_src_mac, "IP":arp_src_ip}) print self.vlan_src_ip_mac # create ARP Response if arp_dst_ip == HOST_IP: # create ethernet pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=ether.ETH_TYPE_8021Q, dst = arp_src_mac, src = HOST_MAC)) # add vlan tag pkt.add_protocol(vlan.vlan(vid=vlan_id, ethertype=ether.ETH_TYPE_ARP)) #add arp header pkt.add_protocol(arp.arp(proto=0x0800,opcode=arp.ARP_REPLY, src_ip= arp_dst_ip, dst_ip= arp_src_ip, src_mac = HOST_MAC, dst_mac = arp_src_mac)) self._send_packet(datapath, in_port, pkt) else: return
def handle_socket_msg(self): pkt_eth = self._pkt.get_protocols(ethernet.ethernet)[0] pkt_ip = self._pkt.get_protocols(ipv4.ipv4)[0] pkt_udp = self._pkt.get_protocols(udp.udp)[0] pkt_dns = DNS(self._pkt[-1]) if pkt_udp.dst_port == 53: #print ('A DNS query for controller is received,',pkt_dns) #print ('--pkt---',self._pkt) #query=pkt_dns.qd.qname.split('.') #new_query=query[1]+'.'+query[2] #print'---query--',new_query cs = self._controller.get_customers() cr_list = [] #index=0 for i in range(len(cs)): print('--pkt_ip.dst---', pkt_ip.dst, '--cs[i].get_name_server()---', cs[i].get_name_server()) if pkt_ip.dst in cs[i].get_name_server(): self._index = i print('--index---', self._index) if pkt_dns: cs = self._controller.get_customers() #create a new DNS packet to send to the name server new_pkt = packet.Packet() print('--dst.mac--', cs[self._index].get_next_hop_mac(), self._controller.get_ip()) new_pkt.add_protocol( ethernet.ethernet(src='00:00:00:00:00:ff', dst=cs[self._index].get_next_hop_mac())) new_pkt.add_protocol( ipv4.ipv4(src=self._controller.get_ip(), dst=cs[self._index].get_name_server(), proto=17)) new_pkt.add_protocol(udp.udp(src_port=22345, dst_port=53)) new_pkt.add_protocol(self._pkt[-1]) new_pkt.serialize() self.send_dns_packet(new_pkt, cs[self._index].get_datapath(), cs[self._index].get_ingress_port())
def _arp_handler(self, datapath, in_port, pkt): eth_hd = pkt.get_protocol(ethernet.ethernet) arp_hd = pkt.get_protocol(arp.arp) #if not ((arp_hd.src_ip in self.mac_table) and (self.mac_table[arp_hd.src_ip]==arp_hd.src_mac)): if True: self.mac_table[arp_hd.src_ip] = arp_hd.src_mac print('INFO: MAC learnt %s@%s at dpid %s' % (arp_hd.src_ip, arp_hd.src_mac, str(datapath.id))) #install flows in mac table ofproto = datapath.ofproto parser = datapath.ofproto_parser actions = [parser.OFPActionSetField(eth_dst=arp_hd.src_mac)] inst = [parser.OFPInstructionActions(ofproto.OFPIT_WRITE_ACTIONS, actions)] if datapath.id == 3: #if arp_hd.src_ip == '192.168.0.2': #for ip in self.probe_conf: #match = parser.OFPMatch(eth_type=0x800, #ipv4_dst=ip) #actions = [parser.OFPActionSetField(eth_dst=arp_hd.src_mac)] #inst = [parser.OFPInstructionActions(ofproto.OFPIT_WRITE_ACTIONS, actions)] #self._add_flow(datapath, 3, 10, 0, match, inst) match = parser.OFPMatch(eth_type=0x800, ipv4_dst=arp_hd.src_ip) self._add_flow(datapath, 3, 10, 0, match, inst) else: match = parser.OFPMatch(metadata=int(IPAddress(arp_hd.src_ip))) self._add_flow(datapath, 4, 10, 0, match, inst) #reply arp request if arp_hd.opcode == arp.ARP_REQUEST and arp_hd.dst_ip in self.virtual_ip: arp_reply = packet.Packet() arp_reply.add_protocol(ethernet.ethernet(ethertype=eth_hd.ethertype, dst=eth_hd.src, src=self.virtual_ip[arp_hd.dst_ip])) arp_reply.add_protocol(arp.arp(opcode=arp.ARP_REPLY, src_mac=self.virtual_ip[arp_hd.dst_ip], src_ip=arp_hd.dst_ip, dst_mac=arp_hd.src_mac, dst_ip=arp_hd.src_ip)) self._send_packet_port(datapath, in_port, arp_reply)
def assemble_ack(self, pkt): req_eth = pkt.get_protocol(ethernet.ethernet) req_ipv4 = pkt.get_protocol(ipv4.ipv4) req_udp = pkt.get_protocol(udp.udp) req = pkt.get_protocol(dhcp.dhcp) if not (self.networkMap.findActiveHostByMac(req_eth.src)): return req.options.option_list.remove( next(opt for opt in req.options.option_list if opt.tag == 53)) req.options.option_list.insert(0, dhcp.option(tag=51, value='8640')) req.options.option_list.insert( 0, dhcp.option(tag=53, value='05'.decode('hex'))) req.options.option_list.insert( 0, dhcp.option(tag=1, value=self.bin_netmask)) req.options.option_list.insert( 0, dhcp.option(tag=3, value=self.bin_server)) req.options.option_list.insert(0, dhcp.option(tag=6, value=self.bin_dns)) ack_pkt = packet.Packet() ack_pkt.add_protocol( ethernet.ethernet(ethertype=req_eth.ethertype, dst=req_eth.src, src=self.hw_addr)) ack_pkt.add_protocol( ipv4.ipv4(dst=req_ipv4.dst, src=self.dhcp_server, proto=req_ipv4.proto)) ack_pkt.add_protocol(udp.udp(src_port=67, dst_port=68)) ack_pkt.add_protocol( dhcp.dhcp(op=2, chaddr=req_eth.src, siaddr=self.dhcp_server, boot_file=req.boot_file, yiaddr=(self.networkMap.findActiveHostByMac( req_eth.src).ip), xid=req.xid, options=req.options)) ack_pkt.serialize() return ack_pkt
def _handle_arp(self, dp, in_port, eth_pkt, pkt_arp): """Handling ARP request and providing a reply based on our table""" if pkt_arp.opcode != arp.ARP_REQUEST: # ignore all except ARP requests return elif pkt_arp.dst_ip not in self._gossipTop.tables.default_arp_table[ dp.id]: print "--->[%s] ARP not in default table, dst: %s" % ( dp.id, pkt_arp.dst_ip) return req_dst = pkt_arp.dst_ip print("--->[%s] Handling ARP message from %s, asking for: %s" % (dp.id, eth_pkt.src, req_dst)) # Creating an arp reply message # Starting with a common ethernet frame to requester pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet( ethertype=eth_pkt.ethertype, dst=eth_pkt.src, src=self._gossipTop.tables.switches_dpid_to_mac[dp.id])) pkt.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=self._gossipTop.tables.default_arp_table[dp.id] [req_dst], src_ip=req_dst, dst_mac=pkt_arp.src_mac, dst_ip=pkt_arp.src_ip)) # updating local tables self._gossipTop.tables.default_arp_table[dp.id][ pkt_arp.src_ip] = pkt_arp.src_mac self._gossipTop.tables.mac_to_port[dp.id][pkt_arp.src_mac] = in_port self._send_arp_reply(dp, pkt, in_port)
def create_arp_packet(self, dst_ip, dst_mac, src_port=None, datapath=None): pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet( dst=dst_mac, src=self.DHCP_SERVER_MAC, ethertype=ether.ETH_TYPE_ARP, )) pkt.add_protocol( arp.arp( hwtype=1, proto=0x0800, hlen=6, plen=4, opcode=2, src_mac=self.DHCP_SERVER_MAC, src_ip=self.DHCP_SERVER_IP, dst_mac=dst_mac, dst_ip=dst_ip, )) pkt.serialize() self.inject_packet(pkt, datapath, src_port)
def send_icmp_port_unreachable(self, datapath, old_pkt, output): pkt = packet.Packet() datapkt = packet.Packet() dst_ip = None for protocol in old_pkt: if not hasattr(protocol, 'protocol_name'): datapkt.add_protocol(protocol) elif protocol.protocol_name == 'ethernet': e = ethernet.ethernet(src=protocol.dst, dst=protocol.src, ethertype=ether_types.ETH_TYPE_IP) pkt.add_protocol(e) elif protocol.protocol_name == 'ipv4': ip = ipv4.ipv4(dst=protocol.src, src=protocol.dst, proto=in_proto.IPPROTO_ICMP) dst_ip = protocol.src pkt.add_protocol(ip) datapkt.add_protocol(protocol) else: datapkt.add_protocol(protocol) datapkt.serialize() icm_data = icmp.dest_unreach(data=datapkt.data) icm = icmp.icmp(type_=icmp.ICMP_DEST_UNREACH, code=icmp.ICMP_PORT_UNREACH_CODE, csum=0, data=icm_data) pkt.add_protocol(icm) pkt.serialize() actions = [datapath.ofproto_parser.OFPActionOutput(output, 0)] ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser res = ofp_parser.OFPPacketOut(datapath=datapath, buffer_id=ofp.OFP_NO_BUFFER, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data) LOG.info('Sending ICMP Port unreachable message for %s', dst_ip) datapath.send_msg(res)
def _send_arp_request(self, datapath, outport_no, dst_ip): src_mac_addr = \ self.dpid_to_switch[datapath.id].ports[outport_no].hw_addr src_ip = \ self.dpid_to_switch[datapath.id].ports[outport_no].gateway.gw_ip p = packet.Packet() e = ethernet.ethernet(dst=mac.BROADCAST, src=src_mac_addr, ethertype=ether.ETH_TYPE_ARP) p.add_protocol(e) a = arp.arp_ip(opcode=arp.ARP_REQUEST, src_mac=src_mac_addr, src_ip=src_ip, dst_mac=mac.DONTCARE, dst_ip=dst_ip) p.add_protocol(a) p.serialize() datapath.send_packet_out( in_port=ofproto_v1_0.OFPP_NONE, actions=[datapath.ofproto_parser.OFPActionOutput(outport_no)], data=p.data)
def handle_packet(self): #print "controller",self._controller, "federation ip",self._federation[0].get_ip() pkt_ip = self._pkt.get_protocols(ipv4.ipv4)[0] pkt_udp = self._pkt.get_protocols(udp.udp)[0] """ Handle DNS packet inside Controller. Each DNS packet carries with a udp packet. We used the DNS class of Scapy library to decode DNS queries. """ pkt_dns = DNS(self._pkt[-1]) cs = self._controller.get_customers() print '-------T-ID------------', self._controller.get_transaction_id() if (pkt_udp.dst_port == 53 and self._controller.get_transaction_id() is None) and pkt_dns.qd.qtype == 1 and pkt_dns.qd.qname != cs[ 0].get_ns_domain_name(): #if pkt_udp.dst_port==53: self._controller.set_port_number(pkt_udp.src_port) self._controller.set_transaction_id(pkt_dns.id) self._controller.set_packet_ip(pkt_ip.dst) ofp = self._datapath.ofproto parser = self._datapath.ofproto_parser output = ofp.OFPP_TABLE match = parser.OFPMatch() actions = [parser.OFPActionOutput(output)] cs = self._controller.get_customers() new_pkt = packet.Packet() new_pkt.add_protocol( ethernet.ethernet(src='00:aa:00:00:0f:11', dst=cs[0].get_as_pe_mac())) new_pkt.add_protocol(pkt_ip) new_pkt.add_protocol(pkt_udp) new_pkt.add_protocol(self._pkt[-1]) new_pkt.serialize() out = parser.OFPPacketOut(datapath=self._datapath, buffer_id=ofp.OFP_NO_BUFFER, in_port=3, actions=actions, data=new_pkt.data) self._datapath.send_msg(out)
def handle_arp(self, datapath, in_port, pkt): ofproto = datapath.ofproto parser = datapath.ofproto_parser eth_pkt = pkt.get_protocol(ethernet.ethernet) arp_pkt = pkt.get_protocol(arp.arp) arp_resolv_mac = self.arp_table[arp_pkt.dst_ip] 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_udp_reply(self, dpid, datapath, eth_dst, eth_src, ipv4_dst, ipv4_src, udp_dst, udp_src, out_port, message): ofproto = datapath.ofproto e = ethernet.ethernet(dst=eth_dst, src=eth_src, ethertype=ether.ETH_TYPE_IP) i = ipv4.ipv4(dst=ipv4_dst, src=ipv4_src, proto=17, total_length=0) u = udp.udp(src_port=udp_src, dst_port=udp_dst, total_length=0, csum=0) udp_h = u.serialize(message, i) ip_h = i.serialize(udp_h + message, e) eth_h = e.serialize(ip_h + udp_h + message, None) actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] data = eth_h + ip_h + udp_h + message 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 _packet_in_handler(self, ev): # 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 parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) pkt_arp = pkt.get_protocols(arp.arp) eth = pkt.get_protocols(ethernet.ethernet)[0] pkt_icmp = pkt.get_protocols(icmp.icmp) pkt_ipv4 = pkt.get_protocols(ipv4.ipv4) pkt_tcp = pkt.get_protocols(tcp.tcp) pkt_udp = pkt.get_protocols(udp.udp) dst = eth.dst src = eth.src dpid = format(datapath.id, "d").zfill(16) self.mac_to_port.setdefault(dpid, {}) self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port #Handle the arp protocol if pkt_arp: src_mac = "10:00:00:00:00:0" + pkt_arp.dst_ip[-1] dst_mac = "10:00:00:00:00:0" + pkt_arp.src_ip[-1] arp_reply_pkt = packet.Packet() arp_reply_pkt.add_protocol(ethernet.ethernet(ethertype=eth.ethertype, dst=eth.src, src=mac_add)) arp_reply_pkt.add_protocol(arp.arp(opcode=arp.ARP_REPLY, src_mac=src_mac, src_ip=pkt_arp.dst_ip, dst_mac=dst_mac, dst_ip=pkt_arp.src_ip)) arp_reply_pkt.serialize()
def _build_igmp(self): dl_dst = '11:22:33:44:55:66' dl_src = 'aa:bb:cc:dd:ee:ff' dl_type = ether.ETH_TYPE_IP e = ethernet(dl_dst, dl_src, dl_type) total_length = 20 + igmp._MIN_LEN nw_proto = inet.IPPROTO_IGMP nw_dst = '11.22.33.44' nw_src = '55.66.77.88' i = ipv4(total_length=total_length, src=nw_src, dst=nw_dst, proto=nw_proto) p = Packet() p.add_protocol(e) p.add_protocol(i) p.add_protocol(self.g) p.serialize() return p
def send_arp(self, datapath, opcode, srcMac, srcIp, dstMac, dstIp, outPort): if opcode == 1: targetMac = "00:00:00:00:00:00" targetIp = dstIp elif opcode == 2: targetMac = dstMac targetIp = dstIp e = ethernet.ethernet(dstMac, srcMac, ether_types.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)] #this packet is constructed by tyhe controller, so the in_port is OFPP_CONTROLLER. 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 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 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 send_arp_reply(self, datapath, srcMac, srcIp, dstMac, dstIp, outPort,msg): e = ethernet.ethernet(dstMac, srcMac, ether_types.ETH_TYPE_ARP) a = arp.arp(1, 0x0800, 6, 4, 2, srcMac, srcIp, dstMac, dstIp) p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() actions = [datapath.ofproto_parser.OFPActionSetDlDst(dl_addr=dstMac), datapath.ofproto_parser.OFPActionSetDlSrc(dl_addr=srcMac), datapath.ofproto_parser.OFPActionOutput(outPort)] match = datapath.ofproto_parser.OFPMatch( in_port=msg.in_port, dl_type=0x0806, nw_src=srcIp,nw_dst=dstIp) self.add_flow(datapath, match, actions) 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 _handle_arp(self, datapath, port, pkt_ethernet, pkt_arp): ofproto = datapath.ofproto parser = datapath.ofproto_parser # Get MAC address from ARP table arp_get_mac = self.arp_table[pkt_arp.dst_ip] # Generate ARP reply message pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=arp_get_mac)) pkt.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=arp_get_mac, src_ip=pkt_arp.dst_ip, dst_mac=pkt_arp.src_mac, dst_ip=pkt_arp.src_ip)) self._send_packet(datapath, port, pkt)
def assemble_offer(self, pkt, chaddr): chaddr_yiaddr = self.get_ip(chaddr) disc_eth = pkt.get_protocol(ethernet.ethernet) disc_ipv4 = pkt.get_protocol(ipv4.ipv4) disc_udp = pkt.get_protocol(udp.udp) disc = pkt.get_protocol(dhcp.dhcp) disc.options.option_list.remove( next(opt for opt in disc.options.option_list if opt.tag == 55)) disc.options.option_list.remove( next(opt for opt in disc.options.option_list if opt.tag == 53)) disc.options.option_list.remove( next(opt for opt in disc.options.option_list if opt.tag == 12)) disc.options.option_list.insert( 0, dhcp.option(tag=1, value=self.bin_netmask)) disc.options.option_list.insert( 0, dhcp.option(tag=3, value=self.bin_server)) disc.options.option_list.insert( 0, dhcp.option(tag=6, value=self.bin_dns)) disc.options.option_list.insert( 0, dhcp.option(tag=12, value=self.hostname)) disc.options.option_list.insert( 0, dhcp.option(tag=53, value=str.encode('\x02'))) disc.options.option_list.insert( 0, dhcp.option(tag=54, value=self.bin_server)) offer_pkt = packet.Packet() offer_pkt.add_protocol(ethernet.ethernet( ethertype=disc_eth.ethertype, dst=disc_eth.src, src=self.hw_addr)) offer_pkt.add_protocol( ipv4.ipv4(dst=disc_ipv4.dst, src=self.dhcp_server, proto=disc_ipv4.proto)) offer_pkt.add_protocol(udp.udp(src_port=67, dst_port=68)) offer_pkt.add_protocol(dhcp.dhcp(op=2, chaddr=disc_eth.src, siaddr=self.dhcp_server, boot_file=disc.boot_file, yiaddr=chaddr_yiaddr, xid=disc.xid, options=disc.options)) self.logger.debug("ASSEMBLED OFFER: %s --> %s",chaddr,chaddr_yiaddr) return offer_pkt
def handle_ip(self, datapath, in_port, pkt): ofproto = datapath.ofproto parser = datapath.ofproto_parser ipv4_pkt = pkt.get_protocol(ipv4.ipv4) # parse out the IPv4 pkt if datapath.id == 3 and ipv4_pkt.proto == inet.IPPROTO_TCP: tcp_pkt = ipv4_pkt.get_protocol(tcp.tcp) # parser out the TCP pkt ### generate the TCP packet with the RST flag set to 1 tcp_hd = tcp.tcp(src_port=1, dst_port=1, seq=0, ack=0,offset=0, bits=2, option=None) ### packet generation is similar to ARP, eth_pkt = pkt.get_protocol(ethernet.ethernet) ### but you need to generate ethernet->ip->tcp and serialize it ether_hd = ethernet.ethernet(dst=eth_pkt.src, src=eth_pkt.dst, ethertype=ether.ETH_TYPE_IP); # 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, tcp_rst_ack.data) datapath.send_msg(out)
def _icmp_send(dp, port_out, ip_src=DISCOVERY_IP_SRC, ip_dst=DISCOVERY_IP_DST, eth_src='02:b0:00:00:00:b5', eth_dst='02:bb:bb:bb:bb:bb', icmp_type=8, icmp_code=0): """ Generates ICMP packet and sends it out of 'port_out' on forwarder 'dp' Keyword arguments: dp -- Datapath port_out -- Port on forwarder (dp) used to spit out packet ip_src -- IP address of sender ip_dst -- IP address of recipient eth_src -- Ethernet address of source (Default is 02:b0:00:00:00:b5 because none wanted to have 0xb00b5 as experimenter ID) eth_dst -- Ethernet destiation address (probably to be reworked) icmp_type -- ICMP type, default is 8 which is Echo icmp_code -- ICMP code, default is 0 which is No Code """ ofp = dp.ofproto parser = dp.ofproto_parser pkt = packet.Packet() pkt.add_protocol(ethernet.ethernet(ethertype=0x0800, dst=eth_dst, src=eth_src)) pkt.add_protocol(ipv4.ipv4(dst=ip_dst, src=ip_src, proto=1)) ##TODO: Rework payload and codes to properly work with Fragmentation needed pkt.add_protocol(icmp.icmp(type_=icmp_type, code=icmp_code, csum=0, data=icmp.echo(1,1,"{'dpid' : "+str(dp.id)+",'port_out' : "+str(port_out)+"}"))) pkt.serialize() data=pkt.data actions=[parser.OFPActionOutput(port_out,0)] out=parser.OFPPacketOut(datapath=dp, buffer_id=ofp.OFP_NO_BUFFER, in_port=ofp.OFPP_CONTROLLER, actions=actions, data=data) dp.send_msg(out)
def bfd_packet(src_mac, dst_mac, src_ip, dst_ip, ipv4_id, src_port, dst_port, diag=0, state=0, flags=0, detect_mult=0, my_discr=0, your_discr=0, desired_min_tx_interval=0, required_min_rx_interval=0, required_min_echo_rx_interval=0, auth_cls=None): """ Generate BFD packet with Ethernet/IPv4/UDP encapsulated. """ # Generate ethernet header first. pkt = packet.Packet() eth_pkt = ethernet.ethernet(dst_mac, src_mac, ETH_TYPE_IP) pkt.add_protocol(eth_pkt) # IPv4 encapsulation # set ToS to 192 (Network control/CS6) # set TTL to 255 (RFC5881 Section 5.) ipv4_pkt = ipv4.ipv4(proto=inet.IPPROTO_UDP, src=src_ip, dst=dst_ip, tos=192, identification=ipv4_id, ttl=255) pkt.add_protocol(ipv4_pkt) # UDP encapsulation udp_pkt = udp.udp(src_port=src_port, dst_port=dst_port) pkt.add_protocol(udp_pkt) # BFD payload bfd_pkt = bfd.bfd( ver=1, diag=diag, state=state, flags=flags, detect_mult=detect_mult, my_discr=my_discr, your_discr=your_discr, desired_min_tx_interval=desired_min_tx_interval, required_min_rx_interval=required_min_rx_interval, required_min_echo_rx_interval=required_min_echo_rx_interval, auth_cls=auth_cls) pkt.add_protocol(bfd_pkt) pkt.serialize() return pkt.data
def send_arp_request(self, ip, of_packet, match, actions): '''Send an ARP request for an IP with unknown MAC address''' self.debug('sending ARP request: IP %s' % ip) entry = (of_packet, match, actions) # If there is another pending ARP request, don't send it again. if ip in self.pending_arp: self.pending_arp[ip].append(entry) return # Save packet so it's sent back again once ARP reply returns self.pending_arp[ip] = [entry] if ip == config.nat_gateway_ip: src_mac = config.nat_external_mac src_ip = config.nat_external_ip else: src_mac = config.nat_internal_mac src_ip = config.nat_internal_ip eth_packet = ethernet.ethernet( dst='ff:ff:ff:ff:ff:ff', # Broadcast src=src_mac, ethertype=ether.ETH_TYPE_ARP) arp_packet = arp.arp(hwtype=1, proto=ether.ETH_TYPE_IP, hlen=6, plen=4, opcode=arp.ARP_REQUEST, src_mac=src_mac, src_ip=src_ip, dst_mac='00:00:00:00:00:00', dst_ip=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_FLOOD)
def _handle_ingress_arp(self, datapath, in_port, pkt_eth, pkt_arp): if pkt_arp.opcode != arp.ARP_REQUEST: return self.logger.info("in arp handler") for host in host_list: if host.ip == pkt_arp.dst_ip: temp_host = host self.logger.info('select host.ip=%s, host.mac=%s' % (temp_host.ip, temp_host.mac)) pkt = packet.Packet() pkt.add_protocol( ethernet.ethernet(ethertype=pkt_eth.ethertype, dst=pkt_eth.src, src=temp_host.mac)) pkt.add_protocol( arp.arp(opcode=arp.ARP_REPLY, src_mac=temp_host.mac, src_ip=temp_host.ip, dst_mac=pkt_arp.src_mac, dst_ip=pkt_arp.src_ip)) self._send_packet(datapath, in_port, pkt)
def test_smoke_packet_in(self): nd_solicit = packet.Packet() eth_src = '01:02:03:04:05:06' eth_dst = 'ff:ff:ff:ff:ff:ff' src_ip = 'fc00::1' dst_ip = 'fc00::2' vid = 2 for protocol in ( ethernet.ethernet(eth_dst, eth_src, ether.ETH_TYPE_8021Q), vlan.vlan(vid=vid, ethertype=ether.ETH_TYPE_IPV6), ipv6.ipv6(src=src_ip, dst=dst_ip, nxt=socket.IPPROTO_ICMPV6, hop_limit=255), icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_SOLICIT, data=icmpv6.nd_neighbor(dst=src_ip, option=icmpv6.nd_option_tla(hw_src=eth_src), res=7))): nd_solicit.add_protocol(protocol) nd_solicit.serialize() fake_dp = FakeDP() fake_pipette = Pipette(dpset={}) class FakeMsg: def __init__(self): self.datapath = fake_dp self.match = {'in_port': FAKEPORT} self.data = nd_solicit.data class FakePiEv: def __init__(self): self.msg = FakeMsg() fake_pipette = Pipette(dpset={}) fake_pipette.packet_in_handler(FakePiEv()) assert fake_dp.msgs
def test_serialize_with_auth_sha1(self): pkt = packet.Packet() eth_pkt = ethernet.ethernet('08:00:27:d1:95:7c', '08:00:27:ed:54:41') pkt.add_protocol(eth_pkt) ip_pkt = ipv4.ipv4(src='192.168.57.2', dst='192.168.57.1', tos=192, identification=2960, proto=inet.IPPROTO_UDP) pkt.add_protocol(ip_pkt) udp_pkt = udp.udp(49152, 3784) pkt.add_protocol(udp_pkt) auth_cls = bfd.KeyedSHA1(auth_key_id=2, seq=16817, auth_key=self.auth_keys[2]) bfd_pkt = bfd.bfd(ver=1, diag=bfd.BFD_DIAG_NO_DIAG, flags=bfd.BFD_FLAG_AUTH_PRESENT, state=bfd.BFD_STATE_DOWN, detect_mult=3, my_discr=1, your_discr=0, desired_min_tx_interval=1000000, required_min_rx_interval=1000000, required_min_echo_rx_interval=0, auth_cls=auth_cls) pkt.add_protocol(bfd_pkt) eq_(len(pkt.protocols), 4) pkt.serialize() eq_(pkt.data, self.data_auth_sha1)