Linux下C语言操作网卡的几个代码实例?特别实用
前面写了一篇关于网络相关的文章:如何获取当前可用网口。
《简简单单教你如何用C语言列举当前所有网口!》
那么如何使用C语言直接操作网口?
比如读写IP地址、读写MAC地址等。
一、原理
主要通过系统用socket()、ioctl()、实现
int socket(int domain, int type, int protocol);
功能:创建套接字
参数:domain: Name Purpose Man pageAF_UNIX, AF_LOCAL Local communication unix(7)AF_INET IPv4 Internet protocols ip(7)type:SOCK_STREAM Provides sequenced, reliable, two-way, connection-basedbyte streams. An out-of-band data transmission mecha‐nism may be supported.SOCK_DGRAM Supports datagrams (connectionless, unreliable messagesof a fixed maximum length).protocol:通常为0
返回值:成功:新的套接字的文件描述符失败:错误码,负值
int ioctl(int fd, unsigned long request, ...);
参数:fd :文件描述符request:命令... :参数
其中网络用到的request定义头文件位于:
/usr/include/linux/sockios.h
/* Linux-specific socket ioctls */
#define SIOCINQ FIONREAD
#define SIOCOUTQ TIOCOUTQ /* output queue size (not sent + not acked) *//* Routing table calls. */
#define SIOCADDRT 0x890B /* add routing table entry */
#define SIOCDELRT 0x890C /* delete routing table entry */
#define SIOCRTMSG 0x890D /* call to routing system *//* Socket configuration controls. */
#define SIOCGIFNAME 0x8910 /* get iface name */
#define SIOCSIFLINK 0x8911 /* set iface channel */
#define SIOCGIFCONF 0x8912 /* get iface list */
#define SIOCGIFFLAGS 0x8913 /* get flags */
#define SIOCSIFFLAGS 0x8914 /* set flags */
#define SIOCGIFADDR 0x8915 /* get PA address */
#define SIOCSIFADDR 0x8916 /* set PA address */
#define SIOCGIFDSTADDR 0x8917 /* get remote PA address */
#define SIOCSIFDSTADDR 0x8918 /* set remote PA address */
#define SIOCGIFBRDADDR 0x8919 /* get broadcast PA address */
#define SIOCSIFBRDADDR 0x891a /* set broadcast PA address */
#define SIOCGIFNETMASK 0x891b /* get network PA mask */
#define SIOCSIFNETMASK 0x891c /* set network PA mask */
#define SIOCGIFMETRIC 0x891d /* get metric */
#define SIOCSIFMETRIC 0x891e /* set metric */
#define SIOCGIFMEM 0x891f /* get memory address (BSD) */
#define SIOCSIFMEM 0x8920 /* set memory address (BSD) */
#define SIOCGIFMTU 0x8921 /* get MTU size */
#define SIOCSIFMTU 0x8922 /* set MTU size */
#define SIOCSIFNAME 0x8923 /* set interface name */
#define SIOCSIFHWADDR 0x8924 /* set hardware address */
#define SIOCGIFENCAP 0x8925 /* get/set encapsulations */
#define SIOCSIFENCAP 0x8926
#define SIOCGIFHWADDR 0x8927 /* Get hardware address */
#define SIOCGIFSLAVE 0x8929 /* Driver slaving support */
#define SIOCSIFSLAVE 0x8930
#define SIOCADDMULTI 0x8931 /* Multicast address lists */
#define SIOCDELMULTI 0x8932
#define SIOCGIFINDEX 0x8933 /* name -> if_index mapping */
#define SIOGIFINDEX SIOCGIFINDEX /* misprint compatibility :-) */
#define SIOCSIFPFLAGS 0x8934 /* set/get extended flags set */
#define SIOCGIFPFLAGS 0x8935
#define SIOCDIFADDR 0x8936 /* delete PA address */
#define SIOCSIFHWBROADCAST 0x8937 /* set hardware broadcast addr */
#define SIOCGIFCOUNT 0x8938 /* get number of devices */
……
其中ioctl的参数需要借助结构体struct ifreq
,
定义头文件:
/usr/include/linux/if.h
#if __UAPI_DEF_IF_IFREQ
struct ifreq {
#define IFHWADDRLEN 6union{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 * ifru_data;struct if_settings ifru_settings;} ifr_ifru;
};
#endif /* __UAPI_DEF_IF_IFREQ */#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*/
二、函数实现
下面将实现不同功能的函数一一列举。
0. 列出所有可用网口
int list_all_port()
{struct ifconf ifconf;struct ifreq *ifr;int m, n, s, fd;if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {return -11;}s = sizeof(struct ifreq)*5;for (;;) {ifr = malloc(s);ifconf.ifc_len = s;ifconf.ifc_req = ifr;if (ioctl(fd, SIOCGIFCONF, &ifconf) < 0) {perror("SIOCGIFCONF:");free(ifr);close(fd);return 1;}if (ifconf.ifc_len != s)break;free(ifr);s *= 2;}close(fd);m = ifconf.ifc_len/sizeof(struct ifreq);for (n = 0; n < m; n++){printf("port:\t%s\n",ifconf.ifc_req[n].ifr_name);}free(ifr);
}
1. 获取指定网卡IP
int getLocalIp(const char *eth, char *ip) {struct ifreq ifr;struct sockaddr_in sin;int fd;bzero(&ifr, sizeof(ifr));if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {return -1;}strcpy(ifr.ifr_name, eth);if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {close(fd);return -1;}memcpy(&sin, &ifr.ifr_addr, sizeof(sin));snprintf(ip, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));close(fd);return 0;
}
2. 设置本网卡IP地址
int setIpAddrManual(const char *eth, char *ipstr) {int fd;struct sockaddr_in sin;struct ifreq ifr;bzero(&ifr, sizeof(ifr));if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){return -1;}strcpy(ifr.ifr_name, eth);sin.sin_addr.s_addr = inet_addr(ipstr);sin.sin_family = AF_INET;memcpy(&ifr.ifr_addr, &sin, sizeof(sin));if (ioctl(fd, SIOCSIFADDR, &ifr) < 0){perror("");close(fd);return -1;}close(fd);return 0;
}
3. 获取本机网卡Mac地址
int getLocalMac(const char *eth, char *mac) {int fd;struct ifreq ifr;bzero(&ifr, sizeof(ifr));if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){return -1;}strcpy(ifr.ifr_name, eth);if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0){close(fd);return -1;}snprintf(mac,18, "%02x:%02x:%02x:%02x:%02x:%02x",(unsigned char) ifr.ifr_hwaddr.sa_data[0],(unsigned char) ifr.ifr_hwaddr.sa_data[1],(unsigned char) ifr.ifr_hwaddr.sa_data[2],(unsigned char) ifr.ifr_hwaddr.sa_data[3],(unsigned char) ifr.ifr_hwaddr.sa_data[4],(unsigned char) ifr.ifr_hwaddr.sa_data[5]);close(fd);return 0;}
4. 设置网卡mac地址
/*
support format [00:11:22:33:44:55]
*/
#define MAC_ARRAY(mac_array) (unsigned int *)&mac_array[0],(unsigned int *)&mac_array[1],(unsigned int *)&mac_array[2],(unsigned int *)&mac_array[3],(unsigned int *)&mac_array[4],(unsigned int *)&mac_array[5]
int setLocalMac(const char *eth, char *mac) {int fd;struct ifreq ifr;unsigned char mac_array[6] = {0};bzero(&ifr, sizeof(ifr));if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){return -1;}strcpy(ifr.ifr_name, eth);ifr.ifr_hwaddr.sa_family = AF_LOCAL;sscanf(mac,"%02x:%02x:%02x:%02x:%02x:%02x",MAC_ARRAY(mac_array));memcpy(ifr.ifr_hwaddr.sa_data,mac_array,6);if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0){perror("SIOCSIFHWADDR:");close(fd);return -1;}close(fd);return 0;
}
注意:
- 网卡地址的第一字节必须是偶数
- sa_family 值必须为:AF_LOCAL
5. 获取网卡mtu
int getMtu(const char *eth, char *mtu) {int fd;struct ifreq ifr;bzero(&ifr, sizeof(ifr));if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){return -1;}strcpy(ifr.ifr_name, eth);if (ioctl(fd, SIOCGIFMTU, &ifr) < 0){close(fd);return -1;} snprintf(mtu,64, "%d", (unsigned char) ifr.ifr_mtu);close(fd);return 0;
}
6. 获取广播地址
int getBroadAddr(const char *eth, char *ip) {int fd;struct sockaddr_in sin;struct ifreq ifr;bzero(&ifr, sizeof(ifr));if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){return -1;}strcpy(ifr.ifr_name, eth);if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0){perror("");close(fd);return -1;}memcpy(&sin, &ifr.ifr_broadaddr, sizeof(sin));snprintf(ip, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));close(fd);return 0;
}
7. 获取掩码
int getNetMask(const char *eth, char *mask) {int fd;struct sockaddr_in sin;struct ifreq ifr;bzero(&ifr, sizeof(ifr));if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){return -1;}strcpy(ifr.ifr_name, eth);if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0){perror("");close(fd);return -1;}memcpy(&sin, &ifr.ifr_netmask, sizeof(sin));snprintf(mask, IP_SIZE, "%s", inet_ntoa(sin.sin_addr));close(fd);return 0;
}
8. 获取网卡flag
int getFlags(const char *eth, char *fg) {int fd;struct sockaddr_in sin;struct ifreq ifr;bzero(&ifr, sizeof(ifr));if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){return -1;}strcpy(ifr.ifr_name, eth);if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0){perror("");close(fd);return -1;}snprintf(fg, IP_SIZE, "%x", ifr.ifr_flags);close(fd);return 0;
}
三、测试
1. 测试程序
int main(int argc, char **argv)
{int fg=0;char mac[32]={};char ip[IP_SIZE]={0};char buf[64];getBroadAddr(ethname,ip);printf("broad ip:\t%s\n",ip);getNetMask(ethname,ip);printf("mask:\t%s\n",ip);setIpAddrManual(ethname, "1.1.1.1");getLocalIp(ethname,ip);printf("ip:\t%s\n",ip);setLocalMac(ethname,"00:11:22:33:44:55");getLocalMac(ethname,mac);printf("mac:\t%s\n",mac);getMtu(ethname,buf);printf("mtu:\t%s\n",buf); return 1;
}
2. 执行结果
执行后结果:
peng@ubuntu:~/work/test/ip$ ifconfig
eth0 Link encap:Ethernet HWaddr 00:11:22:33:44:55 inet addr:1.1.1.1 Bcast:1.255.255.255 Mask:255.0.0.0inet6 addr: fe80::d9d4:d42b:a04a:9d40/64 Scope:LinkUP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:188577 errors:0 dropped:0 overruns:0 frame:0TX packets:208116 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:53762370 (53.7 MB) TX bytes:172094089 (172.0 MB)
完整代码获取,请点赞转发,并后台留言:eth
相关文章:

Linux下C语言操作网卡的几个代码实例?特别实用
前面写了一篇关于网络相关的文章:如何获取当前可用网口。 《简简单单教你如何用C语言列举当前所有网口!》 那么如何使用C语言直接操作网口? 比如读写IP地址、读写MAC地址等。 一、原理 主要通过系统用socket()、ioctl()、实现 int sock…...
noip2011选择旅馆
1.审题:第一个人与第二个人入住的旅馆要求是同色的; 两个人去消费的旅馆并没有要求与入住的旅馆是同色的(这点要小心) 2.要求记录以下数据: 1)a[color]表示当前同为颜色color的旅馆数 2)b[co…...

vue造轮子完整指南--npm组件包开发步骤
一、项目包文件的创建和初始化。 1. 新建项目包。 vue create <Project Name> //用于发布npm包的项目文件名 ps:一般选择自定义,然后不需要Vuex和Router,其他选项按自己实际情况选择安装即可。 2.修改原始src文件名、新增组件项目存放文件和修改…...

28 drf-Vue个人向总结-1
文章目录 前后端分离开发展示项目项补充知识开发问题浏览器解决跨域问题 drf 小tips设置资源root目录使用自定义的user表设置资源路径media数据库补充删除表中数据单页面与多页面模式过滤多层自关联后端提交的数据到底是什么jwt token登录设置普通的 token 原理使用流程解析 jw…...

线性代数(七) 矩阵分析
前言 从性线变换我们得出,矩阵和函数是密不可分的。如何用函数的思维来分析矩阵。 矩阵的序列 通过这个定义我们就定义了矩阵序列的收敛性。 研究矩阵序列收敛性的常用方法,是用《常见向量范数和矩阵范数》来研究矩阵序列的极限。 长度是范数的一个特…...

myArm 全新七轴桌面型机械臂
引言 在不断演进的科技世界中,我们始终追求创新和卓越,以满足客户的需求并超越他们的期望。今天,我们很高兴地宣布我们的最新产品——myArm 300 Pi,一款七轴的桌面型机械臂。这款产品的独特之处在于其灵活性和可编程性,…...
tomcat乱码解决
解决乱码 1、修改bin\catalina.bat配置文件 修改tomcat的配置文件,找到tomcat路径下的\bin目录下的catalina.bat文件,修改 set “JAVA_OPTS%JAVA_OPTS% %JSSE_OPTS% -Dfile.encodingUTF-8 -Dsun.jnu.encodingUTF-8 ” 2、修改conf\logging.properties配置…...

【Linux】详解线程第三篇——线程同步和生产消费者模型
线程同步和生消模型 前言正式开始再次用黄牛抢票来讲解线程同步的思想通过条件变量来实现线程同步条件变量接口介绍初始化和销毁pthread_cond_waitsignal和broadcast 生产消费者模型三种关系用基本工程师思维再次理解基于生产消费者模型的阻塞队列版本一版本二多生多消 利用RAI…...
k8s 安装
文章目录 k8s 客户端安装k8s集群minikubekindkubeadm 验证 k8s 客户端 用于连接k8s集群,建议下载1.23.x的版本,其他的版本本地运行可能会有莫名其妙的报错 https://dl.k8s.io/release/v1.23.16/bin/linux/amd64/kubectl 安装k8s集群 minikube Minik…...

红队打靶:THE PLANETS: MERCURY打靶思路详解(vulnhub)
目录 写在开头 第一步:主机发现和端口扫描 第二步:Web渗透 第三步:获取初步立足点并搜集信息 第四步:软连接劫持sudo提权 总结与思考 写在开头 本篇博客在自己的理解之上根据大佬红队笔记的视频进行打靶,详述了…...

【网络协议】IP
当连接多个异构的局域网形成强烈需求时,用户不满足于仅在一个局域网内进行通信,他们希望通过更高一层协议最终实现异构网络之间的连接。既然需要通过更高一层的协议将多个局域网进行互联,那么这个协议就必须为不同的局域网环境定义统一的寻址…...
Python 布尔类型
布尔值表示两个值之一:True(真)或False(假)。 布尔值 在编程中,您经常需要知道一个表达式是否为True或False。 您可以在Python中评估任何表达式,并获得两个答案之一:True或False。…...

iOS设备管理器iMazing比iTunes好用吗?有哪些优势
虽然 iTunes 是 Apple 官方指定的 iPhone 数据备份和管理工具,但是一直以来 iTunes 卡顿的使用体验和过慢的备份过程为不少人诟病。如果大家也被 iTunes 体验不佳的备份和管理功能所困扰,那么简单易用、功能强大的iMazing 能为你解决这个问题。 iMazing…...
Opengl之深度测试
在坐标系统小节中,我们渲染了一个3D箱子,并且运用了深度缓冲(Depth Buffer)来防止被阻挡的面渲染到其它面的前面。在这一节中,我们将会更加深入地讨论这些储存在深度缓冲(或z缓冲(z-buffer))中的深度值(Depth Value),以及它们是如何确定一个片段是处于其它片段后方的。 …...
利用ICG-NH2/Amine进行DNA标记1686147-55-6星戈瑞
ICG-NH2(吲哚菁绿胺)可以用于DNA标记,这种标记方法通常涉及到DNA上的胺基反应基团和ICG-NH2之间的化学反应。以下是一种常见的方法,用于利用ICG-NH2标记DNA分子: 步骤: 1.准备目标DNA:你需要准…...
Pyecharts数据可视化
Pyecharts数据可视化 1、Pyecharts模块2、柱状图3、折线图4、饼图5、散点图6、图表合并7、词云8、地图 1、Pyecharts模块 ECharts是百度提供的基于JavaScript的开源可视化库,主要用于Web端数据可视化 Echarts是通过JS实现的,Pyecharts则可以使用Python来…...

集合-List集合
系列文章目录 1.集合-Collection-CSDN博客 2.集合-List集合-CSDN博客 文章目录 目录 系列文章目录 文章目录 前言 一 . 什么是List? 二 . List集合的特点 三 . 常用方法 1.void add(int index, E element): 将指定的元素插入到列表的指定位置。 2.E remove(int in…...
vuex的使用
1 vuex的使用 1 vuex的使用 store/index.js -在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式 的管理(读/写),也是一种组件间通信的方式,且适用于任意…...

raw图片处理软件:DxO PhotoLab 6 mac中文版支持相机格式
DxO PhotoLab 6 mac是一款专业的RAW图片处理软件,适用于Mac操作系统。它具有先进的图像处理技术和直观易用的界面,可帮助用户轻松地将RAW格式的照片转换为高质量的JPEG或TIFF图像。 DxO PhotoLab 6支持多种相机品牌的RAW格式,包括佳能、尼康、…...
ReactPortals传送门
ReactPortals传送门 React Portals提供了一种将子节点渲染到父组件以外的DOM节点的解决方案,即允许将JSX作为children渲染至DOM的不同部分,最常见用例是子组件需要从视觉上脱离父容器,例如对话框、浮动工具栏、提示信息等。 描述 <div&…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...