环境配置
在AIX
上,可以使用smitty tcpip
命令给单个网卡配置多个IP
别名。操作步骤如下:
- 选择
Further Configuration
- 选择
Network Interfaces
- 选择
Network Interfaces Selection
- 选择
Configure Aliases
5.选择Add an IPV4 Network Alias
- 选择需要配置的网卡,我们这里选择
en1
- 在
IPV4 ADDRESS
处输入新的IP
,NETMASK
不需要配置
- 按
F10
保存退出。
查看网卡信息,已经配置完成。
bash-5.0# ifconfig -a
en0: flags=1e080863,c0<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT,CHECKSUM_OFFLOAD(ACTIVE),LARGESEND,CHAIN>inet 192.168.21.251 netmask 0xffffff00 broadcast 192.168.21.255tcp_sendspace 131072 tcp_recvspace 65536 rfc1323 0
en1: flags=1e080863,c0<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT,CHECKSUM_OFFLOAD(ACTIVE),LARGESEND,CHAIN>inet 192.168.2.251 netmask 0xffffff00 broadcast 192.168.2.255inet 192.168.2.216 netmask 0xffffff00 broadcast 192.168.2.255
lo0: flags=e08084b,c0<UP,BROADCAST,LOOPBACK,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT,LARGESEND,CHAIN>inet 127.0.0.1 netmask 0xff000000 broadcast 127.255.255.255inet6 ::1%1/0tcp_sendspace 131072 tcp_recvspace 131072 rfc1323 1
C 代码实现
在IBM官方文档,有介绍使用ioctl函数获取单网卡多IP的方法,链接如下: https://www.ibm.com/docs/en/aix/7.2?topic=i-ioctl-socket-control-operations
调用方式为:
ioctl (fd, SIOCGIFADDRS, (caddr_t)ifaddrsp);
其中,会用到一个struct ifreqaddrs *ifaddrsp
的结构体,该结构体如下:
struct ifreqaddrs {char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */int ifaddrs; /* returned number of address on if */int naddrs; /* number of addresses returned in req*/union {struct sockaddr_in addr_in;struct sockaddr_in6 addr_in6;} ifrasu[1];
};
我们需要将网卡名提前传入到ifaddrsp->ifr_name
中,最终多个IP会通过ifaddrsp->ifrasu
的数组返回。
不过需要注意的是,ifaddrsp
的内存需要手动申请,如果你需要获取n个IP,那么你至少需要申请sizeof (struct ifreqaddrs) + (n * sizeof (struct sockaddr_in)
大小的内存。
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>int main() {struct sockaddr *sa;int sockfd, i;sockfd = socket(AF_INET, SOCK_DGRAM, 0);//第一遍调用,单纯获取IP个数struct ifreqaddrs *ifaddrsp = calloc(1, sizeof (struct ifreqaddrs));//此处传入网卡名为en1strcpy(ifaddrsp->ifr_name, "en1");if (ioctl(sockfd, SIOCGIFADDRS, ifaddrsp) == 0) {printf("ifaddrs: %d\n", ifaddrsp->ifaddrs);}//第二遍调用,根据IP个数申请内存空间struct ifreqaddrs *ifaddrsp2 = calloc(1, sizeof (struct ifreqaddrs) + (ifaddrsp->ifaddrs * sizeof (struct sockaddr_in)));strcpy(ifaddrsp2->ifr_name, "en1");//设置需要获取的ip个数及网卡名ifaddrsp2->naddrs = ifaddrsp->ifaddrs;ioctl(sockfd, SIOCGIFADDRS, ifaddrsp2);//打印IP地址for (i = 0; i < ifaddrsp2->naddrs; i++) {char ip[64] = {0};inet_ntop(AF_INET,&ifaddrsp2->ifrasu[i].addr_in.sin_addr, ip, sizeof(ip));printf("ip%d: %s \n", i+1, ip);} close(sockfd);free(ifaddrsp);free(ifaddrsp2);return 0;
}
以上代码运行结果:
bash-5.0# ./a.out
ifaddrs: 2
ip1: 192.168.2.251
ip2: 192.168.2.216
推荐一个零声学院免费教程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习: C/C++Linux服务器开发/高级架构师