C语言获取Linux单网卡的多IP地址

news/2025/3/19 14:46:05/

环境配置

上一篇文章主要讲了AIX系统下的单网卡多IP的IP的配置以及C语言获取的方法。相比AIX,Linux下配置就方便得多。
首先找到我们需要配置的网卡名,比如p2p2, 进入到/etc/sysconfig/network-scripts/目录,找到ifcgf-p2p2文件,打开是这个样子的:

TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=no
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=p2p2
UUID=0a69226b-6051-4cb4-a1d3-17f37896275a
DEVICE=p2p2
ONBOOT=no
GATEWAY=192.168.11.1
IPADDR=192.168.11.111
NETMASK=255.255.255.0
DNS=114.114.114.114

我们直接在里面增加需要添加的IP,如下所示:

TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=no
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=p2p2
UUID=0a69226b-6051-4cb4-a1d3-17f37896275a
DEVICE=p2p2
ONBOOT=no
GATEWAY=192.168.11.1
IPADDR=192.168.11.111
NETMASK=255.255.255.0
DNS=114.114.114.114
IPADDR2=192.168.11.11
GATEWAY2=192.168.11.1
NETMASK2=255.255.255.0
DNS2=114.114.114.114
IPADDR3=192.168.11.12
GATEWAY3=192.168.11.1
NETMASK3=255.255.255.0
DNS3=114.114.114.114

如上图,我们增加了两个IP, 一个为192.168.11.11,一个为192.168.11.12
保存后将网卡重新上线一下:

[root@ck10 chenyc]#ifdown p2p2
[root@ck10 chenyc]#ifup p2p2

完成后,从ifcofig是看不出来的:

[root@ck10 chenyc]# ifconfig p2p2
p2p2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 192.168.11.111  netmask 255.255.255.0  broadcast 192.168.11.255inet6 fe80::cd7f:92f2:deb5:fb14  prefixlen 64  scopeid 0x20<link>ether 90:e2:ba:8f:06:41  txqueuelen 1000  (Ethernet)RX packets 0  bytes 0 (0.0 B)RX errors 0  dropped 0  overruns 0  frame 0TX packets 232  bytes 47704 (46.5 KiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

但是用ip a命令可以看到已经生效:

7: p2p2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether 90:e2:ba:8f:06:41 brd ff:ff:ff:ff:ff:ffinet 192.168.11.111/24 brd 192.168.11.255 scope global noprefixroute p2p2valid_lft forever preferred_lft foreverinet 192.168.11.11/24 brd 192.168.11.255 scope global secondary noprefixroute p2p2valid_lft forever preferred_lft foreverinet 192.168.11.12/24 brd 192.168.11.255 scope global secondary noprefixroute p2p2valid_lft forever preferred_lft foreverinet6 fe80::cd7f:92f2:deb5:fb14/64 scope link noprefixroute valid_lft forever preferred_lft forever

C代码实现

Linux 下获取单网卡的多IP实现方法有很多,我这里演示两种实现方法。

方法一

#include <stdio.h>
#include <stdlib.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/if.h>
#include<string.h>
int main(int argc, char **argv) {struct ifaddrs *ifaddr, *ifa;if (getifaddrs(&ifaddr) == -1) {perror("getifaddrs");exit(EXIT_FAILURE);}for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {if (ifa->ifa_addr == NULL) {continue;}if (strcmp(ifa->ifa_name, "p2p2") == 0 ){char ip[64] = {0};struct sockaddr_in *sock = ( struct sockaddr_in*)ifa->ifa_addr;inet_ntop(AF_INET,&sock->sin_addr, ip, sizeof(ip));printf("name: %s, ip: %s\n", ifa->ifa_name, ip);}}freeifaddrs(ifaddr);exit(EXIT_SUCCESS);
}

第一种方法主要是利用getifaddrs函数获取到所有的网卡信息,这些信息会返回到一个 struct ifaddrs结构体中,该结构体本身是一个单向链表,结构如下所示:

            struct ifaddrs {struct ifaddrs  *ifa_next;    /* Next item in list */char            *ifa_name;    /* Name of interface */unsigned int     ifa_flags;   /* Flags from SIOCGIFFLAGS */struct sockaddr *ifa_addr;    /* Address of interface */struct sockaddr *ifa_netmask; /* Netmask of interface */union {struct sockaddr *ifu_broadaddr;/* Broadcast address of interface */struct sockaddr *ifu_dstaddr;/* Point-to-point destination address */} ifa_ifu;#define              ifa_broadaddr ifa_ifu.ifu_broadaddr#define              ifa_dstaddr   ifa_ifu.ifu_dstaddrvoid            *ifa_data;    /* Address-specific data */};

其中,ifa_next存储的是下一条网卡信息的地址,ifa_name存储的是网卡名,ifa_addr存储的就是IP地址。
不过这个函数会获取到一些冗余的信息,这些信息并不是我们所需要的,上面代码运行结果如下所示:

[root@ck10 chenyc]# ./1
name: p2p2, ip: 7.0.0.0
name: p2p2, ip: 192.168.11.111
name: p2p2, ip: 192.168.11.11
name: p2p2, ip: 192.168.11.12
name: p2p2, ip: 0.0.0.0

多了一个7.0.0.00.0.0.0

方法二

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/types.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  
#include <linux/if.h>
#include<stdio.h> 
#define BUF_SIZE 1024int main()
{int sock_fd;struct ifconf conf;struct ifreq *ifr;char buff[BUF_SIZE] = {0};int num;int i;sock_fd = socket(PF_INET, SOCK_DGRAM, 0);if ( sock_fd < 0 )     return -1;conf.ifc_len = BUF_SIZE;conf.ifc_buf = buff;if ( ioctl(sock_fd, SIOCGIFCONF, &conf) < 0 ){close(sock_fd);return -1;}num = conf.ifc_len / sizeof(struct ifreq);ifr = conf.ifc_req;for(i = 0; i < num; i++){struct sockaddr_in *sin = (struct sockaddr_in *)(&ifr->ifr_addr);if ( ioctl(sock_fd, SIOCGIFFLAGS, ifr) < 0 ){close(sock_fd);return -1;}if ( (ifr->ifr_flags & IFF_UP) && strcmp("p2p2",ifr->ifr_name) == 0 ){printf("ip: %s\n", inet_ntoa(sin->sin_addr));}ifr++;}close(sock_fd);return -1;
}

这段代码的逻辑就好理解得多。直接调用ioctl接口,先用SIOCGIFCONF获取到所有的网卡,然后再用SIOCGIFFLAGS依次拿到各个网卡的信息即可。这样子取出来的数据就是我们需要的结果。
上面代码运行结果如下:

[root@ck10 chenyc]# ./2
ip: 192.168.11.111
ip: 192.168.11.11
ip: 192.168.11.12

推荐一个零声学院免费教程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习: C/C++Linux服务器开发/高级架构师


http://www.ppmy.cn/news/121394.html

相关文章

LeetCode 70. 爬楼梯 计算爬楼梯共计多少种方法可达

1、问题&#xff1a; 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1. 1 阶 1 阶 2.…

第十九章行为型模式—中介者模式

文章目录 中介者模式解决的问题结构实例存在的问题适用场景 中介者模式和代理模式的区别代理模式中介模式桥接模式总结 行为型模式用于描述程序在运行时复杂的流程控制&#xff0c;即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务&#xff0c;它涉及算法…

充电桩检测设备厂家TK4860C交流充电桩检定装置

TK4860系列是专门针对现有交流充电桩现场检测过程中接线复杂、负载笨重、现场检测效率低等问题而研制的一系列高效检测仪器&#xff0c;旨在更好的开展充电桩的强制检定工作。 充电桩检测设备是一款在交流充电桩充电过程中实时检测充电电量的标准仪器&#xff0c;仪器以新能源…

小米max2装鸿蒙,小米Max2最全评测 小米Max2值不值得买?

小米Max2最全评测 小米Max2值不值得买&#xff1f;【IT168 评测】2016年的5月10日&#xff0c;小米首款大屏手机小米Max发布。而在一代小米Max发布初期&#xff0c;外界对这款手机的市场预期并不高&#xff0c;毕竟有着6.44寸大屏的它定位有些过于“精准”&#xff0c;面向的用…

小米5主板原理图_小米5手机拆解及评测 小米5拆机详细图解教程(4)

来看下取下的前像头&#xff0c;小米5的前摄像头只有400W相对其他设备有点小了&#xff0c;但是f/2.0 光圈 80 广角这点还是不错的。 接下来我们看看主板&#xff0c;主板上覆盖了很多屏蔽罩&#xff0c;这些屏蔽罩都是焊接式的&#xff0c;接下来我们拆开看看屏蔽罩下的原件及…

小米新手机鸿蒙系统,安卓终于被抛弃了!迎来鸿蒙系统新时代:结果小米新系统惨遭吐槽...

【4月15日讯】相信大家都知道&#xff0c;自从华为官方确认华为手机将全面“脱离Android系统”&#xff0c;转投自研鸿蒙OS系统以后&#xff0c;很多花粉们也在不断地期待华为鸿蒙OS系统能够早日“转正”&#xff0c;自己也能够早日体验到华为鸿蒙OS系统正式版&#xff0c;但就…

小米5 android 4.1.2,小米手机2安卓4.1 MIUI系统试玩

小米手机2搭载了基于Android 4.1深度定制的MIUI系统&#xff0c;而且这次MIUI有了中文名——米柚。其中不但加入了Android 4.1的新特性&#xff0c;还有新的功能。 可以看到MIUI V4在配色上已经进行改变&#xff0c;不过系统设置菜单还是与原生系统较为一致。这次小米手机2搭载…

原生android系统小米4,评测小米手机原生系统4.0怎么样

如今米系统4.0已经公布很久了&#xff0c;对于所有的疑云也慢慢的解开&#xff0c;但这个新的系统到底好不好用了&#xff1f;也一直是手机友友关心的问题。MIUI V4是要基于Android 2.3.5K系统下面升级才行的&#xff0c;因为Android 2.3.5K开始&#xff0c;更新了系统分区。小…