linux获取ip的系统函数,Linux系统编程获取IP,子网掩码,网关等

  • Post author:
  • Post category:linux


最近项目中需要获取linux系统的所有网口信息并设置默认网口,通过查询资料发现通过linux提供的ioctl()函数可以获取相关信息。下面首先介绍几个需要使用到的结构体,然后提供一个实例。

1. 结构体ifconf和ifreq

//ifconf通常是用来保存所有接口信息的

struct ifconf

{

int ifc_len; /* size of buffer */

union

{

char *ifcu_buf; /* input from user->kernel*/

struct ifreq *ifcu_req; /* return from kernel->user*/

} ifc_ifcu;

};

//ifreq用来保存某个接口的信息

struct ifreq {

char ifr_name[IFNAMSIZ];

union {

struct sockaddr ifru_addr;

struct sockaddr ifru_dstaddr;

struct sockaddr ifru_broadaddr;

short ifru_flags;

int ifru_metric;

caddr_t ifru_data;

} ifr_ifru;

};

2. 结构体sockaddr和sockaddr_in

struct sockaddr {

unsigned short sa_family; // 2 bytes address family, AF_xxx

char sa_data[14]; // 14 bytes of protocol address

};

struct sockaddr_in {

short sin_family; // 2 bytes e.g. AF_INET, AF_INET6

unsigned short sin_port; // 2 bytes e.g. htons(3490)

struct in_addr sin_addr; // 4 bytes see struct in_addr, below

char sin_zero[8]; // 8 bytes zero this if you want to

};

struct in_addr {

unsigned long s_addr; // 4 bytes load with inet_pton()

};

二者长度一样,都是16个字节,即占用的内存大小是一致的,因此可以互相转化。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。

3. 实例

#include

#include

#include

#include

#include

#include

int getInterfaceInfo(void)

{

int fd;

int interfaceNum = 0;

struct ifreq buf[16];

struct ifconf ifc;

struct ifreq ifrcopy;

char mac[16] = {0};

char ip[32] = {0};

char broadAddr[32] = {0};

char subnetMask[32] = {0};

if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)

{

perror(“socket”);

close(fd);

return -1;

}

ifc.ifc_len = sizeof(buf);

ifc.ifc_buf = (caddr_t)buf;

if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc))//获取所有网口信息

{

interfaceNum = ifc.ifc_len / sizeof(struct ifreq);

printf(“interface num = %dn”, interfaceNum);

while (interfaceNum– > 0) //逐个提取

{

printf(“ndevice name: %sn”, buf[interfaceNum].ifr_name);

//ignore the interface that not up or not runing

ifrcopy = buf[interfaceNum];

if (ioctl(fd, SIOCGIFFLAGS, &ifrcopy))//设置网口标记

{

printf(“ioctl: %s [%s:%d]n”, strerror(errno), __FILE__, __LINE__);

close(fd);

return -1;

}

//get the mac of this interface

if (!ioctl(fd, SIOCGIFHWADDR, (char *)(&buf[interfaceNum])))

{

memset(mac, 0, sizeof(mac));

snprintf(mac, sizeof(mac), “%02x%02x%02x%02x%02x%02x”,

(unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[0],

(unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[1],

(unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[2],

(unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[3],

(unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[4],

(unsigned char)buf[interfaceNum].ifr_hwaddr.sa_data[5]);

printf(“device mac: %sn”, mac);

}

else

{

printf(“ioctl: %s [%s:%d]n”, strerror(errno), __FILE__, __LINE__);

close(fd);

return -1;

}

//get the IP of this interface

if (!ioctl(fd, SIOCGIFADDR, (char *)&buf[interfaceNum]))

{

snprintf(ip, sizeof(ip), “%s”,

(char *)inet_ntoa(((struct sockaddr_in * &

(buf[interfaceNum].ifr_addr))->sin_addr));

printf(“device ip: %sn”, ip);

}

else

{

printf(“ioctl: %s [%s:%d]n”, strerror(errno), __FILE__, __LINE__);

close(fd);

return -1;

}

//get the broad address of this interface

if (!ioctl(fd, SIOCGIFBRDADDR, &buf[interfaceNum]))

{

snprintf(broadAddr, sizeof(broadAddr), “%s”,

(char *)inet_ntoa(((struct sockaddr_in *)&

(buf[interfaceNum].ifr_broadaddr))->sin_addr));

printf(“device broadAddr: %sn”, broadAddr);

}

else

{

printf(“ioctl: %s [%s:%d]n”, strerror(errno), __FILE__, __LINE__);

close(fd);

return -1;

}

//get the subnet mask of this interface

if (!ioctl(fd, SIOCGIFNETMASK, &buf[interfaceNum]))

{

snprintf(subnetMask, sizeof(subnetMask), “%s”,

(char *)inet_ntoa(((struct sockaddr_in *)&

(buf[interfaceNum].ifr_netmask))->sin_addr));

printf(“device subnetMask: %sn”, subnetMask);

}

else

{

printf(“ioctl: %s [%s:%d]n”, strerror(errno), __FILE__, __LINE__);

close(fd);

return -1;

}

}

}

else

{

printf(“ioctl: %s [%s:%d]n”, strerror(errno), __FILE__, __LINE__);

close(fd);

return -1;

}

close(fd);

return 0;

}

int main(void)

{

getInterfaceInfo();

return 0;

}

参考: