+struct print_info {
+ if_printer printer;
+};
+
+struct dump_info {
+ char *WFileName;
+ pcap_t *pd;
+ pcap_dumper_t *p;
+};
+
+static void
+show_dlts_and_exit(pcap_t *pd)
+{
+ int n_dlts;
+ int *dlts = 0;
+ const char *dlt_name;
+
+ n_dlts = pcap_list_datalinks(pd, &dlts);
+ if (n_dlts < 0)
+ error("%s", pcap_geterr(pd));
+ else if (n_dlts == 0 || !dlts)
+ error("No data link types.");
+
+ (void) fprintf(stderr, "Data link types (use option -y to set):\n");
+
+ while (--n_dlts >= 0) {
+ dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]);
+ if (dlt_name != NULL) {
+ (void) fprintf(stderr, " %s (%s)", dlt_name,
+ pcap_datalink_val_to_description(dlts[n_dlts]));
+
+ /*
+ * OK, does tcpdump handle that type?
+ */
+ if (lookup_printer(dlts[n_dlts]) == NULL)
+ (void) fprintf(stderr, " (not supported)");
+ putchar('\n');
+ } else {
+ (void) fprintf(stderr, " DLT %d (not supported)\n",
+ dlts[n_dlts]);
+ }
+ }
+ free(dlts);
+ exit(0);
+}
+
+/*
+ * Set up flags that might or might not be supported depending on the
+ * version of libpcap we're using.
+ */
+#ifdef WIN32
+#define B_FLAG "B:"
+#define B_FLAG_USAGE " [ -B size ]"
+#else /* WIN32 */
+#define B_FLAG
+#define B_FLAG_USAGE
+#endif /* WIN32 */
+
+#ifdef HAVE_PCAP_FINDALLDEVS
+#ifndef HAVE_PCAP_IF_T
+#undef HAVE_PCAP_FINDALLDEVS
+#endif
+#endif
+
+#ifdef HAVE_PCAP_FINDALLDEVS
+#define D_FLAG "D"
+#else
+#define D_FLAG
+#endif
+
+#ifdef HAVE_PCAP_DUMP_FLUSH
+#define U_FLAG "U"
+#else
+#define U_FLAG
+#endif
+
+#ifndef WIN32
+/* Drop root privileges and chroot if necessary */
+static void
+droproot(const char *username, const char *chroot_dir)
+{
+ struct passwd *pw = NULL;
+
+ if (chroot_dir && !username) {
+ fprintf(stderr, "tcpdump: Chroot without dropping root is insecure\n");
+ exit(1);
+ }
+
+ pw = getpwnam(username);
+ if (pw) {
+ if (chroot_dir) {
+ if (chroot(chroot_dir) != 0 || chdir ("/") != 0) {
+ fprintf(stderr, "tcpdump: Couldn't chroot/chdir to '%.64s': %s\n",
+ chroot_dir, pcap_strerror(errno));
+ exit(1);
+ }
+ }
+ if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
+ setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
+ fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
+ username,
+ (unsigned long)pw->pw_uid,
+ (unsigned long)pw->pw_gid,
+ pcap_strerror(errno));
+ exit(1);
+ }
+ }
+ else {
+ fprintf(stderr, "tcpdump: Couldn't find user '%.32s'\n",
+ username);
+ exit(1);
+ }
+}
+#endif /* WIN32 */
+
+static int
+getWflagChars(int x)
+{
+ int c = 0;
+
+ x -= 1;
+ while (x > 0) {
+ c += 1;
+ x /= 10;
+ }
+
+ return c;
+}
+
+
+static void
+MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars)
+{
+ if (cnt == 0 && max_chars == 0)
+ strcpy(buffer, orig_name);
+ else
+ sprintf(buffer, "%s%0*d", orig_name, max_chars, cnt);
+}
+
+static int tcpdump_printf(netdissect_options *ndo _U_,
+ const char *fmt, ...)
+{
+
+ va_list args;
+ int ret;
+
+ va_start(args, fmt);
+ ret=vfprintf(stdout, fmt, args);
+ va_end(args);
+
+ return ret;
+}
+