summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2004-04-25 04:34:06 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2004-04-25 04:34:06 +0000
commit02e4ba579e5d3a5e96773d05e9ea6941ea48bf83 (patch)
treed50ef13e8a3a01a1d7c5759a1ceec6a7e3fd4961 /sys
parent84b2b7baa39e50e3e65a993b1d9f2605249b779e (diff)
add TCPCTL_DROP; ok deraadt, cedric, grange, ...
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/tcp_usrreq.c37
-rw-r--r--sys/netinet/tcp_var.h7
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 \
}