[patch] ifHighSpeed overflow fix

"James M. Leddy" <[email protected]>
Newsgroups gmane.network.net-snmp.user
Message-ID <[email protected]>
Hey all,

I found a user was having a similiar problem as me here 
http://sourceforge.net/mailarchive/message.php?msg_name=4762D47F.8040603%40cittio.com

Anyway I went ahead and patched it so it works, and would like to share
the changes with the rest of you so that those of us with 10GigE cards 
won't
run into this in the future.  Basically, the value 10 trillion overflows
32-bit integers, causing this issue. 

patch attached

PS, If anyone has the original email address I would appreciate it
if you could ask him to test this (assuming he's still having the
issue).

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/

_______________________________________________
Net-snmp-users mailing list
[email protected]
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users
non-overflow-config.patch (text/x-patch, 5.2 KB)
diff -pruN net-snmp-5.4.1.2/agent/mibgroup/if-mib/data_access/interface.c net-snmp-5.4.1.2-non-overflow/agent/mibgroup/if-mib/data_access/interface.c
--- net-snmp-5.4.1.2/agent/mibgroup/if-mib/data_access/interface.c	2007-01-22 11:18:29.000000000 -0500
+++ net-snmp-5.4.1.2-non-overflow/agent/mibgroup/if-mib/data_access/interface.c	2008-09-03 15:33:10.000000000 -0400
@@ -680,7 +680,14 @@ netsnmp_access_interface_entry_overrides
         netsnmp_access_interface_entry_overrides_get(entry->name);
     if (if_ptr) {
         entry->type = if_ptr->type;
-        entry->speed = if_ptr->speed;
+	/*
+	 * enforce speed limit
+	 */
+	if (if_ptr->speed > 4294967295)
+	    entry->speed = 4294967295;
+	else
+	    entry->speed = if_ptr->speed;
+	entry->speed_high = if_ptr->speed/1000000;
     }
 }
 
@@ -725,7 +732,7 @@ _parse_interface_config(const char *toke
         config_perror("Out of memory");
         return;
     }
-    if_new->speed = strtoul(speed, &ecp, 0);
+    if_new->speed = strtoull(speed, &ecp, 0);
     if (*ecp) {
         config_perror("Bad SPEED value");
         free(if_new);
diff -pruN net-snmp-5.4.1.2/agent/mibgroup/if-mib/data_access/interface_linux.c net-snmp-5.4.1.2-non-overflow/agent/mibgroup/if-mib/data_access/interface_linux.c
--- net-snmp-5.4.1.2/agent/mibgroup/if-mib/data_access/interface_linux.c	2007-07-06 17:14:03.000000000 -0400
+++ net-snmp-5.4.1.2-non-overflow/agent/mibgroup/if-mib/data_access/interface_linux.c	2008-09-03 15:34:45.000000000 -0400
@@ -627,15 +627,26 @@ netsnmp_arch_interface_container_load(ne
                 entry->type = IANAIFTYPE_OTHER;
         }
 
-        if (IANAIFTYPE_ETHERNETCSMACD == entry->type)
-            entry->speed =
+        if (IANAIFTYPE_ETHERNETCSMACD == entry->type) {
+	    /* prevent int32 overflow */	    
+            entry->speed_high =
                 netsnmp_linux_interface_get_if_speed(fd, entry->name);
+	    /* Maximum speed is 4,294,967,295 */
+	    if (entry->speed_high > 4294)
+		entry->speed = 4294967295;
+	    else
+		entry->speed = entry->speed_high*1000*1000;
 #ifdef APPLIED_PATCH_836390   /* xxx-rks ifspeed fixes */
-        else if (IANAIFTYPE_PROPVIRTUAL == entry->type)
+	/* patch hasn't been applied in 4 years, I thinnk it's safe to 
+	 * delete this stuff */
+        } else if (IANAIFTYPE_PROPVIRTUAL == entry->type) {
             entry->speed = _get_bonded_if_speed(entry);
+	    entry->speed_high = entry->speed/1000000;
 #endif
-        else
+	} else {
             netsnmp_access_interface_entry_guess_speed(entry);
+	    entry->speed_high = entry->speed/1000000;
+	}
         
         netsnmp_access_interface_ioctl_flags_get(fd, entry);
 
@@ -672,8 +683,6 @@ netsnmp_arch_interface_container_load(ne
 
         netsnmp_access_interface_entry_overrides(entry);
 
-        entry->speed_high = entry->speed / 1000000;
-
         if (! (load_flags & NETSNMP_ACCESS_INTERFACE_LOAD_NO_STATS))
             _parse_stats(entry, stats, scan_expected);
 
@@ -748,7 +757,7 @@ netsnmp_linux_interface_get_if_speed(int
     /* return in bps */
     DEBUGMSGTL(("mibII/interfaces", "ETHTOOL_GSET on %s speed = %d\n",
                 ifr.ifr_name, edata.speed));
-    return edata.speed*1000*1000;
+    return edata.speed;
 }
 #endif
  
@@ -762,7 +771,7 @@ netsnmp_linux_interface_get_if_speed_mii
 netsnmp_linux_interface_get_if_speed(int fd, const char *name)
 #endif
 {
-    unsigned int retspeed = 10000000;
+    unsigned int retspeed = 10;
     struct ifreq ifr;
 
     /* the code is based on mii-diag utility by Donald Becker
@@ -774,7 +783,7 @@ netsnmp_linux_interface_get_if_speed(int
     int mii_reg, i;
     ushort mii_val[32];
     ushort bmcr, bmsr, nway_advert, lkpar;
-    const unsigned int media_speeds[] = {10000000, 10000000, 100000000, 100000000, 10000000, 0};	
+    const unsigned int media_speeds[] = {10, 10, 100, 100, 10, 0};	
     /* It corresponds to "10baseT", "10baseT-FD", "100baseTx", "100baseTx-FD", "100baseT4", "Flow-control", 0, */
 
     strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
@@ -822,7 +831,7 @@ netsnmp_linux_interface_get_if_speed(int
     
     if(!(bmcr & 0x1000) ){
         DEBUGMSGTL(("mibII/interfaces", "Auto-negotiation disabled.\n"));
-        retspeed = bmcr & 0x2000 ? 100000000 : 10000000;
+        retspeed = bmcr & 0x2000 ? 100 : 10;
         return retspeed;
     }
     /* Link partner got our advertised abilities */	
@@ -843,7 +852,7 @@ netsnmp_linux_interface_get_if_speed(int
         else
             DEBUGMSGTL(("mibII/interfaces", "No common media type was autonegotiated!\n"));
     }else if(lkpar & 0x00A0){
-        retspeed = (lkpar & 0x0080) ? 100000000 : 10000000;
+        retspeed = (lkpar & 0x0080) ? 100 : 10;
     }
     return retspeed;
 }
diff -pruN net-snmp-5.4.1.2/include/net-snmp/data_access/interface.h net-snmp-5.4.1.2-non-overflow/include/net-snmp/data_access/interface.h
--- net-snmp-5.4.1.2/include/net-snmp/data_access/interface.h	2006-09-14 13:15:32.000000000 -0400
+++ net-snmp-5.4.1.2-non-overflow/include/net-snmp/data_access/interface.h	2008-09-03 15:33:23.000000000 -0400
@@ -176,7 +176,7 @@ typedef struct netsnmp_interface_entry_s
 typedef struct _conf_if_list {
     const char     *name;
     int             type;
-    u_long          speed;
+    unsigned long long speed;
     struct _conf_if_list *next;
 } netsnmp_conf_if_list;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.