diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2004-04-25 04:34:06 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2004-04-25 04:34:06 +0000 |
commit | 02e4ba579e5d3a5e96773d05e9ea6941ea48bf83 (patch) | |
tree | d50ef13e8a3a01a1d7c5759a1ceec6a7e3fd4961 /sys | |
parent | 84b2b7baa39e50e3e65a993b1d9f2605249b779e (diff) |
add TCPCTL_DROP; ok deraadt, cedric, grange, ...
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 37 | ||||
-rw-r--r-- | sys/netinet/tcp_var.h | 7 |
2 files changed, 36 insertions, 8 deletions
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 612783fe551..abafe056ef2 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_usrreq.c,v 1.82 2004/04/12 19:05:38 tedu Exp $ */ +/* $OpenBSD: tcp_usrreq.c,v 1.83 2004/04/25 04:34:05 markus Exp $ */ /* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */ /* @@ -120,7 +120,7 @@ int *tcpctl_vars[TCPCTL_MAXID] = TCPCTL_VARS; struct inpcbtable tcbtable; -int tcp_ident(void *, size_t *, void *, size_t); +int tcp_ident(void *, size_t *, void *, size_t, int); #ifdef INET6 int @@ -771,25 +771,36 @@ tcp_usrclosed(tp) } /* - * Look up a socket for ident.. + * Look up a socket for ident or tcpdrop, ... */ int -tcp_ident(oldp, oldlenp, newp, newlen) +tcp_ident(oldp, oldlenp, newp, newlen, dodrop) void *oldp; size_t *oldlenp; void *newp; size_t newlen; + int dodrop; { int error = 0, s; struct tcp_ident_mapping tir; struct inpcb *inp; + struct tcpcb *tp = NULL; struct sockaddr_in *fin, *lin; #ifdef INET6 struct sockaddr_in6 *fin6, *lin6; struct in6_addr f6, l6; #endif - if (oldp == NULL || newp != NULL || newlen != 0) + if (oldp == NULL) + return (EINVAL); + if (dodrop) { + /* + * XXX stupid permission hack: + * only root may set newp, so we require newp for tcp_drop() + */ + if (newp == NULL) + return (EPERM); + } else if (newp != NULL || newlen != 0) return (EINVAL); if (*oldlenp < sizeof(tir)) return (ENOMEM); @@ -830,6 +841,16 @@ tcp_ident(oldp, oldlenp, newp, newlen) break; } + if (dodrop) { + if (inp && (tp = intotcpcb(inp)) && + ((inp->inp_socket->so_options & SO_ACCEPTCONN) == 0)) + tp = tcp_drop(tp, ECONNABORTED); + else + error = ESRCH; + splx(s); + return (error); + } + if (inp == NULL) { ++tcpstat.tcps_pcbhashmiss; switch (tir.faddr.ss_family) { @@ -892,7 +913,11 @@ tcp_sysctl(name, namelen, oldp, oldlenp, newp, newlen) baddynamicports.tcp, sizeof(baddynamicports.tcp))); case TCPCTL_IDENT: - return (tcp_ident(oldp, oldlenp, newp, newlen)); + return (tcp_ident(oldp, oldlenp, newp, newlen, 0)); + + case TCPCTL_DROP: + return (tcp_ident(oldp, oldlenp, newp, newlen, 1)); + #ifdef TCP_ECN case TCPCTL_ECN: return (sysctl_int(oldp, oldlenp, newp, newlen, diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 30b9f4aa41c..dbc9718f540 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_var.h,v 1.62 2004/04/20 20:05:29 markus Exp $ */ +/* $OpenBSD: tcp_var.h,v 1.63 2004/04/25 04:34:05 markus Exp $ */ /* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */ /* @@ -465,7 +465,8 @@ struct tcpstat { #define TCPCTL_SYN_BUCKET_LIMIT 16 /* max size of hash bucket */ #define TCPCTL_RFC3390 17 /* enable/disable RFC3390 increased cwnd */ #define TCPCTL_REASS_LIMIT 18 /* max entries for tcp reass queues */ -#define TCPCTL_MAXID 19 +#define TCPCTL_DROP 19 /* drop tcp connection */ +#define TCPCTL_MAXID 20 #define TCPCTL_NAMES { \ { 0, 0 }, \ @@ -487,6 +488,7 @@ struct tcpstat { { "synbucketlimit", CTLTYPE_INT }, \ { "rfc3390", CTLTYPE_INT }, \ { "reasslimit", CTLTYPE_INT }, \ + { "drop", CTLTYPE_STRUCT }, \ } #define TCPCTL_VARS { \ @@ -508,6 +510,7 @@ struct tcpstat { &tcp_syn_cache_limit, \ &tcp_syn_bucket_limit, \ &tcp_do_rfc3390, \ + NULL, \ NULL \ } |