diff options
Diffstat (limited to 'freebsd/contrib/tcpdump/tcpdump.c')
-rw-r--r-- | freebsd/contrib/tcpdump/tcpdump.c | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/freebsd/contrib/tcpdump/tcpdump.c b/freebsd/contrib/tcpdump/tcpdump.c index b1e7f0d1..5b658412 100644 --- a/freebsd/contrib/tcpdump/tcpdump.c +++ b/freebsd/contrib/tcpdump/tcpdump.c @@ -139,6 +139,7 @@ The Regents of the University of California. All rights reserved.\n"; #include <sys/sysctl.h> #include <machine/rtems-bsd-commands.h> #include <assert.h> +#include <sched.h> #include <rtems.h> #include <rtems/linkersets.h> #define setpriority(a, b, c) @@ -206,8 +207,10 @@ cap_channel_t *capdns; static void error(FORMAT_STRING(const char *), ...) NORETURN PRINTFLIKE(1, 2); static void warning(FORMAT_STRING(const char *), ...) PRINTFLIKE(1, 2); static void exit_tcpdump(int) NORETURN; +#ifndef __rtems__ static RETSIGTYPE cleanup(int); static RETSIGTYPE child_cleanup(int); +#endif /* __rtems__ */ static void print_version(void); static void print_usage(void); static void show_tstamp_types_and_exit(pcap_t *, const char *device) NORETURN; @@ -219,6 +222,7 @@ static void show_devices_and_exit (void) NORETURN; static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *); static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *); +#ifndef __rtems__ static void droproot(const char *, const char *); #ifdef SIGNAL_REQ_INFO @@ -232,6 +236,7 @@ RETSIGTYPE requestinfo(int); #elif defined(HAVE_ALARM) static void verbose_stats_dump(int sig); #endif +#endif /* __rtems__ */ static void info(int); static u_int packets_captured; @@ -623,6 +628,7 @@ static const struct option longopts[] = { { NULL, 0, NULL, 0 } }; +#ifndef __rtems__ #ifndef _WIN32 /* Drop root privileges and chroot if necessary */ static void @@ -654,7 +660,6 @@ droproot(const char *username, const char *chroot_dir) fprintf(stderr, "dropped privs to %s\n", username); } #else -#ifndef __rtems__ if (initgroups(pw->pw_name, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) { fprintf(stderr, "%s: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n", @@ -667,7 +672,6 @@ droproot(const char *username, const char *chroot_dir) else { fprintf(stderr, "dropped privs to %s\n", username); } -#endif /* __rtems__ */ #endif /* HAVE_LIBCAP_NG */ } else { @@ -689,6 +693,7 @@ droproot(const char *username, const char *chroot_dir) } #endif /* _WIN32 */ +#endif /* __rtems__ */ static int getWflagChars(int x) @@ -1196,26 +1201,22 @@ typedef struct { FILE *in; pcap_t *pd; rtems_id master; + bool terminate; } pcap_loop_context; static void pcap_loop_monitor(rtems_task_argument arg) { - pcap_loop_context *ctx; + const pcap_loop_context *ctx; FILE *in; pcap_t *pd; - rtems_id master; rtems_status_code sc; - ctx = (pcap_loop_context *)arg; + ctx = (const pcap_loop_context *)arg; in = ctx->in; pd = ctx->pd; - master = ctx->master; - - sc = rtems_event_transient_send(master); - assert(sc == RTEMS_SUCCESSFUL); - while (true) { + while (!ctx->terminate) { int c; c = fgetc(in); @@ -1224,19 +1225,22 @@ pcap_loop_monitor(rtems_task_argument arg) pcap_breakloop(pd); break; } + + sched_yield(); } - rtems_task_delete(RTEMS_SELF); - assert(0); + sc = rtems_event_transient_send(ctx->master); + assert(sc == RTEMS_SUCCESSFUL); + + rtems_task_exit(); } -static int -pcap_loop_wrapper(pcap_t *pd, int cnt, pcap_handler cb, u_char *ud) +static void +pcap_create_loop_monitor(pcap_loop_context *ctx, pcap_t *pd) { rtems_status_code sc; rtems_task_priority priority; rtems_id id; - pcap_loop_context ctx; sc = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &priority); @@ -1246,27 +1250,38 @@ pcap_loop_wrapper(pcap_t *pd, int cnt, pcap_handler cb, u_char *ud) RTEMS_MINIMUM_STACK_SIZE, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, &id); if (sc != RTEMS_SUCCESSFUL) { - fprintf(stderr, "tcpdump: cannot create helper thread: %s\n", + error("cannot create pcap loop monitor thread: %s\n", rtems_status_text(sc)); - return (-1); } fprintf(stdout, "tcpdump: press <ENTER> or 'q' or 'Q' to quit\n"); - ctx.in = stdin; - ctx.pd = pd; - ctx.master = rtems_task_self(); + ctx->in = stdin; + ctx->pd = pd; + ctx->master = rtems_task_self(); + ctx->terminate = false; sc = rtems_task_start(id, pcap_loop_monitor, - (rtems_task_argument)&ctx); + (rtems_task_argument)ctx); assert(sc == RTEMS_SUCCESSFUL); +} + +static void +pcap_terminate_loop_monitor(pcap_loop_context *ctx) +{ + rtems_status_code sc; + + ctx->terminate = true; sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT); assert(sc == RTEMS_SUCCESSFUL); - - return (pcap_loop(pd, cnt, cb, ud)); } -#define pcap_loop(pd, cnt, cb, ud) pcap_loop_wrapper(pd, cnt, cb, ud) +static void +destroy_pcap_dumper(void *arg) +{ + + pcap_dump_close(arg); +} #endif /* __rtems__ */ int #ifndef __rtems__ @@ -1283,15 +1298,19 @@ main(int argc, char **argv) int dlt; const char *dlt_name; struct bpf_program fcode; +#ifndef __rtems__ #ifndef _WIN32 RETSIGTYPE (*oldhandler)(int); #endif +#endif /* __rtems__ */ struct dump_info dumpinfo; u_char *pcap_userdata; char ebuf[PCAP_ERRBUF_SIZE]; char VFileLine[PATH_MAX + 1]; +#ifndef __rtems__ char *username = NULL; char *chroot_dir = NULL; +#endif /* __rtems__ */ char *ret = NULL; char *end; #ifdef HAVE_PCAP_FINDALLDEVS @@ -1663,9 +1682,11 @@ main(int argc, char **argv) zflag = optarg; break; +#ifndef __rtems__ case 'Z': username = optarg; break; +#endif /* __rtems__ */ case '#': ndo->ndo_packet_number = 1; @@ -1962,6 +1983,7 @@ main(int argc, char **argv) init_print(ndo, localnet, netmask, timezone_offset); +#ifndef __rtems__ #ifndef _WIN32 (void)setsignal(SIGPIPE, cleanup); (void)setsignal(SIGTERM, cleanup); @@ -2029,6 +2051,7 @@ main(int argc, char **argv) } #endif /* _WIN32 */ +#endif /* __rtems__ */ if (pcap_setfilter(pd, &fcode) < 0) error("%s", pcap_geterr(pd)); @@ -2123,6 +2146,12 @@ main(int argc, char **argv) if (Uflag) pcap_dump_flush(p); #endif +#ifdef __rtems__ + if (rtems_bsd_program_add_destructor(destroy_pcap_dumper, p) == + NULL) { + error("cannot add destructor"); + } +#endif /* __rtems__ */ } else { dlt = pcap_datalink(pd); ndo->ndo_if_printer = get_if_printer(ndo, dlt); @@ -2130,6 +2159,7 @@ main(int argc, char **argv) pcap_userdata = (u_char *)ndo; } +#ifndef __rtems__ #ifdef SIGNAL_REQ_INFO /* * We can't get statistics when reading from a file rather @@ -2154,6 +2184,7 @@ main(int argc, char **argv) alarm(1); #endif } +#endif /* __rtems__ */ if (RFileName == NULL) { /* @@ -2196,7 +2227,19 @@ main(int argc, char **argv) #endif /* HAVE_CAPSICUM */ do { +#ifdef __rtems__ + pcap_loop_context ctx; + + if (RFileName == NULL) { + pcap_create_loop_monitor(&ctx, pd); + } +#endif /* __rtems__ */ status = pcap_loop(pd, cnt, callback, pcap_userdata); +#ifdef __rtems__ + if (RFileName == NULL) { + pcap_terminate_loop_monitor(&ctx); + } +#endif /* __rtems__ */ if (WFileName == NULL) { /* * We're printing packets. Flush the printed output, @@ -2315,6 +2358,7 @@ main(int argc, char **argv) exit_tcpdump(status == -1 ? 1 : 0); } +#ifndef __rtems__ /* make a clean exit on interrupts */ static RETSIGTYPE cleanup(int signo _U_) @@ -2367,6 +2411,7 @@ child_cleanup(int signo _U_) wait(NULL); } #endif /* HAVE_FORK && HAVE_VFORK */ +#endif /* __rtems__ */ static void info(register int verbose) @@ -2727,6 +2772,7 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) char Wpcap_version[]="3.1"; #endif +#ifndef __rtems__ #ifdef SIGNAL_REQ_INFO RETSIGTYPE requestinfo(int signo _U_) { @@ -2755,6 +2801,7 @@ static void verbose_stats_dump(int sig _U_) alarm(1); } #endif +#endif /* __rtems__ */ USES_APPLE_DEPRECATED_API static void |