static int noit_snmp_handler(eventer_t e, int mask, void *closure, struct timeval *now) { fd_set fdset; int fds, block = 0; struct timeval timeout = { 0, 0 }; struct target_session *ts = closure; FD_ZERO(&fdset); FD_SET(e->fd, &fdset); fds = e->fd + 1; snmp_sess_read(ts->sess_handle, &fdset); if(noit_snmp_session_cleanse(ts)) return 0; snmp_sess_select_info(ts->sess_handle, &fds, &fdset, &timeout, &block); _set_ts_timeout(ts, block ? &timeout : NULL); return EVENTER_READ | EVENTER_EXCEPTION; }
void mux_poller::poll() { static const char *funcname {"snmp::mux_poller::poll"}; if (0 == tasks.size()) return; int fds, block; fd_set fdset; timeval timeout; taskdata::iterator it = tasks.begin(); for (unsigned active_hosts;;) { active_hosts = sessions.size(); if (active_hosts < max_hosts) { if (0 == active_hosts and it == tasks.end()) return; unsigned delta = max_hosts - active_hosts; void *sessp; for (unsigned i = 0; it != tasks.end() and i < delta; ++i, ++it) { polltask &task = it->second; sessp = init_snmp_session(it->first.c_str(), task.community.c_str(), task.version, callback_wrap, static_cast<void *>(&task)); sessions.emplace_front(sessp); task.pdata = &(sessions.front()); try { async_send(sessp, snmp_clone_pdu(task.request)); } catch (snmprun_error &error) { throw snmprun_error {errtype::runtime, funcname, "poll failed: %s", error.what()}; } } } fds = block = 0; FD_ZERO(&fdset); for (auto &sess : sessions) snmp_sess_select_info(sess.sessp, &fds, &fdset, &timeout, &block); if (0 > (fds = select(fds, &fdset, nullptr, nullptr, &timeout))) throw snmprun_error {errtype::runtime, funcname, "select() failed: %s", strerror(errno)}; if (fds) { for (auto &sess : sessions) snmp_sess_read(sess.sessp, &fdset); } else { for (auto &sess : sessions) snmp_sess_timeout(sess.sessp); } sessions.remove_if([](const polldata &p) { return (pollstate::finished == p.state); }); } }
v8::Handle<v8::Value> Session::onData(const v8::Arguments& args) { fd_set fdset; struct timeval timeout; int block = 1; int numfds = 0; UNWRAP(Session, wrap, args.This()); SwapScope scope(wrap, args); if(0 == wrap->session_) { return ThrowError("Session hasn't opened."); } if(2 != args.Length()) { return ThrowError("Must pass the msg and rinfo arguments to onData."); } FD_ZERO(&fdset); /** * block input: set to 1 if input timeout value is undefined * set to 0 if input timeout value is defined * block output: set to 1 if output timeout value is undefined * set to 0 if output rimeout vlaue id defined */ if(1 != snmp_sess_select_info(wrap->session_, &numfds, &fdset, &timeout, &block)) { return v8::Undefined(); } if(-1 == snmp_sess_read(wrap->session_, &fdset)) { return ThrowError(snmp_api_errstring(wrap->arguments_.s_snmp_errno)); } if(0 == block) { v8::Handle<v8::Object> ret = v8::Object::New(); v8::Handle<v8::Object> timeout_v8 = v8::Object::New(); timeout_v8->Set(tv_sec_symbol, from_long(timeout.tv_sec)); timeout_v8->Set(tv_usec_symbol, from_long(timeout.tv_usec)); ret->Set(timeout_symbol, timeout_v8); return scope.Close(ret); } else { return v8::Undefined(); } }
v8::Handle<v8::Value> Session::readData(const v8::Arguments& args) { fd_set fdset; struct timeval timeout; int block = 1; int numfds = 0; v8::HandleScope scope; UNWRAP(Session, wrap, args.This()); if(0 == wrap->session_) { return ThrowError("Session hasn't opened."); } if(0 != args.Length()) { return ThrowError("Must not pass any arguments to readData."); } FD_ZERO(&fdset); /** * block input: set to 1 if input timeout value is undefined * set to 0 if input timeout value is defined * block output: set to 1 if output timeout value is undefined * set to 0 if output rimeout vlaue id defined */ if(0 == snmp_sess_select_info(wrap->session_, &numfds, &fdset, &timeout, &block)) { snmp_sess_timeout(wrap->session_); goto error; } if(0 == block) { int ret = select(numfds, &fdset, 0, 0, &timeout); if(SOCKET_ERROR == ret || 0 == ret) { snmp_sess_timeout(wrap->session_); goto error; } } if(-1 == snmp_sess_read(wrap->session_, &fdset)) { return ThrowError(snmp_api_errstring(wrap->arguments_.s_snmp_errno)); } error: return v8::Undefined(); }
int snmp_sess_synch_response(void *sessp, netsnmp_pdu *pdu, netsnmp_pdu **response) { netsnmp_session *ss; struct synch_state lstate, *state; snmp_callback cbsav; void *cbmagsav; int numfds, count; fd_set fdset; struct timeval timeout, *tvp; int block; ss = snmp_sess_session(sessp); memset((void *) &lstate, 0, sizeof(lstate)); state = &lstate; cbsav = ss->callback; cbmagsav = ss->callback_magic; ss->callback = snmp_synch_input; ss->callback_magic = (void *) state; if ((state->reqid = snmp_sess_send(sessp, pdu)) == 0) { snmp_free_pdu(pdu); state->status = STAT_ERROR; } else state->waiting = 1; while (state->waiting) { numfds = 0; FD_ZERO(&fdset); block = SNMPBLOCK; tvp = &timeout; timerclear(tvp); snmp_sess_select_info(sessp, &numfds, &fdset, tvp, &block); if (block == 1) tvp = NULL; /* block without timeout */ count = select(numfds, &fdset, 0, 0, tvp); if (count > 0) { snmp_sess_read(sessp, &fdset); } else switch (count) { case 0: snmp_sess_timeout(sessp); break; case -1: if (errno == EINTR) { continue; } else { snmp_errno = SNMPERR_GENERR; /* * CAUTION! if another thread closed the socket(s) * waited on here, the session structure was freed. * It would be nice, but we can't rely on the pointer. * ss->s_snmp_errno = SNMPERR_GENERR; * ss->s_errno = errno; */ snmp_set_detail(strerror(errno)); } /* * FALLTHRU */ default: state->status = STAT_ERROR; state->waiting = 0; } } *response = state->pdu; ss->callback = cbsav; ss->callback_magic = cbmagsav; return state->status; }
int main(int argc, char *argv[]) { int arg; char *prognam; char *cp = NULL; const char* sysUpTime = NULL; /* initialize tcpip, if necessary */ SOCK_STARTUP; prognam = strrchr(argv[0], '/'); if (prognam) ++prognam; else prognam = argv[0]; putenv(strdup("POSIXLY_CORRECT=1")); netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DISABLE_PERSISTENT_LOAD, 1); netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DISABLE_PERSISTENT_SAVE, 1); while ((arg = getopt(argc, argv, ":Vhm:M:D:dP:L:U:c:x:")) != -1) { switch (arg) { case 'h': usage(prognam); result = 0; goto out; case 'm': setenv("MIBS", optarg, 1); break; case 'M': setenv("MIBDIRS", optarg, 1); break; case 'c': context = optarg; contextLen = strlen(context); break; case 'D': debug_register_tokens(optarg); snmp_set_do_debugging(1); break; case 'd': netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DUMP_PACKET, 1); break; case 'U': sysUpTime = optarg; break; case 'V': fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version()); result = 0; goto out; #ifndef DISABLE_MIB_LOADING case 'P': cp = snmp_mib_toggle_options(optarg); if (cp != NULL) { fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp); usage(prognam); goto out; } break; #endif /* DISABLE_MIB_LOADING */ case 'L': if (snmp_log_options(optarg, argc, argv) < 0) goto out; break; case 'x': if (optarg != NULL) { netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, optarg); } else usage(argv[0]); break; case ':': fprintf(stderr, "Option -%c requires an operand\n", optopt); usage(prognam); goto out; case '?': fprintf(stderr, "Unrecognized option: -%c\n", optopt); usage(prognam); goto out; } } arg = optind; init_snmp(NETSNMP_APPLICATION_CONFIG_TYPE); agentx_config_init(); /* NOTIFY varlist */ pdu = pdu_create_opt_context(AGENTX_MSG_NOTIFY, context, contextLen); if (sysUpTime) snmp_add_var(pdu, sysuptime_oid, sysuptime_oid_len, 't', sysUpTime); if (arg == argc) { fprintf(stderr, "Missing trap-oid parameter\n"); usage(prognam); goto out; } if (snmp_add_var(pdu, snmptrap_oid, snmptrap_oid_len, 'o', argv[arg])) { snmp_perror(argv[arg]); goto out; } ++arg; while (arg < argc) { oid name[MAX_OID_LEN]; size_t name_length = MAX_OID_LEN; arg += 3; if (arg > argc) { fprintf(stderr, "%s: Missing type/value for variable\n", argv[arg - 3]); goto out; } if (!snmp_parse_oid(argv[arg - 3], name, &name_length)) { snmp_perror(argv[arg - 3]); goto out; } if (snmp_add_var(pdu, name, name_length, argv[arg - 2][0], argv[arg - 1]) != 0) { snmp_perror(argv[arg - 3]); goto out; } } packetid = 0; state = &Connecting; next_state = NULL; if(state->entry) state->entry(state); /* main loop here... */ for(;;) { int block = 1; int numfds = 0; int count; fd_set fdset; struct timeval timeout; while(next_state) { if(state->exit) state->exit(state); DEBUGMSGTL(("process", "State transition: %s -> %s\n", state->name, next_state->name)); state = next_state; next_state = NULL; if(state->entry) state->entry(state); } if(state == &Exit) break; FD_ZERO(&fdset); snmp_sess_select_info(sessp, &numfds, &fdset, &timeout, &block); count = select(numfds, &fdset, NULL, NULL, !block ? &timeout : NULL); if (count > 0) snmp_sess_read(sessp, &fdset); else if (count == 0) snmp_sess_timeout(sessp); else if (errno != EINTR) { snmp_log(LOG_ERR, "select error [%s]\n", strerror(errno)); change_state(&Exit); } } /* at shutdown time */ snmp_free_pdu(pdu); pdu = NULL; snmp_shutdown(NETSNMP_APPLICATION_CONFIG_TYPE); out: SOCK_CLEANUP; return result; }