windows原始套接字接受

windows下原始套接字的使用

#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <MSTcpIP.h>

#pragma comment(lib,"Ws2_32.lib")

#define SOURCE_PORT 7234
#define MAX_RECEIVEBYTE 255

typedef struct ip_hdr //定义IP首部
{
    unsigned char h_verlen; //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地址
}IPHEADER;

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;




//CheckSum:计算校验和的子函数
USHORT checksum(USHORT *buffer, int size)
{
    unsigned long cksum=0;
    while(size >1)
    {
        cksum+=*buffer++;
        size -=sizeof(USHORT);
    }
    if(size )
    {
        cksum += *(UCHAR*)buffer;
    }

    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >>16);
    return (USHORT)(~cksum);
}

int main(int argc, char* argv[]){
    int res = 0;
    WSADATA WSAData;
    SOCKET sock;
    SOCKADDR_IN addr_in;
    IPHEADER ipHeader;
    
    BOOL flag;
    int rect,nTimeOver;


    if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0)
    {
        printf("WSAStartup Error!\n");
        return false;
    }

    res = ~0;
    sock=socket(AF_INET, SOCK_RAW, IPPROTO_IP);
    //sock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED);
    if(INVALID_SOCKET == sock){
        res = -1;
    }
  
    flag=true;
    if (setsockopt(sock,IPPROTO_IP, IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)
    {
        res = WSAGetLastError();
        printf("setsockopt IP_HDRINCL error!\n");
        return false;
    }

    nTimeOver=1000;
    if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver))==SOCKET_ERROR)
    {
        printf("setsockopt SO_SNDTIMEO error!\n");
        return false;
    }


    addr_in.sin_family=AF_INET;
    addr_in.sin_port=0;
    addr_in.sin_addr.S_un.S_addr=inet_addr("192.168.10.55");

    res = bind(sock, (sockaddr*)&addr_in, sizeof(addr_in));

    u_long dwValue = 1;
     res = ioctlsocket(sock, SIO_RCVALL, &dwValue);
//     DWORD lpvBuffer = 1;
//     DWORD lpcbBytesReturned = 0 ;
//     res = WSAIoctl(sock, SIO_RCVALL, &lpvBuffer, sizeof(lpvBuffer), NULL, 0, & lpcbBytesReturned, NULL, NULL); 

    

    
    unsigned char buf[1024 << 4] = {0};
 
    for(int i = 0; ;i++){
        memset(buf, 0, sizeof(buf));
        rect=recv(sock, (char*)buf, sizeof(buf), 0);
        if (rect==SOCKET_ERROR){
            printf("send error!:%d\n",WSAGetLastError());
            return false;
        }else{
            unsigned char* p = buf;
            if(buf[9] == 0x01){
                p += 12;
                printf("srcIP:%d.%d.%d.%d  -->  desIP:%d.%d.%d.%d type=%d code=%d\n",
                    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], buf[sizeof(IPHEADER)], buf[sizeof(IPHEADER) + 1]);
            }
        }
    }

    closesocket(sock);
    WSACleanup();

    getchar();
    return 0;
} 




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值