Ejemplo n.º 1
0
int netsnmp_access_arp_load(netsnmp_arp_access *access)
{
    int err = 0;

    access->generation++;
    DEBUGMSGTL(("access:route:container",
                "route_container_arch_load ipv4\n"));
    err = _load_arp_table_from_sysctl(access);
    if (err != 0) {
        NETSNMP_LOGONCE((LOG_ERR,
            "netsnmp_access_arp_ipv4 failed %d\n", err));
        goto out;
    }
    access->gc_hook(access);
    access->synchronized = (err == 0);

#ifdef NETSNMP_ENABLE_IPV6
    DEBUGMSGTL(("access:route:container",
                "route_container_arch_load ipv6\n"));
    err = _load_ndp_table_from_sysctl(access);
    if (err != 0) {
        NETSNMP_LOGONCE((LOG_ERR,
            "netsnmp_access_arp_ipv6 failed %d\n", err));
        goto out;
    }
    access->gc_hook(access);
    access->synchronized = (err == 0);
#endif

out:
    return (err == 0 ? 0 : -1);
}
Ejemplo n.º 2
0
/** arch specific load
 * @internal
 *
 * @retval  0 success
 * @retval -1 no container specified
 * @retval -2 could not access data source
 */
int
netsnmp_access_route_container_arch_load(netsnmp_container* container,
					 u_int load_flags)
{
    int count, err;

    err = 0;

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

    if (container == NULL) {
        snmp_log(LOG_ERR, "no container specified/found for access_route\n");
        return -1;
    }

    err = _load_ipv4(container, &count);
    if (err != 0) {
        NETSNMP_LOGONCE((LOG_ERR, "_load_ipv4 failed %d\n", err));
        goto out;
    }

    if (err != 0 || load_flags & NETSNMP_ACCESS_ROUTE_LOAD_IPV4_ONLY)
	return err;

    err = _load_ipv6(container, &count);
    if (err != 0) {
        NETSNMP_LOGONCE((LOG_ERR, "_load_ipv6 failed %d\n", err));
        goto out;
    }

out:
    return (err == 0 ? 0 : -3);
}
Ejemplo n.º 3
0
int
tcpTable_load(netsnmp_cache *cache, void *vmagic)
{
    FILE           *in;
    char            line[256];

    tcpTable_free(cache, NULL);

#if HAVE_NETLINK_NETLINK_H
    if (tcpTable_load_netlink() == 0) {
        return 0;
    }
#endif

    if (!(in = fopen("/proc/net/tcp", "r"))) {
        DEBUGMSGTL(("mibII/tcpTable", "Failed to load TCP Table (linux1)\n"));
        NETSNMP_LOGONCE((LOG_ERR, "snmpd: cannot open /proc/net/tcp ...\n"));
        return -1;
    }

    /*
     * scan proc-file and build up a linked list
     * This will actually be built up in reverse,
     *   but since the entries are unsorted, that doesn't matter.
     */
    while (line == fgets(line, sizeof(line), in)) {
        struct inpcb    pcb, *nnew;
        unsigned int    lp, fp;
        int             state, uid;

        if (6 != sscanf(line,
                        "%*d: %x:%x %x:%x %x %*X:%*X %*X:%*X %*X %d",
                        &pcb.inp_laddr.s_addr, &lp,
                        &pcb.inp_faddr.s_addr, &fp, &state, &uid))
            continue;

        pcb.inp_lport = htons((unsigned short) lp);
        pcb.inp_fport = htons((unsigned short) fp);

        pcb.inp_state = (state & 0xf) < 12 ? linux_states[state & 0xf] : 2;
        if (pcb.inp_state == 5 /* established */ ||
                pcb.inp_state == 8 /*  closeWait  */ )
            tcp_estab++;
        pcb.uid = uid;

        nnew = SNMP_MALLOC_TYPEDEF(struct inpcb);
        if (nnew == NULL)
            break;
        memcpy(nnew, &pcb, sizeof(struct inpcb));
        nnew->inp_next = tcp_head;
        tcp_head       = nnew;
    }

    fclose(in);

    DEBUGMSGTL(("mibII/tcpTable", "Loaded TCP Table (linux)\n"));
    return 0;
}
Ejemplo n.º 4
0
struct hostent *
netsnmp_gethostbyname(const char *name)
{
#if HAVE_GETHOSTBYNAME
#ifdef DNSSEC_LOCAL_VALIDATION
    val_status_t val_status;
#endif
    struct hostent *hp = NULL;

    if (NULL == name)
        return NULL;

    DEBUGMSGTL(("dns:gethostbyname", "looking up %s\n", name));

#ifdef DNSSEC_LOCAL_VALIDATION
    hp  = val_gethostbyname(netsnmp_validator_context(), name, &val_status);
    DEBUGMSGTL(("dns:sec:val", "val_status %d / %s; trusted: %d\n",
                val_status, p_val_status(val_status),
                val_istrusted(val_status)));
    if (!val_istrusted(val_status)) {
        snmp_log(LOG_WARNING,
                 "The authenticity of DNS response is not trusted (%s)\n",
                 p_val_status(val_status));
        /** continue anyways if DNSSEC_WARN_ONLY is set */
        if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
                                    NETSNMP_DS_LIB_DNSSEC_WARN_ONLY))
            hp = NULL;
    }
    else if (val_does_not_exist(val_status) && hp)
        hp = NULL;
#else
    hp = gethostbyname(name);
#endif
    if (hp == NULL) {
        DEBUGMSGTL(("dns:gethostbyname",
                    "couldn't resolve %s\n", name));
    } else if (hp->h_addrtype != AF_INET) {
        DEBUGMSGTL(("dns:gethostbyname",
                    "warning: response for %s not AF_INET!\n", name));
    } else {
        DEBUGMSGTL(("dns:gethostbyname",
                    "%s resolved okay\n", name));
    }
    return hp;
#else
    NETSNMP_LOGONCE((LOG_ERR, "gethostbyname not available"));
    return NULL;
#endif /* HAVE_GETHOSTBYNAME */
}
Ejemplo n.º 5
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);
        }
    }
}
Ejemplo n.º 6
0
struct hostent *
netsnmp_gethostbyaddr(const void *addr, socklen_t len, int type)
{
#if HAVE_GETHOSTBYADDR
    struct hostent *hp = NULL;
    struct sockaddr_in *saddr_in =
        NETSNMP_REMOVE_CONST(struct sockaddr_in *,addr);

    DEBUGMSGTL(("dns:gethostbyaddr", "resolving { AF_INET, %s:%hu }\n",
                inet_ntoa(saddr_in->sin_addr), ntohs(saddr_in->sin_port)));

#ifdef DNSSEC_LOCAL_VALIDATION
    val_status_t val_status;
    hp = val_gethostbyaddr(netsnmp_validator_context(),
                           (const void*)&saddr_in->sin_addr,
                           sizeof(struct in_addr), AF_INET, &val_status);
    DEBUGMSGTL(("dns:sec:val", "val_status %d / %s; trusted: %d\n",
                val_status, p_val_status(val_status),
                val_istrusted(val_status)));
    if (!val_istrusted(val_status)) {
        snmp_log(LOG_WARNING,
                 "The authenticity of DNS response is not trusted (%s)\n",
                 p_val_status(val_status));
        /** continue anyways if DNSSEC_WARN_ONLY is set */
        if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
                                    NETSNMP_DS_LIB_DNSSEC_WARN_ONLY))
            hp = NULL;
    }
    else if (val_does_not_exist(val_status) && hp)
        hp = NULL;
#else
    hp = gethostbyaddr((const void*) &saddr_in->sin_addr,
                       sizeof(struct in_addr), AF_INET);
#endif
    if (hp == NULL) {
        DEBUGMSGTL(("dns:gethostbyaddr", "couldn't resolve addr\n"));
    } else if (hp->h_addrtype != AF_INET) {
        DEBUGMSGTL(("dns:gethostbyaddr",
                    "warning: response for addr not AF_INET!\n"));
    } else {
        DEBUGMSGTL(("dns:gethostbyaddr", "addr resolved okay\n"));
    }
    return hp;
#else
    NETSNMP_LOGONCE((LOG_ERR, "gethostbyaddr not available"));
    return NULL;
#endif
}
Ejemplo n.º 7
0
static void
_access_interface_entry_save_name(const char *name, oid index)
{
    int tmp;

    if(NULL == name)
        return;

    tmp = se_find_value_in_slist("interfaces", name);
    if (tmp == SE_DNE) {
        se_add_pair_to_slist("interfaces", strdup(name), index);
        DEBUGMSGTL(("access:interface:ifIndex",
                    "saved ifIndex %" NETSNMP_PRIo "u for %s\n",
                    index, name));
    }
    else
        if (index != (oid)tmp) {
            NETSNMP_LOGONCE((LOG_ERR, "IfIndex of an interface changed. Such " \
                         "interfaces will appear multiple times in IF-MIB.\n"));
            DEBUGMSGTL(("access:interface:ifIndex",
                        "index %" NETSNMP_PRIo "u != tmp for %s\n",
                        index, name));
        }
}
Ejemplo n.º 8
0
/*
 * Based on load_flags, load ipSystemStatsTable or ipIfStatsTable for ipv4 entries. 
 */
static int
_systemstats_v4(netsnmp_container* container, u_int load_flags)
{
    FILE           *devin;
    char            line[1024];
    netsnmp_systemstats_entry *entry = NULL;
    int             scan_count;
    char           *stats, *start = line;
    int             len;
    unsigned long long scan_vals[19];

    DEBUGMSGTL(("access:systemstats:container:arch", "load v4 (flags %x)\n",
                load_flags));

    netsnmp_assert(container != NULL); /* load function shoulda checked this */

    if (load_flags & NETSNMP_ACCESS_SYSTEMSTATS_LOAD_IFTABLE) {
        /* we do not support ipIfStatsTable for ipv4 */
        return 0;
    }

    if (!(devin = fopen("/proc/net/snmp", "r"))) {
        DEBUGMSGTL(("access:systemstats",
                    "Failed to load Systemstats Table (linux1)\n"));
        NETSNMP_LOGONCE((LOG_ERR, "cannot open /proc/net/snmp ...\n"));
        return -2;
    }

    /*
     * skip header, but make sure it's the length we expect...
     */
    fgets(line, sizeof(line), devin);
    len = strlen(line);
    if (224 != len) {
        fclose(devin);
        snmp_log(LOG_ERR, "unexpected header length in /proc/net/snmp."
                 " %d != 224\n", len);
        return -4;
    }

    /*
     * This file provides the statistics for each systemstats.
     * Read in each line in turn, isolate the systemstats name
     *   and retrieve (or create) the corresponding data structure.
     */
    start = fgets(line, sizeof(line), devin);
    fclose(devin);
    if (start) {

        len = strlen(line);
        if (line[len - 1] == '\n')
            line[len - 1] = '\0';

        while (*start && *start == ' ')
            start++;

        if ((!*start) || ((stats = strrchr(start, ':')) == NULL)) {
            snmp_log(LOG_ERR,
                     "systemstats data format error 1, line ==|%s|\n", line);
            return -4;
        }

        DEBUGMSGTL(("access:systemstats", "processing '%s'\n", start));

        *stats++ = 0; /* null terminate name */
        while (*stats == ' ') /* skip spaces before stats */
            stats++;

        entry = netsnmp_access_systemstats_entry_create(1, 0,
                    "ipSystemStatsTable.ipv4");
        if(NULL == entry) {
            netsnmp_access_systemstats_container_free(container,
                                                      NETSNMP_ACCESS_SYSTEMSTATS_FREE_NOFLAGS);
            return -3;
        }

        /*
         * OK - we've now got (or created) the data structure for
         *      this systemstats, including any "static" information.
         * Now parse the rest of the line (i.e. starting from 'stats')
         *      to extract the relevant statistics, and populate
         *      data structure accordingly.
         */

        memset(scan_vals, 0x0, sizeof(scan_vals));
        scan_count = sscanf(stats,
                            "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu"
                            "%llu %llu %llu %llu %llu %llu %llu %llu %llu",
                            &scan_vals[0],&scan_vals[1],&scan_vals[2],
                            &scan_vals[3],&scan_vals[4],&scan_vals[5],
                            &scan_vals[6],&scan_vals[7],&scan_vals[8],
                            &scan_vals[9],&scan_vals[10],&scan_vals[11],
                            &scan_vals[12],&scan_vals[13],&scan_vals[14],
                            &scan_vals[15],&scan_vals[16],&scan_vals[17],
                            &scan_vals[18]);
        DEBUGMSGTL(("access:systemstats", "  read %d values\n", scan_count));

        if(scan_count != 19) {
            snmp_log(LOG_ERR,
                     "error scanning systemstats data (expected %d, got %d)\n",
                     19, scan_count);
            netsnmp_access_systemstats_entry_free(entry);
            return -4;
        }
        /* entry->stats. = scan_vals[0]; / * Forwarding */
        /* entry->stats. = scan_vals[1]; / * DefaultTTL */
        entry->stats.HCInReceives.low = scan_vals[2] & 0xffffffff;
        entry->stats.HCInReceives.high = scan_vals[2] >> 32;
        entry->stats.InHdrErrors = scan_vals[3];
        entry->stats.InAddrErrors = scan_vals[4];
        entry->stats.HCOutForwDatagrams.low = scan_vals[5] & 0xffffffff;
        entry->stats.HCOutForwDatagrams.high = scan_vals[5] >> 32;
        entry->stats.InUnknownProtos = scan_vals[6];
        entry->stats.InDiscards = scan_vals[7];
        entry->stats.HCInDelivers.low = scan_vals[8] & 0xffffffff;
        entry->stats.HCInDelivers.high = scan_vals[8] >> 32;
        entry->stats.HCOutRequests.low = scan_vals[9] & 0xffffffff;
        entry->stats.HCOutRequests.high = scan_vals[9] >> 32;
        entry->stats.HCOutDiscards.low = scan_vals[10] & 0xffffffff;;
        entry->stats.HCOutDiscards.high = scan_vals[10] >> 32;
        entry->stats.HCOutNoRoutes.low = scan_vals[11] & 0xffffffff;;
        entry->stats.HCOutNoRoutes.high = scan_vals[11] >> 32;
        /* entry->stats. = scan_vals[12]; / * ReasmTimeout */
        entry->stats.ReasmReqds = scan_vals[13];
        entry->stats.ReasmOKs = scan_vals[14];
        entry->stats.ReasmFails = scan_vals[15];
        entry->stats.HCOutFragOKs.low = scan_vals[16] & 0xffffffff;;
        entry->stats.HCOutFragOKs.high = scan_vals[16] >> 32;
        entry->stats.HCOutFragFails.low = scan_vals[17] & 0xffffffff;;
        entry->stats.HCOutFragFails.high = scan_vals[17] >> 32;
        entry->stats.HCOutFragCreates.low = scan_vals[18] & 0xffffffff;;
        entry->stats.HCOutFragCreates.high = scan_vals[18] >> 32;

        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINRECEIVES] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_INHDRERRORS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_INADDRERRORS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFORWDATAGRAMS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_INUNKNOWNPROTOS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_INDISCARDS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINDELIVERS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTREQUESTS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTDISCARDS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTNOROUTES] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_REASMREQDS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_REASMOKS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_REASMFAILS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFRAGOKS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFRAGFAILS] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTFRAGCREATES] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_DISCONTINUITYTIME] = 1;
        entry->stats.columnAvail[IPSYSTEMSTATSTABLE_REFRESHRATE] = 1;

        /*
         * load addtional statistics defined by RFC 4293
         * As these are supported linux 2.6.22 or later, it is no problem
         * if loading them are failed.
         */
        _additional_systemstats_v4(entry, load_flags);

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

    return 0;
}
Ejemplo n.º 9
0
static int
_additional_systemstats_v4(netsnmp_systemstats_entry* entry,
                           u_int load_flags)
{
    FILE           *devin;
    char            line[1024];
    int             scan_count;
    unsigned long long scan_vals[12];
    int             retval = 0;

    DEBUGMSGTL(("access:systemstats:container:arch",
                "load addtional v4 (flags %u)\n", load_flags));

    if (!(devin = fopen("/proc/net/netstat", "r"))) {
        DEBUGMSGTL(("access:systemstats",
                    "cannot open /proc/net/netstat\n"));
        NETSNMP_LOGONCE((LOG_ERR,"cannot open /proc/net/netstat\n"));
        return -2;
    }

    /*
     * Get header and stat lines
     */
    while (fgets(line, sizeof(line), devin)) {
        if (strncmp(IP_EXT_HEAD, line, sizeof(IP_EXT_HEAD) - 1) == 0) {
            /* next line should includes IPv4 addtional statistics */
            if ((fgets(line, sizeof(line), devin)) == NULL) {
                retval = -4;
                break;
            }
            if (strncmp(IP_EXT_HEAD, line, sizeof(IP_EXT_HEAD) - 1) != 0) {
                retval = -4;
                break;
            }

            memset(scan_vals, 0x0, sizeof(scan_vals));
            scan_count = sscanf(line,
                                "%*s"   /* ignore `IpExt:' */
                                "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
                                &scan_vals[0], &scan_vals[1], &scan_vals[2],
                                &scan_vals[3], &scan_vals[4], &scan_vals[5],
                                &scan_vals[6], &scan_vals[7], &scan_vals[8],
                                &scan_vals[9], &scan_vals[10], &scan_vals[11]);
            if (scan_count < 6) {
                snmp_log(LOG_ERR,
                        "error scanning addtional systemstats data"
                        "(minimum expected %d, got %d)\n",
                        6, scan_count);
                retval = -4;
                break;
            }

            entry->stats.HCInNoRoutes.low    = scan_vals[0] & 0xffffffff;
            entry->stats.HCInNoRoutes.high   = scan_vals[0] >> 32;
            entry->stats.InTruncatedPkts     = scan_vals[1];
            entry->stats.HCInMcastPkts.low   = scan_vals[2] & 0xffffffff;
            entry->stats.HCInMcastPkts.high  = scan_vals[2] >> 32;
            entry->stats.HCOutMcastPkts.low  = scan_vals[3] & 0xffffffff;
            entry->stats.HCOutMcastPkts.high = scan_vals[3] >> 32;
            entry->stats.HCInBcastPkts.low   = scan_vals[4] & 0xffffffff;
            entry->stats.HCInBcastPkts.high  = scan_vals[4] >> 32;
            entry->stats.HCOutBcastPkts.low  = scan_vals[5] & 0xffffffff;
            entry->stats.HCOutBcastPkts.high = scan_vals[5] >> 32;

            entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINNOROUTES] = 1;
            entry->stats.columnAvail[IPSYSTEMSTATSTABLE_INTRUNCATEDPKTS] = 1;
            entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINMCASTPKTS] = 1;
            entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTMCASTPKTS] = 1;
            entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINBCASTPKTS] = 1;
            entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTBCASTPKTS] = 1;
	    if (scan_count >= 12) {
		entry->stats.HCInOctets.low        = scan_vals[6] & 0xffffffff;
		entry->stats.HCInOctets.high       = scan_vals[6] >> 32;
		entry->stats.HCOutOctets.low       = scan_vals[7] & 0xffffffff;
		entry->stats.HCOutOctets.high      = scan_vals[7] >> 32;
		entry->stats.HCInMcastOctets.low   = scan_vals[8] & 0xffffffff;
		entry->stats.HCInMcastOctets.high  = scan_vals[8] >> 32;
		entry->stats.HCOutMcastOctets.low  = scan_vals[9] & 0xffffffff;
		entry->stats.HCOutMcastOctets.high = scan_vals[9] >> 32;
		/* 10 and 11 are In/OutBcastOctets */
		entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINOCTETS] = 1;
		entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTOCTETS] = 1;
		entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCINMCASTOCTETS] = 1;
		entry->stats.columnAvail[IPSYSTEMSTATSTABLE_HCOUTMCASTOCTETS] = 1;
	    }
        }
    }
Ejemplo n.º 10
0
/* ---------------------------------------------------------------------
 */
int
netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags)
{
    rpmts                 ts;

    rpmdbMatchIterator    mi;
    Header                h;
    char                 *n, *v, *r, *g;
    int32_t              *t;
    time_t                install_time;
    size_t                date_len;
    int                   i = 1;
    netsnmp_swinst_entry *entry;

    ts = rpmtsCreate();
    rpmtsSetVSFlags( ts, (_RPMVSF_NOSIGNATURES|_RPMVSF_NODIGESTS));

    mi = rpmtsInitIterator( ts, RPMDBI_PACKAGES, NULL, 0);
    if (mi == NULL)
	NETSNMP_LOGONCE((LOG_ERR, "rpmdbOpen() failed\n"));

    while (NULL != (h = rpmdbNextIterator( mi )))
    {
        const u_char *dt;
        entry = netsnmp_swinst_entry_create( i++ );
        if (NULL == entry)
            continue;   /* error already logged by function */
        CONTAINER_INSERT(container, entry);

        h = headerLink( h );
        headerGetEntry( h, RPMTAG_NAME,        NULL, (void**)&n, NULL);
        headerGetEntry( h, RPMTAG_VERSION,     NULL, (void**)&v, NULL);
        headerGetEntry( h, RPMTAG_RELEASE,     NULL, (void**)&r, NULL);
        headerGetEntry( h, RPMTAG_GROUP,       NULL, (void**)&g, NULL);
        headerGetEntry( h, RPMTAG_INSTALLTIME, NULL, (void**)&t, NULL);

        entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
                                      "%s-%s-%s", n, v, r);
        if (entry->swName_len > sizeof(entry->swName))
            entry->swName_len = sizeof(entry->swName);
        entry->swType = (NULL != strstr( g, "System Environment"))
                        ? 2      /* operatingSystem */
                        : 4;     /*  application    */

        install_time = *t;
        dt = date_n_time( &install_time, &date_len );
        if (date_len != 8 && date_len != 11) {
            snmp_log(LOG_ERR, "Bogus length from date_n_time for %s", entry->swName);
            entry->swDate_len = 0;
        }
        else {
            entry->swDate_len = date_len;
            memcpy(entry->swDate, dt, entry->swDate_len);
        }

        headerFree( h );
    }
    rpmdbFreeIterator( mi );
    rpmtsFree( ts );

    DEBUGMSGTL(("swinst:load:arch", "loaded %d entries\n",
                (int)CONTAINER_SIZE(container)));

    return 0;
}
Ejemplo n.º 11
0
static int
_load_ipv4(netsnmp_container* container, u_long *index )
{
    FILE           *in;
    char            line[256];
    netsnmp_route_entry *entry = NULL;
    char            name[16];
    int             fd;

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

    netsnmp_assert(NULL != container);

    /*
     * fetch routes from the proc file-system:
     */
    if (!(in = fopen("/proc/net/route", "r"))) {
        NETSNMP_LOGONCE((LOG_ERR, "cannot open /proc/net/route\n"));
        return -2;
    }

    /*
     * create socket for ioctls (see NOTE[1], below)
     */
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd < 0) {
        snmp_log(LOG_ERR, "could not create socket\n");
        fclose(in);
        return -2;
    }

    fgets(line, sizeof(line), in); /* skip header */

    while (fgets(line, sizeof(line), in)) {
        char            rtent_name[32];
        int             refcnt, rc;
        uint32_t        dest, nexthop, mask;
        unsigned        flags, use;

        entry = netsnmp_access_route_entry_create();

        /*
         * as with 1.99.14:
         *    Iface Dest     GW       Flags RefCnt Use Met Mask     MTU  Win IRTT
         * BE eth0  00000000 C0A80101 0003  0      0   0   FFFFFFFF 1500 0   0 
         * LE eth0  00000000 0101A8C0 0003  0      0   0   00FFFFFF    0 0   0  
         */
        rc = sscanf(line, "%s %x %x %x %d %u %d %x %*d %*d %*d\n",
                    rtent_name, &dest, &nexthop,
                    /*
                     * XXX: fix type of the args 
                     */
                    &flags, &refcnt, &use, &entry->rt_metric1,
                    &mask);
        DEBUGMSGTL(("9:access:route:container", "line |%s|\n", line));
        if (8 != rc) {
            snmp_log(LOG_ERR,
                     "/proc/net/route data format error (%d!=8), line ==|%s|",
                     rc, line);
            
            netsnmp_access_route_entry_free(entry);        
            continue;
        }

        /*
         * temporary null terminated name
         */
        strlcpy(name, rtent_name, sizeof(name));

        /*
         * don't bother to try and get the ifindex for routes with
         * no interface name.
         * NOTE[1]: normally we'd use netsnmp_access_interface_index_find,
         * but since that will open/close a socket, and we might
         * have a lot of routes, call the ioctl routine directly.
         */
        if ('*' != name[0])
            entry->if_index =
                netsnmp_access_interface_ioctl_ifindex_get(fd,name);

        /*
         * arbitrary index
         */
        entry->ns_rt_index = ++(*index);

#ifdef USING_IP_FORWARD_MIB_IPCIDRROUTETABLE_IPCIDRROUTETABLE_MODULE
        memcpy(&entry->rt_mask, &mask, 4);
        /** entry->rt_tos = XXX; */
        /** rt info ?? */
#endif
        /*
         * copy dest & next hop
         */
        entry->rt_dest_type = INETADDRESSTYPE_IPV4;
        entry->rt_dest_len = 4;
        memcpy(entry->rt_dest, &dest, 4);

        entry->rt_nexthop_type = INETADDRESSTYPE_IPV4;
        entry->rt_nexthop_len = 4;
        memcpy(entry->rt_nexthop, &nexthop, 4);

        /*
         * count bits in mask
         */
        mask = htonl(mask);
        entry->rt_pfx_len = netsnmp_ipaddress_ipv4_prefix_len(mask);

#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 the if index
         * as the policy, to distinguise between them. Hopefully this is
         * unique.
         * xxx-rks: It should really only be for the duplicate case, but that
         *     would be more complicated than I want to get into now. Fix later.
         */
        if (0 == nexthop) {
            entry->rt_policy = calloc(3, sizeof(oid));
            entry->rt_policy[2] = entry->if_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
         */
        if (CONTAINER_INSERT(container, entry) < 0)
        {
            DEBUGMSGTL(("access:route:container", "error with route_entry: insert into container failed.\n"));
            netsnmp_access_route_entry_free(entry);
            continue;
        }
    }

    fclose(in);
    close(fd);
    return 0;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
int get_exec_output (struct extensible *ex)
{
#ifndef USING_UTILITIES_EXECUTE_MODULE
    ex->result = -1;
    NETSNMP_LOGONCE ((LOG_WARNING, "support for run_exec_command not available\n"));
#else
#if HAVE_EXECV
    char cachefile[STRMAX];

    char cache[NETSNMP_MAXCACHESIZE];

    int cachebytes;

    int cfd;

#ifdef NETSNMP_EXCACHETIME
    long curtime;

    static char lastcmd[STRMAX];

    static int lastresult;
#endif

    DEBUGMSGTL (("exec:get_exec_output", "calling %s\n", ex->command));

    sprintf (cachefile, "%s/%s", get_persistent_directory (), NETSNMP_CACHEFILE);
#ifdef NETSNMP_EXCACHETIME
    curtime = time (NULL);
    if (curtime > (cachetime + NETSNMP_EXCACHETIME) || strcmp (ex->command, lastcmd) != 0)
    {
        strcpy (lastcmd, ex->command);
        cachetime = curtime;
#endif

        cachebytes = NETSNMP_MAXCACHESIZE;
        ex->result = run_exec_command (ex->command, NULL, cache, &cachebytes);

        unlink (cachefile);
        /*
         * XXX  Use SNMP_FILEMODE_CLOSED instead of 644? 
         */
        if ((cfd = open (cachefile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0)
        {
            snmp_log (LOG_ERR, "can not create cache file\n");
            setPerrorstatus (cachefile);
#ifdef NETSNMP_EXCACHETIME
            cachetime = 0;
#endif
            return -1;
        }
        if (cachebytes > 0)
            write (cfd, (void *) cache, cachebytes);
        close (cfd);
#ifdef NETSNMP_EXCACHETIME
        lastresult = ex->result;
    }
    else
    {
        ex->result = lastresult;
    }
#endif
    DEBUGMSGTL (("exec:get_exec_output", "using cached value\n"));
    if ((cfd = open (cachefile, O_RDONLY)) < 0)
    {
        snmp_log (LOG_ERR, "can not open cache file\n");
        setPerrorstatus (cachefile);
        return -1;
    }
    return (cfd);
#else                            /* !HAVE_EXECV */
#if defined(WIN32) && !defined(HAVE_EXECV)

/* MSVC and MinGW.  Cygwin already works as it has execv and fork */
    int fd;

    /* Reference:  MS tech note: 190351 */
    HANDLE hOutputReadTmp, hOutputRead, hOutputWrite = NULL;

    HANDLE hErrorWrite;

    SECURITY_ATTRIBUTES sa;

    PROCESS_INFORMATION pi;

    STARTUPINFO si;

    sa.nLength = sizeof (SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    DEBUGMSGTL (("exec:get_exec_output", "calling %s\n", ex->command));

    /* Child temporary output pipe with Inheritance on (sa.bInheritHandle is true) */
    if (!CreatePipe (&hOutputReadTmp, &hOutputWrite, &sa, 0))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_pipes CreatePipe ChildOut: %lu\n", GetLastError ()));
        return -1;
    }

    /* Copy the stdout handle to the stderr handle in case the child closes one of 
     * its stdout handles. */
    if (!DuplicateHandle (GetCurrentProcess (), hOutputWrite, GetCurrentProcess (),
                          &hErrorWrite, 0, TRUE, DUPLICATE_SAME_ACCESS))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_output DuplicateHandle: %lu\n", GetLastError ()));
        return -1;
    }

    /* Create new copies of the input and output handles but set bInheritHandle to 
     * FALSE so the new handle can not be inherited.  Otherwise the handles can not
     * be closed.  */
    if (!DuplicateHandle (GetCurrentProcess (), hOutputReadTmp, GetCurrentProcess (),
                          &hOutputRead, 0, FALSE, DUPLICATE_SAME_ACCESS))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_output DupliateHandle ChildOut: %lu\n", GetLastError ()));
        CloseHandle (hErrorWrite);
        return -1;
    }

    /* Close the temporary output and input handles */
    if (!CloseHandle (hOutputReadTmp))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_output CloseHandle (hOutputReadTmp): %lu\n", GetLastError ()));
        CloseHandle (hErrorWrite);
        CloseHandle (hOutputRead);
        return -1;
    }

    /* Associates a C run-time file descriptor with an existing operating-system file handle. */
    fd = _open_osfhandle ((long) hOutputRead, 0);

    /* Set up STARTUPINFO for CreateProcess with the handles and have it hide the window
     * for the new process. */
    ZeroMemory (&si, sizeof (STARTUPINFO));
    si.cb = sizeof (STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.hStdOutput = hOutputWrite;
    si.hStdError = hErrorWrite;
    si.wShowWindow = SW_HIDE;

    /* Launch the process that you want to redirect.  Example snmpd.conf pass_persist:
     * pass_persist    .1.3.6.1.4.1.2021.255  c:/perl/bin/perl c:/temp/pass_persisttest
     */
    if (!CreateProcess (NULL, ex->command, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_output CreateProcess:'%s' %lu\n", ex->command, GetLastError ()));
        CloseHandle (hErrorWrite);
        CloseHandle (hOutputRead);
        return -1;
    }

    /* Set global child process handle */
    ex->pid = pi.hProcess;
    ex->tid = pi.hThread;

    /* Close pipe handles to make sure that no handles to the write end of the
     * output pipe are maintained in this process or else the pipe will
     * not close when the child process exits and any calls to ReadFile 
     * will hang.
     */

    if (!CloseHandle (hOutputWrite))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_output CloseHandle hOutputWrite: %lu\n", GetLastError ()));
        return -1;
    }
    if (!CloseHandle (hErrorWrite))
    {
        DEBUGMSGTL (("util_funcs", "get_exec_output CloseHandle hErrorWrite: %lu\n", GetLastError ()));
        return -1;
    }
    return fd;
#endif                            /* WIN32 */
#endif
#endif                            /* !defined(USING_UTILITIES_EXECUTE_MODULE) */
    return -1;
}
Ejemplo n.º 14
0
/**
 * update entry stats (checking for counter wrap)
 *
 * @retval  0 : success
 * @retval <0 : error
 */
int
netsnmp_access_systemstats_entry_update_stats(netsnmp_systemstats_entry * prev_vals,
                                              netsnmp_systemstats_entry * new_vals)
{
    DEBUGMSGTL(("access:systemstats", "check_wrap\n"));
    
    /*
     * sanity checks
     */
    if ((NULL == prev_vals) || (NULL == new_vals) ||
        (prev_vals->index[0] != new_vals->index[0])
        || (prev_vals->index[1] != new_vals->index[1]))
        return -1;

    /*
     * if we've determined that we have 64 bit counters, just copy them.
     */
    if (0 == need_wrap_check) {
        memcpy(&prev_vals->stats, &new_vals->stats, sizeof(new_vals->stats));
        _calculate_entries(prev_vals);
        return 0;
    }

    if (NULL == prev_vals->old_stats) {
        /*
         * if we don't have old stats, they can't have wrapped, so just copy
         */
        prev_vals->old_stats = SNMP_MALLOC_TYPEDEF(netsnmp_ipstats);
        if (NULL == prev_vals->old_stats) {
            return -2;
        }
    }
    else {
        /*
         * update straight 32 bit counters
         */
        memcpy(&prev_vals->stats.columnAvail[0], &new_vals->stats.columnAvail[0], sizeof(new_vals->stats.columnAvail));
        prev_vals->stats.InHdrErrors = new_vals->stats.InHdrErrors;
        prev_vals->stats.InAddrErrors = new_vals->stats.InAddrErrors;
        prev_vals->stats.InUnknownProtos = new_vals->stats.InUnknownProtos;
        prev_vals->stats.InTruncatedPkts = new_vals->stats.InTruncatedPkts;
        prev_vals->stats.ReasmReqds = new_vals->stats.ReasmReqds;
        prev_vals->stats.ReasmOKs = new_vals->stats.ReasmOKs;
        prev_vals->stats.ReasmFails = new_vals->stats.ReasmFails;
        prev_vals->stats.InDiscards = new_vals->stats.InDiscards;

        /*
         * update 64bit counters
         */
        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInNoRoutes,
                                       &new_vals->stats.HCInNoRoutes,
                                       &prev_vals->old_stats->HCInNoRoutes,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInNoRoutes to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutNoRoutes,
                                       &new_vals->stats.HCOutNoRoutes,
                                       &prev_vals->old_stats->HCOutNoRoutes,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutNoRoutes to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutDiscards,
                                       &new_vals->stats.HCOutDiscards,
                                       &prev_vals->old_stats->HCOutDiscards,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutDiscards to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragReqds,
                                       &new_vals->stats.HCOutFragReqds,
                                       &prev_vals->old_stats->HCOutFragReqds,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutFragReqds to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragOKs,
                                       &new_vals->stats.HCOutFragOKs,
                                       &prev_vals->old_stats->HCOutFragOKs,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutFragOKs to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragFails,
                                       &new_vals->stats.HCOutFragFails,
                                       &prev_vals->old_stats->HCOutFragFails,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutFragFails to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutFragCreates,
                                       &new_vals->stats.HCOutFragCreates,
                                       &prev_vals->old_stats->HCOutFragCreates,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutFragCreates to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInReceives,
                                       &new_vals->stats.HCInReceives,
                                       &prev_vals->old_stats->HCInReceives,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInReceives to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInOctets,
                                       &new_vals->stats.HCInOctets,
                                       &prev_vals->old_stats->HCInOctets,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInOctets to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInForwDatagrams,
                                       &new_vals->stats.HCInForwDatagrams,
                                       &prev_vals->old_stats->HCInForwDatagrams,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInForwDatagrams to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInDelivers,
                                       &new_vals->stats.HCInDelivers,
                                       &prev_vals->old_stats->HCInDelivers,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInDelivers to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutRequests,
                                       &new_vals->stats.HCOutRequests,
                                       &prev_vals->old_stats->HCOutRequests,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutRequests to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutForwDatagrams,
                                       &new_vals->stats.HCOutForwDatagrams,
                                       &prev_vals->old_stats->HCOutForwDatagrams,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutForwDatagrams to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutTransmits,
                                       &new_vals->stats.HCOutTransmits,
                                       &prev_vals->old_stats->HCOutTransmits,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutTransmits to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutOctets,
                                       &new_vals->stats.HCOutOctets,
                                       &prev_vals->old_stats->HCOutOctets,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutOctets to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInMcastPkts,
                                       &new_vals->stats.HCInMcastPkts,
                                       &prev_vals->old_stats->HCInMcastPkts,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInMcastPkts to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInMcastOctets,
                                       &new_vals->stats.HCInMcastOctets,
                                       &prev_vals->old_stats->HCInMcastOctets,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInMcastOctets to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutMcastPkts,
                                       &new_vals->stats.HCOutMcastPkts,
                                       &prev_vals->old_stats->HCOutMcastPkts,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutMcastPkts to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutMcastOctets,
                                       &new_vals->stats.HCOutMcastOctets,
                                       &prev_vals->old_stats->HCOutMcastOctets,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutMcastOctets to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCInBcastPkts,
                                       &new_vals->stats.HCInBcastPkts,
                                       &prev_vals->old_stats->HCInBcastPkts,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCInBcastPkts to 64bits in %s\n",
                    prev_vals->tableName));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.HCOutBcastPkts,
                                       &new_vals->stats.HCOutBcastPkts,
                                       &prev_vals->old_stats->HCOutBcastPkts,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding HCOutBcastPkts to 64bits in %s\n",
                    prev_vals->tableName));
    }

    /*
     * if we've decided we no longer need to check wraps, free old stats
     */
    if (0 == need_wrap_check) {
        SNMP_FREE(prev_vals->old_stats);
    } else {
        /*
         * update old stats from new stats.
         * careful - old_stats is a pointer to stats...
         */
        memcpy(prev_vals->old_stats, &new_vals->stats, sizeof(new_vals->stats));
    }

    _calculate_entries(prev_vals);

    return 0;
}
Ejemplo n.º 15
0
/*
 * try to get load average
 * Inputs: pointer to array of doubles, number of elements in array
 * Returns: 0=array has values, -1=error occurred.
 */
int
try_getloadavg(double *r_ave, size_t s_ave)
{
#ifndef HAVE_GETLOADAVG
#ifdef HAVE_SYS_FIXPOINT_H
    fix             favenrun[3];
#endif
#if (defined(ultrix) || defined(sun) || defined(__alpha) || defined(dynix))
    int             i;
#if (defined(sun) || defined(__alpha) || defined(dynix))
    long            favenrun[3];
    if (s_ave > 3)              /* bounds check */
        return (-1);
#define FIX_TO_DBL(_IN) (((double) _IN)/((double) FSCALE))
#endif
#endif
#if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
    perfstat_cpu_total_t cs;
#endif
#if defined(hpux10) || defined(hpux11)
    struct pst_dynamic pst_buf;
#endif
#ifdef irix6
    int             i, favenrun[3];
    sgt_cookie_t    cookie;
#endif
#endif	/* !HAVE_GETLOADAVG */

#ifdef HAVE_GETLOADAVG
    if (getloadavg(r_ave, s_ave) == -1)
        return (-1);
#elif defined(linux)
    {
        FILE           *in = fopen("/proc/loadavg", "r");
        if (!in) {
            NETSNMP_LOGONCE((LOG_ERR, "snmpd: cannot open /proc/loadavg\n"));
            return (-1);
        }
        fscanf(in, "%lf %lf %lf", r_ave, (r_ave + 1), (r_ave + 2));
        fclose(in);
    }
#elif (defined(ultrix) || defined(sun) || defined(__alpha) || defined(dynix))
    if (auto_nlist(LOADAVE_SYMBOL, (char *) favenrun, sizeof(favenrun)) ==
        0)
        return (-1);
    for (i = 0; i < s_ave; i++)
        *(r_ave + i) = FIX_TO_DBL(favenrun[i]);
#elif defined(hpux10) || defined(hpux11)
    if (pstat_getdynamic(&pst_buf, sizeof(struct pst_dynamic), 1, 0) < 0)
        return(-1);
    r_ave[0] = pst_buf.psd_avg_1_min;
    r_ave[1] = pst_buf.psd_avg_5_min;
    r_ave[2] = pst_buf.psd_avg_15_min;
#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
    if(perfstat_cpu_total((perfstat_id_t *)NULL, &cs, sizeof(perfstat_cpu_total_t), 1) > 0) {
        r_ave[0] = cs.loadavg[0] / 65536.0;
        r_ave[1] = cs.loadavg[1] / 65536.0;
        r_ave[2] = cs.loadavg[2] / 65536.0;
    }
#elif defined(irix6)
    SGT_COOKIE_INIT(&cookie);
    SGT_COOKIE_SET_KSYM(&cookie, "avenrun");
    sysget(SGT_KSYM, (char*)favenrun, sizeof(favenrun), SGT_READ, &cookie);
    for (i = 0; i < s_ave; i++)
      r_ave[i] = favenrun[i] / 1000.0;
    DEBUGMSGTL(("ucd-snmp/loadave", "irix6: %d %d %d\n", favenrun[0], favenrun[1], favenrun[2]));
#elif !defined(cygwin)
#if defined(NETSNMP_CAN_USE_NLIST) && defined(LOADAVE_SYMBOL)
    if (auto_nlist(LOADAVE_SYMBOL, (char *) r_ave, sizeof(double) * s_ave)
        == 0)
#endif
        return (-1);
#endif
    /*
     * XXX
     *   To calculate this, we need to compare
     *   successive values of the kernel array
     *   '_cp_times', and calculate the resulting
     *   percentage changes.
     *     This calculation needs to be performed
     *   regularly - perhaps as a background process.
     *
     *   See the source to 'top' for full details.
     *
     * The linux SNMP HostRes implementation
     *   uses 'avenrun[0]*100' as an approximation.
     *   This is less than accurate, but has the
     *   advantage of being simple to implement!
     *
     * I'm also assuming a single processor
     */
    return 0;
}
Ejemplo n.º 16
0
/**
 * update stats
 *
 * @retval  0 : success
 * @retval -1 : error
 */
int
netsnmp_access_interface_entry_update_stats(netsnmp_interface_entry * prev_vals,
                                            netsnmp_interface_entry * new_vals)
{
    DEBUGMSGTL(("access:interface", "check_wrap\n"));
    
    /*
     * sanity checks
     */
    if ((NULL == prev_vals) || (NULL == new_vals) ||
        (NULL == prev_vals->name) || (NULL == new_vals->name) ||
        (0 != strncmp(prev_vals->name, new_vals->name, strlen(prev_vals->name))))
        return -1;

    /*
     * if we've determined that we have 64 bit counters, just copy them.
     */
    if (0 == need_wrap_check) {
        memcpy(&prev_vals->stats, &new_vals->stats, sizeof(new_vals->stats));
        return 0;
    }

    if (NULL == prev_vals->old_stats) {
        /*
         * if we don't have old stats, copy previous stats
         */
        prev_vals->old_stats = SNMP_MALLOC_TYPEDEF(netsnmp_interface_stats);
        if (NULL == prev_vals->old_stats) {
            return -2;
        }
        memcpy(prev_vals->old_stats, &prev_vals->stats, sizeof(prev_vals->stats));
    }

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.ibytes,
                                       &new_vals->stats.ibytes,
                                       &prev_vals->old_stats->ibytes,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding ifHCInOctets to 64bits\n"));

        if (new_vals->ns_flags & NETSNMP_INTERFACE_FLAGS_CALCULATE_UCAST) {
            if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.iall,
                                           &new_vals->stats.iall,
                                           &prev_vals->old_stats->iall,
                                           &need_wrap_check))
                NETSNMP_LOGONCE((LOG_ERR,
                        "Error expanding packet count to 64bits\n"));
        } else {
            if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.iucast,
                                           &new_vals->stats.iucast,
                                           &prev_vals->old_stats->iucast,
                                           &need_wrap_check))
                NETSNMP_LOGONCE((LOG_ERR,
                        "Error expanding ifHCInUcastPkts to 64bits\n"));
        }

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.iucast,
                                       &new_vals->stats.iucast,
                                       &prev_vals->old_stats->iucast,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding ifHCInUcastPkts to 64bits\n"));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.imcast,
                                       &new_vals->stats.imcast,
                                       &prev_vals->old_stats->imcast,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding ifHCInMulticastPkts to 64bits\n"));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.ibcast,
                                       &new_vals->stats.ibcast,
                                       &prev_vals->old_stats->ibcast,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding ifHCInBroadcastPkts to 64bits\n"));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.obytes,
                                       &new_vals->stats.obytes,
                                       &prev_vals->old_stats->obytes,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding ifHCOutOctets to 64bits\n"));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.oucast,
                                       &new_vals->stats.oucast,
                                       &prev_vals->old_stats->oucast,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding ifHCOutUcastPkts to 64bits\n"));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.omcast,
                                       &new_vals->stats.omcast,
                                       &prev_vals->old_stats->omcast,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding ifHCOutMulticastPkts to 64bits\n"));

        if (0 != netsnmp_c64_check32_and_update(&prev_vals->stats.obcast,
                                       &new_vals->stats.obcast,
                                       &prev_vals->old_stats->obcast,
                                       &need_wrap_check))
            NETSNMP_LOGONCE((LOG_ERR,
                    "Error expanding ifHCOutBroadcastPkts to 64bits\n"));

    /*
     * Copy 32 bit counters
     */
    prev_vals->stats.ierrors = new_vals->stats.ierrors;
    prev_vals->stats.idiscards = new_vals->stats.idiscards;
    prev_vals->stats.iunknown_protos = new_vals->stats.iunknown_protos;
    prev_vals->stats.inucast = new_vals->stats.inucast;
    prev_vals->stats.oerrors = new_vals->stats.oerrors;
    prev_vals->stats.odiscards = new_vals->stats.odiscards;
    prev_vals->stats.oqlen = new_vals->stats.oqlen;
    prev_vals->stats.collisions = new_vals->stats.collisions;
    prev_vals->stats.onucast = new_vals->stats.onucast;

    /*
     * if we've decided we no longer need to check wraps, free old stats
     */
    if (0 == need_wrap_check) {
        SNMP_FREE(prev_vals->old_stats);
    }
    else {
        /*
         * update old stats from new stats.
         * careful - old_stats is a pointer to stats...
         */
        memcpy(prev_vals->old_stats, &new_vals->stats, sizeof(new_vals->stats));
    }
    
    return 0;
}
Ejemplo n.º 17
0
/*
 *  Trap handler for invoking a suitable script
 */
int   command_handler( netsnmp_pdu           *pdu,
                       netsnmp_transport     *transport,
                       netsnmp_trapd_handler *handler)
{
#ifndef USING_UTILITIES_EXECUTE_MODULE
    NETSNMP_LOGONCE((LOG_WARNING,
                     "support for run_shell_command not available\n"));
    return NETSNMPTRAPD_HANDLER_FAIL;
#else
    u_char         *rbuf = NULL;
    size_t          r_len = 64, o_len = 0;
    int             oldquick;

    DEBUGMSGTL(( "snmptrapd", "command_handler\n"));
    DEBUGMSGTL(( "snmptrapd", "token = '%s'\n", handler->token));
    if (handler && handler->token && *handler->token) {
	netsnmp_pdu    *v2_pdu = NULL;
	if (pdu->command == SNMP_MSG_TRAP)
	    v2_pdu = convert_v1pdu_to_v2(pdu);
	else
	    v2_pdu = pdu;
        oldquick = snmp_get_quick_print();
        snmp_set_quick_print(1);

        /*
	 * Format the trap and pass this string to the external command
	 */
        if ((rbuf = (u_char *) calloc(r_len, 1)) == NULL) {
            snmp_log(LOG_ERR, "couldn't display trap -- malloc failed\n");
            return NETSNMPTRAPD_HANDLER_FAIL;	/* Failed but keep going */
        }

        /*
         *  If there's a format string registered for this trap, then use it.
         *  Otherwise use the standard execution format setting.
         */
        if (handler && handler->format && *handler->format) {
            DEBUGMSGTL(( "snmptrapd", "format = '%s'\n", handler->format));
            realloc_format_trap(&rbuf, &r_len, &o_len, 1,
                                             handler->format,
                                             v2_pdu, transport);
        } else {
	    if ( pdu->command == SNMP_MSG_TRAP && exec_format1 ) {
                DEBUGMSGTL(( "snmptrapd", "exec v1 = '%s'\n", exec_format1));
                realloc_format_trap(&rbuf, &r_len, &o_len, 1,
                                             exec_format1, pdu, transport);
	    } else if ( pdu->command != SNMP_MSG_TRAP && exec_format2 ) {
                DEBUGMSGTL(( "snmptrapd", "exec v2/3 = '%s'\n", exec_format2));
                realloc_format_trap(&rbuf, &r_len, &o_len, 1,
                                             exec_format2, pdu, transport);
	    } else {
                DEBUGMSGTL(( "snmptrapd", "execute format\n"));
                realloc_format_trap(&rbuf, &r_len, &o_len, 1, EXECUTE_FORMAT,
                                             v2_pdu, transport);
            }
	}

        /*
         *  and pass this formatted string to the command specified
         */
        run_shell_command(handler->token, (char*)rbuf, NULL, NULL);   /* Not interested in output */
        snmp_set_quick_print(oldquick);
        if (pdu->command == SNMP_MSG_TRAP)
            snmp_free_pdu(v2_pdu);
        free(rbuf);
    }
    return NETSNMPTRAPD_HANDLER_OK;
#endif /* !def USING_UTILITIES_EXECUTE_MODULE */
}
Ejemplo n.º 18
0
int
netsnmp_getaddrinfo(const char *name, const char *service,
                    const struct addrinfo *hints, struct addrinfo **res)
{
#if HAVE_GETADDRINFO
    struct addrinfo *addrs = NULL;
    struct addrinfo hint;
    int             err;
#ifdef DNSSEC_LOCAL_VALIDATION
    val_status_t    val_status;
#endif

    DEBUGMSGTL(("dns:getaddrinfo", "looking up "));
    if (name)
        DEBUGMSG(("dns:getaddrinfo", "\"%s\"", name));
    else
        DEBUGMSG(("dns:getaddrinfo", "<NULL>"));

    if (service)
	DEBUGMSG(("dns:getaddrinfo", ":\"%s\"", service));

    if (hints)
	DEBUGMSG(("dns:getaddrinfo", " with hint ({ ... })"));
    else
	DEBUGMSG(("dns:getaddrinfo", " with no hint"));

    DEBUGMSG(("dns:getaddrinfo", "\n"));

    if (NULL == hints) {
        memset(&hint, 0, sizeof hint);
        hint.ai_flags = 0;
        hint.ai_family = PF_INET;
        hint.ai_socktype = SOCK_DGRAM;
        hint.ai_protocol = 0;
        hints = &hint;
    } else {
        memcpy(&hint, hints, sizeof hint);
    }

#ifndef DNSSEC_LOCAL_VALIDATION
    err = getaddrinfo(name, NULL, &hint, &addrs);
#else /* DNSSEC_LOCAL_VALIDATION */
    err = val_getaddrinfo(netsnmp_validator_context(), name, NULL, &hint,
                          &addrs, &val_status);
    DEBUGMSGTL(("dns:sec:val", "err %d, val_status %d / %s; trusted: %d\n",
                err, val_status, p_val_status(val_status),
                val_istrusted(val_status)));
    if (! val_istrusted(val_status)) {
        int rc;
        if ((err != 0) && VAL_GETADDRINFO_HAS_STATUS(err)) {
            snmp_log(LOG_WARNING,
                     "WARNING: UNTRUSTED error in DNS resolution for %s!\n",
                     name);
            rc = EAI_FAIL;
        } else {
            snmp_log(LOG_WARNING,
                     "The authenticity of DNS response is not trusted (%s)\n",
                     p_val_status(val_status));
            rc = EAI_NONAME;
        }
        /** continue anyways if DNSSEC_WARN_ONLY is set */
        if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
                                    NETSNMP_DS_LIB_DNSSEC_WARN_ONLY))
            return rc;
    }


#endif /* DNSSEC_LOCAL_VALIDATION */
    *res = addrs;
    if ((0 == err) && addrs && addrs->ai_addr) {
        DEBUGMSGTL(("dns:getaddrinfo", "answer { AF_INET, %s:%hu }\n",
                    inet_ntoa(((struct sockaddr_in*)addrs->ai_addr)->sin_addr),
                    ntohs(((struct sockaddr_in*)addrs->ai_addr)->sin_port)));
    }
    return err;
#else
    NETSNMP_LOGONCE((LOG_ERR, "getaddrinfo not available"));
    return EAI_FAIL;
#endif /* getaddrinfo */
}
Ejemplo n.º 19
0
/*
 * Locate the appropriate transport domain and call the create function for
 * it.
 */
netsnmp_transport *
netsnmp_tdomain_transport_full(const char *application,
                               const char *str, int local,
                               const char *default_domain,
                               const char *default_target)
{
    netsnmp_tdomain    *match = NULL;
    const char         *addr = NULL;
    const char * const *spec = NULL;
    int                 any_found = 0;
    char buf[SNMP_MAXPATH];
    char **lspec = 0;

    DEBUGMSGTL(("tdomain",
                "tdomain_transport_full(\"%s\", \"%s\", %d, \"%s\", \"%s\")\n",
                application, str ? str : "[NIL]", local,
                default_domain ? default_domain : "[NIL]",
                default_target ? default_target : "[NIL]"));

    /* see if we can load a host-name specific set of conf files */
    if (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                NETSNMP_DS_LIB_DONT_LOAD_HOST_FILES) &&
            netsnmp_is_fqdn(str)) {
        static int have_added_handler = 0;
        char *newhost;
        struct config_line *config_handlers;
        struct config_files file_names;
        char *prev_hostname;

        /* register a "transport" specifier */
        if (!have_added_handler) {
            have_added_handler = 1;
            netsnmp_ds_register_config(ASN_OCTET_STR,
                                       "snmp", "transport",
                                       NETSNMP_DS_LIBRARY_ID,
                                       NETSNMP_DS_LIB_HOSTNAME);
        }

        /* we save on specific setting that we don't allow to change
           from one transport creation to the next; ie, we don't want
           the "transport" specifier to be a default.  It should be a
           single invocation use only */
        prev_hostname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                              NETSNMP_DS_LIB_HOSTNAME);
        if (prev_hostname)
            prev_hostname = strdup(prev_hostname);

        /* read in the hosts/STRING.conf files */
        config_handlers = read_config_get_handlers("snmp");
        snprintf(buf, sizeof(buf)-1, "hosts/%s", str);
        file_names.fileHeader = buf;
        file_names.start = config_handlers;
        file_names.next = NULL;
        DEBUGMSGTL(("tdomain", "checking for host specific config %s\n",
                    buf));
        read_config_files_of_type(EITHER_CONFIG, &file_names);

        if (NULL !=
                (newhost = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                           NETSNMP_DS_LIB_HOSTNAME))) {
            strlcpy(buf, newhost, sizeof(buf));
            str = buf;
        }

        netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
                              NETSNMP_DS_LIB_HOSTNAME,
                              prev_hostname);
        SNMP_FREE(prev_hostname);
    }

    /* First try - assume that there is a domain in str (domain:target) */

    if (str != NULL) {
        const char *cp;
        if ((cp = strchr(str, ':')) != NULL) {
            char* mystring = (char*)malloc(cp + 1 - str);
            memcpy(mystring, str, cp - str);
            mystring[cp - str] = '\0';
            addr = cp + 1;

            match = find_tdomain(mystring);
            free(mystring);
        }
    }

    /*
     * Second try, if there is no domain in str (target), then try the
     * default domain
     */

    if (match == NULL) {
        addr = str;
        if (addr && *addr == '/') {
            DEBUGMSGTL(("tdomain",
                        "Address starts with '/', so assume \"unix\" "
                        "domain\n"));
            match = find_tdomain("unix");
        } else if (default_domain) {
            DEBUGMSGTL(("tdomain",
                        "Use user specified default domain \"%s\"\n",
                        default_domain));
            if (!strchr(default_domain, ','))
                match = find_tdomain(default_domain);
            else {
                int commas = 0;
                const char *cp = default_domain;
                char *dup = strdup(default_domain);

                while (*++cp) if (*cp == ',') commas++;
                lspec = (char **) calloc(commas+2, sizeof(char *));
                commas = 1;
                lspec[0] = strtok(dup, ",");
                while ((lspec[commas++] = strtok(NULL, ",")))
                    ;
                spec = (const char * const *)lspec;
            }
        } else {
            spec = netsnmp_lookup_default_domains(application);
            if (spec == NULL) {
                DEBUGMSGTL(("tdomain",
                            "No default domain found, assume \"udp\"\n"));
                match = find_tdomain("udp");
            } else {
                const char * const * r = spec;
                DEBUGMSGTL(("tdomain",
                            "Use application default domains"));
                while(*r) {
                    DEBUGMSG(("tdomain", " \"%s\"", *r));
                    ++r;
                }
                DEBUGMSG(("tdomain", "\n"));
            }
        }
    }

    for(;;) {
        if (match) {
            netsnmp_transport *t = NULL;
            const char* addr2;

            any_found = 1;
            /*
             * Ok, we know what domain to try, lets see what default data
             * should be used with it
             */
            if (default_target != NULL)
                addr2 = default_target;
            else
                addr2 = netsnmp_lookup_default_target(application,
                                                      match->prefix[0]);
            DEBUGMSGTL(("tdomain",
                        "trying domain \"%s\" address \"%s\" "
                        "default address \"%s\"\n",
                        match->prefix[0], addr ? addr : "[NIL]",
                        addr2 ? addr2 : "[NIL]"));
            if (match->f_create_from_tstring) {
                NETSNMP_LOGONCE((LOG_WARNING,
                                 "transport domain %s uses deprecated f_create_from_tstring\n",
                                 match->prefix[0]));
                t = match->f_create_from_tstring(addr, local);
            }
            else
                t = match->f_create_from_tstring_new(addr, local, addr2);
            if (t) {
                if (lspec) {
                    free(lspec[0]);
                    free(lspec);
                }
                return t;
            }
        }
        addr = str;
        if (spec && *spec)
            match = find_tdomain(*spec++);
        else
            break;
    }
    if (!any_found)
        snmp_log(LOG_ERR, "No support for any checked transport domain\n");
    if (lspec) {
        free(lspec[0]);
        free(lspec);
    }
    return NULL;
}