#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>
#pragma pack(1)
#pragma comment( lib, "ws2_32.lib " )
#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((int)cTTL){
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.rar_TTL 操作系统
版权申诉
151 浏览量
2022-09-19
16:55:51
上传
评论
收藏 3KB RAR 举报
寒泊
- 粉丝: 75
- 资源: 1万+
最新资源
- WebCrawler.scr
- 【计算机专业毕业设计】大学生就业信息管理系统设计源码.zip
- YOLO 数据集:8种路面缺陷病害检测【包含划分好的数据集、类别class文件、数据可视化脚本】
- JAVA实现Modbus RTU或Modbus TCPIP案例.zip
- 基于YOLOv8的FPS TPS AI自动锁定源码+使用步骤说明.zip
- JAVA实现Modbus RTU或Modbus TCPIP案例.zip
- 基于yolov8+streamlit的火灾检测部署源码+模型.zip
- 测试aaaaaaabbbbb
- VID20240521070643.mp4
- Android系统原理与开发学习要点详解-培训课件.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈