Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.244.44] |
|
Сообщ.
#1
,
|
|
|
весь интернет обошел - не могу найти элементарного исходника пинга. сам я начинаю только и хочу разобраться как это работает, но все исходники, которые находил слишком большие и много в них наворочено, в общем не пониаю я их. Подскажить плз или киньте ссылку на статейку по написанию оного продукта.
исходник надо на Си под linux но можно и под win. Спасибо за помощь. |
Сообщ.
#2
,
|
|
|
возьми из busybox (http://busybox.net)
|
Сообщ.
#4
,
|
|
|
под *nix
все предельно просто накидал кусок который просто посылает и ждет ответ ... без всяких наворотов. #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) (може только у меня там крокозябара?) |
Сообщ.
#5
,
|
|
|
А где можно разжиться ИП заголовком ибо эта прога не различает пакеты от разных станций
|