diff --git a/CHANGELOG b/CHANGELOG index f04a99df9..6b354b2df 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -52,6 +52,12 @@ o [NSE] script_scan_result structure has been changed to a class, o [NSE] The runlevel structure has been placed in the thread record structure so we no longer need to manage the runlevel explicitly on the heap. [Patrick] +o Nsock now supports binding to a local address and setting IPv4 options + with nsi_set_localaddr() and nsi_set_ipoptions(), respectively. [Kris] + +o Nmap's Nsock-utilizing subsystems (DNS, NSE, version detection) have been + updated to support the -S and --ip-options flags. [Kris] + Nmap 4.68 [2008-6-28] o Doug integrated all of your version detection submissions and diff --git a/NmapOps.cc b/NmapOps.cc index 2aed985dc..10ef7cf70 100644 --- a/NmapOps.cc +++ b/NmapOps.cc @@ -272,6 +272,8 @@ void NmapOps::Initialize() { scripttrace = 0; scriptupdatedb = 0; #endif + memset(&sourcesock, 0, sizeof(sourcesock)); + sourcesocklen = 0; } bool NmapOps::TCPScan() { @@ -378,9 +380,6 @@ void NmapOps::ValidateOptions() { if (osscan) { fatal("TCP/IP fingerprinting (for OS scan) requires %s.", privreq); } - - if (ipoptionslen) - fatal("Sorry, using ip options requires %s.", privreq); } diff --git a/nmap_dns.cc b/nmap_dns.cc index 05552807e..c457be27a 100644 --- a/nmap_dns.cc +++ b/nmap_dns.cc @@ -857,6 +857,14 @@ static void connect_dns_servers() { s = *serverI; s->nsd = nsi_new(dnspool, NULL); + if (o.spoofsource) { + struct sockaddr_storage ss; + size_t sslen; + o.SourceSockAddr(&ss, &sslen); + nsi_set_localaddr(s->nsd, &ss, sslen); + } + if (o.ipoptionslen) + nsi_set_ipoptions(s->nsd, o.ipoptions, o.ipoptionslen); s->reqs_on_wire = 0; s->capacity = CAPACITY_MIN; s->write_busy = 0; diff --git a/nse_nsock.cc b/nse_nsock.cc index f2885738f..1347d0ea6 100644 --- a/nse_nsock.cc +++ b/nse_nsock.cc @@ -342,6 +342,14 @@ static int l_nsock_connect(lua_State *L) { } udata->nsiod = nsi_new(nsp, NULL); + if (o.spoofsource) { + struct sockaddr_storage ss; + size_t sslen; + o.SourceSockAddr(&ss, &sslen); + nsi_set_localaddr(udata->nsiod, &ss, sslen); + } + if (o.ipoptionslen) + nsi_set_ipoptions(udata->nsiod, o.ipoptions, o.ipoptionslen); nsock_descriptors_used++; switch (how[0]) { diff --git a/service_scan.cc b/service_scan.cc index 53c29e932..4f6cc6c8b 100644 --- a/service_scan.cc +++ b/service_scan.cc @@ -1766,6 +1766,12 @@ static void startNextProbe(nsock_pool nsp, nsock_iod nsi, ServiceGroup *SG, if ((svc->niod = nsi_new(nsp, svc)) == NULL) { fatal("Failed to allocate Nsock I/O descriptor in %s()", __func__); } + if (o.spoofsource) { + o.SourceSockAddr(&ss, &ss_len); + nsi_set_localaddr(svc->niod, &ss, ss_len); + } + if (o.ipoptionslen) + nsi_set_ipoptions(svc->niod, o.ipoptions, o.ipoptionslen); svc->target->TargetSockAddr(&ss, &ss_len); if (svc->tunnel == SERVICE_TUNNEL_NONE) { nsock_connect_tcp(nsp, svc->niod, servicescan_connect_handler, @@ -1964,6 +1970,12 @@ static int launchSomeServiceProbes(nsock_pool nsp, ServiceGroup *SG) { if (o.debugging > 1) { log_write(LOG_PLAIN, "Starting probes against new service: %s:%hi (%s)\n", svc->target->targetipstr(), svc->portno, proto2ascii(svc->proto)); } + if (o.spoofsource) { + o.SourceSockAddr(&ss, &ss_len); + nsi_set_localaddr(svc->niod, &ss, ss_len); + } + if (o.ipoptionslen) + nsi_set_ipoptions(svc->niod, o.ipoptions, o.ipoptionslen); svc->target->TargetSockAddr(&ss, &ss_len); if (svc->proto == IPPROTO_TCP) nsock_connect_tcp(nsp, svc->niod, servicescan_connect_handler,