pcap_dumper_t * priv_pcap_dump_open(pcap_t *p, char *fname) { int fd, err; FILE *f; if (priv_fd < 0) errx(1, "%s: called from privileged portion", __func__); if (fname[0] == '-' && fname[1] == '\0') { f = stdout; priv_init_done(); } else { write_command(priv_fd, PRIV_OPEN_OUTPUT); fd = receive_fd(priv_fd); must_read(priv_fd, &err, sizeof(err)); if (fd < 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Failed to open output file %s: %s", fname, strerror(err)); return (NULL); } f = fdopen(fd, "w"); if (f == NULL) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, pcap_strerror(errno)); close(fd); return (NULL); } } (void)sf_write_header(f, p->linktype, p->tzoff, p->snapshot); return ((pcap_dumper_t *)f); }
static pcap_dumper_t * pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname) { #if defined(WIN32) || defined(MSDOS) /* * If we're writing to the standard output, put it in binary * mode, as savefiles are binary files. * * Otherwise, we turn off buffering. * XXX - why? And why not on the standard output? */ if (f == stdout) SET_BINMODE(f); else setbuf(f, NULL); #endif if (sf_write_header(f, linktype, p->tzoff, p->snapshot) == -1) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s", fname, pcap_strerror(errno)); if (f != stdout) (void)fclose(f); return (NULL); } return ((pcap_dumper_t *)f); }
static pcap_dumper_t * pcap_setup_dump(pcap_t *p, FILE *f, const char *fname) { if (sf_write_header(f, p->linktype, p->tzoff, p->snapshot) == -1) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s", fname, pcap_strerror(errno)); if (f != stdout) (void)fclose(f); return (NULL); } return ((pcap_dumper_t *)f); }
/* * Initialize so that sf_write() will output to the file named 'fname'. */ pcap_dumper_t * pcap_dump_open(pcap_t *p, const char *fname) { FILE *f; if (fname[0] == '-' && fname[1] == '\0') f = stdout; else { f = fopen(fname, "w"); if (f == NULL) { sprintf(p->errbuf, "%s: %s", fname, pcap_strerror(errno)); return (NULL); } } (void)sf_write_header(f, p->linktype, p->tzoff, p->snapshot); return ((pcap_dumper_t *)f); }
/* * Initialize so that sf_write_header() will output to the file named 'fname'. */ FILE * sr_dump_open(const char *fname, int thiszone, int snaplen) { FILE *fp; if (fname[0] == '-' && fname[1] == '\0') fp = stdout; else { fp = fopen(fname, "w"); if (fp == NULL) { fprintf(stderr, "sr_dump_open: can't open %s", fname); return (NULL); } } sf_write_header(fp, LINKTYPE_ETHERNET, thiszone, snaplen); return fp; }
pcap_dumper_t * pcap_dump_open_append(pcap_t *p, const char *fname) { FILE *f; int linktype; int amt_read; struct pcap_file_header ph; linktype = dlt_to_linktype(p->linktype); if (linktype == -1) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: link-layer type %d isn't supported in savefiles", fname, linktype); return (NULL); } if (fname[0] == '-' && fname[1] == '\0') return (pcap_setup_dump(p, linktype, stdout, "standard output")); #if !defined(_WIN32) && !defined(MSDOS) f = fopen(fname, "r+"); #else f = fopen(fname, "rb+"); #endif if (f == NULL) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, pcap_strerror(errno)); return (NULL); } /* * Try to read a pcap header. */ amt_read = fread(&ph, 1, sizeof (ph), f); if (amt_read != sizeof (ph)) { if (ferror(f)) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname, pcap_strerror(errno)); fclose(f); return (NULL); } else if (feof(f) && amt_read > 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: truncated pcap file header", fname); fclose(f); return (NULL); } } #if defined(_WIN32) || defined(MSDOS) /* * We turn off buffering. * XXX - why? And why not on the standard output? */ setbuf(f, NULL); #endif /* * If a header is already present and: * * it's not for a pcap file of the appropriate resolution * and the right byte order for this machine; * * the link-layer header types don't match; * * the snapshot lengths don't match; * * return an error. */ if (amt_read > 0) { /* * A header is already present. * Do the checks. */ switch (ph.magic) { case TCPDUMP_MAGIC: if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: different time stamp precision, cannot append to file", fname); fclose(f); return (NULL); } break; case NSEC_TCPDUMP_MAGIC: if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: different time stamp precision, cannot append to file", fname); fclose(f); return (NULL); } break; case SWAPLONG(TCPDUMP_MAGIC): case SWAPLONG(NSEC_TCPDUMP_MAGIC): snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: different byte order, cannot append to file", fname); fclose(f); return (NULL); case KUZNETZOV_TCPDUMP_MAGIC: case SWAPLONG(KUZNETZOV_TCPDUMP_MAGIC): case NAVTEL_TCPDUMP_MAGIC: case SWAPLONG(NAVTEL_TCPDUMP_MAGIC): snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: not a pcap file to which we can append", fname); fclose(f); return (NULL); default: snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: not a pcap file", fname); fclose(f); return (NULL); } /* * Good version? */ if (ph.version_major != PCAP_VERSION_MAJOR || ph.version_minor != PCAP_VERSION_MINOR) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: version is %u.%u, cannot append to file", fname, ph.version_major, ph.version_minor); fclose(f); return (NULL); } if (linktype != ph.linktype) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: different linktype, cannot append to file", fname); fclose(f); return (NULL); } if (p->snapshot != ph.snaplen) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: different snaplen, cannot append to file", fname); fclose(f); return (NULL); } } else { /* * A header isn't present; attempt to write it. */ if (sf_write_header(p, f, linktype, p->tzoff, p->snapshot) == -1) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s", fname, pcap_strerror(errno)); (void)fclose(f); return (NULL); } } /* * Start writing at the end of the file. */ if (fseek(f, 0, SEEK_END) == -1) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't seek to end of %s: %s", fname, pcap_strerror(errno)); (void)fclose(f); return (NULL); } return ((pcap_dumper_t *)f); }