diff --git a/reactos/dll/win32/iphlpapi/icmp.c b/reactos/dll/win32/iphlpapi/icmp.c index 63da35d500d..ab0245a2dc4 100644 --- a/reactos/dll/win32/iphlpapi/icmp.c +++ b/reactos/dll/win32/iphlpapi/icmp.c @@ -538,8 +538,23 @@ DWORD WINAPI IcmpSendEcho( return 0; } - if (ReplySize 0) + reqsize += RequestSize; reqbuf=HeapAlloc(GetProcessHeap(), 0, reqsize); if (reqbuf==NULL) { SetLastError(ERROR_OUTOFMEMORY); @@ -577,7 +594,8 @@ DWORD WINAPI IcmpSendEcho( icmp_header->icmp_cksum=0; icmp_header->icmp_id=id; icmp_header->icmp_seq=seq; - memcpy(reqbuf+ICMP_MINLEN, RequestData, RequestSize); + if (RequestData && RequestSize > 0) + memcpy(reqbuf+ICMP_MINLEN, RequestData, RequestSize); icmp_header->icmp_cksum=cksum=in_cksum((u_short*)reqbuf,reqsize); addr.sin_family=AF_INET; @@ -633,9 +651,8 @@ DWORD WINAPI IcmpSendEcho( #endif addrlen=sizeof(addr); ier=ReplyBuffer; - ip_header=(struct ip *) ((char *) ReplyBuffer+sizeof(ICMP_ECHO_REPLY)); - endbuf=(char *) ReplyBuffer+ReplySize; - maxlen=ReplySize-sizeof(ICMP_ECHO_REPLY); + endbuf=((char *) ReplyBuffer)+ReplySize; + maxlen=sizeof(struct ip)+ICMP_MINLEN+RequestSize; /* Send the packet */ TRACE("Sending %d bytes (RequestSize=%d) to %s\n", reqsize, RequestSize, inet_ntoa(addr.sin_addr)); @@ -673,6 +690,7 @@ DWORD WINAPI IcmpSendEcho( } /* Get the reply */ + ip_header=HeapAlloc(GetProcessHeap(), 0, maxlen); ip_header_len=0; /* because gcc was complaining */ #ifdef __REACTOS__ while ((res=select(icp->sid+1,&fdr,NULL,NULL,&timeout))>0) { @@ -683,6 +701,8 @@ DWORD WINAPI IcmpSendEcho( res=recvfrom(icp->sid, (char*)ip_header, maxlen, 0, (struct sockaddr*)&addr,(int*)&addrlen); TRACE("received %d bytes from %s\n",res, inet_ntoa(addr.sin_addr)); ier->Status=IP_REQ_TIMED_OUT; + if (res < 0) + break; /* Check whether we should ignore this packet */ if ((ip_header->ip_p==IPPROTO_ICMP) && (res>=sizeof(struct ip)+ICMP_MINLEN)) { @@ -704,7 +724,7 @@ DWORD WINAPI IcmpSendEcho( case ICMP_UNREACH_ISOLATED: #endif #ifdef ICMP_UNREACH_HOST_PROHIB - case ICMP_UNREACH_HOST_PROHIB: + case ICMP_UNREACH_HOST_PROHIB: #endif #ifdef ICMP_UNREACH_TOSHOST case ICMP_UNREACH_TOSHOST: @@ -744,9 +764,9 @@ DWORD WINAPI IcmpSendEcho( rep_ip_header=(struct ip*)(((char*)icmp_header)+ICMP_MINLEN); rep_icmp_header=(struct icmp*)(((char*)rep_ip_header)+(rep_ip_header->ip_hl << 2)); - /* Make sure that this is really a reply to our packet */ + /* Make sure that this is really a reply to our packet */ if (ip_header_len+ICMP_MINLEN+(rep_ip_header->ip_hl << 2)+ICMP_MINLEN>ip_header->ip_len) { - ier->Status=IP_REQ_TIMED_OUT; + ier->Status=IP_REQ_TIMED_OUT; } else if ((rep_icmp_header->icmp_type!=ICMP_ECHO) || (rep_icmp_header->icmp_code!=0) || (rep_icmp_header->icmp_id!=id) || @@ -762,11 +782,11 @@ DWORD WINAPI IcmpSendEcho( TRACE("expected type,code=8,0 id,seq=%d,%d cksum=%d\n", id,seq, cksum); - ier->Status=IP_REQ_TIMED_OUT; - } + ier->Status=IP_REQ_TIMED_OUT; + } } - } - } + } + } if (ier->Status==IP_REQ_TIMED_OUT) { /* This packet was not for us. @@ -778,6 +798,8 @@ DWORD WINAPI IcmpSendEcho( if (t < 0) t = 0; timeout.tv_sec = t / 1000; timeout.tv_usec = (t % 1000) * 1000; + FD_ZERO(&fdr); + FD_SET(icp->sid, &fdr); #else DWORD t = (recv_time - send_time); if (Timeout > t) Timeout -= t; @@ -809,8 +831,6 @@ DWORD WINAPI IcmpSendEcho( /* Prepare for the next packet */ ier++; - ip_header=(struct ip*)(((char*)ip_header)+sizeof(ICMP_ECHO_REPLY)); - maxlen=endbuf-(char*)ip_header; /* Check out whether there is more but don't wait this time */ #ifdef __REACTOS__ @@ -825,6 +845,7 @@ DWORD WINAPI IcmpSendEcho( FD_SET(icp->sid,&fdr); #endif } + HeapFree(GetProcessHeap(), 0, ip_header); res=ier-(ICMP_ECHO_REPLY*)ReplyBuffer; if (res==0) SetLastError(IP_REQ_TIMED_OUT); diff --git a/reactos/dll/win32/iphlpapi/ip.h b/reactos/dll/win32/iphlpapi/ip.h index 823ac6ab1ae..dc0836e053f 100644 --- a/reactos/dll/win32/iphlpapi/ip.h +++ b/reactos/dll/win32/iphlpapi/ip.h @@ -61,6 +61,16 @@ struct ip { #ifdef _IP_VHL u_char ip_vhl; /* version << 4 | header length >> 2 */ #else +#ifdef __REACTOS__ +#if BYTE_ORDER == LITTLE_ENDIAN + u_char ip_hl : 4, /* header length */ + ip_v : 4; /* version */ +#endif +#if BYTE_ORDER == BIG_ENDIAN + u_char ip_v : 4, /* version */ + ip_hl : 4; /* header length */ +#endif +#else #if BYTE_ORDER == LITTLE_ENDIAN u_int ip_hl:4, /* header length */ ip_v:4; /* version */ @@ -69,6 +79,7 @@ struct ip { u_int ip_v:4, /* version */ ip_hl:4; /* header length */ #endif +#endif /* __REACTOS__ */ #endif /* not _IP_VHL */ u_char ip_tos; /* type of service */ u_short ip_len; /* total length */ @@ -151,6 +162,16 @@ struct ip_timestamp { u_char ipt_code; /* IPOPT_TS */ u_char ipt_len; /* size of structure (variable) */ u_char ipt_ptr; /* index of current entry */ +#ifdef __REACTOS__ +#if BYTE_ORDER == LITTLE_ENDIAN + u_char ipt_flg:4, /* flags, see below */ + ipt_oflw:4; /* overflow counter */ +#endif +#if BYTE_ORDER == BIG_ENDIAN + u_char ipt_oflw:4, /* overflow counter */ + ipt_flg:4; /* flags, see below */ +#endif +#else #if BYTE_ORDER == LITTLE_ENDIAN u_int ipt_flg:4, /* flags, see below */ ipt_oflw:4; /* overflow counter */ @@ -159,6 +180,7 @@ struct ip_timestamp { u_int ipt_oflw:4, /* overflow counter */ ipt_flg:4; /* flags, see below */ #endif +#endif /* __REACTOS__ */ union ipt_timestamp { n_long ipt_time[1]; struct ipt_ta {