/*
 *  Interface MIB architecture support
 *
 * $Id$
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>

#ifdef HAVE_LINUX_ETHTOOL_H
#include <linux/types.h>
typedef __u64 u64;         /* hack, so we may include kernel's ethtool.h */
typedef __u32 u32;         /* ditto */
typedef __u16 u16;         /* ditto */
typedef __u8 u8;           /* ditto */
#include <linux/ethtool.h>
#endif /* HAVE_LINUX_ETHTOOL_H */

#include "mibII/mibII_common.h"
#include "if-mib/ifTable/ifTable_constants.h"

#include <net-snmp/agent/net-snmp-agent-includes.h>

#if HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#else
#error "linux should have sys/ioctl header"
#endif

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

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <linux/sockios.h>

#ifndef IF_NAMESIZE
#define IF_NAMESIZE 16
#endif

unsigned long long
netsnmp_linux_interface_get_if_speed(int fd, const char *name,
        unsigned long long defaultspeed);
#ifdef HAVE_LINUX_ETHTOOL_H
unsigned long long
netsnmp_linux_interface_get_if_speed_mii(int fd, const char *name,
        unsigned long long defaultspeed);
#endif

#define PROC_SYS_NET_IPVx_NEIGH_RETRANS_TIME_MS "/proc/sys/net/ipv%d/neigh/%s/retrans_time_ms"
#define PROC_SYS_NET_IPVx_NEIGH_RETRANS_TIME    "/proc/sys/net/ipv%d/neigh/%s/retrans_time"
static const char *proc_sys_retrans_time;
static unsigned short retrans_time_factor = 1;


#define PROC_SYS_NET_IPVx_BASE_REACHABLE_TIME_MS "/proc/sys/net/ipv%d/neigh/%s/base_reachable_time_ms"
#define PROC_SYS_NET_IPVx_BASE_REACHABLE_TIME "/proc/sys/net/ipv%d/neigh/%s/base_reachable_time"
static const char *proc_sys_basereachable_time;
static unsigned short basereachable_time_ms = 0;
void
netsnmp_arch_interface_init(void)
{
    /*
     * Check which retransmit time interface is available
     */
    char proc_path[ 64+IF_NAMESIZE];
    char proc_path2[64+IF_NAMESIZE];
    struct stat st;

    snprintf(proc_path,  sizeof(proc_path),
             PROC_SYS_NET_IPVx_NEIGH_RETRANS_TIME_MS, 6, "default");
    snprintf(proc_path2, sizeof(proc_path2),
             PROC_SYS_NET_IPVx_NEIGH_RETRANS_TIME_MS, 4, "default");

    if ((stat(proc_path, &st) == 0) || (stat(proc_path2, &st) == 0)) {
        proc_sys_retrans_time = PROC_SYS_NET_IPVx_NEIGH_RETRANS_TIME_MS;
    } else {
        proc_sys_retrans_time = PROC_SYS_NET_IPVx_NEIGH_RETRANS_TIME;
        retrans_time_factor = 10;
    }

    snprintf(proc_path,  sizeof(proc_path),  PROC_SYS_NET_IPVx_BASE_REACHABLE_TIME_MS, 6, "default");
    snprintf(proc_path2,  sizeof(proc_path),  PROC_SYS_NET_IPVx_BASE_REACHABLE_TIME, 4, "default");

    if ((stat(proc_path, &st) == 0) || (stat(proc_path2, &st) == 0)) {
        proc_sys_basereachable_time = PROC_SYS_NET_IPVx_BASE_REACHABLE_TIME_MS;
        basereachable_time_ms = 1;
    }
    else {
        proc_sys_basereachable_time = PROC_SYS_NET_IPVx_BASE_REACHABLE_TIME;
    }
}

/*
 * find the ifIndex for an interface name
 * NOTE: The Linux version is not efficient for large numbers of calls.
 *   consider using netsnmp_access_interface_ioctl_ifindex_get()
 *   for loops which need to look up a lot of indexes.
 *
 * @retval 0 : no index found
 * @retval >0: ifIndex for interface
 */
oid
netsnmp_arch_interface_index_find(const char *name)
{
    return netsnmp_access_interface_ioctl_ifindex_get(-1, name);
}


/*
 * check for ipv6 addresses
 */
void
_arch_interface_has_ipv6(oid if_index, u_int *flags,
                         netsnmp_container *addr_container)
{
#ifdef NETSNMP_ENABLE_IPV6
    netsnmp_ipaddress_entry *addr_entry = NULL;
    netsnmp_iterator        *addr_it = NULL;
    u_int                    addr_container_flags = 0; /* must init to 0 */
#endif

    if (NULL == flags)
        return;

    *flags &= ~NETSNMP_INTERFACE_FLAGS_HAS_IPV6;

#ifndef SIOCGMIIPHY
#define SIOCGMIIPHY 0x8947
#endif

#ifndef SIOCGMIIREG
#define SIOCGMIIREG 0x8948
#endif

#ifdef NETSNMP_ENABLE_IPV6
    /*
     * get ipv6 addresses
     */
    if (NULL == addr_container) {
        /*
         * we only care about ipv6, if we need to allocate our own
         * temporary container. set the flags (which we also use later
         * to determine if we need to free the container).
         */
        addr_container_flags = NETSNMP_ACCESS_IPADDRESS_LOAD_IPV6_ONLY;
        addr_container =
            netsnmp_access_ipaddress_container_load(NULL,
                                                    addr_container_flags);
        if (NULL == addr_container) {
            DEBUGMSGTL(("access:ifcontainer",
                        "couldn't get ip addresses container\n"));
            return;
        }
    }
    else {
        /*
         * addr_container flags must be 0, so we don't release the
         * user's container.
         */
        netsnmp_assert(0 == addr_container_flags);
    }


    /*
     * get an ipaddress container iterator, and look for ipv6 addrs
     */   
    addr_it = CONTAINER_ITERATOR(addr_container);
    if (NULL == addr_it) {
        DEBUGMSGTL(("access:ifcontainer",
                    "couldn't get ip addresses iterator\n"));
        if (0!=addr_container_flags)
            netsnmp_access_ipaddress_container_free(addr_container, 0);
        return;
    }

    addr_entry = ITERATOR_FIRST(addr_it);
    for( ; addr_entry ; addr_entry = ITERATOR_NEXT(addr_it) ) {
        /*
         * skip non matching indexes and ipv4 addresses
         */
        if ((if_index != addr_entry->if_index) ||
            (4 == addr_entry->ia_address_len))
            continue;

        /*
         * found one! no need to keep looking, set the flag and bail
         */
        *flags |= NETSNMP_INTERFACE_FLAGS_HAS_IPV6;
        break;
    }

    /*
     * make mama proud and clean up after ourselves
     */
    ITERATOR_RELEASE(addr_it);
    if (0!=addr_container_flags)
        netsnmp_access_ipaddress_container_free(addr_container, 0);    
#endif
}

/**
 * @internal
 */
static void
_arch_interface_flags_v4_get(netsnmp_interface_entry *entry)
{
    FILE           *fin;
    char            line[256];

    /*
     * get the retransmit time
     */
    snprintf(line,sizeof(line), proc_sys_retrans_time, 4,
             entry->name);
    if (!(fin = fopen(line, "r"))) {
        DEBUGMSGTL(("access:interface",
                    "Failed to open %s\n", line));
    }
    else {
        if (fgets(line, sizeof(line), fin)) {
            entry->retransmit_v4 = atoi(line) * retrans_time_factor;
            entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_V4_RETRANSMIT;
        }
        fclose(fin);
    }
}


#ifdef NETSNMP_ENABLE_IPV6
/**
 * @internal
 */
static void
_arch_interface_flags_v6_get(netsnmp_interface_entry *entry)
{
    FILE           *fin;
    char            line[256];

    /*
     * get the retransmit time
     */
    snprintf(line,sizeof(line), proc_sys_retrans_time, 6,
             entry->name);
    if (!(fin = fopen(line, "r"))) {
        DEBUGMSGTL(("access:interface",
                    "Failed to open %s\n", line));
    }
    else {
        if (fgets(line, sizeof(line), fin)) {
            entry->retransmit_v6 = atoi(line) * retrans_time_factor;
            entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_V6_RETRANSMIT;
        }
        fclose(fin);
    }

    /*
     * get the forwarding status
     */
    snprintf(line, sizeof(line), "/proc/sys/net/ipv6/conf/%s/forwarding",
             entry->name);
    if (!(fin = fopen(line, "r"))) {
        DEBUGMSGTL(("access:interface",
                    "Failed to open %s\n", line));
    }
    else {
        if (fgets(line, sizeof(line), fin)) {
            entry->forwarding_v6 = atoi(line);
            entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_V6_FORWARDING;
        }
        fclose(fin);
    }

    /*
     * get the reachable time
     */
    snprintf(line, sizeof(line), proc_sys_basereachable_time, 6, entry->name);
    if (!(fin = fopen(line, "r"))) {
        DEBUGMSGTL(("access:interface",
                    "Failed to open %s\n", line));
    }
    else {
        if (fgets(line, sizeof(line), fin)) {
            if (basereachable_time_ms) {
                entry->reachable_time = atoi(line); /* millisec */
            } else {
                entry->reachable_time = atoi(line)*1000; /* sec to  millisec */
            }

            entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_V6_REACHABLE;
        }
        fclose(fin);
    }
}
#endif /* NETSNMP_ENABLE_IPV6 */

/**
 * @internal
 */
static int
_parse_stats(netsnmp_interface_entry *entry, char *stats, int expected)
{
    /*
     * scanline_2_2:
     *  [               IN                        ]
     *   byte pkts errs drop fifo frame cmprs mcst |
     *  [               OUT                               ]
     *   byte pkts errs drop fifo colls carrier compressed
     */
#ifdef SCNuMAX
    uintmax_t       rec_pkt, rec_oct, rec_err, rec_drop, rec_mcast;
    uintmax_t       snd_pkt, snd_oct, snd_err, snd_drop, coll;
    const char     *scan_line_2_2 =
        "%"   SCNuMAX " %"  SCNuMAX " %"  SCNuMAX " %"  SCNuMAX
        " %*" SCNuMAX " %*" SCNuMAX " %*" SCNuMAX " %"  SCNuMAX
        " %"  SCNuMAX " %"  SCNuMAX " %"  SCNuMAX " %"  SCNuMAX
        " %*" SCNuMAX " %"  SCNuMAX;
    const char     *scan_line_2_0 =
        "%"   SCNuMAX " %"  SCNuMAX " %*" SCNuMAX " %*" SCNuMAX
        " %*" SCNuMAX " %"  SCNuMAX " %"  SCNuMAX " %*" SCNuMAX
        " %*" SCNuMAX " %"  SCNuMAX;
#else
    unsigned long   rec_pkt, rec_oct, rec_err, rec_drop, rec_mcast;
    unsigned long   snd_pkt, snd_oct, snd_err, snd_drop, coll;
    const char     *scan_line_2_2 =
        "%lu %lu %lu %lu %*lu %*lu %*lu %lu %lu %lu %lu %lu %*lu %lu";
    const char     *scan_line_2_0 =
        "%lu %lu %*lu %*lu %*lu %lu %lu %*lu %*lu %lu";
#endif
    static const char     *scan_line_to_use = NULL;
    int             scan_count;

    if (10 == expected)
        scan_line_to_use = scan_line_2_2;
    else {
        netsnmp_assert(5 == expected);
        scan_line_to_use = scan_line_2_0;
    }

    while (*stats == ' ')
        stats++;

    if ((*stats == 'N') &&
        (0 == strncmp(stats, "No statistics available",
                      strlen("No statistics available"))))
        return -1;

    /*
     * Now parse the rest of the line (i.e. starting from 'stats')
     *      to extract the relevant statistics, and populate
     *      data structure accordingly.
     * Use the entry flags field to indicate which counters are valid
     */
    rec_pkt = rec_oct = rec_err = rec_drop = rec_mcast = 0;
    snd_pkt = snd_oct = snd_err = snd_drop = coll = 0;
    if (scan_line_to_use == scan_line_2_2) {
        scan_count = sscanf(stats, scan_line_to_use,
                            &rec_oct, &rec_pkt, &rec_err, &rec_drop, &rec_mcast,
                            &snd_oct, &snd_pkt, &snd_err, &snd_drop,
                            &coll);
        if (scan_count == expected) {
            entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_BYTES;
            entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_DROPS;
            /*
             *  2.4 kernel includes a single multicast (input) counter?
             */
            entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_MCAST_PKTS;
            entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_HIGH_SPEED;
#ifdef SCNuMAX   /* XXX - should be flag for 64-bit variables */
            entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_HIGH_BYTES;
            entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_HIGH_PACKETS;
#endif
        }
    } else {
        scan_count = sscanf(stats, scan_line_to_use,
                            &rec_pkt, &rec_err,
                            &snd_pkt, &snd_err, &coll);
        if (scan_count == expected) {
            entry->ns_flags &= ~NETSNMP_INTERFACE_FLAGS_HAS_MCAST_PKTS;
            rec_oct = rec_drop = 0;
            snd_oct = snd_drop = 0;
        }
    }
    if(scan_count != expected) {
        snmp_log(LOG_ERR,
                 "error scanning interface data (expected %d, got %d)\n",
                 expected, scan_count);
        return scan_count;
    }
    entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_ACTIVE;
    
    /*
     * linux previous to 1.3.~13 may miss transmitted loopback pkts: 
     */
    if (!strcmp(entry->name, "lo") && rec_pkt > 0 && !snd_pkt)
        snd_pkt = rec_pkt;
    
    /*
     * subtract out multicast packets from rec_pkt before
     * we store it as unicast counter.
     */
    rec_pkt -= rec_mcast;

    entry->stats.ibytes.low = rec_oct & 0xffffffff;
    entry->stats.iucast.low = rec_pkt & 0xffffffff;
    entry->stats.imcast.low = rec_mcast & 0xffffffff;
    entry->stats.obytes.low = snd_oct & 0xffffffff;
    entry->stats.oucast.low = snd_pkt & 0xffffffff;
#ifdef SCNuMAX   /* XXX - should be flag for 64-bit variables */
    entry->stats.ibytes.high = rec_oct >> 32;
    entry->stats.iucast.high = rec_pkt >> 32;
    entry->stats.imcast.high = rec_mcast >> 32;
    entry->stats.obytes.high = snd_oct >> 32;
    entry->stats.oucast.high = snd_pkt >> 32;
#endif
    entry->stats.ierrors   = rec_err;
    entry->stats.idiscards = rec_drop;
    entry->stats.oerrors   = snd_err;
    entry->stats.odiscards = snd_drop;
    entry->stats.collisions = coll;
    
    /*
     * calculated stats.
     *
     *  we have imcast, but not ibcast.
     */
    entry->stats.inucast = entry->stats.imcast.low +
        entry->stats.ibcast.low;
    entry->stats.onucast = entry->stats.omcast.low +
        entry->stats.obcast.low;
    
    return 0;
}

/*
 *
 * @retval  0 success
 * @retval -1 no container specified
 * @retval -2 could not open /proc/net/dev
 * @retval -3 could not create entry (probably malloc)
 */
int
netsnmp_arch_interface_container_load(netsnmp_container* container,
                                      u_int load_flags)
{
    FILE           *devin;
    char            line[256];
    netsnmp_interface_entry *entry = NULL;
    static char     scan_expected = 0;
    int             fd;
#ifdef NETSNMP_ENABLE_IPV6
    netsnmp_container *addr_container;
#endif

    DEBUGMSGTL(("access:interface:container:arch", "load (flags %p)\n",
                load_flags));

    if (NULL == container) {
        snmp_log(LOG_ERR, "no container specified/found for interface\n");
        return -1;
    }

    if (!(devin = fopen("/proc/net/dev", "r"))) {
        DEBUGMSGTL(("access:interface",
                    "Failed to load Interface Table (linux1)\n"));
        snmp_log(LOG_ERR, "cannot open /proc/net/dev ...\n");
        return -2;
    }

    /*
     * create socket for ioctls
     */
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd < 0) {
        snmp_log(LOG_ERR, "could not create socket\n");
        fclose(devin);
        return -2;
    }

#ifdef NETSNMP_ENABLE_IPV6
    /*
     * get ipv6 addresses
     */
    addr_container = netsnmp_access_ipaddress_container_load(NULL, 0);
#endif

    /*
     * Read the first two lines of the file, containing the header
     * This indicates which version of the kernel we're working with,
     * and hence which statistics are actually available.
     *
     * Wes originally suggested parsing the field names in this header
     * to detect the position of individual fields directly,
     * but I suspect this is probably more trouble than it's worth.
     */
    fgets(line, sizeof(line), devin);
    fgets(line, sizeof(line), devin);

    if( 0 == scan_expected ) {
        if (strstr(line, "compressed")) {
            scan_expected = 10;
            DEBUGMSGTL(("access:interface",
                        "using linux 2.2 kernel /proc/net/dev\n"));
        } else {
            scan_expected = 5;
            DEBUGMSGTL(("access:interface",
                        "using linux 2.0 kernel /proc/net/dev\n"));
        }
    }

    /*
     * The rest of the file provides the statistics for each interface.
     * Read in each line in turn, isolate the interface name
     *   and retrieve (or create) the corresponding data structure.
     */
    while (fgets(line, sizeof(line), devin)) {
        char           *stats, *ifstart = line;
        u_int           flags;
        oid             if_index;

        flags = 0;
        if (line[strlen(line) - 1] == '\n')
            line[strlen(line) - 1] = '\0';

        while (*ifstart && *ifstart == ' ')
            ifstart++;

        if ((!*ifstart) || ((stats = strrchr(ifstart, ':')) == NULL)) {
            snmp_log(LOG_ERR,
                     "interface data format error 1, line ==|%s|\n", line);
            continue;
        }
        if ((scan_expected == 10) && ((stats - line) < 6)) {
            snmp_log(LOG_ERR,
                     "interface data format error 2 (%d < 6), line ==|%s|\n",
                     (int)(stats - line), line);
        }

        DEBUGMSGTL(("9:access:ifcontainer", "processing '%s'\n", ifstart));

        /*
         * get index via ioctl.
         * If we've met this interface before, use the same index.
         * Otherwise find an unused index value and use that.
         */
        *stats++ = 0; /* null terminate name */

        if_index = netsnmp_arch_interface_index_find(ifstart);

        /*
         * set address type flags.
         * the only way I know of to check an interface for
         * ip version is to look for ip addresses. If anyone
         * knows a better way, put it here!
         */
#ifdef NETSNMP_ENABLE_IPV6
        _arch_interface_has_ipv6(if_index, &flags, addr_container);
#endif
        netsnmp_access_interface_ioctl_has_ipv4(fd, ifstart, 0, &flags);

        /*
         * do we only want one address type?
         */
        if (((load_flags & NETSNMP_ACCESS_INTERFACE_LOAD_IP4_ONLY) &&
             ((flags & NETSNMP_INTERFACE_FLAGS_HAS_IPV4) == 0)) ||
            ((load_flags & NETSNMP_ACCESS_INTERFACE_LOAD_IP6_ONLY) &&
             ((flags & NETSNMP_INTERFACE_FLAGS_HAS_IPV6) == 0))) {
            DEBUGMSGTL(("9:access:ifcontainer",
                        "interface '%s' excluded by ip version\n",
                        ifstart));
            continue;
        }

        entry = netsnmp_access_interface_entry_create(ifstart, 0);
        if(NULL == entry) {
#ifdef NETSNMP_ENABLE_IPV6
            netsnmp_access_ipaddress_container_free(addr_container, 0);
#endif
            netsnmp_access_interface_container_free(container,
                                                    NETSNMP_ACCESS_INTERFACE_FREE_NOFLAGS);
            fclose(devin);
            close(fd);
            return -3;
        }
        entry->ns_flags = flags; /* initial flags; we'll set more later */

        /*
         * xxx-rks: get descr by linking mem from /proc/pci and /proc/iomem
         */


        /*
         * use ioctls for some stuff
         *  (ignore rc, so we get as much info as possible)
         */
        netsnmp_access_interface_ioctl_physaddr_get(fd, entry);

        /*
         * physaddr should have set type. make some guesses (based
         * on name) if not.
         */
        if(0 == entry->type) {
            typedef struct _match_if {
               int             mi_type;
               const char     *mi_name;
            }              *pmatch_if, match_if;
            
            static match_if lmatch_if[] = {
                {IANAIFTYPE_SOFTWARELOOPBACK, "lo"},
                {IANAIFTYPE_ETHERNETCSMACD, "eth"},
                {IANAIFTYPE_ETHERNETCSMACD, "vmnet"},
                {IANAIFTYPE_ISO88025TOKENRING, "tr"},
                {IANAIFTYPE_FASTETHER, "feth"},
                {IANAIFTYPE_GIGABITETHERNET,"gig"},
                {IANAIFTYPE_INFINIBAND,"ib"},
                {IANAIFTYPE_PPP, "ppp"},
                {IANAIFTYPE_SLIP, "sl"},
                {IANAIFTYPE_TUNNEL, "sit"},
                {IANAIFTYPE_BASICISDN, "ippp"},
                {IANAIFTYPE_PROPVIRTUAL, "bond"}, /* Bonding driver find fastest slave */
                {IANAIFTYPE_PROPVIRTUAL, "vad"},  /* ANS driver - ?speed? */
                {0, 0}                  /* end of list */
            };

            int             len;
            register pmatch_if pm;
            
            for (pm = lmatch_if; pm->mi_name; pm++) {
                len = strlen(pm->mi_name);
                if (0 == strncmp(entry->name, pm->mi_name, len)) {
                    entry->type = pm->mi_type;
                    break;
                }
            }
            if(NULL == pm->mi_name)
                entry->type = IANAIFTYPE_OTHER;
        }

        if (IANAIFTYPE_ETHERNETCSMACD == entry->type) {
            unsigned long long speed;
            unsigned long long defaultspeed = NOMINAL_LINK_SPEED;
            if (!(entry->os_flags & IFF_RUNNING)) {
                /*
                 * use speed 0 if the if speed cannot be determined *and* the
                 * interface is down
                 */
                defaultspeed = 0;
            }
            speed = netsnmp_linux_interface_get_if_speed(fd,
                    entry->name, defaultspeed);
            if (speed > 0xffffffffL) {
                entry->speed = 0xffffffff;
            } else
                entry->speed = speed;
            entry->speed_high = speed / 1000000LL;
        }
#ifdef APPLIED_PATCH_836390   /* xxx-rks ifspeed fixes */
        else if (IANAIFTYPE_PROPVIRTUAL == entry->type)
            entry->speed = _get_bonded_if_speed(entry);
#endif
        else
            netsnmp_access_interface_entry_guess_speed(entry);
        
        netsnmp_access_interface_ioctl_flags_get(fd, entry);

        netsnmp_access_interface_ioctl_mtu_get(fd, entry);

        /*
         * Zero speed means link problem.
         * - i'm not sure this is always true...
         */
        if((entry->speed == 0) && (entry->os_flags & IFF_UP)) {
            entry->os_flags &= ~IFF_RUNNING;
        }

        /*
         * check for promiscuous mode.
         *  NOTE: there are 2 ways to set promiscuous mode in Linux
         *  (kernels later than 2.2.something) - using ioctls and
         *  using setsockopt. The ioctl method tested here does not
         *  detect if an interface was set using setsockopt. google
         *  on IFF_PROMISC and linux to see lots of arguments about it.
         */
        if(entry->os_flags & IFF_PROMISC) {
            entry->promiscuous = 1; /* boolean */
        }

        /*
         * hardcoded max packet size
         * (see ip_frag_reasm: if(len > 65535) goto out_oversize;)
         */
        entry->reasm_max_v4 = entry->reasm_max_v6 = 65535;
        entry->ns_flags |= 
            NETSNMP_INTERFACE_FLAGS_HAS_V4_REASMMAX |
            NETSNMP_INTERFACE_FLAGS_HAS_V6_REASMMAX;

        netsnmp_access_interface_entry_overrides(entry);

        if (! (load_flags & NETSNMP_ACCESS_INTERFACE_LOAD_NO_STATS))
            _parse_stats(entry, stats, scan_expected);

        if (flags & NETSNMP_INTERFACE_FLAGS_HAS_IPV4)
            _arch_interface_flags_v4_get(entry);

#ifdef NETSNMP_ENABLE_IPV6
        if (flags & NETSNMP_INTERFACE_FLAGS_HAS_IPV6)
            _arch_interface_flags_v6_get(entry);
#endif /* NETSNMP_ENABLE_IPV6 */

        /*
         * add to container
         */
        CONTAINER_INSERT(container, entry);
    }
#ifdef NETSNMP_ENABLE_IPV6
    netsnmp_access_ipaddress_container_free(addr_container, 0);
#endif
    fclose(devin);
    close(fd);
    return 0;
}

int
netsnmp_arch_set_admin_status(netsnmp_interface_entry * entry,
                              int ifAdminStatus_val)
{
    int and_complement;
    
    DEBUGMSGTL(("access:interface:arch", "set_admin_status\n"));

    if(IFADMINSTATUS_UP == ifAdminStatus_val)
        and_complement = 0; /* |= */
    else
        and_complement = 1; /* &= ~ */

    return netsnmp_access_interface_ioctl_flags_set(-1, entry,
                                                    IFF_UP, and_complement);
}

#ifdef HAVE_LINUX_ETHTOOL_H
/**
 * Determines network interface speed from ETHTOOL_GSET
 */
unsigned long long
netsnmp_linux_interface_get_if_speed(int fd, const char *name,
            unsigned long long defaultspeed)
{
    int ret;
    struct ifreq ifr;
    struct ethtool_cmd edata;
    uint16_t speed_hi;
    uint32_t speed;

    memset(&ifr, 0, sizeof(ifr));
    memset(&edata, 0, sizeof(edata));
    edata.cmd = ETHTOOL_GSET;
    
    strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
    ifr.ifr_data = (char *) &edata;
    
    ret = ioctl(fd, SIOCETHTOOL, &ifr);
    if (ret == -1 || edata.speed == 0) {
        DEBUGMSGTL(("mibII/interfaces", "ETHTOOL_GSET on %s failed (%d / %d)\n",
                    ifr.ifr_name, ret, edata.speed));
        return netsnmp_linux_interface_get_if_speed_mii(fd,name,defaultspeed);
    }

#ifdef HAVE_STRUCT_ETHTOOL_CMD_SPEED_HI
    speed_hi = edata.speed_hi;
#else
    speed_hi = 0;
#endif
    speed = speed_hi << 16 | edata.speed;
    if (speed == 0xffff || speed == 0xffffffffUL /*SPEED_UNKNOWN*/)
        speed = defaultspeed;
    /* return in bps */
    DEBUGMSGTL(("mibII/interfaces", "ETHTOOL_GSET on %s speed = %#x -> %d\n",
                ifr.ifr_name, speed_hi << 16 | edata.speed, speed));
    return speed * 1000LL * 1000LL;
}
#endif
 
/**
 * Determines network interface speed from MII
 */
unsigned long long
#ifdef HAVE_LINUX_ETHTOOL_H
netsnmp_linux_interface_get_if_speed_mii(int fd, const char *name,
        unsigned long long  defaultspeed)
#else
netsnmp_linux_interface_get_if_speed(int fd, const char *name,
        unsigned long long defaultspeed)
#endif
{
    unsigned long long retspeed = defaultspeed;
    struct ifreq ifr;

    /* the code is based on mii-diag utility by Donald Becker
     * see ftp://ftp.scyld.com/pub/diag/mii-diag.c
     */
    ushort *data = (ushort *)(&ifr.ifr_data);
    unsigned phy_id;
    int mii_reg, i;
    ushort mii_val[32];
    ushort bmcr, bmsr, nway_advert, lkpar;
    const unsigned long long media_speeds[] = {10000000, 10000000, 100000000, 100000000, 10000000, 0};
    /* It corresponds to "10baseT", "10baseT-FD", "100baseTx", "100baseTx-FD", "100baseT4", "Flow-control", 0, */

    strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
    data[0] = 0;
    
    /*
     * SIOCGMIIPHY has been defined since at least kernel 2.4.10 (Sept 2001).
     * It's probably safe to drop the interim SIOCDEVPRIVATE handling now!
     */
    if (ioctl(fd, SIOCGMIIPHY, &ifr) < 0) {
        DEBUGMSGTL(("mibII/interfaces", "SIOCGMIIPHY on %s failed\n",
                    ifr.ifr_name));
        return retspeed;
    }

    /* Begin getting mii register values */
    phy_id = data[0];
    for (mii_reg = 0; mii_reg < 8; mii_reg++){
        data[0] = phy_id;
        data[1] = mii_reg;
        if(ioctl(fd, SIOCGMIIREG, &ifr) <0){
            DEBUGMSGTL(("mibII/interfaces", "SIOCGMIIREG on %s failed\n", ifr.ifr_name));
        }
        mii_val[mii_reg] = data[3];		
    }
    /*Parsing of mii values*/
    /*Invalid basic mode control register*/
    if (mii_val[0] == 0xffff  ||  mii_val[1] == 0x0000) {
        DEBUGMSGTL(("mibII/interfaces", "No MII transceiver present!.\n"));
        return retspeed;
    }
    /* Descriptive rename. */
    bmcr = mii_val[0]; 	  /*basic mode control register*/
    bmsr = mii_val[1]; 	  /* basic mode status register*/
    nway_advert = mii_val[4]; /* autonegotiation advertisement*/
    lkpar = mii_val[5]; 	  /*link partner ability*/
    
    /*Check for link existence, returns 0 if link is absent*/
    if ((bmsr & 0x0016) != 0x0004){
        DEBUGMSGTL(("mibII/interfaces", "No link...\n"));
        retspeed = 0;
        return retspeed;
    }
    
    if(!(bmcr & 0x1000) ){
        DEBUGMSGTL(("mibII/interfaces", "Auto-negotiation disabled.\n"));
        retspeed = bmcr & 0x2000 ? 100000000 : 10000000;
        return retspeed;
    }
    /* Link partner got our advertised abilities */	
    if (lkpar & 0x4000) {
        int negotiated = nway_advert & lkpar & 0x3e0;
        int max_capability = 0;
        /* Scan for the highest negotiated capability, highest priority
           (100baseTx-FDX) to lowest (10baseT-HDX). */
        int media_priority[] = {8, 9, 7, 6, 5}; 	/* media_names[i-5] */
        for (i = 0; media_priority[i]; i++){
            if (negotiated & (1 << media_priority[i])) {
                max_capability = media_priority[i];
                break;
            }
        }
        if (max_capability)
            retspeed = media_speeds[max_capability - 5];
        else
            DEBUGMSGTL(("mibII/interfaces", "No common media type was autonegotiated!\n"));
    }else if(lkpar & 0x00A0){
        retspeed = (lkpar & 0x0080) ? 100000000 : 10000000;
    }
    return retspeed;
}
