Python program to convert wildcard mask to netmask - python

I need help with writing a python program to achieve this task.
I am trying to convert wildcard mask to netmask.
Input:
192.168.0.1 0.0.0.15
Expected output:
192.168.0.1 255.255.255.240

What have you tried? I think it is just xor operator on the bits. Let me know if I'm correct please.
my inputs: 192.168.0.1 0.0.0.15
expected output: 192.168.0.1 255.255.255.240
ip, wcmask = input.split()
netmask='.'.join([str(255^int(i)) for i in wcmask.split('.')])
return '{} {}'.format(ip, netmask)

python2
>>> import ipaddress
>>> print ipaddress.ip_network(u'192.168.0.1/0.0.0.15', strict=False).netmask
255.255.255.240
python3
>>> import ipaddress
>>> print(ipaddress.ip_network('192.168.0.1/0.0.0.15', strict=False).netmask)
255.255.255.240

Convert wildcard to subnet
from cisco_acl import Address
address = Address("192.168.0.1 0.0.0.15")
subnets = address.subnets()
print(subnets)
# ['192.168.0.0 255.255.255.240']
Convert non-contiguous wildcard to list of subnets
from cisco_acl import Address
address = Address("192.168.0.1 0.0.3.15")
subnets = address.subnets()
print(subnets)
# ['192.168.0.0 255.255.255.240',
# '192.168.1.0 255.255.255.240',
# '192.168.2.0 255.255.255.240',
# '192.168.3.0 255.255.255.240']

Related

How can I print in an f-string an IP address in the dotted binary notation from the output of inet_pton()?

The following code is supposed to take an IP from its user, convert it to the binary and print it to the screen.
#!/usr/bin/env python3
from socket import inet_aton, inet_pton, AF_INET
ip = input("IP?\n")
ip = inet_pton(AF_INET, ip)
print(f"{ip}")
When given 185.254.27.69 it prints
b'\xb9\xfe\x1bE' .f"{ip:08b}" does not work, perhaps because of the three dots in between the fours octets.. How could I get the dotted binary format of an IP printed on the screen? Any resources of use?
Unless I'm missing something, I don't see a reason to use inet_pton here. It converts to packed bytes, when you want a binary representation of the numbers (I assume):
ip = input("IP?\n")
print('.'.join(f'{int(num):08b}' for num in ip.split('.')))
For the input you supplied:
IP?
185.254.27.69
10111001.11111110.00011011.01000101
this code works for binary ip and keeps leading zeros:
from socket import inet_aton, inet_pton, AF_INET
ip = ip2 = input("IP?\n")
ip = inet_pton(AF_INET, ip)
ip2 = ip2.split(".")
ip3 = ""
for ip in ip2:
ip = int(ip)
if len(ip3) == 0:
zeros = str(bin(ip)[2:]).zfill(8)
ip3 += zeros
else:
zeros = str(bin(ip)[2:]).zfill(8)
ip3 += "." + zeros
print(f"{ip3}")

Parsing a text file in Python

I am new in python and I am trying to extract values out of a text file.
Input:
Vlan101, Interface status: protocol-up/link-up/admin-up, iod: 257,
IP address: 1.1.1.1, IP subnet: 1.1.1.0/24
IP broadcast address: 255.255.255.255
Output:
Vlan101,1.1.1.0/24
I have a code which is working but not giving me the desired output.
My code:
if 'Vlan' in text:
vlanArray = text.split(",")
print(vlanArray[0])
if 'IP subnet' in text:
ipAddress = text.split(":")
lenipAdd = len(ipAddress)
print(ipAddress[lenipAdd-1].strip())
Any help would be appreciated.
It seems you going a bit to fast. I would suggest to first try an intermediate step:
vlanArray = text.split(",")
for txt in vlanArray:
print(txt)
This should give you direction about the next steps to take.
You can use a regular expression to extract the information you need:
s = """Vlan101, Interface status: protocol-up/link-up/admin-up, iod: 257,
IP address: 1.1.1.1, IP subnet: 1.1.1.0/24
IP broadcast address: 255.255.255.255"""
import re
m = re.match(r'^([\d\w]+)(.*)(IP subnet: )([0-9./]+)', s, re.DOTALL | re.S | re.MULTILINE )
result = m.groups()
print (result[0], result[-1])
Returns:
Vlan101 1.1.1.0/24
There is no need for 2 or more split of same text. Try below:
Do the split of the text and store in an array
Run the loop through the array
Check if the array item contains Vlan or IP subnet
If true, append in the output variable
Like below:
vlanArray = text.split(",")
outTxt = []
for subTxt in vlanArray:
if 'Vlan' in subTxt:
outTxt.append(subTxt)
if 'IP subnet' in subTxt:
ipAddress = subTxt.split(":")
lenipAdd = len(ipAddress)
outTxt.append(ipAddress[lenipAdd-1].strip())
outTxt = ','.join(outTxt)

Python hex IP as string to DDN IP string

I have the following IP in hex: 0xac141315
I would like to convert it to its DDN equivalent.
I used to use '.'.join([str(x) for x in 0xac141315.asNumbers()]) when 0xac141315 had the following type: <class 'CiscoNetworkAddress'>
Or is there a way to convert the string back to CiscoNetworkAddress?
According to CISCO-TC MIB, CiscoNetworkAddress is actually an octet string. There are many ways to turn octet string into a DDN. For example, with ipaddress module from Python 3 stdlib:
>>> from pysnmp.hlapi import OctetString
>>> ip = OctetString(hexValue='ac141315') # this is what you have
>>>
>>> ipaddress.IPv4Address(ip.asOctets())
IPv4Address('172.20.19.21')
Or you can turn it into SNMP SMI IP address:
>>> from pysnmp.hlapi import IpAddress
>>> IpAddress(ip.asOctets()).prettyPrint()
'172.20.19.21'
Also, you could get a sequence of integer octets right from your existing object:
>>> ip.asNumbers()
(172, 20, 19, 21)
Keep in mind, that CiscoNetworkAddress is designed to hold many different address types, not just IPv4. So you should probably apply the IPv4 conversion only when it's actually IPv4 address.
Here is a complete example of how to convert to decimal ip:
#!/usr/bin/python
import sys
# Must be (0xXXXXXXXX)
if len(sys.argv)< 2:
print("Usage: %s (HEX FORMAT, for example 0xAC141315)" % sys.argv[0])
sys.exit(0)
user_option = sys.argv[1]
hex_data=user_option[2:]
#Check if length = 8
if len(hex_data)< 8:
hex_data = ''.join(('0',hex_data))
def hex_to_ip_decimal(hex_data):
ipaddr = "%i.%i.%i.%i" % (int(hex_data[0:2],16),int(hex_data[2:4],16),int(hex_data[4:6],16),int(hex_data[6:8],16))
return ipaddr
result=hex_to_ip_decimal(hex_data)
print result

converting IP string to hex for dpkt.IP

I want to learn packet decoder processing using dpkt. On the site, I saw the following example code:
>>> from dpkt.ip import IP
>>> ip = IP(src='\x01\x02\x03\x04', dst='\x05\x06\x07\x08', p=1)
>>> ...
How do I convert an IP String like '1.2.3.4' to '\x01\x02\x03\x04'?
Use socket.inet_aton:
>>> import socket
>>> socket.inet_aton('1.2.3.4')
'\x01\x02\x03\x04'
To get the dotted decimal back, use socket.inet_ntoa:
>>> socket.inet_ntoa('\x01\x02\x03\x04')
'1.2.3.4'
UPDATE
In Python 3.3+, ipaddress.IPv4Address is another option.
>>> import ipaddress
>>> ipaddress.IPv4Address('1.2.3.4').packed
b'\x01\x02\x03\x04'
>>> ipaddress.IPv4Address(b'\x01\x02\x03\x04')
IPv4Address('1.2.3.4')
>>> str(ipaddress.IPv4Address(b'\x01\x02\x03\x04'))
'1.2.3.4'

How can I generate all possible IPs from a CIDR list in Python?

Let's say I have a text file contains a bunch of cidr ip ranges like this:
x.x.x.x/24
x.x.x.x/24
x.x.x.x/23
x.x.x.x/23
x.x.x.x/22
x.x.x.x/22
x.x.x.x/21
and goes on...
How can I convert these cidr notations to all possible ip list in a new text file in Python?
You can use netaddr for this. The code below will create a file on your disk and fill it with every ip address in the requested block:
from netaddr import *
f = open("everyip.txt", "w")
ip = IPNetwork('10.0.0.0/8')
for addr in ip:
f.write(str(addr) + '\n')
f.close()
If you don't need the satisfaction of writing your script from scratch, you could use the python cidrize package.
based off How can I generate all possible IPs from a list of ip ranges in Python?
import struct, socket
def ips(start, end):
start = struct.unpack('>I', socket.inet_aton(start))[0]
end = struct.unpack('>I', socket.inet_aton(end))[0]
return [socket.inet_ntoa(struct.pack('>I', i)) for i in range(start, end)]
# ip/CIDR
ip = '012.123.234.34'
CIDR = 10
i = struct.unpack('>I', socket.inet_aton(ip))[0] # number
# 175893026
start = (i >> CIDR) << CIDR # shift right end left to make 0 bits
end = i | ((1 << CIDR) - 1) # or with 11111 to make highest number
start = socket.inet_ntoa(struct.pack('>I', start)) # real ip address
end = socket.inet_ntoa(struct.pack('>I', end))
ips(start, end)

Categories