summaryrefslogtreecommitdiffstats
path: root/contrib/bsnmp/snmpd/trans_udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bsnmp/snmpd/trans_udp.c')
-rw-r--r--contrib/bsnmp/snmpd/trans_udp.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/contrib/bsnmp/snmpd/trans_udp.c b/contrib/bsnmp/snmpd/trans_udp.c
index b6895a0..a5c262c 100644
--- a/contrib/bsnmp/snmpd/trans_udp.c
+++ b/contrib/bsnmp/snmpd/trans_udp.c
@@ -55,7 +55,7 @@ static void udp_close_port(struct tport *);
static int udp_init_port(struct tport *);
static ssize_t udp_send(struct tport *, const u_char *, size_t,
const struct sockaddr *, size_t);
-static ssize_t udp_recv(struct port_input *);
+static ssize_t udp_recv(struct tport *, struct port_input *);
/* exported */
const struct transport_def udp_trans = {
@@ -217,8 +217,30 @@ udp_send(struct tport *tp, const u_char *buf, size_t len,
const struct sockaddr *addr, size_t addrlen)
{
struct udp_port *p = (struct udp_port *)tp;
+ struct cmsghdr *cmsg;
+ struct in_addr *src_addr;
+ struct msghdr msg;
+ char cbuf[CMSG_SPACE(sizeof(struct in_addr))];
+ struct iovec iov;
- return (sendto(p->input.fd, buf, len, 0, addr, addrlen));
+ iov.iov_base = __DECONST(void*, buf);
+ iov.iov_len = len;
+
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = __DECONST(void *, addr);
+ msg.msg_namelen = addrlen;
+ msg.msg_control = cbuf;
+ msg.msg_controllen = sizeof(cbuf);
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = IPPROTO_IP;
+ cmsg->cmsg_type = IP_SENDSRCADDR;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+ src_addr = (struct in_addr *)(void*)CMSG_DATA(cmsg);
+ memcpy(src_addr, &p->recv_addr, sizeof(struct in_addr));
+
+ return (sendmsg(p->input.fd, &msg, 0));
}
static void
@@ -309,8 +331,9 @@ recv_dgram(struct port_input *pi, struct in_addr *laddr)
* Receive something
*/
static ssize_t
-udp_recv(struct port_input *pi)
+udp_recv(struct tport *tp, struct port_input *pi)
{
+ struct udp_port *p = (struct udp_port *)tp;
struct in_addr *laddr;
struct msghdr msg;
char cbuf[CMSG_SPACE(sizeof(struct in_addr))];
@@ -330,6 +353,8 @@ udp_recv(struct port_input *pi)
ret = recv_dgram(pi, laddr);
+ memcpy(&p->recv_addr, laddr, sizeof(struct in_addr));
+
if (laddr->s_addr == INADDR_ANY) {
msg.msg_control = NULL;
msg.msg_controllen = 0;
OpenPOWER on IntegriCloud