⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snmp.xs

📁 snmp的源代码,已经在我的ubuntu下编译通过
💻 XS
📖 第 1 页 / 共 5 页
字号:
       * Ideally, we would use the return value from the callback to       * decide what response, if any, we send, and what the error status       * and error index should be.       */      reply_pdu = snmp_clone_pdu(pdu);      if (reply_pdu) {        reply_pdu->command = SNMP_MSG_RESPONSE;        reply_pdu->reqid = pdu->reqid;        reply_pdu->errstat = reply_pdu->errindex = 0;        snmp_send(ss, reply_pdu);      } else {        warn("Couldn't clone PDU for inform response");      }      /* FALLTHRU */    case SNMP_MSG_TRAP2:      traplist = newAV();      traplist_ref = newRV_noinc((SV*)traplist);#if 0      /* of dubious utility... */      av_push(traplist, newSViv(pdu->command));#endif      av_push(traplist, newSViv(pdu->reqid));      if ((transport = snmp_sess_transport(snmp_sess_pointer(ss))) != NULL) {	cp = transport->f_fmtaddr(transport, pdu->transport_data,				  pdu->transport_data_length);	av_push(traplist, newSVpv(cp, strlen(cp)));	free(cp);      } else {	/*  This shouldn't ever happen; every session has a transport.  */	av_push(traplist, newSVpv("", 0));      }      av_push(traplist, newSVpv((char*) pdu->community, pdu->community_len));      /* FALLTHRU */    case SNMP_MSG_RESPONSE:      {      varlist = newAV();      varlist_ref = newRV_noinc((SV*)varlist);      /*      ** Set up for numeric OID's, if necessary.  Save the old values      ** so that they can be restored when we finish -- these are      ** library-wide globals, and have to be set/restored for each      ** session.      */      old_numeric = netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_OIDS);      old_printfull = netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_FULL_OID);      if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseLongNames", 12, 1))) {         getlabel_flag |= USE_LONG_NAMES;         netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_FULL_OID, 1);      }      /* 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_NUMERIC_OIDS;         netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_OIDS, 1);      }      sv_bless(varlist_ref, gv_stashpv("SNMP::VarList",0));      for(vars = (pdu?pdu->variables:NULL); vars; vars = vars->next_variable) {         varbind = newAV();         varbind_ref = newRV_noinc((SV*)varbind);         sv_bless(varbind_ref, gv_stashpv("SNMP::Varbind",0));         av_push(varlist, varbind_ref);         *str_buf = '.';         *(str_buf+1) = '\0';         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] = '\0';         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);      } /* for */      /* Reset the library's behavior for numeric/symbolic OID's. */      netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_OIDS, old_numeric );      netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_FULL_OID, old_printfull);      } /* case SNMP_MSG_RESPONSE */      break;    default:;    } /* switch pdu->command */    break;  case NETSNMP_CALLBACK_OP_TIMED_OUT:    varlist_ref = &sv_undef;    break;  default:;  } /* switch op */  sv_2mortal(cb);  cb = __push_cb_args2(cb,                 (SvTRUE(varlist_ref) ? sv_2mortal(varlist_ref):varlist_ref),	         (SvTRUE(traplist_ref) ? sv_2mortal(traplist_ref):traplist_ref));  __call_callback(cb, G_DISCARD);  FREETMPS;  LEAVE;  sv_2mortal(sess_ref);  return 1;}static SV *__push_cb_args2(sv,esv,tsv)SV *sv;SV *esv;SV *tsv;{   dSP;   if (SvTYPE(SvRV(sv)) != SVt_PVCV) sv = SvRV(sv);   PUSHMARK(sp);   if (SvTYPE(sv) == SVt_PVAV) {      AV *av = (AV *) sv;      int n = av_len(av) + 1;      SV **x = av_fetch(av, 0, 0);      if (x) {         int i = 1;         sv = *x;         for (i = 1; i < n; i++) {            x = av_fetch(av, i, 0);            if (x) {               SV *arg = *x;               XPUSHs(sv_mortalcopy(arg));            } else {               XPUSHs(&sv_undef);            }         }      } else {         sv = &sv_undef;      }   }   if (esv) XPUSHs(sv_mortalcopy(esv));   if (tsv) XPUSHs(sv_mortalcopy(tsv));   PUTBACK;   return sv;}static int__call_callback(sv, flags)SV *sv;int flags;{ dSP; I32 myframe = TOPMARK; I32 count; ENTER; if (SvTYPE(sv) == SVt_PVCV)  {   count = perl_call_sv(sv, flags);  } else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVCV)  {   count = perl_call_sv(SvRV(sv), flags);  } else  {   SV **top = stack_base + myframe + 1;   SV *obj = *top;   if (SvPOK(sv) && SvROK(obj) && SvOBJECT(SvRV(obj)))    {     count = perl_call_method(SvPV(sv, na), flags);    }   else if (SvPOK(obj) && SvROK(sv) && SvOBJECT(SvRV(sv)))    {     /* We have obj method ...        Used to be used instead of LangMethodCall()      */     *top = sv;     count = perl_call_method(SvPV(obj, na), flags);    }   else    {     count = perl_call_sv(sv, flags);    } } LEAVE; return count;}/* Bulkwalk support routines *//* Add a context pointer to the list of valid pointers.  Place it in the first** NULL slot in the array.*/static int_context_add(walk_context *context){    int i, j, new_sz;    if ((i = _context_okay(context)) != 0)	/* Already exists?  Okay. */	return i;    /* Initialize the array if necessary. */    if (_valid_contexts == NULL) {	/* Create the _valid_contexts structure. */	Newz(0, _valid_contexts, 1, struct valid_contexts);	assert(_valid_contexts != NULL);	/* Populate the original valid contexts array. */	Newz(0, _valid_contexts->valid, 4, walk_context *);	assert(_valid_contexts->valid != NULL);	/* Computer number of slots in the array. */	_valid_contexts->sz_valid = sizeof(*_valid_contexts->valid) /							sizeof(walk_context *);	for (i = 0; i < _valid_contexts->sz_valid; i++)	    _valid_contexts->valid[i] = NULL;	DBPRT(3, (DBOUT "Created valid_context array 0x%p (%d slots)\n",			    _valid_contexts->valid, _valid_contexts->sz_valid));    }    /* Search through the list, looking for NULL's -- unused slots. */    for (i = 0; i < _valid_contexts->sz_valid; i++)	if (_valid_contexts->valid[i] == NULL)	    break;    /* Did we walk off the end of the list?  Need to grow the list.  Double    ** it for now.    */    if (i == _valid_contexts->sz_valid) {	new_sz = _valid_contexts->sz_valid * 2;	Renew(_valid_contexts->valid, new_sz, walk_context *);	assert(_valid_contexts->valid != NULL);	DBPRT(3, (DBOUT "Resized valid_context array 0x%p from %d to %d slots\n",		    _valid_contexts->valid, _valid_contexts->sz_valid, new_sz));	_valid_contexts->sz_valid = new_sz;	/* Initialize the new half of the resized array. */	for (j = i; j < new_sz; j++)	    _valid_contexts->valid[j] = NULL;    }    /* Store the context pointer in the array and return 0 (success). */    _valid_contexts->valid[i] = context;    DBPRT(3,(DBOUT "Add context 0x%p to valid context list\n", context));    return 0;}/* Remove a context pointer from the valid list.  Replace the pointer with** NULL in the valid pointer list.*/static int_context_del(walk_context *context){    int i;    if (_valid_contexts == NULL)	/* Make sure it was initialized. */	return 1;    for (i = 0; i < _valid_contexts->sz_valid; i++) {	if (_valid_contexts->valid[i] == context) {	    DBPRT(3,(DBOUT "Remove context 0x%p from valid context list\n", context));	    _valid_contexts->valid[i] = NULL;	/* Remove it from the list.  */	    return 0;				/* Return successful status. */	}    }    return 1;}/* Check if a specific context pointer is in the valid list.  Return true (1)** if the context is still in the valid list, or 0 if not (or context is NULL).*/static int_context_okay(walk_context *context){    int i;    if (_valid_contexts == NULL)	/* Make sure it was initialized. */	return 0;    if (context == NULL)		/* Asked about a NULL context? Fail. */	return 0;    for (i = 0; i < _valid_contexts->sz_valid; i++)	if (_valid_contexts->valid[i] == context)	    return 1;			/* Found it! */    return 0;				/* No match -- return failure. */}/* Check if the walk is completed, based upon the context.  Also set the** ignore flag on any completed variables -- this prevents them from being** being sent in later packets.*/static int_bulkwalk_done(walk_context *context){   int is_done = 1;   int i;   bulktbl *bt_entry;		/* bulktbl requested OID entry */   /* Don't consider walk done until at least one packet has been exchanged. */   if (context->pkts_exch == 0)      return 0;   /* Fix up any requests that have completed.  If the complete flag is set,   ** or it is a non-repeater OID, set the ignore flag so that it will not   ** be considered further.  Assume we are done with the walk, and note   ** otherwise if we aren't.  Return 1 if all requests are complete, or 0   ** if there's more to do.   */   for (i = 0; i < context->nreq_oids; i ++) {      bt_entry = &context->req_oids[i];      if (bt_entry->complete || bt_entry->norepeat) { 	/* This request is complete.  Remove it from list of 	** walks still in progress. 	*/ 	DBPRT(1, (DBOUT "Ignoring %s request oid %s\n", 	      bt_entry->norepeat? "nonrepeater" : "completed", 	      snprint_objid(_debugx, sizeof(_debugx), bt_entry->req_oid, 				    bt_entry->req_len))); 	/* Ignore this OID in any further packets. */ 	bt_entry->ignore = 1;      }      /* If any OID is not being ignored, the walk is not done.  Must loop      ** through all requests to do the fixup -- no early return possible.      */      if (!bt_entry->ignore) 	 is_done = 0;   }   return is_done;		/* Did the walk complete? */}/* Callback registered with SNMP.  Return 1 from this callback to cause the** current request to be deleted from the retransmit queue.*/static int_bulkwalk_async_cb(int		op,		  SnmpSession	*ss,		  int 		reqid,		  netsnmp_pdu *pdu,		  void		*context_ptr){   walk_context *context;   int	done = 0;   int	npushed;   SV **err_str_svp;   SV **err_num_svp;   /* Handle callback request for asynchronous bulkwalk.  If the bulkwalk has   ** not completed, and has not timed out, send the next request packet in   ** the walk.   **   ** Return 0 to indicate success (caller ignores return value).   */   DBPRT(2, (DBOUT "bulkwalk_async_cb(op %d, reqid 0x%08X, context 0x%p)\n",							op, reqid, context_ptr));   context = (walk_context *)context_ptr;   /* Make certain this is a valid context pointer.  This pdu may   ** have been retransmitted after the bulkwalk was completed   ** (and the context was destroyed).  If so, just return.   */   if (!_context_okay(context)) {      DBPRT(2,(DBOUT "Ignoring PDU for dead context 0x%p...\n", context));      return 1;   }   /* Is this a retransmission of a request we've already seen or some   ** unexpected request id?  If so, just ignore it.   */   if (reqid != context->exp_reqid) {       DBPRT(2,             (DBOUT "Got reqid 0x%08X, expected reqid 0x%08X.  Ignoring...\n", reqid,              context->exp_reqid));      return 1;   }   /* Ignore any future packets for this reqid. */   context->exp_reqid = -1;   err_str_svp = hv_fetch((HV*)SvRV(context->sess_ref), "ErrorStr", 8, 1);   err_num_svp = hv_fetch((HV*)SvRV(context->sess_ref), "ErrorNum", 8, 1);   switch (op) {      case NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE:      {	 DBPRT(1,(DBOUT "Received message for reqid 0x%08X ...\n", reqid));	 switch (pdu->command)	 {	    case SNMP_MSG_RESPONSE:	    {	       DBPRT(2, (DBOUT "Calling bulkwalk_recv_pdu(context 0x%p, pdu 0x%p)\n",							   context_ptr, pdu));	       /* Handle the response PDU.  If an error occurs or there were	       ** no variables in the response, consider the walk done.  If	       ** the response was okay, check if we have any more to do after	       ** this response.	       */	       if (_bulkwalk_recv_pdu(context, pdu) <= 0)		  done = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -