Get local ip in C on linux

The local ip is the source ip in IP packets send out from a system. The kernal maintains routing tables which it uses to decide the default gateway , its interface and the local ip configured for that interface. The /proc/net/route file (not really a file but appears like one) has more information about it.

A typical /proc/net/route output would look like :

1 cat /proc/net/route
2 Iface   Destination     Gateway         Flags   RefCnt  Use     Metric  Mask            MTU     Window  IRTT                                                      
3 eth0    0000A8C0        00000000        0001    0       0       1       00FFFFFF        0       0       0                                                                              
4 eth0    0000FEA9        00000000        0001    0       0       1000    0000FFFF        0       0       0                                                                           
5 eth0    00000000        0100A8C0        0003    0       0       0       00000000        0       0       0

The above lists the interface , destination , gateway etc. The interface (Iface) whose destination is 00000000 is the interface of the default gateway.

Now have a look at the route command output

1 $ route -n
2 Kernel IP routing table
3 Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
4 192.168.0.0     0.0.0.0         255.255.255.0   U     1      0        0 eth0
5 169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0
6 0.0.0.0         192.168.0.1     0.0.0.0         UG    0      0        0 eth0

Now the gateway for the destination 0.0.0.0 is the default gateway. So from the /proc/net/route output this line is of interest :

1 eth0    00000000        0100A8C0        0003    0       0       0       00000000        0       0       0

Its destination is 00000000 and gateway is 0100A8C0. The gateway is actually the IP address of the gateway in hex format in reverse order (little endian). Its 01.00.A8.C0 or 1.0.168.192

So by reading that line in a C program we can find out the default gateway and its interface. The IP address of this interface shall be the source ip in IP packets send out from this system.

The code for this is pretty simple as we can see :

1 FILE *f;
2 char line[100] , *p , *c;
3  
4 f = fopen("/proc/net/route" "r");
5  
6 while(fgets(line , 100 , f))
7 {
8     p = strtok(line , " \t");
9     c = strtok(NULL , " \t");
10      
11     if(p!=NULL && c!=NULL)
12     {
13         if(strcmp(c , "00000000") == 0)
14         {
15             printf("Default interface is : %s \n" , p);
16             break;
17         }
18     }
19 }

The above code prints : “Default interface is : eth0″

Now we need to get the ip address of the default interface eth0. The getnameinfo function can be used for this.
Sample code is found here.

Combining that with our previous code we get :

1 /*
2  * Find local ip used as source ip in ip packets.
3  * Read the /proc/net/route file
4  */
5  
6 #include<stdio.h> //printf
7 #include<string.h>    //memset
8 #include<errno.h> //errno
9 #include<sys/socket.h>
10 #include<netdb.h>
11 #include<ifaddrs.h>
12 #include<stdlib.h>
13 #include<unistd.h>
14  
15 int main ( int argc , char *argv[] )
16 {
17     FILE *f;
18     char line[100] , *p , *c;
19      
20     f = fopen("/proc/net/route" "r");
21      
22     while(fgets(line , 100 , f))
23     {
24         p = strtok(line , " \t");
25         c = strtok(NULL , " \t");
26          
27         if(p!=NULL && c!=NULL)
28         {
29             if(strcmp(c , "00000000") == 0)
30             {
31                 printf("Default interface is : %s \n" , p);
32                 break;
33             }
34         }
35     }
36      
37     //which family do we require , AF_INET or AF_INET6
38     int fm = AF_INET;
39     struct ifaddrs *ifaddr, *ifa;
40     int family , s;
41     char host[NI_MAXHOST];
42  
43     if (getifaddrs(&ifaddr) == -1)
44     {
45         perror("getifaddrs");
46         exit(EXIT_FAILURE);
47     }
48  
49     //Walk through linked list, maintaining head pointer so we can free list later
50     for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
51     {
52         if (ifa->ifa_addr == NULL)
53         {
54             continue;
55         }
56  
57         family = ifa->ifa_addr->sa_family;
58  
59         if(strcmp( ifa->ifa_name , p) == 0)
60         {
61             if (family == fm)
62             {
63                 s = getnameinfo( ifa->ifa_addr, (family == AF_INET) ? sizeof(structsockaddr_in) : sizeof(struct sockaddr_in6) , host , NI_MAXHOST , NULL , 0 , NI_NUMERICHOST);
64                  
65                 if (s != 0)
66                 {
67                     printf("getnameinfo() failed: %s\n", gai_strerror(s));
68                     exit(EXIT_FAILURE);
69                 }
70                  
71                 printf("address: %s", host);
72             }
73             printf("\n");
74         }
75     }
76  
77     freeifaddrs(ifaddr);
78      
79     return 0;
80 }

Output

1 Default interface is : eth0
2  
3 address: 192.168.0.6

Another method is to open a connection to a remote server and call getsockname

Code

1 /*
2  * Find local ip used as source ip in ip packets.
3  * Use getsockname and a udp connection
4  */
5  
6 #include<stdio.h> //printf
7 #include<string.h>    //memset
8 #include<errno.h> //errno
9 #include<sys/socket.h>    //socket
10 #include<netinet/in.h> //sockaddr_in
11 #include<arpa/inet.h> //getsockname
12 #include<unistd.h>    //close
13  
14 int main ( int argc , char *argv[] )
15 {
16     const char* google_dns_server = "8.8.8.8";
17     int dns_port = 53;
18      
19     struct sockaddr_in serv;
20      
21     int sock = socket ( AF_INET, SOCK_DGRAM, 0);
22      
23     //Socket could not be created
24     if(sock < 0)
25     {
26         perror("Socket error");
27     }
28      
29     memset( &serv, 0, sizeof(serv) );
30     serv.sin_family = AF_INET;
31     serv.sin_addr.s_addr = inet_addr( google_dns_server );
32     serv.sin_port = htons( dns_port );
33  
34     int err = connect( sock , (const struct sockaddr*) &serv , sizeof(serv) );
35      
36     struct sockaddr_in name;
37     socklen_t namelen = sizeof(name);
38     err = getsockname(sock, (struct sockaddr*) &name, &namelen);
39          
40     char buffer[100];
41     const char* p = inet_ntop(AF_INET, &name.sin_addr, buffer, 100);
42          
43     if(p != NULL)
44     {
45         printf("Local ip is : %s \n" , buffer);
46     }
47     else
48     {
49         //Some error
50         printf ("Error number : %d . Error message : %s \n" errno strerror(errno));
51     }
52  
53     close(sock);
54      
55     return 0;
56 }

Output

1 Local ip is : 192.168.0.6
时间: 2024-09-19 09:49:38

Get local ip in C on linux的相关文章

linux ip命令和ifconfig命令

From: http://blog.jobbole.com/97270/ From: https://linux.cn/article-3144-1.html From: http://chrinux.blog.51cto.com/6466723/1188108 From: http://www.linuxdiyf.com/linux/23935.html net-tools 和 iproute2 对比         如今很多系统管理员依然通过组合使用诸如ifconfig.route.arp和

linux下的shell命令的编写,以及java如何调用linux的shell命令(java如何获取linux上的网卡的ip信息)

程序员都很懒,你懂的! 最近在开发中,需要用到服务器的ip和mac信息.但是服务器是架设在linux系统上的,对于多网口,在获取ip时就产生了很大的问题.下面是在windows系统上,java获取本地ip的方法.贴代码: package com.herman.test; import java.net.InetAddress; /** * @see 获取计算机ip * @author Herman.Xiong * @date 2014年5月16日 09:35:38 */ public class

python在windows和linux下获得本机本地ip地址方法小结_python

本文实例总结了python在windows和linux下获得本机本地ip地址方法.分享给大家供大家参考.具体分析如下: python的socket包含了丰富的函数和方法可以获得本机的ip地址信息,socket对象的gethostbyname方法可以根据主机名获得本机ip地址,socket对象的gethostbyname_ex方法可以获得本机所有ip地址列表 第一种方法:通过socket.gethostbyname方法获得 import socket localIP = socket.gethos

Linux学习之CentOS(二十九)--Linux网卡高级命令、IP别名及多网卡绑定的方法_Linux

本篇随笔将详细讲解Linux系统的网卡高级命令.IP别名以及Linux下多网卡绑定的知识 一.网卡高级命令 在之前的一篇随笔里Linux学习之CentOS(九)--Linux系统的网络环境配置,详细讲解了Linux系统下的网络环境配置等知识,我们了解了一些关于网络配置的一些基本命令.在这里将补充一些Linux系统下有关网卡的一些高级命令. ①mii-tool 命令 mii-tool命令我们可以用来查看网卡状态信息,包括了以太网连接是否正常,使用的是哪种型号的网卡等等 [root@xiaoluo

Linux route命令详解和使用示例(查看和操作IP路由表)

Linux系统的route命令用于显示和操作IP路由表(show / manipulate the IP routing table).要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或者同时位于两个网络的网关来实现     在Linux系统中,设置路由通常是为了解决以下问题:该Linux系统在一个局域网中,局域网中有一个网关,能够让机器访问Internet,那么就需要将这台机器的IP地址设置为Linux机器的默认路由.要注意的是,直接在命令行下执行route命令来添加路由,不会永

基于iproute命令集配置Linux网络(ip命令)

iproute是Linux下一个网络管理工具包合集,用于取代先前的如ifconfig,route,ifup,ifdown,netstat等历史网络管理工具.该工具包功能强大,它通过网络链路套接字接口与内核进行联系.iproute的用户界面比net-tools的用户界面要更直观.对网络资源比如链路.IP地址.路由和隧道等用"对象"抽象进行了恰当的定义,因此可以使用一致的语法来管理不同的对象.本文主要描述使用该工具包的ip命令来配置Linux网络. 一.iproute工具包集 查看ipro

如何在Linux中找出所有在线主机的IP地址

你可以在 Linux 的生态系统中找到很多网络监控工具,它们可以为你生成出网络中所有设备的摘要,包括它们的 IP 地址等信息. 然而,实际上有时候你只需要一个简单的命令行工具,运行一个简单的命令就能提供同样的信息. 本篇教程会向你展示如何找出所有连接到给定网络的主机的 IP 地址.这里我们会使用 Nmap 工具来找出所有连接到相同网络的设备的IP地址. Nmap (Network Mapper 的简称)是一款开源.强大并且多功能的探查网络的命令行工具,用来执行安全扫描.网络审计.查找远程主机的开

window/linux批量扫描IP端口程序脚本

假设1.txt文件内容为 127.0.0.1 192.168.1.1 然后我们获取文件内容IP进行扫描window .bat版本 :1.txt为文件名,根据需求进行修改 :C:\nmap\nmap-6.46\nmap.exe 为namp的路径,根据需求进行修改 :把1.txt与该扫描脚本放一起  代码如下 复制代码 @echo off for /f "delims=." %%i in (1.txt) do C:\nmap\nmap-6.46\nmap.exe -T3 -A -v -p-

UNIX IP Stack 调整指南_unix linux

本文的目的是为了调整UNIX IP堆栈以更有效的防止现今多种类型的攻击,详细 描述了一些UNIX服务系统中网络服务如HTTP或者routing的推荐设置,其中系统 包括了如下不同的UNIX: A. IBM AIX 4.3.X B. Sun Solaris 7 C. Compaq Tru64 UNIX 5.X D. HP HP-UX 11.0 (research ongoing) E. Linux kernel 2.2 (tested both SuSE Linux 7.0 和 RedHat 7.