删掉默认之后
(每道题开头都有同一段:net_02 的 to_int / mask、判「前缀是否包含地址」的 contains,和本机的路由表 ROUTES——每行 (前缀, 下一跳或 None 表示直连, 接口, 度量)。)
本机的路由表:
0.0.0.0/0 via 192.168.10.1 eth0 100 ← 默认
192.168.10.0/24 直连 eth0 100
10.0.0.0/8 via 192.168.10.254 eth0 100 ← 机房
10.20.0.0/16 via 192.168.10.253 eth0 100 ← 机房里更具体的一段
127.0.0.0/8 直连 lo 0把默认路由那一行去掉,再对同样六个地址查表,看几个查不到(None):
def to_int(ip):
a, b, c, d = [int(x) for x in ip.split(".")]
return (a << 24) | (b << 16) | (c << 8) | d
def mask(prefix):
return (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF
def contains(cidr, ip):
net, p = cidr.split("/")
return to_int(net) & mask(int(p)) == to_int(ip) & mask(int(p))
ROUTES = [
("0.0.0.0/0", "192.168.10.1", "eth0", 100),
("192.168.10.0/24", None, "eth0", 100),
("10.0.0.0/8", "192.168.10.254", "eth0", 100),
("10.20.0.0/16", "192.168.10.253", "eth0", 100),
("127.0.0.0/8", None, "lo", 0),
]
def lookup(routes, ip):
best = None
for cidr, via, dev, metric in routes:
if not contains(cidr, ip):
continue
plen = int(cidr.split("/")[1])
if best is None or plen > best[0] or (plen == best[0] and metric < best[1]):
best = (plen, metric, cidr, via, dev)
return best
no_default = [r for r in ROUTES if r[0] != "0.0.0.0/0"]
ips = ("8.8.8.8", "1.1.1.1", "10.7.7.7", "192.168.11.5", "172.16.0.9", "192.168.10.1")
lost = [ip for ip in ips if lookup(no_default, ip) is None]
print(str(len(lost)) + "/" + ",".join(lost))
全部评论