📄 ipdump.c
字号:
/********************************************************************** * TCP/IP僷働僢僩儌僯僞儕儞僌僾儘僌儔儉 (ipdump.c) * Ver 2.0 2004擭 7寧 10擔 * 惂嶌丒挊嶌 懞嶳岞曐 (Yukio Murayama) * * 巊梡嫋戻彂 * 杮僾儘僌儔儉偼丄TCP/IP僾儘僩僐儖偺妛廗丄媦傃丄僱僢僩儚乕僋僾儘 * 僌儔儈儞僌偺媄擻傪岦忋偝偣傞偨傔偵偺傒丄偦偺傑傑丄傑偨偼丄廋惓 * 偟偰巊梡偡傞偙偲偑偱偒傑偡丅杮僾儘僌儔儉偵偮偄偰丄朄棩偱嬛巭偝 * 傟偰偄傞偐丄傑偨偼丄岞彉椙懎偵斀偡傞傛偆側夵憿丄媦傃丄巊梡傪嬛 * 巭偟傑偡丅杮僾儘僌儔儉偼柍曐徹偱偡丅惂嶌幰偼杮僾儘僌儔儉偵傛偭 * 偰敪惗偟偨偄偐側傞懝奞偵偮偄偰傕愑擟傪庢傞偙偲偼偱偒傑偣傫丅 **********************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <time.h>#include <sys/time.h>#include <sys/socket.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/ip_icmp.h>#define __FAVOR_BSD#include <netinet/tcp.h>#include <netinet/udp.h>#include <arpa/inet.h>#ifndef __linux#include <sys/ioctl.h>#include <net/bpf.h>#include <net/if.h>#include <fcntl.h>#endif#include <netinet/if_ether.h>#define MAXSIZE 8192#define CMAX 256#define OPTNUM 9#define ON 1#define OFF 0#define DEF_IF "en0" /* Mac OS X偺僨僼僅儖僩僀儞僞僼僃乕僗柤 */enum {ETHER, ARP, IP, TCP, UDP, ICMP, DUMP, ALL, TIME};enum {IP_ADDR, PORT};/* 僷働僢僩僼傿儖僞梡儅僋儘 */#define FILTER_ARP(_p) (filter.flg[IP_ADDR] ?\ ((*(int *) (_p)->arp_spa == filter.ip.s_addr\ || *(int *) (_p)->arp_tpa == filter.ip.s_addr) ?\ 1 : 0)\ : 1)#define FILTER_IP(_p) (filter.flg[IP_ADDR] ?\ (((_p)->ip_src.s_addr == filter.ip.s_addr\ || (_p)->ip_dst.s_addr == filter.ip.s_addr) ?\ 1 : 0)\ : 1)#define FILTER_TCP(_p) (filter.flg[PORT] ?\ (((_p)->th_sport == filter.port\ || (_p)->th_dport == filter.port) ?\ 1 : 0)\ : 1)#define FILTER_UDP(_p) (filter.flg[PORT] ?\ (((_p)->uh_sport == filter.port\ || (_p)->uh_dport == filter.port) ?\ 1 : 0)\ : 1)struct filter { struct in_addr ip; /* IP傾僪儗僗 */ u_int16_t port; /* 億乕僩斣崋 */ int flg[2]; /* 僼傿儖僞僼儔僌 */};#ifndef __linuxint open_bpf(char *ifname, int *bufsize);#endifvoid print_ethernet(struct ether_header *eth);void print_arp(struct ether_arp *arp);void print_ip(struct ip *ip);void print_icmp(struct icmp *icmp);void print_tcp(struct tcphdr *tcp);void print_tcp_mini(struct tcphdr *tcp);void print_udp(struct udphdr *udp);void dump_packet(unsigned char *buff, int len);char *mac_ntoa(u_char *d);char *tcp_ftoa(int flag);char *ip_ttoa(int flag);char *ip_ftoa(int flag);void help(char *cmd);int main(int argc, char **argv){ int s; /* 僜働僢僩僨傿僗僋儕僾僞 */ int c; /* getopt()偱庢摼偟偨暥帤 */ char ifname[CMAX] = ""; /* 僀儞僞僼僃乕僗柤 */ int opt[OPTNUM]; /* 昞帵僆僾僔儑儞偺僼儔僌 */ extern int optind; /* getopt()偺僌儘乕僶儖曄悢 */#ifndef __linux struct bpf_hdr *bp; /* BPF僿僢僟峔憿懱 */ int bpf_len; /* BPF偱偺庴怣僨乕僞偺挿偝 */ int bufsize; /* BPF撪晹偺僶僢僼傽僒僀僘 */#endif struct filter filter; /* 僼傿儖僞偡傞忣曬 */ /* 昞帵偡傞僷働僢僩(僆僾僔儑儞)偺弶婜抣 */ opt[ETHER] = OFF; opt[ARP] = ON; opt[IP] = ON; opt[TCP] = ON; opt[UDP] = ON; opt[ICMP] = ON; opt[DUMP] = OFF; opt[ALL] = OFF; opt[TIME] = OFF; /* 僼傿儖僞偺弶婜抣 */ filter.flg[IP_ADDR] = OFF; filter.flg[PORT] = OFF; /* 僐儅儞僪儔僀儞僆僾僔儑儞偺専嵏 */ while ((c = getopt(argc, argv, "aei:p:f:dhft")) != EOF) { switch (c) { case 'a': /* all */ opt[ALL] = ON; break; case 'e': /* ethernet */ opt[ETHER]= ON; break; case 'd': /* dump */ opt[DUMP] = ON; break; case 't': /* time */ opt[TIME] = ON; break; case 'i': /* if name */ snprintf(ifname, CMAX, "%s", optarg); break; case 'p': /* protocol */ opt[ARP] = OFF; opt[IP] = OFF; opt[TCP] = OFF; opt[UDP] = OFF; opt[ICMP] = OFF; optind--; while (argv[optind] != NULL && argv[optind][0] != '-') { if (strcmp(argv[optind], "arp") == 0) opt[ARP] = ON; else if (strcmp(argv[optind], "ip") == 0) opt[IP] = ON; else if (strcmp(argv[optind], "tcp") == 0) opt[TCP] = ON; else if (strcmp(argv[optind], "udp") == 0) opt[UDP] = ON; else if (strcmp(argv[optind], "icmp") == 0) opt[ICMP] = ON; else if (strcmp(argv[optind], "other") == 0) ; else { help(argv[0]); exit(EXIT_FAILURE); } optind++; } break; case 'f': /* filter */ optind--; while (argv[optind] != NULL && argv[optind][0] != '-') { if (strcmp(argv[optind], "ip") == 0 && argv[optind+1] != NULL) { filter.flg[IP_ADDR] = ON; filter.ip.s_addr = inet_addr(argv[++optind]); } else if (strcmp(argv[optind], "port")==0 && argv[optind+1]!=NULL) { filter.flg[PORT] = ON; filter.port = htons(atoi(argv[++optind])); } else { help(argv[0]); exit(EXIT_FAILURE); } optind++; } break; case 'h': /* help */ case '?': default: help(argv[0]); exit(EXIT_FAILURE); break; } } if (optind < argc) { while (optind < argc) printf("%s ", argv[optind++]); printf("\n"); help(argv[0]); exit(EXIT_FAILURE); } if (filter.flg[IP_ADDR]) printf("filter ip = %s\n", inet_ntoa(filter.ip)); if (filter.flg[PORT]) printf("filter port = %d\n", htons(filter.port));#ifdef __linux if ((s = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) { perror("socket"); exit(EXIT_FAILURE); } if (strcmp(ifname, "") != 0) { struct sockaddr sa; memset(&sa, 0, sizeof sa); sa.sa_family = AF_INET; snprintf(sa.sa_data, CMAX, "%s", ifname); if (bind(s, &sa, sizeof sa) < 0) { perror("bind"); exit(EXIT_FAILURE); } }#else if (strcmp(ifname, "") == 0) strcpy(ifname, DEF_IF); if ((s = open_bpf(ifname, &bufsize)) < 0) exit(EXIT_FAILURE); bpf_len = 0;#endif while (1) { struct ether_header *eth; /* Ethernet僿僢僟峔憿懱 */ struct ether_arp *arp; /* ARP僷働僢僩峔憿懱 */ struct ip *ip; /* IP僿僢僟峔憿懱 */ struct icmp *icmp; /* ICMP僷働僢僩峔憿懱 */ struct tcphdr *tcp; /* TCP僿僢僟峔憿懱 */ struct udphdr *udp; /* UDP僿僢僟峔憿懱 */ char buff[MAXSIZE]; /* 僨乕僞庴怣僶僢僼傽 */ char *p; /* 僿僢僟偺愭摢傪昞偡嶌嬈梡億僀儞僞 */ char *p0; /* 僷働僢僩偺愭摢傪昞偡億僀儞僞 */ int len; /* 庴怣偟偨僨乕僞偺挿偝 */ int disp; /* 夋柺偵弌椡偟偨偐偳偆偐偺僼儔僌 */ struct timeval tv; /* 僷働僢僩傪僟儞僾偟偨帪崗 */ struct tm tm; /* localtime偱偺帪崗昞帵 */#ifndef __linux /* BPF偐傜偺擖椡 */ if (bpf_len <= 0) { /* 暋悢偺僷働僢僩傪堦妵庢傝弌偟 */ if ((bpf_len = read(s, buff, bufsize)) < 0) { perror("read"); exit(EXIT_FAILURE); } bp = (struct bpf_hdr *) buff; } else { /* BPF偺師偺僷働僢僩傊億僀儞僞傪堏摦 */ bp = (struct bpf_hdr *) ((char *) bp + bp->bh_hdrlen + bp->bh_caplen); bp = (struct bpf_hdr *) BPF_WORDALIGN((int) bp); } /* 僷働僢僩僟儞僾偺帪崗傪僙僢僩 */ memcpy(&tv, &(bp->bh_tstamp), sizeof tv); localtime_r((time_t *) &tv.tv_sec, &tm); /* Ethernet僿僢僟偺愭摢偵億僀儞僞傪僙僢僩 */ p = p0 = (char *) bp + bp->bh_hdrlen; len = bp->bh_caplen;#ifdef DEBUG /* BPF僿僢僟峔憿偺抣傪昞帵 */ printf("bpf_len=%d,", bpf_len); printf("hdrlen=%d,", bp->bh_hdrlen); printf("caplen=%d,", bp->bh_caplen); printf("datalen=%d\n", bp->bh_datalen);#endif /* 師偺while儖乕僾偺偨傔偺張棟 */ bpf_len -= BPF_WORDALIGN(bp->bh_hdrlen + bp->bh_caplen);#else /* Linux SOCK_PACKET偐傜偺擖椡 */ if ((len = read(s, buff, MAXSIZE)) < 0) { perror("read"); exit(EXIT_FAILURE); } /* 僷働僢僩僟儞僾偺帪崗傪僙僢僩 */ gettimeofday(&tv, (struct timezone *) 0); localtime_r((time_t *) &tv.tv_sec, &tm); /* Ethernet僿僢僟偺愭摢偵億僀儞僞傪僙僢僩 */ p = p0 = buff;#endif /* * 僷働僢僩夝愅儖乕僠儞 */ disp = OFF; /* 夋柺偵弌椡偡傞偐偳偆偐僼儔僌 */ /* Ethernet僿僢僟峔憿懱偺愝掕 */ eth = (struct ether_header *) p; p += sizeof (struct ether_header); if (ntohs(eth->ether_type) == ETHERTYPE_ARP) { arp = (struct ether_arp *) p; if (opt[ARP] == ON && FILTER_ARP(arp)) disp = ON; } else if (ntohs(eth->ether_type) == ETHERTYPE_IP) { ip = (struct ip *) p; p += ((int) (ip->ip_hl) << 2); if (!FILTER_IP(ip)) continue; if (opt[IP] == ON && opt[TCP] != ON && opt[UDP] != ON && opt[ICMP] != ON) disp = ON; switch (ip->ip_p) { case IPPROTO_TCP: tcp = (struct tcphdr *) p; p += ((int) (tcp->th_off) << 2); if (!FILTER_TCP(tcp)) continue; if (opt[TCP] == ON) disp = ON; break; case IPPROTO_UDP: udp = (struct udphdr *) p; p += sizeof (struct udphdr); if (!FILTER_UDP(udp)) continue; if (opt[UDP] == ON) disp = ON; break; case IPPROTO_ICMP: icmp = (struct icmp *) p; p = icmp->icmp_data; if (opt[ICMP] == ON) disp = ON; break; default: if (opt[ALL] == ON) disp = ON; break; } } else if (opt[ETHER] == ON && opt[ALL] == ON) disp = ON; /* * 僷働僢僩昞帵儖乕僠儞 */ if (disp == ON || opt[ALL] == ON) { if (opt[TIME] == ON) printf("Time: %02d:%02d:%02d.%06d\n", tm.tm_hour, tm.tm_min, tm.tm_sec, (int) tv.tv_usec); if (opt[ETHER] == ON) print_ethernet(eth); if (ntohs(eth->ether_type) == ETHERTYPE_ARP) { if (opt[ARP] == ON) print_arp(arp); } else if (ntohs(eth->ether_type) == ETHERTYPE_IP) { if (opt[IP] == ON) print_ip(ip); if (ip->ip_p == IPPROTO_TCP && opt[TCP] == ON) print_tcp(tcp); else if (ip->ip_p == IPPROTO_UDP && opt[UDP] == ON) print_udp(udp); else if (ip->ip_p == IPPROTO_ICMP && opt[ICMP] == ON) print_icmp(icmp); else if (opt[ALL] == ON) printf("Protocol: unknown\n"); } else if (opt[ALL] == ON) printf("Protocol: unknown\n"); if (opt[DUMP] == ON) dump_packet(p0, len); printf("\n"); } } return 0;}/* * char *mac_ntoa(u_char *d); * 婡擻 * 攝楍偵奿擺偝傟偰偄傞MAC傾僪儗僗傪暥帤楍偵曄姺 * static曄悢傪棙梡偡傞偨傔丄旕儕僄儞僩儔儞僩娭悢 * 堷偒悢 * u_char *d; MAC傾僪儗僗偑奿擺偝傟偰偄傞椞堟偺愭摢傾僪儗僗 * 栠傝抣 * 暥帤楍偵曄姺偝傟偨MAC傾僪儗僗 */char *mac_ntoa(u_char *d){#define MAX_MACSTR 50 static char str[MAX_MACSTR]; /* 暥帤楍偵曄姺偟偨MAC傾僪儗僗傪曐懚 */ snprintf(str, MAX_MACSTR, "%02x:%02x:%02x:%02x:%02x:%02x", d[0], d[1], d[2], d[3], d[4], d[5]); return str;}/* * void print_ethernet(struct ether_header *eth); * 婡擻 * Ethernet僿僢僟偺昞帵 * 堷偒悢 * struct ether_header *eth; Ethernet僿僢僟峔憿懱傊偺億僀儞僞 * 栠傝抣 * 側偟 */void print_ethernet(struct ether_header *eth){ int type = ntohs(eth->ether_type); /* Ethernet僞僀僾 */ if (type <= 1500) printf("IEEE 802.3 Ethernet Frame:\n"); else printf("Ethernet Frame:\n"); printf("+-------------------------+-------------------------" "+-------------------------+\n"); printf("| Destination MAC Address: " " %17s|\n", mac_ntoa(eth->ether_dhost)); printf("+-------------------------+-------------------------" "+-------------------------+\n"); printf("| Source MAC Address: " " %17s|\n", mac_ntoa(eth->ether_shost)); printf("+-------------------------+-------------------------" "+-------------------------+\n"); if (type < 1500) printf("| Length: %5u|\n", type); else printf("| Ethernet Type: 0x%04x|\n", type); printf("+-------------------------+\n");}/* * void print_arp(struct ether_arp *arp); * 婡擻 * ARP僷働僢僩偺昞帵 * 堷偒悢 * struct ether_arp *arp; ARP僷働僢僩峔憿懱傊偺億僀儞僞 * 栠傝抣 * 側偟 */void print_arp(struct ether_arp *arp){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -