Ticket #55: generate pcap traces for PlanetLab
authorClaudio-Daniel Freire <claudio-daniel.freire@inria.fr>
Tue, 12 Jul 2011 14:11:22 +0000 (16:11 +0200)
committerClaudio-Daniel Freire <claudio-daniel.freire@inria.fr>
Tue, 12 Jul 2011 14:11:22 +0000 (16:11 +0200)
src/nepi/testbeds/planetlab/metadata_v01.py
src/nepi/testbeds/planetlab/scripts/tun_connect.py
src/nepi/testbeds/planetlab/tunproto.py

index ceea03d..986265d 100644 (file)
@@ -333,7 +333,12 @@ def preconfigure_tuniface(testbed_instance, guid):
 
     # Set enabled traces
     traces = testbed_instance._get_traces(guid)
-    element.capture = 'packets' in traces
+    for capmode in ('pcap', 'packets'):
+        if capmode in traces:
+            element.capture = capmode
+            break
+    else:
+        element.capture = False
     
     # Do some validations
     element.validate()
@@ -934,6 +939,10 @@ traces = dict({
                 "name": "packets",
                 "help": "Detailled log of all packets going through the interface",
               }),
+    "pcap": dict({
+                "name": "pcap",
+                "help": "PCAP trace of all packets going through the interface",
+              }),
     })
 
 create_order = [ INTERNET, NODE, NODEIFACE, TAPIFACE, TUNIFACE, NETPIPE, NEPIDEPENDENCY, NS3DEPENDENCY, DEPENDENCY, APPLICATION ]
@@ -989,7 +998,7 @@ factories_info = dict({
                 "txqueuelen",
                 "tun_proto", "tun_addr", "tun_port", "tun_key"
             ],
-            "traces": ["packets"],
+            "traces": ["packets", "pcap"],
             "connector_types": ["node","udp","tcp","fd->"],
             "tags": [tags.INTERFACE, tags.ALLOW_ADDRESSES],
         }),
@@ -1005,7 +1014,7 @@ factories_info = dict({
                 "txqueuelen",
                 "tun_proto", "tun_addr", "tun_port", "tun_key"
             ],
-            "traces": ["packets"],
+            "traces": ["packets", "pcap"],
             "connector_types": ["node","udp","tcp","fd->"],
             "tags": [tags.INTERFACE, tags.ALLOW_ADDRESSES],
         }),
index af7126c..a23a3a8 100644 (file)
@@ -100,8 +100,13 @@ parser.add_option(
     "-N", "--no-capture", dest="no_capture", 
     action = "store_true",
     default = False,
-    help = "If specified, packets won't be logged to standard error "
-           "(default is to log them to standard error). " )
+    help = "If specified, packets won't be logged to standard output "
+           "(default is to log them to standard output). " )
+parser.add_option(
+    "-c", "--pcap-capture", dest="pcap_capture", metavar="FILE",
+    default = None,
+    help = "If specified, packets won't be logged to standard output, "
+           "but dumped to a pcap-formatted trace in the specified file. " )
 
 (options, remaining_args) = parser.parse_args(sys.argv[1:])
 
@@ -354,8 +359,7 @@ def tun_fwd(tun, remote):
         cipher_key = options.cipher_key,
         udp = options.udp,
         TERMINATE = TERMINATE,
-        stderr = open("/dev/null","w") if options.no_capture 
-                 else sys.stderr 
+        stderr = open("/dev/null","w")
     )
 
 
@@ -444,12 +448,6 @@ try:
             sock.connect(options.pass_fd)
         passfd.sendfd(sock, tun.fileno(), '0')
         
-        # Launch a tcpdump subprocess, to capture and dump packets,
-        # we will not be able to capture them ourselves.
-        # Make sure to catch sigterm and kill the tcpdump as well
-        tcpdump = subprocess.Popen(
-            ["tcpdump","-l","-n","-i",tun_name])
-        
         # just wait forever
         def tun_fwd(tun, remote):
             while not TERMINATE:
@@ -514,6 +512,13 @@ try:
             rsock,raddr = lsock.accept()
         remote = os.fdopen(rsock.fileno(), 'r+b', 0)
 
+    if not options.no_capture:
+        # Launch a tcpdump subprocess, to capture and dump packets.
+        # Make sure to catch sigterm and kill the tcpdump as well
+        tcpdump = subprocess.Popen(
+            ["tcpdump","-l","-n","-i",tun_name, "-s", "4096"]
+            + ["-w",options.pcap_capture,"-U"] * bool(options.pcap_capture) )
+    
     print >>sys.stderr, "Connected"
 
     tun_fwd(tun, remote)
index a80f5dd..2a3c954 100644 (file)
@@ -196,6 +196,8 @@ class TunProtoBase(object):
             args.extend(("-Q",str(local_txq)))
         if not local_cap:
             args.append("-N")
+        elif local_cap == 'pcap':
+            args.extend(('-c','pcap'))
         if extra_args:
             args.extend(map(str,extra_args))
         if not listen and check_proto != 'fd':
@@ -404,14 +406,24 @@ class TunProtoBase(object):
             time.sleep(interval)
             interval = min(30.0, interval * 1.1)
     
+    _TRACEMAP = {
+        # tracename : (remotename, localname)
+        'packets' : ('capture','capture'),
+        'pcap' : ('pcap','capture.pcap'),
+    }
+    
     def remote_trace_path(self, whichtrace):
-        if whichtrace != 'packets':
+        tracemap = self._TRACEMAP
+        
+        if whichtrace not in tracemap:
             return None
         
-        return os.path.join(self.home_path, 'capture')
+        return os.path.join(self.home_path, tracemap[whichtrace][1])
         
     def sync_trace(self, local_dir, whichtrace):
-        if whichtrace != 'packets':
+        tracemap = self._TRACEMAP
+        
+        if whichtrace not in tracemap:
             return None
         
         local = self.local()
@@ -419,7 +431,7 @@ class TunProtoBase(object):
         if not local:
             return None
         
-        local_path = os.path.join(local_dir, 'capture')
+        local_path = os.path.join(local_dir, tracemap[whichtrace][1])
         
         # create parent local folders
         if os.path.dirname(local_path):
@@ -434,7 +446,7 @@ class TunProtoBase(object):
         # sync files
         (out,err),proc = server.popen_scp(
             '%s@%s:%s' % (local.node.slicename, local.node.hostname, 
-                os.path.join(self.home_path, 'capture')),
+                os.path.join(self.home_path, tracemap[whichtrace][0])),
             local_path,
             port = None,
             agent = None,