📄 ping.c
字号:
PICMPV6_ECHO_REPLY reply6;
BOOL sourceRouting = FALSE;
char *SendBuffer, *RcvBuffer;
uint RcvSize;
uint SendSize = DEFAULT_SEND_SIZE;
HANDLE hIcmp;
LPTSTR pszCur;
socklen_t addressLen;
int Family = PF_UNSPEC;
// Ask fr Winsock version 2.2 (currently getaddrinfo() etc only exported from WS2)
err = WSAStartup(MAKEWORD(2,2), &WsaData);
if (err) {
OutputMessage (TEXT("WsaStartup Failed %d\r\n"), GetLastError());
return(1);
}
memset(&sourceAddress, 0, sizeof sourceAddress);
g_AI = NULL;
g_NextAI = NULL;
totalReplies = 0;
if (argc < 2) {
PrintUsage();
return(1);
}
for (i = 1; (i < (uint) argc); i++) {
if ((argv[i][0] == '-') || (argv[i][0] == '/')) { // Have an option
switch (argv[i][1]) {
case '?':
PrintUsage();
return(0);
case 'd':
v_fDebugOut = TRUE;
break;
case 'l':
SendSize = (uint)param(argv, argc, i++, 0, 0xfff7,
&ValidParms);
break;
case 't':
Count = (uint)-1;
break;
case 'n':
Count = (uint)param(argv, argc, i++, 1, 0xffffffff,
&ValidParms);
break;
case 'f':
Flags = IP_FLAG_DF;
break;
case 'i':
TTL = (uchar)param(argv, argc, i++, 0, 0xff, &ValidParms);
break;
case 'v':
TOS = (uchar)param(argv, argc, i++, 0, 0xff, &ValidParms);
break;
case 'w':
Timeout = param(argv, argc, i++, 0, 0xffffffff, &ValidParms);
break;
case 'a':
dnsreq = TRUE;
break;
case 'r': // Record Route
if ((OptIndex + 3) > MAX_OPT_SIZE) {
OutputMessage (TEXT("Too many options\r\n"));
return(1);
}
Opt = SendOptions;
Opt[OptIndex] = IP_OPT_RR;
Opt[OptIndex + 2] = 4; // Set initial pointer value
TempCount = (uchar)param(argv, argc, i++, 0, 9, &ValidParms);
TempCount = (TempCount * sizeof(ulong)) + 3;
if ((TempCount + OptIndex) > MAX_OPT_SIZE) {
OutputMessage (TEXT("Too many options\r\n"));
return(1);
}
Opt[OptIndex+1] = TempCount;
OptLength += TempCount;
OptIndex += TempCount;
sourceRouting = TRUE;
break;
case 's': // Timestamp
if ((OptIndex + 4) > MAX_OPT_SIZE) {
OutputMessage (TEXT("Too many options\r\n"));
return(1);
}
Opt = SendOptions;
Opt[OptIndex] = IP_OPT_TS;
Opt[OptIndex + 2] = 5; // Set initial pointer value
TempCount = (uchar)param(argv, argc, i++, 1, 4, &ValidParms);
TempCount = (TempCount * (sizeof(ulong) * 2)) + 4;
if ((TempCount + OptIndex) > MAX_OPT_SIZE) {
OutputMessage (TEXT("Too many options\r\n"));
return(1);
}
Opt[OptIndex+1] = TempCount;
Opt[OptIndex+3] = 1;
OptLength += TempCount;
OptIndex += TempCount;
sourceRouting = TRUE;
break;
case 'S': // source address (IPv6 only)
if(++i < (uint)argc)
{
struct addrinfo hints, *ai;
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = PF_INET6;
if (WideCharToMultiByte(CP_OEMCP, 0, argv[i], -1, source, sizeof(source), NULL, NULL) != 0)
if(getaddrinfo(source, NULL, &hints, &ai) == 0)
{
memcpy(&sourceAddress, ai->ai_addr, ai->ai_addrlen);
Family = PF_INET6;
freeaddrinfo(ai);
break;
}
}
OutputMessage (TEXT("-S option must be followed by an IPv6 IP address.\r\n"));
return(1);
break;
case '4': // force IPv4
Family = PF_INET;
break;
case '6': // force IPv6
Family = PF_INET6;
break;
default:
OutputMessage (TEXT("Bad option %s.\r\n\r\n"), argv[i]);
PrintUsage();
return(1);
break;
}
} else { // Not an option, must be an IP address.
if (found_addr) {
OutputMessage (TEXT("Bad parameter %s.\r\n"), argv[i]);
return(1);
}
found_addr = i; // Remember name/address arg index
}
}
if (!found_addr) {
OutputMessage(TEXT("IP address must be specified.\r\n"));
return(1);
}
if (TRUE != ValidParms) {
return (1);
}
if(ResolveTarget(Family, argv[found_addr], (LPSOCKADDR)&address, &addressLen, hostname, sizeof(hostname), dnsreq))
{
found_addr = 1;
if(address.ss_family == AF_INET6 &&
IsLinkLocal(&((SOCKADDR_IN6*)&address)->sin6_addr) &&
((SOCKADDR_IN6*)&address)->sin6_scope_id == 0)
{
OutputMessage(TEXT("Scope Id must be specified for link local address.\r\n"));
return 1;
}
} else {
OutputMessage(TEXT("Bad IP address %s.\r\n"), argv[i]);
return(1);
}
SendBuffer = LocalAlloc(LMEM_FIXED, SendSize);
if (SendBuffer == NULL) {
OutputMessage (TEXT("No Memory\r\n"));
return(1);
}
//
// Calculate receive buffer size and try to allocate it.
//
if (SendSize <= DEFAULT_SEND_SIZE) {
RcvSize = DEFAULT_BUFFER_SIZE;
} else {
RcvSize = MAX_BUFFER_SIZE;
}
RcvBuffer = LocalAlloc(LMEM_FIXED, RcvSize);
if (RcvBuffer == NULL) {
OutputMessage (TEXT("No Memory\r\n"));
LocalFree(SendBuffer);
return(1);
}
if(address.ss_family == AF_INET)
{
hIcmp = IcmpCreateFile();
}
else
{
if(sourceAddress.ss_family == AF_UNSPEC)
{
SOCKET s;
DWORD BytesReturned;
//
// A source address was not specified.
// Get the preferred source address for this destination.
//
// If you want each individual echo request
// to select a source address, use "-S ::".
//
s = socket(address.ss_family, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET) {
OutputMessage(TEXT("Can't create socket: %d"), WSAGetLastError());
return (1);
}
(void) WSAIoctl(s, SIO_ROUTING_INTERFACE_QUERY,
&address, sizeof address,
&sourceAddress, sizeof sourceAddress,
&BytesReturned, NULL, NULL);
closesocket(s);
getnameinfo((LPSOCKADDR)&sourceAddress, BytesReturned, source, sizeof(source),
NULL, 0, NI_NUMERICHOST);
}
hIcmp = Icmp6CreateFile();
}
//
// Initialize the send buffer pattern.
//
for (i = 0; i < SendSize; i++) {
SendBuffer[i] = 'a' + (i % 23);
}
//
// Initialize the send options
//
SendOpts.OptionsData = Opt;
SendOpts.OptionsSize = OptLength;
SendOpts.Ttl = TTL;
SendOpts.Tos = TOS;
SendOpts.Flags = Flags;
do {
getnameinfo((LPSOCKADDR)&address, addressLen, literal, sizeof(literal),
NULL, 0, NI_NUMERICHOST);
if (hostname[0])
{
if(source[0])
OutputMessage(TEXT("Pinging Host %hs [%hs]\r\nfrom %hs\r\n"), hostname, literal, source);
else
OutputMessage(TEXT("Pinging Host %hs [%hs]\r\n"), hostname, literal);
}
else
{
if(source[0])
OutputMessage(TEXT("Pinging Host %hs\r\nfrom %hs\r\n"), literal, source);
else
OutputMessage(TEXT("Pinging Host %hs\r\n"), literal);
}
for (i = 0; i < Count; i++)
{
if(address.ss_family == AF_INET)
{
numberOfReplies = IcmpSendEcho(hIcmp, ((LPSOCKADDR_IN)&address)->sin_addr.s_addr,
SendBuffer, (unsigned short) SendSize,
&SendOpts, RcvBuffer, RcvSize, Timeout);
if (numberOfReplies == 0)
{
errorCode = GetLastError();
OutputMessage(TEXT("PING: transmit failed, error code %lu\r\n"),
errorCode);
}
else
{
totalReplies += numberOfReplies;
reply4 = (PICMP_ECHO_REPLY) RcvBuffer;
while (numberOfReplies--)
{
pszCur = szOutBuf;
pszCur += wsprintf(pszCur, TEXT("Reply from %hs: "), literal);
if (reply4->Status == IP_SUCCESS)
{
pszCur += wsprintf(pszCur, TEXT("Echo size=%d "), reply4->DataSize);
if (reply4->DataSize != SendSize)
{
pszCur += wsprintf(pszCur, TEXT("(sent %d) "), SendSize);
}
else
{
char *sendptr, *recvptr;
sendptr = &(SendBuffer[0]);
recvptr = (char *) reply4->Data;
for (j = 0; j < SendSize; j++)
if (*sendptr++ != *recvptr++)
{
pszCur += wsprintf(pszCur, TEXT("- MISCOMPARE at offset %d - "), j);
break;
}
}
if (reply4->RoundTripTime)
{
pszCur += wsprintf(pszCur, TEXT("time=%lums "), reply4->RoundTripTime);
}
else
{
pszCur += wsprintf(pszCur, TEXT("time<1ms "));
}
pszCur += wsprintf(pszCur, TEXT("TTL=%u\r\n"), (uint)reply4->Options.Ttl);
OutputMessage (TEXT("%s"), szOutBuf);
if (reply4->Options.OptionsSize)
{
ProcessOptions(reply4, dnsreq);
}
}
else
{
pszCur += wsprintf(pszCur, TEXT("Error %d\r\n"), reply4->Status );
OutputMessage (TEXT("%s"), szOutBuf);
}
reply4++;
}
if (i < (Count - 1))
{
reply4--;
if (reply4->RoundTripTime < MIN_INTERVAL)
{
Sleep(MIN_INTERVAL - reply4->RoundTripTime);
}
}
}
}
else
{
numberOfReplies = Icmp6SendEcho2(NULL, NULL, NULL, NULL,
(LPSOCKADDR_IN6)&sourceAddress,
(LPSOCKADDR_IN6)&address, SendBuffer, (WORD)SendSize,
&SendOpts, RcvBuffer, RcvSize, Timeout);
if (numberOfReplies == 0)
{
errorCode = GetLastError();
OutputMessage(TEXT("PING: transmit failed, error code %lu\r\n"), errorCode);
}
else
{
totalReplies += numberOfReplies;
reply6 = (PICMPV6_ECHO_REPLY) RcvBuffer;
while (numberOfReplies--)
{
getnameinfo((LPSOCKADDR)&address, addressLen, literal,
sizeof(literal), NULL, 0, NI_NUMERICHOST);
pszCur = szOutBuf;
pszCur += wsprintf(pszCur, TEXT("Reply from %hs: "), literal);
if(reply6->Status == IP_SUCCESS)
{
if (reply6->RoundTripTime)
{
pszCur += wsprintf(pszCur, TEXT("time=%lums "), reply6->RoundTripTime);
}
else
{
pszCur += wsprintf(pszCur, TEXT("time<1ms "));
}
OutputMessage (TEXT("%s\r\n"), szOutBuf);
}
else
{
pszCur += wsprintf(pszCur, TEXT("Error %d\r\n"), reply6->Status );
OutputMessage (TEXT("%s"), szOutBuf);
}
reply6++;
}
if(i < (Count - 1))
{
reply6--;
if (reply6->RoundTripTime < MIN_INTERVAL)
{
Sleep(MIN_INTERVAL - reply6->RoundTripTime);
}
}
}
}
}
} while ((0 == totalReplies) && GetNextAddress((LPSOCKADDR)&address, &addressLen, hostname, sizeof(hostname)));
LocalFree(SendBuffer);
LocalFree(RcvBuffer);
if (g_AI) {
freeaddrinfo(g_AI);
}
IcmpCloseHandle (hIcmp);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -