static int send_cmd(int fd, RawRequest_t *raw_cmd, int nr, const char *message, int retries) { int j; int ret=-1; if(!nr) return 0; for (j=0; j< retries; j++){ switch(send_one_cmd(fd, raw_cmd, message)) { case -1: return -1; case 1: j++; continue; case 0: break; } if((ret=analyze_reply(raw_cmd, j)) > 0) return ret; /* ok */ } if(j > 1 && j == retries) { fprintf(stderr,"Too many errors, giving up\n"); return 0; } return -1; }
void recv_icmp6(void){ int len,icmplen,datalen; char buf[1024]; char abuf[100]; const char *name; struct sockaddr_in6 from; struct icmp6_hdr *icmp; struct timeval time_recv; struct timeval *time_recvp=NULL; #ifdef HAVE_RECVMSG char ans_data[4096]; struct iovec iov; struct msghdr msg; struct cmsghdr *c; iov.iov_base=buf; iov.iov_len=1000; msg.msg_name=&from; msg.msg_namelen=sizeof(from); msg.msg_iov=&iov; msg.msg_iovlen=1; msg.msg_control=ans_data; msg.msg_controllen=sizeof(ans_data); len=recvmsg(icmp6_sock, &msg, MSG_DONTWAIT); #else socklen_t sl; sl=sizeof(from); len=recvfrom(icmp6_sock,buf,1024,0,(struct sockaddr *)&from,&sl); #endif if (len<0){ if (errno==EAGAIN) return; myperror("recvfrom"); return; } if (len==0) return; #if defined(HAVE_RECVMSG) && defined(SO_TIMESTAMP) debug("checking CMSG..."); for (c = CMSG_FIRSTHDR(&msg); c; c = CMSG_NXTHDR(&msg, c)) { debug("CMSG level: %i type: %i",c->cmsg_level,c->cmsg_type); if (c->cmsg_level != SOL_SOCKET || c->cmsg_type != SO_TIMESTAMP) continue; if (c->cmsg_len < CMSG_LEN(sizeof(struct timeval))) continue; time_recvp = (struct timeval*)CMSG_DATA(c); debug("Got timestamp from CMSG"); } #endif if (time_recvp==NULL){ #ifdef SIOCGSTAMP if (!ioctl(icmp6_sock, SIOCGSTAMP, &time_recv)){ debug("Got timestamp from ioctl()"); }else #endif { gettimeofday(&time_recv,NULL); debug("Got timestamp from gettimeofday()"); } time_recvp=&time_recv; } icmplen=len; icmp=(struct icmp6_hdr *)buf; if (icmp->icmp6_type != ICMP6_ECHO_REPLY) return; if (icmp->icmp6_id != ident) return; name=inet_ntop(AF_INET6,&from.sin6_addr,abuf,100); debug("Ping reply from %s",name); datalen=icmplen-sizeof(*icmp); if (datalen!=sizeof(struct trace_info)){ debug("Packet data truncated."); return; } #ifdef FORKED_RECEIVER pipe_reply(*time_recvp,icmp->icmp6_seq,(struct trace_info*)(icmp+1)); #else analyze_reply(*time_recvp,icmp->icmp6_seq,(struct trace_info*)(icmp+1)); #endif }