我想在数据包发出去之前把IP数据报的源地址给换成别的,于是我就采取了这样的方法 
      ... ... ... 
  sockRaw = WSASocket (AF_INET, 
      SOCK_RAW, 
      IPPROTO_ICMP, 
      NULL,0,0); 
      ... ... ... 
  bread = setsockopt(sockRaw,IPPROTO_IP,IP_HDRINCL,&ion, 
sizeof(ion)); 
  bwrote = sendto(sockRaw,ip_data,datasize,0,(struct sockaddr*)&dest, 
sizeof(dest)); 
      ... ... ... 
  我是用了IP_HDRINCL,但程序却无反应,如果把ip_data改成icmp_data 
则用抓包工具看到的结果是IP报头仍然是原来的, 
  所以我不明白为什么我用了原始socket和IP_HDRINCL,并且是在Win2000下运行,为什么还是不能改IP包头呢? 
  一些资料上的实例都是同时改TCP(或UDP),IP的报头,对于这些程序我没运行过,所以怀疑是否能够很好的运行。

解决方案 »

  1.   

    IP_HDRINCL选项只是说明可以用RAW SOCKET,要想操作包头,要定义包结构,然后在根据需要操作。具体可以查找一下以前的帖子
      

  2.   

    同意ksyou
    #define MAX_MESSAGE        4068
    #define MAX_PACKET         4096
    //
    // Setup some default values 
    //
    #define DEFAULT_PORT       5000
    #define DEFAULT_IP         "192.168.0.100"
    #define DEFAULT_COUNT      5
    #define DEFAULT_MESSAGE    "This is a test"//
    // Define the IP header. Make the version and length field one
    // character since we can't declare two 4 bit fields without
    // the compiler aligning them on at least a 1 byte boundary.
    //
    typedef struct ip_hdr
    {
        unsigned char  ip_verlen;        // IP version & length
        unsigned char  ip_tos;           // IP type of service
        unsigned short ip_totallength;   // Total length
        unsigned short ip_id;            // Unique identifier 
        unsigned short ip_offset;        // Fragment offset field
        unsigned char  ip_ttl;           // Time to live
        unsigned char  ip_protocol;      // Protocol(TCP,UDP etc)
        unsigned short ip_checksum;      // IP checksum
        unsigned int   ip_srcaddr;       // Source address
        unsigned int   ip_destaddr;      // Destination address
    } IP_HDR, *PIP_HDR, FAR* LPIP_HDR;
    //
    // Define the UDP header 
    //
    typedef struct udp_hdr
    {
        unsigned short src_portno;       // Source port number
        unsigned short dst_portno;       // Destination port number
        unsigned short udp_length;       // UDP packet length
        unsigned short udp_checksum;     // UDP checksum (optional)
    } UDP_HDR, *PUDP_HDR;//
    // Global variables
    //
    unsigned long  dwToIP,               // IP to send to
                   dwFromIP;             // IP to send from (spoof)
    unsigned short iToPort,              // Port to send to
                   iFromPort;            // Port to send from (spoof)
    DWORD          dwCount;              // Number of times to send char  
       //  Creating a raw socket    //
        s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_UDP, NULL, 0,0);
        if (s == INVALID_SOCKET)
        {
            printf("WSASocket() failed: %d\n", WSAGetLastError());
            return -1;
        }    // Enable the IP header include option 
        //
        bOpt = TRUE;
        ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));
        if (ret == SOCKET_ERROR)
        {
            printf("setsockopt(IP_HDRINCL) failed: %d\n", WSAGetLastError());
            return -1;
        }
        // Initalize the IP header
        //
        iTotalSize = sizeof(ipHdr) + sizeof(udpHdr) + strlen(strMessage);    iIPVersion = 4;
        iIPSize = sizeof(ipHdr) / sizeof(unsigned long);
        //
        // IP version goes in the high order 4 bits of ip_verlen. The
        // IP header length (in 32-bit words) goes in the lower 4 bits.
        //
        ipHdr.ip_verlen = (iIPVersion << 4) | iIPSize;
        ipHdr.ip_tos = 0;                         // IP type of service
        ipHdr.ip_totallength = htons(iTotalSize); // Total packet len
        ipHdr.ip_id = 0;                 // Unique identifier: set to 0
        ipHdr.ip_offset = 0;             // Fragment offset field
        ipHdr.ip_ttl = 128;              // Time to live
        ipHdr.ip_protocol = 0x11;        // Protocol(UDP) 
        ipHdr.ip_checksum = 0 ;          // IP checksum
        ipHdr.ip_srcaddr = dwFromIP;     // Source address
        ipHdr.ip_destaddr = dwToIP;      // Destination address
        //
        // Initalize the UDP header
        //
        iUdpSize = sizeof(udpHdr) + strlen(strMessage);    udpHdr.src_portno = htons(iFromPort) ;
        udpHdr.dst_portno = htons(iToPort) ;
        udpHdr.udp_length = htons(iUdpSize) ;
        udpHdr.udp_checksum = 0 ;
        // 
        // Build the UDP pseudo-header for calculating the UDP checksum.
        // The pseudo-header consists of the 32-bit source IP address, 
        // the 32-bit destination IP address, a zero byte, the 8-bit
        // IP protocol field, the 16-bit UDP length, and the UDP
        // header itself along with its data (padded with a 0 if
        // the data is odd length).
        //
        iUdpChecksumSize = 0;
        ptr = buf;
        ZeroMemory(buf, MAX_PACKET);    memcpy(ptr, &ipHdr.ip_srcaddr,  sizeof(ipHdr.ip_srcaddr));  
        ptr += sizeof(ipHdr.ip_srcaddr);
        iUdpChecksumSize += sizeof(ipHdr.ip_srcaddr);    memcpy(ptr, &ipHdr.ip_destaddr, sizeof(ipHdr.ip_destaddr)); 
        ptr += sizeof(ipHdr.ip_destaddr);
        iUdpChecksumSize += sizeof(ipHdr.ip_destaddr);    ptr++;
        iUdpChecksumSize += 1;    memcpy(ptr, &ipHdr.ip_protocol, sizeof(ipHdr.ip_protocol)); 
        ptr += sizeof(ipHdr.ip_protocol);
        iUdpChecksumSize += sizeof(ipHdr.ip_protocol);    memcpy(ptr, &udpHdr.udp_length, sizeof(udpHdr.udp_length)); 
        ptr += sizeof(udpHdr.udp_length);
        iUdpChecksumSize += sizeof(udpHdr.udp_length);
        
        memcpy(ptr, &udpHdr, sizeof(udpHdr)); 
        ptr += sizeof(udpHdr);
        iUdpChecksumSize += sizeof(udpHdr);    for(i = 0; i < strlen(strMessage); i++, ptr++)
            *ptr = strMessage[i];
        iUdpChecksumSize += strlen(strMessage);    cksum = checksum((USHORT *)buf, iUdpChecksumSize);
        udpHdr.udp_checksum = cksum;
        //
        // Now assemble the IP and UDP headers along with the data
        //  so we can send it
        //        
        ZeroMemory(buf, MAX_PACKET);
        ptr = buf;    memcpy(ptr, &ipHdr, sizeof(ipHdr));   ptr += sizeof(ipHdr);
        memcpy(ptr, &udpHdr, sizeof(udpHdr)); ptr += sizeof(udpHdr);
        memcpy(ptr, strMessage, strlen(strMessage));    // Apparently, this SOCKADDR_IN structure makes no difference.
        // Whatever we put as the destination IP addr in the IP header
        // is what goes. Specifying a different destination in remote
     // will be ignored.
        //
        remote.sin_family = AF_INET;
        remote.sin_port = htons(iToPort);
        remote.sin_addr.s_addr = dwToIP;
       
        for(i = 0; i < dwCount; i++)
        {
            ret = sendto(s, buf, iTotalSize, 0, (SOCKADDR *)&remote, 
                sizeof(remote));
            if (ret == SOCKET_ERROR)
            {
                printf("sendto() failed: %d\n", WSAGetLastError());
                break;
            }
            else
                printf("sent %d bytes\n", ret);
        }
        closesocket(s) ;
        WSACleanup() ;
      

  3.   

    同意ksyou
    #define MAX_MESSAGE        4068
    #define MAX_PACKET         4096
    //
    // Setup some default values 
    //
    #define DEFAULT_PORT       5000
    #define DEFAULT_IP         "192.168.0.100"
    #define DEFAULT_COUNT      5
    #define DEFAULT_MESSAGE    "This is a test"//
    // Define the IP header. Make the version and length field one
    // character since we can't declare two 4 bit fields without
    // the compiler aligning them on at least a 1 byte boundary.
    //
    typedef struct ip_hdr
    {
        unsigned char  ip_verlen;        // IP version & length
        unsigned char  ip_tos;           // IP type of service
        unsigned short ip_totallength;   // Total length
        unsigned short ip_id;            // Unique identifier 
        unsigned short ip_offset;        // Fragment offset field
        unsigned char  ip_ttl;           // Time to live
        unsigned char  ip_protocol;      // Protocol(TCP,UDP etc)
        unsigned short ip_checksum;      // IP checksum
        unsigned int   ip_srcaddr;       // Source address
        unsigned int   ip_destaddr;      // Destination address
    } IP_HDR, *PIP_HDR, FAR* LPIP_HDR;
    //
    // Define the UDP header 
    //
    typedef struct udp_hdr
    {
        unsigned short src_portno;       // Source port number
        unsigned short dst_portno;       // Destination port number
        unsigned short udp_length;       // UDP packet length
        unsigned short udp_checksum;     // UDP checksum (optional)
    } UDP_HDR, *PUDP_HDR;//
    // Global variables
    //
    unsigned long  dwToIP,               // IP to send to
                   dwFromIP;             // IP to send from (spoof)
    unsigned short iToPort,              // Port to send to
                   iFromPort;            // Port to send from (spoof)
    DWORD          dwCount;              // Number of times to send char  
       //  Creating a raw socket    //
        s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_UDP, NULL, 0,0);
        if (s == INVALID_SOCKET)
        {
            printf("WSASocket() failed: %d\n", WSAGetLastError());
            return -1;
        }    // Enable the IP header include option 
        //
        bOpt = TRUE;
        ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));
        if (ret == SOCKET_ERROR)
        {
            printf("setsockopt(IP_HDRINCL) failed: %d\n", WSAGetLastError());
            return -1;
        }
        // Initalize the IP header
        //
        iTotalSize = sizeof(ipHdr) + sizeof(udpHdr) + strlen(strMessage);    iIPVersion = 4;
        iIPSize = sizeof(ipHdr) / sizeof(unsigned long);
        //
        // IP version goes in the high order 4 bits of ip_verlen. The
        // IP header length (in 32-bit words) goes in the lower 4 bits.
        //
        ipHdr.ip_verlen = (iIPVersion << 4) | iIPSize;
        ipHdr.ip_tos = 0;                         // IP type of service
        ipHdr.ip_totallength = htons(iTotalSize); // Total packet len
        ipHdr.ip_id = 0;                 // Unique identifier: set to 0
        ipHdr.ip_offset = 0;             // Fragment offset field
        ipHdr.ip_ttl = 128;              // Time to live
        ipHdr.ip_protocol = 0x11;        // Protocol(UDP) 
        ipHdr.ip_checksum = 0 ;          // IP checksum
        ipHdr.ip_srcaddr = dwFromIP;     // Source address
        ipHdr.ip_destaddr = dwToIP;      // Destination address
        //
        // Initalize the UDP header
        //
        iUdpSize = sizeof(udpHdr) + strlen(strMessage);    udpHdr.src_portno = htons(iFromPort) ;
        udpHdr.dst_portno = htons(iToPort) ;
        udpHdr.udp_length = htons(iUdpSize) ;
        udpHdr.udp_checksum = 0 ;
        // 
        // Build the UDP pseudo-header for calculating the UDP checksum.
        // The pseudo-header consists of the 32-bit source IP address, 
        // the 32-bit destination IP address, a zero byte, the 8-bit
        // IP protocol field, the 16-bit UDP length, and the UDP
        // header itself along with its data (padded with a 0 if
        // the data is odd length).
        //
        iUdpChecksumSize = 0;
        ptr = buf;
        ZeroMemory(buf, MAX_PACKET);    memcpy(ptr, &ipHdr.ip_srcaddr,  sizeof(ipHdr.ip_srcaddr));  
        ptr += sizeof(ipHdr.ip_srcaddr);
        iUdpChecksumSize += sizeof(ipHdr.ip_srcaddr);    memcpy(ptr, &ipHdr.ip_destaddr, sizeof(ipHdr.ip_destaddr)); 
        ptr += sizeof(ipHdr.ip_destaddr);
        iUdpChecksumSize += sizeof(ipHdr.ip_destaddr);    ptr++;
        iUdpChecksumSize += 1;    memcpy(ptr, &ipHdr.ip_protocol, sizeof(ipHdr.ip_protocol)); 
        ptr += sizeof(ipHdr.ip_protocol);
        iUdpChecksumSize += sizeof(ipHdr.ip_protocol);    memcpy(ptr, &udpHdr.udp_length, sizeof(udpHdr.udp_length)); 
        ptr += sizeof(udpHdr.udp_length);
        iUdpChecksumSize += sizeof(udpHdr.udp_length);
        
        memcpy(ptr, &udpHdr, sizeof(udpHdr)); 
        ptr += sizeof(udpHdr);
        iUdpChecksumSize += sizeof(udpHdr);    for(i = 0; i < strlen(strMessage); i++, ptr++)
            *ptr = strMessage[i];
        iUdpChecksumSize += strlen(strMessage);    cksum = checksum((USHORT *)buf, iUdpChecksumSize);
        udpHdr.udp_checksum = cksum;
        //
        // Now assemble the IP and UDP headers along with the data
        //  so we can send it
        //        
        ZeroMemory(buf, MAX_PACKET);
        ptr = buf;    memcpy(ptr, &ipHdr, sizeof(ipHdr));   ptr += sizeof(ipHdr);
        memcpy(ptr, &udpHdr, sizeof(udpHdr)); ptr += sizeof(udpHdr);
        memcpy(ptr, strMessage, strlen(strMessage));    // Apparently, this SOCKADDR_IN structure makes no difference.
        // Whatever we put as the destination IP addr in the IP header
        // is what goes. Specifying a different destination in remote
     // will be ignored.
        //
        remote.sin_family = AF_INET;
        remote.sin_port = htons(iToPort);
        remote.sin_addr.s_addr = dwToIP;
       
        for(i = 0; i < dwCount; i++)
        {
            ret = sendto(s, buf, iTotalSize, 0, (SOCKADDR *)&remote, 
                sizeof(remote));
            if (ret == SOCKET_ERROR)
            {
                printf("sendto() failed: %d\n", WSAGetLastError());
                break;
            }
            else
                printf("sent %d bytes\n", ret);
        }
        closesocket(s) ;
        WSACleanup() ;
      

  4.   

    是的,我是按照上面所说的数据结构和其他的一些事情都做了,只是我不是把IP和UDP
    一起使用,也不是把IP和TCP一起使用,而是把IP和ICMP一起使用,于是就行不通了
      

  5.   

    发送自定义ICMP包你可以参考http://www.vckbase.com/document/viewdoc.asp?id=652
      

  6.   

    你这个不叫“替换”。如果真正想替换只能在NDIS的中间层做