views:

40

answers:

2

I am writing a C library which involves telling other computers on the subnet to send me messages. Therefore I must announce to them my IP address. This library should work on Linux, OS X and Windows. Currently I'm thinking mostly about the POSIX layer.

Given that a computer can have more than one address (for example if it has more than one network interface),

  1. What's the best way to find my default IP address (e.g. in the simplest most common case of a computer with a single connection to the subnet.) Currently I'm cycling through the system NICs using getifaddrs and returning the first one that is associated (with preference to non-loopback), but I think this is probably not adequate.

  2. What would be a good API for allowing users of the library to choose which interface to send on? I assume some sort of enumeration of the NICs and IPs of the computer, then selecting the NIC by name and finding its IP. This seems pretty complicated from a user standpoint though. Perhaps some way to determine the system's route to the subnet by netmask, given the IP of another computer on the subnet? I have little idea how to do that, though.

For 2, we can eventually assume there may be a GUI or command-line option allowing users to choose the NIC, but in general I want to make it as easy as possible for it to automatically tell other computers how to direct UDP messages to it.

Any opinions appreciated, thanks!

+2  A: 

If you're already communicating with other computers using IP, the packets will already be announcing a return address that the far end can use to determine where its messages should go.

Attempting to deduce the right interface address to use and embedding it in a message isn't a good idea for four reasons (probably more). First, you're going to end up reimplementing all of the logic your OS does to figure out how to route outbound packets. Second, if the routing table changes between the time you make that decision and the time you actually need to connect to the other computers and tell them where to send traffic, you'll be sending them the wrong address. Third, the destination computers may not always be on the same subnet, in which case none of the interfaces will match. Fourth, if the packets undergo any form of rewriting (e.g., NAT) between you and the destination, the software doing it will have no idea that it needs to dive into your packets and the systems at the far end won't be using the right address.

Blrfl
okay thanks, I agree with your answer in principle, except your first point: "you're going to end up reimplementing all of the logic your OS does to figure out how to route outbound packets." Actually I was asking if there's a way I can get the OS to do this for me and let me query its decision, not how I can reimplement it myself.
Steve
Ah, okay. I read your question as asking how to figure it out beforehand without making a connection so you could suggest one to your user. The only way I can think of to do that is to actually establish a connection and then call `getsockname()` to see how it fell out. By that point, the far end can already determine the near-end's IP, so sending it is kind of a moot point. The only other way is to query the routing table (which I'm 97% sure can't be done portably) and figure the source interface manually.
Blrfl
A: 

1. Default ip address

There isn't really such a thing as a default ip address of a host. In general though most hosts are configured with a default route that the OS decides to use if it can't find, by looking at it's routing table in conjunction with the destination ip address of the packet, another interface to send a packet out on. This interface will have an ip address and I suppose you could consider it to be the default ip address. But, in the case of a multi-homed host the source ip address that is used depends on the destination ip address in the ip header and that's worked out by the operating system in conjuction with the routing table. Which is why there's no such thing as a default ip address. And even if you did use the ip address associated with the default route, and told the users of the other hosts about this address there's no gaurantee that a packet from their end to your host will arrive because their hosts might be on a different subnet (i.e. not accessable via the default route).

2. Routing API:

This sounds like you want to implement some sort of routing at the application level. This logic is something the operating system handles when deciding where to send a packet, so I don't think you need to implement this.

3. Advertizing services and mDNS:

If you know that the other hosts are on the same subnet look into mDNS (mulitcast dns). This will allow you to advertize services (ip address, port number) that your host has and other hosts that contact the same multicast group can discover this information. avahi is an implementation of mDNS.

sashang
"This sounds like you want to implement some sort of routing at the application level." Not really. Maybe I should have said it in the question, but I want to announce on a multicast port what my IP address is so that other clients can send me messages directly.
Steve
@Steve: If that's the case then look into multicast dns. It allows a host to announce ip addresses.
sashang