1 #!/usr/local/bin/python2.7
8 PAYLOAD_MAGIC = 0x42c0ffee
10 class Sniffer(threading.Thread):
11 def __init__(self, recvif):
12 threading.Thread.__init__(self)
19 self.packets = sp.sniff(iface=self._recvif, timeout=3)
21 def check_ping_request(packet, dst_ip, args):
23 return check_ping6_request(packet, dst_ip, args)
25 return check_ping4_request(packet, dst_ip, args)
27 def check_ping4_request(packet, dst_ip, args):
29 Verify that the packet matches what we'd have sent
31 ip = packet.getlayer(sp.IP)
37 icmp = packet.getlayer(sp.ICMP)
40 if sp.icmptypes[icmp.type] != 'echo-request':
43 raw = packet.getlayer(sp.Raw)
46 if raw.load != str(PAYLOAD_MAGIC):
49 # Wait to check expectations until we've established this is the packet we
52 if ip.tos != int(args.expect_tos[0]):
53 print "Unexpected ToS value %d, expected %s" \
54 % (ip.tos, args.expect_tos[0])
60 def check_ping6_request(packet, dst_ip, args):
62 Verify that the packet matches what we'd have sent
64 ip = packet.getlayer(sp.IPv6)
70 icmp = packet.getlayer(sp.ICMPv6EchoRequest)
73 if icmp.data != str(PAYLOAD_MAGIC):
78 def ping(send_if, dst_ip, args):
80 ip = sp.IP(dst=dst_ip)
81 icmp = sp.ICMP(type='echo-request')
82 raw = sp.Raw(str(PAYLOAD_MAGIC))
85 ip.tos = int(args.send_tos[0])
87 req = ether / ip / icmp / raw
88 sp.sendp(req, iface=send_if, verbose=False)
90 def ping6(send_if, dst_ip, args):
92 ip6 = sp.IPv6(dst=dst_ip)
93 icmp = sp.ICMPv6EchoRequest(data=PAYLOAD_MAGIC)
95 req = ether / ip6 / icmp
96 sp.sendp(req, iface=send_if, verbose=False)
99 parser = argparse.ArgumentParser("pft_ping.py",
100 description="Ping test tool")
101 parser.add_argument('--sendif', nargs=1,
103 help='The interface through which the packet(s) will be sent')
104 parser.add_argument('--recvif', nargs=1,
105 help='The interface on which to expect the ICMP echo response')
106 parser.add_argument('--ip6', action='store_true',
108 parser.add_argument('--to', nargs=1,
110 help='The destination IP address for the ICMP echo request')
113 parser.add_argument('--send-tos', nargs=1,
114 help='Set the ToS value for the transmitted packet')
117 parser.add_argument('--expect-tos', nargs=1,
118 help='The expected ToS value in the received packet')
120 args = parser.parse_args()
122 # We may not have a default route. Tell scapy where to start looking for routes
123 sp.conf.iface6 = args.sendif[0]
126 if not args.recvif is None:
127 sniffer = Sniffer(args.recvif[0])
130 ping6(args.sendif[0], args.to[0], args)
132 ping(args.sendif[0], args.to[0], args)
137 for packet in sniffer.packets:
138 if check_ping_request(packet, args.to[0], args):
141 # We did not get the packet we expected
144 if __name__ == '__main__':