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

📄 getos.cpp

📁 利用TTL的返回值来远程判断操作系统的类型 开发环境VC++ 6.0
💻 CPP
字号:
#include"getos.h"

int WaitForEchoReply(SOCKET s)
{
	struct timeval Timeout;
	fd_set readfds;

	readfds.fd_count = 1;
	readfds.fd_array[0] = s;
	Timeout.tv_sec = 5;
	Timeout.tv_usec = 0;
	return(select(1,&readfds,NULL,NULL,&Timeout));
}

u_short in_cksum(u_short * addr,int len)
{
	register int nleft = len;
	register u_short * w = addr;
	register u_short answer;
	register int sum = 0;
	
	while(nleft > 1)
	{
		sum += *w++;
		nleft -= 2;
	}

	if(nleft == 1)
	{
		u_short u = 0;
		*(u_char *)(&u) = *(u_char*)w;
		sum += u;
	}

	sum = (sum >> 16) + (sum & 0xffff);
	sum += (sum >> 16);
	answer = ~sum;
	return(answer);
}

int SendEchoRequest(SOCKET s, LPSOCKADDR_IN lpstToAddr)
{
	static ECHOREQUEST echoReq;
	static nId = 1;
	static nSeq = 1;
	int nRet;

	echoReq.icmpHdr.Type = ICMP_ECHOREQ;
	echoReq.icmpHdr.Code = 0;
	echoReq.icmpHdr.Checksum = 0;
	echoReq.icmpHdr.ID = nId++;
	echoReq.icmpHdr.Seq = nSeq++;

	for(nRet = 0; nRet < REQ_DATASIZE; nRet++)
		echoReq.cData[nRet] += nRet;

	echoReq.dwTime = GetTickCount();
	echoReq.icmpHdr.Checksum = in_cksum((u_short*)&echoReq,sizeof(ECHOREQUEST));

	nRet = sendto(s,(LPSTR)&echoReq,sizeof(ECHOREQUEST),0,(LPSOCKADDR)lpstToAddr,sizeof(SOCKADDR_IN));
	if(nRet == SOCKET_ERROR)
	{
		printf("sendto error:%d",WSAGetLastError());
	}
	return(nRet);
}

DWORD RecvEchoReply(SOCKET s,LPSOCKADDR_IN lpsaFrom,u_char * pTTL)
{
	ECHOREPLY echoReply;
	int nRet;
	int nAddrLen = sizeof(struct sockaddr_in);

	nRet = recvfrom(s,(LPSTR)&echoReply,sizeof(ECHOREPLY),0,(LPSOCKADDR)lpsaFrom,&nAddrLen);
	if(nRet == SOCKET_ERROR)
	{
		printf("recvfrom error:%d",WSAGetLastError());
	}

	*pTTL = echoReply.ipHdr.TTL;
	return(echoReply.echoRequest.dwTime);
}

void ping(LPCSTR pstrHost)
{
	SOCKET rawSocket;
	LPHOSTENT lpHost;
	struct sockaddr_in saDest, saSrc;
	DWORD dwTimeSent, dwElapsed;
	u_char cTTL;
	int nLoop, nRet;

	rawSocket = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
	if(rawSocket == SOCKET_ERROR)
	{
		printf("socket error:%d",WSAGetLastError());
		return ;
	}

	lpHost = gethostbyname(pstrHost);
	if(lpHost == NULL)
	{
		printf("host not found:%s",pstrHost);
		return;
	}

	saDest.sin_addr.s_addr = *((u_long FAR *)(lpHost->h_addr));
	saDest.sin_family = AF_INET;
	saDest.sin_port = 0;

	printf("\npinging %s [%s] with %d bytes of data:\n",pstrHost,inet_ntoa(saDest.sin_addr),REQ_DATASIZE);

	for(nLoop = 0; nLoop < 4; nLoop ++)
	{
		SendEchoRequest(rawSocket,&saDest);
		nRet = WaitForEchoReply(rawSocket);
		if(nRet == SOCKET_ERROR)
		{
			printf("select error:%d",WSAGetLastError());
			break;
		}
		if(!nRet)
		{
			printf("\nTime out...");
			break;
		}

		dwTimeSent = RecvEchoReply(rawSocket,&saSrc,&cTTL);
		dwElapsed = GetTickCount() - dwTimeSent;
		printf("\nReply from %s bytes=%d time=%ldms TTL=%d",inet_ntoa(saSrc.sin_addr),REQ_DATASIZE,dwElapsed,cTTL);
	}

	if(cTTL > 0 && cTTL <= 32)
		printf("\n\nThe remote Operation system may be Windows 95\n");
	else if(cTTL > 32 && cTTL <= 64)
		printf("\n\nThe remote Operation system may be Compaq Tru64 5.0\nor may be Linux Kernel 2.2.x&2.4.x\n");
	else if(cTTL > 64 && cTTL <= 128)
		printf("\n\nThe remote Operation system may be Windows NT/2000/2003/XP\n");
	else 
		printf("\n\nThe remote Operation system may be UNIX class\n");

	nRet = closesocket(rawSocket);
	if(nRet == SOCKET_ERROR)
	{
		printf("closesocket error:%d",WSAGetLastError());
		return;
	}
}


int main(int argc,char ** argv)
{
	WSADATA wsaData;
	WORD wVersionRequest = MAKEWORD(1,1);
	int nRet;

	if(argc != 2)
	{
		printf("usage : getos hostname\n");
		return 0;
	}

	nRet = WSAStartup(wVersionRequest,&wsaData);
	if(nRet)
	{
		printf("error to init...\n");
		return 0;
	}
	if(wsaData.wVersion != wVersionRequest)
	{
		printf("winsock version not support..\n");
		return 0;
	}

	ping(argv[1]);
	WSACleanup();
}

⌨️ 快捷键说明

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