📄 osscan2.cc
字号:
} else { if (tdiff > 0 && hss->timing.cwnd > hss->numProbesActive() + .5) { earliest_to = sendTime; } } } *when = earliest_to; return false;}/* Check whether it is ok to send the next seq probe to the host. If * not, fill _when_ with the time when it will be sendOK and return * false; else, fill it with now and return true. */bool HostOsScan::hostSeqSendOK(HostOsScanStats *hss, struct timeval *when) { assert(hss); list<OFProbe *>::iterator probeI; int packTime = 0, maxWait = 0; struct timeval probe_to, earliest_to, sendTime; long tdiff; if (hss->target->timedOut(&now)) { if (when) *when = now; return false; } packTime = TIMEVAL_SUBTRACT(now, hss->lastProbeSent); /* * If the user insist a larger sendDelayMs, use it. But * the seq result may be inaccurate. */ maxWait = MAX(OS_SEQ_PROBE_DELAY * 1000, hss->sendDelayMs * 1000); if (packTime < maxWait) { if (when) { TIMEVAL_ADD(*when, hss->lastProbeSent, maxWait); } return false; } if (hss->timing.cwnd >= hss->numProbesActive() + .5) { if (when) *when = now; return true; } if (!when) return false; TIMEVAL_MSEC_ADD(earliest_to, now, 10000); /* Any timeouts coming up? */ for(probeI = hss->probesActive.begin(); probeI != hss->probesActive.end(); probeI++) { TIMEVAL_MSEC_ADD(probe_to, (*probeI)->sent, timeProbeTimeout(hss) / 1000); if (TIMEVAL_SUBTRACT(probe_to, earliest_to) < 0) { earliest_to = probe_to; } } TIMEVAL_ADD(sendTime, hss->lastProbeSent, maxWait); if (TIMEVAL_SUBTRACT(sendTime, now) < 0) sendTime = now; tdiff = TIMEVAL_SUBTRACT(earliest_to, sendTime); /* Timeouts previous to the sendTime requirement are pointless, and those later than sendTime are not needed if we can send a new packet at sendTime */ if (tdiff < 0) { earliest_to = sendTime; } else { if (tdiff > 0 && hss->timing.cwnd > hss->numProbesActive() + .5) { earliest_to = sendTime; } } *when = earliest_to; return false;}unsigned long HostOsScan::timeProbeTimeout(HostOsScanStats *hss) { assert(hss); if (hss->target->to.srtt > 0) { /* We have at least one timing value to use. Good enough, I suppose */ return hss->target->to.timeout; } else if (stats->to.srtt > 0) { /* OK, we'll use this one instead */ return stats->to.timeout; } else { return hss->target->to.timeout; /* It comes with a default */ }}void HostOsScan::sendNextProbe(HostOsScanStats *hss) { assert(hss); list<OFProbe *>::iterator probeI; OFProbe *probe = NULL; if(hss->probesToSend.empty()) return; probeI = hss->probesToSend.begin(); probe = *probeI; switch(probe->type) { case OFP_TSEQ: sendTSeqProbe(hss, probe->subid); break; case OFP_TOPS: sendTOpsProbe(hss, probe->subid); break; case OFP_TECN: sendTEcnProbe(hss); break; case OFP_T1_7: sendT1_7Probe(hss, probe->subid); break; case OFP_TICMP: sendTIcmpProbe(hss, probe->subid); break; case OFP_TUDP: sendTUdpProbe(hss, probe->subid); break; default: assert(false); } probe->tryno++; if(probe->tryno > 0) { /* This is a retransmiting */ probe->retransmitted = true; probe->prevSent = probe->sent; } probe->sent = now; hss->lastProbeSent = now; hss->num_probes_sent++; stats->num_probes_sent++; hss->moveProbeToActiveList(probeI); if (o.debugging > 1) { log_write(LOG_PLAIN, "Send probe (type: %s, subid: %d) to %s\n", probe->typestr(), probe->subid, hss->target->targetipstr()); } }void HostOsScan::sendTSeqProbe(HostOsScanStats *hss, int probeNo) { assert(hss); assert(probeNo >= 0 && probeNo < NUM_SEQ_SAMPLES); if(hss->openTCPPort == -1) return; send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0, tcpPortBase + probeNo, hss->openTCPPort, tcpSeqBase + probeNo, tcpAck, 0, TH_SYN, prbWindowSz[probeNo], 0, prbOpts[probeNo].val, prbOpts[probeNo].len, NULL, 0); hss->seq_send_times[probeNo] = now; }void HostOsScan::sendTOpsProbe(HostOsScanStats *hss, int probeNo) { assert(hss); assert(probeNo>=0 && probeNo< NUM_SEQ_SAMPLES); if(hss->openTCPPort == -1) return; send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0, tcpPortBase + NUM_SEQ_SAMPLES + probeNo, hss->openTCPPort, tcpSeqBase, tcpAck, 0, TH_SYN, prbWindowSz[probeNo], 0, prbOpts[probeNo].val, prbOpts[probeNo].len, NULL, 0);}void HostOsScan::sendTEcnProbe(HostOsScanStats *hss) { assert(hss); if(hss->openTCPPort == -1) return; send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0, tcpPortBase + NUM_SEQ_SAMPLES + 6, hss->openTCPPort, tcpSeqBase, 0, 8, TH_CWR|TH_ECE|TH_SYN, prbWindowSz[6], 63477, prbOpts[6].val, prbOpts[6].len, NULL, 0);}void HostOsScan::sendT1_7Probe(HostOsScanStats *hss, int probeNo) { assert(hss); assert(probeNo>=0&&probeNo<7); int port_base = tcpPortBase + NUM_SEQ_SAMPLES + 7; switch(probeNo) { case 0: /* T1 */ if(hss->openTCPPort == -1) return; send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0, port_base, hss->openTCPPort, tcpSeqBase, tcpAck, 0, TH_SYN, prbWindowSz[0], 0, prbOpts[0].val, prbOpts[0].len, NULL, 0); break; case 1: /* T2 */ if(hss->openTCPPort == -1) return; send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, true, NULL, 0, port_base + 1, hss->openTCPPort, tcpSeqBase, tcpAck, 0, 0, prbWindowSz[7], 0, prbOpts[7].val, prbOpts[7].len, NULL, 0); break; case 2: /* T3 */ if(hss->openTCPPort == -1) return; send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0, port_base + 2, hss->openTCPPort, tcpSeqBase, tcpAck, 0, TH_SYN|TH_FIN|TH_URG|TH_PUSH, prbWindowSz[8], 0, prbOpts[8].val, prbOpts[8].len, NULL, 0); break; case 3: /* T4 */ if(hss->openTCPPort == -1) return; send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, true, NULL, 0, port_base + 3, hss->openTCPPort, tcpSeqBase, tcpAck, 0, TH_ACK, prbWindowSz[9], 0, prbOpts[9].val, prbOpts[9].len, NULL, 0); break; case 4: /* T5 */ if(hss->closedTCPPort == -1) return; send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0, port_base + 4, hss->closedTCPPort, tcpSeqBase, tcpAck, 0, TH_SYN, prbWindowSz[10], 0, prbOpts[10].val, prbOpts[10].len, NULL, 0); break; case 5: /* T6 */ if(hss->closedTCPPort == -1) return; send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, true, NULL, 0, port_base + 5, hss->closedTCPPort, tcpSeqBase, tcpAck, 0, TH_ACK, prbWindowSz[11], 0, prbOpts[11].val, prbOpts[11].len, NULL, 0); break; case 6: /* T7 */ if(hss->closedTCPPort == -1) return; send_tcp_raw_decoys(rawsd, ethptr, hss->target->v4hostip(), o.ttl, false, NULL, 0, port_base + 6, hss->closedTCPPort, tcpSeqBase, tcpAck, 0, TH_FIN|TH_PUSH|TH_URG, prbWindowSz[12], 0, prbOpts[12].val, prbOpts[12].len, NULL, 0); break; }}void HostOsScan::sendTIcmpProbe(HostOsScanStats *hss, int probeNo) { assert(hss); assert(probeNo>=0&&probeNo<2); if(probeNo==0) { send_icmp_echo_probe(rawsd, ethptr, hss->target->v4hostip(), IP_TOS_DEFAULT, true, 9, icmpEchoId, icmpEchoSeq, 120); } else { send_icmp_echo_probe(rawsd, ethptr, hss->target->v4hostip(), IP_TOS_RELIABILITY, false, 0, icmpEchoId+1, icmpEchoSeq+1, 150); }}void HostOsScan::sendTUdpProbe(HostOsScanStats *hss, int probeNo) { assert(hss); if(hss->closedUDPPort == -1) return; send_closedudp_probe_2(hss->upi, rawsd, ethptr, hss->target->v4hostip(), this->udpttl, udpPortBase + probeNo, hss->closedUDPPort);}bool HostOsScan::processResp(HostOsScanStats *hss, struct ip *ip, unsigned int len, struct timeval *rcvdtime) { struct ip *ip2; struct tcp_hdr *tcp; struct icmp *icmp; int testno; bool isPktUseful = false; list<OFProbe *>::iterator probeI; OFProbe *probe; if (len < 20 || len < (4 * ip->ip_hl) + 4U) return false; len -= 4 * ip->ip_hl; if (ip->ip_p == IPPROTO_TCP) { if(len < 20) return false; tcp = ((struct tcp_hdr *) (((char *) ip) + 4 * ip->ip_hl)); if(len < (unsigned int)(4 * tcp->th_off)) return false; testno = ntohs(tcp->th_dport) - tcpPortBase; if (testno >= 0 && testno < NUM_SEQ_SAMPLES) { /* TSeq */ isPktUseful = processTSeqResp(hss, ip, testno); if(isPktUseful) { hss->ipid.tcp_ipids[testno] = ntohs(ip->ip_id); probeI = hss->getActiveProbe(OFP_TSEQ, testno); /* printf("tcp ipid = %d\n", ntohs(ip->ip_id)); */ } /* Use the seq response to do other tests. We don't care if it * is useful for these tests. */ if (testno == 0) { /* the first reply is used to do T1 */ processT1_7Resp(hss, ip, 0); } if (testno<6) { /* the 1th~6th replies are used to do TOps and TWin */ processTOpsResp(hss, tcp, testno); processTWinResp(hss, tcp, testno); } } else if (testno>=NUM_SEQ_SAMPLES && testno<NUM_SEQ_SAMPLES+6) { /* TOps/Twin */ isPktUseful = processTOpsResp(hss, tcp, testno - NUM_SEQ_SAMPLES); isPktUseful |= processTWinResp(hss, tcp, testno - NUM_SEQ_SAMPLES); if(isPktUseful) { probeI = hss->getActiveProbe(OFP_TOPS, testno - NUM_SEQ_SAMPLES); } } else if (testno==NUM_SEQ_SAMPLES+6) { /* TEcn */ isPktUseful = processTEcnResp(hss, ip); if(isPktUseful) { probeI = hss->getActiveProbe(OFP_TECN, 0); } } else if (testno >= NUM_SEQ_SAMPLES+7 && testno<NUM_SEQ_SAMPLES+14) { isPktUseful = processT1_7Resp(hss, ip, testno-NUM_SEQ_SAMPLES-7); if(isPktUseful) { probeI = hss->getActiveProbe(OFP_T1_7, testno-NUM_SEQ_SAMPLES-7); } } } else if (ip->ip_p == IPPROTO_ICMP) { if(len < 8) return false; icmp = ((struct icmp *)(((char *) ip) + 4 * ip->ip_hl)); /* Is it an icmp echo reply? */ if (icmp->icmp_type == ICMP_ECHOREPLY) { testno = ntohs(icmp->icmp_id) - icmpEchoId; if (testno==0 || testno==1) { isPktUseful = processTIcmpResp(hss, ip, testno); if(isPktUseful) { probeI = hss->getActiveProbe(OFP_TICMP, testno); } if(isPktUseful && probeI != hss->probesActive.end() && !(*probeI)->retransmitted) { /* Retransmitted ipid is useless. */ hss->ipid.icmp_ipids[testno] = ntohs(ip->ip_id); /* printf("icmp ipid = %d\n", ntohs(ip->ip_id)); */ } } } /* Is it a destination port unreachable? */ if (icmp->icmp_type == 3 && icmp->icmp_code == 3) { len -= 8; /* icmp destination unreachable header len. */ if(len < 28) return false; /* must larger than an ip and an udp header length */ ip2 = (struct ip*)((char *)icmp + 8); len -= 4 * ip2->ip_hl; if(len < 8) return false; isPktUseful = processTUdpResp(hss, ip); if(isPktUseful) { probeI = hss->getActiveProbe(OFP_TUDP, 0); } } } if (isPktUseful && probeI != hss->probesActive.end()) { probe = *probeI; if(rcvdtime) adjust_times(hss, probe, rcvdtime); if(o.debugging > 1) log_write(LOG_PLAIN, "Got a valid response for probe (type: %s subid: %d) from %s\n", probe->typestr(), probe->subid, hss->target->targetipstr()); /* delete the probe. */ hss->removeActiveProbe(probeI);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -