Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.os.linux.misc > #85981
| From | John Ames <commodorejohn@gmail.com> |
|---|---|
| Newsgroups | comp.os.linux.misc |
| Subject | Re: CIDR Calculator |
| Date | 2026-04-27 13:31 -0700 |
| Organization | A place where nothing fits quite right |
| Message-ID | <20260427133111.00001bba@gmail.com> (permalink) |
| References | <XnsB43B9C55314F7makowiecatnycapdotrE@157.180.91.226> |
On Mon, 27 Apr 2026 19:22:04 -0000 (UTC)
Joe Makowiec <makowiec@invalid.invalid> wrote:
> However, if you feed it something like 192.168.0.8 to 192.168.5.200,
> it gives back a bunch of ranges with a number of /29s and /26s, a
> couple of /24s and a total of a dozen ranges. What i want is a
> calculator which will look at the high and the low, and figure out
> that 192.168.0.0/21 will cover the whole thing.
>
> Added useless information: what prompts this request is that my
> mailserver has been getting hit with a bunch of sasl hack attempts,
> many of which come from Bharti Airtel, which I assume is an ISP or a
> wireless / cellphone provider.
Funnily enough, I was just having to do this the other way 'round some
months ago - whitelisting StarLink and its nineteen billion /8s for
certain customers as we try to block wardialing on our RDP servers. If
it helps, this is the utility I came up with - not *exactly* what you
specified, but it'll sort a list of CIDRs and combine contiguous ranges
into single entries.
Written in FreeBasic. Usage: melonballer [in-file] [out-file]
### melonballer.bas ###
type cidr
ip as ulong
r as ubyte
end type
function parseCider(s as string) as cidr
dim as string z
dim as integer i, j
dim as ubyte q(5)
dim as cidr c
z = ""
j = 0
for i = 1 to len(s)
if asc(mid(s,i,1)) >= asc("0") and asc(mid(s,i,1)) <= asc("9") then
z = z & mid(s,i,1)
else
q(j) = val(z)
j += 1
z = ""
endif
next
if z <> "" then
q(j) = val(z)
j += 1
endif
if j < 5 or q(4) > 31 then
c.ip = 0
c.r = 32
else
c.ip = q(0) shl 24
c.ip = c.ip or (q(1) shl 16)
c.ip = c.ip or (q(2) shl 8)
c.ip = c.ip or q(3)
c.r = q(4)
endif
parseCider = c
end function
function squeezeCider(ipBase as ulong, ipBound as ulong) as cidr
' Returns a CIDR covering the given range.
dim as cidr c
dim as ulong i
c.ip = ipBase
i = ipBound - ipBase
c.r = 0
do while i > 1
i = i shr 1
c.r += 1
loop
c.r = 32 - c.r
squeezeCider = c
end function
function ipMin(c as cidr) as ulong
dim as long i
i = -1 shl (32 - c.r)
ipMin = c.ip and i
end function
function ipMax(c as cidr) as ulong
ipMax = c.ip + (1 shl (32 - c.r)) - 1
end function
function contiguous(foo as cidr, bar as cidr) as Boolean
' Returns true if foo comes after bar.
contiguous = false
if ipMax(bar) + 1 = foo.ip then contiguous = true
end function
function contained(foo as cidr, bar as cidr) as Boolean
' Returns true if foo falls within bar.
contained = false
if foo.ip >= bar.ip and ipMax(foo) <= ipMax(bar) then contained = true
end function
function powerOfTwo(i as ulong) as Boolean
' Returns true if i is a power of two.
dim as ulong j
powerOfTwo = false
if i = 1 then powerOfTwo = true
if i <= 1 then exit function
j = 1 shl 31
do while ((i and j) = 0) and j <> 0
j = j shr 1
loop
j -= 1
if ((i and j) = 0) and j <> 0 then powerOfTwo = true
end function
function printCider(c as cidr) as string
dim as string s
s = ""
s &= str(c.ip shr 24) & "." & str((c.ip shr 16) and 255) & "." & str((c.ip shr 8) and 255) & "." & str(c.ip and 255) & "/" & str(c.r)
printCider = s
end function
function printIp(ip as ulong) as string
dim as string s
s = ""
s &= str(ip shr 24) & "." & str((ip shr 16) and 255) & "." & str((ip shr 8) and 255) & "." & str(ip and 255)
printIp = s
end function
open command(1) for input as 1
dim as integer i, j, k, bookmark
dim as cidr cList(), oList(), c
dim as string s
' Build the input list.
do while not eof(1)
line input #1, s
c = parseCider(trim(s))
if ubound(cList) < 0 then
redim cList(0)
cList(0) = c
continue do
endif
redim preserve cList(ubound(cList) + 1)
cList(ubound(cList)) = c
loop
close 1
' Build the output list.
redim oList(0)
oList(0) = cList(0)
for i = 1 to ubound(cList)
for j = 0 to uBound(oList)
' Have we already covered this range?
if contained(cList(i), oList(j)) then goto skipEntry
if contiguous(cList(i), oList(j)) then
' We've hit a block of contiguous addresses - see how far it goes before we can't combine them.
bookmark = i
k = i + 1
do while k <= ubound(cList)
' If we're no longer contiguous; stop searching.
if not contiguous(cList(k), cList(k - 1)) then exit do
' Is the range we're covering a power of two?
if powerOfTwo((ipMax(cList(k)) + 1) - oList(j).ip) then bookmark = k
k += 1
loop
' The range from oList(j) to cList(bookmark) is contiguous and power-of-two-sized; combine it.
s = printCider(oList(j))
for k = i to bookmark
s &= ", " & printCider(cList(k))
next
c = squeezeCider(oList(j).ip, ipMax(cList(bookmark)) + 1)
if ipMin(c) = oList(j).ip and ipMax(c) = ipMax(cList(bookmark)) then
oList(j) = c
s &= " -> " & printCider(c)
print s
print "Min: "; printIp(ipMin(cList(i))), "Max: "; printIp(ipMax(cList(bookmark))), printCider(c); ": "; printIp(ipMin(c)); " - "; printIp(ipMax(c))
print
' Advance past cList(bookmark).
i = bookmark
endif
goto skipEntry
endif
next j
' If we've gotten this far and have neither skipped nor combined, add it to the output list.
redim preserve oList(ubound(oList) + 1)
oList(ubound(oList)) = cList(i)
skipEntry:
next i
' Write the output list.
open command(2) for output as 1
for i = 0 to ubound(oList)
print #1, printCider(oList(i))
next
close 1
Back to comp.os.linux.misc | Previous | Next — Previous in thread | Next in thread | Find similar
CIDR Calculator Joe Makowiec <makowiec@invalid.invalid> - 2026-04-27 19:22 +0000
Re: CIDR Calculator John Ames <commodorejohn@gmail.com> - 2026-04-27 13:31 -0700
Re: CIDR Calculator Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-04-29 01:59 +0000
Re: CIDR Calculator Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-04-27 22:35 +0000
Re: CIDR Calculator Marc Haber <mh+usenetspam2616@zugschl.us> - 2026-04-28 07:49 +0200
Re: CIDR Calculator Rene Kita <mail@rkta.de> - 2026-04-29 07:09 +0000
Re: CIDR Calculator Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-04-29 08:05 +0000
Re: CIDR Calculator Fritz Wuehler <fritz@spamexpire-202604.rodent.frell.theremailer.net> - 2026-04-29 00:08 +0200
Re: CIDR Calculator 🇵🇱Jacek Marcin Jaworski🇵🇱 <jmj@energokod.gda.pl> - 2026-04-29 07:10 +0200
Re: CIDR Calculator 🇵🇱Jacek Marcin Jaworski🇵🇱 <jmj@energokod.gda.pl> - 2026-04-29 23:52 +0200
csiph-web