From 728ec7c41327c154df46e4939a484032467d1763 Mon Sep 17 00:00:00 2001
From: jow <jow@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Date: Wed, 5 Aug 2009 11:17:59 +0000
Subject: [PATCH] [PATCH] mini_snmpd: support for IPv6 The following patch adds
 IPv6 support to mini-snmpd in the packages repository. It is then able to
 handle requests from IPv4 and IPv6 clients. Signed-off-by: Linus L?ssing
 <linus.luessing@web.de>

git-svn-id: svn://svn.openwrt.org/openwrt/packages@17129 3c298f89-4303-0410-b956-a3cf2f4a3e73
---
 net/mini_snmpd/Makefile                       |   2 +-
 net/mini_snmpd/patches/104-ipv6-support.patch | 285 ++++++++++++++++++
 2 files changed, 286 insertions(+), 1 deletion(-)
 create mode 100644 net/mini_snmpd/patches/104-ipv6-support.patch

diff --git a/net/mini_snmpd/Makefile b/net/mini_snmpd/Makefile
index c47a957a9..120f51351 100644
--- a/net/mini_snmpd/Makefile
+++ b/net/mini_snmpd/Makefile
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=mini_snmpd
 PKG_VERSION:=1.0
-PKG_RELEASE:=3
+PKG_RELEASE:=4
 
 PKG_SOURCE:=mini_snmpd.tar.gz
 PKG_SOURCE_URL:=http://members.aon.at/linuxfreak/linux/
diff --git a/net/mini_snmpd/patches/104-ipv6-support.patch b/net/mini_snmpd/patches/104-ipv6-support.patch
new file mode 100644
index 000000000..5dc5622aa
--- /dev/null
+++ b/net/mini_snmpd/patches/104-ipv6-support.patch
@@ -0,0 +1,285 @@
+--- a/mini_snmpd.c
++++ b/mini_snmpd.c
+@@ -90,9 +90,10 @@
+ 
+ static void handle_udp_client(void)
+ {
+-	struct sockaddr_in sockaddr;
++	struct sockaddr_in6 sockaddr;
+ 	socklen_t socklen;
+ 	int rv;
++	char straddr[INET6_ADDRSTRLEN];
+ 
+ 	/* Read the whole UDP packet from the socket at once */
+ 	socklen = sizeof (sockaddr);
+@@ -105,8 +106,8 @@
+ 	}
+ 	g_udp_client.timestamp = time(NULL);
+ 	g_udp_client.sockfd = g_udp_sockfd;
+-	g_udp_client.addr = sockaddr.sin_addr.s_addr;
+-	g_udp_client.port = sockaddr.sin_port;
++	g_udp_client.addr = sockaddr.sin6_addr;
++	g_udp_client.port = sockaddr.sin6_port;
+ 	g_udp_client.size = rv;
+ 	g_udp_client.outgoing = 0;
+ #ifdef DEBUG
+@@ -114,13 +115,14 @@
+ #endif
+ 
+ 	/* Call the protocol handler which will prepare the response packet */
++	inet_ntop(AF_INET6, &sockaddr.sin6_addr, straddr, sizeof(straddr));
+ 	if (snmp(&g_udp_client) == -1) {
+ 		lprintf(LOG_WARNING, "could not handle packet from UDP client %s:%d: %m\n",
+-			inet_ntoa(sockaddr.sin_addr), sockaddr.sin_port);
++			straddr, sockaddr.sin6_port);
+ 		return;
+ 	} else if (g_udp_client.size == 0) {
+ 		lprintf(LOG_WARNING, "could not handle packet from UDP client %s:%d: ignored\n",
+-			inet_ntoa(sockaddr.sin_addr), sockaddr.sin_port);
++			straddr, sockaddr.sin6_port);
+ 		return;
+ 	}
+ 	g_udp_client.outgoing = 1;
+@@ -128,13 +130,14 @@
+ 	/* Send the whole UDP packet to the socket at once */
+ 	rv = sendto(g_udp_sockfd, g_udp_client.packet, g_udp_client.size,
+ 		MSG_DONTWAIT, (struct sockaddr *)&sockaddr, socklen);
++	inet_ntop(AF_INET6, &sockaddr.sin6_addr, straddr, sizeof(straddr));
+ 	if (rv == -1) {
+ 		lprintf(LOG_WARNING, "could not send packet to UDP client %s:%d: %m\n",
+-			inet_ntoa(sockaddr.sin_addr), sockaddr.sin_port);
++			straddr, sockaddr.sin6_port);
+ 	} else if (rv != g_udp_client.size) {
+ 		lprintf(LOG_WARNING, "could not send packet to UDP client %s:%d: "
+-			"only %d of %d bytes written\n", inet_ntoa(sockaddr.sin_addr),
+-			sockaddr.sin_port, rv, (int) g_udp_client.size);
++			"only %d of %d bytes written\n", straddr,
++			sockaddr.sin6_port, rv, (int) g_udp_client.size);
+ 	}
+ #ifdef DEBUG
+ 	dump_packet(&g_udp_client);
+@@ -143,11 +146,12 @@
+ 
+ static void handle_tcp_connect(void)
+ {
+-	struct sockaddr_in tmp_sockaddr;
+-	struct sockaddr_in sockaddr;
++	struct sockaddr_in6 tmp_sockaddr;
++	struct sockaddr_in6 sockaddr;
+ 	socklen_t socklen;
+ 	client_t *client;
+ 	int rv;
++	char straddr[INET6_ADDRSTRLEN];
+ 
+ 	/* Accept the new connection (remember the client's IP address and port) */
+ 	socklen = sizeof (sockaddr);
+@@ -168,10 +172,11 @@
+ 			lprintf(LOG_ERR, "could not accept TCP connection: internal error");
+ 			exit(EXIT_SYSCALL);
+ 		}
+-		tmp_sockaddr.sin_addr.s_addr = client->addr;
+-		tmp_sockaddr.sin_port = client->port;
++		tmp_sockaddr.sin6_addr = client->addr;
++		tmp_sockaddr.sin6_port = client->port;
++		inet_ntop(AF_INET6, &tmp_sockaddr.sin6_addr, straddr, sizeof(straddr));
+ 		lprintf(LOG_WARNING, "maximum number of %d clients reached, kicking out %s:%d\n",
+-			MAX_NR_CLIENTS, inet_ntoa(tmp_sockaddr.sin_addr), tmp_sockaddr.sin_port);
++			MAX_NR_CLIENTS, straddr, tmp_sockaddr.sin6_port);
+ 		close(client->sockfd);
+ 	} else {
+ 		client = malloc(sizeof (client_t));
+@@ -183,35 +188,38 @@
+ 	}
+ 
+ 	/* Now fill out the client control structure values */
++	inet_ntop(AF_INET6, &sockaddr.sin6_addr, straddr, sizeof(straddr));
+ 	lprintf(LOG_DEBUG, "connected TCP client %s:%d\n",
+-		inet_ntoa(sockaddr.sin_addr), sockaddr.sin_port);
++		straddr, sockaddr.sin6_port);
+ 	client->timestamp = time(NULL);
+ 	client->sockfd = rv;
+-	client->addr = sockaddr.sin_addr.s_addr;
+-	client->port = sockaddr.sin_port;
++	client->addr = sockaddr.sin6_addr;
++	client->port = sockaddr.sin6_port;
+ 	client->size = 0;
+ 	client->outgoing = 0;
+ }
+ 
+ static void handle_tcp_client_write(client_t *client)
+ {
+-	struct sockaddr_in sockaddr;
++	struct sockaddr_in6 sockaddr;
+ 	int rv;
++	char straddr[INET6_ADDRSTRLEN];
+ 
+ 	/* Send the packet atomically and close socket if that did not work */
+-	sockaddr.sin_addr.s_addr = client->addr;
+-	sockaddr.sin_port = client->port;
++	sockaddr.sin6_addr = client->addr;
++	sockaddr.sin6_port = client->port;
+ 	rv = send(client->sockfd, client->packet, client->size, 0);
++	inet_ntop(AF_INET6, &sockaddr.sin6_addr, straddr, sizeof(straddr));
+ 	if (rv == -1) {
+ 		lprintf(LOG_WARNING, "could not send packet to TCP client %s:%d: %m\n",
+-			inet_ntoa(sockaddr.sin_addr), sockaddr.sin_port);
++			straddr, sockaddr.sin6_port);
+ 		close(client->sockfd);
+ 		client->sockfd = -1;
+ 		return;
+ 	} else if (rv != client->size) {
+ 		lprintf(LOG_WARNING, "could not send packet to TCP client %s:%d: "
+-			"only %d of %d bytes written\n", inet_ntoa(sockaddr.sin_addr),
+-			sockaddr.sin_port, rv, (int) client->size);
++			"only %d of %d bytes written\n", straddr,
++			sockaddr.sin6_port, rv, (int) client->size);
+ 		close(client->sockfd);
+ 		client->sockfd = -1;
+ 		return;
+@@ -227,23 +235,25 @@
+ 
+ static void handle_tcp_client_read(client_t *client)
+ {
+-	struct sockaddr_in sockaddr;
++	struct sockaddr_in6 sockaddr;
+ 	int rv;
++	char straddr[INET6_ADDRSTRLEN];
+ 
+ 	/* Read from the socket what arrived and put it into the buffer */
+-	sockaddr.sin_addr.s_addr = client->addr;
+-	sockaddr.sin_port = client->port;
++	sockaddr.sin6_addr = client->addr;
++	sockaddr.sin6_port = client->port;
+ 	rv = read(client->sockfd, client->packet + client->size,
+ 		sizeof (client->packet) - client->size);
++	inet_ntop(AF_INET6, &sockaddr.sin6_addr, straddr, sizeof(straddr));
+ 	if (rv == -1) {
+ 		lprintf(LOG_WARNING, "could not read packet from TCP client %s:%d: %m\n",
+-			inet_ntoa(sockaddr.sin_addr), sockaddr.sin_port);
++			straddr, sockaddr.sin6_port);
+ 		close(client->sockfd);
+ 		client->sockfd = -1;
+ 		return;
+ 	} else if (rv == 0) {
+ 		lprintf(LOG_DEBUG, "disconnected TCP client %s:%d\n",
+-			inet_ntoa(sockaddr.sin_addr), sockaddr.sin_port);
++			straddr, sockaddr.sin6_port);
+ 		close(client->sockfd);
+ 		client->sockfd = -1;
+ 		return;
+@@ -255,7 +265,7 @@
+ 	rv = snmp_packet_complete(client);
+ 	if (rv == -1) {
+ 		lprintf(LOG_WARNING, "could not handle packet from TCP client %s:%d: %m\n",
+-			inet_ntoa(sockaddr.sin_addr), sockaddr.sin_port);
++			straddr, sockaddr.sin6_port);
+ 		close(client->sockfd);
+ 		client->sockfd = -1;
+ 		return;
+@@ -270,13 +280,13 @@
+ 	/* Call the protocol handler which will prepare the response packet */
+ 	if (snmp(client) == -1) {
+ 		lprintf(LOG_WARNING, "could not handle packet from TCP client %s:%d: %m\n",
+-			inet_ntoa(sockaddr.sin_addr), sockaddr.sin_port);
++			straddr, sockaddr.sin6_port);
+ 		close(client->sockfd);
+ 		client->sockfd = -1;
+ 		return;
+ 	} else if (client->size == 0) {
+ 		lprintf(LOG_WARNING, "could not handle packet from TCP client %s:%d: ignored\n",
+-			inet_ntoa(sockaddr.sin_addr), sockaddr.sin_port);
++			straddr, sockaddr.sin6_port);
+ 		close(client->sockfd);
+ 		client->sockfd = -1;
+ 		return;
+@@ -313,7 +323,7 @@
+ 	int option_index = 1;
+ 	int c;
+ 
+-	struct sockaddr_in sockaddr;
++	struct sockaddr_in6 sockaddr;
+ 	socklen_t socklen;
+ 	fd_set rfds;
+ 	fd_set wfds;
+@@ -399,14 +409,14 @@
+ #endif
+ 
+ 	/* Open the server's UDP port and prepare it for listening */
+-	g_udp_sockfd = socket(PF_INET, SOCK_DGRAM, 0);
++	g_udp_sockfd = socket(PF_INET6, SOCK_DGRAM, 0);
+ 	if (g_udp_sockfd == -1) {
+ 		lprintf(LOG_ERR, "could not create UDP socket: %m\n");
+ 		exit(EXIT_SYSCALL);
+ 	}
+-	sockaddr.sin_family = AF_INET;
+-	sockaddr.sin_port = htons(g_udp_port);
+-	sockaddr.sin_addr.s_addr = INADDR_ANY;
++	sockaddr.sin6_family = AF_INET6;
++	sockaddr.sin6_port = htons(g_udp_port);
++	sockaddr.sin6_addr = in6addr_any;
+ 	socklen = sizeof (sockaddr);
+ 	if (bind(g_udp_sockfd, (struct sockaddr *)&sockaddr, socklen) == -1) {
+ 		lprintf(LOG_ERR, "could not bind UDP socket to port %d: %m\n", g_udp_port);
+@@ -414,7 +424,7 @@
+ 	}
+ 
+ 	/* Open the server's TCP port and prepare it for listening */
+-	g_tcp_sockfd = socket(PF_INET, SOCK_STREAM, 0);
++	g_tcp_sockfd = socket(PF_INET6, SOCK_STREAM, 0);
+ 	if (g_tcp_sockfd == -1) {
+ 		lprintf(LOG_ERR, "could not create TCP socket: %m\n");
+ 		exit(EXIT_SYSCALL);
+@@ -424,9 +434,9 @@
+ 		lprintf(LOG_WARNING, "could not set SO_REUSEADDR on TCP socket: %m\n");
+ 		exit(EXIT_SYSCALL);
+ 	}
+-	sockaddr.sin_family = AF_INET;
+-	sockaddr.sin_port = htons(g_tcp_port);
+-	sockaddr.sin_addr.s_addr = INADDR_ANY;
++	sockaddr.sin6_family = AF_INET6;
++	sockaddr.sin6_port = htons(g_tcp_port);
++	sockaddr.sin6_addr = in6addr_any;
+ 	socklen = sizeof (sockaddr);
+ 	if (bind(g_tcp_sockfd, (struct sockaddr *)&sockaddr, socklen) == -1) {
+ 		lprintf(LOG_ERR, "could not bind TCP socket to port %d: %m\n", g_tcp_port);
+--- a/mini_snmpd.h
++++ b/mini_snmpd.h
+@@ -129,7 +129,7 @@
+ typedef struct client_s {
+ 	time_t timestamp;
+ 	int sockfd;
+-	in_addr_t addr;
++	struct in6_addr addr;
+ 	in_port_t port;
+ 	unsigned char packet[MAX_PACKET_SIZE];
+ 	size_t size;
+--- a/utils.c
++++ b/utils.c
+@@ -91,12 +91,13 @@
+ 
+ void dump_packet(const client_t *client)
+ {
+-	struct in_addr client_addr;
++	struct in6_addr client_addr;
++	char straddr[INET6_ADDRSTRLEN];
+ 	char buffer[BUFSIZ];
+ 	int len;
+ 	int i;
+ 
+-	client_addr.s_addr = client->addr;
++	client_addr = client->addr;
+ 	len = 0;
+ 	for (i = 0; i < client->size; i++) {
+ 		len += snprintf(buffer + len, sizeof (buffer) - len,
+@@ -105,9 +106,10 @@
+ 			break;
+ 		}
+ 	}
++	inet_ntop(AF_INET6, &client_addr, straddr, sizeof(straddr));
+ 	lprintf(LOG_DEBUG, "%s %u bytes %s %s:%d (%s)\n",
+ 		client->outgoing ? "transmitted" : "received", (int) client->size,
+-		client->outgoing ? "to" : "from", inet_ntoa(client_addr),
++		client->outgoing ? "to" : "from", straddr,
+ 		ntohs(client->port), buffer);
+ }
+