summaryrefslogtreecommitdiffstats
path: root/freebsd/contrib/tcpdump/tcpdump.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/contrib/tcpdump/tcpdump.c')
-rw-r--r--freebsd/contrib/tcpdump/tcpdump.c95
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