SNMP

 view release on metacpan or  search on metacpan

SNMP.xs  view on Meta::CPAN

	CODE:
        {
        int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));

        if ((mib_file == NULL) || (*mib_file == '\0')) {
           if (get_tree_head() == NULL) {
              if (verbose) warn("snmp_read_mib: initializing MIB\n");
              netsnmp_init_mib();
              if (get_tree_head()) {
                 if (verbose) warn("done\n");
              } else {
                 if (verbose) warn("failed\n");
              }
	   }
        } else {
           if (verbose) warn("snmp_read_mib: reading MIB: %s\n", mib_file);
           if (strcmp("ALL",mib_file))
              read_mib(mib_file);
           else
             read_all_mibs();
           if (get_tree_head()) {
              if (verbose) warn("done\n");
           } else {
              if (verbose) warn("failed\n");
           }
        }
        RETVAL = (IV)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 {
           netsnmp_read_module(module);
        }
        if (get_tree_head()) {
           if (verbose) warn("Read %s\n", module);
        } else {
           if (verbose) warn("Failed reading %s\n", module);
        }
        RETVAL = (IV)get_tree_head();
        }
        OUTPUT:
        RETVAL


void
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;
	   size_t 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));

SNMP.xs  view on Meta::CPAN

                        }
                      }
                    }

                    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 && SvPOK(*varbind_val_f) ?
				       SvCUR(*varbind_val_f):0), type);

		    if (verbose && res == FAILURE)
		      warn("error: set: 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);

              ss->callback = NULL;
              ss->callback_magic = NULL;

              if (SvTRUE(perl_callback)) {
                 snmp_xs_cb_data *xs_cb_data;
                 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));

                 # 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 = __snmp_xs_cb;
                 ss->callback_magic = xs_cb_data;
                 sv_2mortal(newSViv(1));
                 goto done;
              }
           }
           sv_2mortal(newSViv(0));
        done:
           ;
        }

void
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;
	   size_t 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;
	   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);

SNMP.xs  view on Meta::CPAN

                                                           vars->name,
							   vars->name_length);
                    str_buf[sizeof(str_buf)-1] = '\0';

                    if (__is_leaf(tp)) {
                       type = tp->type;
                    } else {
                       local_getlabel_flag |= NON_LEAF_NAME;
                       type = __translate_asn_type(vars->type);
                    }
                    __get_label_iid(str_buf,&label,&iid,local_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(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);
	}

void
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;
	   size_t 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;
	   char str_buf[STR_BUF_SIZE], *str_bufp = str_buf;
           size_t str_buf_len = sizeof(str_buf);
           char tmp_buf_prefix[STR_BUF_SIZE];
           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));

SNMP.xs  view on Meta::CPAN

                    }
                    
                    if (__is_leaf(tp)) {
                       type = tp->type;
                    } else {
                       local_getlabel_flag |= NON_LEAF_NAME;
                       type = __translate_asn_type(vars->type);
                    }
                    __get_label_iid(str_buf,&label,&iid,local_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(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);
	}

void
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;
	   size_t 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;
	   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);

SNMP.xs  view on Meta::CPAN

                       local_getlabel_flag |= NON_LEAF_NAME;
                       type = __translate_asn_type(vars->type);
                    }
                    __get_label_iid(str_buf,&label,&iid,local_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(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);
	}

void
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];
	   size_t 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("bulkwalk: 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%p\n",
						    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 */

SNMP.xs  view on Meta::CPAN

		 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));
		 goto err;
	      }

              /* 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;
	}


void
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;
	   size_t 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));

SNMP.xs  view on Meta::CPAN


                    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 && SvPOK(*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);
        }


void
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;
	   size_t 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;
              }


	      /******************************************************/

SNMP.xs  view on Meta::CPAN


                    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 && SvPOK(*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);
        }



void
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;
	   size_t 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;
              }

SNMP.xs  view on Meta::CPAN

           timerclear(tvp);
           snmp_select_info(&numfds, &fdset, tvp, &block);
           __recalc_timeout(tvp,ctvp,ltvp,itvp,&block);
           # printf("pre-select: numfds = %ld, block = %ld\n", 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 = %ld\n",fd_count,block);
           if (fd_count > 0) {
                       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:
	{



( run in 1.069 second using v1.01-cache-2.11-cpan-5511b514fd6 )