def make_ndp_grat_ndp_packet( pktlen=64, eth_dst='00:01:02:03:04:05', eth_src='00:06:07:08:09:0a', dl_vlan_enable=False, vlan_vid=0, vlan_pcp=0, ipv6_src='2001:db8:85a3::8a2e:370:7334', ipv6_dst='2001:db8:85a3::8a2e:370:7335', ipv6_tc=0, ipv6_ecn=None, ipv6_dscp=None, ipv6_hlim=255, ipv6_fl=0, ipv6_tgt='2001:db8:85a3::8a2e:370:7334', hw_tgt='00:06:07:08:09:0a', ): """ Generates a simple NDP advertisement similar to PTF testutils simple_arp_packet. Args: pktlen: length of packet eth_dst: etheret destination address. eth_src: ethernet source address dl_vlan_enable: True to add vlan header. vlan_vid: vlan ID vlan_pcp: vlan priority ipv6_src: IPv6 source address ipv6_dst: IPv6 destination address ipv6_tc: IPv6 traffic class ipv6_ecn: IPv6 traffic class ECN ipv6_dscp: IPv6 traffic class DSCP ipv6_hlim: IPv6 hop limit/ttl ipv6_fl: IPv6 flow label ipv6_tgt: ICMPv6 ND advertisement target address. hw_tgt: IPv6 ND advertisement destination link-layer address. Returns: Crafted scapy packet for using with send_packet(). """ if MINSIZE > pktlen: pktlen = MINSIZE ipv6_tc = ip_make_tos(ipv6_tc, ipv6_ecn, ipv6_dscp) pkt = Ether(dst=eth_dst, src=eth_src) if dl_vlan_enable or vlan_vid or vlan_pcp: pkt /= Dot1Q(vlan=vlan_vid, prio=vlan_pcp) pkt /= IPv6(src=ipv6_src, dst=ipv6_dst, fl=ipv6_fl, tc=ipv6_tc, hlim=ipv6_hlim) pkt /= ICMPv6ND_NA(R=0, S=0, O=1, tgt=ipv6_tgt) pkt /= ICMPv6NDOptDstLLAddr(lladdr=hw_tgt) pkt /= ("D" * (pktlen - len(pkt))) return pkt
def send_neighbour_advertisement_on_software_interfaces(cls, args): for i in args: ip = cls.VPP_SOFT_IP6S[i] cls.log("Sending ICMPv6ND_NA message for %s on port %u" % (ip, i)) pkt = (Ether(dst="ff:ff:ff:ff:ff:ff", src=cls.MY_MACS[i]) / IPv6(src=cls.MY_SOFT_IP6S[i], dst=ip) / ICMPv6ND_NA(tgt=ip, R=0, S=0) / ICMPv6NDOptDstLLAddr(lladdr=cls.MY_MACS[i])) cls.pg_add_stream(i, pkt) cls.pg_enable_capture([i]) cls.cli(2, "trace add pg-input 1") cls.pg_start()
def handle_ns_request(self, pipe, packet): ''' process incoming NS request and send corresponding NA. ''' self.log("ND: RX NS: {0} <-- {1},{2}".format(packet[ICMPv6ND_NS].tgt, packet[IPv6].src, packet[Ether].src)) na_response = Ether(src=packet[Ether].dst, dst=packet[Ether].src)/ \ IPv6(src=packet[ICMPv6ND_NS].tgt, dst=packet[IPv6].src, hlim = 255)/ \ ICMPv6ND_NA(tgt=packet[ICMPv6ND_NS].tgt, R = 0, S = 1, O = 1)/ \ ICMPv6NDOptDstLLAddr(lladdr=packet[Ether].dst) if not self.vlan.is_default(): self.vlan.embed(na_response, fmt=self.fmt) self.log("ND: TX NA: {0},{1} -> {2},{3}".format( packet[ICMPv6ND_NS].tgt, packet[Ether].dst, packet[IPv6].src, packet[Ether].src)) pipe.async_tx_pkt(na_response) self.record.verified()
def main(): args = TrafficScriptArg(['src_mac', 'dst_mac', 'src_ip', 'dst_ip']) rxq = RxQueue(args.get_arg('rx_if')) txq = TxQueue(args.get_arg('tx_if')) src_mac = args.get_arg('src_mac') dst_mac = args.get_arg('dst_mac') src_ip = args.get_arg('src_ip') dst_ip = args.get_arg('dst_ip') echo_id = 0xa echo_seq = 0x1 sent_packets = [] # send ICMPv6 neighbor advertisement message pkt_send = (Ether(src=src_mac, dst='ff:ff:ff:ff:ff:ff') / IPv6(src=src_ip, dst='ff02::1:ff00:2') / ICMPv6ND_NA(tgt=src_ip, R=0) / ICMPv6NDOptDstLLAddr(lladdr=src_mac)) sent_packets.append(pkt_send) txq.send(pkt_send) # send ICMPv6 echo request pkt_send = (Ether(src=src_mac, dst=dst_mac) / IPv6(src=src_ip, dst=dst_ip) / ICMPv6EchoRequest(id=echo_id, seq=echo_seq)) sent_packets.append(pkt_send) txq.send(pkt_send) # receive ICMPv6 echo reply while True: ether = rxq.recv(2, sent_packets) if ether is None: raise RuntimeError('ICMPv6 echo reply Rx timeout') if ether.haslayer(ICMPv6ND_NS): # read another packet in the queue if the current one is ICMPv6ND_NS continue else: # otherwise process the current packet break if not ether.haslayer(IPv6): raise RuntimeError( 'Unexpected packet with no IPv6 received {0}'.format( ether.__repr__())) ipv6 = ether[IPv6] if not ipv6.haslayer(ICMPv6EchoReply): raise RuntimeError('Unexpected packet with no ICMPv6 echo reply ' 'received {0}'.format(ipv6.__repr__())) icmpv6 = ipv6[ICMPv6EchoReply] # check identifier and sequence number if icmpv6.id != echo_id or icmpv6.seq != echo_seq: raise RuntimeError('Invalid ICMPv6 echo reply received ID {0} seq {1} ' 'should be ID {2} seq {3}'.format( icmpv6.id, icmpv6.seq, echo_id, echo_seq)) # verify checksum cksum = icmpv6.cksum del icmpv6.cksum tmp = ICMPv6EchoReply(str(icmpv6)) if not checksum_equal(tmp.cksum, cksum): raise RuntimeError('Invalid checksum {0} should be {1}'.format( cksum, tmp.cksum)) sys.exit(0)
def main(): args = TrafficScriptArg(['src_mac', 'dst_mac', 'src_ip', 'dst_ip']) rxq = RxQueue(args.get_arg('rx_if')) txq = TxQueue(args.get_arg('tx_if')) src_mac = args.get_arg('src_mac') dst_mac = args.get_arg('dst_mac') src_ip = args.get_arg('src_ip') dst_ip = args.get_arg('dst_ip') sent_packets = [] # send ICMPv6 neighbor solicitation message pkt_send = (Ether(src=src_mac, dst='ff:ff:ff:ff:ff:ff') / IPv6(src=src_ip, dst='ff02::1:ff00:2') / ICMPv6ND_NS(tgt=dst_ip) / ICMPv6NDOptSrcLLAddr(lladdr=src_mac)) sent_packets.append(pkt_send) txq.send(pkt_send) # receive ICMPv6 neighbor advertisement message ether = rxq.recv(2, sent_packets) if ether is None: raise RuntimeError('ICMPv6 echo reply Rx timeout') if not ether.haslayer(IPv6): raise RuntimeError( 'Unexpected packet with no IPv6 received {0}'.format( ether.__repr__())) ipv6 = ether['IPv6'] if not ipv6.haslayer(ICMPv6ND_NA): raise RuntimeError( 'Unexpected packet with no ICMPv6 ND-NA received {0}'.format( ipv6.__repr__())) icmpv6_na = ipv6['ICMPv6 Neighbor Discovery - Neighbor Advertisement'] # verify target address if icmpv6_na.tgt != dst_ip: raise RuntimeError('Invalid target address {0} should be {1}'.format( icmpv6_na.tgt, dst_ip)) if not icmpv6_na.haslayer(ICMPv6NDOptDstLLAddr): raise RuntimeError( 'Missing Destination Link-Layer Address option in ICMPv6 ' + 'Neighbor Advertisement {0}'.format(icmpv6_na.__repr__())) option = 'ICMPv6 Neighbor Discovery Option - Destination Link-Layer Address' dst_ll_addr = icmpv6_na[option] # verify destination link-layer address field if dst_ll_addr.lladdr != dst_mac: raise RuntimeError('Invalid lladdr {0} should be {1}'.format( dst_ll_addr.lladdr, dst_mac)) # verify checksum cksum = icmpv6_na.cksum del icmpv6_na.cksum tmp = ICMPv6ND_NA(str(icmpv6_na)) if not checksum_equal(tmp.cksum, cksum): raise RuntimeError('Invalid checksum {0} should be {1}'.format( cksum, tmp.cksum)) sys.exit(0)
def main(): # start_size - start size of the ICMPv6 echo data # end_size - end size of the ICMPv6 echo data # step - increment step args = TrafficScriptArg([ 'src_mac', 'dst_mac', 'src_ip', 'dst_ip', 'start_size', 'end_size', 'step' ]) rxq = RxQueue(args.get_arg('rx_if')) txq = TxQueue(args.get_arg('tx_if')) src_mac = args.get_arg('src_mac') dst_mac = args.get_arg('dst_mac') src_ip = args.get_arg('src_ip') dst_ip = args.get_arg('dst_ip') start_size = int(args.get_arg('start_size')) end_size = int(args.get_arg('end_size')) step = int(args.get_arg('step')) echo_id = 0xa # generate some random data buffer data = bytearray(os.urandom(end_size)) # send ICMPv6 neighbor advertisement message sent_packets = [] pkt_send = (Ether(src=src_mac, dst=dst_mac) / IPv6(src=src_ip, dst=dst_ip) / ICMPv6ND_NA(tgt=src_ip, R=0) / ICMPv6NDOptDstLLAddr(lladdr=src_mac)) sent_packets.append(pkt_send) txq.send(pkt_send) # send ICMPv6 echo request with incremented data length and receive ICMPv6 # echo reply for echo_seq in range(start_size, end_size + 1, step): pkt_send = ( Ether(src=src_mac, dst=dst_mac) / IPv6(src=src_ip, dst=dst_ip) / ICMPv6EchoRequest(id=echo_id, seq=echo_seq, data=data[0:echo_seq])) sent_packets.append(pkt_send) txq.send(pkt_send) ether = rxq.recv(ignore=sent_packets) if ether is None: raise RuntimeError( 'ICMPv6 echo reply seq {0} Rx timeout'.format(echo_seq)) if not ether.haslayer(IPv6): raise RuntimeError( 'Unexpected packet with no IPv6 received {0}'.format( ether.__repr__())) ipv6 = ether['IPv6'] if not ipv6.haslayer(ICMPv6EchoReply): raise RuntimeError( 'Unexpected packet with no IPv6 ICMP received {0}'.format( ipv6.__repr__())) icmpv6 = ipv6['ICMPv6 Echo Reply'] if icmpv6.id != echo_id or icmpv6.seq != echo_seq: raise RuntimeError( 'Invalid ICMPv6 echo reply received ID {0} seq {1} should be ' 'ID {2} seq {3}, {0}'.format(icmpv6.id, icmpv6.seq, echo_id, echo_seq)) cksum = icmpv6.cksum del icmpv6.cksum tmp = ICMPv6EchoReply(str(icmpv6)) if not checksum_equal(tmp.cksum, cksum): raise RuntimeError('Invalid checksum {0} should be {1}'.format( cksum, tmp.cksum)) sent_packets.remove(pkt_send) sys.exit(0)
def main(): args = TrafficScriptArg([ 'src_mac', 'dst_mac', 'src_nh_mac', 'dst_nh_mac', 'src_ip', 'dst_ip', 'h_num' ]) src_rxq = RxQueue(args.get_arg('rx_if')) src_txq = TxQueue(args.get_arg('rx_if')) dst_rxq = RxQueue(args.get_arg('tx_if')) dst_txq = TxQueue(args.get_arg('tx_if')) src_mac = args.get_arg('src_mac') dst_mac = args.get_arg('dst_mac') src_nh_mac = args.get_arg('src_nh_mac') dst_nh_mac = args.get_arg('dst_nh_mac') src_ip = args.get_arg('src_ip') dst_ip = args.get_arg('dst_ip') hop_num = int(args.get_arg('h_num')) hop_limit = 64 echo_id = 0xa echo_seq = 0x1 src_sent_packets = [] dst_sent_packets = [] # send ICMPv6 neighbor advertisement message pkt_send = (Ether(src=src_mac, dst='ff:ff:ff:ff:ff:ff') / IPv6(src=src_ip, dst='ff02::1:ff00:2') / ICMPv6ND_NA(tgt=src_ip, R=0) / ICMPv6NDOptDstLLAddr(lladdr=src_mac)) src_sent_packets.append(pkt_send) src_txq.send(pkt_send) pkt_send = (Ether(src=dst_mac, dst='ff:ff:ff:ff:ff:ff') / IPv6(src=dst_ip, dst='ff02::1:ff00:2') / ICMPv6ND_NA(tgt=dst_ip, R=0) / ICMPv6NDOptDstLLAddr(lladdr=dst_mac)) dst_sent_packets.append(pkt_send) dst_txq.send(pkt_send) # send ICMPv6 echo request from first TG interface pkt_send = (Ether(src=src_mac, dst=src_nh_mac) / IPv6(src=src_ip, dst=dst_ip, hlim=hop_limit) / ICMPv6EchoRequest(id=echo_id, seq=echo_seq)) src_sent_packets.append(pkt_send) src_txq.send(pkt_send) # receive ICMPv6 echo request on second TG interface ether = dst_rxq.recv(2, dst_sent_packets) if ether is None: raise RuntimeError('ICMPv6 echo reply Rx timeout') if not ether.haslayer(IPv6): raise RuntimeError( 'Unexpected packet with no IPv6 received {0}'.format( ether.__repr__())) ipv6 = ether['IPv6'] # verify hop limit processing if ipv6.hlim != (hop_limit - hop_num): raise RuntimeError('Invalid hop limit {0} should be {1}'.format( ipv6.hlim, hop_limit - hop_num)) if not ipv6.haslayer(ICMPv6EchoRequest): raise RuntimeError( 'Unexpected packet with no IPv6 ICMP received {0}'.format( ipv6.__repr__())) icmpv6 = ipv6['ICMPv6 Echo Request'] # check identifier and sequence number if icmpv6.id != echo_id or icmpv6.seq != echo_seq: raise RuntimeError( 'Invalid ICMPv6 echo reply received ID {0} seq {1} should be ' \ 'ID {2} seq {3}'.format(icmpv6.id, icmpv6.seq, echo_id, echo_seq)) # verify checksum cksum = icmpv6.cksum del icmpv6.cksum tmp = ICMPv6EchoRequest(str(icmpv6)) if not checksum_equal(tmp.cksum, cksum): raise RuntimeError('Invalid checksum {0} should be {1}'.format( cksum, tmp.cksum)) # send ICMPv6 echo reply from second TG interface pkt_send = (Ether(src=dst_mac, dst=dst_nh_mac) / IPv6(src=dst_ip, dst=src_ip) / ICMPv6EchoReply(id=echo_id, seq=echo_seq)) dst_sent_packets.append(pkt_send) dst_txq.send(pkt_send) # receive ICMPv6 echo reply on first TG interface ether = src_rxq.recv(2, src_sent_packets) if ether is None: raise RuntimeError('ICMPv6 echo reply Rx timeout') if not ether.haslayer(IPv6): raise RuntimeError( 'Unexpected packet with no IPv6 received {0}'.format( ether.__repr__())) ipv6 = ether['IPv6'] # verify hop limit processing if ipv6.hlim != (hop_limit - hop_num): raise RuntimeError('Invalid hop limit {0} should be {1}'.format( ipv6.hlim, hop_limit - hop_num)) if not ipv6.haslayer(ICMPv6EchoReply): raise RuntimeError( 'Unexpected packet with no IPv6 ICMP received {0}'.format( ipv6.__repr__())) icmpv6 = ipv6['ICMPv6 Echo Reply'] # check identifier and sequence number if icmpv6.id != echo_id or icmpv6.seq != echo_seq: raise RuntimeError( 'Invalid ICMPv6 echo reply received ID {0} seq {1} should be ' \ 'ID {2} seq {3}'.format(icmpv6.id, icmpv6.seq, echo_id, echo_seq)) # verify checksum cksum = icmpv6.cksum del icmpv6.cksum tmp = ICMPv6EchoReply(str(icmpv6)) if not checksum_equal(tmp.cksum, cksum): raise RuntimeError('Invalid checksum {0} should be {1}'.format( cksum, tmp.cksum)) sys.exit(0)
def main(): args = TrafficScriptArg([ 'src_mac', 'dst_mac', 'src_nh_mac', 'dst_nh_mac', 'src_ip', 'dst_ip', 'h_num' ], ['is_dst_tg']) src_rxq = RxQueue(args.get_arg('tx_if')) src_txq = TxQueue(args.get_arg('tx_if')) src_mac = args.get_arg('src_mac') dst_mac = args.get_arg('dst_mac') src_nh_mac = args.get_arg('src_nh_mac') dst_nh_mac = args.get_arg('dst_nh_mac') src_ip = args.get_arg('src_ip') dst_ip = args.get_arg('dst_ip') hop_num = int(args.get_arg('h_num')) is_dst_tg = True if args.get_arg('is_dst_tg') in ['True', ''] else False dst_rxq = RxQueue(args.get_arg('rx_if')) if is_dst_tg else None dst_txq = TxQueue(args.get_arg('rx_if')) if is_dst_tg else None hop_limit = 64 echo_id = 0xa echo_seq = 0x1 src_sent_packets = [] dst_sent_packets = [] # send ICMPv6 neighbor advertisement message pkt_send = (Ether(src=src_mac, dst='ff:ff:ff:ff:ff:ff') / IPv6(src=src_ip, dst='ff02::1:ff00:2') / ICMPv6ND_NA(tgt=src_ip, R=0) / ICMPv6NDOptDstLLAddr(lladdr=src_mac)) src_sent_packets.append(pkt_send) src_txq.send(pkt_send) if is_dst_tg: # send ICMPv6 neighbor advertisement message pkt_send = (Ether(src=dst_mac, dst='ff:ff:ff:ff:ff:ff') / IPv6(src=dst_ip, dst='ff02::1:ff00:2') / ICMPv6ND_NA(tgt=dst_ip, R=0) / ICMPv6NDOptDstLLAddr(lladdr=dst_mac)) dst_sent_packets.append(pkt_send) dst_txq.send(pkt_send) # send ICMPv6 echo request from first TG interface pkt_send = (Ether(src=src_mac, dst=src_nh_mac) / IPv6(src=src_ip, dst=dst_ip, hlim=hop_limit) / ICMPv6EchoRequest(id=echo_id, seq=echo_seq)) src_sent_packets.append(pkt_send) src_txq.send(pkt_send) if is_dst_tg: # receive ICMPv6 echo request on second TG interface while True: ether = dst_rxq.recv(2, dst_sent_packets) if ether is None: raise RuntimeError('ICMPv6 echo reply Rx timeout') if ether.haslayer(ICMPv6ND_NS): # read another packet in the queue if the current one is # ICMPv6ND_NS continue else: # otherwise process the current packet break if not ether.haslayer(IPv6): raise RuntimeError( 'Unexpected packet with no IPv6 received: {0}'.format( ether.__repr__())) ipv6 = ether[IPv6] # verify hop limit processing if ipv6.hlim != (hop_limit - hop_num): raise RuntimeError('Invalid hop limit {0} should be {1}'.format( ipv6.hlim, hop_limit - hop_num)) if not ipv6.haslayer(ICMPv6EchoRequest): raise RuntimeError('Unexpected packet with no IPv6 ICMP received ' '{0}'.format(ipv6.__repr__())) icmpv6 = ipv6[ICMPv6EchoRequest] # check identifier and sequence number if icmpv6.id != echo_id or icmpv6.seq != echo_seq: raise RuntimeError('Invalid ICMPv6 echo reply received ID {0} ' 'seq {1} should be ID {2} seq {3}'.format( icmpv6.id, icmpv6.seq, echo_id, echo_seq)) # verify checksum cksum = icmpv6.cksum del icmpv6.cksum tmp = ICMPv6EchoRequest(str(icmpv6)) if not checksum_equal(tmp.cksum, cksum): raise RuntimeError('Invalid checksum {0} should be {1}'.format( cksum, tmp.cksum)) # send ICMPv6 echo reply from second TG interface pkt_send = (Ether(src=dst_mac, dst=dst_nh_mac) / IPv6(src=dst_ip, dst=src_ip, hlim=(ipv6.hlim - 1)) / ICMPv6EchoReply(id=echo_id, seq=echo_seq)) dst_sent_packets.append(pkt_send) dst_txq.send(pkt_send) # receive ICMPv6 echo reply on first TG interface while True: ether = src_rxq.recv(2, src_sent_packets) if ether is None: raise RuntimeError('ICMPv6 echo reply Rx timeout') if ether.haslayer(ICMPv6ND_NS): # read another packet in the queue if the current one is ICMPv6ND_NS continue else: # otherwise process the current packet break if not ether.haslayer(IPv6): raise RuntimeError( 'Unexpected packet with no IPv6 layer received {0}'.format( ether.__repr__())) ipv6 = ether[IPv6] # verify hop limit processing; destination node decrements hlim by one in # outgoing ICMPv6 Echo Reply directions = 2 if is_dst_tg else 1 hop_limit_reply = hop_limit - directions * hop_num - 1 if ipv6.hlim != hop_limit_reply: raise RuntimeError('Invalid hop limit {0} should be {1}'.format( ipv6.hlim, hop_limit_reply)) if not ipv6.haslayer(ICMPv6EchoReply): raise RuntimeError( 'Unexpected packet with no IPv6 ICMP received {0}'.format( ipv6.__repr__())) icmpv6 = ipv6[ICMPv6EchoReply] # check identifier and sequence number if icmpv6.id != echo_id or icmpv6.seq != echo_seq: raise RuntimeError('Invalid ICMPv6 echo reply received ID {0} ' 'seq {1} should be ID {2} seq {3}'.format( icmpv6.id, icmpv6.seq, echo_id, echo_seq)) # verify checksum cksum = icmpv6.cksum del icmpv6.cksum tmp = ICMPv6EchoReply(str(icmpv6)) if not checksum_equal(tmp.cksum, cksum): raise RuntimeError('Invalid checksum {0} should be {1}'.format( cksum, tmp.cksum)) sys.exit(0)