主要是用ioctl函数,同时需要头文件<net/if.h>

/* net/if.h -- declarations for inquiring about network interfacesCopyright (C) 1997-2014 Free Software Foundation, Inc.This file is part of the GNU C Library.The GNU C Library is free software; you can redistribute it and/ormodify it under the terms of the GNU Lesser General PublicLicense as published by the Free Software Foundation; eitherversion 2.1 of the License, or (at your option) any later version.The GNU C Library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULesser General Public License for more details.You should have received a copy of the GNU Lesser General PublicLicense along with the GNU C Library; if not, see<http://www.gnu.org/licenses/>.  */#ifndef _NET_IF_H
#define _NET_IF_H   1#include <features.h>#ifdef __USE_MISC
# include <sys/types.h>
# include <sys/socket.h>
#endif/* Length of interface name.  */
#define IF_NAMESIZE 16struct if_nameindex{unsigned int if_index;    /* 1, 2, ... */char *if_name;       /* null terminated name: "eth0", ... */};#ifdef __USE_MISC
/* Standard interface flags. */
enum{IFF_UP = 0x1,     /* Interface is up.  */
# define IFF_UP IFF_UPIFF_BROADCAST = 0x2, /* Broadcast address valid.  */
# define IFF_BROADCAST  IFF_BROADCASTIFF_DEBUG = 0x4,      /* Turn on debugging.  */
# define IFF_DEBUG  IFF_DEBUGIFF_LOOPBACK = 0x8,       /* Is a loopback net.  */
# define IFF_LOOPBACK   IFF_LOOPBACKIFF_POINTOPOINT = 0x10,    /* Interface is point-to-point link.  */
# define IFF_POINTOPOINT IFF_POINTOPOINTIFF_NOTRAILERS = 0x20, /* Avoid use of trailers.  */
# define IFF_NOTRAILERS IFF_NOTRAILERSIFF_RUNNING = 0x40,      /* Resources allocated.  */
# define IFF_RUNNING    IFF_RUNNINGIFF_NOARP = 0x80,       /* No address resolution protocol.  */
# define IFF_NOARP  IFF_NOARPIFF_PROMISC = 0x100,  /* Receive all packets.  */
# define IFF_PROMISC    IFF_PROMISC/* Not supported */IFF_ALLMULTI = 0x200,    /* Receive all multicast packets.  */
# define IFF_ALLMULTI   IFF_ALLMULTIIFF_MASTER = 0x400,        /* Master of a load balancer.  */
# define IFF_MASTER IFF_MASTERIFF_SLAVE = 0x800,       /* Slave of a load balancer.  */
# define IFF_SLAVE  IFF_SLAVEIFF_MULTICAST = 0x1000,   /* Supports multicast.  */
# define IFF_MULTICAST  IFF_MULTICASTIFF_PORTSEL = 0x2000, /* Can set media type.  */
# define IFF_PORTSEL    IFF_PORTSELIFF_AUTOMEDIA = 0x4000, /* Auto media select active.  */
# define IFF_AUTOMEDIA  IFF_AUTOMEDIAIFF_DYNAMIC = 0x8000  /* Dialup device with changing addresses.  */
# define IFF_DYNAMIC    IFF_DYNAMIC};/* The ifaddr structure contains information about one address of aninterface.  They are maintained by the different address families,are allocated and attached when an address is set, and are linkedtogether so all addresses for an interface can be located.  */struct ifaddr{struct sockaddr ifa_addr;   /* Address of interface.  */union{struct sockaddr   ifu_broadaddr;struct sockaddr   ifu_dstaddr;} ifa_ifu;struct iface *ifa_ifp;    /* Back-pointer to interface.  */struct ifaddr *ifa_next;   /* Next address for interface.  */};# define ifa_broadaddr  ifa_ifu.ifu_broadaddr   /* broadcast address    */
# define ifa_dstaddr    ifa_ifu.ifu_dstaddr /* other end of link    *//* Device mapping structure. I'd just gone off and designed abeautiful scheme using only loadable modules with arguments fordriver options and along come the PCMCIA people 8)Ah well. The get() side of this is good for WDSETUP, and it'll behandy for debugging things. The set side is fine for now and beingvery small might be worth keeping for clean configuration.  */struct ifmap{unsigned long int mem_start;unsigned long int mem_end;unsigned short int base_addr;unsigned char irq;unsigned char dma;unsigned char port;/* 3 bytes spare */};/* Interface request structure used for socket ioctl's.  All interfaceioctl's must have parameter definitions which begin with ifr_name.The remainder may be interface specific.  */struct ifreq{
# define IFHWADDRLEN    6
# define IFNAMSIZ   IF_NAMESIZEunion{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)/* Structure used in SIOCGIFCONF request.  Used to retrieve interfaceconfiguration for machine (useful for programs which must know allnetworks accessible).  */struct ifconf{int    ifc_len;            /* Size of buffer.  */union{__caddr_t ifcu_buf;struct ifreq *ifcu_req;} ifc_ifcu;};
# define ifc_buf    ifc_ifcu.ifcu_buf   /* Buffer address.  */
# define ifc_req    ifc_ifcu.ifcu_req   /* Array of structures.  */
# define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0) /* not right */
#endif  /* Misc.  */__BEGIN_DECLS/* Convert an interface name to an index, and vice versa.  */
extern unsigned int if_nametoindex (const char *__ifname) __THROW;
extern char *if_indextoname (unsigned int __ifindex, char *__ifname) __THROW;/* Return a list of all interfaces and their indices.  */
extern struct if_nameindex *if_nameindex (void) __THROW;/* Free the data returned from if_nameindex.  */
extern void if_freenameindex (struct if_nameindex *__ptr) __THROW;__END_DECLS#endif /* net/if.h */

首先创建SOCK_DGRAM套接口,然后用ioctl的命令参数SIOCGIFCONF获取网络接口,因为设备上的网络接口上可能有多个,缓冲区可能不够,用到累加的方法 ,如果当前次获取的ifreq的长度与上一次的长度不一样,就添加10个ifreq的长度,直到与前次的长度一样,说明所有的网络接口已经获取到了。在获取到网络接口后,需要判断接口是什么 类型的,是否是回环,广播地址,多播地址,这个涉及到ioctl的命令参数SIOCGIFFLAGS。将多个网络接口用链表形式连接起来,当中用到二级指针来连接,ifihead和二级指针ifipnext,刚开始ifihead=NULL,ifipnext = &ifinext,当找到一个网络接口后,将找到的网络接口赋值给*ifipnext,而将ifipnext重新赋值给这个找到的网络接口的成员ifi_next

#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>#define IFI_NAME 16
#define IFI_HADDR 8
#define IFI_ALIAS 1struct ifi_info
{char ifi_name[IFI_NAME];   char ifi_haddr[IFI_HADDR];short ifi_hlen;short ifi_flags;short ifi_myflags;struct sockaddr* ifi_addr;struct sockaddr* ifi_brdaddr;struct sockaddr* ifi_dstaddr;struct ifi_info *ifi_next;
};struct ifi_info *get_ifi_info(int,int);
struct ifi_info *Get_ifi_info(int, int);
void free_ifi_info(struct ifi_info *);
char *sock_ntop(struct sockaddr*, int);int main(int argc, char **argv)
{struct ifi_info *ifi, *ifihead;struct sockaddr *sa;char *ptr;int i, family, doaliases;if (argc != 3) {fprintf(stderr, "usage:prifinfo <inet4|inet6> <doaliases>\n");return -1;}if (strcmp(argv[1], "inet4") == 0) {family = AF_INET;} else if (strcmp(argv[1], "inet6") == 0) {family = AF_INET6;}doaliases = atoi(argv[2]);for (ifihead = ifi = get_ifi_info(family, doaliases); ifi != NULL; ifi = ifi->ifi_next) {printf("%s:<" , ifi->ifi_name);if (ifi->ifi_flags & IFF_UP) printf("UP ");if (ifi->ifi_flags & IFF_BROADCAST) printf("BCAST ");if (ifi->ifi_flags & IFF_MULTICAST) printf("MCAST ");if (ifi->ifi_flags & IFF_LOOPBACK) printf("LOOP ");if (ifi->ifi_flags & IFF_POINTOPOINT) printf("P2P ");printf("> \n");if ((i = ifi->ifi_hlen) > 0) {ptr = ifi->ifi_haddr;do {printf("%s%x", (i == ifi->ifi_hlen) ? " " : ":", *ptr++);} while (--i > 0);printf("\n");}if ((sa = ifi->ifi_addr) != NULL) {printf(" IP addr: %s\n", sock_ntop(sa, sizeof(*sa)));}if((sa = ifi->ifi_brdaddr) != NULL) {printf(" broadcast addr: %s\n", sock_ntop(sa, sizeof(*sa)));}if ((sa = ifi->ifi_dstaddr) != NULL) {printf(" destination addr: %s\n", sock_ntop(sa, sizeof(*sa)));   }}free_ifi_info(ifihead);return 0;
}struct ifi_info *get_ifi_info(int family, int doaliases)
{struct ifi_info *ifi, *ifihead, **ifipnext;int sockfd, len, lastlen, flags, myflags;char *ptr, *buf, lastname[128], *cptr;struct ifconf ifc;struct ifreq *ifr, ifrcopy;struct sockaddr_in *sinptr;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {fprintf(stderr, "socket error:%s\n", strerror(errno));return NULL;}lastlen = 0;len = 100 * sizeof(struct ifreq);for (;;) {buf = malloc(len);ifc.ifc_len = len;ifc.ifc_buf = buf;if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {if (errno != EINVAL || lastlen != 0) {fprintf(stderr, "ioctl error:%s\n", strerror(errno));return NULL;}} else {if (ifc.ifc_len == lastlen) break;lastlen = ifc.ifc_len;}len += 10 * sizeof(struct ifreq);free(buf);}ifihead = NULL;ifipnext = &ifihead;lastname[0] = 0;for (ptr = buf; ptr < buf + ifc.ifc_len;) {ifr = (struct ifreq*)ptr;switch(ifr->ifr_addr.sa_family) {case AF_INET6:len = sizeof(struct sockaddr_in6);break;  case AF_INET:default:len = sizeof(struct sockaddr_in);break;}ptr += sizeof(ifr->ifr_name) + len;if (ifr->ifr_addr.sa_family != family) {continue;}myflags = 0;if ((cptr = strchr(ifr->ifr_name, ':')) != NULL) {*cptr = 0;}if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {if (doaliases == 0) {continue;}myflags = IFI_ALIAS;}memcpy(lastname, ifr->ifr_name, IFNAMSIZ);ifrcopy = *ifr;ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);flags = ifrcopy.ifr_flags;if ((flags & IFF_UP) == 0) continue;ifi = calloc(1, sizeof(struct ifi_info));*ifipnext = ifi;ifipnext = &ifi->ifi_next;ifi->ifi_flags = flags;ifi->ifi_myflags = myflags;memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);   ifi->ifi_name[IFI_NAME - 1] = 0;switch(ifr->ifr_addr.sa_family) {case AF_INET:   sinptr = (struct sockaddr_in*)&ifr->ifr_addr;if (ifi->ifi_addr == NULL) {ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in));memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));}if (flags & IFF_BROADCAST) {ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy);sinptr = (struct sockaddr_in*)&ifrcopy.ifr_broadaddr;ifi->ifi_brdaddr = calloc(1, sizeof(struct sockaddr_in));memcpy(ifi->ifi_brdaddr, sinptr, sizeof(struct sockaddr_in));   }if (flags & IFF_POINTOPOINT) {ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy);sinptr = (struct sockaddr_in*)&ifrcopy.ifr_dstaddr;ifi->ifi_dstaddr = calloc(1, sizeof(struct sockaddr_in));memcpy(ifi->ifi_dstaddr, sinptr, sizeof(struct sockaddr_in));}break;default:break;}} free(buf);return(ifihead);
}void free_ifi_info(struct ifi_info *ifihead)
{struct ifi_info *ifi, *ifinext;for (ifi = ifihead; ifi != NULL; ifi = ifinext) {if (ifi->ifi_addr != NULL) free(ifi->ifi_addr);if (ifi->ifi_brdaddr != NULL) free(ifi->ifi_brdaddr);if (ifi->ifi_dstaddr != NULL) free(ifi->ifi_dstaddr);ifinext = ifi->ifi_next;free(ifi);}
}char *sock_ntop(struct sockaddr* sa, int len)
{char portstr[7];static char str[128];switch(sa->sa_family) {case AF_INET: {struct sockaddr_in *sin = (struct sockaddr_in*)sa;if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL) return NULL;if (ntohs(sin->sin_port) != 0) {snprintf(portstr, sizeof(portstr), ".%d", ntohs(sin->sin_port));strcat(str, portstr);}return str;}}return NULL;
}

输出为:

网络编程学习笔记(获取所有网络接口)相关推荐

  1. java 网络编程学习笔记

    java 网络编程学习笔记 C/S模式:客户端和服务器 客户端创建流程 1 1.建立Socket端点 2 3 Socket s = new Socket(绑定地址, 绑定端口); 2.确认源数据方式和 ...

  2. 15Java网络编程学习笔记

    Java网络编程学习笔记 文章目录 1 网络基础 1.1 网络通信 1.2 网络 1.3 IP地址 1.5 域名 1.6 端口号 1.7 网络通信协议 1.8 TCP协议 1.9 UDP协议 2 In ...

  3. [Linux网络编程学习笔记]索引

    一.Linux基本知识 [学习笔记]Linux平台的文件I/O操作 [学习笔记]Linux平台的文件,目录及操作 [Linux学习笔记]标准输入输出 [Linux学习笔记]进程概念及控制 [Linux ...

  4. 编程开发:Linux网络编程学习笔记

    非常全面.通俗易懂.值得借鉴的Linux网络编程学习笔记.关键字:linux linux编程 网络编程 linux网络编程 下载地址:点我下载 特别说明:本资源收集于网络,版权归原作者及版权商所有,仅 ...

  5. python网络编程学习笔记(二)

    python网络编程学习(四) 多用途客户端协议 一.ftp 功能:上传下载文件,删除命名文件,建立删除目录,自动压缩,保存目录 1.代码: #coding=utf-8 '''连接远程ftp服务器,显 ...

  6. Linux网络编程学习笔记

    声明:1.未经过原作者许可,不可用于商业行为:2.本笔记仅用于知识学习,如有侵权,立即删除. 1.学习链接 黑马程序员-Linux网络编程:https://www.bilibili.com/video ...

  7. Linux网络编程学习笔记(TCP)

    文章目录 1 字节序 1.1 定义 1.2 字节序转换函数 2 Socket地址 2.1 通用socket地址(实际开发不使用) 2.2 专用socket地址 2 IP地址转换 3 TCP通信流程 3 ...

  8. [Linux网络编程学习笔记]套接字地址结构

    好久没有看那Linux网络编程这本书了,今天看到了重点部分-TCP套接字.下面先来看看套接字的地址结构 Linux系统的套接字可以支持多种协议,每种不同的协议都是用不同的地址结构.在头文件<li ...

  9. JAVA UDP网络编程学习笔记

    一.UDP网络编程概述 采用TCP协议通信时,客户端的Socket必须先与服务器建立连接,连接建立成功后,服务器端也会持有客户端连接的Socket,客户端的Socket与服务器端的Socket是对应的 ...

最新文章

  1. canal应用二:mysql数据实时同步到redis
  2. C函数加密实现及常用字符串处理函数的使用
  3. [Lua学习]简单链表
  4. 【算法】LeetCode算法题-Remove Duplicates from Sorted Array
  5. linux运行tcl脚本语言,Tool Command Language (Tcl)初体验
  6. Ceph 笔记(二)
  7. 华为云ModelArts 3.0助力行业AI高效落地
  8. java day36【XML概念 、语法 、解析】
  9. k8s mysql 弹性_k8s 弹性伸缩,基于prometheus自定义指标
  10. 戴德金--连续性和无理数--我自己做的中文翻译第4页
  11. 夏威夷大学计算机专业排名,夏威夷大学(美国夏威夷大学排名)
  12. PC微信逆向-PC微信HOOK-发送Gif表情(版本3.0.0.47)
  13. 1665 完成所有任务的最少初始能量
  14. 93. 复原 IP 地址
  15. python爬小说一本一本爬_【学习笔记】Python爬取某一本小说
  16. linux ps 被替换文件怎么恢复,被覆盖的文件如何恢复_被替换掉的文件怎么恢复-win7之家...
  17. 2021最新版万年历小程序搭建教程
  18. 余额宝​微服务深度治理
  19. 2019,淘宝无货源转型之路势在必行,单类目玩法实操案例解析
  20. 【极简版GH60】【GH60剖析】【七】分析源代码

热门文章

  1. BZOJ 1176([Balkan2007]Mokia-CDQ分治-分治询问)
  2. Python学习札记(二)
  3. poj 1873 枚举+凸包
  4. python工程师薪资坑吗-6年Python开发工程师精心总结学习思路,再不看看就凉了...
  5. python快速编程入门课后简答题答案-Python编程:从入门到实践(第2版)第1章习题答案...
  6. python经典程序练习题-99道经典练习题助你全面掌握python基础知识,附技巧答案...
  7. python视频教程从入门到精通全集-python从入门到精通视频(全60集)免费高速下载...
  8. python编程语法大全-python语法汇总
  9. python散点图点的大小-python散点图面积大小比例轴长度
  10. python爬取百度百科词条-python简单爬虫爬取百度百科python词条网页