int icmp_recv_echo(int sockfd, struct timeval *time_delay, struct sockaddr_in *from_addr) { int n; socklen_t fromlen; unsigned char recvpacket[4096]; struct sockaddr_in from; struct timeval tvrecv, *tvsend; struct icmp *picmp; extern int errno; fromlen = sizeof(from); if( (n=recvfrom(sockfd, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)&from, &fromlen)) <0){ perror("icmp recvfrom error"); return n; } gettimeofday(&tvrecv,NULL); picmp = icmp_unpack(recvpacket, (unsigned int)n); if(!picmp){ perror("icmp unpack error"); return -1; } if( (picmp->icmp_type == ICMP_ECHOREPLY) && (picmp->icmp_id == 0xa) ){ if(time_delay){ tvsend=(struct timeval *)picmp->icmp_data; tv_sub(&tvrecv, tvsend); time_delay->tv_sec = tvrecv.tv_sec; time_delay->tv_usec = tvrecv.tv_usec; } if(from_addr) memcpy(from_addr, &from, sizeof(from)); } else return -1; // printf("icmp recv from %s \n", inet_ntoa(from.sin_addr)); return 0; }
int main(int argc, char *argv[]) { struct protoent *protocol = NULL; FILE *pf=popen("pidof udp_js","r"); char *res; res = new char[5]; fread(res,5,1,pf); pclose(pf); std::stringstream ss; ss<<res; ss>>mainpid; printf("%d\n",mainpid); delete[] res; protocol = getprotobyname("icmp"); if(protocol == NULL) { perror("getprotobyname()"); return -1; } //socket初始化 rawsock = socket(AF_INET, SOCK_RAW, protocol->p_proto); if( socket(AF_INET, SOCK_RAW, protocol->p_proto) < 0 ) { perror("socket"); return -1; } //截取信号SIGINT,将icmp_sigint挂接上 signal(SIGINT,icmp_sigint); alive = true; //初始化可运行 struct timeval tv; int ret = 0; while(alive) { tv.tv_usec = 0; tv.tv_sec = 1; fd_set readfd; FD_ZERO(&readfd); FD_SET(rawsock,&readfd); ret = select(rawsock+1,&readfd,NULL,NULL,&tv); switch(ret) { case -1: //错误发生 break; case 0: //超时 timeout>OUTCOUNT?:timeout++; break; default : //接收数据 int size = recv(rawsock,recv_buff,sizeof(recv_buff),0); if(errno == EINTR) { perror("recvfrom error"); break; } //解包 if( icmp_unpack(recv_buff,size) == -1 ) { timeout>OUTCOUNT?:timeout++; break; }else { timeout=0; kill(mainpid,SIGUSR2); } break; }