Browse Source

fixed weird python problem:json output is unique now

Marius Schwarz 4 years ago
parent
commit
906e38aaae
1 changed files with 31 additions and 16 deletions
  1. 31 16
      nmap-to-json.py

+ 31 - 16
nmap-to-json.py

@@ -36,6 +36,7 @@ class Port:
                 "protocol":self.protocol,
                 "service":self.service,
                 "version":self.version,
+                "state":self.state,
                 }
 
 
@@ -46,6 +47,15 @@ class Host:
     hostname = ""
     ports = [] # Array of Port() items
 
+    def merge_ports(self, host):
+
+        local_ports = [p.port_number for p in self.ports]
+        for p in host.ports:
+            if p.port_number not in local_ports:
+                self.ports.append(p)
+
+
+
     def todict(self, full):
         return {
                 "ip":self.ip,
@@ -68,25 +78,30 @@ def open_gnmap(filename):
 def parse_line(line):
     global hosts
 
-    # split line into different fields
+    # Create new Instance
+    host = Host()
+    host.ports = [] # needs to get reset
+
+    # Split line into different fields
     fields = line.split("\t")
 
     # parse the different fields
-    out_host = parse_fields(fields)
-    merge_hosts(out_host)
+    parse_fields(host, fields)
 
+    # merge known hosts
+    merge_hosts(host)
+    # delete instance
+    del host
 
-def parse_host_field(field):
 
-    host = Host()
+def parse_host_field(host, field):
     subfields = field.split(" (")
     host.ip = subfields[0]
     host.hostname =subfields[1].replace(")", "")
     if DEBUG: print(f"DEBUG: parse_host_field::ip={host.ip};hostname={host.hostname}")
-    return host
 
 def parse_ports_field(host, field):
-    portlist = field.split("/,")
+    portlist = [s.strip() for s in field.split("/,")]
 
     # loop through the ports and append them to the host
     for p in portlist:
@@ -100,7 +115,7 @@ def parse_ports_field(host, field):
         port.sunRPCinfo = portparts[5]
         port.version = portparts[6]
         host.ports.append(port)
-    return host
+        del port
 
 def parse_status_field(host, field):
     host.status = field
@@ -109,7 +124,6 @@ def parse_status_field(host, field):
 
 # Jumptable for the different fields
 field_parser = {
-        "Host": parse_host_field,
         "Ports": parse_ports_field,
         "Status": parse_status_field,
 }
@@ -124,29 +138,30 @@ def merge_hosts(host):
     global hosts
 
     for ih in hosts:
+        # hosts already present in list
         if ih.ip == host.ip:
-            ih.ports = host.ports
+            ih.merge_ports(host)
             break
     else:
         hosts.append(host)
 
 # parsed the different fields, each separeted by a space
-def parse_fields(fields):
+def parse_fields(host, fields):
 
     # create a Host instance
-    host = Host()
-
     # loop each field that is present
     for field in fields:
-        field_type, field_value = field.split(": ")
+        field_parts = field.split(": ")
+        field_type = field_parts[0]
+        field_value = "".join(field_parts[1:])
 
         if DEBUG: print(f"DEBUG: field_type={field_type}")
         if DEBUG: print(f"DEBUG: field_content={field_value}")
         # Host Field is the most important one
         if field_type == "Host":
-            host = parse_host_field(field_value)
+            parse_host_field(host, field_value)
         else:
-            host = field_parser.get(field_type, not_implemented)(host, field_value)
+            field_parser.get(field_type, not_implemented)(host, field_value)
 
     return host