diff --git a/osscan2.cc b/osscan2.cc index a5ef75da2..8891f2d24 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -1015,8 +1015,6 @@ HostOsScanStats::HostOsScanStats(Target * t) { TWin_AVs[i] = NULL; } - icmpEchoReply = NULL; - distance = -1; distance_guess = -1; } @@ -1041,8 +1039,6 @@ HostOsScanStats::~HostOsScanStats() { delete probesActive.front(); probesActive.pop_front(); } - - if (icmpEchoReply) free(icmpEchoReply); } @@ -1165,12 +1161,6 @@ void HostOsScanStats::initScanStats() { memset(&seq_send_times, 0, sizeof(seq_send_times)); - if (icmpEchoReply) { - free(icmpEchoReply); - icmpEchoReply = NULL; - } - storedIcmpReply = -1; - memset(&upi, 0, sizeof(upi)); } @@ -1982,13 +1972,9 @@ bool HostOsScan::processResp(HostOsScanStats *hss, const u8 *pkt, unsigned int l /* Is it an icmp echo reply? */ if (icmp.icmp_type == ICMP_ECHOREPLY) { - if (len + iphlen < ntohs(ip.ip_len)) { - /* processTIcmpResp requires ip.ip_len bytes of actual packet */ - return false; - } testno = ntohs(icmp.icmp_id) - icmpEchoId; if (testno == 0 || testno == 1) { - isPktUseful = processTIcmpResp(hss, &ip, pkt, testno); + isPktUseful = processTIcmpResp(hss, &ip, &icmp, testno); if (isPktUseful) { probeI = hss->getActiveProbe(OFP_TICMP, testno); } @@ -3037,53 +3023,27 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, const struct ip *ip, cons } -bool HostOsScan::processTIcmpResp(HostOsScanStats *hss, const struct ip *ip, const u8 *pkt, int replyNo) { +bool HostOsScan::processTIcmpResp(HostOsScanStats *hss, const struct ip *ip, const struct icmp *icmp, int replyNo) { assert(replyNo == 0 || replyNo == 1); - unsigned short value1, value2; - if (hss->FP_TIcmp) return false; - u16 iplen = ntohs(ip->ip_len); - if (hss->icmpEchoReply == NULL) { - /* This is the first icmp reply we get, store it and return. */ - hss->icmpEchoReply = (u8 *) safe_malloc(iplen); - memcpy(hss->icmpEchoReply, pkt, iplen); - hss->storedIcmpReply = replyNo; - return true; - } else if (hss->storedIcmpReply == replyNo) { + if (hss->icmpEchoReply[replyNo].received) { /* This is a duplicated icmp reply. */ return false; } - - const struct ip *ip1, *ip2; - const u8 *ip1pkt, *ip2pkt; - struct ip tmp; - /* Ok, now we get another reply. */ - if (hss->storedIcmpReply == 0) { - ip1pkt = hss->icmpEchoReply; - memcpy(&tmp, ip1pkt, sizeof(tmp)); - ip1 = &tmp; - - ip2pkt = pkt; - ip2 = ip; - } else { - ip2pkt = hss->icmpEchoReply; - memcpy(&tmp, ip2pkt, sizeof(tmp)); - ip2 = &tmp; - - ip1pkt = pkt; - ip1 = ip; + else { + hss->icmpEchoReply[replyNo].received = true; + hss->icmpEchoReply[replyNo].ip_off = ip->ip_off; + hss->icmpEchoReply[replyNo].icmp_code = icmp->icmp_code; } + HostOsScanStats::icmpEchoReply_t &reply1 = hss->icmpEchoReply[0]; + HostOsScanStats::icmpEchoReply_t &reply2 = hss->icmpEchoReply[1]; - struct icmp icmp1, icmp2; - iplen = ntohs(ip1->ip_len); - memcpy(&icmp1, ip1pkt + 4 * ip1->ip_hl, MIN(iplen, sizeof(icmp1))); - iplen = ntohs(ip2->ip_len); - memcpy(&icmp2, ip2pkt + 4 * ip2->ip_hl, MIN(iplen, sizeof(icmp2))); - - assert(icmp1.icmp_type == 0 && icmp2.icmp_type == 0); + if (!reply1.received || !reply2.received) { + return true; + } hss->FP_TIcmp= new FingerTest(FingerPrintDef::IE, *o.reference_FPs->MatchPoints); FingerTest &test = *hss->FP_TIcmp; @@ -3096,8 +3056,8 @@ bool HostOsScan::processTIcmpResp(HostOsScanStats *hss, const struct ip *ip, con * N. Both not set; * O. Other(both different with the sender, -_-b). */ - value1 = (ntohs(ip1->ip_off) & IP_DF); - value2 = (ntohs(ip2->ip_off) & IP_DF); + u16 value1 = (ntohs(reply1.ip_off) & IP_DF); + u16 value2 = (ntohs(reply2.ip_off) & IP_DF); if (value1 && value2) /* both set */ test.setAVal("DFI", "Y"); @@ -3112,15 +3072,15 @@ bool HostOsScan::processTIcmpResp(HostOsScanStats *hss, const struct ip *ip, con /* TTL */ - test.setAVal("T", hss->target->FPR->cp_hex(ip1->ip_ttl)); + test.setAVal("T", hss->target->FPR->cp_hex(ip->ip_ttl)); /* ICMP Code value. Test values: * [Value]. Both set Code to the same value [Value]; * S. Both use the Code that the sender uses; * O. Other. */ - value1 = icmp1.icmp_code; - value2 = icmp2.icmp_code; + value1 = reply1.icmp_code; + value2 = reply2.icmp_code; if (value1 == value2) { if (value1 == 0) test.setAVal("CD", "Z"); diff --git a/osscan2.h b/osscan2.h index bfb19bb35..53e5fa2c6 100644 --- a/osscan2.h +++ b/osscan2.h @@ -319,8 +319,13 @@ class HostOsScanStats { int TWinReplyNum; /* how many TWin replies are received. */ int TOpsReplyNum; /* how many TOps replies are received. Actually it is the same with TOpsReplyNum. */ - u8 *icmpEchoReply; /* To store one of the two icmp replies */ - int storedIcmpReply; /* Which one of the two icmp replies is stored? */ + struct icmpEchoReply_t { + bool received; + u16 ip_off; + u8 icmp_code; + icmpEchoReply_t() : received(false), ip_off(0), icmp_code(0) {} + }; + icmpEchoReply_t icmpEchoReply[2]; /* To store the two icmp replies */ struct udpprobeinfo upi; /* info of the udp probe we sent */ }; @@ -410,7 +415,7 @@ private: bool processT1_7Resp(HostOsScanStats *hss, const struct ip *ip, const struct tcp_hdr *tcp, const u8 *tcppkt, int tcplen, int replyNo); bool processTUdpResp(HostOsScanStats *hss, const u8 *ip); bool processTUdpResp(HostOsScanStats *hss, const struct ip *ip, const struct icmp *icmp, const u8 *icmppkt, unsigned int icmplen); - bool processTIcmpResp(HostOsScanStats *hss, const struct ip *ip, const u8 *pkt, int replyNo); + bool processTIcmpResp(HostOsScanStats *hss, const struct ip *ip, const struct icmp *icmp, int replyNo); /* Generic sending functions used by the above probe functions. */ int send_tcp_probe(HostOsScanStats *hss,