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