这是VC知识库杨老师的代码,在Win7上调试运行发现不能抓到下载到本地计算机的数据包,谁能给解释一下?
#include <Winsock2.h>
#include <mstcpip.h>#pragma comment(lib,"WS2_32.lib")typedef struct _iphdr
{
    unsigned char h_lenver;        //4位首部长度+4位IP版本号
    unsigned char tos;            //8位服务类型TOS
    unsigned short total_len;    //16位总长度(字节)
    unsigned short ident;        //16位标识
    unsigned short frag_and_flags; //3位标志位
    unsigned char ttl;            //8位生存时间 TTL
    unsigned char proto;        //8位协议 (TCP, UDP 或其他)
    unsigned short checksum;    //16位IP首部校验和
    unsigned int sourceIP;        //32位源IP地址
    unsigned int destIP;        //32位目的IP地址
}IP_HEADER;  typedef struct _tcphdr        //定义TCP首部
{
    USHORT th_sport;        //16位源端口
    USHORT th_dport;        //16位目的端口
    unsigned int th_seq;
    unsigned int th_ack;
    unsigned char th_lenres;//4位首部长度/6位保留字
    unsigned char th_flag;    //6位标志位
    USHORT th_win;            //16位窗口大小
    USHORT th_sum;            //16位校验和
    USHORT th_urp;            //16位紧急数据偏移量
}TCP_HEADER;typedef struct _udphdr        //定义UDP首部
{  
    unsigned short uh_sport;
    unsigned short uh_dport;
    unsigned short uh_len;
    unsigned short uh_sum;
} UDP_HEADER;  typedef struct _icmphdr        //定义ICMP首部
{  
    BYTE i_type;            //8位类型
    BYTE i_code;            //8位代码
    USHORT i_cksum;            //16位校验和
    USHORT i_id;            //识别号(一般用进程号作为识别号)
    USHORT i_seq;            //报文序列号
    ULONG timestamp;        //时间戳
}ICMP_HEADER;bool DecodeIpPack(const char *,int);    // IP 解包
bool DecodeTcpPack(const char *);        // TCP 解包
bool DecodeUdpPack(const char *);        // UDP 解包
bool DecodeIcmpPack(const char *);        // ICMP 解包
const char * CheckProtocol(int);// 查询协议int _tmain(int argc, _TCHAR* argv[])
{
    // 初始化SOCKET
    WSADATA wsaData;
    int iErrorCode = ::WSAStartup( MAKEWORD(2,1), &wsaData );
    if( SOCKET_ERROR == iErrorCode )
    {
        printf( "WSAStartup() error. " );
        return -1;
    }
    
    SOCKET sock = ::socket( AF_INET, SOCK_RAW, IPPROTO_IP );
    if( INVALID_SOCKET == sock )
    {
        printf( "socket() error. " );
        return -1;
    }    //获取本机IP地址
    char szHostName[200];
    iErrorCode = ::gethostname( szHostName, sizeof(szHostName) );
    if( SOCKET_ERROR == iErrorCode )
    {
        printf( "gethostname() error. " );
        return -1;
    }    PHOSTENT pHostent = ::gethostbyname( szHostName );
    if( NULL == pHostent )
    {
        printf( "gethostbyname() error. " );
        return -1;
    }    SOCKADDR_IN sa;
    sa.sin_family = AF_INET;
    memcpy( &sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length );
    sa.sin_port = htons( 60000 );    iErrorCode = ::bind( sock, (PSOCKADDR)&sa, sizeof(sa) );
    if( SOCKET_ERROR == iErrorCode )
    {
        printf( "bind() error. " );
        return -1;
    }    // 设置 SOCK_RAW 为 SIO_RCVALL,接收所有的 IP 包
    DWORD dwBufferLen[10];
    DWORD dwBufferInLen = 1;
    DWORD dwBytesReturned = 0;
    iErrorCode = ::WSAIoctl( sock, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen,
        sizeof( dwBufferLen ), &dwBytesReturned, NULL, NULL );
    if( SOCKET_ERROR == iErrorCode )
    {
        printf( "Ioctl() error. " );
        return -1;
    }    //侦听IP报文
    while( 1 )
    {
        char package[8 * 1024] = { 0 };    // 数据缓冲区
        iErrorCode = ::recv( sock, package, sizeof(package), 0 );
        if( SOCKET_ERROR == iErrorCode )
                printf( "recv() error. " );
        else if( !DecodeIpPack( package, iErrorCode ) )    // 解析 IP 包
                printf( "DecodeIpPack() error. " );
    }    // ::Closesocket( sock );
    // ::WSACleanup();
    return 0;
}  // 解析 IP 包
bool DecodeIpPack(const char *buf, int iBufSize)
{
    IP_HEADER *pIpheader;
    int iProtocol, iTTL;
    char szProtocol[12];
    char szSourceIP[16];
    char szDestIP[16];
    SOCKADDR_IN saSource, saDest;
    pIpheader = (IP_HEADER *)buf;    //Check Proto  
    iProtocol = pIpheader->proto;
    ::strcpy( szProtocol, CheckProtocol(iProtocol) );    //Check Source IP
    saSource.sin_addr.s_addr = pIpheader->sourceIP;
    ::strcpy( szSourceIP, inet_ntoa(saSource.sin_addr) );    //Check Dest IP
    saDest.sin_addr.s_addr = pIpheader->destIP;
    ::strcpy( szDestIP, inet_ntoa(saDest.sin_addr) );
    iTTL = pIpheader->ttl;    //Output  
    printf( "%s ", szProtocol );
    printf( "%s->%s ", szSourceIP, szDestIP );
    printf( "bytes=%d TTL=%d ",iBufSize,iTTL );    //Calculate IP Header Length
    int iIphLen = sizeof(unsigned long) * ( pIpheader->h_lenver & 0x0f );    //Decode Sub Protocol:TCP, UDP, ICMP, etc
    switch( iProtocol )
    {  
    case IPPROTO_TCP:    DecodeTcpPack( buf + iIphLen );        break;
    case IPPROTO_UDP:    DecodeUdpPack( buf + iIphLen );        break;
    case IPPROTO_ICMP:    DecodeIcmpPack( buf + iIphLen );    break;
    default:    break;
    }
    printf( " " );    int col = 0;
    char ascii[17];
    for( int i=0; i<iBufSize; i++ )
    {
        printf( "%02X ", (unsigned char)buf[i] );        ascii[ col++ ] = ( unsigned char )buf[i] < 0x20 ? '.' : buf[i];        if( 15 == i%16 )
        {
            ascii[ col ] = 0;
            printf( "%s ", ascii );
            col = 0;
        }
        else if( 7 == i%8 )    printf( "- " );
    }
    if( col )
    {
        for( int i=col; i<16; i++ )
        {
            printf( "   " );
            if( 15 == i%16 )
            {
                ascii[ col ] = 0;
                printf( "%s ", ascii );
            }
            else if( 7 == i%8 )    printf( "- " );
        }
    }    return true;  
}  //协议识别程序
const char * CheckProtocol(int iProtocol)
{  
    typedef struct _protomap    //定义子协议映射表  
    {  
        int ProtoNum;
        char ProtoText[12];
    }PROTOMAP;    static PROTOMAP ProtoMap[]={    //为子协议映射表赋值  
    { IPPROTO_IP,    "IP"    },
    { IPPROTO_ICMP,    "ICMP"    },
    { IPPROTO_IGMP,    "IGMP"    },
    { IPPROTO_GGP,    "GGP"    },
    { IPPROTO_IPV4,    "IPV4"    },
    { IPPROTO_TCP,    "TCP"    },
    { IPPROTO_PUP,    "PUP"    },
    { IPPROTO_UDP,    "UDP"    },
    { IPPROTO_IDP,    "IDP"    },
    { IPPROTO_IPV6, "IPV6"    },
    { IPPROTO_ROUTING,    "ROUTING"    },
    { IPPROTO_FRAGMENT,    "FRAGMENT"    },
    { IPPROTO_ESP,    "ESP"    },
    { IPPROTO_AH,    "AH"    },
    { IPPROTO_ICMPV6,    "ICMPV6"    },
    { IPPROTO_NONE,    "NONE"    },
    { IPPROTO_DSTOPTS,    "DSTOPTS"    },
    { IPPROTO_ND,    "ND"    },
    { IPPROTO_ICLFXBM,    "ICLFXBM"    },
    { IPPROTO_RAW,    "RAW"    },
    { IPPROTO_MAX,    "MAX"    },
    };
    
    const int nProtoCount = sizeof(ProtoMap)/sizeof(PROTOMAP);    for(int i=0; i<nProtoCount; i++)
    {
        if(ProtoMap[i].ProtoNum==iProtocol)
            return ProtoMap[i].ProtoText;
    }
    return "";  
}  //TCP解包程序  
bool DecodeTcpPack(const char * TcpBuf)
{  
    TCP_HEADER * pTcpHeader;
    int i;
    pTcpHeader = (TCP_HEADER * )TcpBuf;
    printf("Port:%d->%d ", ntohs(pTcpHeader->th_sport),ntohs(pTcpHeader->th_dport));
    unsigned char FlagMask = 1;
    for( i=0; i<6; i++ )
    {
        static char * TcpFlag = "FSRPAU";     //定义TCP标志位  
        if( ( pTcpHeader->th_flag ) & FlagMask )
                printf( "%c", TcpFlag[i] );
        else    printf( "-" );        FlagMask = FlagMask << 1;
    }  
    return true;  
}  //UDP解包程序  
bool DecodeUdpPack(const char * UdpBuf)
{  
    UDP_HEADER *pUdpHeader;
    pUdpHeader = (UDP_HEADER * )UdpBuf;
    printf("Port:%d->%d ", ntohs(pUdpHeader->uh_sport), ntohs(pUdpHeader->uh_dport));
    printf("Len=%d", ntohs(pUdpHeader->uh_len));
    return true;
}  //ICMP解包程序  
bool DecodeIcmpPack(const char * IcmpBuf)
{  
    ICMP_HEADER *pIcmpHeader;
    pIcmpHeader = (ICMP_HEADER * )IcmpBuf;
    printf("Type:%d,%d ", pIcmpHeader->i_type,pIcmpHeader->i_code);
    printf("ID=%d SEQ=%d", pIcmpHeader->i_id, pIcmpHeader->i_seq);
    return true;
}

解决方案 »

  1.   

    Win7上不一定还支持你的方式,用Winpcap等
      

  2.   


    论坛签名======================================================================ddlddy:你好!
    截至 2011-03-25 16:05:19 前:
    你已发帖 48 个, 未结贴 0 个;
    结贴率为: 100.00%

    当您的问题得到解答后请及时结贴.

    http://topic.csdn.net/u/20090501/15/7548d251-aec2-4975-a9bf-ca09a5551ba5.html
    http://topic.csdn.net/u/20100428/09/BC9E0908-F250-42A6-8765-B50A82FE186A.html
    http://topic.csdn.net/u/20100626/09/f35a4763-4b59-49c3-8061-d48fdbc29561.html如何给分和结贴?
    http://community.csdn.net/Help/HelpCenter.htm#结帖如何给自己的回帖中也加上签名?
    http://blog.csdn.net/q107770540/archive/2011/03/15/6250007.aspx
      

  3.   

    可否给个链接,最好有例子,wincap看过一点,不熟,比较麻烦!
      

  4.   

    原始套接和IP还有关系,它只捕获你设置的本地IP所收到的数据,看看你设置了什么地址
      

  5.   

    找到原因了,就是完win7防火墙的事