From 84420aa30002b84c07c77a5d431d204e9eac3360 Mon Sep 17 00:00:00 2001 From: dmiller Date: Fri, 21 Aug 2026 01:14:28 +0000 Subject: [PATCH] Try to use the correct sockaddr size when setting source. See #3438 --- NmapOps.cc | 15 ++++++++++++++- NmapOps.h | 2 +- Target.cc | 13 +++++++++++++ nping/NpingTarget.cc | 30 ++++++++++++++++++++++++++++-- nping/NpingTarget.h | 4 ++-- 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/NmapOps.cc b/NmapOps.cc index ea55ecda8..b29ee7027 100644 --- a/NmapOps.cc +++ b/NmapOps.cc @@ -170,9 +170,22 @@ const struct sockaddr_storage *NmapOps::SourceSockAddr() const { /* Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted to sockaddr_storage */ -void NmapOps::setSourceSockAddr(struct sockaddr_storage *ss, size_t ss_len) { +void NmapOps::setSourceSockAddr(const struct sockaddr_storage *ss, size_t ss_len) { assert(ss_len > 0 && ss_len <= sizeof(*ss)); memcpy(&sourcesock, ss, ss_len); + if (ss_len == sizeof(*ss)) { +#if HAVE_SOCKADDR_SA_LEN + if (((const struct sockaddr *)ss)->sa_len > 0) { + ss_len = ((const struct sockaddr *)ss)->sa_len; + } else +#endif + if (ss->ss_family == AF_INET) { + ss_len = sizeof(struct sockaddr_in); + } + else if (ss->ss_family == AF_INET6) { + ss_len = sizeof(struct sockaddr_in6); + } + } sourcesocklen = ss_len; } diff --git a/NmapOps.h b/NmapOps.h index cecf420da..d6123e1b5 100644 --- a/NmapOps.h +++ b/NmapOps.h @@ -92,7 +92,7 @@ class NmapOps { const struct sockaddr_storage *SourceSockAddr() const; /* Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted to sockaddr_storage */ - void setSourceSockAddr(struct sockaddr_storage *ss, size_t ss_len); + void setSourceSockAddr(const struct sockaddr_storage *ss, size_t ss_len); // The time this obj. was instantiated or last ReInit()ed. const struct timeval *getStartTime() { return &start_time; } diff --git a/Target.cc b/Target.cc index bb393276d..7195a4f52 100644 --- a/Target.cc +++ b/Target.cc @@ -284,6 +284,19 @@ const struct sockaddr_storage *Target::SourceSockAddr() const { void Target::setSourceSockAddr(const struct sockaddr_storage *ss, size_t ss_len) { assert(ss_len > 0 && ss_len <= sizeof(*ss)); memcpy(&sourcesock, ss, ss_len); + if (ss_len == sizeof(*ss)) { +#ifdef HAVE_SOCKADDR_SA_LEN + if (((const struct sockaddr *)ss)->sa_len > 0) { + ss_len = ((const struct sockaddr *)ss)->sa_len; + } else +#endif + if (ss->ss_family == AF_INET) { + ss_len = sizeof(struct sockaddr_in); + } + else if (ss->ss_family == AF_INET6) { + ss_len = sizeof(struct sockaddr_in6); + } + } sourcesocklen = ss_len; GenerateSourceIPString(); } diff --git a/nping/NpingTarget.cc b/nping/NpingTarget.cc index 9dc0593bc..53ef95ed9 100644 --- a/nping/NpingTarget.cc +++ b/nping/NpingTarget.cc @@ -260,9 +260,22 @@ int NpingTarget::getSourceSockAddr(struct sockaddr_storage *ss, size_t *ss_len) /** Set source address used to reach the target. * Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted * to sockaddr_storage */ -int NpingTarget::setSourceSockAddr(struct sockaddr_storage *ss, size_t ss_len) { +int NpingTarget::setSourceSockAddr(const struct sockaddr_storage *ss, size_t ss_len) { assert(ss_len > 0 && ss_len <= sizeof(*ss)); memcpy(&sourcesock, ss, ss_len); + if (ss_len == sizeof(*ss)) { +#ifdef HAVE_SOCKADDR_SA_LEN + if (((const struct sockaddr *)ss)->sa_len > 0) { + ss_len = ((const struct sockaddr *)ss)->sa_len; + } else +#endif + if (ss->ss_family == AF_INET) { + ss_len = sizeof(struct sockaddr_in); + } + else if (ss->ss_family == AF_INET6) { + ss_len = sizeof(struct sockaddr_in6); + } + } sourcesocklen = ss_len; return OP_SUCCESS; } /* End of setSourceSockAddr() */ @@ -271,9 +284,22 @@ int NpingTarget::setSourceSockAddr(struct sockaddr_storage *ss, size_t ss_len) { /** Set source address used to reach the target. * Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted * to sockaddr_storage */ -int NpingTarget::setSpoofedSourceSockAddr(struct sockaddr_storage *ss, size_t ss_len) { +int NpingTarget::setSpoofedSourceSockAddr(const struct sockaddr_storage *ss, size_t ss_len) { assert(ss_len > 0 && ss_len <= sizeof(*ss)); memcpy(&spoofedsrcsock, ss, ss_len); + if (ss_len == sizeof(*ss)) { +#ifdef HAVE_SOCKADDR_SA_LEN + if (((const struct sockaddr *)ss)->sa_len > 0) { + ss_len = ((const struct sockaddr *)ss)->sa_len; + } else +#endif + if (ss->ss_family == AF_INET) { + ss_len = sizeof(struct sockaddr_in); + } + else if (ss->ss_family == AF_INET6) { + ss_len = sizeof(struct sockaddr_in6); + } + } spoofedsrcsocklen = ss_len; this->spoofedsrc_set=true; return OP_SUCCESS; diff --git a/nping/NpingTarget.h b/nping/NpingTarget.h index 25b57d220..f8ddfa63a 100644 --- a/nping/NpingTarget.h +++ b/nping/NpingTarget.h @@ -144,9 +144,9 @@ class NpingTarget { /* Source address used to reach the target */ int getSourceSockAddr(struct sockaddr_storage *ss, size_t *ss_len); - int setSourceSockAddr(struct sockaddr_storage *ss, size_t ss_len); + int setSourceSockAddr(const struct sockaddr_storage *ss, size_t ss_len); int getSpoofedSourceSockAddr(struct sockaddr_storage *ss, size_t *ss_len); - int setSpoofedSourceSockAddr(struct sockaddr_storage *ss, size_t ss_len); + int setSpoofedSourceSockAddr(const struct sockaddr_storage *ss, size_t ss_len); bool spoofingSourceAddress(); struct in_addr getIPv4SourceAddress(); const struct in_addr *getIPv4SourceAddress_aux();