/*
 * standard Net-SNMP includes 
 */

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

/*
 * include our parent header 
 */
#include "etherlike-mib/dot3StatsTable/dot3StatsTable.h"
#include "etherlike-mib/dot3StatsTable/dot3StatsTable_data_access.h"
#include "etherlike-mib/dot3StatsTable/ioctl_imp_common.h"

/*
 * @retval  0 success
 * @retval -1 getifaddrs failed 
 * @retval -2 memory allocation failed
 */

struct ifname *
dot3stats_interface_name_list_get (struct ifname *list_head, int *retval)
{
    struct ifaddrs *addrs = NULL, *p = NULL;
    struct ifname *nameptr1=NULL, *nameptr2 = NULL;

    DEBUGMSGTL(("access:dot3StatsTable:interface_name_list_get",
                "called\n"));

    if ((getifaddrs(&addrs)) < 0) {
        DEBUGMSGTL(("access:dot3StatsTable:interface_name_list_get",
                    "getifaddrs failed\n"));
        snmp_log (LOG_ERR, "access:dot3StatsTable,interface_name_list_get, getifaddrs failed\n");
        *retval = -1;
        return NULL;
    }

    for (p = addrs; p; p = p->ifa_next) {

        if (!list_head) {
            list_head = malloc(sizeof(struct ifname));
            if (!list_head) {
                DEBUGMSGTL(("access:dot3StatsTable:interface_name_list_get",
                            "memory allocation failed\n"));
                snmp_log (LOG_ERR, "access:dot3StatsTable,interface_name_list_get, memory allocation failed\n");
                freeifaddrs(addrs);
                *retval = -2;
                return NULL;
            }
            memset(list_head, 0, sizeof (struct ifname));
            strlcpy(list_head->name, p->ifa_name, IF_NAMESIZE);
            continue;
        }

         for (nameptr1 = list_head; nameptr1; nameptr2 = nameptr1, nameptr1 = nameptr1->ifn_next)
            if (!strncmp(p->ifa_name, nameptr1->name, IF_NAMESIZE))
                break;

        if (nameptr1)
            continue;

        nameptr2->ifn_next = malloc(sizeof(struct ifname));
        if (!nameptr2->ifn_next) {
            DEBUGMSGTL(("access:dot3StatsTable:interface_name_list_get",
                        "memory allocation failed\n"));
            snmp_log (LOG_ERR, "access:dot3StatsTable,interface_name_list_get, memory allocation failed\n");
            dot3stats_interface_name_list_free (list_head);
            freeifaddrs(addrs);
            *retval = -2;
            return NULL;
        }
        nameptr2 = nameptr2->ifn_next;
        memset(nameptr2, 0, sizeof (struct ifname));
        strlcpy(nameptr2->name, p->ifa_name, IF_NAMESIZE);
        continue;

    }

    freeifaddrs(addrs);
    return list_head;
}

/*
 * @retval 0 success
 * @retval -1 invalid pointer
 */

int
dot3stats_interface_name_list_free (struct ifname *list_head)
{
    struct ifname *nameptr1 = NULL, *nameptr2 = NULL;

    DEBUGMSGTL(("access:dot3StatsTable:interface_name_list_free",
                "called\n"));

    if (!list_head) {
        snmp_log (LOG_ERR, "access:dot3StatsTable:interface_name_list_free: invalid pointer list_head");
        DEBUGMSGTL(("access:dot3StatsTable:interface_name_list_free",
                    "invalid pointer list_head\n"));
        return -1;
    }

    for (nameptr1 = list_head; nameptr1; nameptr1 = nameptr2) {
            nameptr2 = nameptr1->ifn_next;
            free (nameptr1);
    }

    return 0;
}

/*
 * @retval  0 : not found
 * @retval !0 : ifIndex
 */

int 
dot3stats_interface_ioctl_ifindex_get (int fd, const char *name) {
#ifndef SIOCGIFINDEX
    return 0;
#else
    struct ifreq    ifrq;
    int rc = 0;

    DEBUGMSGTL(("access:dot3StatsTable:interface_ioctl_ifindex_get", "called\n"));
                 
    rc = _dot3Stats_ioctl_get(fd, SIOCGIFINDEX, &ifrq, name);
    if (rc < 0) {
        DEBUGMSGTL(("access:dot3StatsTable:interface_ioctl_ifindex_get",
                    "error on interface '%s'\n", name));
        snmp_log (LOG_ERR, "access:dot3StatsTable:interface_ioctl_ifindex_get, error on interface '%s'\n", name);
        return 0;

    }

    return ifrq.ifr_ifindex;
#endif /* SIOCGIFINDEX */
}

# if HAVE_LINUX_RTNETLINK_H /* { NETLINK */
/*
 * The following code is based upon code I got from Stephen Hemminger
 */
#include <linux/rtnetlink.h>
#include <errno.h>

struct rtnl_handle {
    int                     fd;
    struct sockaddr_nl      local;
    struct sockaddr_nl      peer;
    __u32                   seq;
    __u32                   dump;
};

struct ifstat_ent {
    struct ifstat_ent *next;
    const char *name;
    int ifindex;
    struct rtnl_link_stats stats;
};

typedef int (*rtnl_filter_t)(const struct sockaddr_nl *, struct nlmsghdr *n, void *);

struct rtnl_dump_filter_arg
{
    rtnl_filter_t filter;
    void *arg1;
    rtnl_filter_t junk;
    void *arg2;
};

static struct ifstat_ent *kern_db;
static const int rcvbuf_size = 1024 * 1024;

static int
rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol)
{
    socklen_t addr_len;
    int sndbuf = 32768;

    memset(rth, 0, sizeof(*rth));

    rth->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
    if (rth->fd < 0) {
        snmp_log(LOG_ERR, "Cannot open netlink socket");
        return -1;
    }

    if (setsockopt(rth->fd,SOL_SOCKET,SO_SNDBUF,&sndbuf,sizeof(sndbuf)) < 0) {
        snmp_log(LOG_ERR, "SO_SNDBUF");
        return -1;
    }

    if (setsockopt(rth->fd,SOL_SOCKET,SO_RCVBUF,&rcvbuf_size,sizeof(rcvbuf_size)) < 0) {
        snmp_log(LOG_ERR, "SO_RCVBUF");
        return -1;
    }

    memset(&rth->local, 0, sizeof(rth->local));
    rth->local.nl_family = AF_NETLINK;
    rth->local.nl_groups = subscriptions;

    if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) {
        snmp_log(LOG_ERR, "Cannot bind netlink socket");
        return -1;
    }
    addr_len = sizeof(rth->local);
    if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) {
        snmp_log(LOG_ERR, "Cannot getsockname");
        return -1;
    }
    if (addr_len != sizeof(rth->local)) {
        snmp_log(LOG_ERR, "Wrong address length %d\n", addr_len);
        return -1;
    }
    if (rth->local.nl_family != AF_NETLINK) {
        snmp_log(LOG_ERR, "Wrong address family %d\n", rth->local.nl_family);
        return -1;
    }
    rth->seq = time(NULL);
    return 0;
}

static int
rtnl_open(struct rtnl_handle *rth, unsigned subscriptions)
{
    return rtnl_open_byproto(rth, subscriptions, NETLINK_ROUTE);
}

static void
rtnl_close(struct rtnl_handle *rth)
{
    if (rth->fd != -1)
        close(rth->fd);
    rth->fd = -1;

    return;
}

static int
rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
{
    struct {
        struct nlmsghdr nlh;
        struct rtgenmsg g;
    } req;

    memset(&req, 0, sizeof(req));
    req.nlh.nlmsg_len = sizeof(req);
    req.nlh.nlmsg_type = type;
    req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
    req.nlh.nlmsg_pid = 0;
    req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
    req.g.rtgen_family = family;

    return send(rth->fd, (void*)&req, sizeof(req), 0);
}

static int
parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
{
    memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
    while (RTA_OK(rta, len))
    {
        if (rta->rta_type <= max)
            tb[rta->rta_type] = rta;
        rta = RTA_NEXT(rta,len);
    }

    if (len)
        snmp_log(LOG_ERR, "parse_rtattr: !!!Deficit %d, rta_len=%d\n", len, rta->rta_len);

    return 0;
}

static int
get_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *m, void *arg)
{
    struct ifinfomsg *ifi = NLMSG_DATA(m);
    struct rtattr * tb[IFLA_MAX+1];
    int len = m->nlmsg_len;
    struct ifstat_ent *n;

    if (m->nlmsg_type != RTM_NEWLINK)
        return 0;

    len -= NLMSG_LENGTH(sizeof(*ifi));
    if (len < 0)
        return -1;

    parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
    if (tb[IFLA_IFNAME] == NULL || tb[IFLA_STATS] == NULL)
        return 0;

    n = malloc(sizeof(*n));
    memset(n, 0, sizeof(*n));

    n->ifindex = ifi->ifi_index;
    n->name = strdup(RTA_DATA(tb[IFLA_IFNAME]));
    memcpy(&n->stats, RTA_DATA(tb[IFLA_STATS]), sizeof(n->stats));
    n->next = kern_db;
    kern_db = n;
    return 0;
}

static int
rtnl_dump_filter_l(struct rtnl_handle *rth,
                   const struct rtnl_dump_filter_arg *arg)
{
    struct sockaddr_nl nladdr;
    struct iovec iov;
    struct msghdr msg = {
        .msg_name = &nladdr,
        .msg_namelen = sizeof(nladdr),
        .msg_iov = &iov,
        .msg_iovlen = 1,
    };
    char buf[16384];

    iov.iov_base = buf;
    while (1) {
        int status;
        const struct rtnl_dump_filter_arg *a;

        iov.iov_len = sizeof(buf);
        status = recvmsg(rth->fd, &msg, 0);

        if (status < 0) {
            if (errno == EINTR || errno == EAGAIN)
                continue;
            fprintf(stderr, "netlink receive error %s (%d)\n",
                            strerror(errno), errno);
            return -1;
        }

        if (status == 0) {
            fprintf(stderr, "EOF on netlink\n");
            return -1;
        }

        for (a = arg; a->filter; a++) {
            struct nlmsghdr *h = (struct nlmsghdr*)buf;

            while (NLMSG_OK(h, status)) {
                int err;

                if (nladdr.nl_pid != 0 ||
                     h->nlmsg_pid != rth->local.nl_pid ||
                     h->nlmsg_seq != rth->dump) {
                    if (a->junk) {
                        err = a->junk(&nladdr, h, a->arg2);
                        if (err < 0)
                            return err;
                    }
                    goto skip_it;
                }

                if (h->nlmsg_type == NLMSG_DONE)
                    return 0;
                if (h->nlmsg_type == NLMSG_ERROR) {
                    struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
                    if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
                        fprintf(stderr, "ERROR truncated\n");
                    } else {
                        errno = -err->error;
                        perror("RTNETLINK answers");
                    }
                    return -1;
                }
                err = a->filter(&nladdr, h, a->arg1);
                if (err < 0)
                    return err;

skip_it:
                h = NLMSG_NEXT(h, status);
            }
        } while (0);
        if (msg.msg_flags & MSG_TRUNC) {
            fprintf(stderr, "Message truncated\n");
            continue;
        }
        if (status) {
            fprintf(stderr, "!!!Remnant of size %d\n", status);
            exit(1);
        }
    }
}

static int
rtnl_dump_filter(struct rtnl_handle *rth,
                 rtnl_filter_t filter,
                 void *arg1,
                 rtnl_filter_t junk,
                 void *arg2)
{
    const struct rtnl_dump_filter_arg a[2] = {
        { .filter = filter, .arg1 = arg1, .junk = junk, .arg2 = arg2 },
        { .filter = NULL,   .arg1 = NULL, .junk = NULL, .arg2 = NULL }
    };

    return rtnl_dump_filter_l(rth, a);
}

int
_dot3Stats_netlink_get_errorcntrs(dot3StatsTable_rowreq_ctx *rowreq_ctx, const char *name)
{
    struct rtnl_handle rth;
    struct ifstat_ent *ke;
    int done;

    if (rtnl_open(&rth, 0) < 0)
    {
        snmp_log(LOG_ERR, "_dot3Stats_netlink_get_errorcntrs: rtnl_open() failed\n");
        return 1;
    }

    if (rtnl_wilddump_request(&rth, AF_INET, RTM_GETLINK) < 0)
    {
        snmp_log(LOG_ERR, "_dot3Stats_netlink_get_errorcntrs: Cannot send dump request");
        rtnl_close(&rth);
        return 1;
    }

    if (rtnl_dump_filter(&rth, get_nlmsg, NULL, NULL, NULL) < 0)
    {
        snmp_log(LOG_ERR, "_dot3Stats_netlink_get_errorcntrs: Dump terminated\n");
        rtnl_close(&rth);
        return 1;
    }

    rtnl_close(&rth);

    /*
     * Now scan kern_db for this if's data
     * While doing so, we'll throw away the kern db.
     */
    done = 0;

    while ((ke = kern_db) != NULL)
    {
        if (strcmp(ke->name, name) == 0)
        {
            dot3StatsTable_data *data = &rowreq_ctx->data;

            DEBUGMSGTL(("access:dot3StatsTable", "IFLA_STATS for %s\n", name));

            data->dot3StatsFCSErrors = ke->stats.rx_crc_errors;
            rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSFCSERRORS_FLAG;

            data->dot3StatsDeferredTransmissions = ke->stats.tx_dropped;
            rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSDEFERREDTRANSMISSIONS_FLAG;

            data->dot3StatsInternalMacTransmitErrors = ke->stats.tx_fifo_errors;
            rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSINTERNALMACTRANSMITERRORS_FLAG;

            data->dot3StatsCarrierSenseErrors = ke->stats.tx_carrier_errors;
            rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSCARRIERSENSEERRORS_FLAG;

            data->dot3StatsFrameTooLongs = ke->stats.rx_frame_errors;
            rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSFRAMETOOLONGS_FLAG;

            data->dot3StatsInternalMacReceiveErrors = ke->stats.rx_fifo_errors;
            rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSINTERNALMACRECEIVEERRORS_FLAG;

            done = 1;
        }
        kern_db = ke->next;
        free(ke);
    }

    return !done;
}
# else /* }{ */
int
_dot3Stats_netlink_get_errorcntrs(dot3StatsTable_rowreq_ctx *rowreq_ctx, const char *name)
{
    return 1;
}
# endif /* } */


/*
 * NAME: getulongfromsysclassnetstatistics
 * PURPOSE: To get a single statistics value from /sys/class/net/<ifname>/statistics/<ctrname>
 * ARGUMENTS: ifname: interface name
 *      ctrname: counter name
 *      valuep: where to store value
 * RETURNS: 0 if value not available
 *      non-0 if value available
 */
static int
getulongfromsysclassnetstatistics(const char *ifname, const char *ctrname, u_long *valuep)
{
    char path[256];
    FILE *fp;
    int rv;

    if (ifname == NULL || ctrname == NULL || valuep == NULL)
        return 0;

    snprintf(path, sizeof(path), "/sys/class/net/%s/statistics/%s", ifname, ctrname);
    fp = fopen(path, "rt");
    if (fp == NULL)
        return 0;

    rv = 1;
    if (fscanf(fp, "%lu", valuep) != 1)
        rv = 0;

    fclose(fp);

    return rv;
}

/*
 * NAME: interface_dot3stats_get_errorcounters
 * PURPOSE: To get ethernet error statistics
 * ARGUMENTS: rowreq_ctx: where to store the value(s)
 *      name: interface name
 * RETURNS: nothing. fields not set if data not available
 */
void
interface_dot3stats_get_errorcounters (dot3StatsTable_rowreq_ctx *rowreq_ctx, const char *name)
{
    u_long value;
    dot3StatsTable_data *data = &rowreq_ctx->data;
    FILE *dev;
    const char NETDEV_FILE[] = "/proc/net/dev";

    if (_dot3Stats_netlink_get_errorcntrs(rowreq_ctx, name) == 0)
    {
        DEBUGMSGTL(("access:dot3StatsTable", "interface_dot3stats_get_errorcounters: got data from IFLA_STATS\n"));
        return;
    }

    if ((dev = fopen(NETDEV_FILE, "r")) != NULL)
    {
        char line[256], *lp, *next;
        size_t namelen = strlen(name);
        unsigned int value;
        unsigned int column;

        while (fgets(line, sizeof(line), dev) != NULL)
        {
            /*    br0:68395635 1038214    0    0    0     0          0    939411 25626606   90708    0    0    0     0       0          0 */
            lp = line;
            while (*lp == ' ' || *lp == '\t')
                lp++;
            if (strncmp(lp, name, namelen) != 0 || lp[namelen] != ':')
                continue;
            lp += namelen + 1;         /* Skip name and colon */

            column = 1;
            while (1)
            {
                value = strtoul(lp, &next, 10);
                if (next == lp)
                    break;             /* no more data */
                switch (column)
                {
                case 3: 
                    data->dot3StatsFCSErrors = value;
                    rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSFCSERRORS_FLAG;
                    break;
                case 12:
                    data->dot3StatsDeferredTransmissions = value;
                    rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSDEFERREDTRANSMISSIONS_FLAG;
                    break;
                case 13:
                    data->dot3StatsInternalMacTransmitErrors = value;
                    rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSINTERNALMACTRANSMITERRORS_FLAG;
                    break;
                case 15:
                    data->dot3StatsCarrierSenseErrors = value;
                    rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSCARRIERSENSEERRORS_FLAG;
                    break;
                case 6:
                    data->dot3StatsFrameTooLongs = value;
                    rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSFRAMETOOLONGS_FLAG;
                    break;
                case 5:
                    data->dot3StatsInternalMacReceiveErrors = value;
                    rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSINTERNALMACRECEIVEERRORS_FLAG;
                    break;
                case 14:
                    data->dot3StatsSingleCollisionFrames = value;
                    rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSSINGLECOLLISIONFRAMES_FLAG;
                    break;
                }
                column++;
                lp = next;
            }
            break;
        }

        fclose(dev);
    }

    if (!(rowreq_ctx->column_exists_flags & COLUMN_DOT3STATSFCSERRORS_FLAG) &&
          getulongfromsysclassnetstatistics(name, "rx_errors", &value)) {
        data->dot3StatsFCSErrors = value;
        rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSFCSERRORS_FLAG;
    }
    if (!(rowreq_ctx->column_exists_flags & COLUMN_DOT3STATSDEFERREDTRANSMISSIONS_FLAG) &&
          getulongfromsysclassnetstatistics(name, "tx_dropped", &value)) {
        data->dot3StatsDeferredTransmissions = value;
        rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSDEFERREDTRANSMISSIONS_FLAG;
    }
    if (!(rowreq_ctx->column_exists_flags & COLUMN_DOT3STATSINTERNALMACTRANSMITERRORS_FLAG) &&
          getulongfromsysclassnetstatistics(name, "tx_fifo_errors", &value)) {
        data->dot3StatsInternalMacTransmitErrors = value;
        rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSINTERNALMACTRANSMITERRORS_FLAG;
    }
    if (!(rowreq_ctx->column_exists_flags & COLUMN_DOT3STATSCARRIERSENSEERRORS_FLAG) &&
          getulongfromsysclassnetstatistics(name, "tx_carrier_errors", &value)) {
        data->dot3StatsCarrierSenseErrors = value;
        rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSCARRIERSENSEERRORS_FLAG;
    }
    if (!(rowreq_ctx->column_exists_flags & COLUMN_DOT3STATSFRAMETOOLONGS_FLAG) &&
          getulongfromsysclassnetstatistics(name, "rx_frame_errors", &value)) {
        data->dot3StatsFrameTooLongs = value;
        rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSFRAMETOOLONGS_FLAG;
    }
    if (!(rowreq_ctx->column_exists_flags & COLUMN_DOT3STATSINTERNALMACRECEIVEERRORS_FLAG) &&
          getulongfromsysclassnetstatistics(name, "rx_fifo_errors", &value)) {
        data->dot3StatsInternalMacReceiveErrors = value;
        rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSINTERNALMACRECEIVEERRORS_FLAG;
    }

    return;
}

/*
 * @retval  0 success
 * @retval -1 cannot get ETHTOOL_DRVINFO failed 
 * @retval -2 nstats zero - no statistcs available
 * @retval -3 memory allocation for holding the statistics failed
 * @retval -4 cannot get ETHTOOL_GSTRINGS information
 * @retval -5 cannot get ETHTOOL_GSTATS information
 * @retval -6 function not supported if HAVE_LINUX_ETHTOOL_H not defined
 */


int 
interface_ioctl_dot3stats_get (dot3StatsTable_rowreq_ctx *rowreq_ctx, int fd, const char *name) {

#ifdef HAVE_LINUX_ETHTOOL_H
    dot3StatsTable_data *data = &rowreq_ctx->data;
    struct ethtool_drvinfo driver_info;
    struct ethtool_gstrings *eth_strings;
    struct ethtool_stats *eth_stats;
    struct ifreq ifr; 
    unsigned int nstats, size_str, i;
    int err;

    DEBUGMSGTL(("access:dot3StatsTable:interface_ioctl_dot3Stats_get",
                "called\n"));

    memset(&ifr, 0, sizeof(ifr));
    strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));

    memset(&driver_info, 0, sizeof (driver_info));
    driver_info.cmd = ETHTOOL_GDRVINFO;
    ifr.ifr_data = (char *)&driver_info;

    err = _dot3Stats_ioctl_get(fd, SIOCETHTOOL, &ifr, name);
    if (err < 0) {
        DEBUGMSGTL(("access:dot3StatsTable:interface_ioctl_dot3Stats_get",
                    "ETHTOOL_GETDRVINFO failed for interface |%s| \n", name));
        return -1;
    }

    nstats = driver_info.n_stats;
    if (nstats < 1) {
        DEBUGMSGTL(("access:dot3StatsTable:interface_ioctl_dot3Stats_get",
                    "no stats available for interface |%s| \n", name));
        return -2;
    }

    size_str = nstats * ETH_GSTRING_LEN;

    eth_strings = malloc(size_str + sizeof (struct ethtool_gstrings));
    if (!eth_strings) {
        DEBUGMSGTL(("access:dot3StatsTable:interface_ioctl_dot3Stats_get",
                    "no memory available\n"));
        snmp_log (LOG_ERR, "access:dot3StatsTable,interface_ioctl_dot3Stats_get, no memory available\n");

        return -3;
    }
    memset (eth_strings, 0, (size_str + sizeof (struct ethtool_gstrings)));

    eth_stats = malloc (size_str + sizeof (struct ethtool_stats));
    if (!eth_stats) {
        free (eth_strings);
        DEBUGMSGTL(("access:dot3StatsTable:interface_ioctl_dot3Stats_get",
                    "no memory available\n"));
        snmp_log (LOG_ERR, "access:dot3StatsTable,interface_ioctl_dot3Stats_get, no memory available\n");

        return -3;
    }
     memset (eth_stats, 0, (size_str + sizeof (struct ethtool_stats)));

    eth_strings->cmd = ETHTOOL_GSTRINGS;
    eth_strings->string_set = ETH_SS_STATS;
    eth_strings->len = nstats;
    ifr.ifr_data = (char *) eth_strings;
    err = _dot3Stats_ioctl_get(fd, SIOCETHTOOL, &ifr, name);
    if (err < 0) {
        DEBUGMSGTL(("access:dot3StatsTable:interface_ioctl_dot3Stats_get",
                    "cannot get stats strings information for interface |%s| \n", name));
        snmp_log (LOG_ERR, "access:dot3StatsTable,interface_ioctl_dot3Stats_get, cannot get stats strings information for interface |%s| \n", name);

        free(eth_strings);
        free(eth_stats);
        return -4;
    }

    eth_stats->cmd = ETHTOOL_GSTATS;
    eth_stats->n_stats = nstats;
    ifr.ifr_data = (char *) eth_stats;
    err = _dot3Stats_ioctl_get(fd, SIOCETHTOOL, &ifr, name);
    if (err < 0) {
        DEBUGMSGTL(("access:dot3StatsTable:interface_ioctl_dot3Stats_get",
                    "cannot get stats strings information for interface |%s| \n", name));
        snmp_log (LOG_ERR, "access:dot3StatsTable,interface_ioctl_dot3Stats_get, cannot get stats information for interface |%s| \n", name);

        free(eth_strings);
        free(eth_stats);
        return -5;
    }

    for (i = 0; i < nstats; i++) {
        char s[ETH_GSTRING_LEN];

        strlcpy(s, (const char *) &eth_strings->data[i * ETH_GSTRING_LEN],
                sizeof(s));
    
        if (DOT3STATSALIGNMENTERRORS(s)) {
            data->dot3StatsAlignmentErrors = (u_long)eth_stats->data[i];
            rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSALIGNMENTERRORS_FLAG;
        }

        if (DOT3STATSMULTIPLECOLLISIONFRAMES(s)) {
            data->dot3StatsMultipleCollisionFrames = (u_long)eth_stats->data[i];
            rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSMULTIPLECOLLISIONFRAMES_FLAG;
        }
            
        if (DOT3STATSLATECOLLISIONS(s)) {
            data->dot3StatsLateCollisions = (u_long)eth_stats->data[i];
            rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSLATECOLLISIONS_FLAG;
        }

        if (DOT3STATSSINGLECOLLISIONFRAMES(s)) {
            data->dot3StatsSingleCollisionFrames = (u_long)eth_stats->data[i];
            rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSSINGLECOLLISIONFRAMES_FLAG;
        }

        if (DOT3STATSEXCESSIVECOLLISIONS(s)) {
            data->dot3StatsExcessiveCollisions = (u_long)eth_stats->data[i];
            rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSEXCESSIVECOLLISIONS_FLAG;
        }
    }

    free(eth_strings);
    free(eth_stats);

    return 0;
#else
    return -6;
#endif
}


/*
 * @retval  0 success
 * @retval -1 ETHTOOL_GSET failed
 * @retval -2 function not supported if HAVE_LINUX_ETHTOOL_H not defined
 */

int
interface_ioctl_dot3stats_duplex_get(dot3StatsTable_rowreq_ctx *rowreq_ctx, int fd, const char* name) {

#ifdef HAVE_LINUX_ETHTOOL_H
    dot3StatsTable_data *data = &rowreq_ctx->data;
    struct ethtool_cmd edata;
    struct ifreq ifr;
    int err;

    DEBUGMSGTL(("access:dot3StatsTable:interface_ioctl_dot3Stats_duplex_get",
                "called\n"));

    memset(&edata, 0, sizeof (edata));
    memset(&ifr, 0, sizeof (ifr));
    edata.cmd = ETHTOOL_GSET;
    ifr.ifr_data = (char *)&edata;

    err = _dot3Stats_ioctl_get (fd, SIOCETHTOOL, &ifr, name);
    if (err < 0) {
        DEBUGMSGTL(("access:dot3StatsTable:interface_ioctl_dot3Stats_duplex_get",
                    "ETHTOOL_GSET failed\n"));

        return -1;
    }
    
    if (err == 0) {
        rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSDUPLEXSTATUS_FLAG;
        switch (edata.duplex) {
        case DUPLEX_HALF:
            data->dot3StatsDuplexStatus = (u_long) DOT3STATSDUPLEXSTATUS_HALFDUPLEX;
            break;
        case DUPLEX_FULL:
            data->dot3StatsDuplexStatus = (u_long) DOT3STATSDUPLEXSTATUS_FULLDUPLEX;
            break;
        default:
            data->dot3StatsDuplexStatus = (u_long) DOT3STATSDUPLEXSTATUS_UNKNOWN;
            break;
        };
    }

    DEBUGMSGTL(("access:dot3StatsTable:interface_ioctl_dot3Stats_duplex_get",
                "ETHTOOL_GSET processed\n"));
    return err;
#else
    return -2;
#endif
}


/*
 * NAME: interface_sysclassnet_dot3stats_get
 * PURPOSE: To get ethernet statistics from /sys/class/net/...
 * ARGUMENTS: rowreq_ctx: where to store the value(s)
 *	name: interface name
 * RETURNS: nothing. fields not set if data not available
 */
void
interface_sysclassnet_dot3stats_get (dot3StatsTable_rowreq_ctx *rowreq_ctx, const char *name)
{
    u_long value;
    dot3StatsTable_data *data = &rowreq_ctx->data;

    if (getulongfromsysclassnetstatistics(name, "rx_errors", &value)) {
	data->dot3StatsFCSErrors = value;
	rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSFCSERRORS_FLAG;
    }
    if (getulongfromsysclassnetstatistics(name, "tx_dropped", &value)) {
	data->dot3StatsDeferredTransmissions = value;
	rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSDEFERREDTRANSMISSIONS_FLAG;
    }
    if (getulongfromsysclassnetstatistics(name, "tx_fifo_errors", &value)) {
	data->dot3StatsInternalMacTransmitErrors = value;
	rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSINTERNALMACTRANSMITERRORS_FLAG;
    }
    if (getulongfromsysclassnetstatistics(name, "tx_carrier_errors", &value)) {
	data->dot3StatsCarrierSenseErrors = value;
	rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSCARRIERSENSEERRORS_FLAG;
    }
    if (getulongfromsysclassnetstatistics(name, "rx_frame_errors", &value)) {
	data->dot3StatsFrameTooLongs = value;
	rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSFRAMETOOLONGS_FLAG;
    }
    if (getulongfromsysclassnetstatistics(name, "rx_fifo_errors", &value)) {
	data->dot3StatsInternalMacReceiveErrors = value;
	rowreq_ctx->column_exists_flags |= COLUMN_DOT3STATSINTERNALMACRECEIVEERRORS_FLAG;
    }

    return;
}



/* 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
 */
int
_dot3Stats_ioctl_get(int fd, int which, struct ifreq *ifrq, const char* name)
{
    int ourfd = -1, rc = 0;

    DEBUGMSGTL(("access:dot3StatsTable:ioctl", "_dot3Stats_ioctl_get\n"));

    /*
     * sanity checks
     */
    if(NULL == name) {
        DEBUGMSGTL(("access:dot3StatsTable:ioctl",
                    "_dot3Stats_ioctl_get invalid ifname '%s'\n", name));
        snmp_log (LOG_ERR, "access:dot3StatsTable:ioctl, _dot3Stats_ioctl_get error on interface '%s'\n", name);
        return -1;
    }

    /*
     * create socket for ioctls
     */
    if(fd < 0) {
        fd = ourfd = socket(AF_INET, SOCK_DGRAM, 0);
        if(ourfd < 0) {
            DEBUGMSGTL(("access:dot3StatsTable:ioctl",
                        "dot3Stats_ioctl_get couldn't create a socket\n"));
            snmp_log (LOG_ERR, "access:dot3StatsTable:ioctl, _dot3Stats_ioctl_get error on interface '%s'\n", name);

            return -2;
        }
    }

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

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

    return rc;
}


