예제 #1
0
    def __send_encrypted_ack(self):
        ack = AckNotificationPacket()
        conf.L3socket = L3RawSocket
        ack.setfieldval(
            'CID',
            string_to_ascii(SessionInstance.get_instance().connection_id))

        next_packet_number_int = PacketNumberInstance.get_instance(
        ).get_next_packet_number()
        next_packet_number_byte = int(next_packet_number_int).to_bytes(
            8, byteorder='little')
        next_packet_number_nonce = int(next_packet_number_int).to_bytes(
            2, byteorder='big')
        # print("Sending encrypted ack for packet number {}".format(next_packet_number_int))

        ack.setfieldval("Packet Number", next_packet_number_int)
        highest_received = PacketNumberInstance.get_instance(
        ).get_highest_received_packet_number()
        # print("Higheste {}".format(highest_received))
        highest_received_packet_number = format(int(highest_received, 16), 'x')

        ack_body = "40"
        ack_body += str(highest_received_packet_number).zfill(2)
        ack_body += "0062"
        ack_body += str(highest_received_packet_number).zfill(2)
        ack_body += "00"
        # not sure yet if we can remove this?
        # if SessionInstance.get_instance().nr_ack_send == 0:
        #     ack_body += str(highest_received_packet_number).zfill(2)
        #     ack_body += "00"
        #     ack_body += "01"
        keys = SessionInstance.get_instance().keys
        if keys:
            request = {
                'mode':
                'encryption',
                'input':
                ack_body,
                'key':
                keys['key1'].hex(),  # For encryption, we use my key
                'additionalData':
                "18" + SessionInstance.get_instance().connection_id +
                next_packet_number_byte.hex()
                [:4],  # Fixed public flags 18 || fixed connection Id || packet number
                'nonce':
                keys['iv1'].hex() +
                next_packet_number_nonce.hex().ljust(16, '0')
            }
        else:
            request = {
                'mode':
                'encryption',
                'input':
                ack_body,
                'key':
                "d309c2ddf54fdb0c34e9ae8f2aa5d0a4",  # Just use a fixed, invalid key
                'additionalData':
                "18" + SessionInstance.get_instance().connection_id +
                next_packet_number_byte.hex()[:4],
                # Fixed public flags 18 || fixed connection Id || packet number
                'nonce':
                "7a40a2e70600000000000000"  # Just use a fixed, invalid nonce.
            }

        # print("Ack request for encryption {}".format(request))

        ciphertext = CryptoConnectionManager.send_message(
            ConnectionEndpoint.CRYPTO_ORACLE,
            json.dumps(request).encode('utf-8'), True)
        ciphertext = ciphertext['data']
        # print("Ciphertext in ack {}".format(ciphertext))

        ack.setfieldval("Message Authentication Hash",
                        string_to_ascii(ciphertext[:24]))
        SessionInstance.get_instance().nr_ack_send += 1

        p = IP(dst=SessionInstance.get_instance().destination_ip) / UDP(
            dport=6121,
            sport=61250) / ack / Raw(load=string_to_ascii(ciphertext[24:]))
        send(p)
예제 #2
0
    def inject(self,
               vicmac,
               rtrmac,
               dstmac,
               vicip,
               svrip,
               vicport,
               svrport,
               acknum,
               seqnum,
               injection,
               TSVal,
               TSecr):
        """Send the injection using Scapy

        This method is where the actual packet is created for sending
        Things such as payload and associated flags are genned here
        FIN/ACK flag is sent to the victim with this method
        """
        print('lib.injector.inject() called !!')
        global npackets
        npackets += 1
        sys.stdout.write(Bcolors.OKBLUE + '[*] Injecting Packet to victim ' + Bcolors.WARNING + vicmac + Bcolors.OKBLUE + ' (TOTAL: ' + str(npackets) + ' injected packets)\r' + Bcolors.ENDC)
        sys.stdout.flush()

        ## Injection using Monitor Mode
        if self.args.inj == 'mon':
            hdr = Headers()
            headers = hdr.default(injection)

            ## WEP/WPA
            if self.args.wep or self.args.wpa:
                packet = self.rTap\
                        /Dot11(
                              FCfield = 'from-DS',
                              addr1 = vicmac,
                              addr2 = rtrmac,
                              addr3 = dstmac,
                              ### DEBUG
                              # subtype = 8L,
                              subtype = 8,
                              type = 2
                              )\
                        /Dot11QoS()\
                        /LLC()\
                        /SNAP()\
                        /IP(
                           dst = vicip,
                           src = svrip
                           )\
                        /TCP(
                            flags = 'FA',
                            sport = int(svrport),
                            dport = int(vicport),
                            seq = int(seqnum),
                            ack = int(acknum)
                            )\
                        /Raw(
                            load = headers + injection
                            )
            ## Open
            else:
                packet = RadioTap()\
                        /Dot11(
                              FCfield = 'from-DS',
                              addr1 = vicmac,
                              addr2 = rtrmac,
                              addr3 = dstmac
                              )\
                        /LLC()\
                        /SNAP()\
                        /IP(
                           dst = vicip,
                           src = svrip
                           )\
                        /TCP(
                            flags = 'FA',
                            sport = int(svrport),
                            dport = int(vicport),
                            seq = int(seqnum),
                            ack = int(acknum)
                            )\
                        /Raw(
                            load = headers + injection
                            )

            if TSVal is not None and TSecr is not None:
                packet[TCP].options = [
                                      ('NOP', None),
                                      ('NOP', None),
                                      ('Timestamp', ((round(time.time()), TSVal)))
                                      ]
            else:
                packet[TCP].options = [
                                      ('NOP', None),
                                      ('NOP', None),
                                      ('Timestamp', ((round(time.time()), 0)))
                                      ]

            ## WPA Injection
            if self.args.wpa is not None:
                if self.shake.encDict.get(vicmac) == 'ccmp':

                    ### Why are we incrementing here?  Been done before in wpaEncrypt(), verify this.
                    try:
                        self.shake.PN[5] += 1
                    except:
                        self.shake.PN[4] += 1

                    try:
                        packet = wpaEncrypt(self.shake.tgtInfo.get(vicmac)[1],
                                            self.shake.origPkt,
                                            packet,
                                            self.shake.PN,
                                            True)

                    except:
                        sys.stdout.write(Bcolors.FAIL + '\n[!] pyDot11 did not work\n[!] Injection failed\n ' + Bcolors.ENDC)
                        sys.stdout.flush()
                else:
                    sys.stdout.write(Bcolors.FAIL + '\n[!] airpwn-ng cannot inject TKIP natively\n[!] Injection failed\n ' + Bcolors.ENDC)
                    sys.stdout.flush()
                    #packet = wpaEncrypt(self.shake.tgtInfo.get(vicmac)[0],
                                        #self.shake.origPkt,
                                        #packet,
                                        #self.shake.PN,
                                        #True)



                if self.args.v is False:
                    sendp(packet, iface = self.interface, verbose = 0)
                else:
                    sendp(packet, iface = self.interface, verbose = 1)
                if self.args.pcap is True:
                    wrpcap('outbound.pcap', packet)

            ## WEP Injection
            elif self.args.wep is not None:
                try:
                    packet = wepEncrypt(packet, self.args.wep)
                except:
                    sys.stdout.write(Bcolors.FAIL + '\n[!] pyDot11 did not work\n[!] Injection failed\n ' + Bcolors.ENDC)
                    sys.stdout.flush()

                if self.args.v is False:
                    sendp(packet, iface = self.interface, verbose = 0)
                else:
                    sendp(packet, iface = self.interface, verbose = 1)
                if self.args.pcap is True:
                    wrpcap('outbound.pcap', packet)


            ## Open WiFi Injection
            else:
                if self.args.v is False:
                    sendp(packet, iface = self.interface, verbose = 0)
                else:
                    sendp(packet, iface = self.interface, verbose = 1)
                if self.args.pcap is True:
                    wrpcap('outbound.pcap', packet)


            ### Single packet exit point
            ### Used for BeEF hook examples and such
            if self.args.single is True:
                sys.stdout.write(Bcolors.OKBLUE + '[*] Injecting Packet to victim ' + Bcolors.WARNING + vicmac + Bcolors.OKBLUE + ' (TOTAL: ' + str(npackets) + ' injected packets)\r' + Bcolors.ENDC)
                sys.exit(0)

        ## Injection using Managed Mode
        else:
            hdr = Headers()
            headers = hdr.default(injection)
            packet = Ether(\
                          src = self.getHwAddr(self.interface),\
                          dst = vicmac\
                          )\
                    /IP(
                        dst = vicip,
                        src = svrip
                        )\
                    /TCP(
                        flags = 'FA',
                        sport = int(svrport),
                        dport = int(vicport),
                        seq = int(seqnum),
                        ack = int(acknum)
                        )\
                    /Raw(
                        load = headers + injection
                        )

            if TSVal is not None:
                packet[TCP].options = [\
                                      ('NOP', None),\
                                      ('NOP', None),\
                                      ('Timestamp', ((round(time.time()), TSVal)))\
                                      ]
            else:
                packet[TCP].options = [\
                                      ('NOP', None),\
                                      ('NOP', None),\
                                      ('Timestamp', ((round(time.time()), 0)))\
                                      ]

            if self.args.v is False:
                sendp(packet, iface = self.interface, verbose = 0)
            else:
                sendp(packet, iface = self.interface, verbose = 1)
            if self.args.pcap is True:
                wrpcap('outbound.pcap', packet)
예제 #3
0
def client_mode(options):
    """"Implements the niping client running mode

    :param options: option set from the command line
    :type options: Values
    """

    times = []
    p = Raw("EYECATCHER" + "\x00" * (options.buffer_size - 10))

    try:
        # Establish the connection
        conn = SAPRoutedStreamSocket.get_nisocket(options.host, options.port,
                                                  options.route_string)
        logging.info("")
        logging.info(datetime.today().ctime())
        logging.info("connect to server o.k.")

        # Send the messages
        for i in range(options.loops):

            # Send the packet and grab the response
            start_time = datetime.now()
            r = conn.sr(p)
            end_time = datetime.now()

            # Check the response
            if str(r.payload) != str(p):
                logging.info("[-] Response on message {} differs".format(i))

            # Calculate and record the elapsed time
            times.append(end_time - start_time)

        # Close the connection properly
        conn.send(Raw())
        conn.close()

    except SocketError:
        logging.error("[*] Connection error")
    except KeyboardInterrupt:
        logging.error("[*] Cancelled by the user")

    if times:
        logging.info("")
        logging.info(datetime.today().ctime())
        logging.info("send and receive {} messages (len {})".format(
            len(times), options.buffer_size))

        # Calculate the stats
        times = [x.total_seconds() * 1000 for x in times]
        times_min = min(times)
        times_max = max(times)
        times_avg = float(sum(times)) / max(len(times), 1)
        times_tr = float(options.buffer_size * len(times)) / float(sum(times))

        times2 = [x for x in times if x not in [times_min, times_max]]
        times2_avg = float(sum(times2)) / max(len(times2), 1)
        times2_tr = float(options.buffer_size * len(times2)) / float(
            sum(times2))

        # Print the stats
        logging.info("")
        logging.info("------- times -----")
        logging.info("avg  {:8.3f} ms".format(times_avg))
        logging.info("max  {:8.3f} ms".format(times_max))
        logging.info("min  {:8.3f} ms".format(times_min))
        logging.info("tr   {:8.3f} kB/s".format(times_tr))

        logging.info("excluding max and min:")
        logging.info("av2  {:8.3f} ms".format(times2_avg))
        logging.info("tr2  {:8.3f} kB/s".format(times2_tr))
        logging.info("")
예제 #4
0
    def test_fif6(self):
        """ Fragments in fragments (6o6) """
        # TODO this should be ideally in setUpClass, but then we hit a bug
        # with VppIpRoute incorrectly reporting it's present when it's not
        # so we need to manually remove the vpp config, thus we cannot have
        # it shared for multiple test cases
        self.tun_ip6 = "1002::1"

        self.gre6 = VppGre6Interface(self, self.src_if.local_ip6, self.tun_ip6)
        self.gre6.add_vpp_config()
        self.gre6.admin_up()
        self.gre6.config_ip6()

        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.gre6.sw_if_index, enable_ip6=True)

        self.route6 = VppIpRoute(self, self.tun_ip6, 128,
                                 [VppRoutePath(self.src_if.remote_ip6,
                                               self.src_if.sw_if_index,
                                               proto=DpoProto.DPO_PROTO_IP6)],
                                 is_ip6=1)
        self.route6.add_vpp_config()

        self.reset_packet_infos()
        for i in range(test_packet_count):
            info = self.create_packet_info(self.src_if, self.dst_if)
            payload = self.info_to_payload(info)
            # Ethernet header here is only for size calculation, thus it
            # doesn't matter how it's initialized. This is to ensure that
            # reassembled packet is not > 9000 bytes, so that it's not dropped
            p = (Ether() /
                 IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6) /
                 UDP(sport=1234, dport=5678) /
                 Raw(payload))
            size = self.packet_sizes[(i // 2) % len(self.packet_sizes)]
            self.extend_packet(p, size, self.padding)
            info.data = p[IPv6]  # use only IPv6 part, without ethernet header

        fragments = [x for _, i in self._packet_infos.iteritems()
                     for x in fragment_rfc8200(
                         i.data, i.index, 400)]

        encapped_fragments = \
            [Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IPv6(src=self.tun_ip6, dst=self.src_if.local_ip6) /
                GRE() /
                p
                for p in fragments]

        fragmented_encapped_fragments = \
            [x for p in encapped_fragments for x in (
                fragment_rfc8200(
                    p,
                    2 * len(self._packet_infos) + p[IPv6ExtHdrFragment].id,
                    200)
                if IPv6ExtHdrFragment in p else [p]
            )
            ]

        self.src_if.add_stream(fragmented_encapped_fragments)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        self.src_if.assert_nothing_captured()
        packets = self.dst_if.get_capture(len(self._packet_infos))
        self.verify_capture(packets, IPv6)
예제 #5
0
    def test_abf6(self):
        """ IPv6 ACL Based Forwarding
        """

        #
        # Simple test for matching IPv6 packets
        #

        #
        # Rule 1
        #
        rule_1 = ({'is_permit': 1,
                   'is_ipv6': 1,
                   'proto': 17,
                   'srcport_or_icmptype_first': 1234,
                   'srcport_or_icmptype_last': 1234,
                   'src_ip_prefix_len': 128,
                   'src_ip_addr': inet_pton(AF_INET6, "2001::2"),
                   'dstport_or_icmpcode_first': 1234,
                   'dstport_or_icmpcode_last': 1234,
                   'dst_ip_prefix_len': 128,
                   'dst_ip_addr': inet_pton(AF_INET6, "2001::1")})
        acl_1 = self.vapi.acl_add_replace(acl_index=4294967295,
                                          r=[rule_1])

        #
        # ABF policy for ACL 1 - path via interface 1
        #
        abf_1 = VppAbfPolicy(self, 10, acl_1,
                             [VppRoutePath("3001::1",
                                           0xffffffff,
                                           proto=DpoProto.DPO_PROTO_IP6)])
        abf_1.add_vpp_config()

        attach_1 = VppAbfAttach(self, 10, self.pg0.sw_if_index,
                                45, is_ipv6=True)
        attach_1.add_vpp_config()

        #
        # a packet matching the rule
        #
        p = (Ether(src=self.pg0.remote_mac,
                   dst=self.pg0.local_mac) /
             IPv6(src="2001::2", dst="2001::1") /
             UDP(sport=1234, dport=1234) /
             Raw('\xa5' * 100))

        #
        # packets are dropped because there is no route to the policy's
        # next hop
        #
        self.send_and_assert_no_replies(self.pg1, p * 65, "no route")

        #
        # add a route resolving the next-hop
        #
        route = VppIpRoute(self, "3001::1", 32,
                           [VppRoutePath(self.pg1.remote_ip6,
                                         self.pg1.sw_if_index,
                                         proto=DpoProto.DPO_PROTO_IP6)],
                           is_ip6=1)
        route.add_vpp_config()

        #
        # now expect packets forwarded.
        #
        self.send_and_expect(self.pg0, p * 65, self.pg1)
예제 #6
0
    def create_stream(self, src_if, packet_sizes, traffic_type=0, ipv6=0,
                      proto=-1, ports=0, fragments=False,
                      pkt_raw=True, etype=-1):
        """
        Create input packet stream for defined interface using hosts or
        deleted_hosts list.

        :param object src_if: Interface to create packet stream for.
        :param list packet_sizes: List of required packet sizes.
        :param traffic_type: 1: ICMP packet, 2: IPv6 with EH, 0: otherwise.
        :return: Stream of packets.
        """
        pkts = []
        if self.flows.__contains__(src_if):
            src_hosts = self.hosts_by_pg_idx[src_if.sw_if_index]
            for dst_if in self.flows[src_if]:
                dst_hosts = self.hosts_by_pg_idx[dst_if.sw_if_index]
                n_int = len(dst_hosts) * len(src_hosts)
                for i in range(0, n_int):
                    dst_host = dst_hosts[i / len(src_hosts)]
                    src_host = src_hosts[i % len(src_hosts)]
                    pkt_info = self.create_packet_info(src_if, dst_if)
                    if ipv6 == 1:
                        pkt_info.ip = 1
                    elif ipv6 == 0:
                        pkt_info.ip = 0
                    else:
                        pkt_info.ip = random.choice([0, 1])
                    if proto == -1:
                        pkt_info.proto = random.choice(self.proto[self.IP])
                    else:
                        pkt_info.proto = proto
                    payload = self.info_to_payload(pkt_info)
                    p = Ether(dst=dst_host.mac, src=src_host.mac)
                    if etype > 0:
                        p = Ether(dst=dst_host.mac,
                                  src=src_host.mac,
                                  type=etype)
                    if pkt_info.ip:
                        p /= IPv6(dst=dst_host.ip6, src=src_host.ip6)
                        if fragments:
                            p /= IPv6ExtHdrFragment(offset=64, m=1)
                    else:
                        if fragments:
                            p /= IP(src=src_host.ip4, dst=dst_host.ip4,
                                    flags=1, frag=64)
                        else:
                            p /= IP(src=src_host.ip4, dst=dst_host.ip4)
                    if traffic_type == self.ICMP:
                        if pkt_info.ip:
                            p /= ICMPv6EchoRequest(type=self.icmp6_type,
                                                   code=self.icmp6_code)
                        else:
                            p /= ICMP(type=self.icmp4_type,
                                      code=self.icmp4_code)
                    else:
                        p /= self.create_upper_layer(i, pkt_info.proto, ports)
                    if pkt_raw:
                        p /= Raw(payload)
                        pkt_info.data = p.copy()
                    if pkt_raw:
                        size = random.choice(packet_sizes)
                        self.extend_packet(p, size)
                    pkts.append(p)
        return pkts
예제 #7
0
    def test_udp_encap(self):
        """ UDP Encap test
        """

        #
        # construct a UDP encap object through each of the peers
        # v4 through the first two peears, v6 through the second.
        #
        udp_encap_0 = VppUdpEncap(self, 0, self.pg0.local_ip4,
                                  self.pg0.remote_ip4, 330, 440)
        udp_encap_1 = VppUdpEncap(self,
                                  1,
                                  self.pg1.local_ip4,
                                  self.pg1.remote_ip4,
                                  331,
                                  441,
                                  table_id=1)
        udp_encap_2 = VppUdpEncap(self,
                                  2,
                                  self.pg2.local_ip6,
                                  self.pg2.remote_ip6,
                                  332,
                                  442,
                                  table_id=2,
                                  is_ip6=1)
        udp_encap_3 = VppUdpEncap(self,
                                  3,
                                  self.pg3.local_ip6,
                                  self.pg3.remote_ip6,
                                  333,
                                  443,
                                  table_id=3,
                                  is_ip6=1)
        udp_encap_0.add_vpp_config()
        udp_encap_1.add_vpp_config()
        udp_encap_2.add_vpp_config()
        udp_encap_3.add_vpp_config()

        #
        # Routes via each UDP encap object - all combinations of v4 and v6.
        #
        route_4o4 = VppIpRoute(self, "1.1.0.1", 32, [
            VppRoutePath("0.0.0.0", 0xFFFFFFFF, is_udp_encap=1, next_hop_id=0)
        ])
        route_4o6 = VppIpRoute(self, "1.1.2.1", 32, [
            VppRoutePath("0.0.0.0", 0xFFFFFFFF, is_udp_encap=1, next_hop_id=2)
        ])
        route_6o4 = VppIpRoute(
            self,
            "2001::1",
            128, [
                VppRoutePath(
                    "0.0.0.0", 0xFFFFFFFF, is_udp_encap=1, next_hop_id=1)
            ],
            is_ip6=1)
        route_6o6 = VppIpRoute(
            self,
            "2001::3",
            128, [
                VppRoutePath(
                    "0.0.0.0", 0xFFFFFFFF, is_udp_encap=1, next_hop_id=3)
            ],
            is_ip6=1)
        route_4o4.add_vpp_config()
        route_4o6.add_vpp_config()
        route_6o6.add_vpp_config()
        route_6o4.add_vpp_config()

        #
        # 4o4 encap
        #
        p_4o4 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                 IP(src="2.2.2.2", dst="1.1.0.1") /
                 UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))
        rx = self.send_and_expect(self.pg0, p_4o4 * 65, self.pg0)
        for p in rx:
            self.validate_outer4(p, udp_encap_0)
            p = IP(p["UDP"].payload.load)
            self.validate_inner4(p, p_4o4)

        #
        # 4o6 encap
        #
        p_4o6 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                 IP(src="2.2.2.2", dst="1.1.2.1") /
                 UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))
        rx = self.send_and_expect(self.pg0, p_4o6 * 65, self.pg2)
        for p in rx:
            self.validate_outer6(p, udp_encap_2)
            p = IP(p["UDP"].payload.load)
            self.validate_inner4(p, p_4o6)

        #
        # 6o4 encap
        #
        p_6o4 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                 IPv6(src="2001::100", dst="2001::1") /
                 UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))
        rx = self.send_and_expect(self.pg0, p_6o4 * 65, self.pg1)
        for p in rx:
            self.validate_outer4(p, udp_encap_1)
            p = IPv6(p["UDP"].payload.load)
            self.validate_inner6(p, p_6o4)

        #
        # 6o6 encap
        #
        p_6o6 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                 IPv6(src="2001::100", dst="2001::3") /
                 UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))
        rx = self.send_and_expect(self.pg0, p_6o6 * 65, self.pg3)
        for p in rx:
            self.validate_outer6(p, udp_encap_3)
            p = IPv6(p["UDP"].payload.load)
            self.validate_inner6(p, p_6o6)

        #
        # A route with an output label
        # the TTL of the inner packet is decremented on LSP ingress
        #
        route_4oMPLSo4 = VppIpRoute(self, "1.1.2.22", 32, [
            VppRoutePath("0.0.0.0",
                         0xFFFFFFFF,
                         is_udp_encap=1,
                         next_hop_id=1,
                         labels=[66])
        ])
        route_4oMPLSo4.add_vpp_config()

        p_4omo4 = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                   IP(src="2.2.2.2", dst="1.1.2.22") /
                   UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))
        rx = self.send_and_expect(self.pg0, p_4omo4 * 65, self.pg1)
        for p in rx:
            self.validate_outer4(p, udp_encap_1)
            p = MPLS(p["UDP"].payload.load)
            self.validate_inner4(p, p_4omo4, ttl=63)
예제 #8
0
파일: test_cnat.py 프로젝트: bonedaddy/vpp
    def cnat_translation(self, vips, isV6=False):
        """ CNat Translation """

        ip_class = IPv6 if isV6 else IP
        ip_v = "ip6" if isV6 else "ip4"
        sports = [1234, 1233]

        #
        # turn the scanner off whilst testing otherwise sessions
        # will time out
        #
        self.vapi.cli("test cnat scanner off")

        sessions = self.vapi.cnat_session_dump()

        trs = []
        for nbr, vip in enumerate(vips):
            trs.append(self.cnat_create_translation(vip, nbr, isV6=isV6))

        self.logger.info(self.vapi.cli("sh cnat client"))
        self.logger.info(self.vapi.cli("sh cnat translation"))

        #
        # translations
        #
        for nbr, vip in enumerate(vips):
            self.cnat_test_translation(trs[nbr], nbr, sports, isV6=isV6)
            self.cnat_test_translation_update(trs[nbr], sports, isV6=isV6)
            if isV6:
                self.logger.info(
                    self.vapi.cli("sh ip6 fib %s" % self.pg0.remote_ip6))
            else:
                self.logger.info(
                    self.vapi.cli("sh ip fib %s" % self.pg0.remote_ip4))
            self.logger.info(self.vapi.cli("sh cnat session verbose"))

        #
        # turn the scanner back on and wait untill the sessions
        # all disapper
        #
        self.vapi.cli("test cnat scanner on")

        n_tries = 0
        sessions = self.vapi.cnat_session_dump()
        while (len(sessions) and n_tries < 100):
            n_tries += 1
            sessions = self.vapi.cnat_session_dump()
            self.sleep(2)

        self.assertTrue(n_tries < 100)

        #
        # load some flows again and purge
        #
        for vip in vips:
            for src in self.pg0.remote_hosts:
                for sport in sports:
                    # from client to vip
                    p1 = (Ether(dst=self.pg0.local_mac, src=src.mac) /
                          ip_class(src=getattr(src, ip_v), dst=vip.ip) /
                          vip.l4p(sport=sport, dport=vip.port) / Raw())
                    self.send_and_expect(self.pg0, p1 * N_PKTS, self.pg2)

        for tr in trs:
            tr.delete()

        self.assertTrue(self.vapi.cnat_session_dump())
        self.vapi.cnat_session_purge()
        self.assertFalse(self.vapi.cnat_session_dump())
예제 #9
0
파일: test_cnat.py 프로젝트: bonedaddy/vpp
    def cnat_test_sourcenat(self, srcNatAddr, l4p=TCP, isV6=False):
        ip_v = "ip6" if isV6 else "ip4"
        ip_class = IPv6 if isV6 else IP
        sports = [1234, 1235, 1236]
        dports = [6661, 6662, 6663]

        self.pg0.generate_remote_hosts(1)
        self.pg0.configure_ipv4_neighbors()
        self.pg0.configure_ipv6_neighbors()
        self.pg1.generate_remote_hosts(len(sports))
        self.pg1.configure_ipv4_neighbors()
        self.pg1.configure_ipv6_neighbors()

        self.vapi.cli("test cnat scanner on")
        t1 = self.cnat_create_translation(srcNatAddr, self.pg0)

        for nbr, remote_host in enumerate(self.pg1.remote_hosts):
            # from pods to outside network
            p1 = (Ether(dst=self.pg0.local_mac,
                        src=self.pg0.remote_hosts[0].mac) /
                  ip_class(src=getattr(self.pg0.remote_hosts[0], ip_v),
                           dst=getattr(remote_host, ip_v)) /
                  l4p(sport=sports[nbr], dport=dports[nbr]) / Raw())

            rxs = self.send_and_expect(self.pg0, p1 * N_PKTS, self.pg1)
            for rx in rxs:
                self.assert_packet_checksums_valid(rx)
                self.assertEqual(rx[ip_class].dst, getattr(remote_host, ip_v))
                self.assertEqual(rx[l4p].dport, dports[nbr])
                self.assertEqual(rx[ip_class].src, srcNatAddr)
                sport = rx[l4p].sport

            # from outside to pods
            p2 = (Ether(dst=self.pg1.local_mac,
                        src=self.pg1.remote_hosts[nbr].mac) /
                  ip_class(src=getattr(remote_host, ip_v), dst=srcNatAddr) /
                  l4p(sport=dports[nbr], dport=sport) / Raw())

            rxs = self.send_and_expect(self.pg1, p2 * N_PKTS, self.pg0)

            for rx in rxs:
                self.assert_packet_checksums_valid(rx)
                self.assertEqual(rx[ip_class].dst,
                                 getattr(self.pg0.remote_hosts[0], ip_v))
                self.assertEqual(rx[l4p].dport, sports[nbr])
                self.assertEqual(rx[l4p].sport, dports[nbr])
                self.assertEqual(rx[ip_class].src, getattr(remote_host, ip_v))

            # add remote host to exclude list
            subnet_mask = 100 if isV6 else 16
            subnet = getattr(remote_host, ip_v) + "/" + str(subnet_mask)
            exclude_subnet = ip_network(subnet, strict=False)

            t1.cnat_exclude_subnet(exclude_subnet)
            self.vapi.cnat_session_purge()

            rxs = self.send_and_expect(self.pg0, p1 * N_PKTS, self.pg1)
            for rx in rxs:
                self.assert_packet_checksums_valid(rx)
                self.assertEqual(rx[ip_class].dst, getattr(remote_host, ip_v))
                self.assertEqual(rx[l4p].dport, dports[nbr])
                self.assertEqual(rx[ip_class].src,
                                 getattr(self.pg0.remote_hosts[0], ip_v))

            # remove remote host from exclude list
            t1.cnat_exclude_subnet(exclude_subnet, isAdd=False)
            self.vapi.cnat_session_purge()

            rxs = self.send_and_expect(self.pg0, p1 * N_PKTS, self.pg1)

            for rx in rxs:
                self.assert_packet_checksums_valid(rx)
                self.assertEqual(rx[ip_class].dst, getattr(remote_host, ip_v))
                self.assertEqual(rx[l4p].dport, dports[nbr])
                self.assertEqual(rx[ip_class].src, srcNatAddr)
예제 #10
0
    def test_pipe(self):
        """ Pipes """

        pipes = [VppPipe(self), VppPipe(self, 10)]

        for p in pipes:
            p.add_vpp_config()
            p.admin_up()

        #
        # L2 cross-connect pipe0 east with pg0 and west with pg1
        #
        self.vapi.sw_interface_set_l2_xconnect(self.pg0.sw_if_index,
                                               pipes[0].east,
                                               enable=1)
        self.vapi.sw_interface_set_l2_xconnect(pipes[0].east,
                                               self.pg0.sw_if_index,
                                               enable=1)
        self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
                                               pipes[0].west,
                                               enable=1)
        self.vapi.sw_interface_set_l2_xconnect(pipes[0].west,
                                               self.pg1.sw_if_index,
                                               enable=1)

        # test bi-drectional L2 flow pg0<->pg1
        p = (Ether(src=self.pg0.remote_mac, dst=self.pg1.remote_mac) /
             IP(src="1.1.1.1", dst="1.1.1.2") / UDP(sport=1234, dport=1234) /
             Raw('\xa5' * 100))

        self.send_and_expect(self.pg0, p * 65, self.pg1)
        self.send_and_expect(self.pg1, p * 65, self.pg0)

        #
        # Attach ACL to ensure features are run on the pipe
        #
        rule_1 = ({
            'is_permit': 0,
            'is_ipv6': 0,
            'proto': 17,
            'srcport_or_icmptype_first': 1234,
            'srcport_or_icmptype_last': 1234,
            'src_ip_prefix_len': 32,
            'src_ip_addr': inet_pton(AF_INET, "1.1.1.1"),
            'dstport_or_icmpcode_first': 1234,
            'dstport_or_icmpcode_last': 1234,
            'dst_ip_prefix_len': 32,
            'dst_ip_addr': inet_pton(AF_INET, "1.1.1.2")
        })
        acl = self.vapi.acl_add_replace(acl_index=4294967295, r=[rule_1])

        # Apply the ACL on the pipe on output
        self.vapi.acl_interface_set_acl_list(pipes[0].east, 0, [acl.acl_index])
        self.send_and_assert_no_replies(self.pg0, p * 65)
        self.send_and_expect(self.pg1, p * 65, self.pg0)

        # remove from output and apply on input
        self.vapi.acl_interface_set_acl_list(pipes[0].east, 0, [])
        self.vapi.acl_interface_set_acl_list(pipes[0].west, 1, [acl.acl_index])
        self.send_and_assert_no_replies(self.pg0, p * 65)
        self.send_and_expect(self.pg1, p * 65, self.pg0)
        self.vapi.acl_interface_set_acl_list(pipes[0].west, 0, [])
        self.send_and_expect(self.pg0, p * 65, self.pg1)
        self.send_and_expect(self.pg1, p * 65, self.pg0)

        #
        # L3 routes in two separate tables so a pipe can be used to L3
        # x-connect
        #
        tables = []
        tables.append(VppIpTable(self, 1))
        tables.append(VppIpTable(self, 2))

        for t in tables:
            t.add_vpp_config()

        self.pg2.set_table_ip4(1)
        self.pg2.config_ip4()
        self.pg2.resolve_arp()
        self.pg3.set_table_ip4(2)
        self.pg3.config_ip4()
        self.pg3.resolve_arp()

        routes = []
        routes.append(
            VppIpRoute(
                self,
                "1.1.1.1",
                32, [VppRoutePath(self.pg3.remote_ip4, self.pg3.sw_if_index)],
                table_id=2))
        routes.append(
            VppIpRoute(self,
                       "1.1.1.1",
                       32, [VppRoutePath("0.0.0.0", pipes[1].east)],
                       table_id=1))
        routes.append(
            VppIpRoute(self,
                       "1.1.1.2",
                       32, [VppRoutePath("0.0.0.0", pipes[1].west)],
                       table_id=2))
        routes.append(
            VppIpRoute(
                self,
                "1.1.1.2",
                32, [VppRoutePath(self.pg2.remote_ip4, self.pg2.sw_if_index)],
                table_id=1))

        for r in routes:
            r.add_vpp_config()

        p_east = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
                  IP(src="1.1.1.2", dst="1.1.1.1") /
                  UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))

        # bind the pipe ends to the correct tables
        self.vapi.sw_interface_set_table(pipes[1].west, 0, 2)
        self.vapi.sw_interface_set_table(pipes[1].east, 0, 1)

        # IP is not enabled on the pipes at this point
        self.send_and_assert_no_replies(self.pg2, p_east * 65)

        # IP enable the Pipes by making them unnumbered
        pipes[0].set_unnumbered(self.pg2.sw_if_index)
        pipes[1].set_unnumbered(self.pg3.sw_if_index)

        self.send_and_expect(self.pg2, p_east * 65, self.pg3)

        # and the return path
        p_west = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
                  IP(src="1.1.1.1", dst="1.1.1.2") /
                  UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))
        self.send_and_expect(self.pg3, p_west * 65, self.pg2)

        #
        # Use ACLs to test features run on the Pipes
        #
        self.vapi.acl_interface_set_acl_list(pipes[1].east, 0, [acl.acl_index])
        self.send_and_assert_no_replies(self.pg2, p_east * 65)
        self.send_and_expect(self.pg3, p_west * 65, self.pg2)

        # remove from output and apply on input
        self.vapi.acl_interface_set_acl_list(pipes[1].east, 0, [])
        self.vapi.acl_interface_set_acl_list(pipes[1].west, 1, [acl.acl_index])
        self.send_and_assert_no_replies(self.pg2, p_east * 65)
        self.send_and_expect(self.pg3, p_west * 65, self.pg2)
        self.vapi.acl_interface_set_acl_list(pipes[1].west, 0, [])
        self.send_and_expect(self.pg2, p_east * 65, self.pg3)
        self.send_and_expect(self.pg3, p_west * 65, self.pg2)

        # cleanup (so the tables delete)
        self.pg2.unconfig_ip4()
        self.pg2.set_table_ip4(0)
        self.pg3.unconfig_ip4()
        self.pg3.set_table_ip4(0)
        self.vapi.sw_interface_set_table(pipes[1].west, 0, 0)
        self.vapi.sw_interface_set_table(pipes[1].east, 0, 0)
예제 #11
0
파일: test_cnat.py 프로젝트: bonedaddy/vpp
    def cnat_test_translation(self, t1, nbr, sports, isV6=False):
        ip_v = "ip6" if isV6 else "ip4"
        ip_class = IPv6 if isV6 else IP
        vip = t1.vip

        #
        # Flows
        #
        for src in self.pg0.remote_hosts:
            for sport in sports:
                # from client to vip
                p1 = (Ether(dst=self.pg0.local_mac, src=src.mac) /
                      ip_class(src=getattr(src, ip_v), dst=vip.ip) /
                      vip.l4p(sport=sport, dport=vip.port) / Raw())

                self.vapi.cli("trace add pg-input 1")
                rxs = self.send_and_expect(self.pg0, p1 * N_PKTS, self.pg1)

                for rx in rxs:
                    self.assert_packet_checksums_valid(rx)
                    self.assertEqual(rx[ip_class].dst,
                                     getattr(self.pg1.remote_hosts[nbr], ip_v))
                    self.assertEqual(rx[vip.l4p].dport, 4000 + nbr)
                    self.assertEqual(rx[ip_class].src, getattr(src, ip_v))
                    self.assertEqual(rx[vip.l4p].sport, sport)

                # from vip to client
                p1 = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
                      ip_class(src=getattr(self.pg1.remote_hosts[nbr], ip_v),
                               dst=getattr(src, ip_v)) /
                      vip.l4p(sport=4000 + nbr, dport=sport) / Raw())

                rxs = self.send_and_expect(self.pg1, p1 * N_PKTS, self.pg0)

                for rx in rxs:
                    self.assert_packet_checksums_valid(rx)
                    self.assertEqual(rx[ip_class].dst, getattr(src, ip_v))
                    self.assertEqual(rx[vip.l4p].dport, sport)
                    self.assertEqual(rx[ip_class].src, vip.ip)
                    self.assertEqual(rx[vip.l4p].sport, vip.port)

                #
                # packets to the VIP that do not match a
                # translation are dropped
                #
                p1 = (Ether(dst=self.pg0.local_mac, src=src.mac) /
                      ip_class(src=getattr(src, ip_v), dst=vip.ip) /
                      vip.l4p(sport=sport, dport=6666) / Raw())

                self.send_and_assert_no_replies(self.pg0, p1 * N_PKTS,
                                                self.pg1)

                #
                # packets from the VIP that do not match a
                # session are forwarded
                #
                p1 = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
                      ip_class(src=getattr(self.pg1.remote_hosts[nbr], ip_v),
                               dst=getattr(src, ip_v)) /
                      vip.l4p(sport=6666, dport=sport) / Raw())

                rxs = self.send_and_expect(self.pg1, p1 * N_PKTS, self.pg0)

        self.assertEqual(t1.get_stats()['packets'],
                         N_PKTS * len(sports) * len(self.pg0.remote_hosts))
    def test_ip_load_balance(self):
        """ IP Load-Balancing """

        #
        # An array of packets that differ only in the destination port
        #
        port_ip_pkts = []
        port_mpls_pkts = []

        #
        # An array of packets that differ only in the source address
        #
        src_ip_pkts = []
        src_mpls_pkts = []

        for ii in range(65):
            port_ip_hdr = (IP(dst="10.0.0.1", src="20.0.0.1") /
                           UDP(sport=1234, dport=1234 + ii) /
                           Raw('\xa5' * 100))
            port_ip_pkts.append(
                (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                 port_ip_hdr))
            port_mpls_pkts.append(
                (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                 MPLS(label=66, ttl=2) / port_ip_hdr))

            src_ip_hdr = (IP(dst="10.0.0.1", src="20.0.0.%d" % ii) /
                          UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))
            src_ip_pkts.append(
                (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                 src_ip_hdr))
            src_mpls_pkts.append(
                (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                 MPLS(label=66, ttl=2) / src_ip_hdr))

        route_10_0_0_1 = VppIpRoute(self, "10.0.0.1", 32, [
            VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index),
            VppRoutePath(self.pg2.remote_ip4, self.pg2.sw_if_index)
        ])
        route_10_0_0_1.add_vpp_config()

        binding = VppMplsIpBind(self, 66, "10.0.0.1", 32)
        binding.add_vpp_config()

        #
        # inject the packet on pg0 - expect load-balancing across the 2 paths
        #  - since the default hash config is to use IP src,dst and port
        #    src,dst
        # We are not going to ensure equal amounts of packets across each link,
        # since the hash algorithm is statistical and therefore this can never
        # be guaranteed. But wuth 64 different packets we do expect some
        # balancing. So instead just ensure there is traffic on each link.
        #
        self.send_and_expect_load_balancing(self.pg0, port_ip_pkts,
                                            [self.pg1, self.pg2])
        self.send_and_expect_load_balancing(self.pg0, src_ip_pkts,
                                            [self.pg1, self.pg2])
        self.send_and_expect_load_balancing(self.pg0, port_mpls_pkts,
                                            [self.pg1, self.pg2])
        self.send_and_expect_load_balancing(self.pg0, src_mpls_pkts,
                                            [self.pg1, self.pg2])

        #
        # change the flow hash config so it's only IP src,dst
        #  - now only the stream with differing source address will
        #    load-balance
        #
        self.vapi.set_ip_flow_hash(0, src=1, dst=1, sport=0, dport=0)

        self.send_and_expect_load_balancing(self.pg0, src_ip_pkts,
                                            [self.pg1, self.pg2])
        self.send_and_expect_load_balancing(self.pg0, src_mpls_pkts,
                                            [self.pg1, self.pg2])

        self.send_and_expect_one_itf(self.pg0, port_ip_pkts, self.pg2)

        #
        # change the flow hash config back to defaults
        #
        self.vapi.set_ip_flow_hash(0, src=1, dst=1, sport=1, dport=1)

        #
        # Recursive prefixes
        #  - testing that 2 stages of load-balancing occurs and there is no
        #    polarisation (i.e. only 2 of 4 paths are used)
        #
        port_pkts = []
        src_pkts = []

        for ii in range(257):
            port_pkts.append(
                (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                 IP(dst="1.1.1.1", src="20.0.0.1") /
                 UDP(sport=1234, dport=1234 + ii) / Raw('\xa5' * 100)))
            src_pkts.append(
                (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                 IP(dst="1.1.1.1", src="20.0.0.%d" % ii) /
                 UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)))

        route_10_0_0_2 = VppIpRoute(self, "10.0.0.2", 32, [
            VppRoutePath(self.pg3.remote_ip4, self.pg3.sw_if_index),
            VppRoutePath(self.pg4.remote_ip4, self.pg4.sw_if_index)
        ])
        route_10_0_0_2.add_vpp_config()

        route_1_1_1_1 = VppIpRoute(self, "1.1.1.1", 32, [
            VppRoutePath("10.0.0.2", 0xffffffff),
            VppRoutePath("10.0.0.1", 0xffffffff)
        ])
        route_1_1_1_1.add_vpp_config()

        #
        # inject the packet on pg0 - expect load-balancing across all 4 paths
        #
        self.vapi.cli("clear trace")
        self.send_and_expect_load_balancing(
            self.pg0, port_pkts, [self.pg1, self.pg2, self.pg3, self.pg4])
        self.send_and_expect_load_balancing(
            self.pg0, src_pkts, [self.pg1, self.pg2, self.pg3, self.pg4])

        #
        # Recursive prefixes
        #  - testing that 2 stages of load-balancing, no choices
        #
        port_pkts = []

        for ii in range(257):
            port_pkts.append(
                (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                 IP(dst="1.1.1.2", src="20.0.0.2") /
                 UDP(sport=1234, dport=1234 + ii) / Raw('\xa5' * 100)))

        route_10_0_0_3 = VppIpRoute(
            self, "10.0.0.3", 32,
            [VppRoutePath(self.pg3.remote_ip4, self.pg3.sw_if_index)])
        route_10_0_0_3.add_vpp_config()

        route_1_1_1_2 = VppIpRoute(self, "1.1.1.2", 32,
                                   [VppRoutePath("10.0.0.3", 0xffffffff)])
        route_1_1_1_2.add_vpp_config()

        #
        # inject the packet on pg0 - expect load-balancing across all 4 paths
        #
        self.vapi.cli("clear trace")
        self.send_and_expect_one_itf(self.pg0, port_pkts, self.pg3)
    def test_ip_sub_nets(self):
        """ IP Sub Nets """

        #
        # Configure a covering route to forward so we know
        # when we are dropping
        #
        cover_route = VppIpRoute(
            self, "10.0.0.0", 8,
            [VppRoutePath(self.pg1.remote_ip4, self.pg1.sw_if_index)])
        cover_route.add_vpp_config()

        p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
             IP(dst="10.10.10.10", src=self.pg0.local_ip4) /
             UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))

        self.pg1.add_stream(p)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        rx = self.pg1.get_capture(1)

        #
        # Configure some non-/24 subnets on an IP interface
        #
        ip_addr_n = socket.inet_pton(socket.AF_INET, "10.10.10.10")

        self.vapi.sw_interface_add_del_address(self.pg0.sw_if_index, ip_addr_n,
                                               16)

        pn = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
              IP(dst="10.10.0.0", src=self.pg0.local_ip4) /
              UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))
        pb = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
              IP(dst="10.10.255.255", src=self.pg0.local_ip4) /
              UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))

        self.send_and_assert_no_replies(self.pg1, pn, "IP Network address")
        self.send_and_assert_no_replies(self.pg1, pb, "IP Broadcast address")

        # remove the sub-net and we are forwarding via the cover again
        self.vapi.sw_interface_add_del_address(self.pg0.sw_if_index,
                                               ip_addr_n,
                                               16,
                                               is_add=0)
        self.pg1.add_stream(pn)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        rx = self.pg1.get_capture(1)
        self.pg1.add_stream(pb)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        rx = self.pg1.get_capture(1)

        #
        # A /31 is a special case where the 'other-side' is an attached host
        # packets to that peer generate ARP requests
        #
        ip_addr_n = socket.inet_pton(socket.AF_INET, "10.10.10.10")

        self.vapi.sw_interface_add_del_address(self.pg0.sw_if_index, ip_addr_n,
                                               31)

        pn = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
              IP(dst="10.10.10.11", src=self.pg0.local_ip4) /
              UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))

        self.pg1.add_stream(pn)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        rx = self.pg0.get_capture(1)
        rx[ARP]

        # remove the sub-net and we are forwarding via the cover again
        self.vapi.sw_interface_add_del_address(self.pg0.sw_if_index,
                                               ip_addr_n,
                                               31,
                                               is_add=0)
        self.pg1.add_stream(pn)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        rx = self.pg1.get_capture(1)
예제 #14
0
    def test_sapdiag_items_lookup(self):
        """Test lookup and filtering of SAPDiagItems inside a SAPDiag
        packet"""
        sapdiag = SAPDiag()

        sapdiag_ses_item = SAPDiagItem(item_type="SES")
        sapdiag.message.append(sapdiag_ses_item)

        sapdiag_appl_item = SAPDiagItem(item_type="APPL",
                                        item_id="ST_USER",
                                        item_sid="RFC_PARENT_UUID")
        sapdiag.message.append(sapdiag_appl_item)

        self.assertIn(sapdiag_ses_item, sapdiag.get_item(0x1))
        self.assertIn(sapdiag_ses_item, sapdiag.get_item("SES"))
        self.assertNotIn(sapdiag_ses_item, sapdiag.get_item(0x10))
        self.assertNotIn(sapdiag_ses_item, sapdiag.get_item("APPL"))

        self.assertIn(sapdiag_appl_item, sapdiag.get_item(0x10))
        self.assertIn(sapdiag_appl_item, sapdiag.get_item("APPL"))
        self.assertIn(sapdiag_appl_item, sapdiag.get_item("APPL", 0x04))
        self.assertIn(sapdiag_appl_item, sapdiag.get_item("APPL", "ST_USER"))
        self.assertIn(sapdiag_appl_item, sapdiag.get_item("APPL", 0x04, 0x10))
        self.assertIn(sapdiag_appl_item,
                      sapdiag.get_item("APPL", "ST_USER", 0x10))
        self.assertIn(sapdiag_appl_item,
                      sapdiag.get_item("APPL", "ST_USER", "RFC_PARENT_UUID"))
        self.assertNotIn(sapdiag_appl_item, sapdiag.get_item(0x1))
        self.assertNotIn(sapdiag_appl_item, sapdiag.get_item("APPL4"))
        self.assertNotIn(sapdiag_appl_item, sapdiag.get_item("APPL", 0x06))
        self.assertNotIn(sapdiag_appl_item,
                         sapdiag.get_item("APPL", "ST_R3INFO"))
        self.assertNotIn(sapdiag_appl_item,
                         sapdiag.get_item("APPL", 0x04, 0x02))
        self.assertNotIn(sapdiag_appl_item,
                         sapdiag.get_item("APPL", "ST_USER", 0x02))
        self.assertNotIn(sapdiag_appl_item,
                         sapdiag.get_item("APPL", "ST_USER", "CONNECT"))

        self.assertListEqual([sapdiag_ses_item, sapdiag_appl_item],
                             sapdiag.get_item([0x01, 0x10]))
        self.assertListEqual([sapdiag_ses_item, sapdiag_appl_item],
                             sapdiag.get_item(["SES", "APPL"]))
        self.assertIn(sapdiag_appl_item,
                      sapdiag.get_item(["APPL"], [0x04, 0x06]))
        self.assertIn(sapdiag_appl_item,
                      sapdiag.get_item(["APPL"], ["ST_USER", "ST_R3INFO"]))
        self.assertIn(sapdiag_appl_item,
                      sapdiag.get_item(["APPL"], 0x04, [0x02, 0x10]))
        self.assertIn(
            sapdiag_appl_item,
            sapdiag.get_item(["APPL"], "ST_USER",
                             ["RFC_PARENT_UUID", "CONNECT"]))
        self.assertNotIn(sapdiag_appl_item, sapdiag.get_item(["SES", "APPL4"]))
        self.assertNotIn(sapdiag_appl_item,
                         sapdiag.get_item(["APPL"], ["ST_R3INFO"]))
        self.assertNotIn(sapdiag_appl_item,
                         sapdiag.get_item(["APPL"], ["ST_USER"], ["CONNECT"]))

        # Insert a wrong item and observe that the lookup still works
        sapdiag.message.append(Raw("\x00" * 10))
        self.assertIn(sapdiag_ses_item, sapdiag.get_item("SES"))
        self.assertIn(
            sapdiag_appl_item,
            sapdiag.get_item(["APPL"], "ST_USER",
                             ["RFC_PARENT_UUID", "CONNECT"]))
예제 #15
0
def zero_mutable_fields(pkt, sending=False):
    """
    When using AH, all "mutable" fields must be "zeroed" before calculating
    the ICV. See RFC 4302, Section 3.3.3.1. Handling Mutable Fields.

    @param pkt: an IP(v6) packet containing an AH layer.
                NOTE: The packet will be modified
    @param sending: if true, ipv6 routing headers will not be reordered
    """

    if pkt.haslayer(AH):
        pkt[AH].icv = chr(0) * len(pkt[AH].icv)
    else:
        raise TypeError('no AH layer found')

    if pkt.version == 4:
        # the tos field has been replaced by DSCP and ECN
        # Routers may rewrite the DS field as needed to provide a
        # desired local or end-to-end service
        pkt.tos = 0
        # an intermediate router might set the DF bit, even if the source
        # did not select it.
        pkt.flags = 0
        # changed en route as a normal course of processing by routers
        pkt.ttl = 0
        # will change if any of these other fields change
        pkt.chksum = 0

        immutable_opts = []
        for opt in pkt.options:
            if opt.option in IMMUTABLE_IPV4_OPTIONS:
                immutable_opts.append(opt)
            else:
                immutable_opts.append(Raw(chr(0) * len(opt)))
        pkt.options = immutable_opts

    else:
        # holds DSCP and ECN
        pkt.tc = 0
        # The flow label described in AHv1 was mutable, and in RFC 2460 [DH98]
        # was potentially mutable. To retain compatibility with existing AH
        # implementations, the flow label is not included in the ICV in AHv2.
        pkt.fl = 0
        # same as ttl
        pkt.hlim = 0

        next_hdr = pkt.payload

        while isinstance(next_hdr, (IPv6ExtHdrHopByHop, IPv6ExtHdrRouting, IPv6ExtHdrDestOpt)):
            if isinstance(next_hdr, (IPv6ExtHdrHopByHop, IPv6ExtHdrDestOpt)):
                for opt in next_hdr.options:
                    if opt.otype & 0x20:
                        # option data can change en-route and must be zeroed
                        opt.optdata = chr(0) * opt.optlen
            elif isinstance(next_hdr, IPv6ExtHdrRouting) and sending:
                # The sender must order the field so that it appears as it
                # will at the receiver, prior to performing the ICV computation.
                next_hdr.segleft = 0
                if next_hdr.addresses:
                    final = next_hdr.addresses.pop()
                    next_hdr.addresses.insert(0, pkt.dst)
                    pkt.dst = final
            else:
                break

            next_hdr = next_hdr.payload

    return pkt
예제 #16
0
# The fields used to identify a version being fingerprinted
version_info_fields = [
    "version", "release", "patch_number", "source_id", "update_level",
    "file_version", "platform", "submitted_by", "comment"
]

# This is the list of target packets that we use during the fingerprinting. Basically it consist of a dict with the
# key being the name of the target packet and the value the construction of it.
fingerprint_targets = {
    # Connect to the SAP Route but not send any packet to trigger a timeout
    "Timeout":
    None,
    # Send a large packet
    "Network packet too big":
    Raw("X" * 10025),
    # Use an invalid opcode
    "Invalid control opcode":
    SAPRouter(type=SAPRouter.SAPROUTER_CONTROL, version=38, opcode=3),
    # Do not send a route
    "No route":
    SAPRouter(type=SAPRouter.SAPROUTER_ROUTE),
    # Set one entry but do no provide a route
    "No route one entry":
    SAPRouter(type=SAPRouter.SAPROUTER_ROUTE, route_entries=1),
    # Set one entry with an invalid length but do no provide it
    "No route invalid length":
    SAPRouter(type=SAPRouter.SAPROUTER_ROUTE,
              route_entries=2,
              route_rest_nodes=1,
              route_length=1,
예제 #17
0
파일: srv6_encap.py 프로젝트: gvnn3/csit
def main():
    """Send, receive and check IPv6 and IPv6ExtHdrSegmentRouting packets."""

    args = TrafficScriptArg([
        u"tx_src_mac", u"tx_dst_mac", u"rx_src_mac", u"rx_dst_mac", u"src_ip",
        u"dst_ip", u"dir0_srcsid", u"dir0_dstsid1", u"dir0_dstsid2",
        u"dir1_srcsid", u"dir1_dstsid1", u"dir1_dstsid2", u"decap",
        u"dir0_dstsid3", u"dir1_dstsid3", u"static_proxy"
    ])

    tx_txq = TxQueue(args.get_arg(u"tx_if"))
    tx_rxq = RxQueue(args.get_arg(u"tx_if"))
    rx_txq = TxQueue(args.get_arg(u"rx_if"))
    rx_rxq = RxQueue(args.get_arg(u"rx_if"))

    tx_src_mac = args.get_arg(u"tx_src_mac")
    tx_dst_mac = args.get_arg(u"tx_dst_mac")
    rx_src_mac = args.get_arg(u"rx_src_mac")
    rx_dst_mac = args.get_arg(u"rx_dst_mac")
    src_ip = args.get_arg(u"src_ip")
    dst_ip = args.get_arg(u"dst_ip")

    dir0_srcsid = args.get_arg(u"dir0_srcsid")
    dir0_dstsid1 = args.get_arg(u"dir0_dstsid1")
    dir0_dstsid2 = args.get_arg(u"dir0_dstsid2")
    dir1_srcsid = args.get_arg(u"dir1_srcsid")
    dir1_dstsid1 = args.get_arg(u"dir1_dstsid1")
    dir1_dstsid2 = args.get_arg(u"dir1_dstsid2")
    decap = args.get_arg(u"decap")
    dir0_dstsid3 = args.get_arg(u"dir0_dstsid3")
    dir1_dstsid3 = args.get_arg(u"dir1_dstsid3")
    static_proxy = args.get_arg(u"static_proxy")

    ip_pkt = IPv6(src=src_ip, dst=dst_ip)

    sent_packets = list()
    tx_pkt_send = (Ether(src=tx_src_mac, dst=tx_dst_mac) / ip_pkt)
    tx_pkt_send /= Raw()
    size_limit = 78
    if len(tx_pkt_send) < size_limit:
        tx_pkt_send[Raw].load += (b"\0" * (size_limit - len(tx_pkt_send)))
    sent_packets.append(tx_pkt_send)
    tx_txq.send(tx_pkt_send)

    while True:
        rx_pkt_recv = rx_rxq.recv(2)

        if rx_pkt_recv is None:
            raise RuntimeError(f"{IPv6.name} packet Rx timeout")

        if rx_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

    check_srv6(rx_pkt_recv, rx_src_mac, rx_dst_mac, src_ip, dst_ip,
               dir0_srcsid, dir0_dstsid1, dir0_dstsid2, dir0_dstsid3, 1)

    ip_pkt = IPv6(src=dst_ip, dst=src_ip)
    ip_pkt /= Raw()
    if len(ip_pkt) < (size_limit - 14):
        ip_pkt[Raw].load += (b"\0" * (size_limit - 14 - len(ip_pkt)))

    rx_pkt_send = (
        Ether(src=rx_dst_mac, dst=rx_src_mac) /
        IPv6(src=dir1_srcsid, dst=dir1_dstsid1) / IPv6ExtHdrSegmentRouting(
            segleft=1 if dir1_dstsid3 == u"None" else 2,
            lastentry=1 if dir1_dstsid3 == u"None" else 2,
            addresses=[dir1_dstsid2, dir1_dstsid1] if dir1_dstsid3 == u"None"
            else [dir1_dstsid3, dir1_dstsid2, dir1_dstsid1]) /
        ip_pkt) if dir1_dstsid2 != u"None" else (
            Ether(src=rx_dst_mac, dst=rx_src_mac) /
            IPv6(src=dir1_srcsid, dst=dir1_dstsid1) / ip_pkt)
    rx_txq.send(rx_pkt_send)

    while True:
        tx_pkt_recv = tx_rxq.recv(2, ignore=sent_packets)

        if tx_pkt_recv is None:
            raise RuntimeError(f"{IPv6.name} packet Rx timeout")

        if tx_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 decap == u"True":
        check_ip(tx_pkt_recv, tx_dst_mac, tx_src_mac, dst_ip, src_ip)
    else:
        check_srv6(tx_pkt_recv, tx_dst_mac, tx_src_mac, dst_ip, src_ip,
                   dir1_srcsid, dir1_dstsid1, dir1_dstsid2, dir1_dstsid3, 2,
                   bool(static_proxy == u"True"))

    sys.exit(0)
예제 #18
0
    def test_wg_peer_resp(self):
        """ Send handshake response """
        wg_output_node_name = '/err/wg-output-tun/'
        wg_input_node_name = '/err/wg-input/'

        port = 12323

        # Create interfaces
        wg0 = VppWgInterface(self,
                             self.pg1.local_ip4,
                             port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        peer_1 = VppWgPeer(self,
                           wg0,
                           self.pg1.remote_ip4,
                           port+1,
                           ["10.11.2.0/24",
                            "10.11.3.0/24"]).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        # wait for the peer to send a handshake
        rx = self.pg1.get_capture(1, timeout=2)

        # consume the handshake in the noise protocol and
        # generate the response
        resp = peer_1.consume_init(rx[0], self.pg1)

        # send the response, get keepalive
        rxs = self.send_and_expect(self.pg1, [resp], self.pg1)

        for rx in rxs:
            b = peer_1.decrypt_transport(rx)
            self.assertEqual(0, len(b))

        # send a packets that are routed into the tunnel
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src=self.pg0.remote_ip4, dst="10.11.3.2") /
             UDP(sport=555, dport=556) /
             Raw(b'\x00' * 80))

        rxs = self.send_and_expect(self.pg0, p * 255, self.pg1)

        peer_1.validate_encapped(rxs, p)

        # send packets into the tunnel, expect to receive them on
        # the other side
        p = [(peer_1.mk_tunnel_header(self.pg1) /
              Wireguard(message_type=4, reserved_zero=0) /
              WireguardTransport(
                  receiver_index=peer_1.sender,
                  counter=ii,
                  encrypted_encapsulated_packet=peer_1.encrypt_transport(
                      (IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20) /
                       UDP(sport=222, dport=223) /
                       Raw())))) for ii in range(255)]

        rxs = self.send_and_expect(self.pg1, p, self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)
예제 #19
0
    def test_cflow_packet(self):
        """verify cflow packet fields"""
        self.logger.info("FFP_TEST_START_0000")
        self.pg_enable_capture(self.pg_interfaces)
        self.pkts = []

        ipfix = VppCFLOW(test=self, intf='pg8', datapath="ip4",
                         layer='l2 l3 l4', active=2)
        ipfix.add_vpp_config()

        route_9001 = VppIpRoute(self, "9.0.0.0", 24,
                                [VppRoutePath(self.pg8._remote_hosts[0].ip4,
                                              self.pg8.sw_if_index)])
        route_9001.add_vpp_config()

        ipfix_decoder = IPFIXDecoder()
        templates = ipfix.verify_templates(ipfix_decoder, count=1)

        self.pkts = [(Ether(dst=self.pg7.local_mac,
                            src=self.pg7.remote_mac) /
                      IP(src=self.pg7.remote_ip4, dst="9.0.0.100") /
                      TCP(sport=1234, dport=4321, flags=80) /
                      Raw(b'\xa5' * 100))]

        nowUTC = int(time.time())
        nowUNIX = nowUTC+2208988800
        self.send_packets(src_if=self.pg7, dst_if=self.pg8)

        cflow = self.wait_for_cflow_packet(self.collector, templates[0], 10)
        self.collector.get_capture(2)

        if cflow[0].haslayer(IPFIX):
            self.assertEqual(cflow[IPFIX].version, 10)
            self.assertEqual(cflow[IPFIX].observationDomainID, 1)
            self.assertEqual(cflow[IPFIX].sequenceNumber, 0)
            self.assertAlmostEqual(cflow[IPFIX].exportTime, nowUTC, delta=5)
        if cflow.haslayer(Data):
            record = ipfix_decoder.decode_data_set(cflow[0].getlayer(Set))[0]
            # ingress interface
            self.assertEqual(int(binascii.hexlify(record[10]), 16), 8)
            # egress interface
            self.assertEqual(int(binascii.hexlify(record[14]), 16), 9)
            # packets
            self.assertEqual(int(binascii.hexlify(record[2]), 16), 1)
            # src mac
            self.assertEqual(mac_ntop(record[56]), self.pg8.local_mac)
            # dst mac
            self.assertEqual(mac_ntop(record[80]), self.pg8.remote_mac)
            flowTimestamp = int(binascii.hexlify(record[156]), 16) >> 32
            # flow start timestamp
            self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
            flowTimestamp = int(binascii.hexlify(record[157]), 16) >> 32
            # flow end timestamp
            self.assertAlmostEqual(flowTimestamp, nowUNIX, delta=1)
            # ethernet type
            self.assertEqual(int(binascii.hexlify(record[256]), 16), 8)
            # src ip
            self.assertEqual(inet_ntop(socket.AF_INET, record[8]),
                             self.pg7.remote_ip4)
            # dst ip
            self.assertEqual(inet_ntop(socket.AF_INET, record[12]),
                             "9.0.0.100")
            # protocol (TCP)
            self.assertEqual(int(binascii.hexlify(record[4]), 16), 6)
            # src port
            self.assertEqual(int(binascii.hexlify(record[7]), 16), 1234)
            # dst port
            self.assertEqual(int(binascii.hexlify(record[11]), 16), 4321)
            # tcp flags
            self.assertEqual(int(binascii.hexlify(record[6]), 16), 80)

        ipfix.remove_vpp_config()
        self.logger.info("FFP_TEST_FINISH_0000")
예제 #20
0
    def test_wg_peer_init(self):
        """ Send handshake init """
        wg_output_node_name = '/err/wg-output-tun/'
        wg_input_node_name = '/err/wg-input/'

        port = 12333

        # Create interfaces
        wg0 = VppWgInterface(self,
                             self.pg1.local_ip4,
                             port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

        peer_1 = VppWgPeer(self,
                           wg0,
                           self.pg1.remote_ip4,
                           port+1,
                           ["10.11.2.0/24",
                            "10.11.3.0/24"]).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        # route a packet into the wg interface
        #  use the allowed-ip prefix
        #  this is dropped because the peer is not initiated
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src=self.pg0.remote_ip4, dst="10.11.3.2") /
             UDP(sport=555, dport=556) /
             Raw())
        self.send_and_assert_no_replies(self.pg0, [p])

        kp_error = wg_output_node_name + "Keypair error"
        self.assertEqual(1, self.statistics.get_err_counter(kp_error))

        # send a handsake from the peer with an invalid MAC
        p = peer_1.mk_handshake(self.pg1)
        p[WireguardInitiation].mac1 = b'foobar'
        self.send_and_assert_no_replies(self.pg1, [p])
        self.assertEqual(1, self.statistics.get_err_counter(
            wg_input_node_name + "Invalid MAC handshake"))

        # send a handsake from the peer but signed by the wrong key.
        p = peer_1.mk_handshake(self.pg1,
                                X25519PrivateKey.generate().public_key())
        self.send_and_assert_no_replies(self.pg1, [p])
        self.assertEqual(1, self.statistics.get_err_counter(
            wg_input_node_name + "Peer error"))

        # send a valid handsake init for which we expect a response
        p = peer_1.mk_handshake(self.pg1)

        rx = self.send_and_expect(self.pg1, [p], self.pg1)

        peer_1.consume_response(rx[0])

        # route a packet into the wg interface
        #  this is dropped because the peer is still not initiated
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src=self.pg0.remote_ip4, dst="10.11.3.2") /
             UDP(sport=555, dport=556) /
             Raw())
        self.send_and_assert_no_replies(self.pg0, [p])
        self.assertEqual(2, self.statistics.get_err_counter(kp_error))

        # send a data packet from the peer through the tunnel
        # this completes the handshake
        p = (IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20) /
             UDP(sport=222, dport=223) /
             Raw())
        d = peer_1.encrypt_transport(p)
        p = (peer_1.mk_tunnel_header(self.pg1) /
             (Wireguard(message_type=4, reserved_zero=0) /
              WireguardTransport(receiver_index=peer_1.sender,
                                 counter=0,
                                 encrypted_encapsulated_packet=d)))
        rxs = self.send_and_expect(self.pg1, [p], self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        # send a packets that are routed into the tunnel
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src=self.pg0.remote_ip4, dst="10.11.3.2") /
             UDP(sport=555, dport=556) /
             Raw(b'\x00' * 80))

        rxs = self.send_and_expect(self.pg0, p * 255, self.pg1)

        for rx in rxs:
            rx = IP(peer_1.decrypt_transport(rx))

            # chech the oringial packet is present
            self.assertEqual(rx[IP].dst, p[IP].dst)
            self.assertEqual(rx[IP].ttl, p[IP].ttl-1)

        # send packets into the tunnel, expect to receive them on
        # the other side
        p = [(peer_1.mk_tunnel_header(self.pg1) /
              Wireguard(message_type=4, reserved_zero=0) /
              WireguardTransport(
                  receiver_index=peer_1.sender,
                  counter=ii+1,
                  encrypted_encapsulated_packet=peer_1.encrypt_transport(
                      (IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20) /
                       UDP(sport=222, dport=223) /
                       Raw())))) for ii in range(255)]

        rxs = self.send_and_expect(self.pg1, p, self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()
예제 #21
0
    def test_fif4(self):
        """ Fragments in fragments (4o4) """

        # TODO this should be ideally in setUpClass, but then we hit a bug
        # with VppIpRoute incorrectly reporting it's present when it's not
        # so we need to manually remove the vpp config, thus we cannot have
        # it shared for multiple test cases
        self.tun_ip4 = "1.1.1.2"

        self.gre4 = VppGreInterface(self, self.src_if.local_ip4, self.tun_ip4)
        self.gre4.add_vpp_config()
        self.gre4.admin_up()
        self.gre4.config_ip4()

        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.gre4.sw_if_index, enable_ip4=True)

        self.route4 = VppIpRoute(self, self.tun_ip4, 32,
                                 [VppRoutePath(self.src_if.remote_ip4,
                                               self.src_if.sw_if_index)])
        self.route4.add_vpp_config()

        self.reset_packet_infos()
        for i in range(test_packet_count):
            info = self.create_packet_info(self.src_if, self.dst_if)
            payload = self.info_to_payload(info)
            # Ethernet header here is only for size calculation, thus it
            # doesn't matter how it's initialized. This is to ensure that
            # reassembled packet is not > 9000 bytes, so that it's not dropped
            p = (Ether() /
                 IP(id=i, src=self.src_if.remote_ip4,
                    dst=self.dst_if.remote_ip4) /
                 UDP(sport=1234, dport=5678) /
                 Raw(payload))
            size = self.packet_sizes[(i // 2) % len(self.packet_sizes)]
            self.extend_packet(p, size, self.padding)
            info.data = p[IP]  # use only IP part, without ethernet header

        fragments = [x for _, p in self._packet_infos.iteritems()
                     for x in fragment_rfc791(p.data, 400)]

        encapped_fragments = \
            [Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IP(src=self.tun_ip4, dst=self.src_if.local_ip4) /
                GRE() /
                p
                for p in fragments]

        fragmented_encapped_fragments = \
            [x for p in encapped_fragments
             for x in fragment_rfc791(p, 200)]

        self.src_if.add_stream(fragmented_encapped_fragments)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        self.src_if.assert_nothing_captured()
        packets = self.dst_if.get_capture(len(self._packet_infos))
        self.verify_capture(packets, IP)

        # TODO remove gre vpp config by hand until VppIpRoute gets fixed
        # so that it's query_vpp_config() works as it should
        self.gre4.remove_vpp_config()
        self.logger.debug(self.vapi.ppcli("show interface"))
예제 #22
0
    def test_wg_peer_init(self):
        """ Handoff """
        wg_output_node_name = '/err/wg-output-tun/'
        wg_input_node_name = '/err/wg-input/'

        port = 12353

        # Create interfaces
        wg0 = VppWgInterface(self,
                             self.pg1.local_ip4,
                             port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

        peer_1 = VppWgPeer(self,
                           wg0,
                           self.pg1.remote_ip4,
                           port+1,
                           ["10.11.2.0/24",
                            "10.11.3.0/24"]).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        # send a valid handsake init for which we expect a response
        p = peer_1.mk_handshake(self.pg1)

        rx = self.send_and_expect(self.pg1, [p], self.pg1)

        peer_1.consume_response(rx[0])

        # send a data packet from the peer through the tunnel
        # this completes the handshake and pins the peer to worker 0
        p = (IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20) /
             UDP(sport=222, dport=223) /
             Raw())
        d = peer_1.encrypt_transport(p)
        p = (peer_1.mk_tunnel_header(self.pg1) /
             (Wireguard(message_type=4, reserved_zero=0) /
              WireguardTransport(receiver_index=peer_1.sender,
                                 counter=0,
                                 encrypted_encapsulated_packet=d)))
        rxs = self.send_and_expect(self.pg1, [p], self.pg0,
                                   worker=0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        # send a packets that are routed into the tunnel
        # and pins the peer tp worker 1
        pe = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
              IP(src=self.pg0.remote_ip4, dst="10.11.3.2") /
              UDP(sport=555, dport=556) /
              Raw(b'\x00' * 80))
        rxs = self.send_and_expect(self.pg0, pe * 255, self.pg1, worker=1)
        peer_1.validate_encapped(rxs, pe)

        # send packets into the tunnel, from the other worker
        p = [(peer_1.mk_tunnel_header(self.pg1) /
              Wireguard(message_type=4, reserved_zero=0) /
              WireguardTransport(
                  receiver_index=peer_1.sender,
                  counter=ii+1,
                  encrypted_encapsulated_packet=peer_1.encrypt_transport(
                      (IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20) /
                       UDP(sport=222, dport=223) /
                       Raw())))) for ii in range(255)]

        rxs = self.send_and_expect(self.pg1, p, self.pg0, worker=1)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        # send a packets that are routed into the tunnel
        # from owrker 0
        rxs = self.send_and_expect(self.pg0, pe * 255, self.pg1, worker=0)

        peer_1.validate_encapped(rxs, pe)

        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()
예제 #23
0
    def test_abf4(self):
        """ IPv4 ACL Based Forwarding
        """

        #
        # We are not testing the various matching capabilities
        # of ACLs, that's done elsewhere. Here ware are testing
        # the application of ACLs to a forwarding path to achieve
        # ABF
        # So we construct just a few ACLs to ensure the ABF policies
        # are correclty constructed and used. And a few path types
        # to test the API path decoding.
        #

        #
        # Rule 1
        #
        rule_1 = ({'is_permit': 1,
                   'is_ipv6': 0,
                   'proto': 17,
                   'srcport_or_icmptype_first': 1234,
                   'srcport_or_icmptype_last': 1234,
                   'src_ip_prefix_len': 32,
                   'src_ip_addr': inet_pton(AF_INET, "1.1.1.1"),
                   'dstport_or_icmpcode_first': 1234,
                   'dstport_or_icmpcode_last': 1234,
                   'dst_ip_prefix_len': 32,
                   'dst_ip_addr': inet_pton(AF_INET, "1.1.1.2")})
        acl_1 = self.vapi.acl_add_replace(acl_index=4294967295, r=[rule_1])

        #
        # ABF policy for ACL 1 - path via interface 1
        #
        abf_1 = VppAbfPolicy(self, 10, acl_1,
                             [VppRoutePath(self.pg1.remote_ip4,
                                           self.pg1.sw_if_index)])
        abf_1.add_vpp_config()

        #
        # Attach the policy to input interface Pg0
        #
        attach_1 = VppAbfAttach(self, 10, self.pg0.sw_if_index, 50)
        attach_1.add_vpp_config()

        #
        # fire in packet matching the ACL src,dst. If it's forwarded
        # then the ABF was successful, since default routing will drop it
        #
        p_1 = (Ether(src=self.pg0.remote_mac,
                     dst=self.pg0.local_mac) /
               IP(src="1.1.1.1", dst="1.1.1.2") /
               UDP(sport=1234, dport=1234) /
               Raw('\xa5' * 100))
        self.send_and_expect(self.pg0, p_1*65, self.pg1)

        #
        # Attach a 'better' priority policy to the same interface
        #
        abf_2 = VppAbfPolicy(self, 11, acl_1,
                             [VppRoutePath(self.pg2.remote_ip4,
                                           self.pg2.sw_if_index)])
        abf_2.add_vpp_config()
        attach_2 = VppAbfAttach(self, 11, self.pg0.sw_if_index, 40)
        attach_2.add_vpp_config()

        self.send_and_expect(self.pg0, p_1*65, self.pg2)

        #
        # Attach a policy with priority in the middle
        #
        abf_3 = VppAbfPolicy(self, 12, acl_1,
                             [VppRoutePath(self.pg3.remote_ip4,
                                           self.pg3.sw_if_index)])
        abf_3.add_vpp_config()
        attach_3 = VppAbfAttach(self, 12, self.pg0.sw_if_index, 45)
        attach_3.add_vpp_config()

        self.send_and_expect(self.pg0, p_1*65, self.pg2)

        #
        # remove the best priority
        #
        attach_2.remove_vpp_config()
        self.send_and_expect(self.pg0, p_1*65, self.pg3)

        #
        # Attach one of the same policies to Pg1
        #
        attach_4 = VppAbfAttach(self, 12, self.pg1.sw_if_index, 45)
        attach_4.add_vpp_config()

        p_2 = (Ether(src=self.pg1.remote_mac,
                     dst=self.pg1.local_mac) /
               IP(src="1.1.1.1", dst="1.1.1.2") /
               UDP(sport=1234, dport=1234) /
               Raw('\xa5' * 100))
        self.send_and_expect(self.pg1, p_2 * 65, self.pg3)

        #
        # detach the policy from PG1, now expect traffic to be dropped
        #
        attach_4.remove_vpp_config()

        self.send_and_assert_no_replies(self.pg1, p_2 * 65, "Detached")
예제 #24
0
파일: injector.py 프로젝트: ICSec/airpwn-ng
    def inject(self, tgtmac, rtrmac, dstmac, tgtip, svrip, tgtport, svrport,
               acknum, seqnum, injection, TSVal, TSecr):
        """Send the injection using Scapy

        This method is where the actual packet is created for sending things
        such as the payload and associated flags.

        FIN/ACK flag is sent to the target with this method.
        """

        ## Headers
        headers = self.hdr.default(injection)

        if self.args.tun is False:

            ## Monitor injection
            if self.args.inj == 'mon':
                packet = RadioTap()\
                         /Dot11(
                                FCfield = 'from-DS',
                                addr1 = tgtmac,
                                addr2 = rtrmac,
                                addr3 = dstmac
                               )\
                         /LLC()\
                         /SNAP()\
                         /IP(
                             dst = tgtip,
                             src = svrip
                            )\
                         /TCP(
                              flags = 'FA',
                              sport = int(svrport),
                              dport = int(tgtport),
                              seq = int(seqnum),
                              ack = int(acknum)
                             )\
                         /Raw(
                              load = headers + injection
                             )

                if TSVal is not None and TSecr is not None:
                    packet[TCP].options = [('NOP', None), ('NOP', None),
                                           ('Timestamp', ((round(time.time()),
                                                           TSVal)))]
                else:
                    packet[TCP].options = [('NOP', None), ('NOP', None),
                                           ('Timestamp', ((round(time.time()),
                                                           0)))]
            ## Managed injection
            else:
                headers = self.hdr.default(injection)
                packet = Ether(
                               src = self.injMac,\
                               dst = tgtmac\
                              )\
                         /IP(
                             dst = tgtip,
                             src = svrip
                             )\
                         /TCP(
                              flags = 'FA',
                              sport = int(svrport),
                              dport = int(tgtport),
                              seq = int(seqnum),
                              ack = int(acknum)
                             )\
                         /Raw(
                              load = headers + injection
                             )

                if TSVal is not None:
                    packet[TCP].options = [\
                                          ('NOP', None),\
                                          ('NOP', None),\
                                          ('Timestamp', ((round(time.time()), TSVal)))\
                                          ]
                else:
                    packet[TCP].options = [\
                                          ('NOP', None),\
                                          ('NOP', None),\
                                          ('Timestamp', ((round(time.time()), 0)))\
                                          ]

        ## Managed
        else:
            try:
                headers = self.hdr.default(injection)
                packet = Ether(
                               src = self.injMac,\
                               dst = tgtmac\
                              )\
                         /IP(
                             dst = tgtip,
                             src = svrip
                            )\
                         /TCP(
                              flags = 'FA',
                              sport = int(svrport),
                              dport = int(tgtport),
                              seq = int(seqnum),
                              ack = int(acknum)
                             )\
                         /Raw(
                              load = headers + injection
                             )

                if TSVal is not None:
                    packet[TCP].options = [
                                           ('NOP', None),\
                                           ('NOP', None),\
                                           ('Timestamp', ((round(time.time()), TSVal)))\
                                          ]
                else:
                    packet[TCP].options = [
                                           ('NOP', None),\
                                           ('NOP', None),\
                                           ('Timestamp', ((round(time.time()), 0)))\
                                          ]
            except Exception as E:
                print(E)

        ## Inject
        try:
            gs(self.injSocket, packet, verbose=False)
            print('[*] Packet injected to {0}'.format(tgtmac))
        except Exception as E:
            print(E)
예제 #25
0
파일: test_gbp.py 프로젝트: zengnotes/vpp
    def test_gbp(self):
        """ Group Based Policy """

        nat_table = VppIpTable(self, 20)
        nat_table.add_vpp_config()

        #
        # Bridge Domains
        #
        self.vapi.bridge_domain_add_del(1,
                                        flood=1,
                                        uu_flood=1,
                                        forward=1,
                                        learn=0,
                                        arp_term=1,
                                        is_add=1)
        self.vapi.bridge_domain_add_del(2,
                                        flood=1,
                                        uu_flood=1,
                                        forward=1,
                                        learn=0,
                                        arp_term=1,
                                        is_add=1)
        self.vapi.bridge_domain_add_del(20,
                                        flood=1,
                                        uu_flood=1,
                                        forward=1,
                                        learn=0,
                                        arp_term=1,
                                        is_add=1)

        #
        # 3 EPGs, 2 of which share a BD.
        #
        epgs = []
        recircs = []
        epgs.append(
            VppGbpEndpointGroup(self, 220, 0, 1, self.pg4, self.loop0,
                                "10.0.0.128", "2001:10::128"))
        recircs.append(VppGbpRecirc(self, epgs[0], self.loop3))
        epgs.append(
            VppGbpEndpointGroup(self, 221, 0, 1, self.pg5, self.loop0,
                                "10.0.1.128", "2001:10:1::128"))
        recircs.append(VppGbpRecirc(self, epgs[1], self.loop4))
        epgs.append(
            VppGbpEndpointGroup(self, 222, 0, 2, self.pg6, self.loop1,
                                "10.0.2.128", "2001:10:2::128"))
        recircs.append(VppGbpRecirc(self, epgs[2], self.loop5))

        #
        # 2 NAT EPGs, one for floating-IP subnets, the other for internet
        #
        epgs.append(
            VppGbpEndpointGroup(self, 333, 20, 20, self.pg7, self.loop2,
                                "11.0.0.128", "3001::128"))
        recircs.append(VppGbpRecirc(self, epgs[3], self.loop6, is_ext=True))
        epgs.append(
            VppGbpEndpointGroup(self, 444, 20, 20, self.pg8, self.loop2,
                                "11.0.0.129", "3001::129"))
        recircs.append(VppGbpRecirc(self, epgs[4], self.loop8, is_ext=True))

        epg_nat = epgs[3]
        recirc_nat = recircs[3]

        #
        # 4 end-points, 2 in the same subnet, 3 in the same BD
        #
        eps = []
        eps.append(
            VppGbpEndpoint(self, self.pg0, epgs[0], recircs[0], "10.0.0.1",
                           "11.0.0.1"))
        eps.append(
            VppGbpEndpoint(self, self.pg1, epgs[0], recircs[0], "10.0.0.2",
                           "11.0.0.2"))
        eps.append(
            VppGbpEndpoint(self, self.pg2, epgs[1], recircs[1], "10.0.1.1",
                           "11.0.0.3"))
        eps.append(
            VppGbpEndpoint(self, self.pg3, epgs[2], recircs[2], "10.0.2.1",
                           "11.0.0.4"))
        eps.append(
            VppGbpEndpoint(self,
                           self.pg0,
                           epgs[0],
                           recircs[0],
                           "2001:10::1",
                           "3001::1",
                           is_ip6=True))
        eps.append(
            VppGbpEndpoint(self,
                           self.pg1,
                           epgs[0],
                           recircs[0],
                           "2001:10::2",
                           "3001::2",
                           is_ip6=True))
        eps.append(
            VppGbpEndpoint(self,
                           self.pg2,
                           epgs[1],
                           recircs[1],
                           "2001:10:1::1",
                           "3001::3",
                           is_ip6=True))
        eps.append(
            VppGbpEndpoint(self,
                           self.pg3,
                           epgs[2],
                           recircs[2],
                           "2001:10:2::1",
                           "3001::4",
                           is_ip6=True))

        #
        # Config related to each of the EPGs
        #
        for epg in epgs:
            # IP config on the BVI interfaces
            if epg != epgs[1] and epg != epgs[4]:
                epg.bvi.set_table_ip4(epg.rd)
                epg.bvi.set_table_ip6(epg.rd)

                # The BVIs are NAT inside interfaces
                self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
                                                          is_inside=1,
                                                          is_add=1)
                self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
                                                  is_inside=1,
                                                  is_add=1)

            self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
                                                   epg.bvi_ip4_n, 32)
            self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
                                                   epg.bvi_ip6_n,
                                                   128,
                                                   is_ipv6=True)

            # EPG uplink interfaces in the BD
            epg.uplink.set_table_ip4(epg.rd)
            epg.uplink.set_table_ip6(epg.rd)
            self.vapi.sw_interface_set_l2_bridge(epg.uplink.sw_if_index,
                                                 epg.bd)

            # add the BD ARP termination entry for BVI IP
            self.vapi.bd_ip_mac_add_del(bd_id=epg.bd,
                                        mac=mactobinary(self.router_mac),
                                        ip=epg.bvi_ip4_n,
                                        is_ipv6=0,
                                        is_add=1)
            self.vapi.bd_ip_mac_add_del(bd_id=epg.bd,
                                        mac=mactobinary(self.router_mac),
                                        ip=epg.bvi_ip6_n,
                                        is_ipv6=1,
                                        is_add=1)

            # epg[1] shares the same BVI to epg[0]
            if epg != epgs[1] and epg != epgs[4]:
                # BVI in BD
                self.vapi.sw_interface_set_l2_bridge(epg.bvi.sw_if_index,
                                                     epg.bd,
                                                     bvi=1)
                # BVI L2 FIB entry
                self.vapi.l2fib_add_del(self.router_mac,
                                        epg.bd,
                                        epg.bvi.sw_if_index,
                                        is_add=1,
                                        bvi_mac=1)

            # EPG in VPP
            epg.add_vpp_config()

        for recirc in recircs:
            # EPG's ingress recirculation interface maps to its RD
            recirc.recirc.set_table_ip4(recirc.epg.rd)
            recirc.recirc.set_table_ip6(recirc.epg.rd)

            # in the bridge to allow DVR. L2 emulation to punt to L3
            self.vapi.sw_interface_set_l2_bridge(recirc.recirc.sw_if_index,
                                                 recirc.epg.bd)
            self.vapi.sw_interface_set_l2_emulation(recirc.recirc.sw_if_index)

            self.vapi.nat44_interface_add_del_feature(
                recirc.recirc.sw_if_index, is_inside=0, is_add=1)
            self.vapi.nat66_add_del_interface(recirc.recirc.sw_if_index,
                                              is_inside=0,
                                              is_add=1)

            recirc.add_vpp_config()

        ep_routes = []
        ep_arps = []
        for ep in eps:
            self.pg_enable_capture(self.pg_interfaces)
            self.pg_start()
            #
            # routes to the endpoints. We need these since there are no
            # adj-fibs due to the fact the the BVI address has /32 and
            # the subnet is not attached.
            #
            r = VppIpRoute(
                self,
                ep.ip,
                ep.ip_len,
                [VppRoutePath(ep.ip, ep.epg.bvi.sw_if_index, proto=ep.proto)],
                is_ip6=ep.is_ip6)
            r.add_vpp_config()
            ep_routes.append(r)

            #
            # ARP entries for the endpoints
            #
            a = VppNeighbor(self,
                            ep.epg.bvi.sw_if_index,
                            ep.itf.remote_mac,
                            ep.ip,
                            af=ep.af)
            a.add_vpp_config()
            ep_arps.append(a)

            # add each EP itf to the its BD
            self.vapi.sw_interface_set_l2_bridge(ep.itf.sw_if_index, ep.epg.bd)

            # add the BD ARP termination entry
            self.vapi.bd_ip_mac_add_del(bd_id=ep.epg.bd,
                                        mac=ep.bin_mac,
                                        ip=ep.ip_n,
                                        is_ipv6=0,
                                        is_add=1)

            # L2 FIB entry
            self.vapi.l2fib_add_del(ep.mac,
                                    ep.epg.bd,
                                    ep.itf.sw_if_index,
                                    is_add=1)

            # Add static mappings for each EP from the 10/8 to 11/8 network
            if ep.af == AF_INET:
                self.vapi.nat44_add_del_static_mapping(ep.ip_n,
                                                       ep.floating_ip_n,
                                                       vrf_id=0,
                                                       addr_only=1)
            else:
                self.vapi.nat66_add_del_static_mapping(ep.ip_n,
                                                       ep.floating_ip_n,
                                                       vrf_id=0)

            # VPP EP create ...
            ep.add_vpp_config()

            # ... results in a Gratuitous ARP/ND on the EPG's uplink
            rx = ep.epg.uplink.get_capture(1, timeout=0.2)

            if ep.is_ip6:
                self.assertTrue(rx[0].haslayer(ICMPv6ND_NA))
                self.assertEqual(rx[0][ICMPv6ND_NA].tgt, ep.ip)
            else:
                self.assertTrue(rx[0].haslayer(ARP))
                self.assertEqual(rx[0][ARP].psrc, ep.ip)
                self.assertEqual(rx[0][ARP].pdst, ep.ip)

            # add the BD ARP termination entry for floating IP
            self.vapi.bd_ip_mac_add_del(bd_id=epg_nat.bd,
                                        mac=ep.bin_mac,
                                        ip=ep.floating_ip_n,
                                        is_ipv6=ep.is_ip6,
                                        is_add=1)

            # floating IPs route via EPG recirc
            r = VppIpRoute(self,
                           ep.floating_ip,
                           ep.ip_len, [
                               VppRoutePath(ep.floating_ip,
                                            ep.recirc.recirc.sw_if_index,
                                            is_dvr=1,
                                            proto=ep.proto)
                           ],
                           table_id=20,
                           is_ip6=ep.is_ip6)
            r.add_vpp_config()
            ep_routes.append(r)

            # L2 FIB entries in the NAT EPG BD to bridge the packets from
            # the outside direct to the internal EPG
            self.vapi.l2fib_add_del(ep.mac,
                                    epg_nat.bd,
                                    ep.recirc.recirc.sw_if_index,
                                    is_add=1)

        #
        # ARP packets for unknown IP are flooded
        #
        pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
                   ARP(op="who-has",
                       hwdst="ff:ff:ff:ff:ff:ff",
                       hwsrc=self.pg0.remote_mac,
                       pdst=epgs[0].bvi_ip4,
                       psrc="10.0.0.88"))

        self.send_and_expect(self.pg0, [pkt_arp], self.pg0)

        #
        # ARP/ND packets get a response
        #
        pkt_arp = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
                   ARP(op="who-has",
                       hwdst="ff:ff:ff:ff:ff:ff",
                       hwsrc=self.pg0.remote_mac,
                       pdst=epgs[0].bvi_ip4,
                       psrc=eps[0].ip))

        self.send_and_expect(self.pg0, [pkt_arp], self.pg0)

        nsma = in6_getnsma(inet_pton(AF_INET6, eps[4].ip))
        d = inet_ntop(AF_INET6, nsma)
        pkt_nd = (Ether(dst=in6_getnsmac(nsma)) / IPv6(dst=d, src=eps[4].ip) /
                  ICMPv6ND_NS(tgt=epgs[0].bvi_ip6) /
                  ICMPv6NDOptSrcLLAddr(lladdr=self.pg0.remote_mac))
        self.send_and_expect(self.pg0, [pkt_nd], self.pg0)

        #
        # broadcast packets are flooded
        #
        pkt_bcast = (Ether(dst="ff:ff:ff:ff:ff:ff", src=self.pg0.remote_mac) /
                     IP(src=eps[0].ip, dst="232.1.1.1") /
                     UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))

        self.vapi.cli("clear trace")
        self.pg0.add_stream(pkt_bcast)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        rxd = eps[1].itf.get_capture(1)
        self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)
        rxd = epgs[0].uplink.get_capture(1)
        self.assertEqual(rxd[0][Ether].dst, pkt_bcast[Ether].dst)

        #
        # packets to non-local L3 destinations dropped
        #
        pkt_intra_epg_220_ip4 = (
            Ether(src=self.pg0.remote_mac, dst=self.router_mac) /
            IP(src=eps[0].ip, dst="10.0.0.99") / UDP(sport=1234, dport=1234) /
            Raw('\xa5' * 100))
        pkt_inter_epg_222_ip4 = (
            Ether(src=self.pg0.remote_mac, dst=self.router_mac) /
            IP(src=eps[0].ip, dst="10.0.1.99") / UDP(sport=1234, dport=1234) /
            Raw('\xa5' * 100))

        self.send_and_assert_no_replies(self.pg0, pkt_intra_epg_220_ip4 * 65)

        pkt_inter_epg_222_ip6 = (
            Ether(src=self.pg0.remote_mac, dst=self.router_mac) /
            IPv6(src=eps[4].ip, dst="2001:10::99") /
            UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))
        self.send_and_assert_no_replies(self.pg0, pkt_inter_epg_222_ip6 * 65)

        #
        # Add the subnet routes
        #
        s41 = VppGbpSubnet(self, 0, "10.0.0.0", 24)
        s42 = VppGbpSubnet(self, 0, "10.0.1.0", 24)
        s43 = VppGbpSubnet(self, 0, "10.0.2.0", 24)
        s41.add_vpp_config()
        s42.add_vpp_config()
        s43.add_vpp_config()
        s61 = VppGbpSubnet(self, 0, "2001:10::1", 64, is_ip6=True)
        s62 = VppGbpSubnet(self, 0, "2001:10:1::1", 64, is_ip6=True)
        s63 = VppGbpSubnet(self, 0, "2001:10:2::1", 64, is_ip6=True)
        s61.add_vpp_config()
        s62.add_vpp_config()
        s63.add_vpp_config()

        self.send_and_expect_bridged(self.pg0, pkt_intra_epg_220_ip4 * 65,
                                     self.pg4)
        self.send_and_expect_bridged(self.pg3, pkt_inter_epg_222_ip4 * 65,
                                     self.pg6)
        self.send_and_expect_bridged6(self.pg3, pkt_inter_epg_222_ip6 * 65,
                                      self.pg6)

        self.logger.info(self.vapi.cli("sh ip fib 11.0.0.2"))
        self.logger.info(self.vapi.cli("sh gbp endpoint-group"))
        self.logger.info(self.vapi.cli("sh gbp endpoint"))
        self.logger.info(self.vapi.cli("sh gbp recirc"))
        self.logger.info(self.vapi.cli("sh int"))
        self.logger.info(self.vapi.cli("sh int addr"))
        self.logger.info(self.vapi.cli("sh int feat loop6"))
        self.logger.info(self.vapi.cli("sh vlib graph ip4-gbp-src-classify"))
        self.logger.info(self.vapi.cli("sh int feat loop3"))

        #
        # Packet destined to unknown unicast is sent on the epg uplink ...
        #
        pkt_intra_epg_220_to_uplink = (
            Ether(src=self.pg0.remote_mac, dst="00:00:00:33:44:55") /
            IP(src=eps[0].ip, dst="10.0.0.99") / UDP(sport=1234, dport=1234) /
            Raw('\xa5' * 100))

        self.send_and_expect_bridged(self.pg0,
                                     pkt_intra_epg_220_to_uplink * 65,
                                     self.pg4)
        # ... and nowhere else
        self.pg1.get_capture(0, timeout=0.1)
        self.pg1.assert_nothing_captured(remark="Flood onto other VMS")

        pkt_intra_epg_221_to_uplink = (
            Ether(src=self.pg2.remote_mac, dst="00:00:00:33:44:66") /
            IP(src=eps[0].ip, dst="10.0.0.99") / UDP(sport=1234, dport=1234) /
            Raw('\xa5' * 100))

        self.send_and_expect_bridged(self.pg2,
                                     pkt_intra_epg_221_to_uplink * 65,
                                     self.pg5)

        #
        # Packets from the uplink are forwarded in the absence of a contract
        #
        pkt_intra_epg_220_from_uplink = (
            Ether(src="00:00:00:33:44:55", dst=self.pg0.remote_mac) /
            IP(src=eps[0].ip, dst="10.0.0.99") / UDP(sport=1234, dport=1234) /
            Raw('\xa5' * 100))

        self.send_and_expect_bridged(self.pg4,
                                     pkt_intra_epg_220_from_uplink * 65,
                                     self.pg0)

        #
        # in the absence of policy, endpoints in the same EPG
        # can communicate
        #
        pkt_intra_epg = (
            Ether(src=self.pg0.remote_mac, dst=self.pg1.remote_mac) /
            IP(src=eps[0].ip, dst=eps[1].ip) / UDP(sport=1234, dport=1234) /
            Raw('\xa5' * 100))

        self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)

        #
        # in the abscense of policy, endpoints in the different EPG
        # cannot communicate
        #
        pkt_inter_epg_220_to_221 = (
            Ether(src=self.pg0.remote_mac, dst=self.pg2.remote_mac) /
            IP(src=eps[0].ip, dst=eps[2].ip) / UDP(sport=1234, dport=1234) /
            Raw('\xa5' * 100))
        pkt_inter_epg_221_to_220 = (
            Ether(src=self.pg2.remote_mac, dst=self.pg0.remote_mac) /
            IP(src=eps[2].ip, dst=eps[0].ip) / UDP(sport=1234, dport=1234) /
            Raw('\xa5' * 100))
        pkt_inter_epg_220_to_222 = (
            Ether(src=self.pg0.remote_mac, dst=self.router_mac) /
            IP(src=eps[0].ip, dst=eps[3].ip) / UDP(sport=1234, dport=1234) /
            Raw('\xa5' * 100))

        self.send_and_assert_no_replies(self.pg0,
                                        pkt_inter_epg_220_to_221 * 65)
        self.send_and_assert_no_replies(self.pg0,
                                        pkt_inter_epg_220_to_222 * 65)

        #
        # A uni-directional contract from EPG 220 -> 221
        #
        c1 = VppGbpContract(self, 220, 221, 0)
        c1.add_vpp_config()

        self.send_and_expect_bridged(self.pg0, pkt_inter_epg_220_to_221 * 65,
                                     self.pg2)
        self.send_and_assert_no_replies(self.pg0,
                                        pkt_inter_epg_220_to_222 * 65)

        #
        # contract for the return direction
        #
        c2 = VppGbpContract(self, 221, 220, 0)
        c2.add_vpp_config()

        self.send_and_expect_bridged(self.pg0, pkt_inter_epg_220_to_221 * 65,
                                     self.pg2)
        self.send_and_expect_bridged(self.pg2, pkt_inter_epg_221_to_220 * 65,
                                     self.pg0)

        #
        # check that inter group is still disabled for the groups
        # not in the contract.
        #
        self.send_and_assert_no_replies(self.pg0,
                                        pkt_inter_epg_220_to_222 * 65)

        #
        # A uni-directional contract from EPG 220 -> 222 'L3 routed'
        #
        c3 = VppGbpContract(self, 220, 222, 0)
        c3.add_vpp_config()

        self.logger.info(self.vapi.cli("sh gbp contract"))

        self.send_and_expect_routed(self.pg0, pkt_inter_epg_220_to_222 * 65,
                                    self.pg3, self.router_mac)

        #
        # remove both contracts, traffic stops in both directions
        #
        c2.remove_vpp_config()
        c1.remove_vpp_config()
        c3.remove_vpp_config()

        self.send_and_assert_no_replies(self.pg2,
                                        pkt_inter_epg_221_to_220 * 65)
        self.send_and_assert_no_replies(self.pg0,
                                        pkt_inter_epg_220_to_221 * 65)
        self.send_and_expect_bridged(self.pg0, pkt_intra_epg * 65, self.pg1)

        #
        # EPs to the outside world
        #

        # in the EP's RD an external subnet via the NAT EPG's recirc
        se1 = VppGbpSubnet(self,
                           0,
                           "0.0.0.0",
                           0,
                           is_internal=False,
                           sw_if_index=recirc_nat.recirc.sw_if_index,
                           epg=epg_nat.epg)
        se1.add_vpp_config()
        se2 = VppGbpSubnet(self,
                           0,
                           "11.0.0.0",
                           8,
                           is_internal=False,
                           sw_if_index=recirc_nat.recirc.sw_if_index,
                           epg=epg_nat.epg)
        se2.add_vpp_config()
        se16 = VppGbpSubnet(self,
                            0,
                            "::",
                            0,
                            is_internal=False,
                            sw_if_index=recirc_nat.recirc.sw_if_index,
                            epg=epg_nat.epg,
                            is_ip6=True)
        se16.add_vpp_config()
        # in the NAT RD an external subnet via the NAT EPG's uplink
        se3 = VppGbpSubnet(self,
                           20,
                           "0.0.0.0",
                           0,
                           is_internal=False,
                           sw_if_index=epg_nat.uplink.sw_if_index,
                           epg=epg_nat.epg)
        se36 = VppGbpSubnet(self,
                            20,
                            "::",
                            0,
                            is_internal=False,
                            sw_if_index=epg_nat.uplink.sw_if_index,
                            epg=epg_nat.epg,
                            is_ip6=True)
        se4 = VppGbpSubnet(self,
                           20,
                           "11.0.0.0",
                           8,
                           is_internal=False,
                           sw_if_index=epg_nat.uplink.sw_if_index,
                           epg=epg_nat.epg)
        se3.add_vpp_config()
        se36.add_vpp_config()
        se4.add_vpp_config()

        self.logger.info(self.vapi.cli("sh ip fib 0.0.0.0/0"))
        self.logger.info(self.vapi.cli("sh ip fib 11.0.0.1"))
        self.logger.info(self.vapi.cli("sh ip6 fib ::/0"))
        self.logger.info(self.vapi.cli("sh ip6 fib %s" % eps[4].floating_ip))

        #
        # From an EP to an outside addess: IN2OUT
        #
        pkt_inter_epg_220_to_global = (
            Ether(src=self.pg0.remote_mac, dst=self.router_mac) /
            IP(src=eps[0].ip, dst="1.1.1.1") / UDP(sport=1234, dport=1234) /
            Raw('\xa5' * 100))

        # no policy yet
        self.send_and_assert_no_replies(self.pg0,
                                        pkt_inter_epg_220_to_global * 65)

        c4 = VppGbpContract(self, 220, 333, 0)
        c4.add_vpp_config()

        self.send_and_expect_natted(self.pg0, pkt_inter_epg_220_to_global * 65,
                                    self.pg7, eps[0].floating_ip)

        pkt_inter_epg_220_to_global = (
            Ether(src=self.pg0.remote_mac, dst=self.router_mac) /
            IPv6(src=eps[4].ip, dst="6001::1") / UDP(sport=1234, dport=1234) /
            Raw('\xa5' * 100))

        self.send_and_expect_natted6(self.pg0,
                                     pkt_inter_epg_220_to_global * 65,
                                     self.pg7, eps[4].floating_ip)

        #
        # From a global address to an EP: OUT2IN
        #
        pkt_inter_epg_220_from_global = (
            Ether(src=self.router_mac, dst=self.pg0.remote_mac) /
            IP(dst=eps[0].floating_ip, src="1.1.1.1") /
            UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))

        self.send_and_assert_no_replies(self.pg7,
                                        pkt_inter_epg_220_from_global * 65)

        c5 = VppGbpContract(self, 333, 220, 0)
        c5.add_vpp_config()

        self.send_and_expect_unnatted(self.pg7,
                                      pkt_inter_epg_220_from_global * 65,
                                      eps[0].itf, eps[0].ip)

        pkt_inter_epg_220_from_global = (
            Ether(src=self.router_mac, dst=self.pg0.remote_mac) /
            IPv6(dst=eps[4].floating_ip, src="6001::1") /
            UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))

        self.send_and_expect_unnatted6(self.pg7,
                                       pkt_inter_epg_220_from_global * 65,
                                       eps[4].itf, eps[4].ip)

        #
        # From a local VM to another local VM using resp. public addresses:
        #  IN2OUT2IN
        #
        pkt_intra_epg_220_global = (
            Ether(src=self.pg0.remote_mac, dst=self.router_mac) /
            IP(src=eps[0].ip, dst=eps[1].floating_ip) /
            UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))

        self.send_and_expect_double_natted(eps[0].itf,
                                           pkt_intra_epg_220_global * 65,
                                           eps[1].itf, eps[0].floating_ip,
                                           eps[1].ip)

        pkt_intra_epg_220_global = (
            Ether(src=self.pg4.remote_mac, dst=self.router_mac) /
            IPv6(src=eps[4].ip, dst=eps[5].floating_ip) /
            UDP(sport=1234, dport=1234) / Raw('\xa5' * 100))

        self.send_and_expect_double_natted6(eps[4].itf,
                                            pkt_intra_epg_220_global * 65,
                                            eps[5].itf, eps[4].floating_ip,
                                            eps[5].ip)

        #
        # cleanup
        #
        for ep in eps:
            # del static mappings for each EP from the 10/8 to 11/8 network
            if ep.af == AF_INET:
                self.vapi.nat44_add_del_static_mapping(ep.ip_n,
                                                       ep.floating_ip_n,
                                                       vrf_id=0,
                                                       addr_only=1,
                                                       is_add=0)
            else:
                self.vapi.nat66_add_del_static_mapping(ep.ip_n,
                                                       ep.floating_ip_n,
                                                       vrf_id=0,
                                                       is_add=0)

        for epg in epgs:
            # IP config on the BVI interfaces
            self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
                                                   epg.bvi_ip4_n,
                                                   32,
                                                   is_add=0)
            self.vapi.sw_interface_add_del_address(epg.bvi.sw_if_index,
                                                   epg.bvi_ip6_n,
                                                   128,
                                                   is_add=0,
                                                   is_ipv6=True)
            self.logger.info(self.vapi.cli("sh int addr"))

            epg.uplink.set_table_ip4(0)
            epg.uplink.set_table_ip6(0)

            if epg != epgs[0] and epg != epgs[3]:
                epg.bvi.set_table_ip4(0)
                epg.bvi.set_table_ip6(0)

                self.vapi.nat44_interface_add_del_feature(epg.bvi.sw_if_index,
                                                          is_inside=1,
                                                          is_add=0)
                self.vapi.nat66_add_del_interface(epg.bvi.sw_if_index,
                                                  is_inside=1,
                                                  is_add=0)

        for recirc in recircs:
            recirc.recirc.set_table_ip4(0)
            recirc.recirc.set_table_ip6(0)

            self.vapi.nat44_interface_add_del_feature(
                recirc.recirc.sw_if_index, is_inside=0, is_add=0)
            self.vapi.nat66_add_del_interface(recirc.recirc.sw_if_index,
                                              is_inside=0,
                                              is_add=0)
예제 #26
0
def kbsrp(pkt,
          channel=None,
          inter=0,
          count=0,
          iface=None,
          store=1,
          prn=None,
          lfilter=None,
          timeout=None,
          verbose=None,
          realtime=None):
    """
    Send and receive packets with KillerBee
    @param channel:  802.15.4 channel to transmit/receive on
    @param inter:    time to wait between tranmissions
    @param count:    number of packets to capture. 0 means infinity
    @param iface:    KillerBee interface to use, or KillerBee() class instance
    @param store:    wether to store sniffed packets or discard them
    @param prn:      function to apply to each packet. If something is returned,
                      it is displayed. Ex:
                      ex: prn = lambda x: x.summary()
    @param lfilter:  python function applied to each packet to determine
                      if further action may be done
                      ex: lfilter = lambda x: x.haslayer(Padding)
    @param timeout:  stop sniffing after a given time (default: None)
    @param verbose:  set verbosity level
    @param realtime: use packet's timestamp, bending time with realtime value
    """
    if verbose is None:
        verbose = conf.verb
    if channel == None:
        channel = conf.killerbee_channel
    if not isinstance(iface, KillerBee):
        if iface is not None:
            kb = KillerBee(device=iface)
        else:
            kb = KillerBee(device=conf.killerbee_device)
        kb.set_channel(channel)
    else:
        kb = iface

    # Make sure the packet has an FCS layer before TX
    if not pkt.haslayer(Dot15d4FCS):
        pkt /= Raw("\x00\x00")

    pkts_out = __kb_send(kb,
                         pkt,
                         inter=inter,
                         loop=0,
                         count=None,
                         verbose=verbose,
                         realtime=realtime)
    if verbose:
        print "\nSent %i packets." % pkts_out

    pkts_in = __kb_recv(kb,
                        count=count,
                        store=store,
                        prn=prn,
                        lfilter=lfilter,
                        verbose=verbose,
                        timeout=timeout)
    if verbose:
        print "\nReceived %i packets." % len(pkts_in)
    return plist.PacketList(pkts_in, 'Results')
예제 #27
0
    def create_stream(self, src_ip_if, dst_ip_if, reverse, packet_sizes,
                      is_ip6, expect_blocked, expect_established,
                      add_extension_header, icmp_stateful=False):
        pkts = []
        rules = []
        permit_rules = []
        permit_and_reflect_rules = []
        total_packet_count = 8
        for i in range(0, total_packet_count):
            modulo = (i//2) % 2
            icmp_type_delta = i % 2
            icmp_code = i
            is_udp_packet = (modulo == 0)
            if is_udp_packet and icmp_stateful:
                continue
            is_reflectable_icmp = (icmp_stateful and icmp_type_delta == 0 and
                                   not is_udp_packet)
            is_reflected_icmp = is_reflectable_icmp and expect_established
            can_reflect_this_packet = is_udp_packet or is_reflectable_icmp
            is_permit = i % 2
            remote_dst_index = i % len(dst_ip_if.remote_hosts)
            remote_dst_host = dst_ip_if.remote_hosts[remote_dst_index]
            if is_permit == 1:
                info = self.create_packet_info(src_ip_if, dst_ip_if)
                payload = self.info_to_payload(info)
            else:
                to_be_blocked = False
                if (expect_blocked and not expect_established):
                    to_be_blocked = True
                if (not can_reflect_this_packet):
                    to_be_blocked = True
                if to_be_blocked:
                    payload = "to be blocked"
                else:
                    info = self.create_packet_info(src_ip_if, dst_ip_if)
                    payload = self.info_to_payload(info)
            if reverse:
                dst_mac = 'de:ad:00:00:00:00'
                src_mac = remote_dst_host._mac
                dst_ip6 = src_ip_if.remote_ip6
                src_ip6 = remote_dst_host.ip6
                dst_ip4 = src_ip_if.remote_ip4
                src_ip4 = remote_dst_host.ip4
                dst_l4 = 1234 + i
                src_l4 = 4321 + i
            else:
                dst_mac = src_ip_if.local_mac
                src_mac = src_ip_if.remote_mac
                src_ip6 = src_ip_if.remote_ip6
                dst_ip6 = remote_dst_host.ip6
                src_ip4 = src_ip_if.remote_ip4
                dst_ip4 = remote_dst_host.ip4
                src_l4 = 1234 + i
                dst_l4 = 4321 + i
            if is_reflected_icmp:
                icmp_type_delta = 1

            # default ULP should be something we do not use in tests
            ulp_l4 = TCP(sport=src_l4, dport=dst_l4)
            # potentially a chain of protocols leading to ULP
            ulp = ulp_l4

            if is_udp_packet:
                if is_ip6:
                    ulp_l4 = UDP(sport=src_l4, dport=dst_l4)
                    if add_extension_header:
                        # prepend some extension headers
                        ulp = (IPv6ExtHdrRouting() / IPv6ExtHdrRouting() /
                               IPv6ExtHdrFragment(offset=0, m=1) / ulp_l4)
                        # uncomment below to test invalid ones
                        # ulp = IPv6ExtHdrRouting(len = 200) / ulp_l4
                    else:
                        ulp = ulp_l4
                    p = (Ether(dst=dst_mac, src=src_mac) /
                         IPv6(src=src_ip6, dst=dst_ip6) /
                         ulp /
                         Raw(payload))
                else:
                    ulp_l4 = UDP(sport=src_l4, dport=dst_l4)
                    # IPv4 does not allow extension headers,
                    # but we rather make it a first fragment
                    flags = 1 if add_extension_header else 0
                    ulp = ulp_l4
                    p = (Ether(dst=dst_mac, src=src_mac) /
                         IP(src=src_ip4, dst=dst_ip4, frag=0, flags=flags) /
                         ulp /
                         Raw(payload))
            elif modulo == 1:
                if is_ip6:
                    ulp_l4 = ICMPv6Unknown(type=128 + icmp_type_delta,
                                           code=icmp_code)
                    ulp = ulp_l4
                    p = (Ether(dst=dst_mac, src=src_mac) /
                         IPv6(src=src_ip6, dst=dst_ip6) /
                         ulp /
                         Raw(payload))
                else:
                    ulp_l4 = ICMP(type=8 - 8*icmp_type_delta, code=icmp_code)
                    ulp = ulp_l4
                    p = (Ether(dst=dst_mac, src=src_mac) /
                         IP(src=src_ip4, dst=dst_ip4) /
                         ulp /
                         Raw(payload))

            if i % 2 == 1:
                info.data = p.copy()
            size = packet_sizes[(i // 2) % len(packet_sizes)]
            self.extend_packet(p, size)
            pkts.append(p)

            rule_family = AF_INET6 if p.haslayer(IPv6) else AF_INET
            rule_prefix_len = 128 if p.haslayer(IPv6) else 32
            rule_l3_layer = IPv6 if p.haslayer(IPv6) else IP

            if p.haslayer(UDP):
                rule_l4_sport = p[UDP].sport
                rule_l4_dport = p[UDP].dport
            else:
                if p.haslayer(ICMP):
                    rule_l4_sport = p[ICMP].type
                    rule_l4_dport = p[ICMP].code
                else:
                    rule_l4_sport = p[ICMPv6Unknown].type
                    rule_l4_dport = p[ICMPv6Unknown].code
            if p.haslayer(IPv6):
                rule_l4_proto = ulp_l4.overload_fields[IPv6]['nh']
            else:
                rule_l4_proto = p[IP].proto

            new_rule = {
                        'is_permit': is_permit,
                        'is_ipv6': p.haslayer(IPv6),
                        'src_ip_addr': inet_pton(rule_family,
                                                 p[rule_l3_layer].src),
                        'src_ip_prefix_len': rule_prefix_len,
                        'dst_ip_addr': inet_pton(rule_family,
                                                 p[rule_l3_layer].dst),
                        'dst_ip_prefix_len': rule_prefix_len,
                        'srcport_or_icmptype_first': rule_l4_sport,
                        'srcport_or_icmptype_last': rule_l4_sport,
                        'dstport_or_icmpcode_first': rule_l4_dport,
                        'dstport_or_icmpcode_last': rule_l4_dport,
                        'proto': rule_l4_proto,
                       }
            rules.append(new_rule)
            new_rule_permit = new_rule.copy()
            new_rule_permit['is_permit'] = 1
            permit_rules.append(new_rule_permit)

            new_rule_permit_and_reflect = new_rule.copy()
            if can_reflect_this_packet:
                new_rule_permit_and_reflect['is_permit'] = 2
            else:
                new_rule_permit_and_reflect['is_permit'] = is_permit

            permit_and_reflect_rules.append(new_rule_permit_and_reflect)
            self.logger.info("create_stream pkt#%d: %s" % (i, payload))

        return {'stream': pkts,
                'rules': rules,
                'permit_rules': permit_rules,
                'permit_and_reflect_rules': permit_and_reflect_rules}
예제 #28
0
def kbdecrypt(pkt, key=None, verbose=None, doMicCheck=False):
    """Decrypt Zigbee frames using AES CCM* with 32-bit MIC"""
    if verbose is None:
        verbose = conf.verb
    if key == None:
        if conf.killerbee_nkey == None:
            log_killerbee.error(
                "Cannot find decryption key. (Set conf.killerbee_nkey)")
            return None
        key = conf.killerbee_nkey
    if len(key) != 16:
        log_killerbee.error(
            "Invalid decryption key, must be a 16 byte string.")
        return None
    elif not pkt.haslayer(ZigbeeSecurityHeader) or not pkt.haslayer(ZigbeeNWK):
        log_killerbee.error(
            "Cannot decrypt frame without a ZigbeeSecurityHeader.")
        return None
    try:
        import zigbee_crypt
    except ImportError:
        log_killerbee.error(
            "Could not import zigbee_crypt extension, cryptographic functionality is not available."
        )
        return None

    #TODO: Investigate and issue a different fix:
    # https://code.google.com/p/killerbee/issues/detail?id=30
    # This function destroys the packet, therefore work on a copy - @cutaway
    pkt = pkt.copy()  #this is hack to fix the below line
    pkt.nwk_seclevel = 5  #the issue appears to be when this is set
    # Now recreate 'pkt' by rebuilding the raw data and creating a new scapy Packet, because
    # scapy splits the data/mic according to the nwk_seclevel in the ZigbeeSecurityHeader when
    # the scapy Packet is created.  The value of nwk_seclevel in the ZigbeeSecurityHeader does
    # not have to be accurate in the transmitted frame: the Zigbee NWK standard states that
    # the nwk_seclevel should be overwritten in the received frame with the value that is being
    # used by all nodes in the Zigbee network - this is to ensure that unencrypted frames can't be
    # maliciously injected.  i.e. the receiver shouldn't trust the received nwk_seclevel.
    newpkt = pkt.build()
    if pkt.haslayer(Dot15d4FCS): pkt = Dot15d4FCS(newpkt)
    else: pkt = Dot15d4(newpkt)

    #mic = struct.unpack(">I", f['mic'])
    mic = pkt.mic

    f = pkt.getlayer(ZigbeeSecurityHeader).fields
    encrypted = f['data']

    sec_ctrl_byte = str(pkt.getlayer(ZigbeeSecurityHeader))[0]

    # Bug fix thanks to cutaway (https://code.google.com/p/killerbee/issues/detail?id=25):
    #nonce = struct.pack('L',f['ext_source'])+struct.pack('I',f['fc']) + sec_ctrl_byte
    nonce = struct.pack('L', f['source']) + struct.pack(
        'I', f['fc']) + sec_ctrl_byte

    #nonce = "" # build the nonce
    #nonce += struct.pack(">Q", f['ext_source'])
    #nonce += struct.pack(">I", f['fc'])
    #fc = (f['reserved1'] << 6) | (f['extended_nonce'] << 5) | (f['key_type'] << 3) | f['reserved2']
    #nonce += chr(fc | 0x05)

    if verbose > 2:
        print "Decrypt Details:"
        print "\tKey:            " + key.encode('hex')
        print "\tNonce:          " + nonce.encode('hex')
        print "\tMic:            " + mic.encode('hex')
        print "\tEncrypted Data: " + encrypted.encode('hex')

    # For zigbeeData, we need the entire zigbee packet, minus the encrypted data and mic (4 bytes).
    # So calculate an amount to crop, equal to the size of the encrypted data and mic.  Note that
    # if there was an FCS, scapy will have already stripped it, so it will not returned by the
    # do_build() call below (and hence doesn't need to be taken into account in crop_size).
    crop_size = 4 + len(pkt.getlayer(ZigbeeSecurityHeader).fields['data'])

    # the Security Control Field flags have to be adjusted before this is calculated, so we store their original values so we can reset them later
    #reserved2 = pkt.getlayer(ZigbeeSecurityHeader).fields['reserved2']
    #pkt.getlayer(ZigbeeSecurityHeader).fields['reserved2'] = (pkt.getlayer(ZigbeeSecurityHeader).fields['reserved2'] | 0x05)
    zigbeeData = pkt.getlayer(ZigbeeNWK).do_build()
    zigbeeData = zigbeeData[:-crop_size]
    #pkt.getlayer(ZigbeeSecurityHeader).fields['reserved2'] = reserved2

    (payload, micCheck) = zigbee_crypt.decrypt_ccm(key, nonce, mic, encrypted,
                                                   zigbeeData)

    if verbose > 2:
        print "\tDecrypted Data: " + payload.encode('hex')

    frametype = pkt.getlayer(ZigbeeNWK).fields['frametype']
    if frametype == 0 and micCheck == 1:
        payload = ZigbeeAppDataPayload(payload)
    elif frametype == 1 and micCheck == 1:
        payload = ZigbeeNWKCommandPayload(payload)
    else:
        payload = Raw(payload)

    if doMicCheck == False:
        return payload
    else:
        if micCheck == 1: return (payload, True)
        else: return (payload, False)
예제 #29
0
from scapy.layers.inet import Ether
from scapy.layers.inet import IP
from scapy.layers.inet import UDP
from scapy.packet import Raw
from scapy.sendrecv import sendp

DESTINATION_MAC_ADDR = "11:22:33:44:55:66"
SOURCE_MAC_ADDR = "aa:bb:cc:dd:ee:ff"
DESTINATION_IP_ADDR = "192.168.0.100"
SOURCE_IP_ADDR = "192.168.0.123"
DESTINATION_PORT = 8080
SOURCE_PORT = 10430
RAW_DATA = "68656c6c6f20776f726c64"  # hello world
NETWORK_INTERFACE = "Wi-Fi"

ether_frame = Ether(src=SOURCE_MAC_ADDR, dst=DESTINATION_MAC_ADDR)
ip_setting = IP(src=SOURCE_IP_ADDR, dst=DESTINATION_IP_ADDR)
udp_setting = UDP(dport=DESTINATION_PORT, sport=SOURCE_PORT)
udp_data = Raw(load=bytes.fromhex(RAW_DATA))
packet = ether_frame / ip_setting / udp_setting / udp_data

sendp(packet, iface=NETWORK_INTERFACE)
예제 #30
0
    def test_punt(self):
        """ Excpetion Path testing """

        #
        # Using the test CLI we will hook in a exception path to
        # send ACL deny packets out of pg0 and pg1.
        # the ACL is src,dst = 1.1.1.1,1.1.1.2
        #
        ip_1_1_1_2 = VppIpRoute(self, "1.1.1.2", 32,
                                [VppRoutePath(self.pg3.remote_ip4,
                                              self.pg3.sw_if_index)])
        ip_1_1_1_2.add_vpp_config()
        ip_1_2 = VppIpRoute(self, "1::2", 128,
                            [VppRoutePath(self.pg3.remote_ip6,
                                          self.pg3.sw_if_index,
                                          proto=DpoProto.DPO_PROTO_IP6)],
                            is_ip6=1)
        ip_1_2.add_vpp_config()

        p4 = (Ether(src=self.pg2.remote_mac,
                    dst=self.pg2.local_mac) /
              IP(src="1.1.1.1", dst="1.1.1.2") /
              UDP(sport=1234, dport=1234) /
              Raw('\xa5' * 100))
        p6 = (Ether(src=self.pg2.remote_mac,
                    dst=self.pg2.local_mac) /
              IPv6(src="1::1", dst="1::2") /
              UDP(sport=1234, dport=1234) /
              Raw('\xa5' * 100))
        self.send_and_expect(self.pg2, p4*1, self.pg3)
        self.send_and_expect(self.pg2, p6*1, self.pg3)

        #
        # apply the punting features
        #
        self.vapi.cli("test punt pg2")

        #
        # pkts now dropped
        #
        self.send_and_assert_no_replies(self.pg2, p4*NUM_PKTS)
        self.send_and_assert_no_replies(self.pg2, p6*NUM_PKTS)

        #
        # Check state:
        #  1 - node error counters
        #  2 - per-reason counters
        #    2, 3 are the index of the assigned punt reason
        #
        stats = self.statistics.get_counter(
            "/err/punt-dispatch/No registrations")
        self.assertEqual(stats, 2*NUM_PKTS)

        stats = self.statistics.get_counter("/net/punt")
        self.assertEqual(stats[0][7]['packets'], NUM_PKTS)
        self.assertEqual(stats[0][8]['packets'], NUM_PKTS)

        #
        # use the test CLI to test a client that punts exception
        # packets out of pg0
        #
        self.vapi.cli("test punt pg0 %s" % self.pg0.remote_ip4)
        self.vapi.cli("test punt pg0 %s" % self.pg0.remote_ip6)

        rx4s = self.send_and_expect(self.pg2, p4*NUM_PKTS, self.pg0)
        rx6s = self.send_and_expect(self.pg2, p6*NUM_PKTS, self.pg0)

        #
        # check the packets come out IP unmodified but destined to pg0 host
        #
        for rx in rx4s:
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(p4[IP].dst, rx[IP].dst)
            self.assertEqual(p4[IP].ttl, rx[IP].ttl)
        for rx in rx6s:
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
            self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)

        stats = self.statistics.get_counter("/net/punt")
        self.assertEqual(stats[0][7]['packets'], 2*NUM_PKTS)
        self.assertEqual(stats[0][8]['packets'], 2*NUM_PKTS)

        #
        # add another registration for the same reason to send packets
        # out of pg1
        #
        self.vapi.cli("test punt pg1 %s" % self.pg1.remote_ip4)
        self.vapi.cli("test punt pg1 %s" % self.pg1.remote_ip6)

        self.vapi.cli("clear trace")
        self.pg2.add_stream(p4 * NUM_PKTS)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        rxd = self.pg0.get_capture(NUM_PKTS)
        for rx in rxd:
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(p4[IP].dst, rx[IP].dst)
            self.assertEqual(p4[IP].ttl, rx[IP].ttl)
        rxd = self.pg1.get_capture(NUM_PKTS)
        for rx in rxd:
            self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
            self.assertEqual(rx[Ether].src, self.pg1.local_mac)
            self.assertEqual(p4[IP].dst, rx[IP].dst)
            self.assertEqual(p4[IP].ttl, rx[IP].ttl)

        self.vapi.cli("clear trace")
        self.pg2.add_stream(p6 * NUM_PKTS)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        rxd = self.pg0.get_capture(NUM_PKTS)
        for rx in rxd:
            self.assertEqual(rx[Ether].dst, self.pg0.remote_mac)
            self.assertEqual(rx[Ether].src, self.pg0.local_mac)
            self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
            self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)
        rxd = self.pg1.get_capture(NUM_PKTS)
        for rx in rxd:
            self.assertEqual(rx[Ether].dst, self.pg1.remote_mac)
            self.assertEqual(rx[Ether].src, self.pg1.local_mac)
            self.assertEqual(p6[IPv6].dst, rx[IPv6].dst)
            self.assertEqual(p6[IPv6].hlim, rx[IPv6].hlim)

        stats = self.statistics.get_counter("/net/punt")
        self.assertEqual(stats[0][7]['packets'], 3*NUM_PKTS)
        self.assertEqual(stats[0][8]['packets'], 3*NUM_PKTS)

        self.logger.info(self.vapi.cli("show vlib graph punt-dispatch"))
        self.logger.info(self.vapi.cli("show punt client"))
        self.logger.info(self.vapi.cli("show punt reason"))
        self.logger.info(self.vapi.cli("show punt stats"))
        self.logger.info(self.vapi.cli("show punt db"))