/* ----------------------------------------------------------------------- *
 *
 *   Copyright 2001-2006 H. Peter Anvin - All Rights Reserved
 *
 *   This program is free software available under the same license
 *   as the "OpenBSD" operating system, distributed at
 *   http://www.openbsd.org/.
 *
 * ----------------------------------------------------------------------- */

/*
 * recvfrom.c
 *
 * Emulate recvfrom() using recvmsg(), but try to capture the local address
 * since some TFTP clients consider it an error to get the reply from another
 * IP address than the request was sent to.
 *
 */

#include "config.h"             /* Must be included first! */
#include "common/tftpsubs.h"
#include "recvfrom.h"
#ifdef HAVE_MACHINE_PARAM_H
#include <machine/param.h>      /* Needed on some versions of FreeBSD */
#endif

#if defined(HAVE_RECVMSG) && defined(HAVE_MSGHDR_MSG_CONTROL)

#include <sys/uio.h>

#ifdef IP_PKTINFO
# ifndef HAVE_STRUCT_IN_PKTINFO
#  ifdef __linux__
/* Assume this version of glibc simply lacks the definition */
struct in_pktinfo {
    int ipi_ifindex;
    struct in_addr ipi_spec_dst;
    struct in_addr ipi_addr;
};
#  else
#   undef IP_PKTINFO            /* No definition, no way to get it */
#  endif
# endif
#endif

#ifndef CMSG_LEN
# define CMSG_LEN(size)	 (sizeof(struct cmsghdr) + (size))
#endif
#ifndef CMSG_SPACE
# define CMSG_SPACE(size) (sizeof(struct cmsghdr) + (size))
#endif

/*
 * Check to see if this is a valid local address.  If so, we should
 * end up having the same local and remote address when trying to
 * bind to it.
 */
static int address_is_local(const union sock_addr *addr)
{
    union sock_addr sa;
    int sockfd = -1;
    int e;
    int rv = 0;
    socklen_t addrlen;

    /* Multicast or universal broadcast address? */
    if (addr->sa.sa_family == AF_INET) {
        if (ntohl(addr->si.sin_addr.s_addr) >= (224UL << 24))
            return 0;
    }
#ifdef HAVE_IPV6
    else if (addr->sa.sa_family == AF_INET6) {
        if (IN6_IS_ADDR_MULTICAST(&addr->s6.sin6_addr))
            return 0;
    }
#endif
    else
        return 0;

    sockfd = socket(addr->sa.sa_family, SOCK_DGRAM, 0);
    if (sockfd < 0)
        goto err;

    if (connect(sockfd, &addr->sa, SOCKLEN(addr)))
        goto err;

    addrlen = SOCKLEN(addr);
    if (getsockname(sockfd, (struct sockaddr *)&sa, &addrlen))
        goto err;

    if (addr->sa.sa_family == AF_INET)
        rv = sa.si.sin_addr.s_addr == addr->si.sin_addr.s_addr;
#ifdef HAVE_IPV6
    else if (addr->sa.sa_family == AF_INET6)
        rv = IN6_ARE_ADDR_EQUAL(&sa.s6.sin6_addr, &addr->s6.sin6_addr);
#endif
    else
        rv = 0;
  err:
    e = errno;

    if (sockfd >= 0)
        close(sockfd);

    errno = e;
    return rv;
}

int
myrecvfrom(int s, void *buf, int len, unsigned int flags,
           struct sockaddr *from, socklen_t * fromlen,
           union sock_addr *myaddr)
{
    struct msghdr msg;
    struct iovec iov;
    int n;
    struct cmsghdr *cmptr;
    union {
        struct cmsghdr cm;
#ifdef IP_PKTINFO
        char control[CMSG_SPACE(sizeof(struct in_addr)) +
                     CMSG_SPACE(sizeof(struct in_pktinfo))];
#else
        char control[CMSG_SPACE(sizeof(struct in_addr))];
#endif
#ifdef HAVE_IPV6
#ifdef HAVE_STRUCT_IN6_PKTINFO
        char control6[CMSG_SPACE(sizeof(struct in6_addr)) +
                     CMSG_SPACE(sizeof(struct in6_pktinfo))];
#else
        char control6[CMSG_SPACE(sizeof(struct in6_addr))];
#endif
#endif
    } control_un;
    int on = 1;
#ifdef IP_PKTINFO
    struct in_pktinfo pktinfo;
#endif
#ifdef HAVE_STRUCT_IN6_PKTINFO
    struct in6_pktinfo pktinfo6;
#endif

    /* Try to enable getting the return address */
#ifdef IP_RECVDSTADDR
    if (from->sa_family == AF_INET)
        setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on));
#endif
#ifdef IP_PKTINFO
    if (from->sa_family == AF_INET)
        setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on));
#endif
#ifdef HAVE_IPV6
#ifdef IPV6_RECVPKTINFO
    if (from->sa_family == AF_INET6)
        setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on));
#endif
#endif
    bzero(&msg, sizeof msg);    /* Clear possible system-dependent fields */
    msg.msg_control = control_un.control;
    msg.msg_controllen = sizeof(control_un);
    msg.msg_flags = 0;

    msg.msg_name = from;
    msg.msg_namelen = *fromlen;
    iov.iov_base = buf;
    iov.iov_len = len;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;

    if ((n = recvmsg(s, &msg, flags)) < 0)
        return n;               /* Error */

    *fromlen = msg.msg_namelen;

    if (myaddr) {
        bzero(myaddr, sizeof(*myaddr));
        myaddr->sa.sa_family = from->sa_family;

        if (msg.msg_controllen < sizeof(struct cmsghdr) ||
            (msg.msg_flags & MSG_CTRUNC))
            return n;           /* No information available */

        for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;
             cmptr = CMSG_NXTHDR(&msg, cmptr)) {

            if (from->sa_family == AF_INET) {
                myaddr->sa.sa_family = AF_INET;
#ifdef IP_RECVDSTADDR
                if (cmptr->cmsg_level == IPPROTO_IP &&
                    cmptr->cmsg_type == IP_RECVDSTADDR) {
                    memcpy(&myaddr->si.sin_addr, CMSG_DATA(cmptr),
                           sizeof(struct in_addr));
                }
#endif

#ifdef IP_PKTINFO
                if (cmptr->cmsg_level == IPPROTO_IP &&
                    cmptr->cmsg_type == IP_PKTINFO) {
                    memcpy(&pktinfo, CMSG_DATA(cmptr),
                           sizeof(struct in_pktinfo));
                    memcpy(&myaddr->si.sin_addr, &pktinfo.ipi_addr,
                           sizeof(struct in_addr));
                }
#endif
            }
#ifdef HAVE_IPV6
            else if (from->sa_family == AF_INET6) {
                myaddr->sa.sa_family = AF_INET6;
#ifdef IP6_RECVDSTADDR
                if (cmptr->cmsg_level == IPPROTO_IPV6 &&
                    cmptr->cmsg_type == IPV6_RECVDSTADDR )
                    memcpy(&myaddr->s6.sin6_addr, CMSG_DATA(cmptr),
                           sizeof(struct in6_addr));
#endif

#ifdef HAVE_STRUCT_IN6_PKTINFO
                if (cmptr->cmsg_level == IPPROTO_IPV6 &&
                    (cmptr->cmsg_type == IPV6_RECVPKTINFO ||
                     cmptr->cmsg_type == IPV6_PKTINFO)) {
                    memcpy(&pktinfo6, CMSG_DATA(cmptr),
                           sizeof(struct in6_pktinfo));
                    memcpy(&myaddr->s6.sin6_addr, &pktinfo6.ipi6_addr,
                           sizeof(struct in6_addr));
                }
#endif
            }
#endif
        }
        /* If the address is not a valid local address,
         * then bind to any address...
         */
        if (address_is_local(myaddr) != 1) {
            if (myaddr->sa.sa_family == AF_INET)
                ((struct sockaddr_in *)myaddr)->sin_addr.s_addr = INADDR_ANY;
#ifdef HAVE_IPV6
            else if (myaddr->sa.sa_family == AF_INET6)
                memset(&myaddr->s6.sin6_addr, 0, sizeof(struct in6_addr));
#endif
        }
    }
    return n;
}

#else                           /* pointless... */

int
myrecvfrom(int s, void *buf, int len, unsigned int flags,
           struct sockaddr *from, int *fromlen, union sock_addr *myaddr)
{
    /* There is no way we can get the local address, fudge it */

    bzero(myaddr, sizeof(*myaddr));
    myaddr->sa.sa_family = from->sa_family;
    sa_set_port(myaddr, htons(IPPORT_TFTP));

    return recvfrom(s, buf, len, flags, from, fromlen);
}

#endif
