+ /*
+ * Check to see if we have a valid TCP connection
+ * corresponding to the address in the ICMPv6 message
+ * payload.
+ */
+ inp = in6_pcbhashlookup(&tcbtable, &sa6->sin6_addr,
+ th.th_dport, (struct in6_addr *)&sa6_src->sin6_addr,
+ th.th_sport);
if (cmd == PRC_MSGSIZE) {
- int valid = 0;
-
- /*
- * Check to see if we have a valid TCP connection
- * corresponding to the address in the ICMPv6 message
- * payload.
- */
- if (in6_pcbhashlookup(&tcbtable, &sa6->sin6_addr,
- th.th_dport, (struct in6_addr *)&sa6_src->sin6_addr,
- th.th_sport))
- valid++;
- else if (in_pcblookup(&tcbtable, &sa6->sin6_addr,
- th.th_dport, (struct in6_addr *)&sa6_src->sin6_addr,
- th.th_sport, INPLOOKUP_IPV6))
- valid++;
-
/*
* Depending on the value of "valid" and routing table
* size (mtudisc_{hi,lo}wat), we will:
@@ -870,13 +868,17 @@ tcp6_ctlinput(cmd, sa, d)
* corresponding routing entry, or
* - ignore the MTU change notification.
*/
- icmp6_mtudisc_update((struct ip6ctlparam *)d, valid);
-
+ icmp6_mtudisc_update((struct ip6ctlparam *)d, inp != NULL);
return;
}
-
- (void) in6_pcbnotify(&tcbtable, sa, th.th_dport,
- (struct sockaddr *)sa6_src, th.th_sport, cmd, NULL, notify);
+ if (inp) {
+ seq = ntohl(th.th_seq);
+ if (inp->inp_socket &&
+ (tp = intotcpcb(inp)) &&
+ SEQ_GEQ(seq, tp->snd_una) &&
+ SEQ_LT(seq, tp->snd_max))
+ notify(inp, inet6ctlerrmap[cmd]);
+ }
} else {
(void) in6_pcbnotify(&tcbtable, sa, 0,
(struct sockaddr *)sa6_src, 0, cmd, NULL, notify);
@@ -892,12 +894,19 @@ tcp_ctlinput(cmd, sa, v)
{
register struct ip *ip = v;
register struct tcphdr *th;
+ struct tcpcb *tp;
+ struct inpcb *inp;
+ struct in_addr faddr;
+ tcp_seq seq;
extern int inetctlerrmap[];
void (*notify)(struct inpcb *, int) = tcp_notify;
int errno;
if (sa->sa_family != AF_INET)
return NULL;
+ faddr = satosin(sa)->sin_addr;
+ if (faddr.s_addr == INADDR_ANY)
+ return NULL;
if ((unsigned)cmd >= PRC_NCMDS)
return NULL;
@@ -906,22 +915,27 @@ tcp_ctlinput(cmd, sa, v)
notify = tcp_quench;
else if (PRC_IS_REDIRECT(cmd))
notify = in_rtchange, ip = 0;
- else if (cmd == PRC_MSGSIZE && ip_mtudisc) {
- th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
+ else if (cmd == PRC_MSGSIZE && ip_mtudisc && ip) {
/*
* Verify that the packet in the icmp payload refers
* to an existing TCP connection.
*/
- if (in_pcblookup(&tcbtable,
- &ip->ip_dst, th->th_dport,
- &ip->ip_src, th->th_sport,
- INPLOOKUP_WILDCARD)) {
+ th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
+ seq = ntohl(th->th_seq);
+ inp = in_pcbhashlookup(&tcbtable,
+ ip->ip_dst, th->th_dport, ip->ip_src, th->th_sport);
+ if (inp && (tp = intotcpcb(inp)) &&
+ SEQ_GEQ(seq, tp->snd_una) &&
+ SEQ_LT(seq, tp->snd_max)) {
struct icmp *icp;
icp = (struct icmp *)((caddr_t)ip -
offsetof(struct icmp, icmp_ip));
/* Calculate new mtu and create corresponding route */
icmp_mtudisc(icp);
+ } else {
+ /* ignore if we don't have a matching connection */
+ return NULL;
}
notify = tcp_mtudisc, ip = 0;
} else if (cmd == PRC_MTUINC)
@@ -933,8 +947,16 @@ tcp_ctlinput(cmd, sa, v)