ongrep

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

commit 3d597962ad880110f68260c37310b9609dec5bea
parent 0b02814bfee10487a341d6d8541f67e164572323
Author: Stephen Gregoratto <dev@sgregoratto.me>
Date:   Sun, 14 Jun 2020 20:13:15 +1000

Start work on reformatting sources in KNF

Diffstat:
Mngrep.c | 2129++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mngrep.h | 81+++++++++++++++++++++++++++++++++++--------------------------------------------
2 files changed, 1120 insertions(+), 1090 deletions(-)

diff --git a/ngrep.c b/ngrep.c @@ -5,6 +5,7 @@ * Please refer to the LICENSE file for more information. * */ +#include <sys/cdefs.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/time.h> @@ -37,1157 +38,1195 @@ #include "ngrep.h" -/* - * Configuration Options - */ -uint32_t snaplen = 65535, limitlen = 65535, promisc = 1, to = 100; -uint32_t match_after = 0, keep_matching = 0, matches = 0, max_matches = 0; -uint32_t seen_frames = 0; - -uint8_t re_match_word = 0, re_ignore_case = 0, re_multiline_match = 1; -uint8_t show_empty = 0, show_hex = 0, show_proto = 0, quiet = 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; +/* Configuration Options */ +uint32_t snaplen = 65535, limitlen = 65535, promisc = 1, to = 100; +uint32_t match_after = 0, keep_matching = 0, matches = 0, max_matches = 0; +uint32_t seen_frames = 0; -char nonprint_char = '.'; +uint8_t re_match_word = 0, re_ignore_case = 0, re_multiline_match = 1; +uint8_t show_empty = 0, show_hex = 0, show_proto = 0, quiet = 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; -/* - * GNU Regex/PCRE - */ +char *read_file = NULL, *dump_file = NULL; +char *usedev = NULL; -int32_t err_offset; -char *re_err = NULL; +char nonprint_char = '.'; -pcre *pattern = NULL; -pcre_extra *pattern_extra = NULL; +/* PCRE and matching */ +int32_t err_offset; +char *re_err = NULL; -/* - * Matching - */ +pcre *pattern = NULL; +pcre_extra *pattern_extra = NULL; -char *match_data = NULL, *bin_data = NULL; -uint16_t match_len = 0; -int8_t (*match_func)() = &blank_match_func; +char *match_data = NULL, *bin_data = NULL; +uint16_t match_len = 0; +int8_t (*match_func)() = &blank_match_func; -int8_t dump_single = 0; -void (*dump_func)(unsigned char *, uint32_t, uint16_t, uint16_t) = &dump_formatted; +int8_t dump_single = 0; +void (*dump_func)(unsigned char *, uint32_t, uint16_t, uint16_t) = &dump_formatted; -/* - * BPF/Network - */ - -char *filter = NULL, *filter_file = NULL; -char pc_err[PCAP_ERRBUF_SIZE]; -uint8_t link_offset; -uint8_t radiotap_present = 0; -uint8_t include_vlan = 1; - -pcap_t *pd = NULL, *pd_dumppcap = NULL; -pcap_dumper_t *pd_dump = NULL; -struct bpf_program pcapfilter; -struct in_addr net, mask; - -/* - * Timestamp/delay functionality - */ +/* BPF/Network */ +char *filter = NULL, *filter_file = NULL; +char pc_err[PCAP_ERRBUF_SIZE]; +uint8_t link_offset; +uint8_t radiotap_present = 0; +uint8_t include_vlan = 1; -struct timeval prev_ts = {0, 0}, prev_delay_ts = {0,0}; -void (*print_time)() = NULL, (*dump_delay)() = dump_delay_proc_init; +pcap_t *pd = NULL, *pd_dumppcap = NULL; +pcap_dumper_t *pd_dump = NULL; +struct bpf_program pcapfilter; +struct in_addr net, mask; +/* Timestamp/delay functionality */ +struct timeval prev_ts = {0, 0}, prev_delay_ts = {0,0}; +void (*print_time)() = NULL, (*dump_delay)() = dump_delay_proc_init; /* - * Window-size functionality (adjust output based on width of console display) + * Window-size functionality + * (adjust output based on width of console display) */ - -uint32_t ws_row, ws_col = 80, ws_col_forced = 0; - - -int main(int argc, char **argv) { - int32_t c; - - signal(SIGINT, clean_exit); - signal(SIGABRT, clean_exit); - signal(SIGQUIT, clean_exit); - signal(SIGPIPE, clean_exit); - signal(SIGWINCH, update_windowsize); - - while ((c = getopt(argc, argv, "NhXViwqpevxlDtTRMCs:n:c:d:A:I:O:S:P:F: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 if (!strcasecmp(optarg, "single")) { - dump_func = &dump_unwrapped; - dump_single = 1; - } else { - printf("fatal: unknown wrap method '%s'\n", optarg); - usage(); - } - } break; - case 'F': - filter_file = optarg; - break; - case 'P': - nonprint_char = *optarg; - break; - case 'S': { - limitlen = _atoui32(optarg); - break; - } - case 'O': - dump_file = optarg; - break; - case 'I': - read_file = optarg; - break; - case 'A': - match_after = _atoui32(optarg); - if (match_after < UINT32_MAX) - match_after++; - break; - case 'd': - usedev = optarg; - break; - case 'c': - ws_col_forced = atoi(optarg); - break; - case 'n': - max_matches = _atoui32(optarg); - break; - case 's': { - uint16_t value = _atoui32(optarg); - if (value > 0) - snaplen = value; - } break; - case 'C': - enable_hilite = 1; - break; - case 'M': - re_multiline_match = 0; - break; - case 'R': - dont_dropprivs = 1; - break; - case 'T': - if (print_time == &print_time_diff) { - print_time = print_time_offset; - memset(&prev_ts, 0, sizeof(prev_ts)); - } else { - print_time = &print_time_diff; - gettimeofday(&prev_ts, NULL); - } - break; - case 't': - print_time = &print_time_absolute; - break; - case 'D': - want_delay = 1; - break; - case 'l': - setvbuf(stdout, NULL, _IOLBF, 0); - break; - case 'x': - show_hex++; - break; - case 'v': - invert_match++; - break; - case 'e': - show_empty++; - break; - case 'p': - promisc = 0; - break; - case 'q': - quiet++; - break; - case 'w': - re_match_word++; - break; - case 'i': - re_ignore_case++; - break; - case 'V': - version(); - case 'X': - bin_match++; - break; - case 'N': - show_proto++; - break; - case 'h': - usage(); - default: - usage(); - } - } - - if (show_hex && dump_func != &dump_formatted) { - printf("fatal: -x (hex dump) is incompatible with -W (alternate format)\n"); - usage(); - } - - if (argv[optind]) - match_data = argv[optind++]; - - /* Setup PCAP input */ - - if (setup_pcap_source()) - clean_exit(2); - - /* Setup BPF filter */ - - if (setup_bpf_filter(argv)) { - include_vlan = 0; - if (filter) { free(filter); filter = NULL; } - - if (setup_bpf_filter(argv)) { - pcap_perror(pd, "pcap"); - clean_exit(2); - } - } - - if (filter) { - if (quiet < 2) - printf("filter: %s\n", filter); - free(filter); - } - - /* Setup matcher */ - - if (match_data) { - if (setup_matcher()) - clean_exit(2); - - if (quiet < 2 && strlen(match_data)) - printf("%smatch: %s%s\n", invert_match?"don't ":"", - (bin_data && !strchr(match_data, 'x'))?"0x":"", match_data); - - if (re_match_word) free(match_data); - } - - /* Misc */ - - if (dump_file) { - pd_dump = pcap_dump_open(pd, dump_file); - if (!pd_dump) { - fprintf(stderr, "fatal: %s\n", pcap_geterr(pd)); - clean_exit(2); - } else printf("output: %s\n", dump_file); - } - - update_windowsize(0); - - drop_privs(); - - while (pcap_loop(pd, -1, (pcap_handler)process, 0)); - - clean_exit(0); - - /* NOT REACHED */ - return 0; +uint32_t ws_row, ws_col = 80, ws_col_forced = 0; + +const char *optstring = "nhXiwqpevxlDtTRMCs:n:c:d:A:I:O:S:P:F:W:"; + +int +main(int argc, char **argv) +{ + int c; + + signal(SIGINT, clean_exit); + signal(SIGABRT, clean_exit); + signal(SIGQUIT, clean_exit); + signal(SIGPIPE, clean_exit); + signal(SIGWINCH, update_windowsize); + + while ((c = getopt(argc, argv, optstring)) != 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 if (!strcasecmp(optarg, "single")) { + dump_func = &dump_unwrapped; + dump_single = 1; + } else { + printf("fatal: unknown wrap method '%s'\n", optarg); + usage(); + } + break; + case 'F': + filter_file = optarg; + break; + case 'P': + nonprint_char = *optarg; + break; + case 'S': + limitlen = _atoui32(optarg); + break; + case 'O': + dump_file = optarg; + break; + case 'I': + read_file = optarg; + break; + case 'A': + match_after = _atoui32(optarg); + if (match_after < UINT32_MAX) + match_after++; + break; + case 'd': + usedev = optarg; + break; + case 'c': + ws_col_forced = atoi(optarg); + break; + case 'n': + max_matches = _atoui32(optarg); + break; + case 's':{ + uint16_t value = _atoui32(optarg); + if (value > 0) + snaplen = value; + } break; + case 'C': + enable_hilite = 1; + break; + case 'M': + re_multiline_match = 0; + break; + case 'R': + dont_dropprivs = 1; + break; + case 'T': + if (print_time == &print_time_diff) { + print_time = print_time_offset; + memset(&prev_ts, 0, sizeof(prev_ts)); + } else { + print_time = &print_time_diff; + gettimeofday(&prev_ts, NULL); + } + break; + case 't': + print_time = &print_time_absolute; + break; + case 'D': + want_delay = 1; + break; + case 'l': + setvbuf(stdout, NULL, _IOLBF, 0); + break; + case 'x': + show_hex++; + break; + case 'v': + invert_match++; + break; + case 'e': + show_empty++; + break; + case 'p': + promisc = 0; + break; + case 'q': + quiet++; + break; + case 'w': + re_match_word++; + break; + case 'i': + re_ignore_case++; + break; + case 'X': + bin_match++; + break; + case 'N': + show_proto++; + break; + case 'h': + /* FALLTHROUGH */ + default: + usage(); + } + } + + if (show_hex && dump_func != &dump_formatted) { + printf("fatal: -x (hex dump) is incompatible with -W (alternate format)\n"); + usage(); + } + if (argv[optind]) + match_data = argv[optind++]; + + /* Setup PCAP input */ + if (setup_pcap_source()) + clean_exit(2); + + /* Setup BPF filter */ + if (setup_bpf_filter(argv)) { + include_vlan = 0; + if (filter) { + free(filter); + filter = NULL; + } + if (setup_bpf_filter(argv)) { + pcap_perror(pd, "pcap"); + clean_exit(2); + } + } + if (filter) { + if (quiet < 2) + printf("filter: %s\n", filter); + free(filter); + } + + /* Setup matcher */ + if (match_data) { + if (setup_matcher()) + clean_exit(2); + + if (quiet < 2 && strlen(match_data)) + printf("%smatch: %s%s\n", invert_match ? "don't " : "", + (bin_data && !strchr(match_data, 'x')) ? "0x" : "", match_data); + + if (re_match_word) + free(match_data); + } + + /* Misc */ + if (dump_file) { + pd_dump = pcap_dump_open(pd, dump_file); + if (!pd_dump) { + fprintf(stderr, "fatal: %s\n", pcap_geterr(pd)); + clean_exit(2); + } else + printf("output: %s\n", dump_file); + } + update_windowsize(0); + + drop_privs(); + + while (pcap_loop(pd, -1, (pcap_handler)process, 0)); + + clean_exit(0); + + /* NOT REACHED */ + return 0; } -int setup_pcap_source(void) { - if (read_file) { - - if (!(pd = pcap_open_offline(read_file, pc_err))) { - perror(pc_err); - return 1; - } - - live_read = 0; - printf("input: %s\n", read_file); - - } else { - - char *dev = usedev ? usedev : pcap_lookupdev(pc_err); - - if (!dev) { - perror(pc_err); - return 1; - } - - if ((pd = pcap_open_live(dev, snaplen, promisc, to, pc_err)) == NULL) { - perror(pc_err); - return 1; - } - - if (pcap_lookupnet(dev, &net.s_addr, &mask.s_addr, pc_err) == -1) { - perror(pc_err); - memset(&net, 0, sizeof(net)); - memset(&mask, 0, sizeof(mask)); - } - - if (quiet < 2) { - printf("interface: %s", dev); - if (net.s_addr && mask.s_addr) { - printf(" (%s/", inet_ntoa(net)); - printf("%s)", inet_ntoa(mask)); - } - printf("\n"); - } - } - - switch(pcap_datalink(pd)) { - case DLT_EN10MB: - link_offset = ETHHDR_SIZE; - break; - - case DLT_IEEE802: - link_offset = TOKENRING_SIZE; - break; - - case DLT_FDDI: - link_offset = FDDIHDR_SIZE; - break; - - case DLT_SLIP: - link_offset = SLIPHDR_SIZE; - break; - - case DLT_PPP: - link_offset = PPPHDR_SIZE; - break; - case DLT_LOOP: - case DLT_NULL: - link_offset = LOOPHDR_SIZE; - break; - case DLT_RAW: - link_offset = RAWHDR_SIZE; - break; - case DLT_IEEE802_11_RADIO: - radiotap_present = 1; - case DLT_IEEE802_11: - link_offset = IEEE80211HDR_SIZE; - break; - case DLT_PFLOG: - link_offset = PFLOGHDR_SIZE; - break; - default: - fprintf(stderr, "fatal: unsupported interface type %u\n", pcap_datalink(pd)); - return 1; - } - - return 0; +int +setup_pcap_source(void) +{ + if (read_file) { + if (!(pd = pcap_open_offline(read_file, pc_err))) { + perror(pc_err); + return 1; + } + live_read = 0; + printf("input: %s\n", read_file); + } else { + char *dev = usedev ? usedev : pcap_lookupdev(pc_err); + + if (!dev) { + perror(pc_err); + return 1; + } + if ((pd = pcap_open_live(dev, snaplen, promisc, to, pc_err)) == NULL) { + perror(pc_err); + return 1; + } + if (pcap_lookupnet(dev, &net.s_addr, &mask.s_addr, pc_err) == -1) { + perror(pc_err); + memset(&net, 0, sizeof(net)); + memset(&mask, 0, sizeof(mask)); + } + if (quiet < 2) { + printf("interface: %s", dev); + if (net.s_addr && mask.s_addr) { + printf(" (%s/", inet_ntoa(net)); + printf("%s)", inet_ntoa(mask)); + } + printf("\n"); + } + } + + switch (pcap_datalink(pd)) { + case DLT_EN10MB: + link_offset = ETHHDR_SIZE; + break; + case DLT_IEEE802: + link_offset = TOKENRING_SIZE; + break; + case DLT_FDDI: + link_offset = FDDIHDR_SIZE; + break; + case DLT_SLIP: + link_offset = SLIPHDR_SIZE; + break; + case DLT_PPP: + link_offset = PPPHDR_SIZE; + break; + case DLT_LOOP: + /* FALLTHROUGH */ + case DLT_NULL: + link_offset = LOOPHDR_SIZE; + break; + case DLT_RAW: + link_offset = RAWHDR_SIZE; + break; + case DLT_IEEE802_11_RADIO: + radiotap_present = 1; + case DLT_IEEE802_11: + link_offset = IEEE80211HDR_SIZE; + break; + case DLT_PFLOG: + link_offset = PFLOGHDR_SIZE; + break; + default: + fprintf(stderr, "fatal: unsupported interface type %u\n", pcap_datalink(pd)); + return 1; + } + + return 0; } -int setup_bpf_filter(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(); - } - - fclose(f); - - filter = get_filter_from_string(buf); +int +setup_bpf_filter(char **argv) +{ + if (filter_file) { + char buf[1024] = {0}; + FILE *f = fopen(filter_file, "r"); - if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) - return 1; + if (!f || !fgets(buf, sizeof(buf) - 1, f)) { + fprintf(stderr, "fatal: unable to get filter from %s: %s\n", filter_file, strerror(errno)); + usage(); + } + fclose(f); - } else if (argv[optind]) { - filter = get_filter_from_argv(&argv[optind]); + filter = get_filter_from_string(buf); - if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) { - free(filter); - filter = get_filter_from_argv(&argv[optind-1]); + if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) + return 1; + } else if (argv[optind]) { + filter = get_filter_from_argv(&argv[optind]); - if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) - return 1; + if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) { + free(filter); + filter = get_filter_from_argv(&argv[optind - 1]); - match_data = NULL; - } + if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) + return 1; - } else { - filter = include_vlan ? strdup(BPF_TEMPLATE_IP_VLAN) : strdup(BPF_TEMPLATE_IP); + match_data = NULL; + } + } else { + filter = include_vlan ? strdup(BPF_TEMPLATE_IP_VLAN) : strdup(BPF_TEMPLATE_IP); - if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) - return 1; - } + if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) + return 1; + } - if (pcap_setfilter(pd, &pcapfilter)) - return 1; + if (pcap_setfilter(pd, &pcapfilter)) + return 1; - return 0; + return 0; } -int setup_matcher(void) { - if (bin_match) { - uint32_t i = 0, n; - uint32_t len; - char *s, *d; - - if (re_match_word || re_ignore_case) { - fprintf(stderr, "fatal: regex switches are incompatible with binary matching\n"); - return 1; - } - - len = (uint32_t)strlen(match_data); - if (len % 2 != 0 || !strishex(match_data)) { - fprintf(stderr, "fatal: invalid hex string specified\n"); - return 1; - } - - bin_data = (char*)malloc(len / 2); - memset(bin_data, 0, len / 2); - d = bin_data; - - if ((s = strchr(match_data, 'x'))) - len -= (uint32_t)(++s - match_data - 1); - else s = match_data; - - while (i <= len) { - sscanf(s+i, "%2x", &n); - *d++ = n; - i += 2; - } - - match_len = len / 2; - match_func = &bin_match_func; - - } else { - - uint32_t pcre_options = PCRE_UNGREEDY; - - if (re_ignore_case) - pcre_options |= PCRE_CASELESS; - - if (re_multiline_match) - pcre_options |= PCRE_DOTALL; - - if (re_match_word) { - char *word_regex = (char*)malloc(strlen(match_data) * 3 + strlen(WORD_REGEX)); - sprintf(word_regex, WORD_REGEX, match_data, match_data, match_data); - match_data = word_regex; - } - - pattern = pcre_compile(match_data, pcre_options, (const char **)&re_err, &err_offset, 0); - - if (!pattern) { - fprintf(stderr, "compile failed: %s\n", re_err); - return 1; - } - - pattern_extra = pcre_study(pattern, 0, (const char **)&re_err); - match_func = &re_match_func; - } - - return 0; +int +setup_matcher(void) +{ + if (bin_match) { + uint32_t i = 0, n; + uint32_t len; + char *s, *d; + + if (re_match_word || re_ignore_case) { + fprintf(stderr, "fatal: regex switches are incompatible with binary matching\n"); + return 1; + } + len = (uint32_t) strlen(match_data); + if (len % 2 != 0 || !strishex(match_data)) { + fprintf(stderr, "fatal: invalid hex string specified\n"); + return 1; + } + bin_data = (char *) malloc(len / 2); + memset(bin_data, 0, len / 2); + d = bin_data; + + if ((s = strchr(match_data, 'x'))) + len -= (uint32_t) (++s - match_data - 1); + else + s = match_data; + + while (i <= len) { + sscanf(s + i, "%2x", &n); + *d++ = n; + i += 2; + } + + match_len = len / 2; + match_func = &bin_match_func; + + } else { + uint32_t pcre_options = PCRE_UNGREEDY; + + if (re_ignore_case) + pcre_options |= PCRE_CASELESS; + + if (re_multiline_match) + pcre_options |= PCRE_DOTALL; + + if (re_match_word) { + char *word_regex = (char *) malloc(strlen(match_data) * 3 + strlen(WORD_REGEX)); + sprintf(word_regex, WORD_REGEX, match_data, match_data, match_data); + match_data = word_regex; + } + pattern = pcre_compile(match_data, pcre_options, (const char **) &re_err, &err_offset, 0); + + if (!pattern) { + fprintf(stderr, "compile failed: %s\n", re_err); + return 1; + } + pattern_extra = pcre_study(pattern, 0, (const char **) &re_err); + match_func = &re_match_func; + } + + return 0; } -static inline uint8_t vlan_frame_count(u_char *p, uint16_t limit) { - uint8_t *et = (uint8_t*)(p + 12); - uint16_t ether_type = EXTRACT_16BITS(et); - uint8_t count = 0; - - while ((void*)et < (void*)(p + limit) && - ether_type != ETHERTYPE_IP && - ether_type != ETHERTYPE_IPV6) { - count++; - et += VLANHDR_SIZE; - ether_type = EXTRACT_16BITS(et); - } - - return count; +static inline uint8_t +vlan_frame_count(u_char * p, uint16_t limit) +{ + uint8_t *et = (uint8_t *) (p + 12); + uint16_t ether_type = EXTRACT_16BITS(et); + uint8_t count = 0; + + while ((void *) et < (void *) (p + limit) && + ether_type != ETHERTYPE_IP && + ether_type != ETHERTYPE_IPV6) { + count++; + et += VLANHDR_SIZE; + ether_type = EXTRACT_16BITS(et); + } + + return count; } -void process(u_char *d, struct pcap_pkthdr *h, u_char *p) { - uint8_t vlan_offset = include_vlan ? vlan_frame_count(p, h->caplen) * VLANHDR_SIZE : 0; - - struct ip *ip4_pkt = (struct ip *) (p + link_offset + vlan_offset); - struct ip6_hdr *ip6_pkt = (struct ip6_hdr*)(p + link_offset + vlan_offset); - - uint32_t ip_ver; - - uint8_t ip_proto = 0; - uint32_t ip_hl = 0; - uint32_t ip_off = 0; - - uint8_t fragmented = 0; - uint16_t frag_offset = 0; - uint32_t frag_id = 0; - - char ip_src[INET6_ADDRSTRLEN + 1], - ip_dst[INET6_ADDRSTRLEN + 1]; - - unsigned char *data; - uint32_t len = h->caplen - vlan_offset; - - seen_frames++; - - if (radiotap_present) { - uint16_t radio_len = ((struct NGREP_rtaphdr_t *)(p))->it_len; - ip4_pkt = (struct ip *)(p + link_offset + radio_len); - len -= radio_len; - } - - ip_ver = ip4_pkt->ip_v; - - switch (ip_ver) { - - case 4: { - ip_hl = ip4_pkt->ip_hl * 4; - ip_proto = ip4_pkt->ip_p; - ip_off = ntohs(ip4_pkt->ip_off); - - fragmented = ip_off & (IP_MF | IP_OFFMASK); - frag_offset = (fragmented) ? (ip_off & IP_OFFMASK) * 8 : 0; - frag_id = ntohs(ip4_pkt->ip_id); - - inet_ntop(AF_INET, (const void *)&ip4_pkt->ip_src, ip_src, sizeof(ip_src)); - inet_ntop(AF_INET, (const void *)&ip4_pkt->ip_dst, ip_dst, sizeof(ip_dst)); - } break; - case 6: { - ip_hl = sizeof(struct ip6_hdr); - ip_proto = ip6_pkt->ip6_nxt; - - if (ip_proto == IPPROTO_FRAGMENT) { - struct ip6_frag *ip6_fraghdr; - - ip6_fraghdr = (struct ip6_frag *)((unsigned char *)(ip6_pkt) + ip_hl); - ip_hl += sizeof(struct ip6_frag); - ip_proto = ip6_fraghdr->ip6f_nxt; - - fragmented = 1; - frag_offset = ntohs(ip6_fraghdr->ip6f_offlg & IP6F_OFF_MASK); - frag_id = ntohl(ip6_fraghdr->ip6f_ident); - } - - inet_ntop(AF_INET6, (const void *)&ip6_pkt->ip6_src, ip_src, sizeof(ip_src)); - inet_ntop(AF_INET6, (const void *)&ip6_pkt->ip6_dst, ip_dst, sizeof(ip_dst)); - } break; - } - - if (quiet < 1) { - printf("#"); - fflush(stdout); - } - - switch (ip_proto) { - case IPPROTO_TCP: { - struct tcphdr *tcp_pkt = (struct tcphdr *)((unsigned char *)(ip4_pkt) + ip_hl); - uint16_t tcphdr_offset = (frag_offset) ? 0 : (tcp_pkt->th_off * 4); - - data = (unsigned char *)(tcp_pkt) + tcphdr_offset; - len -= link_offset + ip_hl + tcphdr_offset; - - if ((int32_t)len < 0) - len = 0; - - dump_packet(h, p, ip_proto, data, len, - ip_src, ip_dst, ntohs(tcp_pkt->th_sport), ntohs(tcp_pkt->th_dport), tcp_pkt->th_flags, - tcphdr_offset, fragmented, frag_offset, frag_id); - } break; - - case IPPROTO_UDP: { - struct udphdr *udp_pkt = (struct udphdr *)((unsigned char *)(ip4_pkt) + ip_hl); - uint16_t udphdr_offset = (frag_offset) ? 0 : sizeof(*udp_pkt); - - data = (unsigned char *)(udp_pkt) + udphdr_offset; - len -= link_offset + ip_hl + udphdr_offset; - - if ((int32_t)len < 0) - len = 0; - - dump_packet(h, p, ip_proto, data, len, ip_src, ip_dst, - ntohs(udp_pkt->uh_sport), ntohs(udp_pkt->uh_dport), 0, - udphdr_offset, fragmented, frag_offset, frag_id); - } break; - - case IPPROTO_ICMP: { - struct icmp *icmp4_pkt = (struct icmp *)((unsigned char *)(ip4_pkt) + ip_hl); - uint16_t icmp4hdr_offset = (frag_offset) ? 0 : 4; - - data = (unsigned char *)(icmp4_pkt) + icmp4hdr_offset; - len -= link_offset + ip_hl + icmp4hdr_offset; - - if ((int32_t)len < 0) - len = 0; - - dump_packet(h, p, ip_proto, data, len, - ip_src, ip_dst, icmp4_pkt->icmp_type, icmp4_pkt->icmp_code, 0, - icmp4hdr_offset, fragmented, frag_offset, frag_id); - } break; - case IPPROTO_ICMPV6: { - struct icmp6_hdr *icmp6_pkt = (struct icmp6_hdr *)((unsigned char *)(ip6_pkt) + ip_hl); - uint16_t icmp6hdr_offset = (frag_offset) ? 0 : 4; - - data = (unsigned char *)(icmp6_pkt) + icmp6hdr_offset; - len -= link_offset + ip_hl + icmp6hdr_offset; - - if ((int32_t)len < 0) - len = 0; - - dump_packet(h, p, ip_proto, data, len, - ip_src, ip_dst, icmp6_pkt->icmp6_type, icmp6_pkt->icmp6_code, 0, - icmp6hdr_offset, fragmented, frag_offset, frag_id); - } break; - case IPPROTO_IGMP: { - struct igmp *igmp_pkt = (struct igmp *)((unsigned char *)(ip4_pkt) + ip_hl); - uint16_t igmphdr_offset = (frag_offset) ? 0 : 4; - - data = (unsigned char *)(igmp_pkt) + igmphdr_offset; - len -= link_offset + ip_hl + igmphdr_offset; - - if ((int32_t)len < 0) - len = 0; - - dump_packet(h, p, ip_proto, data, len, - ip_src, ip_dst, igmp_pkt->igmp_type, igmp_pkt->igmp_code, 0, - igmphdr_offset, fragmented, frag_offset, frag_id); - } break; - - default: { - data = (unsigned char *)(ip4_pkt) + ip_hl; - len -= link_offset + ip_hl; - - if ((int32_t)len < 0) - len = 0; - - dump_packet(h, p, ip_proto, data, len, - ip_src, ip_dst, 0, 0, 0, - 0, fragmented, frag_offset, frag_id); - } break; - - } - - if (max_matches && matches >= max_matches) - clean_exit(0); - - if (match_after && keep_matching) - keep_matching--; +void +process(u_char *d, struct pcap_pkthdr *h, u_char *p) +{ + uint8_t vlan_offset = include_vlan ? + vlan_frame_count(p, h->caplen) * VLANHDR_SIZE : 0; + + struct ip *ip4_pkt = (struct ip *) (p + link_offset + vlan_offset); + struct ip6_hdr *ip6_pkt = (struct ip6_hdr *) (p + link_offset + vlan_offset); + + uint32_t ip_ver; + + uint8_t ip_proto = 0; + uint32_t ip_hl = 0; + uint32_t ip_off = 0; + + uint8_t fragmented = 0; + uint16_t frag_offset = 0; + uint32_t frag_id = 0; + + char ip_src[INET6_ADDRSTRLEN + 1]; + char ip_dst[INET6_ADDRSTRLEN + 1]; + + unsigned char *data; + uint32_t len = h->caplen - vlan_offset; + + seen_frames++; + + if (radiotap_present) { + uint16_t radio_len = ((struct NGREP_rtaphdr_t *) (p))->it_len; + ip4_pkt = (struct ip *) (p + link_offset + radio_len); + len -= radio_len; + } + ip_ver = ip4_pkt->ip_v; + + switch (ip_ver) { + case 4:{ + ip_hl = ip4_pkt->ip_hl * 4; + ip_proto = ip4_pkt->ip_p; + ip_off = ntohs(ip4_pkt->ip_off); + + fragmented = ip_off & (IP_MF | IP_OFFMASK); + frag_offset = (fragmented) ? (ip_off & IP_OFFMASK) * 8 : 0; + frag_id = ntohs(ip4_pkt->ip_id); + + inet_ntop(AF_INET, (const void *) &ip4_pkt->ip_src, ip_src, sizeof(ip_src)); + inet_ntop(AF_INET, (const void *) &ip4_pkt->ip_dst, ip_dst, sizeof(ip_dst)); + } break; + case 6:{ + ip_hl = sizeof(struct ip6_hdr); + ip_proto = ip6_pkt->ip6_nxt; + + if (ip_proto == IPPROTO_FRAGMENT) { + struct ip6_frag *ip6_fraghdr; + + ip6_fraghdr = (struct ip6_frag *) ((unsigned char *) (ip6_pkt) + ip_hl); + ip_hl += sizeof(struct ip6_frag); + ip_proto = ip6_fraghdr->ip6f_nxt; + + fragmented = 1; + frag_offset = ntohs(ip6_fraghdr->ip6f_offlg & IP6F_OFF_MASK); + frag_id = ntohl(ip6_fraghdr->ip6f_ident); + } + inet_ntop(AF_INET6, (const void *) &ip6_pkt->ip6_src, ip_src, sizeof(ip_src)); + inet_ntop(AF_INET6, (const void *) &ip6_pkt->ip6_dst, ip_dst, sizeof(ip_dst)); + } break; + } + + if (quiet < 1) { + printf("#"); + fflush(stdout); + } + + switch (ip_proto) { + case IPPROTO_TCP:{ + struct tcphdr *tcp_pkt = (struct tcphdr *) ((unsigned char *) (ip4_pkt) + ip_hl); + uint16_t tcphdr_offset = (frag_offset) ? 0 : (tcp_pkt->th_off * 4); + + data = (unsigned char *) (tcp_pkt) + tcphdr_offset; + len -= link_offset + ip_hl + tcphdr_offset; + + if ((int32_t) len < 0) + len = 0; + + dump_packet(h, p, ip_proto, data, len, + ip_src, ip_dst, ntohs(tcp_pkt->th_sport), ntohs(tcp_pkt->th_dport), tcp_pkt->th_flags, + tcphdr_offset, fragmented, frag_offset, frag_id); + } break; + case IPPROTO_UDP:{ + struct udphdr *udp_pkt = (struct udphdr *) ((unsigned char *) (ip4_pkt) + ip_hl); + uint16_t udphdr_offset = (frag_offset) ? 0 : sizeof(*udp_pkt); + + data = (unsigned char *) (udp_pkt) + udphdr_offset; + len -= link_offset + ip_hl + udphdr_offset; + + if ((int32_t) len < 0) + len = 0; + + dump_packet(h, p, ip_proto, data, len, ip_src, ip_dst, + ntohs(udp_pkt->uh_sport), ntohs(udp_pkt->uh_dport), 0, + udphdr_offset, fragmented, frag_offset, frag_id); + } break; + + case IPPROTO_ICMP:{ + struct icmp *icmp4_pkt = (struct icmp *) ((unsigned char *) (ip4_pkt) + ip_hl); + uint16_t icmp4hdr_offset = (frag_offset) ? 0 : 4; + + data = (unsigned char *) (icmp4_pkt) + icmp4hdr_offset; + len -= link_offset + ip_hl + icmp4hdr_offset; + + if ((int32_t) len < 0) + len = 0; + + dump_packet(h, p, ip_proto, data, len, + ip_src, ip_dst, icmp4_pkt->icmp_type, icmp4_pkt->icmp_code, 0, + icmp4hdr_offset, fragmented, frag_offset, frag_id); + } break; + case IPPROTO_ICMPV6:{ + struct icmp6_hdr *icmp6_pkt = (struct icmp6_hdr *) ((unsigned char *) (ip6_pkt) + ip_hl); + uint16_t icmp6hdr_offset = (frag_offset) ? 0 : 4; + + data = (unsigned char *) (icmp6_pkt) + icmp6hdr_offset; + len -= link_offset + ip_hl + icmp6hdr_offset; + + if ((int32_t) len < 0) + len = 0; + + dump_packet(h, p, ip_proto, data, len, + ip_src, ip_dst, icmp6_pkt->icmp6_type, icmp6_pkt->icmp6_code, 0, + icmp6hdr_offset, fragmented, frag_offset, frag_id); + } break; + case IPPROTO_IGMP:{ + struct igmp *igmp_pkt = (struct igmp *) ((unsigned char *) (ip4_pkt) + ip_hl); + uint16_t igmphdr_offset = (frag_offset) ? 0 : 4; + + data = (unsigned char *) (igmp_pkt) + igmphdr_offset; + len -= link_offset + ip_hl + igmphdr_offset; + + if ((int32_t) len < 0) + len = 0; + + dump_packet(h, p, ip_proto, data, len, + ip_src, ip_dst, igmp_pkt->igmp_type, igmp_pkt->igmp_code, 0, + igmphdr_offset, fragmented, frag_offset, frag_id); + } break; + + default:{ + data = (unsigned char *) (ip4_pkt) + ip_hl; + len -= link_offset + ip_hl; + + if ((int32_t) len < 0) + len = 0; + + dump_packet(h, p, ip_proto, data, len, + ip_src, ip_dst, 0, 0, 0, + 0, fragmented, frag_offset, frag_id); + } break; + + } + + if (max_matches && matches >= max_matches) + clean_exit(0); + + if (match_after && keep_matching) + keep_matching--; } -void dump_packet(struct pcap_pkthdr *h, u_char *p, uint8_t proto, unsigned char *data, uint32_t len, - 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, &match_index, &match_size) == invert_match) && !keep_matching) - return; - - if (!live_read && want_delay) - dump_delay(h); - - { - char ident; - - switch (proto) { - case IPPROTO_TCP: ident = TCP; break; - case IPPROTO_UDP: ident = UDP; break; - case IPPROTO_ICMP: ident = ICMP; break; - case IPPROTO_ICMPV6: ident = ICMPv6; break; - case IPPROTO_IGMP: ident = IGMP; break; - default: ident = UNKNOWN; break; - } - - printf("\n%c", ident); - } - - if (show_proto) - printf("(%u)", proto); - - printf(" "); - - if (print_time) - print_time(h); - - if ((proto == IPPROTO_TCP || proto == IPPROTO_UDP) && (sport || dport) && (hdr_offset || frag_offset == 0)) - - printf("%s:%u -> %s:%u", ip_src, sport, ip_dst, dport); - - else - - printf("%s -> %s", ip_src, ip_dst); - - if (proto == IPPROTO_TCP && flags) - printf(" [%s%s%s%s%s%s%s%s]", - (flags & TH_ACK) ? "A" : "", - (flags & TH_SYN) ? "S" : "", - (flags & TH_RST) ? "R" : "", - (flags & TH_FIN) ? "F" : "", - (flags & TH_URG) ? "U" : "", - (flags & TH_PUSH)? "P" : "", - (flags & TH_ECE) ? "E" : "", - (flags & TH_CWR) ? "C" : ""); - - switch (proto) { - case IPPROTO_ICMP: - case IPPROTO_ICMPV6: - case IPPROTO_IGMP: - printf(" %u:%u", sport, dport); - } - - if (frag) - printf(" %s%u@%u:%u", - frag_offset?"+":"", frag_id, frag_offset, len); - - if (dump_single) - printf(" "); - else - printf(" #%u\n", seen_frames); - - if (quiet < 3) - dump_func(data, len, match_index, match_size); - - if (pd_dump) - pcap_dump((u_char*)pd_dump, h, p); +void +dump_packet(struct pcap_pkthdr *h, u_char *p, uint8_t proto, + unsigned char *data, uint32_t len, 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; + char ident; + + if (!show_empty && len == 0) + return; + + if (len > limitlen) + len = limitlen; + + if (len > 0 && + match_func(data, len, &match_index, &match_size) == invert_match && + !keep_matching) + return; + + if (!live_read && want_delay) + dump_delay(h); + + switch (proto) { + case IPPROTO_TCP: + ident = TCP; + break; + case IPPROTO_UDP: + ident = UDP; + break; + case IPPROTO_ICMP: + ident = ICMP; + break; + case IPPROTO_ICMPV6: + ident = ICMPv6; + break; + case IPPROTO_IGMP: + ident = IGMP; + break; + default: + ident = UNKNOWN; + break; + } + + printf("\n%c", ident); + + if (show_proto) + printf("(%u)", proto); + + printf(" "); + + if (print_time) + print_time(h); + + if ((proto == IPPROTO_TCP || proto == IPPROTO_UDP) && + (sport || dport) && + (hdr_offset || frag_offset == 0)) + printf("%s:%u -> %s:%u", ip_src, sport, ip_dst, dport); + else + printf("%s -> %s", ip_src, ip_dst); + + if (proto == IPPROTO_TCP && flags) + printf(" [%s%s%s%s%s%s%s%s]", + (flags & TH_ACK) ? "A" : "", + (flags & TH_SYN) ? "S" : "", + (flags & TH_RST) ? "R" : "", + (flags & TH_FIN) ? "F" : "", + (flags & TH_URG) ? "U" : "", + (flags & TH_PUSH) ? "P" : "", + (flags & TH_ECE) ? "E" : "", + (flags & TH_CWR) ? "C" : ""); + + switch (proto) { + case IPPROTO_ICMP: + /* FALLTHROUTH */ + case IPPROTO_ICMPV6: + /* FALLTHROUGH */ + case IPPROTO_IGMP: + printf(" %u:%u", sport, dport); + } + + if (frag) + printf(" %s%u@%u:%u", + frag_offset ? "+" : "", frag_id, frag_offset, len); + + if (dump_single) + printf(" "); + else + printf(" #%u\n", seen_frames); + + if (quiet < 3) + 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, uint16_t *mindex, uint16_t *msize) { - 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: - case PCRE_ERROR_UNKNOWN_NODE: - case PCRE_ERROR_NOMEMORY: - perror("she's dead, jim\n"); - clean_exit(2); - - case PCRE_ERROR_NOMATCH: - return 0; - - default: - *mindex = sub[0]; - *msize = sub[1] - sub[0]; - } - matches++; - - if (match_after && keep_matching != match_after) - keep_matching = match_after; - - return 1; +int8_t +re_match_func(unsigned char *data, uint32_t len, uint16_t *mindex, + uint16_t *msize) +{ + static int sub [2]; + int did_match = pcre_exec(pattern, 0, (const char *)data, (int32_t)len, + 0, 0, 0, 0); + if (did_match < 0) { + switch (did_match) { + case PCRE_ERROR_NULL: + case PCRE_ERROR_BADOPTION: + case PCRE_ERROR_BADMAGIC: + case PCRE_ERROR_UNKNOWN_NODE: + case PCRE_ERROR_NOMEMORY: + perror("she's dead, jim\n"); + clean_exit(2); + case PCRE_ERROR_NOMATCH: + return 0; + } + } + + *mindex = sub[0]; + *msize = sub[1] - sub[0]; + matches++; + + if (match_after && keep_matching != match_after) + keep_matching = match_after; + + return 1; } -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; +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; - if (stop < 0) - return 0; + if (stop < 0) + return 0; - while (i <= stop) - if (!memcmp(data+(i++), bin_data, match_len)) { - matches++; + while (i <= stop) { + if (!memcmp(data + (i++), bin_data, match_len)) { + matches++; - if (match_after && keep_matching != match_after) - keep_matching = match_after; + if (match_after && keep_matching != match_after) + keep_matching = match_after; - *mindex = i - 1; - *msize = match_len; + *mindex = i - 1; + *msize = match_len; - return 1; - } - - return 0; + return 1; + } + } + return 0; } -int8_t blank_match_func(unsigned char *data, uint32_t len, uint16_t *mindex, uint16_t *msize) { - matches++; +int8_t +blank_match_func(unsigned char *data, uint32_t len, uint16_t *mindex, + uint16_t *msize) +{ + matches++; - *mindex = 0; - *msize = 0; + *mindex = 0; + *msize = 0; - return 1; + return 1; } -void dump_byline(unsigned char *data, uint32_t len, uint16_t mindex, uint16_t msize) { - if (len > 0) { - 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("%s", ANSI_hilite); - - printf("%c", (*s == '\n' || isprint(*s)) ? *s : nonprint_char); - s++; - - if (should_hilite && s == hilite_end) - printf("%s", ANSI_off); - } - - printf("\n"); - } +void +dump_byline(unsigned char *data, uint32_t len, uint16_t mindex, uint16_t msize) +{ + if (len > 0) { + 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("%s", ANSI_hilite); + + printf("%c", + (*s == '\n' || isprint(*s)) ? *s : nonprint_char); + s++; + + if (should_hilite && s == hilite_end) + printf("%s", ANSI_off); + } + + printf("\n"); + } } -void dump_unwrapped(unsigned char *data, uint32_t len, uint16_t mindex, uint16_t msize) { - if (len > 0) { - 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("%s", ANSI_hilite); - - printf("%c", isprint(*s) ? *s : nonprint_char); - s++; - - if (should_hilite && s == hilite_end) - printf("%s", ANSI_off); - } - - printf("\n"); - } +void +dump_unwrapped(unsigned char *data, uint32_t len, uint16_t mindex, + uint16_t msize) +{ + if (len > 0) { + 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("%s", ANSI_hilite); + + printf("%c", isprint(*s) ? *s : nonprint_char); + s++; + + if (should_hilite && s == hilite_end) + printf("%s", ANSI_off); + } + + printf("\n"); + } } -void dump_formatted(unsigned char *data, uint32_t len, uint16_t mindex, uint16_t msize) { - if (len > 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) { - for (j = 0; j < width; j++) { - if (should_hilite && (mindex <= (i+j) && (i+j) < mindex + msize)) { - hiliting = 1; - printf("%s", ANSI_hilite); - } - - if (i + j < len) - printf("%02x ", str[j]); - else printf(" "); - - if ((j+1) % (width/2) == 0) - printf(" "); - - if (hiliting) { - hiliting = 0; - printf("%s", ANSI_off); - } - } - } - - for (j = 0; j < width; j++) { - if (should_hilite && mindex <= (i+j) && (i+j) < mindex + msize) { - hiliting = 1; - printf("%s", ANSI_hilite); - } - - if (i + j < len) - printf("%c", isprint(str[j]) ? str[j] : nonprint_char); - else printf(" "); - - if (hiliting) { - hiliting = 0; - printf("%s", ANSI_off); - } - } - - str += width; - i += j; - - printf("\n"); - } - } +void +dump_formatted(unsigned char *data, uint32_t len, uint16_t mindex, + uint16_t msize) +{ + if (len > 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) { + for (j = 0; j < width; j++) { + if (should_hilite + && (mindex <= (i + j) + && (i + j) < mindex + msize)) { + hiliting = 1; + printf("%s", ANSI_hilite); + } + + if (i + j < len) + printf("%02x ", str[j]); + else + printf(" "); + + if ((j + 1) % (width / 2) == 0) + printf(" "); + + if (hiliting) { + hiliting = 0; + printf("%s", ANSI_off); + } + } + } + + for (j = 0; j < width; j++) { + if (should_hilite && mindex <= (i + j) + && (i + j) < mindex + msize) { + hiliting = 1; + printf("%s", ANSI_hilite); + } + + if (i + j < len) + printf("%c", isprint(str[j]) + ? str[j] + : nonprint_char); + else + printf(" "); + + if (hiliting) { + hiliting = 0; + printf("%s", ANSI_off); + } + } + + str += width; + i += j; + + printf("\n"); + } + } } -char *get_filter_from_string(char *str) { - const char *template = include_vlan ? BPF_TEMPLATE_USERSPEC_IP_VLAN : BPF_TEMPLATE_USERSPEC_IP; - char *mine, *s; - uint32_t len; +char * +get_filter_from_string(char *str) +{ + const char *template; + char *mine, *s; + uint32_t len; + + template = include_vlan ? + BPF_TEMPLATE_USERSPEC_IP_VLAN : + BPF_TEMPLATE_USERSPEC_IP; - if (!str || !*str) - return NULL; + if (!str || !*str) + return NULL; - len = (uint32_t)strlen(str); + len = (uint32_t) strlen(str); - for (s = str; *s; s++) - if (*s == '\r' || *s == '\n') - *s = ' '; + for (s = str; *s; s++) + if (*s == '\r' || *s == '\n') + *s = ' '; - if (!(mine = (char*)malloc(len + strlen(template) + 1))) - return NULL; + if (!(mine = (char *) malloc(len + strlen(template) + 1))) + return NULL; - memset(mine, 0, len + strlen(template) + 1); + memset(mine, 0, len + strlen(template) + 1); - sprintf(mine, template, str); + sprintf(mine, template, str); - return mine; + return mine; } -char *get_filter_from_argv(char **argv) { - const char *template = include_vlan ? BPF_TEMPLATE_USERSPEC_IP_VLAN : BPF_TEMPLATE_USERSPEC_IP; - char **arg = argv, *theirs, *mine; - char *from, *to; - uint32_t len = 0; +char * +get_filter_from_argv(char **argv) +{ + const char *template; + char **arg = argv, *theirs, *mine; + char *from, *to; + uint32_t len = 0; + + template = include_vlan ? + BPF_TEMPLATE_USERSPEC_IP_VLAN : + BPF_TEMPLATE_USERSPEC_IP; - if (!*arg) - return NULL; + if (!*arg) + return NULL; - while (*arg) - len += (uint32_t)strlen(*arg++) + 1; + while (*arg) + len += (uint32_t) strlen(*arg++) + 1; - if (!(theirs = (char*)malloc(len + 1)) || - !(mine = (char*)malloc(len + strlen(template) + 1))) - return NULL; + if (!(theirs = (char *) malloc(len + 1)) || + !(mine = (char *) malloc(len + strlen(template) + 1))) + return NULL; - memset(theirs, 0, len + 1); - memset(mine, 0, len + strlen(template) + 1); + memset(theirs, 0, len + 1); + memset(mine, 0, len + strlen(template) + 1); - arg = argv; - to = theirs; + arg = argv; + to = theirs; - while ((from = *arg++)) { - while ((*to++ = *from++)); - *(to-1) = ' '; - } + while ((from = *arg++)) { + while ((*to++ = *from++)); + *(to - 1) = ' '; + } - sprintf(mine, template, theirs); + sprintf(mine, template, theirs); - free(theirs); - return mine; + free(theirs); + + return mine; } -uint8_t strishex(char *str) { - char *s; +uint8_t +strishex(char *str) +{ + char *s; - if ((s = strchr(str, 'x'))) - s++; - else - s = str; + if ((s = strchr(str, 'x'))) + s++; + else + s = str; - while (*s) - if (!isxdigit(*s++)) - return 0; + while (*s) + if (!isxdigit(*s++)) + return 0; - return 1; + return 1; } -void print_time_absolute(struct pcap_pkthdr *h) { - struct tm *t = localtime((const time_t *)&h->ts.tv_sec); +void +print_time_absolute(struct pcap_pkthdr * h) +{ + struct tm *t = localtime((const time_t *) & h->ts.tv_sec); - printf("%02u/%02u/%02u %02u:%02u:%02u.%06u ", - t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, - t->tm_min, t->tm_sec, (uint32_t)h->ts.tv_usec); + printf("%02u/%02u/%02u %02u:%02u:%02u.%06u ", + t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, + t->tm_min, t->tm_sec, (uint32_t) h->ts.tv_usec); } -void print_time_diff(struct pcap_pkthdr *h) { - uint32_t secs, usecs; +void +print_time_diff(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); - } + 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); + } - printf("+%u.%06u ", secs, usecs); + printf("+%u.%06u ", secs, usecs); - prev_ts.tv_sec = h->ts.tv_sec; - prev_ts.tv_usec = h->ts.tv_usec; + prev_ts.tv_sec = h->ts.tv_sec; + 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 +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; +void +dump_delay_proc_init(struct pcap_pkthdr * h) +{ + dump_delay = &dump_delay_proc; - prev_delay_ts.tv_sec = h->ts.tv_sec; - prev_delay_ts.tv_usec = h->ts.tv_usec; + prev_delay_ts.tv_sec = h->ts.tv_sec; + prev_delay_ts.tv_usec = h->ts.tv_usec; - dump_delay(h); + dump_delay(h); } -void dump_delay_proc(struct pcap_pkthdr *h) { - uint32_t secs, usecs; +void +dump_delay_proc(struct pcap_pkthdr * h) +{ + uint32_t secs, usecs; - secs = h->ts.tv_sec - prev_delay_ts.tv_sec; - if (h->ts.tv_usec >= prev_delay_ts.tv_usec) - usecs = h->ts.tv_usec - prev_delay_ts.tv_usec; - else { - secs--; - usecs = 1000000 - (prev_delay_ts.tv_usec - h->ts.tv_usec); - } + secs = h->ts.tv_sec - prev_delay_ts.tv_sec; + if (h->ts.tv_usec >= prev_delay_ts.tv_usec) + usecs = h->ts.tv_usec - prev_delay_ts.tv_usec; + else { + secs--; + usecs = 1000000 - (prev_delay_ts.tv_usec - h->ts.tv_usec); + } - sleep(secs); - usleep(usecs); + sleep(secs); + usleep(usecs); - prev_delay_ts.tv_sec = h->ts.tv_sec; - prev_delay_ts.tv_usec = h->ts.tv_usec; + prev_delay_ts.tv_sec = h->ts.tv_sec; + prev_delay_ts.tv_usec = h->ts.tv_usec; } -void update_windowsize(int32_t e) { - if (e == 0 && ws_col_forced) - - ws_col = ws_col_forced; - - else if (!ws_col_forced) { - const struct winsize ws; - - if (!ioctl(0, TIOCGWINSZ, &ws)) { - ws_row = ws.ws_row; - ws_col = ws.ws_col; - } - else { - ws_row = 24; - ws_col = 80; - } - - } +void +update_windowsize(int32_t e) +{ + if (e == 0 && ws_col_forced) + ws_col = ws_col_forced; + else if (!ws_col_forced) { + const struct winsize ws; + + if (!ioctl(0, TIOCGWINSZ, &ws)) { + ws_row = ws.ws_row; + ws_col = ws.ws_col; + } else { + ws_row = 24; + ws_col = 80; + } + + } } -void drop_privs(void) { +void +drop_privs(void) +{ #if 0 - struct passwd *pw; - uid_t newuid; - gid_t newgid; - - if ((getuid() || geteuid()) || dont_dropprivs) - return; - - pw = getpwnam("_ngrep"); - if (!pw) { - perror("attempt to drop privileges failed: getpwnam failed"); - clean_exit(2); - } - - newgid = pw->pw_gid; - newuid = pw->pw_uid; - - if (getgroups(0, NULL) > 0) - if (setgroups(1, &newgid) == -1) { - perror("attempt to drop privileges failed"); - clean_exit(2); - } - - if (((getgid() != newgid) && (setgid(newgid) == -1)) || - ((getegid() != newgid) && (setegid(newgid) == -1)) || - ((getuid() != newuid) && (setuid(newuid) == -1)) || - ((geteuid() != newuid) && (seteuid(newuid) == -1))) { - - perror("attempt to drop privileges failed"); - clean_exit(2); - } + struct passwd *pw; + uid_t newuid; + gid_t newgid; + + if ((getuid() || geteuid()) || dont_dropprivs) + return; + + pw = getpwnam("_ngrep"); + if (!pw) { + perror("attempt to drop privileges failed: getpwnam failed"); + clean_exit(2); + } + newgid = pw->pw_gid; + newuid = pw->pw_uid; + + if (getgroups(0, NULL) > 0) + if (setgroups(1, &newgid) == -1) { + perror("attempt to drop privileges failed"); + clean_exit(2); + } + if (((getgid() != newgid) && (setgid(newgid) == -1)) || + ((getegid() != newgid) && (setegid(newgid) == -1)) || + ((getuid() != newuid) && (setuid(newuid) == -1)) || + ((geteuid() != newuid) && (seteuid(newuid) == -1))) { + + perror("attempt to drop privileges failed"); + clean_exit(2); + } #endif } -void usage(void) { - printf("usage: ngrep <-" - "hNXViwqpevxlDtTRM> <-IO pcap_dump> <-n num> <-d dev> <-A num>\n" - " <-s snaplen> <-S limitlen> <-W normal|byline|single|none> <-c cols>\n" - " <-P char> <-F file>" - "\n" - " <match expression> <bpf filter>\n" - " -h is help/usage\n" - " -V is version information\n" - " -q is be quiet (don't print packet reception hash marks)\n" - " -e is show empty packets\n" - " -i is ignore case\n" - " -v is invert match\n" - " -R is don't do privilege revocation logic\n" - " -x is print in alternate hexdump format\n" - " -X is interpret match expression as hexadecimal\n" - " -w is word-regex (expression must match as a word)\n" - " -p is don't go into promiscuous mode\n" - " -l is make stdout line buffered\n" - " -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" - " -n is look at only num packets\n" - " -A is dump num packets after a match\n" - " -s is set the bpf caplen\n" - " -S is set the limitlen on matched packets\n" - " -W is set the dump format (normal, byline, single, none)\n" - " -c is force the column width to the specified size\n" - " -P is set the non-printable display char to what is specified\n" - " -F is read the bpf filter from the specified file\n" - " -N is show sub protocol number\n" - " -d is use specified device instead of the pcap default\n" - ""); - - exit(2); -} - - -void version(void) { - printf("ngrep: V%s, %s\n", VERSION, pcap_lib_version()); - exit(0); +void +usage(void) +{ + printf("usage: ngrep <-" + "hNXViwqpevxlDtTRM> <-IO pcap_dump> <-n num> <-d dev> <-A num>\n" + " <-s snaplen> <-S limitlen> <-W normal|byline|single|none> <-c cols>\n" + " <-P char> <-F file>" + "\n" + " <match expression> <bpf filter>\n" + " -h is help/usage\n" + " -V is version information\n" + " -q is be quiet (don't print packet reception hash marks)\n" + " -e is show empty packets\n" + " -i is ignore case\n" + " -v is invert match\n" + " -R is don't do privilege revocation logic\n" + " -x is print in alternate hexdump format\n" + " -X is interpret match expression as hexadecimal\n" + " -w is word-regex (expression must match as a word)\n" + " -p is don't go into promiscuous mode\n" + " -l is make stdout line buffered\n" + " -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" + " -n is look at only num packets\n" + " -A is dump num packets after a match\n" + " -s is set the bpf caplen\n" + " -S is set the limitlen on matched packets\n" + " -W is set the dump format (normal, byline, single, none)\n" + " -c is force the column width to the specified size\n" + " -P is set the non-printable display char to what is specified\n" + " -F is read the bpf filter from the specified file\n" + " -N is show sub protocol number\n" + " -d is use specified device instead of the pcap default\n" + ""); + + exit(2); } - -void clean_exit(int32_t sig) { - struct pcap_stat s; - - signal(SIGINT, SIG_IGN); - signal(SIGABRT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - signal(SIGPIPE, SIG_IGN); - signal(SIGWINCH, SIG_IGN); - - if (quiet < 1 && sig >= 0) - printf("exit\n"); - - if (pattern) pcre_free(pattern); - if (pattern_extra) pcre_free(pattern_extra); - if (bin_data) free(bin_data); - - /* We used to report pcap_stats; but PCAP manpage says pcap_stats "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) - printf("%u received, %u matched\n", seen_frames, matches); - - if (pd) pcap_close(pd); - if (pd_dumppcap) pcap_close(pd_dumppcap); - if (pd_dump) pcap_dump_close(pd_dump); - - exit(matches ? 0 : 1); +void +clean_exit(int32_t sig) +{ + signal(SIGINT, SIG_IGN); + signal(SIGABRT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + signal(SIGPIPE, SIG_IGN); + signal(SIGWINCH, SIG_IGN); + + if (quiet < 1 && sig >= 0) + printf("exit\n"); + + if (pattern) + pcre_free(pattern); + if (pattern_extra) + pcre_free(pattern_extra); + if (bin_data) + free(bin_data); + + /* + * We used to report pcap_stats; but PCAP manpage says pcap_stats + * "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) + printf("%u received, %u matched\n", seen_frames, matches); + + if (pd) + pcap_close(pd); + if (pd_dumppcap) + pcap_close(pd_dumppcap); + if (pd_dump) + pcap_dump_close(pd_dump); + + exit(matches ? 0 : 1); } diff --git a/ngrep.h b/ngrep.h @@ -6,13 +6,10 @@ * */ -#define VERSION "1.47.1-git" - /* * We cache the standard frame sizes here to save us time and * additional dependencies on more operating system include files. */ - #define ETHHDR_SIZE 14 #define TOKENRING_SIZE 22 #define PPPHDR_SIZE 4 @@ -56,7 +53,6 @@ */ #define BPF_FILTER_IP_TYPE "(ip || ip6)" - #define BPF_TEMPLATE_IP BPF_FILTER_IP_TYPE #define BPF_TEMPLATE_IP_VLAN "(" BPF_FILTER_IP_TYPE " || (vlan && " BPF_FILTER_IP_TYPE "))" #define BPF_TEMPLATE_USERSPEC_IP "( %s) and " BPF_TEMPLATE_IP @@ -68,63 +64,58 @@ * Single-char packet "ident" flags. */ typedef enum { - TCP = 'T', UDP = 'U', ICMP = 'I', ICMPv6 = 'I', IGMP = 'G', UNKNOWN = '?' + TCP = 'T', UDP = 'U', ICMP = 'I', ICMPv6 = 'I', IGMP = 'G', UNKNOWN = '?' } netident_t; /* * Prototypes function signatures. */ -int setup_pcap_source(void); -int setup_bpf_filter(char **); -int setup_matcher(void); +int setup_pcap_source(void); +int setup_bpf_filter(char **); +int setup_matcher(void); -void process(u_char *, struct pcap_pkthdr *, u_char *); +void process(u_char *, struct pcap_pkthdr *, u_char *); -void version(void); -void usage(); -void update_windowsize(int32_t); -void clean_exit(int32_t); +void version(void); +__dead void usage(void); +void update_windowsize(int32_t); +void clean_exit(int32_t); -void dump_packet(struct pcap_pkthdr *, u_char *, uint8_t, unsigned char *, uint32_t, - const char *, const char *, uint16_t, uint16_t, uint8_t, - uint16_t, uint8_t, uint16_t, uint32_t); +void dump_packet(struct pcap_pkthdr *, u_char *, uint8_t, unsigned char *, uint32_t, + const char *, const char *, uint16_t, uint16_t, uint8_t, + uint16_t, uint8_t, uint16_t, uint32_t); -void dump_unwrapped(unsigned char *, uint32_t, uint16_t, uint16_t); -void dump_formatted(unsigned char *, uint32_t, uint16_t, uint16_t); -void dump_byline (unsigned char *, uint32_t, uint16_t, uint16_t); +void dump_unwrapped(unsigned char *, uint32_t, uint16_t, uint16_t); +void dump_formatted(unsigned char *, uint32_t, uint16_t, uint16_t); +void dump_byline(unsigned char *, uint32_t, uint16_t, uint16_t); -void dump_delay_proc_init(struct pcap_pkthdr *); -void dump_delay_proc (struct pcap_pkthdr *); +void dump_delay_proc_init(struct pcap_pkthdr *); +void dump_delay_proc(struct pcap_pkthdr *); -int8_t re_match_func (unsigned char *, uint32_t, uint16_t *, uint16_t *); -int8_t bin_match_func (unsigned char *, uint32_t, uint16_t *, uint16_t *); -int8_t blank_match_func(unsigned char *, uint32_t, uint16_t *, uint16_t *); +int8_t re_match_func(unsigned char *, uint32_t, uint16_t *, uint16_t *); +int8_t bin_match_func(unsigned char *, uint32_t, uint16_t *, uint16_t *); +int8_t blank_match_func(unsigned char *, uint32_t, uint16_t *, uint16_t *); -void print_time_absolute(struct pcap_pkthdr *); -void print_time_diff (struct pcap_pkthdr *); -void print_time_offset (struct pcap_pkthdr *); +void print_time_absolute(struct pcap_pkthdr *); +void print_time_diff(struct pcap_pkthdr *); +void print_time_offset(struct pcap_pkthdr *); -char *get_filter_from_string(char *); -char *get_filter_from_argv (char **); +char *get_filter_from_string(char *); +char *get_filter_from_argv(char **); -uint8_t strishex(char *); +uint8_t strishex(char *); -void drop_privs(void); +void drop_privs(void); struct NGREP_rtaphdr_t { - uint8_t it_version; - uint8_t it_pad; - uint16_t it_len; - uint32_t it_present; + uint8_t it_version; + uint8_t it_pad; + uint16_t it_len; + uint32_t it_present; }; - -/* - * ANSI color/hilite stuff. - */ - -const char ANSI_red[] = "\33[01;31m"; -const char ANSI_bold[] = "\33[01m"; - -const char *ANSI_hilite = ANSI_red; -const char ANSI_off[] = "\33[00m"; +/* ANSI color/hilite stuff. */ +const char ANSI_red[] = "\33[01;31m"; +const char ANSI_bold[] = "\33[01m"; +const char *ANSI_hilite = ANSI_red; +const char ANSI_off[] = "\33[00m";