How do I increment the IP address in python when we have start_ip in 4 octets format and the step also in 4 octet format.
Let's suppose I start with an IP address of 225.1.1.1, and the step as 0.0.0.1
When I say next_ip = start_ip + step, it should actually evaluate the expand produce the result.
I know that the ipaddr module does this with just an addition, but that does not seem to work when the step is also given in the ipv4 format.
Any known steps to do this:
import ipaddr
a = ipaddr.ipaddress('225.1.1.1')
b = a +1
This actually returns the desired result. but when increment like this:
b = a + 0.0.0.1 it does not seem to work.
Any known solutions for this?
Not refined but works i guess, here is the python snippet
def increment_ip_addr(ip_addr):
ip_arr = ip_addr.split('.')
def increment_by_1(digit):
return str(int(digit) + 1)
if int(ip_arr[3]) > 254:
ip_arr[3] = "1"
if int(ip_arr[2]) > 254:
ip_arr[2] = "1"
if int(ip_arr[1]) > 254:
ip_arr[1] = "1"
if int(ip_arr[0]) > 254:
ip_arr[0] = "1"
else:
ip_arr[0] = increment_by_1(ip_arr[0])
else:
ip_arr[1] = increment_by_1(ip_arr[1])
else:
ip_arr[2] = increment_by_1(ip_arr[2])
else:
ip_arr[3] = increment_by_1(ip_arr[3])
print(f"for ip address: {ip_addr} The incremented ip is: {'.'.join(ip_arr)}")
[increment_ip_addr(ip_addr) for ip_addr in ['1.1.1.1', "1.1.1.255", "1.255.1.255", "255.255.255.255"]]
corresponding console output:
for ip address: 1.1.1.1 The incremented ip is: 1.1.1.2
for ip address: 1.1.1.255 The incremented ip is: 1.1.2.1
for ip address: 1.255.1.255 The incremented ip is: 1.255.2.1
for ip address: 255.255.255.255 The incremented ip is: 1.1.1.1
Let me know in case of optimized version
this piece of code can add two 4 octets :
first = '192.168.0.4'
second = '0.0.0.1'
ipaddress.ip_address(first) + int(ipaddress.ip_address(second))
this will result in: IPv4Address('192.168.0.5')
I have the following:-
start_range = "10.40.0.0/16"
end_range = "10.100.0.0/16"
I have to write a logic to iterate over all possible ranges(with same subnet mask /16) from start to end. For each subnet I will be doing some processing and then continuing to the next one.
I could achieve this in trivial way where I know, I have to increment last network octate(i.e increment 40 to 41 -> 42 -> 43 and so on).
start_subnet = "10.40.0.0/16"
end_subnet = "10.100.0.0/16"
start_val = int(start_subnet.split(".")[1])
end_val = int(end_subnet.split('.')[1])
subnet_split = start_subnet.split(".")
subnet_split[1] = "{}"
subnet_proto = ".".join(subnet_split) # "10.{}.0.0/16"
for i in range(start_val, end_val+1): # iterate from 40 to 100
cur_subnet = subnet_proto.format(i) # "10.40.0.0/16", "10.41.0.0/16" etc
# do processing on cur_subnet
Is there a better(Pythonic) way to get the next subnet(in CIDR format). May be netaddr module has something I am not aware of?
Following usage of netaddr helped me to get the expected result.
from netaddr import IPNetwork
start_range = IPNetwork("10.40.0.0/16")
end_range = IPNetwork("10.45.0.0/16")
allowed_range = []
while start_range<=end_range:
allowed_range.append(start_range)
start_range = start_range.next()
print allowed_range
This would print the following:-
[IPNetwork('10.40.0.0/16'), IPNetwork('10.41.0.0/16'),
IPNetwork('10.42.0.0/16'), IPNetwork('10.43.0.0/16'),
IPNetwork('10.44.0.0/16'), IPNetwork('10.45.0.0/16')]
This might be what you have in mind (not really well thought-through or tested, you've been warned!).
The ipaddress module is from python3 but it has a backport, just run
pip install ipaddress
to get it.
import ipaddress
def subnet_range(start_subnet, end_subnet):
start = ipaddress.ip_network(unicode(start_subnet))
end = ipaddress.ip_network(unicode(end_subnet))
assert start.prefixlen == end.prefixlen
ranges = [
n
for ipaddr in ipaddress.summarize_address_range(
list(start)[0],
list(end)[0])
for n in ipaddr.subnets(new_prefix=start.prefixlen)][:-1]
ranges.append(end)
return ranges
if __name__ == "__main__":
start_subnet = "9.250.0.0/16"
end_subnet = "10.100.0.0/16"
for r in subnet_range(start_subnet, end_subnet):
print r
import os
ipRange = []
for i in range(1, 254):
ipRange.append('192.168.5' + '.' + str(i))
for e in ipRange:
print os.system('nslookup ' + str(e))
This outputs the full output of nslookup for each ip - is there a way to discard the empty results and make the output look more like this?
192.168.5.5 testbox4
192.168.5.6 box3
192.168.5.8 hellobox
192.168.5.9 server2012
192.168.5.18 dnsbox
192.168.5.19 sallysbox
192.168.5.20 bobsbox
192.168.5.21 serverx
Do you need to use system? This would do without system calls:
import socket
for i in range(0, 255):
ipa = "130.233.192." + str(i)
try:
a = socket.gethostbyaddr(ipa)
print (ipa, a[0])
except socket.herror:
pass
EDIT: change 255 to 256 if you want to query .255 as well but in class C networks this is the broadcast address and not in DNS. If you are trawling through class A or B networks, then .255 could be valid as well
I'm using python ipaddr it's working but if I wanna open a text file where i'm getting an ip address i'm getting an error.
This is What I have:
import ipaddr
from itertools import islice
def address1():
with open('address.txt','r+') as file:
lines = islice(file, 1, 5)
for line in lines:
found_address = line.find('Address')
if found_address != -1:
address = line[found_address+len('Address:'):] #address = 192.168.0.9/25
mask = ipaddr.IPv4Network(address)
resultado = mask.broadcast
print resultado
return resultado
def get_network():
addr = '192.168.0.9/25'
mask = ipaddr.IPv4Network(addr)
resultado_broadcast = mask.broadcast
print resultado_broadcast
return resultado_broadcast
#address1() #if I comment out this line and I run the next one works...
get_network() #if I run this one works...
My ip address from address.txt :
Address 192.168.0.9/25
the same I used in get_network()
So why I'm getting error in address1()?
output of get_network()
As you can see works... but if I run address1()
I got this error.
Does anyone know how to make address1() work? is it possible?
thanks...!
I'm trying to make a test for checking whether a sys.argv input matches the RegEx for an IP address...
As a simple test, I have the following...
import re
pat = re.compile("\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}")
test = pat.match(hostIP)
if test:
print "Acceptable ip address"
else:
print "Unacceptable ip address"
However when I pass random values into it, it returns "Acceptable IP address" in most cases, except when I have an "address" that is basically equivalent to \d+.
Using regex to validate IP address is a bad idea - this will pass 999.999.999.999 as valid. Try this approach using socket instead - much better validation and just as easy, if not easier to do.
import socket
def valid_ip(address):
try:
socket.inet_aton(address)
return True
except:
return False
print valid_ip('10.10.20.30')
print valid_ip('999.10.20.30')
print valid_ip('gibberish')
If you really want to use parse-the-host approach instead, this code will do it exactly:
def valid_ip(address):
try:
host_bytes = address.split('.')
valid = [int(b) for b in host_bytes]
valid = [b for b in valid if b >= 0 and b<=255]
return len(host_bytes) == 4 and len(valid) == 4
except:
return False
You have to modify your regex in the following way
pat = re.compile("^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
that's because . is a wildcard that stands for "every character"
regex for ip v4:
^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
otherwise you take not valid ip address like 999.999.999.999, 256.0.0.0 etc
I came across the same situation, I found the answer with use of socket library helpful but it doesn't provide support for ipv6 addresses. Found a better way for it:
Unfortunately, it Works for python3 only
import ipaddress
def valid_ip(address):
try:
print (ipaddress.ip_address(address))
return True
except:
return False
print (valid_ip('10.10.20.30'))
print (valid_ip('2001:DB8::1'))
print (valid_ip('gibberish'))
You are trying to use . as a . not as the wildcard for any character. Use \. instead to indicate a period.
def ipcheck():
# 1.Validate the ip adderess
input_ip = input('Enter the ip:')
flag = 0
pattern = "^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$"
match = re.match(pattern, input_ip)
if (match):
field = input_ip.split(".")
for i in range(0, len(field)):
if (int(field[i]) < 256):
flag += 1
else:
flag = 0
if (flag == 4):
print("valid ip")
else:
print('No match for ip or not a valid ip')
import re
ipv=raw_input("Enter an ip address")
a=ipv.split('.')
s=str(bin(int(a[0]))+bin(int(a[1]))+bin(int(a[2]))+bin(int(a[3])))
s=s.replace("0b",".")
m=re.search('\.[0,1]{1,8}\.[0,1]{1,8}\.[0,1]{1,8}\.[0,1]{1,8}$',s)
if m is not None:
print "Valid sequence of input"
else :
print "Invalid input sequence"
Just to keep it simple I have used this approach.
Simple as in to explain how really ipv4 address is evaluated.
Checking whether its a binary number is although not required.
Hope you like this.
str = "255.255.255.255"
print(str.split('.'))
list1 = str.split('.')
condition=0
if len(list1)==4:
for i in list1:
if int(i)>=0 and int(i)<=255:
condition=condition+1
if condition!=4:
print("Given number is not IP address")
else:
print("Given number is valid IP address")
If you really want to use RegExs, the following code may filter the non-valid ip addresses in a file, no matter the organiqation of the file, one or more per line, even if there are more text (concept itself of RegExs) :
def getIps(filename):
ips = []
with open(filename) as file:
for line in file:
ipFound = re.compile("^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$").findall(line)
hasIncorrectBytes = False
try:
for ipAddr in ipFound:
for byte in ipAddr:
if int(byte) not in range(1, 255):
hasIncorrectBytes = True
break
else:
pass
if not hasIncorrectBytes:
ips.append(ipAddr)
except:
hasIncorrectBytes = True
return ips
re.sub('((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])', '--', '127.0.0.1')
With this regular expression, only numbers from 0 to 255 could compose the address. It also handles leading zeros, so 127.00.0.1 would no pass.
IP address uses following authentication :
255 ---> 250-255
249 ---> 200-249
199 ---> 100-199
99 ---> 10-99
9 ---> 1-9
import re
k = 0
while k < 5 :
i = input("\nEnter Ip address : ")
ip = re.match("^([1][0-9][0-9].|^[2][5][0-5].|^[2][0-4][0-9].|^[1][0-9][0-9].|^[0-9][0-9].|^[0-9].)([1][0-9][0-9].|[2][5][0-5].|[2][0-4][0-9].|[1][0-9][0-9].|[0-9][0-9].|[0-9].)([1][0-9][0-9].|[2][5][0-5].|[2][0-4][0-9].|[1][0-9][0-9].|[0-9][0-9].|[0-9].)([1][0-9][0-9]|[2][5][0-5]|[2][0-4][0-9]|[1][0-9][0-9]|[0-9][0-9]|[0-9])$",i)
k = k + 1
if ip:
print ("\n=====================")
print ("Valid IP address")
print ("=====================")
break
else :
print ("\nInvalid IP")
else :
print ("\nAllowed Max 5 times")
Reply me if you have doubt?
import re
st1 = 'This is my IP Address10.123.56.25 789.356.441.561 127 255 123.55 192.168.1.2.3 192.168.2.2 str1'
Here my valid IP Address is only 192.168.2.2 and assuming 10.123.56.25 is not a valid one as it is combined with some string and 192.168.1.2.3 not valid.
pat = r'\s(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\s|$))'
match = re.search(pat,st1)
print match.group()
================ RESTART: C:/Python27/Srujan/re_practice.py ================
192.168.2.2
This will grep the exact IP Address, we can ignore any pattern look like an IP Address but not a valid one. Ex: 'Address10.123.56.25', '789.356.441.561' '192.168.1.2.3'.
Please comment if any modifications are required.
This works for python 2.7:
import re
a=raw_input("Enter a valid IP_Address:")
b=("[0-9]+"+".")+"{3}"
if re.match(b,a) and b<255:
print "Valid"
else:
print "invalid"
""" regex for finding valid ip address """
import re
IPV4 = re.fullmatch('([0-2][0-5]{2}|\d{2}|\d).([0-2][0-5]{2}|\d{2}|\d).([0-2][0-5]{2}|\d{2}|\d).([0-2][0-5]{2}|\d{2}|\d)', '100.1.1.2')
if IPV4:
print ("Valid IP address")
else:
print("Invalid IP address")