/*
 * 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) {
            if ( (list_head = (struct ifname *) malloc (sizeof(struct ifname))) < 0) {
                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;

        if ( (nameptr2->ifn_next = (struct ifname *) malloc (sizeof(struct ifname))) < 0) {
            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, 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", name));
            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;
}


