На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> исходники ping , простой нужно
    весь интернет обошел - не могу найти элементарного исходника пинга. сам я начинаю только и хочу разобраться как это работает, но все исходники, которые находил слишком большие и много в них наворочено, в общем не пониаю я их. Подскажить плз или киньте ссылку на статейку по написанию оного продукта.
    исходник надо на Си под linux но можно и под win.

    Спасибо за помощь.
      возьми из busybox (http://busybox.net)
          под *nix

          все предельно просто
          накидал кусок который просто посылает и ждет ответ ... без всяких наворотов.

          ExpandedWrap disabled
             
            #include <stdio.h>
            #include <string.h>
            #include <netdb.h>
            #include <sys/types.h>
            #include <sys/socket.h>
            #include <netinet/in.h>
            #include <arpa/inet.h>
            #include <errno.h>
            #include <sys/time.h>
            #include <signal.h>
            #include <unistd.h>
             
            //заголовок ICMP  :D
            typedef struct tagIcmpHead /* icmp header */
            {
                unsigned char icmp_type;    /* icmp service type */
                                        /* 8 echo require, 0 echo reply */
                unsigned char icmp_code;    /* icmp header code */
                unsigned short icmp_chksum; /* icmp header chksum */
                unsigned short icmp_id;     /* icmp packet identification */
                unsigned short icmp_seq;    /* icmp packet sequent */
                unsigned char icmp_data[56]; /* icmp data, use as pointer */
            } ICMPHEAD;
             
            // функция рачета  контрольной суммы. Исходник взят у У. Р. Стивенса (царство ему небесное)
            //но алгоритм довольно простой и известный
             
            unsigned short in_cksum(unsigned short *addr, int len)
            {
                int             nleft = len;
                int             sum = 0;
                unsigned short  *w = addr;
                unsigned short  answer = 0;
             
                /*
                 * Our algorithm is simple, using a 32 bit accumulator (sum), we add
                 * sequential 16 bit words to it, and at the end, fold back all the
                 * carry bits from the top 16 bits into the lower 16 bits.
                 */
                while (nleft > 1)  {
                    sum += *w++;
                    nleft -= 2;
                }
             
                    /* 4mop up an odd byte, if necessary */
                if (nleft == 1) {
                    *(unsigned char *)(&answer) = *(unsigned char *)w ;
                    sum += answer;
                }
             
                    /* 4add back carry outs from top 16 bits to low 16 bits */
                sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
                sum += (sum >> 16);         /* add carry */
                answer = ~sum;              /* truncate to 16 bits */
                return(answer);
            }
             
             
             
            int main()
            {
            int s;
            struct sockaddr_in sai;
            ICMPHEAD icmp, *picmp;
            int siz;
            int len;
            int flag=0;
            char buf[255];
            pid_t pid;
                
                pid=getpid();
                s=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
                if(s<0){
                    printf("socket error\n");
                    return 1;
                }
                bzero(&sai, sizeof(sai));
                
                sai.sin_family = AF_INET;
                sai.sin_addr.s_addr = inet_addr("192.168.1.1");  // destination хост поменяй тут на свой
                
                
                icmp.icmp_type = 8;             // 8 - реквест ; 0 - реплай
                icmp.icmp_code = 0;         // код  
                icmp.icmp_id = pid;         // чаще всего сдесь именно идентификатор процесса
                icmp.icmp_seq = 1;          // порядковый номер пакета - при дальнейшей отправке увеличивай на 1
                gettimeofday((struct timeval *) icmp.icmp_data, NULL);  //  в данные заноси текущее время
                                            //(по rfc отвечающий не должен изменять это поле и
                                            // легко вычислить потом время хождения пакета)
             
                len = sizeof(icmp);     /* checksum ICMP header and data */
                icmp.icmp_chksum = 0;
                icmp.icmp_chksum = in_cksum((u_short *) &icmp, len); // расчет контроьной суммы -
                                        //в linux можно оставить 0 ядhо само пересчитает
                                        //*BSD таких воьностей не допускает
             
                sendto(s, &icmp, sizeof(icmp), 0, (struct sockaddr *)&sai, sizeof(sai)); // посылаем
                
                siz=sizeof(sai);    
                while(!flag){
                    recvfrom(s, buf, 255, 0, 0, 0); // принимаен пакеты и ищем наш  :D :D :D
                    picmp = &buf[20];       // смещение на размер ip заголовка -
                                    // пакет принимается полностью в отличае от отправки ...
                                    // лучше, конечно применять sizeof тут ибо протокол божет быть и v6.
                    printf("recv pack with id %u\n", picmp->icmp_id);  
                    flag = ( (0 == picmp->icmp_type) && pid == picmp->icmp_id); // если это наш пакет и это ответ -
                                                 // то ставим флаг и завершаем цикл.
                                                // тут нужно еще таймоут сделать ибо если никто
                                                //не ответит прога зависнит "навсегда".
                }
                
                printf("recv pack\n");
                
                return 0;
            }


          там while(!flag) (може только у меня там крокозябара?)
          Сообщение отредактировано: .failer -
            А где можно разжиться ИП заголовком ибо эта прога не различает пакеты от разных станций
            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,0622 ]   [ 16 queries used ]   [ Generated: 20.04.24, 01:33 GMT ]