Re: Programming w/ 2 Ethernet Cards

From: Shawn Bayern (shawn.bayern@yale.edu)
Date: Thu Jan 20 2000 - 20:13:42 EST


On Thu, 20 Jan 2000, Sasha Oblak wrote:

> I have two ethernet cards connected to my PC, and these two cards are
> connected to two different ethernets. I am trying to program some
> simple socket stuff, but I don't know how to specify which ethernet
> card I want to open the connection on. man pages are not helping.
>
> Does any body know how to open a connection on a specified enthernet
> card?

This is kind of subtle. My first response is really "are you sure that's
what you're trying to do?" The socket interface is a high-level
abstraction that lets you avoid thinking about low-level details; it just,
by default, passes datagrams to the IP stack for routing. You're
essentially asking about routing, so you may want to just solve your
problem at the level of the routing protocol.

To demonstrate what I mean, note that you can't do it with just bind(),
even though that looks like the obvious solution. Why bind()? Because
each one of your ethernet cards probably has at least one distinct IP
address associated with it. (Keep in mind that IP addresses, in
principle, are associated with interfaces, not hosts.) Thus, since you
can bind() a socket to a particular IP address, you might think that that
associates the socket to the network card that has that address. But it
doesn't work like that by default; bind() changes the source address for
the IP datagrams that go over the socket, but it doesn't actually affect
which interface the datagrams go out on. (You can easily end up with a
packet that's sent out over an interface whose IP address is different
from the packet's source IP address.)

Now, there's an option in setsockopt() called SO_DONTROUTE that's supposed
to avoid standard routing. If you set that, the routing protocol is
circumvented, and the packet is sent directly to the interface. At least,
that's what I *think* happens; I don't have a suitable machine to test it
on. But try that -- it might do exactly what you want. That is, in case
the order isn't clear,

        socket() -> setsockopt() -> bind() -> connect()

I'm assuming, of course, that you're setting up an outgoing connection.
For incoming connections, bind() does exactly what you want by default;
you can easily listen on a particular IP address (i.e., interface) instead
of listening on all of them.

Shawn



This archive was generated by hypermail 2b29 : Wed Apr 27 2005 - 03:30:03 EDT