全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1809
推到 Plurk!
推到 Facebook!

微軟的ping範例

 
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-02-26 16:45:01 IP:61.218.xxx.xxx 未訂閱
微軟的ping範例     
 
 /******************************************************************************* ping.c - Simple ping utility using SOCK_RAW
* 
* This is a part of the Microsoft Source Code Samples.
* Copyright 1996-1997 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/
#pragma pack(1)
#define WIN32_LEAN_AND_MEAN
#include < winsock.h >
#include < stdio.h >
#include < stdlib.h > 
#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0
#define ICMP_MIN 8 // minimum 8 byte icmp packet (just header)
#define IP_RECORD_ROUTE 0x07
/* The IP header */
typedef struct iphdr
{
unsigned int h_len : 4; // length of the header
unsigned int version : 4; // Version of IP
unsigned char tos; // Type of service
unsigned short total_len; // total length of the packet
unsigned short ident; // unique identifier
unsigned short frag_and_flags; // flags
unsigned char ttl; // Time to live
unsigned char proto; // protocol (TCP, UDP etc)
unsigned short checksum; // IP checksum
unsigned int sourceIP;
unsigned int destIP;
} IpHeader;
/* IP option header*/
typedef struct _ipopthdr
{
unsigned char code; //option type
unsigned char len; //length of option hdr
unsigned char ptr; //offset into options
unsigned long addr[9]; //list of IP addrs
} IpOptionHeader;
//
// ICMP header
//
typedef struct _ihdr
{
BYTE i_type;
BYTE i_code; /* type sub code */
USHORT i_cksum;
USHORT i_id;
USHORT i_seq;
/* This is not the std header, but we reserve space for time */
ULONG timestamp;
} IcmpHeader;
#define STATUS_FAILED 0xFFFF
#define DEF_PACKET_SIZE 32
#define MAX_PACKET 1024
#define MAX_IP_HDR_SIZE 60
#define xmalloc(s) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (s))
#define xfree(p) HeapFree(GetProcessHeap(), 0, (p))
void fill_icmp_data(char *, int);
USHORT checksum(USHORT *, int);
void decode_resp(char *, int, struct sockaddr_in *);
/* */
void Usage(char *progname)
{
fprintf(stderr, "Usage:\n");
fprintf(stderr, "%s  [data_size]\n", progname);
fprintf(stderr, "datasize can be up to 1Kb\n");
ExitProcess(STATUS_FAILED);
}
/* */
int main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET sockRaw;
struct sockaddr_in dest, from;
struct hostent *hp;
int bread, datasize;
int fromlen=sizeof(from);
int timeout=1000;
char *dest_ip;
char *icmp_data;
char *recvbuf;
unsigned int addr=0;
USHORT seq_no=0;
IpOptionHeader ipopt;
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
fprintf(stderr, "WSAStartup failed: %d\n", GetLastError());
ExitProcess(STATUS_FAILED);
}
if(argc < 2)
{
Usage(argv[0]);
}
sockRaw=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if(sockRaw == INVALID_SOCKET)
{
fprintf(stderr, "WSASocket() failed: %d\n", WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
ZeroMemory(&ipopt, sizeof(ipopt));
ipopt.code=IP_RECORD_ROUTE;
ipopt.ptr=4;
ipopt.len=39;
bread=setsockopt(sockRaw, IPPROTO_IP, IP_OPTIONS, (char *) &ipopt, sizeof(ipopt));
if(bread == SOCKET_ERROR)
{
fprintf(stderr, "failed to set ip options: %d\n", WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
bread=setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof(timeout));
if(bread == SOCKET_ERROR)
{
fprintf(stderr, "failed to set recv timeout: %d\n", WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
timeout=1000;
bread=setsockopt(sockRaw, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(timeout));
if(bread == SOCKET_ERROR)
{
fprintf(stderr, "failed to set send timeout: %d\n", WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
memset(&dest, 0, sizeof(dest));
hp=gethostbyname(argv[1]);
if(!hp)
{
addr=inet_addr(argv[1]);
}
if((!hp) && (addr == INADDR_NONE))
{
fprintf(stderr, "Unable to resolve %s\n", argv[1]);
ExitProcess(STATUS_FAILED);
}
if(hp != NULL)
memcpy(&(dest.sin_addr), hp->h_addr, hp->h_length);
else
dest.sin_addr.s_addr=addr;
if(hp)
dest.sin_family=hp->h_addrtype;
else
dest.sin_family=AF_INET;
dest_ip=inet_ntoa(dest.sin_addr);
if(argc > 2)
{
datasize=atoi(argv[2]);
if(datasize == 0) datasize=DEF_PACKET_SIZE;
}
else
datasize=DEF_PACKET_SIZE;
datasize =sizeof(IcmpHeader);
icmp_data= (char *)xmalloc(MAX_PACKET);
recvbuf= (char *)xmalloc(MAX_PACKET);
if(!icmp_data)
{
fprintf(stderr, "HeapAlloc failed %d\n", GetLastError());
ExitProcess(STATUS_FAILED);
}
memset(icmp_data, 0, MAX_PACKET);
fill_icmp_data(icmp_data, datasize);
while(1)
{
int bwrote;
((IcmpHeader *)icmp_data)->i_cksum=0;
((IcmpHeader *)icmp_data)->timestamp=GetTickCount();
((IcmpHeader *)icmp_data)->i_seq=seq_no  ;
((IcmpHeader *)icmp_data)->i_cksum=checksum((USHORT *)icmp_data, datasize);
bwrote=sendto(sockRaw, icmp_data, datasize, 0, (struct sockaddr *) &dest, sizeof(dest));
if(bwrote == SOCKET_ERROR)
{
if(WSAGetLastError() == WSAETIMEDOUT)
{
printf("timed out\n");
continue;
}
fprintf(stderr, "sendto failed: %d\n", WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
if(bwrote < datasize)
{
fprintf(stdout, "Wrote %d bytes\n", bwrote);
}
bread=recvfrom(sockRaw, recvbuf, MAX_PACKET, 0, (struct sockaddr *) &from, &fromlen);
if(bread == SOCKET_ERROR)
{
if(WSAGetLastError() == WSAETIMEDOUT)
{
printf("timed out\n");
continue;
}
fprintf(stderr, "recvfrom failed: %d\n", WSAGetLastError());
ExitProcess(STATUS_FAILED);
}
decode_resp(recvbuf, bread, &from);
Sleep(1000);
}
return 0;
}
/*
If the IP option header is present, find the IP options within the 
IP header and print the record route option values.
*/
void decode_ip_opt(char *buf, int bytes)
{
IpOptionHeader *ipopt=NULL;
IN_ADDR inaddr;
int i;
ipopt=(IpOptionHeader *) (buf   20);
printf("RouteRecord:");
for(i=0; i < (ipopt->ptr / 4) - 1; i  )
{
inaddr.S_un.S_addr=ipopt->addr[i];
if(i != 0)
{
printf(" ");
}
printf("[%-15s]\n", inet_ntoa(inaddr));
}
return;
}
/* 
The response is an IP packet. We must decode the IP header to locate 
the ICMP data 
*/
void decode_resp(char *buf, int bytes, struct sockaddr_in *from)
{
IpHeader *iphdr;
IcmpHeader *icmphdr;
unsigned short iphdrlen;
static int icmpcount=0;
iphdr= (IpHeader *)buf;
iphdrlen=iphdr->h_len * 4; // number of 32-bit words *4 = bytes
if((iphdrlen == MAX_IP_HDR_SIZE) && (!icmpcount))
{
decode_ip_opt(buf, bytes);
}
if(bytes < iphdrlen   ICMP_MIN)
{
printf("Too few bytes from %s\n", inet_ntoa(from->sin_addr));
}
icmphdr=(IcmpHeader *) (buf   iphdrlen);
if(icmphdr->i_type != ICMP_ECHOREPLY)
{
fprintf(stderr, "non-echo type %d recvd\n", icmphdr->i_type);
return;
}
if(icmphdr->i_id != (USHORT) GetCurrentProcessId())
{
fprintf(stderr, "someone else's packet!\n");
return;
}
printf("%d bytes from %s:", bytes, inet_ntoa(from->sin_addr));
printf(" icmp_seq = %d. ", icmphdr->i_seq);
printf(" time: %d ms ", GetTickCount() - icmphdr->timestamp);
printf("\n");
}
/* */
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size > 1)
{
cksum =*buffer  ;
size-=sizeof(USHORT);
}
if(size)
{
cksum =*(UCHAR *)buffer;
}
cksum=(cksum >> 16)   (cksum & 0xffff);
cksum =(cksum >> 16);
return(USHORT) (~cksum);
}
/* 
Helper function to fill in various stuff in our ICMP request.
*/
void fill_icmp_data(char *icmp_data, int datasize)
{
IcmpHeader *icmp_hdr;
char *datapart;
icmp_hdr= (IcmpHeader *)icmp_data;
icmp_hdr->i_type=ICMP_ECHO;
icmp_hdr->i_code=0;
icmp_hdr->i_id=(USHORT) GetCurrentProcessId();
icmp_hdr->i_cksum=0;
icmp_hdr->i_seq=0;
datapart=icmp_data   sizeof(IcmpHeader);
//
// Place some junk in the buffer.
//
memset(datapart, 'E', datasize - sizeof(IcmpHeader));
}     
聯盟----Visita網站http://www.vista.org.tw ---[ 發問前請先找找舊文章 ]---
系統時間:2024-04-24 13:42:58
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!