summaryrefslogtreecommitdiff
path: root/savefile.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2013-07-01 12:41:36 -0700
committerGuy Harris <guy@alum.mit.edu>2013-07-01 12:41:36 -0700
commit9b4ac1a5da2f6c887c1e1c8f65549ca77ca00678 (patch)
tree92231acb792a70c48e9f5ecc999a42068cffe792 /savefile.c
parent3e9963fef588935e16e81fda522a9bd521ff8698 (diff)
downloadlibpcap-9b4ac1a5da2f6c887c1e1c8f65549ca77ca00678.tar.gz
Replace the _nsectime routines with _with_tstamp_precision routines.
For opening savefiles, instead of having separate open_offline and open_offline_nsectime routines, have open_offline_with_tstamp_precision routies that take an additional PCAP_TSTAMP_PRECISION_xxx argument, and make the open_offline routines wrappers around them requesting microsecond precision. Also, the timestamp precisions are a separate "namespace" from the timestamp types, so give them their own numerical value set, starting at 0 for microsecond precision. For pcap files, figure out up front whether we pass the time stamps through, scale them up, or scale them down, and save that with the private data and just use it when reading the capture file; that's less work than determining that for every packet.
Diffstat (limited to 'savefile.c')
-rw-r--r--savefile.c209
1 files changed, 51 insertions, 158 deletions
diff --git a/savefile.c b/savefile.c
index 7cabba89..79077117 100644
--- a/savefile.c
+++ b/savefile.c
@@ -170,12 +170,15 @@ sf_cleanup(pcap_t *p)
pcap_freecode(&p->fcode);
}
-static FILE *
-sf_open(const char *fname)
+pcap_t *
+pcap_open_offline_with_tstamp_precision(const char *fname, u_int precision,
+ char *errbuf)
{
- FILE *fp = NULL;
+ FILE *fp;
+ pcap_t *p;
- if (fname[0] == '-' && fname[1] == '\0') {
+ if (fname[0] == '-' && fname[1] == '\0')
+ {
fp = stdin;
#if defined(WIN32) || defined(MSDOS)
/*
@@ -184,78 +187,37 @@ sf_open(const char *fname)
*/
SET_BINMODE(fp);
#endif
- } else {
+ }
+ else {
#if !defined(WIN32) && !defined(MSDOS)
fp = fopen(fname, "r");
#else
fp = fopen(fname, "rb");
#endif
+ if (fp == NULL) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
+ pcap_strerror(errno));
+ return (NULL);
+ }
}
-
- return fp;
-}
-
-static void
-pcap_open_offline_set_common_properties(pcap_t *p)
-{
- p->read_op = pcap_offline_read;
- p->inject_op = sf_inject;
- p->setfilter_op = install_bpf_program;
- p->setdirection_op = sf_setdirection;
- p->set_datalink_op = NULL; /* we don't support munging link-layer headers */
- p->getnonblock_op = sf_getnonblock;
- p->setnonblock_op = sf_setnonblock;
- p->stats_op = sf_stats;
-#ifdef WIN32
- p->setbuff_op = sf_setbuff;
- p->setmode_op = sf_setmode;
- p->setmintocopy_op = sf_setmintocopy;
-#endif
- p->cleanup_op = sf_cleanup;
- p->activated = 1;
-}
-
-pcap_t *
-pcap_open_offline(const char *fname, char *errbuf)
-{
- FILE *fp;
- pcap_t *p;
-
- fp = sf_open(fname);
- if (!fp) {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, pcap_strerror(errno));
- return NULL;
+ p = pcap_fopen_offline_with_tstamp_precision(fp, precision, errbuf);
+ if (p == NULL) {
+ if (fp != stdin)
+ fclose(fp);
}
-
- p = pcap_fopen_offline(fp, errbuf);
- if (!p && fp != stdin)
- fclose(fp);
-
- return p;
+ return (p);
}
pcap_t *
-pcap_open_offline_nsectime(const char *fname, char *errbuf)
+pcap_open_offline(const char *fname, char *errbuf)
{
- FILE *fp;
- pcap_t *p;
-
- fp = sf_open(fname);
- if (!fp) {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, pcap_strerror(errno));
- return NULL;
- }
-
- p = pcap_fopen_offline_nsectime(fp, errbuf);
- if (!p && fp != stdin) {
- fclose(fp);
- }
-
- return p;
+ return (pcap_open_offline_with_tstamp_precision(fname,
+ PCAP_TSTAMP_PRECISION_MICRO, errbuf));
}
#ifdef WIN32
-pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
+pcap_t* pcap_hopen_offline_with_tstamp_precision(intptr_t osfd, u_int precision,
+ char *errbuf)
{
int fd;
FILE *file;
@@ -274,33 +236,18 @@ pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
return NULL;
}
- return pcap_fopen_offline(file, errbuf);
+ return pcap_fopen_offline_with_tstamp_precision(file, precision,
+ errbuf);
}
-pcap_t* pcap_hopen_offline_nsectime(intptr_t osfd, char *errbuf)
+pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
{
- int fd;
- FILE *file;
-
- fd = _open_osfhandle(osfd, _O_RDONLY);
- if ( fd < 0 )
- {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, pcap_strerror(errno));
- return NULL;
- }
-
- file = _fdopen(fd, "rb");
- if ( file == NULL )
- {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, pcap_strerror(errno));
- return NULL;
- }
-
- return pcap_fopen_offline_nsectime(file, errbuf);
+ return pcap_hopen_offline_with_tstamp_precision(osfd,
+ PCAP_TSTAMP_PRECISION_MICRO, errbuf);
}
#endif
-static pcap_t *(*check_headers[])(bpf_u_int32, FILE *, int, char *, int *) = {
+static pcap_t *(*check_headers[])(bpf_u_int32, FILE *, u_int, char *, int *) = {
pcap_check_header,
pcap_ng_check_header
};
@@ -311,7 +258,8 @@ static pcap_t *(*check_headers[])(bpf_u_int32, FILE *, int, char *, int *) = {
static
#endif
pcap_t *
-pcap_fopen_offline(FILE *fp, char *errbuf)
+pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
+ char *errbuf)
{
register pcap_t *p;
bpf_u_int32 magic;
@@ -345,7 +293,7 @@ pcap_fopen_offline(FILE *fp, char *errbuf)
* Try all file types.
*/
for (i = 0; i < N_FILE_TYPES; i++) {
- p = (*check_headers[i])(magic, fp, 0, errbuf, &err);
+ p = (*check_headers[i])(magic, fp, precision, errbuf, &err);
if (p != NULL) {
/* Yup, that's it. */
goto found;
@@ -381,7 +329,21 @@ found:
p->selectable_fd = fileno(fp);
#endif
- pcap_open_offline_set_common_properties(p);
+ p->read_op = pcap_offline_read;
+ p->inject_op = sf_inject;
+ p->setfilter_op = install_bpf_program;
+ p->setdirection_op = sf_setdirection;
+ p->set_datalink_op = NULL; /* we don't support munging link-layer headers */
+ p->getnonblock_op = sf_getnonblock;
+ p->setnonblock_op = sf_setnonblock;
+ p->stats_op = sf_stats;
+#ifdef WIN32
+ p->setbuff_op = sf_setbuff;
+ p->setmode_op = sf_setmode;
+ p->setmintocopy_op = sf_setmintocopy;
+#endif
+ p->cleanup_op = sf_cleanup;
+ p->activated = 1;
return (p);
}
@@ -390,79 +352,10 @@ found:
static
#endif
pcap_t *
-pcap_fopen_offline_nsectime(FILE *fp, char *errbuf)
+pcap_fopen_offline(FILE *fp, char *errbuf)
{
- register pcap_t *p;
- bpf_u_int32 magic;
- size_t amt_read;
- u_int i;
- int err;
-
- /*
- * Read the first 4 bytes of the file; the network analyzer dump
- * file formats we support (pcap and pcap-ng), and several other
- * formats we might support in the future (such as snoop, DOS and
- * Windows Sniffer, and Microsoft Network Monitor) all have magic
- * numbers that are unique in their first 4 bytes.
- */
- amt_read = fread((char *)&magic, 1, sizeof(magic), fp);
- if (amt_read != sizeof(magic)) {
- if (ferror(fp)) {
- snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "error reading dump file: %s",
- pcap_strerror(errno));
- } else {
- snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "truncated dump file; tried to read %lu file header bytes, only got %lu",
- (unsigned long)sizeof(magic),
- (unsigned long)amt_read);
- }
- return (NULL);
- }
-
- /*
- * Try all file types.
- */
- for (i = 0; i < N_FILE_TYPES; i++) {
- p = (*check_headers[i])(magic, fp, 1, errbuf, &err);
- if (p != NULL) {
- /* Yup, that's it. */
- goto found;
- }
- if (err) {
- /*
- * Error trying to read the header.
- */
- return (NULL);
- }
- }
-
- /*
- * Well, who knows what this mess is....
- */
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown file format");
- return (NULL);
-
-found:
- p->rfile = fp;
-
- /* Padding only needed for live capture fcode */
- p->fddipad = 0;
-
-#if !defined(WIN32) && !defined(MSDOS)
- /*
- * You can do "select()" and "poll()" on plain files on most
- * platforms, and should be able to do so on pipes.
- *
- * You can't do "select()" on anything other than sockets in
- * Windows, so, on Win32 systems, we don't have "selectable_fd".
- */
- p->selectable_fd = fileno(fp);
-#endif
-
- pcap_open_offline_set_common_properties(p);
-
- return p;
+ return (pcap_fopen_offline_with_tstamp_precision(fp,
+ PCAP_TSTAMP_PRECISION_MICRO, errbuf));
}
/*