Networking with Scapy

goliathusdesigner

Junior Member
Nov 22, 2020
4
0
6
Hi all,

I recently just started taking up Python and Scapy and am facing some difficulties with the script structure.
1606099291165.png



I was presented with creating a script with these requirements, but I'm unable to make it run so that "-verbose" input changes verbose=0, to verbose=1.
That as well with the output of the list of IP addresses being scanned. Right now, it is only printing out whatever I typed (e.g. 192.168.1.1/24 instead of a list)

This is my current script.
Code:
from scapy.all import *
import sys

#If user just run script
if len(sys.argv) == 1:
    verbose = 0
    user_input=input("Press R to Retry, -v for Verbose, or -help for assistance: ")
    if user_input == "R":
        destIPs=input("Enter IP Address: ")
        pac = IP(dst=destIPs) / ICMP()
        ans, unans = sr(pac, timeout=0.5, verbose=0)
        ans.summary()

        f = open("Network Summary.txt", "w")
        print(destIPs, ans, unans, file=f)
        f.close()
        sys.exit()
    elif user_input == "-help":
        print("To use this script, enter an IP address or IP range to scan. "
              "-verbose brings up the processes of sending/receiving packets")
        sys.exit()
    elif user_input == "-verbose":
        verbose = 1
    if verbose == 1:
        print("Showing processes...")
        destIPs = input("Enter IP Address: ")
        pac = IP(dst=destIPs) / ICMP()
        ans, unans = sr(pac, timeout=0.5, verbose=0)
        ans.summary()

        f = open("Network Summary.txt", "w")
        print(destIPs, ans, unans, file=f)
        f.close()
        sys.exit()






#If user runs script + IP Address
elif len(sys.argv) == 2:
    pac = IP(dst=sys.argv[1]) / ICMP()
    ans, unans = sr(pac, timeout=0.5, verbose=0)
    ans.summary()
    f = open("Network Scan Results.txt", "w")
    print(sys.argv[1], ans, unans, file=f)
    f.close()




verbose = 0

Please help me figure this out as I've been doing my head in for the past 2 weeks trying to create something out of nothing.
 

mxnerd

Diamond Member
Jul 6, 2007
6,799
1,103
126
Not familiar with either Python or Scapy, but I'm a bit interested in the topic so I did some study and wrote partial code. You have to finish the code yourself.

scanner.py
Python:
import ipaddress
import sys
from scapy.all import *

def is_ipv4(s):
        try:
#https://docs.python.org/3/library/ipaddress.html
            ipaddress.ip_address(s)
            #Return an IPv4Address or IPv6Address object depending on the IP address passed as argument.
            #A ValueError is raised if address does not represent a valid IPv4 or IPv6 address.
            #valid IP
            return True
        except ValueError:
            return False

def is_ipv4network(s):
        try:
#https://docs.python.org/3/library/ipaddress.html
            ipaddress.ip_network(s)
            #Return an IPv4Network or IPv6Network object depending on the IP address passed as argument.
            #A ValueError is raised if address does not represent a valid IPv4 or IPv6 address, or if the network has host bits set.
            #valid CIDR
            return True
        except ValueError:
            return False

if len(sys.argv) == 1 or \
    len(sys.argv) >= 3 or \
    '-help' in sys.argv or \
    'pythonw.exe' in sys.executable:
    print('Usage: python', sys.argv[0],  'IP address   or')
    print('       python', sys.argv[0],  'IP range using CIDR notation\n')
    sys.exit()

ipstr = sys.argv[1]

#if len(sys.argv) >= 2 then continue
if is_ipv4(ipstr):
        CIDR = False
elif is_ipv4network(ipstr):
        CIDR = True
else:
    print ('invalid IP or CIDR')
    sys.exit()

if '-verbose' in sys.argv:
    bool_verbose = True
else:
    bool_verbose = False

#print header line
width = 30
linestr = "+" + "-" * (width-2) + "+"
print ( linestr )
print ( "|" + str(ipstr).center(width-2, " ") + "|" )

if CIDR:
    #loop through all hosts in a network
    print ( linestr )
    for host_ip in ipaddress.IPv4Network(ipstr).hosts():
        p = IP(dst = host_ip) / ICMP()
        #sr() will return 2 lists
        ans, unans = sr(p, timeout = 1, verbose = bool_verbose)
        #print ('SR:', ans, unans, '\n')
        lstr = "|" + str(host_ip).center(int(width/2), " ") + "|"
        if ans:
            print (lstr , '    UP     |')
        else:
            print (lstr , '   DOWN    |')
        print( linestr )

else:
    print ( linestr )
    host_ip = ipstr
    p = IP(dst = host_ip) / ICMP()
    ans, unans = sr(p, timeout = 1, verbose = bool_verbose)
    #print (ans, unans, '\n')
    lstr = "|" + str(host_ip).center(int(width/2), " ") + "|"
    if ans:
        print (lstr , '    UP     |')
    else:
        print (lstr , '   DOWN    |')
    print ( linestr )

192.168.0.1 is my router gateway
192.168.0.20 is my PC
and no machine with IP 192.168.0.2

don't know why it got different responses in different situations.

Code:
C:\script>python scanner.py 192.168.0.1
+----------------------------+
|        192.168.0.1         |
+----------------------------+
|  192.168.0.1  |     UP     |
+----------------------------+

C:\script>python scanner.py 192.168.0.2
+----------------------------+
|        192.168.0.2         |
+----------------------------+
|  192.168.0.2  |    DOWN    |
+----------------------------+

C:\script>python scanner.py 192.168.0.20
+----------------------------+
|        192.168.0.20        |
+----------------------------+
|  192.168.0.20 |    DOWN    |
+----------------------------+

C:\script>python scanner.py 192.168.0.0/30
+----------------------------+
|       192.168.0.0/30       |
+----------------------------+
|  192.168.0.1  |    DOWN    |
+----------------------------+
|  192.168.0.2  |    DOWN    |
+----------------------------+

C:\script>python scanner.py
Usage: python scanner.py IP address   or
       python scanner.py IP range using CIDR notation

C:\script>python scanner.py -help
Usage: python scanner.py IP address   or
       python scanner.py IP range using CIDR notation
 
Last edited: