Example #1
0
    def test_default_args(self):
        prev = ipv4(proto=inet.IPPROTO_IGMP)
        g = igmpv3_report()
        prev.serialize(g, None)
        buf = g.serialize(bytearray(), prev)
        res = unpack_from(igmpv3_report._PACK_STR, six.binary_type(buf))
        buf = bytearray(buf)
        pack_into('!H', buf, 2, 0)

        eq_(res[0], IGMP_TYPE_REPORT_V3)
        eq_(res[1], checksum(buf))
        eq_(res[2], 0)

        # records without record_num
        prev = ipv4(proto=inet.IPPROTO_IGMP)
        record1 = igmpv3_report_group(MODE_IS_INCLUDE, 0, 0, '225.0.0.1')
        record2 = igmpv3_report_group(MODE_IS_INCLUDE, 0, 2, '225.0.0.2',
                                      ['172.16.10.10', '172.16.10.27'])
        record3 = igmpv3_report_group(MODE_IS_INCLUDE, 1, 0, '225.0.0.3', [],
                                      b'abc\x00')
        record4 = igmpv3_report_group(MODE_IS_INCLUDE, 1, 2, '225.0.0.4',
                                      ['172.16.10.10', '172.16.10.27'],
                                      b'abc\x00')
        records = [record1, record2, record3, record4]
        g = igmpv3_report(records=records)
        prev.serialize(g, None)
        buf = g.serialize(bytearray(), prev)
        res = unpack_from(igmpv3_report._PACK_STR, six.binary_type(buf))
        buf = bytearray(buf)
        pack_into('!H', buf, 2, 0)

        eq_(res[0], IGMP_TYPE_REPORT_V3)
        eq_(res[1], checksum(buf))
        eq_(res[2], len(records))
Example #2
0
    def _do_leave(self, leave, in_port, msg):
        """the process when the snooper received a LEAVE message."""
        datapath = msg.datapath
        dpid = datapath.id
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        # check whether the querier port has been specified.
        if not self._to_querier.get(dpid):
            self.logger.info("no querier exists.")
            return

        # save this LEAVE message and reset the condition of the port
        # that received this message.
        self._to_hosts.setdefault(dpid, {})
        self._to_hosts[dpid].setdefault(leave.address, {
            'replied': False,
            'leave': None,
            'ports': {}
        })
        self._to_hosts[dpid][leave.address]['leave'] = msg
        self._to_hosts[dpid][leave.address]['ports'][in_port] = {
            'out': False,
            'in': False
        }

        # create a specific query.
        timeout = igmp.LAST_MEMBER_QUERY_INTERVAL
        res_igmp = igmp.igmp(msgtype=igmp.IGMP_TYPE_QUERY,
                             maxresp=timeout * 10,
                             csum=0,
                             address=leave.address)
        res_ipv4 = ipv4.ipv4(total_length=len(ipv4.ipv4()) + len(res_igmp),
                             proto=inet.IPPROTO_IGMP,
                             ttl=1,
                             src=self._to_querier[dpid]['ip'],
                             dst=igmp.MULTICAST_IP_ALL_HOST)
        res_ether = ethernet.ethernet(dst=igmp.MULTICAST_MAC_ALL_HOST,
                                      src=self._to_querier[dpid]['mac'],
                                      ethertype=ether.ETH_TYPE_IP)
        res_pkt = packet.Packet()
        res_pkt.add_protocol(res_ether)
        res_pkt.add_protocol(res_ipv4)
        res_pkt.add_protocol(res_igmp)
        res_pkt.serialize()

        # send a specific query to the host that sent this message.
        actions = [parser.OFPActionOutput(ofproto.OFPP_IN_PORT)]
        self._do_packet_out(datapath, res_pkt.data, in_port, actions)

        # wait for REPORT messages.
        hub.spawn(self._do_timeout_for_leave, timeout, datapath, leave.address,
                  in_port)
Example #3
0
    def test_serialize_option(self):
        # prepare test data
        offset = 0
        csum = 0
        option = [
            tcp.TCPOptionMaximumSegmentSize(max_seg_size=1460),
            tcp.TCPOptionSACKPermitted(),
            tcp.TCPOptionTimestamps(ts_val=287454020, ts_ecr=1432778632),
            tcp.TCPOptionNoOperation(),
            tcp.TCPOptionWindowScale(shift_cnt=9),
        ]
        option_buf = (b'\x02\x04\x05\xb4'
                      b'\x04\x02'
                      b'\x08\x0a\x11\x22\x33\x44\x55\x66\x77\x88'
                      b'\x01'
                      b'\x03\x03\x09')
        prev = ipv4(4, 5, 0, 0, 0, 0, 0, 64, inet.IPPROTO_TCP, 0,
                    '192.168.10.1', '192.168.100.1')

        # test serializer
        t = tcp.tcp(self.src_port, self.dst_port, self.seq, self.ack, offset,
                    self.bits, self.window_size, csum, self.urgent, option)
        buf = t.serialize(bytearray(), prev)
        r_option_buf = buf[tcp.tcp._MIN_LEN:tcp.tcp._MIN_LEN + len(option_buf)]
        eq_(option_buf, r_option_buf)

        # test parser
        (r_tcp, _, _) = tcp.tcp.parser(buf)
        eq_(str(option), str(r_tcp.option))
Example #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)
Example #5
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
Example #6
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)
Example #7
0
    def _build_vlan(self):
        src_mac = '00:07:0d:af:f4:54'
        dst_mac = '00:00:00:00:00:00'
        ethertype = ether.ETH_TYPE_8021Q
        e = ethernet(dst_mac, src_mac, ethertype)

        version = 4
        header_length = 20
        tos = 0
        total_length = 24
        identification = 0x8a5d
        flags = 0
        offset = 1480
        ttl = 64
        proto = inet.IPPROTO_ICMP
        csum = 0xa7f2
        src = '131.151.32.21'
        dst = '131.151.32.129'
        option = b'TEST'
        ip = ipv4(version, header_length, tos, total_length, identification,
                  flags, offset, ttl, proto, csum, src, dst, option)

        p = Packet()

        p.add_protocol(e)
        p.add_protocol(self.v)
        p.add_protocol(ip)
        p.serialize()

        return p
Example #8
0
    def test_serialize(self):
        src_ip = '192.168.0.1'
        dst_ip = vrrp.VRRP_IPV4_DST_ADDRESS
        prev = ipv4.ipv4(4, 5, 0, 0, 0, 0, 0, vrrp.VRRP_IPV4_TTL,
                         inet.IPPROTO_VRRP, 0, src_ip, dst_ip)

        type_ = vrrp.VRRP_TYPE_ADVERTISEMENT
        vrid = 5
        priority = 10
        max_adver_int = 30
        ip_address = '192.168.0.2'
        ip_addresses = [ip_address]

        vrrp_ = vrrp.vrrpv2.create(type_, vrid, priority, max_adver_int,
                                   ip_addresses)

        buf = vrrp_.serialize(bytearray(), prev)
        pack_str = vrrp.vrrpv2._PACK_STR + '4sII'
        pack_len = struct.calcsize(pack_str)
        res = struct.unpack(pack_str, six.binary_type(buf))
        eq_(res[0], vrrp.vrrp_to_version_type(vrrp.VRRP_VERSION_V2, type_))
        eq_(res[1], vrid)
        eq_(res[2], priority)
        eq_(res[3], len(ip_addresses))
        eq_(res[4], vrrp.VRRP_AUTH_NO_AUTH)
        eq_(res[5], max_adver_int)
        # res[6] is checksum
        eq_(res[7], addrconv.ipv4.text_to_bin(ip_address))
        eq_(res[8], 0)
        eq_(res[9], 0)
        eq_(len(buf), pack_len)

        # checksum
        s = packet_utils.checksum(buf)
        eq_(0, s)
Example #9
0
    def test_serialize(self):
        offset = 5
        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_TCP, 0, src_ip,
                    dst_ip)

        t = tcp.tcp(self.src_port, self.dst_port, self.seq, self.ack, offset,
                    self.bits, self.window_size, csum, self.urgent)
        buf = t.serialize(bytearray(), prev)
        res = struct.unpack(tcp.tcp._PACK_STR, six.binary_type(buf))

        eq_(res[0], self.src_port)
        eq_(res[1], self.dst_port)
        eq_(res[2], self.seq)
        eq_(res[3], self.ack)
        eq_(res[4], offset << 4)
        eq_(res[5], self.bits)
        eq_(res[6], self.window_size)
        eq_(res[8], self.urgent)

        # test __len__
        # offset indicates the number of 32 bit (= 4 bytes)
        # words in the TCP Header.
        # So, we compare len(tcp) with offset * 4, here.
        eq_(offset * 4, len(t))

        # checksum
        ph = struct.pack('!4s4sBBH', addrconv.ipv4.text_to_bin(src_ip),
                         addrconv.ipv4.text_to_bin(dst_ip), 0, 6, offset * 4)
        d = ph + buf
        s = packet_utils.checksum(d)
        eq_(0, s)
Example #10
0
    def _build_itag(self):
        b_src_mac = '00:07:0d:af:f4:54'
        b_dst_mac = '00:00:00:00:00:00'
        b_ethertype = ether.ETH_TYPE_8021AD
        e1 = ethernet.ethernet(b_dst_mac, b_src_mac, b_ethertype)

        b_pcp = 0
        b_cfi = 0
        b_vid = 32
        b_ethertype = ether.ETH_TYPE_8021Q
        bt = vlan.svlan(b_pcp, b_cfi, b_vid, b_ethertype)

        c_src_mac = '11:11:11:11:11:11'
        c_dst_mac = 'aa:aa:aa:aa:aa:aa'
        c_ethertype = ether.ETH_TYPE_8021AD
        e2 = ethernet.ethernet(c_dst_mac, c_src_mac, c_ethertype)

        s_pcp = 0
        s_cfi = 0
        s_vid = 32
        s_ethertype = ether.ETH_TYPE_8021Q
        st = vlan.svlan(s_pcp, s_cfi, s_vid, s_ethertype)

        c_pcp = 0
        c_cfi = 0
        c_vid = 32
        c_ethertype = ether.ETH_TYPE_IP
        ct = vlan.vlan(c_pcp, c_cfi, c_vid, c_ethertype)

        version = 4
        header_length = 20
        tos = 0
        total_length = 24
        identification = 0x8a5d
        flags = 0
        offset = 1480
        ttl = 64
        proto = inet.IPPROTO_ICMP
        csum = 0xa7f2
        src = '131.151.32.21'
        dst = '131.151.32.129'
        option = b'TEST'
        ip = ipv4.ipv4(version, header_length, tos, total_length,
                       identification, flags, offset, ttl, proto, csum, src,
                       dst, option)

        p = packet.Packet()

        p.add_protocol(e1)
        p.add_protocol(bt)
        p.add_protocol(self.it)
        p.add_protocol(e2)
        p.add_protocol(st)
        p.add_protocol(ct)
        p.add_protocol(ip)
        p.serialize()

        return p
Example #11
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)
Example #12
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
Example #13
0
    def test_default_args(self):
        prev = ipv4(proto=inet.IPPROTO_IGMP)
        g = igmpv3_query()
        prev.serialize(g, None)
        buf = g.serialize(bytearray(), prev)
        res = unpack_from(igmpv3_query._PACK_STR, six.binary_type(buf))
        buf = bytearray(buf)
        pack_into('!H', buf, 2, 0)

        eq_(res[0], IGMP_TYPE_QUERY)
        eq_(res[1], 100)
        eq_(res[2], checksum(buf))
        eq_(res[3], addrconv.ipv4.text_to_bin('0.0.0.0'))
        eq_(res[4], 2)
        eq_(res[5], 0)
        eq_(res[6], 0)

        # srcs without num
        prev = ipv4(proto=inet.IPPROTO_IGMP)
        srcs = ['192.168.1.1', '192.168.1.2', '192.168.1.3']
        g = igmpv3_query(srcs=srcs)
        prev.serialize(g, None)
        buf = g.serialize(bytearray(), prev)
        res = unpack_from(igmpv3_query._PACK_STR, six.binary_type(buf))
        buf = bytearray(buf)
        pack_into('!H', buf, 2, 0)

        eq_(res[0], IGMP_TYPE_QUERY)
        eq_(res[1], 100)
        eq_(res[2], checksum(buf))
        eq_(res[3], addrconv.ipv4.text_to_bin('0.0.0.0'))
        eq_(res[4], 2)
        eq_(res[5], 0)
        eq_(res[6], len(srcs))

        res = unpack_from('4s4s4s', six.binary_type(buf),
                          igmpv3_query._MIN_LEN)

        eq_(res[0], addrconv.ipv4.text_to_bin(srcs[0]))
        eq_(res[1], addrconv.ipv4.text_to_bin(srcs[1]))
        eq_(res[2], addrconv.ipv4.text_to_bin(srcs[2]))
Example #14
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)
Example #15
0
    def create_packet(self, primary_ip_address, vlan_id=None):
        """Prepare a VRRP packet.

        Returns a newly created os_ken.lib.packet.packet.Packet object
        with appropriate protocol header objects added by add_protocol().
        It's caller's responsibility to serialize().
        The serialized packet would looks like the ones described in
        the following sections.

        * RFC 3768 5.1. VRRP Packet Format
        * RFC 5798 5.1. VRRP Packet Format

        ================== ====================
        Argument           Description
        ================== ====================
        primary_ip_address Source IP address
        vlan_id            VLAN ID.  None for no VLAN.
        ================== ====================
        """
        if self.is_ipv6:
            traffic_class = 0xc0        # set tos to internetwork control
            flow_label = 0
            payload_length = ipv6.ipv6._MIN_LEN + len(self)     # XXX _MIN_LEN
            e = ethernet.ethernet(VRRP_IPV6_DST_MAC_ADDRESS,
                                  vrrp_ipv6_src_mac_address(self.vrid),
                                  ether.ETH_TYPE_IPV6)
            ip = ipv6.ipv6(6, traffic_class, flow_label, payload_length,
                           inet.IPPROTO_VRRP, VRRP_IPV6_HOP_LIMIT,
                           primary_ip_address, VRRP_IPV6_DST_ADDRESS)
        else:
            header_length = ipv4.ipv4._MIN_LEN // 4      # XXX _MIN_LEN
            total_length = 0
            tos = 0xc0  # set tos to internetwork control
            identification = self.get_identification()
            e = ethernet.ethernet(VRRP_IPV4_DST_MAC_ADDRESS,
                                  vrrp_ipv4_src_mac_address(self.vrid),
                                  ether.ETH_TYPE_IP)
            ip = ipv4.ipv4(4, header_length, tos, total_length, identification,
                           0, 0, VRRP_IPV4_TTL, inet.IPPROTO_VRRP, 0,
                           primary_ip_address, VRRP_IPV4_DST_ADDRESS)

        p = packet.Packet()
        p.add_protocol(e)
        if vlan_id is not None:
            vlan_ = vlan.vlan(0, 0, vlan_id, e.ethertype)
            e.ethertype = ether.ETH_TYPE_8021Q
            p.add_protocol(vlan_)
        p.add_protocol(ip)
        p.add_protocol(self)
        return p
Example #16
0
    def _build_igmp(self):
        dl_dst = '11:22:33:44:55:66'
        dl_src = 'aa:bb:cc:dd:ee:ff'
        dl_type = ether.ETH_TYPE_IP
        e = ethernet(dl_dst, dl_src, dl_type)

        total_length = len(ipv4()) + len(self.g)
        nw_proto = inet.IPPROTO_IGMP
        nw_dst = '11.22.33.44'
        nw_src = '55.66.77.88'
        i = ipv4(total_length=total_length,
                 src=nw_src,
                 dst=nw_dst,
                 proto=nw_proto,
                 ttl=1)

        p = Packet()

        p.add_protocol(e)
        p.add_protocol(i)
        p.add_protocol(self.g)
        p.serialize()
        return p
Example #17
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
Example #18
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
Example #19
0
    def test_default_args(self):
        prev = ipv4(proto=inet.IPPROTO_TCP)
        t = tcp.tcp()
        buf = t.serialize(bytearray(), prev)
        res = struct.unpack(tcp.tcp._PACK_STR, buf)

        eq_(res[0], 1)
        eq_(res[1], 1)
        eq_(res[2], 0)
        eq_(res[3], 0)
        eq_(res[4], 5 << 4)
        eq_(res[5], 0)
        eq_(res[6], 0)
        eq_(res[8], 0)

        # with option, without offset
        t = tcp.tcp(option=[tcp.TCPOptionMaximumSegmentSize(1460)])
        buf = t.serialize(bytearray(), prev)
        res = struct.unpack(tcp.tcp._PACK_STR + '4s', buf)

        eq_(res[0], 1)
        eq_(res[1], 1)
        eq_(res[2], 0)
        eq_(res[3], 0)
        eq_(res[4], 6 << 4)
        eq_(res[5], 0)
        eq_(res[6], 0)
        eq_(res[8], 0)
        eq_(res[9], b'\x02\x04\x05\xb4')

        # with option, with long offset
        t = tcp.tcp(offset=7, option=[tcp.TCPOptionWindowScale(shift_cnt=9)])
        buf = t.serialize(bytearray(), prev)
        res = struct.unpack(tcp.tcp._PACK_STR + '8s', buf)

        eq_(res[0], 1)
        eq_(res[1], 1)
        eq_(res[2], 0)
        eq_(res[3], 0)
        eq_(res[4], 7 << 4)
        eq_(res[5], 0)
        eq_(res[6], 0)
        eq_(res[8], 0)
        eq_(res[9], b'\x03\x03\x09\x00\x00\x00\x00\x00')
Example #20
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)
Example #21
0
def decode(nfa):
    """This function analyses nflog packet by using os-ken packet library."""

    prefix = ffi.string(libnflog.nflog_get_prefix(nfa))
    packet_hdr = libnflog.nflog_get_msg_packet_hdr(nfa)
    hw_proto = socket.ntohs(packet_hdr.hw_protocol)

    msg = ''
    msg_packet_hwhdr = libnflog.nflog_get_msg_packet_hwhdr(nfa)
    if msg_packet_hwhdr != ffi.NULL:
        packet_hwhdr = ffi.string(msg_packet_hwhdr)
        if len(packet_hwhdr) >= 12:
            dst, src = struct.unpack_from('!6s6s', packet_hwhdr)
            # Dump ethernet packet to get mac addresses
            eth = ethernet.ethernet(addrconv.mac.bin_to_text(dst),
                                    addrconv.mac.bin_to_text(src),
                                    ethertype=hw_proto)
            msg = str(eth)

    # Dump IP packet
    pkt = _payload(nfa)
    if hw_proto == ether_types.ETH_TYPE_IP:
        ip_pkt, proto, data = ipv4.ipv4().parser(pkt)
        msg += str(ip_pkt)
        proto_pkt, a, b = proto.parser(data)
        msg += str(proto_pkt)
    elif hw_proto == ether_types.ETH_TYPE_IPV6:
        ip_pkt, proto, data = ipv6.ipv6().parser(pkt)
        proto_pkt, a, b = proto.parser(data)
        msg += str(proto_pkt)
    elif hw_proto == ether_types.ETH_TYPE_ARP:
        ip_pkt, proto, data = arp.arp().parser(pkt)
        msg += str(ip_pkt)
    else:
        msg += "Does not support hw_proto: " + str(hw_proto)

    return {
        'prefix': encodeutils.safe_decode(prefix),
        'msg': encodeutils.safe_decode(msg)
    }
Example #22
0
    def _build_echo(self, _type, echo):
        e = self._build_ether(ether.ETH_TYPE_IP)
        ip = ipv4.ipv4(version=4,
                       header_length=5,
                       tos=0,
                       total_length=84,
                       identification=0,
                       flags=0,
                       offset=0,
                       ttl=64,
                       proto=inet.IPPROTO_ICMP,
                       csum=0,
                       src=self.OSKEN_IP,
                       dst=self.HOST_IP)
        ping = icmp.icmp(_type, code=0, csum=0, data=echo)

        p = packet.Packet()
        p.add_protocol(e)
        p.add_protocol(ip)
        p.add_protocol(ping)
        p.serialize()
        return p
Example #23
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)
Example #24
0
def echo_reply(vid, eth_src, eth_dst, src_ip, dst_ip, data):
    """Return an ICMP echo reply packet.

    Args:
        vid (int or None): VLAN VID to use (or None).
        eth_src (str): Ethernet source address.
        eth_dst (str): destination Ethernet MAC address.
        src_ip (ipaddress.IPv4Address): source IPv4 address.
        dst_ip (ipaddress.IPv4Address): destination IPv4 address.
    Returns:
        ryu.lib.packet.icmp: serialized ICMP echo reply packet.
    """
    pkt = build_pkt_header(vid, eth_src, eth_dst, valve_of.ether.ETH_TYPE_IP)
    ipv4_pkt = ipv4.ipv4(dst=dst_ip,
                         src=src_ip,
                         proto=valve_of.inet.IPPROTO_ICMP)
    pkt.add_protocol(ipv4_pkt)
    icmp_pkt = icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                         code=icmp.ICMP_ECHO_REPLY_CODE,
                         data=data)
    pkt.add_protocol(icmp_pkt)
    pkt.serialize()
    return pkt
Example #25
0
    def _send_query(self):
        """ send a QUERY message periodically."""
        timeout = 60
        ofproto = self._datapath.ofproto
        parser = self._datapath.ofproto_parser
        if ofproto_v1_0.OFP_VERSION == ofproto.OFP_VERSION:
            send_port = ofproto.OFPP_NONE
        else:
            send_port = ofproto.OFPP_ANY

        # create a general query.
        res_igmp = igmp.igmp(msgtype=igmp.IGMP_TYPE_QUERY,
                             maxresp=igmp.QUERY_RESPONSE_INTERVAL * 10,
                             csum=0,
                             address='0.0.0.0')
        res_ipv4 = ipv4.ipv4(total_length=len(ipv4.ipv4()) + len(res_igmp),
                             proto=inet.IPPROTO_IGMP,
                             ttl=1,
                             src='0.0.0.0',
                             dst=igmp.MULTICAST_IP_ALL_HOST)
        res_ether = ethernet.ethernet(
            dst=igmp.MULTICAST_MAC_ALL_HOST,
            src=self._datapath.ports[ofproto.OFPP_LOCAL].hw_addr,
            ethertype=ether.ETH_TYPE_IP)
        res_pkt = packet.Packet()
        res_pkt.add_protocol(res_ether)
        res_pkt.add_protocol(res_ipv4)
        res_pkt.add_protocol(res_igmp)
        res_pkt.serialize()

        flood = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)]

        while True:
            # reset reply status.
            for status in self._mcast.values():
                for port in status.keys():
                    status[port] = False

            # send a general query to the host that sent this message.
            self._do_packet_out(self._datapath, res_pkt.data, send_port, flood)
            hub.sleep(igmp.QUERY_RESPONSE_INTERVAL)

            # QUERY timeout expired.
            del_groups = []
            for group, status in self._mcast.items():
                del_ports = []
                actions = []
                for port in status.keys():
                    if not status[port]:
                        del_ports.append(port)
                    else:
                        actions.append(parser.OFPActionOutput(port))
                if len(actions) and len(del_ports):
                    self._set_flow_entry(self._datapath, actions,
                                         self.server_port, group)
                if not len(actions):
                    self._del_flow_entry(self._datapath, self.server_port,
                                         group)
                    del_groups.append(group)
                if len(del_ports):
                    for port in del_ports:
                        self._del_flow_entry(self._datapath, port, group)
                for port in del_ports:
                    del status[port]
            for group in del_groups:
                del self._mcast[group]

            rest_time = timeout - igmp.QUERY_RESPONSE_INTERVAL
            hub.sleep(rest_time)
Example #26
0
 def _create_fake_empty_packet(self):
     pkt = os_ken_packet.Packet()
     pkt.add_protocol(ethernet.ethernet(
         ethertype=ether.ETH_TYPE_IP))
     pkt.add_protocol(ipv4.ipv4())
     return pkt
Example #27
0
 def _gen_ipv4(self, proto, src=None, dst=None):
     return ipv4.ipv4(
         src=(src or SRC_IPV4_1),
         dst=(dst or DST_IPV4_1),
         proto=proto,
     )
Example #28
0
class Test_ipv4(unittest.TestCase):
    """ Test case for ipv4
    """

    version = 4
    header_length = 5 + 10
    ver_hlen = version << 4 | header_length
    tos = 0
    total_length = header_length + 64
    identification = 30774
    flags = 4
    offset = 1480
    flg_off = flags << 13 | offset
    ttl = 64
    proto = inet.IPPROTO_TCP
    csum = 0xadc6
    src = '131.151.32.21'
    dst = '131.151.32.129'
    length = header_length * 4
    option = b'\x86\x28\x00\x00\x00\x01\x01\x22' \
        + b'\x00\x01\xae\x00\x00\x00\x00\x00' \
        + b'\x00\x00\x00\x00\x00\x00\x00\x00' \
        + b'\x00\x00\x00\x00\x00\x00\x00\x00' \
        + b'\x00\x00\x00\x00\x00\x00\x00\x01'

    buf = pack(ipv4._PACK_STR, ver_hlen, tos, total_length, identification,
               flg_off, ttl, proto, csum,
               addrconv.ipv4.text_to_bin(src),
               addrconv.ipv4.text_to_bin(dst)) \
        + option

    ip = ipv4(version, header_length, tos, total_length, identification,
              flags, offset, ttl, proto, csum, src, dst, option)

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_init(self):
        eq_(self.version, self.ip.version)
        eq_(self.header_length, self.ip.header_length)
        eq_(self.tos, self.ip.tos)
        eq_(self.total_length, self.ip.total_length)
        eq_(self.identification, self.ip.identification)
        eq_(self.flags, self.ip.flags)
        eq_(self.offset, self.ip.offset)
        eq_(self.ttl, self.ip.ttl)
        eq_(self.proto, self.ip.proto)
        eq_(self.csum, self.ip.csum)
        eq_(self.src, self.ip.src)
        eq_(self.dst, self.ip.dst)
        eq_(self.length, len(self.ip))
        eq_(self.option, self.ip.option)

    def test_parser(self):
        res, ptype, _ = self.ip.parser(self.buf)

        eq_(res.version, self.version)
        eq_(res.header_length, self.header_length)
        eq_(res.tos, self.tos)
        eq_(res.total_length, self.total_length)
        eq_(res.identification, self.identification)
        eq_(res.flags, self.flags)
        eq_(res.offset, self.offset)
        eq_(res.ttl, self.ttl)
        eq_(res.proto, self.proto)
        eq_(res.csum, self.csum)
        eq_(res.src, self.src)
        eq_(res.dst, self.dst)
        eq_(ptype, tcp)

    def test_serialize(self):
        buf = self.ip.serialize(bytearray(), None)
        res = struct.unpack_from(ipv4._PACK_STR, six.binary_type(buf))
        option = buf[ipv4._MIN_LEN:ipv4._MIN_LEN + len(self.option)]

        eq_(res[0], self.ver_hlen)
        eq_(res[1], self.tos)
        eq_(res[2], self.total_length)
        eq_(res[3], self.identification)
        eq_(res[4], self.flg_off)
        eq_(res[5], self.ttl)
        eq_(res[6], self.proto)
        eq_(res[8], addrconv.ipv4.text_to_bin(self.src))
        eq_(res[9], addrconv.ipv4.text_to_bin(self.dst))
        eq_(option, self.option)

        # checksum
        csum = packet_utils.checksum(buf)
        eq_(csum, 0)

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

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