Funkce ping
computer at optimit.cz
computer at optimit.cz
Thu Apr 17 16:40:41 CEST 1997
> mam takovy, mozna dost blby dotaz. Jak pracuje program (prikaz) ping.
> Hledal jsem to ve vsech moznych priruckach, ale nic jsem nenasel.
Pracuje pomerne jednoduse. Program samotny je dost slozity, pro svoji
potrebu na lokalni (!) siti jsem si ping hodne upravil. Na Internetu
by vam to moc nefungovalo, ale jako ilustrace to postaci.
Pro ping se pouziva protokol ICMP (Internet Control Message Protocol),
popsany v RFC792. Strucny popis vysel v knizce
Pavel Smrha, Vladimir Rudolf: "Internetworking pomoci TCP/IP",
nakladatelstvi Kopp.
-------------------------------------------------------------
Petr Bravenec, computer at optimit.cz
-------------- next part --------------
/* Na detaily mrkni do rfc792 nebo do knizky
"Internetworking pomoci TCP/IP" na stranku 37 */
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifdef SVR4
#include <netinet/in_systm.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#ifndef SVR3
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#endif
#include <netdb.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <sys/file.h>
#ifndef SVR3
#include <stdlib.h>
#endif
#include <string.h>
#include <errno.h>
#ifdef Linux
#define icmp_type type
#define icmp_code code
#define icmp_cksum checksum
#define icmp_seq un.echo.sequence
#define icmp_id un.echo.id
#endif
void pinger ();
int ping ();
struct sockaddr whereto;
int paclen=20;
int ping_sock;
int ident;
/******************************************************************************/
int ping (target)
char *target;
{
struct protoent *proto;
struct sockaddr_in from;
struct sockaddr_in *to;
int fromlen;
int i,cc,hold;
char packet[1024];
ident = getpid () & 0xFFFF;
/**************************/
/* Priprava struktur cile */
to = (struct sockaddr_in *)&whereto;
to->sin_family = AF_INET;
to->sin_addr.s_addr = inet_addr (target);
/* tady si zjistuji IP adresu pocitace - abych vedel, kam pingnout */
if (to->sin_addr.s_addr == -1) {
struct hostent *hp;
hp = gethostbyname (target);
if (NULL == hp) {
fprintf (stderr,"Neznamy pocitac %s\n",target);
return 0;
}
memcpy (&to->sin_addr, hp->h_addr, hp->h_length);
}
#if defined SVR3 || defined Linux
}
#else
/**************************/
/* Pro ping je provozovan na specialnim protokolu ICMP */
/* cili obchazi TCP i UDP (v /etc/services ho nenajdete) */
if (NULL == (proto = getprotobyname ("icmp"))) {
fprintf (stderr,"Ping: neznamy protokol ICMP\n");
return 0;
}
if (0> (ping_sock = socket (AF_INET, SOCK_RAW, proto->p_proto))) {
fprintf (stderr,"Ping: nejde vytvorit socket: %s\n",strerror(errno));
return 0;
}
hold = 64;
if (0 > setsockopt (ping_sock, SOL_SOCKET, SO_RCVBUF, (char *)&hold, sizeof (hold))) {
fprintf (stderr,"Chyba setsockopt: %s\n",strerror(errno));
return 0;
}
for (i=0; i<10; i++) {
fd_set re;
struct timeval timo;
FD_ZERO (&re);
FD_SET (ping_sock, &re);
timo.tv_sec=1;
timo.tv_usec=0;
pinger (); /* posli na pocitac jeden pinganec */
select (ping_sock+1,&re,NULL,NULL,&timo); /* cekam 1s na odpoved */
/* skutecny ping ceka dele */
/* ja jsem na local net */
if (FD_ISSET(ping_sock,&re)) {
struct icmphdr *icp; /* precteme si, co se vratilo */
cc = recvfrom (ping_sock, packet, paclen, 0, (struct sockaddr *)&from, &fromlen);
if (0> cc) {
fprintf (stderr,"Ping: recvfrom: %s\n",strerror(errno));
}
icp = (struct icmphdr *)packet;
if (cc == 20 && icp->icmp_id==ident && icp->icmp_type==0) {
close (ping_sock);
return 1;
}
}
}
close (ping_sock);
return 0;
}
/******************************************************************************/
void pinger () {
struct icmphdr *icp;
char outpack[1024];
int i;
for (i=0; i<paclen; i++)
outpack[i]=0xFF;
icp = (struct icmphdr *)outpack;
icp->icmp_type = ICMP_ECHO;
icp->icmp_code = 0;
icp->icmp_cksum = 0;
icp->icmp_seq = 0;
icp->icmp_id = ident; /* ID */
i = sendto (ping_sock, icp, paclen, 0, &whereto, sizeof (struct sockaddr) );
if (i!=paclen || i<0) {
fprintf (stderr,"Ping: chyba odeslani paketu: %s\n",strerror(errno));
}
}
#endif
More information about the net
mailing list