/*******************************************************************-o-****** * read_config * * Parameters: * *filename * *line_handler * when * * Read <filename> and process each line in accordance with the list of * <line_handler> functions. * * * For each line in <filename>, search the list of <line_handler>'s * for an entry that matches the first token on the line. This comparison is * case insensitive. * * For each match, check that <when> is the designated time for the * <line_handler> function to be executed before processing the line. */ void read_config(const char *filename, struct config_line *line_handler, int when) { #ifdef CYGPKG_SNMPLIB_FILESYSTEM_SUPPORT FILE *ifile; char line[STRINGMAX], token[STRINGMAX], tmpbuf[STRINGMAX]; char *cptr; int i, done; struct config_line *lptr; linecount = 0; curfilename = filename; if ((ifile = fopen(filename, "r")) == NULL) { #ifdef ENOENT if (errno == ENOENT) { DEBUGMSGTL(("read_config", "%s: %s\n", filename, strerror(errno))); } else #endif /* ENOENT */ #ifdef EACCES if (errno == EACCES) { DEBUGMSGTL(("read_config", "%s: %s\n", filename, strerror(errno))); } else #endif /* EACCES */ #if defined(ENOENT) || defined(EACCES) { snmp_log_perror(filename); } #else /* defined(ENOENT) || defined(EACCES) */ snmp_log_perror(filename); #endif /* ENOENT */ return; } else { DEBUGMSGTL(("read_config", "Reading configuration %s\n", filename)); } while (fgets(line, sizeof(line), ifile) != NULL) { lptr = line_handler; linecount++; cptr = line; i = strlen(line)-1; if (line[i] == '\n') line[i] = 0; /* check blank line or # comment */ if ((cptr = skip_white(cptr))) { cptr = copy_word(cptr,token); if (cptr == NULL) { sprintf(tmpbuf,"Blank line following %s token.", token); config_perror(tmpbuf); } else { for(lptr = line_handler, done=0; lptr != NULL && !done; lptr = lptr->next) { if (!strcasecmp(token,lptr->config_token)) { if (when == EITHER_CONFIG || lptr->config_time == when) { DEBUGMSGTL(("read_config", "%s:%d Parsing: %s\n", filename, linecount, line)); (*(lptr->parse_line))(token,cptr); } done = 1; } } if (!done && when != PREMIB_CONFIG && !ds_get_boolean(DS_LIBRARY_ID, DS_LIB_NO_TOKEN_WARNINGS)) { sprintf(tmpbuf,"Unknown token: %s.", token); config_pwarn(tmpbuf); } } } } fclose(ifile); #endif return; } /* end read_config() */
void init_hr_storage(void) { #ifdef USE_SYSCTL int mib[2]; size_t len; #elif defined(hpux10) || defined(hpux11) struct pst_static pst_buf; #endif #ifdef USE_SYSCTL mib[0] = CTL_HW; mib[1] = HW_PHYSMEM; len = sizeof(physmem); if (sysctl(mib, 2, &physmem, &len, NULL, 0) == -1) snmp_log_perror("sysctl: physmem"); mib[1] = HW_PAGESIZE; len = sizeof(pagesize); if (sysctl(mib, 2, &pagesize, &len, NULL, 0) == -1) snmp_log_perror("sysctl: pagesize"); physmem /= pagesize; #elif defined(hpux10) || defined(hpux11) if (pstat_getstatic(&pst_buf, sizeof(struct pst_static), 1, 0) < 0) { snmp_log_perror("pstat_getstatic"); } else { physmem = pst_buf.physical_memory; pagesize = pst_buf.page_size; } #else /* !USE_SYSCTL && !hpux10 && !hpux11 */ #ifndef WIN32 #ifdef HAVE_GETPAGESIZE pagesize = getpagesize(); #elif defined(_SC_PAGESIZE) pagesize = sysconf(_SC_PAGESIZE); #elif defined(PGSHIFT) pagesize = 1 << PGSHIFT; #elif defined(PAGE_SHIFT) pagesize = 1 << PAGE_SHIFT; #elif defined(PAGE_SIZE) pagesize = PAGE_SIZE; #elif defined(linux) { struct stat kc_buf; if (stat("/proc/kcore", &kc_buf) == -1) snmp_log_perror("/proc/kcore"); pagesize = kc_buf.st_size / 1024; /* 4K too large ? */ } #else pagesize = PAGESIZE; #endif #else /* WIN32 */ pagesize = 4096; /* Yes...Yes it does. */ #endif #ifdef _SC_PHYS_PAGES physmem = sysconf(_SC_PHYS_PAGES); #else #ifdef dynix physmem = sysconf(_SC_PHYSMEM); #else auto_nlist(PHYSMEM_SYMBOL, (char *) &physmem, sizeof(physmem)); #endif #endif #endif /* !USE_SYSCTL && !hpux10 && !hpux11 */ #ifdef TOTAL_MEMORY_SYMBOL auto_nlist(TOTAL_MEMORY_SYMBOL, 0, 0); #endif #ifdef MBSTAT_SYMBOL auto_nlist(MBSTAT_SYMBOL, 0, 0); #endif #if defined(darwin8) myHost = mach_host_self(); #endif REGISTER_MIB("host/hr_storage", hrstore_variables, variable4, hrstore_variables_oid); snmpd_register_config_handler("storageUseNFS", parse_storage_config, NULL, "1 | 2\t\t(1 = enable, 2 = disable)"); }
static void ARP_Scan_Init(void) { #ifndef CAN_USE_SYSCTL #ifndef linux #ifdef hpux11 int fd; struct nmparms p; int val; unsigned int ulen; int ret; if (at) free(at); at = (mib_ipNetToMediaEnt *) 0; arptab_size = 0; if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) >= 0) { p.objid = ID_ipNetToMediaTableNum; p.buffer = (void *) &val; ulen = sizeof(int); p.len = &ulen; if ((ret = get_mib_info(fd, &p)) == 0) arptab_size = val; if (arptab_size > 0) { ulen = (unsigned) arptab_size *sizeof(mib_ipNetToMediaEnt); at = (mib_ipNetToMediaEnt *) malloc(ulen); p.objid = ID_ipNetToMediaTable; p.buffer = (void *) at; p.len = &ulen; if ((ret = get_mib_info(fd, &p)) < 0) arptab_size = 0; } close_mib(fd); } arptab_current = 0; #else /* hpux11 */ if (!at) { auto_nlist(ARPTAB_SIZE_SYMBOL, (char *) &arptab_size, sizeof arptab_size); #ifdef STRUCT_ARPHD_HAS_AT_NEXT at = (struct arphd *) malloc(arptab_size * sizeof(struct arphd)); #else at = (struct arptab *) malloc(arptab_size * sizeof(struct arptab)); #endif } #ifdef STRUCT_ARPHD_HAS_AT_NEXT auto_nlist(ARPTAB_SYMBOL, (char *) at, arptab_size * sizeof(struct arphd)); at_ptr = at[0].at_next; #else auto_nlist(ARPTAB_SYMBOL, (char *) at, arptab_size * sizeof(struct arptab)); #endif arptab_current = 0; #endif /* hpux11 */ #else /* linux */ static time_t tm = 0; /* Time of last scan */ FILE *in; int i; char line[128]; int za, zb, zc, zd, ze, zf, zg, zh, zi, zj; char ifname[21]; arptab_current = 0; /* Anytime this is called we need to reset 'current' */ if (time(NULL) < tm + 1) { /*Our cool one second cache implementation :-) */ return; } in = fopen("/proc/net/arp", "r"); if (!in) { snmp_log(LOG_ERR, "snmpd: Cannot open /proc/net/arp\n"); arptab_size = 0; return; } /* * Get rid of the header line */ fgets(line, sizeof(line), in); i = 0; while (fgets(line, sizeof(line), in)) { u_long tmp_a; int tmp_flags; if (i >= arptab_curr_max_size) { struct arptab *newtab = (struct arptab *) realloc(at, (sizeof(struct arptab) * (arptab_curr_max_size + ARP_CACHE_INCR))); if (newtab == at) { snmp_log(LOG_ERR, "Error allocating more space for arpcache. " "Cache will continue to be limited to %d entries", arptab_curr_max_size); break; } else { arptab_curr_max_size += ARP_CACHE_INCR; at = newtab; } } if (12 != sscanf(line, "%d.%d.%d.%d 0x%*x 0x%x %x:%x:%x:%x:%x:%x %*[^ ] %20s\n", &za, &zb, &zc, &zd, &tmp_flags, &ze, &zf, &zg, &zh, &zi, &zj, ifname)) { snmp_log(LOG_ERR, "Bad line in /proc/net/arp: %s", line); continue; } /* * Invalidated entries have their flag set to 0. * * We want to ignore them */ if (tmp_flags == 0) { continue; } at[i].at_flags = tmp_flags; at[i].at_enaddr[0] = ze; at[i].at_enaddr[1] = zf; at[i].at_enaddr[2] = zg; at[i].at_enaddr[3] = zh; at[i].at_enaddr[4] = zi; at[i].at_enaddr[5] = zj; tmp_a = ((u_long) za << 24) | ((u_long) zb << 16) | ((u_long) zc << 8) | ((u_long) zd); at[i].at_iaddr.s_addr = htonl(tmp_a); at[i].if_index = Interface_Index_By_Name(ifname, strlen(ifname)); i++; } arptab_size = i; fclose(in); time(&tm); #endif /* linux */ #else /* CAN_USE_SYSCTL */ int mib[6]; size_t needed; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = AF_INET; mib[4] = NET_RT_FLAGS; mib[5] = RTF_LLINFO; if (at) free(at); rtnext = lim = at = 0; if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) snmp_log_perror("route-sysctl-estimate"); else { if ((at = malloc(needed ? needed : 1)) == NULL) snmp_log_perror("malloc"); else { if (sysctl(mib, 6, at, &needed, NULL, 0) < 0) snmp_log_perror("actual retrieval of routing table"); else { lim = at + needed; rtnext = at; } } } #endif /* CAN_USE_SYSCTL */ }
/*******************************************************************-o-****** * receive * * Parameters: * * Returns: * 0 On success. * -1 System error. * * Infinite while-loop which monitors incoming messges for the agent. * Invoke the established message handlers for incoming messages on a per * port basis. Handle timeouts. */ static int receive(void) { int numfds; fd_set fdset; struct timeval timeout, *tvp = &timeout; struct timeval sched, *svp = &sched, now, *nvp = &now; int count, block; #ifdef USING_SMUX_MODULE int i, sd; #endif /* USING_SMUX_MODULE */ /* * Set the 'sched'uled timeout to the current time + one TIMETICK. */ gettimeofday(nvp, (struct timezone *) NULL); svp->tv_usec = nvp->tv_usec + TIMETICK; svp->tv_sec = nvp->tv_sec; while (svp->tv_usec >= ONE_SEC) { svp->tv_usec -= ONE_SEC; svp->tv_sec++; } /* * Loop-forever: execute message handlers for sockets with data, * reset the 'sched'uler. */ while (running) { if (reconfig) { reconfig = 0; snmp_log(LOG_INFO, "Reconfiguring daemon\n"); update_config(); } tvp = &timeout; tvp->tv_sec = 0; tvp->tv_usec = TIMETICK; numfds = 0; FD_ZERO(&fdset); block = 0; snmp_select_info(&numfds, &fdset, tvp, &block); if (block == 1) tvp = NULL; /* block without timeout */ #ifdef USING_SMUX_MODULE if (smux_listen_sd >= 0) { FD_SET(smux_listen_sd, &fdset); numfds = smux_listen_sd >= numfds ? smux_listen_sd + 1 : numfds; for (i = 0; i < sdlen; i++) { FD_SET(sdlist[i], &fdset); numfds = sdlist[i] >= numfds ? sdlist[i] + 1 : numfds; } } #endif /* USING_SMUX_MODULE */ count = select(numfds, &fdset, 0, 0, tvp); if (count > 0) { snmp_read(&fdset); } else switch(count) { case 0: snmp_timeout(); break; case -1: if (errno == EINTR) { continue; } else { snmp_log_perror("select"); } return -1; default: snmp_log(LOG_ERR, "select returned %d\n", count); return -1; } /* endif -- count>0 */ #ifdef USING_SMUX_MODULE /* handle the SMUX sd's */ if (smux_listen_sd >= 0) { for (i = 0; i < sdlen; i++) { if (FD_ISSET(sdlist[i], &fdset)) { if (smux_process(sdlist[i]) < 0) { for (; i < (sdlen - 1); i++) { sdlist[i] = sdlist[i+1]; } sdlen--; } } } /* new connection */ if (FD_ISSET(smux_listen_sd, &fdset)) { if ((sd = smux_accept(smux_listen_sd)) >= 0) { sdlist[sdlen++] = sd; } } } #endif /* USING_SMUX_MODULE */ /* * If the time 'now' is greater than the 'sched'uled time, then: * * Check alarm and event timers. * Reset the 'sched'uled time to current time + one TIMETICK. * Age the cache network addresses (from whom messges have * been received). */ gettimeofday(nvp, (struct timezone *) NULL); if (nvp->tv_sec > svp->tv_sec || (nvp->tv_sec == svp->tv_sec && nvp->tv_usec > svp->tv_usec)) { svp->tv_usec = nvp->tv_usec + TIMETICK; svp->tv_sec = nvp->tv_sec; while (svp->tv_usec >= ONE_SEC) { svp->tv_usec -= ONE_SEC; svp->tv_sec++; } if (log_addresses && lastAddrAge++ > 600) { lastAddrAge = 0; for(count = 0; count < ADDRCACHE; count++) { if (addrCache[count].status == OLD) addrCache[count].status = UNUSED; if (addrCache[count].status == USED) addrCache[count].status = OLD; } } } /* endif -- now>sched */ /* run requested alarms */ run_alarms(); } /* endwhile */ snmp_log(LOG_INFO, "Received TERM or STOP signal... shutting down...\n"); return 0; } /* end receive() */
/* * Load the latest CPU usage statistics */ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { static char *buff = NULL; static int bsize = 0; static int first = 1; static int num_cpuline_elem = 0; int bytes_read, statfd, i; char *b1, *b2; unsigned long long cusell = 0, cicell = 0, csysll = 0, cidell = 0, ciowll = 0, cirqll = 0, csoftll = 0, cstealll = 0, cguestll = 0, cguest_nicell = 0; netsnmp_cpu_info* cpu; if ((statfd = open(STAT_FILE, O_RDONLY, 0)) == -1) { snmp_log_perror(STAT_FILE); return -1; } if (bsize == 0) { bsize = getpagesize()-1; buff = (char*)malloc(bsize+1); if (buff == NULL) { return -1; } } while ((bytes_read = read(statfd, buff, bsize)) == bsize) { bsize += BUFSIZ; buff = (char*)realloc(buff, bsize+1); DEBUGMSGTL(("cpu", "/proc/stat buffer increased to %d\n", bsize)); close(statfd); statfd = open(STAT_FILE, O_RDONLY, 0); if (statfd == -1) { snmp_log_perror(STAT_FILE); return -1; } } close(statfd); if ( bytes_read < 0 ) { snmp_log_perror(STAT_FILE "read error"); return -1; } buff[bytes_read] = '\0'; /* * CPU statistics (overall and per-CPU) */ b1 = buff; while ((b2 = strstr( b1, "cpu" ))) { if (b2[3] == ' ') { cpu = netsnmp_cpu_get_byIdx( -1, 0 ); if (!cpu) { snmp_log_perror("No (overall) CPU info entry"); return -1; } b1 = b2+4; /* Skip "cpu " */ } else { sscanf( b2, "cpu%d", &i ); /* Create on the fly to support non-x86 systems - see init */ cpu = netsnmp_cpu_get_byIdx( i, 1 ); if (!cpu) { snmp_log_perror("Missing CPU info entry"); break; } b1 = b2; /* Skip "cpuN " */ while(*b1 != ' ') b1++; b1++; } num_cpuline_elem = sscanf(b1, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", &cusell, &cicell, &csysll, &cidell, &ciowll, &cirqll, &csoftll, &cstealll, &cguestll, &cguest_nicell); DEBUGMSGTL(("cpu", "/proc/stat cpu line number of elements: %i\n", num_cpuline_elem)); /* kernel 2.6.33 and above */ if (num_cpuline_elem == 10) { cpu->guestnice_ticks = cguest_nicell; } /* kernel 2.6.24 and above */ if (num_cpuline_elem >= 9) { cpu->guest_ticks = cguestll; } /* kernel 2.6.11 and above */ if (num_cpuline_elem >= 8) { cpu->steal_ticks = cstealll; } /* kernel 2.6 */ if (num_cpuline_elem >= 5) { cpu->wait_ticks = ciowll; cpu->intrpt_ticks = cirqll; cpu->sirq_ticks = csoftll; } /* rest */ cpu->user_ticks = cusell; cpu->nice_ticks = cicell; cpu->sys_ticks = csysll; cpu->idle_ticks = cidell; } if ( b1 == buff ) { if (first) snmp_log(LOG_ERR, "No cpu line in %s\n", STAT_FILE); } /* * Interrupt/Context Switch statistics * XXX - Do these really belong here ? */ cpu = netsnmp_cpu_get_byIdx( -1, 0 ); _cpu_load_swap_etc( buff, cpu ); /* * XXX - TODO: extract per-CPU statistics * (Into separate netsnmp_cpu_info data structures) */ first = 0; return 0; }
/*******************************************************************-o-****** * receive * * Parameters: * * Returns: * 0 On success. * -1 System error. * * Infinite while-loop which monitors incoming messages for the agent. * Invoke the established message handlers for incoming messages on a per * port basis. Handle timeouts. */ static int receive(void) { int numfds; netsnmp_large_fd_set readfds, writefds, exceptfds; struct timeval timeout, *tvp = &timeout; int count, block, i; #ifdef USING_SMUX_MODULE int sd; #endif /* USING_SMUX_MODULE */ netsnmp_large_fd_set_init(&readfds, FD_SETSIZE); netsnmp_large_fd_set_init(&writefds, FD_SETSIZE); netsnmp_large_fd_set_init(&exceptfds, FD_SETSIZE); /* * ignore early sighup during startup */ reconfig = 0; #if defined(WIN32) create_stdin_waiter_thread(); #endif /* * Loop-forever: execute message handlers for sockets with data */ while (netsnmp_running) { if (reconfig) { #if HAVE_SIGHOLD sighold(SIGHUP); #endif reconfig = 0; snmp_log(LOG_INFO, "Reconfiguring daemon\n"); /* Stop and restart logging. This allows logfiles to be rotated etc. */ netsnmp_logging_restart(); snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n", netsnmp_get_version()); update_config(); send_easy_trap(SNMP_TRAP_ENTERPRISESPECIFIC, 3); #if HAVE_SIGHOLD sigrelse(SIGHUP); #endif } /* * default to sleeping for a really long time. INT_MAX * should be sufficient (eg we don't care if time_t is * a long that's bigger than an int). */ tvp = &timeout; tvp->tv_sec = INT_MAX; tvp->tv_usec = 0; numfds = 0; NETSNMP_LARGE_FD_ZERO(&readfds); NETSNMP_LARGE_FD_ZERO(&writefds); NETSNMP_LARGE_FD_ZERO(&exceptfds); block = 0; snmp_select_info2(&numfds, &readfds, tvp, &block); if (block == 1) { tvp = NULL; /* block without timeout */ } #ifdef USING_SMUX_MODULE if (smux_listen_sd >= 0) { NETSNMP_LARGE_FD_SET(smux_listen_sd, &readfds); numfds = smux_listen_sd >= numfds ? smux_listen_sd + 1 : numfds; for (i = 0; i < smux_snmp_select_list_get_length(); i++) { sd = smux_snmp_select_list_get_SD_from_List(i); if (sd != 0) { NETSNMP_LARGE_FD_SET(sd, &readfds); numfds = sd >= numfds ? sd + 1 : numfds; } } } #endif /* USING_SMUX_MODULE */ #ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER netsnmp_external_event_info2(&numfds, &readfds, &writefds, &exceptfds); #endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */ reselect: #ifndef NETSNMP_FEATURE_REMOVE_REGISTER_SIGNAL for (i = 0; i < NUM_EXTERNAL_SIGS; i++) { if (external_signal_scheduled[i]) { external_signal_scheduled[i]--; external_signal_handler[i](i); } } #endif /* NETSNMP_FEATURE_REMOVE_REGISTER_SIGNAL */ DEBUGMSGTL(("snmpd/select", "select( numfds=%d, ..., tvp=%p)\n", numfds, tvp)); if (tvp) DEBUGMSGTL(("timer", "tvp %ld.%ld\n", (long) tvp->tv_sec, (long) tvp->tv_usec)); count = netsnmp_large_fd_set_select(numfds, &readfds, &writefds, &exceptfds, tvp); DEBUGMSGTL(("snmpd/select", "returned, count = %d\n", count)); if (count > 0) { #ifdef USING_SMUX_MODULE /* * handle the SMUX sd's */ if (smux_listen_sd >= 0) { for (i = 0; i < smux_snmp_select_list_get_length(); i++) { sd = smux_snmp_select_list_get_SD_from_List(i); if (NETSNMP_LARGE_FD_ISSET(sd, &readfds)) { if (smux_process(sd) < 0) { smux_snmp_select_list_del(sd); } } } /* * new connection */ if (NETSNMP_LARGE_FD_ISSET(smux_listen_sd, &readfds)) { if ((sd = smux_accept(smux_listen_sd)) >= 0) { smux_snmp_select_list_add(sd); } } } #endif /* USING_SMUX_MODULE */ #ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER netsnmp_dispatch_external_events2(&count, &readfds, &writefds, &exceptfds); #endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */ /* If there are still events leftover, process them */ if (count > 0) { snmp_read2(&readfds); } } else switch (count) { case 0: snmp_timeout(); break; case -1: DEBUGMSGTL(("snmpd/select", " errno = %d\n", errno)); if (errno == EINTR) { /* * likely that we got a signal. Check our special signal * flags before retrying select. */ if (netsnmp_running && !reconfig) { goto reselect; } continue; } else { snmp_log_perror("select"); } return -1; default: snmp_log(LOG_ERR, "select returned %d\n", count); return -1; } /* endif -- count>0 */ /* * see if persistent store needs to be saved */ snmp_store_if_needed(); /* * run requested alarms */ run_alarms(); netsnmp_check_outstanding_agent_requests(); } /* endwhile */ netsnmp_large_fd_set_cleanup(&readfds); netsnmp_large_fd_set_cleanup(&writefds); netsnmp_large_fd_set_cleanup(&exceptfds); #if defined(WIN32) join_stdin_waiter_thread(); #endif snmp_log(LOG_INFO, "Received TERM or STOP signal... shutting down...\n"); return 0; } /* end receive() */
void netsnmp_fsys_arch_load( void ) { int ret = 0; uint size = 0; struct vmount *aixmnt, *aixcurr; char *path; struct statfs stat_buf; netsnmp_fsys_info *entry; char tmpbuf[1024]; /* * Retrieve information about the currently mounted filesystems... */ ret = mntctl(MCTL_QUERY, sizeof(uint), &size); if ( ret != 0 || size<=0 ) { snmp_log_perror( "initial mntctl failed" ); return; } aixmnt = (struct vmount *)malloc( size ); if ( aixmnt == NULL ) { snmp_log_perror( "cannot allocate memory for mntctl data" ); return; } ret = mntctl(MCTL_QUERY, size, aixmnt ); if ( ret <= 0 ) { free(aixmnt); snmp_log_perror( "main mntctl failed" ); return; } aixcurr = aixmnt; /* * ... and insert this into the filesystem container. */ for ( aixcurr = aixmnt; (aixcurr-aixmnt) >= size; aixcurr = (char*)aixcurr + aixcurr->vmt_length ) { path = vmt2dataptr( aixcurr, VMT_OBJECT ); entry = netsnmp_fsys_by_path( path, NETSNMP_FS_FIND_CREATE ); if (!entry) { continue; } strlcpy(entry->path, path, sizeof(entry->path)); strlcpy(entry->device, vmt2dataptr(aixcurr, VMT_STUB), sizeof(entry->device)); entry->type = _fsys_type( aixcurr->vmt_gfstype ); if (!(entry->type & _NETSNMP_FS_TYPE_SKIP_BIT)) entry->flags |= NETSNMP_FS_FLAG_ACTIVE; if ( _fsys_remote( entry->device, entry->type, vmt2dataptr( aixcurr, VMT_HOST) )) entry->flags |= NETSNMP_FS_FLAG_REMOTE; if ( aixcurr->vmt_flags & MNT_READONLY ) entry->flags |= NETSNMP_FS_FLAG_RONLY; /* * The root device is presumably bootable. * Other partitions probably aren't! */ if ((entry->path[0] == '/') && (entry->path[1] == '\0')) entry->flags |= NETSNMP_FS_FLAG_BOOTABLE; /* * XXX - identify removeable disks */ /* * Optionally skip retrieving statistics for remote mounts */ if ( (entry->flags & NETSNMP_FS_FLAG_REMOTE) && netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES)) continue; if ( statfs( entry->path, &stat_buf ) < 0 ) { snprintf( tmpbuf, sizeof(tmpbuf), "Cannot statfs %s\n", entry->path ); snmp_log_perror( tmpbuf ); continue; } entry->units = stat_buf.f_bsize; entry->size = stat_buf.f_blocks; entry->used = (stat_buf.f_blocks - stat_buf.f_bfree); entry->avail = stat_buf.f_bavail; entry->inums_total = stat_buf.f_files; entry->inums_avail = stat_buf.f_ffree; netsnmp_fsys_calculate32(entry); } free(aixmnt); aixmnt = NULL; aixcurr = NULL; }
static int getmib(int groupname, int subgroupname, void *statbuf, size_t size, size_t entrysize, req_e req_type, void *resp, size_t *length, int (*comp)(void *, void *), void *arg) { int rc, ret = 0, flags; char buf[BUFSIZE]; struct strbuf strbuf; struct T_optmgmt_req *tor = (struct T_optmgmt_req *) buf; struct T_optmgmt_ack *toa = (struct T_optmgmt_ack *) buf; struct T_error_ack *tea = (struct T_error_ack *) buf; struct opthdr *req; found_e result = FOUND; DEBUGMSGTL(("kernel_sunos5", "...... getmib (%d, %d, ...)\n", groupname, subgroupname)); /* * Open the stream driver and push all MIB-related modules */ if (sd == -2) { /* First time */ if ((sd = open(STREAM_DEV, O_RDWR)) == -1) { snmp_log_perror(STREAM_DEV); ret = -1; goto Return; } if (ioctl(sd, I_PUSH, "tcp") == -1) { snmp_log_perror("I_PUSH tcp"); ret = -1; goto Return; } if (ioctl(sd, I_PUSH, "udp") == -1) { snmp_log_perror("I_PUSH udp"); ret = -1; goto Return; } DEBUGMSGTL(("kernel_sunos5", "...... modules pushed OK\n")); } if (sd == -1) { ret = -1; goto Return; } /* * First, use bigger buffer, to accelerate skipping unwanted messages */ strbuf.buf = buf; strbuf.maxlen = BUFSIZE; tor->PRIM_type = T_OPTMGMT_REQ; tor->OPT_offset = sizeof(struct T_optmgmt_req); tor->OPT_length = sizeof(struct opthdr); #ifdef MI_T_CURRENT tor->MGMT_flags = MI_T_CURRENT; /* Solaris < 2.6 */ #else tor->MGMT_flags = T_CURRENT; /* Solaris 2.6 */ #endif req = (struct opthdr *)(tor + 1); req->level = groupname; req->name = subgroupname; req->len = 0; strbuf.len = tor->OPT_length + tor->OPT_offset; flags = 0; if ((rc = putmsg(sd, &strbuf, NULL, flags))) { ret = -2; goto Return; } req = (struct opthdr *) (toa + 1); for (;;) { flags = 0; if ((rc = getmsg(sd, &strbuf, NULL, &flags)) == -1) { ret = -EIO; break; } if (rc == 0 && strbuf.len >= sizeof(struct T_optmgmt_ack) && toa->PRIM_type == T_OPTMGMT_ACK && toa->MGMT_flags == T_SUCCESS && req->len == 0) { ret = 2; break; } if (strbuf.len >= sizeof(struct T_error_ack) && tea->PRIM_type == T_ERROR_ACK) { /* Protocol error */ ret = -((tea->TLI_error == TSYSERR) ? tea->UNIX_error : EPROTO); break; } if (rc != MOREDATA || strbuf.len < sizeof(struct T_optmgmt_ack) || toa->PRIM_type != T_OPTMGMT_ACK || toa->MGMT_flags != T_SUCCESS) { ret = -ENOMSG; /* No more messages */ break; } /* * The order in which we get the statistics is determined by the kernel * and not by the group name, so we have to loop until we get the * required statistics. */ if (req->level != groupname || req->name != subgroupname) { strbuf.maxlen = BUFSIZE; strbuf.buf = buf; do { rc = getmsg(sd, NULL, &strbuf, &flags); } while (rc == MOREDATA); continue; } /* * Now when we found our stat, switch buffer to a caller-provided * one. Manipulating the size of it one can control performance, * reducing the number of getmsg calls */ strbuf.buf = statbuf; strbuf.maxlen = size; strbuf.len = 0; flags = 0; do { rc = getmsg(sd, NULL, &strbuf, &flags); switch (rc) { case -1: rc = -ENOSR; goto Return; default: rc = -ENODATA; goto Return; case MOREDATA: case 0: if (req_type == GET_NEXT && result == NEED_NEXT) /* * End of buffer, so "next" is the first item in the next * buffer */ req_type = GET_FIRST; result = getentry(req_type, (void *) strbuf.buf, strbuf.len, entrysize, resp, comp, arg); *length = strbuf.len; /* To use in caller for cacheing */ break; } } while (rc == MOREDATA && result != FOUND); if (result == FOUND) { /* Search is successful */ if (rc != MOREDATA) { ret = 0; /* Found and no more data */ } else { ret = 1; /* Found and there is another unread data block */ } break; } else { /* Restore buffers, continue search */ strbuf.buf = buf; strbuf.maxlen = BUFSIZE; } } Return: if (sd >= 0) ioctl(sd, I_FLUSH, FLUSHRW); DEBUGMSGTL(("kernel_sunos5", "...... getmib returns %d\n", ret)); return ret; }
int getstats(void) { FILE* parts; time_t now; now = time(NULL); if (cache_time + CACHE_TIMEOUT > now) { return 0; } if (!head.indices) { head.alloc = DISK_INCR; head.indices = (linux_diskio *)malloc(head.alloc*sizeof(linux_diskio)); } head.length = 0; memset(head.indices, 0, head.alloc*sizeof(linux_diskio)); /* Is this a 2.6 kernel? */ parts = fopen("/proc/diskstats", "r"); if (parts) { char buffer[1024]; while (fgets(buffer, sizeof(buffer), parts)) { linux_diskio* pTemp; if (head.length == head.alloc) { head.alloc += DISK_INCR; head.indices = (linux_diskio *)realloc(head.indices, head.alloc*sizeof(linux_diskio)); } pTemp = &head.indices[head.length]; sscanf (buffer, "%d %d", &pTemp->major, &pTemp->minor); if (sscanf (buffer, "%d %d %s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n", &pTemp->major, &pTemp->minor, pTemp->name, &pTemp->rio, &pTemp->rmerge, &pTemp->rsect, &pTemp->ruse, &pTemp->wio, &pTemp->wmerge, &pTemp->wsect, &pTemp->wuse, &pTemp->running, &pTemp->use, &pTemp->aveq) != 14) sscanf (buffer, "%d %d %s %lu %lu %lu %lu\n", &pTemp->major, &pTemp->minor, pTemp->name, &pTemp->rio, &pTemp->rsect, &pTemp->wio, &pTemp->wsect); head.length++; } } else { /* See if a 2.4 kernel */ char buffer[1024]; int rc; parts = fopen("/proc/partitions", "r"); if (!parts) { snmp_log_perror("/proc/partitions"); return 1; } /* * first few fscanfs are garbage we don't care about. skip it. */ fgets(buffer, sizeof(buffer), parts); fgets(buffer, sizeof(buffer), parts); while (! feof(parts)) { linux_diskio* pTemp; if (head.length == head.alloc) { head.alloc += DISK_INCR; head.indices = (linux_diskio *)realloc(head.indices, head.alloc*sizeof(linux_diskio)); } pTemp = &head.indices[head.length]; rc = fscanf (parts, "%d %d %lu %s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n", &pTemp->major, &pTemp->minor, &pTemp->blocks, pTemp->name, &pTemp->rio, &pTemp->rmerge, &pTemp->rsect, &pTemp->ruse, &pTemp->wio, &pTemp->wmerge, &pTemp->wsect, &pTemp->wuse, &pTemp->running, &pTemp->use, &pTemp->aveq); if (rc != 15) { snmp_log(LOG_ERR, "diskio.c: cannot find statistics in /proc/partitions\n"); return 1; } head.length++; } } fclose(parts); cache_time = now; return 0; }
int getKstat(const char *statname, const char *varname, void *value) { kstat_ctl_t *ksc; kstat_t *ks, *kstat_data; kstat_named_t *d; size_t i, instance; char module_name[64]; int ret; u_longlong_t val; /* The largest value */ void *v; static char buf[128]; if (value == NULL) { /* Pretty useless but ... */ v = (void *) &val; } else { v = value; } if (kstat_fd == 0) { kstat_fd = kstat_open(); if (kstat_fd == 0) { snmp_log_perror("kstat_open"); } } if ((ksc = kstat_fd) == NULL) { ret = -10; goto Return; /* kstat errors */ } if (statname == NULL || varname == NULL) { ret = -20; goto Return; } /* * First, get "kstat_headers" statistics. It should * contain all available modules. */ if ((ks = kstat_lookup(ksc, "unix", 0, "kstat_headers")) == NULL) { ret = -10; goto Return; /* kstat errors */ } if (kstat_read(ksc, ks, NULL) <= 0) { ret = -10; goto Return; /* kstat errors */ } kstat_data = ks->ks_data; /* * Now, look for the name of our stat in the headers buf */ for (i = 0; i < ks->ks_ndata; i++) { DEBUGMSGTL(("kernel_sunos5", "module: %s instance: %d name: %s class: %s type: %d flags: %x\n", kstat_data[i].ks_module, kstat_data[i].ks_instance, kstat_data[i].ks_name, kstat_data[i].ks_class, kstat_data[i].ks_type, kstat_data[i].ks_flags)); if (strcmp(statname, kstat_data[i].ks_name) == 0) { strcpy(module_name, kstat_data[i].ks_module); instance = kstat_data[i].ks_instance; break; } } if (i == ks->ks_ndata) { ret = -1; goto Return; /* Not found */ } /* * Get the named statistics */ if ((ks = kstat_lookup(ksc, module_name, instance, statname)) == NULL) { ret = -10; goto Return; /* kstat errors */ } if (kstat_read(ksc, ks, NULL) <= 0) { ret = -10; goto Return; /* kstat errors */ } /* * This function expects only name/value type of statistics, so if it is * not the case return an error */ if (ks->ks_type != KSTAT_TYPE_NAMED) { ret = -2; goto Return; /* Invalid stat type */ } for (i = 0, d = KSTAT_NAMED_PTR(ks); i < ks->ks_ndata; i++, d++) { DEBUGMSGTL(("kernel_sunos5", "variable: \"%s\" (type %d)\n", d->name, d->data_type)); if (strcmp(d->name, varname) == 0) { switch (d->data_type) { case KSTAT_DATA_CHAR: DEBUGMSGTL(("kernel_sunos5", "value: %s\n", d->value.c)); *(char **)v = buf; buf[sizeof(buf)-1] = 0; strncpy(buf, d->value.c, sizeof(buf)-1); break; #ifdef KSTAT_DATA_INT32 /* Solaris 2.6 and up */ case KSTAT_DATA_INT32: *(Counter *)v = d->value.i32; DEBUGMSGTL(("kernel_sunos5", "value: %d\n", d->value.i32)); break; case KSTAT_DATA_UINT32: *(Counter *)v = d->value.ui32; DEBUGMSGTL(("kernel_sunos5", "value: %u\n", d->value.ui32)); break; case KSTAT_DATA_INT64: *(int64_t *)v = d->value.i64; DEBUGMSGTL(("kernel_sunos5", "value: %ld\n", d->value.i64)); break; case KSTAT_DATA_UINT64: *(uint64_t *)v = d->value.ui64; DEBUGMSGTL(("kernel_sunos5", "value: %lu\n", d->value.ui64)); break; #else case KSTAT_DATA_LONG: *(Counter *)v = d->value.l; DEBUGMSGTL(("kernel_sunos5", "value: %ld\n", d->value.l)); break; case KSTAT_DATA_ULONG: *(Counter *)v = d->value.ul; DEBUGMSGTL(("kernel_sunos5", "value: %lu\n", d->value.ul)); break; case KSTAT_DATA_LONGLONG: *(Counter *)v = d->value.ll; DEBUGMSGTL(("kernel_sunos5", "value: %lld\n", (long)d->value.ll)); break; case KSTAT_DATA_ULONGLONG: *(Counter *)v = d->value.ull; DEBUGMSGTL(("kernel_sunos5", "value: %llu\n", (unsigned long)d->value.ull)); break; #endif case KSTAT_DATA_FLOAT: *(float *)v = d->value.f; DEBUGMSGTL(("kernel_sunos5", "value: %f\n", d->value.f)); break; case KSTAT_DATA_DOUBLE: *(double *)v = d->value.d; DEBUGMSGTL(("kernel_sunos5", "value: %f\n", d->value.d)); break; default: DEBUGMSGTL(("kernel_sunos5", "UNKNOWN TYPE %d (stat \"%s\" var \"%s\")\n", d->data_type, statname, varname)); ret = -3; goto Return; /* Invalid data type */ } ret = 0; /* Success */ goto Return; } } ret = -4; /* Name not found */ Return: return ret; }
int getKstatString(const char *statname, const char *varname, char *value, size_t value_len) { kstat_ctl_t *ksc; kstat_t *ks, *kstat_data; kstat_named_t *d; size_t i, instance; char module_name[64]; int ret; if (kstat_fd == 0) { kstat_fd = kstat_open(); if (kstat_fd == 0) { snmp_log_perror("kstat_open"); } } if ((ksc = kstat_fd) == NULL) { ret = -10; goto Return; /* kstat errors */ } if (statname == NULL || varname == NULL) { ret = -20; goto Return; } /* * First, get "kstat_headers" statistics. It should * contain all available modules. */ if ((ks = kstat_lookup(ksc, "unix", 0, "kstat_headers")) == NULL) { ret = -10; goto Return; /* kstat errors */ } if (kstat_read(ksc, ks, NULL) <= 0) { ret = -10; goto Return; /* kstat errors */ } kstat_data = ks->ks_data; /* * Now, look for the name of our stat in the headers buf */ for (i = 0; i < ks->ks_ndata; i++) { DEBUGMSGTL(("kernel_sunos5", "module: %s instance: %d name: %s class: %s type: %d flags: %x\n", kstat_data[i].ks_module, kstat_data[i].ks_instance, kstat_data[i].ks_name, kstat_data[i].ks_class, kstat_data[i].ks_type, kstat_data[i].ks_flags)); if (strcmp(statname, kstat_data[i].ks_name) == 0) { strcpy(module_name, kstat_data[i].ks_module); instance = kstat_data[i].ks_instance; break; } } if (i == ks->ks_ndata) { ret = -1; goto Return; /* Not found */ } /* * Get the named statistics */ if ((ks = kstat_lookup(ksc, module_name, instance, statname)) == NULL) { ret = -10; goto Return; /* kstat errors */ } if (kstat_read(ksc, ks, NULL) <= 0) { ret = -10; goto Return; /* kstat errors */ } /* * This function expects only name/value type of statistics, so if it is * not the case return an error */ if (ks->ks_type != KSTAT_TYPE_NAMED) { ret = -2; goto Return; /* Invalid stat type */ } for (i = 0, d = KSTAT_NAMED_PTR(ks); i < ks->ks_ndata; i++, d++) { DEBUGMSGTL(("kernel_sunos5", "variable: \"%s\" (type %d)\n", d->name, d->data_type)); if (strcmp(d->name, varname) == 0) { switch (d->data_type) { case KSTAT_DATA_CHAR: value[value_len-1] = '\0'; strncpy(value, d->value.c, value_len-1); DEBUGMSGTL(("kernel_sunos5", "value: %s\n", d->value.c)); break; default: DEBUGMSGTL(("kernel_sunos5", "NONSTRING TYPE %d (stat \"%s\" var \"%s\")\n", d->data_type, statname, varname)); ret = -3; goto Return; /* Invalid data type */ } ret = 0; /* Success */ goto Return; } } ret = -4; /* Name not found */ Return: return ret; }
int getKstatInt(const char *classname, const char *statname, const char *varname, int *value) { kstat_ctl_t *ksc; kstat_t *ks; kid_t kid; kstat_named_t *named; int ret = 0; /* fail unless ... */ if (kstat_fd == 0) { kstat_fd = kstat_open(); if (kstat_fd == 0) { snmp_log_perror("kstat_open"); } } if ((ksc = kstat_fd) == NULL) { goto Return; } ks = kstat_lookup(ksc, classname, -1, statname); if (ks == NULL) { goto Return; } kid = kstat_read(ksc, ks, NULL); if (kid == -1) { goto Return; } named = kstat_data_lookup(ks, varname); if (named == NULL) { goto Return; } ret = 1; /* maybe successful */ switch (named->data_type) { #ifdef KSTAT_DATA_INT32 /* Solaris 2.6 and up */ case KSTAT_DATA_INT32: *value = named->value.i32; break; case KSTAT_DATA_UINT32: *value = named->value.ui32; break; case KSTAT_DATA_INT64: *value = named->value.i64; break; case KSTAT_DATA_UINT64: *value = named->value.ui64; break; #else case KSTAT_DATA_LONG: *value = named->value.l; break; case KSTAT_DATA_ULONG: *value = named->value.ul; break; case KSTAT_DATA_LONGLONG: *value = named->value.ll; break; case KSTAT_DATA_ULONGLONG: *value = named->value.ull; break; #endif default: DEBUGMSGTL(("kernel_sunos5", "non-int type in kstat data: \"%s\" \"%s\" \"%s\" %d\n", classname, statname, varname, named->data_type)); ret = 0; /* fail */ break; } Return: return ret; }
static void getstat(unsigned long *cuse, unsigned long *cice, unsigned long *csys, unsigned long *cide, unsigned *pin, unsigned *pout, unsigned *swpin, unsigned *swpout, unsigned *itot, unsigned *i1, unsigned *ct, unsigned long *ciow, unsigned long *cirq, unsigned long *csoft) { int statfd, vmstatfd; static int first = 1; static char *buff = NULL, *vmbuff = NULL; static int bsize = 0, vmbsize = 0; char *b, *c; time_t now; unsigned long long cpunum; unsigned long long cusell = 0, cicell = 0, csysll = 0, cidell = 0, ciowll = 0, cirqll = 0, csoftll = 0, ctll = 0, itotll = 0, i1ll = 0; time(&now); if (cache_time + CACHE_TIMEOUT < now) { if ((statfd = open(STAT_FILE, O_RDONLY, 0)) == -1) { snmp_log_perror(STAT_FILE); return; } if (bsize == 0) { bsize = 256; buff = malloc(bsize); } while (read(statfd, buff, bsize) == bsize) { bsize += 256; buff = realloc(buff, bsize); DEBUGMSGTL(("vmstat", "/proc/stat buffer increased to %d\n", bsize)); close(statfd); statfd = open(STAT_FILE, O_RDONLY, 0); } close(statfd); if (has_vmstat && (vmstatfd = open(VMSTAT_FILE, O_RDONLY, 0)) != -1) { if (vmbsize == 0) { vmbsize = 256; vmbuff = malloc(vmbsize); } while (read(vmstatfd, vmbuff, vmbsize) == vmbsize) { vmbsize += 256; vmbuff = realloc(vmbuff, vmbsize); close(vmstatfd); vmstatfd = open(VMSTAT_FILE, O_RDONLY, 0); } close(vmstatfd); } else has_vmstat = 0; cache_time = now; } *itot = 0; *i1 = 1; c = buff; while ((c = strstr(c+1, "cpu")) != NULL) b = c; sscanf(b, "cpu%llu", &cpunum); cpunum++; b = strstr(buff, "cpu "); if (b) { if (!has_cpu_26 || sscanf(b, "cpu %llu %llu %llu %llu %llu %llu %llu", &cusell, &cicell, &csysll, &cidell, &ciowll, &cirqll, &csoftll) != 7) { has_cpu_26 = 0; sscanf(b, "cpu %llu %llu %llu %llu", &cusell, &cicell, &csysll, &cidell); *ciow = *cirq = *csoft = 0; } else { *ciow = (unsigned long)(ciowll/cpunum); *cirq = (unsigned long)(cirqll/cpunum); *csoft = (unsigned long)(csoftll/cpunum); } *cuse = (unsigned long)(cusell/cpunum); *cice = (unsigned long)(cicell/cpunum); *csys = (unsigned long)(csysll/cpunum); *cide = (unsigned long)(cidell/cpunum); } else { if (first) snmp_log(LOG_ERR, "No cpu line in %s\n", STAT_FILE); *cuse = *cice = *csys = *cide = *ciow = *cirq = *csoft = 0; } if (has_vmstat) { b = strstr(vmbuff, "pgpgin "); if (b) sscanf(b, "pgpgin %u", pin); else { if (first) snmp_log(LOG_ERR, "No pgpgin line in %s\n", VMSTAT_FILE); *pin = 0; } b = strstr(vmbuff, "pgpgout "); if (b) sscanf(b, "pgpgout %u", pout); else { if (first) snmp_log(LOG_ERR, "No pgpgout line in %s\n", VMSTAT_FILE); *pout = 0; } b = strstr(vmbuff, "pswpin "); if (b) sscanf(b, "pswpin %u", swpin); else { if (first) snmp_log(LOG_ERR, "No pswpin line in %s\n", VMSTAT_FILE); *swpin = 0; } b = strstr(vmbuff, "pswpout "); if (b) sscanf(b, "pswpout %u", swpout); else { if (first) snmp_log(LOG_ERR, "No pswpout line in %s\n", VMSTAT_FILE); *swpout = 0; } } else { b = strstr(buff, "page "); if (b) sscanf(b, "page %u %u", pin, pout); else { if (first) snmp_log(LOG_ERR, "No page line in %s\n", STAT_FILE); *pin = *pout = 0; } b = strstr(buff, "swap "); if (b) sscanf(b, "swap %u %u", swpin, swpout); else { if (first) snmp_log(LOG_ERR, "No swap line in %s\n", STAT_FILE); *swpin = *swpout = 0; } } b = strstr(buff, "intr "); if (b) { sscanf(b, "intr %llu %llu", &itotll, &i1ll); *itot = (unsigned)itotll; *i1 = (unsigned)i1ll; } else { if (first) snmp_log(LOG_ERR, "No intr line in %s\n", STAT_FILE); *itot = 0; } b = strstr(buff, "ctxt "); if (b) { sscanf(b, "ctxt %llu", &ctll); *ct = (unsigned long)ctll; } else { if (first) snmp_log(LOG_ERR, "No ctxt line in %s\n", STAT_FILE); *ct = 0; } first = 0; }
/* * Load the latest CPU usage statistics */ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { static char *buff = NULL; static int bsize = 0; static int first = 1; static int has_cpu_26 = 1; int statfd, i; char *b1, *b2; unsigned long long cusell = 0, cicell = 0, csysll = 0, cidell = 0, ciowll = 0, cirqll = 0, csoftll = 0; netsnmp_cpu_info* cpu; if ((statfd = open(STAT_FILE, O_RDONLY, 0)) == -1) { snmp_log_perror(STAT_FILE); return -1; } if (bsize == 0) { bsize = 256; buff = malloc(bsize); } while (read(statfd, buff, bsize) == bsize) { bsize += 256; buff = realloc(buff, bsize); DEBUGMSGTL(("cpu", "/proc/stat buffer increased to %d\n", bsize)); close(statfd); statfd = open(STAT_FILE, O_RDONLY, 0); } close(statfd); /* * CPU statistics (overall and per-CPU) */ b1 = buff; while ((b2 = strstr( b1, "cpu" ))) { if (b2[3] == ' ') { cpu = netsnmp_cpu_get_byIdx( -1, 0 ); if (!cpu) { snmp_log_perror("No (overall) CPU info entry"); return -1; } b1 = b2+4; /* Skip "cpu " */ } else { sscanf( b2, "cpu%d", &i ); /* Create on the fly to support non-x86 systems - see init */ cpu = netsnmp_cpu_get_byIdx( i, 1 ); if (!cpu) { snmp_log_perror("Missing CPU info entry"); break; } b1 = b2+5; /* Skip "cpuN " */ } if (!has_cpu_26 || sscanf(b1, "%llu %llu %llu %llu %llu %llu %llu", &cusell, &cicell, &csysll, &cidell, &ciowll, &cirqll, &csoftll) != 7) { has_cpu_26 = 0; sscanf(b1, "%llu %llu %llu %llu", &cusell, &cicell, &csysll, &cidell); } else { cpu->wait_ticks = (unsigned long)ciowll; cpu->intrpt_ticks = (unsigned long)cirqll; cpu->sirq_ticks = (unsigned long)csoftll; } cpu->user_ticks = (unsigned long)cusell; cpu->nice_ticks = (unsigned long)cicell; cpu->sys_ticks = (unsigned long)csysll; cpu->idle_ticks = (unsigned long)cidell; } if ( b1 == buff ) { if (first) snmp_log(LOG_ERR, "No cpu line in %s\n", STAT_FILE); } /* * Interrupt/Context Switch statistics * XXX - Do these really belong here ? */ cpu = netsnmp_cpu_get_byIdx( -1, 0 ); _cpu_load_swap_etc( buff, cpu ); /* * XXX - TODO: extract per-CPU statistics * (Into separate netsnmp_cpu_info data structures) */ first = 0; return 0; }
/* * Load the latest memory usage statistics */ int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) { int statfd; static char *buff = NULL; static int bsize = 0; static int first = 1; ssize_t bytes_read; char *b; unsigned long memtotal = 0, memfree = 0, memshared = 0, buffers = 0, cached = 0, swaptotal = 0, swapfree = 0; netsnmp_memory_info *mem; /* * Retrieve the memory information from the underlying O/S... */ if ((statfd = open(MEMINFO_FILE, O_RDONLY, 0)) == -1) { snmp_log_perror(MEMINFO_FILE); return -1; } if (bsize == 0) { bsize = MEMINFO_INIT_SIZE; buff = malloc(bsize); if (NULL == buff) { snmp_log(LOG_ERR, "malloc failed\n"); return -1; } } while ((bytes_read = read(statfd, buff, bsize)) == bsize) { b = realloc(buff, bsize + MEMINFO_STEP_SIZE); if (NULL == b) { snmp_log(LOG_ERR, "malloc failed\n"); return -1; } buff = b; bsize += MEMINFO_STEP_SIZE; DEBUGMSGTL(("mem", "/proc/meminfo buffer increased to %d\n", bsize)); close(statfd); statfd = open(MEMINFO_FILE, O_RDONLY, 0); if (statfd == -1) { snmp_log_perror(MEMINFO_FILE); return -1; } } close(statfd); if (bytes_read <= 0) { snmp_log_perror(MEMINFO_FILE); } /* * ... parse this into a more useable form... */ b = strstr(buff, "MemTotal: "); if (b) sscanf(b, "MemTotal: %lu", &memtotal); else { if (first) snmp_log(LOG_ERR, "No MemTotal line in /proc/meminfo\n"); } b = strstr(buff, "MemFree: "); if (b) sscanf(b, "MemFree: %lu", &memfree); else { if (first) snmp_log(LOG_ERR, "No MemFree line in /proc/meminfo\n"); } b = strstr(buff, "MemShared: "); if (b) sscanf(b, "MemShared: %lu", &memshared); else { if (first) if (0 == netsnmp_os_prematch("Linux","2.4")) snmp_log(LOG_ERR, "No MemShared line in /proc/meminfo\n"); } b = strstr(buff, "Buffers: "); if (b) sscanf(b, "Buffers: %lu", &buffers); else { if (first) snmp_log(LOG_ERR, "No Buffers line in /proc/meminfo\n"); } b = strstr(buff, "Cached: "); if (b) sscanf(b, "Cached: %lu", &cached); else { if (first) snmp_log(LOG_ERR, "No Cached line in /proc/meminfo\n"); } b = strstr(buff, "SwapTotal: "); if (b) sscanf(b, "SwapTotal: %lu", &swaptotal); else { if (first) snmp_log(LOG_ERR, "No SwapTotal line in /proc/meminfo\n"); } b = strstr(buff, "SwapFree: "); if (b) sscanf(b, "SwapFree: %lu", &swapfree); else { if (first) snmp_log(LOG_ERR, "No SwapFree line in /proc/meminfo\n"); } first = 0; /* * ... and save this in a standard form. */ mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 1 ); if (!mem) { snmp_log_perror("No Physical Memory info entry"); } else { if (!mem->descr) mem->descr = strdup("Physical memory"); mem->units = 1024; mem->size = memtotal; mem->free = memfree; mem->other = -1; } mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_VIRTMEM, 1 ); if (!mem) { snmp_log_perror("No Virtual Memory info entry"); } else { if (!mem->descr) mem->descr = strdup("Virtual memory"); mem->units = 1024; mem->size = memtotal+swaptotal; mem->free = memfree +swapfree; mem->other = -1; } mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SHARED, 1 ); if (!mem) { snmp_log_perror("No Shared Memory info entry"); } else { if (!mem->descr) mem->descr = strdup("Shared memory"); mem->units = 1024; mem->size = memshared; mem->free = -1; mem->other = -1; } mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_CACHED, 1 ); if (!mem) { snmp_log_perror("No Cached Memory info entry"); } else { if (!mem->descr) mem->descr = strdup("Cached memory"); mem->units = 1024; mem->size = cached; mem->free = -1; mem->other = -1; } mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 1 ); if (!mem) { snmp_log_perror("No Swap info entry"); } else { if (!mem->descr) mem->descr = strdup("Swap space"); mem->units = 1024; mem->size = swaptotal; mem->free = swapfree; mem->other = -1; } mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_MBUF, 1 ); if (!mem) { snmp_log_perror("No Buffer, etc info entry"); } else { if (!mem->descr) mem->descr = strdup("Memory buffers"); mem->units = 1024; mem->size = buffers; mem->free = -1; mem->other = -1; } return 0; }
/*******************************************************************-o-****** * setup_engineID * * Parameters: * **eidp * *text Printable (?) text to be plugged into the snmpEngineID. * * Return: * Length of allocated engineID string in bytes, -OR- * -1 on error. * * * Create an snmpEngineID using text and the local IP address. If eidp * is defined, use it to return a pointer to the newly allocated data. * Otherwise, use the result to define engineID defined in this module. * * Line syntax: * engineID <text> | NULL * * XXX What if a node has multiple interfaces? * XXX What if multiple engines all choose the same address? * (answer: You're screwed, because you might need a kul database * which is dependant on the current engineID. Enumeration and other * tricks won't work). */ int setup_engineID(u_char ** eidp, const char *text) { int enterpriseid = htonl(ENTERPRISE_OID), netsnmpoid = htonl(NETSNMP_OID), localsetup = (eidp) ? 0 : 1; /* * Use local engineID if *eidp == NULL. */ #ifdef HAVE_GETHOSTNAME u_char buf[SNMP_MAXBUF_SMALL]; struct hostent *hent = NULL; #endif u_char *bufp = NULL; size_t len; int localEngineIDType = engineIDType; int tmpint; time_t tmptime; engineIDIsSet = 1; #ifdef HAVE_GETHOSTNAME #ifdef AF_INET6 /* * see if they selected IPV4 or IPV6 support */ if ((ENGINEID_TYPE_IPV6 == localEngineIDType) || (ENGINEID_TYPE_IPV4 == localEngineIDType)) { /* * get the host name and save the information */ gethostname((char *) buf, sizeof(buf)); hent = gethostbyname((char *) buf); if (hent && hent->h_addrtype == AF_INET6) { localEngineIDType = ENGINEID_TYPE_IPV6; } else { /* * Not IPV6 so we go with default */ localEngineIDType = ENGINEID_TYPE_IPV4; } } #else /* * No IPV6 support. Check if they selected IPV6 engineID type. * If so make it IPV4 instead */ if (ENGINEID_TYPE_IPV6 == localEngineIDType) { localEngineIDType = ENGINEID_TYPE_IPV4; } if (ENGINEID_TYPE_IPV4 == localEngineIDType) { /* * get the host name and save the information */ gethostname((char *) buf, sizeof(buf)); hent = gethostbyname((char *) buf); } #endif #endif /* HAVE_GETHOSTNAME */ /* * Determine if we have text and if so setup our localEngineIDType * * appropriately. */ if (NULL != text) { engineIDType = localEngineIDType = ENGINEID_TYPE_TEXT; } /* * Determine length of the engineID string. */ len = 5; /* always have 5 leading bytes */ switch (localEngineIDType) { case ENGINEID_TYPE_TEXT: len += strlen(text); /* 5 leading bytes+text. No NULL char */ break; #if defined(IFHWADDRLEN) && defined(SIOCGIFHWADDR) case ENGINEID_TYPE_MACADDR: /* MAC address */ len += 6; /* + 6 bytes for MAC address */ break; #endif case ENGINEID_TYPE_IPV4: /* IPv4 */ len += 4; /* + 4 byte IPV4 address */ break; case ENGINEID_TYPE_IPV6: /* IPv6 */ len += 16; /* + 16 byte IPV6 address */ break; case ENGINEID_TYPE_NETSNMP_RND: /* Net-SNMP specific encoding */ if (engineID) /* already setup, keep current value */ return engineIDLength; if (oldEngineID) { len = oldEngineIDLength; } else { len += sizeof(int) + sizeof(time_t); } break; default: snmp_log(LOG_ERR, "Unknown EngineID type requested for setup (%d). Using IPv4.\n", localEngineIDType); localEngineIDType = ENGINEID_TYPE_IPV4; /* make into IPV4 */ len += 4; /* + 4 byte IPv4 address */ break; } /* switch */ /* * Allocate memory and store enterprise ID. */ if ((bufp = (u_char *) malloc(len)) == NULL) { snmp_log_perror("setup_engineID malloc"); return -1; } if (localEngineIDType == ENGINEID_TYPE_NETSNMP_RND) /* * we must use the net-snmp enterprise id here, regardless */ memcpy(bufp, &netsnmpoid, sizeof(netsnmpoid)); /* XXX Must be 4 bytes! */ else memcpy(bufp, &enterpriseid, sizeof(enterpriseid)); /* XXX Must be 4 bytes! */ bufp[0] |= 0x80; /* * Store the given text -OR- the first found IP address * -OR- the MAC address -OR- random elements * (the latter being the recommended default) */ switch (localEngineIDType) { case ENGINEID_TYPE_NETSNMP_RND: if (oldEngineID) { /* * keep our previous notion of the engineID */ memcpy(bufp, oldEngineID, oldEngineIDLength); } else { /* * Here we've desigend our own ENGINEID that is not based on * an address which may change and may even become conflicting * in the future like most of the default v3 engineID types * suffer from. * * Ours is built from 2 fairly random elements: a random number and * the current time in seconds. This method suffers from boxes * that may not have a correct clock setting and random number * seed at startup, but few OSes should have that problem. */ bufp[4] = ENGINEID_TYPE_NETSNMP_RND; tmpint = random(); memcpy(bufp + 5, &tmpint, sizeof(tmpint)); tmptime = time(NULL); memcpy(bufp + 5 + sizeof(tmpint), &tmptime, sizeof(tmptime)); } break; case ENGINEID_TYPE_TEXT: bufp[4] = ENGINEID_TYPE_TEXT; memcpy((char *) bufp + 5, text, strlen(text)); break; #ifdef HAVE_GETHOSTNAME #ifdef AF_INET6 case ENGINEID_TYPE_IPV6: bufp[4] = ENGINEID_TYPE_IPV6; memcpy(bufp + 5, hent->h_addr_list[0], hent->h_length); break; #endif #endif #if defined(IFHWADDRLEN) && defined(SIOCGIFHWADDR) case ENGINEID_TYPE_MACADDR: { int x; bufp[4] = ENGINEID_TYPE_MACADDR; /* * use default NIC if none provided */ if (NULL == engineIDNic) { x = getHwAddress(DEFAULT_NIC, &bufp[5]); } else { x = getHwAddress(engineIDNic, &bufp[5]); } if (0 != x) /* * function failed fill MAC address with zeros */ { memset(&bufp[5], 0, 6); } } break; #endif case ENGINEID_TYPE_IPV4: default: bufp[4] = ENGINEID_TYPE_IPV4; #ifdef HAVE_GETHOSTNAME if (hent && hent->h_addrtype == AF_INET) { memcpy(bufp + 5, hent->h_addr_list[0], hent->h_length); } else { /* Unknown address type. Default to 127.0.0.1. */ bufp[5] = 127; bufp[6] = 0; bufp[7] = 0; bufp[8] = 1; } #else /* HAVE_GETHOSTNAME */ /* * Unknown address type. Default to 127.0.0.1. */ bufp[5] = 127; bufp[6] = 0; bufp[7] = 0; bufp[8] = 1; #endif /* HAVE_GETHOSTNAME */ break; } /* * Pass the string back to the calling environment, or use it for * our local engineID. */ if (localsetup) { SNMP_FREE(engineID); engineID = bufp; engineIDLength = len; } else { *eidp = bufp; } return len; } /* end setup_engineID() */
int write_rte(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t length) { struct rtent *rp; int var; long val; u_long dst; char buf[8]; u_short flags; int oldty; /* * object identifier is of form: * 1.3.6.1.2.1.4.21.1.X.A.B.C.D , where A.B.C.D is IP address. * IPADDR starts at offset 10. */ if (length != 14) { snmp_log(LOG_ERR, "length error\n"); return SNMP_ERR_NOCREATION; } var = name[9]; dst = *((u_long *) & name[10]); rp = findCacheRTE(dst); if (!rp) { rp = cacheKernelRTE(dst); } if (action == RESERVE1 && !rp) { rp = newCacheRTE(); if (!rp) { snmp_log(LOG_ERR, "newCacheRTE"); return SNMP_ERR_RESOURCEUNAVAILABLE; } rp->rt_type = rp->xx_type = 2; } else if (action == COMMIT) { } else if (action == FREE) { if (rp->rt_type == 2) { /* was invalid before */ delCacheRTE(dst); } } switch (var) { case IPROUTEDEST: if (action == RESERVE1) { if (var_val_type != ASN_OCTET_STR) { snmp_log(LOG_ERR, "not octet"); return SNMP_ERR_WRONGTYPE; } memcpy(buf, var_val, (var_val_len > 8) ? 8 : var_val_len); if (var_val_type != ASN_OCTET_STR) { snmp_log(LOG_ERR, "not octet2"); return SNMP_ERR_WRONGTYPE; } rp->xx_dst = *((u_long *) buf); } else if (action == COMMIT) { rp->rt_dst = rp->xx_dst; } break; case IPROUTEMETRIC1: if (action == RESERVE1) { if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "not int1"); return SNMP_ERR_WRONGTYPE; } val = *((long *) var_val); if (val < -1) { snmp_log(LOG_ERR, "not right1"); return SNMP_ERR_WRONGVALUE; } rp->xx_metric1 = val; } else if (action == RESERVE2) { if ((rp->xx_metric1 == 1) && (rp->xx_type != 4)) { snmp_log(LOG_ERR, "reserve2 failed\n"); return SNMP_ERR_WRONGVALUE; } } else if (action == COMMIT) { rp->rt_metric1 = rp->xx_metric1; } break; case IPROUTEIFINDEX: if (action == RESERVE1) { if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "not right2"); return SNMP_ERR_WRONGTYPE; } val = *((long *) var_val); if (val <= 0) { snmp_log(LOG_ERR, "not right3"); return SNMP_ERR_WRONGVALUE; } rp->xx_ifix = val; } else if (action == COMMIT) { rp->rt_ifix = rp->xx_ifix; } break; case IPROUTENEXTHOP: if (action == RESERVE1) { if (var_val_type != ASN_OCTET_STR) { snmp_log(LOG_ERR, "not right4"); return SNMP_ERR_WRONGTYPE; } memcpy(buf, var_val, (var_val_len > 8) ? 8 : var_val_len); if (var_val_type != ASN_OCTET_STR) { snmp_log(LOG_ERR, "not right5"); return SNMP_ERR_WRONGTYPE; } rp->xx_nextIR = *((u_long *) buf); } else if (action == COMMIT) { rp->rt_nextIR = rp->xx_nextIR; } case IPROUTETYPE: /* * flag meaning: * * IPROUTEPROTO (rt_proto): none: (cant set == 3 (netmgmt)) * * IPROUTEMETRIC1: 1 iff gateway, 0 otherwise * IPROUTETYPE: 4 iff gateway, 3 otherwise */ if (action == RESERVE1) { if (var_val_type != ASN_INTEGER) { return SNMP_ERR_WRONGTYPE; } val = *((long *) var_val); if ((val < 2) || (val > 4)) { /* only accept invalid, direct, indirect */ snmp_log(LOG_ERR, "not right6"); return SNMP_ERR_WRONGVALUE; } rp->xx_type = val; } else if (action == COMMIT) { oldty = rp->rt_type; rp->rt_type = rp->xx_type; if (rp->rt_type == 2) { /* invalid, so delete from kernel */ if (delRoute (rp->rt_dst, rp->rt_nextIR, rp->rt_ifix, rp->old_flags) < 0) { snmp_log_perror("delRoute"); } } else { /* * it must be valid now, so flush to kernel */ if (oldty != 2) { /* was the old entry valid ? */ if (delRoute (rp->old_dst, rp->old_nextIR, rp->old_ifix, rp->old_flags) < 0) { snmp_log_perror("delRoute"); } } /* * not invalid, so remove from cache */ flags = (rp->rt_type == 4 ? RTF_GATEWAY : 0); if (addRoute(rp->rt_dst, rp->rt_nextIR, rp->rt_ifix, flags) < 0) { snmp_log_perror("addRoute"); } delCacheRTE(rp->rt_type); } } break; case IPROUTEPROTO: default: DEBUGMSGTL(("snmpd", "unknown sub-id %d in write_rte\n", var)); return SNMP_ERR_NOCREATION; } return SNMP_ERR_NOERROR; }
/*******************************************************************-o-****** * setup_engineID * * Parameters: * **eidp * *text Printable (?) text to be plugged into the snmpEngineID. * * Return: * Length of allocated engineID string in bytes, -OR- * -1 on error. * * * Create an snmpEngineID using text and the local IP address. If eidp * is defined, use it to return a pointer to the newly allocated data. * Otherwise, use the result to define engineID defined in this module. * * Line syntax: * engineID <text> | NULL * * XXX What if a node has multiple interfaces? * XXX What if multiple engines all choose the same address? * (answer: You're screwed, because you might need a kul database * which is dependant on the current engineID. Enumeration and other * tricks won't work). */ int setup_engineID(u_char **eidp, const char *text) { int enterpriseid = htonl(ENTERPRISE_NUMBER), localsetup = (eidp) ? 0 : 1; /* Use local engineID if *eidp == NULL. */ #ifdef HAVE_GETHOSTNAME u_char buf[SNMP_MAXBUF_SMALL]; struct hostent *hent; #endif u_char *bufp = NULL; size_t len; /* * Determine length of the engineID string. */ if (text) { len = 5+strlen(text); /* 5 leading bytes+text. */ } else { len = 5 + 4; /* 5 leading bytes + four byte IPv4 address */ #ifdef HAVE_GETHOSTNAME gethostname((char *)buf, sizeof(buf)); hent = gethostbyname((char *)buf); #ifdef AF_INET6 if (hent && hent->h_addrtype == AF_INET6) len += 12; /* 16 bytes total for IPv6 address. */ #endif #endif /* HAVE_GETHOSTNAME */ } /* endif -- text (1) */ /* * Allocate memory and store enterprise ID. */ if ((bufp = (u_char *) malloc(len)) == NULL) { snmp_log_perror("setup_engineID malloc"); return -1; } memcpy(bufp, &enterpriseid, sizeof(enterpriseid)); /* XXX Must be 4 bytes! */ bufp[0] |= 0x80; /* * Store the given text -OR- the first found IP address. */ if (text) { bufp[4] = 4; memcpy((char *)bufp+5, text, strlen(text)); } else { bufp[4] = 1; #ifdef HAVE_GETHOSTNAME gethostname((char *)buf, sizeof(buf)); hent = gethostbyname((char *)buf); if (hent && hent->h_addrtype == AF_INET) { memcpy(bufp+5, hent->h_addr_list[0], hent->h_length); #ifdef AF_INET6 } else if (hent && hent->h_addrtype == AF_INET6) { bufp[4] = 2; memcpy(bufp+5, hent->h_addr_list[0], hent->h_length); #endif } else { /* Unknown address type. Default to 127.0.0.1. */ bufp[5] = 127; bufp[6] = 0; bufp[7] = 0; bufp[8] = 1; } #else /* HAVE_GETHOSTNAME */ /* Unknown address type. Default to 127.0.0.1. */ bufp[5] = 127; bufp[6] = 0; bufp[7] = 0; bufp[8] = 1; #endif /* HAVE_GETHOSTNAME */ } /* endif -- text (2) */ /* * Pass the string back to the calling environment, or use it for * our local engineID. */ if (localsetup) { SNMP_FREE(engineID); engineID = bufp; engineIDLength = len; } else { *eidp = bufp; } return len; } /* end setup_engineID() */
int main(int argc, char *argv[]) #endif { static const char options[] = "aAc:CdD::fhHI:l:L:m:M:n:p:P:qrsS:UvV-:Y:" #if HAVE_UNISTD_H "g:u:" #endif #if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE) "x:" #endif #ifdef USING_AGENTX_SUBAGENT_MODULE "X" #endif ; int arg, i, ret, exit_code = 1; int dont_fork = 0, do_help = 0; int log_set = 0; int agent_mode = -1; char *pid_file = NULL; char option_compatability[] = "-Le"; #ifndef WIN32 int prepared_sockets = 0; #endif #if HAVE_GETPID int fd; FILE *PID; #endif SOCK_STARTUP; #ifndef NETSNMP_NO_SYSTEMD /* check if systemd has sockets for us and don't close them */ prepared_sockets = netsnmp_sd_listen_fds(0); #endif /* NETSNMP_NO_SYSTEMD */ #ifndef WIN32 /* * close all non-standard file descriptors we may have * inherited from the shell. */ if (!prepared_sockets) netsnmp_close_fds(2); #endif /* * register signals ASAP to prevent default action (usually core) * for signals during startup... */ #ifdef SIGTERM DEBUGMSGTL(("signal", "registering SIGTERM signal handler\n")); signal(SIGTERM, SnmpdShutDown); #endif #ifdef SIGINT DEBUGMSGTL(("signal", "registering SIGINT signal handler\n")); signal(SIGINT, SnmpdShutDown); #endif #ifdef SIGHUP signal(SIGHUP, SIG_IGN); /* do not terminate on early SIGHUP */ #endif #ifdef SIGUSR1 DEBUGMSGTL(("signal", "registering SIGUSR1 signal handler\n")); signal(SIGUSR1, SnmpdDump); #endif #ifdef SIGPIPE DEBUGMSGTL(("signal", "registering SIGPIPE signal handler\n")); signal(SIGPIPE, SIG_IGN); /* 'Inline' failure of wayward readers */ #endif #ifdef SIGXFSZ signal(SIGXFSZ, SnmpdCatchRandomSignal); #endif #ifdef NETSNMP_NO_ROOT_ACCESS /* * Default to no. */ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1); #endif /* * Default to NOT running an AgentX master. */ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_MASTER, 0); netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_TIMEOUT, -1); netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_RETRIES, -1); netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_CACHE_TIMEOUT, 5); /* * This is incredibly ugly, but it's probably the simplest way * to handle the old '-L' option as well as the new '-Lx' style */ for (i=0; i<argc; i++) { if (!strcmp(argv[i], "-L")) argv[i] = option_compatability; } #ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG #ifdef WIN32 snmp_log_syslogname(app_name_long); #else snmp_log_syslogname(app_name); #endif #endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */ netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE, app_name); /* * Now process options normally. */ while ((arg = getopt(argc, argv, options)) != EOF) { switch (arg) { case '-': if (strcasecmp(optarg, "help") == 0) { usage(argv[0]); goto out; } if (strcasecmp(optarg, "version") == 0) { version(); exit_code = 0; goto out; } handle_long_opt(optarg); break; case 'a': log_addresses++; break; case 'A': netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPEND_LOGFILES, 1); break; case 'c': if (optarg != NULL) { netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OPTIONALCONFIG, optarg); } else { usage(argv[0]); } break; case 'C': netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1); break; case 'd': netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DUMP_PACKET, ++snmp_dump_packet); break; case 'D': #ifdef NETSNMP_DISABLE_DEBUGGING fprintf(stderr, "Debugging not configured\n"); goto out; #else debug_register_tokens(optarg); snmp_set_do_debugging(1); #endif break; case 'f': dont_fork = 1; break; #if HAVE_UNISTD_H case 'g': if (optarg != NULL) { char *ecp; int gid; gid = strtoul(optarg, &ecp, 10); #if HAVE_GETGRNAM && HAVE_PWD_H if (*ecp) { struct group *info; info = getgrnam(optarg); gid = info ? info->gr_gid : -1; endgrent(); } #endif if (gid < 0) { fprintf(stderr, "Bad group id: %s\n", optarg); goto out; } netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_GROUPID, gid); } else { usage(argv[0]); } break; #endif case 'h': usage(argv[0]); break; case 'H': do_help = 1; break; case 'I': if (optarg != NULL) { add_to_init_list(optarg); } else { usage(argv[0]); } break; #ifndef NETSNMP_FEATURE_REMOVE_LOGGING_FILE case 'l': printf("Warning: -l option is deprecated, use -Lf <file> instead\n"); if (optarg != NULL) { if (strlen(optarg) > PATH_MAX) { fprintf(stderr, "%s: logfile path too long (limit %d chars)\n", argv[0], PATH_MAX); goto out; } snmp_enable_filelog(optarg, netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPEND_LOGFILES)); log_set = 1; } else { usage(argv[0]); } break; #endif /* NETSNMP_FEATURE_REMOVE_LOGGING_FILE */ case 'L': if (snmp_log_options( optarg, argc, argv ) < 0 ) { usage(argv[0]); } log_set = 1; break; case 'm': if (optarg != NULL) { setenv("MIBS", optarg, 1); } else { usage(argv[0]); } break; case 'M': if (optarg != NULL) { setenv("MIBDIRS", optarg, 1); } else { usage(argv[0]); } break; case 'n': if (optarg != NULL) { app_name = optarg; netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE, app_name); } else { usage(argv[0]); } break; case 'P': printf("Warning: -P option is deprecated, use -p instead\n"); /* FALL THROUGH */ case 'p': if (optarg != NULL) { pid_file = optarg; } else { usage(argv[0]); } break; case 'q': netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, 1); break; case 'r': netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS); break; #ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG case 's': printf("Warning: -s option is deprecated, use -Lsd instead\n"); snmp_enable_syslog(); log_set = 1; break; case 'S': printf("Warning: -S option is deprecated, use -Ls <facility> instead\n"); if (optarg != NULL) { switch (*optarg) { case 'd': case 'D': Facility = LOG_DAEMON; break; case 'i': case 'I': Facility = LOG_INFO; break; case '0': Facility = LOG_LOCAL0; break; case '1': Facility = LOG_LOCAL1; break; case '2': Facility = LOG_LOCAL2; break; case '3': Facility = LOG_LOCAL3; break; case '4': Facility = LOG_LOCAL4; break; case '5': Facility = LOG_LOCAL5; break; case '6': Facility = LOG_LOCAL6; break; case '7': Facility = LOG_LOCAL7; break; default: fprintf(stderr, "invalid syslog facility: -S%c\n",*optarg); usage(argv[0]); } snmp_enable_syslog_ident(snmp_log_syslogname(NULL), Facility); log_set = 1; } else { fprintf(stderr, "no syslog facility specified\n"); usage(argv[0]); } break; #endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */ case 'U': netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_LEAVE_PIDFILE); break; #if HAVE_UNISTD_H case 'u': if (optarg != NULL) { char *ecp; int uid; uid = strtoul(optarg, &ecp, 10); #if HAVE_GETPWNAM && HAVE_PWD_H if (*ecp) { struct passwd *info; info = getpwnam(optarg); uid = info ? info->pw_uid : -1; endpwent(); } #endif if (uid < 0) { fprintf(stderr, "Bad user id: %s\n", optarg); goto out; } netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_USERID, uid); } else { usage(argv[0]); } break; #endif case 'v': version(); exit_code = 0; goto out; case 'V': netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_VERBOSE, 1); break; #if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE) case 'x': if (optarg != NULL) { netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, optarg); } else { usage(argv[0]); } netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_MASTER, 1); break; #endif case 'X': #if defined(USING_AGENTX_SUBAGENT_MODULE) agent_mode = SUB_AGENT; #else fprintf(stderr, "%s: Illegal argument -X:" "AgentX support not compiled in.\n", argv[0]); usage(argv[0]); goto out; #endif break; case 'Y': netsnmp_config_remember(optarg); break; default: usage(argv[0]); break; } } if (do_help) { netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1); init_agent(app_name); /* register our .conf handlers */ init_mib_modules(); init_snmp(app_name); fprintf(stderr, "Configuration directives understood:\n"); read_config_print_usage(" "); exit_code = 0; goto out; } if (optind < argc) { #ifndef NETSNMP_NO_LISTEN_SUPPORT /* * There are optional transport addresses on the command line. */ DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind, argc)); for (i = optind; i < argc; i++) { char *c, *astring; if ((c = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PORTS))) { astring = (char*)malloc(strlen(c) + 2 + strlen(argv[i])); if (astring == NULL) { fprintf(stderr, "malloc failure processing argv[%d]\n", i); goto out; } sprintf(astring, "%s,%s", c, argv[i]); netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PORTS, astring); SNMP_FREE(astring); } else { netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PORTS, argv[i]); } } DEBUGMSGTL(("snmpd/main", "port spec: %s\n", netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PORTS))); #else /* NETSNMP_NO_LISTEN_SUPPORT */ fprintf(stderr, "You specified ports to open; this agent was built to only send notifications\n"); goto out; #endif /* NETSNMP_NO_LISTEN_SUPPORT */ } #if defined(NETSNMP_DAEMONS_DEFAULT_LOG_SYSLOG) if (0 == log_set) snmp_enable_syslog(); #else #ifdef NETSNMP_LOGFILE #ifndef NETSNMP_FEATURE_REMOVE_LOGGING_FILE if (0 == log_set) snmp_enable_filelog(NETSNMP_LOGFILE, netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPEND_LOGFILES)); #endif /* NETSNMP_FEATURE_REMOVE_LOGGING_FILE */ #endif /* NETSNMP_LOGFILE */ #endif /* ! NETSNMP_DEFAULT_LOG_SYSLOG */ #ifdef USING_UTIL_FUNCS_RESTART_MODULE { /* * Initialize a argv set to the current for restarting the agent. */ char *cptr, **argvptr; argvrestartp = (char **)malloc((argc + 2) * sizeof(char *)); argvptr = argvrestartp; for (i = 0, ret = 1; i < argc; i++) { ret += strlen(argv[i]) + 1; } argvrestart = (char *) malloc(ret); argvrestartname = (char *) malloc(strlen(argv[0]) + 1); if (!argvrestartp || !argvrestart || !argvrestartname) { fprintf(stderr, "malloc failure processing argvrestart\n"); goto out; } strcpy(argvrestartname, argv[0]); for (cptr = argvrestart, i = 0; i < argc; i++) { strcpy(cptr, argv[i]); *(argvptr++) = cptr; cptr += strlen(argv[i]) + 1; } } #endif /* USING_UTIL_FUNCS_RESTART_MODULE */ if (agent_mode == -1) { if (strstr(argv[0], "agentxd") != NULL) { netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, SUB_AGENT); } else { netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, MASTER_AGENT); } } else { netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, agent_mode); } if (init_agent(app_name) != 0) { snmp_log(LOG_ERR, "Agent initialization failed\n"); goto out; } init_mib_modules(); /* * start library */ init_snmp(app_name); if ((ret = init_master_agent()) != 0) { /* * Some error opening one of the specified agent transports. */ snmp_log(LOG_ERR, "Server Exiting with code 1\n"); goto out; } /* * Initialize the world. Detach from the shell. Create initial user. */ if(!dont_fork) { int quit = ! netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_QUIT_IMMEDIATELY); ret = netsnmp_daemonize(quit, #ifndef NETSNMP_FEATURE_REMOVE_LOGGING_STDIO snmp_stderrlog_status() #else /* NETSNMP_FEATURE_REMOVE_LOGGING_STDIO */ 0 #endif /* NETSNMP_FEATURE_REMOVE_LOGGING_STDIO */ ); /* * xxx-rks: do we care if fork fails? I think we should... */ if(ret != 0) { snmp_log(LOG_ERR, "Server Exiting with code 1\n"); goto out; } } #if HAVE_GETPID if (pid_file != NULL) { /* * unlink the pid_file, if it exists, prior to open. Without * doing this the open will fail if the user specified pid_file * already exists. */ unlink(pid_file); fd = open(pid_file, O_CREAT | O_EXCL | O_WRONLY, 0600); if (fd == -1) { snmp_log_perror(pid_file); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { goto out; } } else { if ((PID = fdopen(fd, "w")) == NULL) { snmp_log_perror(pid_file); goto out; } else { fprintf(PID, "%d\n", (int) getpid()); fclose(PID); } #ifndef _MSC_VER /* The sequence open()/fdopen()/fclose()/close() makes MSVC crash, hence skip the close() call when using the MSVC runtime. */ close(fd); #endif } } #endif #if defined(HAVE_UNISTD_H) && (defined(HAVE_CHOWN) || defined(HAVE_SETGID) || defined(HAVE_SETUID)) { const char *persistent_dir; int uid, gid; persistent_dir = get_persistent_directory(); mkdirhier( persistent_dir, NETSNMP_AGENT_DIRECTORY_MODE, 0 ); uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_USERID); gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_GROUPID); #ifdef HAVE_CHOWN if ( uid != 0 || gid != 0 ) chown( persistent_dir, uid, gid ); #endif #ifdef HAVE_SETGID if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_GROUPID)) > 0) { DEBUGMSGTL(("snmpd/main", "Changing gid to %d.\n", gid)); if (setgid(gid) == -1 #ifdef HAVE_SETGROUPS || setgroups(1, (gid_t *)&gid) == -1 #endif ) { snmp_log_perror("setgid failed"); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { goto out; } } } #endif #ifdef HAVE_SETUID if ((uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_USERID)) > 0) { #if HAVE_GETPWNAM && HAVE_PWD_H && HAVE_INITGROUPS struct passwd *info; /* * Set supplementary groups before changing UID * (which probably involves giving up privileges) */ info = getpwuid(uid); if (info) { DEBUGMSGTL(("snmpd/main", "Supplementary groups for %s.\n", info->pw_name)); if (initgroups(info->pw_name, (gid != 0 ? (gid_t)gid : info->pw_gid)) == -1) { snmp_log_perror("initgroups failed"); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { goto out; } } } endpwent(); #endif DEBUGMSGTL(("snmpd/main", "Changing uid to %d.\n", uid)); if (setuid(uid) == -1) { snmp_log_perror("setuid failed"); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { goto out; } } } #endif } #endif /* * Store persistent data immediately in case we crash later. */ snmp_store(app_name); #ifdef SIGHUP DEBUGMSGTL(("signal", "registering SIGHUP signal handler\n")); signal(SIGHUP, SnmpdReconfig); #endif /* * Send coldstart trap if possible. */ send_easy_trap(0, 0); /* * We're up, log our version number. */ snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version()); #ifdef WIN32SERVICE agent_status = AGENT_RUNNING; #endif netsnmp_addrcache_initialise(); /* * Let systemd know we're up. */ #ifndef NETSNMP_NO_SYSTEMD netsnmp_sd_notify(1, "READY=1\n"); if (prepared_sockets) /* * Clear the environment variable, we already processed all the sockets * by now. */ netsnmp_sd_listen_fds(1); #endif /* * Forever monitor the dest_port for incoming PDUs. */ DEBUGMSGTL(("snmpd/main", "We're up. Starting to process data.\n")); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_QUIT_IMMEDIATELY)) receive(); DEBUGMSGTL(("snmpd/main", "sending shutdown trap\n")); SnmpTrapNodeDown(); DEBUGMSGTL(("snmpd/main", "Bye...\n")); snmp_shutdown(app_name); shutdown_master_agent(); shutdown_agent(); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_LEAVE_PIDFILE) && (pid_file != NULL)) { unlink(pid_file); } #ifdef WIN32SERVICE agent_status = AGENT_STOPPED; #endif #ifdef USING_UTIL_FUNCS_RESTART_MODULE SNMP_FREE(argvrestartname); SNMP_FREE(argvrestart); SNMP_FREE(argvrestartp); #endif /* USING_UTIL_FUNCS_RESTART_MODULE */ exit_code = 0; out: SOCK_CLEANUP; return exit_code; } /* End main() -- snmpd */
static void snmptrapd_main_loop(void) { int count, numfds, block; fd_set readfds,writefds,exceptfds; struct timeval timeout, *tvp; while (netsnmp_running) { if (reconfig) { /* * If we are logging to a file, receipt of SIGHUP also * indicates that the log file should be closed and * re-opened. This is useful for users that want to * rotate logs in a more predictable manner. */ netsnmp_logging_restart(); snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n", netsnmp_get_version()); trapd_update_config(); if (trap1_fmt_str_remember) { parse_format( NULL, trap1_fmt_str_remember ); } reconfig = 0; } numfds = 0; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); block = 0; tvp = &timeout; timerclear(tvp); tvp->tv_sec = 5; snmp_select_info(&numfds, &readfds, tvp, &block); if (block == 1) tvp = NULL; /* block without timeout */ #ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER netsnmp_external_event_info(&numfds, &readfds, &writefds, &exceptfds); #endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */ count = select(numfds, &readfds, &writefds, &exceptfds, tvp); if (count > 0) { #ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER netsnmp_dispatch_external_events(&count, &readfds, &writefds, &exceptfds); #endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */ /* If there are any more events after external events, then * try SNMP events. */ if (count > 0) { snmp_read(&readfds); } } else { switch (count) { case 0: snmp_timeout(); break; case -1: if (errno == EINTR) continue; snmp_log_perror("select"); netsnmp_running = 0; break; default: fprintf(stderr, "select returned %d\n", count); netsnmp_running = 0; } } run_alarms(); } }
int main(int argc, char *argv[]) { int arg, i; int ret; u_short dest_port = SNMP_PORT; int dont_fork = 0; char logfile[SNMP_MAXBUF_SMALL]; char *cptr, **argvptr; char *pid_file = NULL; #if HAVE_GETPID FILE *PID; #endif int dont_zero_log = 0; int stderr_log=0, syslog_log=0; int uid=0, gid=0; logfile[0] = 0; #ifdef LOGFILE strcpy(logfile, LOGFILE); #endif /* * usage: snmpd */ for (arg = 1; arg < argc; arg++) { if (argv[arg][0] == '-') { switch (argv[arg][1]) { case 'c': if (++arg == argc) usage(argv[0]); ds_set_string(DS_LIBRARY_ID, DS_LIB_OPTIONALCONFIG, argv[arg]); break; case 'C': ds_set_boolean(DS_LIBRARY_ID, DS_LIB_DONT_READ_CONFIGS, 1); break; case 'd': snmp_set_dump_packet(++snmp_dump_packet); ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE, 1); break; case 'q': snmp_set_quick_print(1); break; case 'T': if (argv[arg][2] != '\0') cptr = &argv[arg][2]; else if (++arg>argc) { fprintf(stderr,"Need UDP or TCP after -T flag.\n"); usage(argv[0]); exit(1); } else { cptr = argv[arg]; } if (strcasecmp(cptr,"TCP") == 0) { ds_set_int(DS_APPLICATION_ID, DS_AGENT_FLAGS, ds_get_int(DS_APPLICATION_ID, DS_AGENT_FLAGS) | SNMP_FLAGS_STREAM_SOCKET); } else if (strcasecmp(cptr,"UDP") == 0) { /* default, do nothing */ } else { fprintf(stderr, "Unknown transport \"%s\" after -T flag.\n", cptr); usage(argv[0]); exit(1); } break; case 'D': debug_register_tokens(&argv[arg][2]); snmp_set_do_debugging(1); break; case 'p': if (++arg == argc) usage(argv[0]); dest_port = atoi(argv[arg]); if (dest_port <= 0) usage(argv[0]); break; case 'x': if (++arg == argc) usage(argv[0]); ds_set_string(DS_APPLICATION_ID, DS_AGENT_X_SOCKET, argv[arg]); break; case 'r': ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS, 1); break; case 'P': if (++arg == argc) usage(argv[0]); pid_file = argv[arg]; case 'a': log_addresses++; break; case 'V': ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_VERBOSE, 1); break; case 'f': dont_fork = 1; break; case 'l': if (++arg == argc) usage(argv[0]); strcpy(logfile, argv[arg]); break; case 'L': stderr_log=1; break; case 's': syslog_log=1; break; case 'A': dont_zero_log = 1; break; #if HAVE_UNISTD_H case 'u': if (++arg == argc) usage(argv[0]); uid = atoi(argv[arg]); break; case 'g': if (++arg == argc) usage(argv[0]); gid = atoi(argv[arg]); break; #endif case 'h': usage(argv[0]); break; case 'H': init_agent("snmpd"); /* register our .conf handlers */ init_mib_modules(); init_snmp("snmpd"); fprintf(stderr, "Configuration directives understood:\n"); read_config_print_usage(" "); exit(0); case 'v': printf("\nUCD-snmp version: %s\n",VersionInfo); printf("Author: Wes Hardaker\n"); printf("Email: [email protected]\n\n"); exit (0); case '-': switch(argv[arg][2]) { case 'v': printf("\nUCD-snmp version: %s\n",VersionInfo); printf("Author: Wes Hardaker\n"); printf("Email: [email protected]\n\n"); exit (0); case 'h': usage(argv[0]); exit(0); } default: printf("invalid option: %s\n", argv[arg]); usage(argv[0]); break; } continue; } } /* end-for */ /* * Initialize a argv set to the current for restarting the agent. */ argvrestartp = (char **) malloc((argc + 2) * sizeof(char *)); argvptr = argvrestartp; for (i = 0, ret = 1; i < argc; i++) { ret += strlen(argv[i]) + 1; } argvrestart = (char *) malloc(ret); argvrestartname = (char *) malloc(strlen(argv[0]) + 1); strcpy(argvrestartname, argv[0]); if ( strstr(argvrestartname, "agentxd") != NULL) ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, SUB_AGENT); else ds_set_boolean(DS_APPLICATION_ID, DS_AGENT_ROLE, MASTER_AGENT); for (cptr = argvrestart, i = 0; i < argc; i++) { strcpy(cptr, argv[i]); *(argvptr++) = cptr; cptr += strlen(argv[i]) + 1; } *cptr = 0; *argvptr = NULL; /* * Open the logfile if necessary. */ /* Should open logfile and/or syslog based on arguments */ if (logfile[0]) snmp_enable_filelog(logfile, dont_zero_log); if (syslog_log) snmp_enable_syslog(); #ifdef BUFSIZ setvbuf(stdout, NULL, _IOLBF, BUFSIZ); #endif /* * Initialize the world. Detach from the shell. * Create initial user. */ #if HAVE_FORK if (!dont_fork && fork() != 0) { exit(0); } #endif #if HAVE_GETPID if (pid_file != NULL) { if ((PID = fopen(pid_file, "w")) == NULL) { snmp_log_perror("fopen"); if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS)) exit(1); } else { fprintf(PID, "%d\n", (int)getpid()); fclose(PID); } } #endif #else /* __ECOS environment: */ void snmpd( void *initfunc( void ) ) { int ret; u_short dest_port = SNMP_PORT; #define stderr_log 1 #endif // --------- // En-bloc reinitialization of statics. running = 1; // --------- SOCK_STARTUP; init_agent("snmpd"); /* do what we need to do first. */ init_mib_modules(); /* start library */ init_snmp("snmpd"); ret = init_master_agent( dest_port, snmp_check_packet, snmp_check_parse ); if( ret != 0 ) Exit(1); /* Exit logs exit val for us */ #ifdef SIGTERM signal(SIGTERM, SnmpdShutDown); #endif #ifdef SIGINT signal(SIGINT, SnmpdShutDown); #endif #ifdef SIGHUP signal(SIGHUP, SnmpdReconfig); #endif #ifdef SIGUSR1 signal(SIGUSR1, SnmpdDump); #endif /* send coldstart trap via snmptrap(1) if possible */ send_easy_trap (0, 0); #if HAVE_UNISTD_H if (gid) { DEBUGMSGTL(("snmpd", "Changing gid to %d.\n", gid)); if (setgid(gid)==-1) { snmp_log_perror("setgid failed"); if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS)) exit(1); } } if (uid) { DEBUGMSGTL(("snmpd", "Changing uid to %d.\n", uid)); if(setuid(uid)==-1) { snmp_log_perror("setuid failed"); if (!ds_get_boolean(DS_APPLICATION_ID, DS_AGENT_NO_ROOT_ACCESS)) exit(1); } } #endif /* honor selection of standard error output */ if (!stderr_log) snmp_disable_stderrlog(); /* we're up, log our version number */ snmp_log(LOG_INFO, "UCD-SNMP version %s\n", VersionInfo); memset(addrCache, 0, sizeof(addrCache)); /* * Call initialization function if necessary */ DEBUGMSGTL(("snmpd", "Calling initfunc().\n")); if ( initfunc ) (initfunc)(); /* * Forever monitor the dest_port for incoming PDUs. */ DEBUGMSGTL(("snmpd", "We're up. Starting to process data.\n")); receive(); #include "mib_module_shutdown.h" DEBUGMSGTL(("snmpd", "sending shutdown trap\n")); SnmpTrapNodeDown(); DEBUGMSGTL(("snmpd", "Bye...\n")); snmp_shutdown("snmpd"); } /* End main() -- snmpd */
main(int argc, char *argv[]) #endif { char options[128] = "aAc:CdD::efF:g:hHI:L:m:M:no:O:PqsS:tu:vx:-:"; netsnmp_session *sess_list = NULL, *ss = NULL; netsnmp_transport *transport = NULL; int arg, i = 0; int uid = 0, gid = 0; char *cp, *listen_ports = NULL; #if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX) int agentx_subagent = 1; #endif netsnmp_trapd_handler *traph; #ifndef WIN32 /* * close all non-standard file descriptors we may have * inherited from the shell. */ for (i = getdtablesize() - 1; i > 2; --i) { (void) close(i); } #endif /* #WIN32 */ #ifdef SIGTERM signal(SIGTERM, term_handler); #endif #ifdef SIGHUP signal(SIGHUP, SIG_IGN); /* do not terminate on early SIGHUP */ #endif #ifdef SIGINT signal(SIGINT, term_handler); #endif #ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); /* 'Inline' failure of wayward readers */ #endif /* * register our configuration handlers now so -H properly displays them */ snmptrapd_register_configs( ); #ifdef NETSNMP_USE_MYSQL snmptrapd_register_sql_configs( ); #endif #ifdef NETSNMP_SECMOD_USM init_usm_conf( "snmptrapd" ); #endif /* NETSNMP_SECMOD_USM */ register_config_handler("snmptrapd", "snmpTrapdAddr", parse_trapd_address, free_trapd_address, "string"); register_config_handler("snmptrapd", "doNotLogTraps", parse_config_doNotLogTraps, NULL, "(1|yes|true|0|no|false)"); #if HAVE_GETPID register_config_handler("snmptrapd", "pidFile", parse_config_pidFile, NULL, "string"); #endif #ifdef HAVE_UNISTD_H register_config_handler("snmptrapd", "agentuser", parse_config_agentuser, NULL, "userid"); register_config_handler("snmptrapd", "agentgroup", parse_config_agentgroup, NULL, "groupid"); #endif register_config_handler("snmptrapd", "doNotFork", parse_config_doNotFork, NULL, "(1|yes|true|0|no|false)"); register_config_handler("snmptrapd", "ignoreAuthFailure", parse_config_ignoreAuthFailure, NULL, "(1|yes|true|0|no|false)"); register_config_handler("snmptrapd", "outputOption", parse_config_outputOption, NULL, "string"); /* * Add some options if they are available. */ #if HAVE_GETPID strcat(options, "p:"); #endif #ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG #ifdef WIN32 snmp_log_syslogname(app_name_long); #else snmp_log_syslogname(app_name); #endif #endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */ /* * Now process options normally. */ while ((arg = getopt(argc, argv, options)) != EOF) { switch (arg) { case '-': if (strcasecmp(optarg, "help") == 0) { usage(); exit(0); } if (strcasecmp(optarg, "version") == 0) { version(); exit(0); } handle_long_opt(optarg); break; case 'a': dropauth = 1; break; case 'A': netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPEND_LOGFILES, 1); break; case 'c': if (optarg != NULL) { netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OPTIONALCONFIG, optarg); } else { usage(); exit(1); } break; case 'C': netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1); break; case 'd': netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DUMP_PACKET, 1); break; case 'D': debug_register_tokens(optarg); snmp_set_do_debugging(1); break; case 'f': dofork = 0; break; case 'F': if (optarg != NULL) { if (( strncmp( optarg, "print", 5 ) == 0 ) || ( strncmp( optarg, "syslog", 6 ) == 0 ) || ( strncmp( optarg, "execute", 7 ) == 0 )) { /* New style: "type=format" */ trap1_fmt_str_remember = strdup(optarg); cp = strchr( trap1_fmt_str_remember, '=' ); if (cp) *cp = ' '; } else { /* Old style: implicitly "print=format" */ trap1_fmt_str_remember = malloc(strlen(optarg) + 7); sprintf( trap1_fmt_str_remember, "print %s", optarg ); } } else { usage(); exit(1); } break; #if HAVE_UNISTD_H case 'g': if (optarg != NULL) { netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_GROUPID, gid = atoi(optarg)); } else { usage(); exit(1); } break; #endif case 'h': usage(); exit(0); case 'H': init_agent("snmptrapd"); #ifdef USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE init_notification_log(); #endif #ifdef NETSNMP_EMBEDDED_PERL init_perl(); #endif init_snmp("snmptrapd"); fprintf(stderr, "Configuration directives understood:\n"); read_config_print_usage(" "); exit(0); case 'I': if (optarg != NULL) { add_to_init_list(optarg); } else { usage(); } break; case 'S': fprintf(stderr, "Warning: -S option has been withdrawn; use -Ls <facility> instead\n"); exit(1); break; case 'm': if (optarg != NULL) { setenv("MIBS", optarg, 1); } else { usage(); exit(1); } break; case 'M': if (optarg != NULL) { setenv("MIBDIRS", optarg, 1); } else { usage(); exit(1); } break; case 'n': netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_APP_NUMERIC_IP, 1); break; case 'o': fprintf(stderr, "Warning: -o option has been withdrawn; use -Lf <file> instead\n"); exit(1); break; case 'O': cp = snmp_out_toggle_options(optarg); if (cp != NULL) { fprintf(stderr, "Unknown output option passed to -O: %c\n", *cp); usage(); exit(1); } break; case 'L': if (snmp_log_options( optarg, argc, argv ) < 0 ) { usage(); exit(1); } break; #if HAVE_GETPID case 'p': if (optarg != NULL) { parse_config_pidFile(NULL, optarg); } else { usage(); exit(1); } break; #endif case 'P': fprintf(stderr, "Warning: -P option has been withdrawn; use -f -Le instead\n"); exit(1); break; case 's': fprintf(stderr, "Warning: -s option has been withdrawn; use -Lsd instead\n"); exit(1); break; case 't': SyslogTrap++; break; #if HAVE_UNISTD_H case 'u': if (optarg != NULL) { char *ecp; uid = strtoul(optarg, &ecp, 10); #if HAVE_GETPWNAM && HAVE_PWD_H if (*ecp) { struct passwd *info; info = getpwnam(optarg); uid = info ? info->pw_uid : -1; endpwent(); } #endif if (uid < 0) { fprintf(stderr, "Bad user id: %s\n", optarg); exit(1); } netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_USERID, uid); } else { usage(); exit(1); } break; #endif case 'v': version(); exit(0); break; case 'x': if (optarg != NULL) { netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, optarg); } else { usage(); exit(1); } break; default: fprintf(stderr, "invalid option: -%c\n", arg); usage(); exit(1); break; } } if (optind < argc) { /* * There are optional transport addresses on the command line. */ for (i = optind; i < argc; i++) { char *astring; if (listen_ports != NULL) { astring = malloc(strlen(listen_ports) + 2 + strlen(argv[i])); if (astring == NULL) { fprintf(stderr, "malloc failure processing argv[%d]\n", i); exit(1); } sprintf(astring, "%s,%s", listen_ports, argv[i]); free(listen_ports); listen_ports = astring; } else { listen_ports = strdup(argv[i]); if (listen_ports == NULL) { fprintf(stderr, "malloc failure processing argv[%d]\n", i); exit(1); } } } } SOCK_STARTUP; /* * I'm being lazy here, and not checking the * return value from these registration calls. * Don't try this at home, children! */ if (0 == snmp_get_do_logging()) { #ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER, syslog_handler); traph->authtypes = TRAP_AUTH_LOG; snmp_enable_syslog(); #else /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */ #ifndef NETSNMP_FEATURE_REMOVE_LOGGING_STDIO traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER, print_handler); traph->authtypes = TRAP_AUTH_LOG; snmp_enable_stderr(); #endif /* NETSNMP_FEATURE_REMOVE_LOGGING_STDIO */ #endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */ } else { traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER, print_handler); traph->authtypes = TRAP_AUTH_LOG; } #if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX) /* * we're an agentx subagent? */ if (agentx_subagent) { /* * make us a agentx client. */ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1); } #endif /* * don't fail if we can't do agentx (ie, socket not there, or not root) */ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS); /* * ignore any warning messages. */ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_CONNECTION_WARNINGS); /* * initialize the agent library */ init_agent("snmptrapd"); #if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX) #ifdef NETSNMP_FEATURE_CHECKING netsnmp_feature_require(register_snmpEngine_scalars_context) #endif /* NETSNMP_FEATURE_CHECKING */ /* * initialize local modules */ if (agentx_subagent) { #ifdef USING_SNMPV3_SNMPENGINE_MODULE extern void register_snmpEngine_scalars_context(const char *); #endif subagent_init(); #ifdef USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE /* register the notification log table */ if (should_init("notificationLogMib")) { netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_NOTIF_LOG_CTX, "snmptrapd"); traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_POST_HANDLER, notification_handler); traph->authtypes = TRAP_AUTH_LOG; init_notification_log(); } #endif #ifdef USING_SNMPV3_SNMPENGINE_MODULE /* * register scalars from SNMP-FRAMEWORK-MIB::snmpEngineID group; * allows engineID probes via the master agent under the * snmptrapd context */ register_snmpEngine_scalars_context("snmptrapd"); #endif } #endif /* USING_AGENTX_SUBAGENT_MODULE && !NETSNMP_SNMPTRAPD_DISABLE_AGENTX */ /* register our authorization handler */ init_netsnmp_trapd_auth(); #if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX) if (agentx_subagent) { #ifdef USING_AGENT_NSVACMACCESSTABLE_MODULE extern void init_register_nsVacm_context(const char *); #endif #ifdef USING_SNMPV3_USMUSER_MODULE #ifdef NETSNMP_FEATURE_CHECKING netsnmp_feature_require(init_register_usmUser_context) #endif /* NETSNMP_FEATURE_CHECKING */ extern void init_register_usmUser_context(const char *); /* register ourselves as having a USM user database */ init_register_usmUser_context("snmptrapd"); #endif #ifdef USING_AGENT_NSVACMACCESSTABLE_MODULE /* register net-snmp vacm extensions */ init_register_nsVacm_context("snmptrapd"); #endif #ifdef USING_TLSTM_MIB_SNMPTLSTMCERTTOTSNTABLE_MODULE init_snmpTlstmCertToTSNTable_context("snmptrapd"); #endif } #endif #ifdef NETSNMP_EMBEDDED_PERL init_perl(); { /* set the default path to load */ char init_file[SNMP_MAXBUF]; snprintf(init_file, sizeof(init_file) - 1, "%s/%s", SNMPSHAREPATH, "snmp_perl_trapd.pl"); netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PERL_INIT_FILE, init_file); } #endif /* * Initialize the world. */ init_snmp("snmptrapd"); #ifdef SIGHUP signal(SIGHUP, hup_handler); #endif if (trap1_fmt_str_remember) { parse_format( NULL, trap1_fmt_str_remember ); } if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_QUIT_IMMEDIATELY)) { /* * just starting up to process specific configuration and then * shutting down immediately. */ netsnmp_running = 0; } /* * if no logging options on command line or in conf files, use syslog */ if (0 == snmp_get_do_logging()) { #ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG #ifdef WIN32 snmp_enable_syslog_ident(app_name_long, Facility); #else snmp_enable_syslog_ident(app_name, Facility); #endif #endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */ } if (listen_ports) cp = listen_ports; else cp = default_port; while (cp != NULL) { char *sep = strchr(cp, ','); if (sep != NULL) { *sep = 0; } transport = netsnmp_transport_open_server("snmptrap", cp); if (transport == NULL) { snmp_log(LOG_ERR, "couldn't open %s -- errno %d (\"%s\")\n", cp, errno, strerror(errno)); snmptrapd_close_sessions(sess_list); SOCK_CLEANUP; exit(1); } else { ss = snmptrapd_add_session(transport); if (ss == NULL) { /* * Shouldn't happen? We have already opened the transport * successfully so what could have gone wrong? */ snmptrapd_close_sessions(sess_list); netsnmp_transport_free(transport); snmp_log(LOG_ERR, "couldn't open snmp - %s", strerror(errno)); SOCK_CLEANUP; exit(1); } else { ss->next = sess_list; sess_list = ss; } } /* * Process next listen address, if there is one. */ if (sep != NULL) { *sep = ','; cp = sep + 1; } else { cp = NULL; } } SNMP_FREE(listen_ports); /* done with them */ #ifdef NETSNMP_USE_MYSQL if( netsnmp_mysql_init() ) { fprintf(stderr, "MySQL initialization failed\n"); exit(1); } #endif #ifndef WIN32 /* * fork the process to the background if we are not printing to stderr */ if (dofork && netsnmp_running) { int fd; switch (fork()) { case -1: fprintf(stderr, "bad fork - %s\n", strerror(errno)); _exit(1); case 0: /* * become process group leader */ if (setsid() == -1) { fprintf(stderr, "bad setsid - %s\n", strerror(errno)); _exit(1); } /* * if we are forked, we don't want to print out to stdout or stderr */ fd = open("/dev/null", O_RDWR); dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); close(fd); break; default: _exit(0); } } #endif /* WIN32 */ #if HAVE_GETPID if (pid_file != NULL) { if ((PID = fopen(pid_file, "w")) == NULL) { snmp_log_perror("fopen"); exit(1); } fprintf(PID, "%d\n", (int) getpid()); fclose(PID); free_config_pidFile(); } #endif snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version()); /* * ignore early sighup during startup */ reconfig = 0; #if HAVE_UNISTD_H #ifdef HAVE_SETGID if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_GROUPID)) != 0) { DEBUGMSGTL(("snmptrapd/main", "Changing gid to %d.\n", gid)); if (setgid(gid) == -1 #ifdef HAVE_SETGROUPS || setgroups(1, (gid_t *)&gid) == -1 #endif ) { snmp_log_perror("setgid failed"); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { exit(1); } } } #endif #ifdef HAVE_SETUID if ((uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_USERID)) != 0) { DEBUGMSGTL(("snmptrapd/main", "Changing uid to %d.\n", uid)); if (setuid(uid) == -1) { snmp_log_perror("setuid failed"); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { exit(1); } } } #endif #endif #ifdef WIN32SERVICE trapd_status = SNMPTRAPD_RUNNING; #endif snmptrapd_main_loop(); if (snmp_get_do_logging()) { struct tm *tm; time_t timer; time(&timer); tm = localtime(&timer); snmp_log(LOG_INFO, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d NET-SNMP version %s Stopped.\n", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, netsnmp_get_version()); } snmp_log(LOG_INFO, "Stopping snmptrapd\n"); #ifdef NETSNMP_EMBEDDED_PERL shutdown_perl(); #endif snmptrapd_close_sessions(sess_list); snmp_shutdown("snmptrapd"); #ifdef WIN32SERVICE trapd_status = SNMPTRAPD_STOPPED; #endif snmp_disable_log(); SOCK_CLEANUP; return 0; }
/* * Load the latest memory usage statistics */ int netsnmp_mem_arch_load (netsnmp_cache * cache, void *magic) { struct pst_static pst; struct pst_dynamic psd; netsnmp_memory_info *mem; long total_swap = 0; long free_swap = 0; long size = 0; /* * Retrieve the memory information from the underlying O/S... */ if (pstat_getstatic (&pst, sizeof (pst), (size_t) 1, 0) == -1) { snmp_log (LOG_ERR, "memory_hpux: pstat_getstatic failed!\n"); return -1; } if (pstat_getdynamic (&psd, sizeof (psd), (size_t) 1, 0) == -1) { snmp_log (LOG_ERR, "memory_hpux: pstat_getdynamic failed!\n"); return -1; } mem = netsnmp_memory_get_byIdx (NETSNMP_MEM_TYPE_PHYSMEM, 1); if (!mem) { snmp_log_perror ("No Memory info entry"); } else { if (!mem->descr) mem->descr = strdup ("Physical memory"); mem->units = pst.page_size; mem->size = pst.physical_memory; mem->free = psd.psd_free; mem->other = -1; } get_swapinfo (&total_swap, &free_swap, &size); mem = netsnmp_memory_get_byIdx (NETSNMP_MEM_TYPE_SWAP, 1); if (!mem) { snmp_log_perror ("No Swap info entry"); } else { if (!mem->descr) mem->descr = strdup ("Swap space (total)"); mem->units = size; mem->size = total_swap; mem->free = free_swap; mem->other = -1; } mem = netsnmp_memory_get_byIdx (NETSNMP_MEM_TYPE_STEXT, 1); if (!mem) { snmp_log_perror ("No Swap text entry"); } else { if (!mem->descr) mem->descr = strdup ("Swapped text pages"); mem->units = pst.page_size; mem->size = psd.psd_vmtxt; mem->free = psd.psd_avmtxt; mem->other = -1; } mem = netsnmp_memory_get_byIdx (NETSNMP_MEM_TYPE_RTEXT, 1); if (!mem) { snmp_log_perror ("No real text entry"); } else { if (!mem->descr) mem->descr = strdup ("Real text pages"); mem->units = pst.page_size; mem->size = psd.psd_rmtxt; mem->free = psd.psd_armtxt; mem->other = -1; } /* mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_MISC, 1 ); if (!mem) { snmp_log_perror("No Buffer, etc info entry"); } else { mem->units = 1024; mem->size = -1; mem->free = (pst.page_size/1024)*psd.psd_free + swap.free_swap; mem->other = -1; } */ return 0; }
main(int argc, char *argv[]) #endif { char options[128] = "aAc:CdD::fhHI:l:L:m:M:n:p:P:qrsS:UvV-:Y:"; int arg, i, ret; int dont_fork = 0, do_help = 0; int log_set = 0; int uid = 0, gid = 0; int agent_mode = -1; char *cptr, **argvptr; char *pid_file = NULL; char option_compatability[] = "-Le"; #if HAVE_GETPID int fd; FILE *PID; #endif #ifndef WIN32 /* * close all non-standard file descriptors we may have * inherited from the shell. */ for (i = getdtablesize() - 1; i > 2; --i) { (void) close(i); } #endif /* #WIN32 */ /* * register signals ASAP to prevent default action (usually core) * for signals during startup... */ #ifdef SIGTERM DEBUGMSGTL(("signal", "registering SIGTERM signal handler\n")); signal(SIGTERM, SnmpdShutDown); #endif #ifdef SIGINT DEBUGMSGTL(("signal", "registering SIGINT signal handler\n")); signal(SIGINT, SnmpdShutDown); #endif #ifdef SIGHUP signal(SIGHUP, SIG_IGN); /* do not terminate on early SIGHUP */ #endif #ifdef SIGUSR1 DEBUGMSGTL(("signal", "registering SIGUSR1 signal handler\n")); signal(SIGUSR1, SnmpdDump); #endif #ifdef SIGPIPE DEBUGMSGTL(("signal", "registering SIGPIPE signal handler\n")); signal(SIGPIPE, SIG_IGN); /* 'Inline' failure of wayward readers */ #endif #ifdef SIGXFSZ signal(SIGXFSZ, SnmpdCatchRandomSignal); #endif #ifdef NETSNMP_NO_ROOT_ACCESS /* * Default to no. */ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1); #endif /* * Default to NOT running an AgentX master. */ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_MASTER, 0); netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_TIMEOUT, -1); netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_RETRIES, -1); netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_CACHE_TIMEOUT, 5); /* * Add some options if they are available. */ #if HAVE_UNISTD_H strcat(options, "g:u:"); #endif #if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE) strcat(options, "x:"); #endif #ifdef USING_AGENTX_SUBAGENT_MODULE strcat(options, "X"); #endif /* * This is incredibly ugly, but it's probably the simplest way * to handle the old '-L' option as well as the new '-Lx' style */ for (i=0; i<argc; i++) { if (!strcmp(argv[i], "-L")) argv[i] = option_compatability; } #ifdef WIN32 snmp_log_syslogname(app_name_long); #else snmp_log_syslogname(app_name); #endif netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE, app_name); /* * Now process options normally. */ while ((arg = getopt(argc, argv, options)) != EOF) { switch (arg) { case '-': if (strcasecmp(optarg, "help") == 0) { usage(argv[0]); } if (strcasecmp(optarg, "version") == 0) { version(); } handle_long_opt(optarg); break; case 'a': log_addresses++; break; case 'A': netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPEND_LOGFILES, 1); break; case 'c': if (optarg != NULL) { netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OPTIONALCONFIG, optarg); } else { usage(argv[0]); } break; case 'C': netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1); break; case 'd': snmp_set_dump_packet(++snmp_dump_packet); netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_VERBOSE, 1); break; case 'D': debug_register_tokens(optarg); snmp_set_do_debugging(1); break; case 'f': dont_fork = 1; break; #if HAVE_UNISTD_H case 'g': if (optarg != NULL) { char *ecp; int gid; gid = strtoul(optarg, &ecp, 10); if (*ecp) { #if HAVE_GETPWNAM && HAVE_PWD_H struct group *info; info = getgrnam(optarg); if (info) { gid = info->gr_gid; } else { #endif fprintf(stderr, "Bad group id: %s\n", optarg); exit(1); #if HAVE_GETPWNAM && HAVE_PWD_H } #endif } netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_GROUPID, gid); } else { usage(argv[0]); } break; #endif case 'h': usage(argv[0]); break; case 'H': do_help = 1; break; case 'I': if (optarg != NULL) { add_to_init_list(optarg); } else { usage(argv[0]); } break; case 'l': printf("Warning: -l option is deprecated, use -Lf <file> instead\n"); if (optarg != NULL) { if (strlen(optarg) > PATH_MAX) { fprintf(stderr, "%s: logfile path too long (limit %d chars)\n", argv[0], PATH_MAX); exit(1); } snmp_enable_filelog(optarg, netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPEND_LOGFILES)); log_set = 1; } else { usage(argv[0]); } break; case 'L': if (snmp_log_options( optarg, argc, argv ) < 0 ) { usage(argv[0]); } log_set = 1; break; case 'm': if (optarg != NULL) { setenv("MIBS", optarg, 1); } else { usage(argv[0]); } break; case 'M': if (optarg != NULL) { setenv("MIBDIRS", optarg, 1); } else { usage(argv[0]); } break; case 'n': if (optarg != NULL) { app_name = optarg; netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE, app_name); } else { usage(argv[0]); } break; case 'P': printf("Warning: -P option is deprecated, use -p instead\n"); case 'p': if (optarg != NULL) { pid_file = optarg; } else { usage(argv[0]); } break; case 'q': snmp_set_quick_print(1); break; case 'r': netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS); break; case 's': printf("Warning: -s option is deprecated, use -Lsd instead\n"); snmp_enable_syslog(); log_set = 1; break; case 'S': printf("Warning: -S option is deprecated, use -Ls <facility> instead\n"); if (optarg != NULL) { switch (*optarg) { case 'd': case 'D': Facility = LOG_DAEMON; break; case 'i': case 'I': Facility = LOG_INFO; break; case '0': Facility = LOG_LOCAL0; break; case '1': Facility = LOG_LOCAL1; break; case '2': Facility = LOG_LOCAL2; break; case '3': Facility = LOG_LOCAL3; break; case '4': Facility = LOG_LOCAL4; break; case '5': Facility = LOG_LOCAL5; break; case '6': Facility = LOG_LOCAL6; break; case '7': Facility = LOG_LOCAL7; break; default: fprintf(stderr, "invalid syslog facility: -S%c\n",*optarg); usage(argv[0]); } snmp_enable_syslog_ident(snmp_log_syslogname(NULL), Facility); log_set = 1; } else { fprintf(stderr, "no syslog facility specified\n"); usage(argv[0]); } break; case 'U': netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_LEAVE_PIDFILE); break; #if HAVE_UNISTD_H case 'u': if (optarg != NULL) { char *ecp; int uid; uid = strtoul(optarg, &ecp, 10); if (*ecp) { #if HAVE_GETPWNAM && HAVE_PWD_H struct passwd *info; info = getpwnam(optarg); if (info) { uid = info->pw_uid; } else { #endif fprintf(stderr, "Bad user id: %s\n", optarg); exit(1); #if HAVE_GETPWNAM && HAVE_PWD_H } #endif } netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_USERID, uid); } else { usage(argv[0]); } break; #endif case 'v': version(); case 'V': netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_VERBOSE, 1); break; #if defined(USING_AGENTX_SUBAGENT_MODULE)|| defined(USING_AGENTX_MASTER_MODULE) case 'x': if (optarg != NULL) { netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, optarg); } else { usage(argv[0]); } netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_MASTER, 1); break; #endif case 'X': #if defined(USING_AGENTX_SUBAGENT_MODULE) agent_mode = SUB_AGENT; #else fprintf(stderr, "%s: Illegal argument -X:" "AgentX support not compiled in.\n", argv[0]); usage(argv[0]); exit(1); #endif break; case 'Y': netsnmp_config_remember(optarg); break; default: usage(argv[0]); break; } } if (do_help) { netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS, 1); init_agent(app_name); /* register our .conf handlers */ init_mib_modules(); init_snmp(app_name); fprintf(stderr, "Configuration directives understood:\n"); read_config_print_usage(" "); exit(0); } if (optind < argc) { /* * There are optional transport addresses on the command line. */ DEBUGMSGTL(("snmpd/main", "optind %d, argc %d\n", optind, argc)); for (i = optind; i < argc; i++) { char *c, *astring; if ((c = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PORTS))) { astring = malloc(strlen(c) + 2 + strlen(argv[i])); if (astring == NULL) { fprintf(stderr, "malloc failure processing argv[%d]\n", i); exit(1); } sprintf(astring, "%s,%s", c, argv[i]); netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PORTS, astring); SNMP_FREE(astring); } else { netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PORTS, argv[i]); } } DEBUGMSGTL(("snmpd/main", "port spec: %s\n", netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PORTS))); } #ifdef NETSNMP_LOGFILE if (0 == log_set) snmp_enable_filelog(NETSNMP_LOGFILE, netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPEND_LOGFILES)); #endif /* * Initialize a argv set to the current for restarting the agent. */ argvrestartp = (char **)malloc((argc + 2) * sizeof(char *)); argvptr = argvrestartp; for (i = 0, ret = 1; i < argc; i++) { ret += strlen(argv[i]) + 1; } argvrestart = (char *) malloc(ret); argvrestartname = (char *) malloc(strlen(argv[0]) + 1); if (!argvrestartp || !argvrestart || !argvrestartname) { fprintf(stderr, "malloc failure processing argvrestart\n"); exit(1); } strcpy(argvrestartname, argv[0]); if (agent_mode == -1) { if (strstr(argvrestartname, "agentxd") != NULL) { netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, SUB_AGENT); } else { netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, MASTER_AGENT); } } else { netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, agent_mode); } for (cptr = argvrestart, i = 0; i < argc; i++) { strcpy(cptr, argv[i]); *(argvptr++) = cptr; cptr += strlen(argv[i]) + 1; } *cptr = 0; *argvptr = NULL; #ifdef BUFSIZ setvbuf(stdout, NULL, _IOLBF, BUFSIZ); #endif /* * Initialize the world. Detach from the shell. Create initial user. */ if(!dont_fork) { int quit = ! netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_QUIT_IMMEDIATELY); ret = netsnmp_daemonize(quit, snmp_stderrlog_status()); /* * xxx-rks: do we care if fork fails? I think we should... */ if(ret != 0) Exit(1); /* Exit logs exit val for us */ } SOCK_STARTUP; init_agent(app_name); /* do what we need to do first. */ init_mib_modules(); /* * start library */ init_snmp(app_name); if ((ret = init_master_agent()) != 0) { /* * Some error opening one of the specified agent transports. */ Exit(1); /* Exit logs exit val for us */ } #if HAVE_GETPID if (pid_file != NULL) { /* * unlink the pid_file, if it exists, prior to open. Without * doing this the open will fail if the user specified pid_file * already exists. */ unlink(pid_file); fd = open(pid_file, O_CREAT | O_EXCL | O_WRONLY, 0600); if (fd == -1) { snmp_log_perror(pid_file); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { exit(1); } } else { if ((PID = fdopen(fd, "w")) == NULL) { snmp_log_perror(pid_file); exit(1); } else { fprintf(PID, "%d\n", (int) getpid()); fclose(PID); } close(fd); } } #endif #if HAVE_UNISTD_H cptr = get_persistent_directory(); mkdirhier( cptr, NETSNMP_AGENT_DIRECTORY_MODE, 0 ); uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_USERID); gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_GROUPID); #ifdef HAVE_CHOWN if ( uid != 0 || gid != 0 ) chown( cptr, uid, gid ); #endif #ifdef HAVE_SETGID if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_GROUPID)) != 0) { DEBUGMSGTL(("snmpd/main", "Changing gid to %d.\n", gid)); if (setgid(gid) == -1 #ifdef HAVE_SETGROUPS || setgroups(1, (gid_t *)&gid) == -1 #endif ) { snmp_log_perror("setgid failed"); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { exit(1); } } } #endif #ifdef HAVE_SETUID if ((uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_USERID)) != 0) { DEBUGMSGTL(("snmpd/main", "Changing uid to %d.\n", uid)); if (setuid(uid) == -1) { snmp_log_perror("setuid failed"); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) { exit(1); } } } #endif #endif /* * Store persistent data immediately in case we crash later. */ snmp_store(app_name); #ifdef SIGHUP DEBUGMSGTL(("signal", "registering SIGHUP signal handler\n")); signal(SIGHUP, SnmpdReconfig); #endif /* * Send coldstart trap if possible. */ send_easy_trap(0, 0); /* * We're up, log our version number. */ snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version()); #ifdef WIN32SERVICE agent_status = AGENT_RUNNING; #endif netsnmp_addrcache_initialise(); /* * Forever monitor the dest_port for incoming PDUs. */ DEBUGMSGTL(("snmpd/main", "We're up. Starting to process data.\n")); if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_QUIT_IMMEDIATELY)) receive(); DEBUGMSGTL(("snmpd/main", "sending shutdown trap\n")); SnmpTrapNodeDown(); DEBUGMSGTL(("snmpd/main", "Bye...\n")); snmp_shutdown(app_name); #ifdef SHUTDOWN_AGENT_CLEANLY /* broken code */ /* these attempt to free all known memory, but result in double frees */ shutdown_master_agent(); shutdown_agent(); #endif if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_LEAVE_PIDFILE) && (pid_file != NULL)) { unlink(pid_file); } #ifdef WIN32SERVICE agent_status = AGENT_STOPPED; #endif SNMP_FREE(argvrestartname); SNMP_FREE(argvrestart); SNMP_FREE(argvrestartp); SOCK_CLEANUP; return 0; } /* End main() -- snmpd */
/* * Interrupt/Context Switch statistics * XXX - Do these really belong here ? */ void _cpu_load_swap_etc( char *buff, netsnmp_cpu_info *cpu ) { static int has_vmstat = 1; static char *vmbuff = NULL; static int vmbsize = 0; static int first = 1; int bytes_read, vmstatfd; char *b; unsigned long long pin, pout, swpin, swpout; unsigned long long itot, iticks, ctx; if (has_vmstat) { vmstatfd = open(VMSTAT_FILE, O_RDONLY, 0); if (vmstatfd == -1 ) { snmp_log(LOG_ERR, "cannot open %s\n", VMSTAT_FILE); has_vmstat = 0; } else { if (vmbsize == 0) { vmbsize = getpagesize()-1; vmbuff = (char*)malloc(vmbsize+1); } while ((bytes_read = read(vmstatfd, vmbuff, vmbsize)) == vmbsize) { vmbsize += BUFSIZ; vmbuff = (char*)realloc(vmbuff, vmbsize+1); close(vmstatfd); vmstatfd = open(VMSTAT_FILE, O_RDONLY, 0); if (vmstatfd == -1) { snmp_log_perror("cannot open " VMSTAT_FILE); return; } } close(vmstatfd); if ( bytes_read < 0 ) { snmp_log_perror(VMSTAT_FILE "read error"); return; } vmbuff[bytes_read] = '\0'; } } if (has_vmstat) { b = strstr(vmbuff, "pgpgin "); if (b) { sscanf(b, "pgpgin %llu", &pin); cpu->pageIn = (unsigned long long)pin*2; /* ??? */ } else { if (first) snmp_log(LOG_ERR, "No pgpgin line in %s\n", VMSTAT_FILE); cpu->pageIn = 0; } b = strstr(vmbuff, "pgpgout "); if (b) { sscanf(b, "pgpgout %llu", &pout); cpu->pageOut = (unsigned long long)pout*2; /* ??? */ } else { if (first) snmp_log(LOG_ERR, "No pgpgout line in %s\n", VMSTAT_FILE); cpu->pageOut = 0; } b = strstr(vmbuff, "pswpin "); if (b) { sscanf(b, "pswpin %llu", &swpin); cpu->swapIn = (unsigned long long)swpin; } else { if (first) snmp_log(LOG_ERR, "No pswpin line in %s\n", VMSTAT_FILE); cpu->swapIn = 0; } b = strstr(vmbuff, "pswpout "); if (b) { sscanf(b, "pswpout %llu", &swpout); cpu->swapOut = (unsigned long long)swpout; } else { if (first) snmp_log(LOG_ERR, "No pswpout line in %s\n", VMSTAT_FILE); cpu->swapOut = 0; } } else { b = strstr(buff, "page "); if (b) { sscanf(b, "page %llu %llu", &pin, &pout); cpu->pageIn = (unsigned long long)pin; cpu->pageOut = (unsigned long long)pout; } else { if (first) snmp_log(LOG_ERR, "No page line in %s\n", STAT_FILE); cpu->pageIn = cpu->pageOut = 0; } b = strstr(buff, "swap "); if (b) { sscanf(b, "swap %llu %llu", &swpin, &swpout); cpu->swapIn = (unsigned long long)swpin; cpu->swapOut = (unsigned long long)swpout; } else { if (first) snmp_log(LOG_ERR, "No swap line in %s\n", STAT_FILE); cpu->swapIn = cpu->swapOut = 0; } } b = strstr(buff, "intr "); if (b) { sscanf(b, "intr %llu %llu", &itot, &iticks); cpu->nInterrupts = (unsigned long long)itot; /* iticks not used? */ } else { if (first) snmp_log(LOG_ERR, "No intr line in %s\n", STAT_FILE); } b = strstr(buff, "ctxt "); if (b) { sscanf(b, "ctxt %llu", &ctx); cpu->nCtxSwitches = (unsigned long long)ctx; } else { if (first) snmp_log(LOG_ERR, "No ctxt line in %s\n", STAT_FILE); } first = 0; }
main(int argc, char *argv[]) #endif { char options[128] = "ac:CdD::efF:hHl:L:m:M:no:PqsS:tvO:-:"; netsnmp_session *sess_list = NULL, *ss = NULL; netsnmp_transport *transport = NULL; int arg, i = 0; int count, numfds, block; fd_set fdset; struct timeval timeout, *tvp; char *cp, *listen_ports = NULL; int agentx_subagent = 1, depmsg = 0; /* * register our configuration handlers now so -H properly displays them */ snmptrapd_register_configs( ); init_usm_conf( "snmptrapd" ); register_config_handler("snmptrapd", "snmptrapdaddr", parse_trapd_address, free_trapd_address, "string"); register_config_handler("snmptrapd", "doNotLogTraps", parse_config_doNotLogTraps, NULL, "(1|yes|true|0|no|false)"); #if HAVE_GETPID register_config_handler("snmptrapd", "pidFile", parse_config_pidFile, NULL, "string"); #endif register_config_handler("snmptrapd", "logOption", parse_config_logOption, NULL, "string"); register_config_handler("snmptrapd", "doNotFork", parse_config_doNotFork, NULL, "(1|yes|true|0|no|false)"); register_config_handler("snmptrapd", "printEventNumbers", parse_config_printEventNumbers, NULL, "(1|yes|true|0|no|false)"); register_config_handler("snmptrapd", "ignoreAuthFailure", parse_config_ignoreAuthFailure, NULL, "(1|yes|true|0|no|false)"); register_config_handler("snmptrapd", "outputOption", parse_config_outputOption, NULL, "string"); #ifdef WIN32 setvbuf(stdout, NULL, _IONBF, BUFSIZ); #else setvbuf(stdout, NULL, _IOLBF, BUFSIZ); #endif /* * Add some options if they are available. */ #if HAVE_GETPID strcat(options, "p:u:"); #endif snmp_log_syslogname(app_name); /* * Now process options normally. */ while ((arg = getopt(argc, argv, options)) != EOF) { switch (arg) { case '-': if (strcasecmp(optarg, "help") == 0) { usage(); exit(0); } if (strcasecmp(optarg, "version") == 0) { version(); exit(0); } handle_long_opt(optarg); break; case 'a': dropauth = 1; break; case 'c': if (optarg != NULL) { netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OPTIONALCONFIG, optarg); } else { usage(); exit(1); } break; case 'C': netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1); break; case 'd': snmp_set_dump_packet(1); break; case 'D': debug_register_tokens(optarg); snmp_set_do_debugging(1); break; case 'e': Event++; break; case 'f': dofork = 0; break; case 'F': if (optarg != NULL) { trap1_fmt_str_remember = optarg; } else { usage(); exit(1); } break; case 'h': usage(); exit(0); case 'H': init_notification_log(); init_snmp("snmptrapd"); fprintf(stderr, "Configuration directives understood:\n"); read_config_print_usage(" "); exit(0); case 'S': fprintf(stderr, "Warning: -S option is deprecated; use -Ls <facility> instead\n"); depmsg = 1; if (optarg != NULL) { switch (*optarg) { case 'd': case 'D': Facility = LOG_DAEMON; break; case 'i': case 'I': Facility = LOG_INFO; break; case '0': Facility = LOG_LOCAL0; break; case '1': Facility = LOG_LOCAL1; break; case '2': Facility = LOG_LOCAL2; break; case '3': Facility = LOG_LOCAL3; break; case '4': Facility = LOG_LOCAL4; break; case '5': Facility = LOG_LOCAL5; break; case '6': Facility = LOG_LOCAL6; break; case '7': Facility = LOG_LOCAL7; break; default: fprintf(stderr, "invalid syslog facility: -S%c\n",*optarg); usage(); exit(1); } } else { fprintf(stderr, "no syslog facility specified\n"); usage(); exit(1); } break; case 'm': if (optarg != NULL) { setenv("MIBS", optarg, 1); } else { usage(); exit(1); } break; case 'M': if (optarg != NULL) { setenv("MIBDIRS", optarg, 1); } else { usage(); exit(1); } break; case 'n': netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_APP_NUMERIC_IP, 1); break; case 'o': fprintf(stderr, "Warning: -o option is deprecated; use -Lf <file> instead\n"); Print++; if (optarg != NULL) { logfile = optarg; snmp_enable_filelog(optarg, 0); } else { usage(); exit(1); } break; case 'O': cp = snmp_out_toggle_options(optarg); if (cp != NULL) { fprintf(stderr, "Unknown output option passed to -O: %c\n", *cp); usage(); exit(1); } break; case 'L': if (snmp_log_options( optarg, argc, argv ) < 0 ) { usage(); exit(1); } Log++; break; case 'P': fprintf(stderr, "Warning: -P option is deprecated; use -f -Le instead\n"); dofork = 0; snmp_enable_stderrlog(); Print++; break; case 's': fprintf(stderr, "Warning: -s option is deprecated; use -Lsd instead\n"); depmsg = 1; Syslog++; break; case 't': SyslogTrap++; break; #if HAVE_GETPID case 'u': fprintf(stderr, "Warning: -u option is deprecated; use -p instead\n"); case 'p': if (optarg != NULL) { parse_config_pidFile(NULL, optarg); } else { usage(); exit(1); } break; #endif case 'v': version(); exit(0); break; default: fprintf(stderr, "invalid option: -%c\n", arg); usage(); exit(1); break; } } if (optind < argc) { /* * There are optional transport addresses on the command line. */ for (i = optind; i < argc; i++) { char *astring; if (listen_ports != NULL) { astring = malloc(strlen(listen_ports) + 2 + strlen(argv[i])); if (astring == NULL) { fprintf(stderr, "malloc failure processing argv[%d]\n", i); exit(1); } sprintf(astring, "%s,%s", listen_ports, argv[i]); free(listen_ports); listen_ports = astring; } else { listen_ports = strdup(argv[i]); if (listen_ports == NULL) { fprintf(stderr, "malloc failure processing argv[%d]\n", i); exit(1); } } } } /* * I'm being lazy here, and not checking the * return value from these registration calls. * Don't try this at home, children! */ if (!Log && !Print) { Syslog = 1; netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER, syslog_handler); } else { netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER, print_handler); } netsnmp_add_global_traphandler(NETSNMPTRAPD_POST_HANDLER, notification_handler); if (Event) { netsnmp_add_traphandler(event_handler, risingAlarm, OID_LENGTH(risingAlarm)); netsnmp_add_traphandler(event_handler, fallingAlarm, OID_LENGTH(fallingAlarm)); netsnmp_add_traphandler(event_handler, unavailableAlarm, OID_LENGTH(unavailableAlarm)); /* XXX - might be worth setting some "magic data" * in the traphandler structure that 'event_handler' * can use to avoid checking the trap OID values. */ } #ifdef USING_AGENTX_SUBAGENT_MODULE /* * we're an agentx subagent? */ if (agentx_subagent) { /* * make us a agentx client. */ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1); } #endif /* * don't fail if we can't do agentx (ie, socket not there, or not root) */ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_ROOT_ACCESS); /* * ignore any warning messages. */ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_NO_CONNECTION_WARNINGS); /* * initialize the agent library */ init_agent("snmptrapd"); /* * initialize local modules */ if (agentx_subagent) { extern void init_register_usmUser_context(const char *); #ifdef USING_AGENTX_SUBAGENT_MODULE void init_subagent(void); init_subagent(); #endif /* register the notification log table */ init_notification_log(); /* register ourselves as having a USM user database */ init_register_usmUser_context("snmptrapd"); } #ifdef NETSNMP_EMBEDDED_PERL init_perl(); { /* set the default path to load */ char init_file[SNMP_MAXBUF]; snprintf(init_file, sizeof(init_file) - 1, "%s/%s", SNMPSHAREPATH, "snmp_perl_trapd.pl"); netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_PERL_INIT_FILE, init_file); } #endif /* * Initialize the world. */ init_snmp("snmptrapd"); if (trap1_fmt_str_remember) { free_trap1_fmt(); free_trap2_fmt(); print_format1 = strdup(trap1_fmt_str_remember); print_format2 = strdup(trap1_fmt_str_remember); } if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_QUIT_IMMEDIATELY)) { /* * just starting up to process specific configuration and then * shutting down immediately. */ running = 0; } #ifndef WIN32 /* * fork the process to the background if we are not printing to stderr */ if (dofork && running) { int fd; switch (fork()) { case -1: fprintf(stderr, "bad fork - %s\n", strerror(errno)); _exit(1); case 0: /* * become process group leader */ if (setsid() == -1) { fprintf(stderr, "bad setsid - %s\n", strerror(errno)); _exit(1); } /* * if we are forked, we don't want to print out to stdout or stderr */ fd = open("/dev/null", O_RDWR); dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); close(fd); break; default: _exit(0); } } #endif /* WIN32 */ #if HAVE_GETPID if (pid_file != NULL) { if ((PID = fopen(pid_file, "w")) == NULL) { snmp_log_perror("fopen"); exit(1); } fprintf(PID, "%d\n", (int) getpid()); fclose(PID); free_config_pidFile(); } #endif if (Syslog) { snmp_enable_syslog_ident(app_name, Facility); snmp_log(LOG_INFO, "Starting snmptrapd %s\n", netsnmp_get_version()); if (depmsg) { snmp_log(LOG_WARNING, "-s and -S options are deprecated; use -Ls <facility> instead\n"); } } if (Print || Log) { struct tm *tm; time_t timer; time(&timer); tm = localtime(&timer); snmp_log(LOG_INFO, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d NET-SNMP version %s Started.\n", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, netsnmp_get_version()); } SOCK_STARTUP; if (listen_ports) cp = listen_ports; else cp = default_port; while (cp != NULL) { char *sep = strchr(cp, ','); char listen_name[128]; char *cp2 = strchr(cp, ':'); if (sep != NULL) { *sep = 0; } /* * Make sure this defaults to listening on port 162 */ if (!cp2) { snprintf(listen_name, sizeof(listen_name), "%s:162", cp); cp2 = listen_name; } else { cp2 = cp; } transport = netsnmp_tdomain_transport(cp2, 1, "udp"); if (transport == NULL) { snmp_log(LOG_ERR, "couldn't open %s -- errno %d (\"%s\")\n", cp2, errno, strerror(errno)); snmptrapd_close_sessions(sess_list); SOCK_CLEANUP; exit(1); } else { ss = snmptrapd_add_session(transport); if (ss == NULL) { /* * Shouldn't happen? We have already opened the transport * successfully so what could have gone wrong? */ snmptrapd_close_sessions(sess_list); netsnmp_transport_free(transport); if (Syslog) { snmp_log(LOG_ERR, "couldn't open snmp - %m"); } SOCK_CLEANUP; exit(1); } else { ss->next = sess_list; sess_list = ss; } } /* * Process next listen address, if there is one. */ if (sep != NULL) { *sep = ','; cp = sep + 1; } else { cp = NULL; } } signal(SIGTERM, term_handler); #ifdef SIGHUP signal(SIGHUP, hup_handler); #endif signal(SIGINT, term_handler); #ifdef WIN32SERVICE trapd_status = SNMPTRAPD_RUNNING; #endif while (running) { if (reconfig) { if (Print || Log) { struct tm *tm; time_t timer; time(&timer); tm = localtime(&timer); /* * If we are logging to a file, receipt of SIGHUP also * indicates the the log file should be closed and * re-opened. This is useful for users that want to * rotate logs in a more predictable manner. */ if (logfile) snmp_enable_filelog(logfile, 1); snmp_log(LOG_INFO, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d NET-SNMP version %s Reconfigured.\n", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, netsnmp_get_version()); } if (Syslog) snmp_log(LOG_INFO, "Snmptrapd reconfiguring"); trapd_update_config(); if (trap1_fmt_str_remember) { free_trap1_fmt(); print_format1 = strdup(trap1_fmt_str_remember); } reconfig = 0; } numfds = 0; FD_ZERO(&fdset); block = 0; tvp = &timeout; timerclear(tvp); tvp->tv_sec = 5; snmp_select_info(&numfds, &fdset, tvp, &block); if (block == 1) tvp = NULL; /* block without timeout */ count = select(numfds, &fdset, 0, 0, tvp); gettimeofday(&Now, 0); if (count > 0) { snmp_read(&fdset); } else switch (count) { case 0: snmp_timeout(); break; case -1: if (errno == EINTR) continue; snmp_log_perror("select"); running = 0; break; default: fprintf(stderr, "select returned %d\n", count); running = 0; } run_alarms(); } if (Print || Log) { struct tm *tm; time_t timer; time(&timer); tm = localtime(&timer); snmp_log(LOG_INFO, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d NET-SNMP version %s Stopped.\n", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, netsnmp_get_version()); } if (Syslog) { snmp_log(LOG_INFO, "Stopping snmptrapd"); } snmptrapd_close_sessions(sess_list); snmp_shutdown("snmptrapd"); #ifdef WIN32SERVICE trapd_status = SNMPTRAPD_STOPPED; #endif snmp_disable_log(); SOCK_CLEANUP; return 0; }
u_char * var_hrstore(struct variable *vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method) { int store_idx = 0; #if !defined(linux) #if defined(solaris2) int freemem; int swap_total, swap_used; #elif defined(hpux10) || defined(hpux11) struct pst_dynamic pst_buf; #elif defined(darwin8) vm_statistics_data_t vm_stat; int count = HOST_VM_INFO_COUNT; #elif defined(TOTAL_MEMORY_SYMBOL) || defined(USE_SYSCTL_VM) #ifdef VM_UVMEXP struct uvmexp uvmexp_totals; #endif struct vmtotal memory_totals; #endif #if HAVE_KVM_GETSWAPINFO struct kvm_swap swapinfo; static kvm_t *kd = NULL; #endif #if HAVE_SYS_POOL_H struct pool mbpool, mclpool; int i; #endif #ifdef MBSTAT_SYMBOL struct mbstat mbstat; #endif #endif /* !linux */ static char string[1024]; struct HRFS_statfs stat_buf; if (vp->magic == HRSTORE_MEMSIZE) { if (header_hrstore(vp, name, length, exact, var_len, write_method) == MATCH_FAILED) return NULL; } else { really_try_next: store_idx = header_hrstoreEntry(vp, name, length, exact, var_len, write_method); if (store_idx == MATCH_FAILED) return NULL; if (store_idx > HRS_TYPE_FIXED_MAX) { if (HRFS_statfs(HRFS_entry->HRFS_mount, &stat_buf) < 0) { snmp_log_perror(HRFS_entry->HRFS_mount); goto try_next; } } #if !defined(linux) && !defined(solaris2) else switch (store_idx) { case HRS_TYPE_MEM: case HRS_TYPE_SWAP: #ifdef USE_SYSCTL_VM { int mib[2]; size_t len = sizeof(memory_totals); mib[0] = CTL_VM; mib[1] = VM_METER; sysctl(mib, 2, &memory_totals, &len, NULL, 0); #ifdef VM_UVMEXP mib[1] = VM_UVMEXP; len = sizeof(uvmexp_totals); sysctl(mib, 2, &uvmexp_totals, &len, NULL, 0); #endif } #elif defined(darwin8) host_statistics(myHost,HOST_VM_INFO,&vm_stat,&count); #elif defined(hpux10) || defined(hpux11) pstat_getdynamic(&pst_buf, sizeof(struct pst_dynamic), 1, 0); #elif defined(TOTAL_MEMORY_SYMBOL) auto_nlist(TOTAL_MEMORY_SYMBOL, (char *) &memory_totals, sizeof(struct vmtotal)); #endif #if HAVE_KVM_GETSWAPINFO if (kd == NULL) kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL); if (!kd) { snmp_log_perror("kvm_openfiles"); goto try_next; } if (kvm_getswapinfo(kd, &swapinfo, 1, 0) < 0) { snmp_log_perror("kvm_getswapinfo"); goto try_next; } #endif break; #if !defined(hpux10) && !defined(hpux11) case HRS_TYPE_MBUF: #if HAVE_SYS_POOL_H auto_nlist(MBPOOL_SYMBOL, (char *) &mbpool, sizeof(mbpool)); auto_nlist(MCLPOOL_SYMBOL, (char *) &mclpool, sizeof(mclpool)); #endif #ifdef MBSTAT_SYMBOL auto_nlist(MBSTAT_SYMBOL, (char *) &mbstat, sizeof(mbstat)); #endif break; #endif /* !hpux10 && !hpux11 */ default: break; } #endif /* !linux && !solaris2 */ } switch (vp->magic) { case HRSTORE_MEMSIZE: long_return = physmem * (pagesize / 1024); return (u_char *) & long_return; case HRSTORE_INDEX: long_return = store_idx; return (u_char *) & long_return; case HRSTORE_TYPE: if (store_idx > HRS_TYPE_FIXED_MAX) if (storageUseNFS && Check_HR_FileSys_NFS()) storage_type_id[storage_type_len - 1] = 10; /* Network Disk */ else storage_type_id[storage_type_len - 1] = 4; /* Assume fixed */ else switch (store_idx) { case HRS_TYPE_MEM: storage_type_id[storage_type_len - 1] = 2; /* RAM */ break; case HRS_TYPE_SWAP: storage_type_id[storage_type_len - 1] = 3; /* Virtual Mem */ break; case HRS_TYPE_MBUF: storage_type_id[storage_type_len - 1] = 1; /* Other */ break; default: storage_type_id[storage_type_len - 1] = 1; /* Other */ break; } *var_len = sizeof(storage_type_id); return (u_char *) storage_type_id; case HRSTORE_DESCR: if (store_idx > HRS_TYPE_FIXED_MAX) { strncpy(string, HRFS_entry->HRFS_mount, sizeof(string)-1); string[ sizeof(string)-1 ] = 0; *var_len = strlen(string); return (u_char *) string; } else { /* store_idx = store_idx - 1; */ *var_len = strlen(hrs_descr[store_idx]); return (u_char *) hrs_descr[store_idx]; } case HRSTORE_UNITS: if (store_idx > HRS_TYPE_FIXED_MAX) #if HRFS_HAS_FRSIZE long_return = stat_buf.f_frsize; #else long_return = stat_buf.f_bsize; #endif else switch (store_idx) { case HRS_TYPE_MEM: case HRS_TYPE_SWAP: #if defined(USE_SYSCTL) || defined(solaris2) long_return = pagesize; #elif defined(NBPG) long_return = NBPG; #else long_return = 1024; /* Report in Kb */ #endif break; case HRS_TYPE_MBUF: #ifdef MSIZE long_return = MSIZE; #elif defined(linux) long_return = 1024; #else long_return = 256; #endif break; default: #if NO_DUMMY_VALUES goto try_next; #endif long_return = 1024; /* As likely as any! */ break; } return (u_char *) & long_return; case HRSTORE_SIZE: if (store_idx > HRS_TYPE_FIXED_MAX) long_return = stat_buf.f_blocks; else switch (store_idx) { #if defined(linux) case HRS_TYPE_MEM: case HRS_TYPE_SWAP: long_return = linux_mem(store_idx, HRSTORE_SIZE); break; #elif defined(solaris2) case HRS_TYPE_MEM: long_return = physmem; break; case HRS_TYPE_SWAP: sol_get_swapinfo(&swap_total, &swap_used); long_return = swap_total; break; #elif defined(hpux10) || defined(hpux11) case HRS_TYPE_MEM: long_return = pst_buf.psd_rm; break; case HRS_TYPE_SWAP: long_return = pst_buf.psd_vm; break; #elif defined(darwin8) case HRS_TYPE_MEM: long_return = physmem; break; case HRS_TYPE_SWAP: long_return = -1; break; #if defined(MBSTAT_SYMBOL) case HRS_TYPE_MBUF: long_return = mbstat.m_mbufs; break; #endif #elif defined(TOTAL_MEMORY_SYMBOL) || defined(USE_SYSCTL_VM) case HRS_TYPE_MEM: long_return = memory_totals.t_rm; break; case HRS_TYPE_SWAP: #if HAVE_KVM_GETSWAPINFO long_return = swapinfo.ksw_total; #elif defined(VM_UVMEXP) long_return = uvmexp_totals.swpages; #else long_return = memory_totals.t_vm; #endif break; #else /* !linux && !solaris2 && !hpux10 && !hpux11 && ... */ case HRS_TYPE_MEM: long_return = physmem; break; case HRS_TYPE_SWAP: #if NO_DUMMY_VALUES goto try_next; #endif long_return = 0; break; #endif /* !linux && !solaris2 && !hpux10 && !hpux11 && ... */ case HRS_TYPE_MBUF: #ifdef linux long_return = linux_mem(store_idx, HRSTORE_SIZE); #elif HAVE_SYS_POOL_H long_return = 0; for (i = 0; i < sizeof(mbstat.m_mtypes) / sizeof(mbstat.m_mtypes[0]); i++) long_return += mbstat.m_mtypes[i]; #elif defined(MBSTAT_SYMBOL) && defined(STRUCT_MBSTAT_HAS_M_MBUFS) long_return = mbstat.m_mbufs; #elif defined(NO_DUMMY_VALUES) goto try_next; #else long_return = 0; #endif break; default: #if NO_DUMMY_VALUES goto try_next; #endif long_return = 1024; break; } return (u_char *) & long_return; case HRSTORE_USED: if (store_idx > HRS_TYPE_FIXED_MAX) long_return = (stat_buf.f_blocks - stat_buf.f_bfree); else switch (store_idx) { #if defined(linux) case HRS_TYPE_MBUF: case HRS_TYPE_MEM: case HRS_TYPE_SWAP: long_return = linux_mem(store_idx, HRSTORE_USED); break; #elif defined(solaris2) case HRS_TYPE_MEM: getKstatInt("unix", "system_pages", "freemem", &freemem); long_return = physmem - freemem; break; case HRS_TYPE_SWAP: sol_get_swapinfo(&swap_total, &swap_used); long_return = swap_used; break; #elif defined(hpux10) || defined(hpux11) case HRS_TYPE_MEM: long_return = pst_buf.psd_arm; break; case HRS_TYPE_SWAP: long_return = pst_buf.psd_avm; break; #elif defined(darwin8) case HRS_TYPE_MEM: long_return = vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count; break; case HRS_TYPE_SWAP: long_return = -1; break; #if defined(MBSTAT_SYMBOL) case HRS_TYPE_MBUF: long_return = mbstat.m_mbufs; break; #endif #elif defined(TOTAL_MEMORY_SYMBOL) || defined(USE_SYSCTL_VM) case HRS_TYPE_MEM: long_return = memory_totals.t_arm; break; case HRS_TYPE_SWAP: #if HAVE_KVM_GETSWAPINFO long_return = swapinfo.ksw_used; #elif defined(VM_UVMEXP) long_return = uvmexp_totals.swpginuse; #else long_return = memory_totals.t_avm; #endif break; #endif /* linux || solaris2 || hpux10 || hpux11 || ... */ #if !defined(linux) && !defined(solaris2) && !defined(hpux10) && !defined(hpux11) case HRS_TYPE_MBUF: #if HAVE_SYS_POOL_H long_return = (mbpool.pr_nget - mbpool.pr_nput) * mbpool.pr_size + (mclpool.pr_nget - mclpool.pr_nput) * mclpool.pr_size; #ifdef MSIZE long_return /= MSIZE; #else long_return /= 256; #endif #elif defined(MBSTAT_SYMBOL) && defined(STRUCT_MBSTAT_HAS_M_CLUSTERS) long_return = mbstat.m_clusters - mbstat.m_clfree; /* unlikely, but... */ #elif defined(NO_DUMMY_VALUES) goto try_next; #else long_return = 0; #endif break; #endif /* !linux && !solaris2 && !hpux10 && !hpux11 && ... */ default: #if NO_DUMMY_VALUES goto try_next; #endif long_return = 1024; break; } return (u_char *) & long_return; case HRSTORE_FAILS: if (store_idx > HRS_TYPE_FIXED_MAX) #if NO_DUMMY_VALUES goto try_next; #else long_return = 0; #endif else switch (store_idx) {
/* * Load the latest memory usage statistics */ int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) { netsnmp_memory_info *mem; perfstat_memory_total_t pstat_mem; long pagesize; /* * Retrieve the memory information from the underlying O/S... */ if (perfstat_memory_total((perfstat_id_t *)NULL, &pstat_mem, sizeof(perfstat_memory_total_t), 1) < 1) { snmp_log(LOG_ERR, "memory_aix: perfstat_memory_total failed!\n"); return -1; } pagesize = getpagesize(); /* * ... and save this in a standard form. */ mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 1 ); if (!mem) { snmp_log_perror("No Physical Memory info entry"); } else { if (!mem->descr) mem->descr = strdup("Physical memory"); mem->units = pagesize; /* or 4096 */ mem->size = pstat_mem.real_total; mem->free = pstat_mem.real_free; } /* ??? Duplicates Physical Memory statistics? */ mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_USERMEM, 1 ); if (!mem) { snmp_log_perror("No (user) Memory info entry"); } else { if (!mem->descr) mem->descr = strdup("Real memory"); mem->units = pagesize; /* or 4096 */ mem->size = pstat_mem.real_total; /* ? less system memory ? */ mem->free = pstat_mem.real_free; } mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_VIRTMEM, 1 ); if (!mem) { snmp_log_perror("No Virtual Memory info entry"); } else { if (!mem->descr) mem->descr = strdup("Virtual memory"); mem->units = pagesize; /* or 4096 */ mem->size = pstat_mem.virt_total; mem->free = pstat_mem.real_free + pstat_mem.pgsp_free; } mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 1 ); if (!mem) { snmp_log_perror("No Swap info entry"); } else { if (!mem->descr) mem->descr = strdup("Swap space"); mem->units = pagesize; /* or 4096 */ mem->size = pstat_mem.pgsp_total; mem->free = pstat_mem.pgsp_free; mem->other = pstat_mem.pgsp_rsvd; } return 0; }
u_char * var_hrstore(struct variable *vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method) { int store_idx = 0; static char string[1024]; struct HRFS_statfs stat_buf; void *ptr; netsnmp_memory_info *mem = NULL; really_try_next: ptr = header_hrstoreEntry(vp, name, length, exact, var_len, write_method); if (ptr == NULL) return NULL; store_idx = name[ HRSTORE_ENTRY_NAME_LENGTH ]; if (store_idx > NETSNMP_MEM_TYPE_MAX ) { if ( netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES) && Check_HR_FileSys_NFS()) return NULL; /* or goto try_next; */ if (HRFS_statfs(HRFS_entry->HRFS_mount, &stat_buf) < 0) { snmp_log_perror(HRFS_entry->HRFS_mount); goto try_next; } } else { mem = (netsnmp_memory_info*)ptr; } switch (vp->magic) { case HRSTORE_INDEX: long_return = store_idx; return (u_char *) & long_return; case HRSTORE_TYPE: if (store_idx > NETSNMP_MEM_TYPE_MAX) if (storageUseNFS && Check_HR_FileSys_NFS()) storage_type_id[storage_type_len - 1] = 10; /* Network Disk */ #if HAVE_HASMNTOPT && !(defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)) /* * hasmntopt takes "const struct mntent*", but HRFS_entry has been * defined differently for AIX, so skip this for AIX */ else if (hasmntopt(HRFS_entry, "loop") != NULL) storage_type_id[storage_type_len - 1] = 5; /* Removable Disk */ #endif else storage_type_id[storage_type_len - 1] = 4; /* Assume fixed */ else switch (store_idx) { case NETSNMP_MEM_TYPE_PHYSMEM: case NETSNMP_MEM_TYPE_USERMEM: storage_type_id[storage_type_len - 1] = 2; /* RAM */ break; case NETSNMP_MEM_TYPE_VIRTMEM: case NETSNMP_MEM_TYPE_SWAP: storage_type_id[storage_type_len - 1] = 3; /* Virtual Mem */ break; default: storage_type_id[storage_type_len - 1] = 1; /* Other */ break; } *var_len = sizeof(storage_type_id); return (u_char *) storage_type_id; case HRSTORE_DESCR: if (store_idx > NETSNMP_MEM_TYPE_MAX) { strlcpy(string, HRFS_entry->HRFS_mount, sizeof(string)); *var_len = strlen(string); return (u_char *) string; } else { if ( !mem || !mem->descr ) goto try_next; *var_len = strlen(mem->descr); return (u_char *) mem->descr; } case HRSTORE_UNITS: if (store_idx > NETSNMP_MEM_TYPE_MAX) #if HRFS_HAS_FRSIZE long_return = stat_buf.f_frsize; #else long_return = stat_buf.f_bsize; #endif else { if ( !mem || mem->units == -1 ) goto try_next; long_return = mem->units; } return (u_char *) & long_return; case HRSTORE_SIZE: if (store_idx > NETSNMP_MEM_TYPE_MAX) long_return = stat_buf.f_blocks; else { if ( !mem || mem->size == -1 ) goto try_next; long_return = mem->size; } return (u_char *) & long_return; case HRSTORE_USED: if (store_idx > NETSNMP_MEM_TYPE_MAX) long_return = (stat_buf.f_blocks - stat_buf.f_bfree); else { if ( !mem || mem->size == -1 || mem->free == -1 ) goto try_next; long_return = mem->size - mem->free; } return (u_char *) & long_return; case HRSTORE_FAILS: if (store_idx > NETSNMP_MEM_TYPE_MAX) #if NETSNMP_NO_DUMMY_VALUES goto try_next; #else long_return = 0; #endif else { if ( !mem || mem->other == -1 )
/* * Load the latest memory usage statistics */ int netsnmp_mem_arch_load (netsnmp_cache * cache, void *magic) { netsnmp_memory_info *mem; struct rminfo meminfo; /* struct for getting memory info, see sys/sysmp.h */ int pagesz, rminfosz; off_t swaptotal, swapfree; /* * Retrieve the memory information from the underlying O/S... */ DEBUGMSGTL (("hardware/memory/memory_irix", "Start retrieving values from OS\n")); pagesz = getpagesize (); DEBUGMSGTL (("hardware/memory/memory_irix", "Page size: %d\n", pagesz)); rminfosz = (int) sysmp (MP_SASZ, MPSA_RMINFO); DEBUGMSGTL (("hardware/memory/memory_irix", "rminfo size: %d\n", rminfosz)); if (sysmp (MP_SAGET, MPSA_RMINFO, &meminfo, rminfosz) < 0) { snmp_log (LOG_ERR, "memory_irix: sysmp failed!\n"); return -1; } swapctl (SC_GETSWAPTOT, &swaptotal); swapctl (SC_GETFREESWAP, &swapfree); /* * ... and save this in a standard form. */ mem = netsnmp_memory_get_byIdx (NETSNMP_MEM_TYPE_PHYSMEM, 1); if (!mem) { snmp_log_perror ("No Physical Memory info entry"); } else { if (!mem->descr) mem->descr = strdup ("Physical memory"); mem->units = pagesz; mem->size = meminfo.physmem; mem->free = meminfo.availrmem; mem->other = -1; DEBUGMSGTL (("hardware/memory/memory_irix", "Physical memory: size %u, free %u\n", mem->size, mem->free)); } mem = netsnmp_memory_get_byIdx (NETSNMP_MEM_TYPE_VIRTMEM, 1); if (!mem) { snmp_log_perror ("No Virtual Memory info entry"); } else { if (!mem->descr) mem->descr = strdup ("Virtual memory"); mem->units = pagesz; /* swaptotal is in blocks, so adjust below */ mem->size = meminfo.physmem + (swaptotal * 512 / pagesz); mem->free = meminfo.availsmem; mem->other = -1; DEBUGMSGTL (("hardware/memory/memory_irix", "Virtual memory: size %u, free %u\n", mem->size, mem->free)); } mem = netsnmp_memory_get_byIdx (NETSNMP_MEM_TYPE_SWAP, 1); if (!mem) { snmp_log_perror ("No Swap info entry"); } else { if (!mem->descr) mem->descr = strdup ("Swap space"); mem->units = 1024; mem->size = swaptotal / 2; /* blocks to KB */ mem->free = swapfree / 2; /* blocks to KB */ mem->other = -1; DEBUGMSGTL (("hardware/memory/memory_irix", "Swap: size %u, free %u\n", mem->size, mem->free)); } return 0; }