ioctl获取网络接口信息

linux下网络程序经常在启动执行后使用ioctl获取主机的全部网络接口信息,

例如接口地址、是否支持广播,是否支持多播等。

函数原型

#include <sys/ioctl.h>
int ioctl(int d, int request, ...);
返回值:成功返回0,出错返回-1

常见选项

SIOCGIFCONF 获取所有接口的列表

SIOCGIFBRDADDR 获取广播地址

SIOCGIFMTU  获取mtu

linux下使用ioctl操作网络接口,需要用到两个结构体

ifconf用来保存所有网络接口信息,结构体为:

struct ifconf
  {
    int	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

ifreq用来保存某个接口的信息

struct ifreq
  {
# define IFHWADDRLEN	6
# define IFNAMSIZ	IF_NAMESIZE
    union
      {
	char ifrn_name[IFNAMSIZ];	/* 接口名字, e.g. "en0".*/
      } ifr_ifrn;

    union
      {
	struct sockaddr ifru_addr;      /* 接口的IP地址 */
	struct sockaddr ifru_dstaddr;
	struct sockaddr ifru_broadaddr; /* 接口的广播地址 */
	struct sockaddr ifru_netmask;   /* 接口的子网掩码 */
	struct sockaddr ifru_hwaddr;    /* 接口的mac地址 */
	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)

操作:

1.通过ioctl获得本地所有接口信息存放在ifconf结构中

2.从ifcong中获得某个ifreq的接口信息

其中:

ifc_len:存放所有接口信息的缓冲区长度

ifc_buf:存放接口信息的缓冲区

首先对ifconf的ifc_len和ifc_buf初始化

用ioctl获取所有接口信息,之后ifc_len内存放实际获得的接口信息总长度,信息存放在ifc_buf中

实例:

#include <net/if.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>

using namespace std;

int main()
{
	//得到套接字描述符
	int sockfd;
	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		perror("socket error");
		exit(-1);
	}

	struct ifconf ifc;
	caddr_t buf;
	int len = 100;

	//初始化ifconf结构
	ifc.ifc_len = 1024;
	if ((buf = (caddr_t)malloc(1024)) == NULL)
	{
		cout << "malloc error" << endl;
		exit(-1);
	}
	ifc.ifc_buf = buf; 

	//获取所有接口信息
	if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)
	{
		perror("ioctl error");
		exit(-1);
	}

	//遍历每一个ifreq结构
	struct ifreq *ifr;
	struct ifreq ifrcopy;
	ifr = (struct ifreq*)buf;
	for(int i = (ifc.ifc_len/sizeof(struct ifreq)); i>0; i--)
	{
		//接口名
		cout << "interface name: "<< ifr->ifr_name << endl;
		//ipv4地址
		cout << "inet addr: "
			 << inet_ntoa(((struct sockaddr_in*)&(ifr->ifr_addr))->sin_addr)
			 << endl;

		//获取广播地址
		ifrcopy = *ifr;
		if (ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy) < 0)
		{
			perror("ioctl error");
			exit(-1);
		}
		cout << "broad addr: "
			 << inet_ntoa(((struct sockaddr_in*)&(ifrcopy.ifr_addr))->sin_addr)
			 << endl;
		//获取mtu
		ifrcopy = *ifr;
		if (ioctl(sockfd, SIOCGIFMTU, &ifrcopy) < 0)
		{
			perror("ioctl error");
			exit(-1);
		}
		cout << "mtu: " << ifrcopy.ifr_mtu << endl;
		cout << endl;
		ifr++;
	}

	return 0;
}

ioctl获取网络接口信息

时间: 2024-10-27 12:19:52

ioctl获取网络接口信息的相关文章

Linux获取网络接口信息

linux获取网络接口信息需要用到的函数为ioctl(),结构体struct ifreq,struct ifconf 1.ioctl()函数原型及作用 1 #include <sys/ioctl.h> 2 3 int ioctl(int d, int request, ...); 4 5 //参数 6 //int d:是一个文件描述符 7 //int request :表示要请求的信息.如IP地址.网络掩码等 8 //......:可变参数,根据request而定 下面是ioctl请求的req

Linux下获取网络接口信息

Linux下的网络接口信息在shell下可以很方便地使用ifconfig查看.同样,使用C/C++也可以很方便地获取接口信息. netdevice是一个低级别的访问Linux网络设备的方法.此方法通过ioctl来获取网络接口的相关信息. 这里需要借助<net/if.h>头文件中定义的ifreq结构体.此结构体包含了网络接口的名称.IP地址.广播地址.网络地址. 掩码等相关信息.在获取上述相关信息的时候需要指明网络接口的名称. 1 struct ifreq { 2 char ifr_name[I

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

转载请注明出处:windeal专栏 Linux 下 可以使用ioctl()函数 以及 结构体 struct ifreq  结构体struct ifconf来获取网络接口的各种信息. ioctl 首先看ioctl()用法 ioctl()原型如下: #include <sys/ioctl.h> int ioctl(int fd, int request, ...); 参数: fd     : 文件描述符 request:  表示要请求的信息.如IP地址.网络掩码等 ...     :  后面的可变

Android——使用Volley+fastJson在新线程中读取网络接口获取天气信息

一,关于Volley 其实最初对于网络数据的访问,我是没想到要用框架的,使用HttpURLConnection或者HttpGet or HttpPost都可以实现.但是why? why I have to use Volley?   Before Volley: class HttpURLConnection_post extends Thread{ @Override public void run() { //设置请求的路径 String strUrl="http://api.qingyun

Linux下获取网络接口ip地址

Linux 下 可以使用ioctl()函数以及结构体 struct ifreq和结构体struct ifconf来获取网络接口的各种信息. 如图,有br0和br1两个接口,当前需要获取br1的ip地址(当然其他接口信息如mac.子网掩码等都可以),方法如下: 具体过程是先通过ictol获取本地的所有接口信息,存放到ifconf结构中,再从其中取出每个ifreq表示的ip信息(一般每个网卡对应一个IP地址,如:"eth0-.eth1-"). 头文件: 1 #include <arp

C# .NET 获取网络适配器信息和路径信息

C# .NET 获取网络适配器信息 1:NetworkInterface 类: 该类位于 System.Net.NetworkInformation 命名空间 该类可以方便的检测本机有多少个网卡(网络适配器),网卡信息,哪些网络连接可用等. 2:常用方法和属性: using System.Net.NetworkInformation; namespace ConsoleApplication1 { class Program { static void Main(string[] args) {

socket,ioctl获取ip

socket,ioctl获取ip 总结一下,今天学习的关于通过socket,ioctl来获得ip,netmask等信息,其中很多内容参照了很多网上的信息,我会一一列出的我用的这个函数,就是下面这个函数,其中的有一些全局变量,很好懂,也就不多做解释了 一.下面对这个函数进行注解一下: int get_nic_IP_Address() //获取各网卡IP地址.子网掩码 { struct ifreq ifreq;  //声明一个struct ifreq结构体(这个结构体中有很多重要的参数,具体可以参照

借助Sigar API获取网络信息

Sigar(全称System Information Gatherer And Reporter,即系统信息收集报表器),它提供了一个开源的跨平台的收集计算机硬件和操作系统信息的API(该API底层接口用C语言编写),本文将演示如何借助Sigar API获取网络信息: package com.ghj.packageoftest; import org.hyperic.sigar.NetFlags; import org.hyperic.sigar.NetInterfaceConfig; impo

【Android实战】实现新浪微博第三方登录获取用户信息

本来最开始研究的腾讯微博第三方登录,但腾讯微博的SDK太糟糕了,估计他们自己都放弃了.想想也是,除了腾讯自家的应用在用腾讯微博,其他的开发者基本不去碰这块.所以马上去研究微博老大去了,平台果然强大,代码和文档一大堆,研究了半天,找点自己需要的功能,还是有点收获,先把这些记录下来,以后再慢慢研究. 目前实现的是实现第三方的登录,获取用户名显示到第三方应用上面. 主类,用到了Afinal框架 public class WbMainAct extends FinalActivity { // @Vie