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

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

#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if_arp.h>
#include <arpa/inet.h>
#include <linux/types.h>
#include <asm/types.h>
#ifdef NETSNMP_ENABLE_IPV6
#ifdef HAVE_LINUX_RTNETLINK_H
#include <linux/rtnetlink.h>
#define NIP6(addr) \
        ntohs((addr).s6_addr16[0]), \
        ntohs((addr).s6_addr16[1]), \
        ntohs((addr).s6_addr16[2]), \
        ntohs((addr).s6_addr16[3]), \
        ntohs((addr).s6_addr16[4]), \
        ntohs((addr).s6_addr16[5]), \
        ntohs((addr).s6_addr16[6]), \
        ntohs((addr).s6_addr16[7])
#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
#endif
#endif

int _load_v4(netsnmp_container *container, int idx_offset);
static int _load_v6(netsnmp_container *container, int idx_offset);
#ifdef HAVE_LINUX_RTNETLINK_H
int get_translation_table_info (int sd, int *status, 
                                char *buff, size_t size);
int fillup_entry_info(netsnmp_arp_entry *entry,
                      struct nlmsghdr *nlmp);
#endif
/**
 */
int
netsnmp_access_arp_container_arch_load(netsnmp_container *container)
{
    int rc = 0, idx_offset = 0;

    rc = _load_v4(container, idx_offset);
    if(rc < 0) {
        u_int flags = NETSNMP_ACCESS_ARP_FREE_KEEP_CONTAINER;
        netsnmp_access_arp_container_free(container, flags);
    }

#if defined (NETSNMP_ENABLE_IPV6)
    idx_offset = (rc < 0) ? 0 : rc;

    rc = _load_v6(container, idx_offset);
    if(rc < 0) {
        u_int flags = NETSNMP_ACCESS_ARP_FREE_KEEP_CONTAINER;
        netsnmp_access_arp_container_free(container, flags);
    }
#endif

    /*
     * return no errors (0) if we found any interfaces
     */
    if(rc > 0)
        rc = 0;

    return rc;
}

/**
 */
int
_load_v4(netsnmp_container *container, int idx_offset)
{
    FILE           *in;
    char            line[128];
    int             rc = 0;
    netsnmp_arp_entry *entry;
    char           arp[3*NETSNMP_ACCESS_ARP_PHYSADDR_BUF_SIZE+1];
    char           *arp_token;
    int             i;

    netsnmp_assert(NULL != container);

#define PROCFILE "/proc/net/arp"
    if (!(in = fopen(PROCFILE, "r"))) {
        snmp_log(LOG_DEBUG,"could not open " PROCFILE "\n");
        return -2;
    }

    /*
     * Get rid of the header line 
     */
    fgets(line, sizeof(line), in);

    /*
     * IP address | HW | Flag | HW address      | Mask | Device
     * 192.168.1.4  0x1  0x2   00:40:63:CC:1C:8C  *      eth0
     */
    while (fgets(line, sizeof(line), in)) {
        
        int             za, zb, zc, zd;
        int             tmp_flags;
        char            ifname[21];

        rc = sscanf(line,
                    "%d.%d.%d.%d 0x%*x 0x%x %96s %*[^ ] %20s\n",
                    &za, &zb, &zc, &zd, &tmp_flags, arp, ifname);
        if (7 != rc) {
            snmp_log(LOG_ERR, PROCFILE " data format error (%d!=12)\n", rc);
            snmp_log(LOG_ERR, " line ==|%s|\n", line);
            continue;
        }
        DEBUGMSGTL(("access:arp:container",
                    "ip addr %d.%d.%d.%d, flags 0x%X, hw addr "
                    "%s, name %s\n",
                    za,zb,zc,zd, tmp_flags, arp, ifname ));

        /*
         */
        entry = netsnmp_access_arp_entry_create();
        if(NULL == entry) {
            rc = -3;
            break;
        }

        /*
         * look up ifIndex
         */
        entry->if_index = netsnmp_access_interface_index_find(ifname);
        if(0 == entry->if_index) {
            snmp_log(LOG_ERR,"couldn't find ifIndex for '%s', skipping\n",
                     ifname);
            netsnmp_access_arp_entry_free(entry);
            continue;
        }

        /*
         * now that we've passed all the possible 'continue', assign
         * index offset.
         */
        entry->ns_arp_index = ++idx_offset;

        /*
         * parse ip addr
         */
        entry->arp_ipaddress[0] = za;
        entry->arp_ipaddress[1] = zb;
        entry->arp_ipaddress[2] = zc;
        entry->arp_ipaddress[3] = zd;
        entry->arp_ipaddress_len = 4;

        /*
         * parse hw addr
         */
        for (arp_token = strtok(arp, ":"), i=0; arp_token != NULL; arp_token = strtok(NULL, ":"), i++) {
            entry->arp_physaddress[i] = strtol(arp_token, NULL, 16);
        }
        entry->arp_physaddress_len = i;

        /*
         * what can we do with hw? from arp manpage:

         default  value  of  this  parameter is ether (i.e. hardware code
         0x01 for  IEEE  802.3  10Mbps  Ethernet).   Other  values  might
         include  network  technologies  such as ARCnet (arcnet) , PROnet
         (pronet) , AX.25 (ax25) and NET/ROM (netrom).
        */

        /*
         * parse mask
         */
        /* xxx-rks: what is mask? how to interpret '*'? */


        /*
         * process type
         */
        if(tmp_flags & ATF_PERM)
            entry->arp_type = INETNETTOMEDIATYPE_STATIC;
        else
            entry->arp_type = INETNETTOMEDIATYPE_DYNAMIC;

        /*
         * process status
         * if flags are 0, we can't tell the difference between
         * stale or incomplete.
         */
        if(tmp_flags & ATF_COM)
            entry->arp_state = INETNETTOMEDIASTATE_REACHABLE;
        else
            entry->arp_state = INETNETTOMEDIASTATE_UNKNOWN;

        /*
         * add entry to container
         */
        if (CONTAINER_INSERT(container, entry) < 0)
        {
            DEBUGMSGTL(("access:arp:container","error with arp_entry: insert into container failed.\n"));
            netsnmp_access_arp_entry_free(entry);
            continue;
        }
    }

    fclose(in);
    if( rc < 0 )
        return rc;

    return idx_offset;
}

#if defined (NETSNMP_ENABLE_IPV6)
static int
_load_v6(netsnmp_container *container, int idx_offset)
{
    char              buffer[16384];
#if defined(HAVE_LINUX_RTNETLINK_H)
    struct nlmsghdr   *nlmp;
#endif
    int               sd = 0;
    int               status = 0;
    int               rc = 0;
    int               len, req_len;
    netsnmp_arp_entry *entry;

    netsnmp_assert(NULL != container);
#if defined(HAVE_LINUX_RTNETLINK_H)
    if((sd = socket (PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
        snmp_log(LOG_ERR,"Unable to create netlink socket\n");
        return -2;
    }

    if(get_translation_table_info (sd, &status, buffer, sizeof(buffer)) < 0) {
       snmp_log(LOG_ERR,"Unable to fetch translation table info\n");
       close(sd);
       return -2;
    }

    for (nlmp = (struct nlmsghdr *)buffer; status > sizeof(*nlmp); ) {
         len = nlmp->nlmsg_len;
         req_len = len - sizeof(*nlmp);
         if (req_len < 0 || len > status) {
             snmp_log(LOG_ERR,"invalid length\n");
             return -2;
         }
         if (!NLMSG_OK (nlmp, status)) {
             snmp_log(LOG_ERR,"NLMSG not OK\n");
             return -2;
         }
         entry = netsnmp_access_arp_entry_create();
         if(NULL == entry) {
            rc = -3;
            break;
         }
         entry->ns_arp_index = ++idx_offset;
         if(fillup_entry_info (entry, nlmp) < 0) {
            DEBUGMSGTL(("access:arp:load_v6", "skipping netlink message that"
                        "did not contain valid ARP information\n"));
            netsnmp_access_arp_entry_free(entry);
            status -= NLMSG_ALIGN(len);
            nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
            continue;
         }
         CONTAINER_INSERT(container, entry);
         status -= NLMSG_ALIGN(len);
         nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
    }

    close(sd);
#endif
    if(rc<0) {
        return rc;
    }

    return idx_offset;
}
#if defined(HAVE_LINUX_RTNETLINK_H)
int 
get_translation_table_info (int sd, int *status, char *buff, size_t size)
{
    struct {
                struct nlmsghdr n;
                struct ndmsg r;
                char   buf[1024];
    } req;
    struct rtattr   *rta;

    memset(&req, 0, sizeof(req));
    req.n.nlmsg_len = NLMSG_LENGTH (sizeof(struct ndmsg));
    req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
    req.n.nlmsg_type = RTM_GETNEIGH;

    req.r.ndm_family = AF_INET6;
    rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.n.nlmsg_len));
    rta->rta_len = RTA_LENGTH(16);

    if(send(sd, &req, req.n.nlmsg_len, 0) < 0) {
       snmp_log(LOG_ERR,"Sending request failed\n");
       return -1;
    }
    if((*status = recv(sd, buff, size, 0)) < 0) {
       snmp_log(LOG_ERR,"Recieving request failed\n");
       return -1;
    }
    if(*status == 0) {
       snmp_log(LOG_ERR,"End of file\n");
       return -1;
    }
    return 0;
}

int
fillup_entry_info(netsnmp_arp_entry *entry, struct nlmsghdr *nlmp)
{
    struct ndmsg   *rtmp;
    struct in6_addr *in6p;
    struct rtattr  *tb[NDA_MAX + 1], *rta;
    size_t          in_len, out_len;
    unsigned int    i;
    int             length;
    char            addr[40];
    u_char         *buf;
    u_char         *hwaddr;

    rtmp = (struct ndmsg *) NLMSG_DATA(nlmp);
    if (nlmp->nlmsg_type != RTM_NEWNEIGH) {
        snmp_log(LOG_ERR, "Wrong netlink message type %d\n", nlmp->nlmsg_type);
        return -1;
    }

    if (rtmp->ndm_state != NUD_NOARP) {
        memset(tb, 0, sizeof(struct rtattr *) * (NDA_MAX + 1));
        length = nlmp->nlmsg_len - NLMSG_LENGTH(sizeof(*rtmp));
        if (length < 0) {
            snmp_log(LOG_ERR, "netlink message length %d < %d is invalid\n",
                     nlmp->nlmsg_len, (int)NLMSG_LENGTH(sizeof(*rtmp)));
            return -1;
        }
        /*
         * this is what the kernel-removed NDA_RTA define did 
         */
        rta = ((struct rtattr *) (((char *) (rtmp)) +
                                  NLMSG_ALIGN(sizeof(struct ndmsg))));
        while (RTA_OK(rta, length)) {
            if (rta->rta_type <= NDA_MAX)
                tb[rta->rta_type] = rta;
            rta = RTA_NEXT(rta, length);
        }
        if (length) {
            snmp_log(LOG_ERR, "Received uneven number of netlink"
                        " messages - %d bytes remaining\n", length);
            return -1;
        }
        /*
         * Fill up the index
         */
        entry->if_index = rtmp->ndm_ifindex;
        /*
         * Fill up ip address 
         */
        if (tb[NDA_DST]) {
            memset(&addr, '\0', sizeof(addr));
            in6p = (struct in6_addr *) RTA_DATA(tb[NDA_DST]);
            sprintf(addr, NIP6_FMT, NIP6(*in6p));
            in_len = entry->arp_ipaddress_len =
                sizeof(entry->arp_ipaddress);
            netsnmp_assert(16 == in_len);
            out_len = 0;
            buf = entry->arp_ipaddress;
            if (1 != netsnmp_hex_to_binary(&buf, &in_len,
                                           &out_len, 0, addr, ":")) {
                snmp_log(LOG_ERR, "error parsing '%s', skipping\n",
                         entry->arp_ipaddress);
                return -1;
            }
            netsnmp_assert(16 == out_len);
            entry->arp_ipaddress_len = out_len;
        }
        if (tb[NDA_LLADDR]) {
            memset(&addr, '\0', sizeof(addr));
            hwaddr = RTA_DATA(tb[NDA_LLADDR]);
            entry->arp_physaddress_len = RTA_PAYLOAD(tb[NDA_LLADDR]);
            buf = entry->arp_physaddress;
            for (i = 0; i < entry->arp_physaddress_len; i++)
                entry->arp_physaddress[i] = hwaddr[i];
        }

        switch (rtmp->ndm_state) {
        case NUD_INCOMPLETE:
            entry->arp_state = INETNETTOMEDIASTATE_INCOMPLETE;
            break;
        case NUD_REACHABLE:
        case NUD_PERMANENT:
            entry->arp_state = INETNETTOMEDIASTATE_REACHABLE;
            break;
        case NUD_STALE:
            entry->arp_state = INETNETTOMEDIASTATE_STALE;
            break;
        case NUD_DELAY:
            entry->arp_state = INETNETTOMEDIASTATE_DELAY;
            break;
        case NUD_PROBE:
            entry->arp_state = INETNETTOMEDIASTATE_PROBE;
            break;
        case NUD_FAILED:
            entry->arp_state = INETNETTOMEDIASTATE_INVALID;
            break;
        case NUD_NONE:
            entry->arp_state = INETNETTOMEDIASTATE_UNKNOWN;
            break;
        default:
            snmp_log(LOG_ERR, "Unrecognized ARP entry state %d", rtmp->ndm_state);
            break;
        }

        switch (rtmp->ndm_state) {
        case NUD_INCOMPLETE:
        case NUD_FAILED:
        case NUD_NONE:
            entry->arp_type = INETNETTOMEDIATYPE_INVALID;
            break;
        case NUD_REACHABLE:
        case NUD_STALE:
        case NUD_DELAY:
        case NUD_PROBE:
            entry->arp_type = INETNETTOMEDIATYPE_DYNAMIC;
            break;
        case NUD_PERMANENT:
            entry->arp_type = INETNETTOMEDIATYPE_STATIC;
            break;
        default:
            entry->arp_type = INETNETTOMEDIATYPE_LOCAL;
            break;
        }
    } else {
        return -1;              /* could not create data for this interface */
    }

    return 0;
}
#endif
#endif
