利用TTL值探测远程主机操作系统类型
来源:互联网 发布:淘宝是cs还是bs 编辑:程序博客网 时间:2024/05/29 04:17
帮别人做的毕业设计。也不复杂,但是确实实现了如题的功能。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>
#pragma pack(1)
#define ICMP_ECHOREPLY 0
#define ICMP_ECHOREQ 8
//IP Header--RFC 791
typedef struct tagIPHDR
{
u_char VHDL; //Version and IHL
u_char TOS ; //Type of server
short TotLen; //Total length
short ID; //Identification
short FlagOff; //Flags and Fragment Offset
u_char TTL; //Time To Live
u_char Protocol; //protocol
u_short checksum; //Checksum
struct in_addr iaSrc; //Internet Address-Source
struct in_addr iaDst; //internet address-destination
}IPHDR, *PIPHDR;
//ICMP Header -RFC 792
typedef struct tagICMPHDR
{
u_char Type; //type
u_char Code; //Code
u_short Checksum; //checksum
u_short ID; //identification
u_short Seq; //sequence
char Data; //data
}ICMPHDR,*PICMPHDR;
#define REQ_DATASIZE 32 //Echo request data size
//ICMP eCHO Request
typedef struct tagECHOREQUEST
{
ICMPHDR icmpHdr;
DWORD dwTime;
CHAR cData[REQ_DATASIZE];
}ECHOREQUEST,*PECHOREQUEST;
//ICMP Echo Reply
typedef struct tagECHOREPLY
{
IPHDR ipHdr;
ECHOREQUEST echoRequest;
char cFiller[256];
}ECHOREPLY,*PCHOREPLY;
#pragma pack()
//internal functions
void Ping(LPCSTR pstrHost);
void ReportError(LPCSTR pstrForm);
int WaitForEchoReply(SOCKET s);
u_short in_cksum(u_short *addr,int len);
//ICMP Echo Request/Reply functions
int SendEchoRequest(SOCKET,LPSOCKADDR_IN);
DWORD RecvEchoReply(SOCKET,LPSOCKADDR_IN,u_char*);
//main()
void main(int argc,char **argv)
{
WSADATA wsaData;
WORD wVersionRequested=MAKEWORD(1,1);
int nRet;
//Checksum arguments
if(argc!=2)
{
fprintf(stderr,"/nUsage:ping hostname/n");
return;
}
//init WinSock
nRet=WSAStartup(wVersionRequested,&wsaData);
if(nRet)
{
fprintf(stderr,"/nError initializing WinSock/n");
return;
}
//checksum version
if (wsaData.wVersion!=wVersionRequested)
{
fprintf(stderr,"/nWinSock version not supported/n");
return;
}
//go do the ping
Ping(argv[1]);
//Free Winsock
WSACleanup();
}
//Ping()
//calls sendechorequest() and
//recvechoreply() and prints results
void Ping(LPCSTR pstrHost)
{
SOCKET rawSocket;
LPHOSTENT lpHost;
struct sockaddr_in saDest;
struct sockaddr_in saSrc;
DWORD dwTimeSent;
DWORD dwElapsed;
u_char cTTL;
int nLoop;
int nRet;
//create a Raw socket
rawSocket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
if(rawSocket==SOCKET_ERROR)
{
ReportError("socket()");
return;
}
//Lookback host
lpHost = gethostbyname(pstrHost);
if (lpHost == NULL)
{
fprintf(stderr,"/nHost not found: %/n,pstrHost");
return;
}
//Stetup destination socket address
saDest.sin_addr.s_addr=*((u_long FAR *) (lpHost->h_addr));
saDest.sin_family = AF_INET;
saDest.sin_port =0;
//Tell the user what we're doing
printf("/nping %s [%s] with %d bytes of data/n",
pstrHost,
inet_ntoa(saDest.sin_addr),
REQ_DATASIZE);
//Ping multiple times
for (nLoop =0; nLoop<4; nLoop++)
{
//Send ICMP echo request
SendEchoRequest(rawSocket, &saDest);
//Use select() to wait for data to be received
nRet =WaitForEchoReply(rawSocket);
if (nRet == SOCKET_ERROR)
{
ReportError("select()");
break;
}
if (!nRet)
{
printf("/nTimeout");
break;
}
//Receive reply
dwTimeSent = RecvEchoReply(rawSocket,&saSrc,&cTTL);
//Calculate elapsed time
dwElapsed = GetTickCount() - dwTimeSent;
}
printf("/n");
int iTTL=(int)cTTL;
printf("所探测操作系统类别:");
switch(iTTL){
case 64:
printf("LINUX/n");
break;
case 128:
printf("WIN2K/NT/XP/n");
break;
case 32:
printf("WINDOWS 早期系列:Windows 95/98/98SE Windows ME /n");
break;
case 255:
printf("UNIX 系列/n");
break;
default:
printf("未知!无法监测!/n");
}
nRet =closesocket(rawSocket);
if (nRet == SOCKET_ERROR)
ReportError("closesocket()");
}
//SendEchoRequest()
//Fill in echo request header
//and send to destination
int SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)
{
static ECHOREQUEST echoReq;
static nId = 1;
static nSeq = 1;
int nRet;
//Fill in echo request
echoReq.icmpHdr.Type = ICMP_ECHOREQ;
echoReq.icmpHdr.Code = 0;
echoReq.icmpHdr.Checksum =0;
echoReq.icmpHdr.ID =nId++;
echoReq.icmpHdr.Seq = nSeq++;
//Fill in some data to send
for (nRet =0;nRet<REQ_DATASIZE;nRet++)
echoReq.cData[nRet]=' '+nRet;
//Save tick count when sent
echoReq.dwTime =GetTickCount();
//Put data in packet and compute checksum
echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq,sizeof(ECHOREQUEST));
//Send the echo request
nRet = sendto(s, /*socket*/
(LPSTR)&echoReq, /*buffer*/
sizeof(ECHOREQUEST),
0, /*flags*/
(LPSOCKADDR)lpstToAddr, /*destination*/
sizeof(SOCKADDR_IN)); /*address length*/
if (nRet == SOCKET_ERROR)
ReportError("sendto()");
return (nRet);
}
//RecvEchoReply()
//Receive incoming data
//and parse out fields
DWORD RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom,u_char *pTTL)
{
ECHOREPLY echoReply;
int nRet;
int nAddrLen = sizeof(struct sockaddr_in);
//Receive the echo reply
nRet = recvfrom(s, //socket
(LPSTR)&echoReply, //buffer
sizeof(ECHOREPLY), //size of buffer
0, //flges
(LPSOCKADDR)lpsaFrom, //From address
&nAddrLen); //pointer to address len
//Check return value
if(nRet == SOCKET_ERROR)
ReportError("recvfrom()");
//return time sent and IP TTL
*pTTL = echoReply.ipHdr.TTL;
return(echoReply.echoRequest.dwTime);
}
//What happend?
void ReportError(LPCSTR pWhere)
{
fprintf(stderr,"/n%s error: %d/n",
WSAGetLastError());
}
//WaitForEchoReply()
//Use select() to determine when
//data is waiting to be read
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));
}
//
//Mike Muuss' in_cksum(0 function
//and his comments from the original
//ping program
/*
* IN_CKSUM
*
*CheckSum routine for Internet Protocol family headers (C Version)
*/
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;
/*
*The algorithm is simple,using a 32 bit accumulator (sum),
*we add sequential 16bit words to it,and at the end,fold
*back all the carry bits from the top 16 bits into the lower
*16 bits.
*
*/
while(nleft>1){
sum+=*w++;
nleft-=2;
}
/*mop up an odd byte,if necessary */
if(nleft==1){
u_short u=0;
*(u_char *)(&u)=*(u_char*)w;
sum+=u;
}
/*
*add back carry outs from toop0 16bits to low 16 bits
*/
sum=(sum>>16)+(sum&0xffff);/*add hi 16 to low 16 */
sum+=(sum>>16); /*add carry */
answer=~sum; /*trumcate to 16 bits */
return (answer);
}
- 利用TTL值探测远程主机操作系统类型
- 修改系统默认的TTL值-预防被探测操作系统
- 根据TTL值判断主机类型
- 利用TTL值来鉴别操作系统
- 利用TTL值简单判定系统类型
- 如何根据TTL判断主机的操作系统
- 防止黑客利用TTL值来鉴别操作系统
- 防止黑客利用TTL值来鉴别操作系统
- 利用ping命令的ttl值来判断服务器操作系统
- 探测远程Windows主机的NetBIOS信息
- 操作系统默认TTL值
- (转载)探测远程Windows主机的NetBIOS信息
- 探测远程主机上防火墙允许开放的端口
- 远程主机探测技术FAQ集 - 扫描篇
- Delphi中用ICMP探测远程主机是否存活
- 得到远程主机操作系统类型(只适用于发现NT5.2及以下系统)
- 通过TCP/IP堆栈特征探测远程操作系统
- 通过TCP/IP堆栈特征探测远程操作系统
- 简单Gridview删除确认
- C++中extern “C”含义深层探索
- 星际争霸官方小说: 刀锋女王-----第一章
- iconv 转码编程简介
- 系統優化的加減法
- 利用TTL值探测远程主机操作系统类型
- about SQL名词解释
- C语言中打印int值的二进制形式
- pb中利用api使pb编写的窗口始终置前
- 模拟屏学习资料_模拟视频 入门
- Java的发展史
- 人人为我,我为人人_众妙首页
- 部署水晶报表时的常见问题及解决方案
- Managed DirectX +C# 开发(入门篇)(一)