openbsd-ports/net/ngrep/patches/patch-ngrep_c
2011-06-18 14:02:38 +00:00

602 lines
18 KiB
Plaintext

$OpenBSD: patch-ngrep_c,v 1.6 2011/06/18 14:02:38 kili Exp $
--- ngrep.c.orig Tue Nov 28 14:38:43 2006
+++ ngrep.c Sat Jun 18 14:55:32 2011
@@ -60,6 +60,7 @@
#include <config.h>
#define strcasecmp stricmp
+#define strncasecmp strnicmp
#else
@@ -74,6 +75,7 @@
#include <stdlib.h>
#include <string.h>
#include <signal.h>
+#include <locale.h>
#if !defined(_WIN32)
#include <errno.h>
@@ -92,7 +94,7 @@
#endif
#if USE_PCRE
-#include "pcre-5.0/pcre.h"
+#include "pcre.h"
#else
#include "regex-0.12/regex.h"
#endif
@@ -114,6 +116,7 @@ uint8_t show_empty = 0, show_hex = 0, show_proto = 0,
uint8_t invert_match = 0, bin_match = 0;
uint8_t live_read = 1, want_delay = 0;
uint8_t dont_dropprivs = 0;
+uint8_t enable_hilite = 0;
char *read_file = NULL, *dump_file = NULL;
char *usedev = NULL;
@@ -145,7 +148,7 @@ uint16_t match_len = 0;
int8_t (*match_func)() = &blank_match_func;
int8_t dump_single = 0;
-void (*dump_func)(unsigned char *, uint32_t) = &dump_formatted;
+void (*dump_func)(unsigned char *, uint32_t, uint16_t, uint16_t) = &dump_formatted;
/*
* BPF/Network
@@ -153,10 +156,10 @@ void (*dump_func)(unsigned char *, uint32_t) = &dump_f
char *filter = NULL, *filter_file = NULL;
char pc_err[PCAP_ERRBUF_SIZE];
-uint8_t link_offset;
+uint8_t link_offset, vlan_offset = 0;
uint8_t radiotap_present = 0;
-pcap_t *pd = NULL;
+pcap_t *pd = NULL, *pd_dumppcap = NULL;
pcap_dumper_t *pd_dump = NULL;
struct bpf_program pcapfilter;
struct in_addr net, mask;
@@ -176,8 +179,7 @@ void (*print_time)() = NULL, (*dump_delay)() = dump_de
/*
- * When !Win32, windowsize stuff. We leave it in regardless to avoid
- * any additional #if complication/obfuscation.
+ * Window-size functionality (adjust output based on width of console display)
*/
uint32_t ws_row, ws_col = 80, ws_col_forced = 0;
@@ -195,7 +197,17 @@ int main(int argc, char **argv) {
signal(SIGWINCH, update_windowsize);
#endif
- while ((c = getopt(argc, argv, "LNhXViwqpevxlDtTRMs:n:c:d:A:I:O:S:P:F:W:")) != EOF) {
+#if !defined(_WIN32)
+ {
+ char const *locale = getenv("LANG");
+ if (locale == NULL)
+ locale = "en_US";
+
+ setlocale(LC_CTYPE, locale);
+ }
+#endif
+
+ while ((c = getopt(argc, argv, "LNhXViwqpevxlDtTRMCs:n:c:d:A:I:O:S:P:F:W:")) != EOF) {
switch (c) {
case 'W': {
if (!strcasecmp(optarg, "normal"))
@@ -257,6 +269,9 @@ int main(int argc, char **argv) {
if (value > 0)
snaplen = value;
} break;
+ case 'C':
+ enable_hilite = 1;
+ break;
case 'M':
re_multiline_match = 0;
break;
@@ -264,13 +279,18 @@ int main(int argc, char **argv) {
dont_dropprivs = 1;
break;
case 'T':
- print_time = &print_time_diff;
+ if (print_time == &print_time_diff) {
+ print_time = print_time_offset;
+ memset(&prev_ts, 0, sizeof(prev_ts));
+ } else {
+ print_time = &print_time_diff;
#if defined(_WIN32)
- prev_ts.tv_sec = (uint32_t)time(NULL);
- prev_ts.tv_usec = 0;
+ prev_ts.tv_sec = (uint32_t)time(NULL);
+ prev_ts.tv_usec = 0;
#else
- gettimeofday(&prev_ts, NULL);
+ gettimeofday(&prev_ts, NULL);
#endif
+ }
break;
case 't':
print_time = &print_time_absolute;
@@ -337,7 +357,12 @@ int main(int argc, char **argv) {
} else {
- char *dev = usedev ? usedev : pcap_lookupdev(pc_err);
+ char *dev = usedev ? usedev :
+#if defined(_WIN32)
+ win32_choosedevice();
+#else
+ pcap_lookupdev(pc_err);
+#endif
if (!dev) {
perror(pc_err);
@@ -391,7 +416,7 @@ int main(int argc, char **argv) {
filter = get_filter_from_argv(&argv[optind-1]);
#if USE_PCAP_RESTART
- PCAP_RESTART_FUNC();
+ PCAP_RESTART_FUNC(NULL);
#endif
if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) {
pcap_perror(pd, "pcap compile");
@@ -408,6 +433,17 @@ int main(int argc, char **argv) {
}
}
+ /* VLAN support: determine # of +4 offsets to accommodate */
+ if (filter) {
+ char const bpf_vlan[] = "vlan";
+ char *s = filter;
+ while (*s)
+ if (strncasecmp(s++, bpf_vlan, sizeof(bpf_vlan)-1) == 0)
+ vlan_offset++;
+
+ vlan_offset *= VLANHDR_SIZE;
+ }
+
if (filter && quiet < 2)
printf("filter: %s\n", filter);
@@ -549,6 +585,10 @@ int main(int argc, char **argv) {
link_offset = PPPHDR_SIZE;
break;
+ case DLT_PPP_ETHER:
+ link_offset = PPPOEHDR_SIZE;
+ break;
+
#if HAVE_DLT_LOOP
case DLT_LOOP:
#endif
@@ -579,21 +619,28 @@ int main(int argc, char **argv) {
break;
#endif
+#if HAVE_DLT_PFLOG
+ case DLT_PFLOG:
+ link_offset = PFLOGHDR_SIZE;
+ break;
+#endif
+
default:
fprintf(stderr, "fatal: unsupported interface type %u\n", pcap_datalink(pd));
clean_exit(-1);
}
+ link_offset += vlan_offset;
+
if (dump_file) {
- if (!(pd_dump = pcap_dump_open(pd, dump_file))) {
+ pd_dump = pcap_dump_open(pd, dump_file);
+ if (!pd_dump) {
fprintf(stderr, "fatal: %s\n", pcap_geterr(pd));
clean_exit(-1);
} else printf("output: %s\n", dump_file);
}
-#if !defined(_WIN32)
update_windowsize(0);
-#endif
#if defined(_WIN32)
win32_initwinsock();
@@ -603,7 +650,7 @@ int main(int argc, char **argv) {
drop_privs();
#endif
- while (pcap_loop(pd, 0, (pcap_handler)process, 0));
+ while (pcap_loop(pd, -1, (pcap_handler)process, 0));
clean_exit(0);
@@ -699,11 +746,6 @@ void process(u_char *d, struct pcap_pkthdr *h, u_char
data = (unsigned char *)(tcp_pkt) + tcphdr_offset;
len -= link_offset + ip_hl + tcphdr_offset;
-#if USE_IPv6
- if (ip_ver == 6)
- len -= ntohs(ip6_pkt->ip6_plen);
-#endif
-
if ((int32_t)len < 0)
len = 0;
@@ -719,20 +761,11 @@ void process(u_char *d, struct pcap_pkthdr *h, u_char
data = (unsigned char *)(udp_pkt) + udphdr_offset;
len -= link_offset + ip_hl + udphdr_offset;
-#if USE_IPv6
- if (ip_ver == 6)
- len -= ntohs(ip6_pkt->ip6_plen);
-#endif
-
if ((int32_t)len < 0)
len = 0;
dump_packet(h, p, ip_proto, data, len, ip_src, ip_dst,
-#if HAVE_DUMB_UDPHDR
- ntohs(udp_pkt->source), ntohs(udp_pkt->dest), 0,
-#else
ntohs(udp_pkt->uh_sport), ntohs(udp_pkt->uh_dport), 0,
-#endif
udphdr_offset, fragmented, frag_offset, frag_id);
} break;
@@ -757,7 +790,7 @@ void process(u_char *d, struct pcap_pkthdr *h, u_char
uint16_t icmp6hdr_offset = (frag_offset) ? 0 : 4;
data = (unsigned char *)(icmp6_pkt) + icmp6hdr_offset;
- len -= link_offset + ip_hl + ntohs(ip6_pkt->ip6_plen) + icmp6hdr_offset;
+ len -= link_offset + ip_hl + icmp6hdr_offset;
if ((int32_t)len < 0)
len = 0;
@@ -808,13 +841,15 @@ void dump_packet(struct pcap_pkthdr *h, u_char *p, uin
const char *ip_src, const char *ip_dst, uint16_t sport, uint16_t dport, uint8_t flags,
uint16_t hdr_offset, uint8_t frag, uint16_t frag_offset, uint32_t frag_id) {
+ uint16_t match_size, match_index;
+
if (!show_empty && len == 0)
return;
if (len > limitlen)
len = limitlen;
- if ((len > 0 && match_func(data, len) == invert_match) && !keep_matching)
+ if ((len > 0 && match_func(data, len, &match_index, &match_size) == invert_match) && !keep_matching)
return;
if (!live_read && want_delay)
@@ -879,15 +914,17 @@ void dump_packet(struct pcap_pkthdr *h, u_char *p, uin
printf("\n");
if (quiet < 3)
- dump_func(data, len);
+ dump_func(data, len, match_index, match_size);
if (pd_dump)
pcap_dump((u_char*)pd_dump, h, p);
}
-int8_t re_match_func(unsigned char *data, uint32_t len) {
+int8_t re_match_func(unsigned char *data, uint32_t len, uint16_t *mindex, uint16_t *msize) {
#if USE_PCRE
- switch(pcre_exec(pattern, 0, data, (int32_t)len, 0, 0, 0, 0)) {
+
+ static int sub[2];
+ switch(pcre_exec(pattern, 0, (char const *)data, (int32_t)len, 0, 0, 0, 0)) {
case PCRE_ERROR_NULL:
case PCRE_ERROR_BADOPTION:
case PCRE_ERROR_BADMAGIC:
@@ -898,15 +935,25 @@ int8_t re_match_func(unsigned char *data, uint32_t len
case PCRE_ERROR_NOMATCH:
return 0;
+
+ default:
+ *mindex = sub[0];
+ *msize = sub[1] - sub[0];
}
#else
- switch (re_search(&pattern, data, (int32_t)len, 0, len, 0)) {
+
+ static struct re_registers regs;
+ switch (re_search(&pattern, (char const *)data, (int32_t)len, 0, len, &regs)) {
case -2:
perror("she's dead, jim\n");
clean_exit(-2);
case -1:
return 0;
+
+ default:
+ *mindex = regs.start[0];
+ *msize = regs.end[0] - regs.start[0];
}
#endif
@@ -919,7 +966,7 @@ int8_t re_match_func(unsigned char *data, uint32_t len
return 1;
}
-int8_t bin_match_func(unsigned char *data, uint32_t len) {
+int8_t bin_match_func(unsigned char *data, uint32_t len, uint16_t *mindex, uint16_t *msize) {
int32_t stop = len - match_len;
int32_t i = 0;
@@ -934,71 +981,118 @@ int8_t bin_match_func(unsigned char *data, uint32_t le
if (match_after && keep_matching != match_after)
keep_matching = match_after;
+ *mindex = i - 1;
+ *msize = match_len;
+
return 1;
}
return 0;
}
-
-int8_t blank_match_func(unsigned char *data, uint32_t len) {
+int8_t blank_match_func(unsigned char *data, uint32_t len, uint16_t *mindex, uint16_t *msize) {
if (max_matches)
matches++;
+ *mindex = 0;
+ *msize = 0;
+
return 1;
}
-void dump_byline(unsigned char *data, uint32_t len) {
+void dump_byline(unsigned char *data, uint32_t len, uint16_t mindex, uint16_t msize) {
if (len > 0) {
- const unsigned char *s = data;
+ const unsigned char *s = data;
+ uint8_t should_hilite = (msize && enable_hilite);
+ unsigned char *hilite_start = data + mindex;
+ unsigned char *hilite_end = hilite_start + msize;
while (s < data + len) {
+ if (should_hilite && s == hilite_start)
+ printf(ANSI_hilite);
+
printf("%c", (*s == '\n' || isprint(*s)) ? *s : nonprint_char);
s++;
+
+ if (should_hilite && s == hilite_end)
+ printf(ANSI_off);
}
printf("\n");
}
}
-void dump_unwrapped(unsigned char *data, uint32_t len) {
+void dump_unwrapped(unsigned char *data, uint32_t len, uint16_t mindex, uint16_t msize) {
if (len > 0) {
- const unsigned char *s = data;
+ const unsigned char *s = data;
+ uint8_t should_hilite = (msize && enable_hilite);
+ unsigned char *hilite_start = data + mindex;
+ unsigned char *hilite_end = hilite_start + msize;
while (s < data + len) {
+ if (should_hilite && s == hilite_start)
+ printf(ANSI_hilite);
+
printf("%c", isprint(*s) ? *s : nonprint_char);
s++;
+
+ if (should_hilite && s == hilite_end)
+ printf(ANSI_off);
}
printf("\n");
}
}
-void dump_formatted(unsigned char *data, uint32_t len) {
+void dump_formatted(unsigned char *data, uint32_t len, uint16_t mindex, uint16_t msize) {
if (len > 0) {
- unsigned char *str = data;
- uint8_t width = show_hex ? 16 : (ws_col-5);
- uint32_t i = 0,
- j = 0;
+ uint8_t should_hilite = (msize && enable_hilite);
+ unsigned char *str = data;
+ uint8_t hiliting = 0;
+ uint8_t width = show_hex ? 16 : (ws_col-5);
+ uint32_t i = 0,
+ j = 0;
while (i < len) {
printf(" ");
- if (show_hex)
+ if (show_hex) {
for (j = 0; j < width; j++) {
+ if (should_hilite && (mindex <= (i+j) && (i+j) < mindex + msize)) {
+ hiliting = 1;
+ printf(ANSI_hilite);
+ }
+
if (i + j < len)
printf("%02x ", str[j]);
else printf(" ");
if ((j+1) % (width/2) == 0)
printf(" ");
+
+ if (hiliting) {
+ hiliting = 0;
+ printf(ANSI_off);
+ }
}
+ }
- for (j = 0; j < width; j++)
+ for (j = 0; j < width; j++) {
+ if (should_hilite && mindex <= (i+j) && (i+j) < mindex + msize) {
+ hiliting = 1;
+ printf(ANSI_hilite);
+ }
+
if (i + j < len)
printf("%c", isprint(str[j]) ? str[j] : nonprint_char);
else printf(" ");
+ if (hiliting) {
+ hiliting = 0;
+ printf(ANSI_off);
+ }
+ }
+
str += width;
i += j;
@@ -1104,6 +1198,27 @@ void print_time_diff(struct pcap_pkthdr *h) {
prev_ts.tv_usec = h->ts.tv_usec;
}
+void print_time_offset(struct pcap_pkthdr *h) {
+ uint32_t secs, usecs;
+
+ secs = h->ts.tv_sec - prev_ts.tv_sec;
+ if (h->ts.tv_usec >= prev_ts.tv_usec)
+ usecs = h->ts.tv_usec - prev_ts.tv_usec;
+ else {
+ secs--;
+ usecs = 1000000 - (prev_ts.tv_usec - h->ts.tv_usec);
+ }
+
+ if (prev_ts.tv_sec == 0 && prev_ts.tv_usec == 0) {
+ prev_ts.tv_sec = h->ts.tv_sec;
+ prev_ts.tv_usec = h->ts.tv_usec;
+ secs = 0;
+ usecs = 0;
+ }
+
+ printf("+%u.%06u ", secs, usecs);
+}
+
void dump_delay_proc_init(struct pcap_pkthdr *h) {
dump_delay = &dump_delay_proc;
@@ -1155,26 +1270,36 @@ void dump_delay_proc(struct pcap_pkthdr *h) {
prev_delay_ts.tv_usec = h->ts.tv_usec;
}
-#if !defined(_WIN32)
void update_windowsize(int32_t e) {
if (e == 0 && ws_col_forced)
ws_col = ws_col_forced;
else if (!ws_col_forced) {
+
+#if !defined(_WIN32)
const struct winsize ws;
if (!ioctl(0, TIOCGWINSZ, &ws)) {
ws_row = ws.ws_row;
ws_col = ws.ws_col;
- } else {
+ }
+#else
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
+ ws_row = csbi.dwSize.Y;
+ ws_col = csbi.dwSize.X;
+ }
+#endif
+ else {
ws_row = 24;
ws_col = 80;
}
+
}
}
-#if USE_DROPPRIVS
+#if !defined(_WIN32) && USE_DROPPRIVS
void drop_privs(void) {
struct passwd *pw;
uid_t newuid;
@@ -1197,6 +1322,14 @@ void drop_privs(void) {
perror("attempt to drop privileges failed");
clean_exit(-1);
}
+ if (chroot("/var/empty") == -1) {
+ perror("attempt to drop privileges failed: chroot failed");
+ clean_exit(-1);
+ }
+ if (chdir("/") == -1) {
+ perror("attempt to drop privileges failed: chdir failed");
+ clean_exit(-1);
+ }
if (((getgid() != newgid) && (setgid(newgid) == -1)) ||
((getegid() != newgid) && (setegid(newgid) == -1)) ||
@@ -1209,7 +1342,6 @@ void drop_privs(void) {
}
#endif
-#endif
void usage(int8_t e) {
printf("usage: ngrep <-"
@@ -1234,6 +1366,7 @@ void usage(int8_t e) {
" -D is replay pcap_dumps with their recorded time intervals\n"
" -t is print timestamp every time a packet is matched\n"
" -T is print delta timestamp every time a packet is matched\n"
+ " specify twice for delta from first match\n"
" -M is don't do multi-line match (do single-line match instead)\n"
" -I is read packet stream from pcap format file pcap_dump\n"
" -O is dump matched packets in pcap format to pcap_dump\n"
@@ -1292,8 +1425,9 @@ void clean_exit(int32_t sig) {
&& pd && !pcap_stats(pd, &s))
printf("%u received, %u dropped\n", s.ps_recv, s.ps_drop);
- if (pd) pcap_close(pd);
- if (pd_dump) pcap_dump_close(pd_dump);
+ if (pd) pcap_close(pd);
+ if (pd_dumppcap) pcap_close(pd_dumppcap);
+ if (pd_dump) pcap_dump_close(pd_dump);
#if defined(_WIN32)
if (delay_socket) closesocket(delay_socket);
@@ -1379,6 +1513,28 @@ char *win32_usedevice(const char *index) {
}
pcap_freealldevs(alldevs);
+
+ return dev;
+}
+
+char *win32_choosedevice(void) {
+ pcap_if_t *alldevs, *d;
+ char errbuf[PCAP_ERRBUF_SIZE];
+ char *dev = NULL;
+
+ if (pcap_findalldevs(&alldevs, errbuf) == -1) {
+ perror("unable to enumerate devices");
+ clean_exit(-1);
+ }
+
+ for (d = alldevs; d != NULL; d = d->next)
+ if ((d->addresses) && (d->addresses->addr))
+ dev = _strdup(d->name);
+
+ pcap_freealldevs(alldevs);
+
+ if (!dev)
+ dev = pcap_lookupdev(errbuf);
return dev;
}