ongrep

A cleaned up fork of ngrep for OpenBSD
git clone git://git.sgregoratto.me/ongrep
Log | Files | Refs | README | LICENSE

commit 96280273f5288d9d908a4e72fdaefe9f39535ac0
parent 5f4e8ef262b0996c8b212bc4737772b52efa17ef
Author: Stephen Gregoratto <dev@sgregoratto.me>
Date:   Wed, 17 Jun 2020 13:30:27 +1000

Fix clean_exit to exit with the proper code

The manual states that an exit code of 2 is for errors. Since clean_exit
is a signal handler, passing it a value of 2 meant I was effectively
sending it SIGINT. Oops.

Fixed by passing it -1 on errors and setting the proper exit code.
Also mark the function as __dead.

Diffstat:
Mngrep.c | 59+++++++++++++++++++++++++++++++++--------------------------
Mngrep.h | 2+-
2 files changed, 34 insertions(+), 27 deletions(-)

diff --git a/ngrep.c b/ngrep.c @@ -248,10 +248,8 @@ main(int argc, char **argv) } } - if (unveil(NULL, NULL) == -1) { - warn("unveil"); - clean_exit(2); - } + if (unveil(NULL, NULL) == -1) + err(2, "unveil"); if (show_hex && dump_func != &dump_formatted) { warnx("-x is incompatible with -W"); @@ -262,7 +260,7 @@ main(int argc, char **argv) /* Setup PCAP input */ if (setup_pcap_source()) - clean_exit(2); + clean_exit(-1); /* * XXX: Originally, the filter would be setup again without the vlan @@ -270,7 +268,7 @@ main(int argc, char **argv) */ if (setup_bpf_filter(argv) == -1) { warnx("cannot compile filter: %s", pcap_geterr(pd)); - clean_exit(2); + clean_exit(-1); } drop_privs(); @@ -283,7 +281,7 @@ main(int argc, char **argv) /* Setup matcher */ if (match_data) { if (setup_matcher()) - clean_exit(2); + clean_exit(-1); if (quiet < 2 && strlen(match_data)) printf("%smatch: %s%s\n", invert_match ? "don't " : "", @@ -298,7 +296,7 @@ main(int argc, char **argv) pd_dump = pcap_dump_open(pd, dump_file); if (!pd_dump) { warnx("pcap_dump_open: %s", pcap_geterr(pd)); - clean_exit(2); + clean_exit(-2); } else printf("output: %s\n", dump_file); } @@ -790,7 +788,7 @@ re_match_func(unsigned char *data, uint32_t len, uint16_t *mindex, case PCRE_ERROR_UNKNOWN_NODE: case PCRE_ERROR_NOMEMORY: warnx("pcre_exec: fatal error"); - clean_exit(2); + clean_exit(-1); case PCRE_ERROR_NOMATCH: return 0; } @@ -969,32 +967,32 @@ get_filter_from_file(void) if ((fd = open(filter_file, O_RDONLY)) == -1) { warn("cannot open %s", filter_file); - clean_exit(2); + clean_exit(-1); } if (fstat(fd, &st) == -1) { warn("cannot stat %s", filter_file); - clean_exit(2); + clean_exit(-1); } if (st.st_size >= SSIZE_MAX) { warn("file too long: %s", filter_file); - clean_exit(2); + clean_exit(-1); } size = prefix + 8 + st.st_size + 2; if (size >= SIZE_MAX) warnx("fstr too long: %s", filter_file); if ((fstr = malloc(size)) == NULL) - err(1, "malloc"); + err(2, "malloc"); (void)strlcpy(fstr, template, size); (void)strlcat(fstr, " and ( ", size); flen = read(fd, fstr + prefix, st.st_size); if (flen == -1) { warn("read %s", filter_file); - clean_exit(2); + clean_exit(-1); } else if (flen != st.st_size) { warn("short read of %s: expected %lld, got %zu", filter_file, st.st_size, flen); - clean_exit(2); + clean_exit(-1); } (void)strlcat(fstr, " )", size); @@ -1021,7 +1019,7 @@ get_filter_from_argv(char **argv) if (size >= SIZE_MAX) { warnx("filter too long"); - clean_exit(2); + clean_exit(-1); } if ((fstr = malloc(size)) == NULL) @@ -1165,31 +1163,31 @@ drop_privs(void) if ((pw = getpwnam(UNPRIV_USER)) == NULL) { warn("cannot drop privileges: getpwnam"); - clean_exit(2); + clean_exit(-1); } endpwent(); if (chroot("/var/empty") == -1) { warn("cannot drop privileges: chroot"); - clean_exit(2); + clean_exit(-1); } if (chdir("/") == -1) { warn("cannot drop privileges: chdir"); - clean_exit(2); + clean_exit(-1); } gidset[0] = pw->pw_gid; if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) { warn("cannot drop privileges: setresgid"); - clean_exit(2); + clean_exit(-1); } if (setgroups(1, gidset) == -1) { warn("cannot drop privileges: setgroups"); - clean_exit(2); + clean_exit(-1); } if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) { warn("cannot drop privileges: setresuid"); - clean_exit(2); + clean_exit(-1); } } @@ -1238,16 +1236,25 @@ usage(void) } void -clean_exit(int32_t sig) +clean_exit(int sig) { + int code; + signal(SIGINT, SIG_IGN); signal(SIGABRT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGWINCH, SIG_IGN); + if (sig == -1) + code = 2; + else if (matches > 0) + code = 0; + else + code = 1; + if (quiet < 1 && sig >= 0) - printf("exit\n"); + puts("exit"); if (pattern) pcre_free(pattern); @@ -1261,7 +1268,7 @@ clean_exit(int32_t sig) * "may or may not" be accurate. So useless. :-( And confusing for a * user to see counts not match what ngrep thinks. */ - if (quiet < 1 && sig >= 0 && !read_file) + if (quiet < 1 && sig >= 0 && read_file == NULL) printf("%u received, %u matched\n", seen_frames, matches); if (pd) @@ -1271,5 +1278,5 @@ clean_exit(int32_t sig) if (pd_dump) pcap_dump_close(pd_dump); - exit(matches ? 0 : 1); + exit(code); } diff --git a/ngrep.h b/ngrep.h @@ -72,7 +72,7 @@ void process(u_char *, struct pcap_pkthdr *, u_char *); __dead void usage(void); void update_windowsize(int32_t); -void clean_exit(int32_t); +__dead void clean_exit(int); void dump_packet(struct pcap_pkthdr *, u_char *, uint8_t, unsigned char *, uint32_t, const char *, const char *, uint16_t, uint16_t, uint8_t,