mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 20:51:30 +00:00
Make osclasses a substructure of osmatch.
This commit is contained in:
@@ -111,13 +111,12 @@ from zenmapCore.NmapOptions import NmapOptions, split_quoted, join_quoted
|
||||
from zenmapCore.StringPool import unique
|
||||
|
||||
# The version of the Nmap DTD this file understands and emits.
|
||||
XML_OUTPUT_VERSION = "1.03"
|
||||
XML_OUTPUT_VERSION = "1.04"
|
||||
|
||||
class HostInfo(object):
|
||||
def __init__(self):
|
||||
self.comment = None;
|
||||
self._tcpsequence = {}
|
||||
self._osclasses = []
|
||||
self._osmatches = []
|
||||
self._ports = []
|
||||
self._ports_used = []
|
||||
@@ -137,8 +136,7 @@ class HostInfo(object):
|
||||
clone = HostInfo()
|
||||
clone.comment = self.comment
|
||||
clone._tcpsequence = copy.deepcopy(self._tcpsequence)
|
||||
clone._osclasses = map(lambda d: copy.deepcopy(d), self._osclasses)
|
||||
clone._osmatches = self._osmatches
|
||||
clone._osmatches = copy.deepcopy(self._osmatches)
|
||||
clone._ports = copy.deepcopy(self._ports)
|
||||
clone._ports_used = self._ports_used
|
||||
clone._extraports = self._extraports
|
||||
@@ -188,17 +186,12 @@ class HostInfo(object):
|
||||
return self._ipidsequence
|
||||
return {}
|
||||
|
||||
# osclasses is a list containing dicts of the form
|
||||
# osmatches is a list of dicts of the form
|
||||
# {'name': u'Linux 2.6.24', 'accuracy': u'98', 'line': u'1000',
|
||||
# 'osclasses': ...}
|
||||
# where each 'osclasses' element is a dict of the form
|
||||
# {'vendor': u'Linux', 'osfamily': u'Linux', 'type': u'general purpose',
|
||||
# 'osgen': u'2.6.X', 'accuracy': u'98'}
|
||||
def set_osclasses(self, classes):
|
||||
self._osclasses = classes
|
||||
|
||||
def get_osclasses(self):
|
||||
return self._osclasses
|
||||
|
||||
# osmatches is a list of dicts of the form
|
||||
# {'name': u'Linux 2.6.24', 'accuracy': u'98', 'line': u'1000'}
|
||||
def set_osmatches(self, matches):
|
||||
self._osmatches = matches
|
||||
|
||||
@@ -222,22 +215,6 @@ class HostInfo(object):
|
||||
return osmatches[-1]
|
||||
|
||||
|
||||
def get_best_osclass(self):
|
||||
"""Return the OS class with the highest accuracy. If there is a tie, one
|
||||
of the best matches will be returned."""
|
||||
if not self._osclasses:
|
||||
return None
|
||||
def osclass_key(osclass):
|
||||
# Sort first by accuracy, then by name so it's deterministic.
|
||||
try:
|
||||
accuracy = float(osclass.get("accuracy", ""))
|
||||
except ValueError:
|
||||
accuracy = 0
|
||||
return (accuracy, osclass.get("name"))
|
||||
osclasses = self.osclasses[:]
|
||||
osclasses.sort(cmp = lambda a, b: cmp(osclass_key(a), osclass_key(b)))
|
||||
return osclasses[-1]
|
||||
|
||||
# ports_used is a list like
|
||||
# [{'state': u'open', 'portid': u'22', 'proto': u'tcp'},
|
||||
# {'state': u'closed', 'portid': u'25', 'proto': u'tcp'},
|
||||
@@ -429,7 +406,6 @@ class HostInfo(object):
|
||||
|
||||
# Properties
|
||||
tcpsequence = property(get_tcpsequence, set_tcpsequence)
|
||||
osclasses = property(get_osclasses, set_osclasses)
|
||||
osmatches = property(get_osmatches, set_osmatches)
|
||||
ports = property(get_ports, set_ports)
|
||||
ports_used = property(get_ports_used, set_ports_used)
|
||||
@@ -876,7 +852,9 @@ class NmapParserSAX(ParserBasics, ContentHandler):
|
||||
self.dic_port["service_extrainfo"] = attrs.get("extrainfo", "")
|
||||
|
||||
def _parse_host_osmatch(self, attrs):
|
||||
self.list_osmatch.append(self._parsing(attrs, [], ['name', 'accuracy', 'line']))
|
||||
osmatch = self._parsing(attrs, [], ['name', 'accuracy', 'line'])
|
||||
osmatch['osclasses'] = []
|
||||
self.list_osmatch.append(osmatch)
|
||||
|
||||
def _parse_host_portused(self, attrs):
|
||||
self.list_portused.append(self._parsing(attrs, ['state', 'proto', 'portid'], []))
|
||||
@@ -972,12 +950,12 @@ class NmapParserSAX(ParserBasics, ContentHandler):
|
||||
self.in_os = True
|
||||
self.list_portused = []
|
||||
self.list_osmatch = []
|
||||
self.list_osclass = []
|
||||
elif self.in_host and self.in_os and name == "osmatch":
|
||||
self._parse_host_osmatch(attrs)
|
||||
elif self.in_host and self.in_os and name == "portused":
|
||||
self._parse_host_portused(attrs)
|
||||
elif self.in_host and self.in_os and name == "osclass":
|
||||
self.list_osclass = []
|
||||
self._parse_host_osclass(attrs)
|
||||
elif self.in_host and name == "uptime":
|
||||
self._parse_host_uptime(attrs)
|
||||
@@ -1015,15 +993,16 @@ class NmapParserSAX(ParserBasics, ContentHandler):
|
||||
self.in_port = False
|
||||
self.list_ports.append(self.dic_port)
|
||||
del(self.dic_port)
|
||||
elif self.in_host and self.in_os and name == "osmatch":
|
||||
self.list_osmatch[-1]['osclasses'].extend(self.list_osclass)
|
||||
self.list_osclass = []
|
||||
elif self.in_host and self.in_os and name == "os":
|
||||
self.in_os = False
|
||||
self.host_info.set_ports_used(self.list_portused)
|
||||
self.host_info.set_osmatches(self.list_osmatch)
|
||||
self.host_info.set_osclasses(self.list_osclass)
|
||||
|
||||
del(self.list_portused)
|
||||
del(self.list_osmatch)
|
||||
del(self.list_osclass)
|
||||
elif self.in_host and self.in_trace and name == "trace":
|
||||
self.in_trace = False
|
||||
|
||||
@@ -1213,22 +1192,21 @@ class NmapParserSAX(ParserBasics, ContentHandler):
|
||||
portid = pu.get("portid", ""))))
|
||||
writer.endElement("portused")
|
||||
|
||||
## Osclass elements
|
||||
for oc in host.osclasses:
|
||||
writer.startElement("osclass",
|
||||
Attributes(dict(vendor = oc.get("vendor", ""),
|
||||
osfamily = oc.get("osfamily", ""),
|
||||
type = oc.get("type", ""),
|
||||
osgen = oc.get("osgen", ""),
|
||||
accuracy = oc.get("accuracy", ""))))
|
||||
writer.endElement("osclass")
|
||||
|
||||
## Osmatch elements
|
||||
for om in host.osmatches:
|
||||
writer.startElement("osmatch",
|
||||
Attributes(dict(name = om.get("name", ""),
|
||||
accuracy = om.get("accuracy", ""),
|
||||
line = om.get("line", ""))))
|
||||
## Osclass elements
|
||||
for oc in om['osclasses']:
|
||||
writer.startElement("osclass",
|
||||
Attributes(dict(vendor = oc.get("vendor", ""),
|
||||
osfamily = oc.get("osfamily", ""),
|
||||
type = oc.get("type", ""),
|
||||
osgen = oc.get("osgen", ""),
|
||||
accuracy = oc.get("accuracy", ""))))
|
||||
writer.endElement("osclass")
|
||||
writer.endElement("osmatch")
|
||||
|
||||
writer.endElement("os")
|
||||
@@ -1358,7 +1336,7 @@ if __name__ == '__main__':
|
||||
for p in host.ports:
|
||||
print "\t%s" % repr(p)
|
||||
print " Ports used:", repr(host.ports_used)
|
||||
print " OS Class:", repr(host.osclasses)
|
||||
print " OS Matches:", repr(host.osmatches)
|
||||
print " Hostnames:", repr(host.hostnames)
|
||||
print " IP:", repr(host.ip)
|
||||
print " IPv6:", repr(host.ipv6)
|
||||
|
||||
Reference in New Issue
Block a user