3-Jun-2004 Mike Slifcak

This patch works with the freebsd5.h patch to
successfully compile on FreeBSD 5.x

Patch using net-snmp-5.1.1 or V5-1-patdhes branch,
Built using FreeBSD 5.2.1

--- net-snmp-5.1.1/agent/mibgroup/ucd-snmp/disk.c	Thu Jan  8 18:10:06 2004
+++ net-snmp/agent/mibgroup/ucd-snmp/disk.c	Thu Jun  3 22:44:57 2004
@@ -566,9 +566,6 @@
     double          totalblks, free, used, avail, availblks;
 #else
     static long     avail;
-#if defined(STRUCT_STATVFS_HAS_F_FILES) || defined(STRUCT_STATFS_HAS_F_FILES)
-    int             percent_inode;
-#endif
 #endif
     static long     long_ret;
     static char     errmsg[300];
@@ -651,18 +648,7 @@
     iserror = (disks[disknum].minimumspace >= 0 ?
                avail < disks[disknum].minimumspace :
                100 - percent <= disks[disknum].minpercent) ? 1 : 0;
-#if defined(STRUCT_STATVFS_HAS_F_FILES) || defined STRUCT_STATFS_HAS_F_FAVAIL
-    percent_inode = vfs.f_favail <= 0 ? 100 :
-        (int) ((double) (vfs.f_files - vfs.f_ffree) /
-               (double) (vfs.f_files -
-                         (vfs.f_ffree - vfs.f_favail)) * 100.0 + 0.5);
-#else
-#if defined(STRUCT_STATFS_HAS_F_FILES) && defined(STRUCT_STATFS_HAS_F_FFREE)
-   percent_inode = vfs.f_files == 0 ? 100.0 :
-      (int) ((double) (vfs.f_files - vfs.f_ffree) /
-	          (double) (vfs.f_files) * 100.0 + 0.5);
-#endif 
-#endif /* defined(STRUCT_STATVFS_HAS_F_FILES) */ 
+
     switch (vp->magic) {
     case DISKTOTAL:
         long_ret = (long)(vfs.f_blocks * multiplier);
@@ -677,7 +663,20 @@
         return ((u_char *) (&long_ret));
 #if defined(STRUCT_STATVFS_HAS_F_FILES) || defined (STRUCT_STATFS_HAS_F_FILES)
     case DISKPERCENTNODE:
-        long_ret = percent_inode;
+        long_ret = 100;
+
+    #if defined(STRUCT_STATFS_HAS_F_FAVAIL)
+	if (vfs.f_avail > 0)
+	    long_ret = (long) ((double) (vfs.f_files - vfs.f_ffree) /
+               (double) (vfs.f_files -
+                         (vfs.f_ffree - vfs.f_favail)) * 100.0 + 0.5);
+    #endif
+    #if defined(STRUCT_STATFS_HAS_F_FFREE)
+	if (vfs.f_files != 0)
+	    long_ret = (long) ((double) (vfs.f_files - vfs.f_ffree) /
+	          (double) (vfs.f_files) * 100.0 + 0.5);
+    #endif 
+
         return ((u_char *) (&long_ret));
 #endif
     case ERRORFLAG:
3-Jun-2004 Mike Slifcak

This patch creates freebsd5.h, required to properly
build Net-SNMP-5.1 or later on FreeBSD 5.x

Patch using net-snmp-5.1.1 or V5-1-patdhes branch,
Built using FreeBSD 5.2.1

Since the original source did not exist at net-snmp-5.1.1,
this patch should also work against net-snmp-5.1.1


--- net-snmp-5.1.1/include/net-snmp/system/freebsd5.h	Wed Jun  2 22:28:45 2004
+++ net-snmp/include/net-snmp/system/freebsd5.h	Wed Jun  2 22:26:18 2004
@@ -0,0 +1,29 @@
+#include "freebsd.h"
+
+/*
+ * freebsd4 is a superset of freebsd2 and freebsd3 
+ */
+#define freebsd2 1
+#define freebsd3 1
+/* freebsd5 is a superset of freebsd4 */
+#define freebsd4 1
+
+#undef IFADDR_SYMBOL
+#define IFADDR_SYMBOL "in_ifaddrhead"
+
+#undef PROC_SYMBOL
+#define PROC_SYMBOL "allproc"
+
+#undef NPROC_SYMBOL
+#define NPROC_SYMBOL "nprocs"
+
+#undef TOTAL_MEMORY_SYMBOL
+
+/* force hr_storage.c to use getfsstat */
+#undef MBSTAT_SYMBOL
+#undef HAVE_STATVFS
+#undef HAVE_SYS_STATVFS_H
+#undef STRUCT_STATVFS_HAS_F_FRSIZE
+/* force ucd-snmp/disk.c to ignore statvfs objects */
+#undef STRUCT_STATFS_HAS_F_FAVAIL
+
3-June-2004 Mike Slifcak

This patch fixes memory leak and array bound violations
that were reported in bug # 895679 .

Several strategy changes were implemented:
 f. IF there are no printers, do not allocate an array of
    pointers to printer descriptions.

 2. It is believed that the number of printers attached to the system
    will not shrink significantly.  Therefore, once an array of
    pointers to printer descriptions is allocated, re-use it.

 3. If any function that references pointers to printer descriptions
    is called before those descriptions are initialized, exit with
    error, gracefully.

 4. Array upper bound does not change if memory allocation fails.

 5. If array grows, free old array storage to prevent memory leak.


Patch using net-snmp-5.1.1 or V5-1-patdhes branch,
Built using FreeBSD 5.2.1

--- net-snmp-5.1.1/agent/mibgroup/host/hr_print.c	Sun Jun 22 15:42:19 2003
+++ net-snmp/agent/mibgroup/host/hr_print.c	Wed Jun  2 23:34:30 2004
@@ -194,9 +194,11 @@
 	 *
 	 *********************/
 
-static int      HRP_index;
-static char   **HRP_name;
-static int      HRP_names, HRP_maxnames;
+static int      HRP_index = 0;
+static char   **HRP_name = NULL;	/* array of printer descriptions */
+static int      HRP_names = 0;		/* number of printer descriptions */
+
+#define HRP_MAX_INCR 10
 
 void
 Init_HR_Print(void)
@@ -212,15 +214,16 @@
     FILE           *p;
 #endif
 
+static int HRP_maxnames = 0;	/* upper bound on array size */
+
+    HRP_index = 0;		/* safe fail at Get_Next_HR_Print */
+
     if (HRP_name) {
+	/* free the descriptions, and keep the array. */
         for (i = 0; i < HRP_names; i++)
             free(HRP_name[i]);
         HRP_names = 0;
-    } else {
-        HRP_maxnames = 5;
-        HRP_name = (char **) calloc(HRP_maxnames, sizeof(char *));
-        if (!HRP_name)
-            return;
+        memset(HRP_name, 0, HRP_maxnames * sizeof(char *));
     }
 
 #if HAVE_PRINTCAP
@@ -255,11 +258,14 @@
 #endif
             if (HRP_names == HRP_maxnames) {
                 char          **tmp;
-                HRP_maxnames += 5;
-                tmp = (char **) calloc(HRP_maxnames, sizeof(char *));
+                tmp = (char **) calloc(HRP_maxnames + HRP_MAX_INCR, sizeof(char *));
                 if (!tmp)
                     goto finish;
-                memcpy(tmp, HRP_name, HRP_names * sizeof(char *));
+                HRP_maxnames += HRP_MAX_INCR;
+		if (HRP_name) {
+			memcpy(tmp, HRP_name, HRP_names * sizeof(char *));
+			free(HRP_name);
+		}
                 HRP_name = tmp;
             }
             HRP_name[HRP_names++] = strdup(ptr);
@@ -279,8 +285,6 @@
 #endif
     }
 #endif                          /* HAVE_anything */
-
-    HRP_index = 0;
 }
 
 int
@@ -301,6 +305,9 @@
 const char     *
 describe_printer(int idx)
 {
+    if (HRP_index == 0)  /* return empty string if not initialized */
+	return "";
+
     DEBUGMSGTL(("host/hr_print", "describe p: %d/%d %s\n", HRP_index, idx,
                 HRP_name[HRP_index - 1]));
     return HRP_name[HRP_index - 1];
3-Jun-2004 Mike Slifcak

This patch removes unused code, which has the added benefit
of successfully compiling on FreeBSD 5.x

Patch using net-snmp-5.1.1 or V5-1-patdhes branch,
Built using FreeBSD 5.2.1

--- net-snmp-5.1.1/agent/mibgroup/ucd-snmp/memory_freebsd2.c	Thu Jan 29 08:53:59 2004
+++ net-snmp/agent/mibgroup/ucd-snmp/memory_freebsd2.c	Thu Jun  3 19:56:18 2004
@@ -195,24 +195,14 @@
 void
 swapmode(void)
 {
-    int             nswdev, dmmax, pagesize;
+    int             pagesize;
     int             i, n;
-    struct swdevt  *sw;
     static kvm_t   *kd = NULL;
     struct kvm_swap kswap[16];
 
     if (kd == NULL)
         kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL);
 
-    auto_nlist(NSWDEV_SYMBOL, (char *) &nswdev, sizeof(nswdev));
-    auto_nlist(DMMAX_SYMBOL, (char *) &dmmax, sizeof(dmmax));
-
-    sw = (struct swdevt *) malloc(nswdev * sizeof(*sw));
-    if (sw == NULL)
-        return;
-
-    auto_nlist(SWDEVT_SYMBOL, (char *) sw, nswdev * sizeof(*sw));
-
     n = kvm_getswapinfo(kd, kswap, sizeof(kswap) / sizeof(kswap[0]), 0);
 
     swapUsed = swapTotal = swapFree = 0;
@@ -241,8 +231,6 @@
     swapTotal *= pagesize;
     swapUsed *= pagesize;
     swapFree *= pagesize;
-
-    free(sw);
 }
 #endif
 
3-Jun-2004 Mike Slifcak

This patch fixes compiling the host hr_swrun module in order to
build Net-SNMP-5.1 or later on FreeBSD 5.x

Patch using net-snmp-5.1.1 or V5-1-patdhes branch,
Built using FreeBSD 5.2.1

--- net-snmp-5.1.1/agent/mibgroup/host/hr_swrun.c	Tue Feb 17 00:35:24 2004
+++ net-snmp/agent/mibgroup/host/hr_swrun.c	Thu Jun  3 21:48:51 2004
@@ -585,7 +585,11 @@
         string[ sizeof(string)-1 ] = 0;
 #endif
 #elif HAVE_KVM_GETPROCS
+    #if defined(freebsd5)
+        strcpy(string, proc_table[LowProcIndex].ki_comm);
+    #else
         strcpy(string, proc_table[LowProcIndex].kp_proc.p_comm);
+    #endif
 #elif defined(linux)
         sprintf(string, "/proc/%d/status", pid);
         if ((fp = fopen(string, "r")) == NULL)
@@ -690,7 +694,11 @@
         *cp1 = 0;
 #endif
 #elif HAVE_KVM_GETPROCS
+    #if defined(freebsd5)
+        strcpy(string, proc_table[LowProcIndex].ki_comm);
+    #else
         strcpy(string, proc_table[LowProcIndex].kp_proc.p_comm);
+    #endif
 #elif defined(linux)
         sprintf(string, "/proc/%d/cmdline", pid);
         if ((fp = fopen(string, "r")) == NULL)
@@ -881,7 +889,11 @@
         }
 #else
 #if HAVE_KVM_GETPROCS
+    #if defined(freebsd5)
+        switch (proc_table[LowProcIndex].ki_stat) {
+    #else
         switch (proc_table[LowProcIndex].kp_proc.p_stat) {
+    #endif
 #elif defined(dynix)
         switch (lowpsinfo.pr_state) {
 #elif defined(solaris2)
@@ -976,9 +988,13 @@
         long_return = proc_buf->p_utime * 100 + proc_buf->p_stime * 100;
 #endif
 #elif HAVE_KVM_GETPROCS
+    #if defined(freebsd5)
+        long_return = proc_table[LowProcIndex].ki_runtime / 100000;
+    #else
         long_return = proc_table[LowProcIndex].kp_proc.p_uticks +
             proc_table[LowProcIndex].kp_proc.p_sticks +
             proc_table[LowProcIndex].kp_proc.p_iticks;
+    #endif
 #elif defined(linux)
         sprintf(string, "/proc/%d/stat", pid);
         if ((fp = fopen(string, "r")) == NULL)
@@ -1049,7 +1065,11 @@
 #elif HAVE_KVM_GETPROCS
 #if defined(freebsd3) && !defined(darwin)
         long_return =
+    #if defined(freebsd5)
+            proc_table[LowProcIndex].ki_size / 1024;
+    #else
             proc_table[LowProcIndex].kp_eproc.e_vm.vm_map.size / 1024;
+    #endif
 #else
         long_return = proc_table[LowProcIndex].kp_eproc.e_vm.vm_tsize +
             proc_table[LowProcIndex].kp_eproc.e_vm.vm_ssize +
@@ -1329,8 +1349,13 @@
 #elif defined(solaris2)
         return proc_table[current_proc_entry++];
 #elif HAVE_KVM_GETPROCS
+    #if defined(freebsd5)
+        if (proc_table[current_proc_entry].ki_stat != 0)
+            return proc_table[current_proc_entry++].ki_pid;
+    #else
         if (proc_table[current_proc_entry].kp_proc.p_stat != 0)
             return proc_table[current_proc_entry++].kp_proc.p_pid;
+    #endif
 #else
         if (proc_table[current_proc_entry].p_stat != 0)
             return proc_table[current_proc_entry++].p_pid;
3-Jun-2004  Mike Slifcak

Patch using net-snmp-5.1.1 or May 2004 V5-1-patdhes branch,
Built using FreeBSD 5.2.1

Impact to other BSD-like systems is not known at time of writing.

diff -ur net-snmp/agent/mibgroup/mibII/tcpTable.c net-snmp/agent/mibgroup/mibII/tcpTable.c
--- net-snmp/agent/mibgroup/mibII/tcpTable.c	Wed Apr  7 00:59:27 2004
+++ net-snmp/agent/mibgroup/mibII/tcpTable.c	Wed Jun  2 13:01:39 2004
@@ -35,6 +34,17 @@
 #include "tcpTable.h"
 #include "sysORTable.h"
 
+static	int StateMap[16] = {
+/* the value "5" represents an established connection.
+ * the value "8" represents a connection in CLOSE_WAIT state.
+ */
+#ifdef hpux
+	1, 2, 3, -1, 4, 5, 8, 6, 10, 9, 7, 11, 0,0,0,0
+#else
+	1, 2, 3,     4, 5, 8, 6, 10, 9, 7, 11, 0,0,0,0,0
+#endif
+};
+
 #ifdef hpux11
 #define	TCPTABLE_ENTRY_TYPE	mib_tcpConnEnt 
 #define	TCPTABLE_STATE		State 
@@ -702,7 +712,13 @@
     char     *tcpcb_buf = NULL;
     struct xinpgen *xig = NULL;
     netsnmp_inpcb  *nnew;
-    int      StateMap[] = { 1, 2, 3, 4, 5, 8, 6, 10, 9, 7, 11 };
+
+#if defined(freebsd4)
+    #define NS_ELEM struct xtcpcb
+#else
+/* this is the original value */
+    #define NS_ELEM struct xinpcb
+#endif
 
     tcpTable_free(NULL, NULL);
 
@@ -729,11 +745,11 @@
         nnew = SNMP_MALLOC_TYPEDEF(netsnmp_inpcb);
         if (!nnew)
             break;
-        nnew->state = StateMap[((struct xinpcb *) xig)->xt_tp.t_state];
+        nnew->state = StateMap[0x0f & ((NS_ELEM *) xig)->xt_tp.t_state];
         if (nnew->state == 5 /* established */ ||
             nnew->state == 8 /*  closeWait  */ )
             tcp_estab++;
-        memcpy(&(nnew->pcb), &(((struct xinpcb *) xig)->xt_inp),
+        memcpy(&(nnew->pcb), &(((NS_ELEM *) xig)->xt_inp),
                            sizeof(struct inpcb));
 
 	nnew->inp_next = tcp_head;
@@ -748,6 +764,7 @@
     }
     DEBUGMSGTL(("mibII/tcpTable", "Failed to load TCP Table (sysctl)\n"));
     return -1;
+#undef NS_ELEM
 }
 #else		/* (defined(CAN_USE_SYSCTL) && defined(TCPCTL_PCBLIST)) */
 #ifdef PCB_TABLE
@@ -758,7 +775,6 @@
     struct inpcb   *entry;
     struct tcpcb    tcpcb;
     netsnmp_inpcb  *nnew;
-    int      StateMap[] = { 1, 2, 3, 4, 5, 8, 6, 10, 9, 7, 11 };
 
     tcpTable_free(NULL, NULL);
 
@@ -778,7 +794,7 @@
             break;
         klookup((unsigned long) entry, (char *)&(nnew->pcb), sizeof(struct inpcb));
         klookup((int) nnew->pcb.inp_ppcb, (char *)&tcpcb, sizeof(struct tcpcb));
-	nnew->state = StateMap[tcpcb.t_state];
+	nnew->state = StateMap[0x0f & tcpcb.t_state];
         if (nnew->state == 5 /* established */ ||
             nnew->state == 8 /*  closeWait  */ )
             tcp_estab++;
@@ -808,11 +824,6 @@
     struct tcpcb   tcpcb;
     netsnmp_inpcb  *nnew;
     struct inpcb   *entry;
-#ifdef hpux
-    int      StateMap[] = { 1, 2, 3, -1, 4, 5, 8, 6, 10, 9, 7, 11 };
-#else
-    int      StateMap[] = { 1, 2, 3,     4, 5, 8, 6, 10, 9, 7, 11 };
-#endif
 
     tcpTable_free(NULL, NULL);
 
@@ -832,7 +843,7 @@
             break;
         klookup((unsigned long) entry, (char *)&(nnew->pcb), sizeof(struct inpcb));
         klookup((int) nnew->pcb.inp_ppcb, (char *)&tcpcb, sizeof(struct tcpcb));
-	nnew->state    = StateMap[tcpcb.t_state];
+	nnew->state    = StateMap[0x0f & tcpcb.t_state];
         if (nnew->state == 5 /* established */ ||
             nnew->state == 8 /*  closeWait  */ )
             tcp_estab++;
diff -ur net-snmp/agent/mibgroup/mibII/udpTable.c net-snmp/agent/mibgroup/mibII/udpTable.c
--- net-snmp/agent/mibgroup/mibII/udpTable.c	Wed Apr  7 00:59:27 2004
+++ net-snmp/agent/mibgroup/mibII/udpTable.c	Wed Jun  2 13:14:30 2004
@@ -65,9 +68,16 @@
 #ifdef linux
 #define INP_NEXT_SYMBOL		inp_next
 #endif
-#define	UDPTABLE_ENTRY_TYPE	struct inpcb 
-#define	UDPTABLE_LOCALADDRESS	inp_laddr.s_addr 
-#define	UDPTABLE_LOCALPORT	inp_lport
+
+typedef struct netsnmp_inpcb_s netsnmp_inpcb;
+struct netsnmp_inpcb_s {
+    struct inpcb    pcb;
+    int             state;
+    netsnmp_inpcb  *inp_next;
+};
+#define	UDPTABLE_ENTRY_TYPE	netsnmp_inpcb 
+#define	UDPTABLE_LOCALADDRESS	pcb.inp_laddr.s_addr 
+#define	UDPTABLE_LOCALPORT	pcb.inp_lport
 #define	UDPTABLE_IS_LINKED_LIST
 
 #endif                          /* WIN32 */
@@ -583,7 +593,7 @@
     int      sname[] = { CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_PCBLIST };
     char     *udpcb_buf = NULL;
     struct xinpgen *xig = NULL;
-    struct inpcb   *nnew;
+    netsnmp_inpcb   *nnew;
 
     udpTable_free(NULL, NULL);
 
@@ -607,12 +617,12 @@
     xig = (struct xinpgen *) ((char *) xig + xig->xig_len);
 
     while (xig && (xig->xig_len > sizeof(struct xinpgen))) {
-        nnew = SNMP_MALLOC_TYPEDEF(struct inpcb);
+        nnew = SNMP_MALLOC_TYPEDEF(netsnmp_inpcb);
         if (!nnew)
             break;
-        memcpy(nnew, ((struct xinpcb *) xig)->xi_inp, sizeof(struct inpcb));
+        memcpy(nnew, &((struct xinpcb *) xig)->xi_inp, sizeof(struct inpcb));
 
-	nnew->next = udp_head;		/* XXX - ?? Check 'next' pointer */
+	nnew->inp_next = udp_head;
 	udp_head   = nnew;
         xig = (struct xinpgen *) ((char *) xig + xig->xig_len);
     }
