📄 ngrep.c
字号:
/* * $Id: ngrep.c,v 1.40 2000/06/21 18:42:37 jpr5 Exp $ * * Copyright (c) 2000 Jordan Ritter <jpr5@darkridge.com> * * Please refer to the COPYRIGHT file for more information. * */#if defined(BSD) || defined(SOLARIS)#include <unistd.h>#include <ctype.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <net/if.h>#endif#if defined(OSF1)#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <net/route.h>#include <sys/mbuf.h>#endif#if defined(LINUX)#include <getopt.h>#include <arpa/inet.h>#include <ctype.h>#endif#if defined(WIN32)#include <io.h>#include <getopt.h>#include <winsock2.h>#include <nettypes.h>#else #include <netinet/ip.h>#include <netinet/tcp.h>#include <netinet/udp.h>#include <netinet/ip_icmp.h>#endif#include <pcap.h>#include <net/bpf.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include "regex.h"#include "ngrep.h"static char ver[] = "V1.41 (win32)";unsigned snaplen = 65535, limitlen = 65535;
int promisc = 1, to = 1000;int show_empty = 0, show_hex = 0, quiet = 0;int match_after = 0, keep_matching = 0;int invert_match = 0, bin_match = 0;int matches = 0, max_matches = 0;int live_read = 1, want_delay = 0;;char pc_err[PCAP_ERRBUF_SIZE], *re_err;int re_match_word = 0, re_ignore_case = 0;struct re_pattern_buffer pattern;char *match_data = NULL, *bin_data = NULL, *filter = NULL;int (*match_func)() = &blank_match_func;int match_len = 0;struct bpf_program pcapfilter;struct in_addr net, mask;pcap_t *pd = NULL;char *dev = NULL;int link_offset;char *read_file = NULL, *dump_file = NULL;pcap_dumper_t *pd_dump = NULL;struct timeval prev_ts = {0, 0}, prev_delay_ts = {0,0};void (*print_time)() = NULL;#ifdef WIN32struct timeval delay_tv;FD_SET delay_fds;int delay_socket = 0;#endifint main(int argc, char **argv) { int c;#ifdef WIN32 if (!init_winsock()) clean_exit(-1);#else signal(SIGQUIT, clean_exit); signal(SIGPIPE, clean_exit);#endif signal(SIGINT, clean_exit); signal(SIGABRT, clean_exit);#ifdef WIN32 while ((c = getopt(argc, argv, "LhXViwqpevxlDtTs:n:d:A:I:O:S:")) != EOF) {#else while ((c = getopt(argc, argv, "hXViwqevxlDtTn:d:A:I:O:")) != EOF) {#endif switch (c) { case 'O': dump_file = optarg; break;
case 'S':
limitlen = atoi(optarg);
break; case 'I': read_file = optarg; break; case 'A': match_after = atoi(optarg) + 1; break;#ifdef WIN32 case 'L': PrintDeviceList(); clean_exit(0); case 'd': { char *devicelist; int i; if ((i = atoi(optarg)) < 1) { fprintf(stderr, "fatal: invalid interface\n"); clean_exit(-1); } if ((devicelist = pcap_lookupdev(pc_err)) == NULL) { perror(pc_err); clean_exit(-1); } if ((dev = GetAdapterFromList(devicelist, i)) == NULL) { fprintf(stderr, "fatal: invalid interface\n"); clean_exit(-1); } }#else case 'd': dev = optarg;#endif break; case 'n': max_matches = atoi(optarg); break;
case 's':
snaplen = atoi(optarg);
break; case 'T': print_time = &print_time_diff; 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 'h': usage(0); default: usage(-1); } } if (argv[optind]) match_data = argv[optind++]; if (read_file) { if (!(pd = pcap_open_offline(read_file, pc_err))) { perror(pc_err); clean_exit(-1); } live_read = 0; printf("input: %s\n", read_file); } else { if (!dev) if (!(dev = pcap_lookupdev(pc_err))) { perror(pc_err); clean_exit(-1); } if ((pd = pcap_open_live(dev, snaplen, promisc, to, pc_err)) == NULL) { perror(pc_err); clean_exit(-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) {#ifdef WIN32 // the win32 port of libpcap has borked code for pcap_lookupnet. // look for this to be fixed in the next version. printf("interface: %S", dev);#else printf("interface: %s", dev); if (net.s_addr && mask.s_addr) { printf(" (%s/", inet_ntoa(net)); printf("%s)", inet_ntoa(mask)); } #endif printf("\n"); } } if (argv[optind]) { filter = get_filter(&argv[optind]); if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) { free(filter); filter = get_filter(&argv[optind-1]);
#if 0
PCAP_RESTART();
#endif
if (pcap_compile(pd, &pcapfilter, filter, 0, mask.s_addr)) { pcap_perror(pd, "pcap compile"); clean_exit(-1); } else match_data = NULL; }
if (!quiet) printf("filter: %s\n", filter); if (pcap_setfilter(pd, &pcapfilter)) { pcap_perror(pd, "pcap set"); clean_exit(-1); } } if (match_data) { if (bin_match) { int i = 0, n; char *s, *d; int len; if (re_match_word || re_ignore_case) { fprintf(stderr, "fatal: regex switches are incompatible with binary matching\n"); clean_exit(-1); } len = strlen(match_data); if (len % 2 != 0 || !strishex(match_data)) { fprintf(stderr, "fatal: invalid hex string specified\n"); clean_exit(-1); } bin_data = malloc(len / 2); memset(bin_data, 0, len / 2); d = bin_data; if ((s = strchr(match_data, 'x'))) len -= ++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 { re_syntax_options = RE_SYNTAX_EGREP; if (re_ignore_case) { char *s; int i; pattern.translate = (char*)malloc(256); s = pattern.translate; for (i = 0; i < 256; i++) s[i] = i; for (i = 'A'; i <= 'Z'; i++) s[i] = i + 32; s = match_data; while (*s) *s++ = tolower(*s); } else pattern.translate = NULL; if (re_match_word) { char *word_regex = malloc(strlen(match_data) * 3 + strlen(WORD_REGEX)); sprintf(word_regex, WORD_REGEX, match_data, match_data, match_data); match_data = word_regex; } (const char *)re_err = re_compile_pattern(match_data, strlen(match_data), &pattern); if (re_err) { fprintf(stderr, "regex compile: %s\n", re_err); clean_exit(-1); } pattern.fastmap = (char*)malloc(256); if (re_compile_fastmap(&pattern)) { perror("fastmap compile failed"); clean_exit(-1); } match_func = &re_match_func; } if (!quiet && match_data && strlen(match_data)) printf("%smatch: %s%s\n", invert_match?"don't ":"", (bin_data && !strchr(match_data, 'x'))?"0x":"", match_data); } if (filter) free(filter); if (re_match_word) free(match_data); switch(pcap_datalink(pd)) {#ifdef WIN32 case DLT_EN100MB:#endif case DLT_EN10MB: case DLT_IEEE802: link_offset = ETHHDR_SIZE; break; case DLT_FDDI: link_offset = FDDIHDR_SIZE; break; case DLT_SLIP: link_offset = SLIPHDR_SIZE; break;#ifdef WIN32 case DLT_PPP_WIN32:#endif case DLT_PPP: link_offset = PPPHDR_SIZE; break; case DLT_RAW: link_offset = RAWHDR_SIZE; break;
#ifdef DLT_LOOP
case DLT_LOOP:
#endif case DLT_NULL: link_offset = LOOPHDR_SIZE; break;
#ifdef DLT_IEEE802_11
case DLT_IEEE802_11:
#endif
link_offset = IEEE80211HDR_SIZE;
break; default: fprintf(stderr, "fatal: unsupported interface type: %d\n", pcap_datalink(pd)); fprintf(stderr, "email author Jordan Ritter <jpr5@darkridge.com> for help\n"); clean_exit(-1); } if (dump_file) { if (!(pd_dump = pcap_dump_open(pd, dump_file))) { fprintf(stderr, "fatal: %s\n", pcap_geterr(pd)); clean_exit(-1); } else printf("output: %s\n", dump_file); } while (pcap_loop(pd, 0, (pcap_handler)process, 0)); clean_exit(0);} void process(u_char *data1, struct pcap_pkthdr* h, u_char *p) { struct ip* ip_packet = (struct ip *)(p + link_offset); unsigned ip_hl = ip_packet->ip_hl*4; unsigned ip_off = ntohs(ip_packet->ip_off); unsigned fragmented = ip_off & (IP_MF | IP_OFFMASK); unsigned frag_offset = fragmented?(ip_off & IP_OFFMASK) * 8:0; char *data; unsigned len; switch (ip_packet->ip_p) { case IPPROTO_TCP: { struct tcphdr* tcp = (struct tcphdr *)(((char *)ip_packet) + ip_hl); unsigned tcphdr_offset = fragmented?0:(tcp->th_off * 4); if (!quiet) { printf("#"); fflush(stdout); } data = ((char*)tcp) + tcphdr_offset;
if ((len = ntohs(ip_packet->ip_len)) < h->caplen)
len -= ip_hl + tcphdr_offset;
else len = h->caplen - link_offset - ip_hl - tcphdr_offset;
if (len > limitlen) len = limitlen;
if (((len || show_empty) && (((int)(*match_func)(data, len)) != invert_match)) || keep_matching) { if (!live_read && want_delay) dump_delay(h); printf("\nT "); if (print_time) print_time(h); if (tcphdr_offset || !frag_offset) { printf("%s:%d -", inet_ntoa(ip_packet->ip_src), ntohs(tcp->th_sport)); printf("> %s:%d", inet_ntoa(ip_packet->ip_dst), ntohs(tcp->th_dport)); printf(" [%s%s%s%s%s%s]", (tcp->th_flags & TH_ACK)?"A":"", (tcp->th_flags & TH_SYN)?"S":"", (tcp->th_flags & TH_RST)?"R":"", (tcp->th_flags & TH_FIN)?"F":"", (tcp->th_flags & TH_URG)?"U":"", (tcp->th_flags & TH_PUSH)?"P":"",
(tcp->th_flags & TH_ECE)?"E":"",
(tcp->th_flags & TH_CWR)?"C":""); } else { printf("%s -", inet_ntoa(ip_packet->ip_src)); printf("> %s", inet_ntoa(ip_packet->ip_dst)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -