Esempio n. 1
0
def dhcpv6_advertise(rx_if, tx_if, link_local_ip, proxy_ip, server_ip,
                     server_mac, proxy_to_server_mac, interface_id):
    """Send and check DHCPv6 ADVERTISE proxy packet.

    :param rx_if: DHCPv6 server interface.
    :param tx_if: Client interface.
    :param link_local_ip: Client link-local address.
    :param proxy_ip: IP address of DHCPv6 proxy server.
    :param server_ip: IP address of DHCPv6 server.
    :param server_mac: MAC address of DHCPv6 server.
    :param proxy_to_server_mac: MAC address of DHCPv6 proxy interface.
    :param interface_id: ID of proxy interface.
    :type rx_if: str
    :type tx_if: str
    :type link_local_ip: str
    :type proxy_ip: str
    :type server_ip: str
    :type server_mac: str
    :type proxy_to_server_mac: str
    :type interface_id: str
    """

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)

    sent_packets = []

    dhcp6_advertise_pkt = Ether(src=server_mac, dst=proxy_to_server_mac) / \
                          IPv6(src=server_ip, dst=proxy_ip) / \
                          UDP(sport=UDP_SERVICES.dhcpv6_server,
                              dport=UDP_SERVICES.dhcpv6_client) / \
                          DHCP6_RelayReply(peeraddr=link_local_ip,
                                           linkaddr=proxy_ip) / \
                          DHCP6OptIfaceId(ifaceid=interface_id) / \
                          DHCP6OptRelayMsg() / \
                          DHCP6_Advertise()

    sent_packets.append(dhcp6_advertise_pkt)
    txq.send(dhcp6_advertise_pkt)

    ether = rxq.recv(2)

    if ether is None:
        raise RuntimeError('DHCPv6 ADVERTISE timeout')

    if ether['IPv6'].src != proxy_ip:
        raise RuntimeError("Source IP address error: {} != {}".format(
            ether['IPv6'].src, proxy_ip))
    print "Source IP address: OK."

    if not _check_udp_checksum(ether['IPv6']):
        raise RuntimeError("Checksum error!")
    print "Checksum: OK."

    msgtype = _get_dhcpv6_msgtype(
        ether['IPv6']['UDP']['DHCPv6 Advertise Message'].msgtype)
    if msgtype != 'ADVERTISE':
        raise RuntimeError(
            "Message type error: {} != ADVERTISE".format(msgtype))
    print "Message type: OK."
Esempio n. 2
0
def main():
    """Send ICMP echo request and wait for ICMP echo reply. It ignores all other
    packets."""
    args = TrafficScriptArg(
        ['dst_mac', 'src_mac', 'dst_ip', 'src_ip', 'timeout'])

    dst_mac = args.get_arg('dst_mac')
    src_mac = args.get_arg('src_mac')
    dst_ip = args.get_arg('dst_ip')
    src_ip = args.get_arg('src_ip')
    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')
    timeout = int(args.get_arg('timeout'))
    wait_step = 1

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []

    # Create empty ip ICMP packet
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        icmp_request = (Ether(src=src_mac, dst=dst_mac) /
                        IP(src=src_ip, dst=dst_ip) / ICMP())
        ip_format = {
            'IPType': 'IP',
            'ICMP_req': 'ICMP',
            'ICMP_rep': 'ICMP',
            'Type': 0
        }
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        icmp_request = (Ether(src=src_mac, dst=dst_mac) /
                        IPv6(src=src_ip, dst=dst_ip) / ICMPv6EchoRequest())
        ip_format = {
            'IPType': 'IPv6',
            'ICMP_req': 'ICMPv6 Echo Request',
            'ICMP_rep': 'ICMPv6 Echo Reply',
            'Type': 129
        }
    else:
        raise ValueError("IP not in correct format")

    # Send created packet on the interface
    sent_packets.append(icmp_request)
    txq.send(icmp_request)

    for _ in range(1000):
        icmp_reply = rxq.recv(wait_step, ignore=sent_packets)
        if icmp_reply is None:
            timeout -= wait_step
            if timeout < 0:
                raise RuntimeError("ICMP echo Rx timeout")
        elif is_icmp_reply(icmp_reply, ip_format):
            if address_check(icmp_request, icmp_reply, ip_format):
                break
    else:
        raise RuntimeError("Max packet count limit reached")

    print "ICMP echo reply received."

    sys.exit(0)
def main():
    """Send IP ICMPv4/ICMPv6 packet from one traffic generator interface to
    the other one."""

    args = TrafficScriptArg(
        ['src_mac', 'dst_mac', 'src_ip', 'dst_ip', 'icmp_type', 'icmp_code'])

    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')

    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')

    icmp_type = int(args.get_arg('icmp_type'))
    icmp_code = int(args.get_arg('icmp_code'))

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)

    sent_packets = []

    # Create empty ip ICMP packet and add padding before sending
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                   IP(src=src_ip, dst=dst_ip) /
                   ICMP(code=icmp_code, type=icmp_type))
        ip_format = 'IP'
        icmp_format = 'ICMP'
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                   IPv6(src=src_ip, dst=dst_ip) /
                   ICMPv6EchoRequest(code=icmp_code, type=icmp_type))
        ip_format = 'IPv6'
        icmp_format = 'ICMPv6'
    else:
        raise ValueError("IP(s) not in correct format")

    # Send created packet on one interface and receive on the other
    sent_packets.append(pkt_raw)
    txq.send(pkt_raw)

    ether = rxq.recv(2)

    # Check whether received packet contains layers Ether, IP and ICMP
    if ether is None:
        raise RuntimeError('ICMP echo Rx timeout')

    if not ether.haslayer(ip_format):
        raise RuntimeError('Not an IP packet received {0}'.format(
            ether.__repr__()))

    # Cannot use haslayer for ICMPv6, every type of ICMPv6 is a separate layer
    # Next header value of 58 means the next header is ICMPv6
    if not ether.haslayer(icmp_format) and ether[ip_format].nh != 58:
        raise RuntimeError('Not an ICMP packet received {0}'.format(
            ether.__repr__()))

    sys.exit(0)
Esempio n. 4
0
def main():
    """Send TCP packet from one traffic generator interface to DUT.

    :raises: If the IP address is invalid.
    """
    args = TrafficScriptArg([
        'src_mac', 'dst_mac', 'src_ip', 'dst_ip', 'timeout', 'framesize',
        'testtype'
    ])

    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')
    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')
    timeout = int(args.get_arg('timeout'))
    frame_size = int(args.get_arg('framesize'))
    test_type = args.get_arg('testtype')

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []

    protocol = TCP
    source_port = sfccon.DEF_SRC_PORT
    destination_port = sfccon.DEF_DST_PORT

    ip_version = None
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        ip_version = IP
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        ip_version = IPv6
    else:
        raise ValueError("Invalid IP version!")

    pkt_header = (
        Ether(src=src_mac, dst=dst_mac) / ip_version(src=src_ip, dst=dst_ip) /
        protocol(sport=int(source_port), dport=int(destination_port)))

    fsize_no_fcs = frame_size - 4
    pad_len = max(0, fsize_no_fcs - len(pkt_header))
    pad_data = "A" * pad_len

    pkt_raw = pkt_header / Raw(load=pad_data)

    # Send created packet on one interface and receive on the other
    sent_packets.append(pkt_raw)
    txq.send(pkt_raw)

    ether = rxq.recv(timeout)

    if ether is None:
        raise RuntimeError("No packet is received!")

    # let us begin to check the NSH SFC loopback  packet
    VerifyPacket.check_the_nsh_sfc_packet(ether, frame_size, test_type)

    # we check all the fields about the loopback packet, this test will pass
    sys.exit(0)
Esempio n. 5
0
def main():
    """Send DHCP DISCOVER packet."""

    args = TrafficScriptArg(['tx_src_ip', 'tx_dst_ip'])

    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)

    tx_src_ip = args.get_arg('tx_src_ip')
    tx_dst_ip = args.get_arg('tx_dst_ip')

    sent_packets = []

    dhcp_discover = Ether(dst="ff:ff:ff:ff:ff:ff") / \
                    IP(src=tx_src_ip, dst=tx_dst_ip) / \
                    UDP(sport=UDP_SERVICES.bootpc, dport=UDP_SERVICES.bootps) / \
                    BOOTP(op=1,) / \
                    DHCP(options=[("message-type", "discover"),
                                  "end"])

    sent_packets.append(dhcp_discover)
    txq.send(dhcp_discover)

    for _ in range(10):
        dhcp_discover = rxq.recv(2)
        if is_discover(dhcp_discover):
            break
    else:
        raise RuntimeError("DHCP DISCOVER Rx timeout")

    sys.exit(0)
Esempio n. 6
0
def main():
    """Main function."""
    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')

    pkt_send = (Ether(src=src_mac, dst=dst_mac) /
                    IP(src=src_ip, dst=dst_ip, proto=61))

    sent_packets = []
    sent_packets.append(pkt_send)
    txq.send(pkt_send)

    pkt_recv = rxq.recv(ignore=sent_packets)

    if pkt_recv is None:
        raise RuntimeError('Timeout waiting for packet')

    check_macswap(pkt_send, pkt_recv)
Esempio n. 7
0
def main():
    args = TrafficScriptArg(
        ['tx_dst_mac', 'rx_dst_mac',
         'inner_src_ip', 'inner_dst_ip',
         'outer_src_ip', 'outer_dst_ip'])

    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')
    tx_dst_mac = args.get_arg('tx_dst_mac')
    rx_dst_mac = args.get_arg('rx_dst_mac')
    inner_src_ip = args.get_arg('inner_src_ip')
    inner_dst_ip = args.get_arg('inner_dst_ip')
    outer_src_ip = args.get_arg('outer_src_ip')
    outer_dst_ip = args.get_arg('outer_dst_ip')

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []

    tx_pkt_raw = Ether(dst=tx_dst_mac) / \
        IP(src=inner_src_ip, dst=inner_dst_ip) / \
        ICMP()

    sent_packets.append(tx_pkt_raw)
    txq.send(tx_pkt_raw)
    ether = rxq.recv(2)

    if ether is None:
        raise RuntimeError("ICMP echo Rx timeout")

    # Check RX headers
    if ether.dst != rx_dst_mac:
        raise RuntimeError("Matching of received destination MAC unsuccessful.")
    logger.debug("Comparison of received destination MAC: OK.")

    if ether['IP'].src != outer_src_ip:
        raise RuntimeError("Matching of received outer source IP unsuccessful.")
    logger.debug("Comparison of received outer source IP: OK.")

    if ether['IP'].dst != outer_dst_ip:
        raise RuntimeError(
            "Matching of received outer destination IP unsuccessful.")
    logger.debug("Comparison of received outer destination IP: OK.")

    if ether['IP'].proto != IP_PROTOS.gre:
        raise RuntimeError("IP protocol is no GRE.")
    logger.debug("Comparison of received GRE protocol: OK.")

    if ether['IP']['GRE']['IP'].src != inner_src_ip:
        raise RuntimeError("Matching of received inner source IP unsuccessful.")
    logger.debug("Comparison of received inner source IP: OK.")

    if ether['IP']['GRE']['IP'].dst != inner_dst_ip:
        raise RuntimeError(
            "Matching of received inner destination IP unsuccessful.")
    logger.debug("Comparison of received inner destination IP: OK.")

    sys.exit(0)
Esempio n. 8
0
def dhcp_request(tx_if, rx_if, tx_src_ip, tx_dst_ip, server_ip, proxy_ip,
                 client_ip, client_mac):
    """Send and check DHCP REQUEST proxy packet."""

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)

    sent_packets = []

    dhcp_request = Ether(src=client_mac, dst="ff:ff:ff:ff:ff:ff") / \
                   IP(src=tx_src_ip, dst=tx_dst_ip) / \
                   UDP(sport=UDP_SERVICES.bootpc, dport=UDP_SERVICES.bootps) / \
                   BOOTP(op=1,
                         giaddr=proxy_ip,
                         siaddr=server_ip) / \
                   DHCP(options=[("message-type", "request"),
                                 ("server_id", server_ip),
                                 ("requested_addr", client_ip),
                                 "end"])

    sent_packets.append(dhcp_request)
    txq.send(dhcp_request)

    ether = rxq.recv(2)

    if ether is None:
        raise RuntimeError('DHCP REQUEST timeout')

    if ether[IP].dst != server_ip:
        raise RuntimeError("Destination IP address error.")
    print "Destination IP address: OK."

    if ether[IP].src != proxy_ip:
        raise RuntimeError("Source IP address error.")
    print "Source IP address: OK."

    if ether[UDP].dport != UDP_SERVICES.bootps:
        raise RuntimeError("UDP destination port error.")
    print "UDP destination port: OK."

    if ether[UDP].sport != UDP_SERVICES.bootpc:
        raise RuntimeError("UDP source port error.")
    print "UDP source port: OK."

    if ether[BOOTP].siaddr != server_ip:
        raise RuntimeError("DHCP server IP address error.")
    print "DHCP server IP address: OK."

    if ether[DHCP].options[2][1] != client_ip:
        raise RuntimeError("Requested IP address error.")
    print "Requested IP address: OK."

    if ether[DHCP].options[3][0] != 'relay_agent_Information':  # option 82
        raise RuntimeError("Relay agent information error.")

    if ether[DHCP].options[0][1] != 3:  # 2 - REQUEST message
        raise RuntimeError("DHCP REQUEST message error.")
    print "DHCP REQUEST message: OK."
Esempio n. 9
0
def main():
    """Send TCP or UDP packet from one traffic generator interface to the other.
    """
    args = TrafficScriptArg([
        'tx_mac', 'rx_mac', 'src_ip', 'dst_ip', 'protocol', 'source_port',
        'destination_port'
    ])

    src_mac = args.get_arg('tx_mac')
    dst_mac = args.get_arg('rx_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')

    protocol = args.get_arg('protocol')
    source_port = args.get_arg('source_port')
    destination_port = args.get_arg('destination_port')

    ip_version = None
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        ip_version = IP
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        ip_version = IPv6
    else:
        ValueError("Invalid IP version!")

    if protocol.upper() == 'TCP':
        protocol = TCP
    elif protocol.upper() == 'UDP':
        protocol = UDP
    else:
        raise ValueError("Invalid type of protocol!")

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)

    pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
               ip_version(src=src_ip, dst=dst_ip) /
               protocol(sport=int(source_port), dport=int(destination_port)))

    txq.send(pkt_raw)
    ether = rxq.recv(2)

    if ether is None:
        raise RuntimeError("TCP/UDP Rx timeout")

    if 'TCP' in ether:
        print("TCP packet received.")

    elif 'UDP' in ether:
        print("UDP packet received.")
    else:
        raise RuntimeError("Not an TCP or UDP packet received {0}".format(
            ether.__repr__()))

    sys.exit(0)
Esempio n. 10
0
def dhcp_offer(rx_if, tx_if, tx_dst_ip, server_ip, proxy_ip, client_ip,
               server_mac, option_82):
    """Send and check DHCP OFFER proxy packet."""

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)

    sent_packets = []

    dhcp_offer = Ether(src=server_mac, dst="ff:ff:ff:ff:ff:ff") / \
                 IP(src=server_ip, dst=tx_dst_ip) / \
                 UDP(sport=UDP_SERVICES.bootps, dport=UDP_SERVICES.bootpc) / \
                 BOOTP(op=2,
                       yiaddr=client_ip,
                       siaddr=server_ip) / \
                 DHCP(options=
                      [("message-type", "offer"),
                       ("server_id", server_ip),
                       ("relay_agent_Information", option_82),
                       "end"])

    txq.send(dhcp_offer)
    sent_packets.append(dhcp_offer)

    ether = rxq.recv(2)

    if ether is None:
        raise RuntimeError('DHCP OFFER timeout')

    if ether[IP].dst != tx_dst_ip:
        raise RuntimeError("Destination IP address error.")
    print "Destination IP address: OK."

    if ether[IP].src != proxy_ip:
        raise RuntimeError("Source IP address error.")
    print "Source IP address: OK."

    if ether[UDP].dport != UDP_SERVICES.bootpc:
        raise RuntimeError("UDP destination port error.")
    print "UDP destination port: OK."

    if ether[UDP].sport != UDP_SERVICES.bootps:
        raise RuntimeError("UDP source port error.")
    print "UDP source port: OK."

    if ether[BOOTP].yiaddr != client_ip:
        raise RuntimeError("Client IP address error.")
    print "Client IP address: OK."

    if ether[BOOTP].siaddr != server_ip:
        raise RuntimeError("DHCP server IP address error.")
    print "DHCP server IP address: OK."

    if ether[DHCP].options[0][1] != 2:  # 2 - OFFER message
        raise RuntimeError("DHCP OFFER message error.")
    print "DHCP OFFER message OK."
Esempio n. 11
0
def main():
    """Send and receive TCP packet."""
    args = TrafficScriptArg(['src_mac', 'dst_mac', 'src_ip', 'dst_ip', 'dscp'])

    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')
    dscp = int(args.get_arg('dscp'))

    if 6 == ip_address(unicode(src_ip)).version:
        is_ipv4 = False
    else:
        is_ipv4 = True

    sent_packets = []

    if is_ipv4:
        ip_pkt = (IP(src=src_ip, dst=dst_ip) / TCP())
    else:
        ip_pkt = (IPv6(src=src_ip, dst=dst_ip) / TCP())

    pkt_send = (Ether(src=src_mac, dst=dst_mac) / ip_pkt)

    sent_packets.append(pkt_send)
    txq.send(pkt_send)

    while True:
        pkt_recv = rxq.recv(2, sent_packets)
        if pkt_recv is None:
            raise RuntimeError('ICMPv6 echo reply Rx timeout')

        if pkt_recv.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 pkt_recv is None:
        raise RuntimeError('Rx timeout')

    if is_ipv4:
        check_ipv4(pkt_recv, dscp)
    else:
        check_ipv6(pkt_recv, dscp)

    sys.exit(0)
Esempio n. 12
0
def dhcp_discover(tx_if, rx_if, tx_src_ip, tx_dst_ip, server_ip, proxy_ip,
                  client_mac):
    """Send and check DHCP DISCOVER proxy packet."""

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)

    sent_packets = []

    dhcp_discover = Ether(src=client_mac, dst="ff:ff:ff:ff:ff:ff") / \
                    IP(src=tx_src_ip, dst=tx_dst_ip) / \
                    UDP(sport=UDP_SERVICES.bootpc, dport=UDP_SERVICES.bootps) / \
                    BOOTP(op=1,) / \
                    DHCP(options=[("message-type", "discover"),
                                  "end"])

    sent_packets.append(dhcp_discover)
    txq.send(dhcp_discover)

    ether = rxq.recv(2)

    if ether is None:
        raise RuntimeError('DHCP DISCOVER timeout')

    if ether[IP].src != proxy_ip:
        raise RuntimeError("Source IP address error.")
    print "Source IP address: OK."

    if ether[IP].dst != server_ip:
        raise RuntimeError("Destination IP address error.")
    print "Destination IP address: OK."

    if ether[UDP].dport != UDP_SERVICES.bootps:
        raise RuntimeError("UDP destination port error.")
    print "UDP destination port: OK."

    if ether[UDP].sport != UDP_SERVICES.bootpc:
        raise RuntimeError("UDP source port error.")
    print "UDP source port: OK."

    if ether[DHCP].options[1][0] != 'relay_agent_Information':  # option 82
        raise RuntimeError("Relay agent information error.")
    option_82 = ether[DHCP].options[1][1]

    if ether[DHCP].options[0][1] != 1:  # 1 - DISCOVER message
        raise RuntimeError("DHCP DISCOVER message error.")
    print "DHCP DISCOVER message OK."

    return option_82
Esempio n. 13
0
def main():
    """Send and receive TCP packet."""
    args = TrafficScriptArg(['src_mac', 'dst_mac', 'src_ip', 'dst_ip', 'dscp'])

    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')
    dscp = int(args.get_arg('dscp'))

    if 6 == ip_address(unicode(src_ip)).version:
        is_ipv4 = False
    else:
        is_ipv4 = True

    sent_packets = []

    if is_ipv4:
        ip_pkt = IP(src=src_ip, dst=dst_ip) / \
                 TCP()
    else:
        ip_pkt = IPv6(src=src_ip, dst=dst_ip) / \
                 TCP()

    pkt_send = Ether(src=src_mac, dst=dst_mac) / \
               ip_pkt

    sent_packets.append(pkt_send)
    txq.send(pkt_send)

    pkt_recv = rxq.recv(2, sent_packets)

    if pkt_recv is None:
        raise RuntimeError('Rx timeout')

    if is_ipv4:
        check_ipv4(pkt_recv, dscp)
    else:
        check_ipv6(pkt_recv, dscp)

    sys.exit(0)
def ipv6_ping(src_if, dst_if, src_mac, dst_mac, proxy_to_src_mac,
              proxy_to_dst_mac, src_ip, dst_ip):
    """Sends ICMPv6 Echo Request, receive it and send a reply.

    :param src_if: First TG interface on link to DUT.
    :param dst_if: Second TG interface on link to DUT.
    :param src_mac: MAC address of first interface.
    :param dst_mac: MAC address of second interface.
    :param proxy_to_src_mac: MAC address of first proxy interface on DUT.
    :param proxy_to_dst_mac: MAC address of second proxy interface on DUT.
    :param src_ip: IP address of first interface.
    :param dst_ip: IP address of second interface.
    :type src_if: str
    :type dst_if: str
    :type src_mac: str
    :type dst_mac: str
    :type proxy_to_src_mac: str
    :type proxy_to_dst_mac: str
    :type src_ip: str
    :type dst_ip: str
    :raises RuntimeError: If a received packet is not correct.
    """
    rxq = RxQueue(dst_if)
    txq = TxQueue(src_if)

    icmpv6_ping_pkt = (Ether(src=src_mac, dst=proxy_to_src_mac) /
                       IPv6(src=src_ip, dst=dst_ip) / ICMPv6EchoRequest())

    txq.send(icmpv6_ping_pkt)

    ether = None
    while True:
        ether = rxq.recv(3)
        if not ether:
            continue
        if ether.haslayer(ICMPv6ND_NS):
            # read another packet in the queue in case of ICMPv6ND_NS packet
            continue
        else:
            # otherwise process the current packet
            break

    if ether is None:
        raise RuntimeError('ICMPv6 Echo Request timeout.')
    try:
        ether[IPv6]["ICMPv6 Echo Request"]
    except KeyError:
        raise RuntimeError("Received packet is not an ICMPv6 Echo Request.")
    print "ICMP Echo: OK."

    rxq = RxQueue(src_if)
    txq = TxQueue(dst_if)

    icmpv6_ping_pkt = (Ether(src=dst_mac, dst=proxy_to_dst_mac) /
                       IPv6(src=dst_ip, dst=src_ip) / ICMPv6EchoReply())

    txq.send(icmpv6_ping_pkt)

    ether = None
    while True:
        ether = rxq.recv(3)
        if not ether:
            continue
        if ether.haslayer(ICMPv6ND_NS):
            # read another packet in the queue in case of ICMPv6ND_NS packet
            continue
        else:
            # otherwise process the current packet
            break

    if ether is None:
        raise RuntimeError('DHCPv6 SOLICIT timeout')
    try:
        ether[IPv6]["ICMPv6 Echo Reply"]
    except KeyError:
        raise RuntimeError("Received packet is not an ICMPv6 Echo Reply.")

    print "ICMP Reply: OK."
def main():
    """Send IP ICMP packet from one traffic generator interface to the other."""
    args = TrafficScriptArg([
        'tg_src_mac', 'tg_dst_mac', 'src_ip', 'dst_ip', 'dut_if1_mac',
        'dut_if2_mac'
    ], [
        'encaps_tx', 'vlan_tx', 'vlan_outer_tx', 'encaps_rx', 'vlan_rx',
        'vlan_outer_rx'
    ])

    tx_src_mac = args.get_arg('tg_src_mac')
    tx_dst_mac = args.get_arg('dut_if1_mac')
    rx_dst_mac = args.get_arg('tg_dst_mac')
    rx_src_mac = args.get_arg('dut_if2_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')

    encaps_tx = args.get_arg('encaps_tx')
    vlan_tx = args.get_arg('vlan_tx')
    vlan_outer_tx = args.get_arg('vlan_outer_tx')
    encaps_rx = args.get_arg('encaps_rx')
    vlan_rx = args.get_arg('vlan_rx')
    vlan_outer_rx = args.get_arg('vlan_outer_rx')

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []
    ip_format = ''
    pkt_raw = Ether(src=tx_src_mac, dst=tx_dst_mac)
    if encaps_tx == 'Dot1q':
        pkt_raw /= Dot1Q(vlan=int(vlan_tx))
    elif encaps_tx == 'Dot1ad':
        pkt_raw.type = 0x88a8
        pkt_raw /= Dot1Q(vlan=vlan_outer_tx)
        pkt_raw /= Dot1Q(vlan=vlan_tx)
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        pkt_raw /= IP(src=src_ip, dst=dst_ip)
        pkt_raw /= ICMP()
        ip_format = IP
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        pkt_raw /= IPv6(src=src_ip, dst=dst_ip)
        pkt_raw /= ICMPv6EchoRequest()
        ip_format = IPv6
    else:
        raise ValueError("IP not in correct format")

    sent_packets.append(pkt_raw)
    txq.send(pkt_raw)
    if tx_if == rx_if:
        ether = rxq.recv(2, ignore=sent_packets)
    else:
        ether = rxq.recv(2)

    if ether is None:
        raise RuntimeError("ICMP echo Rx timeout")

    if rx_dst_mac == ether[Ether].dst and rx_src_mac == ether[Ether].src:
        logger.trace("MAC matched")
    else:
        raise RuntimeError("Matching packet unsuccessful: {0}".format(
            ether.__repr__()))

    if encaps_rx == 'Dot1q':
        if ether[Dot1Q].vlan == int(vlan_rx):
            logger.trace("VLAN matched")
        else:
            raise RuntimeError('Ethernet frame with wrong VLAN tag ({}-'
                               'received, {}-expected):\n{}'.format(
                                   ether[Dot1Q].vlan, vlan_rx,
                                   ether.__repr__()))
        ip = ether[Dot1Q].payload
    elif encaps_rx == 'Dot1ad':
        raise NotImplementedError()
    else:
        ip = ether.payload

    if not isinstance(ip, ip_format):
        raise RuntimeError("Not an IP packet received {0}".format(
            ip.__repr__()))

    # Compare data from packets
    if src_ip == ip.src:
        logger.trace("Src IP matched")
    else:
        raise RuntimeError("Matching Src IP unsuccessful: {} != {}".format(
            src_ip, ip.src))

    if dst_ip == ip.dst:
        logger.trace("Dst IP matched")
    else:
        raise RuntimeError("Matching Dst IP unsuccessful: {} != {}".format(
            dst_ip, ip.dst))

    sys.exit(0)
Esempio n. 16
0
def main():
    """Send VxLAN packet from TG to DUT.

    :raises: If the IP address is invalid.
    """
    args = TrafficScriptArg(['src_mac', 'dst_mac', 'src_ip', 'dst_ip',
                             'timeout', 'framesize', 'testtype'])

    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')
    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')
    timeout = max(2, int(args.get_arg('timeout')))
    frame_size = int(args.get_arg('framesize'))
    test_type = args.get_arg('testtype')

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []

    protocol = TCP
    source_port = SfcCon.DEF_SRC_PORT
    destination_port = SfcCon.DEF_DST_PORT

    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        ip_version = IP
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        ip_version = IPv6
    else:
        raise ValueError("Invalid IP version!")

    innerpkt = (Ether(src=src_mac, dst=dst_mac) /
                ip_version(src=src_ip, dst=dst_ip) /
                protocol(sport=int(source_port), dport=int(destination_port)))

    vxlan = '\x08\x00\x00\x00\x00\x00\x01\x00'

    raw_data = vxlan + str(innerpkt)

    pkt_header = (Ether(src=src_mac, dst=dst_mac) /
                  ip_version(src=src_ip, dst=dst_ip) /
                  UDP(sport=int(source_port), dport=4789) /
                  Raw(load=raw_data))

    fsize_no_fcs = frame_size - 4
    pad_len = max(0, fsize_no_fcs - len(pkt_header))
    pad_data = "A" * pad_len

    pkt_raw = pkt_header / Raw(load=pad_data)

    # Send created packet on one interface and receive on the other
    sent_packets.append(pkt_raw)
    txq.send(pkt_raw)

    while True:
        ether = rxq.recv(timeout)
        if ether is None:
            raise RuntimeError('No packet is received!')

        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

    # let us begin to check the proxy outbound packet
    VerifyPacket.check_the_nsh_sfc_packet(ether, frame_size, test_type)

    # we check all the fields about the proxy outbound, this test will pass
    sys.exit(0)
Esempio n. 17
0
def main():
    """Send 100 IP ICMP packets traffic and check if it is divided into
    two paths."""
    args = TrafficScriptArg(
        ['src_ip', 'dst_ip', 'tg_if1_mac', 'dut_if1_mac', 'dut_if2_mac',
         'path_1_mac', 'path_2_mac'])

    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    tg_if1_mac = args.get_arg('tg_if1_mac')
    dut_if1_mac = args.get_arg('dut_if1_mac')
    dut_if2_mac = args.get_arg('dut_if2_mac')
    path_1_mac = args.get_arg('path_1_mac')
    path_2_mac = args.get_arg('path_2_mac')
    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')
    path_1_counter = 0
    path_2_counter = 0

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []
    ip_format = ''
    pkt_raw = ''
    separator = ''

    if valid_ipv4(src_ip):
        separator = '.'
    elif valid_ipv6(src_ip):
        separator = ':'
    else:
        raise ValueError("Source address not in correct format")

    src_ip_base = (src_ip.rsplit(separator, 1))[0] + separator

    for i in range(1, 101):
        if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
            pkt_raw = (Ether(src=tg_if1_mac, dst=dut_if1_mac) /
                       IP(src=src_ip_base+str(i), dst=dst_ip) /
                       ICMP())
            ip_format = 'IP'
        elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
            pkt_raw = (Ether(src=tg_if1_mac, dst=dut_if1_mac) /
                       IPv6(src=src_ip_base+str(i), dst=dst_ip) /
                       ICMPv6EchoRequest())
            ip_format = 'IPv6'
        else:
            raise ValueError("IP not in correct format")

        sent_packets.append(pkt_raw)
        txq.send(pkt_raw)
        ether = rxq.recv(2)

        if ether is None:
            raise RuntimeError("ICMP echo Rx timeout")
        if not ether.haslayer(ip_format):
            raise RuntimeError("Not an IP packet received {0}"
                               .format(ether.__repr__()))

        if ether['Ethernet'].src != dut_if2_mac:
            raise RuntimeError("Source MAC address error")

        if ether['Ethernet'].dst == path_1_mac:
            path_1_counter += 1
        elif ether['Ethernet'].dst == path_2_mac:
            path_2_counter += 1
        else:
            raise RuntimeError("Destination MAC address error")

    if (path_1_counter + path_2_counter) != 100:
        raise RuntimeError("Packet loss: recevied only {} packets of 100 "
                           .format(path_1_counter + path_2_counter))

    if path_1_counter == 0:
        raise RuntimeError("Path 1 error!")

    if path_2_counter == 0:
        raise RuntimeError("Path 2 error!")

    print "Path_1 counter: {}".format(path_1_counter)
    print "Path_2 counter: {}".format(path_2_counter)

    sys.exit(0)
Esempio n. 18
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)
Esempio n. 19
0
def main():
    """Send IP ICMPv4/ICMPv6 packet from one traffic generator interface to
    the other one. Dot1q or Dot1ad tagging of the ethernet frame can be set.
    """
    args = TrafficScriptArg(['src_mac', 'dst_mac', 'src_ip', 'dst_ip'],
                            ['encaps', 'vlan1', 'vlan2', 'encaps_rx',
                             'vlan1_rx', 'vlan2_rx'])

    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')

    encaps = args.get_arg('encaps')
    vlan1 = args.get_arg('vlan1')
    vlan2 = args.get_arg('vlan2')
    encaps_rx = args.get_arg('encaps_rx')
    vlan1_rx = args.get_arg('vlan1_rx')
    vlan2_rx = args.get_arg('vlan2_rx')

    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)

    sent_packets = []
    ip_format = ''
    icmp_format = ''
    # Create empty ip ICMP packet and add padding before sending
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        if encaps == 'Dot1q':
            pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                       Dot1Q(vlan=int(vlan1)) /
                       IP(src=src_ip, dst=dst_ip) /
                       ICMP())
        elif encaps == 'Dot1ad':
            pkt_raw = (Ether(src=src_mac, dst=dst_mac, type=0x88A8) /
                       Dot1Q(vlan=int(vlan1), type=0x8100) /
                       Dot1Q(vlan=int(vlan2)) /
                       IP(src=src_ip, dst=dst_ip) /
                       ICMP())
        else:
            pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                       IP(src=src_ip, dst=dst_ip) /
                       ICMP())
        ip_format = IP
        icmp_format = ICMP
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        if encaps == 'Dot1q':
            pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                       Dot1Q(vlan=int(vlan1)) /
                       IPv6(src=src_ip, dst=dst_ip) /
                       ICMPv6EchoRequest())
        elif encaps == 'Dot1ad':
            pkt_raw = (Ether(src=src_mac, dst=dst_mac, type=0x88A8) /
                       Dot1Q(vlan=int(vlan1), type=0x8100) /
                       Dot1Q(vlan=int(vlan2)) /
                       IPv6(src=src_ip, dst=dst_ip) /
                       ICMPv6EchoRequest())
        else:
            pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                       IPv6(src=src_ip, dst=dst_ip) /
                       ICMPv6EchoRequest())
        ip_format = IPv6
        icmp_format = ICMPv6EchoRequest
    else:
        raise ValueError("IP(s) not in correct format")

    # Send created packet on one interface and receive on the other
    sent_packets.append(pkt_raw)
    txq.send(pkt_raw)

    # Receive ICMP / ICMPv6 echo reply
    while True:
        ether = rxq.recv(2,)
        if ether is None:
            raise RuntimeError('ICMP echo 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

    # Check whether received packet contains layers IP/IPv6 and
    # ICMP/ICMPv6EchoRequest
    if encaps_rx:
        if encaps_rx == 'Dot1q':
            if not vlan1_rx:
                vlan1_rx = vlan1
            if not ether.haslayer(Dot1Q):
                raise RuntimeError('Not VLAN tagged Eth frame received:\n{0}'.
                                   format(ether.__repr__()))
            elif ether[Dot1Q].vlan != int(vlan1_rx):
                raise RuntimeError('Ethernet frame with wrong VLAN tag ({}) '
                                   'received ({} expected):\n{}'.
                                   format(ether[Dot1Q].vlan, vlan1_rx,
                                          ether.__repr__()))
        elif encaps_rx == 'Dot1ad':
            if not vlan1_rx:
                vlan1_rx = vlan1
            if not vlan2_rx:
                vlan2_rx = vlan2
            # TODO
            raise RuntimeError('Encapsulation {0} not implemented yet.'.
                               format(encaps_rx))
        else:
            raise RuntimeError('Unsupported encapsulation expected: {0}'.
                               format(encaps_rx))

    if not ether.haslayer(ip_format):
        raise RuntimeError('Not an IP/IPv6 packet received:\n{0}'.
                           format(ether.__repr__()))

    if not ether.haslayer(icmp_format):
        raise RuntimeError('Not an ICMP/ICMPv6EchoRequest packet received:\n'
                           '{0}'.format(ether.__repr__()))

    sys.exit(0)
Esempio n. 20
0
def main():
    """Send packets to VPP, then listen for IPFIX flow report. Verify that
    the correct packet count was reported."""
    args = TrafficScriptArg([
        'src_mac', 'dst_mac', 'src_ip', 'dst_ip', 'protocol', 'port', 'count',
        'sessions'
    ])

    dst_mac = args.get_arg('dst_mac')
    src_mac = args.get_arg('src_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    tx_if = args.get_arg('tx_if')

    protocol = args.get_arg('protocol')
    count = int(args.get_arg('count'))
    sessions = int(args.get_arg('sessions'))

    txq = TxQueue(tx_if)
    rxq = RxQueue(tx_if)

    # generate simple packet based on arguments
    ip_version = None
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        ip_version = IP
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        ip_version = IPv6
    else:
        ValueError("Invalid IP version!")

    if protocol.upper() == 'TCP':
        protocol = TCP
    elif protocol.upper() == 'UDP':
        protocol = UDP
    else:
        raise ValueError("Invalid type of protocol!")

    packets = []
    for x in range(sessions):
        pkt = (Ether(src=src_mac, dst=dst_mac) /
               ip_version(src=src_ip, dst=dst_ip) / protocol(sport=x, dport=x))
        pkt = auto_pad(pkt)
        packets.append(pkt)

    # do not print details for sent packets
    verbose = False
    print("Sending more than one packet. Details will be filtered for "
          "all packets sent.")

    ignore = []
    for x in range(sessions):
        for _ in range(count):
            txq.send(packets[x], verbose=verbose)
            ignore.append(packets[x])

    # allow scapy to recognize IPFIX headers and templates
    ipfix = IPFIXHandler()

    # clear receive buffer
    while True:
        pkt = rxq.recv(1, ignore=packets, verbose=verbose)
        if pkt is None:
            break

    data = None
    ports = [x for x in range(sessions)]

    # get IPFIX template and data
    while True:
        pkt = rxq.recv(5)
        if pkt is None:
            raise RuntimeError("RX timeout")

        if pkt.haslayer("ICMPv6ND_NS"):
            # read another packet in the queue if the current one is ICMPv6ND_NS
            continue

        if pkt.haslayer("IPFIXHeader"):
            if pkt.haslayer("IPFIXTemplate"):
                # create or update template for IPFIX data packets
                ipfix.update_template(pkt)
            elif pkt.haslayer("IPFIXData"):
                for x in range(sessions):
                    try:
                        data = pkt.getlayer(IPFIXData, x + 1).fields
                    except AttributeError:
                        raise RuntimeError("Could not find data layer "
                                           "#{0}".format(x + 1))
                    port = verify_data(data, count, src_ip, dst_ip, protocol)
                    if port in ports:
                        ports.remove(port)
                    else:
                        raise RuntimeError("Unexpected or duplicate port {0} "
                                           "in flow report.".format(port))
                print("All {0} sessions verified "
                      "with packet count {1}.".format(sessions, count))
                sys.exit(0)
            else:
                raise RuntimeError("Unable to parse IPFIX template "
                                   "or data set.")
        else:
            raise RuntimeError("Received non-IPFIX packet or IPFIX header was"
                               "not recognized.")
Esempio n. 21
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():
    """Main function of the script file."""
    args = TrafficScriptArg(
        ['client_mac', 'server_mac', 'server_ip', 'client_ip', 'client_mask'],
        ['hostname', 'offer_xid'])

    server_if = args.get_arg('rx_if')
    server_mac = args.get_arg('server_mac')
    server_ip = args.get_arg('server_ip')

    client_mac = args.get_arg('client_mac')
    client_ip = args.get_arg('client_ip')
    client_mask = args.get_arg('client_mask')

    hostname = args.get_arg('hostname')
    offer_xid = args.get_arg('offer_xid')

    rx_src_ip = '0.0.0.0'
    rx_dst_ip = '255.255.255.255'

    rxq = RxQueue(server_if)
    txq = TxQueue(server_if)
    sent_packets = []

    for _ in range(10):
        dhcp_discover = rxq.recv(10)
        if is_discover(dhcp_discover):
            break
    else:
        raise RuntimeError("DHCP DISCOVER Rx error.")

    dhcp_offer = Ether(src=server_mac, dst=dhcp_discover.src)
    dhcp_offer /= IP(src=server_ip, dst="255.255.255.255")
    dhcp_offer /= UDP(sport=67, dport=68)
    dhcp_offer /= BOOTP(
        op=2,
        # if offer_xid differs from xid value in DHCP DISCOVER
        # the DHCP OFFER has to be discarded
        xid=int(offer_xid) if offer_xid else dhcp_discover['BOOTP'].xid,
        yiaddr=client_ip,
        siaddr=server_ip,
        chaddr=dhcp_discover['BOOTP'].chaddr)
    dhcp_offer_options = [
        ("message-type", "offer"),  # Option 53
        ("subnet_mask", client_mask),  # Option 1
        ("server_id", server_ip),  # Option 54, dhcp server
        ("lease_time", 43200),  # Option 51
        "end"
    ]
    dhcp_offer /= DHCP(options=dhcp_offer_options)

    txq.send(dhcp_offer)
    sent_packets.append(dhcp_offer)

    max_other_pkts = 10
    for _ in range(0, max_other_pkts):
        dhcp_request = rxq.recv(5, sent_packets)
        if not dhcp_request:
            raise RuntimeError("DHCP REQUEST Rx timeout.")
        if is_request(dhcp_request):
            break
    else:
        raise RuntimeError("Max RX packet limit reached.")

    if offer_xid:
        # if offer_xid differs from xid value in DHCP DISCOVER the DHCP OFFER
        # has to be discarded
        raise RuntimeError("DHCP REQUEST received. DHCP OFFER with wrong XID "
                           "has not been discarded.")

    # CHECK ETHER, IP, UDP
    if dhcp_request.dst != dhcp_discover.dst:
        raise RuntimeError("Destination MAC error.")
    print "Destination MAC: OK."

    if dhcp_request.src != dhcp_discover.src:
        raise RuntimeError("Source MAC error.")
    print "Source MAC: OK."

    if dhcp_request['IP'].dst != rx_dst_ip:
        raise RuntimeError("Destination IP error.")
    print "Destination IP: OK."

    if dhcp_request['IP'].src != rx_src_ip:
        raise RuntimeError("Source IP error.")
    print "Source IP: OK."

    if dhcp_request['IP']['UDP'].dport != UDP_SERVICES.bootps:
        raise RuntimeError("BOOTPs error.")
    print "BOOTPs: OK."

    if dhcp_request['IP']['UDP'].sport != UDP_SERVICES.bootpc:
        raise RuntimeError("BOOTPc error.")
    print "BOOTPc: OK."

    # CHECK BOOTP
    if dhcp_request['BOOTP'].op != dhcp_discover['BOOTP'].op:
        raise RuntimeError("BOOTP operation error.")
    print "BOOTP operation: OK"

    if dhcp_request['BOOTP'].xid != dhcp_discover['BOOTP'].xid:
        raise RuntimeError("BOOTP XID error.")
    print "BOOTP XID: OK"

    if dhcp_request['BOOTP'].ciaddr != '0.0.0.0':
        raise RuntimeError("BOOTP ciaddr error.")
    print "BOOTP ciaddr: OK"

    ca = dhcp_request['BOOTP'].chaddr[:dhcp_request['BOOTP'].hlen].encode(
        'hex')
    if ca != client_mac.replace(':', ''):
        raise RuntimeError("BOOTP client hardware address error.")
    print "BOOTP client hardware address: OK"

    if dhcp_request['BOOTP'].options != dhcp_discover['BOOTP'].options:
        raise RuntimeError("DHCP options error.")
    print "DHCP options: OK"

    # CHECK DHCP OPTIONS
    dhcp_options = dhcp_request['DHCP options'].options

    hn = filter(lambda x: x[0] == 'hostname', dhcp_options)
    if hostname:
        try:
            if hn[0][1] != hostname:
                raise RuntimeError("Client's hostname doesn't match.")
        except IndexError:
            raise RuntimeError("Option list doesn't contain hostname option.")
    else:
        if len(hn) != 0:
            raise RuntimeError("Option list contains hostname option.")
    print "Option 12 hostname: OK"

    # Option 50
    ra = filter(lambda x: x[0] == 'requested_addr', dhcp_options)[0][1]
    if ra != client_ip:
        raise RuntimeError("Option 50 requested_addr error.")
    print "Option 50 requested_addr: OK"

    # Option 53
    mt = filter(lambda x: x[0] == 'message-type', dhcp_options)[0][1]
    if mt != 3:  # request
        raise RuntimeError("Option 53 message-type error.")
    print "Option 53 message-type: OK"

    # Option 54
    sid = filter(lambda x: x[0] == 'server_id', dhcp_options)[0][1]
    if sid != server_ip:
        raise RuntimeError("Option 54 server_id error.")
    print "Option 54 server_id: OK"

    # Option 55
    prl = filter(lambda x: x[0] == 'param_req_list', dhcp_options)[0][1]
    if prl != '\x01\x1c\x02\x03\x0f\x06w\x0c,/\x1ay*':
        raise RuntimeError("Option 55 param_req_list error.")
    print "Option 55 param_req_list: OK"

    # Option 255
    if 'end' not in dhcp_options:
        raise RuntimeError("end option error.")
    print "end option: OK"

    sys.exit(0)
Esempio n. 23
0
def main():
    """Send VxLAN-GPE+NSH packet from TG to DUT.

    :raises: If the IP address is invalid.
    """
    args = TrafficScriptArg([
        'src_mac', 'dst_mac', 'src_ip', 'dst_ip', 'timeout', 'framesize',
        'testtype'
    ])

    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')
    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')
    timeout = int(args.get_arg('timeout'))
    frame_size = int(args.get_arg('framesize'))
    test_type = args.get_arg('testtype')

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []

    protocol = TCP
    source_port = sfccon.DEF_SRC_PORT
    destination_port = sfccon.DEF_DST_PORT

    ip_version = None
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        ip_version = IP
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        ip_version = IPv6
    else:
        raise ValueError("Invalid IP version!")

    innerpkt = (Ether(src=src_mac, dst=dst_mac) /
                ip_version(src=src_ip, dst=dst_ip) /
                protocol(sport=int(source_port), dport=int(destination_port)))

    vxlangpe_nsh = '\x0c\x00\x00\x04\x00\x00\x09\x00\x00\x06' \
                   '\x01\x03\x00\x00\xb9\xff\xC0\xA8\x32\x4B' \
                   '\x00\x00\x00\x09\xC0\xA8\x32\x48\x03\x00\x12\xB5'

    raw_data = vxlangpe_nsh + str(innerpkt)

    pkt_header = (Ether(src=src_mac, dst=dst_mac) /
                  ip_version(src=src_ip, dst=dst_ip) /
                  UDP(sport=int(source_port), dport=4790) / Raw(load=raw_data))

    fsize_no_fcs = frame_size - 4
    pad_len = max(0, fsize_no_fcs - len(pkt_header))
    pad_data = "A" * pad_len

    pkt_raw = pkt_header / Raw(load=pad_data)

    # Send created packet on one interface and receive on the other
    sent_packets.append(pkt_raw)
    txq.send(pkt_raw)

    ether = rxq.recv(2)

    if ether is None:
        raise RuntimeError("No packet is received!")

    # let us begin to check the proxy inbound packet
    VerifyPacket.check_the_nsh_sfc_packet(ether, frame_size, test_type)

    # we check all the fields about the proxy inbound, this test will pass
    sys.exit(0)
def imcpv6nd_solicit(tx_if, src_mac, dst_mac, src_ip, dst_ip):
    """Send ICMPv6 Neighbor Solicitation packet and expect a response
     from the proxy.

    :param tx_if: Interface on TG.
    :param src_mac: MAC address of TG interface.
    :param dst_mac: MAC address of proxy interface.
    :param src_ip: IP address of TG interface.
    :param dst_ip: IP address of proxied interface.
    :type tx_if: str
    :type src_mac: str
    :type dst_mac: str
    :type src_ip: str
    :type dst_ip: str
    :raises RuntimeError: If the received packet is not correct.
    """

    rxq = RxQueue(tx_if)
    txq = TxQueue(tx_if)

    sent_packets = []

    icmpv6nd_solicit_pkt = (Ether(src=src_mac, dst=dst_mac) /
                            IPv6(src=src_ip) / ICMPv6ND_NS(tgt=dst_ip))

    sent_packets.append(icmpv6nd_solicit_pkt)
    txq.send(icmpv6nd_solicit_pkt)

    ether = None
    for _ in range(5):
        ether = rxq.recv(3, ignore=sent_packets)
        if not ether:
            continue
        if ether.haslayer(ICMPv6ND_NS):
            # read another packet in the queue in case of ICMPv6ND_NS packet
            continue
        else:
            # otherwise process the current packet
            break

    if ether is None:
        raise RuntimeError('ICMPv6ND Proxy response timeout.')

    if ether.src != dst_mac:
        raise RuntimeError("Source MAC address error: {} != {}".format(
            ether.src, dst_mac))
    print "Source MAC address: OK."

    if ether.dst != src_mac:
        raise RuntimeError("Destination MAC address error: {} != {}".format(
            ether.dst, src_mac))
    print "Destination MAC address: OK."

    if ether[IPv6].src != dst_ip:
        raise RuntimeError("Source IP address error: {} != {}".format(
            ether[IPv6].src, dst_ip))
    print "Source IP address: OK."

    if ether[IPv6].dst != src_ip:
        raise RuntimeError("Destination IP address error: {} != {}".format(
            ether[IPv6].dst, src_ip))
    print "Destination IP address: OK."

    try:
        target_addr = ether[IPv6][ICMPv6ND_NA].tgt
    except (KeyError, AttributeError):
        raise RuntimeError("Not an ICMPv6ND Neighbor Advertisement packet.")

    if target_addr != dst_ip:
        raise RuntimeError(
            "ICMPv6 field 'Target address' error: {} != {}".format(
                target_addr, dst_ip))
    print "Target address field: OK."
Esempio n. 25
0
def main():
    """Send and receive IPsec packet."""
    args = TrafficScriptArg([
        'src_mac', 'dst_mac', 'src_ip', 'dst_ip', 'crypto_alg', 'crypto_key',
        'integ_alg', 'integ_key', 'l_spi', 'r_spi'
    ], ['src_tun', 'dst_tun'])

    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')
    crypto_alg = args.get_arg('crypto_alg')
    crypto_key = args.get_arg('crypto_key')
    integ_alg = args.get_arg('integ_alg')
    integ_key = args.get_arg('integ_key')
    l_spi = int(args.get_arg('l_spi'))
    r_spi = int(args.get_arg('r_spi'))
    src_tun = args.get_arg('src_tun')
    dst_tun = args.get_arg('dst_tun')

    is_ipv4 = True
    if 6 == ip_address(unicode(src_ip)).version:
        is_ipv4 = False

    tunnel_out = None
    tunnel_in = None

    if src_tun and dst_tun:
        if is_ipv4:
            tunnel_out = IP(src=src_tun, dst=dst_tun)
            tunnel_in = IP(src=dst_tun, dst=src_tun)
        else:
            tunnel_out = IPv6(src=src_tun, dst=dst_tun)
            tunnel_in = IPv6(src=dst_tun, dst=src_tun)
    else:
        src_tun = src_ip
        dst_tun = dst_ip

    sa_in = SecurityAssociation(ESP,
                                spi=r_spi,
                                crypt_algo=crypto_alg,
                                crypt_key=crypto_key,
                                auth_algo=integ_alg,
                                auth_key=integ_key,
                                tunnel_header=tunnel_in)

    sa_out = SecurityAssociation(ESP,
                                 spi=l_spi,
                                 crypt_algo=crypto_alg,
                                 crypt_key=crypto_key,
                                 auth_algo=integ_alg,
                                 auth_key=integ_key,
                                 tunnel_header=tunnel_out)

    sent_packets = []

    if is_ipv4:
        ip_pkt = IP(src=src_ip, dst=dst_ip) / \
                 ICMP()
        ip_pkt = IP(str(ip_pkt))
    else:
        ip_pkt = IPv6(src=src_ip, dst=dst_ip) / \
                 ICMPv6EchoRequest()
        ip_pkt = IPv6(str(ip_pkt))

    e_pkt = sa_out.encrypt(ip_pkt)
    pkt_send = Ether(src=src_mac, dst=dst_mac) / \
               e_pkt

    sent_packets.append(pkt_send)
    txq.send(pkt_send)

    pkt_recv = rxq.recv(2, sent_packets)

    if pkt_recv is None:
        raise RuntimeError('ESP packet Rx timeout')

    if is_ipv4:
        check_ipv4(pkt_recv, src_tun, dst_ip, src_ip, sa_in)
    else:
        check_ipv6(pkt_recv, src_tun, dst_ip, src_ip, sa_in)

    sys.exit(0)
Esempio n. 26
0
def ipv6_ping(src_if, dst_if, src_mac, dst_mac, proxy_to_src_mac,
              proxy_to_dst_mac, src_ip, dst_ip):
    """Sends ICMPv6 Echo Request, receive it and send a reply.

    :param src_if: First TG interface on link to DUT.
    :param dst_if: Second TG interface on link to DUT.
    :param src_mac: MAC address of first interface.
    :param dst_mac: MAC address of second interface.
    :param proxy_to_src_mac: MAC address of first proxy interface on DUT.
    :param proxy_to_dst_mac: MAC address of second proxy interface on DUT.
    :param src_ip: IP address of first interface.
    :param dst_ip: IP address of second interface.
    :type src_if: str
    :type dst_if: str
    :type src_mac: str
    :type dst_mac: str
    :type proxy_to_src_mac: str
    :type proxy_to_dst_mac: str
    :type src_ip: str
    :type dst_ip: str
    :raises RuntimeError: If a received packet is not correct.
    """
    rxq = RxQueue(dst_if)
    txq = TxQueue(src_if)

    icmpv6_ping_pkt = \
        Ether(src=src_mac, dst=proxy_to_src_mac) / \
        IPv6(src=src_ip, dst=dst_ip) / \
        ICMPv6EchoRequest()

    txq.send(icmpv6_ping_pkt)

    ether = None
    for _ in range(5):
        pkt = rxq.recv(3)
        if pkt is not None:
            ether = pkt
            break

    if ether is None:
        raise RuntimeError('ICMPv6 Echo Request timeout.')
    try:
        ether["IPv6"]["ICMPv6 Echo Request"]
    except KeyError:
        raise RuntimeError("Received packet is not an ICMPv6 Echo Request.")
    print "ICMP Echo: OK."

    rxq = RxQueue(src_if)
    txq = TxQueue(dst_if)

    icmpv6_ping_pkt = \
        Ether(src=dst_mac, dst=proxy_to_dst_mac) / \
        IPv6(src=dst_ip, dst=src_ip) / \
        ICMPv6EchoReply()

    txq.send(icmpv6_ping_pkt)

    ether = None
    for _ in range(5):
        pkt = rxq.recv(3)
        if pkt is not None:
            ether = pkt
            break

    if ether is None:
        raise RuntimeError('DHCPv6 SOLICIT timeout')
    try:
        ether["IPv6"]["ICMPv6 Echo Reply"]
    except KeyError:
        raise RuntimeError("Received packet is not an ICMPv6 Echo Reply.")

    print "ICMP Reply: OK."
Esempio n. 27
0
def main():
    """Send packets to VPP, then listen for IPFIX flow report. Verify that
    the correct packet count was reported."""
    args = TrafficScriptArg([
        'src_mac', 'dst_mac', 'src_ip', 'dst_ip', 'protocol', 'port', 'count'
    ])

    dst_mac = args.get_arg('dst_mac')
    src_mac = args.get_arg('src_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    tx_if = args.get_arg('tx_if')

    protocol = args.get_arg('protocol')
    source_port = int(args.get_arg('port'))
    destination_port = int(args.get_arg('port'))
    count = int(args.get_arg('count'))

    txq = TxQueue(tx_if)
    rxq = RxQueue(tx_if)

    # generate simple packet based on arguments
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        ip_version = IP
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        ip_version = IPv6
    else:
        raise ValueError("Invalid IP version!")

    if protocol.upper() == 'TCP':
        protocol = TCP
    elif protocol.upper() == 'UDP':
        protocol = UDP
    else:
        raise ValueError("Invalid type of protocol!")

    pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
               ip_version(src=src_ip, dst=dst_ip) /
               protocol(sport=int(source_port), dport=int(destination_port)))

    # do not print details for sent packets when sending more than one
    if count > 1:
        verbose = False
        print("Sending more than one packet. Details will be filtered for "
              "all packets sent.")
    else:
        verbose = True

    pkt_pad = auto_pad(pkt_raw)
    ignore = []
    for _ in range(count):
        txq.send(pkt_pad, verbose=verbose)
        ignore.append(pkt_pad)

    # allow scapy to recognize IPFIX headers and templates
    ipfix = IPFIXHandler()
    data = None
    # get IPFIX template and data
    while True:
        pkt = rxq.recv(10, ignore=ignore, verbose=verbose)
        if pkt is None:
            raise RuntimeError("RX timeout")

        if pkt.haslayer("ICMPv6ND_NS"):
            # read another packet in the queue if the current one is ICMPv6ND_NS
            continue

        if pkt.haslayer("IPFIXHeader"):
            if pkt.haslayer("IPFIXTemplate"):
                # create or update template for IPFIX data packets
                ipfix.update_template(pkt)
            elif pkt.haslayer("IPFIXData"):
                data = pkt.getlayer(IPFIXData).fields
                break
            else:
                raise RuntimeError("Unable to parse IPFIX set after header.")
        else:
            raise RuntimeError("Received non-IPFIX packet or IPFIX header "
                               "not recognized.")

    # verify packet count
    if data["packetTotalCount"] != count:
        raise RuntimeError("IPFIX reported wrong packet count. Count was {0},"
                           "but should be {1}".format(data["packetTotalCount"],
                                                      count))
    # verify IP addresses
    keys = data.keys()
    err = "{0} mismatch. Packets used {1}, but were classified as {2}."
    if ip_version == IP:
        if "IPv4_src" in keys:
            if data["IPv4_src"] != src_ip:
                raise RuntimeError(
                    err.format("Source IP", src_ip, data["IPv4_src"]))
        if "IPv4_dst" in keys:
            if data["IPv4_dst"] != dst_ip:
                raise RuntimeError(
                    err.format("Destination IP", dst_ip, data["IPv4_dst"]))
    else:
        if "IPv6_src" in keys:
            if data["IPv6_src"] != src_ip:
                raise RuntimeError(
                    err.format("Source IP", src_ip, data["IPv6_src"]))
        if "IPv6_dst" in keys:
            if data["IPv6_dst"] != dst_ip:
                raise RuntimeError(
                    err.format("Source IP", src_ip, data["IPv6_dst"]))
    # verify port numbers
    for item in ("src_port", "tcp_src_port", "udp_src_port"):
        try:
            if int(data[item]) != source_port:
                raise RuntimeError(
                    err.format("Source port", source_port, data[item]))
        except KeyError:
            pass
    for item in ("dst_port", "tcp_dst_port", "udp_dst_port"):
        try:
            if int(data[item]) != destination_port:
                raise RuntimeError(
                    err.format("Source port", destination_port, data[item]))
        except KeyError:
            pass
    # verify protocol ID
    if "Protocol_ID" in keys:
        if protocol == TCP and int(data["Protocol_ID"]) != 6:
            raise RuntimeError("TCP Packets were classified as not TCP.")
        if protocol == UDP and int(data["Protocol_ID"]) != 17:
            raise RuntimeError("UDP Packets were classified as not UDP.")
    sys.exit(0)
Esempio n. 28
0
def main():
    """Send Router Solicitation packet, check if the received response\
     is a Router Advertisement packet and verify."""

    args = TrafficScriptArg(['src_mac', 'dst_mac', 'src_ip'])

    router_mac = args.get_arg('dst_mac')
    src_mac = args.get_arg('src_mac')
    src_ip = args.get_arg('src_ip')
    if not src_ip:
        src_ip = mac_to_ipv6_linklocal(src_mac)
    tx_if = args.get_arg('tx_if')

    txq = TxQueue(tx_if)
    rxq = RxQueue(tx_if)

    pkt_raw = (Ether(src=src_mac, dst='33:33:00:00:00:02') /
               IPv6(src=src_ip, dst='ff02::2') / ICMPv6ND_RS())

    sent_packets = [pkt_raw]
    txq.send(pkt_raw)

    while True:
        ether = rxq.recv(2, sent_packets)
        if ether is None:
            raise RuntimeError('ICMP echo 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

    # Check whether received packet contains layer RA and check other values
    if ether.src != router_mac:
        raise RuntimeError('Packet source MAC ({0}) does not match router MAC '
                           '({1}).'.format(ether.src, router_mac))
    if ether.dst != src_mac:
        raise RuntimeError('Packet destination MAC ({0}) does not match RS '
                           'source MAC ({1}).'.format(ether.dst, src_mac))

    if not ether.haslayer(ICMPv6ND_RA):
        raise RuntimeError('Not an RA packet received {0}'.format(
            ether.__repr__()))

    src_address = ipaddress.IPv6Address(unicode(ether['IPv6'].src))
    dst_address = ipaddress.IPv6Address(unicode(ether['IPv6'].dst))
    router_link_local = ipaddress.IPv6Address(
        unicode(mac_to_ipv6_linklocal(router_mac)))
    rs_src_address = ipaddress.IPv6Address(unicode(src_ip))

    if src_address != router_link_local:
        raise RuntimeError('Packet source address ({0}) does not match link '
                           'local address({1})'.format(src_address,
                                                       router_link_local))

    if dst_address != rs_src_address:
        raise RuntimeError('Packet destination address ({0}) does not match '
                           'RS source address ({1}).'.format(
                               dst_address, rs_src_address))

    if ether['IPv6'].hlim != 255:
        raise RuntimeError('Hop limit not correct: {0}!=255'.format(
            ether['IPv6'].hlim))

    ra_code = ether[ICMPv6ND_RA].code
    if ra_code != 0:
        raise RuntimeError('ICMP code: {0} not correct. '.format(ra_code))

    sys.exit(0)
def main():  # pylint: disable=too-many-statements, too-many-locals
    """Main function of the script file."""
    args = TrafficScriptArg([
        'tx_dst_mac', 'tx_src_mac', 'tx_dst_ipv6', 'tx_src_ipv6',
        'tx_dst_ipv4', 'tx_src_ipv4', 'tx_src_udp_port', 'rx_dst_mac',
        'rx_src_mac'
    ])
    rx_if = args.get_arg('rx_if')
    tx_if = args.get_arg('tx_if')
    tx_src_mac = args.get_arg('tx_src_mac')
    tx_dst_mac = args.get_arg('tx_dst_mac')
    tx_dst_ipv6 = args.get_arg('tx_dst_ipv6')
    tx_src_ipv6 = args.get_arg('tx_src_ipv6')
    tx_dst_ipv4 = args.get_arg('tx_dst_ipv4')
    tx_src_ipv4 = args.get_arg('tx_src_ipv4')
    tx_src_udp_port = int(args.get_arg('tx_src_udp_port'))
    tx_dst_udp_port = 20000
    rx_dst_mac = args.get_arg('rx_dst_mac')
    rx_src_mac = args.get_arg('rx_src_mac')

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []

    # Create empty UDP datagram in IPv4 and IPv6
    tx_pkt = (Ether(dst=tx_dst_mac, src=tx_src_mac) /
              IPv6(src=tx_src_ipv6, dst=tx_dst_ipv6) /
              IP(src=tx_src_ipv4, dst=tx_dst_ipv4) /
              UDP(sport=tx_src_udp_port, dport=tx_dst_udp_port))

    txq.send(tx_pkt)
    sent_packets.append(tx_pkt)

    for _ in range(5):
        pkt = rxq.recv(2)
        if _is_udp_in_ipv4(pkt):
            ether = pkt
            break
    else:
        raise RuntimeError("UDP in IPv4 Rx error.")

    # check ethernet
    if ether.dst != rx_dst_mac:
        raise RuntimeError("Destination MAC error {} != {}.".format(
            ether.dst, rx_dst_mac))
    print "Destination MAC: OK."

    if ether.src != rx_src_mac:
        raise RuntimeError("Source MAC error {} != {}.".format(
            ether.src, rx_src_mac))
    print "Source MAC: OK."

    ipv4 = ether.payload

    # check ipv4
    if ipv4.dst != tx_dst_ipv4:
        raise RuntimeError("Destination IPv4 error {} != {}.".format(
            ipv4.dst, tx_dst_ipv4))
    print "Destination IPv4: OK."

    if ipv4.src != tx_src_ipv4:
        raise RuntimeError("Source IPv4 error {} != {}.".format(
            ipv4.src, tx_src_ipv4))
    print "Source IPv4: OK."

    if ipv4.proto != 17:  # UDP
        raise RuntimeError("IPv4 protocol error {} != UDP.".format(ipv4.proto))
    print "IPv4 protocol: OK."

    udp = ipv4.payload

    # check udp
    if udp.dport != tx_dst_udp_port:
        raise RuntimeError("UDP dport error {} != {}.".format(
            udp.dport, tx_dst_udp_port))
    print "UDP dport: OK."

    if udp.sport != tx_src_udp_port:
        raise RuntimeError("UDP sport error {} != {}.".format(
            udp.sport, tx_src_udp_port))
    print "UDP sport: OK."

    sys.exit(0)
def main():
    """Main function of the script file."""
    args = TrafficScriptArg(
        ['server_mac', 'server_ip', 'client_ip', 'client_mask', 'lease_time'])

    server_if = args.get_arg('rx_if')
    server_mac = args.get_arg('server_mac')
    server_ip = args.get_arg('server_ip')

    client_ip = args.get_arg('client_ip')
    client_mask = args.get_arg('client_mask')

    lease_time = int(args.get_arg('lease_time'))

    rxq = RxQueue(server_if)
    txq = TxQueue(server_if)
    sent_packets = []

    for _ in range(10):
        dhcp_discover = rxq.recv(10)
        if is_discover(dhcp_discover):
            break
    else:
        raise RuntimeError("DHCP DISCOVER Rx error.")

    dhcp_offer = Ether(src=server_mac, dst=dhcp_discover.src)
    dhcp_offer /= IP(src=server_ip, dst="255.255.255.255")
    dhcp_offer /= UDP(sport=67, dport=68)
    dhcp_offer /= BOOTP(op=2,
                        xid=dhcp_discover['BOOTP'].xid,
                        yiaddr=client_ip,
                        siaddr=server_ip,
                        chaddr=dhcp_discover['BOOTP'].chaddr)
    dhcp_offer_options = [
        ("message-type", "offer"),  # Option 53
        ("subnet_mask", client_mask),  # Option 1
        ("server_id", server_ip),  # Option 54, dhcp server
        ("lease_time", lease_time),  # Option 51
        "end"
    ]
    dhcp_offer /= DHCP(options=dhcp_offer_options)

    txq.send(dhcp_offer)
    sent_packets.append(dhcp_offer)

    max_other_pkts = 10
    for _ in range(0, max_other_pkts):
        dhcp_request = rxq.recv(5, sent_packets)
        if not dhcp_request:
            raise RuntimeError("DHCP REQUEST Rx timeout.")
        if is_request(dhcp_request):
            break
    else:
        raise RuntimeError("Max RX packet limit reached.")

    # Send dhcp ack
    dhcp_ack = Ether(src=server_mac, dst=dhcp_request.src)
    dhcp_ack /= IP(src=server_ip, dst="255.255.255.255")
    dhcp_ack /= UDP(sport=67, dport=68)
    dhcp_ack /= BOOTP(op=2,
                      xid=dhcp_request['BOOTP'].xid,
                      yiaddr=client_ip,
                      siaddr=server_ip,
                      flags=dhcp_request['BOOTP'].flags,
                      chaddr=dhcp_request['BOOTP'].chaddr)
    dhcp_ack_options = [
        ("message-type", "ack"),  # Option 53. 5: ACK, 6: NAK
        ("subnet_mask", client_mask),  # Option 1
        ("server_id", server_ip),  # Option 54, dhcp server
        ("lease_time", lease_time),  # Option 51,
        "end"
    ]
    dhcp_ack /= DHCP(options=dhcp_ack_options)

    txq.send(dhcp_ack)
    sent_packets.append(dhcp_ack)

    sys.exit(0)