Support for time stamping packets in text2pcap, from Gordon McKinney.

svn path=/trunk/; revision=4252
This commit is contained in:
Guy Harris 2001-11-24 08:14:12 +00:00
parent 73fc903278
commit c871a24514
5 changed files with 171 additions and 10 deletions

View File

@ -850,6 +850,7 @@ Marc Milgram <mmilgram[AT]arrayinc.com> {
Gordon McKinney <gordon[AT]night-ray.com> {
Enhanced Ethereal icon for Windows
Support for time stamping packets in text2pcap
}
Pavel Novotny <Pavel.Novotny[AT]icn.siemens.de> {

View File

@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
# $Id: Makefile.am,v 1.383 2001/11/22 03:07:05 hagbard Exp $
# $Id: Makefile.am,v 1.384 2001/11/24 08:14:10 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@ -640,9 +640,16 @@ tethereal_static_LDADD = \
tethereal_LDFLAGS = -export-dynamic
tethereal_static_LDFLAGS = -Wl,-static
# Optional objects that I know how to build, and that are needed by
# text2pcap.
text2pcap_optional_objects = @STRERROR_O@ @STRPTIME_O@
text2pcap_SOURCES = text2pcap.c text2pcap-scanner.l
text2pcap_DEPENDENCIES = text2pcap.h
# This automake variable adds to the link-line for the executable
text2pcap_LDADD = $(text2pcap_optional_objects)
mergecap_SOURCES = mergecap.c
mergecap_DEPENDENCIES = wiretap/libwiretap.a

View File

@ -1,7 +1,7 @@
## Makefile for building ethereal.exe with Microsoft C and nmake
## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake
#
# $Id: Makefile.nmake,v 1.143 2001/11/21 02:08:57 guy Exp $
# $Id: Makefile.nmake,v 1.144 2001/11/24 08:14:10 guy Exp $
include config.nmake
include <win32.mak>
@ -350,7 +350,7 @@ mergecap.exe : config.h mergecap.obj getopt.obj wiretap\wiretap-$(WTAP_VERSION).
/OUT:mergecap.exe $(conflags) $(conlibsdll) $(LDFLAGS) /SUBSYSTEM:console mergecap.obj getopt.obj $(mergecap_LIBS) image\mergecap.res
<<
text2pcap.exe : config.h text2pcap.obj text2pcap-scanner.obj getopt.obj image\text2pcap.res
text2pcap.exe : config.h text2pcap.obj text2pcap-scanner.obj getopt.obj strptime.obj image\text2pcap.res
@echo Linking $@
$(LINK) @<<
/OUT:text2pcap.exe $(conflags) $(conlibsdll) $(LDFLAGS) /SUBSYSTEM:console text2pcap.obj text2pcap-scanner.obj getopt.obj image\text2pcap.res

View File

@ -13,6 +13,7 @@ S<[ B<-l> typenum ]>
S<[ B<-e> l3pid ]>
S<[ B<-i> proto ]>
S<[ B<-u> srcport,destport ]>
S<[ B<-t> timefmt ]>
I<infile>
I<outfile>
@ -132,6 +133,15 @@ IP or Ethernet headers. Note that this automatically includes
appropriate Ethernet and IP headers with each packet. Example: I<-u
1000,69> to make the packets look like TFTP/UDP packets.
=item -t timefmt
Treats the text before the packet as a date/time code; I<timevmt> is a
format string of the sort supported by L<strptime(3)>.
Example: The time "10:15:14.5476" has the format code "%H:%M:%S."
B<NOTE:> The subsecond component delimiter must be specified (.) but no
pattern is required; the remaining number is assumed to be fractions of
a second.
=head1 SEE ALSO

View File

@ -6,7 +6,7 @@
*
* (c) Copyright 2001 Ashok Narayanan <ashokn@cisco.com>
*
* $Id: text2pcap.c,v 1.6 2001/11/24 07:55:07 guy Exp $
* $Id: text2pcap.c,v 1.7 2001/11/24 08:14:10 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -81,9 +81,11 @@
# include "config.h"
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
@ -101,6 +103,10 @@
# include "getopt.h"
#endif
#ifdef NEED_STRPTIME_H
# include "strptime.h"
#endif
#ifndef TRUE
#define TRUE 1
#endif
@ -135,13 +141,23 @@ unsigned long hdr_udp_src = 0;
/* This is where we store the packet currently being built */
#define MAX_PACKET 64000
unsigned char packet_buf[MAX_PACKET];
unsigned char packet_buf[MAX_PACKET];
unsigned long curr_offset = 0;
/* This buffer contains strings present before the packet offset 0 */
#define PACKET_PREAMBLE_MAX_LEN 2048
static unsigned char packet_preamble[PACKET_PREAMBLE_MAX_LEN+1];
static int packet_preamble_len = 0;
/* Number of packets read and written */
unsigned long num_packets_read = 0;
unsigned long num_packets_written = 0;
/* Time code of packet, derived from packet_preamble */
static unsigned long ts_sec = 0;
static unsigned long ts_usec = 0;
static char *ts_fmt = NULL;
/* Input file */
char *input_filename;
FILE *input_file = NULL;
@ -344,8 +360,8 @@ write_current_packet (void)
}
/* Write PCap header */
ph.ts_sec = num_packets_written;
ph.ts_usec = num_packets_written;
ph.ts_sec = ts_sec;
ph.ts_usec = ts_usec;
ph.incl_len = length;
ph.orig_len = length;
fwrite(&ph, sizeof(ph), 1, output_file);
@ -409,6 +425,116 @@ write_file_header (void)
fwrite(&fh, sizeof(fh), 1, output_file);
}
/*----------------------------------------------------------------------
* Append a token to the packet preamble.
*/
static void
append_to_preamble(char *str)
{
size_t toklen;
if (packet_preamble_len != 0) {
if (packet_preamble_len == PACKET_PREAMBLE_MAX_LEN)
return; /* no room to add more preamble */
/* Add a blank separator between the previous token and this token. */
packet_preamble[packet_preamble_len++] = ' ';
}
toklen = strlen(str);
if (toklen != 0) {
if (packet_preamble_len + toklen > PACKET_PREAMBLE_MAX_LEN)
return; /* no room to add the token to the preamble */
strcpy(&packet_preamble[packet_preamble_len], str);
packet_preamble_len += toklen;
}
}
/*----------------------------------------------------------------------
* Parse the preamble to get the timecode.
*/
static void
parse_preamble (void)
{
struct tm timecode;
char *subsecs;
char *p;
int subseclen;
int i;
/*
* If no "-t" flag was specified, don't attempt to parse a packet
* preamble to extract a time stamp.
*/
if (ts_fmt == NULL)
return;
ts_sec = 0;
ts_usec = 0;
/*
* Null-terminate the preamble.
*/
packet_preamble[packet_preamble_len] = '\0';
/* Ensure preamble has more than two chars before atempting to parse.
* This should cover line breaks etc that get counted.
*/
if ( strlen(packet_preamble) > 2 ) {
memset(&timecode, '\0', sizeof timecode);
/* Get Time leaving subseconds */
subsecs = strptime( packet_preamble, ts_fmt, &timecode );
if (subsecs != NULL) {
/* Get the long time from the tm structure */
ts_sec = (unsigned long)mktime( &timecode );
} else
ts_sec = -1; /* we failed to parse it */
/* This will ensure incorrectly parsed dates get set to zero */
if ( -1L == (long)ts_sec )
{
ts_sec = 0;
ts_usec = 0;
}
else
{
/* Parse subseconds */
ts_usec = strtol(subsecs, &p, 10);
if (subsecs == p) {
/* Error */
ts_usec = 0;
} else {
/*
* Convert that number to a number
* of microseconds; if it's N digits
* long, it's in units of 10^(-N) seconds,
* so, to convert it to units of
* 10^-6 seconds, we multiply by
* 10^(6-N).
*/
subseclen = p - subsecs;
if (subseclen > 6) {
/*
* *More* than 6 digits; 6-N is
* negative, so we divide by
* 10^(N-6).
*/
for (i = subseclen - 6; i != 0; i--)
ts_usec /= 10;
} else if (subseclen < 6) {
for (i = 6 - subseclen; i != 0; i--)
ts_usec *= 10;
}
}
}
}
/*printf("Format(%s), time(%u), subsecs(%u)\n\n", ts_fmt, ts_sec, ts_usec);*/
/* Clear Preamble */
packet_preamble_len = 0;
}
/*----------------------------------------------------------------------
* Start a new packet
*/
@ -422,6 +548,9 @@ start_new_packet (void)
write_current_packet();
curr_offset = 0;
num_packets_read ++;
/* Ensure we parse the packet preamble as it may contain the time */
parse_preamble();
}
/*----------------------------------------------------------------------
@ -462,6 +591,9 @@ parse_token (token_t token, char *str)
/* ----- Waiting for new packet -------------------------------------------*/
case INIT:
switch(token) {
case T_TEXT:
append_to_preamble(str);
break;
case T_DIRECTIVE:
process_directive(str);
break;
@ -481,6 +613,9 @@ parse_token (token_t token, char *str)
/* ----- Processing packet, start of new line -----------------------------*/
case START_OF_LINE:
switch(token) {
case T_TEXT:
append_to_preamble(str);
break;
case T_DIRECTIVE:
process_directive(str);
break;
@ -590,7 +725,7 @@ help (char *progname)
fprintf(stderr,
"\n"
"Usage: %s [-d] [-q] [-o h|o] [-l typenum] [-e l3pid] [-i proto] \n"
" [-u srcp destp] <input-filename> <output-filename>\n"
" [-u srcp destp] [-t timefmt] <input-filename> <output-filename>\n"
"\n"
"where <input-filename> specifies input filename (use - for standard input)\n"
" <output-filename> specifies output filename (use - for standard output)\n"
@ -610,7 +745,11 @@ help (char *progname)
" Automatically prepends Ethernet header as well. Example: -i 46\n"
" -u srcp destp: Prepend dummy UDP header with specified dest and source ports (in DECIMAL).\n"
" Automatically prepends Ethernet and IP headers as well\n"
" Example: -u 30 40"
" Example: -u 30 40\n"
" -t timefmt : Treats the text before the packet as a time code parsed by strptime format patterns.\n"
" Example: The time \"10:15:14.5476\" has the format code \"%%H:%%M:%%S.\"\n"
" NOTE: The subsecond component delimiter must be specified (.) but no\n"
" pattern is required; the remaining number is assumed to be subseconds."
"\n",
progname);
@ -627,7 +766,7 @@ parse_options (int argc, char *argv[])
char *p;
/* Scan CLI parameters */
while ((c = getopt(argc, argv, "dqr:w:e:i:l:o:u:")) != -1) {
while ((c = getopt(argc, argv, "dqr:w:e:i:l:o:u:t:")) != -1) {
switch(c) {
case '?': help(argv[0]); break;
case 'h': help(argv[0]); break;
@ -658,6 +797,10 @@ parse_options (int argc, char *argv[])
hdr_ethernet = TRUE;
hdr_ethernet_proto = 0x800;
break;
case 't':
ts_fmt = optarg;
break;
case 'u':
hdr_udp = TRUE;