linux c 获取网络接口信息 ioct l函数 ifreq ifconf 结构体 简介_ioctl siocgifconf-程序员宅基地

目录

ioctl

struct ifreq

struct ifconf


 

ioctl

原型如下:

#include <sys/ioctl.h>
int ioctl(int fd, int request, ...);

参数:

    fd     : 文件描述符

request:  表示要请求的信息。如IP地址、网络掩码等

     ...     :  后面的可变参数根据request而定

比如我们请求所有网络接口的清单:

struct ifconf IoCtlReq;
...
ioctl( Sock, SIOCGIFCONF, &IoCtlReq )

与接口相关的request如下表所示

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

 

 

struct ifreq

结构体 struct ifreq用来保存某个接口的信息。

// if.h
/*
 * 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
	union
	{
		char	ifrn_name[IFNAMSIZ];		/* if 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	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*/

ifr_name 标识了某一接口。

可以通过ioctl获取该接口的信息。如:

ioctl(Sock, SIOCGIFNETMASK, &IfReq);//获取网络接口地址掩码

该代码需要先对IfReq->ifr_name赋值,然后获取与IfReq->ifr_name向匹配的网络接口 的地址掩码

 

struct ifconf

结构体struct ifconf通常用来保存所有接口信息

// if.h
/*
 * 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 {
		char __user *ifcu_buf;
		struct ifreq __user *ifcu_req;
	} ifc_ifcu;
};
#define	ifc_buf	ifc_ifcu.ifcu_buf		/* buffer address	*/
#define	ifc_req	ifc_ifcu.ifcu_req		/* array of structures	*/

该结构体可以用来获取所哟网络接口的名字和信息(不是全部信息,是ip地址)

实例:

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
typedef uint32_t uint32;
#define MAX_IF 10
int main()
{
    struct ifreq ifVec[MAX_IF];//用来保存所有接口

    int sock = -1;

    if ((sock = socket( AF_INET, SOCK_DGRAM, 0 )) < 0)
    {
        fprintf(stderr, "Error:%d, cannot open RAM;\n");
    }

    // get if vector
    struct ifconf ioIfConf;
    ioIfConf.ifc_buf = (void *)ifVec;
    ioIfConf.ifc_len = sizeof(ifVec);
    printf("Len:%d\n", ioIfConf.ifc_len);

    if (ioctl(sock, SIOCGIFCONF, &ioIfConf) < 0) //获取所有网络接口信息
    {
        fprintf(stderr, "Error:%d   ioctl IFCONF\n");
    }

    printf("Len:%d\n", ioIfConf.ifc_len); // 和前面到len对比,发现ioctl修改里len到大小
    //循环打印每个网络接口到信息
    {
        struct ifreq *ifPt;
        struct ifreq *ifEndPt;
        ifPt = ifVec;
        ifEndPt = (void *)((char *)ifVec + ioIfConf.ifc_len);
        for (ifPt = ifVec; ifPt < ifEndPt; ifPt++)
        {
            struct ifreq ifReq;
            if (ifPt->ifr_addr.sa_family != AF_INET)
            {
                continue;
            }

            // Temp keepers of interface params...
            uint32 u32_addr, u32_mask;

            /*	打印ip地址	*/
            char ipDotBuf[16], subnetDotBuf[16], maskDotBuf[16]; // 保存点分十进制到ip地址
            u32_addr = ((struct sockaddr_in *)&ifPt->ifr_addr)->sin_addr.s_addr;
            inet_ntop(AF_INET, &u32_addr, ipDotBuf, (socklen_t )sizeof(ipDotBuf));
            printf("IP Address: %s\n", ipDotBuf);

            /*    打印地址掩码    */
            bzero(&ifReq, sizeof(struct ifreq));
            memcpy(ifReq.ifr_name, ifPt->ifr_name, sizeof(ifReq.ifr_name));
            if (ioctl(sock, SIOCGIFNETMASK, &ifReq ) < 0)
            {
                fprintf(stderr, "Error: %d, cannot get mask\n", errno);
            }
            else
            {
                u32_mask = ((struct sockaddr_in *)&ifReq.ifr_addr)->sin_addr.s_addr;
                inet_ntop(AF_INET, &u32_mask, maskDotBuf, (socklen_t )sizeof(maskDotBuf));
                printf("Mask: %s\n", maskDotBuf);
            }

            /*    打印MTU    */
            bzero(&ifReq, sizeof(struct ifreq));
            memcpy(ifReq.ifr_name, ifPt->ifr_name, sizeof(ifReq.ifr_name));
            if (ioctl(sock, SIOCGIFMTU, &ifReq ) < 0)
            {
                fprintf(stderr, "Error: %d, cannot get MTU\n", errno);
            }
            else
            {
                printf("SIOCGIFMTU:%d\n", ifReq.ifr_mtu);
            }

            /*    其他信息的打印方式与掩码和MTU相同    */
        }
    }
}

运行结果:

windeal@ubuntu:~/Windeal/apue$ ./exe 
Len:320
Len:64
IP Address: 127.0.0.1
Mask: 255.0.0.0
SIOCGIFMTU:16436
IP Address: 172.17.92.198
Mask: 255.255.254.0
SIOCGIFMTU:1500
windeal@ubuntu:~/Windeal/apue$ 

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/whatday/article/details/106470305

智能推荐

python降版本的影响_将Python从版本2.7.9降级到2.7.8_weixin_39622901的博客-程序员宅基地

In upgrading some Python modules, I also updated my Python version to 2.7.9. Doing so, however, has broken Google App Engine, and I need to revert down to at least 2.7.8. I used MacPorts to install ..._win10安装python2.7。9降级

Mybatis OGNL导致的并发安全问题_ognl并发_殷十娘的博客-程序员宅基地

Mybatis是一个开源的轻量级半自动化ORM框架,使得面向对象应用程序与关系数据库的映射变得更加容易。MyBatis使用xml描述符或注解将对象与存储过程或SQL语句相结合。Mybatis最大优点是应用程序与Sql进行解耦,sql语句是写在Xml Mapper文件中。OGNL表达式在Mybatis当中应用非常广泛,其表达式的灵活性使得动态Sql功能的非常强大。OGNL是Object-Graph..._ognl并发

训练中文分词HMM模型,得到A(状态转移矩阵)、B(混淆矩阵)、Pi(初始状态概率)_语料训练hmm模型代码_雨点儿的博客-程序员宅基地

#!F://python# page coding=utf-8# 本代码用来训练中文分词HMM模型,得到A矩阵(状态转移矩阵)、B矩阵(混淆矩阵)、Pi向量(初始概率向量)并且用pickle 将他们的utf-8码写到了文件当中去import pickleimport codecsA_dic = {} # 状态转移矩阵B_dic = {} # 混淆矩阵Pi_dic = {}_语料训练hmm模型代码

百度WebUploader上传图片,图片回显编辑,查看_weixin_30600503的博客-程序员宅基地

编辑图片,可以删除上次上传的图片,可以新加上传图片1.首选还是引入css和js(两个css,三个js)自定义css.webuploader-container { position: relative;}.webuploader-element-invisible { position: absolute !important; ..._webuploader 怎么编辑图片

vue实现简单的待办事项清单_vue待办事项_当然大人的博客-程序员宅基地

笔记一篇,备查。初学vue的时候,做了一个待办事项清单。首页 First.vue<template> <div id="app"> <div class="q">待办事项清单</div> <p class="e">不积跬步无以至千里</p> <hr style="margin: 0 10% 6% 10%;" /> <div class="u"> <p&g_vue待办事项

NoSQL与SQL:选择数据管理解决方案-程序员宅基地

目录 1.简介 2.分布式系统:CAP定理 3.关系数据存储 3.1。 MySQL的/ MariaDB的 3.2。 PostgreSQL的 3.3。 其他 4.为什么要使用NoSQL? 5.键/值数据存储 5.1。 DynamoDB 5.2。 记忆快取 5.3。 雷迪斯 5.4。 里亚克 5.5。 气钉 5.6。 基础数据库 ...

随便推点

一些开源搜索引擎实现——倒排使用原始文件,列存储Hbase,KV store如levelDB、mongoDB、redis,以及SQL的,如sqlite或者xxSQL..._weixin_34062329的博客-程序员宅基地

本文说明:除开ES,Solr,sphinx系列的其他开源搜索引擎汇总于此。A search engine based on Node.js and LevelDBA persistent, network resilient, full text search library for the browser and Node.jshttps...

HDMI中SCL和SDA两个引脚的作用_hdmi sda_白面小书生的博客-程序员宅基地

高清晰度多媒体界面(英语:High Definition Multimedia Interface,简称HDMI)PinPin定义1Hot Plug Detect2Utility3TMDS Data2+4TMDS Data2 Shield5TMDS Data2-6TMDS Data1_hdmi sda

SVG 之pathData使用_宝宝也要写博客的博客-程序员宅基地

前几天无意看到有关矢量图的相关知识。在练习尝试之后,写篇博客作为笔记。有不足之处还请各位大神提议。 这个是一个简单的小例子 一条直线 - 这是效果图 - 参数 表示 M0 代表移动点在x轴的位置为0 0 表示移动点初始时 y轴的位置 L30 表示一条在x轴上长度是30的直线 0 表示该直线在y轴..._pathdata

egg 完整实例 增删改查MongoDB,websocket_weixin_30496751的博客-程序员宅基地

项目地址 github.com/richard1015…技术栈 eggjs、MongoDB、swagger、websocket、Amap演示地址:前台 school.zhuzhida.vipAPI文档地址 school.zhuzhida.vip/swagger-ui.…后台管理 schoolmgr.zhuzhida.vip后台管..._egg+mongodb写增删改查接口

Linux基础学习总结_linux技术基础课程总结_贪心的鬼的博客-程序员宅基地

Linux学习笔记一、shell 及零碎知识二、文件和目录操作2.1 根目录2.2 用户目录2.3 相关命令三、文件权限3.1 文件知识3.2 chmod修改文件属性3.2.1 文字设定法3.2.2 数字设定法3.3 chown 修改指定文件的拥有者3.4 chgrp 改变文件或目录的所属群组四、查找和检索4.1 find4.1.1 按文件名查找4.1.2 按文件大小查找4.1.3 按文件日期查找4.1.4 按深度查找4.1.5 按文件类型查找4.2 grep五、压缩工具5.1 Linux常见的压缩格式5._linux技术基础课程总结

PostgreSQL的集群化和容器化部署-程序员宅基地

2019独角兽企业重金招聘Python工程师标准>>> ..._pgsql 多读多写

推荐文章

热门文章

相关标签