/*
 *  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 inerface '%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;
}
