/**
 * check entry for update
 *
 */
static void
_snarf_arp_entry(netsnmp_arp_entry *arp_entry,
                 netsnmp_container *container)
{
    inetNetToMediaTable_rowreq_ctx *rowreq_ctx;
    int             inetAddressType;

    DEBUGTRACE;

    netsnmp_assert(NULL != arp_entry);
    netsnmp_assert(NULL != container);

    /*
     * convert the addr len to an inetAddressType
     */
    switch (arp_entry->arp_ipaddress_len) {
    case 4:
        inetAddressType = INETADDRESSTYPE_IPV4;
        break;

    case 6:
        inetAddressType = INETADDRESSTYPE_IPV6;
        break;

    default:
        netsnmp_access_arp_entry_free(arp_entry);
        snmp_log(LOG_ERR, "unsupported address type\n");
        return;
    }

    /*
     * allocate an row context and set the index(es), then add it to
     * the container
     */
    rowreq_ctx = inetNetToMediaTable_allocate_rowreq_ctx(arp_entry, NULL);
    if ((NULL != rowreq_ctx) &&
        (MFD_SUCCESS == inetNetToMediaTable_indexes_set
         (rowreq_ctx, rowreq_ctx->data->if_index, inetAddressType,
          rowreq_ctx->data->arp_ipaddress,
          rowreq_ctx->data->arp_ipaddress_len))) {
        rowreq_ctx->inetNetToMediaRowStatus = ROWSTATUS_ACTIVE;
        CONTAINER_INSERT(container, rowreq_ctx);
    } else {
        if (rowreq_ctx) {
            snmp_log(LOG_ERR, "error setting index while loading "
                     "inetNetToMediaTable cache.\n");
            inetNetToMediaTable_release_rowreq_ctx(rowreq_ctx);
        } else
            netsnmp_access_arp_entry_free(arp_entry);
    }
}
Exemple #2
0
static void netsnmp_access_arp_read_netlink(int fd, void *data)
{
    netsnmp_arp_access *access = (netsnmp_arp_access *) data;
    netsnmp_arp_entry *entry;
    char buf[16384];
    struct nlmsghdr *h;
    int r, len;

    do {
        r = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
        if (r < 0) {
            if (errno == EINTR)
                continue;
            if (errno == EAGAIN)
                return;
            snmp_log(LOG_WARNING, "netlink buffer overrun\n");
            access->synchronized = 0;
            if (access->cache_expired != NULL)
                *access->cache_expired = 1;
            return;
        }
    } while (0);
    len = r;

    for (h = (struct nlmsghdr *) buf; NLMSG_OK(h, len); h = NLMSG_NEXT(h, len)) {
        if (h->nlmsg_type == NLMSG_DONE) {
            access->synchronized = 1;
            continue;
        }

        entry = netsnmp_access_arp_entry_create();
        if (NULL == entry)
            break;

        DEBUGMSGTL(("access:netlink:arp", "arp netlink notification\n"));

        entry->generation = access->generation;
        r = fillup_entry_info (entry, h);
        if (r > 0) {
            access->update_hook(access, entry);
        } else {
            if (r < 0) {
                NETSNMP_LOGONCE((LOG_ERR, "filling entry info failed\n"));
                DEBUGMSGTL(("access:netlink:arp", "filling entry info failed\n"));
            }
            netsnmp_access_arp_entry_free(entry);
        }
    }
}
Exemple #3
0
int
_load_v4(netsnmp_container *container, int idx_offset)
{
    FILE           *in;
    char            line[128];
    int             rc = 0;
    netsnmp_arp_entry *entry;
    
    netsnmp_assert(NULL != container);

#define PROCFILE "/proc/net/arp"
    if (!(in = fopen(PROCFILE, "r"))) {
        snmp_log(LOG_ERR,"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, ze, zf, zg, zh, zi, zj;
        int             tmp_flags;
        char            ifname[21];

        rc = sscanf(line,
                    "%d.%d.%d.%d 0x%*x 0x%x %x:%x:%x:%x:%x:%x %*[^ ] %20s\n",
                    &za, &zb, &zc, &zd, &tmp_flags, &ze, &zf, &zg, &zh, &zi,
                    &zj, ifname);
        if (12 != 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 "
                    "%x:%x:%x:%x:%x:%x, name %s\n",
                    za,zb,zc,zd, tmp_flags, ze,zf,zg,zh,zi,zj, 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
         */
        entry->arp_physaddress[0] = ze;
        entry->arp_physaddress[1] = zf;
        entry->arp_physaddress[2] = zg;
        entry->arp_physaddress[3] = zh;
        entry->arp_physaddress[4] = zi;
        entry->arp_physaddress[5] = zj;
        entry->arp_physaddress_len = 6;

        /*
         * 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
         */
        CONTAINER_INSERT(container, entry);
    }

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

    return idx_offset;
}
Exemple #4
0
void
_access_arp_entry_release(netsnmp_arp_entry * entry, void *context)
{
    netsnmp_access_arp_entry_free(entry);
}
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;
}
Exemple #6
0
static int
_load_v4(netsnmp_arp_access *access)
{
    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 != access);

#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;
        unsigned 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->generation = access->generation;
        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
         */
        access->update_hook(access, entry);
    }

    fclose(in);
    return 0;
}