Search code examples
pythonsubprocessoutputnmap

Python subprocess nmap output different from terminal command


I'm trying to use the output of nmap command in linux (shell output):

sudo nmap -sn 192.168.1.0/24
------
Nmap scan report for 192.168.1.98
Host is up (0.094s latency).
MAC Address: B8:27:EB:CE:0A:9F (Raspberry Pi Foundation)

In a python script via subprocess:

import subprocess
p = subprocess.Popen(["nmap", "-sn", "192.168.1.0/24"], stdout=subprocess.PIPE)
output, err = p.communicate()
print ("*** Running nmap -sn 192.168.1.0/24 ***\n", output)

Which works pretty well except from the fact that I NEED the MAC line that shell output has and subprocess doesn't.

subprocess output:

\nNmap scan report for 192.168.1.98\nHost is up (0.015s latency).\n

I'm working on an idea of getting IP via MAC/Name and I can't see how to do it without that line...


Solution

  • You don't need to run nmap as a subprocess in python, You can just install the nmap library and import it.

    pip install python-nmap
    

    Then write your code:

    import json
    import nmap
    
    np = nmap.PortScanner()
    
    target = '192.168.1.0/24'
    
    # Scan the subnet 
    results = np.scan(hosts=target, arguments='-sn')
    
    # Clean the data nmap returns
    results = results['scan']
    output = {}
    for result in results:
        output[result] = {}
        # Add the MAC addr to the IP
        try:
            output[result]['mac']       = results[result]['addresses']['mac']
        except:
            output[result]['mac']       = 'No MAC address avalible'
        # Add the vendor to the IP
        try:
            output[result]['vendor']    = list(results[result]['vendor'].values())[0]
        except:
            output[result]['vendor']    = 'No vendor info avalible'
    
    print(json.dumps(output,indent=2))
    

    When you run your code you have to run it as sudo or else you wont get the MAC addresses.

    Output should look like this

    {
      "192.168.1.1": {
        "mac": "16:91:82:xx:xx:xx",
        "vendor": "No vendor info avalible"
      },
      "192.168.1.10": {
        "mac": "44:39:C4:xx:xx:xx",
        "vendor": "Universal Global Scientific Industrial"
      },
      "192.168.1.50": {
        "mac": "No MAC address avalible",
        "vendor": "No vendor info avalible"
      }
    }
    

    I hope it was helpful :-)