Linuxはネットワークインターフェース情報を取得します
Linuxがネットワークインターフェース情報を取得するために使用する必要のある関数は、ioctl()、structure struct ifreq、structifconfです。
1.ioctl()関数のプロトタイプと関数
#include <sys/ioctl.h>
int ioctl(int d, int request, ...);
//参数
//int d:是一个文件描述符
//int request :表示要请求的信息。如IP地址、网络掩码等
//......:可变参数,根据request而定
以下は、ioctlリクエストのリクエストパラメータと、argアドレスが指す必要のあるデータ型です
。2。structifreq構造体
この構造はinclude / net / if.hで定義され、IPアドレスの構成、インターフェイスのアクティブ化、MTUおよびその他のインターフェイス情報の構成に使用されます。
/* Interface request structure used for socket ioctl's. All interface
ioctl's must have parameter definitions which begin with ifr_name.
The remainder may be interface specific. */
struct ifreq
{
# define IFHWADDRLEN 6
# define IFNAMSIZ IF_NAMESIZE
union
{
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */
} ifr_ifrn;
union
{
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
short int ifru_flags;
int ifru_ivalue;
int ifru_mtu;
struct ifmap ifru_map;
char ifru_slave[IFNAMSIZ]; /* Just fits the size */
char ifru_newname[IFNAMSIZ];
__caddr_t ifru_data;
} ifr_ifru;
};
# define ifr_name ifr_ifrn.ifrn_name /* interface name */
# define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
# define ifr_addr ifr_ifru.ifru_addr /* address */
# define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
# define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
# define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
# define ifr_flags ifr_ifru.ifru_flags /* flags */
# define ifr_metric ifr_ifru.ifru_ivalue /* metric */
# define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
# define ifr_map ifr_ifru.ifru_map /* device map */
# define ifr_slave ifr_ifru.ifru_slave /* slave device */
# define ifr_data ifr_ifru.ifru_data /* for use by interface */
# define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */
# define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
# define ifr_qlen ifr_ifru.ifru_ivalue /* queue length */
# define ifr_newname ifr_ifru.ifru_newname /* New name */
# define _IOT_ifreq _IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
# define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
# define _IOT_ifreq_int _IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
3.struct ifconf
ifreqはifconf構造に含まれています。ifconf構造体は通常、すべてのインターフェースに関する情報を格納するために使用されます。
/* Structure used in SIOCGIFCONF request. Used to retrieve interface
configuration for machine (useful for programs which must know all
networks accessible). */
struct ifconf
{
int ifc_len; /* Size of buffer. */
union
{
__caddr_t ifcu_buf;
struct ifreq *ifcu_req;
} ifc_ifcu;
};
# define ifc_buf ifc_ifcu.ifcu_buf /* Buffer address. */
# define ifc_req ifc_ifcu.ifcu_req /* Array of structures. */
# define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0) /* not right */
#endif /* Misc. */
次の手順は、マシンのIPアドレスを取得することです
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <arpa/inet.h>
#ifndef IFNAMESZ
#define IFNAMESZ 16
#endif
int main(int argc, char *argv[])
{
if (argc != 2) {
printf("using %s <ETH_NAME>\n", argv[0]);
return 0;
}
int sock = 0;
struct sockaddr_in sin;
struct ifreq ifr;//用来保存接口的信息
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1) {
perror("socket");
return 1;
}
memcpy(ifr.ifr_name, argv[1], IFNAMESZ);
ifr.ifr_name[IFNAMESZ - 1] = '\0';
if (ioctl(sock, SIOCGIFADDR, &ifr) == 0) {
//SIOCGIFADDR 获取接口地址
memcpy(&sin, &ifr.ifr_addr, sizeof(sin)); //将获得地址拷贝到 sockaddr_in 结构体中
printf("Ip: %s\n", inet_ntoa(sin.sin_addr));
}
if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) {
memcpy(&sin, &ifr.ifr_netmask, sizeof(sin));
printf("netmask: %s\n", inet_ntoa(sin.sin_addr));
}
close(sock);
return 0;
}