libpcap应用实例
来源:互联网 发布:数据库服务器 交换机 编辑:程序博客网 时间:2024/04/30 07:41
libpcap落地包dump
#include <stdio.h>#include <pcap.h> /*Libpcap头文件*/void packet_callback(u_char *user,const struct pcap_pkthdr* packet_header,const u_char* packet_content){ static int packet_number = 1; /*静态局部变量,用来存放捕获到的数据包的个数*/ printf("The %d packet is captured len%d.\n",packet_number,packet_header->len); /*输出捕获数据包的个数*/ pcap_dump(user, packet_header, packet_content); /*调用pcap_dump函数写入文件*/ packet_number++; /*每次调用此回调函数,个数+1*/}void main(){ pcap_t* pcap_handle; /*Libpcap句柄*/ pcap_dumper_t *dumpfp; /*定义dump句柄*/ char error_content[PCAP_ERRBUF_SIZE]; /*用来存储错误信息*/ char *net_interface; /*用来存储网络接口*/ struct bpf_program bpf_filter; /*BPF过滤规则*/ char bpf_filter_string[] = "tcp port 80"; /*过滤规则字符串形式*/ bpf_u_int32 net_mask; /*网络掩码*/ bpf_u_int32 net_ip; /*网络地址*/ net_interface = pcap_lookupdev(error_content); /*获取网络接口*/ pcap_lookupnet(net_interface, &net_ip,&net_mask,error_content); /*获取网络地址和掩码*/ pcap_handle = pcap_open_live(net_interface, BUFSIZ, 1, 0, error_content); pcap_compile(pcap_handle, &bpf_filter, bpf_filter_string, 0, net_ip); pcap_setfilter(pcap_handle, &bpf_filter); dumpfp = pcap_dump_open(pcap_handle, "./traffic"); pcap_loop(pcap_handle, -1, packet_callback, (u_char *)dumpfp); pcap_close(pcap_handle); /*关闭Libpcap操作*/ pcap_dump_close(dumpfp); /*关闭写入的文件*/}
libpcap落地包转发
/*pcap_sendpacket 转发包*/#include <pcap.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>/* default snap length (maximum bytes per packet to capture) */#define SNAP_LEN 1518/* ethernet headers are always exactly 14 bytes [1] */#define SIZE_ETHERNET 14/* Ethernet addresses are 6 bytes */#define ETHER_ADDR_LEN 6int main(int argc, char **argv){ char *dev = NULL; /* capture device name */ char errbuf[PCAP_ERRBUF_SIZE]; /* error buffer */ pcap_t *handle; /* packet capture handle */ pcap_t *sendhandle; /* packet capture handle */ const u_char *packet; struct pcap_pkthdr header; char filter_exp[] = "tcp port 80"; /* filter expression [3] */ struct bpf_program fp; /* compiled filter program (expression) */ bpf_u_int32 mask; /* subnet mask */ bpf_u_int32 net; /* ip */ int num_packets = -1; /* number of packets to capture */ dev = pcap_lookupdev(errbuf); if (dev == NULL) { fprintf(stderr, "Couldn't find default device: %s\n", errbuf); exit(EXIT_FAILURE); } sendhandle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf); if (handle == NULL) { fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); exit(EXIT_FAILURE); } handle = pcap_open_offline("traffic", errbuf); while(1){ packet = pcap_next(handle,&header); pcap_sendpacket(sendhandle, packet, header.len) ; } /* cleanup */ pcap_freecode(&fp); pcap_close(handle); printf("\nCapture complete.\n");return 0;}
libpcap中转包程序
网关设置/etc/sysconfig/network-scripts/ifcfg-eth0/*本机需要设置为SRCIP,DESTIP机器的网关通过SRCIP机器,连接DEST地址,DEST必须和SRCIP不是一个网段,这样通过网关转到本机本程序捕获后,将DEST转化到DESTIP,SRCIP转化到SRC(为了回消息的时候也通过网关给本机)这样SRCIP访问DESTIP会通过本机中转,本机可以截获所有信息*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pcap.h>#include <sys/types.h>#include <netinet/ip.h>#include <netinet/if_ether.h>#include <netinet/tcp.h>#include <netinet/in.h>#include <arpa/inet.h>#include <string.h>void handle_packet(u_char *user, const struct pcap_pkthdr* pkthdr,const u_char* packet);unsigned short check_sum(unsigned short *addr,int len);void print_payload(const u_char *payload, int len);void print_hex_ascii_line(const u_char *payload, int len, int offset);struct psd_header{ unsigned long saddr; unsigned long daddr; char mbz; char ptcl; unsigned short tcpl; };unsigned short port;#define SRCIP "192.168.100.51"//源真实IP#define DESTIP "192.168.100.190"//目标真实IP#define DEST "192.168.0.190" //目标虚拟地址#define SRC "192.168.0.207" //源虚拟地址(无所谓不用改,只要不在一个网段就行)#define PORT 8443//程序所在本机为网关/* default snap length (maximum bytes per packet to capture) */#define SNAP_LEN 1518int main(int argc, char **argv){ char *dev = NULL; char errbuf[PCAP_ERRBUF_SIZE]; pcap_t *handle = NULL; struct bpf_program filter; char filter_app[] = "tcp port 8443 and ( host 192.168.100.190 or 192.168.100.51 )";//源真实IP+目标真实IP+端口 bpf_u_int32 mask; bpf_u_int32 net; struct pcap_pkthdr header; const u_char *packet; int on = 1; int sockfd = socket(PF_INET,SOCK_RAW,IPPROTO_TCP); if(sockfd < 0){ fprintf(stderr,"Socket error:\n"); exit(-4); } if(setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on)) < 0) fprintf(stderr,"HDRINCL error\n"); /* create a socket */ if (argc == 2) { dev = argv[1]; } else if (argc > 2) { fprintf(stderr, "error: unrecognized command-line options\n\n"); exit(EXIT_FAILURE); } else { /* find a capture device if not specified on command-line */ dev = pcap_lookupdev(errbuf); if (dev == NULL) { fprintf(stderr, "Couldn't find default device: %s\n", errbuf); exit(EXIT_FAILURE); } } /* get network number and mask associated with capture device */ if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf); net = 0; mask = 0; } /* print capture info */ printf("Device: %s\n", dev); printf("Filter expression: %s\n", filter_app); if(NULL == (handle = pcap_open_live(dev,SNAP_LEN,1,0,errbuf))){ fprintf(stderr,"pcap_open_live() error:%s\n",errbuf); exit(-2); } if(-1 == pcap_compile(handle,&filter,filter_app,1,net)){ fprintf(stderr,"pcap_compile() error.\n"); exit(-3); } pcap_setfilter(handle,&filter);// while(1){// packet = pcap_next(handle,&header);// printf("captured a packet with length of [%d]\n",header.len);// handle_packet(&header,packet,sockfd);// } pcap_loop(handle, -1, handle_packet, (u_char *)&sockfd); pcap_close(handle); return 0;}void handle_packet(u_char *user, const struct pcap_pkthdr* pkthdr,const u_char* packet){ int sockfd = *user; u_char buffer[SNAP_LEN]; int len = pkthdr->len; struct iphdr* ip; struct tcphdr* tcp; char srcbuf[16]; char dstbuf[16]; u_char temp[SNAP_LEN]; struct sockaddr_in addr; struct psd_header psdhdr; int ip_len; memset(buffer,0,SNAP_LEN); memset(temp,0,SNAP_LEN); memcpy(buffer,packet,len); memset(srcbuf,0,16); memset(dstbuf,0,16); memset(&addr,0,sizeof(struct sockaddr_in)); memset(&psdhdr,0,sizeof(struct psd_header)); ip = (struct iphdr *)(buffer + sizeof(struct ethhdr)); tcp = (struct tcphdr *)(buffer + sizeof(struct ethhdr) + sizeof(struct iphdr)); //int iphl_size = ip->ihl *4 ; //ip头长度 // int tcphl_size =tcp->doff * 4;//tcp头长度 //u_char *payload = (u_char *)(buffer + sizeof(struct ethhdr) + iphl_size + tcphl_size ); /* compute tcp payload (segment) size */ //int size_payload = ntohs(ip->tot_len) - ( iphl_size + tcphl_size) ; /* * Print payload data; it might be binary, so don't just * treat it as a string. */// if (size_payload > 0) {// printf(" Payload (%d bytes):\n", size_payload);// print_payload(payload, size_payload);// } ip_len = ntohs(ip->tot_len); strcpy(srcbuf,inet_ntoa(((struct ip *)(buffer + sizeof(struct ethhdr)))->ip_src)); strcpy(dstbuf,inet_ntoa(((struct ip *)(buffer + sizeof(struct ethhdr)))->ip_dst)); printf("source ip:%s\n",srcbuf); printf("destination ip:%s\n",dstbuf); printf("len:%d\n",ip_len); printf("fin:%x,syn:%x,rst:%x,psh:%x,ack:%x,urg:%x\n", tcp->fin,tcp->syn,tcp->rst,tcp->psh,tcp->ack,tcp->urg ); if(strcmp(dstbuf,DEST) == 0) { if(strcmp(srcbuf,SRCIP) == 0) { addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = inet_addr(DESTIP); ip->daddr = addr.sin_addr.s_addr; ip->saddr = inet_addr(SRC); ip->check = 0; ip->check = check_sum((unsigned short *)ip,sizeof(struct iphdr)); tcp->dest = addr.sin_port; port = tcp->source; tcp->source = htons(PORT); tcp->check = 0; psdhdr.saddr = ip->saddr; psdhdr.daddr = ip->daddr; psdhdr.mbz = 0; psdhdr.ptcl = IPPROTO_TCP; psdhdr.tcpl = htons(ip_len - sizeof(struct iphdr)); memcpy(temp,&psdhdr,sizeof(struct psd_header)); memcpy(temp + sizeof(struct psd_header),tcp,ip_len - sizeof(struct iphdr)); tcp->check = check_sum((unsigned short *)temp,sizeof(struct psd_header) + ip_len - sizeof(struct iphdr)); sendto(sockfd,buffer + sizeof(struct ethhdr),ip_len,0,(struct sockaddr *)(&addr),sizeof(struct sockaddr)); } } else if(strcmp(srcbuf,DESTIP) == 0) { if(strcmp(dstbuf,SRC) == 0) { addr.sin_family = AF_INET; addr.sin_port = port; addr.sin_addr.s_addr = inet_addr(SRCIP); ip->daddr = addr.sin_addr.s_addr; ip->saddr = inet_addr(DEST); ip->check = 0; ip->check = check_sum((unsigned short *)ip,sizeof(struct iphdr)); tcp->dest = addr.sin_port; tcp->source = htons(PORT); tcp->check = 0; psdhdr.saddr = ip->saddr; psdhdr.daddr = ip->daddr; psdhdr.mbz = 0; psdhdr.ptcl = IPPROTO_TCP; psdhdr.tcpl = htons(ip_len - sizeof(struct iphdr)); memcpy(temp,&psdhdr,sizeof(struct psd_header)); memcpy(temp + sizeof(struct psd_header),tcp,ip_len - sizeof(struct iphdr)); tcp->check = check_sum((unsigned short *)temp,sizeof(struct psd_header) + ip_len - sizeof(struct iphdr)); sendto(sockfd,buffer + sizeof(struct ethhdr),ip_len,0,(struct sockaddr *)(&addr),sizeof(struct sockaddr)); } }}unsigned short check_sum(unsigned short *addr,int len){ register int nleft = len; register int sum = 0; register u_short *w = addr; u_short answer = 0; while(nleft > 1){ sum += *w++; nleft -= 2; } if(nleft == 1){ *(u_char *)(&answer) = *(u_char *)w; sum += answer; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return (answer);}/* * print packet payload data (avoid printing binary data) */void print_payload(const u_char *payload, int len){ int len_rem = len; int line_width = 16; /* number of bytes per line */ int line_len; int offset = 0; /* zero-based offset counter */ const u_char *ch = payload; if (len <= 0) return; /* data fits on one line */ if (len <= line_width) { print_hex_ascii_line(ch, len, offset); return; } /* data spans multiple lines */ for ( ;; ) { /* compute current line length */ line_len = line_width % len_rem; /* print line */ print_hex_ascii_line(ch, line_len, offset); /* compute total remaining */ len_rem = len_rem - line_len; /* shift pointer to remaining bytes to print */ ch = ch + line_len; /* add offset */ offset = offset + line_width; /* check if we have line width chars or less */ if (len_rem <= line_width) { /* print last line and get out */ print_hex_ascii_line(ch, len_rem, offset); break; } }return;}/* * print data in rows of 16 bytes: offset hex ascii * * 00000 47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a GET / HTTP/1.1.. */void print_hex_ascii_line(const u_char *payload, int len, int offset){ int i; int gap; const u_char *ch; /* offset */ printf("%05d ", offset); /* hex */ ch = payload; for(i = 0; i < len; i++) { printf("%02x ", *ch); ch++; /* print extra space after 8th byte for visual aid */ if (i == 7) printf(" "); } /* print space to handle line less than 8 bytes */ if (len < 8) printf(" "); /* fill hex gap with spaces if not full line */ if (len < 16) { gap = 16 - len; for (i = 0; i < gap; i++) { printf(" "); } } printf(" "); /* ascii (if printable) */ ch = payload; for(i = 0; i < len; i++) { if (isprint(*ch)) printf("%c", *ch); else printf("."); ch++; } printf("\n");return;}
0 0
- libpcap应用实例
- libpcap应用
- libpcap使用入门实例
- libpcap
- libpcap
- LIBPCAP
- libpcap
- libpcap
- libpcap
- Libpcap
- libpcap
- libpcap
- libpcap
- libpcap
- libpcap
- linux 下 libpcap抓包实例程序
- libpcap库的使用与实例解析
- 网络编程系列之五 libpcap库(共24个函数的实例)
- Oracle 触发器 插入,更新,删除,数据同步,两表同步
- 开源Cortex-M模拟器QEMU的使用方法
- IOS pch 文件的设置
- 黑马程序员-----------中文乱码一
- ios在移动动画过程中响应触摸
- libpcap应用实例
- 使用js实现全选 单选 全部选
- iOS-UITextField限制输入的字符个数
- 编程日常
- 2020: C语言实验——计算表达式
- thinkphp
- view
- Nginx源码分析 - 初探Nginx的架构
- [Memcached]Memcached 的删除机制和发展方向