void dump_registry( void ) { struct subtree *myptr, *myptr2; struct snmp_index *idxptr, *idxptr2; char start_oid[SPRINT_MAX_LEN]; char end_oid[SPRINT_MAX_LEN]; for( myptr = subtrees ; myptr != NULL; myptr = myptr->next) { sprint_objid(start_oid, myptr->start, myptr->start_len); sprint_objid(end_oid, myptr->end, myptr->end_len); printf("%c %s - %s %c\n", ( myptr->variables ? ' ' : '(' ), start_oid, end_oid, ( myptr->variables ? ' ' : ')' )); for( myptr2 = myptr ; myptr2 != NULL; myptr2 = myptr2->children) { if ( myptr2->label && myptr2->label[0] ) printf("\t%s\n", myptr2->label); } } if ( snmp_index_head ) printf("\nIndex Allocations:\n"); for( idxptr = snmp_index_head ; idxptr != NULL; idxptr = idxptr->next_oid) { sprint_objid(start_oid, idxptr->varbind.name, idxptr->varbind.name_length); printf("%s indexes:\n", start_oid); for( idxptr2 = idxptr ; idxptr2 != NULL; idxptr2 = idxptr2->next_idx) { switch( idxptr2->varbind.type ) { case ASN_INTEGER: printf(" %c %ld %c\n", ( idxptr2->session ? ' ' : '(' ), *idxptr2->varbind.val.integer, ( idxptr2->session ? ' ' : ')' )); break; case ASN_OCTET_STR: printf(" %c %s %c\n", ( idxptr2->session ? ' ' : '(' ), idxptr2->varbind.val.string, ( idxptr2->session ? ' ' : ')' )); break; case ASN_OBJECT_ID: sprint_objid(end_oid, idxptr2->varbind.val.objid, idxptr2->varbind.val_len/sizeof(oid)); printf(" %c %s %c\n", ( idxptr2->session ? ' ' : '(' ), end_oid, ( idxptr2->session ? ' ' : ')' )); break; default: printf("unsupported type (%d)\n", idxptr2->varbind.type); } } } }
int header_system(struct variable *vp, oid *name, int *length, int exact, int *var_len, WriteMethod **write_method) { #define SYSTEM_NAME_LENGTH 8 oid newname[MAX_OID_LEN]; int result; char c_oid[SPRINT_MAX_LEN]; if (snmp_get_do_debugging()) { sprint_objid (c_oid, name, *length); DEBUGMSGTL(("mibII/system", "var_system: %s %d\n", c_oid, exact)); DEBUGMSGTL(("mibII/system", "vp len: %d / %d\n", vp->namelen, 8)); } memcpy((char *)newname, (char *)vp->name, (int)vp->namelen * sizeof(oid)); newname[SYSTEM_NAME_LENGTH] = 0; result = snmp_oid_compare(name, *length, newname, (int)vp->namelen + 1); if ((exact && (result != 0)) || (!exact && (result >= 0))) return(MATCH_FAILED); memcpy( (char *)name,(char *)newname, ((int)vp->namelen + 1) * sizeof(oid)); *length = vp->namelen + 1; *write_method = 0; *var_len = sizeof(long); /* default to 'long' results */ return(MATCH_SUCCEEDED); }
void debugmsg_oid(const char *token, oid *theoid, size_t len) { char c_oid[SPRINT_MAX_LEN]; sprint_objid(c_oid, theoid, len); debugmsg(token, c_oid); }
void DEBUGPOID(oid *theoid, size_t len) { char c_oid[SPRINT_MAX_LEN]; sprint_objid(c_oid,theoid,len); DEBUGP(c_oid); }
int snmp_check_parse( struct snmp_session *session, struct snmp_pdu *pdu, int result) { if ( result == 0 ) { if ( ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE) && snmp_get_do_logging() ) { char c_oid [SPRINT_MAX_LEN]; struct variable_list *var_ptr; switch (pdu->command) { case SNMP_MSG_GET: snmp_log(LOG_DEBUG, " GET message\n"); break; case SNMP_MSG_GETNEXT: snmp_log(LOG_DEBUG, " GETNEXT message\n"); break; case SNMP_MSG_RESPONSE: snmp_log(LOG_DEBUG, " RESPONSE message\n"); break; case SNMP_MSG_SET: snmp_log(LOG_DEBUG, " SET message\n"); break; case SNMP_MSG_TRAP: snmp_log(LOG_DEBUG, " TRAP message\n"); break; case SNMP_MSG_GETBULK: snmp_log(LOG_DEBUG, " GETBULK message, non-rep=%d, max_rep=%d\n", pdu->errstat, pdu->errindex); break; case SNMP_MSG_INFORM: snmp_log(LOG_DEBUG, " INFORM message\n"); break; case SNMP_MSG_TRAP2: snmp_log(LOG_DEBUG, " TRAP2 message\n"); break; case SNMP_MSG_REPORT: snmp_log(LOG_DEBUG, " REPORT message\n"); break; } for ( var_ptr = pdu->variables ; var_ptr != NULL ; var_ptr=var_ptr->next_variable ) { sprint_objid (c_oid, var_ptr->name, var_ptr->name_length); snmp_log(LOG_DEBUG, " -- %s\n", c_oid); } } return 1; } return 0; /* XXX: does it matter what the return value is? */ }
static void sprint_object_identifier(//buf, var, foo, quiet) char *buf, struct variable_list *var, struct enum_list *foo, int quiet) { if (var->type != SMI_OBJID){ sprintf(buf, WIDE("Wrong Type (should be OBJECT IDENTIFIER): ")); buf += strlen(buf); sprint_by_type(buf, var, (struct enum_list *)NULL, quiet); return; } if (!quiet) { sprintf(buf, WIDE("OBJECT IDENTIFIER:\t")); buf += strlen(buf); } sprint_objid(buf, (oid *)(var->val.objid), var->val_len / sizeof(oid)); }
/* * Generic SNMP object fetcher * * st=1 snmpget() - query an agent and return a single value. * st=2 snmpwalk() - walk the mib and return a single dimensional array * containing the values. * st=3 snmprealwalk() and snmpwalkoid() - walk the mib and return an * array of oid,value pairs. * st=5-8 ** Reserved ** * st=11 snmpset() - query an agent and set a single value * */ void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st) { zval **a1, **a2, **a3, **a4, **a5, **a6, **a7; struct snmp_session session, *ss; struct snmp_pdu *pdu=NULL, *response; struct variable_list *vars; char *objid; oid name[MAX_NAME_LEN]; int name_length; int status, count,rootlen=0,gotroot=0; oid root[MAX_NAME_LEN]; char buf[2048]; char buf2[2048]; int keepwalking=1; long timeout=SNMP_DEFAULT_TIMEOUT; long retries=SNMP_DEFAULT_RETRIES; int myargc = ZEND_NUM_ARGS(); char type = (char) 0; char *value = (char *) 0; if (myargc < 3 || myargc > 7 || zend_get_parameters_ex(myargc, &a1, &a2, &a3, &a4, &a5, &a6, &a7) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(a1); convert_to_string_ex(a2); convert_to_string_ex(a3); if (st == 11) { if (myargc < 5) { WRONG_PARAM_COUNT; } convert_to_string_ex(a4); convert_to_string_ex(a5); if(myargc > 5) { convert_to_long_ex(a6); timeout = (*a6)->value.lval; } if(myargc > 6) { convert_to_long_ex(a7); retries = (*a7)->value.lval; } type = (*a4)->value.str.val[0]; value = (*a5)->value.str.val; } else { if(myargc > 3) { convert_to_long_ex(a4); timeout = (*a4)->value.lval; } if(myargc > 4) { convert_to_long_ex(a5); retries = (*a5)->value.lval; } } objid = (*a3)->value.str.val; if (st >= 2) { /* walk */ rootlen = MAX_NAME_LEN; if ( strlen(objid) ) { /* on a walk, an empty string means top of tree - no error */ if ( read_objid(objid, root, &rootlen) ) { gotroot = 1; } else { php_error(E_WARNING,"Invalid object identifier: %s\n", objid); } } if (gotroot == 0) { memmove((char *)root, (char *)objid_mib, sizeof(objid_mib)); rootlen = sizeof(objid_mib) / sizeof(oid); gotroot = 1; } } memset(&session, 0, sizeof(struct snmp_session)); session.peername = (*a1)->value.str.val; session.version = SNMP_VERSION_1; /* * FIXME: potential memory leak * This is a workaround for an "artifact" (Mike Slifcak) * in (at least) ucd-snmp 3.6.1 which frees * memory it did not allocate */ #ifdef UCD_SNMP_HACK session.community = (u_char *)strdup((*a2)->value.str.val); /* memory freed by SNMP library, strdup NOT estrdup */ #else session.community = (u_char *)(*a2)->value.str.val; #endif session.community_len = (*a2)->value.str.len; session.retries = retries; session.timeout = timeout; session.authenticator = NULL; snmp_synch_setup(&session); if ((ss = snmp_open(&session)) == NULL) { php_error(E_WARNING,"Could not open snmp\n"); RETURN_FALSE; } if (st >= 2) { memmove((char *)name, (char *)root, rootlen * sizeof(oid)); name_length = rootlen; if (array_init(return_value) == FAILURE) { php_error(E_WARNING, "Cannot prepare result array"); RETURN_FALSE; } } while(keepwalking) { keepwalking=0; if (st == 1) { pdu = snmp_pdu_create(SNMP_MSG_GET); name_length = MAX_NAME_LEN; if ( !read_objid(objid, name, &name_length) ) { php_error(E_WARNING,"Invalid object identifier: %s\n", objid); RETURN_FALSE; } snmp_add_null_var(pdu, name, name_length); } else if (st == 11) { pdu = snmp_pdu_create(SNMP_MSG_SET); if (snmp_add_var(pdu, name, name_length, type, value)) { php_error(E_WARNING,"Could not add variable: %s\n", name); RETURN_FALSE; } } else if (st >= 2) { pdu = snmp_pdu_create(SNMP_MSG_GETNEXT); snmp_add_null_var(pdu, name, name_length); } retry: status = snmp_synch_response(ss, pdu, &response); if (status == STAT_SUCCESS) { if (response->errstat == SNMP_ERR_NOERROR) { for (vars = response->variables; vars; vars = vars->next_variable) { if (st >= 2 && st != 11 && (vars->name_length < rootlen || memcmp(root, vars->name, rootlen * sizeof(oid)))) { continue; /* not part of this subtree */ } if (st != 11) { sprint_value(buf,vars->name, vars->name_length, vars); } #if 0 Debug("snmp response is: %s\n",buf); #endif if (st == 1) { RETVAL_STRING(buf,1); } else if (st == 2) { add_next_index_string(return_value,buf,1); /* Add to returned array */ } else if (st == 3) { sprint_objid(buf2, vars->name, vars->name_length); add_assoc_string(return_value,buf2,buf,1); } if (st >= 2 && st != 11) { if (vars->type != SNMP_ENDOFMIBVIEW && vars->type != SNMP_NOSUCHOBJECT && vars->type != SNMP_NOSUCHINSTANCE) { memmove((char *)name, (char *)vars->name,vars->name_length * sizeof(oid)); name_length = vars->name_length; keepwalking = 1; } } } } else { if (st != 2 || response->errstat != SNMP_ERR_NOSUCHNAME) { php_error(E_WARNING,"Error in packet.\nReason: %s\n", snmp_errstring(response->errstat)); if (response->errstat == SNMP_ERR_NOSUCHNAME) { for (count=1, vars = response->variables; vars && count != response->errindex; vars = vars->next_variable, count++); if (vars) { sprint_objid(buf,vars->name, vars->name_length); } php_error(E_WARNING,"This name does not exist: %s\n",buf); } if (st == 1) { if ((pdu = snmp_fix_pdu(response, SNMP_MSG_GET)) != NULL) { goto retry; } } else if (st == 11) { if ((pdu = snmp_fix_pdu(response, SNMP_MSG_SET)) != NULL) { goto retry; } } else if (st >= 2) { if ((pdu = snmp_fix_pdu(response, SNMP_MSG_GETNEXT)) != NULL) { goto retry; } } RETURN_FALSE; } } } else if (status == STAT_TIMEOUT) { php_error(E_WARNING,"No Response from %s\n", (*a1)->value.str.val); RETURN_FALSE; } else { /* status == STAT_ERROR */ php_error(E_WARNING,"An error occurred, Quitting...\n"); RETURN_FALSE; } if (response) { snmp_free_pdu(response); } } /* keepwalking */ snmp_close(ss); }
int header_hrdisk(struct variable *vp, oid *name, int *length, int exact, int *var_len, WriteMethod **write_method) { #define HRDISK_ENTRY_NAME_LENGTH 11 oid newname[MAX_OID_LEN]; int disk_idx, LowIndex = -1; int result; char c_oid[SPRINT_MAX_LEN]; if (snmp_get_do_debugging()) { sprint_objid (c_oid, name, *length); DEBUGMSGTL(("host/hr_disk", "var_hrdisk: %s %d\n", c_oid, exact)); } memcpy( (char *)newname,(char *)vp->name, (int)vp->namelen * sizeof(oid)); /* Find "next" disk entry */ Init_HR_Disk(); for ( ;; ) { disk_idx = Get_Next_HR_Disk(); if ( disk_idx == -1 ) break; newname[HRDISK_ENTRY_NAME_LENGTH] = disk_idx; result = snmp_oid_compare(name, *length, newname, (int)vp->namelen + 1); if (exact && (result == 0)) { LowIndex = disk_idx; Save_HR_Disk_Specific(); break; } if ((!exact && (result < 0)) && ( LowIndex == -1 || disk_idx < LowIndex )) { LowIndex = disk_idx; Save_HR_Disk_Specific(); #ifdef HRD_MONOTONICALLY_INCREASING break; #endif } } if ( LowIndex == -1 ) { DEBUGMSGTL(("host/hr_disk", "... index out of range\n")); return(MATCH_FAILED); } newname[HRDISK_ENTRY_NAME_LENGTH] = LowIndex; memcpy( (char *)name,(char *)newname, ((int)vp->namelen + 1) * sizeof(oid)); *length = vp->namelen + 1; *write_method = 0; *var_len = sizeof(long); /* default to 'long' results */ if (snmp_get_do_debugging()) { sprint_objid (c_oid, name, *length); DEBUGMSGTL(("host/hr_disk", "... get disk stats %s\n", c_oid)); } return LowIndex; }
u_char * var_rip2(struct variable *vp, oid *name, int *length, int exact, int *var_len, WriteMethod **write_method) { u_char *var; int result; char c_oid[SPRINT_MAX_LEN]; if (snmp_get_do_debugging()) { sprint_objid (c_oid, name, *length); DEBUGMSGTL(("smux/snmp_rip2", "[var_rip2] var len %d, oid requested Len %d-%s\n",*var_len, *length,c_oid)); } /* * Pass on the request to Gated. * If the request sent out was a get next, check to see if * it lies in the rip2 range. If it doesn't, return NULL. * In either case, make sure that errors are checked on the * returned packets. */ /* No writes for now */ *write_method = NULL; /* * Donot allow access to the peer stuff as it crashes gated. * However A GetNext on the last 23.3.1.9 variable will force gated into * the peer stuff and cause it to crash. * The only way to fix this is to either solve the Gated problem, or * remove the peer variables from Gated itself and cause it to return * NULL at the crossing. Currently doing the later. */ /* Reject GET and GETNEXT for anything above rip2ifconf range */ result = snmp_oid_compare(name, *length, max_rip_mib, sizeof(max_rip_mib)/sizeof(u_int)); if (result >= 0) { DEBUGMSGTL(("smux/snmp_rip2", "Over shot\n")); return NULL; } /* for GETs we need to be in the rip2 range so reject anything below */ result = snmp_oid_compare(name, *length, min_rip_mib, sizeof(min_rip_mib)/sizeof(u_int)); if (exact && (result < 0)) { DEBUGMSGTL(("smux/snmp_rip2", "Exact but doesn't match length %d, size %d\n", *length, sizeof(min_rip_mib))); return NULL; } /* * On return, 'var' points to the value returned which is of length * '*var_len'. 'name' points to the new (same as the one passed in for * GETs) oid which has 'length' suboids. * 'smux_type' contains the type of the variable. */ var = smux_snmp_process(exact, name, length, var_len); if (snmp_get_do_debugging()) { DEBUGMSGTL(("smux/snmp_rip2", "[var_rip2] var len %d, oid obtained Len %d-%s\n",*var_len, *length,c_oid)); } vp->type = smux_type; /* XXX Need a mechanism to return errors in gated's responses */ if (var == NULL) return NULL; /* * Any resullt returned should be within the rip2 tree. * rip_mib - static u_int rip_mib[] = {1, 3, 6, 1, 2, 1, 23}; */ if (memcmp(rip_mib, name, sizeof(rip_mib)) != 0) { return NULL; } else { return var; } }
/* * Generic SNMP object fetcher * * st=1 GET * st=2 WALK */ void _php3_snmp(INTERNAL_FUNCTION_PARAMETERS, int st) { pval *a1, *a2, *a3; struct snmp_session session, *ss; struct snmp_pdu *pdu=NULL, *response; struct variable_list *vars; char *community, *hostname; char *objid; oid name[MAX_NAME_LEN]; int name_length; int status, count,rootlen=0,gotroot=0; oid root[MAX_NAME_LEN]; char buf[2048]; int keepwalking=1; static int mib_init=0; if (getParameters(ht, 3, &a1, &a2, &a3) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string(a1); convert_to_string(a2); convert_to_string(a3); hostname=a1->value.str.val; community=a2->value.str.val; objid=a3->value.str.val; if (!mib_init) { init_mib(); mib_init=1; } if (st==2) { /* walk */ rootlen = MAX_NAME_LEN; if (strlen(objid)) { /* on a walk, an empty string means top of tree - no error */ if (read_objid(objid, root, &rootlen)) { gotroot = 1; } else { php3_error(E_WARNING,"Invalid object identifier: %s\n", objid); } } if (gotroot == 0) { memmove((char *)root, (char *)objid_mib, sizeof(objid_mib)); rootlen = sizeof(objid_mib) / sizeof(oid); gotroot = 1; } } memset(&session, 0, sizeof(struct snmp_session)); session.peername = hostname; session.version = SNMP_VERSION_1; session.community = (u_char *)community; session.community_len = strlen((char *)community); session.retries = SNMP_DEFAULT_RETRIES; session.timeout = SNMP_DEFAULT_TIMEOUT; session.authenticator = NULL; snmp_synch_setup(&session); ss = snmp_open(&session); if (ss == NULL){ php3_error(E_WARNING,"Couldn't open snmp\n"); RETURN_FALSE; } if (st==2) { memmove((char *)name, (char *)root, rootlen * sizeof(oid)); name_length = rootlen; /* prepare result array */ array_init(return_value); } while(keepwalking) { keepwalking=0; if (st==1) pdu = snmp_pdu_create(GET_REQ_MSG); else if (st==2) pdu = snmp_pdu_create(GETNEXT_REQ_MSG); if (st==1) { name_length = MAX_NAME_LEN; if (!read_objid(objid, name, &name_length)) { php3_error(E_WARNING,"Invalid object identifier: %s\n", objid); RETURN_FALSE; } } snmp_add_null_var(pdu, name, name_length); retry: status = snmp_synch_response(ss, pdu, &response); if (status == STAT_SUCCESS) { if (response->errstat == SNMP_ERR_NOERROR) { for(vars = response->variables; vars; vars = vars->next_variable) { if (st==2 && (vars->name_length < rootlen || memcmp(root, vars->name, rootlen * sizeof(oid)))) continue; /* not part of this subtree */ sprint_value(buf,vars->name, vars->name_length, vars); #if 0 Debug("snmp response is: %s\n",buf); #endif if (st==1) { RETVAL_STRING(buf,1); } else if (st==2) { /* Add to returned array */ add_next_index_string(return_value,buf,1); if (vars->type != SNMP_ENDOFMIBVIEW && vars->type != SNMP_NOSUCHOBJECT && vars->type != SNMP_NOSUCHINSTANCE) { memmove((char *)name, (char *)vars->name,vars->name_length * sizeof(oid)); name_length = vars->name_length; keepwalking = 1; } } } } else { if (st!=2 || response->errstat != SNMP_ERR_NOSUCHNAME) { php3_error(E_WARNING,"Error in packet.\nReason: %s\n", snmp_errstring(response->errstat)); if (response->errstat == SNMP_ERR_NOSUCHNAME) { for(count=1, vars = response->variables; vars && count != response->errindex; vars = vars->next_variable, count++); if (vars) sprint_objid(buf,vars->name, vars->name_length); php3_error(E_WARNING,"This name does not exist: %s\n",buf); } if (st==1) { if ((pdu = snmp_fix_pdu(response, GET_REQ_MSG)) != NULL) goto retry; } else if (st==2) { if ((pdu = snmp_fix_pdu(response, GETNEXT_REQ_MSG)) != NULL) goto retry; } RETURN_FALSE; } } } else if (status == STAT_TIMEOUT) { php3_error(E_WARNING,"No Response from %s\n", hostname); RETURN_FALSE; } else { /* status == STAT_ERROR */ php3_error(E_WARNING,"An error occurred, Quitting\n"); RETURN_FALSE; } if (response) snmp_free_pdu(response); } /* keepwalking */ snmp_close(ss); }