ip route get 会说什么

👁️ 2 人浏览 💬 0 人评论 ❤️ 添加收藏

(每道题开头都有同一段:net_02 的 to_int / mask、判「前缀是否包含地址」的 contains,和本机的路由表 ROUTES——每行 (前缀, 下一跳或 None 表示直连, 接口, 度量)。)

ip route get 8.8.8.8 会打出「8.8.8.8 via 192.168.10.1 dev eth0」。用 lookup 模拟三个地址,紧凑打成「地址>下一跳>接口」(直连的下一跳打 -):

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

IPROUTE = """default via 192.168.10.1 dev eth0 proto static metric 100
10.0.0.0/8 via 192.168.10.254 dev eth0 metric 100
10.20.0.0/16 via 192.168.10.253 dev eth0 metric 100
192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.5"""

def parse_line(line):
    w = line.split()
    cidr = "0.0.0.0/0" if w[0] == "default" else w[0]
    via = w[w.index("via") + 1] if "via" in w else None
    dev = w[w.index("dev") + 1]
    metric = int(w[w.index("metric") + 1]) if "metric" in w else 0
    return (cidr, via, dev, metric)


def parse_table(text):
    return [parse_line(l) for l in text.strip().split("\n")]

t = parse_table(IPROUTE)
for ip in ("8.8.8.8", "10.20.5.5", "192.168.10.77"):
    r = lookup(t, ip)
    print(ip + ">" + (r[3] or "-") + ">" + r[4], end="|")
提交你的答案
请登录后提交答案。
去登录
代码编辑器
Ctrl + Enter 运行
本次输入:
输出:

                        
👩‍🏫
AI
💬 题目评论

全部评论