zoukankan      html  css  js  c++  java
  • 07python实现traceroute程序

    # 这个脚本是实现Linux中traceroute程序的,是探测从我们这个机器到我们要探测的IP地址中间都需要经过那些路由。
    # 原理:我们的机器发送UDP高端口的数据包,发送给目的地址,首先设置ttl为1,然后逐次增加,在没有到达我们的目的IP
    # 地址的路由,会发送ICMP的超时报文,然后我们从中提取IP地址,因为我们发送的是高端口的报文,到达目的地址的时候,
    # 目的地址会发送ICMP的端口不可达报文,这样我们就探测出从我们源端口到目的端口的路由。
    from scapy.all import *
    import struct,re,random

    # 跟我们实现ping程序的想法是一样的,首先构造一个发送一个UDP报文的函数,
    # 入参为目的地址,ttl数。
    def traceroute_one(dst,ttl_no,dport):
    # 定义发包时间。
    send_time = time.time()
    try:
    # 发送一个包,接收一个包。
    traceroute_one_reply = sr1(IP(dst=dst, ttl=ttl_no) / UDP(dport=dport) / b'hello world', timeout=1,
    verbose=False)
    # 判断ICMP包是不是超时回答。
    if traceroute_one_reply.getlayer(ICMP).type == 11 and traceroute_one_reply.getlayer(ICMP).code == 0:
    # 提取源地址
    src_ip = traceroute_one_reply.getlayer(IP).src
    # 定义接收时间。
    recv_time = time.time()
    # 计算时间ms数
    mid_time = (recv_time - send_time) * 1000
    # 返回。
    return 1,src_ip,mid_time
    # 这里接接收的是最后一跳。ICMP应该是端口不可达。
    elif traceroute_one_reply.getlayer(ICMP).type == 3 and traceroute_one_reply.getlayer(ICMP).code == 3:
    # 下边处理是一样的。
    src_ip = traceroute_one_reply.getlayer(IP).src
    recv_time = time.time()
    mid_time = (recv_time - send_time) * 1000
    return 2, src_ip, mid_time
    except Exception as e:
    return None


    def traceroute(dst,hops):
    # 目的端口从33434开始算起,入参为目的地址,我们想要查找的路由的条数。
    dport = 33434
    hop = 0
    # 进行循环包。
    while hop < hops:
    hop += 1
    # 这里需要改变端口。
    dport += hop
    # 发送一个包,获取返回值。
    traceroute_result = traceroute_one(dst,hop,dport)
    # 如果出现了错误,打印*号。
    if traceroute_result == None:
    print('*')
    # 这里代表中间路由,我们进行打印信息。
    elif traceroute_result[0] == 1:
    print("%d %s %4.2fms" % (hop,traceroute_result[1],traceroute_result[2]))
    # 最后一个包,为端口不可达,打印信息后,需要退出循环,因为已经到达目的地址了,虽然可能没有达到我们定义的条数。
    elif traceroute_result[0] == 2:
    print("%d %s %4.2fms" % (hop, traceroute_result[1], traceroute_result[2]))
    break
    time.sleep(1)
    if __name__ == "__main__":
    traceroute('180.101.49.12',10)
    # 接下来我们就可以使用wirshark进行抓包来看一下。

  • 相关阅读:
    010 --- 第14章 观察者模式
    009 --- 第13章 建造者模式
    008 --- 第12章 外观模式
    007 --- 第10章 模板方法模式
    006 --- 第9章 原型模式
    redis lua 中keys[1] 和argv[1] 的理解
    redis 入门总结
    mysql 8.0 特性简单总结
    MySql事务隔离级别 浅见
    浅谈Java中的String、StringBuffer、StringBuilder
  • 原文地址:https://www.cnblogs.com/cong12586/p/14203408.html
Copyright © 2011-2022 走看看