Re: how to tell a socket to use a specific interface...
Re: how to tell a socket to use a specific interface...
- Subject: Re: how to tell a socket to use a specific interface...
- From: Bryan Christianson <email@hidden>
- Date: Sat, 21 May 2005 12:12:56 +1200
At 2:20 PM -0500 5/20/05, Philip George wrote:
How can I specify that a socket use a specific interface?
I thought it was bind() that did this, but it doesn't seem like
that's what it's doing at all.
If I have an airport connection to one network and a cat5 connection
to another, how can i tell my socket to use a specific one.
Here's the code i've got that isn't working (although I'm pretty
sure the setsockopt() line is okay) :
// setup local address stuff...
struct sockaddr_in LOCaddr;
LOCaddr.sin_family = AF_INET;
LOCaddr.sin_addr.s_addr = inet_addr(local_ip);
// set to true for SO_DONTROUTE...
int drval = 1;
// bind to specific interface and then set SO_DONTROUTE...
if (bind(sockethandle, (struct sockaddr *)&LOCaddr, sizeof(LOCaddr))==0) {
setsockopt(sockethandle, SOL_SOCKET, SO_DONTROUTE, &val, sizeof(val));
}
Now that I'm looking at this isolated code, it seems more and more
obvious that bind() isn't what i want. Haha. Now that I think
about it, I guess it's probably more likely related to the dns
server called 'bind'.
In any case... what is it that I need to do here?
Thanks.
- Philip
I solved this problem by forking off the route command and
interpreting the returned string to find the interface that the
kernel will use to send the packet. Its kind of ugly, but without
messing around in routing tables etc it does seem to work pretty well.
From inside my program I execute this shell command (use popen or equivalent)
/sbin/route get <ip address>
This returns:
route to: <ip address>
destination: default
mask: default
gateway: cora
interface: en0
flags: <UP,GATEWAY,DONE,STATIC,PRCLONING>
recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
0 0 0 0 0 0 1500 0
which is then easily scanned to find the interface name (en0 in this case).
There are a number of different ways to get the IP address associated
with this interface, the simplest one (that I know of) being the
ioctl call (see below). This then tells you the IP address of the
interface from which your packet will be sent.
However, the choice of interface is made by the routing setup, not by
the code that sends the packet. You can adjust the 'preferred'
interface using the the Network control in System Settings and moving
your 'preferred' interface to the top of the list of Network Port
Configurations - i.e adjusting the default route.
Hope that helps.
int getinterfaceaddress(char *ifname, struct in_addr *addr) {
int error = 0;
int sock;
struct sockaddr_in *sa;
struct ifreq ifreq;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock < 0)
return(-1);
strncpy(ifreq.ifr_name, ifname, sizeof(ifreq.ifr_name));
error = ioctl(sock, SIOCGIFADDR, &ifreq);
if(!error) {
sa = (struct sockaddr_in *)&ifreq.ifr_addr;
*addr = sa->sin_addr;
}
close(sock);
return(error);
}
--
Bryan Christianson
email: <mailto:email@hidden>
Home Page: <http://crash.ihug.co.nz/~bryanc>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden