diff options
author | Guy Harris <guy@alum.mit.edu> | 2013-07-01 12:41:36 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2013-07-01 12:41:36 -0700 |
commit | 9b4ac1a5da2f6c887c1e1c8f65549ca77ca00678 (patch) | |
tree | 92231acb792a70c48e9f5ecc999a42068cffe792 /savefile.c | |
parent | 3e9963fef588935e16e81fda522a9bd521ff8698 (diff) | |
download | libpcap-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.c | 209 |
1 files changed, 51 insertions, 158 deletions
@@ -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)); } /* |