网络编程Create socket failed!

要求是接收解析ICMPecho请求报文,
用命令行PraseICMP.exe log_file.txt
的形式执行。

 // ParsePacket.cpp : 定义控制台应用程序的入口点。
//

//#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")

#define _WINSOCK_DEPRECATED_NO_WARNINGS

/* ICMP 首部 -- RFC 792 */
struct icmp_hdr
{   
    unsigned char type;         /* 类型 */
    unsigned char code;         /* 代码 */
    unsigned short checksum;    /* 校验和 */
    unsigned short id;          /* 标识符 */
    unsigned short seq;         /* 序列号 */

    /* 这之后的不是标准 ICMP 首部, 用于记录时间 */
    unsigned long timestamp;
};

//定义IP头部结构
typedef struct _IP_HEADER
{
    union
    {
        BYTE Version;       //版本(前4位)
        BYTE HdrLen;        //IP头部长度(后4位)
    };
    BYTE ServiceType;       //服务类型
    WORD TotalLen;          //总长度
    WORD ID;                //标识
    union
    {
        WORD Flags;         //标志u(前3位)
        WORD FragOff;       //分段偏移(后13位)
    };
    BYTE TimeToLive;        //生命期
    BYTE Protocol;          //协议
    WORD HdrChksum;         //头校验和
    DWORD SrcAddr;          //源地址
    DWORD DstAddr;          //目的地址
    BYTE Options;           //选项

}IP_HEADER;

#define IO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define BUFFER_SIZE 65535


//解析IP包的头部长度
void getIHL(BYTE b, BYTE &length)
{
    length = (b & 0x0f) * 4;
}

//解析ICMP类型
char* geticmptype(char type)
{
    switch (type)
    {
    case 0:
        return "查询报文----应答";
    case 3:
        return "差错报告报文----目的不可达";
    case 4:
        return "控制报文----源抑制";
    case 5:
        return "控制报文----路由重定向";
    case 8:
        return "查询报文----回送请求";
    case 10:
        return "查询报文----路由器请求";
    case 11:
        return "差错报告报文----超时";
    case 12:
        return "差错报告报文----参数出错";
    case 13:
        return "查询报文----时间戳请求";
    case 14:
        return "查询报文----时间戳应答";
    case 17:
        return "查询报文----掩码请求";
    case 18:
        return "查询报文----掩码应答";
    case 19:
        return "差错报告报文----通告";
    default:
        return "Unknown";
    }
}



void ipparse(FILE* file, char* buffer)
{
    int i,j;
    int iphead;
    IP_HEADER ip = *(IP_HEADER*)buffer;

    iphead=(ip.Version & 0x0f)<<2;
    icmp_hdr icmp_hd = *(icmp_hdr*)(buffer+iphead);

    fseek(file, 0, SEEK_END);

    if(ip.Protocol == 1 && icmp_hd.type==8)
    {

        printf("\n------ICMP eacho请求报文前50B------\n"); 
        for(i=0;i<5;i++)
        {
            for(j=0;j<10;j++)
            {
                printf("%x%x ",(unsigned char)buffer[10*i+j]>>4,buffer[10*i+j]&0x0f);
            }
            printf("\n");
        }

        fprintf(file, "------解析ICMP eacho请求报文------\n");
        //解析IP包的源IP地址
        fprintf(file, "SrcAddr: %s\n", inet_ntoa(*(in_addr*)&ip.SrcAddr));

        //解析IP包的目的IP地址
        fprintf(file, "DstAdrr: %s\n", inet_ntoa(*(in_addr*)&ip.DstAddr));

        //解析ICMP类型
        fprintf(file, "Type: %s\n",geticmptype(icmp_hd.type));

        //解析ICMP代码
        fprintf(file, "Code: %d\n",icmp_hd.code);

        //解析ICMP校验和
        fprintf(file, "Sum: 0x%x\n",ntohs((unsigned int)icmp_hd.checksum));

        //解析ICMP标识符
        fprintf(file, "ID: %d\n",ntohs(icmp_hd.id));

        //解析ICMP序列号
        fprintf(file, "Seq: %d\n",ntohs(icmp_hd.seq));
    }
}


int main(int argc, char* argv[])
{
    //检查输入的命令格式
    if (argc != 2)
    {
        printf("Please input command:ParseICMP.exe log_file.txt\n");
        return 0;
    }


    //打开输出日志文件
    FILE* file;
    if ((file = fopen(argv[1], "wb+")) == NULL)
    {
        printf("Fail to open file %s!", argv[1]);
        return 0;
    }

    //初始化Socket环境
    WSADATA wsData;
    if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0)
    {
        printf("WSAStartup failed!");
        return 0;
    }

    //建立原始Socket
    SOCKET sock;
    if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == INVALID_SOCKET)
    {
        printf("Create socket failed!");
        return 0;
    }

    //设置IP头部操作选项,flag设置为ture
    BOOL flag = true;
    if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)) == SOCKET_ERROR)
    {
        printf("Setsockopt failed!");
        return 0;
    }

    //获取本地主机名
    char hostName[128];
    if (gethostname(hostName, 100) == SOCKET_ERROR)
    {
        printf("Gethostbyname failed!");
        return 0;
    }

    //获取本地主机IP地址
    hostent* pHostIP;
    if ((pHostIP = gethostbyname(hostName)) == NULL)
    {
        printf("Gethostbyname failed!");
        return 0;
    }

    //填充SOCKADDR_IN结构
    sockaddr_in addr_in, cliadd;
    addr_in.sin_addr = *(in_addr*)pHostIP->h_addr_list[0];
    addr_in.sin_family = AF_INET;
    addr_in.sin_port = htons(5050);

    //把原始Socket绑定到本地网卡
    if (bind(sock, (PSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR)
    {
        printf("Bind failed!");
        return 0;
    }


    int ilen = sizeof(cliadd);

    //设置SOCK_RAW为SIO_RCVALL,接收所有数据包
    DWORD dwValue = 1;
    DWORD dwBufferLen[10];
    DWORD dwBufferInLen = 1;
    DWORD dwBytesReturned = 0;
    if (WSAIoctl(sock, IO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen),
        &dwBytesReturned, NULL, NULL) == SOCKET_ERROR)
    {
        printf("Ioctlsocket failed!");
        return 0;
    }

    //监听经过本机的IP包
    char buffer[BUFFER_SIZE];
    printf("Listening on local host...\n");
    while (true)
    {
    //  int size = recv(sock, buffer, BUFFER_SIZE, 0);
        int size = recvfrom(sock, buffer, BUFFER_SIZE, 0 , (struct sockaddr*)&cliadd, &ilen);
        if (size > 0)
        {
            ipparse(stdout, buffer);
            //ipparse(file, buffer);
        }
    }
    fclose(file);
    return 0;
}



1个回答

打印下返回值
1) socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
protocol = 6
*answer = inetsw_array[0]
protocol == answer->protocol && protocol != IPPROTO_IP : TRUE
OK

http://blog.csdn.net/jnu_simba/article/details/12371127

fcbayernyang
fcbayernyang 解决了。。这个要用管理员权限打开。
3 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐