[Nagiosplug-devel] feature request -selecting your network interface

Andreas Ericsson ae at op5.se
Mon Oct 2 11:21:28 CEST 2006


Ahh, the wonders of opensource. Someone got curious and Good Things 
Happened. Kudos for introducing the concept in actual code.

More below.

bobi at netshel.net wrote:
> Hi,
> 
> I don't know why I felt like doing this - guess I was curious if you could
> bind to a local address for a TCP stream prior to calling connect(2).  I
> didn't think it would work, because the routing table usually controls
> which interface to send a packet out on (and hence, which source IP
> address to emebed in the IP header.)  But if an address is reachable from
> more than one interface, I supposed it could work.
> 
> Anyway, please find attached a tar-ball containing three patch files for:
> 
> 1. netutils.h
> 2. netutils.c
> 3. check_tcp.c
> 
> If you patch the above three files, and re-make check_tcp, it will allow
> you to specify the source IP address.
> 
> The new option is: -I src-ip-address
> 
> I've tested it on my Linux box which has two interfaces (plus loopback,)
> and it seems to work well.  I watched the packets go out with tcpdump and,
> sure enough, the IP headers had the source IP address that I'd specified
> in the command line.
> 
> One note, though:  If you specify an interface IP address which can't
> reach your destination host, the connect(2) call inside netutils.c will
> return an EINVAL error.  I know this because I tried accessing an external
> host through the loopback interface (127.0.0.1) and it returned EINVAL,
> which is what you'd expect.
> 

Yup. The only objection I have to this patch is the lack of an 
error-message when the user has done this exact mistake, or when the 
user has put a source-ip that's not present on the system as argument to -I.

So after the connect(2) call, I'd put something like this:
---%<---%<---%<---
if (result < 0 && src_ip && errno == EINVAL)
   die("UNKNOWN: Can't send to %s through interface with address %s\n",
       target, src_ip);
---%<---%<---%<---


and after the bind(2) call, I'd put something like this:
---%<---%<---%<---
/* SVr4 defines EADDRNOTAVAIL. Many systems have it, so check for it */
#ifdef EADDRNOTAVAIL
if (result < 0 && errno == EADDRNOTAVAIL)
	die("UNKNOWN: Can't send from source-ip %s. No interface has that 
address\n", source_ip);
#endif
---%<---%<---%<---

With proper variables, inet_ntoa()'s and die() semantics, ofc (yes, I 
actually am that lazy ;-)

-- 
Andreas Ericsson                   andreas.ericsson at op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231




More information about the Devel mailing list