решил выложить(хотя может ошибся разделом)
Писан не мною, но юзаю и мне нравиться(выкладываю в оргинале как он был)
netcalc.py
Код: Выделить всё
#! /usr/local/bin/python
#
# this prog was loosely ported from a similar javascript
# implementation written by me earlier. In javascript
# variables are 32 bits and signed, so I opted to use arrays
# of 4 integers to represent each IP address.
#
# Python allows unlimited precision, so a different approach
# might have been indicated. -- Next time... ;)
#
# (c)2000 Manfred Bartz <md-NetCalc@logi.cc>
# You may use this source code as per the
# "Gnu General Public License (GPL)" <http://www.gnu.org/>
# V1.1 Added ability to calculate the best fit subnet based on
# an IP address range.
#
# V1.1a Made HTML tag generation a command line option (--html)
# rather than assuming it from sys.stdout.isatty()
#
import getopt, sys, string, re
# netaddr/netmask format
PattAddrMask = re.compile(\
'^(\d+)\.(\d+)\.(\d+)\.(\d+)\s{0,2}/\s{0,2}(\d+)\.(\d+)\.(\d+)\.(\d+).*$')
PattAddrRange = re.compile(\
'^(\d+)\.(\d+)\.(\d+)\.(\d+)\s{0,2}[-:]\s{0,2}(\d+)\.(\d+)\.(\d+)\.(\d+).*$')
PattPartialNetmask = re.compile(\
'^\d+\.\d+\.\d+\.\d+/(\d+\.[\.0-9]+)[^\.\d]*$')
# netaddr/masklen format
PattAddrMLen = re.compile(\
'^(\d+)\.(\d+)\.(\d+)\.(\d+)/(\d+).*$')
# netaddr/masklen format
PattAddrOnly = re.compile(\
'^(\d+)\.(\d+)\.(\d+)\.(\d+)\D*$')
NetAddr = [0,0,0,0]
HostAddr = [0,0,0,0]
HostAddr2 = [0,0,0,0]
NetMask = [0,0,0,0]
Broadcast = [0,0,0,0]
FirstHost = [0,0,0,0]
LastHost = [0,0,0,0]
#----------------------------------------------------------------------
def RangeOk(n, min, max):
if (n >= min) and (n <= max):
return 1
return 0
#----------------------------------------------------------------------
def allBits0(n):
r = 0
for i in range(len(n)):
r = r | n[i]
return r == 0
#----------------------------------------------------------------------
def allBits1(n):
r = 0xFF
for i in range(len(n)):
r = r & n[i]
return (r & 0xFF) == 0xFF
#----------------------------------------------------------------------
def quitOutOfRange(s):
print '%s%s bad: each number in the dotted quad must be in the range 0 to 255!%s' \
% (TagRed, s, TagNormal)
sys.exit(1)
#----------------------------------------------------------------------
def tellBadMask(s):
print '%sNetMask bad: %s%s' % (TagRed, s, TagNormal)
print
#----------------------------------------------------------------------
def ParseInput(inpLine):
global NetMaskBad
global MaskLen
global isAddrRange
NetMaskBad = 0
MaskLen = 0
NxorAddr = [0,0,0,0]
MatchResult = PattAddrRange.match(inpLine)
if MatchResult:
# print 'netaddr1/netaddr2 format'
isAddrRange = 1
for i in range(4):
HostAddr[i] = string.atoi(MatchResult.group(i+1))
if not RangeOk(HostAddr[i], 0, 255):
quitOutOfRange('HostAddr1')
for i in range(4):
HostAddr2[i] = string.atoi(MatchResult.group(i+5))
if not RangeOk(HostAddr2[i], 0, 255):
quitOutOfRange('HostAddr2')
NxorAddr[i] = ~ (HostAddr[i] ^ HostAddr2[i])
i = 0
done = 0
while i < 4:
bitmask = 0x80
for b in range(8):
if not done:
if NxorAddr[i] & bitmask:
MaskLen = MaskLen + 1
else:
done = 1
bitmask = bitmask >> 1
i = i + 1
else:
MatchResult = PattAddrMask.match(inpLine)
if MatchResult:
# print 'netaddr/netmask format'
for i in range(4):
HostAddr[i] = string.atoi(MatchResult.group(i+1))
if not RangeOk(HostAddr[i], 0, 255):
quitOutOfRange('HostAddr')
for i in range(4):
NetMask[i] = string.atoi(MatchResult.group(i+5))
if not RangeOk(NetMask[i], 0, 255):
quitOutOfRange('NetMask')
i = 0
done = 0
while i < 4:
bitmask = 0x80
for b in range(8):
if not done:
if NetMask[i] & bitmask:
MaskLen = MaskLen + 1
else:
done = 1
else:
if NetMask[i] & bitmask:
NetMaskBad = 1
bitmask = bitmask >> 1
i = i + 1
else:
MatchResult = PattPartialNetmask.match(inpLine)
if MatchResult:
tellBadMask('"%s" is partial mask, use full mask or specify mask length' \
% MatchResult.group(1));
sys.exit(1)
else:
MatchResult = PattAddrMLen.match(inpLine)
if MatchResult:
# print 'netaddr/MaskLen format'
for i in range(4):
HostAddr[i] = string.atoi(MatchResult.group(i+1))
if not RangeOk(HostAddr[i], 0, 255):
quitOutOfRange('HostAddr')
MaskLen = string.atoi(MatchResult.group(5))
if not RangeOk(MaskLen, 0, 32):
tellBadMask('must be in the range of 0 to 32 bits, set to 32');
MaskLen = 32
else:
MatchResult = PattAddrOnly.match(inpLine)
if MatchResult:
# print 'netaddr only format'
for i in range(4):
HostAddr[i] = string.atoi(MatchResult.group(i+1))
if not RangeOk(HostAddr[i], 0, 255):
quitOutOfRange('HostAddr')
MaskLen = 8 # default is old class A
if (HostAddr[0] & 0xC0) == 0x80: # old class B
MaskLen = 16
print 'Assuming class B netmask\n'
elif (HostAddr[0] & 0xE0) == 0xC0: # old class C
MaskLen = 24
print 'Assuming class C netmask\n'
elif (HostAddr[0] & 0xF0) == 0xE0: # class D (multicast)
MaskLen = 4
# print 'Assuming class D netmask\n'
elif (HostAddr[0] & 0xF0) == 0xF0: # class E (experimental)
MaskLen = 4
# print 'Assuming class E netmask\n'
else:
if not (allBits0(HostAddr) or allBits1(HostAddr)):
print 'Assuming class A netmask\n'
else:
# print 'sys.exc_type=', sys.exc_type
print inpLine
print 'beats me...'
sys.exit(1)
i = 0
n = MaskLen
while n > 0:
bitmask = 0x80
for b in range(8):
if n > 0:
NetMask[i] = NetMask[i] | bitmask
n = n - 1
bitmask = bitmask >> 1
i = i + 1
#----------------------------------------------------------------------
def CalcHosts():
global NumHosts
NumHosts = 0L
for i in range(4):
NetAddr[i] = HostAddr[i] & NetMask[i]
Broadcast[i] = HostAddr[i] | (~NetMask[i] & 0xFF)
if (RangeOk(MaskLen, 0, 30)):
for i in range(4):
FirstHost[i] = NetAddr[i]
LastHost[i] = Broadcast[i]
FirstHost[3] = FirstHost[3] + 1
LastHost[3] = LastHost[3] - 1
NumHosts = (0x01L << (32 - MaskLen)) - 2L
#----------------------------------------------------------------------
def FormatDecBinHex(n):
global dottedQuad
global binString
global hexString
dottedQuad = '%d.%d.%d.%d' % (n[0], n[1], n[2], n[3])
hexString = '0x%02X%02X%02X%02X' % (n[0], n[1], n[2], n[3])
binString = ''
i = 0
m = 0
bitmask = 0x80
# set color for mask bits
binString = binString + TagDarkBlue
while i < 4:
while bitmask:
m = m + 1
if m > MaskLen:
break
if n[i] & bitmask:
binString = binString + '1'
else:
binString = binString + '0'
bitmask = bitmask >> 1
if m > MaskLen:
break
if not bitmask:
bitmask = 0x80
i = i + 1
if (i < 4):
binString = binString + '.'
# set color for host bits
binString = binString + TagNormal + TagDarkRed
while i < 4:
while bitmask:
if n[i] & bitmask:
binString = binString + '1'
else:
binString = binString + '0'
bitmask = bitmask >> 1
if not bitmask:
bitmask = 0x80
i = i + 1
if (i < 4):
binString = binString + '.'
# restore default color
binString = binString + TagNormal
#----------------------------------------------------------------------
def PrintInfo():
global NumHosts
if NetMaskBad:
tellBadMask('must be consecutive ones starting at MSB')
FormatDecBinHex(HostAddr)
if not isAddrRange:
print '%sHost%sAddr %-18.18s %s %s' \
% (TagDarkRed+TagBold, TagUnBold+TagNormal, dottedQuad, binString, hexString)
else:
print '%sAddress1%s %-18.18s %s %s' \
% (TagBold, TagUnBold, dottedQuad, binString, hexString)
if allBits1(HostAddr):
print '%sThis is the global broadcast address!%s' \
% (TagRed, TagNormal)
return
if isAddrRange:
FormatDecBinHex(HostAddr2)
print '%sAddress2%s %-18.18s %s %s' \
% (TagBold, TagUnBold, dottedQuad, binString, hexString)
FormatDecBinHex(NetMask)
print '%sNet%sMask %-18.18s %s %s' \
% (TagDarkBlue+TagBold, TagUnBold+TagNormal, dottedQuad, binString, hexString)
if allBits0(HostAddr) and allBits0(NetMask):
print '%sThis is the entire Internet!%s' % (TagRed, TagNormal)
print
FormatDecBinHex(NetAddr)
AddrAndMask = '%s/%s' % (dottedQuad, MaskLen)
print 'NetAddr %-18.18s %s %s' % (AddrAndMask, binString, hexString)
if not NetMaskBad:
if (RangeOk(MaskLen, 0, 30)):
FormatDecBinHex(FirstHost)
print 'First Host %-18.18s %s %s' % (dottedQuad, binString, hexString)
FormatDecBinHex(LastHost)
print 'Last Host %-18.18s %s %s' % (dottedQuad, binString, hexString)
if (RangeOk(MaskLen, 0, 31)):
FormatDecBinHex(Broadcast)
print 'Broadcast %-18.18s %s %s' % (dottedQuad, binString, hexString)
if (RangeOk(MaskLen, 0, 30)):
print 'N Hosts %s' % string.replace(str(NumHosts),"L","",1)
print
HostPtr = '%d.%d.%d.%d.in-addr.arpa.' \
% (HostAddr[3], HostAddr[2], HostAddr[1], HostAddr[0])
print '%-30.30s IN PTR' % HostPtr
if not NetMaskBad:
NetPtr = '%d.%d.%d.%d.in-addr.arpa.' \
% (NetAddr[3], NetAddr[2], NetAddr[1], NetAddr[0])
print '%-30.30s IN PTR' % NetPtr
print
if (NetAddr[0] & 0xF0) == 0xE0:
print 'Note: Network address is class D (multicast)'
elif (NetAddr[0] & 0xF0) == 0xF0:
print 'Note: Network address is class E (experimental)'
## if (NetAddr[0] & 0xF0) >= 0xE0 and MaskLen != 4:
## print ' %sThe mask length should possibly be 4%s' \
## % (TagRed, TagNormal)
#----------------------------------------------------------------------
# main prog
print 'NetCalc V1.1a'
OptionList, ArgList = getopt.getopt(sys.argv[1:], '', ['html', 'debug'])
# any args?
if len(ArgList) < 1:
print 'Need an argument...'
sys.exit(1)
# any options?
isHTML = 0
isDebug = 0
for Option, Value in OptionList:
if Option == '--html':
isHTML = 1
if Option == '--debug':
isDebug = 1
# init
if isHTML:
TagBlack = "<FONT COLOR=\"#000000\">"
TagDarkBlue= "<FONT COLOR=\"#001860\">"
TagDarkRed = "<FONT COLOR=\"#600000\">"
TagRed = "<FONT COLOR=\"#A00000\">"
TagNormal = "</FONT>"
TagBold = "<B>"
TagUnBold = "</B>"
else:
TagBlack = ""
TagDarkBlue= ""
TagDarkRed = ""
TagRed = ""
TagNormal = ""
TagBold = ""
TagUnBold = ""
isAddrRange = 0
# action
ParseInput(ArgList[0])
CalcHosts()
PrintInfo()
sys.exit(0)
пробуем...
Код: Выделить всё
#
# netcalc.py 192.168.0.0/22
NetCalc V1.1a
HostAddr 192.168.0.0 11000000.10101000.00000000.00000000 0xC0A80000
NetMask 255.255.252.0 11111111.11111111.11111100.00000000 0xFFFFFC00
NetAddr 192.168.0.0/22 11000000.10101000.00000000.00000000 0xC0A80000
First Host 192.168.0.1 11000000.10101000.00000000.00000001 0xC0A80001
Last Host 192.168.3.254 11000000.10101000.00000011.11111110 0xC0A803FE
Broadcast 192.168.3.255 11000000.10101000.00000011.11111111 0xC0A803FF
N Hosts 1022
0.0.168.192.in-addr.arpa. IN PTR
0.0.168.192.in-addr.arpa. IN PTR
#