Can I bind a (large) block of addresses to an interface?

Solution 1:

Linux 2.6.37 and above supports this via a feature called AnyIP. For instance if I run

ip route add local 2001:db8::/32 dev lo

on an Ubuntu 11.04 machine it will accept connections on any address in the 2001:db8::/32 network.

Solution 2:

Yes, Linux supports binding a block of network addresses to a network interface... but only on the loopback interface. So you can do this:

ip addr add 192.168.5.0/24 dev lo

And then do this:

$ nmap -sP -oG - 192.168.5.0/24

# Nmap 5.21 scan initiated Tue Dec  7 11:38:28 2010 as: nmap -sP -oG - 192.168.5.0/24 
Host: 192.168.5.0 ()    Status: Up
Host: 192.168.5.1 ()    Status: Up
Host: 192.168.5.2 ()    Status: Up
[...]
Host: 192.168.5.254 ()  Status: Up
Host: 192.168.5.255 ()  Status: Up
# Nmap done at Tue Dec  7 11:38:46 2010 -- 256 IP addresses (256 hosts up) scanned in 0.11 seconds

With the appropriate routes in place this will do what you want... for IPv4 addresses. You've asked about IPv6, and I don't have any experience with IPv6, but there's a good chance it will work the same way.

I originally read about this here (towards the bottom of the article). Note that this article also discusses how to explicitly assign multiple addresses to an interface using CentOS/Red Hat features I hadn't previously known about.


Solution 3:

So I see a few options here:

  1. use a script to bind the addresses all to the interface individually

  2. route the block you want to the single address of your machine, and then have that machine use the pcap interface to intercept all traffic for said block (as if it was a router) and handle it.

  3. You could concievably play tricks with NAT rules to then rewrite a block of Ips that were routed to one machine into a single internal IP on that machine... but you'll still end up with one internal IP per IP you really want to pay attention to, which gets you back to solution 1.

If I were you, I'd just write the small script in option 1. Or use the one from here:

#!/bin/sh
if [ "$#" -ne "4" ]; then
        echo Usage:
        echo " $0 interface ip range netmask"
        echo " examples:"
        echo "  1) Assuming you want to bind the IP range 192.168.0.1..192.168.0.254 to eth0 with netmask 255.255.255.0:"
        echo "  $0 eth0 192.168.0. 1..254 255.255.255.0"
        echo "  2) Assuming you want to bind the IPv6 range 2001:41d0:1:5000::1-2001:41d0:1:5000::254 to eth0 with netmask /56"
        echo "  $0 eth0 2001:41d0:1:5000:: 1..254 56"
else
        echo "Attempting to assign the IP range $2($3) to interface $1 with netmask $4"
        for ip in $(eval echo "{$3}"); do ifconfig -v $1 add $2$ip netmask $4; done
fi

Solution 4:

As others have said, you can use the AnyIP mechanism to route arriving packets for an entire subnet to the localhost interface, but keep in mind that you'll also need to get your upstream router to route all of the desired packets to this machine in the first place. This can be done simply with routing table entries on the router, or via BGP. ARP is not really appropriate given that your machine would have to ARP for each IP individually.

Tags:

Linux

Ipv6