Date: Thu, 25 Aug 2005 23:18:26 GMT From: Victor Cruceru <soc-victor@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 82568 for review Message-ID: <200508252318.j7PNIQ6i091839@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82568 Change 82568 by soc-victor@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(); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508252318.j7PNIQ6i091839>