summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_usrreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/tcp_usrreq.c')
-rw-r--r--sys/netinet/tcp_usrreq.c37
1 files changed, 31 insertions, 6 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,