When I fixed the fmtaddr implementation in several Net-SNMP transports I
hadn't noticed that these changes broke the target MIB. Hence this patch
that fixes the target MIB.

See also https://sourceforge.net/p/net-snmp/bugs/2871/.

Reported-by: Anders Wallin <wayl...@users.sourceforge.net>
Fixes: 3bd8dc8b2d90 ("snmplib/transports: Avoid that the create_from_ostring 
methods truncate IPv6 addresses")
---
 .../notification/snmpNotifyTable_data.c       |  6 ++-
 agent/mibgroup/target/snmpTargetAddrEntry.c   |  6 +--
 .../target/snmpTargetAddrEntry_data.h         |  2 +-
 include/net-snmp/library/snmpIPv4BaseDomain.h |  4 ++
 include/net-snmp/library/snmpIPv6BaseDomain.h |  6 +++
 include/net-snmp/library/snmp_transport.h     |  9 +++-
 snmplib/transports/snmpAAL5PVCDomain.c        | 41 ++++++++++++++++++-
 snmplib/transports/snmpDTLSUDPDomain.c        | 13 ++++--
 snmplib/transports/snmpIPXDomain.c            | 34 +++++++++++++--
 snmplib/transports/snmpIPv4BaseDomain.c       | 26 ++++++++++++
 snmplib/transports/snmpIPv6BaseDomain.c       | 27 ++++++++++++
 snmplib/transports/snmpSSHDomain.c            | 22 +++++++++-
 snmplib/transports/snmpSTDDomain.c            |  8 +++-
 snmplib/transports/snmpTCPDomain.c            |  7 +++-
 snmplib/transports/snmpTCPIPv6Domain.c        |  7 +++-
 snmplib/transports/snmpTLSTCPDomain.c         |  9 ++++
 snmplib/transports/snmpUDPDomain.c            |  7 +++-
 snmplib/transports/snmpUDPIPv6Domain.c        |  7 +++-
 snmplib/transports/snmpUDPsharedDomain.c      | 17 ++++++--
 snmplib/transports/snmpUnixDomain.c           |  8 +++-
 20 files changed, 238 insertions(+), 28 deletions(-)

diff --git a/agent/mibgroup/notification/snmpNotifyTable_data.c 
b/agent/mibgroup/notification/snmpNotifyTable_data.c
index c14b892ffcf7..9a2b42f98734 100644
--- a/agent/mibgroup/notification/snmpNotifyTable_data.c
+++ b/agent/mibgroup/notification/snmpNotifyTable_data.c
@@ -344,8 +344,10 @@ notifyTable_register_notifications(int major, int minor,
     ptr->nameData = netsnmp_memdup_nt(name, nameLen, &ptr->nameLen);
     memcpy(ptr->tDomain, t->domain, t->domain_length * sizeof(oid));
     ptr->tDomainLen = t->domain_length;
-    ptr->tAddressLen = t->remote_length;
-    ptr->tAddress = t->remote;
+    if (t->f_get_taddr)
+        t->f_get_taddr(t, &ptr->tAddress, &ptr->tAddressLen);
+    else
+        netsnmp_assert(0);
 
     ptr->timeout = ss->timeout / 1000;
     ptr->retryCount = ss->retries;
diff --git a/agent/mibgroup/target/snmpTargetAddrEntry.c 
b/agent/mibgroup/target/snmpTargetAddrEntry.c
index 66d186633073..03adb2610ec2 100644
--- a/agent/mibgroup/target/snmpTargetAddrEntry.c
+++ b/agent/mibgroup/target/snmpTargetAddrEntry.c
@@ -385,9 +385,9 @@ write_snmpTargetAddrTAddress(int action,
                 return SNMP_ERR_INCONSISTENTVALUE;
             }
 
-            old_addr = (char *) target->tAddress;
+            old_addr = target->tAddress;
             old_len = target->tAddressLen;
-            target->tAddress = (u_char *) malloc(var_val_len);
+            target->tAddress = malloc(var_val_len);
             if (target->tAddress == NULL) {
                 return SNMP_ERR_RESOURCEUNAVAILABLE;
             }
@@ -419,7 +419,7 @@ write_snmpTargetAddrTAddress(int action,
             if (target->storageType != SNMP_STORAGE_READONLY
                 && target->rowStatus != SNMP_ROW_ACTIVE) {
                 SNMP_FREE(target->tAddress);
-                target->tAddress = (u_char *) old_addr;
+                target->tAddress = old_addr;
                 target->tAddressLen = old_len;
                 if (target->rowStatus == SNMP_ROW_NOTINSERVICE &&
                     snmpTargetAddr_rowStatusCheck(target) == 0) {
diff --git a/agent/mibgroup/target/snmpTargetAddrEntry_data.h 
b/agent/mibgroup/target/snmpTargetAddrEntry_data.h
index 4d0e23d7a545..0af434e8d7e4 100644
--- a/agent/mibgroup/target/snmpTargetAddrEntry_data.h
+++ b/agent/mibgroup/target/snmpTargetAddrEntry_data.h
@@ -44,7 +44,7 @@
          size_t          nameLen;
          oid             tDomain[MAX_OID_LEN];
          int             tDomainLen;
-         unsigned char  *tAddress;
+         void           *tAddress;
          size_t          tAddressLen;
          int             timeout;      /* Timeout in centiseconds */
          int             retryCount;
diff --git a/include/net-snmp/library/snmpIPv4BaseDomain.h 
b/include/net-snmp/library/snmpIPv4BaseDomain.h
index cbeee85641ba..cb6a4585cf48 100644
--- a/include/net-snmp/library/snmpIPv4BaseDomain.h
+++ b/include/net-snmp/library/snmpIPv4BaseDomain.h
@@ -19,6 +19,10 @@ extern          "C" {
 
     char *netsnmp_ipv4_fmtaddr(const char *prefix, netsnmp_transport *t,
                                const void *data, int len);
+    void netsnmp_ipv4_get_taddr(struct netsnmp_transport_s *t, void **addr,
+                                size_t *addr_len);
+    int netsnmp_ipv4_ostring_to_sockaddr(struct sockaddr_in *sin,
+                                         const void *o, size_t o_len);
 
 /*
  * Convert a "traditional" peername into a sockaddr_in structure which is
diff --git a/include/net-snmp/library/snmpIPv6BaseDomain.h 
b/include/net-snmp/library/snmpIPv6BaseDomain.h
index cf424eb16655..8f67ee62f7f4 100644
--- a/include/net-snmp/library/snmpIPv6BaseDomain.h
+++ b/include/net-snmp/library/snmpIPv6BaseDomain.h
@@ -21,6 +21,12 @@ extern          "C" {
     char *netsnmp_ipv6_fmtaddr(const char *prefix, netsnmp_transport *t,
                                const void *data, int len);
     NETSNMP_IMPORT
+    void netsnmp_ipv6_get_taddr(struct netsnmp_transport_s *t, void **addr,
+                                size_t *addr_len);
+    NETSNMP_IMPORT
+    int netsnmp_ipv6_ostring_to_sockaddr(struct sockaddr_in6 *sin6,
+                                         const void *o, size_t o_len);
+    NETSNMP_IMPORT
     int netsnmp_sockaddr_in6_2(struct sockaddr_in6 *addr,
                                const char *inpeername,
                                const char *default_target);
diff --git a/include/net-snmp/library/snmp_transport.h 
b/include/net-snmp/library/snmp_transport.h
index a514c581181d..e361624a4566 100644
--- a/include/net-snmp/library/snmp_transport.h
+++ b/include/net-snmp/library/snmp_transport.h
@@ -213,6 +213,11 @@ typedef struct netsnmp_transport_s {
     /* allocated host name identifier; used by configuration system
        to load localhost.conf for host-specific configuration */
     u_char         *identifier; /* udp:localhost:161 -> "localhost" */
+
+    /* Get the remote address in the format required by SNMP-TARGET-MIB */
+    void           (*f_get_taddr)(struct netsnmp_transport_s *t,
+                                  void **addr, size_t *addr_len);
+
 } netsnmp_transport;
 
 typedef struct netsnmp_transport_list_s {
@@ -232,7 +237,9 @@ typedef struct netsnmp_tdomain_s {
      */
     netsnmp_transport *(*f_create_from_tstring) (const char *, int);
 
-    netsnmp_transport *(*f_create_from_ostring) (const void *, size_t, int);
+    /* @o and @o_len define an address in the format used by SNMP-TARGET-MIB */
+    netsnmp_transport *(*f_create_from_ostring) (const void *o, size_t o_len,
+                                                 int local);
 
     struct netsnmp_tdomain_s *next;
 
diff --git a/snmplib/transports/snmpAAL5PVCDomain.c 
b/snmplib/transports/snmpAAL5PVCDomain.c
index ccc550031555..2d28f268b505 100644
--- a/snmplib/transports/snmpAAL5PVCDomain.c
+++ b/snmplib/transports/snmpAAL5PVCDomain.c
@@ -67,7 +67,25 @@ netsnmp_aal5pvc_fmtaddr(netsnmp_transport *t, const void 
*data, int len)
     }
 }
 
-
+static void
+netsnmp_aal5pvc_get_taddr(netsnmp_transport *t, void **addr, size_t *addr_len)
+{
+    struct sockaddr_atmpvc *sa = t->remote;
+    unsigned char *p;
+
+    *addr_len = 8;
+    if (!(*addr = malloc(*addr_len)))
+        return;
+    p = *addr;
+    p[0] = sa->sap_addr.itf >> 8;
+    p[1] = sa->sap_addr.itf >> 0;
+    p[2] = sa->sap_addr.vpi >> 8;
+    p[3] = sa->sap_addr.vpi >> 0;
+    p[4] = sa->sap_addr.vci >> 24;
+    p[5] = sa->sap_addr.vci >> 16;
+    p[6] = sa->sap_addr.vci >> 8;
+    p[7] = sa->sap_addr.vci >> 0;
+}
 
 /*
  * You can write something into opaque that will subsequently get passed back 
@@ -285,6 +303,7 @@ netsnmp_aal5pvc_transport(const struct sockaddr_atmpvc 
*addr, int local)
     t->f_close    = netsnmp_aal5pvc_close;
     t->f_accept   = NULL;
     t->f_fmtaddr  = netsnmp_aal5pvc_fmtaddr;
+    t->f_get_taddr = netsnmp_aal5pvc_get_taddr;
 
     return t;
 }
@@ -322,12 +341,30 @@ netsnmp_aal5pvc_create_tstring(const char *str, int local,
     }
 }
 
+static int netsnmp_aal5pvc_ostring_to_sockaddr(struct sockaddr_atmpvc *sa,
+                                               const void *o, size_t o_len)
+{
+    const unsigned char *p = o;
 
+    if (o_len != 8)
+        return 0;
+
+    memset(sa, 0, sizeof(*sa));
+    sa->sap_family = AF_ATMPVC;
+    sa->sap_addr.itf = (p[0] << 8) + (p[1] << 0);
+    sa->sap_addr.vpi = (p[2] << 8) + (p[3] << 0);
+    sa->sap_addr.vci = (p[4] << 24) + (p[5] << 16) + (p[6] << 8) + (p[7] << 0);
+    return 1;
+}
 
 netsnmp_transport *
 netsnmp_aal5pvc_create_ostring(const void *o, size_t o_len, int local)
 {
-    return netsnmp_aal5pvc_transport(o, local);
+    struct sockaddr_atmpvc sa;
+
+    if (netsnmp_aal5pvc_ostring_to_sockaddr(&sa, o, o_len))
+        return netsnmp_aal5pvc_transport(&sa, local);
+    return NULL;
 }
 
 
diff --git a/snmplib/transports/snmpDTLSUDPDomain.c 
b/snmplib/transports/snmpDTLSUDPDomain.c
index 7df7af90b76d..96860b8358d0 100644
--- a/snmplib/transports/snmpDTLSUDPDomain.c
+++ b/snmplib/transports/snmpDTLSUDPDomain.c
@@ -1486,6 +1486,7 @@ _transport_common(netsnmp_transport *t, int local)
     t->f_setup_session = netsnmp_tlsbase_session_init;
     t->f_accept        = NULL;
     t->f_fmtaddr       = netsnmp_dtlsudp4_fmtaddr;
+    t->f_get_taddr     = netsnmp_ipv4_get_taddr;
 
     t->flags = NETSNMP_TRANSPORT_FLAG_TUNNELED;
 
@@ -1553,6 +1554,7 @@ netsnmp_dtlsudp6_transport(const struct sockaddr_in6 
*addr, int local)
     /* XXX: and buf size */        
 
     t->f_fmtaddr       = netsnmp_dtlsudp6_fmtaddr;
+    t->f_get_taddr     = netsnmp_ipv6_get_taddr;
 
     return t;
 }
@@ -1601,11 +1603,14 @@ netsnmp_dtlsudp_create_tstring(const char *str, int 
isserver,
 netsnmp_transport *
 netsnmp_dtlsudp_create_ostring(const void *o, size_t o_len, int local)
 {
-    if (o_len == sizeof(struct sockaddr_in))
-        return netsnmp_dtlsudp_transport(o, local);
+    struct sockaddr_in sin;
+    struct sockaddr_in6 sin6;
+
+    if (netsnmp_ipv4_ostring_to_sockaddr(&sin, o, o_len))
+        return netsnmp_dtlsudp_transport(&sin, local);
 #ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
-    else if (o_len == sizeof(struct sockaddr_in6))
-        return netsnmp_dtlsudp6_transport(o, local);
+    else if (netsnmp_ipv6_ostring_to_sockaddr(&sin6, o, o_len))
+        return netsnmp_dtlsudp6_transport(&sin6, local);
 #endif
     else
         return NULL;
diff --git a/snmplib/transports/snmpIPXDomain.c 
b/snmplib/transports/snmpIPXDomain.c
index ce5b85e0bd8d..55070476ce1e 100644
--- a/snmplib/transports/snmpIPXDomain.c
+++ b/snmplib/transports/snmpIPXDomain.c
@@ -33,6 +33,7 @@
 #include <net-snmp/output_api.h>
 #include <net-snmp/config_api.h>
 
+#include <net-snmp/library/snmp_assert.h>
 #include <net-snmp/library/snmp_transport.h>
 #include <net-snmp/library/tools.h>
 
@@ -69,7 +70,19 @@ netsnmp_ipx_fmtaddr(netsnmp_transport *t, const void *data, 
int len)
     }
 }
 
-
+static void netsnmp_ipx_get_taddr(struct netsnmp_transport_s *t,
+                                  void **addr, size_t *addr_len)
+{
+    struct sockaddr_ipx *sa = t->remote;
+
+    netsnmp_assert(t->remote_length == sizeof(*sa));
+    *addr_len = 12;
+    if ((*addr = malloc(*addr_len))) {
+        memcpy(*addr + 0,  &sa->sipx_network, 4);
+        memcpy(*addr + 4,  &sa->sipx_node,    6);
+        memcpy(*addr + 10, &sa->sipx_port,    2);
+    }
+}
 
 /*
  * You can write something into opaque that will subsequently get passed back 
@@ -276,6 +289,7 @@ netsnmp_ipx_transport(const struct sockaddr_ipx *addr, int 
local)
     t->f_close    = netsnmp_ipx_close;
     t->f_accept   = NULL;
     t->f_fmtaddr  = netsnmp_ipx_fmtaddr;
+    t->f_get_taddr = netsnmp_ipx_get_taddr;
 
     return t;
 }
@@ -430,13 +444,27 @@ netsnmp_ipx_create_tstring(const char *str, int local,
     }
 }
 
+static int netsnmp_ipx_ostring_to_sockaddr(struct sockaddr_ipx *sa,
+                                           const void *o, size_t o_len)
+{
+    if (o_len != 12)
+        return 0;
 
+    memset(sa, 0, sizeof(*sa));
+    sa->sipx_family = AF_IPX;
+    memcpy(&sa->sipx_network, o + 0, 4);
+    memcpy(&sa->sipx_node,    o + 4, 6);
+    memcpy(&sa->sipx_port,    o + 10, 2);
+    return 1;
+}
 
 netsnmp_transport *
 netsnmp_ipx_create_ostring(const void *o, size_t o_len, int local)
 {
-    if (o_len == sizeof(struct sockaddr_ipx))
-        return netsnmp_ipx_transport(o, local);
+    struct sockaddr_ipx sa;
+
+    if (netsnmp_ipx_ostring_to_sockaddr(&sa, o, o_len))
+        return netsnmp_ipx_transport(&sa, local);
 
     return NULL;
 }
diff --git a/snmplib/transports/snmpIPv4BaseDomain.c 
b/snmplib/transports/snmpIPv4BaseDomain.c
index 910bb56234db..fafc1ab8045c 100644
--- a/snmplib/transports/snmpIPv4BaseDomain.c
+++ b/snmplib/transports/snmpIPv4BaseDomain.c
@@ -242,3 +242,29 @@ netsnmp_ipv4_fmtaddr(const char *prefix, netsnmp_transport 
*t,
     return tmp;
 }
 
+void netsnmp_ipv4_get_taddr(struct netsnmp_transport_s *t, void **addr,
+                            size_t *addr_len)
+{
+    struct sockaddr_in *sin = t->remote;
+
+    netsnmp_assert(t->remote_length == sizeof(*sin));
+
+    *addr_len = 6;
+    if ((*addr = malloc(*addr_len))) {
+        memcpy(*addr,     &sin->sin_addr, 4);
+        memcpy(*addr + 4, &sin->sin_port, 2);
+    }
+}
+
+int netsnmp_ipv4_ostring_to_sockaddr(struct sockaddr_in *sin, const void *o,
+                                     size_t o_len)
+{
+    if (o_len != 6)
+        return 0;
+
+    memset(sin, 0, sizeof(*sin));
+    sin->sin_family = AF_INET;
+    memcpy(&sin->sin_addr, o + 0, 4);
+    memcpy(&sin->sin_port, o + 4, 2);
+    return 1;
+}
diff --git a/snmplib/transports/snmpIPv6BaseDomain.c 
b/snmplib/transports/snmpIPv6BaseDomain.c
index 4336b6a6ae9d..c4a801f87228 100644
--- a/snmplib/transports/snmpIPv6BaseDomain.c
+++ b/snmplib/transports/snmpIPv6BaseDomain.c
@@ -151,6 +151,33 @@ netsnmp_ipv6_fmtaddr(const char *prefix, netsnmp_transport 
*t,
     return tmp;
 }
 
+void netsnmp_ipv6_get_taddr(struct netsnmp_transport_s *t, void **addr,
+                            size_t *addr_len)
+{
+    struct sockaddr_in6 *sin6 = t->remote;
+
+    netsnmp_assert(t->remote_length == sizeof(*sin6));
+
+    *addr_len = 18;
+    if ((*addr = malloc(*addr_len))) {
+        memcpy(*addr,      &sin6->sin6_addr, 16);
+        memcpy(*addr + 16, &sin6->sin6_port, 2);
+    }
+}
+
+int netsnmp_ipv6_ostring_to_sockaddr(struct sockaddr_in6 *sin6, const void *o,
+                                     size_t o_len)
+{
+    if (o_len != 18)
+        return 0;
+
+    memset(sin6, 0, sizeof(*sin6));
+    sin6->sin6_family = AF_INET6;
+    memcpy(&sin6->sin6_addr, o + 0,  16);
+    memcpy(&sin6->sin6_port, o + 16, 2);
+    return 1;
+}
+
 int
 netsnmp_sockaddr_in6_2(struct sockaddr_in6 *addr,
                        const char *inpeername, const char *default_target)
diff --git a/snmplib/transports/snmpSSHDomain.c 
b/snmplib/transports/snmpSSHDomain.c
index 3ca4f81c9f93..3854e00b2889 100644
--- a/snmplib/transports/snmpSSHDomain.c
+++ b/snmplib/transports/snmpSSHDomain.c
@@ -123,7 +123,18 @@ netsnmp_ssh_fmtaddr(netsnmp_transport *t, const void 
*data, int len)
     }
 }
 
-
+static void netsnmp_ssh_get_taddr(struct netsnmp_transport_s *t,
+                                  void **addr, size_t *addr_len)
+{
+    switch (t->remote_length) {
+    case sizeof(sockaddr_in):
+        netsnmp_ipv4_get_taddr(t, addr, addr_len);
+        break;
+    default:
+        *addr = NULL;
+        netsnmp_assert(0);
+    }
+}
 
 /*
  * You can write something into opaque that will subsequently get passed back 
@@ -883,6 +894,7 @@ netsnmp_ssh_transport(const struct sockaddr_in *addr, int 
local)
     t->f_close    = netsnmp_ssh_close;
     t->f_accept   = netsnmp_ssh_accept;
     t->f_fmtaddr  = netsnmp_ssh_fmtaddr;
+    t->f_get_taddr = netsnmp_ssh_get_taddr;
 
     return t;
 }
@@ -907,7 +919,13 @@ netsnmp_ssh_create_tstring(const char *str, int local,
 netsnmp_transport *
 netsnmp_ssh_create_ostring(const void *o, size_t o_len, int local)
 {
-    return netsnmp_ssh_transport(o, local);
+    struct sockaddr_in sin;
+
+    if (netsnmp_ipv4_ostring_to_sockaddr(&sin, o, o_len))
+        return netsnmp_ssh_transport(&sin, local);
+    else
+        netsnmp_assert(0);
+    return NULL;
 }
 
 void
diff --git a/snmplib/transports/snmpSTDDomain.c 
b/snmplib/transports/snmpSTDDomain.c
index 5845f25937c6..d85eb9e85a5e 100644
--- a/snmplib/transports/snmpSTDDomain.c
+++ b/snmplib/transports/snmpSTDDomain.c
@@ -53,7 +53,12 @@ netsnmp_std_fmtaddr(netsnmp_transport *t, const void *data, 
int len)
     return strdup("STDInOut");
 }
 
-
+static void
+netsnmp_std_get_taddr(netsnmp_transport *t, void **addr, size_t *addr_len)
+{
+    *addr_len = t->remote_length;
+    *addr = netsnmp_memdup(t->remote, *addr_len);
+}
 
 /*
  * You can write something into opaque that will subsequently get passed back 
@@ -176,6 +181,7 @@ netsnmp_std_transport(const char *instring, size_t 
instring_len,
     t->f_close    = netsnmp_std_close;
     t->f_accept   = netsnmp_std_accept;
     t->f_fmtaddr  = netsnmp_std_fmtaddr;
+    t->f_get_taddr = netsnmp_std_get_taddr;
 
     /*
      * if instring is not null length, it specifies a path to a prog
diff --git a/snmplib/transports/snmpTCPDomain.c 
b/snmplib/transports/snmpTCPDomain.c
index 00ad39af03cf..edfecdd6360c 100644
--- a/snmplib/transports/snmpTCPDomain.c
+++ b/snmplib/transports/snmpTCPDomain.c
@@ -310,6 +310,7 @@ netsnmp_tcp_transport(const struct sockaddr_in *addr, int 
local)
     t->f_close    = netsnmp_socketbase_close;
     t->f_accept   = netsnmp_tcp_accept;
     t->f_fmtaddr  = netsnmp_tcp_fmtaddr;
+    t->f_get_taddr = netsnmp_ipv4_get_taddr;
 
     return t;
 }
@@ -334,7 +335,11 @@ netsnmp_tcp_create_tstring(const char *str, int local,
 netsnmp_transport *
 netsnmp_tcp_create_ostring(const void *o, size_t o_len, int local)
 {
-    return netsnmp_tcp_transport(o, local);
+    struct sockaddr_in sin;
+
+    if (netsnmp_ipv4_ostring_to_sockaddr(&sin, o, o_len))
+        return netsnmp_tcp_transport(&sin, local);
+    return NULL;
 }
 
 
diff --git a/snmplib/transports/snmpTCPIPv6Domain.c 
b/snmplib/transports/snmpTCPIPv6Domain.c
index bdd5c2906835..07fa6af51278 100644
--- a/snmplib/transports/snmpTCPIPv6Domain.c
+++ b/snmplib/transports/snmpTCPIPv6Domain.c
@@ -316,6 +316,7 @@ netsnmp_tcp6_transport(const struct sockaddr_in6 *addr, int 
local)
     t->f_close    = netsnmp_socketbase_close;
     t->f_accept   = netsnmp_tcp6_accept;
     t->f_fmtaddr  = netsnmp_tcp6_fmtaddr;
+    t->f_get_taddr = netsnmp_ipv6_get_taddr;
 
     return t;
 }
@@ -346,7 +347,11 @@ netsnmp_tcp6_create_tstring(const char *str, int local,
 netsnmp_transport *
 netsnmp_tcp6_create_ostring(const void *o, size_t o_len, int local)
 {
-    return netsnmp_tcp6_transport(o, local);
+    struct sockaddr_in6 sin6;
+
+    if (netsnmp_ipv6_ostring_to_sockaddr(&sin6, o, o_len))
+        return netsnmp_tcp6_transport(&sin6, local);
+    return NULL;
 }
 
 
diff --git a/snmplib/transports/snmpTLSTCPDomain.c 
b/snmplib/transports/snmpTLSTCPDomain.c
index 550dcad61431..df7086ed8d98 100644
--- a/snmplib/transports/snmpTLSTCPDomain.c
+++ b/snmplib/transports/snmpTLSTCPDomain.c
@@ -124,6 +124,14 @@ netsnmp_tlstcp_fmtaddr(netsnmp_transport *t, const void 
*data, int len)
     }
     }
 }
+
+static void netsnmp_tlstcp_get_taddr(struct netsnmp_transport_s *t,
+                                     void **addr, size_t *addr_len)
+{
+    *addr_len = t->remote_length;
+    *addr = netsnmp_memdup(t->remote, *addr_len);
+}
+
 /*
  * You can write something into opaque that will subsequently get passed back 
  * to your send function if you like.  For instance, you might want to
@@ -986,6 +994,7 @@ netsnmp_tlstcp_transport(const char *addr_string, int 
isserver)
     t->f_config        = netsnmp_tlsbase_config;
     t->f_setup_session = netsnmp_tlsbase_session_init;
     t->f_fmtaddr       = netsnmp_tlstcp_fmtaddr;
+    t->f_get_taddr     = netsnmp_tlstcp_get_taddr;
 
     t->flags |= NETSNMP_TRANSPORT_FLAG_TUNNELED | 
NETSNMP_TRANSPORT_FLAG_STREAM;
 
diff --git a/snmplib/transports/snmpUDPDomain.c 
b/snmplib/transports/snmpUDPDomain.c
index 7543b3419a7a..2dd812d40b48 100644
--- a/snmplib/transports/snmpUDPDomain.c
+++ b/snmplib/transports/snmpUDPDomain.c
@@ -146,6 +146,7 @@ netsnmp_udp_transport_base(netsnmp_transport *t)
     t->f_close    = netsnmp_socketbase_close;
     t->f_accept   = NULL;
     t->f_fmtaddr  = netsnmp_udp_fmtaddr;
+    t->f_get_taddr = netsnmp_ipv4_get_taddr;
 
     return t;
 }
@@ -628,7 +629,11 @@ netsnmp_udp_create_tspec(netsnmp_tdomain_spec *tspec)
 netsnmp_transport *
 netsnmp_udp_create_ostring(const void *o, size_t o_len, int local)
 {
-    return netsnmp_udp_transport(o, local);
+    struct sockaddr_in sin;
+
+    if (netsnmp_ipv4_ostring_to_sockaddr(&sin, o, o_len))
+        return netsnmp_udp_transport(&sin, local);
+    return NULL;
 }
 
 
diff --git a/snmplib/transports/snmpUDPIPv6Domain.c 
b/snmplib/transports/snmpUDPIPv6Domain.c
index 5b9313165296..3d003f208763 100644
--- a/snmplib/transports/snmpUDPIPv6Domain.c
+++ b/snmplib/transports/snmpUDPIPv6Domain.c
@@ -263,6 +263,7 @@ netsnmp_udp6_transport_init(const struct sockaddr_in6 
*addr, int flags)
     t->f_close    = netsnmp_socketbase_close;
     t->f_accept   = NULL;
     t->f_fmtaddr  = netsnmp_udp6_fmtaddr;
+    t->f_get_taddr = netsnmp_ipv6_get_taddr;
 
     t->domain = netsnmp_UDPIPv6Domain;
     t->domain_length =
@@ -951,7 +952,11 @@ netsnmp_udp6_create_tspec(netsnmp_tdomain_spec *tspec)
 netsnmp_transport *
 netsnmp_udp6_create_ostring(const void *o, size_t o_len, int local)
 {
-    return netsnmp_udp6_transport(o, local);
+    struct sockaddr_in6 sin6;
+
+    if (netsnmp_ipv6_ostring_to_sockaddr(&sin6, o, o_len))
+        return netsnmp_udp6_transport(&sin6, local);
+    return NULL;
 }
 
 
diff --git a/snmplib/transports/snmpUDPsharedDomain.c 
b/snmplib/transports/snmpUDPsharedDomain.c
index 5e77f6a43548..d84dd4ee1cb8 100644
--- a/snmplib/transports/snmpUDPsharedDomain.c
+++ b/snmplib/transports/snmpUDPsharedDomain.c
@@ -178,6 +178,12 @@ _transport_common(netsnmp_transport *t)
     t->f_fmtaddr       = _udpshared_fmtaddr;
     t->f_setup_session = _setup_session;
     t->flags = NETSNMP_TRANSPORT_FLAG_SHARED;
+    if (t->base_transport->domain == netsnmpUDPDomain)
+        t->f_get_taddr = netsnmp_ipv4_get_taddr;
+    else if (t->base_transport->domain == netsnmp_UDPIPv6Domain)
+        t->f_get_taddr = netsnmp_ipv6_get_taddr;
+    else
+        netsnmp_assert(0);
 
     return t;
 }
@@ -340,13 +346,16 @@ netsnmp_udpshared6_transport_with_source(const struct 
sockaddr_in6 *addr6,
 netsnmp_transport *
 netsnmp_udpshared_create_ostring(const void *o, size_t o_len, int local)
 {
+    struct sockaddr_in sin;
+    struct sockaddr_in6 sin6;
+
     DEBUGMSGTL(("udpshared:create", "from ostring\n"));
 
-    if (o_len == sizeof(struct sockaddr_in))
-        return netsnmp_udpshared_transport(o, local);
+    if (netsnmp_ipv4_ostring_to_sockaddr(&sin, o, o_len))
+        return netsnmp_udpshared_transport(&sin, local);
 #ifdef NETSNMP_TRANSPORT_UDPIPV6_DOMAIN
-    else if (o_len == sizeof(struct sockaddr_in6))
-        return netsnmp_udpshared6_transport(o, local);
+    else if (netsnmp_ipv6_ostring_to_sockaddr(&sin6, o, o_len))
+        return netsnmp_udpshared6_transport(&sin6, local);
 #endif
     return NULL;
 }
diff --git a/snmplib/transports/snmpUnixDomain.c 
b/snmplib/transports/snmpUnixDomain.c
index ab57accac16e..2d4a452b38c7 100644
--- a/snmplib/transports/snmpUnixDomain.c
+++ b/snmplib/transports/snmpUnixDomain.c
@@ -107,7 +107,12 @@ netsnmp_unix_fmtaddr(netsnmp_transport *t, const void 
*data, int len)
     }
 }
 
-
+static void
+netsnmp_unix_get_taddr(netsnmp_transport *t, void **addr, size_t *addr_len)
+{
+    *addr_len = t->remote_length;
+    *addr = netsnmp_memdup(t->remote, *addr_len);
+}
 
 /*
  * You can write something into opaque that will subsequently get passed back
@@ -459,6 +464,7 @@ netsnmp_unix_transport(const struct sockaddr_un *addr, int 
local)
     t->f_close    = netsnmp_unix_close;
     t->f_accept   = netsnmp_unix_accept;
     t->f_fmtaddr  = netsnmp_unix_fmtaddr;
+    t->f_get_taddr = netsnmp_unix_get_taddr;
 
     return t;
 }
-- 
2.17.1



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Net-snmp-coders mailing list
Net-snmp-coders@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to