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: