diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1999-01-08 11:35:10 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1999-01-08 11:35:10 +0000 |
commit | 31a4a466bd4e268bf67e70a654d1d91354af0c64 (patch) | |
tree | 5fbcf5a6cfcf5a40a75e73b81a651ae89dad734b /sys/netinet | |
parent | 5357d4177b6823683997a5326ec84bd65389f26a (diff) |
IPV6 pieces; NRL
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ip_icmp.c | 116 |
1 files changed, 86 insertions, 30 deletions
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index 9603862ebd7..ba1071a6a94 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_icmp.c,v 1.15 1999/01/08 01:04:17 deraadt Exp $ */ +/* $OpenBSD: ip_icmp.c,v 1.16 1999/01/08 11:35:09 deraadt Exp $ */ /* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */ /* @@ -36,6 +36,18 @@ * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 */ +/* +%%% portions-copyright-nrl-95 +Portions of this software are Copyright 1995-1998 by Randall Atkinson, +Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights +Reserved. All rights under this copyright have been assigned to the US +Naval Research Laboratory (NRL). The NRL Copyright Notice and License +Agreement Version 1.1 (January 17, 1995) applies to these portions of the +software. +You should have received a copy of the license with this software. If you +didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>. +*/ + #include <sys/param.h> #include <sys/systm.h> #include <sys/malloc.h> @@ -259,36 +271,62 @@ icmp_input(m, va_alist) case ICMP_UNREACH: switch (code) { - case ICMP_UNREACH_NET: - case ICMP_UNREACH_HOST: - case ICMP_UNREACH_PROTOCOL: - case ICMP_UNREACH_PORT: - case ICMP_UNREACH_SRCFAIL: - code += PRC_UNREACH_NET; - break; - - case ICMP_UNREACH_NEEDFRAG: - code = PRC_MSGSIZE; - break; + case ICMP_UNREACH_NET: + case ICMP_UNREACH_HOST: + case ICMP_UNREACH_PROTOCOL: + case ICMP_UNREACH_PORT: + case ICMP_UNREACH_SRCFAIL: + code += PRC_UNREACH_NET; + break; + + case ICMP_UNREACH_NEEDFRAG: +#ifdef INET6 + if (icp->icmp_nextmtu) { + extern int ipv6_trans_mtu + __P((struct mbuf **, int, int)); + struct mbuf *m0 = m; + + /* + * Do cool v4-related path MTU, for now, + * only v6-in-v4 can handle it. + */ + if (icmplen >= ICMP_V6ADVLENMIN && + icmplen >= ICMP_V6ADVLEN(icp) && + icp->icmp_ip.ip_p == IPPROTO_IPV6) { + /* + * ipv6_trans_mtu returns 1 if + * the mbuf is still intact. + */ + if (ipv6_trans_mtu(&m0,icp->icmp_nextmtu, + hlen + ICMP_V6ADVLEN(icp))) { + m = m0; + goto raw; + } else + return; + } + } +#endif /* INET6 */ + code = PRC_MSGSIZE; + break; - case ICMP_UNREACH_NET_UNKNOWN: - case ICMP_UNREACH_NET_PROHIB: - case ICMP_UNREACH_TOSNET: - code = PRC_UNREACH_NET; - break; - - case ICMP_UNREACH_HOST_UNKNOWN: - case ICMP_UNREACH_ISOLATED: - case ICMP_UNREACH_HOST_PROHIB: - case ICMP_UNREACH_TOSHOST: - case ICMP_UNREACH_FILTER_PROHIB: - case ICMP_UNREACH_HOST_PRECEDENCE: - case ICMP_UNREACH_PRECEDENCE_CUTOFF: - code = PRC_UNREACH_HOST; - break; - - default: - goto badcode; + case ICMP_UNREACH_NET_UNKNOWN: + case ICMP_UNREACH_NET_PROHIB: + case ICMP_UNREACH_TOSNET: + code = PRC_UNREACH_NET; + break; + + case ICMP_UNREACH_HOST_UNKNOWN: + case ICMP_UNREACH_ISOLATED: + case ICMP_UNREACH_HOST_PROHIB: + case ICMP_UNREACH_TOSHOST: + case ICMP_UNREACH_FILTER_PROHIB: + case ICMP_UNREACH_HOST_PRECEDENCE: + case ICMP_UNREACH_PRECEDENCE_CUTOFF: + code = PRC_UNREACH_HOST; + break; + + default: + goto badcode; } goto deliver; @@ -320,6 +358,24 @@ icmp_input(m, va_alist) if (IN_MULTICAST(icp->icmp_ip.ip_dst.s_addr)) goto badcode; NTOHS(icp->icmp_ip.ip_len); +#ifdef INET6 + /* Get more contiguous data for a v6 in v4 ICMP message. */ + if (icp->icmp_ip.ip_p == IPPROTO_IPV6) { + if (icmplen < ICMP_V6ADVLENMIN || + icmplen < ICMP_V6ADVLEN(icp)) { + icmpstat.icps_badlen++; + goto freeit; + } else { + if (!(m = m_pullup(m, (ip->ip_hl << 2) + + ICMP_V6ADVLEN(icp)))) { + icmpstat.icps_tooshort++; + return; + } + ip = mtod(m, struct ip *); + icp = (struct icmp *)(m->m_data + (ip->ip_hl << 2)); + } + } +#endif /* INET6 */ #ifdef ICMPPRINTFS if (icmpprintfs) printf("deliver to protocol %d\n", icp->icmp_ip.ip_p); |