《Linux网络接口》---------struct ifreq struct ifconf

来源:互联网 发布:特马技巧算法 编辑:程序博客网 时间:2024/05/21 17:57

网络接口--------------struct ifconfstruct ifreq

 

网络相关的ioctl请求的request参数及arg地址必须指向的数据类型如下表所示:

接口

SIOCGIFCONF

SIOCSIFADDR

SIOCGIFADDR

SIOCSIFBRDADDR

SIOCGIFBRDADDR

SIOCSIFNETMASK

SIOCGIFNETMASK


获取所有接口列表

设置接口地址

获取接口地址

设置广播地址

获取广播地址

设置子网掩码

获取子网掩码


Struct  ifconf

Struct  ifreq

Struct  ifreq

Struct  ifreq

Struct  ifreq

Struct  ifreq

Struct  ifreq


Ifreq结构用来配置ip地址,激活接口,配置MTU。在Linux系统中获取IP地址通常都是通过ifconfig命令来实现的,然而ifconfig命令实际是通过ioctl接口与内核通信,ifconfig命令首先打开一个socket,然后调用ioctlrequest传递到内核,从而获取request请求数据。处理网络接口的许多程序沿用的初始步骤之一就是从内核获取配置在系统中的所有接口。

Struct     ifreq     data;

Fd = socket(AF_NET,SOCK_DGRAM,0);

<      request       >

Ioctl(fd,SIOCGIFADDR,&data);

 struct ifconf结构体


struct ifconf{

lint ifc_len;

union{

    caddr_t  ifcu_buf

    Struct   ifreq *ifcu_req;

}ifc_ifcu

}

 

#define    ifc_buf    ifc_ifcu.ifcu_buf

#define    ifc_req    ifc_ifcu.ifcu_req

Struct ifreq接口

Struct ifreq{

Char ifr_name[IFNAMSIZ];

Union{

    Struct  sockaddr  ifru_addr;

    Struct  sockaddr  ifru_dstaddr;

    Struct  sockaddr  ifru_broadaddr;

    Struct  sockaddr  ifru_netmask;

    Struct  sockaddr  ifru_hwaddr;

    Short  ifru_flags;

    Int     ifru_metric;

    Caddr_t ifru_data;

}ifr_ifru;

};

#define ifr_addr        ifr_ifru.ifru_addr

#define ifr_broadaddr   ifr_ifru.ifru_broadadd

#define ifr_hwaddr      ifr_ifru_hwaddr



对于
ifconfifc_buf,其实就是Nifc_req,从上面的结构体中可以看出来,通过下面两幅图可以更加明显。 


接下来通过代码实现ifconfig功能,即可以查看本地的IPMAC地址、子网掩码等,首先通过ifconfig我们可以查看本机的信息,如下所示:


 

接下来通过代码实现如下所示

#include<stdlib.h>#include<stdio.h>#include<unistd.h>#include<net/if.h>#include<net/if_arp.h>#include<arpa/inet.h>#include<sys/ioctl.h>#include<errno.h> #define ETH_NAME  "eth0" static void get_local_ip(int sock_fd);static void get_netmask_addr(int sock_fd);static void get_mac_addr(int sock_fd);static void get_broad_addr(int sock_fd);struct sockaddr_in  sin;struct sockaddr_in  netmask;struct sockaddr_in  broad;struct ifreq ifr;unsigned char arp[6];int main(){int sockfd;//create socketsockfd = socket(AF_INET,SOCK_DGRAM,0);if(sockfd == -1){perror("socket");return -1;}get_local_ip(sockfd);get_mac_addr(sockfd);get_netmask_addr(sockfd);get_broad_addr(sockfd);return 0;}static void get_local_ip(int sock_fd){strncpy(ifr.ifr_name,ETH_NAME,IFNAMSIZ);ifr.ifr_name[IFNAMSIZ - 1] = 0;if(ioctl(sock_fd,SIOCGIFADDR,&ifr) == 0){memcpy(&sin,&ifr.ifr_addr,sizeof(sin));fprintf(stdout,"eth0: %s\n",inet_ntoa(sin.sin_addr));}}static void get_mac_addr(int sock_fd){if(ioctl(sock_fd,SIOCGIFHWADDR,&ifr)==0){memcpy(arp,ifr.ifr_hwaddr.sa_data,6);printf("adapter hardware address %x:%x:%x:%x:%x:%x\n",arp[0],arp[1],arp[2],arp[3],arp[4],arp[5]);}}static void get_netmask_addr(int sock_fd){if(ioctl(sock_fd,SIOCGIFNETMASK,&ifr)==0){memcpy(&netmask,&ifr.ifr_netmask,sizeof(netmask));printf("netmask: %s\n",inet_ntoa(netmask.sin_addr));}}static void get_broad_addr(int sock_fd){if(ioctl(sock_fd,SIOCGIFBRDADDR,&ifr)==0){memcpy(&broad,&ifr.ifr_broadaddr,sizeof(broad));printf("broad: %s\n",inet_ntoa(broad.sin_addr));}}

所要查看的网卡名字为eth0;

然后创建一个SOCKET通信

static void get_local_ip(int sock_fd)函数用来获取本机IP地址,请求(request)SIOCGIFADDR

static void get_mac_addr(int sock_fd)获取本机的MAC地址,requestSIOCGIFHWADDR

static void get_netmask_addr(int sock_fd)获取子网掩码地址,requestSIOCGIFNETMASK

static void get_broad_addr(int sock_fd)获取广播地址,requestSIOCGIFBRDADDR


关注微信公众号获取更多Linux知识



0 0
原创粉丝点击