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
原创粉丝点击