pcap-file: Add timestamp support for reading and writing pcap files.
authorBen Pfaff <blp@nicira.com>
Fri, 22 Nov 2013 19:42:06 +0000 (11:42 -0800)
committerBen Pfaff <blp@nicira.com>
Mon, 23 Dec 2013 18:33:01 +0000 (10:33 -0800)
Only the write support is initially useful, but an upcoming commit will add
a user for the read support.

Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/pcap-file.c
lib/pcap-file.h
tests/test-flows.c
utilities/ovs-ofctl.c

index 4ba4624..99dff23 100644 (file)
@@ -24,6 +24,7 @@
 #include "byte-order.h"
 #include "compiler.h"
 #include "ofpbuf.h"
+#include "timeval.h"
 #include "vlog.h"
 
 VLOG_DEFINE_THIS_MODULE(pcap);
@@ -128,12 +129,13 @@ pcap_write_header(FILE *file)
 }
 
 int
-pcap_read(FILE *file, struct ofpbuf **bufp)
+pcap_read(FILE *file, struct ofpbuf **bufp, long long int *when)
 {
     struct pcaprec_hdr prh;
     struct ofpbuf *buf;
     void *data;
     size_t len;
+    bool swap;
 
     *bufp = NULL;
 
@@ -151,15 +153,22 @@ pcap_read(FILE *file, struct ofpbuf **bufp)
 
     /* Calculate length. */
     len = prh.incl_len;
-    if (len > 0xffff) {
-        uint32_t swapped_len = uint32_byteswap(len);
-        if (swapped_len > 0xffff) {
-            VLOG_WARN("bad packet length %"PRIuSIZE" or %"PRIu32" "
+    swap = len > 0xffff;
+    if (swap) {
+        len = uint32_byteswap(len);
+        if (len > 0xffff) {
+            VLOG_WARN("bad packet length %"PRIuSIZE" or %"PRIu32
                       "reading pcap file",
-                      len, swapped_len);
+                      len, uint32_byteswap(len));
             return EPROTO;
         }
-        len = swapped_len;
+    }
+
+    /* Calculate time. */
+    if (when) {
+        uint32_t ts_sec = swap ? uint32_byteswap(prh.ts_sec) : prh.ts_sec;
+        uint32_t ts_usec = swap ? uint32_byteswap(prh.ts_usec) : prh.ts_usec;
+        *when = ts_sec * 1000LL + ts_usec / 1000;
     }
 
     /* Read packet. */
@@ -180,8 +189,11 @@ void
 pcap_write(FILE *file, struct ofpbuf *buf)
 {
     struct pcaprec_hdr prh;
-    prh.ts_sec = 0;
-    prh.ts_usec = 0;
+    struct timeval tv;
+
+    xgettimeofday(&tv);
+    prh.ts_sec = tv.tv_sec;
+    prh.ts_usec = tv.tv_usec;
     prh.incl_len = buf->size;
     prh.orig_len = buf->size;
     ignore(fwrite(&prh, sizeof prh, 1, file));
index 46625c3..7148b18 100644 (file)
@@ -24,7 +24,7 @@ struct ofpbuf;
 FILE *pcap_open(const char *file_name, const char *mode);
 int pcap_read_header(FILE *);
 void pcap_write_header(FILE *);
-int pcap_read(FILE *, struct ofpbuf **);
+int pcap_read(FILE *, struct ofpbuf **, long long int *when);
 void pcap_write(FILE *, struct ofpbuf *);
 
 #endif /* pcap-file.h */
index 6528b07..99a9e69 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -61,7 +61,7 @@ main(int argc OVS_UNUSED, char *argv[])
         union flow_in_port in_port_;
         n++;
 
-        retval = pcap_read(pcap, &packet);
+        retval = pcap_read(pcap, &packet, NULL);
         if (retval == EOF) {
             ovs_fatal(0, "unexpected end of file reading pcap file");
         } else if (retval) {
index c35e15b..2988fb6 100644 (file)
@@ -3122,7 +3122,7 @@ ofctl_parse_pcap(int argc OVS_UNUSED, char *argv[])
         struct flow flow;
         int error;
 
-        error = pcap_read(pcap, &packet);
+        error = pcap_read(pcap, &packet, NULL);
         if (error == EOF) {
             break;
         } else if (error) {