diff options
-rw-r--r-- | sys/netinet/in_pcb.c | 34 | ||||
-rw-r--r-- | sys/netinet/in_pcb.h | 3 | ||||
-rw-r--r-- | sys/netinet/ip_icmp.c | 9 |
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; |