ongrep

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

commit edb557f0fcc132d806233d8d5974fddfac307fb7
parent e44e8f90e6692e7bb87361c4acd8f56067736490
Author: Jordan Ritter <jpr5@darkridge.com>
Date:   Mon, 29 Dec 2003 01:30:26 +0000

added ``-F'' (read bpf filter from file) option

Diffstat:
Mngrep.8 | 6++++++
Mngrep.c | 62+++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mngrep.h | 4+++-
3 files changed, 64 insertions(+), 8 deletions(-)

diff --git a/ngrep.8 b/ngrep.8 @@ -96,6 +96,12 @@ a packet is matched. Print a timestamp in the form of +S.UUUUUU, indicating the delta between packet matches. +.IP "-F file" +Read in the bpf filter from the specified filename. This is a +compatibility option for users familiar with tcpdump. Please note +that specifying ``-F'' will override any bpf filter specified on the +command-line. + .IP "-P char" Specify an alternate character to signify non-printable characters when displayed. The default is ``.''. diff --git a/ngrep.c b/ngrep.c @@ -60,6 +60,7 @@ #include <stdlib.h> #include <string.h> #include <signal.h> +#include <errno.h> #include <sys/ioctl.h> @@ -104,7 +105,7 @@ pcre_extra *pattern_extra = NULL; struct re_pattern_buffer pattern; #endif -char *match_data = NULL, *bin_data = NULL, *filter = NULL; +char *match_data = NULL, *bin_data = NULL, *filter = NULL, *filter_file = NULL; int (*match_func)() = &blank_match_func; void (*dump_func)(char *, int) = &dump_formatted; int match_len = 0; @@ -133,7 +134,7 @@ int main(int argc, char **argv) { signal(SIGPIPE, clean_exit); signal(SIGWINCH, update_windowsize); - while ((c = getopt(argc, argv, "hXViwqpevxlDtTs:n:d:A:I:O:S:P:W:")) != EOF) { + while ((c = getopt(argc, argv, "hXViwqpevxlDtTs:n:d:A:I:O:S:P:F:W:")) != EOF) { switch (c) { case 'W': { if (!strcasecmp(optarg, "normal")) @@ -148,6 +149,9 @@ int main(int argc, char **argv) { } } break; + case 'F': + filter_file = optarg; + break; case 'P': nonprint_char = *optarg; break; @@ -268,13 +272,30 @@ int main(int argc, char **argv) { } } + if (filter_file) { + char buf[1024] = {0}; + FILE *f = fopen(filter_file, "r"); + + if (!f || !fgets(buf, sizeof(buf)-1, f)) { + fprintf(stderr, "fatal: unable to get filter from %s: %s\n", filter_file, strerror(errno)); + usage(-1); + } + + fclose(f); + + filter = get_filter_from_string(buf); + + if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) { + pcap_perror(pd, "pcap compile"); + clean_exit(-1); + } - if (argv[optind]) { - filter = get_filter(&argv[optind]); + } else if (argv[optind]) { + filter = get_filter_from_argv(&argv[optind]); if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) { free(filter); - filter = get_filter(&argv[optind-1]); + filter = get_filter_from_argv(&argv[optind-1]); #if USE_PCAP_RESTART PCAP_RESTART_FUNC(); @@ -284,7 +305,9 @@ int main(int argc, char **argv) { clean_exit(-1); } else match_data = NULL; } + } + if (filter) { if (!quiet) printf("filter: %s\n", filter); if (pcap_setfilter(pd, &pcapfilter)) { @@ -772,8 +795,33 @@ void dump_formatted(char *data, int len) { } } +char *get_filter_from_string(char *str) { + char *mine; + int len; + + if (!str || !*str) + return NULL; + + len = strlen(str); + + { + char *s; + for (s = str; *s; s++) + if (*s == '\r' || *s == '\n') + *s = ' '; + } + + if (!(mine = (char*)malloc(len + sizeof(IP_ONLY)))) + return NULL; + + memset(mine, 0, len + sizeof(IP_ONLY)); + + sprintf(mine, IP_ONLY, str); + + return mine; +} -char *get_filter(char **argv) { +char *get_filter_from_argv(char **argv) { char **arg = argv, *theirs, *mine; char *from, *to; int len = 0; @@ -967,7 +1015,7 @@ void drop_privs(void) { void usage(int e) { printf("usage: ngrep <-hXViwqpevxlDtT> <-IO pcap_dump> <-n num> <-d dev> <-A num>\n" " <-s snaplen> <-S limitlen> <-W normal|byline|none>\n" - " <-P char> <match expression> <bpf filter>\n"); + " <-P char> <-F file> <match expression> <bpf filter>\n"); exit(e); } diff --git a/ngrep.h b/ngrep.h @@ -35,12 +35,14 @@ #define TH_CWR 0x80 #endif -char *get_filter(char **); void process(u_char *, struct pcap_pkthdr*, u_char *); void clean_exit(int); void usage(int); void version(void); +char *get_filter_from_string(char *); +char *get_filter_from_argv(char **); + int re_match_func(char *, int); int bin_match_func(char *, int); int blank_match_func(char *, int);