]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Merge remote-tracking branch 'upstream/master'
authorWesley Shields <[email protected]>
Mon, 10 Sep 2012 17:05:53 +0000 (13:05 -0400)
committerWesley Shields <[email protected]>
Mon, 10 Sep 2012 17:05:53 +0000 (13:05 -0400)
1  2 
tcpdump.c

diff --combined tcpdump.c
index 59aae52764ac6750def856e052e381c041d6199f,98ec2d5df6ad14cfc554568c912a87c444353cb5..c43ab8549548f620f2715f707027477ba540f1a5
+++ b/tcpdump.c
@@@ -589,6 -589,8 +589,8 @@@ static voi
  MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars)
  {
          char *filename = malloc(NAME_MAX + 1);
+         if (filename == NULL)
+             error("Makefilename: malloc);
  
          /* Process with strftime if Gflag is set. */
          if (Gflag != 0) {
@@@ -630,51 -632,14 +632,51 @@@ static int tcpdump_printf(netdissect_op
    return ret;
  }
  
 +struct print_info get_print_info(int type) {
 +      struct print_info printinfo;
 +
 +      printinfo.ndo_type = 1;
 +      printinfo.ndo = gndo;
 +      printinfo.p.ndo_printer = lookup_ndo_printer(type);
 +      if (printinfo.p.ndo_printer == NULL) {
 +              printinfo.p.printer = lookup_printer(type);
 +              printinfo.ndo_type = 0;
 +              if (printinfo.p.printer == NULL) {
 +                      gndo->ndo_dltname = pcap_datalink_val_to_name(type);
 +                      if (gndo->ndo_dltname != NULL)
 +                              error("packet printing is not supported for link type %s: use -w",
 +                                    gndo->ndo_dltname);
 +                      else
 +                              error("packet printing is not supported for link type %d: use -w", type);
 +              }
 +      }
 +      return (printinfo);
 +}
 +
 +char *get_next_file(FILE *VFile, char *ptr) {
 +      char *ret;
 +
 +      ret = fgets(ptr, NAME_MAX, VFile);
 +      if (!ret)
 +              return NULL;
 +
 +      if (ptr[strlen(ptr) - 1] == '\n')
 +              ptr[strlen(ptr) - 1] = '\0';
 +
 +      return ret;
 +}
 +
  int
  main(int argc, char **argv)
  {
        register int cnt, op, i;
        bpf_u_int32 localnet, netmask;
 -      register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName;
 +      register char *cp, *infile, *cmdbuf, *device, *RFileName, *VFileName, *WFileName;
        pcap_handler callback;
        int type;
 +      int dlt;
 +      int new_dlt;
 +      const char *dlt_name;
        struct bpf_program fcode;
  #ifndef WIN32
        RETSIGTYPE (*oldhandler)(int);
        struct dump_info dumpinfo;
        u_char *pcap_userdata;
        char ebuf[PCAP_ERRBUF_SIZE];
 +      char VFileLine[NAME_MAX + 1];
        char *username = NULL;
        char *chroot_dir = NULL;
 +      char *ret = NULL;
  #ifdef HAVE_PCAP_FINDALLDEVS
        pcap_if_t *devpointer;
        int devnum;
  #endif
        int status;
 +      FILE *VFile;
  #ifdef WIN32
        if(wsockinit() != 0) return 1;
  #endif /* WIN32 */
        device = NULL;
        infile = NULL;
        RFileName = NULL;
 +      VFileName = NULL;
        WFileName = NULL;
        if ((cp = strrchr(argv[0], '/')) != NULL)
                program_name = cp + 1;
  #endif
  
        while (
 -          (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1)
 +          (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "V:vw:W:xXy:Yz:Z:")) != -1)
                switch (op) {
  
                case 'a':
                        ++vflag;
                        break;
  
 +              case 'V':
 +                      VFileName = optarg;
 +                      break;
 +
                case 'w':
                        WFileName = optarg;
                        break;
                break;
        }
  
 +      if (fflag != 0 && (VFileName != NULL || RFileName != NULL))
 +              error("-f can not be used with -V or -r");
 +
 +      if (VFileName != NULL && RFileName != NULL)
 +              error("-V and -r are mutually exclusive.");
 +
  #ifdef WITH_CHROOT
        /* if run as root, prepare for chrooting */
        if (getuid() == 0 || geteuid() == 0) {
        }
  #endif
  
 -      if (RFileName != NULL) {
 -              int dlt;
 -              const char *dlt_name;
 -
 +      if (RFileName != NULL || VFileName != NULL) {
  #ifndef WIN32
                /*
                 * We don't need network access, so relinquish any set-UID
                if (setgid(getgid()) != 0 || setuid(getuid()) != 0 )
                        fprintf(stderr, "Warning: setgid/setuid failed !\n");
  #endif /* WIN32 */
 +              if (VFileName != NULL) {
 +                      if (VFileName[0] == '-' && VFileName[1] == '\0')
 +                              VFile = stdin;
 +                      else
 +                              VFile = fopen(VFileName, "r");
 +
 +                      if (VFile == NULL)
 +                              error("Unable to open file: %s\n", strerror(errno));
 +
 +                      ret = get_next_file(VFile, VFileLine);
 +                      if (!ret)
 +                              error("Nothing in %s\n", VFileName);
 +                      RFileName = VFileLine;
 +              }
 +
                pd = pcap_open_offline(RFileName, ebuf);
                if (pd == NULL)
                        error("%s", ebuf);
                }
                localnet = 0;
                netmask = 0;
 -              if (fflag != 0)
 -                      error("-f and -r options are incompatible");
        } else {
                if (device == NULL) {
                        device = pcap_lookupdev(ebuf);
  
        if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
                error("%s", pcap_geterr(pd));
 -      free(cmdbuf);
        if (dflag) {
                bpf_dump(&fcode, dflag);
                pcap_close(pd);
 +              free(cmdbuf);
                exit(0);
        }
        init_addrtoname(localnet, netmask);
  #endif
        } else {
                type = pcap_datalink(pd);
 -                printinfo.ndo_type = 1;
 -                printinfo.ndo = gndo;
 -              printinfo.p.ndo_printer = lookup_ndo_printer(type);
 -                if (printinfo.p.ndo_printer == NULL) {
 -                        printinfo.p.printer = lookup_printer(type);
 -                        printinfo.ndo_type = 0;
 -                        if (printinfo.p.printer == NULL) {
 -                                gndo->ndo_dltname = pcap_datalink_val_to_name(type);
 -                                if (gndo->ndo_dltname != NULL)
 -                                        error("packet printing is not supported for link type %s: use -w",
 -                                              gndo->ndo_dltname);
 -                                else
 -                                        error("packet printing is not supported for link type %d: use -w", type);
 -                        }
 -                }
 +              printinfo = get_print_info(type);
                callback = print_packet;
                pcap_userdata = (u_char *)&printinfo;
        }
  
  #ifndef WIN32
        if (RFileName == NULL) {
 -              int dlt;
 -              const char *dlt_name;
 -
                if (!vflag && !WFileName) {
                        (void)fprintf(stderr,
                            "%s: verbose output suppressed, use -v or -vv for full protocol decode\n",
                (void)fflush(stderr);
        }
  #endif /* WIN32 */
 -      status = pcap_loop(pd, cnt, callback, pcap_userdata);
 -      if (WFileName == NULL) {
 -              /*
 -               * We're printing packets.  Flush the printed output,
 -               * so it doesn't get intermingled with error output.
 -               */
 -              if (status == -2) {
 +      do {
 +              status = pcap_loop(pd, cnt, callback, pcap_userdata);
 +              if (WFileName == NULL) {
                        /*
 -                       * We got interrupted, so perhaps we didn't
 -                       * manage to finish a line we were printing.
 -                       * Print an extra newline, just in case.
 +                       * We're printing packets.  Flush the printed output,
 +                       * so it doesn't get intermingled with error output.
                         */
 -                      putchar('\n');
 +                      if (status == -2) {
 +                              /*
 +                               * We got interrupted, so perhaps we didn't
 +                               * manage to finish a line we were printing.
 +                               * Print an extra newline, just in case.
 +                               */
 +                              putchar('\n');
 +                      }
 +                      (void)fflush(stdout);
 +              }
 +              if (status == -1) {
 +                      /*
 +                       * Error.  Report it.
 +                       */
 +                      (void)fprintf(stderr, "%s: pcap_loop: %s\n",
 +                          program_name, pcap_geterr(pd));
 +              }
 +              if (RFileName == NULL) {
 +                      /*
 +                       * We're doing a live capture.  Report the capture
 +                       * statistics.
 +                       */
 +                      info(1);
 +              }
 +              pcap_close(pd);
 +              if (VFileName != NULL) {
 +                      ret = get_next_file(VFile, VFileLine);
 +                      if (ret) {
 +                              RFileName = VFileLine;
 +                              pd = pcap_open_offline(RFileName, ebuf);
 +                              if (pd == NULL)
 +                                      error("%s", ebuf);
 +                              new_dlt = pcap_datalink(pd);
 +                              if (WFileName && new_dlt != dlt)
 +                                      error("%s: new dlt does not match original", RFileName);
 +                              printinfo = get_print_info(new_dlt);
 +                              dlt_name = pcap_datalink_val_to_name(new_dlt);
 +                              if (dlt_name == NULL) {
 +                                      fprintf(stderr, "reading from file %s, link-type %u\n",
 +                                      RFileName, new_dlt);
 +                              } else {
 +                                      fprintf(stderr,
 +                                      "reading from file %s, link-type %s (%s)\n",
 +                                      RFileName, dlt_name,
 +                                      pcap_datalink_val_to_description(new_dlt));
 +                              }
 +                              if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
 +                                      error("%s", pcap_geterr(pd));
 +                              if (pcap_setfilter(pd, &fcode) < 0)
 +                                      error("%s", pcap_geterr(pd));
 +                      }
                }
 -              (void)fflush(stdout);
 -      }
 -      if (status == -1) {
 -              /*
 -               * Error.  Report it.
 -               */
 -              (void)fprintf(stderr, "%s: pcap_loop: %s\n",
 -                  program_name, pcap_geterr(pd));
 -      }
 -      if (RFileName == NULL) {
 -              /*
 -               * We're doing a live capture.  Report the capture
 -               * statistics.
 -               */
 -              info(1);
        }
 -      pcap_close(pd);
 +      while (ret != NULL);
 +
 +      free(cmdbuf);
        exit(status == -1 ? 1 : 0);
  }
  
@@@ -2050,7 -1976,7 +2052,7 @@@ usage(void
        (void)fprintf(stderr,
  "\t\t[ -i interface ]" j_FLAG_USAGE " [ -M secret ]\n");
        (void)fprintf(stderr,
 -"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]\n");
 +"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -V file ] [ -w file ]\n");
        (void)fprintf(stderr,
  "\t\t[ -W filecount ] [ -y datalinktype ] [ -z command ]\n");
        (void)fprintf(stderr,