ICMP тип ответа 0 от несуществующих хостов (ОС C, QNX) - PullRequest
0 голосов
/ 26 ноября 2018

Я пытаюсь написать простую программу на C под QNX, которая ищет хост, последовательно проверяя адреса.Программа, кажется, работает нормально, если мне нужно сканировать только несколько адресов, чтобы найти хост, но мне нужно пропинговать больше несуществующих хостов, чтобы найти искомые странные вещи.Я иногда склонен пропускать существующий узел, но получаю ответ от другого несуществующего.Icmp_type пакета, который я получаю, равен 0 (ICMP ECHO Reply), хотя я уверен, что этот хост не находится в сети.Это также тогда случайно, для IP-адреса которого я получаю тип ответа ICMP_ECHO.Я думаю, это какая-то проблема времени.Буду очень признателен за подсказку, как ее решить или почему это происходит.

int16_t MyPing(
    HAFDaemon_Ws *const io_pWs,         /*!< The daemon instance. */
    uint16_t SearchSplit
        )
{
  eSuccess eOk = SUCCESS_FAIL;
  struct icmp *Spkt;
  struct icmp *Rpkt;
  int32_t SentSize = 0;
  int32_t RecvSize =0;
  char  s_addr[16]; 
  char icmpPacketTx [192];
  char icmpPacketRx [192];
  SOCKET_ADDRESS    h_addr;
  int16_t  NodeAddress=-1;
  uint16_t i;
  uint16_t SplitEnd=SearchSplit+9;
  Spkt = (struct icmp *) (icmpPacketTx);
  memset(Spkt, 0, sizeof(icmpPacketTx));
  Rpkt = (struct icmp *) (icmpPacketRx);
  memset(Rpkt, 0, sizeof(icmpPacketRx));
  Spkt->icmp_type = ICMP_ECHO;
  Spkt->icmp_cksum = in_cksum((unsigned short *) Spkt, sizeof(icmpPacketTx));
  int32_t MsgSize = sizeof(icmpPacketTx);
    if (SUCCESS_OK == eOk)
    {
        eOk =ICMPOpenSocket( &(io_pWs->EchoSock),ICMP_SEND_TIMEOUT,ICMP_RECV_TIMEOUT); /*Open ICMP scoket*/
    }
    if (SUCCESS_OK == eOk)
    {
    for (i=SearchSplit;i<SplitEnd;i++) 
        {
            sprintf(s_addr,"192.168.%u.%u",i,sBaySlot.sSlot);
            if (1==inet_aton(s_addr,&h_addr.sin_addr))  
        {
            eOk = OsalSocketAddressInit(&(io_pWs->PingHandle),h_addr,0U );
                /*Send messege*/
            eOk = SendMsg(io_pWs->EchoSock, //send message wrapps sendto()
                              icmpPacketTx,
                                  MsgSize,
                                  &SentSize,
                                  io_pWs->PingHandle);
                //wait for reply
                sleep(2U);
                eOk = GetMsg(io_pWs->EchoSock, //wrappes rcvfrom
                                icmpPacketRx,
                                MsgSize,
                                &RecvSize, io_pWs->PingHandle); 
                if (RecvSize>0)                             
                {
                    struct ip *ip = (struct ip *) icmpPacketRx;
                    Rpkt = (struct icmp *) (icmpPacketRx + (ip->ip_hl<< 2)); //remove ip header
                    if (Rpkt->icmp_type== ICMP_ECHOREPLY)
                    {
                        NodeAddress=i;
                    break;
                    }
                }
        }
    }
   }
    UdpCloseSocket(io_pWs->EchoSock);
    return NodeAddress;
}
eSuccess ICMPOpenSocket(
    SOCKET *const o_pSocket,        /*!< Pointer to buffer to hold id of newly
                                         created socket. */
    uint16_t i_SendTimeout,         /*!< Send timeout in ms, 0 => wait
                                         forever. */
    uint16_t i_RecvTimeout          /*!< Receive timeout in ms, 0 => wait
                                         forever. */
)
{
    eSuccess Ok = SUCCESS_FAIL;
    struct sockaddr_in sock_add;    /*Sock address buffer to be used */
    struct timeval tv;
    SOCKET Sock = INVALID_SOCKET;
    int32_t SockRes = INVALID_SOCKET;
    int ttl =60;
    int one=1;
    const int val=255;    
    Sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); //ICMP
    if ((INVALID_SOCKET != Sock) && (o_pSocket != NULL))
    {
        memset(&sock_add, 0, sizeof(struct sockaddr_in));

        sock_add.sin_family = (uint8_t)AF_INET;
        sock_add.sin_addr.s_addr = htonl(INADDR_ANY);
        *o_pSocket = Sock;
        Ok = SUCCESS_OK;
    }
    if ((SUCCESS_OK == Ok) && (i_RecvTimeout > 0U))
    {
        /* Set the timeout.*/
        tv.tv_sec = i_RecvTimeout / 1000U;
        tv.tv_usec = (1000U * (i_RecvTimeout % 1000U));
        SockRes = setsockopt(Sock, SOL_SOCKET, SO_RCVTIMEO,
                             &tv, sizeof(tv));
        if (SockRes < 0)
        {
            Ok = SUCCESS_FAIL;
        }

    }
    if ((SUCCESS_OK == Ok) && (i_SendTimeout > 0U))
    {
        /* Set the timeout.*/
        tv.tv_sec = i_SendTimeout / 1000U;
        tv.tv_usec = (1000U * (i_SendTimeout % 1000U));


        SockRes = setsockopt(Sock, SOL_SOCKET, SO_SNDTIMEO,
                             &tv, sizeof(tv));
        if (SockRes < 0)
        {
            Ok = SUCCESS_FAIL;
        }
    }
    if ((SUCCESS_OK == Ok))
    {
        SockRes =setsockopt(Sock, SOL_SOCKET,SO_DONTROUTE,&one, sizeof(one));
        if (SockRes < 0)
        {
            Ok = SUCCESS_FAIL;
        }
    }
    return Ok;
}
...