Revision: 14863
Author: adrian.chadd
Date: Fri Jul 8 22:32:28 2011
Log: Enable IPv6 support for the SNMP agent.
http://code.google.com/p/lusca-cache/source/detail?r=14863
Modified:
/playpen/LUSCA_HEAD_ipv6/src/cf.data.pre
/playpen/LUSCA_HEAD_ipv6/src/globals.h
/playpen/LUSCA_HEAD_ipv6/src/snmp_core.c
/playpen/LUSCA_HEAD_ipv6/src/structs.h
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/cf.data.pre Fri Jul 1 07:59:54 2011
+++ /playpen/LUSCA_HEAD_ipv6/src/cf.data.pre Fri Jul 8 22:32:28 2011
@@ -4789,6 +4789,18 @@
the same value since they both use port 3401.
DOC_END
+NAME: snmp_outgoing_address6
+TYPE: address6
+LOC: Config.Addrs.snmp_outgoing6
+DEFAULT: ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+DOC_NONE
+
+NAME: snmp_incoming_address6
+TYPE: address6
+LOC: Config.Addrs.snmp_incoming6
+DEFAULT: ::0
+DOC_NONE
+
COMMENT_START
ICP OPTIONS
-----------------------------------------------------------------------------
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/globals.h Sun Jul 4 06:56:53 2010
+++ /playpen/LUSCA_HEAD_ipv6/src/globals.h Fri Jul 8 22:32:28 2011
@@ -80,13 +80,17 @@
#ifdef SQUID_SNMP
extern int theInSnmpConnection; /* -1 */
extern int theOutSnmpConnection; /* -1 */
+extern int theInSnmpConnection6; /* -1 */
+extern int theOutSnmpConnection6; /* -1 */
extern char *snmp_agentinfo;
#endif
extern int n_disk_objects; /* 0 */
extern iostats IOStats;
extern struct _acl_deny_info_list *DenyInfoList; /* NULL */
extern struct in_addr theOutICPAddr;
+#if 0
extern struct in_addr theOutSNMPAddr;
+#endif
extern struct timeval squid_start;
extern int store_dirs_rebuilding; /* 1 */
extern int store_swap_size; /* 0 */
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/snmp_core.c Mon Sep 6 21:39:50 2010
+++ /playpen/LUSCA_HEAD_ipv6/src/snmp_core.c Fri Jul 8 22:32:28 2011
@@ -289,13 +289,16 @@
snmpConnectionOpen(void)
{
u_short port;
+#if 0
struct sockaddr_in xaddr;
socklen_t len;
int x;
+#endif
debug(49, 5) ("snmpConnectionOpen: Called\n");
if ((port = Config.Port.snmp) > (u_short) 0) {
enter_suid();
+
theInSnmpConnection = comm_open(SOCK_DGRAM,
IPPROTO_UDP,
Config.Addrs.snmp_incoming,
@@ -303,12 +306,25 @@
COMM_NONBLOCKING,
COMM_TOS_DEFAULT,
"SNMP Port");
+
+ sqinet_set_port(&Config.Addrs.snmp_incoming6, port, SQADDR_NONE);
+ theInSnmpConnection6 = comm_open6(SOCK_DGRAM,
+ IPPROTO_UDP,
+ &Config.Addrs.snmp_incoming6,
+ COMM_NONBLOCKING,
+ COMM_TOS_DEFAULT,
+ "SNMP Port");
+
leave_suid();
- if (theInSnmpConnection < 0)
+ if (theInSnmpConnection < 0 || theInSnmpConnection6 < 0)
fatal("Cannot open snmp Port");
- commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL,
0);
+ commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp,
+ NULL, 0);
+ commSetSelect(theInSnmpConnection6, COMM_SELECT_READ, snmpHandleUdp,
+ NULL, 0);
debug(1, 1) ("Accepting SNMP messages on port %d, FD %d.\n",
(int) port, theInSnmpConnection);
+
if (! IsNoAddr(&Config.Addrs.snmp_outgoing)) {
enter_suid();
theOutSnmpConnection = comm_open(SOCK_DGRAM,
@@ -332,6 +348,32 @@
} else {
theOutSnmpConnection = theInSnmpConnection;
}
+
+ if (! sqinet_is_noaddr(&Config.Addrs.snmp_outgoing6)) {
+ enter_suid();
+ sqinet_set_port(&Config.Addrs.snmp_outgoing6, port, SQADDR_NONE);
+ theOutSnmpConnection = comm_open6(SOCK_DGRAM,
+ IPPROTO_UDP,
+ &Config.Addrs.snmp_outgoing6,
+ COMM_NONBLOCKING,
+ COMM_TOS_DEFAULT,
+ "SNMP Port");
+ leave_suid();
+ if (theOutSnmpConnection6 < 0)
+ fatal("Cannot open Outgoing SNMP Port");
+ commSetSelect(theOutSnmpConnection6,
+ COMM_SELECT_READ,
+ snmpHandleUdp,
+ NULL, 0);
+ debug(1, 1) ("Outgoing SNMP messages on port %d, FD %d.\n",
+ (int) port, theOutSnmpConnection);
+ fd_note(theOutSnmpConnection6, "Outgoing SNMP socket");
+ fd_note(theInSnmpConnection6, "Incoming SNMP socket");
+ } else {
+ theOutSnmpConnection6 = theInSnmpConnection6;
+ }
+
+#if 0
memset(&theOutSNMPAddr, '\0', sizeof(struct in_addr));
len = sizeof(struct sockaddr_in);
memset(&xaddr, '\0', len);
@@ -342,32 +384,51 @@
theOutSnmpConnection, xstrerror());
else
theOutSNMPAddr = xaddr.sin_addr;
+#endif
}
}
void
snmpConnectionShutdown(void)
{
- if (theInSnmpConnection < 0)
+ if (theInSnmpConnection < 0 && theInSnmpConnection6 < 0)
return;
- if (theInSnmpConnection != theOutSnmpConnection) {
- debug(49, 1) ("FD %d Closing SNMP socket\n", theInSnmpConnection);
- comm_close(theInSnmpConnection);
- }
+
/*
* Here we set 'theInSnmpConnection' to -1 even though the SNMP 'in'
* and 'out' sockets might be just one FD. This prevents this
* function from executing repeatedly. When we are really ready to
* exit or restart, main will comm_close the 'out' descriptor.
- */ theInSnmpConnection = -1;
+ */
+
+ if (theInSnmpConnection != -1) {
+ if (theInSnmpConnection != theOutSnmpConnection) {
+ debug(49, 1) ("FD %d Closing IPv4 SNMP socket\n",
+ theInSnmpConnection);
+ comm_close(theInSnmpConnection);
+ theInSnmpConnection6 = -1;
+ }
+ }
+
+ if (theInSnmpConnection6 != -1) {
+ if (theInSnmpConnection6 != theOutSnmpConnection6) {
+ debug(49, 1) ("FD %d Closing IPv6 SNMP socket\n",
+ theInSnmpConnection6);
+ comm_close(theInSnmpConnection6);
+ theInSnmpConnection6 = -1;
+ }
+ }
+
/*
* Normally we only write to the outgoing SNMP socket, but we
* also have a read handler there to catch messages sent to that
* specific interface. During shutdown, we must disable reading
* on the outgoing socket.
*/
- assert(theOutSnmpConnection > -1);
- commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, NULL, NULL, 0);
+ if (theOutSnmpConnection != -1)
+ commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, NULL, NULL,
0);
+ if (theOutSnmpConnection6 != -1)
+ commSetSelect(theOutSnmpConnection6, COMM_SELECT_READ, NULL, NULL,
0);
}
void
@@ -391,15 +452,15 @@
snmpHandleUdp(int sock, void *not_used)
{
LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE);
- struct sockaddr_in from;
+ struct sockaddr_storage from;
socklen_t from_len;
snmp_request_t *snmp_rq;
int len;
- debug(49, 5) ("snmpHandleUdp: Called.\n");
+ debug(49, 5) ("snmpHandleUdp: Called: FD %d\n", sock);
commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
- from_len = sizeof(struct sockaddr_in);
+ from_len = sizeof(from);
memset(&from, '\0', from_len);
memset(buf, '\0', SNMP_REQUEST_SIZE);
@@ -413,21 +474,29 @@
&from_len);
if (len > 0) {
+ char sbuf[MAX_IPSTRLEN];
buf[len] = '\0';
- debug(49, 3) ("snmpHandleUdp: FD %d: received %d bytes from %s.\n",
- sock,
- len,
- inet_ntoa(from.sin_addr));
+ sqaddr_t f;
+ sqinet_init(&f);
+ sqinet_set_sockaddr(&f, &from);
+ if (do_debug(49, 3)) {
+ (void) sqinet_ntoa(&f, sbuf, MAX_IPSTRLEN, SQADDR_NONE);
+ debug(49, 3) ("snmpHandleUdp: FD %d: received %d bytes from %s.\n",
+ sock, len, sbuf);
+ }
snmp_rq = xcalloc(1, sizeof(snmp_request_t));
snmp_rq->buf = (u_char *) buf;
snmp_rq->len = len;
snmp_rq->sock = sock;
snmp_rq->outbuf = xmalloc(snmp_rq->outlen = SNMP_REQUEST_SIZE);
- xmemcpy(&snmp_rq->from, &from, sizeof(struct sockaddr_in));
+ sqinet_init(&snmp_rq->from);
+ sqinet_copy(&snmp_rq->from, &f);
snmpDecodePacket(snmp_rq);
+ sqinet_done(&snmp_rq->from);
xfree(snmp_rq->outbuf);
xfree(snmp_rq);
+ sqinet_done(&f);
} else {
debug(49, 1) ("snmpHandleUdp: FD %d recvfrom: %s\n", sock, xstrerror());
}
@@ -453,7 +522,7 @@
Community = snmp_parse(&rq->session, PDU, buf, len);
memset(&checklist, '\0', sizeof(checklist));
aclCheckSetup(&checklist);
- sqinet_set_v4_inaddr(&checklist.src_address, &rq->from.sin_addr);
+ sqinet_copy(&checklist.src_address, &rq->from);
checklist.snmp_community = (char *) Community;
if (Community)
@@ -464,8 +533,9 @@
debug(49, 5) ("snmpDecodePacket: reqid=[%d]\n", PDU->reqid);
snmpConstructReponse(rq);
} else {
- debug(49, 1) ("Failed SNMP agent query from : %s.\n",
- inet_ntoa(rq->from.sin_addr));
+ char sbuf[MAX_IPSTRLEN];
+ (void) sqinet_ntoa(&rq->from, sbuf, MAX_IPSTRLEN, SQADDR_NONE);
+ debug(49, 1) ("Failed SNMP agent query from : %s.\n", sbuf);
snmp_free_pdu(PDU);
}
if (Community)
@@ -485,8 +555,18 @@
RespPDU = snmpAgentResponse(rq->PDU);
snmp_free_pdu(rq->PDU);
if (RespPDU != NULL) {
+ int family;
snmp_build(&rq->session, RespPDU, rq->outbuf, &rq->outlen);
- comm_udp_sendto(rq->sock, &rq->from, sizeof(rq->from), rq->outbuf,
rq->outlen);
+ /* check address family */
+ /* XXX is this needed? How's rq->sock figured out? */
+ family = sqinet_get_family(&rq->from);
+ if (family == AF_INET)
+ assert(rq->sock == theOutSnmpConnection);
+ else if (family == AF_INET6)
+ assert(rq->sock == theOutSnmpConnection6);
+ else
+ debug(49, 0) ("%s: address family=%d ?!\n", __func__, family);
+ comm_udp_sendto6(rq->sock, &rq->from, rq->outbuf, rq->outlen);
snmp_free_pdu(RespPDU);
}
}
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/structs.h Fri Jul 8 21:30:40 2011
+++ /playpen/LUSCA_HEAD_ipv6/src/structs.h Fri Jul 8 22:32:28 2011
@@ -242,7 +242,7 @@
int sock;
long reqid;
int outlen;
- struct sockaddr_in from;
+ sqaddr_t from;
struct snmp_pdu *PDU;
aclCheck_t *acl_checklist;
u_char *community;
@@ -577,6 +577,8 @@
#if SQUID_SNMP
struct in_addr snmp_incoming;
struct in_addr snmp_outgoing;
+ sqaddr_t snmp_incoming6;
+ sqaddr_t snmp_outgoing6;
#endif
struct in_addr client_netmask_v4;
sqaddr_t client_netmask_v6;
--
You received this message because you are subscribed to the Google Groups
"lusca-commit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/lusca-commit?hl=en.