Check Arbitrary Network Blocks in CIDR Notation
Last Update 1998-08-27
From: ad@ultra.net (Alex Petrov)
Newsgroups: comp.mail.sendmail
Subject: support for CIDR networks
Date: Wed, 19 Aug 1998 23:54:48 GMT
Message-ID: <35db61a5.38855432@10.20.30.41>
i noticed that majority of (ruleset) code which implements access
control based on {client_addr} supports only classfull networks:
A.B.C.D - host (/32)
A.B.C - class C (/24)
A.B - class B (/16)
A - class A (/8)
here is an example of this kind of code:
SLookUpAddress
R<$+> <$+> <$*> $: < $(access $1 $: ? $) > <$1> <$2> <$3>
R<?> <$+.$-> <$+> <$*> $@ $>LookUpAddress <$1> <$3> <$4>
R<?> <$+> <$+> <$*> $@ <$2> <$3>
R<$*> <$+> <$+> <$*> $@ <$1> <$4>
i have a jcode which supports arbitrary network blocks in cidr
notation A.B.C.D/N. it uses "netmasks" class which helps determine
supernet for a given host or network. (for example, supernet for host
12.34.56.78 is 12.34.56.78/31, supernet for network 12.34.56.78/31 is
12.34.56.76/30, etc see the table bellow (note that table continues
only up to /16 which is enough for practical purpuses).
host/network supernet
==============================
12.34.56.78 12.34.56.78/31
12.34.56.78/31 12.34.56.76/30
12.34.56.76/30 12.34.56.72/29
12.34.56.72/29 12.34.56.64/28
12.34.56.64/28 12.34.56.64/27
12.34.56.64/27 12.34.56.64/26
12.34.56.64/26 12.34.56.0/25
12.34.56.0/25 12.34.56.0/24
12.34.56.0/24 12.34.56.0/23
12.34.56.0/23 12.34.56.0/22
12.34.56.0/22 12.34.56.0/21
12.34.56.0/21 12.34.48.0/20
12.34.48.0/20 12.34.32.0/19
12.34.32.0/19 12.34.0.0/18
12.34.0.0/18 12.34.0.0/17
12.34.0.0/17 12.34.0.0/16
"netmasks" class contains pairs like:
78 78/31
78/31 76/30
76/30 72/29
72/29 64/28
64/28 64/27
64/27 64/26
64/26 0/25
0/25 0/24
56.0/24 56.0/23
56.0/23 56.0/22
56.0/22 56.0/21
56.0/21 48.0/20
48.0/20 32.0/19
32.0/19 0.0/18
0.0/18 0.0/17
0.0/17 0.0/16
total size of "netmasks" file is 1276 records. netmasks.db file size
is 57344 bytes. I have a small perl script which generates netmaksks
file.
the code bellow supports access file entries like:
12.34.56.64/26 ok
12.34.56.0/22 relay
12.34.56.29/30 discard
12.34.56.128/25 reject
the algorithm is the following: for each network containing
{client_addr} starting from a /32 (host address) to maximum
of /16 check if this network has an entry in access class.
and finaly here is the code:
C{notfound} notfound
Knetmask hash /etc/mail/netmasks.db
Sexample
R$* $: $(dequote "" $&{client_addr} $)
R$*.$* $>check_all_supernets $1.$2
R$~{notfound} $@ $1 return if match found
# if match not found other tests may follow
...
##
Scheck_all_supernets
R$* $: $>supernet $1
R notfound $@ notfound
R$* $: $1 $| $>check_access $1
R$* $| notfound $@ $1
R$* $| $* $@ $2
R$* $# 4.3.5. $: 435 <$1> internal error in supernet block
Scheck_access
R$* $@$(access $1$:notfound$)
Ssupernet
R$+.$+.$+.$+/$+ $: $1.$2.$3.$(netmask $4/$5 $:$4^$5 $)
R$+.$+.$+.$+^$+ $: $1.$2.$(netmask $3.$4/$5 $:notfound $)
R$* notfound $@ notfound
R$+.$+.$+.$+/$+ $@ $1.$2.$3.$4/$5
R$+.$+.$+.$+ $: $1.$2.$3.$(netmask $4 $:$4^ $)
R$*^ $# 4.3.5. $: 435 internal error in netmasks database
R$* $@ $1
let me know if you found this interesting or have any questions.
-alex
ad@ultra.net
[Content]
Claus Aßmann
Please send comments to:
<ca@sendmail.org>