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)
X
正在加载信息~
2
最新回复 (0)