Module supernetting
[show private | hide private]
[frames | no frames]

Module supernetting

supernetting.py merges a list of subnets to remove subnets which are a part of a greater (least specific) subnet.

The script can used to get a smaller routing tables or a smaller firewall rule set.

The algorithm is detailed described in mergeSubnets and sumSubnets.

Tested at:
 - SunOS 5.8; Python 2.2.1
 - Linux 2.6.11 on x86; Python 2.3.5
Revision History:
   $Log: supernetting-module.html,v $
   Revision 1.1  2005-05-21 10:35:18  carsten

   - Dokumentation zu supernetting.py erstellt mit epydoc

   Revision 1.3  2005/05/19 18:39:04  carsten
   - version 1.0
   - rename some function to get a more readable name
   - use internal functions to converts ip addresses between dotted quad
     and integer numbers
   - enhance and correct documentation
   - add option --test to allow a simple function test
   - run pychecker and fix a lof of messages

   Revision 1.2  2005/04/17 10:20:21  carsten
   - version 1.0rc1
   - enhance documentation
   - add command line options
   - add a detailed usage message
   - small improvements

   Revision 1.1  2005/02/20 11:17:38  carsten
   - initial import to CVS
   - script merge subnets (supernetting)

Version: see __version__

Author: Carsten Grohmann <mail (at) carstengrohmann (dot) de>

License: GPL version 2.0 or above

Note: You can use the same functionality in perl with the NetAddr-IP module from http://search.cpan.org/dist/NetAddr-IP/

To Do: add support for iana styled ip addresses

Function Summary
  decimalToDottedQuad(number)
Convert a long integer IP address to dotted quad IP address
  dottedQuadToDecimal(ipaddress)
Convert a dotted quad IP address in long integer
  error(message, returnvalue)
Prints an error message to stderr and leave the script
  formatSubnet(subnet)
Transforms a subnet with a decimal IP into a subnet with a dotted quad IP
  getCIDRNetmask(subnet)
Return the netmask from the subnet
  getDecimalIP(subnet)
Returns a decimal IP address from a subnetmask with a decimal IP inside
  getIP(subnet)
Returns the IP address from a subnet
  getNetworkAddress(subnet, netmask)
Returns the network address.
  info(message)
Prints a information
  isCIDRSubnet(subnet)
Checks if the subnet mask a valid dotted quad IP address with a subnet mask in CIDR style
  main()
main loop - get and check the command line options and runs the functions
  mergeSubnets(subnetlist)
Merge subnets (Supernetting)
  normSubnet(subnet)
Clear all bits of the host part in a subnet address dotted quad style
  sumSubnets(subnetlist)
Summarise a list of subnets.
  test()
Runs some tests to check the correct work of different functions
  usage(rval)
Print usage message and exit
  warning(message)
Prints a warn message

Variable Summary
str __author__: author of this script and his email address
str __copyright__: copyright and licence string
str __date__: date of the last changes
str __revision__: internal revision number
str __version__: version number of this script
dict lowest_bit: dictionary with the lowest bit of a netmask; it will used to get faster access and better readability of the source code
dict mask_hex: used for fast translations beetween CIDR styled subnetmasks and normal styled subnet masks
int verbose: switch to enable or disable additional informations about the merging and reducing of the subnets; see also info

Function Details

decimalToDottedQuad(number)

Convert a long integer IP address to dotted quad IP address
Parameters:
number - long integer IP address
           (type=long integer)
Returns:
dotted quad IP address
Raises:
TypeError - on wrong type of the parameter
ValueError - if the parameter is not a number

Example: decimalToDottedQuad(123456789L) will returns "7.91.205.21"

dottedQuadToDecimal(ipaddress)

Convert a dotted quad IP address in long integer
Parameters:
ipaddress - IP address in dotted quad style
           (type=string)
Returns:
IP address as long integer
Raises:
TypeError - on wrong type of the parameter
ValueError - if the parameter ipaddress is not a number

Example: dottedQuadToDecimal("1.2.3.4") returns 16909060L

error(message='', returnvalue=1)

Prints an error message to stderr and leave the script

The message will print out with "ERROR:" as prefix
Parameters:
message - the error message
returnvalue - exit value; default is set to 1; None will continue the script
Raises:
ValueError - on a empty error message

formatSubnet(subnet)

Transforms a subnet with a decimal IP into a subnet with a dotted quad IP
Parameters:
subnet - subnet address
           (type=string)
Returns:
subnet with dotted quad IP
Raises:
ValueError - if the parameter is empty or not a subnet

Example: formatSubnet("1/28") will return "0.0.0.1/28"

getCIDRNetmask(subnet)

Return the netmask from the subnet
Parameters:
subnet - any subnetmask in CIDR style e.g. "1.2.3.4/30"
           (type=string)
Returns:
the netmask in cidr style as integer
Raises:
TypeError - on wrong type of the parameter
ValueError - on empty or wrong format of the parameter

Note: There is no validity check of the returned value

Example: getCIDRNetmask("1.2.3.4/5") returns 5

getDecimalIP(subnet)

Returns a decimal IP address from a subnetmask with a decimal IP inside
Parameters:
subnet - any subnetmask with a decimal IP address e.g. "123456/24" or "1234567/255.255.255.0"
           (type=string)
Returns:
a decimal IP address as long
Raises:
TypeError - on wrong type of the parameter
ValueError - on empty or wrong format of the parameter

Example: getDecimalIP("123456/24") returns 123456L or getDecimalIP("1234567/255.255.255.0") returns 1234567L

getIP(subnet)

Returns the IP address from a subnet
Parameters:
subnet - every kind of subnetmask
           (type=string)
Returns:
a IP address as string
Raises:
TypeError - on wrong type of the parameter
ValueError - on empty or wrong format of the parameter

Example: getIP("12345678/23") returns "12345678"; getIP("12.34.56.78/255.255.255.0") returns "12.34.56.78"

getNetworkAddress(subnet, netmask=0)

Returns the network address.

This function have two imput formats:
  • One parameter:
    1. parameter: subnet addresses in CIDR style with a decimal IP e.g. "12345678/21"
  • Two parameters:
    1. parameter: IP address as decimal number
    2. parameter: Subnetmask in CIDR style as decimal number
Parameters:
subnet
           (type=string or long)
netmask
           (type=int or long)
Returns:
the network address as decimal number
Raises:
TypeError - on wrong type of the parameter
ValueError - on empty or wrong format of the parameter

Example: getNetworkAddress("3232236289/16") returns 3232235520L

info(message='')

Prints a information

The message will print out with "INFO:" as prefix.
Parameters:
message - the information message
Raises:
ValueError - on a empty information

See Also: verbose

isCIDRSubnet(subnet)

Checks if the subnet mask a valid dotted quad IP address with a subnet mask in CIDR style
Returns:
True or False

Note: This functions doesn't raise exceptions.

main()

main loop - get and check the command line options and runs the functions

mergeSubnets(subnetlist)

Merge subnets (Supernetting)

A even networkaddress and the following odd networkaddress with the same netmask can merge to the even networkaddress with a networkmask reduced by 1 bit. This smaller (least specific) subnet contains both parent subnets.

Example: The subnets 4.0.0.0/8 and 5.0.0.0/8 can reduce to 4.0.0.0/7.

The function checks also if subnets are parts of other subnets and reduces the unnecessary subnet entry. See sumSubnets to get more informations about this step.

You get smaller routing or firewall tables thru this both steps.

It is possible to optimize this function to get more speed. To optimize it, change the handling of the odd right bit of the subnetmask.
Parameters:
subnetlist
           (type=list or tuple of strings)
Returns:
list of subnets
Raises:
TypeError - if parameter subnetlist is not a list

See Also: sumSubnets

normSubnet(subnet)

Clear all bits of the host part in a subnet address dotted quad style
Parameters:
subnet
           (type=string)
Returns:
normalized subnet address
Raises:
TypeError - on wrong type of the parameter
ValueError - if the parameter is empty or not a subnet

Example: normSubnet("3232236035/24") returns "3232236032/24"

sumSubnets(subnetlist)

Summarise a list of subnets.

Remove all subnet, which are a member of smaller subnet
Parameters:
subnetlist - a list of subnets, every subnet have to consist of a long int IP address and a subnetmask in CIDR style
           (type=list or tuple of strings)
Returns:
list of subnets
Raises:
TypeError - if parameter subnetlist is not a list

See Also: mergeSubnets

test()

Runs some tests to check the correct work of different functions

usage(rval=0)

Print usage message and exit
Parameters:
rval - return value of this script

warning(message='')

Prints a warn message

The message will print out with "WARNING:" as prefix.
Parameters:
message - the warning message
Raises:
ValueError - on a empty warning message

Variable Details

__author__

author of this script and his email address
Type:
str
Value:
'Carsten Grohmann <mail (at) carstengrohmann dot de>'                  

__copyright__

copyright and licence string
Type:
str
Value:
'Carsten Grohmann (c) 2005; Licence: GPL V2.0 or above'                

__date__

date of the last changes
Type:
str
Value:
'$Date: 2005-05-21 10:35:18 $'                                         

__revision__

internal revision number
Type:
str
Value:
'$Revision: 1.1 $'                                                     

__version__

version number of this script
Type:
str
Value:
'1.0'                                                                  

lowest_bit

dictionary with the lowest bit of a netmask; it will used to get faster access and better readability of the source code
Type:
dict
Value:
{0: 4294967296L,
 1: 2147483648L,
 2: 1073741824L,
 3: 536870912L,
 4: 268435456L,
 5: 134217728L,
 6: 67108864L,
 7: 33554432L,
...                                                                    

mask_hex

used for fast translations beetween CIDR styled subnetmasks and normal styled subnet masks
Type:
dict
Value:
{0: '0x00000000L',
 1: '0x80000000L',
 2: '0xC0000000L',
 3: '0xE0000000L',
 4: '0xF0000000L',
 5: '0xF8000000L',
 6: '0xFC000000L',
 7: '0xFE000000L',
...                                                                    

verbose

switch to enable or disable additional informations about the merging and reducing of the subnets; see also info
Type:
int
Value:
0                                                                     

Generated by Epydoc 2.1 on Thu May 19 20:42:10 2005 http://epydoc.sf.net