Beispiel #1
0
 def _create_test_dhcp_request_packet(self):
     option_list = []
     bin_server = addrconv.ipv4.text_to_bin('192.168.1.1')
     option_list.append(
         dhcp.option(tag=dhcp.DHCP_SERVER_IDENTIFIER_OPT, value=bin_server))
     option_list.append(
         dhcp.option(tag=dhcp.DHCP_MESSAGE_TYPE_OPT, value=b'\x03'))
     options = dhcp.options(option_list=option_list)
     ret_pkt = packet.Packet()
     ret_pkt.add_protocol(
         ethernet.ethernet(dst="ff:ff:ff:ff:ff:ff",
                           src=self.port_info['mac_address']))
     ret_pkt.add_protocol(
         ipv4.ipv4(dst="255.255.255.255",
                   src="0.0.0.0",
                   proto=inet.IPPROTO_UDP))
     ret_pkt.add_protocol(
         udp.udp(src_port=constants.DHCP_CLIENT_PORT,
                 dst_port=constants.DHCP_RESPONSE_PORT))
     ret_pkt.add_protocol(
         dhcp.dhcp(op=dhcp.DHCP_BOOT_REQUEST,
                   chaddr=self.port_info['mac_address'],
                   siaddr='0.0.0.0',
                   xid=3454038351,
                   options=options))
     return ret_pkt
Beispiel #2
0
    def _create_test_dhcp6_packet(self, zero_time=False):
        ret_pkt = packet.Packet()
        ret_pkt.add_protocol(
            ethernet.ethernet(
                ethertype=ether_types.ETH_TYPE_IPV6,
                dst='33:33:00:01:00:02',
                src=self.port_info['mac_address']))
        ret_pkt.add_protocol(
            ipv6.ipv6(
                src='fe80::f816:3eff:fe60:714b',
                dst='ff02::1:2',
                nxt=inet.IPPROTO_UDP))
        ret_pkt.add_protocol(
            udp.udp(
                src_port=constants.DHCPV6_RESPONSE_PORT,
                dst_port=constants.DHCPV6_CLIENT_PORT))

        options = [dhcp6.option(
            code=1,
            data=b"\x00\x01\x00\x01",
            length=4)]
        if zero_time:
            options.append(dhcp6.option(
                code=3,
                data=b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
                length=12))
        else:
            options.append(dhcp6.option(
                code=3,
                data=b"\x01\x02\x03\x04\x05\x06\x07\x08\x0a\x0b\x0c\x0d",
                length=12))
        ret_pkt.add_protocol(dhcp6.dhcp6(
            dhcp6.DHCPV6_REQUEST, dhcp6.options(option_list=options)))
        return ret_pkt
Beispiel #3
0
    def test_serialize(self):
        src_port = 6431
        dst_port = 8080
        total_length = 0
        csum = 0

        src_ip = '192.168.10.1'
        dst_ip = '192.168.100.1'
        prev = ipv4(4, 5, 0, 0, 0, 0, 0, 64, inet.IPPROTO_UDP, 0, src_ip,
                    dst_ip)

        u = udp(src_port, dst_port, total_length, csum)
        buf = u.serialize(bytearray(), prev)
        res = struct.unpack(udp._PACK_STR, buf)

        eq_(res[0], src_port)
        eq_(res[1], dst_port)
        eq_(res[2], struct.calcsize(udp._PACK_STR))

        # checksum
        ph = struct.pack('!4s4sBBH', addrconv.ipv4.text_to_bin(src_ip),
                         addrconv.ipv4.text_to_bin(dst_ip), 0, 17, res[2])
        d = ph + buf + bytearray()
        s = packet_utils.checksum(d)
        eq_(0, s)
Beispiel #4
0
    def test_serialize(self):
        pkt = packet.Packet()

        eth_pkt = ethernet.ethernet('b0:a8:6e:18:b8:08', '64:87:88:e9:cb:c8')
        pkt.add_protocol(eth_pkt)

        ip_pkt = ipv4.ipv4(src='172.28.3.1',
                           dst='172.28.3.2',
                           tos=192,
                           identification=26697,
                           proto=inet.IPPROTO_UDP)
        pkt.add_protocol(ip_pkt)

        udp_pkt = udp.udp(49152, 3784)
        pkt.add_protocol(udp_pkt)

        bfd_pkt = bfd.bfd(ver=1,
                          diag=bfd.BFD_DIAG_CTRL_DETECT_TIME_EXPIRED,
                          state=bfd.BFD_STATE_UP,
                          detect_mult=3,
                          my_discr=6,
                          your_discr=7,
                          desired_min_tx_interval=60000,
                          required_min_rx_interval=60000,
                          required_min_echo_rx_interval=0)
        pkt.add_protocol(bfd_pkt)

        eq_(len(pkt.protocols), 4)

        pkt.serialize()
        eq_(pkt.data, self.data)
Beispiel #5
0
    def test_default_args(self):
        prev = ipv4(proto=inet.IPPROTO_UDP)
        u = udp()
        buf = u.serialize(bytearray(), prev)
        res = struct.unpack(udp._PACK_STR, buf)

        eq_(res[0], 1)
        eq_(res[1], 1)
        eq_(res[2], udp._MIN_LEN)
Beispiel #6
0
    def bfd_packet(src_mac,
                   dst_mac,
                   src_ip,
                   dst_ip,
                   ipv4_id,
                   src_port,
                   dst_port,
                   diag=0,
                   state=0,
                   flags=0,
                   detect_mult=0,
                   my_discr=0,
                   your_discr=0,
                   desired_min_tx_interval=0,
                   required_min_rx_interval=0,
                   required_min_echo_rx_interval=0,
                   auth_cls=None):
        """
        Generate BFD packet with Ethernet/IPv4/UDP encapsulated.
        """
        # Generate ethernet header first.
        pkt = packet.Packet()
        eth_pkt = ethernet.ethernet(dst_mac, src_mac, ETH_TYPE_IP)
        pkt.add_protocol(eth_pkt)

        # IPv4 encapsulation
        # set ToS to 192 (Network control/CS6)
        # set TTL to 255 (RFC5881 Section 5.)
        ipv4_pkt = ipv4.ipv4(proto=inet.IPPROTO_UDP,
                             src=src_ip,
                             dst=dst_ip,
                             tos=192,
                             identification=ipv4_id,
                             ttl=255)
        pkt.add_protocol(ipv4_pkt)

        # UDP encapsulation
        udp_pkt = udp.udp(src_port=src_port, dst_port=dst_port)
        pkt.add_protocol(udp_pkt)

        # BFD payload
        bfd_pkt = bfd.bfd(
            ver=1,
            diag=diag,
            state=state,
            flags=flags,
            detect_mult=detect_mult,
            my_discr=my_discr,
            your_discr=your_discr,
            desired_min_tx_interval=desired_min_tx_interval,
            required_min_rx_interval=required_min_rx_interval,
            required_min_echo_rx_interval=required_min_echo_rx_interval,
            auth_cls=auth_cls)
        pkt.add_protocol(bfd_pkt)

        pkt.serialize()
        return pkt.data
Beispiel #7
0
    def test_reply_ttl_invalid_message_with_rate_limit(self):
        pkt = packet.Packet()
        pkt.add_protocol(ethernet.ethernet(dst='aa:bb:cc:dd:ee:ff'))
        pkt.add_protocol(ipv4.ipv4(proto=in_proto.IPPROTO_UDP))
        pkt.add_protocol(udp.udp())
        pkt.serialize()

        lswitch = l2.LogicalSwitch(
            id='lswitch1',
            topic='topic1',
            unique_key=9,
            version=1,
        )
        self.app.db_store.update(lswitch)

        lrouter = l3.LogicalRouter(
            id='lrouter1',
            topic='topic1',
            version=1,
            unique_key=22,
            ports=[
                l3.LogicalRouterPort(
                    id='lrouter1-port1',
                    unique_key=55,
                    topic='topic1',
                    mac='aa:bb:cc:dd:ee:ff',
                    network='10.0.0.1/24',
                    lswitch='lswitch1',
                ),
            ],
        )
        self.app.db_store.update(lrouter)

        event = ofp_event.EventOFPMsgBase(msg=ofproto_parser.OFPPacketIn(
            datapath=mock.Mock(),
            reason=self.app.ofproto.OFPR_INVALID_TTL,
            match=ofproto_parser.OFPMatch(
                metadata=lswitch.unique_key,
                reg5=lrouter.unique_key,
            ),
            data=pkt.data,
        ))

        with mock.patch("dragonflow.controller.common."
                        "icmp_error_generator.generate") as icmp_error:
            for _ in range(self.app.conf.router_ttl_invalid_max_rate * 2):
                self.app.packet_in_handler(event)

            self.assertEqual(self.app.conf.router_ttl_invalid_max_rate,
                             icmp_error.call_count)
            icmp_error.assert_called_with(icmp.ICMP_TIME_EXCEEDED,
                                          icmp.ICMP_TTL_EXPIRED_CODE, mock.ANY,
                                          "10.0.0.1", mock.ANY)
Beispiel #8
0
    def get_ret_packet(self, packet_in, port_info, req_type):
        ip_info = self.get_port_ip(port_info,
                                   ip_version=constants.IP_VERSION_6)
        if not ip_info:
            return
        gateway_ip = ip_info['gateway_ip']
        mac = port_info['mac_address']

        header_eth = packet_in.get_protocol(ethernet.ethernet)
        header_ipv6 = packet_in.get_protocol(ipv6.ipv6)
        header_dhcp = packet_in.get_protocol(dhcp6.dhcp6)

        if req_type == 'CONFIRM':
            options = self.get_reply_dhcp_options(
                mac,
                message="all addresses still on link",
                req_options=header_dhcp.options.option_list)
        if req_type == 'RELEASE':
            options = self.get_reply_dhcp_options(
                mac,
                message="release received",
                req_options=header_dhcp.options.option_list)
        else:
            options = self.get_dhcp_options(mac, ip_info,
                                            header_dhcp.options.option_list,
                                            req_type)

        ret_pkt = packet.Packet()
        ret_pkt.add_protocol(
            ethernet.ethernet(ethertype=header_eth.ethertype,
                              dst=header_eth.src,
                              src=self.hw_addr))
        ret_pkt.add_protocol(
            ipv6.ipv6(src=gateway_ip,
                      dst=header_ipv6.src,
                      nxt=inet.IPPROTO_UDP))
        ret_pkt.add_protocol(
            udp.udp(src_port=constants.DHCPV6_RESPONSE_PORT,
                    dst_port=constants.DHCPV6_CLIENT_PORT))

        ret_type = self.get_ret_type(req_type)

        ret_pkt.add_protocol(
            dhcp6.dhcp6(ret_type,
                        options,
                        transaction_id=header_dhcp.transaction_id))

        return ret_pkt
Beispiel #9
0
    def _create_dhcp_response(self, packet, dhcp_request, response_type, lport,
                              dhcp_port):
        pkt_ipv4 = packet.get_protocol(ipv4.ipv4)
        pkt_ethernet = packet.get_protocol(ethernet.ethernet)

        try:
            subnet = lport.subnets[0]
        except IndexError:
            LOG.warning("No subnet found for port %s", lport.id)
            return

        dhcp_server_address = self._dhcp_ip_by_subnet.get(subnet.id)
        if not dhcp_server_address:
            LOG.warning("Could not find DHCP server address for subnet %s",
                        subnet.id)
            return

        option_list = self._build_dhcp_options(dhcp_request, response_type,
                                               lport, subnet,
                                               dhcp_server_address)

        options = dhcp.options(option_list=option_list)

        dhcp_response = os_ken_packet.Packet()
        dhcp_response.add_protocol(
            ethernet.ethernet(ethertype=ether.ETH_TYPE_IP,
                              dst=pkt_ethernet.src,
                              src=dhcp_port.mac))
        dhcp_response.add_protocol(
            ipv4.ipv4(dst=pkt_ipv4.src,
                      src=dhcp_server_address,
                      proto=pkt_ipv4.proto))
        dhcp_response.add_protocol(
            udp.udp(src_port=const.DHCP_SERVER_PORT,
                    dst_port=const.DHCP_CLIENT_PORT))

        siaddr = lport.dhcp_params.siaddr or dhcp_server_address

        dhcp_response.add_protocol(
            dhcp.dhcp(op=dhcp.DHCP_BOOT_REPLY,
                      chaddr=pkt_ethernet.src,
                      siaddr=siaddr,
                      boot_file=dhcp_request.boot_file,
                      yiaddr=lport.ip,
                      xid=dhcp_request.xid,
                      options=options))
        return dhcp_response
Beispiel #10
0
    def get_ret_packet(self, packet_in, port_info, is_ack=False):
        ip_info = self.get_port_ip(port_info,
                                   ip_version=constants.IP_VERSION_4)
        if not ip_info:
            return
        ip_addr = ip_info['ip_address']
        gateway_ip = ip_info['gateway_ip']

        options = self.get_dhcp_options(port_info, is_ack)
        if is_ack:
            fqdn = 'host-%s' % ip_addr.replace('.', '-').replace(':', '-')
            if cfg.CONF.dns_domain:
                fqdn = '%s.%s' % (fqdn, cfg.CONF.dns_domain)
            domain_name_bin = struct.pack('!%ds' % len(fqdn),
                                          bytes(str(fqdn).encode()))
            options.option_list.append(
                dhcp.option(tag=dhcp.DHCP_HOST_NAME_OPT,
                            value=domain_name_bin))

        header_eth = packet_in.get_protocol(ethernet.ethernet)
        header_ipv4 = packet_in.get_protocol(ipv4.ipv4)
        header_dhcp = packet_in.get_protocol(dhcp.dhcp)

        ret_pkt = packet.Packet()
        ret_pkt.add_protocol(
            ethernet.ethernet(ethertype=header_eth.ethertype,
                              dst=header_eth.src,
                              src=self.hw_addr))
        ret_pkt.add_protocol(
            ipv4.ipv4(dst=header_ipv4.dst,
                      src=gateway_ip,
                      proto=header_ipv4.proto))
        ret_pkt.add_protocol(
            udp.udp(src_port=constants.DHCP_RESPONSE_PORT,
                    dst_port=constants.DHCP_CLIENT_PORT))
        ret_pkt.add_protocol(
            dhcp.dhcp(op=dhcp.DHCP_BOOT_REPLY,
                      chaddr=header_eth.src,
                      siaddr=gateway_ip,
                      boot_file=header_dhcp.boot_file,
                      yiaddr=ip_addr,
                      xid=header_dhcp.xid,
                      options=options))
        return ret_pkt
Beispiel #11
0
    def test_reply_icmp_unreachable_with_rate_limit(self):
        pkt = packet.Packet()
        pkt.add_protocol(ethernet.ethernet(dst='aa:bb:cc:dd:ee:ff'))
        pkt.add_protocol(ipv4.ipv4(dst='10.0.0.1', proto=in_proto.IPPROTO_UDP))
        pkt.add_protocol(udp.udp())
        pkt.serialize()

        lrouter = l3.LogicalRouter(
            id='lrouter1',
            topic='topic1',
            version=1,
            unique_key=22,
            ports=[
                l3.LogicalRouterPort(
                    id='lrouter1-port1',
                    unique_key=55,
                    topic='topic1',
                    mac='aa:bb:cc:dd:ee:ff',
                    network='10.0.0.1/24',
                ),
            ],
        )
        self.app.db_store.update(lrouter)

        event = ofp_event.EventOFPMsgBase(msg=ofproto_parser.OFPPacketIn(
            datapath=mock.Mock(),
            reason=self.app.ofproto.OFPR_PACKET_IN,
            match=ofproto_parser.OFPMatch(reg7=lrouter.ports[0].unique_key, ),
            data=pkt.data,
        ))
        with mock.patch("dragonflow.controller.common."
                        "icmp_error_generator.generate") as icmp_error:
            for _ in range(self.app.conf.router_port_unreach_max_rate * 2):
                self.app.packet_in_handler(event)

            self.assertEqual(self.app.conf.router_port_unreach_max_rate,
                             icmp_error.call_count)
            icmp_error.assert_called_with(icmp.ICMP_DEST_UNREACH,
                                          icmp.ICMP_PORT_UNREACH_CODE,
                                          pkt.data,
                                          pkt=mock.ANY)
Beispiel #12
0
    def test_serialize_with_auth_sha1(self):
        pkt = packet.Packet()

        eth_pkt = ethernet.ethernet('08:00:27:d1:95:7c', '08:00:27:ed:54:41')
        pkt.add_protocol(eth_pkt)

        ip_pkt = ipv4.ipv4(src='192.168.57.2',
                           dst='192.168.57.1',
                           tos=192,
                           identification=2960,
                           proto=inet.IPPROTO_UDP)
        pkt.add_protocol(ip_pkt)

        udp_pkt = udp.udp(49152, 3784)
        pkt.add_protocol(udp_pkt)

        auth_cls = bfd.KeyedSHA1(auth_key_id=2,
                                 seq=16817,
                                 auth_key=self.auth_keys[2])

        bfd_pkt = bfd.bfd(ver=1,
                          diag=bfd.BFD_DIAG_NO_DIAG,
                          flags=bfd.BFD_FLAG_AUTH_PRESENT,
                          state=bfd.BFD_STATE_DOWN,
                          detect_mult=3,
                          my_discr=1,
                          your_discr=0,
                          desired_min_tx_interval=1000000,
                          required_min_rx_interval=1000000,
                          required_min_echo_rx_interval=0,
                          auth_cls=auth_cls)

        pkt.add_protocol(bfd_pkt)

        eq_(len(pkt.protocols), 4)

        pkt.serialize()
        eq_(pkt.data, self.data_auth_sha1)
Beispiel #13
0
 def _gen_udp(cls, src_port=SRC_PORT, dst_port=DST_PORT):
     return udp.udp(
         src_port=src_port,
         dst_port=dst_port,
     )
Beispiel #14
0
class Test_udp(unittest.TestCase):
    """ Test case for udp
    """
    src_port = 6431
    dst_port = 8080
    total_length = 65507
    csum = 12345
    u = udp(src_port, dst_port, total_length, csum)
    buf = pack(udp._PACK_STR, src_port, dst_port, total_length, csum)

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_init(self):
        eq_(self.src_port, self.u.src_port)
        eq_(self.dst_port, self.u.dst_port)
        eq_(self.total_length, self.u.total_length)
        eq_(self.csum, self.u.csum)

    def test_parser(self):
        r1, r2, _ = self.u.parser(self.buf)

        eq_(self.src_port, r1.src_port)
        eq_(self.dst_port, r1.dst_port)
        eq_(self.total_length, r1.total_length)
        eq_(self.csum, r1.csum)
        eq_(None, r2)

    def test_serialize(self):
        src_port = 6431
        dst_port = 8080
        total_length = 0
        csum = 0

        src_ip = '192.168.10.1'
        dst_ip = '192.168.100.1'
        prev = ipv4(4, 5, 0, 0, 0, 0, 0, 64, inet.IPPROTO_UDP, 0, src_ip,
                    dst_ip)

        u = udp(src_port, dst_port, total_length, csum)
        buf = u.serialize(bytearray(), prev)
        res = struct.unpack(udp._PACK_STR, buf)

        eq_(res[0], src_port)
        eq_(res[1], dst_port)
        eq_(res[2], struct.calcsize(udp._PACK_STR))

        # checksum
        ph = struct.pack('!4s4sBBH', addrconv.ipv4.text_to_bin(src_ip),
                         addrconv.ipv4.text_to_bin(dst_ip), 0, 17, res[2])
        d = ph + buf + bytearray()
        s = packet_utils.checksum(d)
        eq_(0, s)

    @raises(Exception)
    def test_malformed_udp(self):
        m_short_buf = self.buf[1:udp._MIN_LEN]
        udp.parser(m_short_buf)

    def test_default_args(self):
        prev = ipv4(proto=inet.IPPROTO_UDP)
        u = udp()
        buf = u.serialize(bytearray(), prev)
        res = struct.unpack(udp._PACK_STR, buf)

        eq_(res[0], 1)
        eq_(res[1], 1)
        eq_(res[2], udp._MIN_LEN)

    def test_json(self):
        jsondict = self.u.to_jsondict()
        u = udp.from_jsondict(jsondict['udp'])
        eq_(str(self.u), str(u))