添加网卡第二IP

前言

当需要同时ping通两个网段的IP时,如果没有第二张可用网卡,那么也可以添加网卡的第二个IP地址。

方法

添加第二个IP的命令是

1
2
netsh interface ip add address "{interface_name}" {ip_address}
{subnet_mask}

1
netsh interface ip add address "以太网" 192.168.1.100 255.255.255.0

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import subprocess
import re
import os
import ipaddress
import time
class EthernetManager:
def __init__(self):
self.interface_name = self.get_adapter_names()[0]

def get_adapter_names(self):
"""获取主要的以太网适配器名称"""
result = os.popen('ipconfig')
res = result.read().strip()
adapter_list = re.findall(
'''(?<=以太网适配器 ).*?(?=:)|(?<=无线局域网适配器 ).*?(?=:)''', res)

def sort_key(adapter_name):
if '以太网' in adapter_name:
return (0, adapter_name)
elif 'Ethernet' in adapter_name:
return (1, adapter_name)
elif 'eht' in adapter_name:
return (2, adapter_name)
elif '本地连接' in adapter_name:
return (3, adapter_name)
else:
return (4, adapter_name)

sorted_adapters = sorted(adapter_list, key=sort_key)
return sorted_adapters

def get_ips(self):
"""获取当前适配器的所有IP地址"""
command = 'ipconfig'
result = subprocess.run(command, capture_output=True, text=True, shell=True)
output = result.stdout.strip()
start = output.find(f"{self.interface_name}:")
end = output.find("默认网关", start)
end = output.find("\n", end)
start = output.find("IPv4 地址")
result = output[start:end].strip()
pattern = r'IPv4.*?((?:\d+\.\d+\.\d+\.\d+))'
ips = re.findall(pattern, result, re.DOTALL)

gateway = result.split(':')[-1].strip()
subnet_mask = result.split('默认网关')[0].split(':')[-1].strip()
# 判断ip地址是否和网关在同一网段
# 使用子网掩码创建IPv4Network对象
network = ipaddress.ip_network(f'0.0.0.0/{subnet_mask}', strict=False)
# 获取前缀长度
prefix_length = network.prefixlen
network = ipaddress.ip_network(f'{gateway}/{prefix_length}', strict=False)

# 判断是否在同一网段,排序,在网关网段的IP地址,挪到最后
def ip_sort(ip):
if ipaddress.ip_address(ip) in network:
return 2
else:
return 1

ips.sort(key=ip_sort)
return ips

def remove_ip(self, ip_address):
"""移除指定的IP地址"""
command = f'netsh interface ip delete address "{self.interface_name}" {ip_address}'
subprocess.run(command, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

def add_ip(self, ip_address, subnet_mask):
"""添加新的IP地址"""
command = f'netsh interface ip add address "{self.interface_name}" {ip_address} {subnet_mask}'
subprocess.run(command, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

def remove_extra_ips(self):
"""移除多余的IP地址,只保留最后一个"""
ips = self.get_ips()
for ip in ips[:-1]: # 保留最后一个IP
self.remove_ip(ip)

def add_second_ip(self, new_ip, subnet_mask):
"""添加第二个IP地址:删除多余IP,然后添加新IP"""
self.remove_extra_ips()
self.add_ip(new_ip, subnet_mask)

def select_adapter(self):
"""选择以太网适配器"""
adapter_list = self.get_adapter_names()
# 打印适配器列表供用户选择
for i, adapter in enumerate(adapter_list, 1):
print(f"{i}. {adapter}")

# 请求用户输入并验证输入
choice = None
while choice not in range(1, len(adapter_list) + 1):
choice = input("请输入选择的网卡编号 (直接按回车默认选择第一个): ")
if choice == '': # 用户直接按回车
choice = 1
break
if choice.isdigit() and 1 <= int(choice) <= len(adapter_list):
break
print("输入错误,请确保输入的是1到", len(adapter_list), "之间的数字")

# 设置em的interface_name属性
self.interface_name = adapter_list[int(choice) - 1]

print(f"您选择的网卡为: {self.interface_name}")

if __name__ == '__main__':
em = EthernetManager()
em.select_adapter()
while True:
ip=input("请输入要添加的IP地址: ")
try:
ipaddress.ip_address(ip)
break
except:
print("输入的IP地址不合法,请重新输入")
while True:
subnet_mask=input("请输入子网掩码,回车默认255.255.255.0:")
if subnet_mask=="":
subnet_mask="255.255.255.0"
break
try:
ipaddress.IPv4Network(f"0.0.0.0/{subnet_mask}")
break
except:
print("输入的子网掩码不合法,请重新输入")
em.add_second_ip(ip, subnet_mask)
time.sleep(5)
if ip in em.get_ips():
print("添加成功")
else:
print("添加失败,请以管理员身份运行")

适用场景

当需要频繁更换第二IP地址时,可以用此脚本来实现。

  • 首先列出所有的网卡,供用户选择
  • 选择网卡后,如果该网卡已经有多个IP,那么只保留一个与默认网关同网段的IP,其余IP地址全部删除
  • 然后输入并添加第二个IP地址
  • 验证是否成功,不成功的原因基本上是因为没有以管理员权限运行

添加网卡第二IP
https://xinhaojin.github.io/2024/08/28/添加网卡第二IP/
作者
xinhaojin
发布于
2024年8月28日
许可协议