How to efficiently ignore unassigned parent ip address networks? - python

I am crawling through the ARIN whois API to find all network ranges. The code below takes a starting IP address, sends it to ARIN, and returns the ending IP address of that network. That ending address is then incremented by one, and this new value becomes the next address sent to ARIN. This works well, but it is inefficient when ISPs have swaths of unassigned addresses because each starting address has to be checked until another assigned network is found.
The code is a self-contained example that shows how there are a few network ranges assigned, and then a period of addresses that are unassigned by AT&T. How should these unassigned networks be checked without checking each and every address?
import requests
from ipaddress import ip_address
IPAddress = str.replace('12.31.71.56','.','-')
while True:
try:
url = 'https://whois.arin.net/rest/net/NET-' + IPAddress + '-1.json'
request = requests.get(url)
response = request.json()
endAddress = response['net']['endAddress']['$']
IPAddress = str.replace((ip_address(endAddress) + 1).compressed,'.','-')
print(IPAddress)
print(response['net']['orgRef']['#name'])
except ValueError:
IPAddress = str.replace(IPAddress,'-','.')
IPAddress = str.replace((ip_address(IPAddress) + 1).compressed,'.','-')
print(IPAddress)
if IPAddress == '12-31-71-150':
break

Related

Why the ip address captured by HTTP_X_FORWARDED_FOR is diferrent from the address shown in the device

I want some clarification regarding IP address captured by HTTP_X_FORWARDED_FOR. In my website I am storing the IP address of the visitors to count the number of visits.
The code that I am using for this is this function is used to capture the IP:
def get_ip(request):
try:
ip_forward = request.META.get('HTTP_X_FORWARDED_FOR')
if ip_forward:
ip = ip_forward.split(",")[0]
print("returning forwarded for ip address", ip)
elif request.META.get('HTTP_X_REAL_IP'):
ip = request.META.get('HTTP_X_REAL_IP')
print ("returning REAL_IP ", ip)
else:
ip = request.META.get('REMOTE_ADDR')
print("returning remote address ", ip)
except:
ip= ""
return ip
after the above function is called on the index view it is then passed to this function for storing the IP:
def visitor_count(ip):
visitor = VisitorCount()
visitor.ip = ip
visitor.date_of_record = datetime.now()
if VisitorCount.objects.all().filter(ip = visitor.ip ,date_of_record__icontains= datetime.today().date()).exists():
pass
print("the ip", visitor.ip,"recorded on", visitor.date_of_record ,"already exists and wil not be saved")
else:
print('this is the ip address of the user that has been saved', visitor.ip)
visitor.save()
return "saved"
as you can see it prints what it is doing. My site is hosted in heroku (if that matters). I went through some SatckOverflow questions but could not find an ans to what I wanted to.
Now, suppose when I am going to the site, and check the logs in heroku, I find this:
"returning forwarded for ip address 103.38.89.218"
where as my IP address shown in the device is 192.168.3.1. Thus the IP address that eventually gets stored is 103.38.89.218.
Why is this so? Why it is not capturing the address shown by my device. Or to be specific how to capture the IP address shown in my device.
And out of curiosity I want to ask, if some day I want to block the access to my site from users coming form certain IP address, will I be needing the address shown by my device or the one captured by HTTP_X_FORWARDED_FOR will do the work.

How can i get http requests in python 3 and have the program sort the status codes

I have a list of cidr notations and i have a python program that generates a list of ip adress from the cidr notation.Here is the program
from netaddr import IPNetwork
for ip in IPNetwork('104.24.0.0/6'):
print ('%s' % ip)
But i want to make the program loop through each of the ip adress and send http requests then search for some specific status code and if it finds the required status code it should return which ip adress has that status code
Try this:
import requests
from netaddr import IPNetwork
required_status_code = 200 # your required status code goes here
for ip in IPNetwork('104.24.0.0/6'):
resp = requests.get(f'http://{ip}')
if resp.status_code == requires_status_code:
print (f'ip {ip} matches required status code!')

Filtering / Labeling Print Results for Device Identification by MAC Address in a Python / Scapy Network Scanner

I'm a beginner, but I am trying to make a network scanning utility that can filter MAC addresses for a specific need; The company I work for has network connected devices that are assigned MAC addresses based on serial numbers. I have found that the first 6 digits of the MAC address are the indicator of our brand. This I have made into a str below. The 4th field of the MAC address is a small range of constant numbers that indicate the model of the device. I have these ready but its essentially a few numbers like '14', '17,' etc.
I'm struggling to figure out a way to "filter" the MAC addresses that are retrieved from the scan and label them depending on the fields of the address. OR even better, only print IP's and Mac addresses that match the startswith(mac_key) and label the remaining objects according to their MAC address 4th field [9:11].
With a lot of reading and help, I've got this so far:
#!/usr/bin/env python
from scapy.all import ARP, Ether, srp
import socket
# importing main functions from Scapy and Socket
mac_key = '04:24:2f'
# Target value for first three fields of MAC address
hostname = socket.gethostname()
IPAddr = socket.gethostbyname(hostname)
target_ip = ("192.168.{}.0/24".format(IPAddr[6]))
# Assigning index value for third section of IP address
# To make third section of target_ip a variable determined by host
# "/24" denotes IP address spectrum for the ARP packet destination
arp = ARP (pdst=target_ip)
# Creating ARP packet assigned to "target_ip"
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
# Creating Ether broadcast packet
# ff:ff:ff:ff:ff:ff MAC address indicates broadcasting
packet = ether/arp
# Stacking
result = srp(packet, timeout=5, verbose=3)[0]
# Defining result with timeout parameter
clients= []
# Client list to be finished below
for sent, received in result:
clients.append({'ip': received.psrc, 'mac': received.hwsrc})
# For each response, append ip and mac address to 'clients' list
print("Devices On This Network:")
print("IP" + " "*18+"MAC")
# Print table of accumulated data
for client in clients:
print("{:24} {}".format(client['ip'], client['mac'].startswith(mac_key)))
# Printing IP addresses and assosciated MACs from clients list
# With bool checking against mac_key
The image below is the result in terminal; the idea would be to only print lines that show a value of TRUE and to add a label based on field [9:11] of the MAC address ex: "Network Device Pro" where the TRUE bool appears, and completely omit the line where a FALSE bool is triggered.
EDIT: Well, I've turned this into a blog at this point. I managed to do exactly what I wanted to do, and I will provide the code below for anyone who is trying to do something similar. I am open to any suggestions to make this more 'pythonic' and improve performance / syntax. I do have one question for anyone who can offer some advice; I want to loop this code and append information to the rendered list and include a user input kill switch to finish it off. This way if a packet does not reach on the first scan, it will still be added to the list. Bonus points if you can offer a suggestion for this, as well as a way to remove entries that don't respond after a consecutive number of loops!!
#!/usr/bin/env python3
# coding: utf-8
#
#
#//////////////////////////////////
#----------------------------------
# ippy Network Scanning Utility
# ~ Daniel Johnston 2020 ~
#----------------------------------
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#
#
print("Initializing Scan...")
from scapy.all import ARP, Ether, srp
import socket
# importing main functions from Scapy and Socket
mac_key = ('00:25:2f')
# Target value for first three fields of MAC address (Brand Identifier)
MTU_key = ('13','15','16','17')
GW_key = ('21')
ECC_key = ('26')
#------serial numbers)------#
#('13','15','16','17','21','26'#
#---------LEGEND------------#
#serial numbers[0:3] = 'MTU'
#serial numbers[4] = 'Gateway'
#serial numbers[5] = 'ECC'
#---------------------------#
hostname = socket.gethostname()
IPAddr = socket.gethostbyname(hostname)
target_ip = ("192.168.{}.0/24".format(IPAddr[6]))
# Assigning index value for third section of IP address
# To make third section of target_ip a variable determined by host
# "/24" denotes IP address spectrum for the ARP packet destination
def devsub(x):
if x.startswith(MTU_key, 9, 11):
print("{} {}".format('MTU', client['ip'],))
if x.startswith(GW_key, 9, 11):
print("{} {}".format('Gateway', client['ip'],))
if x.startswith(ECC_key, 9, 11):
print("{} {}".format('ECC', client['ip'],))
# Defining function to print associated IP addresses, of MAC address
# Matches(done later), and assigning a device name based on
# index[9:11] of MAC
arp = ARP (pdst=target_ip)
# Creating ARP packet assigned to "target_ip"
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
# Creating Ether broadcast packet
# ff:ff:ff:ff:ff:ff MAC address indicates broadcasting
packet = ether/arp
# Stacking
result = srp(packet, timeout=5, verbose=3)[0]
# Defining result with timeout parameter
clients= []
# Client list to be finished below
for sent, received in result:
clients.append({'ip': received.psrc, 'mac': received.hwsrc})
# For each response, append ip and mac address to 'clients' list
print("~"*20)
print("-"*20)
print("Devices On This Network:")
print("-"*20)
print("Device" + " " * 4 + "IP Address")
#Text formatting
for client in clients:
if client['mac'].startswith(mac_key):
devsub(client['mac'])
#Running primary filter to only include MAC addresses that pass
# .startswith(mac_key) into devsub function to print device name
# Associated with MAC[9:11] variables, and the appropriate IP address
So this is the current output, with 1 matching device
It makes more sense to use scapy builtins than rewrite them. In this case, use arping. To save yourself time as you work with scapy (like here), you should read the manual.
This will print the 4th octets to a file:
from scapy.all import arping
local_devices = arping("192.168.1.0/24")
local_macs = [device[1].src for device in local_devices[0]]
fourth_octets = [mac[9:11] for mac in local_macs]
with open("fourth_octets.txt", "w") as f:
f.write("\n".join(fourth_octet))
Explanation in Scapy Interpreter
>>> # Get local devices. Four have been found, and 252 provided no answer.
>>> local_devices = arping("192.168.128.0/24")
>>> local_devices
(<ARPing: TCP:0 UDP:0 ICMP:0 Other:4>,
<Unanswered: TCP:0 UDP:0 ICMP:0 Other:252>)
>>> # Get the mac addrs of each of the ARP responses with a list comprehension
>>> local_macs = [device[1].src for device in local_devices[0]]
>>> local_macs
['e0:55:3d:4d:e4:58',
'00:18:0a:27:26:ee',
'e0:55:3d:d2:0a:12',
'38:53:9c:08:b9:9f']
>>> # Get the fourth octet by string position in the macs
>>> fourth_octets = [mac[9:11] for mac in local_macs]
>>> fourth_octets
['4d', '27', 'd2', '08']
>>> # Write to the file with the fourth octets, each on a line
>>> with open("fourth_octets.txt", "w") as f:
f.write("\n".join(fourth_octets))
>>> # Verify that the text file looks as expected
>>> with open("fourth_octets.txt") as f:
print(f.read())
4d
27
d2
08

How do I change Network Adapter settings based on input from user on which adapter?

UPDATE: Lots of updates to this question as I've figured out how to get the Index of the NIC, but it's not allowing me to set the IP. What am I missing where it won't accept the IP settings when I tried to apply it?
I'm needing to script a method to change network adapter settings in Python 3.7, but base it on user input where it lists all network adapters on the laptop and the user then chooses the correct adapter.
I've been using the WMI module and have tried many different ways to make this work with no luck. I can get a list of enumerated adapters and then provide input. I just cannot get this chosen adapter number translated to the WMI found network adapter.
import wmi
#List NICs by Index and Description
c = wmi.WMI()
for nic in c.Win32_NetworkAdapterConfiguration(IPEnabled=True):
print(nic.Index, nic.Description)
#Choose which NIC to apply changes to:
nic_selection_index = c.Win32_NetworkAdapterConfiguration(Index = input('Choose Network Adapter Number on left to change: '))
#Will be hidden once working
print(nic_selection_index)
#Get IP Info to use on NIC
ip = input('Enter IP to use: ')
subnetmask = input('Enter Subnet Mask to use: ')
gateway = input('Enter Default Gateway to use: ')
print(ip)
print(subnetmask)
print(gateway)
## Set IP address, subnetmask and default gateway
## Note: EnableStatic() and SetGateways() methods require *lists* of values to be passed
nic_selection_index.EnableStatic(IPAddress=[ip],SubnetMask=[subnetmask])
nic_selection_index.SetGateways(DefaultIPGateway=[gateway])
#Results:
Traceback (most recent call last):
File "test nic change.py", line 56, in <module>
nic_selection_index.EnableStatic(IPAddress=[ip],SubnetMask=[subnetmask])
AttributeError: 'list' object has no attribute 'EnableStatic'
I've referenced other questions that are setting the IP but they're not setting it based on user input that I put in. I need to be able to prompt the user for the information. Thanks!!
All, I was able to get this working, even adding in some DNS changes as well. I'm posting in case anyone else is ever looking for this exact need.
import wmi
#List NICs by Index and Description
c = wmi.WMI()
for nic in c.Win32_NetworkAdapterConfiguration(IPEnabled=True):
print(nic.Index, nic.Description)
#Choose which NIC to apply changes to:
nic_selection_index = c.Win32_NetworkAdapterConfiguration(Index = input('Choose Network Adapter Number on left to change: '))
#This selects the entire NIC properties -- can't just use the index value above
nic_selection_all = nic_selection_index[0]
#Will be hidden once working
print(nic_selection_all)
#Get IP Info to use on NIC
ip = input('Enter IP to use: ')
subnetmask = input('Enter Subnet Mask to use: ')
gateway = input('Enter Default Gateway to use: ')
dns = '127.0.0.1'
print(ip)
print(subnetmask)
print(gateway)
## Set IP address, subnetmask and default gateway
## Note: EnableStatic() and SetGateways() methods require *lists* of values to be passed
nic_selection_all.EnableStatic(IPAddress=[ip],SubnetMask=[subnetmask])
nic_selection_all.SetGateways(DefaultIPGateway=[gateway])
nic_selection_all.SetDNSServerSearchOrder([dns])
nic_selection_all.SetDNSDomain("my.random.domain")

Python DNS lookup: How to format a type AAAA (ipv6) bytearray response

Given the name of a domain, type of record, and address of a DNS server the program must return the ip address of the given domain. The parse answer method presented in this code takes a python byte array as its parameter and is able to handle ipv4 responses.
def parse_answer(self, msg_resp):
length = msg_resp[msg_resp.index(0xc0) + 11]
addr = msg_resp[len(msg_resp)-length:]
address = ""
for i in range(length):
address = address + str(addr[i]) + "."
return address.strip(' . ')
When the implementation is presented with a request for google.com in ipv6 format, Wireshark returns that the ipv6 address of the site is 2607:f8b0:4009:808::200e as well as the following byte array:
The parse_answer method returns:
38.7.248.176.64.9.8.8.0.0.0.0.0.0.32.14

Categories