[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Blocking sub-range of IP addresses



Actually, the previous post's usage of netmask would
probably do the trick:

floyd@deblin:~$ netmask -c 1.2.3.1:1.2.3.4
        1.2.3.1/32
        1.2.3.2/31
        1.2.3.4/32

so, e.g.:

for hostmask in `netmask -c 1.2.3.1:1.2.3.4`; do
iptables -A INPUT -s $hostmask -d `ifconfig eth0 |
grep 'inet addr' | awk '{print $2}' | cut -d: -f2` -p
tcp --dport 22 -j ACCEPT; done

would work nicely. Actually, this may make a nice
module for netfilter in the kernel for ipv4. That is,
being able to specify a contiguous IP block to
iptables and have it do the internal calculations that
netmask -c is doing. Something like:

iptables -m ip_block -A INPUT -s 1.2.3.1:1.2.3.4 -d
...

Would be really cool.

Anyway, thanks for the suggestions all!
Josh

--- Karl Hammar <karl@kalle.csb.ki.se> wrote:
> > It would be useful to have something that would
> take
> > an IP address range and return the minimum
> coverage
> > CIDR for that block (for use in feeding to
> iptables).
> > 
> > For example, if I want to allow access for hosts
> > 1.2.3.1 - 1.2.3.4, I currently can allow them
> > individually or just allow the entire /24. But is
> > there any easier way to allow ip ranges in
> iptables,
> > short of doing each individual IP or generalizing
> to a
> > class boundary? Can ipsc do this easily?
> > 
> > Thanks,
> > Josh
> ...
> 
>  I don't really have that, but attached program
> gives you the longest
> common prefix for a few ip's.
> 
>  $ ./ipnumber -p 192.168.93.3 192.168.93.2
> 192.168.93.1
>  192.168.93.0/30 (255.255.255.252)
>  $ ./ipnumber -p 192.168.90.3 192.168.2.28          
>   
>  192.168.0.0/17 (255.255.128.0)
> 
> Regards,
> /Karl
> 
>
-----------------------------------------------------------------------
> Karl Hammar                    Aspö Data          
> karl@kalle.csb.ki.se
> Lilla Aspö 2340                                     
>           Networks
> S-742 94 Östhammar          +46  173 140 57         
>          Computers
> Sweden                     +46  70 511 97 84        
>         Consulting
>
-----------------------------------------------------------------------
> 
> > /** Copyright: Karl Hammar, Aspö Data
>  ** Copyright terms: GPL
>  **/
> 
> #include <arpa/inet.h>
> #include <ctype.h>
> #include <errno.h>
> #include <netinet/in.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
> 
> /* int function return value: 0 == SUCCESS, else
> error */
> 
> /*
>  * Ip numbers (or addresses, same thing differnet
> names)
>  * are just 32 bit unsigned integers
>  * the numbers we are used to (e.g. "192.168.1.3")
>  * are only a way to present thoose ip numbers for
> humans.
>  * That format is called dotted quad, since it
> consists of
>  * four ("quad") numbers with dots between.
>  *
>  * Theese two routinges convert between the human
> and computer
>  * way of seeing the ip numbers
>  */
> int dot2num( char *dotted_quad, uint32_t *num);
> 
>  /* len is length of dotted_quad buffer.
>   * len >= INET_ADDRSTRLEN, see man inet_ntop
>   */
> int num2dot( uint32_t  num, char *dotted_quad,
> size_t len);
> 
> /* convert so can print/read binary numbers, sorry
> printf/scanf don't do this */
> int str2num( char *str, uint32_t *num, char **ptr);
>  /* the buffers length (len) must be at least 33
> characters long (32 digits + one '\0')  */
> int num2str( uint32_t  num, char *buffer, size_t
> buflen);
> 
> /*
> to help routers, ip numbers are split in two parts:
> the first is a network prefix and
> the latter is computer (or host, well actually
> interface) number on that network
> 
> It works like ip_address = network_number +
> computer_number_on_that_network
> You can compare it to a memory buffer, address (aka.
> ip number) = buffer_pointer (aka. network) + offset
> (aka. host number on that network)
> 
> This helps routers since they don't have to store
> routes to all hosts
> they only have to keep records of networks.
> Also "network" is not necceserely the same thing as
> a LAN.
> Network is just all computers with some common top
> bits in their ip numbers
> (note: "common top bits" i.e. ALL bits before the
> split, and
> remember ip numbers is a simple unsigned integer)
> that you can reach if you go along a given route.
> 
> Subnetting is really that simple!
> But the dotted quad format makes it hard see and
> understand.
> Why -- because the dot makes the split between
> network and host part hard to see.
> 
> By counting number of bits in the prefix we get the
> prefix length,
> which is the same number as used in the cidr
> notation.
> 
>  Public example:
> hostname    ip number      as binary
> www.ibm.com 129.42.17.99  
> 10000001001010100001000101100011
> www.ge.com  216.74.139.56 
> 11011000010010101000101100111000
> common prefix              1
> prefix length              1
> 
>  Local example:
> calcit      192.168.93.1  
> 11000000101010000101110100000001
> hematit     192.168.93.2  
> 11000000101010000101110100000010
> granat      192.168.93.37 
> 11000000101010000101110100100101
> common prefix             
> 11000000101010000101110100
> prefix length              26
> 
> The bit positions where the prefix is, are called
> network bits,
> and the others (representing the host part) are
> called the host bits.
> 
> The ip number with address 0 on a network is called
> the "network address"
> and it is that number which goes into the routing
> table along with the prefix length.
> Another related number is the broadcast address.
> It is useful on a ethernet LAN.
> The broadcast address is by convention the last
> address of a network.
> 
> The network address is only meaningful for routing,
> i.e. in the IP-layer,
> and the broadcast address have the same meaning as
> the ip number.
> A given host accept packets to that address as
> destined to itself and have
> no meaning besides that and that all hosts on a
> given physical (or end) network
> should have the same broadcast address so you easily
> can address them all.
> So, the broadcast address do not have a meaning for
> all networks.
> 
> To tell the world about a network, we use the
> network address
> (or any address on the same network, since they have
> the same prefix)
> and the prefix length.
> It is usually presented like "192.168.93.0/26" or
> "network: 192.168.93.0, subnet mask:
> 255.255.255.192"
> The first variant is called the CIDR notation and
> the second is presented with a netmask (or subnet
> mask).
> In the CIDR notation we uses the prefix length
> directly,
> The netmask is an 32 bit unsigned integer with all
> bits in the prefix set to high (1)
> and all other set to low (0).
> It is then converted to dotted quad notation just as
> eny other ip number.
> 
>  Example:
> network   192.168.93.0   
> 11000000101010000101110100000000
> granat    192.168.93.37  
> 11000000101010000101110100100101
> broadcast 192.168.93.63  
> 11000000101010000101110100111111
> 
> prefix                    11000000101010000101110100
> netmask   255.255.255.192
> 11111111111111111111111111000000
> */
> 
> uint32_t get_network_bits(uint32_t num, uint32_t
> mask);
> uint32_t get_host_bits(   uint32_t num, uint32_t
> mask);
> uint32_t get_network_number(uint32_t num, uint32_t
> mask);
> uint32_t get_broadcast_address(uint32_t num,
> uint32_t mask);
> 
> int update_common_prefix(uint32_t *prefix, int
> *cidr, uint32_t num);
> int cidr2mask(int cidr, uint32_t *mask);
> int mask2cidr(uint32_t mask, int *cidr);
> 
>
/************************************************************************/
> struct {
>   char *cmd;
> } global;
> 
> int Usage(void);
> int do_b(int argc, char *argv[]);
> int do_B(int argc, char *argv[]);
> int do_m(int argc, char *argv[]);
> int do_M(int argc, char *argv[]);
> int do_p(int argc, char *argv[]);
> int do_i(int argc, char *argv[]);
> int do_r(int argc, char *argv[]);
> 
> int Usage(void) {
>   printf("Usage:\n");
>   printf("	%s -b ip.nr\n", global.cmd);
>   printf("	%s -B binary_number\n", global.cmd);
>   printf("	%s -m netmask\n", global.cmd);
>   printf("	%s -M cidr\n", global.cmd);
>   printf("	%s -p ip.nr ...\n", global.cmd);
>   printf("	%s -i ip.nr subnetmask\n", global.cmd);
>   printf("	%s -i ip.nr/cidr\n", global.cmd);
>   printf("	%s -r ip.nr subnetmask\n", global.cmd);
>   printf("	%s -r ip.nr/cidr\n", global.cmd);
>   printf("Synopsis:\n");
> 
=== message truncated ===



Reply to: