Hi Joe,
you wrote:
> I'm running Smoothwall on Linux and would like to use ipchains to
> block internet access from a particular range of internal ip addresses
> (192.168.0.110 to 192.168.0.190) on my network. Is this possible
> without writing a seperate line for each address? Can I do something
> like:
>
> ipchains -A input -j DENY -p all -l -s 192.168.0.110 - 192.168.0.110
No, ipchains can only match on networks where the smallest network is a
single IP. You have to specify it with the network number and netmask.
For your example this gives following 8 networks:
$ ./cidr 192.168.0.110 192.168.0.190
192.168.0.110/31
192.168.0.112/28
192.168.0.128/27
192.168.0.160/28
192.168.0.176/29
192.168.0.184/30
192.168.0.188/31
192.168.0.190/32
Note that if you can include 192.168.0.191 into the rule only 3 networks
are needed to specify the complete range:
$ ./cidr 192.168.0.110 192.168.0.191
192.168.0.110/31
192.168.0.112/28
192.168.0.128/26
As the usual tools seems not to do this calculation for you I attached a
little C program doing it.
Michael
--
Linux@TekXpress
http://www-users.rwth-aachen.de/Mich...kxp/tekxp.html
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void printcidrs(u_int32_t ip_start, u_int32_t ip_end)
{
int bits1;
u_int32_t temp;
// Count the number of ending 0 bits in ip_start to get a starting point
for ( temp=ip_start,bits1=0; bits1<32; bits1++,temp>>=1 )
if ( temp & 1 )
break;
// Reduce this count until ip_end fits into the range
while ( bits1 > 0 )
{
if ( (ip_start | ((1<<bits1)-1)) <= ip_end )
break;
bits1--;
}
// Now print the CIDR for the first part
{
struct in_addr ip;
ip.s_addr = htonl(ip_start);
printf("%s/%d\n", inet_ntoa(ip), 32-bits1);
}
ip_start |= ((1<<bits1)-1);
ip_start++;
if ( ip_start <= ip_end )
printcidrs(ip_start, ip_end);
}
int main(int argc, char*argv[])
{
if ( argc == 3 )
{
struct in_addr ip_start, ip_end;
if ( inet_aton(argv[1], &ip_start) )
{
if ( inet_aton(argv[2], &ip_end) )
{
ip_start.s_addr = ntohl(ip_start.s_addr);
ip_end.s_addr = ntohl(ip_end.s_addr);
if ( (u_int32_t)ip_start.s_addr <= (u_int32_t)ip_end.s_addr )
{
printcidrs(ip_start.s_addr, ip_end.s_addr);
}
else
printf("start '%s' is not less or equal end '%s'\n", argv[1], argv[2]);
}
else
printf("'%s' in not a dot-quad\n", argv[2]);
}
else
printf("'%s' in not a dot-quad\n", argv[1]);
}
else
printf("Usage: %s start-IP end-IP\n", argv[0]);
return 1;
}