diff --git a/IETF-MIB-LICENSE.txt b/IETF-MIB-LICENSE.txt deleted file mode 100644 index 5fd2a6a..0000000 --- a/IETF-MIB-LICENSE.txt +++ /dev/null @@ -1,41 +0,0 @@ -MIBs included in this software taken from IETF Documents are considered -Code Components in accordance with the IETF Trust License Policy, as found -here: - -http://trustee.ietf.org/license-info/ - -They are available under the terms of the Simplified BSD license, a copy of -which is included below. - -***** - -Copyright (c) 2013 IETF Trust and the persons identified as authors of -the code. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -· Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - -· Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -· Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS -IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/agent/Makefile.in b/agent/Makefile.in index 9571c53..4448009 100644 --- a/agent/Makefile.in +++ b/agent/Makefile.in @@ -297,7 +297,7 @@ getmibstat.o: mibgroup/kernel_sunos5.c $(CC) $(CFLAGS) -o $@ -D_GETMIBSTAT_TEST -DDODEBUG -c $? snmpd$(EXEEXT): ${LAGENTOBJS} $(USELIBS) $(AGENTLIB) $(HELPERLIB) $(MIBLIB) $(LIBTARG) - $(LINK) $(CFLAGS) -o $@ -pie ${LAGENTOBJS} ${LDFLAGS} ${OUR_AGENT_LIBS} + $(LINK) $(CFLAGS) -o $@ ${LAGENTOBJS} ${LDFLAGS} ${OUR_AGENT_LIBS} libnetsnmpagent.$(LIB_EXTENSION)$(LIB_VERSION): ${LLIBAGENTOBJS} $(USELIBS) $(LIB_LD_CMD) $(AGENTLIB) ${LLIBAGENTOBJS} $(USELIBS) ${LAGENTLIBS} @LD_NO_UNDEFINED@ $(LDFLAGS) $(PERLLDOPTS_FOR_LIBS) $(LIB_LD_LIBS) @AGENTLIBS@ diff --git a/agent/agent_trap.c b/agent/agent_trap.c index 667b4ed..d49c2dc 100644 --- a/agent/agent_trap.c +++ b/agent/agent_trap.c @@ -174,11 +174,6 @@ _trap_version_incr(int version) case SNMP_VERSION_3: ++_v2_sessions; break; -#ifdef USING_AGENTX_PROTOCOL_MODULE - case AGENTX_VERSION_1: - /* agentx registers in sinks, no need to count */ - break; -#endif default: snmp_log(LOG_ERR, "unknown snmp version %d\n", version); } @@ -206,11 +201,6 @@ _trap_version_decr(int version) _v2_sessions = 0; } break; -#ifdef USING_AGENTX_PROTOCOL_MODULE - case AGENTX_VERSION_1: - /* agentx registers in sinks, no need to count */ - break; -#endif default: snmp_log(LOG_ERR, "unknown snmp version %d\n", version); } diff --git a/agent/mibgroup/agentx/master.c b/agent/mibgroup/agentx/master.c index 93d5621..99c4123 100644 --- a/agent/mibgroup/agentx/master.c +++ b/agent/mibgroup/agentx/master.c @@ -221,7 +221,7 @@ agentx_got_response(int operation, /* response is too late, free the cache */ if (magic) netsnmp_free_delegated_cache((netsnmp_delegated_cache*) magic); - return 1; + return 0; } requests = cache->requests; @@ -280,11 +280,6 @@ agentx_got_response(int operation, netsnmp_free_delegated_cache(cache); return 0; - case NETSNMP_CALLBACK_OP_RESEND: - DEBUGMSGTL(("agentx/master", "resend on session %8p req=0x%x\n", - session, (unsigned)reqid)); - return 0; - case NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE: /* * This session is alive diff --git a/agent/mibgroup/disman/event/mteTrigger.c b/agent/mibgroup/disman/event/mteTrigger.c index 6cdf2bb..c02e32f 100644 --- a/agent/mibgroup/disman/event/mteTrigger.c +++ b/agent/mibgroup/disman/event/mteTrigger.c @@ -1012,7 +1012,7 @@ mteTrigger_run( unsigned int reg, void *clientarg) * Similarly, if no fallEvent is configured, * there's no point in trying to fire it either. */ - if (entry->mteTThFallEvent[0] != '\0' ) { + if (entry->mteTThRiseEvent[0] != '\0' ) { entry->mteTriggerXOwner = entry->mteTThObjOwner; entry->mteTriggerXObjects = entry->mteTThObjects; entry->mteTriggerFired = vp1; @@ -1105,7 +1105,7 @@ mteTrigger_run( unsigned int reg, void *clientarg) * Similarly, if no fallEvent is configured, * there's no point in trying to fire it either. */ - if (entry->mteTThDFallEvent[0] != '\0' ) { + if (entry->mteTThDRiseEvent[0] != '\0' ) { entry->mteTriggerXOwner = entry->mteTThObjOwner; entry->mteTriggerXObjects = entry->mteTThObjects; entry->mteTriggerFired = vp1; diff --git a/agent/mibgroup/hardware/cpu/cpu_linux.c b/agent/mibgroup/hardware/cpu/cpu_linux.c index 5f1489f..ad8eae2 100644 --- a/agent/mibgroup/hardware/cpu/cpu_linux.c +++ b/agent/mibgroup/hardware/cpu/cpu_linux.c @@ -122,7 +122,6 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { bsize = getpagesize()-1; buff = (char*)malloc(bsize+1); if (buff == NULL) { - close(statfd); return -1; } } diff --git a/agent/mibgroup/hardware/fsys/fsys_mntctl.c b/agent/mibgroup/hardware/fsys/fsys_mntctl.c index 3364dc5..e7d9a1c 100644 --- a/agent/mibgroup/hardware/fsys/fsys_mntctl.c +++ b/agent/mibgroup/hardware/fsys/fsys_mntctl.c @@ -43,9 +43,8 @@ _fsys_type( int type) case MNT_NFS: case MNT_NFS3: - return NETSNMP_FS_TYPE_NFS; case MNT_AUTOFS: - return NETSNMP_FS_TYPE_AUTOFS; + return NETSNMP_FS_TYPE_NFS; /* * The following code covers selected filesystems @@ -157,12 +156,10 @@ netsnmp_fsys_arch_load( void ) /* * Optionally skip retrieving statistics for remote mounts - * AUTOFS is skipped by default */ - if ( ((entry->flags & NETSNMP_FS_FLAG_REMOTE) && + if ( (entry->flags & NETSNMP_FS_FLAG_REMOTE) && netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, - NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES)) || - entry->type == (NETSNMP_FS_TYPE_AUTOFS)) + NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES)) continue; if ( statfs( entry->path, &stat_buf ) < 0 ) { diff --git a/agent/mibgroup/hardware/fsys/fsys_mntent.c b/agent/mibgroup/hardware/fsys/fsys_mntent.c index 93e405d..3cdcea1 100644 --- a/agent/mibgroup/hardware/fsys/fsys_mntent.c +++ b/agent/mibgroup/hardware/fsys/fsys_mntent.c @@ -150,13 +150,6 @@ _fsys_type( char *typename ) !strcmp(typename, MNTTYPE_LOFS)) return NETSNMP_FS_TYPE_OTHER; - /* Detection of AUTOFS. - * This file system will be ignored by default - */ - else if ( !strcmp(typename, MNTTYPE_AUTOFS)) - return NETSNMP_FS_TYPE_AUTOFS; - - /* * All other types are silently skipped */ @@ -246,10 +239,6 @@ netsnmp_fsys_arch_load( void ) NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES)) continue; - /* Skip AUTOFS enteries */ - if ( entry->type == (NETSNMP_FS_TYPE_AUTOFS)) - continue; - #ifdef irix6 if ( NSFS_STATFS( entry->path, &stat_buf, sizeof(struct statfs), 0) < 0 ) #else diff --git a/agent/mibgroup/hardware/fsys/mnttypes.h b/agent/mibgroup/hardware/fsys/mnttypes.h index 53f1cc8..bb1b401 100644 --- a/agent/mibgroup/hardware/fsys/mnttypes.h +++ b/agent/mibgroup/hardware/fsys/mnttypes.h @@ -165,9 +165,6 @@ #ifndef MNTTYPE_APP #define MNTTYPE_APP "app" #endif -#ifndef MNTTYPE_AUTOFS -#define MNTTYPE_AUTOFS "autofs" -#endif #ifndef MNTTYPE_DEVPTS #define MNTTYPE_DEVPTS "devpts" #endif diff --git a/agent/mibgroup/hardware/memory/memory_linux.c b/agent/mibgroup/hardware/memory/memory_linux.c index 2e972df..6c20d95 100644 --- a/agent/mibgroup/hardware/memory/memory_linux.c +++ b/agent/mibgroup/hardware/memory/memory_linux.c @@ -29,7 +29,7 @@ int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) { ssize_t bytes_read; char *b; unsigned long memtotal = 0, memfree = 0, memshared = 0, - buffers = 0, cached = 0, sreclaimable = 0, + buffers = 0, cached = 0, swaptotal = 0, swapfree = 0; netsnmp_memory_info *mem; @@ -127,13 +127,6 @@ int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) { if (first) snmp_log(LOG_ERR, "No SwapTotal line in /proc/meminfo\n"); } - b = strstr(buff, "SReclaimable: "); - if (b) - sscanf(b, "SReclaimable: %lu", &sreclaimable); - else { - if (first) - snmp_log(LOG_ERR, "No SReclaimable line in /proc/meminfo\n"); - } b = strstr(buff, "SwapFree: "); if (b) sscanf(b, "SwapFree: %lu", &swapfree); @@ -190,7 +183,7 @@ int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) { if (!mem->descr) mem->descr = strdup("Cached memory"); mem->units = 1024; - mem->size = cached+sreclaimable; + mem->size = cached; mem->free = 0; /* Report cached size/used as equal */ mem->other = -1; } diff --git a/agent/mibgroup/host/data_access/swinst_rpm.c b/agent/mibgroup/host/data_access/swinst_rpm.c index 15ff470..f6bb2e0 100644 --- a/agent/mibgroup/host/data_access/swinst_rpm.c +++ b/agent/mibgroup/host/data_access/swinst_rpm.c @@ -75,9 +75,6 @@ netsnmp_swinst_arch_init(void) snprintf( pkg_directory, SNMP_MAXPATH, "%s/Packages", dbpath ); SNMP_FREE(rpmdbpath); dbpath = NULL; -#ifdef HAVE_RPMGETPATH - rpmFreeRpmrc(); -#endif if (-1 == stat( pkg_directory, &stat_buf )) { snmp_log(LOG_ERR, "Can't find directory of RPM packages"); pkg_directory[0] = '\0'; @@ -105,6 +102,7 @@ netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags) rpmtd td_name, td_version, td_release, td_group, td_time; #else char *n, *v, *r, *g; + int32_t *t; #endif time_t install_time; size_t date_len; @@ -148,13 +146,14 @@ netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags) install_time = rpmtdGetNumber(td_time); g = rpmtdGetString(td_group); #else - n = headerGetString( h, RPMTAG_NAME); - v = headerGetString( h, RPMTAG_VERSION); - r = headerGetString( h, RPMTAG_RELEASE); - g = headerGetString( h, RPMTAG_GROUP); - install_time = headerGetNumber( h, RPMTAG_INSTALLTIME); + headerGetEntry( h, RPMTAG_NAME, NULL, (void**)&n, NULL); + headerGetEntry( h, RPMTAG_VERSION, NULL, (void**)&v, NULL); + headerGetEntry( h, RPMTAG_RELEASE, NULL, (void**)&r, NULL); + headerGetEntry( h, RPMTAG_GROUP, NULL, (void**)&g, NULL); + headerGetEntry( h, RPMTAG_INSTALLTIME, NULL, (void**)&t, NULL); entry->swName_len = snprintf( entry->swName, sizeof(entry->swName), "%s-%s-%s", n, v, r); + install_time = *t; #endif entry->swType = (g && NULL != strstr( g, "System Environment")) ? 2 /* operatingSystem */ diff --git a/agent/mibgroup/host/data_access/swrun.c b/agent/mibgroup/host/data_access/swrun.c index 111eda0..fc23eda 100644 --- a/agent/mibgroup/host/data_access/swrun.c +++ b/agent/mibgroup/host/data_access/swrun.c @@ -144,10 +144,6 @@ swrun_count_processes_by_name( char *name ) return 0; /* or -1 */ it = CONTAINER_ITERATOR( swrun_container ); - if((entry = (netsnmp_swrun_entry*)ITERATOR_FIRST( it )) != NULL) { - if (0 == strcmp( entry->hrSWRunName, name )) - i++; - } while ((entry = (netsnmp_swrun_entry*)ITERATOR_NEXT( it )) != NULL) { if (0 == strcmp( entry->hrSWRunName, name )) i++; diff --git a/agent/mibgroup/host/hr_filesys.c b/agent/mibgroup/host/hr_filesys.c index bc11123..56c8b20 100644 --- a/agent/mibgroup/host/hr_filesys.c +++ b/agent/mibgroup/host/hr_filesys.c @@ -834,27 +834,6 @@ Check_HR_FileSys_NFS (void) return 0; /* no NFS file system */ } -/* This function checks whether current file system is an AutoFs - * HRFS_entry must be valid prior to calling this function - * return 1 if AutoFs, 0 otherwise - */ -int -Check_HR_FileSys_AutoFs (void) -{ -#if HAVE_GETFSSTAT - if ( HRFS_entry->HRFS_type != NULL && -#if defined(MNTTYPE_AUTOFS) - !strcmp( HRFS_entry->HRFS_type, MNTTYPE_AUTOFS) -#else - !strcmp( HRFS_entry->HRFS_type, "autofs") -#endif - ) -#endif /* HAVE_GETFSSTAT */ - return 1; /* AUTOFS */ - - return 0; /* no AUTOFS */ -} - void End_HR_FileSys(void) { diff --git a/agent/mibgroup/host/hr_filesys.h b/agent/mibgroup/host/hr_filesys.h index 36cd7dd..2f00355 100644 --- a/agent/mibgroup/host/hr_filesys.h +++ b/agent/mibgroup/host/hr_filesys.h @@ -10,7 +10,6 @@ extern void Init_HR_FileSys(void); extern FindVarMethod var_hrfilesys; extern int Get_Next_HR_FileSys(void); extern int Check_HR_FileSys_NFS(void); -extern int Check_HR_FileSys_AutoFs(void); extern int Get_FSIndex(char *); extern long Get_FSSize(char *); /* Temporary */ diff --git a/agent/mibgroup/host/hr_storage.c b/agent/mibgroup/host/hr_storage.c index b7c23fd..a868984 100644 --- a/agent/mibgroup/host/hr_storage.c +++ b/agent/mibgroup/host/hr_storage.c @@ -540,10 +540,9 @@ really_try_next: store_idx = name[ HRSTORE_ENTRY_NAME_LENGTH ]; if (store_idx > NETSNMP_MEM_TYPE_MAX ) { - if ( (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, + if ( netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES) && - Check_HR_FileSys_NFS()) || - Check_HR_FileSys_AutoFs()) + 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); @@ -684,8 +683,7 @@ Get_Next_HR_Store(void) if (HRS_index >= 0) { if (!(netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES) && - Check_HR_FileSys_NFS()) && - !Check_HR_FileSys_AutoFs()) { + Check_HR_FileSys_NFS())) { return HRS_index + NETSNMP_MEM_TYPE_MAX; } } else { diff --git a/agent/mibgroup/host/hr_swinst.c b/agent/mibgroup/host/hr_swinst.c index 1b0d3b3..c2cf5e5 100644 --- a/agent/mibgroup/host/hr_swinst.c +++ b/agent/mibgroup/host/hr_swinst.c @@ -231,9 +231,6 @@ init_hr_swinst(void) snprintf(path, sizeof(path), "%s/packages.rpm", swi->swi_dbpath); path[ sizeof(path)-1 ] = 0; swi->swi_directory = strdup(path); -#ifdef HAVE_RPMGETPATH - rpmFreeRpmrc(); -#endif } #else # ifdef _PATH_HRSW_directory @@ -482,9 +479,9 @@ var_hrswinst(struct variable * vp, } #else # ifdef HAVE_LIBRPM - const char *rpm_group = headerGetString(swi->swi_h, RPMTAG_GROUP); - if ( NULL != rpm_group ) { - if ( strstr(rpm_group, "System Environment") != NULL ) + char *rpm_groups; + if ( headerGetEntry(swi->swi_h, RPMTAG_GROUP, NULL, (void **) &rpm_groups, NULL) ) { + if ( strstr(rpm_groups, "System Environment") != NULL ) long_return = 2; /* operatingSystem */ else long_return = 4; /* applcation */ @@ -501,8 +498,9 @@ var_hrswinst(struct variable * vp, case HRSWINST_DATE: { #ifdef HAVE_LIBRPM - time_t installTime = headerGetNumber(swi->swi_h, RPMTAG_INSTALLTIME); - if ( 0 != installTime ) { + int32_t *rpm_data; + if ( headerGetEntry(swi->swi_h, RPMTAG_INSTALLTIME, NULL, (void **) &rpm_data, NULL) ) { + time_t installTime = *rpm_data; ret = date_n_time(&installTime, var_len); } else { ret = date_n_time(NULL, var_len); @@ -662,7 +660,7 @@ Save_HR_SW_info(int ix) if (1 <= ix && ix <= swi->swi_nrec && ix != swi->swi_prevx) { int offset; Header h; - const char *n, *v, *r; + char *n, *v, *r; offset = swi->swi_recs[ix - 1]; @@ -687,9 +685,11 @@ Save_HR_SW_info(int ix) swi->swi_h = h; swi->swi_prevx = ix; - n = headerGetString(swi->swi_h, RPMTAG_NAME); - v = headerGetString(swi->swi_h, RPMTAG_VERSION); - r = headerGetString(swi->swi_h, RPMTAG_RELEASE); + headerGetEntry(swi->swi_h, RPMTAG_NAME, NULL, (void **) &n, NULL); + headerGetEntry(swi->swi_h, RPMTAG_VERSION, NULL, (void **) &v, + NULL); + headerGetEntry(swi->swi_h, RPMTAG_RELEASE, NULL, (void **) &r, + NULL); snprintf(swi->swi_name, sizeof(swi->swi_name), "%s-%s-%s", n, v, r); swi->swi_name[ sizeof(swi->swi_name)-1 ] = 0; } diff --git a/agent/mibgroup/host/hrh_filesys.c b/agent/mibgroup/host/hrh_filesys.c index 5bdf02b..5ad82b2 100644 --- a/agent/mibgroup/host/hrh_filesys.c +++ b/agent/mibgroup/host/hrh_filesys.c @@ -429,9 +429,3 @@ Check_HR_FileSys_NFS (void) { return (HRFS_entry->flags & NETSNMP_FS_FLAG_REMOTE) ? 1 : 0; } - -int -Check_HR_FileSys_AutoFs (void) -{ - return (HRFS_entry->type == (NETSNMP_FS_TYPE_AUTOFS)) ? 1 : 0; -} diff --git a/agent/mibgroup/host/hrh_filesys.h b/agent/mibgroup/host/hrh_filesys.h index c0f5d6e..568917e 100644 --- a/agent/mibgroup/host/hrh_filesys.h +++ b/agent/mibgroup/host/hrh_filesys.h @@ -10,7 +10,6 @@ extern void Init_HR_FileSys(void); extern FindVarMethod var_hrhfilesys; extern int Get_Next_HR_FileSys(void); extern int Check_HR_FileSys_NFS(void); -extern int Check_HR_FileSys_AutoFs(void); extern int Get_FSIndex(char *); extern long Get_FSSize(char *); /* Temporary */ diff --git a/agent/mibgroup/host/hrh_storage.c b/agent/mibgroup/host/hrh_storage.c index 490ae90..8107669 100644 --- a/agent/mibgroup/host/hrh_storage.c +++ b/agent/mibgroup/host/hrh_storage.c @@ -367,10 +367,9 @@ really_try_next: store_idx = name[ HRSTORE_ENTRY_NAME_LENGTH ]; if (HRFS_entry && store_idx > NETSNMP_MEM_TYPE_MAX && - ((netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, + netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES) && - Check_HR_FileSys_NFS()) || - Check_HR_FileSys_AutoFs())) + Check_HR_FileSys_NFS()) return NULL; if (store_idx <= NETSNMP_MEM_TYPE_MAX ) { mem = (netsnmp_memory_info*)ptr; @@ -509,8 +508,7 @@ Get_Next_HR_Store(void) if (HRS_index >= 0) { if (!(netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES) && - Check_HR_FileSys_NFS()) && - !Check_HR_FileSys_AutoFs()) { + Check_HR_FileSys_NFS())) { return HRS_index + NETSNMP_MEM_TYPE_MAX; } } else { diff --git a/agent/mibgroup/ip-mib/data_access/ipaddress_common.c b/agent/mibgroup/ip-mib/data_access/ipaddress_common.c index 2f61230..72c2714 100644 --- a/agent/mibgroup/ip-mib/data_access/ipaddress_common.c +++ b/agent/mibgroup/ip-mib/data_access/ipaddress_common.c @@ -121,7 +121,6 @@ _remove_duplicates(netsnmp_container *container, u_int container_flags) for (entry = ITERATOR_FIRST(it); entry; entry = ITERATOR_NEXT(it)) { if (prev_entry && _access_ipaddress_entry_compare_addr(prev_entry, entry) == 0) { /* 'entry' is duplicate of the previous one -> delete it */ - NETSNMP_LOGONCE((LOG_ERR, "Duplicate IPv4 address detected, some interfaces may not be visible in IP-MIB\n")); netsnmp_access_ipaddress_entry_free(entry); } else { CONTAINER_INSERT(ret, entry); diff --git a/agent/mibgroup/ip-mib/data_access/ipaddress_linux.c b/agent/mibgroup/ip-mib/data_access/ipaddress_linux.c index b57000a..8743130 100644 --- a/agent/mibgroup/ip-mib/data_access/ipaddress_linux.c +++ b/agent/mibgroup/ip-mib/data_access/ipaddress_linux.c @@ -234,7 +234,7 @@ _load_v6(netsnmp_container *container, int idx_offset) #define PROCFILE "/proc/net/if_inet6" if (!(in = fopen(PROCFILE, "r"))) { - NETSNMP_LOGONCE((LOG_ERR, "ipaddress_linux: could not open " PROCFILE)); + snmp_log_perror("ipaddress_linux: could not open " PROCFILE); return -2; } @@ -543,18 +543,15 @@ netsnmp_access_ipaddress_extra_prefix_info(int index, u_long *preferedlt, status = send (sd, &req, req.nlhdr.nlmsg_len, 0); if (status < 0) { snmp_log(LOG_ERR, "could not send netlink request\n"); - close(sd); return -1; } status = recv (sd, buf, sizeof(buf), 0); if (status < 0) { snmp_log (LOG_ERR, "could not recieve netlink request\n"); - close(sd); return -1; } if (status == 0) { snmp_log (LOG_ERR, "nothing to read\n"); - close(sd); return -1; } for (nlmp = (struct nlmsghdr *)buf; status > sizeof(*nlmp); ){ @@ -564,13 +561,11 @@ netsnmp_access_ipaddress_extra_prefix_info(int index, u_long *preferedlt, if (req_len < 0 || len > status) { snmp_log (LOG_ERR, "invalid netlink message\n"); - close(sd); return -1; } if (!NLMSG_OK (nlmp, status)) { snmp_log (LOG_ERR, "invalid NLMSG message\n"); - close(sd); return -1; } rtmp = (struct ifaddrmsg *)NLMSG_DATA(nlmp); diff --git a/agent/mibgroup/mibII/ipAddr.c b/agent/mibgroup/mibII/ipAddr.c index ffed5cd..2b9d3d1 100644 --- a/agent/mibgroup/mibII/ipAddr.c +++ b/agent/mibgroup/mibII/ipAddr.c @@ -495,16 +495,14 @@ Address_Scan_Next(Index, Retin_ifaddr) } #elif defined(linux) -#include static struct ifreq *ifr; static int ifr_counter; static void Address_Scan_Init(void) { - int i; + int num_interfaces = 0; int fd; - int lastlen = 0; /* get info about all interfaces */ @@ -512,45 +510,28 @@ Address_Scan_Init(void) SNMP_FREE(ifc.ifc_buf); ifr_counter = 0; + do + { if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { DEBUGMSGTL(("snmpd", "socket open failure in Address_Scan_Init\n")); return; } + num_interfaces += 16; - /* - * Cope with lots of interfaces and brokenness of ioctl SIOCGIFCONF - * on some platforms; see W. R. Stevens, ``Unix Network Programming - * Volume I'', p.435... - */ - - for (i = 8;; i *= 2) { - ifc.ifc_len = sizeof(struct ifreq) * i; - ifc.ifc_req = calloc(i, sizeof(struct ifreq)); - - if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) { - if (errno != EINVAL || lastlen != 0) { - /* - * Something has gone genuinely wrong... - */ - snmp_log(LOG_ERR, "bad rc from ioctl, errno %d", errno); - SNMP_FREE(ifc.ifc_buf); - close(fd); - return; - } - } else { - if (ifc.ifc_len == lastlen) { - /* - * The length is the same as the last time; we're done... - */ - break; - } - lastlen = ifc.ifc_len; - } - free(ifc.ifc_buf); /* no SNMP_FREE, getting ready to reassign */ + ifc.ifc_len = sizeof(struct ifreq) * num_interfaces; + ifc.ifc_buf = (char*) realloc(ifc.ifc_buf, ifc.ifc_len); + + if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) + { + ifr=NULL; + close(fd); + return; + } + close(fd); } - - close(fd); + while (ifc.ifc_len >= (sizeof(struct ifreq) * num_interfaces)); + ifr = ifc.ifc_req; } diff --git a/agent/mibgroup/ucd-snmp/disk.c b/agent/mibgroup/ucd-snmp/disk.c index e8e8923..d827dcc 100644 --- a/agent/mibgroup/ucd-snmp/disk.c +++ b/agent/mibgroup/ucd-snmp/disk.c @@ -153,10 +153,9 @@ static void disk_free_config(void); static void disk_parse_config(const char *, char *); static void disk_parse_config_all(const char *, char *); #if HAVE_FSTAB_H || HAVE_GETMNTENT || HAVE_STATFS -static void refresh_disk_table(int addNewDisks, int minpercent); +static void find_and_add_allDisks(int minpercent); static void add_device(char *path, char *device, - int minspace, int minpercent, int addNewDisks, - int override); + int minspace, int minpercent, int override); static void modify_disk_parameters(int index, int minspace, int minpercent); static int disk_exists(char *path); @@ -168,7 +167,6 @@ struct diskpart { char path[STRMAX]; int minimumspace; int minpercent; - int alive; }; #define MAX_INT_32 0x7fffffff @@ -176,7 +174,6 @@ struct diskpart { unsigned int numdisks; int allDisksIncluded = 0; -int allDisksMinPercent = 0; unsigned int maxdisks = 0; struct diskpart *disks; @@ -241,7 +238,6 @@ init_disk(void) disk_free_config, "minpercent%"); allDisksIncluded = 0; - allDisksMinPercent = 0; } static void @@ -257,7 +253,6 @@ disk_free_config(void) disks[i].minpercent = -1; } allDisksIncluded = 0; - allDisksMinPercent = 0; } static void @@ -318,7 +313,7 @@ disk_parse_config(const char *token, char *cptr) * check if the disk already exists, if so then modify its * parameters. if it does not exist then add it */ - add_device(path, find_device(path), minspace, minpercent, 1, 1); + add_device(path, find_device(path), minspace, minpercent, 1); #endif /* HAVE_FSTAB_H || HAVE_GETMNTENT || HAVE_STATFS */ } @@ -377,7 +372,7 @@ disk_parse_config_all(const char *token, char *cptr) #if HAVE_FSTAB_H || HAVE_GETMNTENT || HAVE_STATFS static void -add_device(char *path, char *device, int minspace, int minpercent, int addNewDisks, int override) +add_device(char *path, char *device, int minspace, int minpercent, int override) { int index; @@ -407,16 +402,10 @@ add_device(char *path, char *device, int minspace, int minpercent, int addNewDis } index = disk_exists(path); - if((index != -1) && (index < maxdisks)) { - /* the path is already in the table */ - disks[index].alive = 1; - /* -> update its device */ - strlcpy(disks[index].device, device, sizeof(disks[index].device)); - if (override == 1) { - modify_disk_parameters(index, minspace, minpercent); - } + if((index != -1) && (index < maxdisks) && (override==1)) { + modify_disk_parameters(index, minspace, minpercent); } - else if(index == -1 && addNewDisks){ + else if(index == -1){ /* add if and only if the device was found */ if(device[0] != 0) { /* The following buffers are cleared above, no need to add '\0' */ @@ -424,7 +413,6 @@ add_device(char *path, char *device, int minspace, int minpercent, int addNewDis strlcpy(disks[numdisks].device, device, sizeof(disks[numdisks].device)); disks[numdisks].minimumspace = minspace; disks[numdisks].minpercent = minpercent; - disks[numdisks].alive = 1; numdisks++; } else { @@ -432,7 +420,6 @@ add_device(char *path, char *device, int minspace, int minpercent, int addNewDis disks[numdisks].minpercent = -1; disks[numdisks].path[0] = 0; disks[numdisks].device[0] = 0; - disks[numdisks].alive = 0; } } } @@ -457,7 +444,7 @@ int disk_exists(char *path) } static void -refresh_disk_table(int addNewDisks, int minpercent) +find_and_add_allDisks(int minpercent) { #if HAVE_GETMNTENT #if HAVE_SYS_MNTTAB_H @@ -493,7 +480,7 @@ refresh_disk_table(int addNewDisks, int minpercent) return; } while (mntfp && NULL != (mntent = getmntent(mntfp))) { - add_device(mntent->mnt_dir, mntent->mnt_fsname, -1, minpercent, addNewDisks, 0); + add_device(mntent->mnt_dir, mntent->mnt_fsname, -1, minpercent, 0); dummy = 1; } if (mntfp) @@ -510,7 +497,7 @@ refresh_disk_table(int addNewDisks, int minpercent) return; } while ((i = getmntent(mntfp, &mnttab)) == 0) { - add_device(mnttab.mnt_mountp, mnttab.mnt_special, -1, minpercent, addNewDisks, 0); + add_device(mnttab.mnt_mountp, mnttab.mnt_special, -1, minpercent, 0); dummy = 1; } fclose(mntfp); @@ -523,7 +510,7 @@ refresh_disk_table(int addNewDisks, int minpercent) #elif HAVE_FSTAB_H setfsent(); /* open /etc/fstab */ while((fstab1 = getfsent()) != NULL) { - add_device(fstab1->fs_file, fstab1->fs_spec, -1, minpercent, addNewDisks, 0); + add_device(fstab1->fs_file, fstab1->fs_spec, -1, minpercent, 0); dummy = 1; } endfsent(); /* close /etc/fstab */ @@ -534,7 +521,7 @@ refresh_disk_table(int addNewDisks, int minpercent) mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); for (i = 0; i < mntsize; i++) { if (strncmp(mntbuf[i].f_fstypename, "zfs", 3) == 0) { - add_device(mntbuf[i].f_mntonname, mntbuf[i].f_mntfromname, -1, minpercent, addNewDisks, 0); + add_device(mntbuf[i].f_mntonname, mntbuf[i].f_mntfromname, -1, minpercent, 0); } } } @@ -550,7 +537,7 @@ refresh_disk_table(int addNewDisks, int minpercent) * statfs we default to the root partition "/" */ if (statfs("/", &statf) == 0) { - add_device("/", statf.f_mntfromname, -1, minpercent, addNewDisks, 0); + add_device("/", statf.f_mntfromname, -1, minpercent, 0); } #endif else { @@ -709,10 +696,6 @@ fill_dsk_entry(int disknum, struct dsk_entry *entry) #endif #endif - if (disks[disknum].alive == 0){ - return -1; - } - entry->dskPercentInode = -1; #if defined(HAVE_STATVFS) || defined(HAVE_STATFS) @@ -843,13 +826,6 @@ var_extensible_disk(struct variable *vp, static long long_ret; static char *errmsg; - int i; - for (i = 0; i < numdisks; i++){ - disks[i].alive = 0; - } - /* dynamically add new disks + update alive flag */ - refresh_disk_table(allDisksIncluded, allDisksMinPercent); - tryAgain: if (header_simple_table (vp, name, length, exact, var_len, write_method, numdisks)) diff --git a/agent/mibgroup/ucd-snmp/proxy.c b/agent/mibgroup/ucd-snmp/proxy.c index 1ef2383..a30ac3f 100644 --- a/agent/mibgroup/ucd-snmp/proxy.c +++ b/agent/mibgroup/ucd-snmp/proxy.c @@ -460,7 +460,7 @@ proxy_handler(netsnmp_mib_handler *handler, if (sp->base_len && reqinfo->mode == MODE_GETNEXT && (snmp_oid_compare(ourname, ourlength, - sp->name, sp->name_len) < 0)) { + sp->base, sp->base_len) < 0)) { DEBUGMSGTL(( "proxy", "request is out of registered range\n")); /* * Create GETNEXT request with an OID so the diff --git a/agent/snmp_agent.c b/agent/snmp_agent.c index 25350e6..26653f4 100644 --- a/agent/snmp_agent.c +++ b/agent/snmp_agent.c @@ -1604,7 +1604,6 @@ free_agent_snmp_session(netsnmp_agent_session *asp) DEBUGMSGTL(("verbose:asp", "asp %p reqinfo %p freed\n", asp, asp->reqinfo)); - if (asp->orig_pdu) snmp_free_pdu(asp->orig_pdu); if (asp->pdu) diff --git a/agent/snmpd.c b/agent/snmpd.c index 45a10c5..6566354 100644 --- a/agent/snmpd.c +++ b/agent/snmpd.c @@ -325,7 +325,6 @@ usage(char *prog) " -S d|i|0-7\t\tuse -Ls instead\n" "\n" ); - exit(1); } static void diff --git a/apps/Makefile.in b/apps/Makefile.in index 1d2294b..e5e1f69 100644 --- a/apps/Makefile.in +++ b/apps/Makefile.in @@ -156,37 +156,37 @@ OTHERUNINSTALL=snmpinformuninstall snmptopuninstall snmptrapdperluninstall # build rules # snmpwalk$(EXEEXT): snmpwalk.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpwalk.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmpwalk.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmpbulkwalk$(EXEEXT): snmpbulkwalk.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpbulkwalk.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmpbulkwalk.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmpbulkget$(EXEEXT): snmpbulkget.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpbulkget.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmpbulkget.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmptranslate$(EXEEXT): snmptranslate.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmptranslate.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmptranslate.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmpstatus$(EXEEXT): snmpstatus.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpstatus.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmpstatus.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmpget$(EXEEXT): snmpget.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpget.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmpget.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmpdelta$(EXEEXT): snmpdelta.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpdelta.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmpdelta.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmptable$(EXEEXT): snmptable.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmptable.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmptable.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmptest$(EXEEXT): snmptest.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmptest.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmptest.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmptrapd$(EXEEXT): $(TRAPD_OBJECTS) $(USETRAPLIBS) $(INSTALLLIBS) - $(LINK) ${CFLAGS} -o $@ -pie $(TRAPD_OBJECTS) $(INSTALLLIBS) ${LDFLAGS} ${TRAPLIBS} + $(LINK) ${CFLAGS} -o $@ $(TRAPD_OBJECTS) $(INSTALLLIBS) ${LDFLAGS} ${TRAPLIBS} snmptrap$(EXEEXT): snmptrap.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmptrap.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmptrap.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmpinform$(EXEEXT): snmptrap$(EXEEXT) rm -f snmpinform @@ -197,40 +197,40 @@ snmptop$(EXEEXT): snmpps$(EXEEXT) $(LN_S) snmpps$(EXEEXT) snmptop$(EXEEXT) snmpset$(EXEEXT): snmpset.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpset.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmpset.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmpusm$(EXEEXT): snmpusm.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpusm.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmpusm.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmpvacm$(EXEEXT): snmpvacm.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpvacm.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmpvacm.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmptls$(EXEEXT): snmptls.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmptls.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmptls.$(OSUFFIX) ${LDFLAGS} ${LIBS} agentxtrap$(EXEEXT): agentxtrap.$(OSUFFIX) $(USEAGENTLIBS) $(LINK) ${CFLAGS} -o $@ agentxtrap.$(OSUFFIX) ${LDFLAGS} $(USEAGENTLIBS) $(PERLLDOPTS_FOR_APPS) ${LIBS} snmpgetnext$(EXEEXT): snmpgetnext.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpgetnext.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmpgetnext.$(OSUFFIX) ${LDFLAGS} ${LIBS} encode_keychange$(EXEEXT): encode_keychange.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie encode_keychange.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ encode_keychange.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmpdf$(EXEEXT): snmpdf.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpdf.$(OSUFFIX) ${LDFLAGS} ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmpdf.$(OSUFFIX) ${LDFLAGS} ${LIBS} snmpps$(EXEEXT): snmpps.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpps.$(OSUFFIX) ${LDFLAGS} @LIBCURSES@ ${LIBS} + $(LINK) ${CFLAGS} -o $@ snmpps.$(OSUFFIX) ${LDFLAGS} @LIBCURSES@ ${LIBS} snmpping$(EXEEXT): snmpping.$(OSUFFIX) $(USELIBS) - $(LINK) ${CFLAGS} -o $@ -pie snmpping.$(OSUFFIX) ${LDFLAGS} ${LIBS} -lm + $(LINK) ${CFLAGS} -o $@ snmpping.$(OSUFFIX) ${LDFLAGS} ${LIBS} -lm snmppcap$(EXEEXT): snmppcap.$(OSUFFIX) $(USELIBS) $(LINK) ${CFLAGS} -o $@ snmppcap.$(OSUFFIX) ${LDFLAGS} ${LIBS} -lpcap libnetsnmptrapd.$(LIB_EXTENSION)$(LIB_VERSION): $(LLIBTRAPD_OBJS) - $(LIB_LD_CMD) $@ ${LLIBTRAPD_OBJS} $(MIBLIB) $(USELIBS) $(PERLLDOPTS_FOR_LIBS) $(LIB_LD_LIBS) $(MYSQL_LIBS) + $(LIB_LD_CMD) $@ ${LLIBTRAPD_OBJS} $(MIBLIB) $(USELIBS) $(PERLLDOPTS_FOR_LIBS) $(LIB_LD_LIBS) $(RANLIB) $@ snmpinforminstall: diff --git a/apps/snmpnetstat/Makefile.in b/apps/snmpnetstat/Makefile.in index c683e45..dfb566d 100644 --- a/apps/snmpnetstat/Makefile.in +++ b/apps/snmpnetstat/Makefile.in @@ -34,4 +34,4 @@ LIBS= ../../snmplib/libnetsnmp.$(LIB_EXTENSION)$(LIB_VERSION) $(VAL_LIBS) @LIBS all: standardall snmpnetstat$(EXEEXT): ${LOBJS} ${USELIBS} - ${LINK} ${CFLAGS} -o $@ -pie ${LOBJS} ${LOCAL_LIBS} ${LDFLAGS} ${LIBS} + ${LINK} ${CFLAGS} -o $@ ${LOBJS} ${LOCAL_LIBS} ${LDFLAGS} ${LIBS} diff --git a/configure b/configure index 34dff8a..cad6b74 100755 --- a/configure +++ b/configure @@ -26138,13 +26138,7 @@ $as_echo "#define NETSNMP_USE_INTERNAL_CRYPTO 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: Internal Crypto Support" >&5 $as_echo "Internal Crypto Support" >&6; } elif test "x$useopenssl" != "xno" ; then - authmodes="MD5 SHA1" - if test "x$ac_cv_func_EVP_sha224" = xyes; then - authmodes="$authmodes SHA224 SHA256" - fi - if test "x$ac_cv_func_EVP_sha384" = xyes; then - authmodes="$authmodes SHA384 SHA512" - fi + authmodes="MD5 SHA1 SHA512 SHA384 SHA256 SHA192" if test "x$enable_privacy" != "xno" ; then if test "x$ac_cv_header_openssl_aes_h" = "xyes" ; then encrmodes="DES AES" @@ -26183,13 +26177,6 @@ fi if test "x$enable_md5" = "xno"; then authmodes=`echo $authmodes | $SED 's/MD5 *//;'` fi -if test "x$ac_cv_func_AES_cfb128_encrypt" = xyes || - test "x$CRYPTO" = xinternal; then - encrmodes="$encrmodes AES128" - if test "x$aes_capable" = "xyes"; then - encrmodes="$encrmodes AES192 AES192C AES256 AES256C" - fi -fi diff --git a/configure.d/config_os_misc2 b/configure.d/config_os_misc2 index be0bcce..1df9bf0 100644 --- a/configure.d/config_os_misc2 +++ b/configure.d/config_os_misc2 @@ -53,13 +53,7 @@ if test "x$CRYPTO" = "xinternal" ; then AC_DEFINE(NETSNMP_USE_INTERNAL_CRYPTO, 1, "Define if internal cryptography code should be used") AC_MSG_RESULT(Internal Crypto Support) elif test "x$useopenssl" != "xno" ; then - authmodes="MD5 SHA1" - if test "x$ac_cv_func_EVP_sha224" = xyes; then - authmodes="$authmodes SHA224 SHA256" - fi - if test "x$ac_cv_func_EVP_sha384" = xyes; then - authmodes="$authmodes SHA384 SHA512" - fi + authmodes="MD5 SHA1 SHA512 SHA384 SHA256 SHA192" if test "x$enable_privacy" != "xno" ; then if test "x$ac_cv_header_openssl_aes_h" = "xyes" ; then encrmodes="DES AES" @@ -92,13 +86,6 @@ fi if test "x$enable_md5" = "xno"; then authmodes=`echo $authmodes | $SED 's/MD5 *//;'` fi -if test "x$ac_cv_func_AES_cfb128_encrypt" = xyes || - test "x$CRYPTO" = xinternal; then - encrmodes="$encrmodes AES128" - if test "x$aes_capable" = "xyes"; then - encrmodes="$encrmodes AES192 AES192C AES256 AES256C" - fi -fi AC_SUBST(LNETSNMPLIBS) AC_SUBST(LAGENTLIBS) diff --git a/dist/autoconf-version b/dist/autoconf-version index 5e1b8b0..264f2ce 100644 --- a/dist/autoconf-version +++ b/dist/autoconf-version @@ -1 +1 @@ -2.69 +2.68 diff --git a/include/net-snmp/agent/hardware/fsys.h b/include/net-snmp/agent/hardware/fsys.h index 21235c0..3f2b284 100644 --- a/include/net-snmp/agent/hardware/fsys.h +++ b/include/net-snmp/agent/hardware/fsys.h @@ -41,7 +41,6 @@ typedef struct netsnmp_fsys_info_s netsnmp_fsys_info; #define NETSNMP_FS_TYPE_SYSFS (4 | _NETSNMP_FS_TYPE_LOCAL | _NETSNMP_FS_TYPE_SKIP_BIT) #define NETSNMP_FS_TYPE_TMPFS (5 | _NETSNMP_FS_TYPE_LOCAL) #define NETSNMP_FS_TYPE_USBFS (6 | _NETSNMP_FS_TYPE_LOCAL) -#define NETSNMP_FS_TYPE_AUTOFS (7 | _NETSNMP_FS_TYPE_LOCAL | _NETSNMP_FS_TYPE_SKIP_BIT) #define NETSNMP_FS_FLAG_ACTIVE 0x01 #define NETSNMP_FS_FLAG_REMOTE 0x02 diff --git a/include/net-snmp/library/int64.h b/include/net-snmp/library/int64.h index f06375e..7a0d0d3 100644 --- a/include/net-snmp/library/int64.h +++ b/include/net-snmp/library/int64.h @@ -10,7 +10,7 @@ extern "C" { * Note: using the U64 typedef is deprecated because this typedef conflicts * with a typedef with the same name defined in the Perl header files. */ -// typedef struct counter64 U64; + typedef struct counter64 U64; #endif #define I64CHARSZ 21 diff --git a/include/net-snmp/library/snmpusm.h b/include/net-snmp/library/snmpusm.h index 87b31f3..3f60787 100644 --- a/include/net-snmp/library/snmpusm.h +++ b/include/net-snmp/library/snmpusm.h @@ -43,7 +43,6 @@ extern "C" { * Structures. */ struct usmStateReference { - int refcnt; char *usr_name; size_t usr_name_length; u_char *usr_engine_id; diff --git a/local/net-snmp-cert b/local/net-snmp-cert index b3e0d41..a45dc57 100755 --- a/local/net-snmp-cert +++ b/local/net-snmp-cert @@ -819,7 +819,8 @@ sub set_default { sub cfg_path { my $path; - $path = "/etc/snmp:/usr/share/snmp:/usr/lib64/snmp:/home/jsafrane/.snmp:/var/lib/net-snmp"; + $path = `$NetSNMP::Cert::CFGTOOL --snmpconfpath`; + chomp $path; return (wantarray ? split(':', $path) : $path); } @@ -1413,8 +1414,8 @@ sub checkReqs { die("$NetSNMP::Cert::OPENSSL (v$ossl_ver): must be $ossl_min_ver or later") if ($ossl_ver cmp $ossl_min_ver) < 0; -# die("$NetSNMP::Cert::CFGTOOL not found: please install") -# if system("$NetSNMP::Cert::CFGTOOL > /dev/null 2>&1"); + die("$NetSNMP::Cert::CFGTOOL not found: please install") + if system("$NetSNMP::Cert::CFGTOOL > /dev/null 2>&1"); } sub initOpts { diff --git a/man/net-snmp-create-v3-user.1.def b/man/net-snmp-create-v3-user.1.def index 3dd54f2..da6944c 100644 --- a/man/net-snmp-create-v3-user.1.def +++ b/man/net-snmp-create-v3-user.1.def @@ -3,7 +3,7 @@ net-snmp-create-v3-user \- create a SNMPv3 user in net-snmp configuration file .SH SYNOPSIS .PP -.B net-snmp-create-v3-user [-ro] [-A authpass] [-a MD5|SHA] [-X privpass] [-x DES|AES] +.B net-snmp-create-v3-user [-ro] [-a authpass] [-x privpass] [-X DES|AES] .B [username] .SH DESCRIPTION .PP @@ -16,16 +16,13 @@ new user in net-snmp configuration file (/var/net-snmp/snmpd.conf by default). displays the net-snmp version number .TP \fB\-ro\fR -creates a user with read-only permissions +create an user with read-only permissions .TP -\fB\-A authpass\fR -specifies the authentication password +\fB\-a authpass\fR +specify authentication password .TP -\fB\-a MD5|SHA\fR -specifies the authentication password hashing algorithm +\fB\-x privpass\fR +specify encryption password .TP -\fB\-X privpass\fR -specifies the encryption password -.TP -\fB\-x DES|AES\fR -specifies the encryption algorithm +\fB\-X DES|AES\fR +specify encryption algorithm diff --git a/man/netsnmp_config_api.3.def b/man/netsnmp_config_api.3.def index bd5abe1..90b20d9 100644 --- a/man/netsnmp_config_api.3.def +++ b/man/netsnmp_config_api.3.def @@ -295,7 +295,7 @@ for one particular machine. .PP The default list of directories to search is \fC SYSCONFDIR/snmp\fP, followed by \fC DATADIR/snmp\fP, -followed by \fC /usr/lib(64)/snmp\fP, +followed by \fC LIBDIR/snmp\fP, followed by \fC $HOME/.snmp\fP. This list can be changed by setting the environmental variable .I SNMPCONFPATH @@ -367,7 +367,7 @@ A colon separated list of directories to search for configuration files in. Default: .br -SYSCONFDIR/snmp:\:DATADIR/snmp:\:/usr/lib(64)/snmp:\:$HOME/.snmp +SYSCONFDIR/snmp:\:DATADIR/snmp:\:LIBDIR/snmp:\:$HOME/.snmp .SH "SEE ALSO" netsnmp_mib_api(3), snmp_api(3) .\" Local Variables: diff --git a/man/snmp_config.5.def b/man/snmp_config.5.def index c3437d6..fd30873 100644 --- a/man/snmp_config.5.def +++ b/man/snmp_config.5.def @@ -10,7 +10,7 @@ First off, there are numerous places that configuration files can be found and read from. By default, the applications look for configuration files in the following 4 directories, in order: SYSCONFDIR/snmp, -DATADIR/snmp, /usr/lib(64)/snmp, and $HOME/.snmp. In each of these +DATADIR/snmp, LIBDIR/snmp, and $HOME/.snmp. In each of these directories, it looks for files snmp.conf, snmpd.conf and/or snmptrapd.conf, as well as snmp.local.conf, snmpd.local.conf and/or snmptrapd.local.conf. *.local.conf are always diff --git a/man/snmpd.conf.5.def b/man/snmpd.conf.5.def index d988155..2c4ddad 100644 --- a/man/snmpd.conf.5.def +++ b/man/snmpd.conf.5.def @@ -1559,7 +1559,7 @@ filename), and call the initialisation routine \fIinit_NAME\fR. .RS .IP "Note:" If the specified PATH is not a fully qualified filename, it will -be interpreted relative to /usr/lib(64)/snmp/dlmod, and \fC.so\fR +be interpreted relative to LIBDIR/snmp/dlmod, and \fC.so\fR will be appended to the filename. .RE .PP diff --git a/net-snmp-config.in b/net-snmp-config.in index 2c239b1..a412412 100644 --- a/net-snmp-config.in +++ b/net-snmp-config.in @@ -140,10 +140,10 @@ else ;; #################################################### compile --base-cflags) - echo -I${NSC_INCLUDEDIR} + echo @CFLAGS@ @CPPFLAGS@ -I${NSC_INCLUDEDIR} ;; --cflags|--cf*) - echo @DEVFLAGS@ -I. -I${NSC_INCLUDEDIR} + echo @CFLAGS@ @DEVFLAGS@ @CPPFLAGS@ -I. -I${NSC_INCLUDEDIR} ;; --srcdir) echo $NSC_SRCDIR diff --git a/net-snmp-create-v3-user.in b/net-snmp-create-v3-user.in index 3aa0eb6..e5ae928 100644 --- a/net-snmp-create-v3-user.in +++ b/net-snmp-create-v3-user.in @@ -58,11 +58,11 @@ case $1 in exit 1 fi case $1 in - DES|AES|AES128|AES192|AES256) + DES|AES|AES128) Xalgorithm=$1 shift ;; - des|aes|aes128|aes192|aes256) + des|aes|aes128) Xalgorithm=`echo $1 | tr a-z A-Z` shift ;; @@ -137,7 +137,7 @@ fi echo $line >> $outfile prefix="@prefix@" datarootdir="@datarootdir@" -outfile="/etc/snmp/snmpd.conf" +outfile="@datadir@/snmp/snmpd.conf" line="$token $user" echo "adding the following line to $outfile:" echo " " $line diff --git a/perl/ASN/Makefile.PL b/perl/ASN/Makefile.PL index b3dc17d..ab676ef 100644 --- a/perl/ASN/Makefile.PL +++ b/perl/ASN/Makefile.PL @@ -93,7 +93,7 @@ sub AsnInitMakeParams { " " . $Params{'LIBS'}; $Params{'CCFLAGS'} = "-I../../include " . $Params{'CCFLAGS'}; } - $Params{'CCFLAGS'} =~ s/ -W(inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings + $Params{'CCFLAGS'} =~ s/ -W(all|inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings $Params{'CCFLAGS'} .= ' -Wformat'; if ($Params{'LIBS'} eq "" || $Params{'CCFLAGS'} eq "") { die "You need to install net-snmp first (I can't find net-snmp-config)"; diff --git a/perl/OID/Makefile.PL b/perl/OID/Makefile.PL index 991884c..32554bc 100644 --- a/perl/OID/Makefile.PL +++ b/perl/OID/Makefile.PL @@ -90,7 +90,7 @@ sub OidInitMakeParams { # } else { # $Params{'PREREQ_PM'} = {'SNMP' => '5.0'}; } - $Params{'CCFLAGS'} =~ s/ -W(inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings + $Params{'CCFLAGS'} =~ s/ -W(all|inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings $Params{'CCFLAGS'} .= ' -Wformat'; if ($Params{'LIBS'} eq "" || $Params{'CCFLAGS'} eq "") { die "You need to install net-snmp first (I can't find net-snmp-config)"; diff --git a/perl/SNMP/Makefile.PL b/perl/SNMP/Makefile.PL index d4a1b71..ba23dfe 100644 --- a/perl/SNMP/Makefile.PL +++ b/perl/SNMP/Makefile.PL @@ -103,7 +103,7 @@ sub SnmpInitMakeParams { # } else { # $Params{'PREREQ_PM'} = { 'NetSNMP::default_store' => 0.01 }; } - $Params{'CCFLAGS'} =~ s/ -W(inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings + $Params{'CCFLAGS'} =~ s/ -W(all|inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings $Params{'CCFLAGS'} .= ' -Wformat'; if (!$ENV{'NETSNMP_PREFIX'}) { $prefix = `$opts->{'nsconfig'} --prefix`; diff --git a/perl/TrapReceiver/Makefile.PL b/perl/TrapReceiver/Makefile.PL index bafadd9..1ca8ef9 100644 --- a/perl/TrapReceiver/Makefile.PL +++ b/perl/TrapReceiver/Makefile.PL @@ -132,7 +132,7 @@ sub TrapReceiverInitMakeParams { $Params{'LIBS'} = `$opts->{'nsconfig'} --libdir` . " $Params{'LIBS'}"; } - $Params{'CCFLAGS'} =~ s/ -W(inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings + $Params{'CCFLAGS'} =~ s/ -W(all|inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings $Params{'CCFLAGS'} .= ' -Wformat'; if ($Params{'CCFLAGS'} eq "") { die "You need to install net-snmp first (I can't find net-snmp-config)"; diff --git a/perl/agent/Makefile.PL b/perl/agent/Makefile.PL index fe85b83..4d8feac 100644 --- a/perl/agent/Makefile.PL +++ b/perl/agent/Makefile.PL @@ -98,7 +98,7 @@ sub AgentInitMakeParams { $Params{'LIBS'} = `$opts->{'nsconfig'} --libdir` . $Params{'LIBS'}; # $Params{'PREREQ_PM'} = {'NetSNMP::OID' => '0.1'}; } - $Params{'CCFLAGS'} =~ s/ -W(inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings + $Params{'CCFLAGS'} =~ s/ -W(all|inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings $Params{'CCFLAGS'} .= ' -Wformat'; if ($Params{'LIBS'} eq "" || $Params{'CCFLAGS'} eq "") { die "You need to install net-snmp first (I can't find net-snmp-config)"; diff --git a/perl/agent/Support/Makefile.PL b/perl/agent/Support/Makefile.PL index 5e9c4be..e828877 100644 --- a/perl/agent/Support/Makefile.PL +++ b/perl/agent/Support/Makefile.PL @@ -90,7 +90,7 @@ sub SupportInitMakeParams { " " . $Params{'LIBS'}; $Params{'CCFLAGS'} = "-I../../include " . $Params{'CCFLAGS'}; } - $Params{'CCFLAGS'} =~ s/ -W(inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings + $Params{'CCFLAGS'} =~ s/ -W(all|inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings $Params{'CCFLAGS'} .= ' -Wformat'; if ($Params{'LIBS'} eq "" || $Params{'CCFLAGS'} eq "") { die "You need to install net-snmp first (I can't find net-snmp-config)"; diff --git a/perl/agent/default_store/Makefile.PL b/perl/agent/default_store/Makefile.PL index 02b74ea..ccdee4d 100644 --- a/perl/agent/default_store/Makefile.PL +++ b/perl/agent/default_store/Makefile.PL @@ -83,7 +83,7 @@ sub AgentDefaultStoreInitMakeParams { " " . $Params{'LIBS'}; $Params{'CCFLAGS'} = "-I../../../include " . $Params{'CCFLAGS'}; } - $Params{'CCFLAGS'} =~ s/ -W(inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings + $Params{'CCFLAGS'} =~ s/ -W(all|inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings $Params{'CCFLAGS'} .= ' -Wformat'; if ($Params{'LIBS'} eq "" || $Params{'CCFLAGS'} eq "") { die "You need to install net-snmp first (I can't find net-snmp-config)"; diff --git a/perl/default_store/Makefile.PL b/perl/default_store/Makefile.PL index 5c31a09..c743259 100644 --- a/perl/default_store/Makefile.PL +++ b/perl/default_store/Makefile.PL @@ -83,7 +83,7 @@ sub DefaultStoreInitMakeParams { " " . $Params{'LIBS'}; $Params{'CCFLAGS'} = "-I../../include " . $Params{'CCFLAGS'}; } - $Params{'CCFLAGS'} =~ s/ -W(inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings + $Params{'CCFLAGS'} =~ s/ -W(all|inline|strict-prototypes|write-strings|cast-qual|no-char-subscripts)//g; # ignore developer warnings $Params{'CCFLAGS'} .= ' -Wformat'; if ($Params{'LIBS'} eq "" || $Params{'CCFLAGS'} eq "") { die "You need to install net-snmp first (I can't find net-snmp-config)"; diff --git a/python/LICENSE b/python/LICENSE new file mode 100644 index 0000000..4c7638f --- /dev/null +++ b/python/LICENSE @@ -0,0 +1,66 @@ +Various copyrights apply to this package, listed in various separate +parts below. Please make sure that you read all the parts. + +---- Part 1: Sparta, Inc (BSD) ----- + +Copyright (c) 2003-2010, Sparta, Inc +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of Sparta, Inc nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS +IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---- Part 2: ScienceLogic, LLC (BSD) ---- + +Copyright (c) 2006, ScienceLogic, LLC +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of ScienceLogic, LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/python/README b/python/README new file mode 100644 index 0000000..f998f8b --- /dev/null +++ b/python/README @@ -0,0 +1,365 @@ + The Python 'netsnmp' Extension Module + for the Net-SNMP Library + +Contents: + Introduction: + Availability: + Contact: + Supported Platforms: + Release Notes: + Installation: + Operational Description: + Trouble Shooting: + Acknowledgments: + License/Copyright: + +Introduction: + + This is the Python 'netsnmp' extension module. The 'netsnmp' module + provides a full featured, tri-lingual SNMP (SNMPv3, SNMPv2c, + SNMPv1) client API. The 'netsnmp' module internals rely on the + Net-SNMP toolkit library. For information on the Net-SNMP library + see the documentation provided with the Net-SNMP distribution or + the project web page available on 'Source Forge': + + http://www.net-snmp.org/ + +Availability: + + The most recent release of the Python 'netsnmp' module can be found + bundled with the latest Net-SNMP distribution available from: + + http://www.net-snmp.org/download.html + +Contact: + + The following mailing list should be consider the primary support + mechanism for this module: + + net-snmp-users@lists.sourceforge.net mail list + + (see http://www.net-snmp.org/lists/users/ to subscribe) + +Supported Platforms: + + Linux 2.x + Other UNIX/POSIX variants (untested) + MS Windows (untested) + + Let us know where it *doesn't* work, as it should on most systems + +Release Notes: + + This initial alpha release of the Python 'netsnmp' extension module + has been developed against net-snmp 5.4.pre1. + + Only syncronous, client-side functionality is implemented. + + Access to the parsed MIB database is not yet implemented. + +KNOWN BUGS: + + Too many to mention at this point + +Installation: + + Build and install the Net-SNMP package - see Net-SNMP README and + INSTALL docs. + + Unix: + + cd net-snmp/python + python setup.py build + python setup.py test (requires a locally running agent w/ config provided) + python setup.py install + + +Operational Description: + + The basic operations of the SNMP protocol are provided by this + module through an object oriented interface for modularity and ease + of use. The primary class is netsnmp.Session which encapsulates + the persistent aspects of a connection between the management + application and the managed agent. This class supplies 'get', + 'getnext', 'getbulk', 'set' and other method calls. + + A description of the fields which can be specified when instantiating an + netsnmp.Session follows: + + netsnmp.Session(=, ... ) + + DestHost - default 'localhost', hostname or ip addr of SNMP agent + Version - default '3', [1, 2 (equiv to 2c), 3] + RemotePort - default '161', allow remote UDP port to be overridden + Timeout - default '500000', micro-seconds before retry + Retries - default '3', retries before failure + RetryNoSuch - default '0', if enabled NOSUCH errors in 'get' pdus will + be repaired, removing the varbind in error, and resent - + undef will be returned for all NOSUCH varbinds, when set + to '0' this feature is disabled and the entire get request + will fail on any NOSUCH error (applies to v1 only) + UseLongNames - set to non-zero to have for 'getnext' methods + generated preferring longer Mib name convention (e.g., + system.sysDescr vs just sysDescr) + UseSprintValue - set to non-zero to have return values + for 'get' and 'getnext' methods formatted with the libraries + sprint_value function. This will result in certain data types + being returned in non-canonical format Note: values returned + with this option set may not be appropriate for 'set' + operations (see discussion of value formats in + description section) + UseEnums - set to non-zero to have integer return values + converted to enumeration identifiers if possible, + these values will also be acceptable when supplied to + 'set' operations + UseNumeric - set to non-zero to have returned by the 'get' + methods untranslated (i.e. dotted-decimal). Setting the + UseLongNames value for the session is highly recommended. + BestGuess - this setting controls how are parsed. setting + to 0 causes a regular lookup. setting to 1 causes a regular + expression match (defined as -Ib in snmpcmd). setting to 2 + causes a random access lookup (defined as -IR in snmpcmd). + ErrorStr - read-only, holds the error message assoc. w/ last request + ErrorNum - read-only, holds the snmp_err or status of last request + ErrorInd - read-only, holds the snmp_err_index when appropriate + + SNMPv1/SNMPv2c options: + Community - default 'public', SNMP community string (used for both R/W) + + SNMPv3 Options: + SecName - default 'initial', security name (v3) + SecLevel - default 'noAuthNoPriv', security level [noAuthNoPriv, + authNoPriv, authPriv] (v3) + ContextEngineId - default , context engineID, will be + probed if not supplied (v3) + Context - default '', context name (v3) + + SNMPv3 over TLS or DTLS options: + OurIdentity - The fingerprint or file name for the local X.509 + certificate to use for our identity. Run + net-snmp-cert to create and manage certificates. + TheirIdentity - The fingerprint or file name for the local X.509 + certificate to use for their identity. + TrustCert - A trusted certificate to use for validating + certificates. Typically this would be a CA + certificate. + TheirHostname - Their hostname to expect. Either "TheirIdentity" + or a trusted certificate plus a hostname is needed + to validate the server is the proper server. + + SNMPv3 with USM security Options: + SecEngineId - default , security engineID, will be probed if not + supplied (v3) + AuthProto - default 'MD5', authentication protocol [MD5, SHA] (v3) + AuthPass - default , authentication passphrase + PrivProto - default 'DES', privacy protocol [DES] (v3) + PrivPass - default , privacy passphrase (v3) + + private: + sess_ptr - internal field used to cache a created session structure + + methods: + + get() + - SNMP GET a netsnmp.VarList object must be supplied, + returns a tuple of values for each varbind in list + + getnext() + - SNMP GETNEXT, a netsnmp.VarList object must be supplied + returns retrieved value(s), VarList passed as arguments + are updated to return a list of next lexicographical + Varbind objects. returns a tuple of values for each + varbind in list + + set() + - SNMP SET, a netsnmp.VarList object must be supplied + the value field in all Varbinds must be in a canonical + format (i.e., well known format) to ensure unambiguous + translation to SNMP MIB data value (see discussion of + canonical value format description section), + returns true on success or None on error. + + getbulk(, , ) + - SNMP GETBULK, a netsnmp.VarList object must be supplied + the single next lexico instance is fetched for the first + n Varbinds in the list as defined by . + For the remaining Varbinds, the next m lexico instances + are retrieved each of the remaining Varbinds, + where m is . Returns a tuple of values + retrieved. + + walk() + - Performs multiple GETNEXT requests in order to + return a tuple of values retrieved from the MIB + below the Varbind passed in. The VarList passed + in will be updated to contain a complete set of + Varbinds created for the results of the walk. + + Note that only one varbind should be contained in the + VarList passed in. The code is structured to maybe + handle this is the the future, but right now walking + multiple trees at once is not yet supported and will + produce insufficient results. + + + Acceptable variable formats: + + netsnmp.VarList: - represents an list of Varbind objects to get or set. + takes are arguments and unspecified number of Varbinds, + or tuples which will be converted to Varbinds. + + + netsnmp.Varbind: - represents a single MIB object to get or set + implemented as Python[, , , ]. + - one of the following forms: + 1) leaf identifier (e.g., 'sysDescr') assumed to be + unique for practical purposes + 2) fully qualified identifier (e.g., + '.iso.org.dod.internet.mgmt.mib-2.system.sysDescr') + 3) fully qualified, dotted-decimal, numeric OID + (e.g., '.1.3.6.1.2.1.1.1') + - the dotted-decimal, instance identifier. for + scalar MIB objects use '0' + - the SNMP data value retrieved from or being set + to the agents MIB. for set operations the + format must be canonical to ensure unambiguous + translation. The canonical forms are as follows: + OBJECTID => dotted-decimal (e.g., .1.3.6.1.2.1.1.1) + OCTETSTR => perl scalar containing octets, + INTEGER => decimal signed integer (or enum), + NETADDR => dotted-decimal, + IPADDR => dotted-decimal, + COUNTER => decimal unsigned integer, + COUNTER64 => decimal unsigned integer, + GAUGE, => decimal unsigned integer, + UINTEGER, => decimal unsigned integer, + TICKS, => decimal unsigned integer, + OPAQUE => perl scalar containing octets, + NULL, => perl scalar containing nothing, + + - SNMP data type (see list above), this field is + populated by 'get' and 'getnext' operations. In + some cases the programmer needs to populate this + field when passing to a 'set' operation. this + field need not be supplied when the attribute + indicated by is already described in the + parsed MIB. for 'set's, if a numeric OID is used + and the object is not in the parsed MIB, + the field must be supplied + + + Python 'netsnmp' package variables and functions: + + + netsnmp.verbose - default '0', + controls warning/info output of themodule + 0 => no output, + 1 => enables warning/info + +(needs implementation) + $SNMP::debugging - default '0', controls debugging output level + within SNMP module and libsnmp + 1 => enables 'SNMP::verbose' (see above) + 2 => level 1 plus snmp_set_do_debugging(1), + 3 => level 2 plus snmp_set_dump_packet(1) + + $SNMP::dump_packet - default '0', set [non-]zero to independently set + snmp_set_dump_packet() + + Exported 'netsnmp' package utility functions: + + snmpget(, ) + - takes args of netsnmp.Session preceded by those of the + corresponding netsnmp.Session method. Returns a tuple with + Varbind values fetched, and input is updated to contain + complete Varbinds fetched. + + snmpgetnext(, ) + - takes args of netsnmp.Session preceded by those of the + corresponding netsnmp.Session method. Returns a tuple with + Varbind values fetched, and input is updated to contain + complete Varbinds fetched. + + snmpgetbulk(nonrepeaters, maxrepetitions,, ) + - takes args of netsnmp.Session preceded by those of the + corresponding netsnmp.Session method. Returns a tuple with + Varbind values fetched, and VarList is updated to contain + complete Varbinds fetched. + + snmpset(, ) + - takes args of netsnmp.Session preceded by those of the + corresponding netsnmp.Session method. returns True on success, + otherwise False. + + snmpwalk(, )) + - takes args of netsnmp.Session preceded by a Varbind or + VarList from which the 'walk' operation will start. + Returns a tuple of values retrieved from the MIB below + the Varbind passed in. If a VarList is passed in it + will be updated to contain a complete set of VarBinds + created for the results of the walk. It is not + recommended to pass in just a Varbind since you loose + the ability to examine the returned OIDs. But, if only + a Varbind is passed in it will be returned unaltered. + + Note that only one varbind should be contained in the + VarList passed in. The code is structured to maybe + handle this is the the future, but right now walking + multiple trees at once is not yet supported and will + produce insufficient results. + +Trouble Shooting: + + If problems occur there are number areas to look at to narrow down the + possibilities. + + The first step should be to test the Net-SNMP installation + independently from the Python 'netsnmp' Extension. + + Try running the apps from the Net-SNMP distribution. + + Make sure your agent (snmpd) is running and properly configured with + read-write access for the community you are using. + + Ensure that your MIBs are installed and environment variables are set + appropriately (see man mib_api) + + Be sure to ensure headers and libraries from old CMU installations are + not being used by mistake (see -NET-SNMP-PATH). + + If the problem occurs during compilation/linking check that the snmp + library being linked is actually the Net-SNMP library (there have been + name conflicts with existing snmp libs). + + Also check that the header files are correct and up to date. + + Sometimes compiling the Net-SNMP library with + 'position-independent-code' enabled is required (HPUX specifically). + + If you cannot resolve the problem you can email + net-snmp-users@lists.sourceforge.net. + + Please give sufficient information to analyze the problem (OS type, + versions for OS/python/net-SNMP/compiler, complete error output, etc.) + +Acknowledgments: + + Giovanni Marzot (the original author) + ScienceLogic, LLC sponsored the initial development of this module. + Wes Hardaker and the net-snmp-coders + + Thanks in advance to any who supply patches, suggestions and feedback. + +License: + + Please see the LICENSE file contained with this package + +Copyright: + + Copyright (c) 2006 G. S. Marzot. All rights reserved. + This program is free software; you can redistribute it and/or + modify it under the same terms as Net-SNMP itself. + + Copyright (c) 2006 SPARTA, Inc. All Rights Reserved. This + program is free software; you can redistribute it and/or modify + it under the same terms as Net-SNMP itself. diff --git a/python/netsnmp/__init__.py b/python/netsnmp/__init__.py new file mode 100644 index 0000000..1d20dac --- /dev/null +++ b/python/netsnmp/__init__.py @@ -0,0 +1 @@ +from client import * diff --git a/python/netsnmp/client.py b/python/netsnmp/client.py new file mode 100644 index 0000000..46a6e37 --- /dev/null +++ b/python/netsnmp/client.py @@ -0,0 +1,281 @@ +import re +from sys import stderr +import netsnmp +import netsnmp.client_intf + +# control verbosity of error output +verbose = 1 + +secLevelMap = {'noAuthNoPriv':1, 'authNoPriv':2, 'authPriv':3} + +def _parse_session_args(kargs): + sessArgs = { + 'Version':3, + 'DestHost':'localhost', + 'Community':'public', + 'Timeout':1000000, + 'Retries':3, + 'RemotePort':161, + 'LocalPort':0, + 'SecLevel':'noAuthNoPriv', + 'SecName':'initial', + 'PrivProto':'DEFAULT', + 'PrivPass':'', + 'AuthProto':'DEFAULT', + 'AuthPass':'', + 'ContextEngineId':'', + 'SecEngineId':'', + 'Context':'', + 'Engineboots':0, + 'Enginetime':0, + 'UseNumeric':0, + 'OurIdentity':'', + 'TheirIdentity':'', + 'TheirHostname':'', + 'TrustCert':'' + } + keys = kargs.keys() + for key in keys: + if sessArgs.has_key(key): + sessArgs[key] = kargs[key] + else: + print >>stderr, "ERROR: unknown key", key + return sessArgs + +def STR(obj): + if obj != None: + obj = str(obj) + return obj + +def obj_to_str(obj): + return type(obj).__name__ + ":" + str(obj.__dict__) + + +class Varbind(object): + def __init__(self, tag=None, iid=None, val=None, type_arg=None): + self.tag = STR(tag) + self.iid = STR(iid) + self.val = STR(val) + self.type = STR(type_arg) + # parse iid out of tag if needed + if iid is None and tag is not None: + regex = re.compile(r'^((?:\.\d+)+|(?:\w+(?:[-:]*\w+)+))\.?(.*)$') + match = regex.match(tag) + if match: + (self.tag, self.iid) = match.group(1, 2) + + def __setattr__(self, name, val): + self.__dict__[name] = STR(val) + + def __str__(self): + return obj_to_str(self) + + def print_str(self): + return self.tag, self.iid, self.val, self.type + + +class VarList(object): + def __init__(self, *vs): + self.varbinds = [] + + for var in vs: + if isinstance(var, netsnmp.client.Varbind): + self.varbinds.append(var) + else: + self.varbinds.append(Varbind(var)) + + def __len__(self): + return len(self.varbinds) + + def __getitem__(self, index): + return self.varbinds[index] + + def __setitem__(self, index, val): + if isinstance(val, netsnmp.client.Varbind): + self.varbinds[index] = val + else: + raise TypeError + + def __iter__(self): + return iter(self.varbinds) + + def __delitem__(self, index): + del self.varbinds[index] + + def __repr__(self): + return repr(self.varbinds) + + def __getslice__(self, i, j): + return self.varbinds[i:j] + + def __str__(self): + return str([str(v) for v in self.varbinds]) + + def append(self, *varlist): + for var in varlist: + if isinstance(var, netsnmp.client.Varbind): + self.varbinds.append(var) + else: + raise TypeError + + +class Session(object): + def __init__(self, **args): + self.sess_ptr = None + self.UseLongNames = 0 + self.UseNumeric = 0 + self.UseSprintValue = 0 + self.UseEnums = 0 + self.BestGuess = 0 + self.RetryNoSuch = 0 + self._clear_error() + + sess_args = _parse_session_args(args) + + for k, v in sess_args.items(): + self.__dict__[k] = v + + + # check for transports that may be tunneled + transportCheck = re.compile('^(tls|dtls|ssh)') + match = transportCheck.match(sess_args['DestHost']) + + if match: + self.sess_ptr = netsnmp.client_intf.session_tunneled( + sess_args['Version'], + sess_args['DestHost'], + sess_args['LocalPort'], + sess_args['Retries'], + sess_args['Timeout'], + sess_args['SecName'], + secLevelMap[sess_args['SecLevel']], + sess_args['ContextEngineId'], + sess_args['Context'], + sess_args['OurIdentity'], + sess_args['TheirIdentity'], + sess_args['TheirHostname'], + sess_args['TrustCert'], + ) + elif sess_args['Version'] == 3: + self.sess_ptr = netsnmp.client_intf.session_v3( + sess_args['Version'], + sess_args['DestHost'], + sess_args['LocalPort'], + sess_args['Retries'], + sess_args['Timeout'], + sess_args['SecName'], + secLevelMap[sess_args['SecLevel']], + sess_args['SecEngineId'], + sess_args['ContextEngineId'], + sess_args['Context'], + sess_args['AuthProto'], + sess_args['AuthPass'], + sess_args['PrivProto'], + sess_args['PrivPass'], + sess_args['Engineboots'], + sess_args['Enginetime']) + else: + self.sess_ptr = netsnmp.client_intf.session( + sess_args['Version'], + sess_args['Community'], + sess_args['DestHost'], + sess_args['LocalPort'], + sess_args['Retries'], + sess_args['Timeout']) + + def _clear_error(self): + self.ErrorStr = '' + self.ErrorNum = 0 + self.ErrorInd = 0 + + def get(self, varlist): + self._clear_error() + res = netsnmp.client_intf.get(self, varlist) + return res + + def set(self, varlist): + self._clear_error() + res = netsnmp.client_intf.set(self, varlist) + return res + + def getnext(self, varlist): + self._clear_error() + res = netsnmp.client_intf.getnext(self, varlist) + return res + + def getbulk(self, nonrepeaters, maxrepetitions, varlist): + self._clear_error() + if self.Version == 1: + return None + res = netsnmp.client_intf.getbulk(self, nonrepeaters, maxrepetitions, varlist) + return res + + def walk(self, varlist): + self._clear_error() + res = netsnmp.client_intf.walk(self, varlist) + return res + + def __del__(self): + res = netsnmp.client_intf.delete_session(self) + return res + + def __str__(self): + return obj_to_str(self) + +def snmpget(*args, **kargs): + sess = Session(**kargs) + var_list = VarList() + for arg in args: + if isinstance(arg, netsnmp.client.Varbind): + var_list.append(arg) + else: + var_list.append(Varbind(arg)) + res = sess.get(var_list) + return res + +def snmpset(*args, **kargs): + sess = Session(**kargs) + var_list = VarList() + for arg in args: + if isinstance(arg, netsnmp.client.Varbind): + var_list.append(arg) + else: + var_list.append(Varbind(arg)) + res = sess.set(var_list) + return res + +def snmpgetnext(*args, **kargs): + sess = Session(**kargs) + var_list = VarList() + for arg in args: + if isinstance(arg, netsnmp.client.Varbind): + var_list.append(arg) + else: + var_list.append(Varbind(arg)) + res = sess.getnext(var_list) + return res + +def snmpgetbulk(nonrepeaters, maxrepetitions, *args, **kargs): + sess = Session(**kargs) + var_list = VarList() + for arg in args: + if isinstance(arg, netsnmp.client.Varbind): + var_list.append(arg) + else: + var_list.append(Varbind(arg)) + res = sess.getbulk(nonrepeaters, maxrepetitions, var_list) + return res + +def snmpwalk(*args, **kargs): + sess = Session(**kargs) + if isinstance(args[0], netsnmp.client.VarList): + var_list = args[0] + else: + var_list = VarList() + for arg in args: + if isinstance(arg, netsnmp.client.Varbind): + var_list.append(arg) + else: + var_list.append(Varbind(arg)) + res = sess.walk(var_list) + return res diff --git a/python/netsnmp/client_intf.c b/python/netsnmp/client_intf.c new file mode 100644 index 0000000..589f24f --- /dev/null +++ b/python/netsnmp/client_intf.c @@ -0,0 +1,2502 @@ +#include + +#if PY_VERSION_HEX < 0x02050000 +typedef int Py_ssize_t; +#define PY_SSIZE_T_MAX INT_MAX +#define PY_SSIZE_T_MIN INT_MIN +#endif + +#include +#include +#include +#include +#include +#include +#include +#ifdef I_SYS_TIME +#include +#endif +#include +#include + +#ifdef HAVE_REGEX_H +#include +#endif + +#define SUCCESS 1 +#define FAILURE 0 + +#define VARBIND_TAG_F 0 +#define VARBIND_IID_F 1 +#define VARBIND_VAL_F 2 +#define VARBIND_TYPE_F 3 + +#define TYPE_UNKNOWN 0 +#define MAX_TYPE_NAME_LEN 32 +#define STR_BUF_SIZE (MAX_TYPE_NAME_LEN * MAX_OID_LEN) +#define ENG_ID_BUF_SIZE 32 + +#define NO_RETRY_NOSUCH 0 + +#define STRLEN(x) (x ? strlen(x) : 0) + + +typedef netsnmp_session SnmpSession; +typedef struct tree SnmpMibNode; +static int __is_numeric_oid (char*); +static int __is_leaf (struct tree*); +static int __translate_asn_type (int); +static int __snprint_value (char **, size_t *, + netsnmp_variable_list*, struct tree *, + int, int); +static int __sprint_num_objid (char **, size_t *, oid *, int); +static int __scan_num_objid (char *, oid *, size_t *); +static int __get_type_str (int, char *); +static int __get_label_iid (char *, char **, char **, int); +static struct tree * __tag2oid (char *, char *, oid *, int *, int *, int); +static int __concat_oid_str (oid *, int *, char *); +#define USE_NUMERIC_OIDS 0x08 +#define NON_LEAF_NAME 0x04 +#define USE_LONG_NAMES 0x02 +#define FAIL_ON_NULL_IID 0x01 +#define NO_FLAGS 0x00 + +static int _debug_level; + + +void +__libraries_init(char *appname) +{ + static int have_inited = 0; + + if (have_inited) + return; + have_inited = 1; + + netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_QUICK_PRINT, 1); + snmp_enable_stderrlog(); + init_snmp(appname); + + netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_BREAKDOWN_OIDS, 1); + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_SUFFIX_ONLY, 1); + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + NETSNMP_OID_OUTPUT_SUFFIX); +} + +static int +__is_numeric_oid(char* oidstr) +{ + if (!oidstr) return 0; + for (; *oidstr; oidstr++) { + if (isalpha((int)*oidstr)) return 0; + } + return(1); +} + +static int +__is_leaf(struct tree* tp) +{ + char buf[MAX_TYPE_NAME_LEN]; + return (tp && (__get_type_str(tp->type,buf) || + (tp->parent && __get_type_str(tp->parent->type,buf) ))); +} + +struct type_table_entry { + uint8_t mib_type; + uint8_t asn_type; + int8_t cmp_len; + const char *name; +}; + +static const struct type_table_entry type_table[] = { + { TYPE_INTEGER32, 0, 8, "INTEGER32" }, + { TYPE_INTEGER, ASN_INTEGER, 3, "INTEGER" }, + { TYPE_UNSIGNED32, 0, 3, "UNSIGNED32" }, + /* -1 to use strcasecmp() to avoid matching COUNTER64 */ + { TYPE_COUNTER, ASN_COUNTER, -1, "COUNTER" }, + { TYPE_GAUGE, ASN_GAUGE, 3, "GAUGE" }, + { TYPE_IPADDR, ASN_IPADDRESS, 3, "IPADDR" }, + { TYPE_OCTETSTR, ASN_OCTET_STR, 3, "OCTETSTR" }, + { TYPE_TIMETICKS, ASN_TIMETICKS, 3, "TICKS" }, + { TYPE_OPAQUE, ASN_OPAQUE, 3, "OPAQUE" }, + { TYPE_OBJID, ASN_OBJECT_ID, 3, "OBJECTID" }, + { TYPE_NETADDR, 0, 3, "NETADDR" }, + { TYPE_COUNTER64, ASN_COUNTER64, 3, "COUNTER64" }, + { TYPE_NULL, ASN_NULL, 3, "NULL" }, + { TYPE_BITSTRING, ASN_BIT_STR, 3, "BITS" }, + /* historic - should not show up but it does? */ + { TYPE_UINTEGER, ASN_UINTEGER, 3, "UINTEGER" }, + { TYPE_NOTIFTYPE, 0, 3, "NOTIF" }, + { TYPE_TRAPTYPE, 0, 4, "TRAP" }, + + { SNMP_ENDOFMIBVIEW, SNMP_ENDOFMIBVIEW, 3, "ENDOFMIBVIEW" }, + { SNMP_NOSUCHOBJECT, SNMP_NOSUCHOBJECT, 7, "NOSUCHOBJECT" }, + { SNMP_NOSUCHINSTANCE, SNMP_NOSUCHINSTANCE, 7, "NOSUCHINSTANCE"}, + + { } +}; + +#ifndef NETSNMP_NO_WRITE_SUPPORT +static int +__translate_appl_type(const char *typestr) +{ + const struct type_table_entry *e; + + if (typestr == NULL || *typestr == '\0') + return TYPE_UNKNOWN; + + for (e = type_table; e->name; e++) { + if ((e->cmp_len < 0 && strcasecmp(typestr, e->name) == 0) || + (e->cmp_len > 0 && strncasecmp(typestr, e->name, e->cmp_len) == 0)) + return e->mib_type; + } + + return TYPE_UNKNOWN; +} +#endif /* NETSNMP_NO_WRITE_SUPPORT */ + +static int +__translate_asn_type(int asn_type) +{ + const struct type_table_entry *e; + + netsnmp_assert(asn_type != 0); + + for (e = type_table; e->name; e++) + if (asn_type == e->asn_type) + return e->mib_type; + + fprintf(stderr, "translate_asn_type: unhandled asn type (%d)\n", asn_type); + return TYPE_OTHER; +} + +static void *enlarge_buffer(char **buf, size_t *buf_len, size_t desired_len) +{ + void *new_buf; + + if (desired_len > *buf_len) { + new_buf = netsnmp_realloc(*buf, desired_len); + if (!new_buf) + return NULL; + *buf = new_buf; + *buf_len = desired_len; + } + return *buf; +} + +#define USE_BASIC 0 +#define USE_ENUMS 1 +#define USE_SPRINT_VALUE 2 +static int +__snprint_value(char **buf, size_t *buf_len, netsnmp_variable_list *var, + struct tree *tp, int type, int flag) +{ + size_t out_len = 0; + int len = 0; + u_char* ip; + struct enum_list *ep; + + + enlarge_buffer(buf, buf_len, 32); + (*buf)[0] = '\0'; + if (flag == USE_SPRINT_VALUE) { + if (sprint_realloc_value((u_char **)buf, buf_len, &out_len, 1, + var->name, var->name_length, var)) { + *buf_len = out_len; + len = STRLEN(*buf); + } + } else { + switch (var->type) { + case ASN_INTEGER: + if (flag == USE_ENUMS) { + for(ep = tp->enums; ep; ep = ep->next) { + if (ep->value == *var->val.integer) { + strlcpy(*buf, ep->label, *buf_len); + len = STRLEN(*buf); + break; + } + } + } + if (!len) { + snprintf(*buf, *buf_len, "%ld", *var->val.integer); + len = STRLEN(*buf); + } + break; + + case ASN_GAUGE: + case ASN_COUNTER: + case ASN_TIMETICKS: + case ASN_UINTEGER: + snprintf(*buf, *buf_len, "%lu", (unsigned long) *var->val.integer); + len = STRLEN(*buf); + break; + + case ASN_OCTET_STR: + case ASN_OPAQUE: + len = var->val_len; + enlarge_buffer(buf, buf_len, len + 1); + if (len > *buf_len - 1) + len = *buf_len - 1; + memcpy(*buf, var->val.string, len); + break; + + case ASN_IPADDRESS: + ip = (u_char*)var->val.string; + snprintf(*buf, *buf_len, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); + len = STRLEN(*buf); + break; + + case ASN_NULL: + break; + + case ASN_OBJECT_ID: + __sprint_num_objid(buf, buf_len, (oid *)(var->val.objid), + var->val_len/sizeof(oid)); + len = STRLEN(*buf); + break; + + case SNMP_ENDOFMIBVIEW: + snprintf(*buf, *buf_len, "%s", "ENDOFMIBVIEW"); + break; + case SNMP_NOSUCHOBJECT: + snprintf(*buf, *buf_len, "%s", "NOSUCHOBJECT"); + break; + case SNMP_NOSUCHINSTANCE: + snprintf(*buf, *buf_len, "%s", "NOSUCHINSTANCE"); + break; + + case ASN_COUNTER64: +#ifdef OPAQUE_SPECIAL_TYPES + case ASN_OPAQUE_COUNTER64: + case ASN_OPAQUE_U64: +#endif + printU64(*buf,(struct counter64 *)var->val.counter64); + len = STRLEN(*buf); + break; + +#ifdef OPAQUE_SPECIAL_TYPES + case ASN_OPAQUE_I64: + printI64(*buf,(struct counter64 *)var->val.counter64); + len = STRLEN(*buf); + break; +#endif + + case ASN_BIT_STR: + if (sprint_realloc_bitstring((u_char **)buf, buf_len, &out_len, 1, + var, NULL, NULL, NULL)) { + *buf_len = out_len; + len = STRLEN(*buf); + } + break; +#ifdef OPAQUE_SPECIAL_TYPES + case ASN_OPAQUE_FLOAT: + if (var->val.floatVal) + snprintf(*buf, *buf_len, "%f", *var->val.floatVal); + break; + + case ASN_OPAQUE_DOUBLE: + if (var->val.doubleVal) + snprintf(*buf, *buf_len, "%f", *var->val.doubleVal); + break; +#endif + + case ASN_NSAP: + default: + fprintf(stderr,"snprint_value: asn type not handled %d\n",var->type); + } + } + return(len); +} + +static int +__sprint_num_objid(char **buf, size_t *buf_len, oid *objid, int len) +{ + char *p, *end; + int i; + + enlarge_buffer(buf, buf_len, len * 16); + p = *buf; + end = *buf + *buf_len; + (*buf)[0] = '\0'; + for (i = 0; i < len; i++) + p += snprintf(p, end - p, ".%lu", *objid++); + + return SUCCESS; +} + +static int +__scan_num_objid(char *buf, oid *objid, size_t *len) +{ + char *cp; + *len = 0; + if (*buf == '.') buf++; + cp = buf; + while (*buf) { + if (*buf++ == '.') { + sscanf(cp, "%lu", objid++); + /* *objid++ = atoi(cp); */ + (*len)++; + cp = buf; + } else { + if (isalpha((int)*buf)) { + return FAILURE; + } + } + } + sscanf(cp, "%lu", objid++); + /* *objid++ = atoi(cp); */ + (*len)++; + return SUCCESS; +} + +static int +__get_type_str(int type, char * str) +{ + const struct type_table_entry *e; + + for (e = type_table; e->name; e++) { + if (type == e->mib_type) { + strcpy(str, e->name); + return SUCCESS; + } + } + + strcpy(str, ""); + if (_debug_level) + printf("__get_type_str:FAILURE(%d)\n", type); + + return FAILURE; +} + +/* does a destructive disection of .... returning + and in seperate strings (note: will destructively + alter input string, 'name') */ +static int +__get_label_iid(char *name, char **last_label, char **iid, int flag) +{ + char *lcp; + char *icp; + int len = STRLEN(name); + int found_label = 0; + + *last_label = *iid = NULL; + + if (len == 0) return(FAILURE); + + /* Handle case where numeric oid's have been requested. The input 'name' + ** in this case should be a numeric OID -- return failure if not. + */ + if ((flag & USE_NUMERIC_OIDS)) { + if (!__is_numeric_oid(name)) + return(FAILURE); + + /* Walk backward through the string, looking for first two '.' chars */ + lcp = &(name[len]); + icp = NULL; + while (lcp > name) { + if (*lcp == '.') { + + /* If this is the first occurence of '.', note it in icp. + ** Otherwise, this must be the second occurrence, so break + ** out of the loop. + */ + if (icp == NULL) + icp = lcp; + else + break; + } + lcp --; + } + + /* Make sure we found at least a label and index. */ + if (!icp) + return(FAILURE); + + /* Push forward past leading '.' chars and separate the strings. */ + lcp ++; + *icp ++ = '\0'; + + *last_label = (flag & USE_LONG_NAMES) ? name : lcp; + *iid = icp; + + return(SUCCESS); + } + + lcp = icp = &(name[len]); + + while (lcp > name) { + if (*lcp == '.') { + if (found_label) { + lcp++; + break; + } else { + icp = lcp; + } + } + if (!found_label && isalpha((int)*lcp)) found_label = 1; + lcp--; + } + + if (!found_label || (!isdigit((int)*(icp+1)) && (flag & FAIL_ON_NULL_IID))) + return(FAILURE); + + if (flag & NON_LEAF_NAME) { /* dont know where to start instance id */ + /* put the whole thing in label */ + icp = &(name[len]); + flag |= USE_LONG_NAMES; + /* special hack in case no mib loaded - object identifiers will + * start with .iso......, in which case it is preferable + * to make the label entirely numeric (i.e., convert "iso" => "1") + */ + if (*lcp == '.' && lcp == name) { + if (!strncmp(".ccitt.",lcp,7)) { + name += 2; + *name = '.'; + *(name+1) = '0'; + } else if (!strncmp(".iso.",lcp,5)) { + name += 2; + *name = '.'; + *(name+1) = '1'; + } else if (!strncmp(".joint-iso-ccitt.",lcp,17)) { + name += 2; + *name = '.'; + *(name+1) = '2'; + } + } + } else if (*icp) { + *(icp++) = '\0'; + } + *last_label = (flag & USE_LONG_NAMES ? name : lcp); + + *iid = icp; + + return(SUCCESS); +} + +/* Convert a tag (string) to an OID array */ +/* Tag can be either a symbolic name, or an OID string */ +static struct tree * +__tag2oid(char *tag, char *iid, oid *oid_arr, int *oid_arr_len, int *type, + int best_guess) +{ + struct tree *tp = NULL; + struct tree *rtp = NULL; + oid newname[MAX_OID_LEN], *op; + size_t newname_len = 0; + + if (type) *type = TYPE_UNKNOWN; + if (oid_arr_len) *oid_arr_len = 0; + if (!tag) goto done; + + /*********************************************************/ + /* best_guess = 0 - same as no switches (read_objid) */ + /* if multiple parts, or uses find_node */ + /* if a single leaf */ + /* best_guess = 1 - same as -Ib (get_wild_node) */ + /* best_guess = 2 - same as -IR (get_node) */ + /*********************************************************/ + + /* numeric scalar (1,2) */ + /* single symbolic (1,2) */ + /* single regex (1) */ + /* partial full symbolic (2) */ + /* full symbolic (2) */ + /* module::single symbolic (2) */ + /* module::partial full symbolic (2) */ + if (best_guess == 1 || best_guess == 2) { + if (!__scan_num_objid(tag, newname, &newname_len)) { /* make sure it's not a numeric tag */ + newname_len = MAX_OID_LEN; + if (best_guess == 2) { /* Random search -IR */ + if (get_node(tag, newname, &newname_len)) { + rtp = tp = get_tree(newname, newname_len, get_tree_head()); + } + } + else if (best_guess == 1) { /* Regex search -Ib */ + clear_tree_flags(get_tree_head()); + if (get_wild_node(tag, newname, &newname_len)) { + rtp = tp = get_tree(newname, newname_len, get_tree_head()); + } + } + } + else { + rtp = tp = get_tree(newname, newname_len, get_tree_head()); + } + if (type) *type = (tp ? tp->type : TYPE_UNKNOWN); + if ((oid_arr == NULL) || (oid_arr_len == NULL)) return rtp; + memcpy(oid_arr,(char*)newname,newname_len*sizeof(oid)); + *oid_arr_len = newname_len; + } + + /* if best_guess is off and multi part tag or module::tag */ + /* numeric scalar */ + /* module::single symbolic */ + /* module::partial full symbolic */ + /* FULL symbolic OID */ + else if (strchr(tag,'.') || strchr(tag,':')) { + if (!__scan_num_objid(tag, newname, &newname_len)) { /* make sure it's not a numeric tag */ + newname_len = MAX_OID_LEN; + if (read_objid(tag, newname, &newname_len)) { /* long name */ + rtp = tp = get_tree(newname, newname_len, get_tree_head()); + } else { + /* failed to parse the OID */ + newname_len = 0; + } + } + else { + rtp = tp = get_tree(newname, newname_len, get_tree_head()); + } + if (type) *type = (tp ? tp->type : TYPE_UNKNOWN); + if ((oid_arr == NULL) || (oid_arr_len == NULL)) return rtp; + memcpy(oid_arr,(char*)newname,newname_len*sizeof(oid)); + *oid_arr_len = newname_len; + } + + /* else best_guess is off and it is a single leaf */ + /* single symbolic */ + else { + rtp = tp = find_node(tag, get_tree_head()); + if (tp) { + if (type) *type = tp->type; + if ((oid_arr == NULL) || (oid_arr_len == NULL)) return rtp; + /* code taken from get_node in snmp_client.c */ + for(op = newname + MAX_OID_LEN - 1; op >= newname; op--){ + *op = tp->subid; + tp = tp->parent; + if (tp == NULL) + break; + } + *oid_arr_len = newname + MAX_OID_LEN - op; + memcpy(oid_arr, op, *oid_arr_len * sizeof(oid)); + } else { + return(rtp); /* HACK: otherwise, concat_oid_str confuses things */ + } + } + done: + if (iid && *iid && oid_arr_len) + __concat_oid_str(oid_arr, oid_arr_len, iid); + return(rtp); +} + +/* function: __concat_oid_str + * + * This function converts a dotted-decimal string, soid_str, to an array + * of oid types and concatenates them on doid_arr begining at the index + * specified by doid_arr_len. + * + * returns : SUCCESS, FAILURE + */ +static int +__concat_oid_str(oid *doid_arr, int *doid_arr_len, char *soid_str) +{ + char *soid_buf; + char *cp; + char *st; + + if (!soid_str || !*soid_str) return SUCCESS;/* successfully added nothing */ + if (*soid_str == '.') soid_str++; + soid_buf = strdup(soid_str); + if (!soid_buf) + return FAILURE; + cp = strtok_r(soid_buf,".",&st); + while (cp) { + sscanf(cp, "%lu", &(doid_arr[(*doid_arr_len)++])); + /* doid_arr[(*doid_arr_len)++] = atoi(cp); */ + cp = strtok_r(NULL,".",&st); + } + free(soid_buf); + return(SUCCESS); +} + +#ifndef NETSNMP_NO_WRITE_SUPPORT +/* + * add a varbind to PDU + */ +static int +__add_var_val_str(netsnmp_pdu *pdu, oid *name, int name_length, char *val, + int len, int type) +{ + netsnmp_variable_list *vars; + oid oidbuf[MAX_OID_LEN]; + int ret = SUCCESS; + + if (pdu->variables == NULL){ + pdu->variables = vars = + (netsnmp_variable_list *)calloc(1,sizeof(netsnmp_variable_list)); + } else { + for(vars = pdu->variables; + vars->next_variable; + vars = vars->next_variable) + /*EXIT*/; + vars->next_variable = + (netsnmp_variable_list *)calloc(1,sizeof(netsnmp_variable_list)); + vars = vars->next_variable; + } + + vars->next_variable = NULL; + vars->name = snmp_duplicate_objid(name, name_length); + vars->name_length = name_length; + switch (type) { + case TYPE_INTEGER: + case TYPE_INTEGER32: + vars->type = ASN_INTEGER; + vars->val.integer = malloc(sizeof(long)); + if (val) + *(vars->val.integer) = strtol(val,NULL,0); + else { + ret = FAILURE; + *(vars->val.integer) = 0; + } + vars->val_len = sizeof(long); + break; + + case TYPE_GAUGE: + case TYPE_UNSIGNED32: + vars->type = ASN_GAUGE; + goto UINT; + case TYPE_COUNTER: + vars->type = ASN_COUNTER; + goto UINT; + case TYPE_TIMETICKS: + vars->type = ASN_TIMETICKS; + goto UINT; + case TYPE_UINTEGER: + vars->type = ASN_UINTEGER; +UINT: + vars->val.integer = malloc(sizeof(long)); + if (val) + sscanf(val,"%lu",vars->val.integer); + else { + ret = FAILURE; + *(vars->val.integer) = 0; + } + vars->val_len = sizeof(long); + break; + + case TYPE_OCTETSTR: + vars->type = ASN_OCTET_STR; + goto OCT; + + case TYPE_BITSTRING: + vars->type = ASN_OCTET_STR; + goto OCT; + + case TYPE_OPAQUE: + vars->type = ASN_OCTET_STR; +OCT: + vars->val.string = malloc(len); + vars->val_len = len; + if (val && len) + memcpy((char *)vars->val.string, val, len); + else { + ret = FAILURE; + vars->val.string = (u_char*)strdup(""); + vars->val_len = 0; + } + break; + + case TYPE_IPADDR: + vars->type = ASN_IPADDRESS; + { + in_addr_t addr; + + if (val) + addr = inet_addr(val); + else { + ret = FAILURE; + addr = 0; + } + vars->val.integer = netsnmp_memdup((u_char **)&addr, sizeof(addr)); + vars->val_len = sizeof(addr); + } + break; + + case TYPE_OBJID: + vars->type = ASN_OBJECT_ID; + vars->val_len = MAX_OID_LEN; + /* if (read_objid(val, oidbuf, &(vars->val_len))) { */ + /* tp = __tag2oid(val,NULL,oidbuf,&(vars->val_len),NULL,0); */ + if (!val || !snmp_parse_oid(val, oidbuf, &vars->val_len)) { + vars->val.objid = NULL; + ret = FAILURE; + } else { + vars->val.objid = snmp_duplicate_objid(oidbuf, vars->val_len); + vars->val_len *= sizeof(oid); + } + break; + + default: + vars->type = ASN_NULL; + vars->val_len = 0; + vars->val.string = NULL; + ret = FAILURE; + } + + return ret; +} +#endif /* NETSNMP_NO_WRITE_SUPPORT */ + +/* takes ss and pdu as input and updates the 'response' argument */ +/* the input 'pdu' argument will be freed */ +static int +__send_sync_pdu(netsnmp_session *ss, netsnmp_pdu *pdu, netsnmp_pdu **response, + int retry_nosuch, char *err_str, int *err_num, int *err_ind) +{ + int status = 0; + long command = pdu->command; + char *tmp_err_str; + + *err_num = 0; + *err_ind = 0; + *response = NULL; + tmp_err_str = NULL; + memset(err_str, '\0', STR_BUF_SIZE); + + if (ss == NULL) { + *err_num = 0; + *err_ind = SNMPERR_BAD_SESSION; + status = SNMPERR_BAD_SESSION; + strlcpy(err_str, snmp_api_errstring(*err_ind), STR_BUF_SIZE); + goto done; + } + +retry: + + Py_BEGIN_ALLOW_THREADS + status = snmp_sess_synch_response(ss, pdu, response); + Py_END_ALLOW_THREADS + + if ((*response == NULL) && (status == STAT_SUCCESS)) status = STAT_ERROR; + + switch (status) { + case STAT_SUCCESS: + switch ((*response)->errstat) { + case SNMP_ERR_NOERROR: + break; + + case SNMP_ERR_NOSUCHNAME: + if (retry_nosuch && (pdu = snmp_fix_pdu(*response, command))) { + if (*response) snmp_free_pdu(*response); + goto retry; + } + + /* Pv1, SNMPsec, Pv2p, v2c, v2u, v2*, and SNMPv3 PDUs */ + case SNMP_ERR_TOOBIG: + case SNMP_ERR_BADVALUE: + case SNMP_ERR_READONLY: + case SNMP_ERR_GENERR: + /* in SNMPv2p, SNMPv2c, SNMPv2u, SNMPv2*, and SNMPv3 PDUs */ + case SNMP_ERR_NOACCESS: + case SNMP_ERR_WRONGTYPE: + case SNMP_ERR_WRONGLENGTH: + case SNMP_ERR_WRONGENCODING: + case SNMP_ERR_WRONGVALUE: + case SNMP_ERR_NOCREATION: + case SNMP_ERR_INCONSISTENTVALUE: + case SNMP_ERR_RESOURCEUNAVAILABLE: + case SNMP_ERR_COMMITFAILED: + case SNMP_ERR_UNDOFAILED: + case SNMP_ERR_AUTHORIZATIONERROR: + case SNMP_ERR_NOTWRITABLE: + /* in SNMPv2c, SNMPv2u, SNMPv2*, and SNMPv3 PDUs */ + case SNMP_ERR_INCONSISTENTNAME: + default: + strlcpy(err_str, (char*)snmp_errstring((*response)->errstat), + STR_BUF_SIZE); + *err_num = (int)(*response)->errstat; + *err_ind = (*response)->errindex; + status = (*response)->errstat; + break; + } + break; + + case STAT_TIMEOUT: + case STAT_ERROR: + snmp_sess_error(ss, err_num, err_ind, &tmp_err_str); + strlcpy(err_str, tmp_err_str, STR_BUF_SIZE); + break; + + default: + strcat(err_str, "send_sync_pdu: unknown status"); + *err_num = ss->s_snmp_errno; + break; + } +done: + if (tmp_err_str) { + free(tmp_err_str); + } + if (_debug_level && *err_num) printf("XXX sync PDU: %s\n", err_str); + return(status); +} + +static PyObject * +py_netsnmp_construct_varbind(void) +{ + PyObject *module; + PyObject *dict; + PyObject *callable; + + module = PyImport_ImportModule("netsnmp"); + dict = PyModule_GetDict(module); + + callable = PyDict_GetItemString(dict, "Varbind"); + + return PyObject_CallFunction(callable, ""); +} + +static int +py_netsnmp_attr_string(PyObject *obj, char * attr_name, char **val, + Py_ssize_t *len) +{ + *val = NULL; + if (obj && attr_name && PyObject_HasAttrString(obj, attr_name)) { + PyObject *attr = PyObject_GetAttrString(obj, attr_name); + if (attr) { + int retval; + retval = PyString_AsStringAndSize(attr, val, len); + Py_DECREF(attr); + return retval; + } + } + + return -1; +} + +static long long +py_netsnmp_attr_long(PyObject *obj, char * attr_name) +{ + long long val = -1; + + if (obj && attr_name && PyObject_HasAttrString(obj, attr_name)) { + PyObject *attr = PyObject_GetAttrString(obj, attr_name); + if (attr) { + val = PyInt_AsLong(attr); + Py_DECREF(attr); + } + } + + return val; +} + +static void * +py_netsnmp_attr_void_ptr(PyObject *obj, char * attr_name) +{ + void *val = NULL; + + if (obj && attr_name && PyObject_HasAttrString(obj, attr_name)) { + PyObject *attr = PyObject_GetAttrString(obj, attr_name); + if (attr) { + val = PyLong_AsVoidPtr(attr); + Py_DECREF(attr); + } + } + + return val; +} + +static int +py_netsnmp_verbose(void) +{ + int verbose = 0; + PyObject *pkg = PyImport_ImportModule("netsnmp"); + if (pkg) { + verbose = py_netsnmp_attr_long(pkg, "verbose"); + Py_DECREF(pkg); + } + + return verbose; +} + +static int +py_netsnmp_attr_set_string(PyObject *obj, char *attr_name, + char *val, size_t len) +{ + int ret = -1; + if (obj && attr_name) { + PyObject* val_obj = (val ? + Py_BuildValue("s#", val, len) : + Py_BuildValue("")); + if (!val_obj) + return -1; + ret = PyObject_SetAttrString(obj, attr_name, val_obj); + Py_DECREF(val_obj); + } + return ret; +} + +/** + * Update python session object error attributes. + * + * Copy the error info which may have been returned from __send_sync_pdu(...) + * into the python object. This will allow the python code to determine if + * an error occured during an snmp operation. + * + * Currently there are 3 attributes we care about + * + * ErrorNum - Copy of the value of netsnmp_session.s_errno. This is the system + * errno that was generated during our last call into the net-snmp library. + * + * ErrorInd - Copy of the value of netsmp_session.s_snmp_errno. These error + * numbers are separate from the system errno's and describe SNMP errors. + * + * ErrorStr - A string describing the ErrorInd that was returned during our last + * operation. + * + * @param[in] session The python object that represents our current Session + * @param[in|out] err_str A string describing err_ind + * @param[in|out] err_num The system errno currently stored by our session + * @param[in|out] err_ind The snmp errno currently stored by our session + */ +static void +__py_netsnmp_update_session_errors(PyObject *session, char *err_str, + int err_num, int err_ind) +{ + PyObject *tmp_for_conversion; + + py_netsnmp_attr_set_string(session, "ErrorStr", err_str, STRLEN(err_str)); + + tmp_for_conversion = PyInt_FromLong(err_num); + if (!tmp_for_conversion) + return; /* nothing better to do? */ + PyObject_SetAttrString(session, "ErrorNum", tmp_for_conversion); + Py_DECREF(tmp_for_conversion); + + tmp_for_conversion = PyInt_FromLong(err_ind); + if (!tmp_for_conversion) + return; /* nothing better to do? */ + PyObject_SetAttrString(session, "ErrorInd", tmp_for_conversion); + Py_DECREF(tmp_for_conversion); +} + +static PyObject * +netsnmp_create_session(PyObject *self, PyObject *args) +{ + int version; + char *community; + char *peer; + int lport; + int retries; + int timeout; + SnmpSession session = {0}; + SnmpSession *ss = NULL; + int verbose = py_netsnmp_verbose(); + + if (!PyArg_ParseTuple(args, "issiii", &version, + &community, &peer, &lport, + &retries, &timeout)) + return NULL; + + __libraries_init("python"); + + snmp_sess_init(&session); + + session.version = -1; +#ifndef DISABLE_SNMPV1 + if (version == 1) { + session.version = SNMP_VERSION_1; + } +#endif +#ifndef DISABLE_SNMPV2C + if (version == 2) { + session.version = SNMP_VERSION_2c; + } +#endif + if (version == 3) { + session.version = SNMP_VERSION_3; + } + if (session.version == -1) { + if (verbose) + printf("error:snmp_new_session:Unsupported SNMP version (%d)\n", version); + goto end; + } + + session.community_len = STRLEN((char *)community); + session.community = (u_char *)community; + session.peername = peer; + session.local_port = lport; + session.retries = retries; /* 5 */ + session.timeout = timeout; /* 1000000L */ + session.authenticator = NULL; + + ss = snmp_sess_open(&session); + + if (ss == NULL) { + if (verbose) + printf("error:snmp_new_session: Couldn't open SNMP session"); + } + end: + return PyLong_FromVoidPtr((void *)ss); +} + +static PyObject * +netsnmp_create_session_v3(PyObject *self, PyObject *args) +{ + int version; + char *peer; + int lport; + int retries; + int timeout; + char * sec_name; + int sec_level; + char * sec_eng_id; + char * context_eng_id; + char * context; + char * auth_proto; + char * auth_pass; + char * priv_proto; + char * priv_pass; + int priv_type; + int eng_boots; + int eng_time; + SnmpSession session = {0}; + SnmpSession *ss = NULL; + int verbose = py_netsnmp_verbose(); + + if (!PyArg_ParseTuple(args, "isiiisisssssssii", &version, + &peer, &lport, &retries, &timeout, + &sec_name, &sec_level, &sec_eng_id, + &context_eng_id, &context, + &auth_proto, &auth_pass, + &priv_proto, &priv_pass, + &eng_boots, &eng_time)) + return NULL; + + __libraries_init("python"); + snmp_sess_init(&session); + + if (version == 3) { + session.version = SNMP_VERSION_3; + } else { + if (verbose) + printf("error:snmp_new_v3_session:Unsupported SNMP version (%d)\n", version); + goto end; + } + + session.peername = peer; + session.retries = retries; /* 5 */ + session.timeout = timeout; /* 1000000L */ + session.authenticator = NULL; + session.contextNameLen = STRLEN(context); + session.contextName = context; + session.securityNameLen = STRLEN(sec_name); + session.securityName = sec_name; + session.securityLevel = sec_level; + session.securityModel = USM_SEC_MODEL_NUMBER; + session.securityEngineIDLen = + hex_to_binary2((unsigned char*)sec_eng_id, STRLEN(sec_eng_id), + (char **) &session.securityEngineID); + session.contextEngineIDLen = + hex_to_binary2((unsigned char*)sec_eng_id, STRLEN(sec_eng_id), + (char **) &session.contextEngineID); + session.engineBoots = eng_boots; + session.engineTime = eng_time; + + if (!strcmp(auth_proto, "DEFAULT")) { + const oid* a = get_default_authtype(&session.securityAuthProtoLen); + session.securityAuthProto + = snmp_duplicate_objid(a, session.securityAuthProtoLen); + } else { + const oid *auth_prot; + int auth_type = usm_lookup_auth_type(auth_proto); + if (auth_type < 0) { + if (verbose) + printf("error:snmp_new_v3_session:Unsupported authentication protocol(%s)\n", auth_proto); + goto end; + } + auth_prot = sc_get_auth_oid(auth_type, &session.securityAuthProtoLen); + if (auth_prot) + session.securityAuthProto = + snmp_duplicate_objid(auth_prot, session.securityAuthProtoLen); + } + if (session.securityLevel >= SNMP_SEC_LEVEL_AUTHNOPRIV) { + if (STRLEN(auth_pass) > 0) { + session.securityAuthKeyLen = USM_AUTH_KU_LEN; + if (generate_Ku(session.securityAuthProto, + session.securityAuthProtoLen, + (u_char *)auth_pass, STRLEN(auth_pass), + session.securityAuthKey, + &session.securityAuthKeyLen) != SNMPERR_SUCCESS) { + if (verbose) + printf("error:snmp_new_v3_session:Error generating Ku from authentication password.\n"); + goto end; + } + } + } + if (!strcmp(priv_proto, "DEFAULT")) { + const oid *p = get_default_privtype(&session.securityPrivProtoLen); + session.securityPrivProto + = snmp_duplicate_objid(p, session.securityPrivProtoLen); + } else { + const oid *priv_prot; + priv_type = usm_lookup_priv_type(priv_proto); + if (priv_type < 0) { + if (verbose) + printf("error:snmp_new_v3_session:Unsupported privacy protocol(%s)\n", priv_proto); + goto end; + } + priv_prot = sc_get_priv_oid(priv_type, &session.securityPrivProtoLen); + if (priv_prot) + session.securityPrivProto = + snmp_duplicate_objid(priv_prot, session.securityPrivProtoLen); + } + + if (session.securityLevel >= SNMP_SEC_LEVEL_AUTHPRIV) { + session.securityPrivKeyLen = USM_PRIV_KU_LEN; + if (generate_Ku(session.securityAuthProto, + session.securityAuthProtoLen, + (u_char *)priv_pass, STRLEN(priv_pass), + session.securityPrivKey, + &session.securityPrivKeyLen) != SNMPERR_SUCCESS) { + if (verbose) + printf("error:v3_session: couldn't gen Ku from priv pass phrase.\n"); + goto end; + } + } + + ss = snmp_sess_open(&session); + + end: + if (ss == NULL) { + if (verbose) + printf("error:v3_session: couldn't open SNMP session(%s).\n", + snmp_api_errstring(snmp_errno)); + } + free (session.securityEngineID); + free (session.contextEngineID); + + return PyLong_FromVoidPtr((void *)ss); +} + +static PyObject * +netsnmp_create_session_tunneled(PyObject *self, PyObject *args) +{ + int version; + char *peer; + int lport; + int retries; + int timeout; + char * sec_name; + int sec_level; + char * context_eng_id; + char * context; + char * our_identity; + char * their_identity; + char * their_hostname; + char * trust_cert; + SnmpSession session = {0}; + SnmpSession *ss = NULL; + int verbose = py_netsnmp_verbose(); + + if (!PyArg_ParseTuple(args, "isiiisissssss", &version, + &peer, &lport, &retries, &timeout, + &sec_name, &sec_level, + &context_eng_id, &context, + &our_identity, &their_identity, + &their_hostname, &trust_cert)) + return NULL; + + __libraries_init("python"); + snmp_sess_init(&session); + + if (version != 3) { + session.version = SNMP_VERSION_3; + if (verbose) + printf("Using version 3 as it's the only version that supports tunneling\n"); + } + + session.peername = peer; + session.retries = retries; /* 5 */ + session.timeout = timeout; /* 1000000L */ + session.contextNameLen = STRLEN(context); + session.contextName = context; + session.securityNameLen = STRLEN(sec_name); + session.securityName = sec_name; + session.securityLevel = sec_level; + session.securityModel = NETSNMP_TSM_SECURITY_MODEL; + + /* create the transport configuration store */ + if (!session.transport_configuration) { + netsnmp_container_init_list(); + session.transport_configuration = + netsnmp_container_find("transport_configuration:fifo"); + if (!session.transport_configuration) { + fprintf(stderr, "failed to initialize the transport configuration container\n"); + return NULL; + } + + session.transport_configuration->compare = + (netsnmp_container_compare*) + netsnmp_transport_config_compare; + } + + if (our_identity && our_identity[0] != '\0') + CONTAINER_INSERT(session.transport_configuration, + netsnmp_transport_create_config("localCert", + our_identity)); + + if (their_identity && their_identity[0] != '\0') + CONTAINER_INSERT(session.transport_configuration, + netsnmp_transport_create_config("peerCert", + their_identity)); + + if (their_hostname && their_hostname[0] != '\0') + CONTAINER_INSERT(session.transport_configuration, + netsnmp_transport_create_config("their_hostname", + their_hostname)); + + if (trust_cert && trust_cert[0] != '\0') + CONTAINER_INSERT(session.transport_configuration, + netsnmp_transport_create_config("trust_cert", + trust_cert)); + + ss = snmp_sess_open(&session); + + if (!ss) + return NULL; + /* + * Note: on a 64-bit system the statement below discards the upper 32 bits of + * "ss", which is most likely a bug. + */ + return Py_BuildValue("i", (int)(uintptr_t)ss); +} + +static PyObject * +netsnmp_delete_session(PyObject *self, PyObject *args) +{ + PyObject *session; + SnmpSession *ss = NULL; + + if (!PyArg_ParseTuple(args, "O", &session)) { + return NULL; + } + + ss = (SnmpSession *)py_netsnmp_attr_void_ptr(session, "sess_ptr"); + + snmp_sess_close(ss); + return (Py_BuildValue("")); +} + + +static PyObject * +netsnmp_get(PyObject *self, PyObject *args) +{ + PyObject *session; + PyObject *varlist; + PyObject *varbind; + PyObject *val_tuple = NULL; + int varlist_len = 0; + int varlist_ind; + netsnmp_session *ss; + netsnmp_pdu *pdu, *response; + netsnmp_variable_list *vars; + struct tree *tp; + int len; + oid *oid_arr; + int oid_arr_len = MAX_OID_LEN; + int type; + char type_str[MAX_TYPE_NAME_LEN]; + u_char *str_buf = NULL; + size_t str_buf_len = 0; + size_t out_len = 0; + int buf_over = 0; + char *tag; + char *iid; + int getlabel_flag = NO_FLAGS; + int sprintval_flag = USE_BASIC; + int verbose = py_netsnmp_verbose(); + int old_format; + int best_guess; + int retry_nosuch; + int err_ind; + int err_num; + char err_str[STR_BUF_SIZE]; + char *tmpstr; + Py_ssize_t tmplen; + + oid_arr = calloc(MAX_OID_LEN, sizeof(oid)); + + if (oid_arr && args) { + + if (!PyArg_ParseTuple(args, "OO", &session, &varlist)) { + goto done; + } + + ss = (SnmpSession *)py_netsnmp_attr_void_ptr(session, "sess_ptr"); + + if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) { + goto done; + } + + if (py_netsnmp_attr_long(session, "UseLongNames")) + getlabel_flag |= USE_LONG_NAMES; + if (py_netsnmp_attr_long(session, "UseNumeric")) + getlabel_flag |= USE_NUMERIC_OIDS; + if (py_netsnmp_attr_long(session, "UseEnums")) + sprintval_flag = USE_ENUMS; + if (py_netsnmp_attr_long(session, "UseSprintValue")) + sprintval_flag = USE_SPRINT_VALUE; + best_guess = py_netsnmp_attr_long(session, "BestGuess"); + retry_nosuch = py_netsnmp_attr_long(session, "RetryNoSuch"); + + pdu = snmp_pdu_create(SNMP_MSG_GET); + + if (varlist) { + PyObject *varlist_iter = PyObject_GetIter(varlist); + + while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) { + if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 || + py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0) + { + oid_arr_len = 0; + } else { + tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, NULL, best_guess); + } + + if (oid_arr_len) { + snmp_add_null_var(pdu, oid_arr, oid_arr_len); + varlist_len++; + } else { + if (verbose) + printf("error: get: unknown object ID (%s)", + (tag ? tag : "")); + snmp_free_pdu(pdu); + Py_DECREF(varbind); + goto done; + } + /* release reference when done */ + Py_DECREF(varbind); + } + + Py_DECREF(varlist_iter); + + if (PyErr_Occurred()) { + /* propagate error */ + if (verbose) + printf("error: get: unknown python error"); + snmp_free_pdu(pdu); + goto done; + } + } + + __send_sync_pdu(ss, pdu, &response, retry_nosuch, err_str, &err_num, + &err_ind); + __py_netsnmp_update_session_errors(session, err_str, err_num, err_ind); + + /* + ** Set up for numeric or full OID's, if necessary. Save the old + ** output format so that it can be restored when we finish -- this + ** is a library-wide global, and has to be set/restored for each + ** session. + */ + old_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT); + + if (py_netsnmp_attr_long(session, "UseLongNames")) { + getlabel_flag |= USE_LONG_NAMES; + + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + NETSNMP_OID_OUTPUT_FULL); + } + /* Setting UseNumeric forces UseLongNames on so check for UseNumeric + after UseLongNames (above) to make sure the final outcome of + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT is NETSNMP_OID_OUTPUT_NUMERIC */ + if (py_netsnmp_attr_long(session, "UseNumeric")) { + getlabel_flag |= USE_LONG_NAMES; + getlabel_flag |= USE_NUMERIC_OIDS; + + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + NETSNMP_OID_OUTPUT_NUMERIC); + } + + val_tuple = PyTuple_New(varlist_len); + /* initialize return tuple */ + for (varlist_ind = 0; varlist_ind < varlist_len; varlist_ind++) { + PyTuple_SetItem(val_tuple, varlist_ind, Py_BuildValue("")); + } + + for(vars = (response ? response->variables : NULL), varlist_ind = 0; + vars && (varlist_ind < varlist_len); + vars = vars->next_variable, varlist_ind++) { + + varbind = PySequence_GetItem(varlist, varlist_ind); + + if (PyObject_HasAttrString(varbind, "tag")) { + if (str_buf == NULL) { + str_buf = (u_char *) netsnmp_malloc(STR_BUF_SIZE); + str_buf_len = STR_BUF_SIZE; + } + *str_buf = '.'; + *(str_buf+1) = '\0'; + out_len = 0; + tp = netsnmp_sprint_realloc_objid_tree(&str_buf, &str_buf_len, + &out_len, 1, &buf_over, + vars->name,vars->name_length); + if (_debug_level) + printf("netsnmp_get:str_buf:%s:%d:%d\n", str_buf, + (int)str_buf_len, (int)out_len); + + if (__is_leaf(tp)) { + type = (tp->type ? tp->type : tp->parent->type); + getlabel_flag &= ~NON_LEAF_NAME; + if (_debug_level) printf("netsnmp_get:is_leaf:%d\n",type); + } else { + getlabel_flag |= NON_LEAF_NAME; + type = __translate_asn_type(vars->type); + if (_debug_level) printf("netsnmp_get:!is_leaf:%d\n",tp->type); + } + __get_label_iid((char *) str_buf, &tag, &iid, getlabel_flag); + + py_netsnmp_attr_set_string(varbind, "tag", tag, STRLEN(tag)); + py_netsnmp_attr_set_string(varbind, "iid", iid, STRLEN(iid)); + + __get_type_str(type, type_str); + + py_netsnmp_attr_set_string(varbind, "type", type_str, strlen(type_str)); + + len = __snprint_value((char **)&str_buf, &str_buf_len, + vars, tp, type, sprintval_flag); + str_buf[len] = '\0'; + py_netsnmp_attr_set_string(varbind, "val", (char *) str_buf, len); + + /* save in return tuple as well */ + if ((type == SNMP_ENDOFMIBVIEW) || + (type == SNMP_NOSUCHOBJECT) || + (type == SNMP_NOSUCHINSTANCE)) { + /* Translate error to None */ + PyTuple_SetItem(val_tuple, varlist_ind, + Py_BuildValue("")); + } else { + PyTuple_SetItem(val_tuple, varlist_ind, + Py_BuildValue("s#", str_buf, len)); + } + Py_DECREF(varbind); + } else { + printf("netsnmp_get: bad varbind (%d)\n", varlist_ind); + Py_XDECREF(varbind); + } + } + + /* Reset the library's behavior for numeric/symbolic OID's. */ + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + old_format); + + if (response) snmp_free_pdu(response); + } + + done: + free(oid_arr); + if (str_buf != NULL) netsnmp_free(str_buf); + return (val_tuple ? val_tuple : Py_BuildValue("")); +} + +static PyObject * +netsnmp_getnext(PyObject *self, PyObject *args) +{ + PyObject *session; + PyObject *varlist; + PyObject *varbind; + PyObject *val_tuple = NULL; + int varlist_len = 0; + int varlist_ind; + netsnmp_session *ss; + netsnmp_pdu *pdu, *response; + netsnmp_variable_list *vars; + struct tree *tp; + int len; + oid *oid_arr; + int oid_arr_len = MAX_OID_LEN; + int type; + char type_str[MAX_TYPE_NAME_LEN]; + u_char *str_buf = NULL; + size_t str_buf_len = 0; + size_t out_len = 0; + int buf_over = 0; + char *tag; + char *iid = NULL; + int getlabel_flag = NO_FLAGS; + int sprintval_flag = USE_BASIC; + int verbose = py_netsnmp_verbose(); + int old_format; + int best_guess; + int retry_nosuch; + int err_ind; + int err_num; + char err_str[STR_BUF_SIZE]; + char *tmpstr; + Py_ssize_t tmplen; + + oid_arr = calloc(MAX_OID_LEN, sizeof(oid)); + + if (oid_arr && args) { + + if (!PyArg_ParseTuple(args, "OO", &session, &varlist)) { + goto done; + } + + ss = (SnmpSession *)py_netsnmp_attr_void_ptr(session, "sess_ptr"); + + if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) { + goto done; + } + memcpy(&err_str, tmpstr, tmplen); + err_num = py_netsnmp_attr_long(session, "ErrorNum"); + err_ind = py_netsnmp_attr_long(session, "ErrorInd"); + + if (py_netsnmp_attr_long(session, "UseLongNames")) + getlabel_flag |= USE_LONG_NAMES; + if (py_netsnmp_attr_long(session, "UseNumeric")) + getlabel_flag |= USE_NUMERIC_OIDS; + if (py_netsnmp_attr_long(session, "UseEnums")) + sprintval_flag = USE_ENUMS; + if (py_netsnmp_attr_long(session, "UseSprintValue")) + sprintval_flag = USE_SPRINT_VALUE; + best_guess = py_netsnmp_attr_long(session, "BestGuess"); + retry_nosuch = py_netsnmp_attr_long(session, "RetryNoSuch"); + + pdu = snmp_pdu_create(SNMP_MSG_GETNEXT); + + if (varlist) { + PyObject *varlist_iter = PyObject_GetIter(varlist); + + while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) { + if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 || + py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0) + { + oid_arr_len = 0; + } else { + tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, NULL, best_guess); + } + + if (_debug_level) + printf("netsnmp_getnext: filling request: %s:%s:%d:%d\n", + tag, iid, oid_arr_len,best_guess); + + if (oid_arr_len) { + snmp_add_null_var(pdu, oid_arr, oid_arr_len); + varlist_len++; + } else { + if (verbose) + printf("error: getnext: unknown object ID (%s)", + (tag ? tag : "")); + snmp_free_pdu(pdu); + Py_DECREF(varbind); + goto done; + } + /* release reference when done */ + Py_DECREF(varbind); + } + + Py_DECREF(varlist_iter); + + if (PyErr_Occurred()) { + /* propagate error */ + if (verbose) + printf("error: getnext: unknown python error"); + snmp_free_pdu(pdu); + goto done; + } + } + + __send_sync_pdu(ss, pdu, &response, retry_nosuch, err_str, &err_num, + &err_ind); + __py_netsnmp_update_session_errors(session, err_str, err_num, err_ind); + + /* + ** Set up for numeric or full OID's, if necessary. Save the old + ** output format so that it can be restored when we finish -- this + ** is a library-wide global, and has to be set/restored for each + ** session. + */ + old_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT); + + if (py_netsnmp_attr_long(session, "UseLongNames")) { + getlabel_flag |= USE_LONG_NAMES; + + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + NETSNMP_OID_OUTPUT_FULL); + } + /* Setting UseNumeric forces UseLongNames on so check for UseNumeric + after UseLongNames (above) to make sure the final outcome of + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT is NETSNMP_OID_OUTPUT_NUMERIC */ + if (py_netsnmp_attr_long(session, "UseNumeric")) { + getlabel_flag |= USE_LONG_NAMES; + getlabel_flag |= USE_NUMERIC_OIDS; + + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + NETSNMP_OID_OUTPUT_NUMERIC); + } + + val_tuple = PyTuple_New(varlist_len); + /* initialize return tuple */ + for (varlist_ind = 0; varlist_ind < varlist_len; varlist_ind++) { + PyTuple_SetItem(val_tuple, varlist_ind, Py_BuildValue("")); + } + + for(vars = (response ? response->variables : NULL), varlist_ind = 0; + vars && (varlist_ind < varlist_len); + vars = vars->next_variable, varlist_ind++) { + + varbind = PySequence_GetItem(varlist, varlist_ind); + + if (PyObject_HasAttrString(varbind, "tag")) { + if (str_buf == NULL) { + str_buf = (u_char *) netsnmp_malloc(STR_BUF_SIZE); + str_buf_len = STR_BUF_SIZE; + } + *str_buf = '.'; + *(str_buf+1) = '\0'; + out_len = 0; + tp = netsnmp_sprint_realloc_objid_tree(&str_buf, &str_buf_len, + &out_len, 1, &buf_over, + vars->name,vars->name_length); + + if (__is_leaf(tp)) { + type = (tp->type ? tp->type : tp->parent->type); + getlabel_flag &= ~NON_LEAF_NAME; + } else { + getlabel_flag |= NON_LEAF_NAME; + type = __translate_asn_type(vars->type); + } + + __get_label_iid((char *) str_buf, &tag, &iid, getlabel_flag); + + if (_debug_level) + printf("netsnmp_getnext: filling response: %s:%s\n", tag, iid); + + py_netsnmp_attr_set_string(varbind, "tag", tag, STRLEN(tag)); + py_netsnmp_attr_set_string(varbind, "iid", iid, STRLEN(iid)); + + __get_type_str(type, type_str); + + py_netsnmp_attr_set_string(varbind, "type", type_str, + strlen(type_str)); + + len = __snprint_value((char **)&str_buf, &str_buf_len, + vars, tp, type, sprintval_flag); + str_buf[len] = '\0'; + + py_netsnmp_attr_set_string(varbind, "val", (char *) str_buf, len); + + /* save in return tuple as well */ + if ((type == SNMP_ENDOFMIBVIEW) || + (type == SNMP_NOSUCHOBJECT) || + (type == SNMP_NOSUCHINSTANCE)) { + /* Translate error to None */ + PyTuple_SetItem(val_tuple, varlist_ind, + Py_BuildValue("")); + } else { + PyTuple_SetItem(val_tuple, varlist_ind, + Py_BuildValue("s#", str_buf, len)); + } + Py_DECREF(varbind); + } else { + printf("netsnmp_getnext: bad varbind (%d)\n", varlist_ind); + Py_XDECREF(varbind); + } + } + + /* Reset the library's behavior for numeric/symbolic OID's. */ + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + old_format); + + if (response) snmp_free_pdu(response); + } + + done: + free(oid_arr); + if (str_buf != NULL) netsnmp_free(str_buf); + return (val_tuple ? val_tuple : Py_BuildValue("")); +} + +static PyObject * +netsnmp_walk(PyObject *self, PyObject *args) +{ + PyObject *session; + PyObject *varlist; + PyObject *varlist_iter; + PyObject *varbind; + PyObject *val_tuple = NULL; + PyObject *varbinds = NULL; + int varlist_len = 0; + int varlist_ind; + netsnmp_session *ss; + netsnmp_pdu *pdu, *response; + netsnmp_pdu *newpdu; + netsnmp_variable_list *vars, *oldvars; + struct tree *tp; + int len; + oid **oid_arr = NULL; + int *oid_arr_len = NULL; + oid **oid_arr_broken_check = NULL; + int *oid_arr_broken_check_len = NULL; + int type; + char type_str[MAX_TYPE_NAME_LEN]; + int status; + u_char *str_buf = NULL; + size_t str_buf_len = 0; + size_t out_len = 0; + int buf_over = 0; + char *tag; + char *iid = NULL; + int getlabel_flag = NO_FLAGS; + int sprintval_flag = USE_BASIC; + int verbose = py_netsnmp_verbose(); + int old_format; + int best_guess; + int retry_nosuch; + int err_ind; + int err_num; + char err_str[STR_BUF_SIZE]; + int notdone = 1; + int result_count = 0; + char *tmpstr; + Py_ssize_t tmplen; + + if (args) { + + if (!PyArg_ParseTuple(args, "OO", &session, &varlist)) { + goto done; + } + + if (!varlist) { + goto done; + } + + if ((varbinds = PyObject_GetAttrString(varlist, "varbinds")) == NULL) { + goto done; + } + ss = (SnmpSession *)py_netsnmp_attr_void_ptr(session, "sess_ptr"); + + if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) { + goto done; + } + memcpy(&err_str, tmpstr, tmplen); + err_num = py_netsnmp_attr_long(session, "ErrorNum"); + err_ind = py_netsnmp_attr_long(session, "ErrorInd"); + + if (py_netsnmp_attr_long(session, "UseLongNames")) + getlabel_flag |= USE_LONG_NAMES; + if (py_netsnmp_attr_long(session, "UseNumeric")) + getlabel_flag |= USE_NUMERIC_OIDS; + if (py_netsnmp_attr_long(session, "UseEnums")) + sprintval_flag = USE_ENUMS; + if (py_netsnmp_attr_long(session, "UseSprintValue")) + sprintval_flag = USE_SPRINT_VALUE; + best_guess = py_netsnmp_attr_long(session, "BestGuess"); + retry_nosuch = py_netsnmp_attr_long(session, "RetryNoSuch"); + + pdu = snmp_pdu_create(SNMP_MSG_GETNEXT); + + /* we need an initial count for memory allocation */ + varlist_iter = PyObject_GetIter(varlist); + varlist_len = 0; + while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) { + varlist_len++; + } + Py_DECREF(varlist_iter); + + oid_arr_len = calloc(varlist_len, sizeof(int)); + oid_arr_broken_check_len = calloc(varlist_len, sizeof(int)); + + oid_arr = calloc(varlist_len, sizeof(oid *)); + oid_arr_broken_check = calloc(varlist_len, sizeof(oid *)); + + for(varlist_ind = 0; varlist_ind < varlist_len; varlist_ind++) { + + oid_arr[varlist_ind] = calloc(MAX_OID_LEN, sizeof(oid)); + oid_arr_broken_check[varlist_ind] = calloc(MAX_OID_LEN, sizeof(oid)); + + oid_arr_len[varlist_ind] = MAX_OID_LEN; + oid_arr_broken_check_len[varlist_ind] = MAX_OID_LEN; + } + + /* get the initial starting oids*/ + varlist_iter = PyObject_GetIter(varlist); + varlist_ind = 0; + while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) { + + if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 || + py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0) + { + oid_arr_len[varlist_ind] = 0; + } else { + tp = __tag2oid(tag, iid, + oid_arr[varlist_ind], &oid_arr_len[varlist_ind], + NULL, best_guess); + } + + if (_debug_level) + printf("netsnmp_walk: filling request: %s:%s:%d:%d\n", + tag, iid, oid_arr_len[varlist_ind],best_guess); + + if (oid_arr_len[varlist_ind]) { + snmp_add_null_var(pdu, oid_arr[varlist_ind], oid_arr_len[varlist_ind]); + } else { + if (verbose) + printf("error: walk: unknown object ID (%s)", + (tag ? tag : "")); + snmp_free_pdu(pdu); + Py_DECREF(varbind); + goto done; + } + /* release reference when done */ + Py_DECREF(varbind); + varlist_ind++; + } + + if (varlist_iter) + Py_DECREF(varlist_iter); + + if (PyErr_Occurred()) { + /* propagate error */ + if (verbose) + printf("error: walk: unknown python error (varlist)"); + snmp_free_pdu(pdu); + goto done; + } + + /* pre-allocate the return tuples */ + val_tuple = PyTuple_New(0); + + if (!val_tuple) { + /* propagate error */ + if (verbose) + printf("error: walk: couldn't allocate a new value tuple"); + snmp_free_pdu(pdu); + goto done; + } + + /* + ** Set up for numeric or full OID's, if necessary. Save the old + ** output format so that it can be restored when we finish -- this + ** is a library-wide global, and has to be set/restored for each + ** session. + */ + old_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT); + + if (py_netsnmp_attr_long(session, "UseLongNames")) { + getlabel_flag |= USE_LONG_NAMES; + + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + NETSNMP_OID_OUTPUT_FULL); + } + + /* Setting UseNumeric forces UseLongNames on so check for UseNumeric + after UseLongNames (above) to make sure the final outcome of + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT is NETSNMP_OID_OUTPUT_NUMERIC */ + if (py_netsnmp_attr_long(session, "UseNumeric")) { + getlabel_flag |= USE_LONG_NAMES; + getlabel_flag |= USE_NUMERIC_OIDS; + + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + NETSNMP_OID_OUTPUT_NUMERIC); + } + + /* delete the existing varbinds that we'll replace */ + PySequence_DelSlice(varbinds, 0, PySequence_Length(varbinds)); + + if (PyErr_Occurred()) { + /* propagate error */ + if (verbose) + printf("error: walk: deleting old varbinds failed\n"); + snmp_free_pdu(pdu); + goto done; + } + + /* save the starting OID */ + + for(vars = pdu->variables, varlist_ind = 0; + vars != NULL; + vars = vars->next_variable, varlist_ind++) { + + oid_arr_broken_check[varlist_ind] = calloc(MAX_OID_LEN, sizeof(oid)); + + oid_arr_broken_check_len[varlist_ind] = vars->name_length; + memcpy(oid_arr_broken_check[varlist_ind], + vars->name, vars->name_length * sizeof(oid)); + } + + while(notdone) { + + status = __send_sync_pdu(ss, pdu, &response, retry_nosuch, + err_str, &err_num, &err_ind); + __py_netsnmp_update_session_errors(session, err_str, err_num, err_ind); + + if (!response || !response->variables || + status != STAT_SUCCESS || + response->errstat != SNMP_ERR_NOERROR) { + notdone = 0; + } else { + newpdu = snmp_pdu_create(SNMP_MSG_GETNEXT); + + for(vars = (response ? response->variables : NULL), + varlist_ind = 0, + oldvars = (pdu ? pdu->variables : NULL); + vars && (varlist_ind < varlist_len); + vars = vars->next_variable, varlist_ind++, + oldvars = (oldvars ? oldvars->next_variable : NULL)) { + + if ((vars->name_length < oid_arr_len[varlist_ind]) || + (memcmp(oid_arr[varlist_ind], vars->name, + oid_arr_len[varlist_ind] * sizeof(oid)) != 0)) { + notdone = 0; + break; + } + + if ((vars->type == SNMP_ENDOFMIBVIEW) || + (vars->type == SNMP_NOSUCHOBJECT) || + (vars->type == SNMP_NOSUCHINSTANCE)) { + notdone = 0; + break; + } + + if (snmp_oid_compare(vars->name, vars->name_length, + oid_arr_broken_check[varlist_ind], + oid_arr_broken_check_len[varlist_ind]) <= 0) { + /* The agent responded with an illegal response + as the returning OID was lexogragically less + then or equal to the requested OID... + We need to give up here because an infite + loop will result otherwise. + + XXX: this really should be an option to + continue like the -Cc option to the snmpwalk + application. + */ + notdone = 0; + break; + } + + varbind = py_netsnmp_construct_varbind(); + + if (PyObject_HasAttrString(varbind, "tag")) { + if (str_buf == NULL) { + str_buf = (u_char *) netsnmp_malloc(STR_BUF_SIZE); + str_buf_len = STR_BUF_SIZE; + } + str_buf[0] = '.'; + str_buf[1] = '\0'; + out_len = 0; + tp = netsnmp_sprint_realloc_objid_tree(&str_buf, &str_buf_len, + &out_len, 1, &buf_over, + vars->name,vars->name_length); + + if (__is_leaf(tp)) { + type = (tp->type ? tp->type : tp->parent->type); + getlabel_flag &= ~NON_LEAF_NAME; + } else { + getlabel_flag |= NON_LEAF_NAME; + type = __translate_asn_type(vars->type); + } + + __get_label_iid((char *) str_buf, &tag, &iid, getlabel_flag); + + if (_debug_level) printf("netsnmp_walk: filling response: %s:%s\n", tag, iid); + + py_netsnmp_attr_set_string(varbind, "tag", tag, STRLEN(tag)); + py_netsnmp_attr_set_string(varbind, "iid", iid, STRLEN(iid)); + + __get_type_str(type, type_str); + + py_netsnmp_attr_set_string(varbind, "type", type_str, + strlen(type_str)); + + len = __snprint_value((char **)&str_buf, &str_buf_len, + vars, tp, type, sprintval_flag); + str_buf[len] = '\0'; + + py_netsnmp_attr_set_string(varbind, "val", (char *) str_buf, + len); + + /* push the varbind onto the return varbinds */ + PyList_Append(varbinds, varbind); + + /* save in return tuple as well */ + /* save in return tuple as well - steals ref */ + _PyTuple_Resize(&val_tuple, result_count+1); + PyTuple_SetItem(val_tuple, result_count++, + Py_BuildValue("s#", str_buf, len)); + } else { + /* Return None for this variable. */ + _PyTuple_Resize(&val_tuple, result_count+1); + PyTuple_SetItem(val_tuple, result_count++, Py_BuildValue("")); + printf("netsnmp_walk: bad varbind (%d)\n", varlist_ind); + } + Py_XDECREF(varbind); + + memcpy(oid_arr_broken_check[varlist_ind], vars->name, + sizeof(oid) * vars->name_length); + oid_arr_broken_check_len[varlist_ind] = vars->name_length; + + snmp_add_null_var(newpdu, vars->name, + vars->name_length); + } + pdu = newpdu; + } + if (response) + snmp_free_pdu(response); + } + + /* Reset the library's behavior for numeric/symbolic OID's. */ + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + old_format); + + + if (PyErr_Occurred()) { + /* propagate error */ + if (verbose) + printf("error: walk response processing: unknown python error"); + Py_DECREF(val_tuple); + } + } + + done: + Py_XDECREF(varbinds); + free(oid_arr_len); + free(oid_arr_broken_check_len); + for(varlist_ind = 0; varlist_ind < varlist_len; varlist_ind ++) { + free(oid_arr[varlist_ind]); + free(oid_arr_broken_check[varlist_ind]); + } + free(oid_arr); + free(oid_arr_broken_check); + if (str_buf != NULL) netsnmp_free(str_buf); + return (val_tuple ? val_tuple : Py_BuildValue("")); +} + + +static PyObject * +netsnmp_getbulk(PyObject *self, PyObject *args) +{ + int nonrepeaters; + int maxrepetitions; + PyObject *session; + PyObject *varlist; + PyObject *varbinds; + PyObject *varbind; + PyObject *varbinds_iter; + PyObject *val_tuple = NULL; + int varbind_ind; + netsnmp_session *ss; + netsnmp_pdu *pdu, *response; + netsnmp_variable_list *vars; + struct tree *tp; + int len; + oid *oid_arr; + int oid_arr_len = MAX_OID_LEN; + int type; + char type_str[MAX_TYPE_NAME_LEN]; + u_char *str_buf = NULL; + size_t str_buf_len = 0; + size_t out_len = 0; + int buf_over = 0; + char *tag; + char *iid; + int getlabel_flag = NO_FLAGS; + int sprintval_flag = USE_BASIC; + int verbose = py_netsnmp_verbose(); + int old_format; + int best_guess; + int retry_nosuch; + int err_ind; + int err_num; + char err_str[STR_BUF_SIZE]; + char *tmpstr; + Py_ssize_t tmplen; + + oid_arr = calloc(MAX_OID_LEN, sizeof(oid)); + + if (oid_arr && args) { + + if (!PyArg_ParseTuple(args, "OiiO", &session, &nonrepeaters, + &maxrepetitions, &varlist)) { + goto done; + } + + if (varlist && (varbinds = PyObject_GetAttrString(varlist, "varbinds"))) { + + ss = (SnmpSession *)py_netsnmp_attr_void_ptr(session, "sess_ptr"); + + if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) { + goto done; + } + memcpy(&err_str, tmpstr, tmplen); + err_num = py_netsnmp_attr_long(session, "ErrorNum"); + err_ind = py_netsnmp_attr_long(session, "ErrorInd"); + + if (py_netsnmp_attr_long(session, "UseLongNames")) + getlabel_flag |= USE_LONG_NAMES; + if (py_netsnmp_attr_long(session, "UseNumeric")) + getlabel_flag |= USE_NUMERIC_OIDS; + if (py_netsnmp_attr_long(session, "UseEnums")) + sprintval_flag = USE_ENUMS; + if (py_netsnmp_attr_long(session, "UseSprintValue")) + sprintval_flag = USE_SPRINT_VALUE; + best_guess = py_netsnmp_attr_long(session, "BestGuess"); + retry_nosuch = py_netsnmp_attr_long(session, "RetryNoSuch"); + + pdu = snmp_pdu_create(SNMP_MSG_GETBULK); + + pdu->errstat = nonrepeaters; + pdu->errindex = maxrepetitions; + + varbinds_iter = PyObject_GetIter(varbinds); + + while (varbinds_iter && (varbind = PyIter_Next(varbinds_iter))) { + if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 || + py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0) + { + oid_arr_len = 0; + } else { + tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, NULL, best_guess); + } + + if (oid_arr_len) { + snmp_add_null_var(pdu, oid_arr, oid_arr_len); + } else { + if (verbose) + printf("error: get: unknown object ID (%s)", + (tag ? tag : "")); + snmp_free_pdu(pdu); + Py_DECREF(varbind); + goto done; + } + /* release reference when done */ + Py_DECREF(varbind); + } + + Py_DECREF(varbinds_iter); + + if (PyErr_Occurred()) { + /* propagate error */ + if (verbose) + printf("error: get: unknown python error"); + snmp_free_pdu(pdu); + goto done; + } + + __send_sync_pdu(ss, pdu, &response, retry_nosuch, err_str, &err_num, + &err_ind); + __py_netsnmp_update_session_errors(session, err_str, err_num, err_ind); + + /* + ** Set up for numeric or full OID's, if necessary. Save the old + ** output format so that it can be restored when we finish -- this + ** is a library-wide global, and has to be set/restored for each + ** session. + */ + old_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT); + + if (py_netsnmp_attr_long(session, "UseLongNames")) { + getlabel_flag |= USE_LONG_NAMES; + + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + NETSNMP_OID_OUTPUT_FULL); + } + /* Setting UseNumeric forces UseLongNames on so check for UseNumeric + after UseLongNames (above) to make sure the final outcome of + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT is NETSNMP_OID_OUTPUT_NUMERIC */ + if (py_netsnmp_attr_long(session, "UseNumeric")) { + getlabel_flag |= USE_LONG_NAMES; + getlabel_flag |= USE_NUMERIC_OIDS; + + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + NETSNMP_OID_OUTPUT_NUMERIC); + } + + /* create tuple in which to return results */ + val_tuple = PyTuple_New(0); + + if(response && response->variables) { + /* clear varlist to receive response varbinds*/ + PySequence_DelSlice(varbinds, 0, PySequence_Length(varbinds)); + + if (PyErr_Occurred()) { + /* propagate error */ + if (verbose) + printf("error: bulk: deleting old varbinds failed\n"); + snmp_free_pdu(pdu); + goto done; + } + + for(vars = response->variables, varbind_ind=0; + vars; + vars = vars->next_variable, varbind_ind++) { + + varbind = py_netsnmp_construct_varbind(); + + if (PyObject_HasAttrString(varbind, "tag")) { + if (str_buf == NULL) { + str_buf = (u_char *) netsnmp_malloc(STR_BUF_SIZE); + str_buf_len = STR_BUF_SIZE; + } + *str_buf = '.'; + *(str_buf+1) = '\0'; + out_len = 0; + buf_over = 0; + tp = netsnmp_sprint_realloc_objid_tree(&str_buf, &str_buf_len, + &out_len, 1, &buf_over, + vars->name,vars->name_length); + if (__is_leaf(tp)) { + type = (tp->type ? tp->type : tp->parent->type); + getlabel_flag &= ~NON_LEAF_NAME; + } else { + getlabel_flag |= NON_LEAF_NAME; + type = __translate_asn_type(vars->type); + } + + __get_label_iid((char *) str_buf, &tag, &iid, getlabel_flag); + + py_netsnmp_attr_set_string(varbind, "tag", tag, STRLEN(tag)); + py_netsnmp_attr_set_string(varbind, "iid", iid, STRLEN(iid)); + + __get_type_str(type, type_str); + + py_netsnmp_attr_set_string(varbind, "type", type_str, + strlen(type_str)); + + len = __snprint_value((char **)&str_buf, &str_buf_len, + vars, tp, type, sprintval_flag); + str_buf[len] = '\0'; + + py_netsnmp_attr_set_string(varbind, "val", (char *) str_buf, len); + + /* push varbind onto varbinds */ + PyList_Append(varbinds, varbind); + + /* save in return tuple as well - steals ref */ + _PyTuple_Resize(&val_tuple, varbind_ind+1); + PyTuple_SetItem(val_tuple, varbind_ind, + Py_BuildValue("s#", str_buf, len)); + + Py_DECREF(varbind); + + } else { + PyObject *none = Py_BuildValue(""); /* new ref */ + /* not sure why making vabind failed - should not happen*/ + PyList_Append(varbinds, none); /* increments ref */ + /* Return None for this variable. */ + PyTuple_SetItem(val_tuple, varbind_ind, none); /* steals ref */ + Py_XDECREF(varbind); + } + } + } + + /* Reset the library's behavior for numeric/symbolic OID's. */ + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + old_format); + + if (response) snmp_free_pdu(response); + + Py_DECREF(varbinds); + + } + + if (PyErr_Occurred()) { + /* propagate error */ + if (verbose) + printf("error: getbulk response processing: unknown python error"); + if (val_tuple) + Py_DECREF(val_tuple); + val_tuple = NULL; + } + } + + done: + free(oid_arr); + if (str_buf != NULL) netsnmp_free(str_buf); + return (val_tuple ? val_tuple : Py_BuildValue("")); +} + +static PyObject * +netsnmp_set(PyObject *self, PyObject *args) +{ + PyObject *ret = NULL; +#ifndef NETSNMP_NO_WRITE_SUPPORT + PyObject *session; + PyObject *varlist; + PyObject *varbind; + netsnmp_session *ss; + netsnmp_pdu *pdu, *response; + struct tree *tp; + char *tag; + char *iid; + char *val; + char *type_str; + int len; + oid *oid_arr; + int oid_arr_len = MAX_OID_LEN; + int type; + u_char tmp_val_str[STR_BUF_SIZE]; + int use_enums; + struct enum_list *ep; + int verbose = py_netsnmp_verbose(); + int best_guess; + int status; + int err_ind; + int err_num; + char err_str[STR_BUF_SIZE]; + char *tmpstr; + Py_ssize_t tmplen; + + oid_arr = calloc(MAX_OID_LEN, sizeof(oid)); + + if (oid_arr && args) { + + if (!PyArg_ParseTuple(args, "OO", &session, &varlist)) { + goto done; + } + + ss = (SnmpSession *)py_netsnmp_attr_void_ptr(session, "sess_ptr"); + + /* PyObject_SetAttrString(); */ + if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) { + goto done; + } + + use_enums = py_netsnmp_attr_long(session, "UseEnums"); + + best_guess = py_netsnmp_attr_long(session, "BestGuess"); + + pdu = snmp_pdu_create(SNMP_MSG_SET); + + if (varlist) { + PyObject *varlist_iter = PyObject_GetIter(varlist); + + while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) { + if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 || + py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0) + { + oid_arr_len = 0; + } else { + tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, &type, best_guess); + } + + if (oid_arr_len==0) { + if (verbose) + printf("error: set: unknown object ID (%s)", + (tag?tag:"")); + snmp_free_pdu(pdu); + goto done; + } + + if (type == TYPE_UNKNOWN) { + if (py_netsnmp_attr_string(varbind, "type", &type_str, NULL) < 0) { + snmp_free_pdu(pdu); + goto done; + } + type = __translate_appl_type(type_str); + if (type == TYPE_UNKNOWN) { + if (verbose) + printf("error: set: no type found for object"); + snmp_free_pdu(pdu); + goto done; + } + } + + if (py_netsnmp_attr_string(varbind, "val", &val, &tmplen) < 0) { + snmp_free_pdu(pdu); + goto done; + } + memset(tmp_val_str, 0, sizeof(tmp_val_str)); + if ( tmplen >= sizeof(tmp_val_str)) { + tmplen = sizeof(tmp_val_str)-1; + } + memcpy(tmp_val_str, val, tmplen); + if (type==TYPE_INTEGER && use_enums && tp && tp->enums) { + for(ep = tp->enums; ep; ep = ep->next) { + if (val && !strcmp(ep->label, val)) { + snprintf((char *) tmp_val_str, sizeof(tmp_val_str), "%d", + ep->value); + break; + } + } + } + len = (int)tmplen; + status = __add_var_val_str(pdu, oid_arr, oid_arr_len, + (char *) tmp_val_str, len, type); + + if (verbose && status == FAILURE) + printf("error: set: adding variable/value to PDU"); + + /* release reference when done */ + Py_DECREF(varbind); + } + + Py_DECREF(varlist_iter); + + if (PyErr_Occurred()) { + /* propagate error */ + if (verbose) + printf("error: set: unknown python error"); + snmp_free_pdu(pdu); + goto done; + } + } + + status = __send_sync_pdu(ss, pdu, &response, NO_RETRY_NOSUCH, + err_str, &err_num, &err_ind); + __py_netsnmp_update_session_errors(session, err_str, err_num, err_ind); + + if (response) snmp_free_pdu(response); + + if (status == STAT_SUCCESS) + ret = Py_BuildValue("i",1); /* success, return True */ + else + ret = Py_BuildValue("i",0); /* fail, return False */ + } + done: + Py_XDECREF(varbind); + free(oid_arr); +#endif /* NETSNMP_NO_WRITE_SUPPORT */ + return (ret ? ret : Py_BuildValue("")); +} + + +static PyMethodDef ClientMethods[] = { + {"session", netsnmp_create_session, METH_VARARGS, + "create a netsnmp session."}, + {"session_v3", netsnmp_create_session_v3, METH_VARARGS, + "create a netsnmp session."}, + {"session_tunneled", netsnmp_create_session_tunneled, METH_VARARGS, + "create a tunneled netsnmp session over tls, dtls or ssh."}, + {"delete_session", netsnmp_delete_session, METH_VARARGS, + "create a netsnmp session."}, + {"get", netsnmp_get, METH_VARARGS, + "perform an SNMP GET operation."}, + {"getnext", netsnmp_getnext, METH_VARARGS, + "perform an SNMP GETNEXT operation."}, + {"getbulk", netsnmp_getbulk, METH_VARARGS, + "perform an SNMP GETBULK operation."}, + {"set", netsnmp_set, METH_VARARGS, + "perform an SNMP SET operation."}, + {"walk", netsnmp_walk, METH_VARARGS, + "perform an SNMP WALK operation."}, + {NULL, NULL, 0, NULL} /* Sentinel */ +}; + +PyMODINIT_FUNC +initclient_intf(void) +{ + (void) Py_InitModule("client_intf", ClientMethods); +} + + + + + diff --git a/python/netsnmp/netsnmp-feature-definitions.h b/python/netsnmp/netsnmp-feature-definitions.h new file mode 100644 index 0000000..1f5a7f4 --- /dev/null +++ b/python/netsnmp/netsnmp-feature-definitions.h @@ -0,0 +1,7 @@ +#include +#include + +netsnmp_feature_require(enable_stderrlog) +netsnmp_feature_require(memory_malloc) +netsnmp_feature_require(memory_free) + diff --git a/python/netsnmp/tests/__init__.py b/python/netsnmp/tests/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/python/netsnmp/tests/__init__.py diff --git a/python/netsnmp/tests/snmpd.conf b/python/netsnmp/tests/snmpd.conf new file mode 100644 index 0000000..b62e4c7 --- /dev/null +++ b/python/netsnmp/tests/snmpd.conf @@ -0,0 +1,425 @@ +############################################################################### +# +# EXAMPLE.conf: +# An example configuration file for configuring the ucd-snmp snmpd agent. +# +############################################################################### +# +# This file is intended to only be an example. If, however, you want +# to use it, it should be placed in /usr/local/etc/snmp/snmpd.conf. +# When the snmpd agent starts up, this is where it will look for it. +# +# You might be interested in generating your own snmpd.conf file using +# the "snmpconf" program (perl script) instead. It's a nice menu +# based interface to writing well commented configuration files. Try it! +# +# Note: This file is automatically generated from EXAMPLE.conf.def. +# Do NOT read the EXAMPLE.conf.def file! Instead, after you have run +# configure & make, and then make sure you read the EXAMPLE.conf file +# instead, as it will tailor itself to your configuration. + +# All lines beginning with a '#' are comments and are intended for you +# to read. All other lines are configuration commands for the agent. + +# +# PLEASE: read the snmpd.conf(5) manual page as well! +# + + +############################################################################### +# Access Control +############################################################################### + +# YOU SHOULD CHANGE THE "COMMUNITY" TOKEN BELOW TO A NEW KEYWORD ONLY +# KNOWN AT YOUR SITE. YOU *MUST* CHANGE THE NETWORK TOKEN BELOW TO +# SOMETHING REFLECTING YOUR LOCAL NETWORK ADDRESS SPACE. + +# By far, the most common question I get about the agent is "why won't +# it work?", when really it should be "how do I configure the agent to +# allow me to access it?" +# +# By default, the agent responds to the "public" community for read +# only access, if run out of the box without any configuration file in +# place. The following examples show you other ways of configuring +# the agent so that you can change the community names, and give +# yourself write access as well. +# +# The following lines change the access permissions of the agent so +# that the COMMUNITY string provides read-only access to your entire +# NETWORK (EG: 10.10.10.0/24), and read/write access to only the +# localhost (127.0.0.1, not its real ipaddress). +# +# For more information, read the FAQ as well as the snmpd.conf(5) +# manual page. + +#### +# First, map the community name (COMMUNITY) into a security name +# (local and mynetwork, depending on where the request is coming +# from): + +# sec.name source community +com2sec local localhost public +com2sec mynetwork 192.168.1.0/24 public + +#### +# Second, map the security names into group names: + +# sec.model sec.name +group MyRWGroup v1 local +group MyRWGroup v2c local +group MyRWGroup usm local +group MyRWGroup usm initial +group MyROGroup v1 mynetwork +group MyROGroup v2c mynetwork +group MyROGroup usm mynetwork + +#### +# Third, create a view for us to let the groups have rights to: + +# incl/excl subtree mask +view all included .1 80 + +#### +# Finally, grant the 2 groups access to the 1 view with different +# write permissions: + +# context sec.model sec.level match read write notif +access MyROGroup "" any noauth exact all none none +access MyRWGroup "" any noauth exact all all none + +# ----------------------------------------------------------------------------- + +rwuser initial priv +createUser initial MD5 auth_pass DES priv_pass + +############################################################################### +# System contact information +# + +# It is also possible to set the sysContact and sysLocation system +# variables through the snmpd.conf file. **PLEASE NOTE** that setting +# the value of these objects here makes these objects READ-ONLY +# (regardless of any access control settings). Any attempt to set the +# value of an object whose value is given here will fail with an error +# status of notWritable. + +# syslocation Right here, right now. +syscontact G. S. Marzot + +# Example output of snmpwalk: +# % snmpwalk -v 1 -c public localhost system +# system.sysDescr.0 = "SunOS name sun4c" +# system.sysObjectID.0 = OID: enterprises.ucdavis.ucdSnmpAgent.sunos4 +# system.sysUpTime.0 = Timeticks: (595637548) 68 days, 22:32:55 +# system.sysContact.0 = "Me " +# system.sysName.0 = "name" +# system.sysLocation.0 = "Right here, right now." +# system.sysServices.0 = 72 + + +# ----------------------------------------------------------------------------- + + +############################################################################### +# Process checks. +# +# The following are examples of how to use the agent to check for +# processes running on the host. The syntax looks something like: +# +# proc NAME [MAX=0] [MIN=0] +# +# NAME: the name of the process to check for. It must match +# exactly (ie, http will not find httpd processes). +# MAX: the maximum number allowed to be running. Defaults to 0. +# MIN: the minimum number to be running. Defaults to 0. + +# +# Examples: +# + +# Make sure mountd is running +proc mountd + +# Make sure there are no more than 4 ntalkds running, but 0 is ok too. +proc ntalkd 4 + +# Make sure at least one sendmail, but less than or equal to 10 are running. +proc sendmail 10 1 + +# A snmpwalk of the prTable would look something like this: +# +# % snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.2021.2 +# enterprises.ucdavis.procTable.prEntry.prIndex.1 = 1 +# enterprises.ucdavis.procTable.prEntry.prIndex.2 = 2 +# enterprises.ucdavis.procTable.prEntry.prIndex.3 = 3 +# enterprises.ucdavis.procTable.prEntry.prNames.1 = "mountd" +# enterprises.ucdavis.procTable.prEntry.prNames.2 = "ntalkd" +# enterprises.ucdavis.procTable.prEntry.prNames.3 = "sendmail" +# enterprises.ucdavis.procTable.prEntry.prMin.1 = 0 +# enterprises.ucdavis.procTable.prEntry.prMin.2 = 0 +# enterprises.ucdavis.procTable.prEntry.prMin.3 = 1 +# enterprises.ucdavis.procTable.prEntry.prMax.1 = 0 +# enterprises.ucdavis.procTable.prEntry.prMax.2 = 4 +# enterprises.ucdavis.procTable.prEntry.prMax.3 = 10 +# enterprises.ucdavis.procTable.prEntry.prCount.1 = 0 +# enterprises.ucdavis.procTable.prEntry.prCount.2 = 0 +# enterprises.ucdavis.procTable.prEntry.prCount.3 = 1 +# enterprises.ucdavis.procTable.prEntry.prErrorFlag.1 = 1 +# enterprises.ucdavis.procTable.prEntry.prErrorFlag.2 = 0 +# enterprises.ucdavis.procTable.prEntry.prErrorFlag.3 = 0 +# enterprises.ucdavis.procTable.prEntry.prErrMessage.1 = "No mountd process running." +# enterprises.ucdavis.procTable.prEntry.prErrMessage.2 = "" +# enterprises.ucdavis.procTable.prEntry.prErrMessage.3 = "" +# enterprises.ucdavis.procTable.prEntry.prErrFix.1 = 0 +# enterprises.ucdavis.procTable.prEntry.prErrFix.2 = 0 +# enterprises.ucdavis.procTable.prEntry.prErrFix.3 = 0 +# +# Note that the errorFlag for mountd is set to 1 because one is not +# running (in this case an rpc.mountd is, but thats not good enough), +# and the ErrMessage tells you what's wrong. The configuration +# imposed in the snmpd.conf file is also shown. +# +# Special Case: When the min and max numbers are both 0, it assumes +# you want a max of infinity and a min of 1. +# + + +# ----------------------------------------------------------------------------- + + +############################################################################### +# Executables/scripts +# + +# +# You can also have programs run by the agent that return a single +# line of output and an exit code. Here are two examples. +# +# exec NAME PROGRAM [ARGS ...] +# +# NAME: A generic name. +# PROGRAM: The program to run. Include the path! +# ARGS: optional arguments to be passed to the program + +# a simple hello world +exec echotest /bin/echo hello world + +# Run a shell script containing: +# +# #!/bin/sh +# echo hello world +# echo hi there +# exit 35 +# +# Note: this has been specifically commented out to prevent +# accidental security holes due to someone else on your system writing +# a /tmp/shtest before you do. Uncomment to use it. +# +#exec shelltest /bin/sh /tmp/shtest + +# Then, +# % snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.2021.8 +# enterprises.ucdavis.extTable.extEntry.extIndex.1 = 1 +# enterprises.ucdavis.extTable.extEntry.extIndex.2 = 2 +# enterprises.ucdavis.extTable.extEntry.extNames.1 = "echotest" +# enterprises.ucdavis.extTable.extEntry.extNames.2 = "shelltest" +# enterprises.ucdavis.extTable.extEntry.extCommand.1 = "/bin/echo hello world" +# enterprises.ucdavis.extTable.extEntry.extCommand.2 = "/bin/sh /tmp/shtest" +# enterprises.ucdavis.extTable.extEntry.extResult.1 = 0 +# enterprises.ucdavis.extTable.extEntry.extResult.2 = 35 +# enterprises.ucdavis.extTable.extEntry.extOutput.1 = "hello world." +# enterprises.ucdavis.extTable.extEntry.extOutput.2 = "hello world." +# enterprises.ucdavis.extTable.extEntry.extErrFix.1 = 0 +# enterprises.ucdavis.extTable.extEntry.extErrFix.2 = 0 + +# Note that the second line of the /tmp/shtest shell script is cut +# off. Also note that the exit status of 35 was returned. + +# ----------------------------------------------------------------------------- + + +############################################################################### +# disk checks +# + +# The agent can check the amount of available disk space, and make +# sure it is above a set limit. + +# disk PATH [MIN=DEFDISKMINIMUMSPACE] +# +# PATH: mount path to the disk in question. +# MIN: Disks with space below this value will have the Mib's errorFlag set. +# Default value = DEFDISKMINIMUMSPACE. + +# Check the / partition and make sure it contains at least 10 megs. + +disk / 10000 + +# % snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.2021.9 +# enterprises.ucdavis.diskTable.dskEntry.diskIndex.1 = 0 +# enterprises.ucdavis.diskTable.dskEntry.diskPath.1 = "/" Hex: 2F +# enterprises.ucdavis.diskTable.dskEntry.diskDevice.1 = "/dev/dsk/c201d6s0" +# enterprises.ucdavis.diskTable.dskEntry.diskMinimum.1 = 10000 +# enterprises.ucdavis.diskTable.dskEntry.diskTotal.1 = 837130 +# enterprises.ucdavis.diskTable.dskEntry.diskAvail.1 = 316325 +# enterprises.ucdavis.diskTable.dskEntry.diskUsed.1 = 437092 +# enterprises.ucdavis.diskTable.dskEntry.diskPercent.1 = 58 +# enterprises.ucdavis.diskTable.dskEntry.diskErrorFlag.1 = 0 +# enterprises.ucdavis.diskTable.dskEntry.diskErrorMsg.1 = "" + +# ----------------------------------------------------------------------------- + + +############################################################################### +# load average checks +# + +# load [1MAX=DEFMAXLOADAVE] [5MAX=DEFMAXLOADAVE] [15MAX=DEFMAXLOADAVE] +# +# 1MAX: If the 1 minute load average is above this limit at query +# time, the errorFlag will be set. +# 5MAX: Similar, but for 5 min average. +# 15MAX: Similar, but for 15 min average. + +# Check for loads: +load 12 14 14 + +# % snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.2021.10 +# enterprises.ucdavis.loadTable.laEntry.loadaveIndex.1 = 1 +# enterprises.ucdavis.loadTable.laEntry.loadaveIndex.2 = 2 +# enterprises.ucdavis.loadTable.laEntry.loadaveIndex.3 = 3 +# enterprises.ucdavis.loadTable.laEntry.loadaveNames.1 = "Load-1" +# enterprises.ucdavis.loadTable.laEntry.loadaveNames.2 = "Load-5" +# enterprises.ucdavis.loadTable.laEntry.loadaveNames.3 = "Load-15" +# enterprises.ucdavis.loadTable.laEntry.loadaveLoad.1 = "0.49" Hex: 30 2E 34 39 +# enterprises.ucdavis.loadTable.laEntry.loadaveLoad.2 = "0.31" Hex: 30 2E 33 31 +# enterprises.ucdavis.loadTable.laEntry.loadaveLoad.3 = "0.26" Hex: 30 2E 32 36 +# enterprises.ucdavis.loadTable.laEntry.loadaveConfig.1 = "12.00" +# enterprises.ucdavis.loadTable.laEntry.loadaveConfig.2 = "14.00" +# enterprises.ucdavis.loadTable.laEntry.loadaveConfig.3 = "14.00" +# enterprises.ucdavis.loadTable.laEntry.loadaveErrorFlag.1 = 0 +# enterprises.ucdavis.loadTable.laEntry.loadaveErrorFlag.2 = 0 +# enterprises.ucdavis.loadTable.laEntry.loadaveErrorFlag.3 = 0 +# enterprises.ucdavis.loadTable.laEntry.loadaveErrMessage.1 = "" +# enterprises.ucdavis.loadTable.laEntry.loadaveErrMessage.2 = "" +# enterprises.ucdavis.loadTable.laEntry.loadaveErrMessage.3 = "" + +# ----------------------------------------------------------------------------- + + +############################################################################### +# Extensible sections. +# + +# This alleviates the multiple line output problem found in the +# previous executable mib by placing each mib in its own mib table: + +# Run a shell script containing: +# +# #!/bin/sh +# echo hello world +# echo hi there +# exit 35 +# +# Note: this has been specifically commented out to prevent +# accidental security holes due to someone else on your system writing +# a /tmp/shtest before you do. Uncomment to use it. +# +# exec .1.3.6.1.4.1.2021.50 shelltest /bin/sh /tmp/shtest + +# % snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.2021.50 +# enterprises.ucdavis.50.1.1 = 1 +# enterprises.ucdavis.50.2.1 = "shelltest" +# enterprises.ucdavis.50.3.1 = "/bin/sh /tmp/shtest" +# enterprises.ucdavis.50.100.1 = 35 +# enterprises.ucdavis.50.101.1 = "hello world." +# enterprises.ucdavis.50.101.2 = "hi there." +# enterprises.ucdavis.50.102.1 = 0 + +# Now the Output has grown to two lines, and we can see the 'hi +# there.' output as the second line from our shell script. +# +# Note that you must alter the mib.txt file to be correct if you want +# the .50.* outputs above to change to reasonable text descriptions. + +# Other ideas: +# +# exec .1.3.6.1.4.1.2021.51 ps /bin/ps +# exec .1.3.6.1.4.1.2021.52 top /usr/local/bin/top +# exec .1.3.6.1.4.1.2021.53 mailq /usr/bin/mailq + +# ----------------------------------------------------------------------------- + + +############################################################################### +# Pass through control. +# + +# Usage: +# pass MIBOID EXEC-COMMAND +# +# This will pass total control of the mib underneath the MIBOID +# portion of the mib to the EXEC-COMMAND. +# +# Note: You'll have to change the path of the passtest script to your +# source directory or install it in the given location. +# +# Example: (see the script for details) +# (commented out here since it requires that you place the +# script in the right location. (its not installed by default)) + +# pass .1.3.6.1.4.1.2021.255 /bin/sh PREFIX/local/passtest + +# % snmpwalk -v 1 -c public localhost .1.3.6.1.4.1.2021.255 +# enterprises.ucdavis.255.1 = "life the universe and everything" +# enterprises.ucdavis.255.2.1 = 42 +# enterprises.ucdavis.255.2.2 = OID: 42.42.42 +# enterprises.ucdavis.255.3 = Timeticks: (363136200) 42 days, 0:42:42 +# enterprises.ucdavis.255.4 = IpAddress: 127.0.0.1 +# enterprises.ucdavis.255.5 = 42 +# enterprises.ucdavis.255.6 = Gauge: 42 +# +# % snmpget -v 1 -c public localhost .1.3.6.1.4.1.2021.255.5 +# enterprises.ucdavis.255.5 = 42 +# +# % snmpset -v 1 -c public localhost .1.3.6.1.4.1.2021.255.1 s "New string" +# enterprises.ucdavis.255.1 = "New string" +# + +# For specific usage information, see the man/snmpd.conf.5 manual page +# as well as the local/passtest script used in the above example. + +############################################################################### +# Subagent control +# + +# The agent can support subagents using a number of extension mechanisms. +# From the 4.2.1 release, AgentX support is being compiled in by default. +# However, this is still experimental code, so should not be used on +# critical production systems. +# Please see the file README.agentx for more details. +# +# If having read, marked, learnt and inwardly digested this information, +# you decide that you do wish to make use of this mechanism, simply +# uncomment the following directive. +# +# master agentx +# +# I repeat - this is *NOT* regarded as suitable for front-line production +# systems, though it is probably stable enough for day-to-day use. +# Probably. +# +# No refunds will be given. + + +############################################################################### +# Further Information +# +# See the snmpd.conf manual page, and the output of "snmpd -H". +# MUCH more can be done with the snmpd.conf than is shown as an +# example here. + +certSecName 10 D020A78EAF99FCE276AA9F43063A69698E4F75D1 --rfc822 +rwuser -s tsm hardaker@wjh.hardakers.net + +trustCert D020A78EAF99FCE276AA9F43063A69698E4F75D1 diff --git a/python/netsnmp/tests/test.py b/python/netsnmp/tests/test.py new file mode 100644 index 0000000..c71812b --- /dev/null +++ b/python/netsnmp/tests/test.py @@ -0,0 +1,446 @@ +""" Runs all unit tests for the netsnmp package. """ +# Copyright (c) 2006 Andy Gross. See LICENSE.txt for details. + +import os +import unittest +import netsnmp + +def snmp_dest(**kwargs): + """Return information about how to communicate with snmpd""" + dest = { + 'Version': 1, + 'DestHost': 'localhost:' + os.environ.get("SNMP_SNMPD_PORT", 161), + 'Community': 'public', + } + for key, value in kwargs.iteritems(): + dest[key] = value + return dest + +def setup_v1(): + return netsnmp.Session(**snmp_dest()) + +def setup_v2(): + sess = netsnmp.Session(**snmp_dest(Version=2)) + sess.UseEnums = 1 + sess.UseLongNames = 1 + return sess + +def setup_v3(): + sess = netsnmp.Session(**snmp_dest(Version=3, + SecLevel='authPriv', + SecName='initial', + PrivPass='priv_pass', + AuthPass='auth_pass')) + sess.UseSprintValue = 1 + return sess + +class BasicTests(unittest.TestCase): + """Basic unit tests for the Net-SNMP Python interface""" + def test_varbind_creation(self): + var = netsnmp.Varbind('sysDescr.0') + self.assertEqual(var.tag, 'sysDescr') + self.assertEqual(var.iid, '0') + + var = netsnmp.Varbind('sysDescr', '0') + self.assertEqual(var.tag, 'sysDescr') + self.assertEqual(var.iid, '0') + + var = netsnmp.Varbind( + '.iso.org.dod.internet.mgmt.mib-2.system.sysDescr', '0') + self.assertEqual(var.tag, + '.iso.org.dod.internet.mgmt.mib-2.system.sysDescr') + self.assertEqual(var.iid, '0') + + var = netsnmp.Varbind( + '.iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0') + self.assertEqual(var.tag, + '.iso.org.dod.internet.mgmt.mib-2.system.sysDescr.0') + self.assertEqual(var.iid, None) + + var = netsnmp.Varbind('.1.3.6.1.2.1.1.1.0') + self.assertEqual(var.tag, '.1.3.6.1.2.1.1.1.0') + self.assertEqual(var.iid, '') + + def test_v1_get(self): + print "\n" + print "---v1 GET tests -------------------------------------\n" + var = netsnmp.Varbind('.1.3.6.1.2.1.1.1', '0') + res = netsnmp.snmpget(var, **snmp_dest()) + + print "v1 snmpget result: ", res, "\n" + self.assertEqual(len(res), 1) + + print "v1 get var: ", var.tag, var.iid, "=", var.val, '(', var.type, ')' + self.assertEqual(var.tag, 'sysDescr') + self.assertEqual(var.iid, '0') + self.assertEqual(var.val, res[0]) + self.assertEqual(var.type, 'OCTETSTR') + + def test_v1_getnext(self): + print "\n" + print "---v1 GETNEXT tests-------------------------------------\n" + var = netsnmp.Varbind('.1.3.6.1.2.1.1.1', '0') + res = netsnmp.snmpgetnext(var, **snmp_dest()) + + print "v1 snmpgetnext result: ", res, "\n" + self.assertEqual(len(res), 1) + + print "v1 getnext var: ", var.tag, var.iid, "=", var.val, '(', var.type, ')' + self.assertTrue(var.tag is not None) + self.assertTrue(var.iid is not None) + self.assertTrue(var.val is not None) + self.assertTrue(var.type is not None) + + def test_v1_set(self): + print "\n" + print "---v1 SET tests-------------------------------------\n" + var = netsnmp.Varbind('sysLocation', '0', 'my new location') + res = netsnmp.snmpset(var, **snmp_dest()) + + print "v1 snmpset result: ", res, "\n" + self.assertEqual(res, 1) + + print "v1 set var: ", var.tag, var.iid, "=", var.val, '(', var.type, ')' + self.assertEqual(var.tag, 'sysLocation') + self.assertEqual(var.iid, '0') + self.assertEqual(var.val, 'my new location') + self.assertTrue(var.type is None) + + def test_v1_walk(self): + print "\n" + print "---v1 walk tests-------------------------------------\n" + varlist = netsnmp.VarList(netsnmp.Varbind('system')) + + print "v1 varlist walk in: " + for var in varlist: + print " ", var.tag, var.iid, "=", var.val, '(', var.type, ')' + + res = netsnmp.snmpwalk(varlist, **snmp_dest()) + print "v1 snmpwalk result: ", res, "\n" + self.assertTrue(len(res) > 0) + + for var in varlist: + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + + def test_v1_walk_2(self): + print "\n" + print "---v1 walk 2-------------------------------------\n" + + print "v1 varbind walk in: " + var = netsnmp.Varbind('system') + self.assertEqual(var.tag, 'system') + self.assertEqual(var.iid, '') + self.assertEqual(var.val, None) + self.assertEqual(var.type, None) + res = netsnmp.snmpwalk(var, **snmp_dest()) + print "v1 snmpwalk result (should be = orig): ", res, "\n" + self.assertTrue(len(res) > 0) + + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + self.assertEqual(var.tag, 'system') + self.assertEqual(var.iid, '') + self.assertEqual(var.val, None) + self.assertEqual(var.type, None) + + def test_v1_mv_get(self): + print "\n" + print "---v1 multi-varbind test-------------------------------------\n" + sess = setup_v1() + + varlist = netsnmp.VarList(netsnmp.Varbind('sysUpTime', 0), + netsnmp.Varbind('sysContact', 0), + netsnmp.Varbind('sysLocation', 0)) + vals = sess.get(varlist) + print "v1 sess.get result: ", vals, "\n" + self.assertTrue(len(vals) > 0) + + for var in varlist: + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + + vals = sess.getnext(varlist) + print "v1 sess.getnext result: ", vals, "\n" + self.assertTrue(len(vals) > 0) + + for var in varlist: + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + + varlist = netsnmp.VarList(netsnmp.Varbind('sysUpTime'), + netsnmp.Varbind('sysORLastChange'), + netsnmp.Varbind('sysORID'), + netsnmp.Varbind('sysORDescr'), + netsnmp.Varbind('sysORUpTime')) + + vals = sess.getbulk(2, 8, varlist) + print "v1 sess.getbulk result: ", vals, "\n" + self.assertEqual(vals, None) # GetBulk is not supported for v1 + + for var in varlist: + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + + def test_v1_set_2(self): + print "\n" + print "---v1 set2-------------------------------------\n" + + sess = setup_v1() + varlist = netsnmp.VarList( + netsnmp.Varbind('sysLocation', '0', 'my newer location')) + res = sess.set(varlist) + print "v1 sess.set result: ", res, "\n" + + def test_v1_walk_3(self): + print "\n" + print "---v1 walk3-------------------------------------\n" + + sess = setup_v1() + varlist = netsnmp.VarList(netsnmp.Varbind('system')) + + vals = sess.walk(varlist) + print "v1 sess.walk result: ", vals, "\n" + self.assertTrue(len(vals) > 0) + + for var in varlist: + print " ", var.tag, var.iid, "=", var.val, '(', var.type, ')' + + def test_v2c_get(self): + print "\n" + print "---v2c get-------------------------------------\n" + + sess = setup_v2() + varlist = netsnmp.VarList(netsnmp.Varbind('sysUpTime', 0), + netsnmp.Varbind('sysContact', 0), + netsnmp.Varbind('sysLocation', 0)) + vals = sess.get(varlist) + print "v2 sess.get result: ", vals, "\n" + self.assertEqual(len(vals), 3) + + def test_v2c_getnext(self): + print "\n" + print "---v2c getnext-------------------------------------\n" + + sess = setup_v2() + varlist = netsnmp.VarList(netsnmp.Varbind('sysUpTime', 0), + netsnmp.Varbind('sysContact', 0), + netsnmp.Varbind('sysLocation', 0)) + for var in varlist: + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + print "\n" + + vals = sess.getnext(varlist) + print "v2 sess.getnext result: ", vals, "\n" + self.assertTrue(len(vals) > 0) + + for var in varlist: + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + print "\n" + + def test_v2c_getbulk(self): + print "\n" + print "---v2c getbulk-------------------------------------\n" + + sess = setup_v2() + varlist = netsnmp.VarList(netsnmp.Varbind('sysUpTime'), + netsnmp.Varbind('sysORLastChange'), + netsnmp.Varbind('sysORID'), + netsnmp.Varbind('sysORDescr'), + netsnmp.Varbind('sysORUpTime')) + + vals = sess.getbulk(2, 8, varlist) + print "v2 sess.getbulk result: ", vals, "\n" + self.assertTrue(len(vals) > 0) + + for var in varlist: + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + print "\n" + + def test_v2c_set(self): + print "\n" + print "---v2c set-------------------------------------\n" + + sess = setup_v2() + + varlist = netsnmp.VarList( + netsnmp.Varbind('sysLocation', '0', 'my even newer location')) + + res = sess.set(varlist) + print "v2 sess.set result: ", res, "\n" + self.assertEqual(res, 1) + + def test_v2c_walk(self): + print "\n" + print "---v2c walk-------------------------------------\n" + + sess = setup_v2() + + varlist = netsnmp.VarList(netsnmp.Varbind('system')) + + vals = sess.walk(varlist) + print "v2 sess.walk result: ", vals, "\n" + self.assertTrue(len(vals) > 0) + + for var in varlist: + print " ", var.tag, var.iid, "=", var.val, '(', var.type, ')' + + def test_v3_get(self): + print "\n" + sess = setup_v3(); + varlist = netsnmp.VarList(netsnmp.Varbind('sysUpTime', 0), + netsnmp.Varbind('sysContact', 0), + netsnmp.Varbind('sysLocation', 0)) + print "---v3 get-------------------------------------\n" + vals = sess.get(varlist) + print "v3 sess.get result: ", vals, "\n" + self.assertTrue(len(vals) > 0) + + for var in varlist: + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + print "\n" + + def test_v3_getnext(self): + print "\n" + print "---v3 getnext-------------------------------------\n" + + sess = setup_v3(); + varlist = netsnmp.VarList(netsnmp.Varbind('sysUpTime', 0), + netsnmp.Varbind('sysContact', 0), + netsnmp.Varbind('sysLocation', 0)) + vals = sess.getnext(varlist) + print "v3 sess.getnext result: ", vals, "\n" + self.assertTrue(len(vals) > 0) + + for var in varlist: + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + print "\n" + + def test_v3_getbulk(self): + sess = setup_v3(); + varlist = netsnmp.VarList(netsnmp.Varbind('sysUpTime'), + netsnmp.Varbind('sysORLastChange'), + netsnmp.Varbind('sysORID'), + netsnmp.Varbind('sysORDescr'), + netsnmp.Varbind('sysORUpTime')) + + vals = sess.getbulk(2, 8, varlist) + print "v3 sess.getbulk result: ", vals, "\n" + self.assertTrue(len(vals) > 0) + + for var in varlist: + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + print "\n" + + def test_v3_set(self): + print "\n" + print "---v3 set-------------------------------------\n" + + sess = setup_v3(); + varlist = netsnmp.VarList( + netsnmp.Varbind('sysLocation', '0', 'my final destination')) + res = sess.set(varlist) + print "v3 sess.set result: ", res, "\n" + self.assertEqual(res, 1) + + def test_v3_walk(self): + print "\n" + print "---v3 walk-------------------------------------\n" + sess = setup_v3(); + varlist = netsnmp.VarList(netsnmp.Varbind('system')) + + vals = sess.walk(varlist) + print "v3 sess.walk result: ", vals, "\n" + self.assertTrue(len(vals) > 0) + + for var in varlist: + print " ", var.tag, var.iid, "=", var.val, '(', var.type, ')' + + +class SetTests(unittest.TestCase): + """SNMP set tests for the Net-SNMP Python interface""" + def testFuncs(self): + """Test code""" + print "\n-------------- SET Test Start ----------------------------\n" + + var = netsnmp.Varbind('sysUpTime', '0') + res = netsnmp.snmpget(var, **snmp_dest()) + print "uptime = ", res[0] + self.assertEqual(len(res), 1) + + + var = netsnmp.Varbind('versionRestartAgent', '0', 1) + res = netsnmp.snmpset(var, **snmp_dest()) + self.assertEqual(res, 1) + + var = netsnmp.Varbind('sysUpTime', '0') + res = netsnmp.snmpget(var, **snmp_dest()) + print "uptime = ", res[0] + self.assertEqual(len(res), 1) + + var = netsnmp.Varbind('nsCacheEntry') + res = netsnmp.snmpgetnext(var, **snmp_dest()) + print "var = ", var.tag, var.iid, "=", var.val, '(', var.type, ')' + self.assertEqual(len(res), 1) + + var.val = 65 + res = netsnmp.snmpset(var, **snmp_dest()) + self.assertEqual(res, 1) + res = netsnmp.snmpget(var, **snmp_dest()) + print "var = ", var.tag, var.iid, "=", var.val, '(', var.type, ')' + self.assertEqual(len(res), 1) + self.assertEqual(res[0], '65'); + + sess = setup_v1() + + varlist = netsnmp.VarList( + netsnmp.Varbind('.1.3.6.1.6.3.12.1.2.1.2.116.101.115.116', '', '.1.3.6.1.6.1.1'), + netsnmp.Varbind('.1.3.6.1.6.3.12.1.2.1.3.116.101.115.116', '', '1234'), + netsnmp.Varbind('.1.3.6.1.6.3.12.1.2.1.9.116.101.115.116', '', 4)) + res = sess.set(varlist) + + print "res = ", res + self.assertEqual(res, 1) + + varlist = netsnmp.VarList(netsnmp.Varbind('snmpTargetAddrTDomain'), + netsnmp.Varbind('snmpTargetAddrTAddress'), + netsnmp.Varbind('snmpTargetAddrRowStatus')) + + res = sess.getnext(varlist) + self.assertEqual(len(res), 3) + self.assertEqual(varlist[0].tag, 'snmpTargetAddrTDomain') + self.assertEqual(varlist[0].iid, '116.101.115.116') + self.assertEqual(varlist[0].val, '.1.3.6.1.6.1.1') + self.assertEqual(varlist[1].tag, 'snmpTargetAddrTAddress') + self.assertEqual(varlist[1].iid, '116.101.115.116') + self.assertEqual(varlist[1].val, '1234') + self.assertEqual(varlist[2].tag, 'snmpTargetAddrRowStatus') + self.assertEqual(varlist[2].iid, '116.101.115.116') + self.assertEqual(varlist[2].val, '3') + + for var in varlist: + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + print "\n" + + varlist = netsnmp.VarList( + netsnmp.Varbind('.1.3.6.1.6.3.12.1.2.1.9.116.101.115.116', '', 6)) + + res = sess.set(varlist) + + print "res = ", res + self.assertEqual(res, 1) + + varlist = netsnmp.VarList(netsnmp.Varbind('snmpTargetAddrTDomain'), + netsnmp.Varbind('snmpTargetAddrTAddress'), + netsnmp.Varbind('snmpTargetAddrRowStatus')) + + res = sess.getnext(varlist) + self.assertEqual(len(res), 3) + self.assertNotEqual(varlist[0].tag, 'snmpTargetAddrTDomain') + self.assertNotEqual(varlist[1].tag, 'snmpTargetAddrTAddress') + self.assertNotEqual(varlist[2].tag, 'snmpTargetAddrRowStatus') + + for var in varlist: + print var.tag, var.iid, "=", var.val, '(', var.type, ')' + print "\n" + + print "\n-------------- SET Test End ----------------------------\n" + + +if __name__ == '__main__': + unittest.main() diff --git a/python/setup.py b/python/setup.py new file mode 100644 index 0000000..a62aabf --- /dev/null +++ b/python/setup.py @@ -0,0 +1,46 @@ +from distutils.core import setup, Extension +from setuptools import setup, Extension, find_packages +import os +import re +import string +import sys + +intree=0 + +args = sys.argv[:] +for arg in args: + if string.find(arg,'--basedir=') == 0: + basedir = string.split(arg,'=')[1] + sys.argv.remove(arg) + intree=1 + +if intree: + netsnmp_libs = os.popen(basedir+'/net-snmp-config --libs').read() + libdir = os.popen(basedir+'/net-snmp-config --build-lib-dirs '+basedir).read() + incdir = os.popen(basedir+'/net-snmp-config --build-includes '+basedir).read() + " " + os.popen(basedir+'/net-snmp-config --base-cflags '+basedir).read() + libs = re.findall(r"-l(\S+)", netsnmp_libs) + libdirs = re.findall(r"-L(\S+)", libdir) + incdirs = re.findall(r"-I(\S+)", incdir) +else: + netsnmp_libs = os.popen('net-snmp-config --libs').read() + libdirs = re.findall(r"-L(\S+)", netsnmp_libs) + incdirs = [] + libs = re.findall(r"-l(\S+)", netsnmp_libs) + +setup( + name="netsnmp-python", version="1.0a1", + description = 'The Net-SNMP Python Interface', + author = 'G. S. Marzot', + author_email = 'giovanni.marzot@sparta.com', + url = 'http://www.net-snmp.org', + license="BSD", + packages=find_packages(), + test_suite = "netsnmp.tests.test", + + ext_modules = [ + Extension("netsnmp.client_intf", ["netsnmp/client_intf.c"], + library_dirs=libdirs, + include_dirs=incdirs, + libraries=libs ) + ] + ) diff --git a/snmplib/read_config.c b/snmplib/read_config.c index a1ddb6c..b8bae0e 100644 --- a/snmplib/read_config.c +++ b/snmplib/read_config.c @@ -1642,7 +1642,7 @@ snmp_save_persistent(const char *type) * save a warning header to the top of the new file */ snprintf(fileold, sizeof(fileold), - "%s%s# Please save normal configuration tokens for %s in /etc/snmp/%s.conf.\n# Only \"createUser\" tokens should be placed here by %s administrators.\n%s", + "%s%s# Please save normal configuration tokens for %s in SNMPCONFPATH/%s.conf.\n# Only \"createUser\" tokens should be placed here by %s administrators.\n%s", "#\n# net-snmp (or ucd-snmp) persistent data file.\n#\n############################################################################\n# STOP STOP STOP STOP STOP STOP STOP STOP STOP \n", "#\n# **** DO NOT EDIT THIS FILE ****\n#\n# STOP STOP STOP STOP STOP STOP STOP STOP STOP \n############################################################################\n#\n# DO NOT STORE CONFIGURATION ENTRIES HERE.\n", type, type, type, diff --git a/snmplib/snmp_api.c b/snmplib/snmp_api.c index fa730fd..554767a 100644 --- a/snmplib/snmp_api.c +++ b/snmplib/snmp_api.c @@ -352,7 +352,6 @@ static int snmpv3_build(u_char ** pkt, size_t * pkt_len, netsnmp_pdu *pdu); static int snmp_parse_version(u_char *, size_t); static int snmp_resend_request(struct session_list *slp, - netsnmp_request_list *orp, netsnmp_request_list *rp, int incr_retries); static void register_default_handlers(void); @@ -4012,12 +4011,7 @@ snmpv3_parse(netsnmp_pdu *pdu, static void free_securityStateRef(netsnmp_pdu* pdu) { - struct snmp_secmod_def *sptr; - - if(!pdu->securityStateRef) - return; - - sptr = find_sec_mod(pdu->securityModel); + struct snmp_secmod_def *sptr = find_sec_mod(pdu->securityModel); if (sptr) { if (sptr->pdu_free_state_ref) { (*sptr->pdu_free_state_ref) (pdu->securityStateRef); @@ -5462,8 +5456,6 @@ snmp_free_pdu(netsnmp_pdu *pdu) if (!pdu) return; - free_securityStateRef(pdu); - /* * If the command field is empty, that probably indicates * that this PDU structure has already been freed. @@ -5638,6 +5630,12 @@ _sess_process_packet_parse_pdu(void *sessp, netsnmp_session * sp, } if (ret != SNMP_ERR_NOERROR) { + /* + * Call the security model to free any securityStateRef supplied w/ msg. + */ + if (pdu->securityStateRef != NULL) { + free_securityStateRef(pdu); + } snmp_free_pdu(pdu); return NULL; } @@ -5719,7 +5717,7 @@ _sess_process_packet_handle_pdu(void *sessp, netsnmp_session * sp, * * inifinite resend */ if (rp->retries <= sp->retries) { - snmp_resend_request(slp, orp, rp, TRUE); + snmp_resend_request(slp, rp, TRUE); break; } else { /* We're done with retries, so no longer waiting for a response */ @@ -5811,6 +5809,12 @@ _sess_process_packet_handle_pdu(void *sessp, netsnmp_session * sp, } } + /* + * Call USM to free any securityStateRef supplied with the message. + */ + if (pdu->securityStateRef && pdu->command == SNMP_MSG_TRAP2) + free_securityStateRef(pdu); + if (!handled) { if (sp->flags & SNMP_FLAGS_SHARED_SOCKET) return -2; @@ -6658,22 +6662,9 @@ snmp_timeout(void) snmp_res_unlock(MT_LIBRARY_ID, MT_LIB_SESSION); } -static void -remove_request(struct snmp_internal_session *isp, - netsnmp_request_list *orp, netsnmp_request_list *rp) -{ - if (orp) - orp->next_request = rp->next_request; - else - isp->requests = rp->next_request; - if (isp->requestsEnd == rp) - isp->requestsEnd = orp; - snmp_free_pdu(rp->pdu); -} - static int -snmp_resend_request(struct session_list *slp, netsnmp_request_list *orp, - netsnmp_request_list *rp, int incr_retries) +snmp_resend_request(struct session_list *slp, netsnmp_request_list *rp, + int incr_retries) { struct snmp_internal_session *isp; netsnmp_session *sp; @@ -6740,11 +6731,9 @@ snmp_resend_request(struct session_list *slp, netsnmp_request_list *orp, sp->s_snmp_errno = SNMPERR_BAD_SENDTO; sp->s_errno = errno; snmp_set_detail(strerror(errno)); - if (rp->callback) { + if (rp->callback) rp->callback(NETSNMP_CALLBACK_OP_SEND_FAILED, sp, rp->pdu->reqid, rp->pdu, rp->cb_data); - remove_request(isp, orp, rp); - } return -1; } else { netsnmp_get_monotonic_clock(&now); @@ -6824,12 +6813,19 @@ snmp_sess_timeout(void *sessp) callback(NETSNMP_CALLBACK_OP_TIMED_OUT, sp, rp->pdu->reqid, rp->pdu, magic); } - remove_request(isp, orp, rp); + if (orp) + orp->next_request = rp->next_request; + else + isp->requests = rp->next_request; + if (isp->requestsEnd == rp) + isp->requestsEnd = orp; + snmp_free_pdu(rp->pdu); freeme = rp; continue; /* don't update orp below */ } else { - if (snmp_resend_request(slp, orp, rp, TRUE)) + if (snmp_resend_request(slp, rp, TRUE)) { break; + } } } orp = rp; diff --git a/snmplib/snmp_client.c b/snmplib/snmp_client.c index b2ea891..2a46351 100644 --- a/snmplib/snmp_client.c +++ b/snmplib/snmp_client.c @@ -402,16 +402,27 @@ _clone_pdu_header(netsnmp_pdu *pdu) return NULL; } - sptr = find_sec_mod(newpdu->securityModel); - if (sptr && sptr->pdu_clone) { - /* call security model if it needs to know about this */ - ret = sptr->pdu_clone(pdu, newpdu); - if (ret) { + if (pdu->securityStateRef && + pdu->command == SNMP_MSG_TRAP2) { + + ret = usm_clone_usmStateReference((struct usmStateReference *) pdu->securityStateRef, + (struct usmStateReference **) &newpdu->securityStateRef ); + + if (ret) + { snmp_free_pdu(newpdu); return NULL; } } + if ((sptr = find_sec_mod(newpdu->securityModel)) != NULL && + sptr->pdu_clone != NULL) { + /* + * call security model if it needs to know about this + */ + (*sptr->pdu_clone) (pdu, newpdu); + } + return newpdu; } diff --git a/snmplib/snmpusm.c b/snmplib/snmpusm.c index 210eaa0..3cfa126 100644 --- a/snmplib/snmpusm.c +++ b/snmplib/snmpusm.c @@ -285,64 +285,39 @@ free_enginetime_on_shutdown(int majorid, int minorid, void *serverarg, struct usmStateReference * usm_malloc_usmStateReference(void) { - struct usmStateReference *retval; - - retval = calloc(1, sizeof(struct usmStateReference)); - if (retval) - retval->refcnt = 1; + struct usmStateReference *retval = (struct usmStateReference *) + calloc(1, sizeof(struct usmStateReference)); return retval; } /* end usm_malloc_usmStateReference() */ -static int -usm_clone(netsnmp_pdu *pdu, netsnmp_pdu *new_pdu) -{ - struct usmStateReference *ref = pdu->securityStateRef; - struct usmStateReference **new_ref = - (struct usmStateReference **)&new_pdu->securityStateRef; - int ret = 0; - - if (!ref) - return ret; - - if (pdu->command == SNMP_MSG_TRAP2) { - netsnmp_assert(pdu->securityModel == SNMP_DEFAULT_SECMODEL); - ret = usm_clone_usmStateReference(ref, new_ref); - } else { - netsnmp_assert(ref == *new_ref); - ref->refcnt++; - } - - return ret; -} - void usm_free_usmStateReference(void *old) { - struct usmStateReference *ref = old; + struct usmStateReference *old_ref = (struct usmStateReference *) old; - if (!ref) - return; + if (old_ref) { - if (--ref->refcnt > 0) - return; + SNMP_FREE(old_ref->usr_name); + SNMP_FREE(old_ref->usr_engine_id); + SNMP_FREE(old_ref->usr_auth_protocol); + SNMP_FREE(old_ref->usr_priv_protocol); - SNMP_FREE(ref->usr_name); - SNMP_FREE(ref->usr_engine_id); - SNMP_FREE(ref->usr_auth_protocol); - SNMP_FREE(ref->usr_priv_protocol); + if (old_ref->usr_auth_key) { + SNMP_ZERO(old_ref->usr_auth_key, old_ref->usr_auth_key_length); + SNMP_FREE(old_ref->usr_auth_key); + } + if (old_ref->usr_priv_key) { + SNMP_ZERO(old_ref->usr_priv_key, old_ref->usr_priv_key_length); + SNMP_FREE(old_ref->usr_priv_key); + } + + SNMP_ZERO(old_ref, sizeof(*old_ref)); + SNMP_FREE(old_ref); - if (ref->usr_auth_key_length && ref->usr_auth_key) { - SNMP_ZERO(ref->usr_auth_key, ref->usr_auth_key_length); - SNMP_FREE(ref->usr_auth_key); - } - if (ref->usr_priv_key_length && ref->usr_priv_key) { - SNMP_ZERO(ref->usr_priv_key, ref->usr_priv_key_length); - SNMP_FREE(ref->usr_priv_key); } - SNMP_FREE(ref); } /* end usm_free_usmStateReference() */ struct usmUser * @@ -1064,6 +1039,7 @@ usm_generate_out_msg(int msgProcModel, /* (UNUSED) */ if ((user = usm_get_user(secEngineID, secEngineIDLen, secName)) == NULL && secLevel != SNMP_SEC_LEVEL_NOAUTH) { DEBUGMSGTL(("usm", "Unknown User(%s)\n", secName)); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_UNKNOWNSECURITYNAME; } @@ -1115,6 +1091,7 @@ usm_generate_out_msg(int msgProcModel, /* (UNUSED) */ thePrivProtocolLength) == 1) { DEBUGMSGTL(("usm", "Unsupported Security Level (%d)\n", theSecLevel)); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_UNSUPPORTEDSECURITYLEVEL; } @@ -1144,6 +1121,7 @@ usm_generate_out_msg(int msgProcModel, /* (UNUSED) */ &msgAuthParmLen, &msgPrivParmLen, &otstlen, &seq_len, &msgSecParmLen) == -1) { DEBUGMSGTL(("usm", "Failed calculating offsets.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_GENERICERROR; } @@ -1165,6 +1143,7 @@ usm_generate_out_msg(int msgProcModel, /* (UNUSED) */ ptr = *wholeMsg = globalData; if (theTotalLength > *wholeMsgLen) { DEBUGMSGTL(("usm", "Message won't fit in buffer.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_GENERICERROR; } @@ -1190,6 +1169,7 @@ usm_generate_out_msg(int msgProcModel, /* (UNUSED) */ htonl(boots_uint), htonl(time_uint), &ptr[privParamsOffset]) == -1) { DEBUGMSGTL(("usm", "Can't set AES iv.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_GENERICERROR; } } @@ -1205,6 +1185,7 @@ usm_generate_out_msg(int msgProcModel, /* (UNUSED) */ &ptr[privParamsOffset]) == -1)) { DEBUGMSGTL(("usm", "Can't set DES-CBC salt.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_GENERICERROR; } } @@ -1217,6 +1198,7 @@ usm_generate_out_msg(int msgProcModel, /* (UNUSED) */ &ptr[dataOffset], &encrypted_length) != SNMP_ERR_NOERROR) { DEBUGMSGTL(("usm", "encryption error.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_ENCRYPTIONERROR; } #ifdef NETSNMP_ENABLE_TESTING_CODE @@ -1244,6 +1226,7 @@ usm_generate_out_msg(int msgProcModel, /* (UNUSED) */ if ((encrypted_length != (theTotalLength - dataOffset)) || (salt_length != msgPrivParmLen)) { DEBUGMSGTL(("usm", "encryption length error.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_ENCRYPTIONERROR; } @@ -1379,6 +1362,7 @@ usm_generate_out_msg(int msgProcModel, /* (UNUSED) */ if (temp_sig == NULL) { DEBUGMSGTL(("usm", "Out of memory.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_GENERICERROR; } @@ -1392,6 +1376,7 @@ usm_generate_out_msg(int msgProcModel, /* (UNUSED) */ SNMP_ZERO(temp_sig, temp_sig_len); SNMP_FREE(temp_sig); DEBUGMSGTL(("usm", "Signing failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_AUTHENTICATIONFAILURE; } @@ -1399,6 +1384,7 @@ usm_generate_out_msg(int msgProcModel, /* (UNUSED) */ SNMP_ZERO(temp_sig, temp_sig_len); SNMP_FREE(temp_sig); DEBUGMSGTL(("usm", "Signing lengths failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_AUTHENTICATIONFAILURE; } @@ -1412,6 +1398,7 @@ usm_generate_out_msg(int msgProcModel, /* (UNUSED) */ /* * endif -- create keyed hash */ + usm_free_usmStateReference(secStateRef); DEBUGMSGTL(("usm", "USM processing completed.\n")); @@ -1561,6 +1548,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ if ((user = usm_get_user(secEngineID, secEngineIDLen, secName)) == NULL && secLevel != SNMP_SEC_LEVEL_NOAUTH) { DEBUGMSGTL(("usm", "Unknown User\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_UNKNOWNSECURITYNAME; } @@ -1613,6 +1601,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ DEBUGMSGTL(("usm", "Unsupported Security Level or type (%d)\n", theSecLevel)); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_UNSUPPORTEDSECURITYLEVEL; } @@ -1647,6 +1636,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ DEBUGMSGTL(("usm", "couldn't malloc %d bytes for encrypted PDU\n", (int)ciphertextlen)); + usm_free_usmStateReference(secStateRef); return SNMPERR_MALLOC; } @@ -1662,6 +1652,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ htonl(boots_uint), htonl(time_uint), iv) == -1) { DEBUGMSGTL(("usm", "Can't set AES iv.\n")); + usm_free_usmStateReference(secStateRef); SNMP_FREE(ciphertext); return SNMPERR_USM_GENERICERROR; } @@ -1676,6 +1667,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ thePrivKeyLength - 8, iv) == -1)) { DEBUGMSGTL(("usm", "Can't set DES-CBC salt.\n")); + usm_free_usmStateReference(secStateRef); SNMP_FREE(ciphertext); return SNMPERR_USM_GENERICERROR; } @@ -1694,6 +1686,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ scopedPdu, scopedPduLen, ciphertext, &ciphertextlen) != SNMP_ERR_NOERROR) { DEBUGMSGTL(("usm", "encryption error.\n")); + usm_free_usmStateReference(secStateRef); SNMP_FREE(ciphertext); return SNMPERR_USM_ENCRYPTIONERROR; } @@ -1710,6 +1703,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ ciphertext, ciphertextlen); if (rc == 0) { DEBUGMSGTL(("usm", "Encryption failed.\n")); + usm_free_usmStateReference(secStateRef); SNMP_FREE(ciphertext); return SNMPERR_USM_ENCRYPTIONERROR; } @@ -1749,6 +1743,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ DEBUGINDENTLESS(); if (rc == 0) { DEBUGMSGTL(("usm", "building privParams failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_TOO_LONG; } @@ -1771,6 +1766,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ DEBUGINDENTLESS(); if (rc == 0) { DEBUGMSGTL(("usm", "building authParams failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_TOO_LONG; } @@ -1793,6 +1789,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ DEBUGINDENTLESS(); if (rc == 0) { DEBUGMSGTL(("usm", "building authParams failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_TOO_LONG; } @@ -1808,6 +1805,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ if (rc == 0) { DEBUGMSGTL(("usm", "building msgAuthoritativeEngineTime failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_TOO_LONG; } @@ -1823,6 +1821,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ if (rc == 0) { DEBUGMSGTL(("usm", "building msgAuthoritativeEngineBoots failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_TOO_LONG; } @@ -1834,6 +1833,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ DEBUGINDENTLESS(); if (rc == 0) { DEBUGMSGTL(("usm", "building msgAuthoritativeEngineID failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_TOO_LONG; } @@ -1846,6 +1846,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ *offset - sp_offset); if (rc == 0) { DEBUGMSGTL(("usm", "building usm security parameters failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_TOO_LONG; } @@ -1859,6 +1860,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ if (rc == 0) { DEBUGMSGTL(("usm", "building msgSecurityParameters failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_TOO_LONG; } @@ -1868,6 +1870,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ while ((*wholeMsgLen - *offset) < globalDataLen) { if (!asn_realloc(wholeMsg, wholeMsgLen)) { DEBUGMSGTL(("usm", "building global data failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_TOO_LONG; } } @@ -1883,6 +1886,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ ASN_CONSTRUCTOR), *offset); if (rc == 0) { DEBUGMSGTL(("usm", "building master packet sequence failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_TOO_LONG; } @@ -1900,6 +1904,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ if (temp_sig == NULL) { DEBUGMSGTL(("usm", "Out of memory.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_GENERICERROR; } @@ -1910,12 +1915,14 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ != SNMP_ERR_NOERROR) { SNMP_FREE(temp_sig); DEBUGMSGTL(("usm", "Signing failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_AUTHENTICATIONFAILURE; } if (temp_sig_len != msgAuthParmLen) { SNMP_FREE(temp_sig); DEBUGMSGTL(("usm", "Signing lengths failed.\n")); + usm_free_usmStateReference(secStateRef); return SNMPERR_USM_AUTHENTICATIONFAILURE; } @@ -1926,6 +1933,7 @@ usm_rgenerate_out_msg(int msgProcModel, /* (UNUSED) */ /* * endif -- create keyed hash */ + usm_free_usmStateReference(secStateRef); DEBUGMSGTL(("usm", "USM processing completed.\n")); return SNMPERR_SUCCESS; } /* end usm_rgenerate_out_msg() */ @@ -3337,7 +3345,6 @@ init_usm(void) def->encode_reverse = usm_secmod_rgenerate_out_msg; def->encode_forward = usm_secmod_generate_out_msg; def->decode = usm_secmod_process_in_msg; - def->pdu_clone = usm_clone; def->pdu_free_state_ref = usm_free_usmStateReference; def->session_setup = usm_session_init; def->handle_report = usm_handle_report; diff --git a/snmplib/transports/snmpUDPIPv4BaseDomain.c b/snmplib/transports/snmpUDPIPv4BaseDomain.c index f364fb3..433eb80 100644 --- a/snmplib/transports/snmpUDPIPv4BaseDomain.c +++ b/snmplib/transports/snmpUDPIPv4BaseDomain.c @@ -317,7 +317,7 @@ netsnmp_udpipv4base_tspec_transport(netsnmp_tdomain_spec *tspec) if (NULL != tspec->source) { struct sockaddr_in src_addr, *srcp = &src_addr; /** get sockaddr from source */ - if (!netsnmp_sockaddr_in2(&src_addr, tspec->source, ":0")) + if (!netsnmp_sockaddr_in2(&src_addr, tspec->source, NULL)) return NULL; return netsnmp_udpipv4base_transport_with_source(&addr, local, srcp); } else { @@ -364,7 +364,7 @@ netsnmp_udpipv4base_transport(const struct sockaddr_in *addr, int local) strcat(client_address, ":0"); have_port = 1; } - rc = netsnmp_sockaddr_in2(&client_addr, client_socket, ":0"); + rc = netsnmp_sockaddr_in2(&client_addr, client_socket, NULL); if (client_address != client_socket) free(client_address); if(rc) { diff --git a/snmplib/transports/snmpUDPIPv6Domain.c b/snmplib/transports/snmpUDPIPv6Domain.c index 105a580..3d003f2 100644 --- a/snmplib/transports/snmpUDPIPv6Domain.c +++ b/snmplib/transports/snmpUDPIPv6Domain.c @@ -464,7 +464,7 @@ netsnmp_udp6_transport(const struct sockaddr_in6 *addr, int local) NETSNMP_DS_LIB_CLIENT_ADDR); if (client_socket) { struct sockaddr_in6 client_addr; - if(netsnmp_sockaddr_in6_2(&client_addr, client_socket, NULL)) { + if(!netsnmp_sockaddr_in6_2(&client_addr, client_socket, NULL)) { return netsnmp_udp6_transport_with_source(addr, local, &client_addr); } diff --git a/testing/fulltests/default/T070com2sec_simple b/testing/fulltests/default/T070com2sec_simple index 7df0b51..2299a8e 100644 --- a/testing/fulltests/default/T070com2sec_simple +++ b/testing/fulltests/default/T070com2sec_simple @@ -134,10 +134,6 @@ SAVECHECKAGENT '<"c406a", 255.255.255.255/255.255.255.255> => "t406a"' SAVECHECKAGENT 'line 30: Error:' # msg from h_strerror so it varies SAVECHECKAGENT 'line 31: Error:' # msg from h_strerror so it varies -FINISHED - -# don't test the rest, it depends on DNS, which is not available in Koji - CHECKAGENT '<"c408a"' if [ "$snmp_last_test_result" -eq 0 ] ; then CHECKAGENT 'line 32: Error:' diff --git a/testing/fulltests/default/T071com2sec6_simple b/testing/fulltests/default/T071com2sec6_simple index bc2d432..aceba57 100644 --- a/testing/fulltests/default/T071com2sec6_simple +++ b/testing/fulltests/default/T071com2sec6_simple @@ -132,10 +132,6 @@ SAVECHECKAGENT '<"c606a", ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/ffff:ffff:ffff SAVECHECKAGENT 'line 27: Error:' SAVECHECKAGENT 'line 28: Error:' -FINISHED - -# don't test the rest, it depends on DNS, which is not available in Koji - # 608 CHECKAGENT '<"c608a"' if [ "$snmp_last_test_result" -eq 0 ] ; then