Is there an easier way? I would like to be able to just put
'61.134.3.0 - 61.134.20.95' in a rule.
Well here's a pretty ugly, but generic, answer. It makes use of David's
suggested recipe. It also calls out to the shell to get some maths
done. You could have a much less ugly solution by having some external
process do all the range checking.
Also, this relies on the shell expression '$(( a * b + c ))' being treated
as an arithmetic expression. Bash does that. Other shells may or may
not. If your shell doesn't, you can get the same effect by doing
'echo "a * b + c" | bc' or by one of a dozen other methods.
# some multipliers that we'll use
m1=16777216
m2=65536
m3=256
# the range of IP addresses that we want to check for
# in this case 61.134.3.0 - 61.134.20.95
rangemin=`echo $(( 61*$m1 + 134*$m2 + 3*$m3 + 0 ))`
rangemax=`echo $(( 61*$m1 + 134*$m2 + 20*$m3 + 95 ))`
# note that really you would say
# rangemin=1032192768
# rangemax=1032197215
# to avoid having to do those calculations for every mail
# David's bit:
:0
* ^Received:.*\[\/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\]
{
IP=$MATCH
:0
* IP ?? ^^\/[0-9]+
{
byte1=$MATCH
:0
* $ IP ?? ^^()$byte1\.\/[0-9]+
{
byte2=$MATCH
:0
* $ IP ?? ^^()$byte1\.$byte2\.\/[0-9]+
{
byte3=$MATCH
:0
* $ IP ?? ^^()$byte1\.$byte2\.$byte3\.\/[0-9]+
{
byte4=$MATCH
# convert that IP address to an integer
res=`echo $(( $byte1*$m1 + $byte2*$m2 + $byte3*$m3 + $byte4))`
# and use scoring to see if it is in range
:0
* 1^0
* $ -$rangemin^0
* $ $res^0
{
:0
* 1^0
* $ -$res^0
* $ $rangemax^0
JunkMail.$TODAY
}
}
}
}
}
}
Personally I'd just pass it all out to Perl to do the range check.
Martin
--
Martin McCarthy /</ PGP key available
`Procmail Companion' \>\ http://www.ancient-scotland.co.uk
Addison Wesley /</ http://www.ehabitat.demon.co.uk
_______________________________________________
procmail mailing list
procmail(_at_)lists(_dot_)RWTH-Aachen(_dot_)DE
http://MailMan.RWTH-Aachen.DE/mailman/listinfo/procmail