python常用网络获取信息函数
引用的库:需要额外安装的IPy netifaces scapy
。
from platform import system
import IPy
import netifaces
from scapy.all import *
from scapy.layers.inet import IP, ICMP
from scapy.layers.l2 import Ether, ARP
可能会有点小问题,如果有就自己改改吧。。有的话也记得
给定一个ip地址获取本机和该ip通信的优先级最高的网卡,linux下返回网卡名字符串,windows返回网卡对象
def get_iface_by_ip(ip):
pkt = IP(dst=ip)
return pkt.route()[0]
给定网卡对象获取ipv6的网卡索引index
def get_ipv6_ifindex(iface):
if system() == "Windows":
return int(netifaces.ifaddresses(iface.guid)[socket.AF_INET6][-1]["broadcast"].split("%")[-1])
elif system() == "Linux" or "Darwin":
return int(netifaces.ifaddresses(iface)[socket.AF_INET6][-1]["broadcast"].split("%")[-1])
else:
return int(netifaces.ifaddresses(iface)[socket.AF_INET6][-1]["broadcast"].split("%")[-1])
给定ip地址获取对应的mac地址,该函数无法保证每次都可以获取到,建议也可以使用getmac这个库
def get_mac_by_ip_arp(ip):
def start():
arp_ask = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=ip)
sendp(arp_ask, verbose=False)
iface = get_iface_by_ip(ip)
local_mac = get_if_hwaddr(iface)
filter_arp = "arp and ether dst " + local_mac
ans = sniff(filter=filter_arp, timeout=7, store=lambda pkt: pkt[ARP].psrc == ip and pkt[ARP].op == 2,
started_callback=start, stop_filter=lambda pkt: pkt[ARP].psrc == ip, iface=iface)
if len(ans) > 0:
return ans[0][ARP].hwsrc
else:
return None
获取网卡的第一个ipv4地址
update 20.12.11:支持网卡存在多个ip的情况
# 从网卡配置的多个ip选择正确的ip
def select_ip(ips, ip):
avaliable = []
for index in range(len(ips)):
subnet = IPy.IP(ips[index]["addr"]).make_net(ips[index]["netmask"])
if ip in subnet:
avaliable.append([index, subnet.prefixlen()])
sorted_ips = sorted(avaliable, key=lambda x: x[1], reverse=False)
if len(sorted_ips) >0 :
return ips[sorted_ips[0][0]]
else:
return None
def get_iface_ipv4(iface, ip):
if system() == "Windows":
right_ip = select_ip(netifaces.ifaddresses(iface.guid)[netifaces.AF_INET], ip)
return right_ip["addr"]
elif system() == "Linux" or "Darwin":
right_ip = select_ip(netifaces.ifaddresses(iface)[netifaces.AF_INET], ip)
return right_ip["addr"]
else:
right_ip = select_ip(netifaces.ifaddresses(iface)[netifaces.AF_INET], ip)
return right_ip["addr"]
获取网卡的第一个ipv6地址
def get_iface_ipv6(iface):
if system() == "Windows":
return netifaces.ifaddresses(iface.guid)[netifaces.AF_INET6][0]["addr"]
elif system() == "Linux" or "Darwin":
return netifaces.ifaddresses(iface)[netifaces.AF_INET6][0]["addr"]
else:
return netifaces.ifaddresses(iface)[netifaces.AF_INET6][0]["addr"]
获取网卡ipv4广播地址
def get_iface_broadcast(iface):
iface_ipv4 = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]["addr"]
iface_ipv4_mask = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]["netmask"]
ips = IPy.IP(iface_ipv4).make_net(iface_ipv4_mask)
return ips.broadcast().strNormal()
通过名字获取网卡
def get_iface(name):
if system() == "Windows":
for _ in IFACES.data:
if IFACES.data[_].name == name:
print("Inteface name: \t" + str(IFACES.data[_].name))
print("Adapter name: \t" + str(IFACES.data[_].description))
return _, IFACES.data[_]
return None, None
elif system() == "Linux" or system() == "Darwin":
if name in get_if_list():
print("Inteface name: \t" + name)
return name, name
else:
return None, None
else:
return None, None
检查tcp端口是否可用
def check_tcp_available(ip, port, timeout=25):
time_start = time.time()
while True:
time.sleep(1)
if time.time() - time_start > timeout:
return False
try:
s = socket.socket()
s.settimeout(1)
s.connect((ip, port))
s.close()
return True
except:
pass
检查目标网络是否可达
def check_network_available(ip, timeout=60):
time_start = time.time()
while True:
time.sleep(1)
if time.time() - time_start > timeout:
return False
try:
ping_pkt = IP(dst=ip, ttl=20) / ICMP()
count = 10
ans, _ = sr(ping_pkt*count, timeout=0.5, inter=0.2, verbose=False)
print("Check...")
if len(ans) / count > 0.5:
print("Network available")
return True
except:
pass
在网卡没有配置网关的情况下,获取虚假网关
其实就是网络号后面的第一个ip地址
def get_fake_gateway(ip, mask):
network_num = IPy.IP(ip).make_net(mask)[0]
network_seq = network_num.strNormal()
network_list = network_seq.split(".")
network_list[-1] = str(int(network_list[-1]) + 1)
gateway_fake = ".".join(network_list)
return gateway_fake
通过ip获取对应网卡信息
def get_netiface_info_by_ip(ip):
pkt = IP(dst=ip)/ICMP()
iface = pkt.route()[0]
if system() == "Windows":
iface_name = iface.name
iface_mac = get_if_hwaddr(iface)
iface_ipv4 = netifaces.ifaddresses(iface.guid)[netifaces.AF_INET][0]["addr"]
iface_ipv4_mask = netifaces.ifaddresses(iface.guid)[netifaces.AF_INET][0]["netmask"]
iface_ipv4_gateway = None
if netifaces.AF_INET in netifaces.gateways():
for each_item in netifaces.gateways()[netifaces.AF_INET]:
if iface in each_item:
iface_ipv4_gateway = each_item[0]
break
if not iface_ipv4_gateway:
iface_ipv4_gateway = get_fake_gateway(iface_ipv4, iface_ipv4_mask)
# print(f"Name:\t{iface_name}\n"
# f"MAC:\t{iface_mac}\n"
# f"IPv4:\t{iface_ipv4}\n"
# f"IPv4_Mask:\t{iface_ipv4_mask}\n"
# f"IPv4_Gateway:\t{iface_ipv4_gateway}\n")
return iface, iface_mac, iface_ipv4, iface_ipv4_mask, iface_ipv4_gateway
elif system() == "Linux" or "Darwin":
iface_name = iface
iface_mac = get_if_hwaddr(iface)
iface_ipv4 = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]["addr"]
iface_ipv4_mask = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]["netmask"]
iface_ipv4_gateway = None
if netifaces.AF_INET in netifaces.gateways():
for each_item in netifaces.gateways()[netifaces.AF_INET]:
if iface in each_item:
iface_ipv4_gateway = each_item[0]
break
if not iface_ipv4_gateway:
iface_ipv4_gateway = get_fake_gateway(iface_ipv4, iface_ipv4_mask)
# print(f"Name:\t{iface_name}\n"
# f"MAC:\t{iface_mac}\n"
# f"IPv4:\t{iface_ipv4}\n"
# f"IPv4_Mask:\t{iface_ipv4_mask}\n"
# f"IPv4_Gateway:\t{iface_ipv4_gateway}\n")
return iface, iface_mac, iface_ipv4, iface_ipv4_mask, iface_ipv4_gateway
else:
print("Not support")