Exemplo n.º 1
0
void add_responses(struct variable_list *vars, struct oid_value ***next_ov, oid *name, size_t *name_length) {
	int found = 0;
	for (struct variable_list *var = vars; var; var = var->next_variable) {
		if (var->name_length < PRINTER_OID_LEN ||
				0 != netsnmp_oid_equals(PRINTER_OID, PRINTER_OID_LEN, var->name, PRINTER_OID_LEN)) {
			// This OID does not have the printer OID prefix, so we're done.
			*name_length = 0;
			return;
		}

		oid *objid = malloc(var->name_length * sizeof(oid));
		memmove(objid, var->name, var->name_length * sizeof(oid));

		size_t value_length = 1, out_length = 0;;
		char *value = malloc(value_length);
		sprint_realloc_value((unsigned char **)&value, &value_length, &out_length, 1, var->name, var->name_length, var);

		**next_ov = calloc(1, sizeof(struct oid_value));
		(**next_ov)->name = objid;
		(**next_ov)->name_length = var->name_length;
		(**next_ov)->value = value;
		*next_ov = &(**next_ov)->next;

		*name_length = var->name_length;
		memmove(name, var->name, *name_length * sizeof(oid));
	}

	return;
}
Exemplo n.º 2
0
/*! \fn void snmp_snprint_value(char *obuf, size_t buf_len, const oid *objid, size_t objidlen, struct variable_list *variable)
 *
 *  \brief replacement for the buggy net-snmp.org snprint_value function
 *
 *	This function format an output buffer with the correct string representation
 *  of an snmp OID result fetched with snmp_get_multi.  The buffer pointed to by
 *  the function is modified.
 *
 */
void snmp_snprint_value(char *obuf, size_t buf_len, const oid *objid, size_t objidlen, struct variable_list *variable) {
	u_char *buf    = NULL;
	size_t out_len = 0;

	if ((buf = (u_char *) calloc(buf_len, 1)) != 0) {
		if (sprint_realloc_value(&buf, &buf_len, &out_len, 1,
				objid, objidlen, variable)) {
			snprintf(obuf, buf_len, "%s", buf);
		}else{
			snprintf(obuf, buf_len, "%s [TRUNCATED]", buf);
		}
	}else{
		SET_UNDEFINED(obuf);
	}

	free(buf);
}
Exemplo n.º 3
0
/*
 * Store data received in response PDU
 */
int print_result (int status, req_t *req, struct snmp_pdu *pdu)
{
	struct variable_list *vp;
	size_t len;
	keyrecord_t *kwalk;
	int keyoidlen;
	oid_t *owalk;
	int done;

	switch (status) {
	  case STAT_SUCCESS:
		if (pdu->errstat == SNMP_ERR_NOERROR) {
			unsigned char *valstr = NULL, *oidstr = NULL;
			size_t valsz = 0, oidsz = 0;

			okcount++;

			switch (dataoperation) {
			  case GET_KEYS:
				/* 
				 * Find the keyrecord currently processed for this request, and
				 * look through the unresolved keys to see if we have a match.
				 * If we do, determine the index for data retrieval.
				 */
				vp = pdu->variables;
				len = 0; sprint_realloc_value(&valstr, &valsz, &len, 1, vp->name, vp->name_length, vp);
				len = 0; sprint_realloc_objid(&oidstr, &oidsz, &len, 1, vp->name, vp->name_length);
				dbgprintf("Got key-oid '%s' = '%s'\n", oidstr, valstr);
				for (kwalk = req->currentkey, done = 0; (kwalk && !done); kwalk = kwalk->next) {
					/* Skip records where we have the result already, or that are not keyed */
					if (kwalk->indexoid || (kwalk->indexmethod != req->currentkey->indexmethod)) {
						continue;
					}

					keyoidlen = strlen(req->currentkey->indexmethod->keyoid);

					switch (kwalk->indexmethod->idxtype) {
					  case MIB_INDEX_IN_OID:
						/* Does the key match the value we just got? */
						if (*kwalk->key == '*') {
							/* Match all. Add an extra key-record at the end. */
							keyrecord_t *newkey;

							newkey = (keyrecord_t *)calloc(1, sizeof(keyrecord_t));
							memcpy(newkey, kwalk, sizeof(keyrecord_t));
							newkey->indexoid = strdup(oidstr + keyoidlen + 1);
							newkey->key = valstr; valstr = NULL;
							newkey->next = kwalk->next;
							kwalk->next = newkey;
							done = 1;
						}
						else if (strcmp(valstr, kwalk->key) == 0) {
							/* Grab the index part of the OID */
							kwalk->indexoid = strdup(oidstr + keyoidlen + 1);
							done = 1;
						}
						break;

					  case MIB_INDEX_IN_VALUE:
						/* Does the key match the index-part of the result OID? */
						if (*kwalk->key == '*') {
							/* Match all. Add an extra key-record at the end. */
							keyrecord_t *newkey;

							newkey = (keyrecord_t *)calloc(1, sizeof(keyrecord_t));
							memcpy(newkey, kwalk, sizeof(keyrecord_t));
							newkey->indexoid = valstr; valstr = NULL;
							newkey->key = strdup(oidstr + keyoidlen + 1);
							newkey->next = kwalk->next;
							kwalk->next = newkey;
							done = 1;
						}
						else if ((*(oidstr+keyoidlen) == '.') && (strcmp(oidstr+keyoidlen+1, kwalk->key)) == 0) {
							/* 
							 * Grab the index which is the value. 
							 * Avoid a strdup by grabbing the valstr pointer.
							 */
							kwalk->indexoid = valstr; valstr = NULL; valsz = 0;
							done = 1;
						}
						break;
					}
				}
				break;

			  case GET_DATA:
				owalk = req->curr_oid;
				vp = pdu->variables;
				while (vp) {
					valsz = len = 0;
					sprint_realloc_value((unsigned char **)&owalk->result, &valsz, &len, 1, 
							     vp->name, vp->name_length, vp);
					owalk = owalk->next; vp = vp->next_variable;
				}
				break;
			}

			if (valstr) xfree(valstr);
			if (oidstr) xfree(oidstr);
		}
		else {
			errorcount++;
			errprintf("ERROR %s: %s\n", req->hostip[req->hostipidx], snmp_errstring(pdu->errstat));
		}
		return 1;

	  case STAT_TIMEOUT:
		timeoutcount++;
		dbgprintf("%s: Timeout\n", req->hostip);
		if (req->hostip[req->hostipidx+1]) {
			req->hostipidx++;
			startonehost(req, 1);
		}
		return 0;

	  case STAT_ERROR:
		errorcount++;
		snmp_sess_perror(req->hostip[req->hostipidx], req->sess);
		return 0;
	}

	return 0;
}
Exemplo n.º 4
0
void
getbulk_table_entries(netsnmp_session * ss)
{
    int             running = 1;
    netsnmp_pdu    *pdu, *response;
    netsnmp_variable_list *vars, *last_var;
    int             count;
    int             status;
    int             i;
    int             row, col;
    char           *buf = NULL;
    size_t          buf_len = 0, out_len = 0;
    char           *cp;
    char           *name_p = NULL;
    char          **dp;

    while (running) {
        /*
         * create PDU for GETBULK request and add object name to request 
         */
        pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
        pdu->non_repeaters = 0;
        pdu->max_repetitions = max_getbulk;
        snmp_add_null_var(pdu, name, name_length);

        /*
         * do the request 
         */
        status = snmp_synch_response(ss, pdu, &response);
        if (status == STAT_SUCCESS) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                /*
                 * check resulting variables 
                 */
                vars = response->variables;
                last_var = NULL;
                while (vars) {
                    out_len = 0;
                    sprint_realloc_objid((u_char **)&buf, &buf_len, &out_len, 1,
                                         vars->name, vars->name_length);
                    if (vars->type == SNMP_ENDOFMIBVIEW ||
                        memcmp(vars->name, name,
                               rootlen * sizeof(oid)) != 0) {
                        if (localdebug) {
                            printf("%s => end of table\n",
                                   buf ? (char *) buf : "[NIL]");
                        }
                        running = 0;
                        break;
                    }
                    if (localdebug) {
                        printf("%s => taken\n",
                               buf ? (char *) buf : "[NIL]");
                    }
                    for (col = 0; col < fields; col++)
                        if (column[col].subid == vars->name[rootlen])
                            break;
		    if (col == fields) {
			extra_columns = 1;
			last_var = vars;
			vars = vars->next_variable;
			continue;
		    }
                    if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
                                              NETSNMP_DS_LIB_EXTENDED_INDEX)) {
                        name_p = strchr(buf, '[');
                    } else {
                        switch (netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
                                                  NETSNMP_DS_LIB_OID_OUTPUT_FORMAT)) {
                        case NETSNMP_OID_OUTPUT_MODULE:
			case 0:
                            name_p = strchr(buf, ':')+1;
                            break;
                        case NETSNMP_OID_OUTPUT_SUFFIX:
                            name_p = buf;
                            break;
                        case NETSNMP_OID_OUTPUT_FULL:
                        case NETSNMP_OID_OUTPUT_NUMERIC:
                        case NETSNMP_OID_OUTPUT_UCD:
                            name_p = buf + strlen(table_name)+1;
                            name_p = strchr(name_p, '.')+1;
                            break;
			default:
			    fprintf(stderr, "Unrecognized -O option: %d\n",
				    netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
					              NETSNMP_DS_LIB_OID_OUTPUT_FORMAT));
			    exit(1);
                        }
                        name_p = strchr(name_p, '.');
                        if ( name_p == NULL ) {
                            /* The 'strchr' call above failed, i.e. the results
                             * don't seem to include instance subidentifiers! */
                            running = 0;
                            break;
                        }
                        name_p++;  /* Move on to the instance identifier */
                    }
                    for (row = 0; row < entries; row++)
                        if (strcmp(name_p, indices[row]) == 0)
                            break;
                    if (row == entries) {
                        entries++;
                        if (entries >= allocated) {
                            if (allocated == 0) {
                                allocated = 10;
                                data =
                                    (char **) malloc(allocated * fields *
                                                     sizeof(char *));
                                memset(data, 0,
                                       allocated * fields *
                                       sizeof(char *));
                                indices =
                                    (char **) malloc(allocated *
                                                     sizeof(char *));
                            } else {
                                allocated += 10;
                                data =
                                    (char **) realloc(data,
                                                      allocated * fields *
                                                      sizeof(char *));
                                memset(data + entries * fields, 0,
                                       (allocated -
                                        entries) * fields *
                                       sizeof(char *));
                                indices =
                                    (char **) realloc(indices,
                                                      allocated *
                                                      sizeof(char *));
                            }
                        }
                        indices[row] = strdup(name_p);
                        i = strlen(name_p);
                        if (i > index_width)
                            index_width = i;
                    }
                    dp = data + row * fields;
                    out_len = 0;
                    sprint_realloc_value((u_char **)&buf, &buf_len, &out_len, 1,
                                         vars->name, vars->name_length,
                                         vars);
                    for (cp = buf; *cp; cp++)
                        if (*cp == '\n')
                            *cp = ' ';
                    dp[col] = buf;
                    i = out_len;
                    buf = NULL;
                    buf_len = 0;
                    if (i > column[col].width)
                        column[col].width = i;
                    last_var = vars;
                    vars = vars->next_variable;
                }
                if (last_var) {
                    name_length = last_var->name_length;
                    memcpy(name, last_var->name,
                           name_length * sizeof(oid));
                }
            } else {
                /*
                 * error in response, print it 
                 */
                running = 0;
                if (response->errstat == SNMP_ERR_NOSUCHNAME) {
                    printf("End of MIB\n");
                } else {
                    fprintf(stderr, "Error in packet.\nReason: %s\n",
                            snmp_errstring(response->errstat));
                    if (response->errstat == SNMP_ERR_NOSUCHNAME) {
                        fprintf(stderr,
                                "The request for this object identifier failed: ");
                        for (count = 1, vars = response->variables;
                             vars && count != response->errindex;
                             vars = vars->next_variable, count++)
                            /*EMPTY*/;
                        if (vars) {
                            fprint_objid(stderr, vars->name,
                                         vars->name_length);
                        }
                        fprintf(stderr, "\n");
                    }
                    exitval = 2;
                }
            }
        } else if (status == STAT_TIMEOUT) {
            fprintf(stderr, "Timeout: No Response from %s\n",
                    ss->peername);
            running = 0;
            exitval = 1;
        } else {                /* status == STAT_ERROR */
            snmp_sess_perror("snmptable", ss);
            running = 0;
            exitval = 1;
        }
        if (response)
            snmp_free_pdu(response);
    }
}
Exemplo n.º 5
0
void
get_table_entries(netsnmp_session * ss)
{
    int             running = 1;
    netsnmp_pdu    *pdu, *response;
    netsnmp_variable_list *vars;
    int             count;
    int             status;
    int             i;
    int             col;
    char           *buf = NULL;
    size_t          out_len = 0, buf_len = 0;
    char           *cp;
    char           *name_p = NULL;
    char          **dp;
    int             have_current_index;

    /*
     * TODO:
     *   1) Deal with multiple index fields
     *   2) Deal with variable length index fields
     *   3) optimize to remove a sparse column from get-requests
     */

    while (running &&
           ((max_width && !column_width) || (entries < max_getbulk))) {
        /*
         * create PDU for GETNEXT request and add object name to request 
         */
        pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
        for (i = 1; i <= fields; i++) {
            name[rootlen] = column[i - 1].subid;
            snmp_add_null_var(pdu, name, name_length);
        }

        /*
         * do the request 
         */
        status = snmp_synch_response(ss, pdu, &response);
        if (status == STAT_SUCCESS) {
            if (response->errstat == SNMP_ERR_NOERROR) {
                /*
                 * check resulting variables 
                 */
                vars = response->variables;
                entries++;
                if (entries >= allocated) {
                    if (allocated == 0) {
                        allocated = 10;
                        data =
                            (char **) malloc(allocated * fields *
                                             sizeof(char *));
                        memset(data, 0,
                               allocated * fields * sizeof(char *));
                        if (show_index)
                            indices =
                                (char **) malloc(allocated *
                                                 sizeof(char *));
                    } else {
                        allocated += 10;
                        data =
                            (char **) realloc(data,
                                              allocated * fields *
                                              sizeof(char *));
                        memset(data + entries * fields, 0,
                               (allocated -
                                entries) * fields * sizeof(char *));
                        if (show_index)
                            indices =
                                (char **) realloc(indices,
                                                  allocated *
                                                  sizeof(char *));
                    }
                }
                dp = data + (entries - 1) * fields;
                col = -1;
                end_of_table = 1;       /* assume end of table */
                have_current_index = 0;
                name_length = rootlen + 1;
                for (vars = response->variables; vars;
                     vars = vars->next_variable) {
                    col++;
                    name[rootlen] = column[col].subid;
                    if ((vars->name_length < name_length) ||
                        (vars->name[rootlen] != column[col].subid) ||
                        memcmp(name, vars->name,
                               name_length * sizeof(oid)) != 0
                        || vars->type == SNMP_ENDOFMIBVIEW) {
                        /*
                         * not part of this subtree 
                         */
                        if (localdebug) {
                            fprint_variable(stderr, vars->name,
                                            vars->name_length, vars);
                            fprintf(stderr, " => ignored\n");
                        }
                        continue;
                    }

                    /*
                     * save index off 
                     */
                    if (!have_current_index) {
                        end_of_table = 0;
                        have_current_index = 1;
                        name_length = vars->name_length;
                        memcpy(name, vars->name,
                               name_length * sizeof(oid));
                        out_len = 0;
                        if (!sprint_realloc_objid
                            ((u_char **)&buf, &buf_len, &out_len, 1, vars->name,
                             vars->name_length)) {
                            break;
                        }
                        i = vars->name_length - rootlen + 1;
                        if (localdebug || show_index) {
                            if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
                                              NETSNMP_DS_LIB_EXTENDED_INDEX)) {
                                name_p = strchr(buf, '[');
                            } else {
                                switch (netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
                                                          NETSNMP_DS_LIB_OID_OUTPUT_FORMAT)) {
                                case NETSNMP_OID_OUTPUT_MODULE:
				case 0:
                                    name_p = strchr(buf, ':');
                                    break;
                                case NETSNMP_OID_OUTPUT_SUFFIX:
                                    name_p = buf;
                                    break;
                                case NETSNMP_OID_OUTPUT_FULL:
                                case NETSNMP_OID_OUTPUT_NUMERIC:
                                case NETSNMP_OID_OUTPUT_UCD:
                                    name_p = buf + strlen(table_name)+1;
                                    name_p = strchr(name_p, '.')+1;
                                    break;
				default:
				    fprintf(stderr, "Unrecognized -O option: %d\n",
					    netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
							      NETSNMP_DS_LIB_OID_OUTPUT_FORMAT));
				    exit(1);
                                }
                                name_p = strchr(name_p, '.') + 1;
                            }
                        }
                        if (localdebug) {
                            printf("Name: %s Index: %s\n", buf, name_p);
                        }
                        if (show_index) {
                            indices[entries - 1] = strdup(name_p);
                            i = strlen(name_p);
                            if (i > index_width)
                                index_width = i;
                        }
                    }

                    if (localdebug && buf) {
                        printf("%s => taken\n", buf);
                    }
                    out_len = 0;
                    sprint_realloc_value((u_char **)&buf, &buf_len, &out_len, 1,
                                         vars->name, vars->name_length,
                                         vars);
                    for (cp = buf; *cp; cp++) {
                        if (*cp == '\n') {
                            *cp = ' ';
                        }
                    }
                    dp[col] = buf;
                    i = out_len;
                    buf = NULL;
                    buf_len = 0;
                    if (i > column[col].width) {
                        column[col].width = i;
                    }
                }

                if (end_of_table) {
                    --entries;
                    /*
                     * not part of this subtree 
                     */
                    if (localdebug) {
                        printf("End of table: %s\n",
                               buf ? (char *) buf : "[NIL]");
                    }
                    running = 0;
                    continue;
                }
            } else {
                /*
                 * error in response, print it 
                 */
                running = 0;
                if (response->errstat == SNMP_ERR_NOSUCHNAME) {
                    printf("End of MIB\n");
                    end_of_table = 1;
                } else {
                    fprintf(stderr, "Error in packet.\nReason: %s\n",
                            snmp_errstring(response->errstat));
                    if (response->errindex != 0) {
                        fprintf(stderr, "Failed object: ");
                        for (count = 1, vars = response->variables;
                             vars && count != response->errindex;
                             vars = vars->next_variable, count++)
                            /*EMPTY*/;
                        if (vars) {
                            fprint_objid(stderr, vars->name,
                                         vars->name_length);
                        }
                        fprintf(stderr, "\n");
                    }
                    exitval = 2;
                }
            }
        } else if (status == STAT_TIMEOUT) {
            fprintf(stderr, "Timeout: No Response from %s\n",
                    ss->peername);
            running = 0;
            exitval = 1;
        } else {                /* status == STAT_ERROR */
            snmp_sess_perror("snmptable", ss);
            running = 0;
            exitval = 1;
        }
        if (response)
            snmp_free_pdu(response);
    }
}