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 1500
inet 192.168.11.111 netmask 255.255.255.0 broadcast 192.168.11.255
inet6 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 0
TX 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 1000
link/ether 90:e2:ba:8f:06:41 brd ff:ff:ff:ff:ff:ff
inet 192.168.11.111/24 brd 192.168.11.255 scope global noprefixroute p2p2
valid_lft forever preferred_lft forever
inet 192.168.11.11/24 brd 192.168.11.255 scope global secondary noprefixroute p2p2
valid_lft forever preferred_lft forever
inet 192.168.11.12/24 brd 192.168.11.255 scope global secondary noprefixroute p2p2
valid_lft forever preferred_lft forever
inet6 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\_dstaddr
void \*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.0
和0.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 1024
int 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;