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

网络接口--------------struct ifconf,struct 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,然后调用ioctl将request传递到内核,从而获取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

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

接下来通过代码实现ifconfig功能,即可以查看本地的IP、MAC地址、子网掩码等,首先通过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地址,request
是SIOCGIFHWADDR
static void get_netmask_addr(int sock_fd)获取子网掩码地址,request是SIOCGIFNETMASK
static void get_broad_addr(int sock_fd)获取广播地址,request是SIOCGIFBRDADDR

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值