Linux下C语言操作网卡的几个代码实例!特别实用
来源:良许Linux教程网
2025-01-14 13:09:37
0浏览
收藏
怎么入门文章编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面golang学习网就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《Linux下C语言操作网卡的几个代码实例!特别实用》,涉及到,有需要的可以收藏一下
下面是对原文的重新表述,重点在于如何用C语言直接操作网络接口,例如读写IP地址和MAC地址。
如何使用C语言直接操作网络接口?
在这篇文章中,我们将讨论如何在C语言中直接操作网络接口。这包括读取和修改IP地址、MAC地址等信息。
1. 基本原理
我们可以通过使用系统提供的socket()和ioctl()函数来实现这些操作。这些函数允许我们与网络接口进行直接的交互,从而获取和设置与网络有关的各种参数。
你可以通过使用这些C语言函数来控制和管理当前系统上的网络接口。通过这两种系统调用,我们可以轻松实现网络接口的操作和管理。
int socket(int domain, int type, int protocol); 功能: 创建套接字 参数: domain: Name Purpose Man page AF_UNIX, AF_LOCAL Local communication unix(7) AF_INET IPv4 Internet protocols ip(7) type: SOCK_STREAM Provides sequenced, reliable, two-way, connection-based byte streams. An out-of-band data transmission mecha‐ nism may be supported. SOCK_DGRAM Supports datagrams (connectionless, unreliable messages of 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 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 * 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*/
二、函数实现
下面将实现不同功能的函数一一列举。
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)) return -1;
}
strcpy(ifr.ifr_name, eth);
if (ioctl(fd, SIOCGIFADDR, &ifr) 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)) 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) "");
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)) return -1;
}
strcpy(ifr.ifr_name, eth);
if (ioctl(fd, SIOCGIFHWADDR, &ifr) 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)) 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) "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)) return -1;
}
strcpy(ifr.ifr_name, eth);
if (ioctl(fd, SIOCGIFMTU, &ifr) 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)) return -1;
}
strcpy(ifr.ifr_name, eth);
if (ioctl(fd, SIOCGIFBRDADDR, &ifr) "");
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)) return -1;
}
strcpy(ifr.ifr_name, eth);
if (ioctl(fd, SIOCGIFNETMASK, &ifr) "");
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)) return -1;
}
strcpy(ifr.ifr_name, eth);
if (ioctl(fd, SIOCGIFFLAGS, &ifr) "");
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.0 inet6 addr: fe80::d9d4:d42b:a04a:9d40/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:188577 errors:0 dropped:0 overruns:0 frame:0 TX packets:208116 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:53762370 (53.7 MB) TX bytes:172094089 (172.0 MB)
完整代码,后天回复:eth
到这里,我们也就讲完了《Linux下C语言操作网卡的几个代码实例!特别实用》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于Linux,Linux系统,Shell脚本,Linux命令,linux入门,linux教程,linux学习,嵌入式Linux的知识点!
版本声明
本文转载于:良许Linux教程网 如有侵犯,请联系study_golang@163.com删除
如何解决电脑壁纸模糊问题,提升桌面美观度
- 上一篇
- 如何解决电脑壁纸模糊问题,提升桌面美观度
- 下一篇
- 轻松搞定!电脑设置上网的详细步骤指南
查看更多
最新文章
-
- 文章 · linux | 7小时前 |
- Linux日志分析与故障排查技巧
- 338浏览 收藏
-
- 文章 · linux | 10小时前 |
- Linux查看CPU使用率常用命令有哪些
- 125浏览 收藏
-
- 文章 · linux | 10小时前 |
- Linux进程管理与优先级设置技巧
- 345浏览 收藏
-
- 文章 · linux | 10小时前 |
- Linux终止用户所有进程的方法
- 408浏览 收藏
-
- 文章 · linux | 13小时前 |
- Linux软件安装方法全解析
- 488浏览 收藏
-
- 文章 · linux | 13小时前 |
- Linux服务依赖管理,systemd全面解析
- 469浏览 收藏
-
- 文章 · linux | 16小时前 |
- Linux搭建DHCP服务器详细教程
- 434浏览 收藏
-
- 文章 · linux | 19小时前 |
- Linux流量监控:iftop与nload使用教程
- 354浏览 收藏
-
- 文章 · linux | 1天前 |
- Linux查看所有用户命令大全
- 140浏览 收藏
-
- 文章 · linux | 1天前 |
- Linux系统更新与补丁管理技巧
- 218浏览 收藏
-
- 文章 · linux | 1天前 |
- LinuxShell脚本入门教程指南
- 333浏览 收藏
查看更多
课程推荐
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
查看更多
AI推荐
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3204次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3417次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3446次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4555次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3824次使用
查看更多
相关文章
-
- 命令行工具:应对Linux服务器安全挑战的利器
- 2023-10-04 501浏览
-
- 如何使用Docker进行容器的水平伸缩和负载均衡
- 2023-11-07 501浏览
-
- linux .profile的作用是什么
- 2024-04-07 501浏览
-
- 如何解决s权限位引发postfix及crontab异常
- 2024-11-21 501浏览
-
- 如何通过脚本自动化Linux上的K8S安装
- 2025-02-17 501浏览

