⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scannerdemo.cpp

📁 vc++网络程序设计实例详解 人民邮电出版社5-6章源码
💻 CPP
字号:
////////////////////////////////////////////////
// ScannerDemo.cpp文件

#include "../common/initsock.h"

#include <windows.h>
#include <stdio.h>
#include "ntddndis.h"
#include "protoutils.h"
#include "ProtoPacket.h"

#include "Iphlpapi.h"
#pragma comment(lib, "Iphlpapi.lib")

#include "../common/comm.h"


DWORD WINAPI SendThread(LPVOID lpParam);
BOOL GetGlobalData();

/////////////////////////////////////////
// 全局数据
u_char	g_ucLocalMac[6];	// 本地MAC地址
DWORD	g_dwGatewayIP;		// 网关IP地址
DWORD	g_dwLocalIP;		// 本地IP地址
DWORD	g_dwMask;			// 子网掩码

CInitSock theSock;




 /* 
计算TCP伪头校验和。TCP校验和基于如下几个域:
	源IP地址
	目的IP地址
	8位0域
	8位协议域
	16位TCP长度
	TCP头
	TCP数据
 */


void ComputeTcpPseudoHeaderChecksum(
    IPHeader    *pIphdr,
    TCPHeader *pTcphdr,
    char    *payload,
    int      payloadlen
    )
{
	char buff[1024];
	char *ptr = buff;
	int chksumlen = 0;
	ULONG zero = 0;
	
		// 伪头
	// 包含源IP地址和目的IP地址
	memcpy(ptr, &pIphdr->ipSource, sizeof(pIphdr->ipSource));
	ptr += sizeof(pIphdr->ipSource);
	chksumlen += sizeof(pIphdr->ipSource);

	memcpy(ptr, &pIphdr->ipDestination, sizeof(pIphdr->ipDestination));
	ptr += sizeof(pIphdr->ipDestination);
	chksumlen += sizeof(pIphdr->ipDestination);

	// 包含8位0域
	memcpy(ptr, &zero, 1);
	ptr += 1;
	chksumlen += 1;

	// 协议
	memcpy(ptr, &pIphdr->ipProtocol, sizeof(pIphdr->ipProtocol));
	ptr += sizeof(pIphdr->ipProtocol);
	chksumlen += sizeof(pIphdr->ipProtocol);

	// TCP长度
	USHORT tcp_len = htons(sizeof(TCPHeader) + payloadlen);
	memcpy(ptr, &tcp_len, sizeof(tcp_len));
	ptr += sizeof(tcp_len);
	chksumlen += sizeof(tcp_len);

		// TCP头
	memcpy(ptr, pTcphdr, sizeof(TCPHeader));
	ptr += sizeof(TCPHeader);
	chksumlen += sizeof(TCPHeader);

		// 净荷
	memcpy(ptr, payload, payloadlen);
	ptr += payloadlen;
	chksumlen += payloadlen;

	// 补齐到下一个16位边界
	for(int i=0; i<payloadlen%2; i++)
	{
		*ptr = 0;
		ptr++;
		chksumlen++;
	}

	// 计算这个校验和,将结果填充到TCP头
	pTcphdr->checksum = checksum((USHORT*)buff, chksumlen);
}

int main()
{
	// 获取全局数据
	GetGlobalData();
	// 启动服务
	if(!ProtoStartService())
	{
		printf(" ProtoStartService() failed %d \n", ::GetLastError());
		return -1;
	}
	// 打开控制设备对象
	HANDLE hControlDevice = ProtoOpenControlDevice();
	if(hControlDevice == INVALID_HANDLE_VALUE)
	{
		printf(" ProtoOpenControlDevice() failed() %d \n", ::GetLastError());
		ProtoStopService();
		return -1;
	}
	// 枚举绑定的下层适配器
	CPROTOAdapters adapters;
	if(!adapters.EnumAdapters(hControlDevice))
	{
		printf(" Enume adapter failed \n");
		ProtoStopService();
		return -1;
	}

	CAdapter adapter;
	// 默认使用第一个适配器
	if(!adapter.OpenAdapter(adapters.m_pwszSymbolicLink[0], FALSE))
	{
		printf(" OpenAdapter failed \n");
		ProtoStopService();
		return -1;
	}
	
	adapter.SetFilter(	//  NDIS_PACKET_TYPE_PROMISCUOUS|
		NDIS_PACKET_TYPE_DIRECTED | 
			NDIS_PACKET_TYPE_MULTICAST | NDIS_PACKET_TYPE_BROADCAST);


	// 目的IP地址和要探测的端口号
	char szDestIP[] = "219.238.168.74";  
	USHORT usDestPort = 80;

	DWORD dwLocalIP = g_dwLocalIP;  // 这里您可以使用假的IP地址和MAC地址
	u_char *pLocalMac = g_ucLocalMac;


	// 得到网关的MAC地址
	u_char arGatewayMac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	ULONG ulLen = 6;
	if(!::SendARP(g_dwGatewayIP, 0, (ULONG*)arGatewayMac, &ulLen) == NO_ERROR)
	{
		printf(" 取得网关的MAC地址出错 \n");
		return -1;
	}

	DWORD dwDestIP = ::inet_addr(szDestIP);

		// 构建TCP数据贞
	char frame[500] = { 0 };
	// 以太头
	ETHeader etHeader;
	memcpy(etHeader.dhost, arGatewayMac, 6);
	memcpy(etHeader.shost, pLocalMac, 6);
	etHeader.type = ::htons(ETHERTYPE_IP);
	memcpy(frame, &etHeader, sizeof(etHeader));

	// IP头
	IPHeader ipHeader = { 0 };
	ipHeader.iphVerLen = (4<<4 | (sizeof(ipHeader)/sizeof(ULONG)));

	ipHeader.ipLength = ::htons(sizeof(IPHeader) + sizeof(TCPHeader));

	ipHeader.ipID = 1;
	ipHeader.ipFlags = 0;
	ipHeader.ipTTL = 128;
	ipHeader.ipProtocol = IPPROTO_TCP;
	ipHeader.ipSource = dwLocalIP;
	ipHeader.ipDestination = dwDestIP;	
	ipHeader.ipChecksum = 0;
	ipHeader.ipChecksum = checksum((USHORT*)&ipHeader, sizeof(ipHeader));

	memcpy(&frame[sizeof(etHeader)], &ipHeader, sizeof(ipHeader));

	// TCP头
	TCPHeader tcpHeader = { 0 };
	tcpHeader.sourcePort = htons(6000);
	tcpHeader.destinationPort = htons(0);
	tcpHeader.sequenceNumber = htonl(55551);
	tcpHeader.acknowledgeNumber = 0;
	tcpHeader.dataoffset =  (sizeof(tcpHeader)/4<<4|0); 

	tcpHeader.flags = TCP_SYN;   // #define   TCP_SYN   0x02
	tcpHeader.urgentPointer = 0;

	tcpHeader.windows = htons(512);
	tcpHeader.checksum = 0;


	//	下面是探测代码。注意,要实现扫描话,在这里循环探测端口号即可
	{
		// 构建封包
		tcpHeader.destinationPort = htons(usDestPort);
		ComputeTcpPseudoHeaderChecksum(&ipHeader, &tcpHeader, NULL, 0);
		memcpy(&frame[sizeof(etHeader) + sizeof(ipHeader)], &tcpHeader, sizeof(tcpHeader));

		printf(" 开始探测【%s:%d】... \n\n",  szDestIP, usDestPort);

		// 发送封包
		int nLen = sizeof(etHeader) + sizeof(ipHeader) + sizeof(tcpHeader);
		if(adapter.SendData(frame, nLen) != nLen)
		{
			printf(" SendData failed \n");
			return 0;
		}

		// 接收封包
		char buff[500] = { 0 };
		for(int i=0; i<5; i++)  // 注意,您应该使用异步方式接收数据。这里使用循环是为了方便
		{
			adapter.RecieveData(buff, nLen);
			ETHeader *pEtherhdr = (ETHeader *)buff;
			if(pEtherhdr->type == ::htons(ETHERTYPE_IP))
			{
				IPHeader *pIphdr = (IPHeader *)&buff[sizeof(ETHeader)];
				if(pIphdr->ipProtocol == IPPROTO_TCP && pIphdr->ipSource == dwDestIP)
				{
					TCPHeader *pTcphdr = (TCPHeader *)&buff[sizeof(ETHeader) + sizeof(IPHeader)];
					
					if((pTcphdr->flags & TCP_SYN) && (pTcphdr->flags & TCP_ACK)) // #define   TCP_ACK   0x10
					{
						printf(" 【%s:%d】Open \n", szDestIP, usDestPort);
					}
					else
					{
						printf(" 【%s:%d】Closed \n", szDestIP, usDestPort);
					}
					break;
				}
			}
		}
	}

	ProtoStopService();

	return 0;
}

BOOL GetGlobalData()
{
	PIP_ADAPTER_INFO pAdapterInfo = NULL;
	ULONG ulLen = 0;

	// 为适配器结构申请内存
	::GetAdaptersInfo(pAdapterInfo,&ulLen);
	pAdapterInfo = (PIP_ADAPTER_INFO)::GlobalAlloc(GPTR, ulLen);

	// 取得本地适配器结构信息
	if(::GetAdaptersInfo(pAdapterInfo,&ulLen) ==  ERROR_SUCCESS)
	{
		if(pAdapterInfo != NULL)
		{
			memcpy(g_ucLocalMac, pAdapterInfo->Address, 6);
			g_dwGatewayIP = ::inet_addr(pAdapterInfo->GatewayList.IpAddress.String);
			g_dwLocalIP = ::inet_addr(pAdapterInfo->IpAddressList.IpAddress.String);
			g_dwMask = ::inet_addr(pAdapterInfo->IpAddressList.IpMask.String);
		}
	}
	::GlobalFree(pAdapterInfo);

	printf(" \n -------------------- 本地主机信息 -----------------------\n\n");
	in_addr in;
	in.S_un.S_addr = g_dwLocalIP;
	printf("      IP Address : %s \n", ::inet_ntoa(in));

	in.S_un.S_addr = g_dwMask;
	printf("     Subnet Mask : %s \n", ::inet_ntoa(in));

	in.S_un.S_addr = g_dwGatewayIP;
	printf(" Default Gateway : %s \n", ::inet_ntoa(in));

	u_char *p = g_ucLocalMac;
	printf("     MAC Address : %02X-%02X-%02X-%02X-%02X-%02X \n", p[0], p[1], p[2], p[3], p[4], p[5]);

	printf(" \n \n ");



	return TRUE;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -