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))
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)
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))
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)
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
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)
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
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)
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)
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
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 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
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]))
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)
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
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
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
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
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')
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)
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) }
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
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)
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
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)
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
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, )
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))