-5

Most examples uses e.g. internet connection e.g. google dns. This is vary bad way since this will not work without internet in local network.

Also some examples uses bad way like analysing "eth0". This is very bad way to have like this hardcoded strings. E.g. in my PC this is not work since my addapter name is "ens160" instead "eth0":

ens160    Link encap:Ethernet  HWaddr 00:50:56:ba:75:ea  
          inet addr:192.168.0.237  Bcast:192.168.1.255  Mask:255.255.254.0
          inet6 addr: ... Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:205280 errors:0 dropped:1 overruns:0 frame:0
          TX packets:68958 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:266539618 (266.5 MB)  TX bytes:4771936 (4.7 MB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:825 errors:0 dropped:0 overruns:0 frame:0
          TX packets:825 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:74843 (74.8 KB)  TX bytes:74843 (74.8 KB)

My address in localnetwork is "192.168.0.237", this is ens160. This is default interface and IP which uses in system when some library creates sockets (e.g. microhttpd or any other). How to retrieve it using standard linux libraries/functions?

Thank you in advance

  • Yes. Sorry. My misspelling. Release, Friday, the end of the working day and head boils. – Alexander Symonenko Jul 28 '17 at 16:06
  • _I need to do X how do I do it_ = too broad. – Captain Obvlious Jul 28 '17 at 16:09
  • 2
    what *is* the default interface after all? why do you need it? get the interface that isn't loopback - if there are multiple interfaces, which one would you pick? – Antti Haapala -- Слава Україні Jul 28 '17 at 16:10
  • Have a look at [here](https://stackoverflow.com/questions/19227781/linux-getting-all-network-interface-names) - you could iterate over the interfaces, first one not being lo (or lo with number appended on some systems) will be the one you are after - unless you have multiple interfaces... In the latter case, consider a command line parameter for your application to select the appropriate one. – Aconcagua Jul 28 '17 at 16:10
  • 2
    What's a "primary interface"? One machine can have multiple external network interfaces. – John Bollinger Jul 28 '17 at 16:11
  • Possible duplicate of [Get IP address of an interface on Linux](https://stackoverflow.com/questions/2283494/get-ip-address-of-an-interface-on-linux), [How do I get my IP address in C on Linux?](https://stackoverflow.com/q/20800319/608639), [using C code to get same info as ifconfig](https://stackoverflow.com/q/4951257/608639), [How do I output my host’s IP addresses from a C program?](https://stackoverflow.com/q/2021549/608639), etc. – jww Jul 28 '17 at 16:18
  • 1
    If your routing table has a default route via some gateway and some interface, examine all the IP addresses of that interface to find the one in the same subnet as the gateway. – Ian Abbott Jul 28 '17 at 16:18
  • >> primary interface: This is means when I creates socket without configuring any interface it uses some "default" addaper and some default external IP for create connection and I see this address in wireshark in remote PC to which I connected. I need exactly this address. – Alexander Symonenko Jul 28 '17 at 16:23

1 Answers1

0

If you just want to discover the default adapter's assigned IP address, e.g. 192.168.0.237, call getifaddrs and enumerate each address. This is the same list of adapters that ifconfig would normally display with associated information for gateway and netmask. Filter out the ones that are flagged as IFF_LOOPBACK or don't have IFF_UP. Some sample code here.

If you have more than one such address, then you need to check the route table and find the default route (the one with a target IP address of 0.0.0.0).

jselbie@ubuntu:~$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.254.2   0.0.0.0         UG    100    0        0 ens33
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 ens33
192.168.254.0   0.0.0.0         255.255.255.0   U     100    0        0 ens33

The first entry, the one with the destination route of 0.0.0.0, is your default route and sends through the ens33 adapter. If there was more than one default route, you would use the one with the lower metric field. In my case, the interface of the 0.0.0.0 route is ens33. The IP address of ens33 can be discovered through a call to getifaddrs as described above. (reference the ifa_name field in the enumerate list of ifaddrs.)

As for programatically enumerating the routing table in C, I actually don't remember how to do this. A quick internet search suggests you can get using a NETLINK socket. I would consult that source code for the route command as well.

selbie
  • 100,020
  • 15
  • 103
  • 173
  • A lot of thanks. Thank you. Your enumiration way and filtering (IFF_LOOPBACK + IFF_UP) suggestion is really works. – Alexander Symonenko Jul 28 '17 at 17:03
  • But a small clarification. Are you sure that first not loopback and upped adapter in the list will be primary (in case of one address as you wrote)? Sorry, I'm not big expert on linux. – Alexander Symonenko Jul 28 '17 at 17:14
  • No, I do not believe you can not assume that the first adapter enumerated is the one hosting the default route. If you have more than one active adapter with an IP address, you need to use the routing table to find the route for 0.0.0.0. – selbie Jul 28 '17 at 19:39
  • Thank you for explanations. Now I understand this problem with defining of external IP. Seems TCP/IP driver does something like this when you connect using typical TCP socket (AF_INET, SOCK_STREAM, 0) for define outgoing interface and IP address. – Alexander Symonenko Jul 31 '17 at 10:33
  • @AlexanderSymonenko - you are correct. When `connect` is called, TCP/IP references the route table to decide which adapter to make the connection through. – selbie Aug 01 '17 at 01:12
  • @AlexanderSymonenko - what are you really trying to do that requires you to be write specific code to use use a specific adapter instead of letting TCP/IP automatically pick the most appropriate one for you? – selbie Aug 01 '17 at 05:31
  • Thx. I need provide my IP address to some backup system for create iSCSI target. We can authorize access to iSCSI device in this system using two ways: whitelist of IP addresses and iSCSI CHAP (Challenge Handshake Auth. Protocol). In any case we choose next way: provide all IP addresses of all available interfaces except loopback for sure. Since e.g. you can have two connected interfaces from one PC in one network but with different IP (for example: high availability, speed up data transfer). And as a consequence you will not sure that two same sockets with same params will have same IP. – Alexander Symonenko Aug 01 '17 at 17:46