-2

I'm implementing a port control protocol (PCP) client working in Linux, implemented in C. It needs to connect to the default gateway to open ports. PCP needs to embed the local IP address in the message itself, not just in the IP headers (presumably this is for detecting the presence of unwanted NAT in the path, but it's a mystery to me how there could be a NAT between the machine itself and its default gateway). PCP also needs to connect to the default gateway, needing its address.

This raises two questions:

  1. How to find the IP address of the default gateway?
  2. How to find the IP address of the machine towards the default gateway even in the presence of multiple interfaces and IP addresses?
juhist
  • 4,210
  • 16
  • 33
  • 4
    Possible duplicate of [Default Gateway in C on Linux](https://stackoverflow.com/q/548105/608639), [Find default gateway ip address, rather than parsing proc filesystem](https://stackoverflow.com/q/10513704/608639), [A simple example of finding default gateway by getadaptersinfo](https://stackoverflow.com/q/23085876/608639), [Getting gateway to use for a given ip in ANSI C](https://stackoverflow.com/q/3288065/608639), [How to get gateway address when subnetting?](https://stackoverflow.com/q/5924211/608639), etc. – jww Jun 30 '18 at 12:31
  • @jww Only half of the question is a duplicate... PCP requires finding your IP address towards the default gateway, and this part is not explained at all in those existing questions. – juhist Jun 30 '18 at 12:37

1 Answers1

1

The answers to the questions are the following:

  1. The default gateway is easily found from /proc/net/route. It's the route having mask of zero, and destination of zero. All of the hex values are in network byte order, so if IP addresses need to be pretty-printed or compared to addresses in host byte order, ntohl may be required.
  2. The easiest way to find the IP address towards the default gateway is to create a UDP socket, not bind() it, connect() it to the default gateway, and use getsockname() to find the IP address it was automatically bound to.

With these features, my PCP client requires absolutely no manual IP address configuration whatsoever. It automatically detects the default gateway and the IP address towards the default gateway.

For (1), an alternative could be NETLINK sockets, but it's much easier to parse /proc/net/route. A second alternative could be to fork and exec netstat with a pipe on its output, and parse its output, but this will make the program dependent on an external binary.

An alternative to (2) could be also to use NETLINK sockets to find the local IP addresses, and then try to deduce which address would be used to connect to the default gateway, but it's much easier to let the Linux kernel do the deduction automatically and read the result using getsockname(). A second alternative could be to fork and exec ip or ifconfig with a pipe on its output, and parse its output and decuce which IP address would be used (the first field of /proc/net/route gives the interface of the default route, so the interface name is already known), but this will also make the program dependent on an external binary, and ifconfig may not be installed always, and also this will require doing the deduction process in the user space.

juhist
  • 4,210
  • 16
  • 33