Update snmpd to 5.9, as part of the Bullseye upgrade

Debian actually did a binNMU for snmpd, so to match the package version
we're building with the version in the offiical repos, that version
needs to be manually specified in the changelog.

Buster still needs 5.7.3, because there's a ABI change between 5.7.3 and
5.9 for libsnmp, so for Buster, make sure that 5.7.3 is built, and for
Bullseye, make sure that 5.9 is built.

Signed-off-by: Saikrishna Arcot <sarcot@microsoft.com>
This commit is contained in:
Saikrishna Arcot 2021-07-14 12:22:27 -07:00 committed by Saikrishna Arcot
parent 05329ebbd8
commit c923310b8c
9 changed files with 1171 additions and 0 deletions

View File

@ -1,7 +1,12 @@
# snmpd package # snmpd package
ifeq ($(BLDENV),bullseye)
SNMPD_VERSION = 5.9+dfsg
SNMPD_VERSION_FULL = $(SNMPD_VERSION)-3+b1
else
SNMPD_VERSION = 5.7.3+dfsg SNMPD_VERSION = 5.7.3+dfsg
SNMPD_VERSION_FULL = $(SNMPD_VERSION)-5 SNMPD_VERSION_FULL = $(SNMPD_VERSION)-5
endif
export SNMPD_VERSION SNMPD_VERSION_FULL export SNMPD_VERSION SNMPD_VERSION_FULL
@ -32,11 +37,19 @@ $(eval $(call add_derived_package,$(LIBSNMP_BASE),$(SNMP_DBG)))
SNMPD_DBG = snmpd-dbgsym_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb SNMPD_DBG = snmpd-dbgsym_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb
$(eval $(call add_derived_package,$(LIBSNMP_BASE),$(SNMPD_DBG))) $(eval $(call add_derived_package,$(LIBSNMP_BASE),$(SNMPD_DBG)))
ifeq ($(BLDENV),bullseye)
LIBSNMP = libsnmp40_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb
else
LIBSNMP = libsnmp30_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb LIBSNMP = libsnmp30_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb
endif
$(LIBSNMP)_RDEPENDS += $(LIBSNMP_BASE) $(LIBSNMP)_RDEPENDS += $(LIBSNMP_BASE)
$(eval $(call add_derived_package,$(LIBSNMP_BASE),$(LIBSNMP))) $(eval $(call add_derived_package,$(LIBSNMP_BASE),$(LIBSNMP)))
ifeq ($(BLDENV),bullseye)
LIBSNMP_DBG = libsnmp40-dbgsym_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb
else
LIBSNMP_DBG = libsnmp30-dbg_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb LIBSNMP_DBG = libsnmp30-dbg_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb
endif
$(LIBSNMP_DBG)_DEPENDS += $(LIBSNMP) $(LIBSNMP_DBG)_DEPENDS += $(LIBSNMP)
$(LIBSNMP_DBG)_RDEPENDS += $(LIBSNMP) $(LIBSNMP_DBG)_RDEPENDS += $(LIBSNMP)
$(eval $(call add_derived_package,$(LIBSNMP_BASE),$(LIBSNMP_DBG))) $(eval $(call add_derived_package,$(LIBSNMP_BASE),$(LIBSNMP_DBG)))

View File

@ -3,6 +3,18 @@ SHELL = /bin/bash
.SHELLFLAGS += -e .SHELLFLAGS += -e
MAIN_TARGET = libsnmp-base_$(SNMPD_VERSION_FULL)_all.deb MAIN_TARGET = libsnmp-base_$(SNMPD_VERSION_FULL)_all.deb
ifneq (,$(findstring 5.9,$(SNMPD_VERSION)))
DERIVED_TARGETS = snmptrapd_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
snmp_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
snmpd_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
snmp-dbgsym_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
snmpd-dbgsym_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
libsnmp40_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
libsnmp40-dbgsym_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
libsnmp-dev_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
libsnmp-perl_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
tkmib_$(SNMPD_VERSION_FULL)_all.deb
else
DERIVED_TARGETS = snmptrapd_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ DERIVED_TARGETS = snmptrapd_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
snmp_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ snmp_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
snmpd_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ snmpd_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
@ -13,18 +25,33 @@ DERIVED_TARGETS = snmptrapd_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
libsnmp-dev_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ libsnmp-dev_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
libsnmp-perl_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \ libsnmp-perl_$(SNMPD_VERSION_FULL)_$(CONFIGURED_ARCH).deb \
tkmib_$(SNMPD_VERSION_FULL)_all.deb tkmib_$(SNMPD_VERSION_FULL)_all.deb
endif
$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
rm -rf net-snmp-$(SNMPD_VERSION) rm -rf net-snmp-$(SNMPD_VERSION)
# download debian net-snmp # download debian net-snmp
ifneq (,$(findstring 5.9,$(SNMPD_VERSION)))
dget -u https://sonicstorage.blob.core.windows.net/debian/pool/main/n/net-snmp/net-snmp_$(SNMPD_VERSION)-3.dsc
else
dget -u https://sonicstorage.blob.core.windows.net/debian/pool/main/n/net-snmp/net-snmp_$(SNMPD_VERSION_FULL).dsc dget -u https://sonicstorage.blob.core.windows.net/debian/pool/main/n/net-snmp/net-snmp_$(SNMPD_VERSION_FULL).dsc
endif
pushd net-snmp-$(SNMPD_VERSION) pushd net-snmp-$(SNMPD_VERSION)
git init git init
git add -f * git add -f *
git commit -m "unmodified snmpd source" git commit -m "unmodified snmpd source"
ifneq (,$(findstring 5.9,$(SNMPD_VERSION)))
# Looks like Debian did a binNMU (binary non-maintainer upload), so the latest dsc
# file that we can get doesn't actually have the exact version number that Debian's
# repos have.
DEBEMAIL="$(shell git config --get user.name) <$(shell git config --get user.email)>" dch --bin-nmu "Rebuild against perl 5.32.0"
dch -r ""
git add debian/changelog
git commit -m "fix package version"
endif
# Apply patches # Apply patches
stg init stg init
stg import -s ../patch-$(SNMPD_VERSION)/series stg import -s ../patch-$(SNMPD_VERSION)/series

View File

@ -0,0 +1,27 @@
From a1edbce39e46b5c8bd5bd7db17fc11fa30e7dd73 Mon Sep 17 00:00:00 2001
From: pavel-shirshov <pavelsh@microsoft.com>
Date: Mon, 27 Aug 2018 16:50:16 +0800
Subject: [PATCH] [SNMP] Stop spamming logs with statfs permission denied log
message #1668
---
agent/mibgroup/hardware/fsys/fsys_mntctl.c | 2 --
agent/mibgroup/hardware/fsys/fsys_mntent.c | 2 --
2 files changed, 4 deletions(-)
diff --git a/agent/mibgroup/hardware/fsys/fsys_mntctl.c b/agent/mibgroup/hardware/fsys/fsys_mntctl.c
index 9fbb068..adc38d6 100644
--- a/agent/mibgroup/hardware/fsys/fsys_mntctl.c
+++ b/agent/mibgroup/hardware/fsys/fsys_mntctl.c
@@ -163,8 +163,6 @@ netsnmp_fsys_arch_load( void )
continue;
if ( statfs( entry->path, &stat_buf ) < 0 ) {
- snprintf( tmpbuf, sizeof(tmpbuf), "Cannot statfs %s", entry->path );
- snmp_log_perror( tmpbuf );
continue;
}
entry->units = stat_buf.f_bsize;
--
2.7.4

View File

@ -0,0 +1,31 @@
From e370973f273ffc1b32673bc94c5a46f75a846d82 Mon Sep 17 00:00:00 2001
From: Niels Baggesen <nba@users.sourceforge.net>
Date: Wed, 31 Aug 2016 21:43:36 +0200
Subject: [PATCH] at.c: properly check return status from realloc. Thanks to
Daniel Eiland (bug 2678)
---
agent/mibgroup/mibII/at.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/agent/mibgroup/mibII/at.c b/agent/mibgroup/mibII/at.c
index f57ba2a..a73fb8c 100644
--- a/agent/mibgroup/mibII/at.c
+++ b/agent/mibgroup/mibII/at.c
@@ -638,11 +638,12 @@ ARP_Scan_Init(void)
struct arptab *newtab = (struct arptab *)
realloc(at, (sizeof(struct arptab) *
(arptab_curr_max_size + ARP_CACHE_INCR)));
- if (newtab == at) {
+ if (newtab == NULL) {
snmp_log(LOG_ERR,
"Error allocating more space for arpcache. "
"Cache will continue to be limited to %d entries",
arptab_curr_max_size);
+ newtab = at;
break;
} else {
arptab_curr_max_size += ARP_CACHE_INCR;
--
2.7.4

View File

@ -0,0 +1,36 @@
From 2170e345858738e65d3156a49d3186e4a9288821 Mon Sep 17 00:00:00 2001
From: Zhenggen Xu <zxu@linkedin.com>
Date: Fri, 12 Oct 2018 17:13:54 -0700
Subject: [PATCH] Subject: [PATCH] CHANGES: BUG: 2743: snmpd crashes when
receiving a GetNext PDU with multiple Varbinds
skip out-of-range varbinds when calling next handler
---
agent/helpers/table.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/agent/helpers/table.c b/agent/helpers/table.c
index 882e84c..b943d6e 100644
--- a/agent/helpers/table.c
+++ b/agent/helpers/table.c
@@ -406,6 +406,8 @@ table_helper_handler(netsnmp_mib_handler *handler,
if (reqinfo->mode == MODE_GET)
table_helper_cleanup(reqinfo, request,
SNMP_NOSUCHOBJECT);
+ else
+ request->processed = 1; /* skip if next handler called */
continue;
}
@@ -483,6 +485,8 @@ table_helper_handler(netsnmp_mib_handler *handler,
#endif /* NETSNMP_NO_WRITE_SUPPORT */
table_helper_cleanup(reqinfo, request,
SNMP_NOSUCHOBJECT);
+ else
+ request->processed = 1; /* skip if next handler called */
continue;
}
/*
--
2.18.0

View File

@ -0,0 +1,211 @@
From a5782d0673044ad0c621daed7975f53238bb038e Mon Sep 17 00:00:00 2001
From: Renuka Manavalan <remanava@microsoft.com>
Date: Tue, 10 Sep 2019 17:51:45 +0000
Subject: [PATCH] Patch from SourceForge: net-snmp commit #793d59 Avoids snmpd
crash when sub agent timesout.
---
agent/mibgroup/agentx/master_admin.c | 1 +
agent/snmp_agent.c | 81 ++++++++++++++++++----------
include/net-snmp/agent/snmp_agent.h | 5 ++
3 files changed, 60 insertions(+), 27 deletions(-)
diff --git a/agent/mibgroup/agentx/master_admin.c b/agent/mibgroup/agentx/master_admin.c
index 4dc1aa7..8c1d194 100644
--- a/agent/mibgroup/agentx/master_admin.c
+++ b/agent/mibgroup/agentx/master_admin.c
@@ -158,6 +158,7 @@ close_agentx_session(netsnmp_session * session, int sessid)
for (sp = session->subsession; sp != NULL; sp = sp->next) {
if (sp->sessid == sessid) {
+ netsnmp_remove_delegated_requests_for_session(sp);
unregister_mibs_by_session(sp);
unregister_index_by_session(sp);
unregister_sysORTable_by_session(sp);
diff --git a/agent/snmp_agent.c b/agent/snmp_agent.c
index b96d650..7cacd1a 100644
--- a/agent/snmp_agent.c
+++ b/agent/snmp_agent.c
@@ -1409,6 +1409,7 @@ init_agent_snmp_session(netsnmp_session * session, netsnmp_pdu *pdu)
asp->treecache_num = -1;
asp->treecache_len = 0;
asp->reqinfo = SNMP_MALLOC_TYPEDEF(netsnmp_agent_request_info);
+ asp->flags = SNMP_AGENT_FLAGS_NONE;
DEBUGMSGTL(("verbose:asp", "asp %p reqinfo %p created\n",
asp, asp->reqinfo));
@@ -1457,6 +1458,9 @@ netsnmp_check_for_delegated(netsnmp_agent_session *asp)
if (NULL == asp->treecache)
return 0;
+
+ if (asp->flags & SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS)
+ return 0;
for (i = 0; i <= asp->treecache_num; i++) {
for (request = asp->treecache[i].requests_begin; request;
@@ -1535,39 +1539,48 @@ int
netsnmp_remove_delegated_requests_for_session(netsnmp_session *sess)
{
netsnmp_agent_session *asp;
- int count = 0;
+ int total_count = 0;
for (asp = agent_delegated_list; asp; asp = asp->next) {
/*
* check each request
*/
+ int i;
+ int count = 0;
netsnmp_request_info *request;
- for(request = asp->requests; request; request = request->next) {
- /*
- * check session
- */
- netsnmp_assert(NULL!=request->subtree);
- if(request->subtree->session != sess)
- continue;
+ for (i = 0; i <= asp->treecache_num; i++) {
+ for (request = asp->treecache[i].requests_begin; request;
+ request = request->next) {
+ /*
+ * check session
+ */
+ netsnmp_assert(NULL!=request->subtree);
+ if(request->subtree->session != sess)
+ continue;
- /*
- * matched! mark request as done
- */
- netsnmp_request_set_error(request, SNMP_ERR_GENERR);
- ++count;
+ /*
+ * matched! mark request as done
+ */
+ netsnmp_request_set_error(request, SNMP_ERR_GENERR);
+ ++count;
+ }
+ }
+ if (count) {
+ asp->flags |= SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS;
+ total_count += count;
}
}
/*
* if we found any, that request may be finished now
*/
- if(count) {
+ if(total_count) {
DEBUGMSGTL(("snmp_agent", "removed %d delegated request(s) for session "
- "%8p\n", count, sess));
- netsnmp_check_outstanding_agent_requests();
+ "%8p\n", total_count, sess));
+ netsnmp_check_delegated_requests();
}
- return count;
+ return total_count;
}
int
@@ -2739,19 +2752,11 @@ handle_var_requests(netsnmp_agent_session *asp)
return final_status;
}
-/*
- * loop through our sessions known delegated sessions and check to see
- * if they've completed yet. If there are no more delegated sessions,
- * check for and process any queued requests
- */
void
-netsnmp_check_outstanding_agent_requests(void)
+netsnmp_check_delegated_requests(void)
{
netsnmp_agent_session *asp, *prev_asp = NULL, *next_asp = NULL;
- /*
- * deal with delegated requests
- */
for (asp = agent_delegated_list; asp; asp = next_asp) {
next_asp = asp->next; /* save in case we clean up asp */
if (!netsnmp_check_for_delegated(asp)) {
@@ -2790,6 +2795,23 @@ netsnmp_check_outstanding_agent_requests(void)
prev_asp = asp;
}
}
+}
+
+
+/*
+ * loop through our sessions known delegated sessions and check to see
+ * if they've completed yet. If there are no more delegated sessions,
+ * check for and process any queued requests
+ */
+void
+netsnmp_check_outstanding_agent_requests(void)
+{
+ netsnmp_agent_session *asp;
+
+ /*
+ * deal with delegated requests
+ */
+ netsnmp_check_delegated_requests();
/*
* if we are processing a set and there are more delegated
@@ -2819,7 +2841,8 @@ netsnmp_check_outstanding_agent_requests(void)
netsnmp_processing_set = netsnmp_agent_queued_list;
DEBUGMSGTL(("snmp_agent", "SET request remains queued while "
- "delegated requests finish, asp = %8p\n", asp));
+ "delegated requests finish, asp = %8p\n",
+ agent_delegated_list));
break;
}
#endif /* NETSNMP_NO_WRITE_SUPPORT */
@@ -2880,6 +2903,10 @@ check_delayed_request(netsnmp_agent_session *asp)
case SNMP_MSG_GETBULK:
case SNMP_MSG_GETNEXT:
netsnmp_check_all_requests_status(asp, 0);
+ if (asp->flags & SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS) {
+ DEBUGMSGTL(("snmp_agent","canceling next walk for asp %p\n", asp));
+ break;
+ }
handle_getnext_loop(asp);
if (netsnmp_check_for_delegated(asp) &&
netsnmp_check_transaction_id(asp->pdu->transid) !=
diff --git a/include/net-snmp/agent/snmp_agent.h b/include/net-snmp/agent/snmp_agent.h
index aad8837..43f4fff 100644
--- a/include/net-snmp/agent/snmp_agent.h
+++ b/include/net-snmp/agent/snmp_agent.h
@@ -32,6 +32,9 @@ extern "C" {
#define SNMP_MAX_PDU_SIZE 64000 /* local constraint on PDU size sent by agent
* (see also SNMP_MAX_MSG_SIZE in snmp_api.h) */
+#define SNMP_AGENT_FLAGS_NONE 0x0
+#define SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS 0x1
+
/*
* If non-zero, causes the addresses of peers to be logged when receptions
* occur.
@@ -205,6 +208,7 @@ extern "C" {
int treecache_num; /* number of current cache entries */
netsnmp_cachemap *cache_store;
int vbcount;
+ int flags;
} netsnmp_agent_session;
/*
@@ -240,6 +244,7 @@ extern "C" {
int init_master_agent(void);
void shutdown_master_agent(void);
int agent_check_and_process(int block);
+ void netsnmp_check_delegated_requests(void);
void netsnmp_check_outstanding_agent_requests(void);
int netsnmp_request_set_error(netsnmp_request_info *request,
--
2.17.1

View File

@ -0,0 +1,799 @@
From 49ce7fc078dfa8c1a1688e05de4e2d151dbcd76a Mon Sep 17 00:00:00 2001
From: Harish Venkatraman <Harish_Venkatraman@dell.com>
Date: Wed, 17 Oct 2018 15:22:04 -0700
Subject: [PATCH] Linux-VRF 5.7.3 Support from https://sourceforge.net/p/net-snmp/patches/1376/
Sourceforge commits related to this consolidated patch are given below.
https://sourceforge.net/p/net-snmp/code/ci/0b637fea62c7b6dc467b94206d0bd2dec6f912ca/
https://sourceforge.net/p/net-snmp/code/ci/19ba7b0a6b56d201a8563fe6505cd82e313c1c9c/
https://sourceforge.net/p/net-snmp/code/ci/76336fb63bb74b4dede5dda5c14fb8cf2d60be8e/
https://sourceforge.net/p/net-snmp/code/ci/c7398de4122102b3250e6dac7c09dbc5d09f1840/
https://sourceforge.net/p/net-snmp/code/ci/0831ed64a39a34dc040eabe39d0229b07fa2a8a5/
https://sourceforge.net/p/net-snmp/code/ci/62f6babcc7cfc54c79b442b8a7f45662b4ddc807/
https://sourceforge.net/p/net-snmp/code/ci/313949522c4d0ddfeac72195fa63512955d9eb28/
This consolidated patch adds native support for VRFs to snmpd. NCLU patches in this same
CCR will be added shortly. The VRF is specified for both listening
addresses as well as TRAP sinks with the 'ipaddr%iface' syntax:
agentAddress 10.0.1.7%mgmt,22.22.22.22%red
trapsink 10.0.1.9%mgmt
trap2sink 22.22.22.25%red
The SO_BINDTODEVICE socket option is used to bind a VRF to a particular
socket.
Testing done included VRFs as well as non-VRF functionality with traps
(v1, v2, and v3)
---
agent/agent_trap.c | 20 ++++++++++--
agent/mibgroup/agentx/master.c | 2 +-
agent/mibgroup/agentx/subagent.c | 2 +-
agent/mibgroup/target/target.c | 3 +-
agent/snmp_agent.c | 21 ++++++++++++-
apps/agentxtrap.c | 2 +-
apps/snmptrap.c | 2 +-
apps/snmptrapd.c | 2 +-
include/net-snmp/library/snmpTCPDomain.h | 2 +-
include/net-snmp/library/snmpUDPBaseDomain.h | 2 +-
include/net-snmp/library/snmpUDPDomain.h | 2 +-
include/net-snmp/library/snmpUDPIPv4BaseDomain.h | 2 +-
include/net-snmp/library/snmpUDPIPv6Domain.h | 2 +-
include/net-snmp/library/snmp_transport.h | 19 +++++++-----
snmplib/snmp_api.c | 4 +--
snmplib/snmp_transport.c | 26 ++++++++--------
snmplib/transports/snmpAliasDomain.c | 6 ++--
snmplib/transports/snmpTCPDomain.c | 16 +++++++---
snmplib/transports/snmpUDPBaseDomain.c | 39 ++++++++++++++++++------
snmplib/transports/snmpUDPDomain.c | 15 ++++-----
snmplib/transports/snmpUDPIPv4BaseDomain.c | 4 +--
snmplib/transports/snmpUDPIPv6Domain.c | 19 ++++-----
snmplib/transports/snmpUnixDomain.c | 5 +--
23 files changed, 141 insertions(+), 76 deletions(-)
diff --git a/agent/agent_trap.c b/agent/agent_trap.c
index 080b8bf..c488ac9 100644
--- a/agent/agent_trap.c
+++ b/agent/agent_trap.c
@@ -226,6 +226,7 @@ create_trap_session2(const char *sink, const char* sinkport,
{
netsnmp_transport *t;
netsnmp_session session, *sesp;
+ char *iface;
memset(&session, 0, sizeof(netsnmp_session));
session.version = version;
@@ -250,7 +251,14 @@ create_trap_session2(const char *sink, const char* sinkport,
((0 == strcmp("localhost",sink)) || (0 == strcmp("127.0.0.1",sink))))
session.localname = strdup("localhost");
- t = netsnmp_tdomain_transport_full("snmptrap", sink, 0, NULL, sinkport);
+ /*
+ * if given an iface (ip%iface) in sink, send the iface too
+ */
+ iface = strchr(sink, '%');
+ if (iface)
+ *iface++ = '\0';
+
+ t = netsnmp_tdomain_transport_full("snmptrap", sink, 0, NULL, sinkport, iface);
if (t != NULL) {
sesp = snmp_add(&session, t, NULL, NULL);
@@ -1219,6 +1227,7 @@ snmpd_parse_config_trapsess(const char *word, char *cptr)
netsnmp_session session, *ss;
netsnmp_transport *transport;
size_t len;
+ char *iface;
/*
* inform or trap? default to trap
@@ -1240,7 +1249,14 @@ snmpd_parse_config_trapsess(const char *word, char *cptr)
NETSNMP_PARSE_ARGS_NOLOGGING |
NETSNMP_PARSE_ARGS_NOZERO);
- transport = netsnmp_transport_open_client("snmptrap", session.peername);
+ /*
+ * if iface is given in peer, we will need to bind to that iface
+ */
+ iface = strchr(session.peername, '%');
+ if (iface)
+ *iface++ = '\0';
+
+ transport = netsnmp_transport_open_client("snmptrap", session.peername, iface);
if (transport == NULL) {
config_perror("snmpd: failed to parse this line.");
return;
diff --git a/agent/mibgroup/agentx/master.c b/agent/mibgroup/agentx/master.c
index baeebaf..6733e7f 100644
--- a/agent/mibgroup/agentx/master.c
+++ b/agent/mibgroup/agentx/master.c
@@ -126,7 +126,7 @@ real_init_master(void)
sess.remote_port = 0;
sess.callback = handle_master_agentx_packet;
errno = 0;
- t = netsnmp_transport_open_server("agentx", sess.peername);
+ t = netsnmp_transport_open_server("agentx", sess.peername, NULL);
if (t == NULL) {
/*
* diagnose snmp_open errors with the input netsnmp_session
diff --git a/agent/mibgroup/agentx/subagent.c b/agent/mibgroup/agentx/subagent.c
index 1f9d31c..6d38a34 100644
--- a/agent/mibgroup/agentx/subagent.c
+++ b/agent/mibgroup/agentx/subagent.c
@@ -843,7 +843,7 @@ subagent_open_master_session(void)
agentx_socket = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_X_SOCKET);
- t = netsnmp_transport_open_client("agentx", agentx_socket);
+ t = netsnmp_transport_open_client("agentx", agentx_socket, NULL);
if (t == NULL) {
/*
* Diagnose snmp_open errors with the input
diff --git a/agent/mibgroup/target/target.c b/agent/mibgroup/target/target.c
index 5619e35..6f58817 100644
--- a/agent/mibgroup/target/target.c
+++ b/agent/mibgroup/target/target.c
@@ -154,7 +154,8 @@ get_target_sessions(char *taglist, TargetFilterFunction * filterfunct,
tAddress,
targaddrs->
tAddressLen,
- 0);
+ 0,
+ NULL);
if (t == NULL) {
DEBUGMSGTL(("target_sessions",
"bad dest \""));
diff --git a/agent/snmp_agent.c b/agent/snmp_agent.c
index b96d650..281e8b2 100644
--- a/agent/snmp_agent.c
+++ b/agent/snmp_agent.c
@@ -1270,6 +1270,7 @@ init_master_agent(void)
char *cptr;
char *buf = NULL;
char *st;
+ char *iface;
/* default to a default cache size */
netsnmp_set_lookup_cache_size(-1);
@@ -1318,6 +1319,9 @@ init_master_agent(void)
* AAL5PVC:itf.vpi.vci (if supported)
* IPX:[network]:node[/port] (if supported)
*
+ *
+ * New format to specify an interface for binding along with IP address
+ * address%iface
*/
cptr = st;
@@ -1334,7 +1338,22 @@ init_master_agent(void)
"requested\n"));
break;
}
- transport = netsnmp_transport_open_server("snmp", cptr);
+
+ /*
+ * at some point, we may want to add the special listendevice
+ * keyword support. Not sure how to interact with ip%iface
+ iface = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_LISTEN_DEVICE);
+ */
+
+ /* Look for %iface so we can send along a specific interface to
+ setsockopt SO_BINDTODEVICE later. */
+ iface = strchr(cptr, '%');
+ if (iface)
+ *iface++ = '\0';
+
+ transport = netsnmp_transport_open_server("snmp", cptr, iface);
+
if (transport == NULL) {
snmp_log(LOG_ERR, "Error opening specified endpoint \"%s\"\n",
diff --git a/apps/agentxtrap.c b/apps/agentxtrap.c
index 4df423c..ebd81a3 100644
--- a/apps/agentxtrap.c
+++ b/apps/agentxtrap.c
@@ -231,7 +231,7 @@ ConnectingEntry(UNUSED tState self)
if(!(t = netsnmp_transport_open_client(
"agentx", netsnmp_ds_get_string(
- NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET)))) {
+ NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET), NULL))) {
snmp_log(LOG_ERR, "Failed to connect to AgentX server\n");
change_state(&Exit);
} else if(!(sess = snmp_sess_add_ex(
diff --git a/apps/snmptrap.c b/apps/snmptrap.c
index 7c086db..28d5257 100644
--- a/apps/snmptrap.c
+++ b/apps/snmptrap.c
@@ -215,7 +215,7 @@ main(int argc, char *argv[])
}
ss = snmp_add(&session,
- netsnmp_transport_open_client("snmptrap", session.peername),
+ netsnmp_transport_open_client("snmptrap", session.peername, NULL),
NULL, NULL);
if (ss == NULL) {
/*
diff --git a/apps/snmptrapd.c b/apps/snmptrapd.c
index bce0d47..122a502 100644
--- a/apps/snmptrapd.c
+++ b/apps/snmptrapd.c
@@ -1186,7 +1186,7 @@ main(int argc, char *argv[])
*sep = 0;
}
- transport = netsnmp_transport_open_server("snmptrap", cp);
+ transport = netsnmp_transport_open_server("snmptrap", cp, NULL);
if (transport == NULL) {
snmp_log(LOG_ERR, "couldn't open %s -- errno %d (\"%s\")\n",
cp, errno, strerror(errno));
diff --git a/include/net-snmp/library/snmpTCPDomain.h b/include/net-snmp/library/snmpTCPDomain.h
index c45856b..3b1fef5 100644
--- a/include/net-snmp/library/snmpTCPDomain.h
+++ b/include/net-snmp/library/snmpTCPDomain.h
@@ -25,7 +25,7 @@ extern "C" {
#define TRANSPORT_DOMAIN_TCP_IP 1,3,6,1,2,1,100,1,5
NETSNMP_IMPORT oid netsnmp_snmpTCPDomain[];
-netsnmp_transport *netsnmp_tcp_transport(struct sockaddr_in *addr, int local);
+netsnmp_transport *netsnmp_tcp_transport(struct sockaddr_in *addr, int local, char *iface);
/*
* "Constructor" for transport domain object.
diff --git a/include/net-snmp/library/snmpUDPBaseDomain.h b/include/net-snmp/library/snmpUDPBaseDomain.h
index b9d2c34..0ab2fe5 100644
--- a/include/net-snmp/library/snmpUDPBaseDomain.h
+++ b/include/net-snmp/library/snmpUDPBaseDomain.h
@@ -18,7 +18,7 @@ extern "C" {
/*
* Prototypes
*/
- void _netsnmp_udp_sockopt_set(int fd, int local);
+ void _netsnmp_udp_sockopt_set(int fd, int local, char *iface);
int netsnmp_udpbase_recv(netsnmp_transport *t, void *buf, int size,
void **opaque, int *olength);
int netsnmp_udpbase_send(netsnmp_transport *t, void *buf, int size,
diff --git a/include/net-snmp/library/snmpUDPDomain.h b/include/net-snmp/library/snmpUDPDomain.h
index 3a09dfd..e402cd8 100644
--- a/include/net-snmp/library/snmpUDPDomain.h
+++ b/include/net-snmp/library/snmpUDPDomain.h
@@ -18,7 +18,7 @@ extern "C" {
config_require(UDPIPv4Base)
#include <net-snmp/library/snmpUDPIPv4BaseDomain.h>
-netsnmp_transport *netsnmp_udp_transport(struct sockaddr_in *addr, int local);
+netsnmp_transport *netsnmp_udp_transport(struct sockaddr_in *addr, int local, char*iface);
/*
diff --git a/include/net-snmp/library/snmpUDPIPv4BaseDomain.h b/include/net-snmp/library/snmpUDPIPv4BaseDomain.h
index 6f7f2c2..8d3e906 100644
--- a/include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+++ b/include/net-snmp/library/snmpUDPIPv4BaseDomain.h
@@ -25,7 +25,7 @@ extern "C" {
*/
netsnmp_transport *netsnmp_udpipv4base_transport(struct sockaddr_in *addr,
- int local);
+ int local, char *iface);
#if defined(HAVE_IP_PKTINFO) || defined(HAVE_IP_RECVDSTADDR)
int netsnmp_udpipv4_recvfrom(int s, void *buf, int len,
diff --git a/include/net-snmp/library/snmpUDPIPv6Domain.h b/include/net-snmp/library/snmpUDPIPv6Domain.h
index 83eba2c..009c510 100644
--- a/include/net-snmp/library/snmpUDPIPv6Domain.h
+++ b/include/net-snmp/library/snmpUDPIPv6Domain.h
@@ -23,7 +23,7 @@ config_require(UDPBase)
NETSNMP_IMPORT oid netsnmp_UDPIPv6Domain[];
netsnmp_transport *netsnmp_udp6_transport(struct sockaddr_in6 *addr,
- int local);
+ int local, char *iface);
/*
diff --git a/include/net-snmp/library/snmp_transport.h b/include/net-snmp/library/snmp_transport.h
index 4162897..a3deda7 100644
--- a/include/net-snmp/library/snmp_transport.h
+++ b/include/net-snmp/library/snmp_transport.h
@@ -206,14 +206,14 @@ typedef struct netsnmp_tdomain_s {
* The f_create_from_tstring field is deprecated, please do not use it
* for new code and try to migrate old code away from using it.
*/
- netsnmp_transport *(*f_create_from_tstring) (const char *, int);
+ netsnmp_transport *(*f_create_from_tstring) (const char *, int, char *);
- netsnmp_transport *(*f_create_from_ostring) (const u_char *, size_t, int);
+ netsnmp_transport *(*f_create_from_ostring) (const u_char *, size_t, int, char *);
struct netsnmp_tdomain_s *next;
netsnmp_transport *(*f_create_from_tstring_new) (const char *, int,
- const char*);
+ const char*, char *);
} netsnmp_tdomain;
@@ -273,29 +273,32 @@ void netsnmp_tdomain_init(void);
NETSNMP_IMPORT
netsnmp_transport *netsnmp_tdomain_transport(const char *str,
int local,
- const char *default_domain);
+ const char *default_domain,
+ char *iface);
NETSNMP_IMPORT
netsnmp_transport *netsnmp_tdomain_transport_full(const char *application,
const char *str,
int local,
const char *default_domain,
- const char *default_target);
+ const char *default_target,
+ char *iface);
NETSNMP_IMPORT
netsnmp_transport *netsnmp_tdomain_transport_oid(const oid * dom,
size_t dom_len,
const u_char * o,
size_t o_len,
- int local);
+ int local,
+ char *iface);
NETSNMP_IMPORT
netsnmp_transport*
-netsnmp_transport_open_client(const char* application, const char* str);
+netsnmp_transport_open_client(const char* application, const char* str, char *iface);
NETSNMP_IMPORT
netsnmp_transport*
-netsnmp_transport_open_server(const char* application, const char* str);
+netsnmp_transport_open_server(const char* application, const char* str, char *iface);
netsnmp_transport*
netsnmp_transport_open(const char* application, const char* str, int local);
diff --git a/snmplib/snmp_api.c b/snmplib/snmp_api.c
index d155c99..5128c56 100644
--- a/snmplib/snmp_api.c
+++ b/snmplib/snmp_api.c
@@ -1557,12 +1557,12 @@ _sess_open(netsnmp_session * in_session)
transport =
netsnmp_tdomain_transport_full("snmp", in_session->peername,
in_session->local_port, "tcp,tcp6",
- NULL);
+ NULL, NULL);
} else {
transport =
netsnmp_tdomain_transport_full("snmp", in_session->peername,
in_session->local_port, "udp,udp6",
- NULL);
+ NULL, NULL);
}
if (NULL != clientaddr_save)
diff --git a/snmplib/snmp_transport.c b/snmplib/snmp_transport.c
index ada4781..40cd631 100644
--- a/snmplib/snmp_transport.c
+++ b/snmplib/snmp_transport.c
@@ -491,7 +491,8 @@ netsnmp_transport *
netsnmp_tdomain_transport_full(const char *application,
const char *str, int local,
const char *default_domain,
- const char *default_target)
+ const char *default_target,
+ char *iface)
{
netsnmp_tdomain *match = NULL;
const char *addr = NULL;
@@ -646,10 +647,10 @@ netsnmp_tdomain_transport_full(const char *application,
NETSNMP_LOGONCE((LOG_WARNING,
"transport domain %s uses deprecated f_create_from_tstring\n",
match->prefix[0]));
- t = match->f_create_from_tstring(addr, local);
+ t = match->f_create_from_tstring(addr, local, iface);
}
else
- t = match->f_create_from_tstring_new(addr, local, addr2);
+ t = match->f_create_from_tstring_new(addr, local, addr2, iface);
if (t) {
if (lspec) {
free(lspec[0]);
@@ -676,10 +677,11 @@ netsnmp_tdomain_transport_full(const char *application,
netsnmp_transport *
netsnmp_tdomain_transport(const char *str, int local,
- const char *default_domain)
+ const char *default_domain,
+ char *iface)
{
return netsnmp_tdomain_transport_full("snmp", str, local, default_domain,
- NULL);
+ NULL, iface);
}
@@ -687,7 +689,7 @@ netsnmp_tdomain_transport(const char *str, int local,
netsnmp_transport *
netsnmp_tdomain_transport_oid(const oid * dom,
size_t dom_len,
- const u_char * o, size_t o_len, int local)
+ const u_char * o, size_t o_len, int local, char *iface)
{
netsnmp_tdomain *d;
int i;
@@ -700,7 +702,7 @@ netsnmp_tdomain_transport_oid(const oid * dom,
for (i = 0; d->prefix[i] != NULL; i++) {
if (netsnmp_oid_equals(dom, dom_len, d->name, d->name_length) ==
0) {
- return d->f_create_from_ostring(o, o_len, local);
+ return d->f_create_from_ostring(o, o_len, local, iface);
}
}
}
@@ -713,19 +715,19 @@ netsnmp_tdomain_transport_oid(const oid * dom,
netsnmp_transport*
netsnmp_transport_open(const char* application, const char* str, int local)
{
- return netsnmp_tdomain_transport_full(application, str, local, NULL, NULL);
+ return netsnmp_tdomain_transport_full(application, str, local, NULL, NULL, NULL);
}
netsnmp_transport*
-netsnmp_transport_open_server(const char* application, const char* str)
+netsnmp_transport_open_server(const char* application, const char* str, char *iface)
{
- return netsnmp_tdomain_transport_full(application, str, 1, NULL, NULL);
+ return netsnmp_tdomain_transport_full(application, str, 1, NULL, NULL, iface);
}
netsnmp_transport*
-netsnmp_transport_open_client(const char* application, const char* str)
+netsnmp_transport_open_client(const char* application, const char* str, char *iface)
{
- return netsnmp_tdomain_transport_full(application, str, 0, NULL, NULL);
+ return netsnmp_tdomain_transport_full(application, str, 0, NULL, NULL, iface);
}
/** adds a transport to a linked list of transports.
diff --git a/snmplib/transports/snmpAliasDomain.c b/snmplib/transports/snmpAliasDomain.c
index eb50cad..dd7a007 100644
--- a/snmplib/transports/snmpAliasDomain.c
+++ b/snmplib/transports/snmpAliasDomain.c
@@ -75,7 +75,7 @@ free_alias_config(void) {
netsnmp_transport *
netsnmp_alias_create_tstring(const char *str, int local,
- const char *default_target)
+ const char *default_target, char *iface)
{
const char *aliasdata;
@@ -85,13 +85,13 @@ netsnmp_alias_create_tstring(const char *str, int local,
return NULL;
}
- return netsnmp_tdomain_transport(aliasdata,local,default_target);
+ return netsnmp_tdomain_transport(aliasdata,local,default_target, iface);
}
netsnmp_transport *
-netsnmp_alias_create_ostring(const u_char * o, size_t o_len, int local)
+netsnmp_alias_create_ostring(const u_char * o, size_t o_len, int local, char *iface)
{
fprintf(stderr, "make ostring\n");
return NULL;
diff --git a/snmplib/transports/snmpTCPDomain.c b/snmplib/transports/snmpTCPDomain.c
index 7feb028..6eb717e 100644
--- a/snmplib/transports/snmpTCPDomain.c
+++ b/snmplib/transports/snmpTCPDomain.c
@@ -144,7 +144,7 @@ netsnmp_tcp_accept(netsnmp_transport *t)
*/
netsnmp_transport *
-netsnmp_tcp_transport(struct sockaddr_in *addr, int local)
+netsnmp_tcp_transport(struct sockaddr_in *addr, int local, char *iface)
{
netsnmp_transport *t = NULL;
netsnmp_udp_addr_pair *addr_pair = NULL;
@@ -212,6 +212,11 @@ netsnmp_tcp_transport(struct sockaddr_in *addr, int local)
* We should set SO_REUSEADDR too.
*/
+ if (iface && setsockopt(t->sock, SOL_SOCKET, SO_BINDTODEVICE,
+ iface, strlen(iface)) == -1)
+ snmp_log(LOG_ERR, "Bind interface %s to socket: %s\n",
+ iface, strerror(errno));
+
setsockopt(t->sock, SOL_SOCKET, SO_REUSEADDR, (void *)&opt,
sizeof(opt));
@@ -305,12 +310,13 @@ netsnmp_tcp_transport(struct sockaddr_in *addr, int local)
netsnmp_transport *
netsnmp_tcp_create_tstring(const char *str, int local,
- const char *default_target)
+ const char *default_target,
+ char *iface)
{
struct sockaddr_in addr;
if (netsnmp_sockaddr_in2(&addr, str, default_target)) {
- return netsnmp_tcp_transport(&addr, local);
+ return netsnmp_tcp_transport(&addr, local, iface);
} else {
return NULL;
}
@@ -319,7 +325,7 @@ netsnmp_tcp_create_tstring(const char *str, int local,
netsnmp_transport *
-netsnmp_tcp_create_ostring(const u_char * o, size_t o_len, int local)
+netsnmp_tcp_create_ostring(const u_char * o, size_t o_len, int local, char *iface)
{
struct sockaddr_in addr;
@@ -328,7 +334,7 @@ netsnmp_tcp_create_ostring(const u_char * o, size_t o_len, int local)
addr.sin_family = AF_INET;
memcpy((u_char *) & (addr.sin_addr.s_addr), o, 4);
addr.sin_port = htons(porttmp);
- return netsnmp_tcp_transport(&addr, local);
+ return netsnmp_tcp_transport(&addr, local, iface);
}
return NULL;
}
diff --git a/snmplib/transports/snmpUDPBaseDomain.c b/snmplib/transports/snmpUDPBaseDomain.c
index 8497f71..7b415bc 100644
--- a/snmplib/transports/snmpUDPBaseDomain.c
+++ b/snmplib/transports/snmpUDPBaseDomain.c
@@ -21,6 +21,9 @@
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
+#if HAVE_NET_IF_H
+#include <net/if.h>
+#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
@@ -53,8 +56,14 @@
#endif
void
-_netsnmp_udp_sockopt_set(int fd, int local)
+_netsnmp_udp_sockopt_set(int fd, int local, char *iface)
{
+
+ if (iface && setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface)) == -1)
+ snmp_log(LOG_ERR, "Bind socket on interface: %s: %s\n", iface, strerror(errno));
+ else if (iface)
+ DEBUGMSGTL(("socket:option", "setting SO_BINDTODEVICE to %s\n", iface));
+
#ifdef SO_BSDCOMPAT
/*
* Patch for Linux. Without this, UDP packets that fail get an ICMP
@@ -237,7 +246,10 @@ int netsnmp_udpbase_sendto(int fd, struct in_addr *srcip, int if_index,
struct msghdr m = { 0 };
char cmsg[CMSG_SPACE(cmsg_data_size)];
int rc;
-
+ char iface[IFNAMSIZ];
+ socklen_t ifacelen = IFNAMSIZ;
+
+ iface[0] = '\0';
iov.iov_base = data;
iov.iov_len = len;
@@ -269,14 +281,23 @@ int netsnmp_udpbase_sendto(int fd, struct in_addr *srcip, int if_index,
memset(&ipi, 0, sizeof(ipi));
/*
- * Except in the case of responding
- * to a broadcast, setting the ifindex
- * when responding results in incorrect
- * behavior of changing the source address
- * that the manager sees the response
- * come from.
+ * For asymmetric multihomed users, we only set ifindex to 0
+ * to let kernel handle return if there was no iface bound to the socket.
*/
- ipi.ipi_ifindex = 0;
+ if (getsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, iface, &ifacelen) != 0) {
+ DEBUGMSGTL(("socket:option", "error getsockopt %s\n", strerror(errno)));
+ DEBUGMSGTL(("socket:option", "sendto: SO_BINDTODEVICE not set ifindex=0\n"));
+ ipi.ipi_ifindex = 0;
+ } else if (!ifacelen) {
+ DEBUGMSGTL(("socket:option", "sendto: SO_BINDTODEVICE not set ifacelen=%d ifindex=0\n",
+ ifacelen));
+ ipi.ipi_ifindex = 0;
+ } else {
+ DEBUGMSGTL(("socket:option", "sendto: SO_BINDTODEVICE dev=%s using ifindex=%d\n",
+ iface, if_index));
+ ipi.ipi_ifindex = if_index;
+ }
+
#if defined(cygwin)
ipi.ipi_addr.s_addr = srcip->s_addr;
#else
diff --git a/snmplib/transports/snmpUDPDomain.c b/snmplib/transports/snmpUDPDomain.c
index a0abd8c..fc68303 100644
--- a/snmplib/transports/snmpUDPDomain.c
+++ b/snmplib/transports/snmpUDPDomain.c
@@ -84,7 +84,7 @@ typedef netsnmp_indexed_addr_pair netsnmp_udp_addr_pair;
* not static, since snmpUDPIPv6Domain needs it, but not public, either.
* (ie don't put it in a public header.)
*/
-void _netsnmp_udp_sockopt_set(int fd, int server);
+void _netsnmp_udp_sockopt_set(int fd, int server, char *iface);
int
netsnmp_sockaddr_in2(struct sockaddr_in *addr,
const char *inpeername, const char *default_target);
@@ -125,11 +125,11 @@ int netsnmp_udp_sendto(int fd, struct in_addr *srcip, int if_index, struct socka
*/
netsnmp_transport *
-netsnmp_udp_transport(struct sockaddr_in *addr, int local)
+netsnmp_udp_transport(struct sockaddr_in *addr, int local, char *iface)
{
netsnmp_transport *t = NULL;
- t = netsnmp_udpipv4base_transport(addr, local);
+ t = netsnmp_udpipv4base_transport(addr, local, iface);
if (NULL == t) {
return NULL;
}
@@ -473,12 +473,13 @@ netsnmp_udp_getSecName(void *opaque, int olength,
netsnmp_transport *
netsnmp_udp_create_tstring(const char *str, int local,
- const char *default_target)
+ const char *default_target,
+ char *iface)
{
struct sockaddr_in addr;
if (netsnmp_sockaddr_in2(&addr, str, default_target)) {
- return netsnmp_udp_transport(&addr, local);
+ return netsnmp_udp_transport(&addr, local, iface);
} else {
return NULL;
}
@@ -486,7 +487,7 @@ netsnmp_udp_create_tstring(const char *str, int local,
netsnmp_transport *
-netsnmp_udp_create_ostring(const u_char * o, size_t o_len, int local)
+netsnmp_udp_create_ostring(const u_char * o, size_t o_len, int local, char *iface)
{
struct sockaddr_in addr;
@@ -495,7 +496,7 @@ netsnmp_udp_create_ostring(const u_char * o, size_t o_len, int local)
addr.sin_family = AF_INET;
memcpy((u_char *) & (addr.sin_addr.s_addr), o, 4);
addr.sin_port = htons(porttmp);
- return netsnmp_udp_transport(&addr, local);
+ return netsnmp_udp_transport(&addr, local, iface);
}
return NULL;
}
diff --git a/snmplib/transports/snmpUDPIPv4BaseDomain.c b/snmplib/transports/snmpUDPIPv4BaseDomain.c
index 8c0fb05..7991b6a 100644
--- a/snmplib/transports/snmpUDPIPv4BaseDomain.c
+++ b/snmplib/transports/snmpUDPIPv4BaseDomain.c
@@ -57,7 +57,7 @@ int netsnmp_udpipv4_sendto(int fd, struct in_addr *srcip, int if_index,
#endif /* HAVE_IP_PKTINFO || HAVE_IP_RECVDSTADDR */
netsnmp_transport *
-netsnmp_udpipv4base_transport(struct sockaddr_in *addr, int local)
+netsnmp_udpipv4base_transport(struct sockaddr_in *addr, int local, char *iface)
{
netsnmp_transport *t = NULL;
int rc = 0, rc2;
@@ -95,7 +95,7 @@ netsnmp_udpipv4base_transport(struct sockaddr_in *addr, int local)
return NULL;
}
- _netsnmp_udp_sockopt_set(t->sock, local);
+ _netsnmp_udp_sockopt_set(t->sock, local, iface);
if (local) {
#ifndef NETSNMP_NO_LISTEN_SUPPORT
diff --git a/snmplib/transports/snmpUDPIPv6Domain.c b/snmplib/transports/snmpUDPIPv6Domain.c
index 18de876..6b44b22 100644
--- a/snmplib/transports/snmpUDPIPv6Domain.c
+++ b/snmplib/transports/snmpUDPIPv6Domain.c
@@ -74,12 +74,6 @@ oid netsnmp_UDPIPv6Domain[] = { TRANSPORT_DOMAIN_UDP_IPV6 };
static netsnmp_tdomain udp6Domain;
/*
- * from snmpUDPDomain. not static, but not public, either.
- * (ie don't put it in a public header.)
- */
-extern void _netsnmp_udp_sockopt_set(int fd, int server);
-
-/*
* Return a string representing the address in data, or else the "far end"
* address if data is NULL.
*/
@@ -186,7 +186,7 @@ netsnmp_udp6_send(netsnmp_transport *t, void *buf, int size,
*/
netsnmp_transport *
-netsnmp_udp6_transport(struct sockaddr_in6 *addr, int local)
+netsnmp_udp6_transport(struct sockaddr_in6 *addr, int local, char *iface)
{
netsnmp_transport *t = NULL;
int rc = 0;
@@ -223,7 +223,7 @@ netsnmp_udp6_transport(struct sockaddr_in6 *addr, int local)
return NULL;
}
- _netsnmp_udp_sockopt_set(t->sock, local);
+ _netsnmp_udp_sockopt_set(t->sock, local, iface);
if (local) {
#ifndef NETSNMP_NO_LISTEN_SUPPORT
@@ -724,12 +724,13 @@ netsnmp_udp6_getSecName(void *opaque, int olength,
netsnmp_transport *
netsnmp_udp6_create_tstring(const char *str, int local,
- const char *default_target)
+ const char *default_target,
+ char *iface)
{
struct sockaddr_in6 addr;
if (netsnmp_sockaddr_in6_2(&addr, str, default_target)) {
- return netsnmp_udp6_transport(&addr, local);
+ return netsnmp_udp6_transport(&addr, local, iface);
} else {
return NULL;
}
@@ -746,7 +747,7 @@ netsnmp_udp6_create_tstring(const char *str, int local,
*/
netsnmp_transport *
-netsnmp_udp6_create_ostring(const u_char * o, size_t o_len, int local)
+netsnmp_udp6_create_ostring(const u_char * o, size_t o_len, int local, char *iface)
{
struct sockaddr_in6 addr;
@@ -755,7 +756,7 @@ netsnmp_udp6_create_ostring(const u_char * o, size_t o_len, int local)
addr.sin6_family = AF_INET6;
memcpy((u_char *) & (addr.sin6_addr.s6_addr), o, 16);
addr.sin6_port = htons((o[16] << 8) + o[17]);
- return netsnmp_udp6_transport(&addr, local);
+ return netsnmp_udp6_transport(&addr, local, iface);
}
return NULL;
}
diff --git a/snmplib/transports/snmpUnixDomain.c b/snmplib/transports/snmpUnixDomain.c
index 47dffc1..af56c5d 100644
--- a/snmplib/transports/snmpUnixDomain.c
+++ b/snmplib/transports/snmpUnixDomain.c
@@ -450,7 +450,8 @@ netsnmp_unix_transport(struct sockaddr_un *addr, int local)
netsnmp_transport *
netsnmp_unix_create_tstring(const char *string, int local,
- const char *default_target)
+ const char *default_target,
+ char *iface)
{
struct sockaddr_un addr;
@@ -476,7 +477,7 @@ netsnmp_unix_create_tstring(const char *string, int local,
netsnmp_transport *
-netsnmp_unix_create_ostring(const u_char * o, size_t o_len, int local)
+netsnmp_unix_create_ostring(const u_char * o, size_t o_len, int local, char *iface)
{
struct sockaddr_un addr;
--
2.7.4

View File

@ -0,0 +1,22 @@
From 6e038423d7a3269dbfd85b3d7ada6015479f1559 Mon Sep 17 00:00:00 2001
From: Qi Luo <qiluo-msft@users.noreply.github.com>
Date: Fri, 20 Sep 2019 00:42:19 +0000
Subject: [PATCH] Enable macro DEB_BUILD_ARCH_OS in order to build ipv6 feature
---
debian/rules | 1 +
1 file changed, 1 insertion(+)
diff --git a/debian/rules b/debian/rules
index 4c3b5b6..1fab6a4 100755
--- a/debian/rules
+++ b/debian/rules
@@ -4,4 +4,5 @@
export DEB_BUILD_MAINT_OPTIONS := hardening=+all
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
+DEB_BUILD_ARCH_OS ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS)
LIB_VERSION = 40
--
2.18.0

View File

@ -0,0 +1,5 @@
0001-SNMP-Stop-spamming-logs-with-statfs-permission-denie.patch
#0002-at.c-properly-check-return-status-from-realloc.-Than.patch
#0006-From-Jiri-Cervenka-snmpd-Fixed-agentx-crashing-and-or-freezing-on-timeout.patch
#0007-Linux-VRF-5.7.3-Support.patch
0008-Enable-macro-DEB_BUILD_ARCH_OS-in-order-to-build-ipv.patch