# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#
# WARNING: This file is machine generated by fidlgen.

include <fuchsia/net/c/fidl.h>
fuchsia_net_LookupIpOptions = fuchsia_net_LookupIpOptions_V4_ADDRS, fuchsia_net_LookupIpOptions_V6_ADDRS, fuchsia_net_LookupIpOptions_CNAME_LOOKUP

fuchsia_net_NameLookup_LookupIp_ResponseHandles {
	addr	fuchsia_net_IpAddressInfoHandles
} [packed]

fuchsia_net_NameLookup_LookupHostname_ResponseHandles {
	void	void
} [packed]

fuchsia_net_IpAddressInfoHandles {
	ipv4_addrs	array[fuchsia_net_Ipv4AddressHandles]
	ipv6_addrs	array[fuchsia_net_Ipv6AddressHandles]
} [packed]

fuchsia_net_Ipv4AddressInLine {
	addrInLine	array[int8, 4]
} [packed]

fuchsia_net_Ipv4AddressOutOfLine {
	void	void
} [packed]

fuchsia_net_Ipv4AddressHandles {
	void	void
} [packed]

fuchsia_net_Ipv6AddressInLine {
	addrInLine	array[int8, 16]
} [packed]

fuchsia_net_Ipv6AddressOutOfLine {
	void	void
} [packed]

fuchsia_net_Ipv6AddressHandles {
	void	void
} [packed]

fuchsia_net_SubnetInLine {
	addrInLine	fuchsia_net_IpAddressInLine
	prefix_len	int8
} [packed]

fuchsia_net_SubnetOutOfLine {
	void	void
} [packed]

fuchsia_net_SubnetHandles {
	void	void
} [packed]

fuchsia_net_AddrInfoHintsInLine {
	flags_		int32
	family		int32
	sock_type	int32
	protocol	int32
} [packed]

fuchsia_net_AddrInfoHintsOutOfLine {
	void	void
} [packed]

fuchsia_net_AddrInfoHintsHandles {
	void	void
} [packed]

fuchsia_net_AddrStorageHandles {
	void	void
} [packed]

fuchsia_net_AddrInfoHandles {
	addr	fuchsia_net_AddrStorageHandles
} [packed]

fuchsia_net_NameLookup_LookupIp_ResultHandles [
	response	fuchsia_net_NameLookup_LookupIp_ResponseHandles
] [varlen]

fuchsia_net_NameLookup_LookupHostname_ResultHandles [
	response	fuchsia_net_NameLookup_LookupHostname_ResponseHandles
] [varlen]

fuchsia_net_IpAddressInLine [
	ipv4InLine	fidl_union_member[fuchsia_net_IpAddressTag_ipv4, fuchsia_net_Ipv4AddressInLine]
	ipv6InLine	fidl_union_member[fuchsia_net_IpAddressTag_ipv6, fuchsia_net_Ipv6AddressInLine]
]

fuchsia_net_IpAddressOutOfLine [
	ipv4OutOfLine	fuchsia_net_Ipv4AddressOutOfLine
	ipv6OutOfLine	fuchsia_net_Ipv6AddressOutOfLine
] [varlen]

fuchsia_net_IpAddressHandles [
	ipv4	fuchsia_net_Ipv4AddressHandles
	ipv6	fuchsia_net_Ipv6AddressHandles
] [varlen]

fuchsia_net_ConnectivityOnNetworkReachableEventHandles {
	void	void
} [packed]

resource zx_chan_fuchsia_net_Connectivity_client[zx_chan]
resource zx_chan_fuchsia_net_Connectivity_server[zx_chan]

zx_channel_create$fuchsia_net_Connectivity(options const[0], out0 ptr[out, zx_chan_fuchsia_net_Connectivity_client], out1 ptr[out, zx_chan_fuchsia_net_Connectivity_server])
fdio_service_connect$fuchsia_net_Connectivity(path ptr[in, string["/svc/fuchsia.net.Connectivity"]], handle zx_chan_fuchsia_net_Connectivity_server)
zx_channel_read$fuchsia_net_ConnectivityOnNetworkReachable(handle zx_chan_fuchsia_net_Connectivity_client, options const[0], bytes ptr[out, array[int8, ZX_CHANNEL_MAX_MSG_BYTES]], num_bytes bytesize[bytes], handles ptr[out, fuchsia_net_ConnectivityOnNetworkReachableEventHandles], num_handles bytesize[handles], actual_bytes ptr[out, int32], actual_handles ptr[out, int32])

fuchsia_net_NameLookupLookupIpRequest {
	hdr			fidl_message_header[818031436]
	hostnameInLine		fidl_string
	options			flags[fuchsia_net_LookupIpOptions, int8]
	hostnameOutOfLine	fidl_aligned[stringnoz]
} [packed]

fuchsia_net_NameLookupLookupIpRequestHandles {
	void	void
} [packed]

fuchsia_net_NameLookupLookupIpResponseHandles {
	result	fuchsia_net_NameLookup_LookupIp_ResultHandles
} [packed]

fuchsia_net_NameLookupLookupHostnameRequest {
	hdr		fidl_message_header[391654548]
	addrInLine	fuchsia_net_IpAddressInLine
	addrOutOfLine	fuchsia_net_IpAddressOutOfLine
} [packed]

fuchsia_net_NameLookupLookupHostnameRequestHandles {
	addr	fuchsia_net_IpAddressHandles
} [packed]

fuchsia_net_NameLookupLookupHostnameResponseHandles {
	result	fuchsia_net_NameLookup_LookupHostname_ResultHandles
} [packed]

resource zx_chan_fuchsia_net_NameLookup_client[zx_chan]
resource zx_chan_fuchsia_net_NameLookup_server[zx_chan]

zx_channel_create$fuchsia_net_NameLookup(options const[0], out0 ptr[out, zx_chan_fuchsia_net_NameLookup_client], out1 ptr[out, zx_chan_fuchsia_net_NameLookup_server])
fdio_service_connect$fuchsia_net_NameLookup(path ptr[in, string["/svc/fuchsia.net.NameLookup"]], handle zx_chan_fuchsia_net_NameLookup_server)
zx_channel_call$fuchsia_net_NameLookupLookupIp(handle zx_chan_fuchsia_net_NameLookup_client, options const[0], deadline zx_time, args ptr[in, fidl_call_args[fuchsia_net_NameLookupLookupIpRequest, fuchsia_net_NameLookupLookupIpRequestHandles, array[int8, ZX_CHANNEL_MAX_MSG_BYTES], fuchsia_net_NameLookupLookupIpResponseHandles]], actual_bytes ptr[out, int32], actual_handles ptr[out, int32])
zx_channel_call$fuchsia_net_NameLookupLookupHostname(handle zx_chan_fuchsia_net_NameLookup_client, options const[0], deadline zx_time, args ptr[in, fidl_call_args[fuchsia_net_NameLookupLookupHostnameRequest, fuchsia_net_NameLookupLookupHostnameRequestHandles, array[int8, ZX_CHANNEL_MAX_MSG_BYTES], fuchsia_net_NameLookupLookupHostnameResponseHandles]], actual_bytes ptr[out, int32], actual_handles ptr[out, int32])

fuchsia_net_SocketProviderGetAddrInfoRequest {
	hdr			fidl_message_header[498796293]
	nodeInLine		fidl_string
	serviceInLine		fidl_string
	hintsInLine		fuchsia_net_AddrInfoHintsInLine
	nodeOutOfLine		fidl_aligned[stringnoz]
	serviceOutOfLine	fidl_aligned[stringnoz]
	hintsOutOfLine		fuchsia_net_AddrInfoHintsOutOfLine
} [packed]

fuchsia_net_SocketProviderGetAddrInfoRequestHandles {
	hints	fuchsia_net_AddrInfoHintsHandles
} [packed]

fuchsia_net_SocketProviderGetAddrInfoResponseHandles {
	resHandles	array[fuchsia_net_AddrInfoHandles, 4]
} [packed]

resource zx_chan_fuchsia_net_SocketProvider_client[zx_chan]
resource zx_chan_fuchsia_net_SocketProvider_server[zx_chan]

zx_channel_create$fuchsia_net_SocketProvider(options const[0], out0 ptr[out, zx_chan_fuchsia_net_SocketProvider_client], out1 ptr[out, zx_chan_fuchsia_net_SocketProvider_server])
fdio_service_connect$fuchsia_net_SocketProvider(path ptr[in, string["/svc/fuchsia.net.SocketProvider"]], handle zx_chan_fuchsia_net_SocketProvider_server)
zx_channel_call$fuchsia_net_SocketProviderGetAddrInfo(handle zx_chan_fuchsia_net_SocketProvider_client, options const[0], deadline zx_time, args ptr[in, fidl_call_args[fuchsia_net_SocketProviderGetAddrInfoRequest, fuchsia_net_SocketProviderGetAddrInfoRequestHandles, array[int8, ZX_CHANNEL_MAX_MSG_BYTES], fuchsia_net_SocketProviderGetAddrInfoResponseHandles]], actual_bytes ptr[out, int32], actual_handles ptr[out, int32])
