git » redes-tp2.git » commit 40c612d

Implementar ping, estimate_rtt y traceroute

author Rodrigo Campos
2012-10-14 00:52:40 UTC
committer Rodrigo Campos
2012-10-14 00:55:40 UTC
parent 30c08aa28a4901f97d46e5ba5d4d4128f9a65d9e

Implementar ping, estimate_rtt y traceroute

Este commit implementa un simple ping, una forma de estimar el RTT
basado en el ping ya implementado y un ICMP traceroute usando el campo
TTL del ping ya implementado tambien.

1a.py +21 -0
1b.py +21 -0
myping.py +68 -0
traceroute.py +23 -0

diff --git a/1a.py b/1a.py
new file mode 100755
index 0000000..46ef5d2
--- /dev/null
+++ b/1a.py
@@ -0,0 +1,21 @@
+#! /usr/bin/env python
+
+import sys
+from myping import ping
+
+
+if __name__ == '__main__':
+
+    if len(sys.argv) < 2:
+        print "Usage:", sys.argv[0], "<destination>"
+        sys.exit(1)
+
+    dst = sys.argv[1]
+
+    p = ping(dst, "test")
+
+    if p:
+        p.show()
+    else:
+        print "Ping timeout or some other error!"
+
diff --git a/1b.py b/1b.py
new file mode 100755
index 0000000..ff1033f
--- /dev/null
+++ b/1b.py
@@ -0,0 +1,21 @@
+#! /usr/bin/env python
+
+import sys
+from myping import estimate_rtt
+
+
+if __name__ == '__main__':
+
+    if len(sys.argv) < 2:
+        print "Usage:", sys.argv[0], "<destination> [count]"
+        sys.exit(1)
+
+    dst = sys.argv[1]
+
+    count = 10
+    if len(sys.argv) >= 3:
+        count = int(sys.argv[2])
+
+    rtt = estimate_rtt(dst, count)
+
+    print "El rtt es:", rtt
diff --git a/myping.py b/myping.py
new file mode 100755
index 0000000..9ab39e9
--- /dev/null
+++ b/myping.py
@@ -0,0 +1,68 @@
+#! /usr/bin/env python
+
+import sys
+import time
+from scapy.all import sr1,IP,ICMP, RandShort
+
+
+def ping(dst, payload, seq=1, ttl=64, timeout=5):
+    """Makes 1 ICMP echo request to dst.
+    @returns: the response in an object that accepts method show(), None on
+    timeout
+    """
+
+    pkt = IP(dst=dst, ttl=ttl) / ICMP(seq=seq, id=RandShort()) / payload
+    pkt = sr1(pkt, timeout=timeout)
+
+    return pkt
+
+
+def estimate_rtt(dst, pkts = 10):
+    """Estimates RTT sending pkts pings to dst.
+    @returns rtt (ms)
+    """
+
+    t1 = time.time()
+
+    for i in range(0, pkts):
+
+        # Use the loop iteration as payload, just to put something
+        ping(dst, payload=str(i), seq=i)
+
+    t2 = time.time()
+
+    # RTT is the time elapsed in average
+    rtt = (t2 - t1) / float(pkts) * 1000
+
+    return rtt
+
+
+def traceroute(dst, maxhops=30):
+
+    hops=[]
+    last_hop = None
+
+    # We don't want to use 0 as TTL, so we start at 1 and go to maxhops
+    # inclusive
+    for ttl in range(1, maxhops + 1):
+
+        pkt = ping(dst, payload='test', ttl=ttl)
+
+        # check if a response arrive. If not, use "*" as hop
+        hop = "*"
+        if pkt:
+            hop = pkt.src
+
+        # If we know which hop is this, and is the same as the last one, there
+        # is no point to keep sending ICMPs with more TTL. No other hop will be
+        # added
+        # We check against last_hop IP and not if "hop == dst", because dst
+        # could be a FQDN
+        if hop != "*" and hop == last_hop:
+            break
+
+        hops.append(hop)
+        last_hop = hop
+        #time.sleep(1)
+
+    return hops
diff --git a/traceroute.py b/traceroute.py
new file mode 100755
index 0000000..d9683b7
--- /dev/null
+++ b/traceroute.py
@@ -0,0 +1,23 @@
+#! /usr/bin/env python
+
+import sys
+from myping import traceroute
+
+
+if __name__ == '__main__':
+
+    if len(sys.argv) < 2:
+        print "Usage:", sys.argv[0], "<destination> [maxhops]"
+        sys.exit(1)
+
+    dst = sys.argv[1]
+
+    maxhops = 30
+    if len(sys.argv) >= 3:
+        maxhops = int(sys.argv[2])
+
+    hops = traceroute(dst, maxhops)
+
+    for index, hop in enumerate(hops, 1):
+
+        print "Hop", index, ":", hop