What's the most Pythonic way to create a list of the addressable IP addresses given a netaddr IPRange or netaddr IPNetwork.
If I use these, then it includes subnet and broadcast addresses:
hosts = list(IPRange('212.55.64.0','212.55.127.255'))
hosts = IPNetwork('192.168.0.1/24')
So what I need for say IPNetwork(192.168.0.0/27) is a list from 192.168.0.1 to 192.168.0.31 note that 192.168.0.0 and 192.168.0.32 must not be included.
EDIT
Thanks for info on how to do it with IPy. Does anybody know if it can be done with netaddr?
The following is a quick script to do what you want using netaddr
(Python 2.7, linux)
from netaddr import *
def addr(address, prefix):
ip = IPNetwork(address)
ip.prefixlen = int(prefix)
return ip
myip = addr('192.168.0.0', '27')
for usable in myip.iter_hosts():
print '%s' % usable
After doing a bit of research I found this way:
l = list(netaddr.IPNetwork('192.168.0.0/27').iter_hosts())
Related
I did find this function on stackoverflow which extract hostname, aliaslist, and ipaddrlist,
but how can I make a function which take a hostname and search all the websites associated with it (hosted by it)?
>>> import socket
>>> def get_ips_for_host(host):
try:
ips = socket.gethostbyname_ex(host)
except socket.gaierror:
ips=[]
return ips
>>> ips = get_ips_for_host('www.slowtravelmagazine.com')
>>> print(repr(ips))
('ext-cust.squarespace.com', ['www.slowtravelmagazine.com'],
['198.185.159.144', '198.185.159.145', '198.49.23.144',
'198.49.23.145'])
You can't. At least not with a built in function. You would need a datasource that contains all websites with their associated IP addresses.
There are probably some providers out there that have an API for this.
Im having a file with ip address in this format
192.168.1.9
192.168.1.10
192.168.1.8
that i read to a list like this
with open("file.txt") as f:
ipaddr = f.read().splitlines()
And then run some functions on.
However, i would also be able to put in network address in this document as in
192.168.0.0/25 and somehow get them translated in the list as
192.168.0.1
192.168.0.2
192.168.0.3
I dont even have a clue how to accomplish this? (running Python 2.6)
The netaddr is one of the best ways to do this:
import netaddr
with open('file.txt') as f:
for line in f:
try:
ip_network = netaddr.IPNetwork(line.strip())
except netaddr.AddrFormatError:
# Not an IP address or subnet!
continue
else:
for ip_addr in ip_network:
print ip_addr
For the example file of:
10.0.0.1
192.168.0.230
192.168.1.0/29
The output it gives is:
10.0.0.1
192.168.0.230
192.168.1.0
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.5
192.168.1.6
192.168.1.7
You need to parse your text file with a regular expression. Look up for the 're' module in Python. A quick implementation of this idea is:
import re
with open("ips.txt") as f:
ip_raw_list = f.read().splitlines()
#Only takes the string after the '/'
reg_ex_1 = r'(?<=/)[0-9]*'
#Only take the first three numbers "0.0.0" of the IP address
reg_ex_2 = r'.*\..*\..*\.'
ip_final_list = list()
for ip_raw in ip_raw_list:
appendix = re.findall(reg_ex_1, ip_raw)
#Ip with no backslash create on input
if not appendix:
ip_final_list.append(ip_raw)
#Ip with backslash create several inputs
else:
for i in range(int(appendix[0])):
ip_final_list.append(re.findall(reg_ex_2, ip_raw)[0] + str(i))
This code uses the power of regular expression to separate IPs of the form '0.0.0.0' from IPs of the form '0.0.0.0/00'. Then for IPs of the first form, you put the IP directly on the final list. For IPs of the second for, you run a for loop to put several inputs in the final list.
I'd like to get full path of my directory, something like:
//192.168.1.23/D/test/test/aaaa/
or
//192.168.1.23/D:/test/test/aaaa/
How can I get QFileDialog to give me the IP address of the HDD that I have selected?
Currently using
self.project= str(QtGui.QFileDialog.getExistingDirectory(self, "Select Directory", lastDir))
tried going via os.path.dirname(self.project) but that only ever goes down to D:\
Thanks!
What you want to do is not possible in PyQt directly with QFileDialog what you can do instead is to get the ip address of your machine with another method and then concatenate that with the file path, something like this. QFileDialog isn't 'Network aware'
import socket
def get_ip_addr():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
return s.getsockname()[0]
ip = get_ip_addr()
path = self.project= str(QtGui.QFileDialog.getExistingDirectory(self, "Select Directory", lastDir))
file_path = '//{}/{}'.format(ip, path) # or what ever formatting suits you
You can also take a look at QNetworkInterface http://pyqt.sourceforge.net/Docs/PyQt4/qnetworkinterface.html#interfaceFromName if you're interested in other addresses on your machine, but the example above just returns the ip address that's used to route to 8.8.8.8
Not sure where I found it but here is the option I followed at the end. I let user decide then which device to use for location
from netifaces import interfaces, ifaddresses, AF_INET
p =[]
for ifaceName in interfaces():
addresses = [i['addr'] for i in ifaddresses(ifaceName).setdefault(AF_INET, [{'addr':'No IP addr'}] )]
p.append(ifaceName.join(addresses))
print p[0],p[1]
print p
The user will input either hostname or the IP address. If the user enters the IP address, I want to leave as it is but if the user enters the hostname I want to convert it into IP address using the following method:
def convert(hostname):
command = subprocess.Popen(['host', hostname],
stdout=subprocess.PIPE).communicate()[0]
progress1 = re.findall(r'\d+.', command)
progress1 = ''.join(progress1)
return progress1
How do I do it?
To get ip whether input is ip or hostname:
ip4 = socket.gethostbyname(ip4_or_hostname)
you can use a regex to match your input and test if it is a ip address or not
test = re.compile('\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b')
result = test.match(hostname)
if not result:
# no match -> must be an hostname #
convert(hostname)
that regex allows invalid ip addresses (like 999.999.999.999) so you may want to tweak it a bit, it's just a quick example
There are a number of questions on stackoverflow already about validating an IP address.
IP Address validation in python
Validating IP Addresses in python
I would like to ask why you are communicating with a subprocess when you can do this within the standard python library.
I would recommend resolving a host name into a IP address by using some of pythons built in functionality.
You can do this by importing and using the python sockets library
For example using the code found in link 1:
import socket
import re
regex = re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
result = regex.match(address)
if not result:
address = socket.gethostbyname(address)
In my case, host name can only contain - as a separator. So you can uncomment and use it according to your requirement.
import re
regex = "^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$"
# string_check= re.compile('[#_!#$%^&*()<>?/\|}{~:.]')
string_check= re.compile('[-]')
ip_host_detail = {}
def is_valid_hostname_ip(IpHost):
# pass regular expression and ip string into search() method
if (re.search(regex, IpHost)):
print("Valid Ip address")
ip_host_detail['is_ip'] = 'True'
ip_host_detail['is_hostname'] = 'False'
return True
elif(string_check.search(IpHost)):
print("Contain hostname")
ip_host_detail['is_hostname'] = 'True'
ip_host_detail['is_ip'] = 'False'
return True
else:
print("Invalid Ip address or hostname:- " + str(IpHost))
ip_host_detail['is_hostname'] = 'False'
ip_host_detail['is_ip'] = 'False'
return False
IpHost = sys.argv[1]
# IpHost = 'RACDC1-VM123'
is_valid_hostname_ip(IpHost)
print(ip_host_detail)
On my linux machine, 1 of 3 network interfaces may be actually connected to the internet. I need to get the IP address of the currently connected interface, keeping in mind that my other 2 interfaces may be assigned IP addresses, just not be connected.
I can just ping a website through each of my interfaces to determine which one has connectivity, but I'd like to get this faster than waiting for a ping time out. And I'd like to not have to rely on an external website being up.
Update:
All my interfaces may have ip addresses and gateways. This is for an embedded device. So we allow the user to choose between say eth0 and eth1. But if there's no connection on the interface that the user tells us to use, we fall back to say eth2 which (in theory) will always work.
So what I need to do is first check if the user's selection is connected and if so return that IP. Otherwise I need to get the ip of eth2. I can get the IPs of the interfaces just fine, it's just determining which one is actually connected.
If the default gateway for the system is reliable, then grab that from the output from route -n the line that contains " UG " (note the spaces) will also contain the IP of the gateway and interface name of the active interface.
the solution is here : http://code.activestate.com/recipes/439093-get-names-of-all-up-network-interfaces-linux-only/
import fcntl
import array
import struct
import socket
import platform
"""
global constants. If you don't like 'em here,
move 'em inside the function definition.
"""
SIOCGIFCONF = 0x8912
MAXBYTES = 8096
def localifs():
"""
Used to get a list of the up interfaces and associated IP addresses
on this machine (linux only).
Returns:
List of interface tuples. Each tuple consists of
(interface name, interface IP)
"""
global SIOCGIFCONF
global MAXBYTES
arch = platform.architecture()[0]
# I really don't know what to call these right now
var1 = -1
var2 = -1
if arch == '32bit':
var1 = 32
var2 = 32
elif arch == '64bit':
var1 = 16
var2 = 40
else:
raise OSError("Unknown architecture: %s" % arch)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
names = array.array('B', '\0' * MAXBYTES)
outbytes = struct.unpack('iL', fcntl.ioctl(
sock.fileno(),
SIOCGIFCONF,
struct.pack('iL', MAXBYTES, names.buffer_info()[0])
))[0]
namestr = names.tostring()
return [(namestr[i:i+var1].split('\0', 1)[0], socket.inet_ntoa(namestr[i+20:i+24])) \
for i in xrange(0, outbytes, var2)]
print localifs()