UDP struct ifreq和struct ifconf获取IP地址
来源:互联网 发布:网络托管 编辑:程序博客网 时间:2024/05/12 03:32
UDP struct ifreq和struct ifconf获取IP地址
(一)获得本地ip地址时要用到两个结构体ifconf和ifreq(#include net/if.h),和一个函数ioctl,ifconf是用来保存所有接口信息的,ifreq用来保存某个接口的信息,具体结构如下:
/* * Interface request structure used for socket * ioctl's.All interface ioctl's must have parameter ifconf通常是用来保存所有接口信息的 * definitions which begin with ifr_name. The * remainder may be interface specific. */ struct ifreq { #define IFHWADDRLEN 6 union { char ifrn_name[IFNAMSIZ]; /* 网络接口名称 如eth0 */ } ifr_ifrn; union { struct sockaddr ifru_addr; /* 本地ip地址 */ struct sockaddr ifru_dstaddr; struct sockaddr ifru_broadaddr; /* 广播ip地址 */ struct sockaddr ifru_netmask; /* 本地子网掩码 */ struct sockaddr ifru_hwaddr; /* 本地MAC地址 */ short ifru_flags; /* 网络接口标记 */ int ifru_ivalue; int ifru_mtu; struct ifmap ifru_map; char ifru_slave[IFNAMSIZ]; /* Just fits the size */ char ifru_newname[IFNAMSIZ]; void __user * ifru_data; /* 用户数据 */ struct if_settings ifru_settings; } 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 ifr_settings ifr_ifru.ifru_settings /* Device/proto settings*/ /* * Structure used in SIOCGIFCONF request. * Used to retrieve interface configuration ifreq用来保存某个接口的信息 * for machine (useful for programs which * must know all networks accessible). */ struct ifconf { int ifc_len; /* 缓冲区大小 ifr_buf */ union { char __user *ifcu_buf;/* 缓冲区指针 input from user->kernel*/ struct ifreq __user *ifcu_req; /* return from kernel->user*/ } ifc_ifcu; }; #define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ #define ifc_req ifc_ifcu.ifcu_req /* array of structures */
ioctl()函数是Linux下面与内核交互的一种办法,函数原型:
int ioctl( int fd, int request, …/* void arg / )
SIOCGIFCONF 是用来获得网络接口列表(struct ifconf)。SIOCGIFFLAGS是获得网络接口标志(struct ifreq)。在Linux系统中,ifconfig命令就是通过ioctl接口与内核通信。
具体办法如下:
1. 先通过ioctl获得本机所有接口的信息,并保存在ifconf中,3个参数(两个需要用户赋值,另一个参数赋值来自内核)
2. 再从ifconf中取出每一个ifreq赋值给定义的*ifr,然后遍历所有地址,依据网卡名可以获得指定网卡的相关参数,具体代码如下。
二 测试代码
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h> /*htonl htons ntohs */#include <sys/ioctl.h>#include <net/if.h>int main(){ int i=0,j=0; int sock; struct ifreq *ifr; struct ifconf ifc; char buf[512]; if((sock = socket(AF_INET, SOCK_DGRAM, 0))<0) { perror("socket"); exit(1); } /* 获取所有套接字接口 */ ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(sock, SIOCGIFCONF, (char *) &ifc) < 0) { perror("ioctl-conf:"); return -1; } ifr = ifc.ifc_req; for(i=(ifc.ifc_len/sizeof(struct ifreq)),j=1; i>0; i--,j++) { /* 获得第j个网络接口名称 */ ifr->ifr_ifindex = j; if(ioctl(sock, SIOCGIFNAME, (char *)ifr)<0) {perror("NET Name error!");exit(-1);} printf("name (SIOCGIFNAME)= %s\n", ifr->ifr_name); /* 获得网卡eth0参数 */ if (!strcmp(ifr->ifr_name, "eth0")) { if (ioctl(sock, SIOCGIFFLAGS, (char *)ifr) < 0){perror("Find eth0 error!");exit(-1);} printf("Find eth0 (SIOCGIFFLAGS) = %d\n", ifr->ifr_flags); } /* 获得MTU */ if(ioctl(sock, SIOCGIFMTU, (char *)ifr)<0) {perror("MTU error!");exit(-1);} printf("MTU (SIOCGIFMTU)= %d\n", ifr->ifr_mtu); /* 获得MAC地址 */ if(ioctl(sock, SIOCGIFHWADDR, (char *)ifr)<0) {perror("MAC error!");exit(-1);} char *hw = ifr->ifr_hwaddr.sa_data; printf("MAC (SIOCGIFHWADDR)= %02x:%02x:%02x:%02x:%02x:%02x\n", hw[0],hw[1]&0xff,hw[2],hw[3],hw[4],hw[5]); /* 查询本地IP */ if(ioctl(sock, SIOCGIFADDR, (char *)ifr)<0) {perror("Local IP error!");exit(-1);} printf("local addr (SIOCGIFADDR) = %s\n", inet_ntoa(((struct sockaddr_in*)&(ifr->ifr_addr))->sin_addr)); /* 查询广播IP */ if(ioctl(sock, SIOCGIFBRDADDR, (char *)ifr)<0) {perror("Broadcast error!");exit(-1);} printf("broadcast addr (SIOCGIFBRDADDR) = %s\n", inet_ntoa(((struct sockaddr_in*)&(ifr->ifr_addr))->sin_addr)); /* 查询目的IP */ if(ioctl(sock, SIOCGIFDSTADDR, (char *)ifr)<0) {perror("Dst IP error!");exit(-1);} printf("dst addr (SIOCGIFDSTADDR) = %s\n", inet_ntoa(((struct sockaddr_in*)&(ifr->ifr_addr))->sin_addr)); /* 查询子网掩码 */ if(ioctl(sock, SIOCGIFNETMASK, (char *)ifr)<0) {perror("SUB Mask error!");exit(-1);} printf("mask addr (SIOCGIFNETMASK) = %s\n", inet_ntoa(((struct sockaddr_in*)&(ifr->ifr_addr))->sin_addr)); ifr++; printf("\n"); } return 0;}
测试结果:
0 0
- UDP struct ifreq和struct ifconf获取IP地址
- struct ifconf 和struct ifreq
- struct ifconf和struct ifreq,获取网线插入状态
- struct ifconf和struct ifreq,获取网线插入状态
- ioctl, struct ifreq, struct ifconf
- linux获取本机IP地址的方法 struct ifconf
- 《Linux网络接口》---------struct ifreq struct ifconf
- 《Linux网络接口》---------struct ifreq struct ifconf
- 获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf
- 获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf
- 用ioctl获得本地ip地址,ifconf和ifreq
- socket ioctl socket options struct ifreq; struct ifconf
- ioctl和struct ifreq
- ioctl和struct ifreq
- ioctl和struct ifreq
- ioctl和struct ifreq
- ioctl和struct ifreq
- ioctl和struct ifreq
- javascript实现document.getElementByClass的方法
- 最新版SDWebImage的使用
- Linux添加/删除用户和用户组
- 使用rsync批量删除文件
- 设置grub2开机启动项为前一次启动项
- UDP struct ifreq和struct ifconf获取IP地址
- 解析jquery获取父窗口的元素
- 1.记录我的代码
- leetCode #122 Best Time to Buy and Sell Stock II
- 30 天学习 30 种新技术系列
- mysql grant 用户权限总结
- 开源视频大数据处理框架(Open Source Video Manage&Processing&Search Center)
- 学习springmvc时,配置spring配置文件时,不能提示?以及配置文件头可以从jar包里找吧?
- jquery Ajax 实例 ($.ajax、$.post、$.get)