Referencing range of IP addresses - python

I am trying to specify a range of addresses that will be set every time an API is called. For the example below, when api is referenced, I would like it to hosts in the range to a list, and not just one as it currently does.
api = xmlrpclib.ServerProxy("http://user:pass#192.168.0.1:8442/")
Generating the addresses seems straightforward enough, but I am unsure how to store it so that when api is reference, it's sends to every host, e.g. 192.168.0.1 - 192.168.0.100 and not just one.
for i in range(100):
ip = "192.168.0.%d" % (i)
print ip
I would also like to be able to specify the range, e.g. 192.168.0.5 - 192.168.0.50 rather then incrementing from zero.
Update: The API does not handle a list very well so the solution need to be able to parse the list. Might this simply require a second for statement?

If you want a different range:
for i in range(5,51):
ip = "192.168.0.%d" % (i)
print ip
Not sure what you mean by setting multiple. That for loop is doing that for you. If you're talking about saving references of your api, you can also throw those into a list.
api = []
for i in xrange(5,51):
ip = "192.168.0.%d" % (i)
api.append(xmlrpclib.ServerProxy("http://user:pass#" + ip))

Related

How to remove/exclude unwanted objects from a list in python

Hi I am trying to get the IP of every interface on my machine using netifaces in python. I am still new to python and working my way through some concepts but it seems like I can query every NIC at once and then put the results into a list the problem is my end goal is to ask the user which network to work on and I want to exclude everything that returns 'No IP addr'.
I have already tried a few different methods including removing strings from the list and that didnt work or only adding IP addresses objects but im pretty sure im not doing it properly since it still errors out. Any help is appreciated.
import os
import socket
from netifaces import interfaces, ifaddresses, AF_INET
def get_self_IP():
for ifaceName in interfaces():
addresses = []
possibilities = [i['addr'] for i in ifaddresses(ifaceName).setdefault(AF_INET, [{'addr':'No IP addr'}] )]
print(' '.join(possibilities))
for i in possibilities:
if isinstance(i, ifaddress.ipaddress): # if i is an IP address
addresses.append(i)
print(addresses)
Also I have two lists now because ive changed it a few times to troubleshoot but if I can keep it as one list and only .append the IPs to it while its gathering IPs rather than have to do an entire separate list with a separate for or if loop it would be ideal but I do not know another way unfortunately.
Not sure if this is what you want, but:
I changed the function to:
def get_self_IP():
addresses = []
for ifaceName in interfaces():
ifaddresses_list = ifaddresses(ifaceName)
possibilities = [i['addr'] for i in ifaddresses_list.setdefault(AF_INET, [{'addr': 'No IP addr'}])]
for i in possibilities:
if ifaddresses_list[2][0]['addr'] != "No IP addr":
addresses.append(i)
print(addresses)
The ifaddresses(ifaceName) returns a dictionary which apparently the key 2 contains the IP address in the index 0 with the key 'addr', which in case the IP doesn't exist the value is No IP addr. In that the if checks if that is not the case and then adds the IP address to the addresses list.
If I didn't understand what you want clearly, please answer with more details :)

Trying to replace last 2 octets of ip address

I have the following ip address "192.168.2.65"
Is there a way to convert the last 2 octets to 0.
I found the following, but it only lets me replace the last one, i need to replace the last 2.
ip = 192.168.2.65
output='.'.join(ip.split('.')[:-1]+["0"])
print(output)
which gives me 192.168.2.0 and i would like to be 192.168.0.0
Index -1 means the last index. If you want to change two, change your index to -2.
output='.'.join(ip.split('.')[:-2]+["0", "0"])
You could also use a regex based approach here:
ip = "192.168.2.65"
output = re.sub(r'\.\d+\.\d+$', '.0.0', ip)
print(output) # prints 192.168.0.0
Dependant on the logic you are trying to apply.. if you are simply wanting to modify a string, the other answers are correct.
However, if you are looking to get the network address for the subnet an address resides in, you should handle the addresses correctly and use the ipaddress module.
This will assist in calculating the correct network & broadcast addresses, and allow you to check inclusions in networks etc.
import ipaddress
interface = IPv4Interface('192.168.2.35/255.255.0.0')
print(interface.network)
#192.168.0.0/16
print(interface.network.network_address)
#192.168.0.0
print(interface.network.broadcast_address)
#192.168.255.255

Python dictionary with a tuple and tuple count as the value

I have a .csv file:
csv file
containing packet header data from a wireshark scan that I am iterating through line by line with a for loop. The list contains around 100,000 items, many of which are repeated. I am trying to find how many times each destination IP address is accessed using TCP protocol(6) on each port ranging from 1 to 1024. Essentially I am trying to create something that looks like this:
{ip address: {(protocol:port):count}}
Where I will know how many times a combination of protocol/port tried to use the IP address as a destination. So far I've tried this:
dst = defaultdict(list)
for pkt in csvfile:
if(pkt.tcpdport > 0 and pkt.tcpdport < 1025):
tup = (pkt.proto, pkt.tcpdport)
dst[pkt.ipdst].append(tup)
When I try to print this out I get a list of IP addresses with the protocol, port tuple listed multiple times per IP address. How can I get it so that I show the tuple followed by a count of how many times it occurs in each dictionary entry instead?
Currently, the line dst[pkt.ipdst].append(tup) is telling python, get the value associated with the IP address, and then append the tuple to it. In this case, that means you're appending the tuple to the dictionary associated with the IP address. This is why you're seeing multiple tuples listed per IP address.
To fix this, simply change your line to dst[pkt.ipdst][tup] += 1. This is telling python to get the dictionary associated with the IP address, get the count associated with the tuple in that dictionary, and then add 1. When printed, this should appear as intended.
Also, define dst as defaultdict(lambda:defaultdict(dict)) so that in case the protocol,port combination hasn't been tried, it won't throw a KeyError.

Python - Create list of IPs based off starting IP

I spent a few hours researching, and this has stumped me. Before I go down a new path, I'm looking for a best practice.
I ultimately want a list of IPs (just the IPs) when given a starting IP, based off the quantity of items in a list.
I've been using the ipaddress module; here's the nearest I've gotten..
import ipaddress
IP_Start = 192.168.1.1
hostnames = [hostname1, hostname2, hostname3]
list_of_ips = []
my_range = range(len(hostnames))
for ips in my_range:
list_of_ips.append(ipaddress.ip_address(IP_Start) + my_range[ips])
print(list_of_ips)
Output:
list_of_ips = [IPv4Address('192.168.1.1'), IPv4Address('192.168.1.2'), IPv4Address('192.168.1.3')]
For some reason, I cannot strip "IPv4Address(' ')" out of the list of strings; my output may not be a traditional list. When using str.replace, I get weird errors and figure replacing is probably not the best practice.
I feel like if I ditch the ipaddress module, there would be a much simpler way of doing this. What would be a better way of doing this so my output is simply
list_of_ips = [192.168.1.1, 192.168.1.2, 192.168.1.3]
IPv4Address is the data type of the object returned. That is the name of a class; the display function for that class says that it returns the format you see, with the IP address as a string. You need to look up the class to find a method (function) or attribute (data field) to give you the IP address as a string, without the rest of the object tagging along.
The simplest way to do this is to convert to str:
for ips in my_range:
list_of_ips.append(str(ipaddress.ip_address(IP_Start)) ... )
Here is how to do it with builtins only
start with a function to convert an IP address to a long integer, and another function to convert a long integer back into an IP address
import socket,struct
def ip_to_int(ip_address):
return struct.unpack('!I', socket.inet_aton(ip_address))[0]
def int_to_ip(int_value):
return socket.inet_ntoa(struct.pack('!I', int_value))
then all you need to do is iterate over your range
def iter_ip_range(start_address, end_address):
for i in range(ip_to_int(start_address), ip_to_int(end_address) + 1):
yield int_to_ip(i)
and just use it
print(list(iter_ip_range("192.168.11.12","192.168.11.22")))

How to check an IP address is within a predefined list in python

Providing that I have this list which contains a number IP addresses:
IpAddresses = ["192.168.0.1","192.168.0.2","192.168.0.3","192.168.0.4"]
Then after receiving a packet I want to check if its source address is included in the predefined list IpAddresses
data, address = rxsocket.recvfrom(4096)
I have tried two alternatives, but both didn't work:
First:
if (address in IpAddresses):
do something
Then, I tried to convert address into string before making the comparison:
str_address = str(address)
if (str_address in IpAddresses):
do something
I am not familiar with python syntax, so please could you show me how to do this.
if address[0] in IpAddresses:
since the address object appears as a tuple only the 0th index appears in your list so you should check for its existence (also you can usually skip the parenthesis on an if statement unless it makes the if statement less readable)

Categories