Revision 27919 added the ability to feed a libpcap-formatted file to
authorGerald Combs <gerald@wireshark.org>
Fri, 15 Oct 2010 16:05:06 +0000 (16:05 -0000)
committerGerald Combs <gerald@wireshark.org>
Fri, 15 Oct 2010 16:05:06 +0000 (16:05 -0000)
rawshark but broke the ability to feed it live packets with a
pcap_pkthdr prefix on some 64-bit architectures.

Add a "-p" flag which lets us explicitly handle file-based or
memory-based packet record headers.

svn path=/trunk/; revision=34522

doc/rawshark.pod
rawshark.c

index 1a3b9db210f735affd65dc1106c6a1584883341a..ab0e9ca5245dedcdc12d4136c41b2621b1794022 100644 (file)
@@ -13,6 +13,7 @@ S<[ B<-l> ]>
 S<[ B<-n> ]>
 S<[ B<-N> E<lt>name resolving flagsE<gt> ]>
 S<[ B<-o> E<lt>preference settingE<gt> ] ...>
+S<[ B<-p> ]>
 S<[ B<-r> E<lt>pipeE<gt>|- ]>
 S<[ B<-R> E<lt>read (display) filterE<gt> ]>
 S<[ B<-s> ]>
@@ -34,8 +35,9 @@ One or more B<-F> flags should be specified in order for the output to be
 useful. The other flags listed above follow the same conventions as
 B<Wireshark> and B<TShark>.
 
-B<Rawshark> expects input records with the following format. Note that this
-matches the pcap_pkthdr struct and packet data used in libpcap.
+B<Rawshark> expects input records with the following format by default. This
+matches the format of the packet header and packet data in a libpcap-formatted
+file on disk.
 
     struct rawshark_rec_s {
         uint32_t ts_sec;      /* Time stamp (seconds) */
@@ -45,6 +47,20 @@ matches the pcap_pkthdr struct and packet data used in libpcap.
         uint8_t data[caplen]; /* Packet data */
     };
 
+If B<-p> is supplied B<rawshark> expects the following format. This matches the
+pcap_pkthdr struct and packet data used in libpcap. Note that the time stamp
+value will match the previous format on some systems but not others.
+
+    struct rawshark_rec_s {
+        struct timeval ts;    /* Time stamp */
+        uint32_t caplen;      /* Length of the packet buffer */
+        uint32_t len;         /* "On the wire" length of the packet */
+        uint8_t *data;        /* Packet data */
+    };
+
+In either case, the endianness (byte ordering) of each integer must match the
+system on which B<rawshark> is running.
+
 =head1 OUTPUT
 
 If one or more fields are specified via the B<-F> flag, B<Rawshark> prints
@@ -156,6 +172,13 @@ form I<prefname>B<:>I<value>, where I<prefname> is the name of the
 preference (which is the same name that would appear in the preference
 file), and I<value> is the value to which it should be set.
 
+=item -p
+
+Assume that packet data is preceded by a pcap_pkthdr struct as defined in
+pcap.h. On some systems the size of the timestamp data will be different from
+the data written to disk. On other systems they are identical and this flag has
+no effect.
+
 =item -r  E<lt>pipeE<gt>|-
 
 Read packet data from I<input source>. It can be either the name of a FIFO
index f259ff44cca43b61c47bcb08d70d154b49b1cab2..a5fd3b9c27815532e3fbe721ef8cd03fd6f2005e 100644 (file)
@@ -140,6 +140,8 @@ typedef enum {
 static gboolean line_buffered;
 static print_format_e print_format = PR_FMT_TEXT;
 
+static gboolean want_pcap_pkthdr;
+
 cf_status_t raw_cf_open(capture_file *cf, const char *fname);
 static int load_cap_file(capture_file *cf);
 static gboolean process_packet(capture_file *cf, gint64 offset,
@@ -202,25 +204,26 @@ print_usage(gboolean print_ver)
 
     fprintf(output, "\n");
     fprintf(output, "Processing:\n");
-    fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
+    fprintf(output, "  -d <encap:dlt>|<proto:protoname>\n");
+    fprintf(output, "                           packet encapsulation or protocol\n");
     fprintf(output, "  -F <field>               field to display\n");
-    fprintf(output, "  -s                       skip PCAP header on input\n");
     fprintf(output, "  -n                       disable all name resolution (def: all enabled)\n");
     fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mntC\"\n");
-    fprintf(output, "  -d <encap:dlt>|<proto:protoname>\n");
-    fprintf(output, "                           packet encapsulation or protocol\n");
+    fprintf(output, "  -p                       use the system's packet header format (which may have 64-bit timestamps)\n");
+    fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
+    fprintf(output, "  -s                       skip PCAP header on input\n");
 
     /*fprintf(output, "\n");*/
     fprintf(output, "Output:\n");
+    fprintf(output, "  -l                       flush output after each packet\n");
     fprintf(output, "  -S                       format string for fields (%%D - name, %%S - stringval, %%N numval)\n");
     fprintf(output, "  -t ad|a|r|d|dd|e         output format of time stamps (def: r: rel. to first)\n");
-    fprintf(output, "  -l                       flush output after each packet\n");
 
     fprintf(output, "\n");
     fprintf(output, "Miscellaneous:\n");
     fprintf(output, "  -h                       display this help and exit\n");
-    fprintf(output, "  -v                       display version info and exit\n");
     fprintf(output, "  -o <name>:<value> ...    override preference setting\n");
+    fprintf(output, "  -v                       display version info and exit\n");
 }
 
 static void
@@ -446,7 +449,7 @@ main(int argc, char *argv[])
     guint                fc;
     gboolean             skip_pcap_header = FALSE;
 
-#define OPTSTRING_INIT "d:F:hlnN:o:r:R:sS:t:v"
+#define OPTSTRING_INIT "d:F:hlnN:o:pr:R:sS:t:v"
 
     static const char    optstring[] = OPTSTRING_INIT;
 
@@ -647,6 +650,9 @@ main(int argc, char *argv[])
                         break;
                 }
                 break;
+            case 'p':        /* Expect pcap_pkthdr packet headers, which may have 64-bit timestamps */
+                want_pcap_pkthdr = TRUE;
+                break;
             case 'r':        /* Read capture file xxx */
                 pipe_name = g_strdup(optarg);
                 break;
@@ -876,12 +882,18 @@ main(int argc, char *argv[])
  */
 static gboolean
 raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, const gchar **err_info, gint64 *data_offset) {
-    struct pcaprec_hdr hdr;
+    struct pcap_pkthdr mem_hdr;
+    struct pcaprec_hdr disk_hdr;
     int bytes_read = 0;
-    int bytes_needed = sizeof(struct pcaprec_hdr);
-    guchar *ptr = (guchar*)&hdr;
+    int bytes_needed = sizeof(disk_hdr);
+    guchar *ptr = (guchar*) &disk_hdr;
     static gchar err_str[100];
 
+    if (want_pcap_pkthdr) {
+        bytes_needed = sizeof(mem_hdr);
+        ptr = (guchar*) &mem_hdr;
+    }
+
     /* Copied from capture_loop.c */
     while (bytes_needed > 0) {
         bytes_read = read(fd, ptr, bytes_needed);
@@ -898,10 +910,18 @@ raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, const gchar **err
         ptr += bytes_read;
     }
 
-    phdr->ts.secs = hdr.ts_sec;
-    phdr->ts.nsecs = hdr.ts_usec * 1000;
-    phdr->caplen = bytes_needed = hdr.incl_len;
-    phdr->len = hdr.orig_len;
+    if (want_pcap_pkthdr) {
+        phdr->ts.secs = mem_hdr.ts.tv_sec;
+        phdr->ts.nsecs = mem_hdr.ts.tv_usec * 1000;
+        phdr->caplen = bytes_needed = mem_hdr.caplen;
+        phdr->len = mem_hdr.len;
+    } else {
+        phdr->ts.secs = disk_hdr.ts_sec;
+        phdr->ts.nsecs = disk_hdr.ts_usec * 1000;
+        phdr->caplen = bytes_needed = disk_hdr.incl_len;
+        phdr->len = disk_hdr.orig_len;
+    }
+
     phdr->pkt_encap = encap;
 
 #if 0