libpcap使用示例
来源:互联网 发布:线切割yh编程系统 编辑:程序博客网 时间:2024/06/08 09:50
/** * @author lijk@.infosec.com.cn * @version 0.0.1 * @date 2016-6-1 11:50:10 */#include <pcap.h>#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <stdbool.h>#include <errno.h>#include <string.h>#include <unistd.h>#include <getopt.h>#include <libgen.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <linux/if_ether.h>#include <linux/ip.h>#include <linux/icmp.h>#include <linux/tcp.h>#include <linux/udp.h>static void dump_packet_fp(FILE *fp, unsigned char *packet, unsigned int packet_len){ int i, j; if(!packet || packet_len <= 0) return; for (i = 0; i < packet_len; i++) { if (i % 16 == 0) fprintf( fp, " "); fprintf( fp, "%02x ", packet[i]); if ((i + 1) % 16 == 0) { fprintf( fp, " "); for (j = 0; j <= i % 16; j++) { unsigned char c; if (i-15+j >= packet_len) break; c = packet[i-15+j]; fprintf( fp, "%c", c > 32 && c < 128 ? c : '.'); } fprintf( fp, "\n"); } } if (packet_len % 16 != 0) { for (j = i % 16; j < 16; j++) { fprintf( fp, " "); } fprintf( fp, " "); for (j = i & ~0xf; j < packet_len; j++) { unsigned char c; c = packet[j]; fprintf( fp, "%c", c > 32 && c < 128 ? c : '.'); } fprintf( fp, "\n"); }}/* struct pcap_pkthdr { struct timeval ts; time stamp bpf_u_int32 caplen; length of portion present bpf_u_int32 len; length this packet (off wire) };*/static void pcap_cb(unsigned char *user, const struct pcap_pkthdr *hdr, const unsigned char *data){ int *cnt = (int *)user; char src_ip[INET_ADDRSTRLEN+1] = {0}, dst_ip[INET_ADDRSTRLEN+1] = {0}; fprintf(stdout, "cnt: %d\n", ++(*cnt)); fprintf(stdout, "--------------------------------\n"); struct ethhdr *eth_hdr = (struct ethhdr*)data; if(eth_hdr == NULL) return; uint8_t eth_hdrlen = sizeof(struct ethhdr); //ETH包头长度: 14 fprintf(stdout, "eth proto: %hu\n", ntohs(eth_hdr->h_proto)); fprintf(stdout, "src_mac: %02x:%02x:%02x:%02x:%02x:%02x ", eth_hdr->h_source[0], eth_hdr->h_source[1], eth_hdr->h_source[2], eth_hdr->h_source[3], eth_hdr->h_source[4], eth_hdr->h_source[5]); fprintf(stdout, "-> "); fprintf(stdout, "dst_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", eth_hdr->h_dest[0], eth_hdr->h_dest[1], eth_hdr->h_dest[2], eth_hdr->h_dest[3], eth_hdr->h_dest[4], eth_hdr->h_dest[5]); struct iphdr *ip_hdr = (struct iphdr *)(hdr->len > eth_hdrlen ? data + eth_hdrlen : NULL);#if 1 if(ntohs(eth_hdr->h_proto) != ETH_P_IP || ip_hdr == NULL) return;#else if(ntohs(eth_hdr->h_proto) != ETH_P_IPV6 || ipv6_hdr == NULL) return;#endif uint8_t ip_hdrlen = ip_hdr->ihl*4; //IP包头长度 uint16_t ip_totlen = ntohs(ip_hdr->tot_len); //IP包总长度 inet_ntop(AF_INET, &ip_hdr->saddr, src_ip, INET_ADDRSTRLEN+1); inet_ntop(AF_INET, &ip_hdr->daddr, dst_ip, INET_ADDRSTRLEN+1); fprintf(stdout, "ip proto: %hhu\n", ip_hdr->protocol); fprintf(stdout, "src_ip: %s ", src_ip); fprintf(stdout, "-> "); fprintf(stdout, "dst_ip: %s\n", dst_ip); if(ip_hdr->protocol == IPPROTO_ICMP) { struct icmphdr *icmp_hdr = (struct icmphdr*)(data + eth_hdrlen + ip_hdrlen); uint8_t icmp_hdrlen = sizeof(struct icmphdr); //ICMP包头长度 uint16_t icmp_bdylen = ip_totlen - ip_hdrlen - icmp_hdrlen; //ICMP包体长度 fprintf(stdout, "type: %hhu ", icmp_hdr->type); fprintf(stdout, "code: %hhu ", icmp_hdr->code); fprintf(stdout, "checksum: %hu\n", ntohs(icmp_hdr->checksum)); dump_packet_fp(stdout, (unsigned char*)(data + eth_hdrlen + ip_hdrlen + icmp_hdrlen), icmp_bdylen); } else if(ip_hdr->protocol == IPPROTO_TCP) { struct tcphdr *tcp_hdr = (struct tcphdr*)(data + eth_hdrlen + ip_hdrlen); uint8_t tcp_hdrlen = tcp_hdr->doff*4; //TCP包头长度 uint16_t tcp_bdylen = ip_totlen - ip_hdrlen - tcp_hdrlen; //TCP包体长度 fprintf(stdout, "src_port: %hu ", ntohs(tcp_hdr->source)); fprintf(stdout, "-> "); fprintf(stdout, "dst_port: %hu\n", ntohs(tcp_hdr->dest)); dump_packet_fp(stdout, (unsigned char*)(data + eth_hdrlen + ip_hdrlen + tcp_hdrlen), tcp_bdylen); } else if(ip_hdr->protocol == IPPROTO_UDP) { struct udphdr *udp_hdr = (struct udphdr*)(data + eth_hdrlen + ip_hdrlen); uint8_t udp_hdrlen = sizeof(struct udphdr); //UDP包头长度: 8 uint16_t udp_totlen = ntohs(udp_hdr->len); //UDP包总长度 fprintf(stdout, "src_port: %hu ", ntohs(udp_hdr->source)); fprintf(stdout, "-> "); fprintf(stdout, "dst_port: %hu\n", ntohs(udp_hdr->dest)); dump_packet_fp(stdout, (unsigned char*)(data + eth_hdrlen + ip_hdrlen + udp_hdrlen), udp_totlen - udp_hdrlen); } else { fprintf(stdout, "unknown ip packet\n"); dump_packet_fp(stdout, (unsigned char*)(data + eth_hdrlen + ip_hdrlen), ip_totlen - ip_hdrlen); } fprintf(stdout, "--------------------------------\n");}static char* copy_argv(register char **argv){ register char **p; register u_int len = 0; char *buf; char *src, *dst; p = argv; if (*p == 0) return NULL; while (*p) len += strlen(*p++) + 1; buf = (char *)malloc(len); if (buf == NULL) return NULL; p = argv; dst = buf; while ((src = *p++) != NULL) { while ((*dst++ = *src++) != '\0') ; dst[-1] = ' '; } dst[-1] = '\0'; return buf;}int main(int argc, char *argv[]){ int c = 0, option_index = 0; int daimon = 0; char *device = "eth0"; char *readfile = NULL; char ebuf[PCAP_ERRBUF_SIZE+1] = {0}; pcap_t *pd = NULL; bpf_u_int32 localnet = PCAP_NETMASK_UNKNOWN, netmask = PCAP_NETMASK_UNKNOWN; char net[INET_ADDRSTRLEN+1] = {0}, mask[INET_ADDRSTRLEN+1] = {0}; struct bpf_program fcode; char *cmdbuf = NULL; int status = 0; static int packet_count = 0; static struct option long_options[] = { {"interface", required_argument, NULL, 'i'}, {"readfile", required_argument, NULL, 'r'}, {"daemon", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {0,0,0,0} }; opterr = 0; while((c = getopt_long(argc, argv, "i:r:dh", long_options, &option_index)) != -1) { switch(c) { case 'i': device = optarg; break; case 'r': readfile = optarg; break; case 'd': daimon = 1; break; case 'h': fprintf(stdout, "Usage:\n"); fprintf(stdout, "-i, --interface <device>, default is: \"%s\"\n", device); fprintf(stdout, "-r, --readfile <pcap>\n"); fprintf(stdout, "-d, --daemon\n"); fprintf(stdout, "-h, --help\n"); exit(EXIT_SUCCESS); break; default: fprintf(stderr, "Usage:\n"); fprintf(stderr, "-i, --interface <device>, default is: \"%s\"\n", device); fprintf(stderr, "-r, --readfile <pcap>\n"); fprintf(stderr, "-d, --daemon\n"); fprintf(stderr, "-h, --help\n"); exit(EXIT_FAILURE); break; } } char *program_name = basename(argv[0]); if(daimon) daemon(0, 0); if(readfile) { access(readfile, R_OK); pd = pcap_open_offline(readfile, ebuf); if(pd == NULL) { fprintf(stderr, "pcap_open_offline: %s\n", ebuf); return -1; } } else { if(device == NULL) { device = pcap_lookupdev(ebuf); if(device == NULL) { fprintf(stderr, "pcap_lookupdev: %s\n", ebuf); return -1; } } pd = pcap_open_live(device, 65535, 0, 1000, ebuf); if(pd == NULL) { fprintf(stderr, "pcap_open_live: %s\n", ebuf); return -1; } if(pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { fprintf(stderr, "pcap_lookupnet: %s\n", ebuf); goto ErrP; } if(inet_ntop(AF_INET, &localnet, net, INET_ADDRSTRLEN+1)) fprintf(stdout, "net: %s\n", net); if(inet_ntop(AF_INET, &netmask, mask, INET_ADDRSTRLEN+1)) fprintf(stdout, "mask: %s\n", mask); } cmdbuf = copy_argv(&argv[optind]); if(pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0) { fprintf(stderr, "pcap_compile: %s\n", pcap_geterr(pd)); goto ErrP; } if(pcap_setfilter(pd, &fcode) < 0) { fprintf(stderr, "pcap_setfilter: %s\n", pcap_geterr(pd)); goto ErrP; } pcap_freecode(&fcode); if(readfile) { while(true) { status = pcap_dispatch(pd, -1, pcap_cb, (unsigned char *)&packet_count); if(status <= 0) { if(status != 0) fprintf(stderr, "pcap_dispatch: %s\n", pcap_geterr(pd)); break; } } } else { while(true) { status = pcap_dispatch(pd, -1, pcap_cb, (unsigned char *)&packet_count); if(status < 0) { fprintf(stderr, "pcap_dispatch: %s\n", pcap_geterr(pd)); break; } } } fprintf(stdout, "%s: succeed\n", program_name); if(cmdbuf) free(cmdbuf); if(pd) pcap_close(pd); exit(EXIT_SUCCESS);ErrP: fprintf(stderr, "%s: failed\n", program_name); if(cmdbuf) free(cmdbuf); if(pd) pcap_close(pd); exit(EXIT_FAILURE);}
1 0
- libpcap使用示例
- libpcap示例
- Winpcap示例,Libpcap示例
- libpcap使用
- libpcap使用
- libpcap使用
- libpcap使用
- libpcap使用
- libpcap使用
- libpcap使用
- libpcap使用
- libpcap使用
- libpcap使用
- libpcap使用
- libpcap使用
- libpcap使用
- libpcap 使用
- libpcap使用
- HTTP Header 详解
- Visual Basic .NET
- light oj 1297 Largest Box
- 河南第五届ACM省赛(Divideing Jewels)
- 39. Combination Sum LeetCode
- libpcap使用示例
- MYSQL 主从复制
- Android开发之Service
- 位置参数变量
- 109. Convert Sorted List to Binary Search Tree LeetCode
- 【010】Xcode7编译时App installation failed There was an internal API error.
- 初识Universal-Image-Loader
- Activity生命周期详解
- android:SpannableString使用详解