Monday, May 6, 2013

How to discover if an IP address is yours

A quick post - sometimes you need to know if an IP address is yours. One way of figuring this out is to ask the kernel to give you a list of all IP addresses it considers local, and go from there. This is pretty laborious however, and requires special processing for for example, *all* of which is local.

Another way which I heard of uses getsockname(2), a call which determines the local address of a socket. If you setup a connection, the kernel will automatically pick the most appropriate source address for you. And should you be setting up a connection to yourself, the source address will be identical to the destination address!

This way, you can easily detect if you own an IP address. The initial downside is that this appears to require sending packets, but it turns out you can avoid this by connect(2)ing a connectionless datagram socket.

The final sequence is (minus error checking):
int s = socket(AF_INET, SOCK_DGRAM, 0);
connect(s, (struct sockaddr*)& remote, sizeof(remote));
struct sockaddr_in local;
socklen_t socklen = sizeof(local);
getsockname(s, (struct sockaddr*) &local, &socklen);
return local.sin_addr.s_addr == remote.sin_addr.s_addr;
//      return memcmp(&local.sin6_addr.s6_addr, &local.sin6_addr.s6_addr, 16)==0;
This trick is described in Steven's Unix Network Programming volume one, section 8.14.


1 comment: