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.