/*
 *  Interface MIB architecture support
 *
 * $Id$
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include "mibII/mibII_common.h"
#include "if-mib/ifTable/ifTable_constants.h"

#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/data_access/interface.h>
#include <net-snmp/data_access/ipaddress.h>
#include "if-mib/data_access/interface.h"

#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#ifdef HAVE_NET_IF_ARP_H
#include <net/if_arp.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif

#include "interface_ioctl.h"
#include "ip-mib/data_access/ipaddress_ioctl.h"

/**
 * ioctl wrapper
 *
 * @param      fd : socket fd to use w/ioctl, or -1 to open/close one
 * @param  which
 * @param ifrq
 * param ifentry : ifentry to update
 * @param name
 *
 * @retval  0 : success
 * @retval -1 : invalid parameters
 * @retval -2 : couldn't create socket
 * @retval -3 : ioctl call failed
 */
static int
_ioctl_get(int fd, int which, struct ifreq *ifrq, const char* name)
{
    int ourfd = -1, rc = 0;

    DEBUGMSGTL(("verbose:access:interface:ioctl",
                "ioctl %d for %s\n", which, name));

    /*
     * sanity checks
     */
    if(NULL == name) {
        snmp_log(LOG_ERR, "invalid ifentry\n");
        return -1;
    }

    /*
     * create socket for ioctls
     */
    if(fd < 0) {
        fd = ourfd = socket(AF_INET, SOCK_DGRAM, 0);
        if(ourfd < 0) {
            snmp_log(LOG_ERR,"couldn't create socket\n");
            return -2;
        }
    }

    strlcpy(ifrq->ifr_name, name, sizeof(ifrq->ifr_name));
    rc = ioctl(fd, which, ifrq);
    if (rc < 0) {
        snmp_log(LOG_ERR,"ioctl %d returned %d\n", which, rc);
        rc = -3;
    }

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

    return rc;
}

#ifdef SIOCGIFHWADDR
/**
 * interface entry physaddr ioctl wrapper
 *
 * @param      fd : socket fd to use w/ioctl, or -1 to open/close one
 * @param ifentry : ifentry to update
 *
 * @retval  0 : success
 * @retval -1 : invalid parameters
 * @retval -2 : couldn't create socket
 * @retval -3 : ioctl call failed
 * @retval -4 : malloc error
 */
int
netsnmp_access_interface_ioctl_physaddr_get(int fd,
                                            netsnmp_interface_entry *ifentry)
{
    struct ifreq    ifrq;
    int rc = 0;

    DEBUGMSGTL(("access:interface:ioctl", "physaddr_get\n"));

    if((NULL != ifentry->paddr) &&
       (ifentry->paddr_len != IFHWADDRLEN)) {
        SNMP_FREE(ifentry->paddr);
    }
    if(NULL == ifentry->paddr) 
        ifentry->paddr = malloc(IFHWADDRLEN);

    if(NULL == ifentry->paddr) {
            rc = -4;
    } else {

        /*
         * NOTE: this ioctl does not guarantee 6 bytes of a physaddr.
         * In particular, a 'sit0' interface only appears to get back
         * 4 bytes of sa_data. Uncomment this memset, and suddenly
         * the sit interface will be 0:0:0:0:?:? where ? is whatever was
         * in the memory before. Not sure if this memset should be done
         * for every ioctl, as the rest seem to work ok...
         */
        memset(ifrq.ifr_hwaddr.sa_data, (0), IFHWADDRLEN);
        ifentry->paddr_len = IFHWADDRLEN;
        rc = _ioctl_get(fd, SIOCGIFHWADDR, &ifrq, ifentry->name);
        if (rc < 0) {
            memset(ifentry->paddr, (0), IFHWADDRLEN);
            rc = -3; /* msg already logged */
        }
        else {
            memcpy(ifentry->paddr, ifrq.ifr_hwaddr.sa_data, IFHWADDRLEN);

            /*
             * arphrd defines vary greatly. ETHER seems to be the only common one
             */
#ifdef ARPHRD_ETHER
            switch (ifrq.ifr_hwaddr.sa_family) {
            case ARPHRD_ETHER:
                ifentry->type = IANAIFTYPE_ETHERNETCSMACD;
                break;
#if defined(ARPHRD_TUNNEL) || defined(ARPHRD_IPGRE) || defined(ARPHRD_SIT)
#ifdef ARPHRD_TUNNEL
            case ARPHRD_TUNNEL:
            case ARPHRD_TUNNEL6:
#endif
#ifdef ARPHRD_IPGRE
            case ARPHRD_IPGRE:
#endif
#ifdef ARPHRD_SIT
            case ARPHRD_SIT:
#endif
                ifentry->type = IANAIFTYPE_TUNNEL;
                break;          /* tunnel */
#endif
#ifdef ARPHRD_INFINIBAND
            case ARPHRD_INFINIBAND:
                ifentry->type = IANAIFTYPE_INFINIBAND;
                break;
#endif
#ifdef ARPHRD_SLIP
            case ARPHRD_SLIP:
            case ARPHRD_CSLIP:
            case ARPHRD_SLIP6:
            case ARPHRD_CSLIP6:
                ifentry->type = IANAIFTYPE_SLIP;
                break;          /* slip */
#endif
#ifdef ARPHRD_PPP
            case ARPHRD_PPP:
                ifentry->type = IANAIFTYPE_PPP;
                break;          /* ppp */
#endif
#ifdef ARPHRD_LOOPBACK
            case ARPHRD_LOOPBACK:
                ifentry->type = IANAIFTYPE_SOFTWARELOOPBACK;
                break;          /* softwareLoopback */
#endif
#ifdef ARPHRD_FDDI
            case ARPHRD_FDDI:
                ifentry->type = IANAIFTYPE_FDDI;
                break;
#endif
#ifdef ARPHRD_ARCNET
            case ARPHRD_ARCNET:
                ifentry->type = IANAIFTYPE_ARCNET;
                break;
#endif
#ifdef ARPHRD_LOCALTLK
            case ARPHRD_LOCALTLK:
                ifentry->type = IANAIFTYPE_LOCALTALK;
                break;
#endif
#ifdef ARPHRD_HIPPI
            case ARPHRD_HIPPI:
                ifentry->type = IANAIFTYPE_HIPPI;
                break;
#endif
#ifdef ARPHRD_ATM
            case ARPHRD_ATM:
                ifentry->type = IANAIFTYPE_ATM;
                break;
#endif
                /*
                 * XXX: more if_arp.h:ARPHRD_xxx to IANAifType mappings... 
                 */
            default:
                DEBUGMSGTL(("access:interface:ioctl", "unknown entry type %d\n",
                            ifrq.ifr_hwaddr.sa_family));
		ifentry->type = IANAIFTYPE_OTHER;
            } /* switch */
#endif /* ARPHRD_LOOPBACK */

        }
    }

    return rc;
}
#endif /* SIOCGIFHWADDR */


#ifdef SIOCGIFFLAGS
/**
 * interface entry flags ioctl wrapper
 *
 * @param      fd : socket fd to use w/ioctl, or -1 to open/close one
 * @param ifentry : ifentry to update
 *
 * @retval  0 : success
 * @retval -1 : invalid parameters
 * @retval -2 : couldn't create socket
 * @retval -3 : ioctl call failed
 */
int
netsnmp_access_interface_ioctl_flags_get(int fd,
                                         netsnmp_interface_entry *ifentry)
{
    struct ifreq    ifrq;
    int rc = 0;

    DEBUGMSGTL(("access:interface:ioctl", "flags_get\n"));

    rc = _ioctl_get(fd, SIOCGIFFLAGS, &ifrq, ifentry->name);
    if (rc < 0) {
        ifentry->ns_flags &= ~NETSNMP_INTERFACE_FLAGS_HAS_IF_FLAGS;
        return rc; /* msg already logged */
    }
    else {
        ifentry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_IF_FLAGS;
        ifentry->os_flags = ifrq.ifr_flags;

        /*
         * ifOperStatus description:
         *   If ifAdminStatus is down(2) then ifOperStatus should be down(2).
         */
        if(ifentry->os_flags & IFF_UP) {
            ifentry->admin_status = IFADMINSTATUS_UP;
            if(ifentry->os_flags & IFF_RUNNING)
                ifentry->oper_status = IFOPERSTATUS_UP;
            else
                ifentry->oper_status = IFOPERSTATUS_DOWN;
        }
        else {
            ifentry->admin_status = IFADMINSTATUS_DOWN;
            ifentry->oper_status = IFOPERSTATUS_DOWN;
        }

        /*
         * ifConnectorPresent description:
         *   This object has the value 'true(1)' if the interface sublayer has a
         *   physical connector and the value 'false(2)' otherwise."
         * So, at very least, false(2) should be returned for loopback devices.
         */
        if(ifentry->os_flags & IFF_LOOPBACK) {
            ifentry->connector_present = 0;
        }
        else {	
            ifentry->connector_present = 1;
        }
    }
    
    return rc;
}

/**
 * interface entry flags ioctl wrapper
 *
 * @param      fd : socket fd to use w/ioctl, or -1 to open/close one
 * @param ifentry : ifentry to update
 *
 * @retval  0 : success
 * @retval -1 : invalid parameters
 * @retval -2 : couldn't create socket
 * @retval -3 : ioctl get call failed
 * @retval -4 : ioctl set call failed
 */
int
netsnmp_access_interface_ioctl_flags_set(int fd,
                                         netsnmp_interface_entry *ifentry,
                                         unsigned int flags, int and_complement)
{
    struct ifreq    ifrq;
    int ourfd = -1, rc = 0;

    DEBUGMSGTL(("access:interface:ioctl", "flags_set\n"));

    /*
     * sanity checks
     */
    if((NULL == ifentry) || (NULL == ifentry->name)) {
        snmp_log(LOG_ERR, "invalid ifentry\n");
        return -1;
    }

    /*
     * create socket for ioctls
     */
    if(fd < 0) {
        fd = ourfd = socket(AF_INET, SOCK_DGRAM, 0);
        if(ourfd < 0) {
            snmp_log(LOG_ERR,"couldn't create socket\n");
            return -2;
        }
    }

    strlcpy(ifrq.ifr_name, ifentry->name, sizeof(ifrq.ifr_name));
    rc = ioctl(fd, SIOCGIFFLAGS, &ifrq);
    if(rc < 0) {
        snmp_log(LOG_ERR,"error getting flags\n");
        close(fd);
        return -3;
    }
    if(0 == and_complement)
        ifrq.ifr_flags |= flags;
    else
        ifrq.ifr_flags &= ~flags;
    rc = ioctl(fd, SIOCSIFFLAGS, &ifrq);
    if(rc < 0) {
        close(fd);
        snmp_log(LOG_ERR,"error setting flags\n");
        ifentry->os_flags = 0;
        return -4;
    }

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

    ifentry->os_flags = ifrq.ifr_flags;

    return 0;
}
#endif /* SIOCGIFFLAGS */

#ifdef SIOCGIFMTU
/**
 * interface entry mtu ioctl wrapper
 *
 * @param      fd : socket fd to use w/ioctl, or -1 to open/close one
 * @param ifentry : ifentry to update
 *
 * @retval  0 : success
 * @retval -1 : invalid parameters
 * @retval -2 : couldn't create socket
 * @retval -3 : ioctl call failed
 */
int
netsnmp_access_interface_ioctl_mtu_get(int fd,
                                       netsnmp_interface_entry *ifentry)
{
    struct ifreq    ifrq;
    int rc = 0;

    DEBUGMSGTL(("access:interface:ioctl", "mtu_get\n"));

    rc = _ioctl_get(fd, SIOCGIFMTU, &ifrq, ifentry->name);
    if (rc < 0) {
        ifentry->mtu = 0;
        return rc; /* msg already logged */
    }
    else {
        ifentry->mtu = ifrq.ifr_mtu;
    }

    return rc;
}
#endif /* SIOCGIFMTU */

/**
 * interface entry ifIndex ioctl wrapper
 *
 * @param      fd : socket fd to use w/ioctl, or -1 to open/close one
 * @param name   : ifentry to update
 *
 * @retval  0 : not found
 * @retval !0 : ifIndex
 */
oid
netsnmp_access_interface_ioctl_ifindex_get(int fd, const char *name)
{
#ifndef SIOCGIFINDEX
    return 0;
#else
    struct ifreq    ifrq;
    int rc = 0;

    DEBUGMSGTL(("access:interface:ioctl", "ifindex_get\n"));

    rc = _ioctl_get(fd, SIOCGIFINDEX, &ifrq, name);
    if (rc < 0) {
        DEBUGMSGTL(("access:interface:ioctl",
                   "ifindex_get error on interface '%s'\n", name));
        return 0;
    }

#if defined(__FreeBSD__)    /* ? Should use HAVE_STRUCT_IFREQ_IFR_INDEX */
    return ifrq.ifr_index;
#else
    return ifrq.ifr_ifindex;
#endif
#endif /* SIOCGIFINDEX */
}

/**
 * check an interface for ipv4 addresses
 *
 * @param sd      : open socket descriptor
 * @param if_name : optional name. takes precedent over if_index.
 * @param if_index: optional if index. only used if no if_name specified
 * @param flags   :
 *
 * @retval < 0 : error
 * @retval   0 : no ip v4 addresses
 * @retval   1 : 1 or more ip v4 addresses
 */
int
netsnmp_access_interface_ioctl_has_ipv4(int sd, const char *if_name,
                                        int if_index, u_int *flags)
{
    int             i, interfaces = 0;
    struct ifconf   ifc;
    struct ifreq   *ifrp;

    /*
     * one or the other
     */
    if ((NULL == flags) ||
        ((0 == if_index) && (NULL == if_name))) {
        return -1;
    }

    interfaces = netsnmp_access_ipaddress_ioctl_get_interface_count(sd, &ifc);
    if(interfaces < 0) {
        close(sd);
        return -2;
    }
    netsnmp_assert(NULL != ifc.ifc_buf);

    *flags &= ~NETSNMP_INTERFACE_FLAGS_HAS_IPV4;

    ifrp = ifc.ifc_req;
    for(i=0; i < interfaces; ++i, ++ifrp) {

        DEBUGMSGTL(("access:ipaddress:container",
                    " interface %d, %s\n", i, ifrp->ifr_name));

        /*
         * search for matching if_name or if_index
         */
        if (NULL != if_name) {
            if  (strncmp(if_name, ifrp->ifr_name, sizeof(ifrp->ifr_name)) != 0)
                continue;
        }
        else {
            /*
             * I think that Linux and Solaris both use ':' in the
             * interface name for aliases.
             */
            char *ptr = strchr(ifrp->ifr_name, ':');
            if (NULL != ptr)
                *ptr = 0;
            
            if (if_index !=
                netsnmp_access_interface_ioctl_ifindex_get(sd, ifrp->ifr_name))
                continue;
        }

        /*
         * check and set v4 or v6 flag, and break if we've found both
         */
        if (AF_INET == ifrp->ifr_addr.sa_family) {
            *flags |= NETSNMP_INTERFACE_FLAGS_HAS_IPV4;
            break;
        }
    }

    /*
     * clean up
     */
    free(ifc.ifc_buf);

    return 0;
}
