> Using the portscan variant of IpServiceMap will work as you have  
> discovered. The reason the snmp variant isn't working has to do with  
> IPv6. Net-SNMP has problems reporting on services that listen on  
> the :::80 port rather than the traditional IPv4 0.0.0.0::80. LDAPS,  
> HTTP, HTTPS and SSH are common examples of these. If you aren't using  
> IPv6 on your network you can fix this by disable IPv6 in your kernel.
> 
> Otherwise, take a look at the solution for "Why doesn't httpd show up  
> in my list of services?" question in the FAQ.
> 
> FAQ: http://www.zenoss.com/community/docs/faqs/faq-english/


This is a serious problem for me, since those services that support v6 and v4 
are often the most critical, like http and ssh.  Disabling v6 support on 500+ 
systems is not an option, and will just have to be rolled back once we deploy 
v6 client support.  

Upon further exploration I've almost worked out a solution for modeling IP 
services bound to ipv6 equivalent of 0.0.0.0 "::".  I had to add some hackery 
to Products/DataCollector/plugins/zenoss/snmp/IpServiceMap.py but it doesn't 
quite work reliably.

Net-SNMP (at least newer versions) supports tcpListenerTable and 
udpEndpointTable, 1.3.6.1.2.1.6.20.1.4 and 1.3.6.1.2.1.7.7.1.8 respectively, 
which are new implementations that handle both v6 and v4 bindings.  I've tested 
this with freshest 5.4.1, but older may have support.  Those that don't should 
still model under the old connection tables.  The table formats are also quite 
different.

This patch ignores specific v6 addresses, since Zenoss can't deal with v6 
services yet anyway.  It's got lots of debug print in it, since it doesn't 
quite work right yet, perhaps due to the way bulk request responses are being 
handled.  I'm sure I'm just overlooking something.  More eyes/testers could 
help.  I've pretty much just duplicated the forloops for tcp and udp.  Not the 
most clever or efficient way, but it proves the concept.

How do you do an attachment in this forum anyway?


Code:
--- zenoss/Products/DataCollector/plugins/zenoss/snmp/IpServiceMap.py   
2007-05-25 15:32:28.000000000 -0600
+++ zenoss-old/Products/DataCollector/plugins/zenoss/snmp/IpServiceMap.py       
2007-12-11 20:27:57.000000000 -0700
@@ -32,6 +32,8 @@
     snmpGetTableMaps = (
         GetTableMap('tcptable', '.1.3.6.1.2.1.6.13.1', {'.1':'state'}),
         GetTableMap('udptable', '.1.3.6.1.2.1.7.5.1', {'.1':'addr'}),
+        GetTableMap('tcplisten', '.1.3.6.1.2.1.6.20.1.4', {'.1':'v4', 
'.2':'v6'}),
+        GetTableMap('udpendpoint', '.1.3.6.1.2.1.7.7.1.8', {'.1':'v4', 
'.2':'v6'}),
     ) 
     
     def process(self, device, results, log):
@@ -40,19 +42,51 @@
         getdata, tabledata = results
         tcptable = tabledata.get("tcptable")
         udptable = tabledata.get("udptable")
+        tcplisten = tabledata.get("tcplisten")
+        udpendpoint = tabledata.get("udpendpoint")
         rm = self.relMap()
         maxport = getattr(device, 'zIpServiceMapMaxPort', 1024)
         #tcp services
         tcpports = {}
         for oid, value in tcptable.items():
+            print "tcp old %s %s" % (oid,value)
             if value['state'] != 2: continue
             oidar = oid.split('.')
             addr = '.'.join(oidar[-10:-6])
             port = int(oidar[-6])
             if port > maxport or port < 1: continue
             om = tcpports.get(port, None)
+            if om: 
+                if not addr in om.ipaddresses:
+                    om.ipaddresses.append(addr)
+            else:
+                om = self.objectMap()
+                om.id = 'tcp_%05d' % port
+                om.ipaddresses = [addr,]
+                om.protocol = 'tcp'
+                om.port = port
+                om.setServiceClass = {'protocol': 'tcp', 'port':port}
+                om.discoveryAgent = self.name()
+                tcpports[port] = om
+                rm.append(om)
+        for oid, value in tcplisten.items():
+            print "tcp new %s %s" % (oid,value)
+            oidar = oid.split('.')
+            port = int(oidar[-1])
+            addr = ''
+            if value.has_key('v4'): #ipv4 binding
+                addr = '.'.join(oidar[-5:-1])
+            elif value.has_key('v6'): #ipv6 binding
+                addr = '.'.join(oidar[-17:-1])
+                if addr == '0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0': 
+                    addr = '::'
+                else: continue #an't handle v6 properly yet
+            else: continue #wha?
+            if port > maxport or port < 1: continue
+            om = tcpports.get(port, None)
             if om:
-                om.ipaddresses.append(addr)
+                if not addr in om.ipaddresses:
+                    om.ipaddresses.append(addr)
             else:
                 om = self.objectMap()
                 om.id = 'tcp_%05d' % port
@@ -67,13 +101,15 @@
         #udp services
         udpports = {}
         for oid, value in udptable.items():
-            oid = oid.split('.')
-            port = int(oid[-1])
+            print "udp old %s %s" % (oid,value)
+            oidar = oid.split('.')
+            port = int(oidar[-1])
             if port > maxport or port < 1: continue
             addr = value['addr']
             om = udpports.get(port, None)
             if om:
-                om.ipaddresses.append(addr)
+                if not addr in om.ipaddresses:
+                    om.ipaddresses.append(addr)
             else:
                 om = self.objectMap()
                 om.id = 'udp_%05d' % port
@@ -84,6 +120,36 @@
                 om.discoveryAgent = self.name()
                 udpports[port]=om
                 rm.append(om)
+        for oid, value in udpendpoint.items():
+            print "udp new %s %s" % (oid,value)
+            oidar = oid.split('.')
+            port = 0
+            addr = ''
+            if value.has_key('v4'): #ipv4 binding
+                port = int(oidar[16])
+                addr = '.'.join(oidar[12:16])
+            elif value.has_key('v6'): #ipv4 binding
+                port = int(oidar[28])
+                addr = '.'.join(oidar[12:28])
+                if addr == '0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0': 
+                    addr = '::'
+                else: continue #can't handle v6 properly yet
+            else: continue
+            if port > maxport or port < 1: continue
+            om = udpports.get(port, None)
+            if om:
+                if not addr in om.ipaddresses:
+                    om.ipaddresses.append(addr)
+            else:
+                om = self.objectMap()
+                om.id = 'udp_%05d' % port
+                om.ipaddresses = [addr,]
+                om.protocol = 'udp'
+                om.port = port
+                om.setServiceClass = {'protocol': 'udp', 'port':port}
+                om.discoveryAgent = self.name()
+                tcpports[port] = om
+                rm.append(om)
         return rm
 
 






-------------------- m2f --------------------

Read this topic online here:
http://community.zenoss.com/forums/viewtopic.php?p=14262#14262

-------------------- m2f --------------------



_______________________________________________
zenoss-users mailing list
[email protected]
http://lists.zenoss.org/mailman/listinfo/zenoss-users

Reply via email to