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:
M | ngrep.8 | | | 12 | ++++++++++++ |
M | ngrep.c | | | 86 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------- |
M | ngrep.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 *);