• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
agchrys
博客园    首页    新随笔    联系   管理    订阅  订阅
libpcap+rawsocket实现数据包转发

 

Code
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <pcap.h>
  5 #include <sys/types.h>
  6 #include <netinet/ip.h>
  7 #include <netinet/if_ether.h>
  8 #include <netinet/tcp.h>
  9 #include <netinet/in.h>
 10 #include <arpa/inet.h>
 11 #include <string.h>
 12 
 13 void handle_packet(const struct pcap_pkthdr* pkthdr,const u_char* packet,int sockfd);
 14 unsigned short check_sum(unsigned short *addr,int len);
 15 
 16 struct psd_header{
 17     unsigned long saddr;
 18     unsigned long daddr;
 19     char mbz;
 20     char ptcl;
 21     unsigned short tcpl;                            
 22 };
 23 
 24 unsigned short port;
 25 
 26 int main(int argc, char **argv)
 27 {
 28     char *dev = NULL;
 29     char errbuf[PCAP_ERRBUF_SIZE];
 30     pcap_t *handle = NULL;
 31     struct bpf_program filter;
 32     char filter_app[] = "tcp port 80";
 33     bpf_u_int32 mask;
 34     bpf_u_int32 net;
 35     struct pcap_pkthdr header;
 36     const u_char *packet;
 37     int sockfd;
 38     int on = 1;
 39 
 40     sockfd = socket(PF_INET,SOCK_RAW,IPPROTO_TCP);
 41     if(sockfd < 0){
 42         fprintf(stderr,"Socket error:\n");
 43         exit(-4);
 44     }
 45     if(setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on)) < 0)
 46       fprintf(stderr,"HDRINCL error\n");
 47 
 48 
 49     if(NULL == (dev = pcap_lookupdev(errbuf))){
 50         fprintf(stderr,"pcap_lookupdev() Error:%s\n",errbuf);
 51         exit(-1);
 52     }
 53 
 54     fprintf(stdout,"sniffing on device: %s\n",dev);
 55 
 56     pcap_lookupnet(dev,&net,&mask,errbuf);
 57 
 58     if(NULL == (handle = pcap_open_live(dev,BUFSIZ,0,0,errbuf))){
 59         fprintf(stderr,"pcap_open_live() error:%s\n",errbuf);
 60         exit(-2);
 61     }
 62 
 63     if(-1 == pcap_compile(handle,&filter,filter_app,1,net)){
 64         fprintf(stderr,"pcap_compile() error.\n");
 65         exit(-3);
 66     }
 67 
 68     pcap_setfilter(handle,&filter);
 69 
 70     while(1){
 71         packet = pcap_next(handle,&header);
 72         printf("captured a packet with length of [%d]\n",header.len);
 73         handle_packet(&header,packet,sockfd);
 74     }
 75 
 76     pcap_close(handle);
 77 
 78     return 0;
 79 }
 80 
 81 void handle_packet(const struct pcap_pkthdr* pkthdr,const u_char* packet,int sockfd){
 82     u_char buffer[65535];
 83     int len = pkthdr->len;
 84     //struct ip* ip;
 85     struct iphdr* ip;
 86     struct tcphdr* tcp;
 87     char srcbuf[16];
 88     char dstbuf[16];
 89     u_char temp[65535];
 90     struct sockaddr_in addr;
 91     struct psd_header psdhdr;
 92     int ip_len;
 93 
 94     memset(buffer,0,65535);
 95     memset(temp,0,65535);
 96     memcpy(buffer,packet,len);
 97     memset(srcbuf,0,16);
 98     memset(dstbuf,0,16);
 99     memset(&addr,0,sizeof(struct sockaddr_in));
100     memset(&psdhdr,0,sizeof(struct psd_header));
101 
102     ip = (struct iphdr *)(buffer + sizeof(struct ethhdr));
103     tcp = (struct tcphdr *)(buffer + sizeof(struct ethhdr) + sizeof(struct iphdr));
104 
105     ip_len = ntohs(ip->tot_len);
106     strcpy(srcbuf,inet_ntoa(((struct ip *)(buffer + sizeof(struct ethhdr)))->ip_src));
107     strcpy(dstbuf,inet_ntoa(((struct ip *)(buffer + sizeof(struct ethhdr)))->ip_dst));
108     printf("source ip:%s\n",srcbuf);
109     printf("destination ip:%s\n",dstbuf);
110     printf("len:%d\n",ip_len);
111 
112     //  printf("%d\n",((struct iphdr *)(buffer + sizeof(struct ethhdr)))->daddr);
113     if(strcmp(dstbuf,"192.168.1.2") == 0){
114         //    printf("source ip:%s\n",srcbuf);
115         //    printf("destination ip:%s\n",dstbuf);
116         if(strcmp(srcbuf,"192.168.1.5") == 0){
117             addr.sin_family = AF_INET;
118             addr.sin_port = htons(80);
119             addr.sin_addr.s_addr = inet_addr("202.120.58.161");
120             ip->daddr = addr.sin_addr.s_addr;
121             ip->saddr = inet_addr("192.168.1.2");
122             ip->check = 0;
123             ip->check = check_sum((unsigned short *)ip,sizeof(struct iphdr));
124             tcp->dest = addr.sin_port;
125             port = tcp->source;
126             tcp->source = htons(80);    
127             tcp->check = 0;
128             psdhdr.saddr = ip->saddr;
129             psdhdr.daddr = ip->daddr;
130             psdhdr.mbz = 0;
131             psdhdr.ptcl = IPPROTO_TCP;
132             psdhdr.tcpl = htons(ip_len - sizeof(struct iphdr));
133             memcpy(temp,&psdhdr,sizeof(struct psd_header));
134             memcpy(temp + sizeof(struct psd_header),tcp,ip_len - sizeof(struct iphdr));
135             tcp->check = check_sum((unsigned short *)temp,sizeof(struct psd_header) + ip_len - sizeof(struct iphdr));
136             sendto(sockfd,buffer + sizeof(struct ethhdr),ip_len,0,(struct sockaddr *)(&addr),sizeof(struct sockaddr));
137         }
138         else if(strcmp(srcbuf,"202.120.58.161") == 0){
139             addr.sin_family = AF_INET;
140             addr.sin_port = port; 
141             addr.sin_addr.s_addr = inet_addr("192.168.1.5");
142             ip->daddr = addr.sin_addr.s_addr;
143             ip->saddr = inet_addr("192.168.1.2");
144             ip->check = 0;
145             ip->check = check_sum((unsigned short *)ip,sizeof(struct iphdr));
146             tcp->dest = addr.sin_port;
147             tcp->source = htons(80);
148             tcp->check = 0;
149             psdhdr.saddr = ip->saddr;
150             psdhdr.daddr = ip->daddr;
151             psdhdr.mbz = 0;
152             psdhdr.ptcl = IPPROTO_TCP;
153             psdhdr.tcpl = htons(ip_len - sizeof(struct iphdr));
154             memcpy(temp,&psdhdr,sizeof(struct psd_header));
155             memcpy(temp + sizeof(struct psd_header),tcp,ip_len - sizeof(struct iphdr));
156             tcp->check = check_sum((unsigned short *)temp,sizeof(struct psd_header) + ip_len - sizeof(struct iphdr)); 
157             sendto(sockfd,buffer + sizeof(struct ethhdr),ip_len,0,(struct sockaddr *)(&addr),sizeof(struct sockaddr));
158         }
159     }
160 }
161 
162 unsigned short check_sum(unsigned short *addr,int len){
163     register int nleft = len;
164     register int sum = 0;
165     register u_short *w = addr;
166     u_short answer = 0;
167 
168     while(nleft > 1){
169         sum += *w++;
170         nleft -= 2;
171     }
172     if(nleft == 1){
173         *(u_char *)(&answer) = *(u_char *)w;
174         sum += answer;
175     }
176     sum = (sum >> 16) + (sum & 0xffff);
177     sum += (sum >> 16);
178     answer = ~sum;
179     return (answer);
180 }
181 

 

192.168.1.5的浏览器中输入http://192.168.1.2/,将会显示bbs.sjtu.edu.cn

 

posted on 2009-06-01 17:34  agchrys  阅读(1418)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3