Example #1
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)
Example #2
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')
    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)
Example #3
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)
Example #5
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)
def main():
    # start_size - start size of the ICMPv4 echo data
    # end_size - end size of the ICMPv4 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))

    sent_packets = []
    pkt_send = create_gratuitous_arp_request(src_mac, src_ip)
    sent_packets.append(pkt_send)
    txq.send(pkt_send)

    # send ICMP echo request with incremented data length and receive ICMP
    # echo reply
    for echo_seq in range(start_size, end_size + 1, step):
        pkt_send = (Ether(src=src_mac, dst=dst_mac) /
                    IP(src=src_ip, dst=dst_ip) /
                    ICMP(id=echo_id, seq=echo_seq) /
                    Raw(load=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(
                'ICMP echo reply seq {0} Rx timeout'.format(echo_seq))

        if not ether.haslayer(IP):
            raise RuntimeError(
                'Unexpected packet with no IPv4 received {0}'.format(
                    ether.__repr__()))

        ipv4 = ether['IP']

        if not ipv4.haslayer(ICMP):
            raise RuntimeError(
                'Unexpected packet with no ICMP received {0}'.format(
                    ipv4.__repr__()))

        icmpv4 = ipv4['ICMP']

        if icmpv4.id != echo_id or icmpv4.seq != echo_seq:
            raise RuntimeError(
                'Invalid ICMP echo reply received ID {0} seq {1} should be '
                'ID {2} seq {3}, {0}'.format(icmpv4.id, icmpv4.seq, echo_id,
                                             echo_seq))

        chksum = icmpv4.chksum
        del icmpv4.chksum
        tmp = ICMP(str(icmpv4))
        if not checksum_equal(tmp.chksum, chksum):
            raise RuntimeError(
                'Invalid checksum {0} should be {1}'.format(chksum, tmp.chksum))

        if 'Raw' in icmpv4:
            load = icmpv4['Raw'].load
        else:
            load = ""
        if load != data[0:echo_seq]:
            raise RuntimeError(
                'Received ICMP payload does not match sent payload')

        sent_packets.remove(pkt_send)

    sys.exit(0)
Example #7
0
def main():
    args = TrafficScriptArg([
        'src_mac', 'dst_mac', 'src_ip', 'dst_ip', 'hops', 'first_hop_mac',
        'is_dst_tg'
    ])

    src_if_name = args.get_arg('tx_if')
    dst_if_name = args.get_arg('rx_if')
    is_dst_tg = True if args.get_arg('is_dst_tg') == 'True' else False

    src_mac = args.get_arg('src_mac')
    first_hop_mac = args.get_arg('first_hop_mac')
    dst_mac = args.get_arg('dst_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    hops = int(args.get_arg('hops'))

    if is_dst_tg and (src_if_name == dst_if_name):
        raise RuntimeError(
            "Source interface name equals destination interface name")

    src_if = Interface(src_if_name)
    src_if.send_pkt(str(create_gratuitous_arp_request(src_mac, src_ip)))
    if is_dst_tg:
        dst_if = Interface(dst_if_name)
        dst_if.send_pkt(str(create_gratuitous_arp_request(dst_mac, dst_ip)))
## recive arp check   @zhuyl
    pkt_resp_recv = src_if.recv_pkt()
    if not isinstance(pkt_resp_recv, None):
        if pkt_resp_recv.haslayer(ARP):
            print("src_if_name: {} \n recv arp: {}".format(
                src_if_name, pkt_resp_recv.show()))
        if is_dst_tg:
            pkt_req_recv = dst_if.recv_pkt()
            if pkt_resp_recv.haslayer(ARP):
                print("dst_if_name: {} \nrecv arp: {}".format(
                    dst_if_name, pkt_resp_recv.show()))


##
        pkt_req_send = (Ether(src=src_mac, dst=first_hop_mac) /
                        IP(src=src_ip, dst=dst_ip) / ICMP())
        src_if.send_pkt(pkt_req_send)

    if is_dst_tg:
        pkt_req_recv = dst_if.recv_pkt()
        if pkt_req_recv is None:
            raise RuntimeError('Timeout waiting for packet')

        check_ttl(pkt_req_send[IP].ttl, pkt_req_recv[IP].ttl, hops)
        pkt_req_send_mod = pkt_req_send.copy()
        pkt_req_send_mod[IP].ttl = pkt_req_recv[IP].ttl
        del pkt_req_send_mod[IP].chksum  # update checksum
        ckeck_packets_equal(pkt_req_send_mod[IP], pkt_req_recv[IP])

        pkt_resp_send = (Ether(src=dst_mac, dst=pkt_req_recv.src) /
                         IP(src=dst_ip, dst=src_ip) / ICMP(type=0)
                         )  # echo-reply
        dst_if.send_pkt(pkt_resp_send)

    pkt_resp_recv = src_if.recv_pkt()
    if pkt_resp_recv is None:
        raise RuntimeError('Timeout waiting for packet')

    if is_dst_tg:
        check_ttl(pkt_resp_send[IP].ttl, pkt_resp_recv[IP].ttl, hops)
        pkt_resp_send_mod = pkt_resp_send.copy()
        pkt_resp_send_mod[IP].ttl = pkt_resp_recv[IP].ttl
        del pkt_resp_send_mod[IP].chksum  # update checksum
        ckeck_packets_equal(pkt_resp_send_mod[IP], pkt_resp_recv[IP])

    if not pkt_resp_recv.haslayer(IP):
        raise RuntimeError(
            'Received packet does not contain IPv4 header: {}'.format(
                pkt_resp_recv.__repr__()))

    if pkt_resp_recv[IP].src != pkt_req_send[IP].dst:
        raise RuntimeError(
            'Received IPv4 packet contains wrong src IP address, '
            '{} instead of {}'.format(pkt_resp_recv[IP].src,
                                      pkt_req_send[IP].dst))

    if pkt_resp_recv[IP].dst != pkt_req_send[IP].src:
        raise RuntimeError(
            'Received IPv4 packet contains wrong dst IP address, '
            '{} instead of {}'.format(pkt_resp_recv[IP].dst,
                                      pkt_req_send[IP].src))

    # verify IPv4 checksum
    copy = pkt_resp_recv.copy()
    chksum = copy[IP].chksum
    del copy[IP].chksum
    tmp = IP(str(copy[IP]))
    if not checksum_equal(tmp.chksum, chksum):
        raise RuntimeError('Received IPv4 packet contains invalid checksum, '
                           '{} instead of {}'.format(chksum, tmp.chksum))

    if not pkt_resp_recv[IP].haslayer(ICMP):
        raise RuntimeError(
            'Received IPv4 packet does not contain ICMP header: {}'.format(
                pkt_resp_recv[IP].__repr__()))

    # verify ICMP checksum
    copy = pkt_resp_recv.copy()
    chksum = copy[IP][ICMP].chksum
    del copy[IP][ICMP].chksum
    tmp = ICMP(str(copy[IP][ICMP]))
    if not checksum_equal(tmp.chksum, chksum):
        raise RuntimeError('Received ICMP packet contains invalid checksum, '
                           '{} instead of {}'.format(chksum, tmp.chksum))

    pkt_req_send_mod = pkt_req_send.copy()
    pkt_req_send_mod[IP][ICMP].type = pkt_resp_recv[IP][ICMP].type
    del pkt_req_send_mod[IP][ICMP].chksum  # update checksum
    ckeck_packets_equal(pkt_req_send_mod[IP][ICMP], pkt_resp_recv[IP][ICMP])