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

📄 ping.c

📁 WinCE下的ping源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:  

    ping.c

Abstract:  

    Packet INternet Groper utility for TCP/IP.  This is a command line
    sample program to demonstrate the use of the icmplib.  Since there
    is no console in a Windows CE system (at least not now) this needs
    to be run under the debugger to view the output.


Functions:


Notes: 


--*/
#include <windows.h>
#include "winsock2.h"
#include "Ws2tcpip.h"
#include <memory.h>
#include "icmpapi.h"
#include "ntddip6.h"

#define DECLARE_OUTMSG
#include "outmsg.h"
#include "lmemdebug.h"

#ifdef DEBUG
DBGPARAM dpCurSettings = 
{
    TEXT("Ping"), {
    TEXT("Unused"),TEXT("Unused"),TEXT("Unused"),TEXT("Unused"),
    TEXT("Unused"),TEXT("Unused"),TEXT("Unused"),TEXT("Unused"),
    TEXT("Unused"),TEXT("Unused"),TEXT("Unused"),TEXT("Unused"),
    TEXT("Unused"),TEXT("Unused"),TEXT("Unused"),TEXT("Unused") },
    0x00000000
}; 
#endif


#define MAX_BUFFER_SIZE       (sizeof(ICMP_ECHO_REPLY) + 0xfff7 + MAX_OPT_SIZE)
#define DEFAULT_BUFFER_SIZE         (0x2000 - 8)
#define DEFAULT_SEND_SIZE           32
#define DEFAULT_COUNT               4
#define DEFAULT_TTL                 32
#define DEFAULT_TOS                 0
#define DEFAULT_TIMEOUT             1000L
#define MIN_INTERVAL                1000L
#define TRUE                        1
#define FALSE                       0

uchar   SendOptions[MAX_OPT_SIZE];

WSADATA WsaData;

TCHAR szOutBuf[1024];

LPADDRINFO g_AI;        // List of ADDRINFOs from getaddrinfo
LPADDRINFO g_NextAI;    // Next ADDRINFO to try
char       g_TargetString[NI_MAXHOST+1];

__inline int
IsLinkLocal(const IPv6Addr *Addr)
{
    return ((Addr->s6_bytes[0] == 0xfe) &&
            ((Addr->s6_bytes[1] & 0xc0) == 0x80));
}

void
PrintUsage(
    void
    )
{
    OutputMessage(TEXT("Usage: ping [-l size] [-n count] [-d] [-i TTL] ")
                  TEXT("[-v TOS] [-w timeout] address\r\n"));
    OutputMessage(TEXT("\r\n"));
    OutputMessage(TEXT("Options:\r\n"));
    OutputMessage(TEXT("    -d            Send output to the debug output port.\r\n"));
    OutputMessage(TEXT("    -t            Ping the specifed host ")
                  TEXT("until interrupted.\r\n"));
    OutputMessage(TEXT("    -l size       Send buffer size.\r\n"));
    OutputMessage(TEXT("    -n count      Send count.\r\n"));
    OutputMessage(TEXT("    -f            Don't fragment.\r\n"));
    OutputMessage(TEXT("    -i TTL        Time to live.\r\n"));
    OutputMessage(TEXT("    -v TOS        Type of service\r\n"));
    OutputMessage(TEXT("    -w timeout    Timeout (in milliseconds)\r\n"));
    OutputMessage(TEXT("    -r count      Record route for count hops.\r\n"));
    OutputMessage(TEXT("    -s count      Timestamp route for count hops.\r\n"));
    OutputMessage(TEXT("    -S address    Source address to use (IPv6-only).\r\n"));
    OutputMessage(TEXT("    -4            Force using IPv4.\r\n"));
    OutputMessage(TEXT("    -6            Force using IPv6.\r\n"));
//    OutputMessage(TEXT("    -j ipaddress  Loose source route.\r\n")));
//    OutputMessage(TEXT("    -k ipaddress  Strict source route.\r\n")));
    OutputMessage(TEXT("\r\n"));
}

void
ProcessOptions(ICMP_ECHO_REPLY *reply,
               BOOLEAN          DoReverseLookup)
{
    UCHAR FAR *optionPtr;
    UCHAR FAR *endPtr;
    BOOLEAN    done = FALSE;
    UCHAR      optionLength;
    UCHAR      entryEndPtr;
    UCHAR      entryPtr;
    UCHAR      addressMode;
    int        entryCount = 0;


    optionPtr = reply->Options.OptionsData;
    endPtr = optionPtr + reply->Options.OptionsSize;

    while ((optionPtr < endPtr) && !done) {
        switch(*optionPtr) {
        case IP_OPT_EOL:
            done = TRUE;
            break;

        case IP_OPT_NOP:
            optionPtr++;
            break;

        case IP_OPT_SECURITY:
            optionPtr += 11;
            break;

        case IP_OPT_SID:
            optionPtr += 4;
            break;

        case IP_OPT_RR:
        case IP_OPT_LSRR:
        case IP_OPT_SSRR:
            if ((optionPtr + 3) > endPtr) {
                OutputMessage (TEXT("Invalid RR option\r\n"));
                done = TRUE;
                break;
            }

            optionLength = optionPtr[1];

            if (((optionPtr + optionLength) > endPtr) ||
                (optionLength < 3)) {
                OutputMessage (TEXT("Invalid RR option\r\n"));
                done = TRUE;
                break;
            }

            entryEndPtr = optionPtr[2];

            if (entryEndPtr < 4) {
                OutputMessage (TEXT("Invalid RR option\r\n"));
                optionPtr += optionLength;
                break;
            }

            if (entryEndPtr > (optionLength + 1)) {
                entryEndPtr = optionLength + 1;
            }

                entryPtr = 4;
                entryCount = 0;

            OutputMessage (TEXT("Route Header --- \r\n"));

            while ((entryPtr + 3) < entryEndPtr) {
                struct in_addr  routeAddress;

                if (entryCount) {
                    OutputMessage (TEXT("\r\n"));

                    if (entryCount == 1) {
                        OutputMessage (TEXT("\r\n"));
                        OutputMessage (TEXT("Route Header2 --\r\n"));
                        entryCount = 0;
                    }
                }

                entryCount++;

                routeAddress.S_un.S_addr = *( (IPAddr UNALIGNED *)
                                             (optionPtr + entryPtr - 1));

                if (DoReverseLookup) {
                    struct hostent *hostEntry;

                    hostEntry = gethostbyaddr((char *) &routeAddress,
                                              sizeof(routeAddress),
                                              AF_INET);

                    if (hostEntry != NULL) {
                        OutputMessage (TEXT("Route %hs %hs "),hostEntry->h_name,
                                       inet_ntoa(routeAddress));
                    }
                    else {
                        OutputMessage (TEXT("Route %hs "),
                                       inet_ntoa(routeAddress));
                    }
                }    
                else {
                    OutputMessage (TEXT("Route %hs "),
                                   inet_ntoa(routeAddress));
                }

                entryPtr += 4;
            }

            OutputMessage (TEXT("\r\n"));

            optionPtr += optionLength;
            break;

        case IP_OPT_TS:
            if ((optionPtr + 4) > endPtr) {
                OutputMessage (TEXT("Invalid TS Option\r\n"));
                done = TRUE;
                break;
            }

            optionLength = optionPtr[1];
            entryEndPtr = optionPtr[2];

            if (entryEndPtr < 5) {
                OutputMessage (TEXT("Invalid TS Option\r\n"));
                optionPtr += optionLength;
                break;
            }

                addressMode = optionPtr[3] & 1;

            if (entryEndPtr > (optionLength + 1)) {
                entryEndPtr = optionLength + 1;
            }

            entryPtr = 5;
            entryCount = 0;
            OutputMessage (TEXT("\tTimestamp:\t"));

            while ((entryPtr + 3) < entryEndPtr) {
                struct in_addr  routeAddress;
                        ULONG           timeStamp;

                if (entryCount) {
                    OutputMessage (TEXT("\r\n\t\t\t"));

                    if (entryCount == 1) {
                        OutputMessage (TEXT("\r\n"));
                        OutputMessage (TEXT("Timestamp Hd2 \r\n"));
                    }
                }
                
                entryCount++;

                if (addressMode) {
                    if ((entryPtr + 8) > entryEndPtr) {
                        break;
                    }

                    routeAddress.S_un.S_addr =
                        *( (IPAddr UNALIGNED *)
                          (optionPtr + entryPtr - 1));

                    if (DoReverseLookup) {
                        struct hostent *hostEntry;

                        hostEntry = gethostbyaddr((char *) &routeAddress,
                                                  sizeof(routeAddress),
                                                  AF_INET);

                        if (hostEntry != NULL) {
                            OutputMessage (TEXT("TS %hs %hs "),
                                           hostEntry->h_name,
                                           inet_ntoa(routeAddress));
                        } else {
                            OutputMessage (TEXT("TS %hs "),
                                           inet_ntoa(routeAddress));
                        }
                    } else {
                        OutputMessage (TEXT("TS %hs "),
                                       inet_ntoa(routeAddress));
                    }

                    entryPtr += 4;
                    
                }
                
                timeStamp = *( (ULONG UNALIGNED *)
                              (optionPtr + entryPtr - 1));

                OutputMessage (TEXT("TimeStamp %u "),
                        ntohl(timeStamp));

                        entryPtr += 4;
            }

            OutputMessage (TEXT("\r\n"));
            optionPtr += optionLength;
            break;
            
        default:
            if ((optionPtr + 2) > endPtr) {
                done = TRUE;
                break;
            }

            optionPtr += optionPtr[1];
            break;
        }
    }
}


BOOLEAN
ResolveTarget(
    int           Family,
    wchar_t      *wTargetString,
    SOCKADDR     *TargetAddress,
    socklen_t    *TargetAddressLen,
    char         *TargetName,
    int           TargetNameLen,
    BOOLEAN       DoReverseLookup
    )
{
    int              i;
    struct addrinfo  hints, *ai;

    if (0 == WideCharToMultiByte(CP_ACP, 0, wTargetString, -1, g_TargetString, sizeof(g_TargetString), NULL, NULL))
        return FALSE;

    TargetName[0] = '\0';

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = Family;
    hints.ai_flags = AI_NUMERICHOST;
    i = getaddrinfo(g_TargetString, "", &hints, &ai);
    if(i == NO_ERROR)
    {
        *TargetAddressLen = ai->ai_addrlen;
        memcpy(TargetAddress, ai->ai_addr, ai->ai_addrlen);

        if (DoReverseLookup)
        {
            getnameinfo(ai->ai_addr, ai->ai_addrlen,
                        TargetName, TargetNameLen,
                        NULL, 0, NI_NAMEREQD);
        }

        freeaddrinfo(ai);
        return(TRUE);
    }
    else
    {
        hints.ai_flags = AI_CANONNAME;
        if (getaddrinfo(g_TargetString, NULL, &hints, &ai) == 0)
        {
            *TargetAddressLen = ai->ai_addrlen;
            memcpy(TargetAddress, ai->ai_addr, ai->ai_addrlen);
            strcpy(TargetName, (ai->ai_canonname)? ai->ai_canonname : g_TargetString);
            g_AI = ai;
            g_NextAI = ai->ai_next;
            return(TRUE);
        }
    }

    return(FALSE);

} // ResolveTarget


//
// GetNextAddress - Return the name and address of the current ADDRINFO and advance to the next ADDRINFO.
//
BOOLEAN
GetNextAddress(
    SOCKADDR     *TargetAddress,
    socklen_t    *TargetAddressLen,
    char         *TargetName,
    int           TargetNameLen
    )
{
    if (g_NextAI) {
        *TargetAddressLen = g_NextAI->ai_addrlen;
        memcpy(TargetAddress, g_NextAI->ai_addr, g_NextAI->ai_addrlen);
        strcpy(TargetName, (g_NextAI->ai_canonname)? g_NextAI->ai_canonname : g_TargetString);
        g_NextAI = g_NextAI->ai_next;
        return TRUE;
    } 
    return FALSE;
} // GetNextAddress



ulong
param(TCHAR **argv, int argc, int current, ulong min, ulong max, BOOL *Valid)
{
    ulong   temp = 0;

    if (current == (argc - 1) ) {
        OutputMessage(TEXT( "Value must be supplied for option %s.\r\n"),
                      argv[current]);
        *Valid = FALSE;
    } else {

        temp = _ttol(argv[current+1]);
        if (temp < min || temp > max) {
            OutputMessage(TEXT( "Bad value for option %s.\r\n"),
                          argv[current]);
            *Valid = FALSE;
        }
    }

    return temp;
}


int WinMain( int argc, TCHAR *argv[] )
{
    BOOL    ValidParms = TRUE;
    uint    i;
    uint    j;
    int     found_addr = 0;
    BOOLEAN dnsreq = FALSE;
    char    hostname[NI_MAXHOST] = "", literal[INET6_ADDRSTRLEN] = "", source[NI_MAXHOST] = "";
    SOCKADDR_STORAGE address;
    SOCKADDR_STORAGE sourceAddress;
    DWORD   numberOfReplies;
    DWORD   totalReplies;
    uint    Count = DEFAULT_COUNT;
    uchar   TTL = DEFAULT_TTL;
    uchar    *Opt = (uchar *)0;         // Pointer to send options
    uint    OptLength = 0;
    int     OptIndex = 0;           // Current index into SendOptions
    uchar   TOS = DEFAULT_TOS;
    uchar   Flags = 0;
    ulong   Timeout = DEFAULT_TIMEOUT;
    IP_OPTION_INFORMATION SendOpts;
    uchar   TempCount;
    DWORD   errorCode;
    int     err;
    PICMP_ECHO_REPLY   reply4;

⌨️ 快捷键说明

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