📄 snmp.xs
字号:
goto found; } } *lastind=0; return NULL;found: if (len > 1){ return_tree = __oid2tp(oidp + 1, len - 1, subtree->child_list, lastind); (*lastind)++; } else { *lastind=1; } if (return_tree) return return_tree; else return subtree;}/* function: __concat_oid_str * * This function converts a dotted-decimal string, soid_str, to an array * of oid types and concatenates them on doid_arr begining at the index * specified by doid_arr_len. * * returns : SUCCESS, FAILURE */static int__concat_oid_str(doid_arr, doid_arr_len, soid_str)oid *doid_arr;int *doid_arr_len;char * soid_str;{ char soid_buf[STR_BUF_SIZE]; char *cp; if (!soid_str || !*soid_str) return SUCCESS;/* successfully added nothing */ if (*soid_str == '.') soid_str++; strcpy(soid_buf, soid_str); cp = strtok(soid_buf,"."); while (cp) { sscanf(cp, "%lu", &(doid_arr[(*doid_arr_len)++])); /* doid_arr[(*doid_arr_len)++] = atoi(cp); */ cp = strtok(NULL,"."); } return(SUCCESS);}/* * add a varbind to PDU */static int__add_var_val_str(pdu, name, name_length, val, len, type) struct snmp_pdu *pdu; oid *name; int name_length; char * val; int len; int type;{ struct variable_list *vars; oid oidbuf[MAX_OID_LEN]; int ret = SUCCESS; struct tree *tp; if (pdu->variables == NULL){ pdu->variables = vars = (struct variable_list *)calloc(1,sizeof(struct variable_list)); } else { for(vars = pdu->variables; vars->next_variable; vars = vars->next_variable) /*EXIT*/; vars->next_variable = (struct variable_list *)calloc(1,sizeof(struct variable_list)); vars = vars->next_variable; } vars->next_variable = NULL; vars->name = (oid *)malloc(name_length * sizeof(oid)); memcpy((char *)vars->name, (char *)name, name_length * sizeof(oid)); vars->name_length = name_length; switch (type) { case TYPE_INTEGER: case TYPE_INTEGER32: vars->type = ASN_INTEGER; vars->val.integer = (long *)malloc(sizeof(long)); *(vars->val.integer) = strtol(val,NULL,0); vars->val_len = sizeof(long); break; case TYPE_GAUGE: vars->type = ASN_GAUGE; goto UINT; case TYPE_COUNTER: vars->type = ASN_COUNTER; goto UINT; case TYPE_TIMETICKS: vars->type = ASN_TIMETICKS; goto UINT; case TYPE_UINTEGER: case TYPE_UNSIGNED32: vars->type = ASN_UINTEGER;UINT: vars->val.integer = (long *)malloc(sizeof(long)); sscanf(val,"%lu",vars->val.integer); vars->val_len = sizeof(long); break; case TYPE_OCTETSTR: vars->type = ASN_OCTET_STR; goto OCT; case TYPE_OPAQUE: vars->type = ASN_OCTET_STR;OCT: vars->val.string = (u_char *)malloc(len); vars->val_len = len; memcpy((char *)vars->val.string, val, len); break; case TYPE_IPADDR: vars->type = ASN_IPADDRESS; vars->val.integer = (long *)malloc(sizeof(long)); *(vars->val.integer) = inet_addr(val); vars->val_len = sizeof(long); break; case TYPE_OBJID: vars->type = ASN_OBJECT_ID; vars->val_len = MAX_OID_LEN; /* if (read_objid(val, oidbuf, &(vars->val_len))) { */ tp = __tag2oid(val,NULL,oidbuf,&(vars->val_len),NULL,0); if (vars->val_len) { vars->val_len *= sizeof(oid); vars->val.objid = (oid *)malloc(vars->val_len); memcpy((char *)vars->val.objid, (char *)oidbuf, vars->val_len); } else { vars->val.objid = NULL; ret = FAILURE; } break; default: vars->type = ASN_NULL; vars->val_len = 0; vars->val.string = NULL; ret = FAILURE; } return ret;}/* takes ss and pdu as input and updates the 'response' argument *//* the input 'pdu' argument will be freed */static int__send_sync_pdu(ss, pdu, response, retry_nosuch, err_str_sv, err_num_sv, err_ind_sv)struct snmp_session *ss;struct snmp_pdu *pdu;struct snmp_pdu **response;int retry_nosuch;SV * err_str_sv;SV * err_num_sv;SV * err_ind_sv;{ int status; long command = pdu->command; *response = NULL;retry: status = snmp_synch_response(ss, pdu, response); if ((*response == NULL) && (status == STAT_SUCCESS)) status = STAT_ERROR; switch (status) { case STAT_SUCCESS: switch ((*response)->errstat) { case SNMP_ERR_NOERROR: break; case SNMP_ERR_NOSUCHNAME: if (retry_nosuch && (pdu = snmp_fix_pdu(*response, command))) { if (*response) snmp_free_pdu(*response); goto retry; } /* Pv1, SNMPsec, Pv2p, v2c, v2u, v2*, and SNMPv3 PDUs */ case SNMP_ERR_TOOBIG: case SNMP_ERR_BADVALUE: case SNMP_ERR_READONLY: case SNMP_ERR_GENERR: /* in SNMPv2p, SNMPv2c, SNMPv2u, SNMPv2*, and SNMPv3 PDUs */ case SNMP_ERR_NOACCESS: case SNMP_ERR_WRONGTYPE: case SNMP_ERR_WRONGLENGTH: case SNMP_ERR_WRONGENCODING: case SNMP_ERR_WRONGVALUE: case SNMP_ERR_NOCREATION: case SNMP_ERR_INCONSISTENTVALUE: case SNMP_ERR_RESOURCEUNAVAILABLE: case SNMP_ERR_COMMITFAILED: case SNMP_ERR_UNDOFAILED: case SNMP_ERR_AUTHORIZATIONERROR: case SNMP_ERR_NOTWRITABLE: /* in SNMPv2c, SNMPv2u, SNMPv2*, and SNMPv3 PDUs */ case SNMP_ERR_INCONSISTENTNAME: default: sv_catpv(err_str_sv, (char*)snmp_errstring((*response)->errstat)); sv_setiv(err_num_sv, (*response)->errstat); sv_setiv(err_ind_sv, (*response)->errindex); status = (*response)->errstat; break; } break; case STAT_TIMEOUT: case STAT_ERROR: sv_catpv(err_str_sv, (char*)snmp_api_errstring(ss->s_snmp_errno)); sv_setiv(err_num_sv, ss->s_snmp_errno); break; default: sv_catpv(err_str_sv, "send_sync_pdu: unknown status"); sv_setiv(err_num_sv, ss->s_snmp_errno); break; } return(status);}static int__snmp_xs_cb (op, ss, reqid, pdu, cb_data)int op;struct snmp_session *ss;int reqid;struct snmp_pdu *pdu;void *cb_data;{ SV *varlist_ref; AV *varlist; SV *varbind_ref; AV *varbind; struct variable_list *vars; struct tree *tp; int len; oid *oid_arr; int oid_arr_len = MAX_OID_LEN; SV *tmp_sv; int type; char tmp_type_str[MAX_TYPE_NAME_LEN]; int status; char str_buf[STR_BUF_SIZE]; char *label; char *iid; char *cp; int getlabel_flag = NO_FLAGS; int sprintval_flag = USE_BASIC; int old_numeric, old_printfull; SV *sv_timestamp = NULL; SV* cb = ((struct snmp_xs_cb_data*)cb_data)->perl_cb; SV* sess_ref = ((struct snmp_xs_cb_data*)cb_data)->sess_ref; SV **err_str_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorStr", 8, 1); SV **err_num_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorNum", 8, 1); SV **err_ind_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorInd", 8, 1); dSP; ENTER; SAVETMPS; free(cb_data); sv_setpv(*err_str_svp, (char*)snmp_errstring(pdu->errstat)); sv_setiv(*err_num_svp, pdu->errstat); sv_setiv(*err_ind_svp, pdu->errindex); varlist_ref = &sv_undef; /* Prevent unintialized use below. */ switch (op) { case RECEIVED_MESSAGE: switch (pdu->command) { case SNMP_MSG_RESPONSE: { if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"TimeStamp", 9, 1))) sv_timestamp = newSViv((IV)time(NULL)); varlist = newAV(); varlist_ref = newRV_noinc((SV*)varlist); /* ** Set up for numeric OID's, if necessary. Save the old values ** so that they can be restored when we finish -- these are ** library-wide globals, and have to be set/restored for each ** session. */ old_numeric = ds_get_boolean(DS_LIBRARY_ID, DS_LIB_PRINT_NUMERIC_OIDS); old_printfull = ds_get_boolean(DS_LIBRARY_ID, DS_LIB_PRINT_FULL_OID); if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseNumeric", 10, 1))) { getlabel_flag |= USE_NUMERIC_OIDS; ds_set_boolean(DS_LIBRARY_ID, DS_LIB_PRINT_NUMERIC_OIDS, 1); } if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseLongNames", 12, 1))) { getlabel_flag |= USE_LONG_NAMES; ds_set_boolean(DS_LIBRARY_ID, DS_LIB_PRINT_FULL_OID, 1); } sv_bless(varlist_ref, gv_stashpv("SNMP::VarList",0)); for(vars = (pdu?pdu->variables:NULL); vars; vars = vars->next_variable) { varbind = newAV(); varbind_ref = newRV_noinc((SV*)varbind); sv_bless(varbind_ref, gv_stashpv("SNMP::Varbind",0)); av_push(varlist, varbind_ref); *str_buf = '.'; *(str_buf+1) = '\0'; tp = get_symbol(vars->name,vars->name_length, get_tree_head(),str_buf+1); if (__is_leaf(tp)) { type = tp->type; } else { getlabel_flag |= NON_LEAF_NAME; type = __translate_asn_type(vars->type); } __get_label_iid(str_buf,&label,&iid,getlabel_flag); av_store(varbind, VARBIND_TAG_F, newSVpv(label, strlen(label))); av_store(varbind, VARBIND_IID_F, newSVpv(iid, strlen(iid))); __get_type_str(type, tmp_type_str); tmp_sv = newSVpv(tmp_type_str, strlen(tmp_type_str)); av_store(varbind, VARBIND_TYPE_F, tmp_sv); len = __sprint_value(str_buf, vars, tp, type, sprintval_flag); tmp_sv = newSVpv((char*)str_buf, len); av_store(varbind, VARBIND_VAL_F, tmp_sv); /* If requested, store a timestamp for this var in the Varbind. */ if (sv_timestamp) av_store(varbind, VARBIND_TIME_F, SvREFCNT_inc(sv_timestamp)); } /* for */ /* Reset the library's behavior for numeric/symbolic OID's. */ ds_set_boolean(DS_LIBRARY_ID, DS_LIB_PRINT_NUMERIC_OIDS, old_numeric ); ds_set_boolean(DS_LIBRARY_ID, DS_LIB_PRINT_FULL_OID, old_printfull); } /* case SNMP_MSG_RESPONSE */ break; default:; } /* switch pdu->command */ break; case TIMED_OUT: varlist_ref = &sv_undef; break; default:; } /* switch op */ sv_2mortal(cb); cb = __push_cb_args(cb, (SvTRUE(varlist_ref) ? sv_2mortal(varlist_ref):varlist_ref)); __call_callback(cb, G_DISCARD); FREETMPS; LEAVE; sv_2mortal(sess_ref); return 1;}static SV *__push_cb_args(sv,esv)SV *sv;SV *esv;{ dSP; if (SvTYPE(SvRV(sv)) != SVt_PVCV) sv = SvRV(sv); PUSHMARK(sp); if (SvTYPE(sv) == SVt_PVAV) { AV *av = (AV *) sv; int n = av_len(av) + 1; SV **x = av_fetch(av, 0, 0); if (x) { int i = 1; sv = *x; for (i = 1; i < n; i++) { x = av_fetch(av, i, 0); if (x) { SV *arg = *x; XPUSHs(sv_mortalcopy(arg)); } else { XPUSHs(&sv_undef); } } } else { sv = &sv_undef; } } if (esv) XPUSHs(sv_mortalcopy(esv)); PUTBACK; return sv;}static int__call_callback(sv, flags)SV *sv;int flags;{ dSP; I32 myframe = TOPMARK; I32 count; ENTER; if (SvTYPE(sv) == SVt_PVCV) { count = perl_call_sv(sv, flags); } else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVCV) { count = perl_call_sv(SvRV(sv), flags); } else { SV **top = stack_base + myframe + 1; SV *obj = *top; if (SvPOK(sv) && SvROK(obj) && SvOBJECT(SvRV(obj))) { count = perl_call_method(SvPV(sv, na), flags); } else if (SvPOK(obj) && SvROK(sv) && SvOBJECT(SvRV(sv))) { /* We have obj method ... Used to be used instead of LangMethodCall() */ *top = sv; count = perl_call_method(SvPV(obj, na), flags); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -