If I enter IP “127“: I want to generate everything from 127.0.0.1 to 127.255.255.255
If I enter IP “127.0” I want to generate everything from 127.0.0.1 to 127.0.255.255
If I enter IP “127.0.0” I want to generate everything from 127.0.0.1 to 127.0.0.255
Using netaddr
Advertisement
Answer
The original question was based on bash.. if you just want the pure python implementation, scroll down:
I think your specific problem can probably be solved in bash with some pain, but here’s a stab at the general problem:
So, first of all it’s probably worth noting that not all the IP addresses in a particular range are valid host addresses. Specifically, the first and last addresses are reserved in IPv4 (network/broadcast).
Secondly, an IPv4 address, say 192.168.0.1, is really just a 32-bit/4-byte number that’s split into 4 chunks of 8-bit/1-byte each. You don’t have place the network/host portion split of the address on an 8-bit boundary though. 127.0.0.0/24 for example places the split at the third dot (24 bits in) and contains host addresses 127.0.0.1-254, but you can equally well split it 28 bits in, e.g. 127.0.0.0/28, which would contain hosts 127.0.0.1-14.
Thirdly, the “correct” way (I believe) to generate the data you are asking for, is by converting the IP address into binary, e.g. 127.0.0.1 = 01111111000000000000000000000001
, determine where your host/network split is (say it’s a /28), fix the first 28 bits, and then count up the binary number and then convert back to the dotted decimal representation if required:
01111111000000000000000000000001 = .1
---------fixed--------------**** ** variable
so you get:
01111111000000000000000000000010 = .2
01111111000000000000000000000011 = .3
etc.
Doing this in bash is of course a pain.
Now, if you have Python3 available, you can use the ipaddress module to generate all the valid host addresses on a given network (see below).
>>> import ipaddress
>>> print("n".join([str(x) for x in ipaddress.ip_network("192.0.2.0/28").hosts()]))
192.0.2.1
192.0.2.2
192.0.2.3
192.0.2.4
192.0.2.5
192.0.2.6
192.0.2.7
192.0.2.8
192.0.2.9
192.0.2.10
192.0.2.11
192.0.2.12
192.0.2.13
192.0.2.14
This module also supports IPv6 incidentally, so you can generate the hosts of 2001:0db8::/120
using ipaddress.ip_network("2001:0db8::/120").hosts()
.
You can (though you don’t have to) wrap this in a shell-script-compatible one-liner..
python3 -c 'import ipaddress; print("n".join([str(x) for x in ipaddress.ip_network("192.0.2.0/28").hosts()]))'
Now, all you need to is
#!/bin/bash
# split it up
IFS='.' read -a array <<< "127.0.0"
#echo ${array[*]}
#127 0 0
mask=$(( ${#array[@]} * 8))
# 28
# add missing 0s.
for $i in {1..4}; do
if [ i -gt ${#array[@]} ]; then
array[i]="0"
fi
done
#echo ${array[*]}
#127 0 0 0
# join, see http://stackoverflow.com/questions/1527049/bash-join-elements-of-an-array
SAVE_IFS=$IFS
IFS="."
full_ip="${array[*]}"
IFS=$SAVE_IFS
# 127.0.0.0
# now add /mask
network="$full_ip/$mask"
# 127.0.0.0/24
python3 -c "import ipaddress; print("\n".join([str(x) for x in ipaddress.ip_network("$network").hosts()]))"
#127.0.0.1
#127.0.0.2
# ...
#127.0.0.254
Pure Python3:
import ipaddress
input="127.0.0"
input_arr=input.split(".") # ['127', '0', '0']
netmask=len(input_arr)*8 # 24
for i in range(len(input_arr), 4):
input_arr.append('0')
# input_arr = ['127', '0', '0', '0']
ip='.'.join(input_arr) # '127.0.0.0'
network=ip + '/' + str(netmask) # '127.0.0.0/24'
print("n".join([str(x) for x in ipaddress.ip_network(network).hosts()]))
If you want to add the network/broadcast, just print the .network_address
and .broadcast_address
in addition.