summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/in_pcb.c34
-rw-r--r--sys/netinet/in_pcb.h3
-rw-r--r--sys/netinet/ip_icmp.c9
3 files changed, 42 insertions, 4 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index a70cce48c03..76166411634 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.c,v 1.45 2000/09/20 16:39:50 provos Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.46 2000/10/09 14:39:46 provos Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
@@ -712,6 +712,38 @@ in_pcbnotifyall(table, dst, errno, notify)
}
/*
+ * Check if we have a socket that talks to the given destination.
+ */
+
+int
+in_pcbconnected(table, dst)
+ struct inpcbtable *table;
+ struct sockaddr *dst;
+{
+ struct inpcb *inp;
+ struct in_addr faddr;
+
+ if (dst->sa_family != AF_INET)
+ return (0);
+ faddr = satosin(dst)->sin_addr;
+ if (faddr.s_addr == INADDR_ANY)
+ return (0);
+
+ for (inp = table->inpt_queue.cqh_first;
+ inp != (struct inpcb *)&table->inpt_queue;
+ inp = inp->inp_queue.cqe_next) {
+#ifdef INET6
+ if (inp->inp_flags & INP_IPV6)
+ continue;
+#endif
+ if (inp->inp_faddr.s_addr == faddr.s_addr && inp->inp_socket)
+ break;
+ }
+
+ return (inp != (struct inpcb *)&table->inpt_queue);
+}
+
+/*
* Check for alternatives when higher level complains
* about service problems. For now, invalidate cached
* routing information. If the route was created dynamically
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 7b8dec2ab7c..4fa8f75133a 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.h,v 1.26 2000/09/18 22:06:37 provos Exp $ */
+/* $OpenBSD: in_pcb.h,v 1.27 2000/10/09 14:39:46 provos Exp $ */
/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
/*
@@ -253,6 +253,7 @@ void in_pcbnotify __P((struct inpcbtable *, struct sockaddr *,
u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int)));
void in_pcbnotifyall __P((struct inpcbtable *, struct sockaddr *,
int, void (*)(struct inpcb *, int)));
+int in_pcbconnected __P((struct inpcbtable *, struct sockaddr *));
void in_pcbrehash __P((struct inpcb *));
void in_rtchange __P((struct inpcb *, int));
void in_setpeeraddr __P((struct inpcb *, struct mbuf *));
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 38e287f1582..a352aec2e7d 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_icmp.c,v 1.26 2000/09/26 01:02:25 angelos Exp $ */
+/* $OpenBSD: ip_icmp.c,v 1.27 2000/10/09 14:39:46 provos Exp $ */
/* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */
/*
@@ -71,6 +71,7 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
#include <netinet/ip_icmp.h>
#include <netinet/ip_var.h>
#include <netinet/icmp_var.h>
+#include <netinet/in_pcb.h>
#include <machine/stdarg.h>
@@ -741,12 +742,16 @@ icmp_mtudisc(icp)
struct sockaddr *dst = sintosa(&icmpsrc);
u_long mtu = ntohs(icp->icmp_nextmtu); /* Why a long? IPv6 */
int error;
-
+ extern struct inpcbtable tcbtable;
+
/* Table of common MTUs: */
static u_short mtu_table[] = {65535, 65280, 32000, 17914, 9180, 8166,
4352, 2002, 1492, 1006, 508, 296, 68, 0};
+ if (!in_pcbconnected(&tcbtable, sintosa(&icmpsrc)))
+ return;
+
rt = rtalloc1(dst, 1);
if (rt == 0)
return;