Ethereal-dev: Re: [ethereal-dev] Editpcap.c

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <gharris@xxxxxxxxxxxx>
Date: Fri, 26 Nov 1999 01:35:02 -0800
> I've attached a version that used Wiretap to *write* the capture file as
> well;

...and now I've attached a version that actually *works*; I screwed up
in the previous version.

BTW, given that it can read any capture file format that Ethereal can
read, and, in the future, may be able to write capture file formats
other than "libpcap" format, perhaps it should be called just "editcap"?

Also, the Internet Traffic Archive, at

	http://ita.ee.lbl.gov/index.html

has not only a pile of Internet traffic traces, but also has, in its
archive of software at

	http://ita.ee.lbl.gov/html/software.html

a program called "tcpdpriv", at

	http://ita.ee.lbl.gov/html/contrib/tcpdpriv.html

which "is [a] program for eliminating confidential information from
packets collected on a network interface (or, from trace files created
using the -w argument to tcpdump)." It's a bit brutal, though, in that
it not only changes IP addresses to hide them, it throws out "the data
portion of a datagram", so it appears that, whilst a
"tcpdpriv"-sanitized trace wouldn't contain passwords, it also wouldn't,
as far as I know, contain NFS requests, NFS responses, CIFS requests,
CIFS responses, HTTP requests, HTTP responses, etc. - just the IP and
perhaps TCP/UDP headers.  (I think the Internet Traffic Archive is
intended for people studying things such as the behavior of TCP on the
Internet, for which you often wouldn't need the TCP payload.)

#include <stdio.h>
#include <glib.h>
#include <sys/time.h>
#include "wtap.h"

int delete[100], max_delete = -1;

/* Can we delete the record? */

int deleteit(int recno)
{
  int i = 0;

  for (i = 0; i<= max_delete; i++) {

    if (recno == delete[i]) return 1;

  }

  return 0;

}

typedef struct {
	char	*filename;
	wtap_dumper *pdh;
} callback_arg;

static int count = 1;

static void
edit_callback(u_char *user, const struct wtap_pkthdr *phdr, int offset,
    const u_char *buf) 
{
  callback_arg *argp = (callback_arg *)user;
  int err;

  if (!deleteit(count)) {

    printf("Record: %u\n", count);

    if (!wtap_dump(argp->pdh, phdr, buf, &err)) {

      fprintf(stderr, "editpcap: Error writing to %s: %s\n", argp->filename,
        wtap_strerror(err));
      exit(1);

    }

  }

  count++;

}

int main(int argc, char *argv[])

{
  wtap *wth;
  int read_bytes, pcnt = 0, i, err;
  callback_arg args;

  if (argc < 3) {

    fprintf(stderr, "Usage: editpcap <infile> <outfile> [ <record#> ... ]\n");
    exit(1);

  }

  wth = wtap_open_offline(argv[1], &err);

  if (!wth) {

    fprintf(stderr, "editpcap: Can't open %s: %s\n", argv[1],
        wtap_strerror(err));
    exit(1);

  }

  args.filename = argv[2];
  args.pdh = wtap_dump_open(argv[2], WTAP_FILE_PCAP,
		wtap_file_encap(wth), wtap_snapshot_length(wth), &err);
  if (args.pdh == NULL) {

    fprintf(stderr, "editpcap: Can't open or create %s: %s\n", argv[2],
        wtap_strerror(err));
    exit(1);

  }

  for (i = 3; i < argc; i++)
    delete[++max_delete] = atoi(argv[i]);

  wtap_loop(wth, 0, edit_callback, (char *)&args, &err);

  if (!wtap_dump_close(args.pdh, &err)) {

    fprintf(stderr, "editpcap: Error writing to %s: %s\n", argv[2],
        wtap_strerror(err));
    exit(1);

  }
  exit(0);
}