SNMP.xs
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:171k
- session.community = (u_char *)community;
- session.peername = peer;
- session.local_port = lport;
- session.retries = retries; /* 5 */
- session.timeout = timeout; /* 1000000L */
- session.authenticator = NULL;
- ss = snmp_open(&session);
- if (ss == NULL) {
- if (verbose) warn("error:snmp_new_session: Couldn't open SNMP session");
- }
- end:
- RETVAL = ss;
- }
- OUTPUT:
- RETVAL
- SnmpSession *
- snmp_new_v3_session(version, peer, retries, timeout, sec_name, sec_level, sec_eng_id, context_eng_id, context, auth_proto, auth_pass, priv_proto, priv_pass, eng_boots, eng_time, auth_master_key, auth_master_key_len, priv_master_key, priv_master_key_len, auth_localized_key, auth_localized_key_len, priv_localized_key, priv_localized_key_len)
- int version
- char * peer
- int retries
- int timeout
- char * sec_name
- int sec_level
- char * sec_eng_id
- char * context_eng_id
- char * context
- char * auth_proto
- char * auth_pass
- char * priv_proto
- char * priv_pass
- int eng_boots
- int eng_time
- char * auth_master_key
- size_t auth_master_key_len
- char * priv_master_key
- size_t priv_master_key_len
- char * auth_localized_key
- size_t auth_localized_key_len
- char * priv_localized_key
- size_t priv_localized_key_len
- CODE:
- {
- /* u_char sec_eng_id_buf[ENG_ID_BUF_SIZE]; */
- /* u_char context_eng_id_buf[ENG_ID_BUF_SIZE]; */
- SnmpSession session = {0};
- SnmpSession *ss = NULL;
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- __libraries_init("perl");
- if (version == 3) {
- session.version = SNMP_VERSION_3;
- } else {
- if (verbose)
- warn("error:snmp_new_v3_session:Unsupported SNMP version (%d)n", version);
- goto end;
- }
- session.peername = strdup(peer);
- session.retries = retries; /* 5 */
- session.timeout = timeout; /* 1000000L */
- session.authenticator = NULL;
- session.contextNameLen = strlen(context);
- session.contextName = context;
- session.securityNameLen = strlen(sec_name);
- session.securityName = sec_name;
- session.securityLevel = sec_level;
- session.securityModel = USM_SEC_MODEL_NUMBER;
- /* session.securityEngineID = sec_eng_id_buf;*/
- session.securityEngineIDLen =
- hex_to_binary2(sec_eng_id, strlen(sec_eng_id),
- (char **) &session.securityEngineID);
- /* session.contextEngineID = context_eng_id_buf; */
- session.contextEngineIDLen =
- hex_to_binary2(sec_eng_id, strlen(sec_eng_id),
- (char **) &session.contextEngineID);
- session.engineBoots = eng_boots;
- session.engineTime = eng_time;
- #ifndef DISABLE_MD5
- if (!strcmp(auth_proto, "MD5")) {
- session.securityAuthProto =
- snmp_duplicate_objid(usmHMACMD5AuthProtocol,
- USM_AUTH_PROTO_MD5_LEN);
- session.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
- } else
- #endif
- if (!strcmp(auth_proto, "SHA")) {
- session.securityAuthProto =
- snmp_duplicate_objid(usmHMACSHA1AuthProtocol,
- USM_AUTH_PROTO_SHA_LEN);
- session.securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
- } else if (!strcmp(auth_proto, "DEFAULT")) {
- const oid *theoid =
- get_default_authtype(&session.securityAuthProtoLen);
- session.securityAuthProto =
- snmp_duplicate_objid(theoid, session.securityAuthProtoLen);
- } else {
- if (verbose)
- warn("error:snmp_new_v3_session:Unsupported authentication protocol(%s)n", auth_proto);
- goto end;
- }
- if (session.securityLevel >= SNMP_SEC_LEVEL_AUTHNOPRIV) {
- if (auth_localized_key_len) {
- memdup(&session.securityAuthLocalKey,
- auth_localized_key,
- auth_localized_key_len);
- session.securityAuthLocalKeyLen = auth_localized_key_len;
- } else if (auth_master_key_len) {
- session.securityAuthKeyLen =
- SNMP_MIN(auth_master_key_len,
- sizeof(session.securityAuthKey));
- memcpy(session.securityAuthKey, auth_master_key,
- session.securityAuthKeyLen);
- } else {
- if (strlen(auth_pass) > 0) {
- session.securityAuthKeyLen = USM_AUTH_KU_LEN;
- if (generate_Ku(session.securityAuthProto,
- session.securityAuthProtoLen,
- (u_char *)auth_pass, strlen(auth_pass),
- session.securityAuthKey,
- &session.securityAuthKeyLen) != SNMPERR_SUCCESS) {
- if (verbose)
- warn("error:snmp_new_v3_session:Error generating Ku from authentication password.n");
- goto end;
- }
- }
- }
- }
- #ifndef DISABLE_DES
- if (!strcmp(priv_proto, "DES")) {
- session.securityPrivProto =
- snmp_duplicate_objid(usmDESPrivProtocol,
- USM_PRIV_PROTO_DES_LEN);
- session.securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;
- } else
- #endif
- if (!strncmp(priv_proto, "AES", 3)) {
- session.securityPrivProto =
- snmp_duplicate_objid(usmAESPrivProtocol,
- USM_PRIV_PROTO_AES_LEN);
- session.securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN;
- } else if (!strcmp(priv_proto, "DEFAULT")) {
- const oid *theoid =
- get_default_privtype(&session.securityPrivProtoLen);
- session.securityPrivProto =
- snmp_duplicate_objid(theoid, session.securityPrivProtoLen);
- } else {
- if (verbose)
- warn("error:snmp_new_v3_session:Unsupported privacy protocol(%s)n", priv_proto);
- goto end;
- }
- if (session.securityLevel >= SNMP_SEC_LEVEL_AUTHPRIV) {
- if (priv_localized_key_len) {
- memdup(&session.securityPrivLocalKey,
- priv_localized_key,
- priv_localized_key_len);
- session.securityPrivLocalKeyLen = priv_localized_key_len;
- } else if (priv_master_key_len) {
- session.securityPrivKeyLen =
- SNMP_MIN(auth_master_key_len,
- sizeof(session.securityPrivKey));
- memcpy(session.securityPrivKey, priv_master_key,
- session.securityPrivKeyLen);
- } else {
- session.securityPrivKeyLen = USM_PRIV_KU_LEN;
- if (generate_Ku(session.securityAuthProto,
- session.securityAuthProtoLen,
- (u_char *)priv_pass, strlen(priv_pass),
- session.securityPrivKey,
- &session.securityPrivKeyLen) != SNMPERR_SUCCESS) {
- if (verbose)
- warn("error:snmp_new_v3_session:Error generating Ku from privacy pass phrase.n");
- goto end;
- }
- }
- }
- ss = snmp_open(&session);
- if (ss == NULL) {
- if (verbose) warn("error:snmp_new_v3_session:Couldn't open SNMP session");
- }
- end:
- RETVAL = ss;
- free (session.contextEngineID);
- }
- OUTPUT:
- RETVAL
- SnmpSession *
- snmp_update_session(sess_ref, version, community, peer, lport, retries, timeout)
- SV * sess_ref
- char * version
- char * community
- char * peer
- int lport
- int retries
- int timeout
- CODE:
- {
- SV **sess_ptr_sv;
- SnmpSession *ss;
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
- ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
- if (!ss) goto update_end;
- ss->version = -1;
- #ifndef DISABLE_SNMPV1
- if (!strcmp(version, "1")) {
- ss->version = SNMP_VERSION_1;
- }
- #endif
- #ifndef DISABLE_SNMPV2C
- if (!strcmp(version, "2") || !strcmp(version, "2c")) {
- ss->version = SNMP_VERSION_2c;
- }
- #endif
- if (!strcmp(version, "3")) {
- ss->version = SNMP_VERSION_3;
- }
- if (ss->version == -1) {
- if (verbose)
- warn("Unsupported SNMP version (%s)n", version);
- goto update_end;
- }
- /* WARNING LEAKAGE but I cant free lib memory under win32 */
- ss->community_len = strlen((char *)community);
- ss->community = (u_char *)strdup(community);
- ss->peername = strdup(peer);
- ss->local_port = lport;
- ss->retries = retries; /* 5 */
- ss->timeout = timeout; /* 1000000L */
- ss->authenticator = NULL;
- update_end:
- RETVAL = ss;
- }
- OUTPUT:
- RETVAL
- int
- snmp_add_mib_dir(mib_dir,force=0)
- char * mib_dir
- int force
- CODE:
- {
- int result = 0; /* Avoid use of uninitialized variable below. */
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- if (mib_dir && *mib_dir) {
- result = add_mibdir(mib_dir);
- }
- if (result) {
- if (verbose) warn("Added mib dir %sn", mib_dir);
- } else {
- if (verbose) warn("Failed to add %sn", mib_dir);
- }
- RETVAL = (I32)result;
- }
- OUTPUT:
- RETVAL
- void
- snmp_init_mib_internals()
- CODE:
- {
- int notused = 1;
- /* this function does nothing */
- /* it is kept only for backwards compatibility */
- }
- int
- snmp_read_mib(mib_file, force=0)
- char * mib_file
- int force
- CODE:
- {
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- if ((mib_file == NULL) || (*mib_file == ' ')) {
- if (get_tree_head() == NULL) {
- if (verbose) warn("initializing MIBn");
- init_mib();
- if (get_tree_head()) {
- if (verbose) warn("donen");
- } else {
- if (verbose) warn("failedn");
- }
- }
- } else {
- if (verbose) warn("reading MIB: %sn", mib_file);
- if (strcmp("ALL",mib_file))
- read_mib(mib_file);
- else
- read_all_mibs();
- if (get_tree_head()) {
- if (verbose) warn("donen");
- } else {
- if (verbose) warn("failedn");
- }
- }
- RETVAL = (I32)get_tree_head();
- }
- OUTPUT:
- RETVAL
- int
- snmp_read_module(module)
- char * module
- CODE:
- {
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- if (!strcmp(module,"ALL")) {
- read_all_mibs();
- } else {
- read_module(module);
- }
- if (get_tree_head()) {
- if (verbose) warn("Read %sn", module);
- } else {
- if (verbose) warn("Failed reading %sn", module);
- }
- RETVAL = (I32)get_tree_head();
- }
- OUTPUT:
- RETVAL
- int
- snmp_set(sess_ref, varlist_ref, perl_callback)
- SV * sess_ref
- SV * varlist_ref
- SV * perl_callback
- PPCODE:
- {
- AV *varlist;
- SV **varbind_ref;
- SV **varbind_val_f;
- AV *varbind;
- I32 varlist_len;
- I32 varlist_ind;
- SnmpSession *ss;
- netsnmp_pdu *pdu, *response;
- struct tree *tp;
- oid *oid_arr;
- int oid_arr_len = MAX_OID_LEN;
- char *tag_pv;
- snmp_xs_cb_data *xs_cb_data;
- SV **sess_ptr_sv;
- SV **err_str_svp;
- SV **err_num_svp;
- SV **err_ind_svp;
- int status = 0;
- int type;
- int res;
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- int use_enums;
- struct enum_list *ep;
- int best_guess;
- New (0, oid_arr, MAX_OID_LEN, oid);
- if (oid_arr && SvROK(sess_ref) && SvROK(varlist_ref)) {
- use_enums = SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseEnums",8,1));
- sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
- ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
- err_str_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorStr", 8, 1);
- err_num_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorNum", 8, 1);
- err_ind_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorInd", 8, 1);
- sv_setpv(*err_str_svp, "");
- sv_setiv(*err_num_svp, 0);
- sv_setiv(*err_ind_svp, 0);
- best_guess = SvIV(*hv_fetch((HV*)SvRV(sess_ref),"BestGuess",9,1));
- pdu = snmp_pdu_create(SNMP_MSG_SET);
- varlist = (AV*) SvRV(varlist_ref);
- varlist_len = av_len(varlist);
- for(varlist_ind = 0; varlist_ind <= varlist_len; varlist_ind++) {
- varbind_ref = av_fetch(varlist, varlist_ind, 0);
- if (SvROK(*varbind_ref)) {
- varbind = (AV*) SvRV(*varbind_ref);
- tag_pv = __av_elem_pv(varbind, VARBIND_TAG_F,NULL);
- tp=__tag2oid(tag_pv,
- __av_elem_pv(varbind, VARBIND_IID_F,NULL),
- oid_arr, &oid_arr_len, &type, best_guess);
- if (oid_arr_len==0) {
- if (verbose)
- warn("error: set: unknown object ID (%s)",
- (tag_pv?tag_pv:"<null>"));
- sv_catpv(*err_str_svp,
- (char*)snmp_api_errstring(SNMPERR_UNKNOWN_OBJID));
- sv_setiv(*err_num_svp, SNMPERR_UNKNOWN_OBJID);
- XPUSHs(&sv_undef); /* unknown OID */
- snmp_free_pdu(pdu);
- goto done;
- }
- if (type == TYPE_UNKNOWN) {
- type = __translate_appl_type(
- __av_elem_pv(varbind, VARBIND_TYPE_F, NULL));
- if (type == TYPE_UNKNOWN) {
- if (verbose)
- warn("error: set: no type found for object");
- sv_catpv(*err_str_svp,
- (char*)snmp_api_errstring(SNMPERR_VAR_TYPE));
- sv_setiv(*err_num_svp, SNMPERR_VAR_TYPE);
- XPUSHs(&sv_undef); /* unknown OID */
- snmp_free_pdu(pdu);
- goto done;
- }
- }
- varbind_val_f = av_fetch(varbind, VARBIND_VAL_F, 0);
- if (type==TYPE_INTEGER && use_enums && tp && tp->enums) {
- for(ep = tp->enums; ep; ep = ep->next) {
- if (varbind_val_f && SvOK(*varbind_val_f) &&
- !strcmp(ep->label, SvPV(*varbind_val_f,na))) {
- sv_setiv(*varbind_val_f, ep->value);
- break;
- }
- }
- }
- res = __add_var_val_str(pdu, oid_arr, oid_arr_len,
- (varbind_val_f && SvOK(*varbind_val_f) ?
- SvPV(*varbind_val_f,na):NULL),
- (varbind_val_f && SvOK(*varbind_val_f) ?
- SvCUR(*varbind_val_f):0), type);
- if (verbose && res == FAILURE)
- warn("error: adding variable/value to PDU");
- } /* if var_ref is ok */
- } /* for all the vars */
- if (SvTRUE(perl_callback)) {
- xs_cb_data =
- (snmp_xs_cb_data*)malloc(sizeof(snmp_xs_cb_data));
- xs_cb_data->perl_cb = newSVsv(perl_callback);
- xs_cb_data->sess_ref = newRV_inc(SvRV(sess_ref));
- status = snmp_async_send(ss, pdu, __snmp_xs_cb,
- (void*)xs_cb_data);
- if (status != 0) {
- XPUSHs(sv_2mortal(newSViv(status))); /* push the reqid?? */
- } else {
- snmp_free_pdu(pdu);
- sv_catpv(*err_str_svp,
- (char*)snmp_api_errstring(ss->s_snmp_errno));
- sv_setiv(*err_num_svp, ss->s_snmp_errno);
- XPUSHs(&sv_undef);
- }
- goto done;
- }
- status = __send_sync_pdu(ss, pdu, &response,
- NO_RETRY_NOSUCH,
- *err_str_svp, *err_num_svp,
- *err_ind_svp);
- if (response) snmp_free_pdu(response);
- if (status) {
- XPUSHs(&sv_undef);
- } else {
- XPUSHs(sv_2mortal(newSVpv(ZERO_BUT_TRUE,0)));
- }
- } else {
- /* BUG!!! need to return an error value */
- XPUSHs(&sv_undef); /* no mem or bad args */
- }
- done:
- Safefree(oid_arr);
- }
- void
- snmp_catch(sess_ref, perl_callback)
- SV * sess_ref
- SV * perl_callback
- PPCODE:
- {
- netsnmp_session *ss;
- SV **sess_ptr_sv;
- SV **err_str_svp;
- SV **err_num_svp;
- SV **err_ind_svp;
- if (SvROK(sess_ref)) {
- sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
- ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
- err_str_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorStr", 8, 1);
- err_num_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorNum", 8, 1);
- err_ind_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorInd", 8, 1);
- sv_setpv(*err_str_svp, "");
- sv_setiv(*err_num_svp, 0);
- sv_setiv(*err_ind_svp, 0);
- snmp_synch_reset(ss);
- ss->callback = NULL;
- ss->callback_magic = NULL;
- if (SvTRUE(perl_callback)) {
- perl_callback = newSVsv(perl_callback);
- # it might be more efficient to pass the varbind_ref to
- # __snmp_xs_cb as part of perl_callback so it is not freed
- # and reconstructed for each call
- ss->callback = __callback_wrapper;
- ss->callback_magic = perl_callback;
- sv_2mortal(newSViv(1));
- goto done;
- }
- }
- sv_2mortal(newSViv(0));
- done:
- ;
- }
- int
- snmp_get(sess_ref, retry_nosuch, varlist_ref, perl_callback)
- SV * sess_ref
- int retry_nosuch
- SV * varlist_ref
- SV * perl_callback
- PPCODE:
- {
- AV *varlist;
- SV **varbind_ref;
- AV *varbind;
- I32 varlist_len;
- I32 varlist_ind;
- netsnmp_session *ss;
- netsnmp_pdu *pdu, *response;
- netsnmp_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];
- snmp_xs_cb_data *xs_cb_data;
- SV **sess_ptr_sv;
- SV **err_str_svp;
- SV **err_num_svp;
- SV **err_ind_svp;
- int status;
- u_char str_buf[STR_BUF_SIZE], *str_bufp = str_buf;
- size_t str_buf_len = sizeof(str_buf);
- size_t out_len = 0;
- int buf_over = 0;
- char *label;
- char *iid;
- int getlabel_flag = NO_FLAGS;
- int sprintval_flag = USE_BASIC;
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- int old_format;
- SV *sv_timestamp = NULL;
- int best_guess;
-
- New (0, oid_arr, MAX_OID_LEN, oid);
- if (oid_arr && SvROK(sess_ref) && SvROK(varlist_ref)) {
- sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
- ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
- err_str_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorStr", 8, 1);
- err_num_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorNum", 8, 1);
- err_ind_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorInd", 8, 1);
- sv_setpv(*err_str_svp, "");
- sv_setiv(*err_num_svp, 0);
- sv_setiv(*err_ind_svp, 0);
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseLongNames", 12, 1)))
- getlabel_flag |= USE_LONG_NAMES;
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseNumeric", 10, 1)))
- getlabel_flag |= USE_NUMERIC_OIDS;
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseEnums", 8, 1)))
- sprintval_flag = USE_ENUMS;
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseSprintValue", 14, 1)))
- sprintval_flag = USE_SPRINT_VALUE;
- best_guess = SvIV(*hv_fetch((HV*)SvRV(sess_ref),"BestGuess",9,1));
-
- pdu = snmp_pdu_create(SNMP_MSG_GET);
- varlist = (AV*) SvRV(varlist_ref);
- varlist_len = av_len(varlist);
- for(varlist_ind = 0; varlist_ind <= varlist_len; varlist_ind++) {
- varbind_ref = av_fetch(varlist, varlist_ind, 0);
- if (SvROK(*varbind_ref)) {
- varbind = (AV*) SvRV(*varbind_ref);
- tp = __tag2oid(__av_elem_pv(varbind, VARBIND_TAG_F, ".0"),
- __av_elem_pv(varbind, VARBIND_IID_F, NULL),
- oid_arr, &oid_arr_len, NULL, best_guess);
- if (oid_arr_len) {
- snmp_add_null_var(pdu, oid_arr, oid_arr_len);
- } else {
- if (verbose)
- warn("error: set: unknown object ID");
- sv_catpv(*err_str_svp,
- (char*)snmp_api_errstring(SNMPERR_UNKNOWN_OBJID));
- sv_setiv(*err_num_svp, SNMPERR_UNKNOWN_OBJID);
- XPUSHs(&sv_undef); /* unknown OID */
- snmp_free_pdu(pdu);
- goto done;
- }
- } /* if var_ref is ok */
- } /* for all the vars */
- if (perl_callback && SvTRUE(perl_callback)) {
- xs_cb_data =
- (snmp_xs_cb_data*)malloc(sizeof(snmp_xs_cb_data));
- xs_cb_data->perl_cb = newSVsv(perl_callback);
- xs_cb_data->sess_ref = newSVsv(sess_ref);
- status = snmp_async_send(ss, pdu, __snmp_xs_cb,
- (void*)xs_cb_data);
- if (status != 0) {
- XPUSHs(sv_2mortal(newSViv(status))); /* push the reqid?? */
- } else {
- snmp_free_pdu(pdu);
- sv_catpv(*err_str_svp,
- (char*)snmp_api_errstring(ss->s_snmp_errno));
- sv_setiv(*err_num_svp, ss->s_snmp_errno);
- XPUSHs(&sv_undef);
- }
- goto done;
- }
- status = __send_sync_pdu(ss, pdu, &response,
- retry_nosuch,
- *err_str_svp, *err_num_svp,
- *err_ind_svp);
- /*
- ** Set up for numeric or full OID's, if necessary. Save the old
- ** output format so that it can be restored when we finish -- this
- ** is a library-wide global, and has to be set/restored for each
- ** session.
- */
- old_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT);
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseLongNames", 12, 1))) {
- getlabel_flag |= USE_LONG_NAMES;
- netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
- NETSNMP_OID_OUTPUT_FULL);
- }
- /* Setting UseNumeric forces UseLongNames on so check for UseNumeric
- after UseLongNames (above) to make sure the final outcome of
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT is NETSNMP_OID_OUTPUT_NUMERIC */
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseNumeric", 10, 1))) {
- getlabel_flag |= USE_LONG_NAMES;
- getlabel_flag |= USE_NUMERIC_OIDS;
- netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
- NETSNMP_OID_OUTPUT_NUMERIC);
- }
- if (SvIOK(*hv_fetch((HV*)SvRV(sess_ref),"TimeStamp", 9, 1)) &&
- SvIV(*hv_fetch((HV*)SvRV(sess_ref),"TimeStamp", 9, 1)))
- sv_timestamp = newSViv((IV)time(NULL));
- for(vars = (response?response->variables:NULL), varlist_ind = 0;
- vars && (varlist_ind <= varlist_len);
- vars = vars->next_variable, varlist_ind++) {
- varbind_ref = av_fetch(varlist, varlist_ind, 0);
- if (SvROK(*varbind_ref)) {
- varbind = (AV*) SvRV(*varbind_ref);
- *str_buf = '.';
- *(str_buf+1) = ' ';
- out_len = 0;
- tp = netsnmp_sprint_realloc_objid_tree(&str_bufp, &str_buf_len,
- &out_len, 0, &buf_over,
- vars->name,vars->name_length);
- str_buf[sizeof(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);
- if (label) {
- av_store(varbind, VARBIND_TAG_F,
- newSVpv(label, strlen(label)));
- } else {
- av_store(varbind, VARBIND_TAG_F,
- newSVpv("", 0));
- }
- if (iid) {
- av_store(varbind, VARBIND_IID_F,
- newSVpv(iid, strlen(iid)));
- } else {
- av_store(varbind, VARBIND_IID_F,
- newSVpv("", 0));
- }
- __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=__snprint_value(str_buf,sizeof(str_buf),
- vars,tp,type,sprintval_flag);
- tmp_sv = newSVpv((char*)str_buf, len);
- av_store(varbind, VARBIND_VAL_F, tmp_sv);
- if (sv_timestamp)
- av_store(varbind, VARBIND_TYPE_F, sv_timestamp);
- XPUSHs(sv_mortalcopy(tmp_sv));
- } else {
- /* Return undef for this variable. */
- XPUSHs(&sv_undef);
- }
- }
- /* Reset the library's behavior for numeric/symbolic OID's. */
- netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
- old_format);
- if (response) snmp_free_pdu(response);
- } else {
- XPUSHs(&sv_undef); /* no mem or bad args */
- }
- done:
- Safefree(oid_arr);
- }
- int
- snmp_getnext(sess_ref, varlist_ref, perl_callback)
- SV * sess_ref
- SV * varlist_ref
- SV * perl_callback
- PPCODE:
- {
- AV *varlist;
- SV **varbind_ref;
- AV *varbind;
- I32 varlist_len;
- I32 varlist_ind;
- netsnmp_session *ss;
- netsnmp_pdu *pdu, *response;
- netsnmp_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];
- snmp_xs_cb_data *xs_cb_data;
- SV **sess_ptr_sv;
- SV **err_str_svp;
- SV **err_num_svp;
- SV **err_ind_svp;
- int status;
- u_char str_buf[STR_BUF_SIZE], *str_bufp = str_buf;
- size_t str_buf_len = sizeof(str_buf);
- u_char tmp_buf_prefix[STR_BUF_SIZE];
- u_char str_buf_prefix[STR_BUF_SIZE];
- size_t out_len = 0;
- int buf_over = 0;
- char *label;
- char *iid;
- int getlabel_flag = NO_FLAGS;
- int sprintval_flag = USE_BASIC;
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- int old_format;
- SV *sv_timestamp = NULL;
- int best_guess;
- char *tmp_prefix_ptr;
- char *st;
-
- New (0, oid_arr, MAX_OID_LEN, oid);
- if (oid_arr && SvROK(sess_ref) && SvROK(varlist_ref)) {
- sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
- ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
- err_str_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorStr", 8, 1);
- err_num_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorNum", 8, 1);
- err_ind_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorInd", 8, 1);
- sv_setpv(*err_str_svp, "");
- sv_setiv(*err_num_svp, 0);
- sv_setiv(*err_ind_svp, 0);
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseLongNames", 12, 1)))
- getlabel_flag |= USE_LONG_NAMES;
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseNumeric", 10, 1)))
- getlabel_flag |= USE_NUMERIC_OIDS;
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseEnums", 8, 1)))
- sprintval_flag = USE_ENUMS;
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseSprintValue", 14, 1)))
- sprintval_flag = USE_SPRINT_VALUE;
- best_guess = SvIV(*hv_fetch((HV*)SvRV(sess_ref),"BestGuess",9,1));
-
- pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
- varlist = (AV*) SvRV(varlist_ref);
- varlist_len = av_len(varlist);
- for(varlist_ind = 0; varlist_ind <= varlist_len; varlist_ind++) {
- varbind_ref = av_fetch(varlist, varlist_ind, 0);
- if (SvROK(*varbind_ref)) {
- varbind = (AV*) SvRV(*varbind_ref);
- /* If the varbind includes the module prefix, capture it for use later */
- strncpy(tmp_buf_prefix, __av_elem_pv(varbind, VARBIND_TAG_F, ".0"), STR_BUF_SIZE);
- tmp_prefix_ptr = strstr(tmp_buf_prefix,"::");
- if (tmp_prefix_ptr) {
- tmp_prefix_ptr = strtok_r(tmp_buf_prefix, "::", &st);
- strncpy(str_buf_prefix, tmp_prefix_ptr, STR_BUF_SIZE);
- }
- else {
- *str_buf_prefix = ' ';
- }
- tp = __tag2oid(__av_elem_pv(varbind, VARBIND_TAG_F, ".0"),
- __av_elem_pv(varbind, VARBIND_IID_F, NULL),
- oid_arr, &oid_arr_len, NULL, best_guess);
- if (oid_arr_len) {
- snmp_add_null_var(pdu, oid_arr, oid_arr_len);
- } else {
- if (verbose)
- warn("error: set: unknown object ID");
- sv_catpv(*err_str_svp,
- (char*)snmp_api_errstring(SNMPERR_UNKNOWN_OBJID));
- sv_setiv(*err_num_svp, SNMPERR_UNKNOWN_OBJID);
- XPUSHs(&sv_undef); /* unknown OID */
- snmp_free_pdu(pdu);
- goto done;
- }
- } /* if var_ref is ok */
- } /* for all the vars */
- if (SvTRUE(perl_callback)) {
- xs_cb_data =
- (snmp_xs_cb_data*)malloc(sizeof(snmp_xs_cb_data));
- xs_cb_data->perl_cb = newSVsv(perl_callback);
- xs_cb_data->sess_ref = newSVsv(sess_ref);
- status = snmp_async_send(ss, pdu, __snmp_xs_cb,
- (void*)xs_cb_data);
- if (status != 0) {
- XPUSHs(sv_2mortal(newSViv(status))); /* push the reqid?? */
- } else {
- snmp_free_pdu(pdu);
- sv_catpv(*err_str_svp,
- (char*)snmp_api_errstring(ss->s_snmp_errno));
- sv_setiv(*err_num_svp, ss->s_snmp_errno);
- XPUSHs(&sv_undef);
- }
- goto done;
- }
- status = __send_sync_pdu(ss, pdu, &response,
- NO_RETRY_NOSUCH,
- *err_str_svp, *err_num_svp,
- *err_ind_svp);
- /*
- ** Set up for numeric or full OID's, if necessary. Save the old
- ** output format so that it can be restored when we finish -- this
- ** is a library-wide global, and has to be set/restored for each
- ** session.
- */
- old_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT);
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseLongNames", 12, 1))) {
- getlabel_flag |= USE_LONG_NAMES;
- netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
- NETSNMP_OID_OUTPUT_FULL);
- }
- /* Setting UseNumeric forces UseLongNames on so check
- for UseNumeric after UseLongNames (above) to make
- sure the final outcome of
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT is
- NETSNMP_OID_OUTPUT_NUMERIC */
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseNumeric", 10, 1))) {
- getlabel_flag |= USE_LONG_NAMES;
- getlabel_flag |= USE_NUMERIC_OIDS;
- netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
- NETSNMP_OID_OUTPUT_NUMERIC);
- }
- if (SvIOK(*hv_fetch((HV*)SvRV(sess_ref),"TimeStamp", 9, 1)) &&
- SvIV(*hv_fetch((HV*)SvRV(sess_ref),"TimeStamp", 9, 1)))
- sv_timestamp = newSViv((IV)time(NULL));
- for(vars = (response?response->variables:NULL), varlist_ind = 0;
- vars && (varlist_ind <= varlist_len);
- vars = vars->next_variable, varlist_ind++) {
- varbind_ref = av_fetch(varlist, varlist_ind, 0);
- if (SvROK(*varbind_ref)) {
- varbind = (AV*) SvRV(*varbind_ref);
- *str_buf = '.';
- *(str_buf+1) = ' ';
- out_len = 0;
- tp = netsnmp_sprint_realloc_objid_tree(&str_bufp, &str_buf_len,
- &out_len, 0, &buf_over,
- vars->name,vars->name_length);
- str_buf[sizeof(str_buf)-1] = ' ';
- /* Prepend the module prefix to the next OID if needed */
- if (*str_buf_prefix) {
- strncat(str_buf_prefix, "::", STR_BUF_SIZE - strlen(str_buf_prefix) - 2);
- strncat(str_buf_prefix, str_buf, STR_BUF_SIZE - strlen(str_buf_prefix));
- strncpy(str_buf, str_buf_prefix, STR_BUF_SIZE);
- }
-
- 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);
- if (label) {
- av_store(varbind, VARBIND_TAG_F,
- newSVpv(label, strlen(label)));
- } else {
- av_store(varbind, VARBIND_TAG_F,
- newSVpv("", 0));
- }
- if (iid) {
- av_store(varbind, VARBIND_IID_F,
- newSVpv(iid, strlen(iid)));
- } else {
- av_store(varbind, VARBIND_IID_F,
- newSVpv("", 0));
- }
- __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=__snprint_value(str_buf,sizeof(str_buf),
- vars,tp,type,sprintval_flag);
- tmp_sv = newSVpv((char*)str_buf, len);
- av_store(varbind, VARBIND_VAL_F, tmp_sv);
- if (sv_timestamp)
- av_store(varbind, VARBIND_TYPE_F, sv_timestamp);
- XPUSHs(sv_mortalcopy(tmp_sv));
- } else {
- /* Return undef for this variable. */
- XPUSHs(&sv_undef);
- }
- }
- /* Reset the library's behavior for numeric/symbolic OID's. */
- netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
- old_format);
- if (response) snmp_free_pdu(response);
- } else {
- XPUSHs(&sv_undef); /* no mem or bad args */
- }
- done:
- Safefree(oid_arr);
- }
- int
- snmp_getbulk(sess_ref, nonrepeaters, maxrepetitions, varlist_ref, perl_callback)
- SV * sess_ref
- int nonrepeaters
- int maxrepetitions
- SV * varlist_ref
- SV * perl_callback
- PPCODE:
- {
- AV *varlist;
- SV **varbind_ref;
- AV *varbind;
- I32 varlist_len;
- I32 varlist_ind;
- netsnmp_session *ss;
- netsnmp_pdu *pdu, *response;
- netsnmp_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];
- snmp_xs_cb_data *xs_cb_data;
- SV **sess_ptr_sv;
- SV **err_str_svp;
- SV **err_num_svp;
- SV **err_ind_svp;
- int status;
- u_char str_buf[STR_BUF_SIZE], *str_bufp = str_buf;
- size_t str_buf_len = sizeof(str_buf);
- size_t out_len = 0;
- int buf_over = 0;
- char *label;
- char *iid;
- int getlabel_flag = NO_FLAGS;
- int sprintval_flag = USE_BASIC;
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- int old_format;
- SV *rv;
- SV *sv_timestamp = NULL;
- int best_guess;
- New (0, oid_arr, MAX_OID_LEN, oid);
- if (oid_arr && SvROK(sess_ref) && SvROK(varlist_ref)) {
- sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
- ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
- err_str_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorStr", 8, 1);
- err_num_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorNum", 8, 1);
- err_ind_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorInd", 8, 1);
- sv_setpv(*err_str_svp, "");
- sv_setiv(*err_num_svp, 0);
- sv_setiv(*err_ind_svp, 0);
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseLongNames", 12, 1)))
- getlabel_flag |= USE_LONG_NAMES;
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseNumeric", 10, 1)))
- getlabel_flag |= USE_NUMERIC_OIDS;
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseEnums", 8, 1)))
- sprintval_flag = USE_ENUMS;
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseSprintValue", 14, 1)))
- sprintval_flag = USE_SPRINT_VALUE;
- best_guess = SvIV(*hv_fetch((HV*)SvRV(sess_ref),"BestGuess",9,1));
-
- pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
- pdu->errstat = nonrepeaters;
- pdu->errindex = maxrepetitions;
- varlist = (AV*) SvRV(varlist_ref);
- varlist_len = av_len(varlist);
- for(varlist_ind = 0; varlist_ind <= varlist_len; varlist_ind++) {
- varbind_ref = av_fetch(varlist, varlist_ind, 0);
- if (SvROK(*varbind_ref)) {
- varbind = (AV*) SvRV(*varbind_ref);
- __tag2oid(__av_elem_pv(varbind, VARBIND_TAG_F, "0"),
- __av_elem_pv(varbind, VARBIND_IID_F, NULL),
- oid_arr, &oid_arr_len, NULL, best_guess);
- if (oid_arr_len) {
- snmp_add_null_var(pdu, oid_arr, oid_arr_len);
- } else {
- if (verbose)
- warn("error: set: unknown object ID");
- sv_catpv(*err_str_svp,
- (char*)snmp_api_errstring(SNMPERR_UNKNOWN_OBJID));
- sv_setiv(*err_num_svp, SNMPERR_UNKNOWN_OBJID);
- XPUSHs(&sv_undef); /* unknown OID */
- snmp_free_pdu(pdu);
- goto done;
- }
- } /* if var_ref is ok */
- } /* for all the vars */
- if (SvTRUE(perl_callback)) {
- xs_cb_data =
- (snmp_xs_cb_data*)malloc(sizeof(snmp_xs_cb_data));
- xs_cb_data->perl_cb = newSVsv(perl_callback);
- xs_cb_data->sess_ref = newSVsv(sess_ref);
- status = snmp_async_send(ss, pdu, __snmp_xs_cb,
- (void*)xs_cb_data);
- if (status != 0) {
- XPUSHs(sv_2mortal(newSViv(status))); /* push the reqid?? */
- } else {
- snmp_free_pdu(pdu);
- sv_catpv(*err_str_svp,
- (char*)snmp_api_errstring(ss->s_snmp_errno));
- sv_setiv(*err_num_svp, ss->s_snmp_errno);
- XPUSHs(&sv_undef);
- }
- goto done;
- }
- status = __send_sync_pdu(ss, pdu, &response,
- NO_RETRY_NOSUCH,
- *err_str_svp, *err_num_svp,
- *err_ind_svp);
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"TimeStamp", 9, 1)))
- sv_timestamp = newSViv((IV)time(NULL));
- av_clear(varlist);
- /*
- ** Set up for numeric or full OID's, if necessary. Save the old
- ** output format so that it can be restored when we finish -- this
- ** is a library-wide global, and has to be set/restored for each
- ** session.
- */
- old_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT);
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseLongNames", 12, 1))) {
- getlabel_flag |= USE_LONG_NAMES;
- netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
- NETSNMP_OID_OUTPUT_FULL);
- }
- /* Setting UseNumeric forces UseLongNames on so check for UseNumeric
- after UseLongNames (above) to make sure the final outcome of
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT is NETSNMP_OID_OUTPUT_NUMERIC */
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseNumeric", 10, 1))) {
- getlabel_flag |= USE_LONG_NAMES;
- getlabel_flag |= USE_NUMERIC_OIDS;
- netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
- NETSNMP_OID_OUTPUT_NUMERIC);
- }
-
- if(response && response->variables) {
- for(vars = response->variables;
- vars;
- vars = vars->next_variable) {
- varbind = (AV*) newAV();
- *str_buf = '.';
- *(str_buf+1) = ' ';
- out_len = 0;
- buf_over = 0;
- str_bufp = str_buf;
- tp = netsnmp_sprint_realloc_objid_tree(&str_bufp, &str_buf_len,
- &out_len, 0, &buf_over,
- vars->name,vars->name_length);
- str_buf[sizeof(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);
- if (label) {
- av_store(varbind, VARBIND_TAG_F,
- newSVpv(label, strlen(label)));
- } else {
- av_store(varbind, VARBIND_TAG_F,
- newSVpv("", 0));
- }
- if (iid) {
- av_store(varbind, VARBIND_IID_F,
- newSVpv(iid, strlen(iid)));
- } else {
- av_store(varbind, VARBIND_IID_F,
- newSVpv("", 0));
- }
- __get_type_str(type, tmp_type_str);
- av_store(varbind, VARBIND_TYPE_F, newSVpv(tmp_type_str,
- strlen(tmp_type_str)));
- len=__snprint_value(str_buf,sizeof(str_buf),
- vars,tp,type,sprintval_flag);
- tmp_sv = newSVpv((char*)str_buf, len);
- av_store(varbind, VARBIND_VAL_F, tmp_sv);
- if (sv_timestamp)
- av_store(varbind, VARBIND_TYPE_F, SvREFCNT_inc(sv_timestamp));
- rv = newRV_noinc((SV *)varbind);
- sv_bless(rv, gv_stashpv("SNMP::Varbind",0));
- av_push(varlist, rv);
- XPUSHs(sv_mortalcopy(tmp_sv));
- }
- } else {
- XPUSHs(&sv_undef);
- }
- /* Reset the library's behavior for numeric/symbolic OID's. */
- netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
- old_format);
- if (response) snmp_free_pdu(response);
- } else {
- XPUSHs(&sv_undef); /* no mem or bad args */
- }
- done:
- Safefree(oid_arr);
- }
- int
- snmp_bulkwalk(sess_ref, nonrepeaters, maxrepetitions, varlist_ref,perl_callback)
- SV * sess_ref
- int nonrepeaters
- int maxrepetitions
- SV * varlist_ref
- SV * perl_callback
- PPCODE:
- {
- AV *varlist;
- SV **varbind_ref;
- AV *varbind;
- I32 varlist_len;
- I32 varlist_ind;
- netsnmp_session *ss;
- netsnmp_pdu *pdu = NULL;
- oid oid_arr[MAX_OID_LEN];
- int oid_arr_len;
- SV **sess_ptr_sv;
- SV **err_str_svp;
- SV **err_num_svp;
- SV **err_ind_svp;
- char str_buf[STR_BUF_SIZE];
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- walk_context *context = NULL; /* Context for this bulkwalk */
- bulktbl *bt_entry; /* Current bulktbl/OID entry */
- int i; /* General purpose iterator */
- int npushed; /* Number of return arrays */
- int okay; /* Did bulkwalk complete okay */
- int best_guess;
- if (!SvROK(sess_ref) || !SvROK(varlist_ref)) {
- if (verbose)
- warn("Bad session or varlist reference!n");
- XSRETURN_UNDEF;
- }
- sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
- ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
- err_str_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorStr", 8, 1);
- err_num_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorNum", 8, 1);
- err_ind_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorInd", 8, 1);
- sv_setpv(*err_str_svp, "");
- sv_setiv(*err_num_svp, 0);
- sv_setiv(*err_ind_svp, 0);
- best_guess = SvIV(*hv_fetch((HV*)SvRV(sess_ref),"BestGuess",9,1));
-
- /* Create and initialize a new session context for this bulkwalk.
- ** This will be used to carry state between callbacks.
- */
- Newz(0x57616b6c /* "Walk" */, context, 1, walk_context);
- if (context == NULL) {
- sprintf(str_buf, "malloc(context) failed (%s)", strerror(errno));
- sv_setpv(*err_str_svp, str_buf);
- sv_setiv(*err_num_svp, SNMPERR_MALLOC);
- goto err;
- }
- /* Store the Perl callback and session reference in the context. */
- context->perl_cb = newSVsv(perl_callback);
- context->sess_ref = newSVsv(sess_ref);
- DBPRT(3,(DBOUT "bulkwalk: sess_ref = 0x%p, sess_ptr_sv = 0x%p, ss = 0x%pn",
- sess_ref, sess_ptr_sv, ss));
- context->getlabel_f = NO_FLAGS; /* long/numeric name flags */
- context->sprintval_f = USE_BASIC; /* Don't do fancy printing */
- context->req_oids = NULL; /* List of oid's requested */
- context->repbase = NULL; /* Repeaters in req_oids[] */
- context->reqbase = NULL; /* Ptr to start of requests */
- context->nreq_oids = 0; /* Number of oid's in list */
- context->repeaters = 0; /* Repeater count (see below) */
- context->non_reps = nonrepeaters; /* Non-repeater var count */
- context->max_reps = maxrepetitions; /* Max repetition/var count */
- context->pkts_exch = 0; /* Packets exchanged in walk */
- context->oid_total = 0; /* OID's received during walk */
- context->oid_saved = 0; /* OID's saved as results */
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseLongNames", 12, 1)))
- context->getlabel_f |= USE_LONG_NAMES;
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseNumeric", 10, 1)))
- context->getlabel_f |= USE_NUMERIC_OIDS;
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseEnums", 8, 1)))
- context->sprintval_f = USE_ENUMS;
- if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseSprintValue", 14, 1)))
- context->sprintval_f = USE_SPRINT_VALUE;
- /* Set up an array of bulktbl's to hold the original list of
- ** requested OID's. This is used to populate the PDU's with
- ** oid values, to contain/sort the return values, and (through
- ** last_oid/last_len) to determine when the bulkwalk for each
- ** variable has completed.
- */
- varlist = (AV*) SvRV(varlist_ref);
- varlist_len = av_len(varlist) + 1; /* XXX av_len returns index of
- ** last element not #elements */
- Newz(0, context->req_oids, varlist_len, bulktbl);
- if (context->req_oids == NULL) {
- sprintf(str_buf, "Newz(req_oids) failed (%s)", strerror(errno));
- if (verbose)
- warn(str_buf);
- sv_setpv(*err_str_svp, str_buf);
- sv_setiv(*err_num_svp, SNMPERR_MALLOC);
- goto err;
- }
- /* Walk through the varbind_list, parsing and copying each OID
- ** into a bulktbl slot in the req_oids array. Bail if there's
- ** some error. Create the initial packet to send out, which
- ** includes the non-repeaters.
- */
- DBPRT(1,(DBOUT "Building request table:n"));
- for (varlist_ind = 0; varlist_ind < varlist_len; varlist_ind++) {
- /* Get a handle on this entry in the request table. */
- bt_entry = &context->req_oids[context->nreq_oids];
- DBPRT(1,(DBOUT " request %d: ", (int)varlist_ind));
- /* Get the request varbind from the varlist, parse it out to
- ** tag and index, and copy it to the req_oid[] array slots.
- */
- varbind_ref = av_fetch(varlist, varlist_ind, 0);
- if (!SvROK(*varbind_ref)) {
- sv_setpv(*err_str_svp,
- (char*)snmp_api_errstring(SNMPERR_BAD_NAME));
- sv_setiv(*err_num_svp, SNMPERR_BAD_NAME);
- goto err;
- }
- varbind = (AV*) SvRV(*varbind_ref);
- __tag2oid(__av_elem_pv(varbind, VARBIND_TAG_F, "0"),
- __av_elem_pv(varbind, VARBIND_IID_F, NULL),
- oid_arr, &oid_arr_len, NULL, best_guess);
- if ((oid_arr_len == 0) || (oid_arr_len > MAX_OID_LEN)) {
- if (verbose)
- warn("error: bulkwalk(): unknown object ID");
- sv_setpv(*err_str_svp,
- (char*)snmp_api_errstring(SNMPERR_UNKNOWN_OBJID));
- sv_setiv(*err_num_svp, SNMPERR_UNKNOWN_OBJID);
- goto err;
- }
- /* Copy the now-parsed OID into the first available slot
- ** in the req_oids[] array. Set both the req_oid (original
- ** request) and the last_oid (last requested/seen oid) to
- ** the initial value. We build packets using last_oid (see
- ** below), so initialize last_oid to the initial request.
- */
- Copy((void *)oid_arr, (void *)bt_entry->req_oid,
- oid_arr_len, oid);
- Copy((void *)oid_arr, (void *)bt_entry->last_oid,
- oid_arr_len, oid);
- bt_entry->req_len = oid_arr_len;
- bt_entry->last_len = oid_arr_len;
- /* Adjust offset to and count of repeaters. Note non-repeater
- ** OID's in the list, if appropriate.
- */
- if (varlist_ind >= context->non_reps) {
- /* Store a pointer to the first repeater value. */
- if (context->repbase == NULL)
- context->repbase = bt_entry;
- context->repeaters ++;
- } else {
- bt_entry->norepeat = 1;
- DBPRT(1,(DBOUT "(nonrepeater) "));
- }
- /* Initialize the array in which to hold the Varbinds to be
- ** returned for the OID or subtree.
- */
- if ((bt_entry->vars = (AV*) newAV()) == NULL) {
- sv_setpv(*err_str_svp, "newAV() failed: ");
- sv_catpv(*err_str_svp, strerror(errno));
- sv_setiv(*err_num_svp, SNMPERR_MALLOC);
- goto err;
- }
- DBPRT(1,(DBOUT "%sn", snprint_objid(_debugx, sizeof(_debugx), oid_arr, oid_arr_len)));
- context->nreq_oids ++;
- }
- /* Keep track of the number of outstanding requests. This lets us
- ** finish processing early if we're done with all requests.
- */
- context->req_remain = context->nreq_oids;
- DBPRT(1,(DBOUT "Total %d variable requests addedn", context->nreq_oids));
- /* If no good variable requests were found, return an error. */
- if (context->nreq_oids == 0) {
- sv_setpv(*err_str_svp, "No variables found in varlist");
- sv_setiv(*err_num_svp, SNMPERR_NO_VARS);
- goto err;
- }
- /* Note that this is a good context. This allows later callbacks
- ** to ignore re-sent PDU's that correspond to completed (and hence
- ** destroyed) bulkwalk contexts.
- */
- _context_add(context);
- /* For asynchronous bulkwalk requests, all we have to do at this
- ** point is enqueue the asynchronous GETBULK request with our
- ** bulkwalk-specific callback and return. Remember that the
- ** bulkwalk_send_pdu() function returns the reqid cast to an
- ** snmp_pdu pointer, or NULL on failure. Return undef if the
- ** initial send fails; bulkwalk_send_pdu() takes care of setting
- ** the various error values.
- **
- ** From here, the callbacks do all the work, including sending
- ** requests for variables and handling responses. The caller's
- ** callback will be invoked as soon as the walk completes.
- */
- if (SvTRUE(perl_callback)) {
- DBPRT(1,(DBOUT "Starting asynchronous bulkwalk...n"));
- pdu = _bulkwalk_send_pdu(context);
- if (pdu == NULL) {
- DBPRT(1,(DBOUT "Initial asynchronous send failed...n"));
- XSRETURN_UNDEF;
- }
- /* Sent okay... Return the request ID in 'pdu' as an SvIV. */
- DBPRT(1,(DBOUT "Okay, request id is %dn", (int)pdu));
- /* XSRETURN_IV((int)pdu); */
- XPUSHs(sv_2mortal(newSViv((int)pdu)));
- XSRETURN(1);
- }
- /* For synchronous bulkwalk, we perform the basic send/receive
- ** iteration right here. Once the walk has been completed, the
- ** bulkwalk_finish() function will push the return values onto
- ** the Perl call stack, and we return.
- */
- DBPRT(1,(DBOUT "Starting synchronous bulkwalk...n"));
- while (!(okay = _bulkwalk_done(context))) {
- /* Send a request for the next batch of variables. */
- DBPRT(1, (DBOUT "Building %s GETBULK bulkwalk PDU (%d)...n",
- context->pkts_exch ? "next" : "first",
- context->pkts_exch));
- pdu = _bulkwalk_send_pdu(context);
- /* If the request failed, consider the walk done. */
- if (pdu == NULL) {
- DBPRT(1,(DBOUT "bulkwalk_send_pdu() failed!n"));
- break;
- }
- /* Handle the variables in this response packet. Break out
- ** of the loop if an error occurs or no variables are found
- ** in the response.
- */
- if ((i = _bulkwalk_recv_pdu(context, pdu)) <= 0) {
- DBPRT(2,(DBOUT "bulkwalk_recv_pdu() returned %d (error/empty)n", i));
- break;
- }
- /* Free the returned pdu. Don't bother to do this for the async
- ** case, since the SNMP callback mechanism itself does the free
- ** for us.
- */
- snmp_free_pdu(pdu);
- /* And loop. The call to bulkwalk_done() sets the ignore flags
- ** for any completed request subtrees. Next time around, they
- ** won't be added to the request sent to the agent.
- */
- continue;
- }
- DBPRT(1, (DBOUT "Bulkwalk done... calling bulkwalk_finish(%s)...n",
- okay ? "okay" : "error"));
- npushed = _bulkwalk_finish(context, okay);
- DBPRT(2,(DBOUT "Returning %d values on the stack.n", npushed));
- XSRETURN(npushed);
- /* Handle error cases and clean up after ourselves. */
- err:
- if (context->req_oids && context->nreq_oids) {
- bt_entry = context->req_oids;
- for (i = 0; i < context->nreq_oids; i++, bt_entry++)
- av_clear(bt_entry->vars);
- }
- if (context->req_oids)
- Safefree(context->req_oids);
- if (context)
- Safefree(context);
- if (pdu)
- snmp_free_pdu(pdu);
- XSRETURN_UNDEF;
- }
- int
- snmp_trapV1(sess_ref,enterprise,agent,generic,specific,uptime,varlist_ref)
- SV * sess_ref
- char * enterprise
- char * agent
- int generic
- int specific
- long uptime
- SV * varlist_ref
- PPCODE:
- {
- AV *varlist;
- SV **varbind_ref;
- SV **varbind_val_f;
- AV *varbind;
- I32 varlist_len;
- I32 varlist_ind;
- SnmpSession *ss;
- netsnmp_pdu *pdu = NULL;
- struct tree *tp;
- oid *oid_arr;
- int oid_arr_len = MAX_OID_LEN;
- SV **sess_ptr_sv;
- SV **err_str_svp;
- SV **err_num_svp;
- SV **err_ind_svp;
- int type;
- int res;
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- int use_enums = SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseEnums",8,1));
- struct enum_list *ep;
- int best_guess;
-
- New (0, oid_arr, MAX_OID_LEN, oid);
- if (oid_arr && SvROK(sess_ref)) {
- sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
- ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
- err_str_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorStr", 8, 1);
- err_num_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorNum", 8, 1);
- err_ind_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorInd", 8, 1);
- sv_setpv(*err_str_svp, "");
- sv_setiv(*err_num_svp, 0);
- sv_setiv(*err_ind_svp, 0);
- best_guess = SvIV(*hv_fetch((HV*)SvRV(sess_ref),"BestGuess",9,1));
-
- pdu = snmp_pdu_create(SNMP_MSG_TRAP);
- if (SvROK(varlist_ref)) {
- varlist = (AV*) SvRV(varlist_ref);
- varlist_len = av_len(varlist);
- for(varlist_ind = 0; varlist_ind <= varlist_len; varlist_ind++) {
- varbind_ref = av_fetch(varlist, varlist_ind, 0);
- if (SvROK(*varbind_ref)) {
- varbind = (AV*) SvRV(*varbind_ref);
- tp=__tag2oid(__av_elem_pv(varbind, VARBIND_TAG_F, NULL),
- __av_elem_pv(varbind, VARBIND_IID_F, NULL),
- oid_arr, &oid_arr_len, &type, best_guess);
- if (oid_arr_len == 0) {
- if (verbose)
- warn("error:trap: unable to determine oid for object");
- goto err;
- }
- if (type == TYPE_UNKNOWN) {
- type = __translate_appl_type(
- __av_elem_pv(varbind, VARBIND_TYPE_F, NULL));
- if (type == TYPE_UNKNOWN) {
- if (verbose)
- warn("error:trap: no type found for object");
- goto err;
- }
- }
- varbind_val_f = av_fetch(varbind, VARBIND_VAL_F, 0);
- if (type==TYPE_INTEGER && use_enums && tp && tp->enums) {
- for(ep = tp->enums; ep; ep = ep->next) {
- if (varbind_val_f && SvOK(*varbind_val_f) &&
- !strcmp(ep->label, SvPV(*varbind_val_f,na))) {
- sv_setiv(*varbind_val_f, ep->value);
- break;
- }
- }
- }
- res = __add_var_val_str(pdu, oid_arr, oid_arr_len,
- (varbind_val_f && SvOK(*varbind_val_f) ?
- SvPV(*varbind_val_f,na):NULL),
- (varbind_val_f && SvOK(*varbind_val_f) ?
- SvCUR(*varbind_val_f):0),
- type);
- if(res == FAILURE) {
- if(verbose) warn("error:trap: adding varbind");
- goto err;
- }
- } /* if var_ref is ok */
- } /* for all the vars */
- }
- pdu->enterprise = (oid *)malloc( MAX_OID_LEN * sizeof(oid));
- tp = __tag2oid(enterprise,NULL, pdu->enterprise,
- &pdu->enterprise_length, NULL, best_guess);
- if (pdu->enterprise_length == 0) {
- if (verbose) warn("error:trap:invalid enterprise id: %s", enterprise);
- goto err;
- }
- /* If agent is given then set the v1-TRAP specific
- agent-address field to that. Otherwise set it to
- our address. */
- if (agent && strlen(agent)) {
- if (__parse_address(agent) == -1 && verbose) {
- warn("error:trap:invalid agent address: %s", agent);
- goto err;
- } else {
- *((in_addr_t *)pdu->agent_addr) = __parse_address(agent);
- }
- } else {
- *((in_addr_t *)pdu->agent_addr) = get_myaddr();
- }
- pdu->trap_type = generic;
- pdu->specific_type = specific;
- pdu->time = uptime;
- if (snmp_send(ss, pdu) == 0) {
- snmp_free_pdu(pdu);
- }
- XPUSHs(sv_2mortal(newSVpv(ZERO_BUT_TRUE,0)));
- } else {
- err:
- XPUSHs(&sv_undef); /* no mem or bad args */
- if (pdu) snmp_free_pdu(pdu);
- }
- Safefree(oid_arr);
- }
- int
- snmp_trapV2(sess_ref,uptime,trap_oid,varlist_ref)
- SV * sess_ref
- char * uptime
- char * trap_oid
- SV * varlist_ref
- PPCODE:
- {
- AV *varlist;
- SV **varbind_ref;
- SV **varbind_val_f;
- AV *varbind;
- I32 varlist_len;
- I32 varlist_ind;
- SnmpSession *ss;
- netsnmp_pdu *pdu = NULL;
- struct tree *tp;
- oid *oid_arr;
- int oid_arr_len = MAX_OID_LEN;
- SV **sess_ptr_sv;
- SV **err_str_svp;
- SV **err_num_svp;
- SV **err_ind_svp;
- int type;
- int res;
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- int use_enums = SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseEnums",8,1));
- struct enum_list *ep;
- int best_guess;
-
- New (0, oid_arr, MAX_OID_LEN, oid);
- if (oid_arr && SvROK(sess_ref) && SvROK(varlist_ref)) {
- sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
- ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
- err_str_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorStr", 8, 1);
- err_num_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorNum", 8, 1);
- err_ind_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorInd", 8, 1);
- sv_setpv(*err_str_svp, "");
- sv_setiv(*err_num_svp, 0);
- sv_setiv(*err_ind_svp, 0);
- best_guess = SvIV(*hv_fetch((HV*)SvRV(sess_ref),"BestGuess",9,1));
-
- pdu = snmp_pdu_create(SNMP_MSG_TRAP2);
- varlist = (AV*) SvRV(varlist_ref);
- varlist_len = av_len(varlist);
- /************************************************/
- res = __add_var_val_str(pdu, sysUpTime, SYS_UPTIME_OID_LEN,
- uptime, strlen(uptime), TYPE_TIMETICKS);
- if(res == FAILURE) {
- if(verbose) warn("error:trap v2: adding sysUpTime varbind");
- goto err;
- }
- res = __add_var_val_str(pdu, snmpTrapOID, SNMP_TRAP_OID_LEN,
- trap_oid ,strlen(trap_oid) ,TYPE_OBJID);
- if(res == FAILURE) {
- if(verbose) warn("error:trap v2: adding snmpTrapOID varbind");
- goto err;
- }
- /******************************************************/
- for(varlist_ind = 0; varlist_ind <= varlist_len; varlist_ind++) {
- varbind_ref = av_fetch(varlist, varlist_ind, 0);
- if (SvROK(*varbind_ref)) {
- varbind = (AV*) SvRV(*varbind_ref);
- tp=__tag2oid(__av_elem_pv(varbind, VARBIND_TAG_F,NULL),
- __av_elem_pv(varbind, VARBIND_IID_F,NULL),
- oid_arr, &oid_arr_len, &type, best_guess);
- if (oid_arr_len == 0) {
- if (verbose)
- warn("error:trap v2: unable to determine oid for object");
- goto err;
- }
- if (type == TYPE_UNKNOWN) {
- type = __translate_appl_type(
- __av_elem_pv(varbind, VARBIND_TYPE_F, NULL));
- if (type == TYPE_UNKNOWN) {
- if (verbose)
- warn("error:trap v2: no type found for object");
- goto err;
- }
- }
- varbind_val_f = av_fetch(varbind, VARBIND_VAL_F, 0);
- if (type==TYPE_INTEGER && use_enums && tp && tp->enums) {
- for(ep = tp->enums; ep; ep = ep->next) {
- if (varbind_val_f && SvOK(*varbind_val_f) &&
- !strcmp(ep->label, SvPV(*varbind_val_f,na))) {
- sv_setiv(*varbind_val_f, ep->value);
- break;
- }
- }
- }
- res = __add_var_val_str(pdu, oid_arr, oid_arr_len,
- (varbind_val_f && SvOK(*varbind_val_f) ?
- SvPV(*varbind_val_f,na):NULL),
- (varbind_val_f && SvOK(*varbind_val_f) ?
- SvCUR(*varbind_val_f):0),
- type);
- if(res == FAILURE) {
- if(verbose) warn("error:trap v2: adding varbind");
- goto err;
- }
- } /* if var_ref is ok */
- } /* for all the vars */
- if (snmp_send(ss, pdu) == 0) {
- snmp_free_pdu(pdu);
- }
- XPUSHs(sv_2mortal(newSVpv(ZERO_BUT_TRUE,0)));
- } else {
- err:
- XPUSHs(&sv_undef); /* no mem or bad args */
- if (pdu) snmp_free_pdu(pdu);
- }
- Safefree(oid_arr);
- }
- int
- snmp_inform(sess_ref,uptime,trap_oid,varlist_ref,perl_callback)
- SV * sess_ref
- char * uptime
- char * trap_oid
- SV * varlist_ref
- SV * perl_callback
- PPCODE:
- {
- AV *varlist;
- SV **varbind_ref;
- SV **varbind_val_f;
- AV *varbind;
- I32 varlist_len;
- I32 varlist_ind;
- SnmpSession *ss;
- netsnmp_pdu *pdu = NULL;
- netsnmp_pdu *response;
- struct tree *tp;
- oid *oid_arr;
- int oid_arr_len = MAX_OID_LEN;
- snmp_xs_cb_data *xs_cb_data;
- SV **sess_ptr_sv;
- SV **err_str_svp;
- SV **err_num_svp;
- SV **err_ind_svp;
- int status = 0;
- int type;
- int res;
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- int use_enums = SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseEnums",8,1));
- struct enum_list *ep;
- int best_guess;
-
- New (0, oid_arr, MAX_OID_LEN, oid);
- if (oid_arr && SvROK(sess_ref) && SvROK(varlist_ref)) {
- sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
- ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
- err_str_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorStr", 8, 1);
- err_num_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorNum", 8, 1);
- err_ind_svp = hv_fetch((HV*)SvRV(sess_ref), "ErrorInd", 8, 1);
- sv_setpv(*err_str_svp, "");
- sv_setiv(*err_num_svp, 0);
- sv_setiv(*err_ind_svp, 0);
- best_guess = SvIV(*hv_fetch((HV*)SvRV(sess_ref),"BestGuess",9,1));
-
- pdu = snmp_pdu_create(SNMP_MSG_INFORM);
- varlist = (AV*) SvRV(varlist_ref);
- varlist_len = av_len(varlist);
- /************************************************/
- res = __add_var_val_str(pdu, sysUpTime, SYS_UPTIME_OID_LEN,
- uptime, strlen(uptime), TYPE_TIMETICKS);
- if(res == FAILURE) {
- if(verbose) warn("error:inform: adding sysUpTime varbind");
- goto err;
- }
- res = __add_var_val_str(pdu, snmpTrapOID, SNMP_TRAP_OID_LEN,
- trap_oid ,strlen(trap_oid) ,TYPE_OBJID);
- if(res == FAILURE) {
- if(verbose) warn("error:inform: adding snmpTrapOID varbind");
- goto err;
- }
- /******************************************************/
- for(varlist_ind = 0; varlist_ind <= varlist_len; varlist_ind++) {
- varbind_ref = av_fetch(varlist, varlist_ind, 0);
- if (SvROK(*varbind_ref)) {
- varbind = (AV*) SvRV(*varbind_ref);
- tp=__tag2oid(__av_elem_pv(varbind, VARBIND_TAG_F,NULL),
- __av_elem_pv(varbind, VARBIND_IID_F,NULL),
- oid_arr, &oid_arr_len, &type, best_guess);
- if (oid_arr_len == 0) {
- if (verbose)
- warn("error:inform: unable to determine oid for object");
- goto err;
- }
- if (type == TYPE_UNKNOWN) {
- type = __translate_appl_type(
- __av_elem_pv(varbind, VARBIND_TYPE_F, NULL));
- if (type == TYPE_UNKNOWN) {
- if (verbose)
- warn("error:inform: no type found for object");
- goto err;
- }
- }
- varbind_val_f = av_fetch(varbind, VARBIND_VAL_F, 0);
- if (type==TYPE_INTEGER && use_enums && tp && tp->enums) {
- for(ep = tp->enums; ep; ep = ep->next) {
- if (varbind_val_f && SvOK(*varbind_val_f) &&
- !strcmp(ep->label, SvPV(*varbind_val_f,na))) {
- sv_setiv(*varbind_val_f, ep->value);
- break;
- }
- }
- }
- res = __add_var_val_str(pdu, oid_arr, oid_arr_len,
- (varbind_val_f && SvOK(*varbind_val_f) ?
- SvPV(*varbind_val_f,na):NULL),
- (varbind_val_f && SvOK(*varbind_val_f) ?
- SvCUR(*varbind_val_f):0),
- type);
- if(res == FAILURE) {
- if(verbose) warn("error:inform: adding varbind");
- goto err;
- }
- } /* if var_ref is ok */
- } /* for all the vars */
- if (SvTRUE(perl_callback)) {
- xs_cb_data =
- (snmp_xs_cb_data*)malloc(sizeof(snmp_xs_cb_data));
- xs_cb_data->perl_cb = newSVsv(perl_callback);
- xs_cb_data->sess_ref = newRV_inc(SvRV(sess_ref));
- status = snmp_async_send(ss, pdu, __snmp_xs_cb,
- (void*)xs_cb_data);
- if (status != 0) {
- XPUSHs(sv_2mortal(newSViv(status))); /* push the reqid?? */
- } else {
- snmp_free_pdu(pdu);
- sv_catpv(*err_str_svp,
- (char*)snmp_api_errstring(ss->s_snmp_errno));
- sv_setiv(*err_num_svp, ss->s_snmp_errno);
- XPUSHs(&sv_undef);
- }
- goto done;
- }
- status = __send_sync_pdu(ss, pdu, &response,
- NO_RETRY_NOSUCH,
- *err_str_svp, *err_num_svp,
- *err_ind_svp);
- if (response) snmp_free_pdu(response);
- if (status) {
- XPUSHs(&sv_undef);
- } else {
- XPUSHs(sv_2mortal(newSVpv(ZERO_BUT_TRUE,0)));
- }
- } else {
- err:
- XPUSHs(&sv_undef); /* no mem or bad args */
- if (pdu) snmp_free_pdu(pdu);
- }
- done:
- Safefree(oid_arr);
- }
- char *
- snmp_get_type(tag, best_guess)
- char * tag
- int best_guess
- CODE:
- {
- struct tree *tp = NULL;
- static char type_str[MAX_TYPE_NAME_LEN];
- char *ret = NULL;
- if (tag && *tag) tp = __tag2oid(tag, NULL, NULL, NULL, NULL, best_guess);
- if (tp) __get_type_str(tp->type, ret = type_str);
- RETVAL = ret;
- }
- OUTPUT:
- RETVAL
- void
- snmp_dump_packet(flag)
- int flag
- CODE:
- {
- snmp_set_dump_packet(flag);
- }
- char *
- snmp_map_enum(tag, val, iflag, best_guess)
- char * tag
- char * val
- int iflag
- int best_guess
- CODE:
- {
- struct tree *tp = NULL;
- struct enum_list *ep;
- char str_buf[STR_BUF_SIZE];
- int ival;
- RETVAL = NULL;
- if (tag && *tag) tp = __tag2oid(tag, NULL, NULL, NULL, NULL, best_guess);
- if (tp) {
- if (iflag) {
- ival = atoi(val);
- for(ep = tp->enums; ep; ep = ep->next) {
- if (ep->value == ival) {
- RETVAL = ep->label;
- break;
- }
- }
- } else {
- for(ep = tp->enums; ep; ep = ep->next) {
- if (strEQ(ep->label, val)) {
- sprintf(str_buf,"%d", ep->value);
- RETVAL = str_buf;
- break;
- }
- }
- }
- }
- }
- OUTPUT:
- RETVAL
- #define SNMP_XLATE_MODE_OID2TAG 1
- #define SNMP_XLATE_MODE_TAG2OID 0
- char *
- snmp_translate_obj(var,mode,use_long,auto_init,best_guess,include_module_name)
- char * var
- int mode
- int use_long
- int auto_init
- int best_guess
- int include_module_name
- CODE:
- {
- char str_buf[STR_BUF_SIZE];
- char str_buf_temp[STR_BUF_SIZE];
- oid oid_arr[MAX_OID_LEN];
- int oid_arr_len = MAX_OID_LEN;
- char * label;
- char * iid;
- int status = FAILURE;
- int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
- struct tree *module_tree = NULL;
- char modbuf[256];
- int old_format; /* Current NETSNMP_DS_LIB_OID_OUTPUT_FORMAT */
- str_buf[0] = ' ';
- str_buf_temp[0] = ' ';
- /* Save old output format and set to FULL so long_names works */
- old_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT);
- netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_FULL);
- switch (mode) {
- case SNMP_XLATE_MODE_TAG2OID:
- if (!__tag2oid(var, NULL, oid_arr, &oid_arr_len, NULL, best_guess)) {
- if (verbose) warn("error:snmp_translate_obj:Unknown OID %sn",var);
- } else {
- status = __sprint_num_objid(str_buf, oid_arr, oid_arr_len);
- }
- break;
- case SNMP_XLATE_MODE_OID2TAG:
- oid_arr_len = 0;
- __concat_oid_str(oid_arr, &oid_arr_len, var);
- snprint_objid(str_buf_temp, sizeof(str_buf_temp), oid_arr, oid_arr_len);
- if (!use_long) {
- label = NULL; iid = NULL;
- if (((status=__get_label_iid(str_buf_temp,
- &label, &iid, NO_FLAGS)) == SUCCESS)
- && label) {
- strcpy(str_buf_temp, label);
- if (iid && *iid) {
- strcat(str_buf_temp, ".");
- strcat(str_buf_temp, iid);
- }
- }
- }
-
- /* Prepend modulename:: if enabled */
- if (include_module_name) {
- module_tree = get_tree (oid_arr, oid_arr_len, get_tree_head());
- if (module_tree) {
- if (strcmp(module_name(module_tree->modid, modbuf), "#-1") ) {
- strcat(str_buf, modbuf);
- strcat(str_buf, "::");
- }
- else {
- strcat(str_buf, "UNKNOWN::");
- }
- }
- }
- strcat(str_buf, str_buf_temp);
- break;
- default:
- if (verbose) warn("snmp_translate_obj:unknown translation mode: %sn", mode);
- }
- if (*str_buf) {
- RETVAL = (char*)str_buf;
- } else {
- RETVAL = (char*)NULL;
- }
- netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, old_format);
- }
- OUTPUT:
- RETVAL
- void
- snmp_set_replace_newer(val)
- int val
- CODE:
- {
- netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
- NETSNMP_DS_LIB_MIB_REPLACE, val);
- }
- void
- snmp_set_save_descriptions(val)
- int val
- CODE:
- {
- snmp_set_save_descriptions(val);
- }
- void
- snmp_set_debugging(val)
- int val
- CODE:
- {
- snmp_set_do_debugging(val);
- }
- void
- snmp_debug_internals(val)
- int val
- CODE:
- {
- #ifdef DEBUGGING
- _debug_level = val;
- #endif /* DEBUGGING */
- }
- void
- snmp_mib_toggle_options(options)
- char *options
- CODE:
- {
- snmp_mib_toggle_options(options);
- }
- void
- snmp_sock_cleanup()
- CODE:
- {
- SOCK_CLEANUP;
- }
- void
- snmp_mainloop_finish()
- CODE:
- {
- mainloop_finish = 1;
- }
- void
- snmp_main_loop(timeout_sec,timeout_usec,perl_callback)
- int timeout_sec
- int timeout_usec
- SV * perl_callback
- CODE:
- {
- int numfds, fd_count;
- fd_set fdset;
- struct timeval time_val, *tvp;
- struct timeval last_time, *ltvp;
- struct timeval ctimeout, *ctvp;
- struct timeval interval, *itvp;
- int block;
- SV *cb;
- mainloop_finish = 0;
- itvp = &interval;
- itvp->tv_sec = timeout_sec;
- itvp->tv_usec = timeout_usec;
- ctvp = &ctimeout;
- ctvp->tv_sec = -1;
- ltvp = &last_time;
- gettimeofday(ltvp,(struct timezone*)0);
- timersub(ltvp,itvp,ltvp);
- while (1) {
- numfds = 0;
- FD_ZERO(&fdset);
- block = 1;
- tvp = &time_val;
- timerclear(tvp);
- snmp_select_info(&numfds, &fdset, tvp, &block);
- __recalc_timeout(tvp,ctvp,ltvp,itvp,&block);
- # printf("pre-select: numfds = %ld, block = %ldn", numfds, block);
- if (block == 1) tvp = NULL; /* block without timeout */
- fd_count = select(numfds, &fdset, 0, 0, tvp);
- #printf("post-select: fd_count = %ld,block = %ldn",fd_count,block);
- if (fd_count > 0) {
- dSP;
- ENTER;
- SAVETMPS;
- snmp_read(&fdset);
- FREETMPS;
- LEAVE;
- } else switch(fd_count) {
- case 0:
- SPAGAIN;
- ENTER;
- SAVETMPS;
- snmp_timeout();
- if (!timerisset(ctvp)) {
- if (SvTRUE(perl_callback)) {
- /* sv_2mortal(perl_callback); */
- cb = __push_cb_args(perl_callback, NULL);
- __call_callback(cb, G_DISCARD);
- ctvp->tv_sec = -1;
- } else {
- FREETMPS;
- LEAVE;
- goto done;
- }
- }
- FREETMPS;
- LEAVE;
- break;
- case -1:
- if (errno == EINTR) {
- continue;
- } else {
- /* snmp_set_detail(strerror(errno)); */
- /* snmp_errno = SNMPERR_GENERR; */
- }
- default:;
- }
- /* A call to snmp_mainloop_finish() in the callback sets the
- ** mainloop_finish flag. Exit the loop after the callback returns.
- */
- if (mainloop_finish)
- goto done;
- }
- done:
- return;
- }
- void
- snmp_get_select_info()
- PPCODE:
- {
- int numfds;
- fd_set fdset;
- struct timeval time_val, *tvp;
- int block;
- int i;
- numfds = 0;
- block = 1;
- tvp = &time_val;
- FD_ZERO(&fdset);
- snmp_select_info(&numfds, &fdset, tvp, &block);
- XPUSHs(sv_2mortal(newSViv(block)));
- if(block){
- XPUSHs(sv_2mortal(newSViv(0)));
- XPUSHs(sv_2mortal(newSViv(0)));
- } else {
- XPUSHs(sv_2mortal(newSViv(tvp->tv_sec)));
- XPUSHs(sv_2mortal(newSViv(tvp->tv_usec)));
- }
- if ( numfds ) {
- for(i=0; i<numfds ; i++) {
- if(FD_ISSET(i, &fdset)){
- XPUSHs(sv_2mortal(newSViv(i)));
- }
- }
- } else {
- XPUSHs(&sv_undef); /* no mem or bad args */
- }
- }
- void
- snmp_read_on_fd(fd)
- int fd
- CODE:
- {
- fd_set fdset;
- FD_ZERO(&fdset);
- FD_SET(fd, &fdset);
- snmp_read(&fdset);
- }
- void
- snmp_check_timeout()
- CODE:
- {
- snmp_timeout();
- }
- MODULE = SNMP PACKAGE = SNMP::MIB::NODE PREFIX = snmp_mib_node_
- SV *
- snmp_mib_node_TIEHASH(cl,key,tp=0)
- char * cl
- char * key
- IV tp
- CODE:
- {
- __libraries_init("perl");
- if (!tp) tp = (IV)__tag2oid(key, NULL, NULL, NULL, NULL,0);
- if (tp) {
- ST(0) = sv_newmortal();
- sv_setref_iv(ST(0), cl, tp);
- } else {
- ST(0) = &sv_undef;
- }
- }
- SV *
- snmp_mib_node_FETCH(tp_ref, key)
- SV * tp_ref
- char * key
- CODE:
- {
- char c = *key;
- char str_buf[STR_BUF_SIZE];
- SnmpMibNode *tp = NULL, *tptmp = NULL;
- struct index_list *ip;
- struct enum_list *ep;
- struct range_list *rp;
- struct varbind_list *vp;
- struct module *mp;
- SV *child_list_aref, *next_node_href, *mib_tied_href = NULL;
- SV **nn_hrefp;
- HV *mib_hv, *enum_hv, *range_hv;
- AV *index_av, *varbind_av, *ranges_av;
- MAGIC *mg = NULL;
- if (SvROK(tp_ref)) tp = (SnmpMibNode*)SvIV((SV*)SvRV(tp_ref));
- ST(0) = sv_newmortal();
- if (tp)
- switch (c) {
- case 'a': /* access */
- if (strncmp("access", key, strlen(key)) == 0) {
- switch (tp->access) {
- case MIB_ACCESS_READONLY:
- sv_setpv(ST(0),"ReadOnly");
- break;
- case MIB_ACCESS_READWRITE:
- sv_setpv(ST(0),"ReadWrite");
- break;
- case MIB_ACCESS_WRITEONLY:
- sv_setpv(ST(0),"WriteOnly");
- break;
- case MIB_ACCESS_NOACCESS:
- sv_setpv(ST(0),"NoAccess");
- break;
- case MIB_ACCESS_NOTIFY:
- sv_setpv(ST(0),"Notify");
- break;
- case MIB_ACCESS_CREATE:
- sv_setpv(ST(0),"Create");
- break;
- default:
- break;
- }
- } else if (strncmp("augments", key, strlen(key)) == 0) {
- sv_setpv(ST(0),tp->augments);
- }
- break;
- case 'c': /* children */
- if (strncmp("children", key, strlen(key))) break;
- child_list_aref = newRV((SV*)newAV());
- for (tp = tp->child_list; tp; tp = tp->next_peer) {
- mib_hv = perl_get_hv("SNMP::MIB", FALSE);
- if (SvMAGICAL(mib_hv)) mg = mg_find((SV*)mib_hv, 'P');
- if (mg) mib_tied_href = (SV*)mg->mg_obj;
- next_node_href = newRV((SV*)newHV());
- __tp_sprint_num_objid(str_buf, tp);
- nn_hrefp = hv_fetch((HV*)SvRV(mib_tied_href),
- str_buf, strlen(str_buf), 1);
- if (!SvROK(*nn_hrefp)) {
- sv_setsv(*nn_hrefp, next_node_href);
- ENTER ;
- SAVETMPS ;
- PUSHMARK(sp) ;
- XPUSHs(SvRV(*nn_hrefp));
- XPUSHs(sv_2mortal(newSVpv("SNMP::MIB::NODE",0)));
- XPUSHs(sv_2mortal(newSVpv(str_buf,0)));
- XPUSHs(sv_2mortal(newSViv((IV)tp)));
- PUTBACK ;
- perl_call_pv("SNMP::_tie",G_VOID);
- /* pp_tie(ARGS); */
- SPAGAIN ;
- FREETMPS ;
- LEAVE ;
- } /* if SvROK */
- av_push((AV*)SvRV(child_list_aref), *nn_hrefp);
- } /* for child_list */
- sv_setsv(ST(0), child_list_aref);
- break;
- case 'v':
- if (strncmp("varbinds", key, strlen(key))) break;
- varbind_av = newAV();
- for (vp = tp->varbinds; vp; vp = vp->next) {
- av_push(varbind_av, newSVpv((vp->vblabel),strlen(vp->vblabel)));
- }
- sv_setsv(ST(0), newRV((SV*)varbind_av));
- break;
- case 'd': /* description */
- if (strncmp("description", key, strlen(key))) {
- if(!(strncmp("defaultValue",key,strlen(key)))) {
- /* We're looking at defaultValue */
- sv_setpv(ST(0), tp->defaultValue);
- break;
- } /* end if */
- } /* end if */
- /* we must be looking at description */
- sv_setpv(ST(0),tp->description);
- break;
- case 'i': /* indexes */
- if (strncmp("indexes", key, strlen(key))) break;
- index_av = newAV();
- if (tp->augments) {
- clear_tree_flags(get_tree_head());
- tptmp = find_best_tree_node(tp->augments, get_tree_head(), NULL);
- if (tptmp == NULL) {
- tptmp = tp;
- }
- } else {
- tptmp = tp;
- }
- if (tptmp)
- for(ip=tptmp->indexes; ip != NULL; ip = ip->next) {
- av_push(index_av,newSVpv((ip->ilabel),strlen(ip->ilabel)));
- }
- sv_setsv(ST(0), newRV((SV*)index_av));
- break;
- case 'l': /* label */
- if (strncmp("label", key, strlen(key))) break;
- sv_setpv(ST(0),tp->label);
- break;
- case 'm': /* moduleID */
- if (strncmp("moduleID", key, strlen(key))) break;
- mp = find_module(tp->modid);
- if (mp) sv_setpv(ST(0), mp->name);
- break;
- case 'n': /* nextNode */
- if (strncmp("nextNode", key, strlen(key))) break;
- tp = __get_next_mib_node(tp);
- if (tp == NULL) {
- sv_setsv(ST(0), &sv_undef);
- break;
- }
- mib_hv = perl_get_hv("SNMP::MIB", FALSE);
- if (SvMAGICAL(mib_hv)) mg = mg_find((SV*)mib_hv, 'P');
- if (mg) mib_tied_href = (SV*)mg->mg_obj;
- __tp_sprint_num_objid(str_buf, tp);
- nn_hrefp = hv_fetch((HV*)SvRV(mib_tied_href),
- str_buf, strlen(str_buf), 1);
- /* if (!SvROK(*nn_hrefp)) { */ /* bug in ucd - 2 .0.0 nodes */
- next_node_href = newRV((SV*)newHV());
- sv_setsv(*nn_hrefp, next_node_href);
- ENTER ;
- SAVETMPS ;
- PUSHMARK(sp) ;
- XPUSHs(SvRV(*nn_hrefp));
- XPUSHs(sv_2mortal(newSVpv("SNMP::MIB::NODE",0)));
- XPUSHs(sv_2mortal(newSVpv(str_buf,0)));
- XPUSHs(sv_2mortal(newSViv((IV)tp)));
- PUTBACK ;
- perl_call_pv("SNMP::_tie",G_VOID);
- /* pp_tie(ARGS); */
- SPAGAIN ;
- FREETMPS ;
- LEAVE ;
- /* } */
- sv_setsv(ST(0), *nn_hrefp);
- break;
- case 'o': /* objectID */
- if (strncmp("objectID", key, strlen(key))) break;
- __tp_sprint_num_objid(str_buf, tp);
- sv_setpv(ST(0),str_buf);
- break;
- case 'p': /* parent */
- if (strncmp("parent", key, strlen(key))) break;
- tp = tp->parent;
- if (tp == NULL) {
- sv_setsv(ST(0), &sv_undef);
- break;
- }
- mib_hv = perl_get_hv("SNMP::MIB", FALSE);
- if (SvMAGICAL(mib_hv)) mg = mg_find((SV*)mib_hv, 'P');
- if (mg) mib_tied_href = (SV*)mg->mg_obj;
- next_node_href = newRV((SV*)newHV());
- __tp_sprint_num_objid(str_buf, tp);
- nn_hrefp = hv_fetch((HV*)SvRV(mib_tied_href),
- str_buf, strlen(str_buf), 1);
- if (!SvROK(*nn_hrefp)) {
- sv_setsv(*nn_hrefp, next_node_href);
- ENTER ;
- SAVETMPS ;
- PUSHMARK(sp) ;
- XPUSHs(SvRV(*nn_hrefp));
- XPUSHs(sv_2mortal(newSVpv("SNMP::MIB::NODE",0)));
- XPUSHs(sv_2mortal(newSVpv(str_buf,0)));
- XPUSHs(sv_2mortal(newSViv((IV)tp)));
- PUTBACK ;
- perl_call_pv("SNMP::_tie",G_VOID);
- /* pp_tie(ARGS); */
- SPAGAIN ;
- FREETMPS ;
- LEAVE ;
- }
- sv_setsv(ST(0), *nn_hrefp);
- break;
- case 'r': /* ranges */
- if (strncmp("reference", key, strlen(key)) == 0) {
- sv_setpv(ST(0),tp->reference);
- break;
- }
- if (strncmp("ranges", key, strlen(key))) break;
- ranges_av = newAV();
- for(rp=tp->ranges; rp ; rp = rp->next) {
- range_hv = newHV();
- hv_store(range_hv, "low", strlen("low"), newSViv(rp->low), 0);
- hv_store(range_hv, "high", strlen("high"), newSViv(rp->high), 0);
- av_push(ranges_av, newRV((SV*)range_hv));
- }
- sv_setsv(ST(0), newRV((SV*)ranges_av));
- break;
- case 's': /* subID */
- if (strncmp("subID", key, strlen(key))) {
- if (strncmp("status", key, strlen(key))) {
- if (strncmp("syntax", key, strlen(key))) break;
- if (tp->tc_index >= 0) {
- sv_setpv(ST(0), get_tc_descriptor(tp->tc_index));
- } else {
- __get_type_str(tp->type, str_buf);
- sv_setpv(ST(0), str_buf);
- }
- break;
- }
- switch(tp->status) {
- case MIB_STATUS_MANDATORY:
- sv_setpv(ST(0),"Mandatory");
- break;
- case MIB_STATUS_OPTIONAL:
- sv_setpv(ST(0),"Optional");
- break;
- case MIB_STATUS_OBSOLETE:
- sv_setpv(ST(0),"Obsolete");
- break;
- case MIB_STATUS_DEPRECATED:
- sv_setpv(ST(0),"Deprecated");
- break;
- case MIB_STATUS_CURRENT:
- sv_setpv(ST(0),"Current");
- break;
- default:
- break;
- }
- } else {
- sv_setiv(ST(0),(I32)tp->subid);
- }
- break;
- case 't': /* type */
- if (strncmp("type", key, strlen(key))) {
- if (strncmp("textualConvention", key, strlen(key))) break;
- sv_setpv(ST(0), get_tc_descriptor(tp->tc_index));
- break;
- }
- __get_type_str(tp->type, str_buf);
- sv_setpv(ST(0), str_buf);
- break;
- case 'T': /* textual convention description */
- if (strncmp("TCDescription", key, strlen(key))) break;
- sv_setpv(ST(0), get_tc_description(tp->tc_index));
- break;
- case 'u': /* units */
- if (strncmp("units", key, strlen(key))) break;
- sv_setpv(ST(0),tp->units);
- break;
- case 'h': /* hint */
- if (strncmp("hint", key, strlen(key))) break;
- sv_setpv(ST(0),tp->hint);
- break;
- case 'e': /* enums */
- if (strncmp("enums", key, strlen(key))) break;
- enum_hv = newHV();
- for(ep=tp->enums; ep != NULL; ep = ep->next) {
- hv_store(enum_hv, ep->label, strlen(ep->label),
- newSViv(ep->value), 0);
- }
- sv_setsv(ST(0), newRV((SV*)enum_hv));
- break;
- default:
- break;
- }
- }
- MODULE = SNMP PACKAGE = SnmpSessionPtr PREFIX = snmp_session_
- void
- snmp_session_DESTROY(sess_ptr)
- SnmpSession *sess_ptr
- CODE:
- {
- snmp_close( sess_ptr );
- }