diff --git a/CHANGELOG b/CHANGELOG index df733a317..1b4c2572f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ # Nmap Changelog ($Id$); -*-text-*- +o Added support for decoys in IPv6. Earlier we supported decoys only in + IPv4. [Abhishek Singh] + o Nmap now supports OpenSSL 1.1.0-pre5 and previous versions. [Vincent Dumont] o [Ncat] Fix a crash ("add_fdinfo() failed.") when --exec was used with --ssl diff --git a/FPEngine.cc b/FPEngine.cc index 72fcb6fd8..39b7a4296 100644 --- a/FPEngine.cc +++ b/FPEngine.cc @@ -456,6 +456,7 @@ void FPNetworkControl::probe_transmission_handler(nsock_pool nsp, nsock_event ns FPProbe *myprobe = (FPProbe *)arg; u8 *buf; size_t len; + int result = true; if (status == NSE_STATUS_SUCCESS) { switch(type) { @@ -470,17 +471,33 @@ void FPNetworkControl::probe_transmission_handler(nsock_pool nsp, nsock_event ns this->first_pcap_scheduled = true; } - buf = myprobe->getPacketBuffer(&len); /* Send the packet*/ - assert(myprobe->host != NULL); - if (send_ip_packet(this->rawsd, myprobe->getEthernet(), myprobe->host->getTargetAddress(), buf, len) == -1) { - myprobe->setFailed(); - this->cc_report_final_timeout(); - myprobe->host->fail_one_probe(); - gh_perror("Unable to send packet in %s", __func__); + for (int decoy = 0; decoy < o.numdecoys; decoy++) { + /* We don't need to change address if decoys aren't specified */ + if (o.numdecoys > 1) { + result = myprobe->changeSourceAddress(&((struct sockaddr_in6 *)&o.decoys[decoy])->sin6_addr) == OP_SUCCESS; + } + /* Decoys have to be sent only if changeSourceAddress worked */ + if (result) { + assert(myprobe->host != NULL); + buf = myprobe->getPacketBuffer(&len); + if (send_ip_packet(this->rawsd, myprobe->getEthernet(), myprobe->host->getTargetAddress(), buf, len) == -1) { + if (decoy == o.decoyturn) { + myprobe->setFailed(); + this->cc_report_final_timeout(); + myprobe->host->fail_one_probe(); + gh_perror("Unable to send packet in %s", __func__); + } + } + free(buf); + } } + /* Reset the address to the original one if decoys were present and original Address wasn't last one */ + if ( o.numdecoys != o.decoyturn+1 ) + result = myprobe->changeSourceAddress(&((struct sockaddr_in6 *)&o.decoys[o.decoyturn])->sin6_addr) == OP_SUCCESS; + assert(result == true); + myprobe->setTimeSent(); - free(buf); break; default: @@ -754,7 +771,7 @@ void FPHost6::fill_FPR(FingerPrintResultsIPv6 *FPR) { FPR->incomplete = this->incomplete_fp; } -static const IPv6Header *find_ipv6(const PacketElement *pe) { +static IPv6Header *find_ipv6(const PacketElement *pe) { while (pe != NULL && pe->protocol_id() != HEADER_TYPE_IPv6) pe = pe->getNextElement(); @@ -1744,7 +1761,7 @@ int FPHost6::build_probe_list() { RoutingHeader *routing; HopByHopHeader *hopbyhop1, *hopbyhop2; RawData *payload; - unsigned int i; + int i; char payloadbuf[300]; assert(this->target_host != NULL); @@ -2736,6 +2753,17 @@ int FPProbe::setTimed() { return OP_SUCCESS; } +/* Changes source address for packet element associated with current FPProbe. */ +int FPProbe::changeSourceAddress(struct in6_addr *addr) { + if (!is_set()) + return OP_FAILURE; + else{ + IPv6Header *ip6 = find_ipv6(getPacket()); + if (ip6 != NULL) + return ip6->setSourceAddress(*addr); + } + return OP_FAILURE; +} /****************************************************************************** * Implementation of class FPResponse. * diff --git a/FPEngine.h b/FPEngine.h index 2fe8e6405..1c34f412b 100644 --- a/FPEngine.h +++ b/FPEngine.h @@ -353,6 +353,7 @@ class FPProbe : public FPPacket { int setFailed(); bool isTimed() const; int setTimed(); + int changeSourceAddress(struct in6_addr *addr); }; diff --git a/NmapOps.cc b/NmapOps.cc index 5a62e6d6f..20a15e2f8 100644 --- a/NmapOps.cc +++ b/NmapOps.cc @@ -570,8 +570,8 @@ dialog where you can start NPF if you have administrator privileges."; fatal("--min-rate=%g must be less than or equal to --max-rate=%g", min_packet_send_rate, max_packet_send_rate); } - if (af() == AF_INET6 && (generate_random_ips|numdecoys|bouncescan|fragscan)) { - fatal("Random targets, decoys, FTP bounce scan, and fragmentation are not supported with IPv6."); + if (af() == AF_INET6 && (generate_random_ips|bouncescan|fragscan)) { + fatal("Random targets, FTP bounce scan, and fragmentation are not supported with IPv6."); } if(ipoptions && osscan) diff --git a/NmapOps.h b/NmapOps.h index 664b9c34a..b65481e12 100644 --- a/NmapOps.h +++ b/NmapOps.h @@ -313,7 +313,7 @@ class NmapOps { int override_excludeports; int version_intensity; - struct in_addr decoys[MAX_DECOYS]; + struct sockaddr_storage decoys[MAX_DECOYS]; int osscan_limit; /* Skip OS Scan if no open or no closed TCP ports */ int osscan_guess; /* Be more aggressive in guessing OS type */ int numdecoys; diff --git a/Target.cc b/Target.cc index 63981a9e6..aba045188 100644 --- a/Target.cc +++ b/Target.cc @@ -353,12 +353,8 @@ void Target::setSourceSockAddr(const struct sockaddr_storage *ss, size_t ss_len) } // Returns IPv4 host address or {0} if unavailable. -struct in_addr Target::v4source() const { - const struct in_addr *addy = v4sourceip(); - struct in_addr in; - if (addy) return *addy; - in.s_addr = 0; - return in; +struct sockaddr_storage Target::source() const { + return sourcesock; } // Returns IPv4 host address or NULL if unavailable. diff --git a/Target.h b/Target.h index 08fb15049..39a0cc8f8 100644 --- a/Target.h +++ b/Target.h @@ -205,7 +205,7 @@ class Target { /* Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted to sockaddr_storage */ void setSourceSockAddr(const struct sockaddr_storage *ss, size_t ss_len); - struct in_addr v4source() const; + struct sockaddr_storage source() const; const struct in_addr *v4sourceip() const; const struct in6_addr *v6sourceip() const; /* The IPv4 or IPv6 literal string for the target host */ diff --git a/docs/refguide.xml b/docs/refguide.xml index 85d0720fd..9fba28c58 100644 --- a/docs/refguide.xml +++ b/docs/refguide.xml @@ -3205,7 +3205,7 @@ services. which host is scanning if only one is actually up on the network. You might want to use IP addresses instead of names (so the decoy networks don't see you in their nameserver - logs). + logs). Right now random IP address generation is only supported with IPv4 Decoys are used both in the initial ping scan (using ICMP, SYN, ACK, or whatever) and during the actual port diff --git a/nmap.cc b/nmap.cc index 245713e65..4f57e0609 100644 --- a/nmap.cc +++ b/nmap.cc @@ -501,6 +501,7 @@ public: this->pre_host_timeout = -1; this->iflist = false; this->af = AF_UNSPEC; + this->decoys = false; } // Pre-specified timing parameters. @@ -512,9 +513,9 @@ public: int pre_max_retries; long pre_host_timeout; char *machinefilename, *kiddiefilename, *normalfilename, *xmlfilename; - bool iflist; + bool iflist, decoys; char *exclude_spec, *exclude_file; - char *spoofSource; + char *spoofSource, *decoy_arguments; const char *spoofmac; int af; std::vector verbose_out; @@ -540,7 +541,7 @@ static void test_file_name(const char *filename, const char *option) { } void parse_options(int argc, char **argv) { - char *p, *q; + char *p; int arg; long l; double d; @@ -1065,52 +1066,7 @@ void parse_options(int argc, char **argv) { } break; case 'D': - p = optarg; - do { - q = strchr(p, ','); - if (q) - *q = '\0'; - if (!strcasecmp(p, "me")) { - if (o.decoyturn != -1) - fatal("Can only use 'ME' as a decoy once.\n"); - o.decoyturn = o.numdecoys++; - } else if (!strcasecmp(p, "rnd") || !strncasecmp(p, "rnd:", 4)) { - int i = 1; - - /* 'rnd:' is allowed and just gives them one */ - if (strlen(p) > 4) - i = atoi(&p[4]); - - if (i < 1) - fatal("Bad 'rnd' decoy \"%s\"", p); - - if (o.numdecoys + i >= MAX_DECOYS - 1) - fatal("You are only allowed %d decoys (if you need more redefine MAX_DECOYS in nmap.h)", MAX_DECOYS); - - while (i--) { - do { - o.decoys[o.numdecoys].s_addr = get_random_u32(); - } while (ip_is_reserved(&o.decoys[o.numdecoys])); - o.numdecoys++; - } - } else { - if (o.numdecoys >= MAX_DECOYS - 1) - fatal("You are only allowed %d decoys (if you need more redefine MAX_DECOYS in nmap.h)", MAX_DECOYS); - - /* Try to resolve it */ - struct sockaddr_in decoytemp; - size_t decoytemplen = sizeof(struct sockaddr_in); - int rc = resolve(p, 0, (sockaddr_storage*)&decoytemp, &decoytemplen, AF_INET); - if (rc != 0) - fatal("Failed to resolve decoy host \"%s\": %s", p, gai_strerror(rc)); - o.decoys[o.numdecoys] = decoytemp.sin_addr; - o.numdecoys++; - } - if (q) { - *q = ','; - p = q + 1; - } - } while (q); + delayed_options.decoy_arguments = optarg; break; case 'd': if (optarg && isdigit(optarg[0])) { @@ -1690,14 +1646,6 @@ void apply_delayed_options() { error("WARNING: a IP Protocol ping scan was requested, but after excluding requested protocols, none remain. Skipping this scan type."); - /* Set up our array of decoys! */ - if (o.decoyturn == -1) { - o.decoyturn = (o.numdecoys == 0) ? 0 : get_random_uint() % o.numdecoys; - o.numdecoys++; - for (i = o.numdecoys - 1; i > o.decoyturn; i--) - o.decoys[i] = o.decoys[i - 1]; - } - /* We need to find what interface to route through if: * --None have been specified AND * --We are root and doing tcp ping OR @@ -1725,6 +1673,68 @@ void apply_delayed_options() { } o.exclude_spec = delayed_options.exclude_spec; + if (delayed_options.decoy_arguments) { + char *p = delayed_options.decoy_arguments, *q; + do { + q = strchr(p, ','); + if (q) + *q = '\0'; + if (!strcasecmp(p, "me")) { + if (o.decoyturn != -1) + fatal("Can only use 'ME' as a decoy once.\n"); + o.decoyturn = o.numdecoys++; + } else if (!strcasecmp(p, "rnd") || !strncasecmp(p, "rnd:", 4)) { + if (delayed_options.af == AF_INET6) + fatal("Random decoys can only be used with IPv4"); + int i = 1; + + /* 'rnd:' is allowed and just gives them one */ + if (strlen(p) > 4) + i = atoi(&p[4]); + + if (i < 1) + fatal("Bad 'rnd' decoy \"%s\"", p); + + if (o.numdecoys + i >= MAX_DECOYS - 1) + fatal("You are only allowed %d decoys (if you need more redefine MAX_DECOYS in nmap.h)", MAX_DECOYS); + + while (i--) { + do { + ((struct sockaddr_in *)&o.decoys[o.numdecoys])->sin_addr.s_addr = get_random_u32(); + } while (ip_is_reserved(&((struct sockaddr_in *)&o.decoys[o.numdecoys])->sin_addr)); + o.numdecoys++; + } + } else { + if (o.numdecoys >= MAX_DECOYS - 1) + fatal("You are only allowed %d decoys (if you need more redefine MAX_DECOYS in nmap.h)", MAX_DECOYS); + + /* Try to resolve it */ + struct sockaddr_storage decoytemp; + size_t decoytemplen = sizeof(struct sockaddr_storage); + int rc; + if (delayed_options.af == AF_INET6){ + rc = resolve(p, 0, (sockaddr_storage*)&decoytemp, &decoytemplen, AF_INET6); + } + else + rc = resolve(p, 0, (sockaddr_storage*)&decoytemp, &decoytemplen, AF_INET); + if (rc != 0) + fatal("Failed to resolve decoy host \"%s\": %s", p, gai_strerror(rc)); + o.decoys[o.numdecoys] = decoytemp; + o.numdecoys++; + } + if (q) { + *q = ','; + p = q + 1; + } + } while (q); + } + /* Set up host address also in array of decoys! */ + if (o.decoyturn == -1) { + o.decoyturn = (o.numdecoys == 0) ? 0 : get_random_uint() % o.numdecoys; + o.numdecoys++; + for (i = o.numdecoys - 1; i > o.decoyturn; i--) + o.decoys[i] = o.decoys[i - 1]; + } } int nmap_main(int argc, char *argv[]) { @@ -2061,7 +2071,7 @@ int nmap_main(int argc, char *argv[]) { o.numhosts_up--; break; } - o.decoys[o.decoyturn] = currenths->v4source(); + o.decoys[o.decoyturn] = currenths->source(); } Targets.push_back(currenths); } @@ -2074,8 +2084,8 @@ int nmap_main(int argc, char *argv[]) { // Our source must be set in decoy list because nexthost() call can // change it (that issue really should be fixed when possible) - if (o.af() == AF_INET && o.RawScan()) - o.decoys[o.decoyturn] = Targets[0]->v4source(); + if (o.RawScan()) + o.decoys[o.decoyturn] = Targets[0]->source(); /* I now have the group for scanning in the Targets vector */ diff --git a/osscan2.cc b/osscan2.cc index 6fb97e662..3b3a6e4f3 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -494,20 +494,23 @@ static void begin_sniffer(HostOsScan *HOS, std::vector &Targets) { if (HOS->pd == NULL) fatal("%s", PCAP_OPEN_ERRMSG); + struct sockaddr_storage ss = Targets[0]->source(); /* Build the final BPF filter */ - if (doIndividual) - len = Snprintf(pcap_filter, sizeof(pcap_filter), "dst host %s and (icmp or (tcp and (%s", - inet_ntoa(Targets[0]->v4source()), dst_hosts); - else - len = Snprintf(pcap_filter, sizeof(pcap_filter), "dst host %s and (icmp or tcp)", - inet_ntoa(Targets[0]->v4source())); - if (len < 0 || len >= (int) sizeof(pcap_filter)) - fatal("ran out of space in pcap filter"); + if (ss.ss_family == AF_INET) { + if (doIndividual) + len = Snprintf(pcap_filter, sizeof(pcap_filter), "dst host %s and (icmp or (tcp and (%s", + inet_ntoa(((struct sockaddr_in *)&ss)->sin_addr), dst_hosts); + else + len = Snprintf(pcap_filter, sizeof(pcap_filter), "dst host %s and (icmp or tcp)", + inet_ntoa(((struct sockaddr_in *)&ss)->sin_addr)); + if (len < 0 || len >= (int) sizeof(pcap_filter)) + fatal("ran out of space in pcap filter"); - /* Compile and apply the filter to the pcap descriptor */ - if (o.debugging) - log_write(LOG_PLAIN, "Packet capture filter (device %s): %s\n", Targets[0]->deviceFullName(), pcap_filter); - set_pcap_filter(Targets[0]->deviceFullName(), HOS->pd, pcap_filter); + /* Compile and apply the filter to the pcap descriptor */ + if (o.debugging) + log_write(LOG_PLAIN, "Packet capture filter (device %s): %s\n", Targets[0]->deviceFullName(), pcap_filter); + set_pcap_filter(Targets[0]->deviceFullName(), HOS->pd, pcap_filter); + } return; } @@ -2192,7 +2195,7 @@ int HostOsScan::send_icmp_echo_probe(HostOsScanStats *hss, ethptr = hss->fill_eth_nfo(ð, ethsd); for (decoy = 0; decoy < o.numdecoys; decoy++) { - packet = build_icmp_raw(&o.decoys[decoy], hss->target->v4hostip(), + packet = build_icmp_raw(&((struct sockaddr_in *)&o.decoys[decoy])->sin_addr, hss->target->v4hostip(), o.ttl, get_random_u16(), tos, df, NULL, 0, seq, id, ICMP_ECHO, pcode, NULL, datalen, &packetlen); if (!packet) @@ -2245,7 +2248,9 @@ int HostOsScan::send_closedudp_probe(HostOsScanStats *hss, } for (decoy = 0; decoy < o.numdecoys; decoy++) { - source = &o.decoys[decoy]; + if (o.decoys[decoy].ss_family == AF_INET6) + return 1; + source = &((struct sockaddr_in *)&o.decoys[decoy])->sin_addr; memset((char *) packet, 0, sizeof(struct ip) + sizeof(struct udp_hdr)); diff --git a/scan_engine_raw.cc b/scan_engine_raw.cc index de8a80e73..343ffb2bb 100644 --- a/scan_engine_raw.cc +++ b/scan_engine_raw.cc @@ -1314,7 +1314,7 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss, if (hss->target->af() == AF_INET) { for (decoy = 0; decoy < o.numdecoys; decoy++) { - packet = build_tcp_raw(&o.decoys[decoy], hss->target->v4hostip(), + packet = build_tcp_raw(&((struct sockaddr_in *)&o.decoys[decoy])->sin_addr, hss->target->v4hostip(), o.ttl, ipid, IP_TOS_DEFAULT, false, o.ipoptions, o.ipoptionslen, sport, pspec->pd.tcp.dport, @@ -1331,24 +1331,21 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss, free(packet); } } else if (hss->target->af() == AF_INET6) { - struct sockaddr_storage source; - struct sockaddr_in6 *sin6; - size_t source_len; - - source_len = sizeof(source); - hss->target->SourceSockAddr(&source, &source_len); - sin6 = (struct sockaddr_in6 *) &source; - packet = build_tcp_raw_ipv6(&sin6->sin6_addr, hss->target->v6hostip(), + for (decoy = 0; decoy < o.numdecoys; decoy++) { + packet = build_tcp_raw_ipv6(&((struct sockaddr_in6 *)&o.decoys[decoy])->sin6_addr, hss->target->v6hostip(), 0, 0, o.ttl, sport, pspec->pd.tcp.dport, seq, ack, 0, pspec->pd.tcp.flags, 0, 0, tcpops, tcpopslen, o.extra_payload, o.extra_payload_length, &packetlen); - probe->setIP(packet, packetlen, pspec); - probe->sent = USI->now; - hss->probeSent(packetlen); - send_ip_packet(USI->rawsd, ethptr, hss->target->TargetSockAddr(), packet, packetlen); - free(packet); + if (decoy == o.decoyturn) { + probe->setIP(packet, packetlen, pspec); + probe->sent = USI->now; + } + hss->probeSent(packetlen); + send_ip_packet(USI->rawsd, ethptr, hss->target->TargetSockAddr(), packet, packetlen); + free(packet); + } } } else if (pspec->type == PS_UDP) { const char *payload; @@ -1358,7 +1355,7 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss, if (hss->target->af() == AF_INET) { for (decoy = 0; decoy < o.numdecoys; decoy++) { - packet = build_udp_raw(&o.decoys[decoy], hss->target->v4hostip(), + packet = build_udp_raw(&((struct sockaddr_in *)&o.decoys[decoy])->sin_addr, hss->target->v4hostip(), o.ttl, ipid, IP_TOS_DEFAULT, false, o.ipoptions, o.ipoptionslen, sport, pspec->pd.udp.dport, @@ -1373,22 +1370,19 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss, free(packet); } } else if (hss->target->af() == AF_INET6) { - struct sockaddr_storage source; - struct sockaddr_in6 *sin6; - size_t source_len; - - source_len = sizeof(source); - hss->target->SourceSockAddr(&source, &source_len); - sin6 = (struct sockaddr_in6 *) &source; - packet = build_udp_raw_ipv6(&sin6->sin6_addr, hss->target->v6hostip(), + for (decoy = 0; decoy < o.numdecoys; decoy++) { + packet = build_udp_raw_ipv6(&((struct sockaddr_in6 *)&o.decoys[decoy])->sin6_addr, hss->target->v6hostip(), 0, 0, o.ttl, sport, pspec->pd.tcp.dport, (char *) payload, payload_length, &packetlen); - probe->setIP(packet, packetlen, pspec); - probe->sent = USI->now; - hss->probeSent(packetlen); - send_ip_packet(USI->rawsd, ethptr, hss->target->TargetSockAddr(), packet, packetlen); - free(packet); + if (decoy == o.decoyturn) { + probe->setIP(packet, packetlen, pspec); + probe->sent = USI->now; + } + hss->probeSent(packetlen); + send_ip_packet(USI->rawsd, ethptr, hss->target->TargetSockAddr(), packet, packetlen); + free(packet); + } } } else if (pspec->type == PS_SCTP) { switch (pspec->pd.sctp.chunktype) { @@ -1414,7 +1408,7 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss, } if (hss->target->af() == AF_INET) { for (decoy = 0; decoy < o.numdecoys; decoy++) { - packet = build_sctp_raw(&o.decoys[decoy], hss->target->v4hostip(), + packet = build_sctp_raw(&((struct sockaddr_in *)&o.decoys[decoy])->sin_addr, hss->target->v4hostip(), o.ttl, ipid, IP_TOS_DEFAULT, false, o.ipoptions, o.ipoptionslen, sport, pspec->pd.sctp.dport, @@ -1430,23 +1424,20 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss, free(packet); } } else if (hss->target->af() == AF_INET6) { - struct sockaddr_storage source; - struct sockaddr_in6 *sin6; - size_t source_len; - - source_len = sizeof(source); - hss->target->SourceSockAddr(&source, &source_len); - sin6 = (struct sockaddr_in6 *) &source; - packet = build_sctp_raw_ipv6(&sin6->sin6_addr, hss->target->v6hostip(), + for (decoy = 0; decoy < o.numdecoys; decoy++) { + packet = build_sctp_raw_ipv6(&((struct sockaddr_in6 *)&o.decoys[decoy])->sin6_addr, hss->target->v6hostip(), 0, 0, o.ttl, sport, pspec->pd.sctp.dport, vtag, chunk, chunklen, o.extra_payload, o.extra_payload_length, &packetlen); - probe->setIP(packet, packetlen, pspec); - probe->sent = USI->now; - hss->probeSent(packetlen); - send_ip_packet(USI->rawsd, ethptr, hss->target->TargetSockAddr(), packet, packetlen); - free(packet); + if (decoy == o.decoyturn) { + probe->setIP(packet, packetlen, pspec); + probe->sent = USI->now; + } + hss->probeSent(packetlen); + send_ip_packet(USI->rawsd, ethptr, hss->target->TargetSockAddr(), packet, packetlen); + free(packet); + } } free(chunk); } else if (pspec->type == PS_PROTO) { @@ -1458,7 +1449,7 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss, sin->sin_family = AF_INET; for (decoy = 0; decoy < o.numdecoys; decoy++) { - sin->sin_addr = o.decoys[decoy]; + sin->sin_addr = ((struct sockaddr_in *)&o.decoys[decoy])->sin_addr; packet = build_protoscan_packet(&ss, hss->target->TargetSockAddr(), pspec->proto, sport, &packetlen); assert(packet != NULL); @@ -1471,18 +1462,29 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss, free(packet); } } else if (hss->target->af() == AF_INET6) { - packet = build_protoscan_packet(hss->target->SourceSockAddr(), hss->target->TargetSockAddr(), + struct sockaddr_storage ss; + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *) &ss; + sin6->sin6_family = AF_INET6; + + for (decoy = 0; decoy < o.numdecoys; decoy++) { + sin6->sin6_addr = ((struct sockaddr_in6 *)&o.decoys[decoy])->sin6_addr; + packet = build_protoscan_packet(&ss, hss->target->TargetSockAddr(), pspec->proto, sport, &packetlen); - assert(packet != NULL); - probe->setIP(packet, packetlen, pspec); - probe->sent = USI->now; - hss->probeSent(packetlen); - send_ip_packet(USI->rawsd, ethptr, hss->target->TargetSockAddr(), packet, packetlen); - free(packet); + assert(packet != NULL); + if (decoy == o.decoyturn) { + probe->setIP(packet, packetlen, pspec); + probe->sent = USI->now; + } + hss->probeSent(packetlen); + send_ip_packet(USI->rawsd, ethptr, hss->target->TargetSockAddr(), packet, packetlen); + free(packet); + } } } else if (pspec->type == PS_ICMP) { for (decoy = 0; decoy < o.numdecoys; decoy++) { - packet = build_icmp_raw(&o.decoys[decoy], hss->target->v4hostip(), + packet = build_icmp_raw(&((struct sockaddr_in *)&o.decoys[decoy])->sin_addr, hss->target->v4hostip(), o.ttl, ipid, IP_TOS_DEFAULT, false, o.ipoptions, o.ipoptionslen, 0, icmp_ident, pspec->pd.icmp.type, pspec->pd.icmp.code, @@ -1497,23 +1499,20 @@ UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss, free(packet); } } else if (pspec->type == PS_ICMPV6) { - struct sockaddr_storage source; - struct sockaddr_in6 *sin6; - size_t source_len; - - source_len = sizeof(source); - hss->target->SourceSockAddr(&source, &source_len); - sin6 = (struct sockaddr_in6 *) &source; - packet = build_icmpv6_raw(&sin6->sin6_addr, hss->target->v6hostip(), + for (decoy =0; decoy < o.numdecoys; decoy++) { + packet = build_icmpv6_raw(&((struct sockaddr_in6 *)&o.decoys[decoy])->sin6_addr, hss->target->v6hostip(), 0, 0, o.ttl, 0, icmp_ident, pspec->pd.icmpv6.type, pspec->pd.icmpv6.code, o.extra_payload, o.extra_payload_length, &packetlen); - probe->setIP(packet, packetlen, pspec); - probe->sent = USI->now; - hss->probeSent(packetlen); - send_ip_packet(USI->rawsd, ethptr, hss->target->TargetSockAddr(), packet, packetlen); - free(packet); + if (decoy == o.decoyturn) { + probe->setIP(packet, packetlen, pspec); + probe->sent = USI->now; + } + hss->probeSent(packetlen); + send_ip_packet(USI->rawsd, ethptr, hss->target->TargetSockAddr(), packet, packetlen); + free(packet); + } } else assert(0); /* Now that the probe has been sent, add it to the Queue for this host */ diff --git a/targets.cc b/targets.cc index 4c877e765..90735e59e 100644 --- a/targets.cc +++ b/targets.cc @@ -571,7 +571,7 @@ static Target *setup_target(const HostGroupState *hs, #endif t->setSourceSockAddr(&rnfo.srcaddr, sizeof(rnfo.srcaddr)); if (hs->current_batch_sz == 0) /* Because later ones can have different src addy and be cut off group */ - o.decoys[o.decoyturn] = t->v4source(); + o.decoys[o.decoyturn] = t->source(); t->setDeviceNames(rnfo.ii.devname, rnfo.ii.devfullname); t->setMTU(rnfo.ii.mtu); // printf("Target %s %s directly connected, goes through local iface %s, which %s ethernet\n", t->NameIP(), t->directlyConnected()? "IS" : "IS NOT", t->deviceName(), (t->ifType() == devt_ethernet)? "IS" : "IS NOT"); @@ -660,7 +660,7 @@ static void refresh_hostbatch(HostGroupState *hs, const addrset *exclude_group, break; } - o.decoys[o.decoyturn] = t->v4source(); + o.decoys[o.decoyturn] = t->source(); hs->hostbatch[hs->current_batch_sz++] = t; } diff --git a/tcpip.cc b/tcpip.cc index 7c7adcac9..5c62300d2 100644 --- a/tcpip.cc +++ b/tcpip.cc @@ -839,7 +839,7 @@ int send_tcp_raw_decoys(int sd, const struct eth_nfo *eth, for (decoy = 0; decoy < o.numdecoys; decoy++) if (send_tcp_raw(sd, eth, - &o.decoys[decoy], victim, + &((struct sockaddr_in *)&o.decoys[decoy])->sin_addr, victim, ttl, df, ipopt, ipoptlen, sport, dport, @@ -956,7 +956,7 @@ int send_udp_raw_decoys(int sd, const struct eth_nfo *eth, int decoy; for (decoy = 0; decoy < o.numdecoys; decoy++) - if (send_udp_raw(sd, eth, &o.decoys[decoy], victim, + if (send_udp_raw(sd, eth, &((struct sockaddr_in *)&o.decoys[decoy])->sin_addr, victim, ttl, ipid, ipops, ipoptlen, sport, dport, data, datalen) == -1) return -1; diff --git a/traceroute.cc b/traceroute.cc index 34a739634..e96e88c2b 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -673,16 +673,7 @@ void Probe::send(int rawsd, eth_t *ethsd, struct timeval *now) { host->target->SourceSockAddr(&source, &source_len); sent_time = get_now(now); } else { - if (o.af() == AF_INET) { - struct sockaddr_in *sin; - - sin = (struct sockaddr_in *) &source; - sin->sin_family = AF_INET; - sin->sin_addr = o.decoys[decoy]; - } else { - /* Decoys are IPv4-only. */ - continue; - } + source = o.decoys[decoy]; } packet = this->build_packet(&source, &packetlen);