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

📄 tracert.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
    {
        _tprintf(_T("   *  "));
    }
    else if ((iSelRet != SOCKET_ERROR) && (iSelRet != 0))
    {
        iSockRet = recvfrom(pInfo->icmpSock,            // socket
                           (char *)pInfo->RecvPacket,  // buffer
                           MAX_PING_PACKET_SIZE,        // size of buffer
                           0,                           // flags
                           (SOCKADDR *)&pInfo->source,  // source address
                           &iFromLen);                  // address length

        if (iSockRet != SOCKET_ERROR)
        {
            /* get time packet was recieved */
            pInfo->lTimeEnd = GetTime(pInfo);
            DebugPrint(_T("reveived %d bytes\n"), iSockRet);
            bRet = TRUE;
        }
        else
        {
            DebugPrint(_T("recvfrom failed: %d\n"), WSAGetLastError());
        }
    }

    return bRet;
}


static INT
DecodeResponse(PAPPINFO pInfo)
{
    unsigned short header_len = pInfo->RecvPacket->h_len * 4;

    /* cast the recieved packet into an ECHO reply and a TTL Exceed and check the ID*/
    ECHO_REPLY_HEADER *IcmpHdr = (ECHO_REPLY_HEADER *)((char*)pInfo->RecvPacket + header_len);
    TTL_EXCEED_HEADER *TTLExceedHdr = (TTL_EXCEED_HEADER *)((char *)pInfo->RecvPacket + header_len);

    /* Make sure the reply is ok */
    if (PACKET_SIZE < header_len + ICMP_MIN_SIZE)
    {
        DebugPrint(_T("too few bytes from %s\n"), inet_ntoa(pInfo->dest.sin_addr));
        return -2;
    }

    switch (IcmpHdr->icmpheader.type)
    {
           case TTL_EXCEEDED :
                if (TTLExceedHdr->OrigIcmpHeader.id != (USHORT)GetCurrentProcessId())
                {
                /* FIXME: our network stack shouldn't allow this... */
                /* we've picked up a packet not related to this process probably from another local program. We ignore it */
                    DebugPrint(_T("Rouge packet: header id,  process id  %d"), TTLExceedHdr->OrigIcmpHeader.id, GetCurrentProcessId());
                    return -1;
                }
                _tprintf(_T("%3Ld ms"), (pInfo->lTimeEnd - pInfo->lTimeStart) / pInfo->TicksPerMs.QuadPart);
                return 0;

           case ECHO_REPLY :
                if (IcmpHdr->icmpheader.id != (USHORT)GetCurrentProcessId())
                {
                /* FIXME: our network stack shouldn't allow this... */
                /* we've picked up a packet not related to this process probably from another local program. We ignore it */
                    DebugPrint(_T("Rouge packet: header id %d, process id  %d"), IcmpHdr->icmpheader.id, GetCurrentProcessId());
                    return -1;
                }
                _tprintf(_T("%3Ld ms"), (pInfo->lTimeEnd - pInfo->lTimeStart) / pInfo->TicksPerMs.QuadPart);
                return 1;

           case DEST_UNREACHABLE :
                _tprintf(_T("  *  "));
                return 2;
    }

    return 0;
}


static BOOL
AllocateBuffers(PAPPINFO pInfo)
{
    pInfo->SendPacket = (PECHO_REPLY_HEADER)HeapAlloc(GetProcessHeap(),
                                                      0,
                                                      sizeof(ECHO_REPLY_HEADER) + PACKET_SIZE);
    if (!pInfo->SendPacket)
        return FALSE;

    pInfo->RecvPacket = (PIPv4_HEADER)HeapAlloc(GetProcessHeap(),
                                                0,
                                                sizeof(IPv4_HEADER) + PACKET_SIZE);
    if (!pInfo->RecvPacket)
    {
        HeapFree(GetProcessHeap(),
                 0,
                 pInfo->SendPacket);

        return FALSE;
    }

    return TRUE;
}


static INT
Driver(PAPPINFO pInfo)
{
    INT iHopCount = 1;              // hop counter. default max is 30
    BOOL bFoundTarget = FALSE;      // Have we reached our destination yet
    INT iRecieveReturn;             // RecieveReturn return value
    PECHO_REPLY_HEADER icmphdr;
    INT iTTL = 1;

    INT ret = -1;

    //temps for getting host name
    CHAR cHost[256];
    CHAR cServ[256];
    CHAR *ip;

    SetupTimingMethod(pInfo);

    if (AllocateBuffers(pInfo) &&
        ResolveHostname(pInfo) &&
        CreateSocket(pInfo))
    {
        /* print tracing info to screen */
        _tprintf(_T("\nTracing route to %s [%s]\n"), cHostname, cDestIP);
        _tprintf(_T("over a maximum of %d hop"), pInfo->iMaxHops);
        pInfo->iMaxHops > 1 ? _tprintf(_T("s:\n\n")) : _tprintf(_T(":\n\n"));

        /* run until we hit either max hops, or find the target */
        while ((iHopCount <= pInfo->iMaxHops) &&
               (bFoundTarget != TRUE))
        {
            USHORT iSeqNum = 0;
            INT i;

            _tprintf(_T("%3d   "), iHopCount);

            /* run 3 pings for each hop */
            for (i = 0; i < 3; i++)
            {
                if (SetTTL(pInfo->icmpSock, iTTL) != TRUE)
                {
                    DebugPrint(_T("error in Setup()\n"));
                    return ret;
                }

                PreparePacket(pInfo, iSeqNum);

                if (SendPacket(pInfo) != SOCKET_ERROR)
                {
                    BOOL bAwaitPacket = FALSE; // indicates whether we have recieved a good packet

                    do
                    {
                        /* Receive replies until we get a successful read, or a fatal error */
                        if ((iRecieveReturn = ReceivePacket(pInfo)) < 0)
                        {
                            /* FIXME: consider moving this into RecievePacket */
                            /* check the seq num in the packet, if it's bad wait for another */
                            WORD hdrLen = pInfo->RecvPacket->h_len * 4;
                            icmphdr = (ECHO_REPLY_HEADER *)((char*)&pInfo->RecvPacket + hdrLen);
                            if (icmphdr->icmpheader.seq != iSeqNum)
                            {
                                _tprintf(_T("bad sequence number!\n"));
                                continue;
                            }
                        }

                        if (iRecieveReturn)
                        {
                            DecodeResponse(pInfo);
                        }
                        else
                            /* packet timed out. Don't wait for it again */
                            bAwaitPacket = FALSE;

                    } while (bAwaitPacket);
                }

                iSeqNum++;
                _tprintf(_T("   "));
            }

            if(pInfo->bResolveAddresses)
            {
                INT iNameInfoRet;               // getnameinfo return value
               /* gethostbyaddr() and getnameinfo() are
                * unimplemented in ROS at present.
                * Alex has advised he will be implementing getnameinfo.
                * I've used that for the time being for testing in Windows*/

                  //ip = inet_addr(inet_ntoa(source.sin_addr));
                  //host = gethostbyaddr((char *)&ip, 4, 0);

                  ip = inet_ntoa(pInfo->source.sin_addr);

                  iNameInfoRet = getnameinfo((SOCKADDR *)&pInfo->source,
                                             sizeof(SOCKADDR),
                                             cHost,
                                             256,
                                             cServ,
                                             256,
                                             NI_NUMERICSERV);
                  if (iNameInfoRet == 0)
                  {
                     /* if IP address resolved to a hostname,
                      * print the IP address after it */
                      if (lstrcmpA(cHost, ip) != 0)
                          _tprintf(_T("%s [%s]"), cHost, ip);
                      else
                          _tprintf(_T("%s"), cHost);
                  }
                  else
                  {
                      DebugPrint(_T("error: %d"), WSAGetLastError());
                      DebugPrint(_T(" getnameinfo failed: %d"), iNameInfoRet);
                  }

            }
            else
               _tprintf(_T("%s"), inet_ntoa(pInfo->source.sin_addr));

            _tprintf(_T("\n"));

            /* check if we've arrived at the target */
            if (strcmp(cDestIP, inet_ntoa(pInfo->source.sin_addr)) == 0)
                bFoundTarget = TRUE;
            else
            {
                iTTL++;
                iHopCount++;
                Sleep(500);
            }
        }
        _tprintf(_T("\nTrace complete.\n"));
        ret = 0;
    }

    return ret;
}


static VOID
Cleanup(PAPPINFO pInfo)
{
    if (pInfo->icmpSock)
        closesocket(pInfo->icmpSock);

    WSACleanup();

    if (pInfo->SendPacket)
        HeapFree(GetProcessHeap(),
                 0,
                 pInfo->SendPacket);

    if (pInfo->SendPacket)
        HeapFree(GetProcessHeap(),
                 0,
                 pInfo->RecvPacket);
}


#if defined(_UNICODE) && defined(__GNUC__)
static
#endif
int _tmain(int argc, LPCTSTR argv[])
{
    PAPPINFO pInfo;
    WSADATA wsaData;
    int ret = -1;

    pInfo = (PAPPINFO)HeapAlloc(GetProcessHeap(),
                                HEAP_ZERO_MEMORY,
                                sizeof(APPINFO));
    if (pInfo)
    {
        pInfo->bResolveAddresses = TRUE;
        pInfo->iMaxHops = 30;
        pInfo->iTimeOut = 1000;

        if (ParseCmdline(argc, argv, pInfo))
        {
            if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
            {
                DebugPrint(_T("WSAStartup failed.\n"));
            }
            else
            {
                ret = Driver(pInfo);
                Cleanup(pInfo);
            }
        }

        HeapFree(GetProcessHeap(),
                 0,
                 pInfo);
    }

    return ret;
}


#if defined(_UNICODE) && defined(__GNUC__)
/* HACK - MINGW HAS NO OFFICIAL SUPPORT FOR wmain()!!! */
int main( int argc, char **argv )
{
    WCHAR **argvW;
    int i, j, Ret = 1;

    if ((argvW = malloc(argc * sizeof(WCHAR*))))
    {
        /* convert the arguments */
        for (i = 0, j = 0; i < argc; i++)
        {
            if (!(argvW[i] = malloc((strlen(argv[i]) + 1) * sizeof(WCHAR))))
            {
                j++;
            }
            swprintf(argvW[i], L"%hs", argv[i]);
        }

        if (j == 0)
        {
            /* no error converting the parameters, call wmain() */
            Ret = wmain(argc, (LPCTSTR *)argvW);
        }

        /* free the arguments */
        for (i = 0; i < argc; i++)
        {
            if (argvW[i])
                free(argvW[i]);
        }
        free(argvW);
    }

    return Ret;
}
#endif

⌨️ 快捷键说明

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