/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
static int
_load6(netsnmp_container *container, u_int load_flags)
{
    int             rc = 0;
    FILE           *in;
    char            line[180];
    static int      log_open_err = 1;

    netsnmp_assert(NULL != container);

#undef PROCFILE
#define PROCFILE "/proc/net/tcp6"
    if (!(in = fopen(PROCFILE, "r"))) {
        snmp_log(LOG_ERR,"could not open " PROCFILE "\n");
        if (1 == log_open_err) {
            snmp_log(LOG_ERR,"could not open " PROCFILE "\n");
            log_open_err = 0;
        }
        return -2;
    }
    /*
     * if we turned off logging of open errors, turn it back on now that
     * we have been able to open the file.
     */
    if (0 == log_open_err)
        log_open_err = 1;
    
    fgets(line, sizeof(line), in); /* skip header */

    /*
     * Note: PPC (big endian)
     *
     *   sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
     *  0: 00000000000000000000000000000001:1466 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000   500        0 326699 1 efb81580 3000 0 0 2 -1
     */
    while (fgets(line, sizeof(line), in)) {
        netsnmp_tcpconn_entry *entry;
        int             state, rc, local_port, remote_port, tmp_state;
        unsigned long long  inode;
        size_t          buf_len, offset;
        char            local_addr[48], remote_addr[48];
        u_char         *tmp_ptr;

        if (6 != (rc = sscanf(line, "%*d: %47[0-9A-Z]:%x %47[0-9A-Z]:%x %x %*x:%*x %*x:%*x %*x %*x %*x %llu",
                              local_addr, &local_port,
                              remote_addr, &remote_port, &tmp_state, &inode))) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing line (%d != 6)\n", rc));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
            continue;
        }
        DEBUGMSGT(("verbose:access:tcpconn:container"," line '%s'\n", line));

        /*
         * check if we care about listen state
         */
        state = (tmp_state & 0xf) < 12 ? linux_states[tmp_state & 0xf] : 2;
        if (load_flags) {
            if (TCPCONNECTIONSTATE_LISTEN == state) {
                if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_NOLISTEN) {
                    DEBUGMSGT(("verbose:access:tcpconn:container",
                               " skipping listen\n"));
                    continue;
                }
            }
            else if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_ONLYLISTEN) {
                    DEBUGMSGT(("verbose:access:tcpconn:container",
                               " skipping non-listen\n"));
                    continue;
            }
        }

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

        /** oddly enough, these appear to already be in network order */
        entry->loc_port = (unsigned short) local_port;
        entry->rmt_port = (unsigned short) remote_port;
        entry->tcpConnState = state;
        entry->pid = netsnmp_get_pid_from_inode(inode);

        /** the addr string may need work */
        buf_len = strlen(local_addr);
        if ((32 != buf_len) ||
            (-1 == netsnmp_addrstr_hton(local_addr, 32))) {
            DEBUGMSGT(("verbose:access:tcpconn:container",
                       " error processing local address\n"));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }
        offset = 0;
        tmp_ptr = entry->loc_addr;
        rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len,
                                   &offset, 0, local_addr, NULL);
        entry->loc_addr_len = offset;
        if (( 16 != entry->loc_addr_len ) && ( 20 != entry->loc_addr_len )) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing local addr (%d != 16|20)\n",
                       entry->loc_addr_len));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }

        buf_len = strlen((char*)remote_addr);
        if ((32 != buf_len) ||
            (-1 == netsnmp_addrstr_hton(remote_addr, 32))) {
            DEBUGMSGT(("verbose:access:tcpconn:container",
                       " error processing remote address\n"));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }
        offset = 0;
        tmp_ptr = entry->rmt_addr;
        rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len,
                                   &offset, 0, remote_addr, NULL);
        entry->rmt_addr_len = offset;
        if (( 16 != entry->rmt_addr_len ) && ( 20 != entry->rmt_addr_len )) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing remote addr (%d != 16|20)\n",
                       entry->rmt_addr_len));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }


        /*
         * add entry to container
         */
        entry->arbitrary_index = CONTAINER_SIZE(container) + 1;
        CONTAINER_INSERT(container, entry);
    }

    fclose(in);

    if(rc<0)
        return rc;

    return 0;
}
Beispiel #2
0
/**
 * convert an ASCII hex string to binary
 *
 * @note This is a wrapper which calls netsnmp_hex_to_binary with a
 * delimiter string of " ".
 *
 * See netsnmp_hex_to_binary for parameter descriptions.
 *
 * @retval 1  success
 * @retval 0  error
 */
int
snmp_hex_to_binary(u_char ** buf, size_t * buf_len, size_t * offset,
                   int allow_realloc, const char *hex)
{
    return netsnmp_hex_to_binary(buf, buf_len, offset, allow_realloc, hex, " ");
}
/**
 * @internal
 * process token value index line
 */
static int
_process_line_udp_ep(netsnmp_line_info *line_info, void *mem,
                     struct netsnmp_line_process_info_s* lpi)
{
    netsnmp_udp_endpoint_entry *ep = (netsnmp_udp_endpoint_entry *)mem;
    char                 *ptr, *sep;
    u_char               *u_ptr;
    size_t                u_ptr_len, offset, len;
    unsigned long long    inode;
    size_t                count = 0;

    /*
     * skip 'sl'
     */
    ptr = skip_not_white(line_info->start);
    if (NULL == ptr) {
        DEBUGMSGTL(("access:udp_endpoint", "no sl '%s'\n",
                       line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    ptr = skip_white(ptr);
    if (NULL == ptr) {
        DEBUGMSGTL(("text:util:tvi", "no space after sl '%s'\n",
                    line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }

    /*
     * get local address. ignore error on hex conversion, since that
     * function doesn't like the ':' between address and port. check the
     * offset to see if it worked. May need to flip string too.
     */
    u_ptr = ep->loc_addr;
    u_ptr_len = sizeof(ep->loc_addr);
    sep = strchr(ptr, ':');
    if (NULL == sep) {
        DEBUGMSGTL(("text:util:tvi", "no ':' '%s'\n",
                    line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    len = (sep - ptr);
    if (-1 == netsnmp_addrstr_hton(ptr, len)) {
        DEBUGMSGTL(("text:util:tvi", "bad length %d for loc addr '%s'\n",
                    (int)u_ptr_len, line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    offset = 0;
    netsnmp_hex_to_binary(&u_ptr, &u_ptr_len, &offset, 0, ptr, NULL);
    if ((4 != offset) && (16 != offset)) {
        DEBUGMSGTL(("text:util:tvi", "bad offset %d for loc addr '%s'\n",
                    (int)offset, line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    ep->loc_addr_len = offset;
    ptr += (offset * 2);
    ++ptr; /* skip ':' */

    /*
     * get local port
     */
    ep->loc_port = strtol(ptr, &ptr, 16);
    ptr = skip_white(ptr);

    /*
     * get remote address. ignore error on hex conversion, since that
     * function doesn't like the ':' between address and port. check the
     * offset to see if it worked. May need to flip string too.
     */
    u_ptr = ep->rmt_addr;
    u_ptr_len = sizeof(ep->rmt_addr);
    sep = strchr(ptr, ':');
    if (NULL == sep) {
        DEBUGMSGTL(("text:util:tvi", "no ':' '%s'\n",
                    line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    len = (sep - ptr);
    if (-1 == netsnmp_addrstr_hton(ptr, len)) {
        DEBUGMSGTL(("text:util:tvi", "bad length %d for rmt addr '%s'\n",
                    (int)u_ptr_len, line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    offset = 0;
    netsnmp_hex_to_binary(&u_ptr, &u_ptr_len, &offset, 0, ptr, NULL);
    if ((4 != offset) && (16 != offset)) {
        DEBUGMSGTL(("text:util:tvi", "bad offset %d for rmt addr '%s'\n",
                    (int)offset, line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }
    ep->rmt_addr_len = offset;
    ptr += (offset * 2);
    ++ptr; /* skip ':' */

    /*
     * get remote port
     */
    ep->rmt_port = strtol(ptr, &ptr, 16);
    ptr = skip_white(ptr);

    /*
     * get state too
     */
    ep->state = strtol(ptr, &ptr, 16);

    /*
     * Use inode as instance value.
     */
    while (count != 5) {
	ptr = skip_white(ptr);
	ptr = skip_not_white(ptr);
	count++;
    }
    inode = strtoull(ptr, &ptr, 0);
    ep->instance = (u_int)inode;

    /*
     * get the pid also
     */
    ep->pid = netsnmp_get_pid_from_inode(inode);

    ep->index = (uintptr_t)(lpi->user_context);
    lpi->user_context = (void*)((char*)(lpi->user_context) + 1);

    ep->oid_index.oids = &ep->index;
    ep->oid_index.len = 1;

    return PMLP_RC_MEMORY_USED;
}
Beispiel #4
0
static int
_load_ipv6(netsnmp_container* container, u_long *index )
{
    FILE           *in;
    char            line[256];
    netsnmp_route_entry *entry = NULL;
    static int      log_open_err = 1;

    DEBUGMSGTL(("access:route:container",
                "route_container_arch_load ipv6\n"));

    netsnmp_assert(NULL != container);

    /*
     * fetch routes from the proc file-system:
     */
    if (!(in = fopen("/proc/net/ipv6_route", "r"))) {
        if (1 == log_open_err) {
            NETSNMP_LOGONCE((LOG_ERR, "cannot open /proc/net/ipv6_route\n"));
            log_open_err = 0;
        }
        return -2;
    }
    /*
     * if we turned off logging of open errors, turn it back on now that
     * we have been able to open the file.
     */
    if (0 == log_open_err)
        log_open_err = 1;
    fgets(line,sizeof(line),in); /* skip header */
    while (fgets(line, sizeof(line), in)) {
        char            c_name[IFNAMSIZ+1];
        char            c_dest[33], c_src[33], c_next[33];
        int             rc;
        unsigned int    dest_pfx, flags;
        size_t          buf_len, buf_offset;
        u_char          *temp_uchar_ptr;

        entry = netsnmp_access_route_entry_create();

        /*
         * based on /usr/src/linux/net/ipv6/route.c, kernel 2.6.7:
         *
         * [        Dest addr /         plen ]
         * fe80000000000000025056fffec00008 80 \
         *
         * [ (?subtree) : src addr/plen : 0/0]
         * 00000000000000000000000000000000 00 \
         *
         * [        next hop              ][ metric ][ref ctn][ use   ]
         * 00000000000000000000000000000000 00000000 00000000 00000000 \
         *
         * [ flags ][dev name]
         * 80200001       lo
         */
        rc = sscanf(line, "%32s %2x %32s %*x %32s %x %*x %*x %x %"
                    SNMP_MACRO_VAL_TO_STR(IFNAMSIZ) "s\n",
                    c_dest, &dest_pfx, c_src, /*src_pfx,*/ c_next,
                    &entry->rt_metric1, /** ref,*/ /* use, */ &flags, c_name);
        DEBUGMSGTL(("9:access:route:container", "line |%s|\n", line));
        if (7 != rc) {
            snmp_log(LOG_ERR,
                     "/proc/net/ipv6_route data format error (%d!=8), "
                     "line ==|%s|", rc, line);
            continue;
        }

        /*
         * temporary null terminated name
         */
        c_name[ sizeof(c_name)-1 ] = 0;
        entry->if_index = se_find_value_in_slist("interfaces", c_name);
        if(SE_DNE == entry->if_index) {
            snmp_log(LOG_ERR,"unknown interface in /proc/net/ipv6_route "
                     "('%s')\n", c_name);
            netsnmp_access_route_entry_free(entry);
            continue;
        }
        /*
         * arbitrary index
         */
        entry->ns_rt_index = ++(*index);

#ifdef USING_IP_FORWARD_MIB_IPCIDRROUTETABLE_IPCIDRROUTETABLE_MODULE
        /** entry->rt_mask = mask; */ /* IPv4 only */
        /** entry->rt_tos = XXX; */
        /** rt info ?? */
#endif
        /*
         * convert hex addresses to binary
         */
        entry->rt_dest_type = INETADDRESSTYPE_IPV6;
        entry->rt_dest_len = 16;
        buf_len = sizeof(entry->rt_dest);
        buf_offset = 0;
        temp_uchar_ptr = entry->rt_dest;
        netsnmp_hex_to_binary(&temp_uchar_ptr, &buf_len, &buf_offset, 0,
                              c_dest, NULL);

        entry->rt_nexthop_type = INETADDRESSTYPE_IPV6;
        entry->rt_nexthop_len = 16;
        buf_len = sizeof(entry->rt_nexthop);
        buf_offset = 0;
        temp_uchar_ptr = entry->rt_nexthop;
        netsnmp_hex_to_binary(&temp_uchar_ptr, &buf_len, &buf_offset, 0,
                              c_next, NULL);

        entry->rt_pfx_len = dest_pfx;

#ifdef USING_IP_FORWARD_MIB_INETCIDRROUTETABLE_INETCIDRROUTETABLE_MODULE
        /*
    inetCidrRoutePolicy OBJECT-TYPE 
        SYNTAX     OBJECT IDENTIFIER 
        MAX-ACCESS not-accessible 
        STATUS     current 
        DESCRIPTION 
               "This object is an opaque object without any defined 
                semantics.  Its purpose is to serve as an additional 
                index which may delineate between multiple entries to 
                the same destination.  The value { 0 0 } shall be used 
                as the default value for this object."
        */
        /*
         * on linux, default routes all look alike, and would have the same
         * indexed based on dest and next hop. So we use our arbitrary index
         * as the policy, to distinguish between them.
         */
        entry->rt_policy = calloc(3, sizeof(oid));
        entry->rt_policy[2] = entry->ns_rt_index;
        entry->rt_policy_len = sizeof(oid)*3;
#endif

        /*
         * get protocol and type from flags
         */
        entry->rt_type = _type_from_flags(flags);
        
        entry->rt_proto = (flags & RTF_DYNAMIC)
            ? IANAIPROUTEPROTOCOL_ICMP : IANAIPROUTEPROTOCOL_LOCAL;

        /*
         * insert into container
         */
        CONTAINER_INSERT(container, entry);
    }

    fclose(in);
    return 0;
}
Beispiel #5
0
/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
static int
_load6(netsnmp_container *container, u_int load_flags)
{
    int             rc = 0;
    FILE           *in;
    char            line[180];
    
    netsnmp_assert(NULL != container);

#undef PROCFILE
#define PROCFILE "/proc/net/tcp6"
    if (!(in = fopen(PROCFILE, "r"))) {
        snmp_log(LOG_ERR,"could not open " PROCFILE "\n");
        return -2;
    }
    
    fgets(line, sizeof(line), in); /* skip header */

    /*
     *   sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
     *  0: 00000000000000000000000000000001:1466 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000   500        0 326699 1 efb81580 3000 0 0 2 -1
     */
    while (fgets(line, sizeof(line), in)) {
        netsnmp_tcpconn_entry *entry;
        int             state, rc, local_port, remote_port, buf_len, offset,
                        tmp_state;
        u_char          local_addr[48], remote_addr[48];
        u_char         *tmp_ptr;

        if (5 != (rc = sscanf(line, "%*d: %47[0-9A-Z]:%x %47[0-9A-Z]:%x %x",
                              local_addr, &local_port,
                              remote_addr, &remote_port, &tmp_state))) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing line (%d != 5)\n", rc));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
            continue;
        }
        DEBUGMSGT(("verbose:access:tcpconn:container"," line '%s'\n", line));

        /*
         * check if we care about listen state
         */
        state = (tmp_state & 0xf) < 12 ? linux_states[tmp_state & 0xf] : 2;
        if (load_flags) {
            if (TCPCONNECTIONSTATE_LISTEN == state) {
                if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_NOLISTEN) {
                    DEBUGMSGT(("verbose:access:tcpconn:container",
                               " skipping listen\n"));
                    continue;
                }
            }
            else if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_ONLYLISTEN) {
                    DEBUGMSGT(("verbose:access:tcpconn:container",
                               " skipping non-listen\n"));
                    continue;
            }
        }

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

        entry->loc_port = htons((unsigned short) local_port);
        entry->rmt_port = htons((unsigned short) remote_port);
        entry->tcpConnState = state;

        buf_len = strlen(local_addr);
        offset = 0;
        tmp_ptr = entry->loc_addr;
        rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len,
                                   &offset, 0, local_addr, NULL);
        entry->loc_addr_len = offset;
        if (( 16 != entry->loc_addr_len ) && ( 20 != entry->loc_addr_len )) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing local addr (%d != 16|20)\n",
                       entry->loc_addr_len));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }

        buf_len = strlen(remote_addr);
        offset = 0;
        tmp_ptr = entry->rmt_addr;
        rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len,
                                   &offset, 0, remote_addr, NULL);
        entry->rmt_addr_len = offset;
        if (( 16 != entry->rmt_addr_len ) && ( 20 != entry->rmt_addr_len )) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing remote addr (%d != 16|20)\n",
                       entry->rmt_addr_len));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }


        /*
         * add entry to container
         */
        entry->arbitrary_index = CONTAINER_SIZE(container) + 1;
        CONTAINER_INSERT(container, entry);
    }

    fclose(in);

    if(rc<0)
        return rc;

    return 0;
}
Beispiel #6
0
/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
static int
_load4(netsnmp_container *container, u_int load_flags)
{
    int             rc = 0;
    FILE           *in;
    char            line[160];
    
    netsnmp_assert(NULL != container);

#define PROCFILE "/proc/net/tcp"
    if (!(in = fopen(PROCFILE, "r"))) {
        snmp_log(LOG_ERR,"could not open " PROCFILE "\n");
        return -2;
    }
    
    fgets(line, sizeof(line), in); /* skip header */

    /*
     *   sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
     *   0: 00000000:8000 00000000:0000 0A 00000000:00000000 00:00000000 00000000    29        0 1028 1 df7b1b80 300 0 0 2 -1
     */
    while (fgets(line, sizeof(line), in)) {
        netsnmp_tcpconn_entry *entry;
        unsigned int    state, local_port, remote_port, tmp_state;
        unsigned long long inode;
        size_t          buf_len, offset;
        char            local_addr[10], remote_addr[10];
        u_char         *tmp_ptr;

        if (6 != (rc = sscanf(line, "%*d: %8[0-9A-Z]:%x %8[0-9A-Z]:%x %x %*x:%*x %*x:%*x %*x %*x %*x %llu",
                              local_addr, &local_port,
                              remote_addr, &remote_port, &tmp_state, &inode))) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing line (%d != 6)\n", rc));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
	    snmp_log(LOG_ERR, "tcp:_load4: bad line in " PROCFILE ": %s\n", line);
	    rc = 0;
            continue;
        }
        DEBUGMSGT(("verbose:access:tcpconn:container"," line '%s'\n", line));

        /*
         * check if we care about listen state
         */
        state = (tmp_state & 0xf) < 12 ? linux_states[tmp_state & 0xf] : 2;
        if (load_flags) {
            if (TCPCONNECTIONSTATE_LISTEN == state) {
                if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_NOLISTEN) {
                    DEBUGMSGT(("verbose:access:tcpconn:container",
                               " skipping listen\n"));
                    continue;
                }
            }
            else if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_ONLYLISTEN) {
                    DEBUGMSGT(("verbose:access:tcpconn:container",
                               " skipping non-listen\n"));
                    continue;
            }
        }

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

        /** oddly enough, these appear to already be in network order */
        entry->loc_port = (unsigned short) local_port;
        entry->rmt_port = (unsigned short) remote_port;
        entry->tcpConnState = state;
        entry->pid = netsnmp_get_pid_from_inode(inode);

        /** the addr string may need work */
        buf_len = strlen(local_addr);
        if ((8 != buf_len) ||
            (-1 == netsnmp_addrstr_hton(local_addr, 8))) {
            DEBUGMSGT(("verbose:access:tcpconn:container",
                       " error processing local address\n"));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }
        offset = 0;
        tmp_ptr = entry->loc_addr;
        rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len,
                                   &offset, 0, local_addr, NULL);
        entry->loc_addr_len = offset;
        if ( 4 != entry->loc_addr_len ) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing local addr (%d != 4)\n",
                       entry->loc_addr_len));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }

        /** the addr string may need work */
        buf_len = strlen((char*)remote_addr);
        if ((8 != buf_len) ||
            (-1 == netsnmp_addrstr_hton(remote_addr, 8))) {
            DEBUGMSGT(("verbose:access:tcpconn:container",
                       " error processing remote address\n"));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }
        offset = 0;
        tmp_ptr = entry->rmt_addr;
        rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len,
                                   &offset, 0, remote_addr, NULL);
        entry->rmt_addr_len = offset;
        if ( 4 != entry->rmt_addr_len ) {
            DEBUGMSGT(("access:tcpconn:container",
                       "error parsing remote addr (%d != 4)\n",
                       entry->rmt_addr_len));
            DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line));
            netsnmp_access_tcpconn_entry_free(entry);
            continue;
        }

        /*
         * add entry to container
         */
        entry->arbitrary_index = CONTAINER_SIZE(container) + 1;
        CONTAINER_INSERT(container, entry);
    }

    fclose(in);

    if(rc<0)
        return rc;

    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, 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;
}
Beispiel #8
0
int
_load_v6(netsnmp_container *container, int idx_offset)
{
#ifndef HAVE_LINUX_RTNETLINK_H
    DEBUGMSGTL(("access:ipaddress:container",
                "cannot get ip address information"
                "as netlink socket is not available\n"));
    return -1;
#else
    FILE           *in;
    char            line[80], addr[40];
    char            if_name[IFNAMSIZ+1];/* +1 for '\0' because of the ugly sscanf below */ 
    u_char          *buf;
    int             if_index, pfx_len, scope, flags, rc = 0;
    size_t          in_len, out_len;
    netsnmp_ipaddress_entry *entry;
    _ioctl_extras           *extras;
    struct address_flag_info addr_info;
    
    netsnmp_assert(NULL != container);

#define PROCFILE "/proc/net/if_inet6"
    if (!(in = fopen(PROCFILE, "r"))) {
        DEBUGMSGTL(("access:ipaddress:container","could not open " PROCFILE "\n"));
        return -2;
    }

    /*
     * address index prefix_len scope status if_name
     */
    while (fgets(line, sizeof(line), in)) {
        /*
         * fe800000000000000200e8fffe5b5c93 05 40 20 80 eth0
         *             A                    D  P  S  F  I
         * A: address
         * D: device number
         * P: prefix len
         * S: scope (see include/net/ipv6.h, net/ipv6/addrconf.c)
         * F: flags (see include/linux/rtnetlink.h, net/ipv6/addrconf.c)
         * I: interface
         */
        rc = sscanf(line, "%39s %08x %08x %04x %02x %" SNMP_MACRO_VAL_TO_STR(IFNAMSIZ) "s\n",
                    addr, &if_index, &pfx_len, &scope, &flags, if_name);
        if( 6 != rc ) {
            snmp_log(LOG_ERR, PROCFILE " data format error (%d!=6), line ==|%s|\n",
                     rc, line);
            continue;
        }
        DEBUGMSGTL(("access:ipaddress:container",
                    "addr %s, index %d, pfx %d, scope %d, flags 0x%X, name %s\n",
                    addr, if_index, pfx_len, scope, flags, if_name));
        /*
         */
        entry = netsnmp_access_ipaddress_entry_create();
        if(NULL == entry) {
            rc = -3;
            break;
        }

        in_len = entry->ia_address_len = sizeof(entry->ia_address);
        netsnmp_assert(16 == in_len);
        out_len = 0;
        entry->flags = flags;
        buf = entry->ia_address;
        if(1 != netsnmp_hex_to_binary(&buf, &in_len,
                                      &out_len, 0, addr, ":")) {
            snmp_log(LOG_ERR,"error parsing '%s', skipping\n",
                     entry->ia_address);
            netsnmp_access_ipaddress_entry_free(entry);
            continue;
        }
        netsnmp_assert(16 == out_len);
        entry->ia_address_len = out_len;

        entry->ns_ia_index = ++idx_offset;

        /*
         * save if name
         */
        extras = netsnmp_ioctl_ipaddress_extras_get(entry);
        memcpy(extras->name, if_name, sizeof(extras->name));
        extras->flags = flags;

        /*
         * yyy-rks: optimization: create a socket outside the loop and use
         * netsnmp_access_interface_ioctl_ifindex_get() here, since
         * netsnmp_access_interface_index_find will open/close a socket
         * every time it is called.
         */
        entry->if_index = netsnmp_access_interface_index_find(if_name);
        memset(&addr_info, 0, sizeof(struct address_flag_info));
        addr_info = netsnmp_access_other_info_get(entry->if_index, AF_INET6);

        /*
          #define IPADDRESSSTATUSTC_PREFERRED  1
          #define IPADDRESSSTATUSTC_DEPRECATED  2
          #define IPADDRESSSTATUSTC_INVALID  3
          #define IPADDRESSSTATUSTC_INACCESSIBLE  4
          #define IPADDRESSSTATUSTC_UNKNOWN  5
          #define IPADDRESSSTATUSTC_TENTATIVE  6
          #define IPADDRESSSTATUSTC_DUPLICATE  7
        */
        if((flags & IFA_F_PERMANENT) || (!flags))
            entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; /* ?? */
#ifdef IFA_F_TEMPORARY
        else if(flags & IFA_F_TEMPORARY)
            entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; /* ?? */
#endif
        else if(flags & IFA_F_DEPRECATED)
            entry->ia_status = IPADDRESSSTATUSTC_DEPRECATED;
        else if(flags & IFA_F_TENTATIVE)
            entry->ia_status = IPADDRESSSTATUSTC_TENTATIVE;
        else {
            entry->ia_status = IPADDRESSSTATUSTC_UNKNOWN;
            DEBUGMSGTL(("access:ipaddress:ipv6",
                        "unknown flags 0x%x\n", flags));
        }

        /*
         * if it's not multi, it must be uni.
         *  (an ipv6 address is never broadcast)
         */
        if(addr_info.anycastflg)
            entry->ia_type = IPADDRESSTYPE_ANYCAST;
        else
            entry->ia_type = IPADDRESSTYPE_UNICAST;


        entry->ia_prefix_len = pfx_len;

        /*
         * can we figure out if an address is from DHCP?
         * use manual until then...
         *
         *#define IPADDRESSORIGINTC_OTHER  1
         *#define IPADDRESSORIGINTC_MANUAL  2
         *#define IPADDRESSORIGINTC_DHCP  4
         *#define IPADDRESSORIGINTC_LINKLAYER  5
         *#define IPADDRESSORIGINTC_RANDOM  6
         *
         * are 'local' address assigned by link layer??
         */
         if (!flags)
             entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER;
#ifdef IFA_F_TEMPORARY
         else if (flags & IFA_F_TEMPORARY)
             entry->ia_origin = IPADDRESSORIGINTC_RANDOM;
#endif
         else if (IN6_IS_ADDR_LINKLOCAL(entry->ia_address))
             entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER;
         else
             entry->ia_origin = IPADDRESSORIGINTC_MANUAL;

         if(entry->ia_origin == IPADDRESSORIGINTC_LINKLAYER)
            entry->ia_storagetype = STORAGETYPE_PERMANENT;

        /* xxx-rks: what can we do with scope? */
#ifdef HAVE_LINUX_RTNETLINK_H
        if(netsnmp_access_ipaddress_extra_prefix_info(entry->if_index, &entry->ia_prefered_lifetime
                                                      ,&entry->ia_valid_lifetime, addr) < 0){
           DEBUGMSGTL(("access:ipaddress:container", "unable to fetch extra prefix info\n"));
        }
#else
        entry->ia_prefered_lifetime = 0;
        entry->ia_valid_lifetime = 0;
#endif
#ifdef SUPPORT_PREFIX_FLAGS
        {
        prefix_cbx      prefix_val;
        memset(&prefix_val, 0, sizeof(prefix_cbx));
        if(net_snmp_find_prefix_info(&prefix_head_list, addr, &prefix_val) < 0) {
           DEBUGMSGTL(("access:ipaddress:container", "unable to find info\n"));
           entry->ia_onlink_flag = 1;  /*Set by default as true*/
           entry->ia_autonomous_flag = 2; /*Set by default as false*/

        } else {
           entry->ia_onlink_flag = prefix_val.ipAddressPrefixOnLinkFlag; 
           entry->ia_autonomous_flag = prefix_val.ipAddressPrefixAutonomousFlag;
        }
        }
#else
        entry->ia_onlink_flag = 1;  /*Set by default as true*/
        entry->ia_autonomous_flag = 2; /*Set by default as false*/
#endif

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

    fclose(in);

    if(rc<0)
        return rc;

    return idx_offset;
}
Beispiel #9
0
int
_load_v6(netsnmp_container *container, int idx_offset)
{
    FILE           *in;
    char            line[80], addr[40], if_name[IFNAMSIZ];
    u_char          *buf;
    int             if_index, pfx_len, scope, flags, rc = 0;
    size_t          in_len, out_len;
    netsnmp_ipaddress_entry *entry;
    _ioctl_extras           *extras;
    static int      log_open_err = 1;
    
    netsnmp_assert(NULL != container);

#define PROCFILE "/proc/net/if_inet6"
    if (!(in = fopen(PROCFILE, "r"))) {
        if (1 == log_open_err) {
            snmp_log(LOG_ERR,"could not open " PROCFILE "\n");
            log_open_err = 0;
        }
        return -2;
    }
    /*
     * if we hadn't been able to open file and turned of err logging,
     * turn it back on now that we opened the file.
     */
    if (0 == log_open_err)
        log_open_err = 1;

    /*
     * address index prefix_len scope status if_name
     */
    while (fgets(line, sizeof(line), in)) {
        /*
         * fe800000000000000200e8fffe5b5c93 05 40 20 80 eth0
         *             A                    D  P  S  F  I
         * A: address
         * D: device number
         * P: prefix len
         * S: scope (see include/net/ipv6.h, net/ipv6/addrconf.c)
         * F: flags (see include/linux/rtnetlink.h, net/ipv6/addrconf.c)
         * I: interface
         */
        rc = sscanf(line, "%39s %02x %02x %02x %02x %8s\n",
                    addr, &if_index, &pfx_len, &scope, &flags, if_name);
        if( 6 != rc ) {
            snmp_log(LOG_ERR, PROCFILE " data format error (%d!=6), line ==|%s|\n",
                     rc, line);
            continue;
        }
        DEBUGMSGTL(("access:ipaddress:container",
                    "addr %s, index %d, pfx %d, scope %d, flags 0x%X, name %s\n",
                    addr, if_index, pfx_len, scope, flags, if_name));
        /*
         */
        entry = netsnmp_access_ipaddress_entry_create();
        if(NULL == entry) {
            rc = -3;
            break;
        }

        in_len = entry->ia_address_len = sizeof(entry->ia_address);
        netsnmp_assert(16 == in_len);
        out_len = 0;
        buf = entry->ia_address;
        if(1 != netsnmp_hex_to_binary(&buf, &in_len,
                                      &out_len, 0, addr, ":")) {
            snmp_log(LOG_ERR,"error parsing '%s', skipping\n",
                     entry->ia_address);
            netsnmp_access_ipaddress_entry_free(entry);
            continue;
        }
        netsnmp_assert(16 == out_len);
        entry->ia_address_len = out_len;

        entry->ns_ia_index = ++idx_offset;

        /*
         * save if name
         */
        extras = netsnmp_ioctl_ipaddress_extras_get(entry);
        memcpy(extras->name, if_name, sizeof(extras->name));
        extras->flags = flags;

        /*
         * yyy-rks: optimization: create a socket outside the loop and use
         * netsnmp_access_interface_ioctl_ifindex_get() here, since
         * netsnmp_access_interface_index_find will open/close a socket
         * every time it is called.
         */
     //   entry->if_index = netsnmp_access_interface_index_find(if_name); //cz modified

        /*
          #define IPADDRESSSTATUSTC_PREFERRED  1
          #define IPADDRESSSTATUSTC_DEPRECATED  2
          #define IPADDRESSSTATUSTC_INVALID  3
          #define IPADDRESSSTATUSTC_INACCESSIBLE  4
          #define IPADDRESSSTATUSTC_UNKNOWN  5
          #define IPADDRESSSTATUSTC_TENTATIVE  6
          #define IPADDRESSSTATUSTC_DUPLICATE  7
        */
        if(flags & IFA_F_PERMANENT)
            entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; /* ?? */
        else if(flags & IFA_F_DEPRECATED)
            entry->ia_status = IPADDRESSSTATUSTC_DEPRECATED;
        else if(flags & IFA_F_TENTATIVE)
            entry->ia_status = IPADDRESSSTATUSTC_TENTATIVE;
        else {
            entry->ia_status = IPADDRESSSTATUSTC_UNKNOWN;
            DEBUGMSGTL(("access:ipaddress:ipv6",
                        "unknown flags 0x%x\n", flags));
        }

        /*
         * if it's not multi, it must be uni.
         *  (an ipv6 address is never broadcast)
         */
        if (IN6_IS_ADDR_MULTICAST(entry->ia_address))
            entry->ia_type = IPADDRESSTYPE_ANYCAST;
        else
            entry->ia_type = IPADDRESSTYPE_UNICAST;


        entry->ia_prefix_len = pfx_len;

        /*
         * can we figure out if an address is from DHCP?
         * use manual until then...
         *
         *#define IPADDRESSORIGINTC_OTHER  1
         *#define IPADDRESSORIGINTC_MANUAL  2
         *#define IPADDRESSORIGINTC_DHCP  4
         *#define IPADDRESSORIGINTC_LINKLAYER  5
         *#define IPADDRESSORIGINTC_RANDOM  6
         *
         * are 'local' address assigned by link layer??
         */
        if (IN6_IS_ADDR_LINKLOCAL(entry->ia_address) ||
            IN6_IS_ADDR_SITELOCAL(entry->ia_address))
            entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER;
        else
            entry->ia_origin = IPADDRESSORIGINTC_MANUAL;

        /* xxx-rks: what can we do with scope? */

        /*
         * add entry to container
         */
        CONTAINER_INSERT(container, entry);
    }

    fclose(in);

    if(rc<0)
        return rc;

    return idx_offset;
}