一、struct ifreq结构体
这个结构定义在/usr/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)
二、用法:
通过ioctl()函数调用 下表列出了网络相关ioctl请求的request 参数以及arg 地址必须指向的数据类型:
类别 Request 说明 数据类型
套 接 口 SIOCATMARK  SIOCSPGRP  SIOCGPGRP 是否位于带外标记  设置套接口的进程ID 或进程组ID  获取套接口的进程ID 或进程组ID int  int  int
文 件 FIONBIN  FIOASYNC  FIONREAD  FIOSETOWN  FIOGETOWN 设置/ 清除非阻塞I/O 标志  设置/ 清除信号驱动异步I/O 标志  获取接收缓存区中的字节数  设置文件的进程ID 或进程组ID  获取文件的进程ID 或进程组ID int  int  int  int  int
接 口 SIOCGIFCONF  SIOCSIFADDR  SIOCGIFADDR  SIOCSIFFLAGS  SIOCGIFFLAGS  SIOCSIFDSTADDR  SIOCGIFDSTADDR  SIOCGIFBRDADDR  SIOCSIFBRDADDR  SIOCGIFNETMASK  SIOCSIFNETMASK  SIOCGIFMETRIC  SIOCSIFMETRIC  SIOCGIFMTU  SIOCxxx 获取所有接口的清单  设置接口地址  获取接口地址  设置接口标志  获取接口标志  设置点到点地址  获取点到点地址  获取广播地址  设置广播地址  获取子网掩码  设置子网掩码  获取接口的测度  设置接口的测度  获取接口MTU  (还有很多取决于系统的实现) struct ifconf  struct ifreq  struct ifreq  struct ifreq  struct ifreq  struct ifreq  struct ifreq  struct ifreq  struct ifreq  struct ifreq  struct ifreq  struct ifreq  struct ifreq  struct ifreq
ARP SIOCSARP  SIOCGARP  SIOCDARP 创建/ 修改ARP 表项  获取ARP 表项  删除ARP 表项 struct arpreq  struct arpreq  struct arpreq
路 由 SIOCADDRT  SIOCDELRT 增加路径  删除路径 struct rtentry  struct rtentry
I_xxx
实例一,获取网卡的IP地址:
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
int inet_sock;
struct ifreq ifr;
inet_sock = socket(AF_INET, SOCK_DGRAM, 0); strcpy(ifr.ifr_name, "eth0");
//SIOCGIFADDR标志代表获取接口地址
if (ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0)
perror("ioctl");
printf("%s\n", inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));
return 0;
}
实例二,实现简单ifconfig功能:
/**
* \file getifstat.c
* \author wzj
* \brief 访问这个struct ifconf 修改,查询状态
* \version
* \note
* \date: 2012年08月11日星期六22:55:25
*/
#include <net/if.h> /* for ifconf */
#include <linux/sockios.h> /* for net status mask */
#include <netinet/in.h> /* for sockaddr_in */
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdio.h> #define MAX_INTERFACE (16) void port_status(unsigned int flags); /* set == 0: do clean , set == 1: do set! */
int set_if_flags(char *pif_name, int sock, int status, int set)
{
struct ifreq ifr;
int ret = 0; strncpy(ifr.ifr_name, pif_name, strlen(pif_name) + 1);
ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
if(ret)
return -1;
/* set or clean */
if(set)
ifr.ifr_flags |= status;
else
ifr.ifr_flags &= ~status;
/* set flags */
ret = ioctl(sock, SIOCSIFFLAGS, &ifr);
if(ret)
return -1; return 0;
} int get_if_info(int fd)
{
struct ifreq buf[MAX_INTERFACE];
struct ifconf ifc;
int ret = 0;
int if_num = 0; ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = (caddr_t) buf; ret = ioctl(fd, SIOCGIFCONF, (char*)&ifc);
if(ret)
{
printf("get if config info failed");
return -1;
}
/* 网口总数 ifc.ifc_len 应该是一个出入参数 */
if_num = ifc.ifc_len/sizeof(struct ifreq);
printf("interface num is interface = %d\n", if_num);
while(if_num-- > 0)
{
printf("net device: %s\n", buf[if_num].ifr_name);
/* 获取第n个网口信息 */
ret = ioctl(fd, SIOCGIFFLAGS, (char*)&buf[if_num]);
if(ret)
continue; /* 获取网口状态 */
port_status(buf[if_num].ifr_flags); /* 获取当前网卡的ip地址 */
ret = ioctl(fd, SIOCGIFADDR, (char*)&buf[if_num]);
if(ret)
continue;
printf("IP address is: \n%s\n", inet_ntoa(((struct sockaddr_in *)(&buf[if_num].ifr_addr))->sin_addr)); /* 获取当前网卡的mac */
ret = ioctl(fd, SIOCGIFHWADDR, (char*)&buf[if_num]);
if(ret)
continue; printf("%02x:%02x:%02x:%02x:%02x:%02x\n\n",
(unsigned char)buf[if_num].ifr_hwaddr.sa_data[0],
(unsigned char)buf[if_num].ifr_hwaddr.sa_data[1],
(unsigned char)buf[if_num].ifr_hwaddr.sa_data[2],
(unsigned char)buf[if_num].ifr_hwaddr.sa_data[3],
(unsigned char)buf[if_num].ifr_hwaddr.sa_data[4],
(unsigned char)buf[if_num].ifr_hwaddr.sa_data[5]
);
}
} void port_status(unsigned int flags)
{
if(flags & IFF_UP)
{
printf("is up\n");
}
if(flags & IFF_BROADCAST)
{
printf("is broadcast\n");
}
if(flags & IFF_LOOPBACK)
{
printf("is loop back\n");
}
if(flags & IFF_POINTOPOINT)
{
printf("is point to point\n");
}
if(flags & IFF_RUNNING)
{
printf("is running\n");
}
if(flags & IFF_PROMISC)
{
printf("is promisc\n");
}
} int main()
{
int fd; fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd > 0)
{
get_if_info(fd);
close(fd);
} return 0;
}
运行结果:
interface num is interface = 2
net device: eth0
is up
is broadcast
is running
IP address is:
192.168.100.200
54:be:f7:33:57:26
net device: lo
is up
is loop back
is running
IP address is:
127.0.0.1
00:00:00:00:00:00
参考转载博客地址:
http://blog.csdn.net/dsg333/article/details/7525634
http://blog.csdn.net/kulung/article/details/6442597
http://blog.csdn.net/joker0910/article/details/7855998

struct ifreq学习和实例的更多相关文章

  1. struct ifreq结构体与ip,子网掩码,网关等信息

    总结一下,今天学习的关于通过socket,ioctl来获得ip,netmask等信息,其中很多内容参照了很多网上的信息,我会一一列出的 我用的这个函数,就是下面这个函数,其中的有一些全局变量,很好懂, ...

  2. SQL语句学习手册实例版

    SQL语句学习手册实例版 表操作 例1  对于表的教学管理数据库中的表 STUDENTS ,可以定义如下: CREATE  TABLE  STUDENTS (SNO      NUMERIC (6, ...

  3. struct ifconf和struct ifreq,获取网线插入状态

    这两天看用C获取当前网口的插入网线状态的程序,遇见了这两个不熟悉的结构体,看了头文件中的说明和详细. struct ifreq 这个结构定义在include/net/if.h,用来配置ip地址,激活接 ...

  4. TCP/IP协议学习之实例ping命令学习笔记

    TCP/IP协议学习之实例ping命令学习笔记(一) 一. 目的为了让网络协议学习更有效果,在真实网络上进行ping命令前相关知识的学习,暂时不管DNS,在内网中,进行2台主机间的ping命令的整个详 ...

  5. 获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf

    转载请注明出处:windeal专栏 Linux 下 可以使用ioctl()函数 以及 结构体 struct ifreq  结构体struct ifconf来获取网络接口的各种信息. ioctl 首先看 ...

  6. struct ifreq 获取IP 和mac和修改mac

    2012-09-11 14:26 struct ifreq 获取IP 和mac和修改mac 配置ip地址和mask地址: ifconfig eth0 192.168.50.22  netmask 25 ...

  7. linux网络接口,struct ifreq struct ifconf结构

    网络相关的ioctl请求的request参数及arg地址必须指向的数据类型如下表所示: 接口 SIOCGIFCONF SIOCSIFADDR SIOCGIFADDR SIOCSIFBRDADDR SI ...

  8. day9-复习学习python实例

    学习实例代码 #求1到100的和print ("##################1到100求和#################")def sum(a,b): s = 0 fo ...

  9. linux下网络编程学习——入门实例ZZ

    http://www.cppblog.com/cuijixin/archive/2008/03/14/44480.html 是不是还对用c怎么实现网络编程感到神秘莫测阿,我们这里就要撕开它神秘的面纱, ...

随机推荐

  1. js检测数据类型四种办法

    面试题中经常会考js数据类型检测,今天我来分享一下js中常用的四种方法判断数据类型,欢迎指点更正. 废话不多说,直入正题. 1.typeof console.log(typeof "&quo ...

  2. 用echarts写的multiple-trees demo

    echarts-multiple-trees 预览https://zhangzn3.github.io/echarts-multiple-trees/demo.html //根据数据条数自适应区域大小

  3. CentOS7.X首次安装docker无法启动的问题解决

    CentOS7.2 随着Docker的不断流行与发展,docker公司(或称为组织)也开启了商业化之路,Docker 从 17.03版本之后分为 CE(Community Edition) 和 EE( ...

  4. linux下Flask框架搭建简单网页

    开始安装FLASK需要创建一个虚拟环境,虚拟环境可以不干扰正在使用的系统环境,避免影响,并且也不需要完全的root权限,更加安全可靠. 搭建环境 Python3.4 进入到microblog目录下创建 ...

  5. 五分钟快速掌握RPC原理及实现

    随着公司规模的不断扩大,以及业务量的激增,单体应用逐步演化为服务/微服务的架构模式, 服务之间的调用大多采用rpc的方式调用,或者消息队列的方式进行解耦.几乎每个大厂都会创建自己的rpc框架,或者基于 ...

  6. 一、自动化平台搭建-python虚拟环境安装

    主要知识点介绍: 安装django环境 创建django项目 设计模型类并利用模型类和数据库进行交互 使用django后台管理数据 编写视图函数,进行URL配置 模板的使用 图书-英雄案例完成 1.虚 ...

  7. 重温TCP

    先放张TCP头图片 一.TCP三次握手目的: 1.保证源主机确定目的主机在线,并可进行通信 2.让源主机检查它是否正在监听试图去连接的端口 3.允许源主机向接收者发送他的起始序列号,使得两主机可以将数 ...

  8. XVII Open Cup named after E.V. Pankratiev. GP of Tatarstan

    A. Arithmetic Derivative 形如$p^p(p是质数)$的数的比值为$1$,用$k$个这种数相乘得到的数的比值为$k$,爆搜即可. #include<cstdio> # ...

  9. (88)Wangdao.com第二十一天_JavaScript 元素节点Element 节点

    Element 节点 (元素节点) 是一组对象 对应网页的 HTML 元素 每一个 HTML 元素,在 DOM 树上都会转化成一个 Element 节点对象(以下简称元素节点) 所有元素节点的 nod ...

  10. spring Cache注解详解

    @CacheConfig:主要用于配置该类中会用到的一些共用的缓存配置.在这里@CacheConfig(cacheNames = "users"):配置了该数据访问对象中返回的内容 ...