php ping

Discussion in 'PHP' started by OdaN, 19 Sep 2010.

  1. OdaN

    OdaN Elder - Старейшина

    Joined:
    4 Mar 2006
    Messages:
    192
    Likes Received:
    17
    Reputations:
    1
    Добрый день, задался тут вопросом, мониторинга, и соответственно возник вопрос. реально ли вобще реализовать сабж? т.е. я имею в виду не system(), и не exec(), а имеенно полноценный класс, или функцию, с отправкой ICMP пакетов, засеканием времени, и возвратом... гугление ни к чему хорошему не привело. покажите примеры, если есть у кого, или ткните лицом в подробное чтиво про пинг, а то знания как оказаллось даже о такой простой вещи как-то совсем не глубоки =)
     
  2. OSW

    OSW Elder - Старейшина

    Joined:
    12 Jul 2007
    Messages:
    325
    Likes Received:
    56
    Reputations:
    7
    тут было что-то
     
    1 person likes this.
  3. Sharky

    Sharky Elder - Старейшина

    Joined:
    1 May 2006
    Messages:
    487
    Likes Received:
    312
    Reputations:
    46
    А в чем проблема. Сокеты и замеряй время.
     
  4. OdaN

    OdaN Elder - Старейшина

    Joined:
    4 Mar 2006
    Messages:
    192
    Likes Received:
    17
    Reputations:
    1
    Ну дык время надо замерять от отправки данных, до ответа. т.е. Надо спровоцировать удаленный узел на ответ, не будет-же он просто так кому попало отвечать =) Я потому и спрашивал почитать про пинг...
     
    #4 OdaN, 20 Sep 2010
    Last edited: 20 Sep 2010
  5. Carvolan

    Carvolan New Member

    Joined:
    20 Sep 2010
    Messages:
    1
    Likes Received:
    0
    Reputations:
    0
    ICMP входит в стек протокола TCP/IP, можете вручную через socket формировать пакеты и смотреть время ответа
     
  6. OdaN

    OdaN Elder - Старейшина

    Joined:
    4 Mar 2006
    Messages:
    192
    Likes Received:
    17
    Reputations:
    1
    Это я знаю >_< что входит в пакет? каую инфу в него пихать? есть где-то спецификация ICMP? почему в разных операционных системах разный размер пакета по умолчанию?

    Общие принципы я знаю. Мне нужна конкретика.
     
    #6 OdaN, 21 Sep 2010
    Last edited: 21 Sep 2010
  7. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    OdaN Вам дали вполне конкретный класс, судя по коду реализующий ICMP. Если интересует стандарт - то это RFC792, почитать можно например тут: http://www.faqs.org/rfcs/rfc792.html
     
    _________________________
  8. OdaN

    OdaN Elder - Старейшина

    Joined:
    4 Mar 2006
    Messages:
    192
    Likes Received:
    17
    Reputations:
    1
    Класс я видел, уже плюсанул, и уже ковыряю =) просто в тему продолжали отвечать, вот я и повторял... За стандарт спасибо.
     
  9. OdaN

    OdaN Elder - Старейшина

    Joined:
    4 Mar 2006
    Messages:
    192
    Likes Received:
    17
    Reputations:
    1
    Если кому интересно, нашел скрипт, пинга для unix, с помощью SOCK_RAW на php.net: http://www.php.net/manual/en/function.socket-create.php

    PHP:
    <?php

    /// start ping.inc.php ///

    $g_icmp_error "No Error";

    // timeout in ms
    function ping($host$timeout)
    {
            
    $port 0;
            
    $datasize 64;
            global 
    $g_icmp_error;
            
    $g_icmp_error "No Error";
            
    $ident = array(ord('J'), ord('C'));
            
    $seq   = array(rand(0255), rand(0255));

         
    $packet '';
         
    $packet .= chr(8); // type = 8 : request
         
    $packet .= chr(0); // code = 0

         
    $packet .= chr(0); // checksum init
         
    $packet .= chr(0); // checksum init

            
    $packet .= chr($ident[0]); // identifier
            
    $packet .= chr($ident[1]); // identifier

            
    $packet .= chr($seq[0]); // seq
            
    $packet .= chr($seq[1]); // seq

            
    for ($i 0$i $datasize$i++)
                    
    $packet .= chr(0);

            
    $chk icmpChecksum($packet);

            
    $packet[2] = $chk[0]; // checksum init
            
    $packet[3] = $chk[1]; // checksum init

            
    $sock socket_create(AF_INETSOCK_RAW,  getprotobyname('icmp'));
            
    $time_start microtime();
        
    socket_sendto($sock$packetstrlen($packet), 0$host$port);
        

        
    $read   = array($sock);
            
    $write  NULL;
            
    $except NULL;

            
    $select socket_select($read$write$except0$timeout 1000);
            if (
    $select === NULL)
            {
                    
    $g_icmp_error "Select Error";
                    
    socket_close($sock);
                    return -
    1;
            }
            elseif (
    $select === 0)
            {
                    
    $g_icmp_error "Timeout";
                    
    socket_close($sock);
                    return -
    1;
            }

        
    $recv '';
        
    $time_stop microtime();
        
    socket_recvfrom($sock$recv655350$host$port);
            
    $recv unpack('C*'$recv);
            
            if (
    $recv[10] !== 1// ICMP proto = 1
            
    {
                    
    $g_icmp_error "Not ICMP packet";
                    
    socket_close($sock);
                    return -
    1;
            }

            if (
    $recv[21] !== 0// ICMP response = 0
            
    {
                    
    $g_icmp_error "Not ICMP response";
                    
    socket_close($sock);
                    return -
    1;
            }

            if (
    $ident[0] !== $recv[25] || $ident[1] !== $recv[26])
            {
                    
    $g_icmp_error "Bad identification number";
                    
    socket_close($sock);
                    return -
    1;
            }
            
            if (
    $seq[0] !== $recv[27] || $seq[1] !== $recv[28])
            {
                    
    $g_icmp_error "Bad sequence number";
                    
    socket_close($sock);
                    return -
    1;
            }

            
    $ms = ($time_stop $time_start) * 1000;
            
            if (
    $ms 0)
            {
                    
    $g_icmp_error "Response too long";
                    
    $ms = -1;
            }

            
    socket_close($sock);

            return 
    $ms;
    }

    function 
    icmpChecksum($data)
    {
            
    $bit unpack('n*'$data);
            
    $sum array_sum($bit);

            if (
    strlen($data) % 2) {
                    
    $temp unpack('C*'$data[strlen($data) - 1]);
                    
    $sum += $temp[1];
            }

            
    $sum = ($sum >> 16) + ($sum 0xffff);
            
    $sum += ($sum >> 16);

            return 
    pack('n*', ~$sum);
    }

    function 
    getLastIcmpError()
    {
            global 
    $g_icmp_error;
            return 
    $g_icmp_error;
    }
    /// end ping.inc.php ///
    ?>