ongrep

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

commit 82e072b5fe5afb6812eb5fcf917fce210f1d7d27
parent 40b17850e618118149b54bae3ebc39efeb4a78b9
Author: Jordan Ritter <jpr5@darkridge.com>
Date:   Mon, 29 Dec 2003 00:45:57 +0000

added -P option (specify alternate non-print char) and -W (specify
different Wrapping output mechanisms for non-hexmode display)

Diffstat:
Mngrep.8 | 12++++++++++++
Mngrep.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Mngrep.h | 5++++-
3 files changed, 81 insertions(+), 22 deletions(-)

diff --git a/ngrep.8 b/ngrep.8 @@ -96,6 +96,18 @@ a packet is matched. Print a timestamp in the form of +S.UUUUUU, indicating the delta between packet matches. +.IP "-P char" +Specify an alternate character to signify non-printable characters +when displayed. The default is ``.''. + +.IP "-W normal|byline|none" +Specify an alternate manner for displaying packets, when not in +hexadecimal mode. The ``byline'' mode honors embedded linefeeds, +wrapping text only when a linefeed is encountered. The ``none'' mode +doesn't wrap under any circumstance (entire payload is displayed on +one line). ``normal'' is the default mode and is only included for +completeness. This option is incompatible with ``-x''. + .IP "-s snaplen" Set the bpf caplen to snaplen (default 65536). diff --git a/ngrep.c b/ngrep.c @@ -85,6 +85,8 @@ int invert_match = 0, bin_match = 0; int matches = 0, max_matches = 0; int live_read = 1, want_delay = 0; +char nonprint_char = '.'; + char pc_err[PCAP_ERRBUF_SIZE]; #if USE_PCRE int err_offset; @@ -104,6 +106,7 @@ struct re_pattern_buffer pattern; char *match_data = NULL, *bin_data = NULL, *filter = NULL; int (*match_func)() = &blank_match_func; +void (*dump_func)(char *, int) = &dump_formatted; int match_len = 0; struct bpf_program pcapfilter; @@ -124,14 +127,30 @@ unsigned ws_row, ws_col; int main(int argc, char **argv) { int c; - signal(SIGINT, clean_exit); - signal(SIGQUIT, clean_exit); - signal(SIGABRT, clean_exit); - signal(SIGPIPE, clean_exit); + signal(SIGINT, clean_exit); + signal(SIGQUIT, clean_exit); + signal(SIGABRT, clean_exit); + signal(SIGPIPE, clean_exit); signal(SIGWINCH, update_windowsize); - while ((c = getopt(argc, argv, "hXViwqpevxlDtTs:n:d:A:I:O:S:")) != EOF) { + while ((c = getopt(argc, argv, "hXViwqpevxlDtTs:n:d:A:I:O:S:P:W:")) != EOF) { switch (c) { + case 'W': { + if (!strcasecmp(optarg, "normal")) + dump_func = &dump_formatted; + else if (!strcasecmp(optarg, "byline")) + dump_func = &dump_byline; + else if (!strcasecmp(optarg, "none")) + dump_func = &dump_unwrapped; + else { + printf("fatal: unknown wrap method '%s'\n", optarg); + usage(-1); + } + } break; + + case 'P': + nonprint_char = *optarg; + break; case 'S': limitlen = atoi(optarg); break; @@ -513,11 +532,10 @@ void process(u_char *data1, struct pcap_pkthdr* h, u_char *p) { if (pd_dump) { pcap_dump((u_char*)pd_dump, h, p); - if (!quiet) dump(data, len); - } else dump(data, len); + if (!quiet) dump_func(data, len); + } else dump_func(data, len); } - } - break; + } break; case IPPROTO_UDP: { struct udphdr* udp = (struct udphdr *)(((char *)ip_packet) + ip_hl); @@ -567,11 +585,10 @@ void process(u_char *data1, struct pcap_pkthdr* h, u_char *p) { if (pd_dump) { pcap_dump((u_char*)pd_dump, h, p); - if (!quiet) dump(data, len); - } else dump(data, len); + if (!quiet) dump_func(data, len); + } else dump_func(data, len); } - } - break; + } break; case IPPROTO_ICMP: { struct icmp* ic = (struct icmp *)(((char *)ip_packet) + ip_hl); @@ -614,11 +631,10 @@ void process(u_char *data1, struct pcap_pkthdr* h, u_char *p) { if (pd_dump) { pcap_dump((u_char*)pd_dump, h, p); - if (!quiet) dump(data, len); - } else dump(data, len); + if (!quiet) dump_func(data, len); + } else dump_func(data, len); } - } - break; + } break; } @@ -692,7 +708,35 @@ int blank_match_func(char *data, int len) { } -void dump(char *data, int len) { +void dump_byline(char *data, int len) { + if (len > 0) { + const char *s = data; + unsigned width; + + while (s < data + len) { + printf("%c", (*s == '\n' || isprint(*s))? *s : nonprint_char); + s++; + } + + printf("\n"); + } +} + +void dump_unwrapped(char *data, int len) { + if (len > 0) { + const char *s = data; + unsigned width; + + while (s < data + len) { + printf("%c", isprint(*s) ? *s : nonprint_char); + s++; + } + + printf("\n"); + } +} + +void dump_formatted(char *data, int len) { if (len > 0) { unsigned width = show_hex?16:(ws_col-5); char *str = data; @@ -713,7 +757,7 @@ void dump(char *data, int len) { for (j = 0; j < width; j++) if (i+j < len) - printf("%c", isprint(str[j])?str[j]:'.'); + printf("%c", isprint(str[j]) ? str[j] : nonprint_char); else printf(" "); str += width; @@ -918,8 +962,8 @@ 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> <match expression>\n" - " <bpf filter>\n"); + " <-s snaplen> <-S limitlen> <-W normal|byline|none>\n" + " <-P char> <match expression> <bpf filter>\n"); exit(e); } diff --git a/ngrep.h b/ngrep.h @@ -37,7 +37,6 @@ char *get_filter(char **); void process(u_char *, struct pcap_pkthdr*, u_char *); -void dump(char *, int); void clean_exit(int); void usage(int); void version(void); @@ -46,6 +45,10 @@ int re_match_func(char *, int); int bin_match_func(char *, int); int blank_match_func(char *, int); +void dump_unwrapped(char *, int); +void dump_byline(char *, int); +void dump_formatted(char *, int); + int strishex(char *); void print_time_absolute(struct pcap_pkthdr *);