|
Packit |
fcad23 |
/* IPV4 base transport support functions
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Portions of this file are subject to the following copyright(s). See
|
|
Packit |
fcad23 |
* the Net-SNMP's COPYING file for more details and other copyrights
|
|
Packit |
fcad23 |
* that may apply:
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Portions of this file are copyrighted by:
|
|
Packit |
fcad23 |
* Copyright (c) 2016 VMware, Inc. All rights reserved.
|
|
Packit |
fcad23 |
* Use is subject to license terms specified in the COPYING file
|
|
Packit |
fcad23 |
* distributed with the Net-SNMP package.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-config.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <net-snmp/types.h>
|
|
Packit |
fcad23 |
#include <net-snmp/library/snmpUDPIPv4BaseDomain.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <stddef.h>
|
|
Packit |
fcad23 |
#include <stdio.h>
|
|
Packit |
fcad23 |
#include <sys/types.h>
|
|
Packit |
fcad23 |
#include <ctype.h>
|
|
Packit |
fcad23 |
#if HAVE_STDLIB_H
|
|
Packit |
fcad23 |
#include <stdlib.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_STRING_H
|
|
Packit |
fcad23 |
#include <string.h>
|
|
Packit |
fcad23 |
#else
|
|
Packit |
fcad23 |
#include <strings.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_SYS_SOCKET_H
|
|
Packit |
fcad23 |
#include <sys/socket.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_NETINET_IN_H
|
|
Packit |
fcad23 |
#include <netinet/in.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_ARPA_INET_H
|
|
Packit |
fcad23 |
#include <arpa/inet.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_NETDB_H
|
|
Packit |
fcad23 |
#include <netdb.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#include <errno.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <net-snmp/types.h>
|
|
Packit |
fcad23 |
#include <net-snmp/library/snmp_debug.h>
|
|
Packit |
fcad23 |
#include <net-snmp/library/tools.h>
|
|
Packit |
fcad23 |
#include <net-snmp/library/snmp_assert.h>
|
|
Packit |
fcad23 |
#include <net-snmp/library/default_store.h>
|
|
Packit |
fcad23 |
#include <net-snmp/library/snmp_transport.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <net-snmp/library/snmpSocketBaseDomain.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifndef NETSNMP_NO_SYSTEMD
|
|
Packit |
fcad23 |
#include <net-snmp/library/sd-daemon.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#if defined(HAVE_IP_PKTINFO) || (defined(HAVE_IP_RECVDSTADDR) && defined(HAVE_IP_SENDSRCADDR))
|
|
Packit |
fcad23 |
int netsnmp_udpipv4_recvfrom(int s, void *buf, int len, struct sockaddr *from,
|
|
Packit |
fcad23 |
socklen_t *fromlen, struct sockaddr *dstip,
|
|
Packit |
fcad23 |
socklen_t *dstlen, int *if_index)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
return netsnmp_udpbase_recvfrom(s, buf, len, from, fromlen, dstip, dstlen,
|
|
Packit |
fcad23 |
if_index);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int netsnmp_udpipv4_sendto(int fd, const struct in_addr *srcip, int if_index,
|
|
Packit |
fcad23 |
const struct sockaddr *remote, const void *data,
|
|
Packit |
fcad23 |
int len)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
return netsnmp_udpbase_sendto(fd, srcip, if_index, remote, data, len);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif /* HAVE_IP_PKTINFO || HAVE_IP_RECVDSTADDR */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_transport *
|
|
Packit |
fcad23 |
netsnmp_udpipv4base_transport_init(const struct sockaddr_in *addr, int local)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_transport *t;
|
|
Packit |
fcad23 |
u_char *addr_ptr;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (addr == NULL || addr->sin_family != AF_INET) {
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
t = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
|
|
Packit |
fcad23 |
if (NULL == t)
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
t->sock = -1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
addr_ptr = netsnmp_memdup(addr, sizeof(*addr));
|
|
Packit |
fcad23 |
if (NULL == addr_ptr) {
|
|
Packit |
fcad23 |
free(t);
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (local) {
|
|
Packit |
fcad23 |
/** This is a server session. */
|
|
Packit |
fcad23 |
t->local_length = sizeof(*addr);
|
|
Packit |
fcad23 |
t->local = addr_ptr;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
/** This is a client session. */
|
|
Packit |
fcad23 |
t->remote = addr_ptr;
|
|
Packit |
fcad23 |
t->remote_length = sizeof(*addr);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGIF("netsnmp_udpbase") {
|
|
Packit |
fcad23 |
netsnmp_indexed_addr_pair addr_pair;
|
|
Packit |
fcad23 |
char *str;
|
|
Packit |
fcad23 |
memset(&addr_pair, 0, sizeof(netsnmp_indexed_addr_pair));
|
|
Packit |
fcad23 |
memcpy(&(addr_pair.remote_addr), addr, sizeof(*addr));
|
|
Packit |
fcad23 |
str = netsnmp_udp_fmtaddr(NULL, (void *)&addr_pair,
|
|
Packit |
fcad23 |
sizeof(netsnmp_indexed_addr_pair));
|
|
Packit |
fcad23 |
DEBUGMSGTL(("netsnmp_udpbase", "open %s %s\n",
|
|
Packit |
fcad23 |
local ? "local" : "remote", str));
|
|
Packit |
fcad23 |
free(str);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (!local) {
|
|
Packit |
fcad23 |
netsnmp_indexed_addr_pair *addr_pair;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* allocate space to save the (remote) address in the
|
|
Packit |
fcad23 |
* transport-specific data pointer for later use by netsnmp_udp_send.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
t->data = calloc(1, sizeof(netsnmp_indexed_addr_pair));
|
|
Packit |
fcad23 |
if (NULL == t->data) {
|
|
Packit |
fcad23 |
netsnmp_transport_free(t);
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
t->data_length = sizeof(netsnmp_indexed_addr_pair);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
addr_pair = (netsnmp_indexed_addr_pair *)t->data;
|
|
Packit |
fcad23 |
memcpy(&addr_pair->remote_addr, addr, sizeof(*addr));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
return t;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_udpipv4base_transport_socket(int flags)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int local = flags & NETSNMP_TSPEC_LOCAL;
|
|
Packit |
fcad23 |
int sock = socket(PF_INET, SOCK_DGRAM, 0);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("UDPBase", "opened socket %d as local=%d\n", sock, local));
|
|
Packit |
fcad23 |
if (sock < 0)
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
_netsnmp_udp_sockopt_set(sock, local);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return sock;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_udpipv4base_transport_bind(netsnmp_transport *t,
|
|
Packit |
fcad23 |
const struct sockaddr_in *addr, int flags)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
#if defined(HAVE_IP_PKTINFO) || defined(HAVE_IP_RECVDSTADDR)
|
|
Packit |
fcad23 |
int sockopt = 1;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
int rc;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (flags & NETSNMP_TSPEC_LOCAL) {
|
|
Packit |
fcad23 |
#ifdef NETSNMP_NO_LISTEN_SUPPORT
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
#endif /* NETSNMP_NO_LISTEN_SUPPORT */
|
|
Packit |
fcad23 |
#ifndef WIN32
|
|
Packit |
fcad23 |
#if defined(HAVE_IP_PKTINFO)
|
|
Packit |
fcad23 |
if (setsockopt(t->sock, SOL_IP, IP_PKTINFO, &sockopt, sizeof sockopt) == -1) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("netsnmp_udpbase", "couldn't set IP_PKTINFO: %s\n",
|
|
Packit |
fcad23 |
strerror(errno)));
|
|
Packit |
fcad23 |
return 1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
DEBUGMSGTL(("netsnmp_udpbase", "set IP_PKTINFO\n"));
|
|
Packit |
fcad23 |
#elif defined(HAVE_IP_RECVDSTADDR)
|
|
Packit |
fcad23 |
if (setsockopt(t->sock, IPPROTO_IP, IP_RECVDSTADDR, &sockopt, sizeof sockopt) == -1) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("netsnmp_udp", "couldn't set IP_RECVDSTADDR: %s\n",
|
|
Packit |
fcad23 |
strerror(errno)));
|
|
Packit |
fcad23 |
return 1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
DEBUGMSGTL(("netsnmp_udp", "set IP_RECVDSTADDR\n"));
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#else /* !defined(WIN32) */
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int sockopt = 1;
|
|
Packit |
fcad23 |
if (setsockopt(t->sock, IPPROTO_IP, IP_PKTINFO, (void *)&sockopt,
|
|
Packit |
fcad23 |
sizeof(sockopt)) == -1) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("netsnmp_udpbase", "couldn't set IP_PKTINFO: %d\n",
|
|
Packit |
fcad23 |
WSAGetLastError()));
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("netsnmp_udpbase", "set IP_PKTINFO\n"));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif /* !defined(WIN32) */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGIF("netsnmp_udpbase") {
|
|
Packit |
fcad23 |
netsnmp_indexed_addr_pair addr_pair;
|
|
Packit |
fcad23 |
char *str;
|
|
Packit |
fcad23 |
memset(&addr_pair, 0x0, sizeof(addr_pair));
|
|
Packit |
fcad23 |
memcpy(&(addr_pair.local_addr), addr, sizeof(*addr));
|
|
Packit |
fcad23 |
str = netsnmp_udp_fmtaddr(NULL, (void *)&addr_pair,
|
|
Packit |
fcad23 |
sizeof(netsnmp_indexed_addr_pair));
|
|
Packit |
fcad23 |
DEBUGMSGTL(("netsnmp_udpbase", "binding socket: %d to %s\n",
|
|
Packit |
fcad23 |
t->sock, str));
|
|
Packit |
fcad23 |
free(str);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
rc = bind(t->sock, (const struct sockaddr *)addr, sizeof(*addr));
|
|
Packit |
fcad23 |
if ( rc != 0 ) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("netsnmp_udpbase",
|
|
Packit |
fcad23 |
"failed to bind for clientaddr: %d %s\n",
|
|
Packit |
fcad23 |
errno, strerror(errno)));
|
|
Packit |
fcad23 |
netsnmp_socketbase_close(t);
|
|
Packit |
fcad23 |
return 1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
netsnmp_udpipv4base_transport_get_bound_addr(netsnmp_transport *t)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_indexed_addr_pair *addr_pair;
|
|
Packit |
fcad23 |
socklen_t local_addr_len = sizeof(addr_pair->local_addr);
|
|
Packit |
fcad23 |
int rc;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** only for client transports: must have data and not local */
|
|
Packit |
fcad23 |
if (NULL == t || NULL != t->local || NULL == t->data ||
|
|
Packit |
fcad23 |
t->data_length < local_addr_len) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "bad parameters for get bound addr\n");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
addr_pair = (netsnmp_indexed_addr_pair *)t->data;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** get local socket address for client session */
|
|
Packit |
fcad23 |
rc = getsockname(t->sock, (struct sockaddr*)&addr_pair->local_addr,
|
|
Packit |
fcad23 |
&local_addr_len);
|
|
Packit |
fcad23 |
netsnmp_assert(rc == 0);
|
|
Packit |
fcad23 |
DEBUGIF("netsnmp_udpbase") {
|
|
Packit |
fcad23 |
char *str;
|
|
Packit |
fcad23 |
str = netsnmp_udp_fmtaddr(NULL, (void *)addr_pair,
|
|
Packit |
fcad23 |
sizeof(netsnmp_indexed_addr_pair));
|
|
Packit |
fcad23 |
DEBUGMSGTL(("netsnmp_udpbase", "socket %d bound to %s\n",
|
|
Packit |
fcad23 |
t->sock, str));
|
|
Packit |
fcad23 |
free(str);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_transport *
|
|
Packit |
fcad23 |
netsnmp_udpipv4base_transport_with_source(const struct sockaddr_in *addr,
|
|
Packit |
fcad23 |
int local,
|
|
Packit |
fcad23 |
const struct sockaddr_in *src_addr)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_transport *t = NULL;
|
|
Packit |
fcad23 |
const struct sockaddr_in *bind_addr;
|
|
Packit |
fcad23 |
int rc, flags = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
t = netsnmp_udpipv4base_transport_init(addr, local);
|
|
Packit |
fcad23 |
if (NULL == t)
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (local) {
|
|
Packit |
fcad23 |
bind_addr = addr;
|
|
Packit |
fcad23 |
flags |= NETSNMP_TSPEC_LOCAL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifndef NETSNMP_NO_SYSTEMD
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Maybe the socket was already provided by systemd...
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
t->sock = netsnmp_sd_find_inet_socket(PF_INET, SOCK_DGRAM, -1,
|
|
Packit |
fcad23 |
ntohs(addr->sin_port));
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
bind_addr = src_addr;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (-1 == t->sock)
|
|
Packit |
fcad23 |
t->sock = netsnmp_udpipv4base_transport_socket(flags);
|
|
Packit |
fcad23 |
if (t->sock < 0) {
|
|
Packit |
fcad23 |
netsnmp_transport_free(t);
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* If we've been given an address to bind to, then bind to it.
|
|
Packit |
fcad23 |
* Otherwise the OS will use "something sensible".
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (NULL == bind_addr)
|
|
Packit |
fcad23 |
return t;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
rc = netsnmp_udpipv4base_transport_bind(t, bind_addr, flags);
|
|
Packit |
fcad23 |
if (rc) {
|
|
Packit |
fcad23 |
netsnmp_transport_free(t);
|
|
Packit |
fcad23 |
t = NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else if (!local)
|
|
Packit |
fcad23 |
netsnmp_udpipv4base_transport_get_bound_addr(t);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return t;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_transport *
|
|
Packit |
fcad23 |
netsnmp_udpipv4base_tspec_transport(netsnmp_tdomain_spec *tspec)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
struct sockaddr_in addr;
|
|
Packit |
fcad23 |
int local;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (NULL == tspec)
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
local = tspec->flags & NETSNMP_TSPEC_LOCAL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** get address from target */
|
|
Packit |
fcad23 |
if (!netsnmp_sockaddr_in2(&addr, tspec->target, tspec->default_target))
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (NULL != tspec->source) {
|
|
Packit |
fcad23 |
struct sockaddr_in src_addr, *srcp = &src_addr;
|
|
Packit |
fcad23 |
/** get sockaddr from source */
|
|
Packit Service |
74476c |
if (!netsnmp_sockaddr_in2(&src_addr, tspec->source, NULL))
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
return netsnmp_udpipv4base_transport_with_source(&addr, local, srcp);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
/** if no source and we do not want any default client address */
|
|
Packit |
fcad23 |
if (tspec->flags & NETSNMP_TSPEC_NO_DFTL_CLIENT_ADDR)
|
|
Packit |
fcad23 |
return netsnmp_udpipv4base_transport_with_source(&addr, local,
|
|
Packit |
fcad23 |
NULL);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** no source and default client address ok */
|
|
Packit |
fcad23 |
return netsnmp_udpipv4base_transport(&addr, local);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_transport *
|
|
Packit |
fcad23 |
netsnmp_udpipv4base_transport(const struct sockaddr_in *addr, int local)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
if (!local) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* This is a client session. If we've been given a
|
|
Packit |
fcad23 |
* client address to send from, then bind to that.
|
|
Packit |
fcad23 |
* Otherwise the send will use "something sensible".
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
const char *client_socket;
|
|
Packit |
fcad23 |
client_socket = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
|
|
Packit |
fcad23 |
NETSNMP_DS_LIB_CLIENT_ADDR);
|
|
Packit |
fcad23 |
if (client_socket) {
|
|
Packit |
fcad23 |
struct sockaddr_in client_addr;
|
|
Packit |
fcad23 |
char *client_address = NETSNMP_REMOVE_CONST(char *,client_socket);
|
|
Packit |
fcad23 |
int have_port, rc;
|
|
Packit |
fcad23 |
int uses_port =
|
|
Packit |
fcad23 |
netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
|
|
Packit |
fcad23 |
NETSNMP_DS_LIB_CLIENT_ADDR_USES_PORT);
|
|
Packit |
fcad23 |
have_port = (strchr(client_socket, ':') != NULL);
|
|
Packit |
fcad23 |
if ((uses_port == 1) && !have_port) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* if NETSNMP_DS_LIB_CLIENT_ADDR expects a port but there
|
|
Packit |
fcad23 |
* is none specified then provide ephemeral one/
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
client_address = malloc(strlen(client_socket) + 3);
|
|
Packit |
fcad23 |
if (client_address == NULL) {
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
strcpy(client_address, client_socket);
|
|
Packit |
fcad23 |
strcat(client_address, ":0");
|
|
Packit |
fcad23 |
have_port = 1;
|
|
Packit |
fcad23 |
}
|
|
Packit Service |
74476c |
rc = netsnmp_sockaddr_in2(&client_addr, client_socket, NULL);
|
|
Packit |
fcad23 |
if (client_address != client_socket)
|
|
Packit |
fcad23 |
free(client_address);
|
|
Packit |
fcad23 |
if(rc) {
|
|
Packit |
fcad23 |
if (!uses_port || !have_port) /* if port isn't from string, */
|
|
Packit |
fcad23 |
client_addr.sin_port = 0; /* ... clear it */
|
|
Packit |
fcad23 |
return netsnmp_udpipv4base_transport_with_source(addr, local,
|
|
Packit |
fcad23 |
&client_addr);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
return netsnmp_udpipv4base_transport_with_source(addr, local, NULL);
|
|
Packit |
fcad23 |
}
|