假设有 
服务进程:S 
客户进程:C 
C和S建立了TCP连接进行通信 
我现在要建立另外一个客户进程C1伪装成进程C,C1能够向S发送数据data,并且对于服务进程S来说,应该认为数据data是C发送的,并把应答数据发送到C 
请问该如何设计进程C1(C1和C是在同一台客户机上的)    

解决方案 »

  1.   

    没做过
    是不是要直接修改C1发送过来的ip包?把ip地址改成c的?
      

  2.   

    长连接是建立来发送是不行的!自己按TCP的格式组IP包,发给主站!
      

  3.   

    对于S来说,它已经建立了C连接了,即它会接收C的MAC地址和端口发送过来的数据,如果你想C1发送的数据S能接收,你就要把C1的端口改为C的端口,用raw来做可能能实现。
    就有如是sniffer pro的修改数据发送
      

  4.   

    向ydzqw(===七条狗===)(@@我不爱做菜) 学习
      

  5.   

    谢谢各位 特别是ydzqw(===七条狗===)(@@我不爱做菜) 
    我试试
    大家请不吝指教
      

  6.   

    在tcp/ip协议下目标ip+目标端口 源ip+源端口 都可以自己设定
    这个用raw_socket就可以实现
    我写了 s c c1 三个程序了
    不过c1却不能按预期的方式工作 比较郁闷
    贴出来大家一起帮我搞定一下3个程序都是在linux下实现的 其中运行c1需要有root权限(raw_socket只有root权限用户才能创建)3个程序是这个工作的:服务进程S:
    运行服务进程有一个参数:服务端口
    假设服务端口为8000 则这样运行: ./s 8000
    程序运行后,如果有客户进程连接,服务器会提示该客户进程的地址和端口
    服务进程接收来自客户端的一个字符串并给该客户一个确认消息。客户进程C:
    客户进程有2个参数:服务器地址 服务器端口
    调试时候服务进程S和客户进程C都在自己机上 所以可以这样运行 ./c localhost 8000
    程序运行后,会等待用户输入一个字符串发送到服务器,同时接收到服务器的确认消息。伪装进程c1:
    伪装进程没有命令行参数,不过运行时候我提示了:cin severport and clientport
    severport就是s的端口 clientport为要伪装的客户进程C的端口(c的端口在c运行后在s中有提示,程序里面c1把源地址和目标地址都设为localhost了),我希望c1运行后服务进程S能发一个消息到客户进程c,但是没有成功。下面是3个程序:
      

  7.   

    /******* 服务器程序 (server.c) ************/ 
    #include<stdio.h> 
    #include<stdlib.h> 
    #include<unistd.h>
    #include<errno.h> 
    #include<string.h> 
    #include<sys/types.h> 
    #include<sys/socket.h>
    #include <netinet/in.h>  
    #include <netdb.h>#define EXIT 100int main(int argc, char *argv[]) 

    int sockfd,new_fd; 
    struct sockaddr_in server_addr; 
    struct sockaddr_in client_addr; 
    int sin_size,portnumber; 
    char hello[]="Get!!!\n"; 
    char buffer[1024];
    int nbytes;if(argc!=2) 

    fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); 
    exit(1); 
    } if((portnumber=atoi(argv[1]))<0) 

    fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); 
    exit(1); 
    } /* 服务器端开始建立socket描述符 */ 
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) 

    fprintf(stderr,"Socket error:%s\n\a",strerror(errno)); 
    exit(1); 
    } /* 服务器端填充 sockaddr结构 */ 
    bzero(&server_addr,sizeof(struct sockaddr_in)); 
    server_addr.sin_family=AF_INET; 
    server_addr.sin_addr.s_addr=htonl(INADDR_ANY); 
    server_addr.sin_port=htons(portnumber); /* 捆绑sockfd描述符 */ 
    if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) 

    fprintf(stderr,"Bind error:%s\n\a",strerror(errno)); 
    exit(1); 
    } /* 监听sockfd描述符 */ 
    if(listen(sockfd,10)==-1) 

    fprintf(stderr,"Listen error:%s\n\a",strerror(errno)); 
    exit(1); 
    } while(1) 

        /* 服务器阻塞,直到客户程序建立连接 */ 
        sin_size=sizeof(struct sockaddr_in); 
        if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1) 
        { 
            fprintf(stderr,"Accept error:%s\n\a",strerror(errno)); 
            exit(1); 
        }     /* 建立一个子进程和客户进程连接 */
        if(fork()==0)
        {
            fprintf(stderr,"Server get connection from %s:%d\n", inet_ntoa(client_addr.sin_addr),
    ntohs(client_addr.sin_port)); 
            while(1)
    {
    if((nbytes=read(new_fd,buffer,1024))==-1) 
            { 
                    fprintf(stderr,"Read Error:%s\n",strerror(errno)); 
                    exit(1); 
            }
    buffer[nbytes]='\0';
    if(strcmp(buffer,"exit")==0)
    {
    close(new_fd);
    exit(EXIT);
    }
            fprintf(stderr,"get message from cilent:%s\n",buffer);

    if(write(new_fd,hello,strlen(hello))==-1) 

                    fprintf(stderr,"Write Error:%s\n",strerror(errno)); 
                    exit(1); 
            }          
    }

        }
    }
    close(sockfd); 
    exit(0); 
    }
      

  8.   

    /******* 客户端程序 client.c ************/ 
    #include<stdio.h> 
    #include<stdlib.h> 
    #include<unistd.h>
    #include<errno.h> 
    #include<string.h> 
    #include<sys/types.h> 
    #include<sys/socket.h>
    #include <netinet/in.h>  
    #include <netdb.h>#define EXIT 100int main(int argc, char *argv[]) 

    int sockfd; 
    char buffer[1024]; 
    struct sockaddr_in server_addr; 
    struct hostent *host; 
    int portnumber,nbytes; int exitstatus;if(argc!=3) 

    fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); 
    exit(1); 
    } if((host=gethostbyname(argv[1]))==NULL) 

    fprintf(stderr,"Gethostname error\n"); 
    exit(1); 
    } if((portnumber=atoi(argv[2]))<0) 

    fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); 
    exit(1); 
    } /* 客户程序开始建立 sockfd描述符 */ 
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) 

    fprintf(stderr,"Socket Error:%s\a\n",strerror(errno)); 
    exit(1); 
    } /* 客户程序填充服务端的资料 */ 
    bzero(&server_addr,sizeof(server_addr)); 
    server_addr.sin_family=AF_INET; 
    server_addr.sin_port=htons(portnumber); 
    server_addr.sin_addr=*((struct in_addr *)host->h_addr); /* 客户程序发起连接请求 */ 
    if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) 

    fprintf(stderr,"Connect Error:%s\a\n",strerror(errno)); 
    exit(1); 

    /* 连接成功了 */
    /* 创建一个子进程往服务器发送数据 */
    if(fork()==0)
    {
    while(1)
    {
    /* getline(buffer); */
    scanf("%s",buffer);
    if(write(sockfd,buffer,strlen(buffer))==-1) 

        fprintf(stderr,"Write Error:%s\n",strerror(errno)); 
        exit(1); 

    if(strcmp(buffer,"exit")==0)
    {
    close(sockfd);
    exit(EXIT);
    }
    }
    }
    /* 创建一干子进程接收并显示服务器来的数据 */
    if(fork()==0)
    {
    while(1)
    {

    if((nbytes=read(sockfd,buffer,1024))==-1) 

    fprintf(stderr,"Read Error:%s\n",strerror(errno)); 
    exit(1); 

    buffer[nbytes]='\0'; 
    printf("Get Message from server:%s",buffer); 
    }
    }
    while(1)
    {
    wait(&exitstatus);
    exitstatus=(exitstatus>>8)%256;
    if(exitstatus==EXIT)
    exit(0);
    }}
     
      

  9.   

    /****************** c1.c **********************/
    #define __USE_BSD /* use bsd'ish ip header */
    #include <sys/socket.h> /* these headers are for a Linux system, but */
    #include <netinet/in.h> /* the names on other systems are easy to guess.. */
    #include <netinet/ip.h>
    #define __FAVOR_BSD /* use bsd'ish tcp header */
    #include <netinet/tcp.h>
    #include <unistd.h>int serverport,clientport;
    char message[]="cloud_long";
    unsigned short /* this function generates header checksums */
    csum (unsigned short *buf, int nwords)
    {
      unsigned long sum;
      for (sum = 0; nwords > 0; nwords--)
        sum += *buf++;
      sum = (sum >> 16) + (sum & 0xffff);
      sum += (sum >> 16);
      return ~sum;
    }int 
    main (void)
    {
      int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP); /* open raw socket */
      char datagram[4096]; /* this buffer will contain ip header, tcp header,
       and payload. we'll point an ip header structure
       at its beginning, and a tcp header structure after
       that to write the header values into it */
      struct ip *iph = (struct ip *) datagram;
      struct tcphdr *tcph = (struct tcphdr *) datagram + sizeof (struct ip);
      struct sockaddr_in sin;
    /* the sockaddr_in containing the dest. address is used
       in sendto() to determine the datagrams path */
     printf("cin serverport and client:");
     scanf("%d%d",&serverport,&clientport);  sin.sin_family = AF_INET;
      sin.sin_port = htons (serverport);/* you byte-order >1byte header values to network
          byte order (not needed on big endian machines) */
      sin.sin_addr.s_addr = inet_addr ("127.0.0.1");  memset (datagram, 0, 4096); /* zero out the buffer */  strcpy(datagram+sizeof(struct ip)+sizeof(struct tcphdr),message);/* we'll now fill in the ip/tcp header values, see above for explanations */
      iph->ip_hl = 5;
      iph->ip_v = 4;
      iph->ip_tos = 0;
      iph->ip_len = sizeof (struct ip) + sizeof (struct tcphdr) + strlen (message);
      iph->ip_id = htonl (54321); /* the value doesn't matter here */
      iph->ip_off = 0;
      iph->ip_ttl = 255;
      iph->ip_p = 6;
      iph->ip_sum = 0; /* set it to 0 before computing the actual checksum later */
      iph->ip_src.s_addr = inet_addr ("127.0.0.1");/* SYN's can be blindly spoofed */
      iph->ip_dst.s_addr = sin.sin_addr.s_addr;
      tcph->th_sport = htons (clientport); /* arbitrary port */
      tcph->th_dport = htons (serverport);
      tcph->th_seq = random ();/* in a SYN packet, the sequence is a random */
      tcph->th_ack = 0;/* number, and the ack sequence is 0 in the 1st packet */
      tcph->th_x2 = 0;
      tcph->th_off = 0; /* first and only tcp segment */
      tcph->th_flags = TH_SYN; /* initial connection request */
      tcph->th_win = htonl (65535); /* maximum allowed window size */
      tcph->th_sum = 0;/* if you set a checksum to zero, your kernel's IP stack
          should fill in the correct checksum during transmission */
      tcph->th_urp = 0;  iph->ip_sum = csum ((unsigned short *) datagram, iph->ip_len >> 1); 
      
    /* finally, it is very advisable to do a IP_HDRINCL call, to make sure
       that the kernel knows the header is included in the data, and doesn't
       insert its own header into the packet before our data */  { /* lets do it the ugly way.. */
        int one = 1;
        const int *val = &one;
        if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
          printf ("Warning: Cannot set HDRINCL!\n");
      }
        
          if (sendto (s, /* our socket */
      datagram, /* the buffer containing headers and data */
      iph->ip_len, /* total length of our datagram */
      0, /* routing flags, normally always 0 */
      (struct sockaddr *) &sin, /* socket addr, just like in */
      sizeof (sin)) < 0) /* a normal send() */
    printf ("error\n");  return 0;
    }