Windows下混杂模式抓包

xingyun86 1月前 174

Windows下混杂模式抓包

#pragma pack(1)
/*以太网帧头格式结构体 14个字节*/
typedef struct ether_header
{
    unsigned char ether_dhost[6];  // 目的MAC地址
    unsigned char ether_shost[6];  // 源MAC地址
    unsigned short ether_type;     // eh_type 的值需要考察上一层的协议,如果为ip则为0x0800
}ETHERHEADER, * PETHERHEADER;
/*以ARP字段结构体 28个字节*/
typedef struct arp_header
{
    unsigned short arp_hrd;
    unsigned short arp_pro;
    unsigned char arp_hln;
    unsigned char arp_pln;
    unsigned short arp_op;
    unsigned char arp_sourha[6];
    unsigned long arp_sourpa;
    unsigned char arp_destha[6];
    unsigned long arp_destpa;
}ARPHEADER, * PARPHEADER;
/*ARP报文结构体 42个字节*/
typedef struct arp_packet
{
    ETHERHEADER etherHeader;
    ARPHEADER   arpHeader;
}ARPPACKET, * PARPPACKET;
/*IPv4报头结构体 20个字节*/
typedef struct ipv4_header
{
    unsigned char ipv4_ver_hl;        // Version(4 bits) + Internet Header Length(4 bits)长度按4字节对齐
    unsigned char ipv4_stype;         // 服务类型
    unsigned short ipv4_plen;         // 总长度(包含IP数据头,TCP数据头以及数据)
    unsigned short ipv4_pidentify;    // ID定义单独IP
    unsigned short ipv4_flag_offset;  // 标志位偏移量
    unsigned char ipv4_ttl;           // 生存时间
    unsigned char ipv4_pro;           // 协议类型
    unsigned short ipv4_crc;          // 校验和
    unsigned long  ipv4_sourpa;       // 源IP地址
    unsigned long  ipv4_destpa;       // 目的IP地址
}IPV4HEADER, * PIPV4HEADER;
/*IPv6报头结构体 40个字节*/
typedef struct ipv6_header
{
    unsigned char ipv6_ver_hl;
    unsigned char ipv6_priority;
    unsigned short ipv6_lable;
    unsigned short ipv6_plen;
    unsigned char  ipv6_nextheader;
    unsigned char  ipv6_limits;
    unsigned char ipv6_sourpa[16];
    unsigned char ipv6_destpa[16];
}IPV6HEADER, * PIPV6HEADER;
/*TCP报头结构体 20个字节*/
typedef struct tcp_header
{
    unsigned short tcp_sourport;     // 源端口
    unsigned short tcp_destport;     // 目的端口
    unsigned long  tcp_seqnu;        // 序列号
    unsigned long  tcp_acknu;        // 确认号
    unsigned char  tcp_hlen;         // 4位首部长度
    unsigned char  tcp_reserved;     // 标志位
    unsigned short tcp_window;       // 窗口大小
    unsigned short tcp_chksum;       // 检验和
    unsigned short tcp_urgpoint;     // 紧急指针
}TCPHEADER, * PTCPHEADER;
/*UDP报头结构体 8个字节*/
typedef struct udp_header
{
    unsigned short udp_sourport;   // 源端口 
    unsigned short udp_destport;   // 目的端口
    unsigned short udp_hlen;       // 长度
    unsigned short udp_crc;        // 校验和
}UDPHEADER, * PUDPHEADER;
#pragma pack()
typedef struct HOSTIP
{
    int iLen;
    char szIPArray[64][64];
}HOSTIP;
SOCKET m_s = INVALID_SOCKET;
HOSTIP m_HostIp = { 0 };
// -------------------------------------------------------
// 初始化与选择套接字
// -------------------------------------------------------
BOOL InitAndSelectNetworkRawSocket()
{
    // 设置套接字版本
    WSADATA wsaData = { 0 };
    if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData))
    {
        return FALSE;
    }
    // 创建原始套接字
    // Windows无法抓取RawSocket MAC层的数据包,只能抓到IP层及以上的数据包
    m_s = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
    // g_RawSocket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (INVALID_SOCKET == m_s)
    {
        WSACleanup();
        return FALSE;
    }
    // 绑定到接口 获取本机名
    char szHostName[MAX_PATH] = { 0 };
    if (SOCKET_ERROR == gethostname(szHostName, MAX_PATH))
    {
        closesocket(m_s);
        WSACleanup();
        return FALSE;
    }
    // 根据本机名获取本机IP地址
    struct hostent* lpHostent = gethostbyname(szHostName);
    if (NULL == lpHostent)
    {
        closesocket(m_s);
        WSACleanup();
        return FALSE;
    }
    // IP地址转换并保存IP地址
    m_HostIp.iLen = 0;
    strcpy(m_HostIp.szIPArray[m_HostIp.iLen], "127.0.0.1");
    m_HostIp.iLen++;
    char* lpszHostIP = NULL;
    while (NULL != (lpHostent->h_addr_list[(m_HostIp.iLen - 1)]))
    {
        lpszHostIP = inet_ntoa(*(struct in_addr*)lpHostent->h_addr_list[(m_HostIp.iLen - 1)]);
        strcpy(m_HostIp.szIPArray[m_HostIp.iLen], lpszHostIP);
        m_HostIp.iLen++;
    }
    // 选择IP地址对应的网卡来嗅探
    printf("选择侦听网卡 \n\n");
    for (int i = 0; i < m_HostIp.iLen; i++)
    {
        printf("\t [*] 序号: %d \t IP地址: %s \n", i, m_HostIp.szIPArray[i]);
    }
    printf("\n 选择网卡序号: ");
    int iChoose = 0;
    scanf("%d", &iChoose);
    // 如果选择超出范围则直接终止
    if ((0 > iChoose) || (iChoose >= m_HostIp.iLen))
    {
        exit(0);
    }
    if ((0 <= iChoose) && (iChoose < m_HostIp.iLen))
    {
        lpszHostIP = m_HostIp.szIPArray[iChoose];
    }
    // 构造地址结构
    struct sockaddr_in SockAddr = { 0 };
    RtlZeroMemory(&SockAddr, sizeof(struct sockaddr_in));
    SockAddr.sin_addr.S_un.S_addr = inet_addr(lpszHostIP);
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_port = htons(0);
    // 绑定套接字
    if (SOCKET_ERROR == bind(m_s, (struct sockaddr*)(&SockAddr), sizeof(struct sockaddr_in)))
    {
        closesocket(m_s);
        WSACleanup();
        return FALSE;
    }
    // 设置混杂模式 抓取所有经过网卡的数据包
    DWORD dwSetVal = 1;
    if (SOCKET_ERROR == ioctlsocket(m_s, SIO_RCVALL, &dwSetVal))
    {
        closesocket(m_s);
        WSACleanup();
        return FALSE;
    }
    return TRUE;
}
// 输出数据包
void PrintData(BYTE* lpBuf, int iLen, int iPrintType)
{
    // 16进制
    if (0 == iPrintType)
    {
        for (int i = 0; i < iLen; i++)
        {
            if ((0 == (i % 8)) && (0 != i))
            {
                printf("  ");
            }
            if ((0 == (i % 16)) && (0 != i))
            {
                printf("\n");
            }
            printf("%02x ", lpBuf[i]);
        }
        printf("\n");
    }
    // ASCII编码
    else if (1 == iPrintType)
    {
        for (int i = 0; i < iLen; i++)
        {
            printf("%c", lpBuf[i]);
        }
        printf("\n");
    }
}
// 解析所有其他数据包
void AnalyseRecvPacket_All(BYTE* lpBuf)
{
    struct sockaddr_in saddr, daddr;
    PIPV4HEADER ip = (PIPV4HEADER)lpBuf;
    saddr.sin_addr.s_addr = ip->ipv4_sourpa;
    daddr.sin_addr.s_addr = ip->ipv4_destpa;
    printf("From:%s --> ", inet_ntoa(saddr.sin_addr));
    printf("To:%s\n", inet_ntoa(daddr.sin_addr));
}
// 解析TCP数据包
void AnalyseRecvPacket_TCP(BYTE* lpBuf)
{
    struct sockaddr_in saddr, daddr;
    PIPV4HEADER ip = (PIPV4HEADER)lpBuf;
    PTCPHEADER tcp = (PTCPHEADER)(lpBuf + (ip->ipv4_ver_hl & 0x0F) * 4);
    int hlen = (ip->ipv4_ver_hl & 0x0F) * 4 + tcp->tcp_hlen * 4;
    // 这里要将网络字节序转换为本地字节序
    int dlen = ntohs(ip->ipv4_plen) - hlen;
    saddr.sin_addr.s_addr = ip->ipv4_sourpa;
    daddr.sin_addr.s_addr = ip->ipv4_destpa;
    printf("From:%s:%d --> ", inet_ntoa(saddr.sin_addr), ntohs(tcp->tcp_sourport));
    printf("To:%s:%d  ", inet_ntoa(daddr.sin_addr), ntohs(tcp->tcp_destport));
    printf("ack:%u  syn:%u length=%d\n", tcp->tcp_acknu, tcp->tcp_seqnu, dlen);
    PrintData((lpBuf + hlen), dlen, 0);
}
// 解析UDP数据包
void AnalyseRecvPacket_UDP(BYTE* lpBuf)
{
    struct sockaddr_in saddr, daddr;
    PIPV4HEADER ip = (PIPV4HEADER)lpBuf;
    PUDPHEADER udp = (PUDPHEADER)(lpBuf + (ip->ipv4_ver_hl & 0x0F) * 4);
    int hlen = (int)((ip->ipv4_ver_hl & 0x0F) * 4 + sizeof(UDPHEADER));
    int dlen = (int)(ntohs(udp->udp_hlen) - 8);
    //  int dlen = (int)(udp->udp_hlen - 8);
    saddr.sin_addr.s_addr = ip->ipv4_sourpa;
    daddr.sin_addr.s_addr = ip->ipv4_destpa;
    printf("Protocol:UDP  ");
    printf("From:%s:%d -->", inet_ntoa(saddr.sin_addr), ntohs(udp->udp_sourport));
    printf("To:%s:%d\n", inet_ntoa(daddr.sin_addr), ntohs(udp->udp_destport));
    PrintData((lpBuf + hlen), dlen, 0);
}
int Run()
{
    // 选择网卡,并设置网络为非阻塞模式
    InitAndSelectNetworkRawSocket();
    struct sockaddr_in RecvAddr = { 0 };
    int iRecvBytes = 0;
    int iRecvAddrLen = sizeof(struct sockaddr_in);
    DWORD dwBufSize = 12000;
    BYTE* lpRecvBuf = (BYTE*)malloc(dwBufSize);
    // 循环接收接收
    while (1)
    {
        RtlZeroMemory(&RecvAddr, iRecvAddrLen);
        iRecvBytes = recvfrom(m_s, (char*)lpRecvBuf, dwBufSize, 0, (struct sockaddr*)(&RecvAddr), &iRecvAddrLen);
        if (0 < iRecvBytes)
        {
            // 接收数据包解码输出
            // 分析IP包的协议类型
            PIPV4HEADER ip = (PIPV4HEADER)lpRecvBuf;
            switch (ip->ipv4_pro)
            {
            case IPPROTO_ICMP:
            {
                // 分析ICMP
                printf("[ICMP]\n");
                AnalyseRecvPacket_All(lpRecvBuf);
                break;
            }
            case IPPROTO_IGMP:
            {
                // 分析IGMP
                printf("[IGMP]\n");
                AnalyseRecvPacket_All(lpRecvBuf);
                break;
            }
            case IPPROTO_TCP:
            {
                // 分析tcp协议
                printf("[TCP]\n");
                AnalyseRecvPacket_TCP(lpRecvBuf);
                break;
            }
            case IPPROTO_UDP:
            {
                // 分析udp协议
                printf("[UDP]\n");
                AnalyseRecvPacket_UDP(lpRecvBuf);
                break;
            }
            default:
            {
                // 其他数据包
                printf("[OTHER IP]\n");
                AnalyseRecvPacket_All(lpRecvBuf);
                break;
            }
            }
        }
    }
    // 释放内存
    free(lpRecvBuf);
    lpRecvBuf = NULL;
    // 关闭套接字
    Sleep(500);
    closesocket(m_s);
    WSACleanup();
    return 0;
}


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回