# Copyright 2017 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

include <sys/types.h>
include <sys/param.h>
include <sys/socket.h>
include <netinet/in.h>
include <net/route.h>
include <netinet6/ip6_mroute.h>
include <linux/linux.h>
include <compat/linux/linux_socket.h>
include <sys/sockio.h>

# IPv6 sockets

resource sock_in6[sock]

sockaddr_in6 {
	family	const[AF_INET6, int16]
	port	sock_port
	flow	int32
	addr	ipv6_addr
	scope	int32
}

sockaddr_storage_in6 {
	addr	sockaddr_in6
	pad	array[const[0, int64], 12]
}

socket$inet6(domain const[AF_INET6], type flags[socket_type], proto int8) sock_in6
accept$inet6(fd sock_in6, peer ptr[out, sockaddr_in6, opt], peerlen ptr[inout, len[peer, int32]]) sock_in6
accept4$inet6(fd sock_in6, peer ptr[out, sockaddr_in6, opt], peerlen ptr[inout, len[peer, int32]], flags flags[accept_flags]) sock_in6
bind$inet6(fd sock_in6, addr ptr[in, sockaddr_in6], addrlen len[addr])
connect$inet6(fd sock_in6, addr ptr[in, sockaddr_in6], addrlen len[addr])
sendto$inet6(fd sock_in6, buf buffer[in], len len[buf], f flags[send_flags], addr ptr[in, sockaddr_in6, opt], addrlen len[addr])
recvfrom$inet6(fd sock_in6, buf buffer[out], len len[buf], f flags[recv_flags], addr ptr[in, sockaddr_in6, opt], addrlen len[addr])
getsockname$inet6(fd sock_in6, addr ptr[out, sockaddr_in6], addrlen ptr[inout, len[addr, int32]])
getpeername$inet6(fd sock_in6, peer ptr[out, sockaddr_in6], peerlen ptr[inout, len[peer, int32]])

# Generic IPv6 options

inet6_option_types_int = IPV6_2292PKTINFO, IPV6_2292HOPOPTS, IPV6_2292DSTOPTS, IPV6_2292RTHDR, IPV6_CHECKSUM, IPV6_2292HOPLIMIT, IPV6_NEXTHOP, IPV6_UNICAST_HOPS, IPV6_MULTICAST_IF, IPV6_MULTICAST_HOPS, IPV6_MULTICAST_LOOP, IPV6_V6ONLY, IPV6_RECVPKTINFO, IPV6_RECVHOPLIMIT, IPV6_HOPLIMIT, IPV6_RECVHOPOPTS, IPV6_RECVRTHDR, IPV6_RECVDSTOPTS, IPV6_RECVPATHMTU, IPV6_DONTFRAG, IPV6_RECVTCLASS, IPV6_TCLASS, IPV6_AUTOFLOWLABEL, IPV6_RECVORIGDSTADDR

inet6_option_types_buf = IPV6_2292PKTOPTIONS, IPV6_IPSEC_POLICY, MCAST_JOIN_GROUP, MCAST_BLOCK_SOURCE, MCAST_UNBLOCK_SOURCE, MCAST_LEAVE_GROUP, MCAST_JOIN_SOURCE_GROUP, MCAST_LEAVE_SOURCE_GROUP, IPV6_PKTINFO, IPV6_HOPOPTS, IPV6_RTHDRDSTOPTS, IPV6_RTHDR, IPV6_DSTOPTS, IPV6_PATHMTU, MRT6_ADD_MIF, MRT6_ADD_MFC, MRT6_DEL_MFC

getsockopt$inet6_int(fd sock_in6, level const[IPPROTO_IPV6], optname flags[inet6_option_types_int], optval ptr[out, int32], optlen ptr[inout, len[optval, int32]])
setsockopt$inet6_int(fd sock_in6, level const[IPPROTO_IPV6], optname flags[inet6_option_types_int], optval ptr[in, int32], optlen len[optval])
getsockopt$inet6_buf(fd sock_in6, level const[IPPROTO_IPV6], optname flags[inet6_option_types_buf], optval buffer[out], optlen ptr[inout, len[optval, int32]])
setsockopt$inet6_buf(fd sock_in6, level const[IPPROTO_IPV6], optname flags[inet6_option_types_buf], optval buffer[in], optlen len[optval])

# Specific IPv6 options

setsockopt$inet6_MCAST_JOIN_GROUP(fd sock_in6, level const[IPPROTO_IPV6], optname const[MCAST_JOIN_GROUP], optval ptr[in, group_req_in6], optlen len[optval])
setsockopt$inet6_MCAST_LEAVE_GROUP(fd sock_in6, level const[IPPROTO_IPV6], optname const[MCAST_LEAVE_GROUP], optval ptr[in, group_req_in6], optlen len[optval])

sockopt_opt_ipv6_group_source_req = MCAST_JOIN_SOURCE_GROUP, MCAST_LEAVE_SOURCE_GROUP, MCAST_BLOCK_SOURCE, MCAST_UNBLOCK_SOURCE

setsockopt$inet6_group_source_req(fd sock_in6, level const[IPPROTO_IPV6], optname flags[sockopt_opt_ipv6_group_source_req], optval ptr[in, group_source_req_in6], optlen len[optval])

setsockopt$inet6_IPV6_PKTINFO(fd sock_in6, level const[IPPROTO_IPV6], optname const[IPV6_PKTINFO], optval ptr[in, in6_pktinfo], optlen len[optval])

# TODO: IPV6_HOPOPTS, IPV6_RTHDRDSTOPTS, IPV6_RTHDR, IPV6_DSTOPTS
# TODO: IPV6_PATHMTU
# TODO: IP6T_SO_GET_REVISION_MATCH, IP6T_SO_GET_REVISION_TARGET

setsockopt$inet6_MRT6_ADD_MIF(fd sock_in6, level const[IPPROTO_IPV6], optname const[MRT6_ADD_MIF], optval ptr[in, mif6ctl], optlen len[optval])
setsockopt$inet6_MRT6_ADD_MFC(fd sock_in6, level const[IPPROTO_IPV6], optname const[MRT6_ADD_MFC], optval ptr[in, mf6cctl], optlen len[optval])
setsockopt$inet6_MRT6_DEL_MFC(fd sock_in6, level const[IPPROTO_IPV6], optname const[MRT6_DEL_MFC], optval ptr[in, mf6cctl], optlen len[optval])

mif6ctl {
	mif6c_mifi	int16
	mif6c_flags	flags[mif6c_flags, int8]
	vifc_threshold	int8
	mif6c_pifi	int16
	vifc_rate_limit	int32
}

mif6c_flags = MIFF_REGISTER

mf6cctl {
	mf6cc_origin	sockaddr_in6
	mf6cc_mcastgrp	sockaddr_in6
	mf6cc_parent	int16
	mf6cc_ifset	array[int32, 8]
}

group_req_in6 {
	gr_interface	int32
	gr_group	sockaddr_storage_in6
}

group_source_req_in6 {
	gsr_interface	int32
	gsr_group	sockaddr_storage_in6
	gsr_source	sockaddr_storage_in6
}

in6_pktinfo {
	ipi6_addr	ipv6_addr
	ipi6_ifindex	ifindex
}
