/*
 * Copyright 2009 Oracle.  All rights reserved.
 *
 * This file is part of nfs-utils.
 *
 * nfs-utils is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * nfs-utils is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with nfs-utils.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef NFS_UTILS_SOCKADDR_H
#define NFS_UTILS_SOCKADDR_H

#include <libio.h>
#include <stdbool.h>
#include <sys/socket.h>
#include <netinet/in.h>

/*
 * This type is for defining buffers that contain network socket
 * addresses.
 *
 * Casting a "struct sockaddr *" to the address of a "struct
 * sockaddr_storage" breaks C aliasing rules.  The "union
 * nfs_sockaddr" type follows C aliasing rules yet specifically
 * allows converting pointers to it between "struct sockaddr *"
 * and a few other network sockaddr-related pointer types.
 *
 * Note that this union is much smaller than a sockaddr_storage.
 * It should be used only for AF_INET or AF_INET6 socket addresses.
 * An AF_LOCAL sockaddr_un, for example, will clearly not fit into
 * a buffer of this type.
 */
union nfs_sockaddr {
	struct sockaddr		sa;
	struct sockaddr_in	s4;
	struct sockaddr_in6	s6;
};

#if SIZEOF_SOCKLEN_T - 0 == 0
#define socklen_t unsigned int
#endif

#define SIZEOF_SOCKADDR_UNKNOWN	(socklen_t)0
#define SIZEOF_SOCKADDR_IN	(socklen_t)sizeof(struct sockaddr_in)

#ifdef IPV6_SUPPORTED
#define SIZEOF_SOCKADDR_IN6	(socklen_t)sizeof(struct sockaddr_in6)
#else	/* !IPV6_SUPPORTED */
#define SIZEOF_SOCKADDR_IN6	SIZEOF_SOCKADDR_UNKNOWN
#endif	/* !IPV6_SUPPORTED */

/**
 * nfs_sockaddr_length - return the size in bytes of a socket address
 * @sap: pointer to socket address
 *
 * Returns the size in bytes of @sap, or zero if the family is
 * not recognized.
 */
static inline socklen_t
nfs_sockaddr_length(const struct sockaddr *sap)
{
	switch (sap->sa_family) {
	case AF_INET:
		return SIZEOF_SOCKADDR_IN;
	case AF_INET6:
		return SIZEOF_SOCKADDR_IN6;
	}
	return SIZEOF_SOCKADDR_UNKNOWN;
}

static inline uint16_t
get_port4(const struct sockaddr *sap)
{
	const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
	return ntohs(sin->sin_port);
}

#ifdef IPV6_SUPPORTED
static inline uint16_t
get_port6(const struct sockaddr *sap)
{
	const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
	return ntohs(sin6->sin6_port);
}
#else	/* !IPV6_SUPPORTED */
static inline uint16_t
get_port6(__attribute__ ((unused)) const struct sockaddr *sap)
{
	return 0;
}
#endif	/* !IPV6_SUPPORTED */

/**
 * nfs_get_port - extract port value from a socket address
 * @sap: pointer to socket address
 *
 * Returns port value in host byte order, or zero if the
 * socket address contains an unrecognized family.
 */
static inline uint16_t
nfs_get_port(const struct sockaddr *sap)
{
	switch (sap->sa_family) {
	case AF_INET:
		return get_port4(sap);
	case AF_INET6:
		return get_port6(sap);
	}
	return 0;
}

static inline void
set_port4(struct sockaddr *sap, const uint16_t port)
{
	struct sockaddr_in *sin = (struct sockaddr_in *)sap;
	sin->sin_port = htons(port);
}

#ifdef IPV6_SUPPORTED
static inline void
set_port6(struct sockaddr *sap, const uint16_t port)
{
	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
	sin6->sin6_port = htons(port);
}
#else	/* !IPV6_SUPPORTED */
static inline void
set_port6(__attribute__ ((unused)) struct sockaddr *sap,
		__attribute__ ((unused)) const uint16_t port)
{
}
#endif	/* !IPV6_SUPPORTED */

/**
 * nfs_set_port - set port value in a socket address
 * @sap: pointer to socket address
 * @port: port value to set
 *
 */
static inline void
nfs_set_port(struct sockaddr *sap, const uint16_t port)
{
	switch (sap->sa_family) {
	case AF_INET:
		set_port4(sap, port);
		break;
	case AF_INET6:
		set_port6(sap, port);
		break;
	}
}

/**
 * nfs_is_v4_loopback - test to see if socket address is AF_INET loopback
 * @sap: pointer to socket address
 *
 * Returns true if the socket address is the standard IPv4 loopback
 * address; otherwise false is returned.
 */
static inline _Bool
nfs_is_v4_loopback(const struct sockaddr *sap)
{
	const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;

	if (sin->sin_family != AF_INET)
		return false;
	if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK))
		return false;
        return true;
}

static inline _Bool
compare_sockaddr4(const struct sockaddr *sa1, const struct sockaddr *sa2)
{
	const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sa1;
	const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sa2;
	return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
}

#ifdef IPV6_SUPPORTED
static inline _Bool
compare_sockaddr6(const struct sockaddr *sa1, const struct sockaddr *sa2)
{
	const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sa1;
	const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sa2;

	if ((IN6_IS_ADDR_LINKLOCAL((char *)&sin1->sin6_addr) &&
	     IN6_IS_ADDR_LINKLOCAL((char *)&sin2->sin6_addr)) ||
	    (IN6_IS_ADDR_SITELOCAL((char *)&sin1->sin6_addr) &&
	     IN6_IS_ADDR_SITELOCAL((char *)&sin2->sin6_addr)))
		if (sin1->sin6_scope_id != sin2->sin6_scope_id)
			return false;

	return IN6_ARE_ADDR_EQUAL((char *)&sin1->sin6_addr,
					(char *)&sin2->sin6_addr);
}
#else	/* !IPV6_SUPPORTED */
static inline _Bool
compare_sockaddr6(__attribute__ ((unused)) const struct sockaddr *sa1,
		__attribute__ ((unused)) const struct sockaddr *sa2)
{
	return false;
}
#endif	/* !IPV6_SUPPORTED */

/**
 * nfs_compare_sockaddr - compare two socket addresses for equality
 * @sa1: pointer to a socket address
 * @sa2: pointer to a socket address
 *
 * Returns true if the two socket addresses contain equivalent
 * network addresses; otherwise false is returned.
 */
static inline _Bool
nfs_compare_sockaddr(const struct sockaddr *sa1, const struct sockaddr *sa2)
{
	if (sa1 == NULL || sa2 == NULL)
		return false;

	if (sa1->sa_family == sa2->sa_family)
		switch (sa1->sa_family) {
		case AF_INET:
			return compare_sockaddr4(sa1, sa2);
		case AF_INET6:
			return compare_sockaddr6(sa1, sa2);
		}

	return false;
}

#endif	/* !NFS_UTILS_SOCKADDR_H */
