PERFORCE change 82568 for review
Victor Cruceru
soc-victor at FreeBSD.org
Thu Aug 25 23:18:28 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=82568
Change 82568 by soc-victor at soc-victor_82.76.158.176 on 2005/08/25 23:18:04
Added the SNMP SET support for the combined v4 & v6 tcpConnectionTable.
This adds the ability of a SNMP client to drop a tcp{4,6} connection from
the managed FreeBSD network element.
Need to add the same capability for the obsoleted tcpConnTable.
Affected files ...
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp46/Makefile#4 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp46/tcp46_snmp.c#6 edit
Differences ...
==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp46/Makefile#4 (text+ko) ====
@@ -33,8 +33,10 @@
SRCS= tcp46_snmp.c
WARNS?= 6
+
#Not having NDEBUG defined will enable assertions and a lot of output on stderr
CFLAGS+= -DNDEBUG
+
XSYM= tcpMIB
DEFS= ${MOD}_tree.def
==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_tcp46/tcp46_snmp.c#6 (text+ko) ====
@@ -80,6 +80,9 @@
#include <netinet/tcp_timer.h>
#include <netinet/tcp_fsm.h>
#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
#include <string.h>
#include <stdlib.h>
#include <assert.h>
@@ -828,7 +831,148 @@
return (0);
}
+static
+int drop_new_tcp_conn(struct asn_oid *conn){
+
+ struct sockaddr_storage addrs[2];
+ int mib[] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_DROP };
+ char local[64] = "", remote[64] = "";
+
+ assert(conn != NULL);
+ memset (&addrs[0], 0, sizeof(addrs));
+ if (conn->subs[0] == IAT_ipv4) {
+ struct sockaddr_in *sinl, *sinr;
+
+ assert(conn->len == 12);
+ if (conn->len != 12) {
+ syslog(LOG_ERR, "%s: malformed SNMP index (wrong length) when deleting a connection",
+ __func__);
+ return -1;
+ }
+
+ if (conn->subs[6] != IAT_ipv4 ) {
+ syslog(LOG_ERR, "%s: malformed SNMP index (remote not a v4) when deleting a connection",
+ __func__);
+ return -1;
+ }
+
+
+
+ memset(&addrs[1], 0, sizeof(addrs[1]));
+ sinl = (struct sockaddr_in *)&addrs[1];
+ sinl->sin_len = sizeof(struct sockaddr_in);
+ sinl->sin_addr.s_addr = htonl(
+ (conn->subs[1] << 24) |
+ (conn->subs[2] << 16) |
+ (conn->subs[3] << 8) |
+ (conn->subs[4] << 0)
+ );
+ sinl->sin_port = htons(conn->subs[5]);
+ addrs[1].ss_family = AF_INET;
+
+ inet_ntop(AF_INET, &sinl->sin_addr, local, 64);
+
+
+
+ memset(&addrs[0], 0, sizeof(addrs[0]));
+ sinr = (struct sockaddr_in *)&addrs[0];
+ sinr->sin_len = sizeof(struct sockaddr_in);
+
+ sinr->sin_addr.s_addr = htonl(
+ (conn->subs[7] << 24) |
+ (conn->subs[8] << 16) |
+ (conn->subs[9] << 8) |
+ (conn->subs[10] << 0)
+ );
+ sinr->sin_port = htons(conn->subs[11]);
+ addrs[0].ss_family = AF_INET;
+
+ inet_ntop(AF_INET, &sinr->sin_addr, remote, 64);
+ syslog(LOG_INFO, "[%s] attempt to delete a tcp4 connection : local: %s:%d - remote: %s:%d \n ",
+ __func__,
+ local,
+ conn->subs[5],
+ remote,
+ conn->subs[11]);
+
+
+ } else if (conn->subs[0] == IAT_ipv6) {
+ struct sockaddr_in6 *sin6l, *sin6r;
+ int i = 0;
+ assert(conn->len == 36);
+ if (conn->len != 36) {
+ syslog(LOG_ERR, "%s: malformed SNMP index (wrong length) when deleting a connection",
+ __func__);
+ return -1;
+ }
+
+ if (conn->subs[18] != IAT_ipv6 ) {
+ syslog(LOG_ERR, "%s: malformed SNMP index (remote not a v6) when deleting a connection",
+ __func__);
+ return -1;
+ }
+
+
+ memset(&addrs[1], 0, sizeof(addrs[1]));
+ sin6l = (struct sockaddr_in6 *)&addrs[1];
+ for (i=0; i<16; i++) {
+ sin6l->sin6_addr.s6_addr[i] = conn->subs[1+i];
+ }
+
+ sin6l->sin6_port = htons(conn->subs[17]);
+#ifdef SIN6_LEN
+ sin6l->sin6_len = sizeof(struct sockaddr_in6);
+#endif /* SIN6_LEN */
+ addrs[1].ss_family = AF_INET6;
+ inet_ntop(AF_INET6, &sin6l->sin6_addr, local, 64);
+
+ memset(&addrs[0], 0, sizeof(addrs[0]));
+ sin6r = (struct sockaddr_in6 *)&addrs[0];
+
+ for (i=0; i<16; i++) {
+ sin6r->sin6_addr.s6_addr[i] = conn->subs[19+i];
+ }
+
+ sin6r->sin6_port = htons(conn->subs[35]);
+#ifdef SIN6_LEN
+ sin6r->sin6_len = sizeof(struct sockaddr_in6);
+#endif /* SIN6_LEN */
+ addrs[0].ss_family = AF_INET6;
+
+ inet_ntop(AF_INET6, &sin6r->sin6_addr, remote, 64);
+
+ syslog(LOG_INFO, "[%s] attempt to delete a tcp6 connection: local: %s:%d - remote: %s:%d \n ",
+ __func__,
+ local,
+ conn->subs[17],
+ remote,
+ conn->subs[35]);
+
+
+ } else {
+ assert(0);
+ syslog(LOG_ERR, "%s: malformed SNMP index (not v4, not v6) when deleting a connection",
+ __func__);
+ return -1;
+
+ }
+ if (sysctl(mib, sizeof (mib) / sizeof (int), NULL,
+ NULL, &addrs, sizeof(addrs)) == -1) {
+ syslog(LOG_ERR, "%s: failed to delete the specified tcp connection: %m", __func__);
+ return -1;
+ } else {
+ TCP46_DPRINTF((stderr, "[%s] one tcp connection deleted\n ",
+ __func__));
+
+ syslog(LOG_INFO, "%s: one tcp connection deleted.", __func__);
+ return 0;
+
+ }
+ return 0;
+}
+
+
/*
* Scalars
*/
@@ -1092,11 +1236,34 @@
return (SNMP_ERR_NOSUCHNAME);
break;
- case SNMP_OP_SET:
- return (SNMP_ERR_NOT_WRITEABLE);
+ case SNMP_OP_SET: {
+ if (value->var.subs[sub - 1] != LEAF_tcpConnectionState) {
+ return (SNMP_ERR_NOT_WRITEABLE);
+ }
+ if (value->v.integer != TCPS_deleteTCB) {
+ return (SNMP_ERR_WRONG_VALUE);
+ }
+
+ for (i = 0; i < tcp46_state_g.all_tcp_total; i++)
+ if (index_compare(&value->var, sub,
+ &tcp46_state_g.all_tcpoids[i].index) == 0)
+ break;
+
+ if (i == tcp46_state_g.all_tcp_total)
+ return (SNMP_ERR_NOSUCHNAME);
+
+ if (drop_new_tcp_conn(&tcp46_state_g.all_tcpoids[i].index) != 0) {
+ return (SNMP_ERR_NOSUCHNAME);
+ }
+ return (SNMP_ERR_NOERROR);
+
+ }
case SNMP_OP_ROLLBACK:
- case SNMP_OP_COMMIT:
+ case SNMP_OP_COMMIT: {
+ return (SNMP_ERR_NOERROR);
+ }
+
default:
abort();
}
More information about the p4-projects
mailing list