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 _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
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 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 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_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 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
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_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 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 _gen_udp(cls, src_port=SRC_PORT, dst_port=DST_PORT): return udp.udp( src_port=src_port, dst_port=dst_port, )
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))