route6.c (53541) | route6.c (62587) |
---|---|
1/* $FreeBSD: head/sys/netinet6/route6.c 62587 2000-07-04 16:35:15Z itojun $ */ 2/* $KAME: route6.c,v 1.15 2000/06/23 16:18:20 itojun Exp $ */ 3 |
|
1/* 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. | 4/* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. |
28 * 29 * $FreeBSD: head/sys/netinet6/route6.c 53541 1999-11-22 02:45:11Z shin $ | |
30 */ 31 | 31 */ 32 |
33#include "opt_inet.h" 34#include "opt_inet6.h" 35 |
|
32#include <sys/param.h> 33#include <sys/mbuf.h> 34#include <sys/socket.h> | 36#include <sys/param.h> 37#include <sys/mbuf.h> 38#include <sys/socket.h> |
39#include <sys/systm.h> |
|
35 36#include <net/if.h> 37 38#include <netinet/in.h> | 40 41#include <net/if.h> 42 43#include <netinet/in.h> |
39#include <netinet6/in6.h> | |
40#include <netinet6/in6_var.h> | 44#include <netinet6/in6_var.h> |
41#include <netinet6/ip6.h> | 45#include |
42#include <netinet6/ip6_var.h> 43 44#include <netinet/icmp6.h> 45 | 46#include <netinet6/ip6_var.h> 47 48#include <netinet/icmp6.h> 49 |
46static int ip6_rthdr0 __P((struct mbuf *, struct ip6_hdr *, struct ip6_rthdr0 *)); | 50static int ip6_rthdr0 __P((struct mbuf *, struct ip6_hdr *, 51 struct ip6_rthdr0 *)); |
47 48int 49route6_input(mp, offp, proto) 50 struct mbuf **mp; 51 int *offp, proto; /* proto is unused */ 52{ 53 register struct ip6_hdr *ip6; 54 register struct mbuf *m = *mp; 55 register struct ip6_rthdr *rh; 56 int off = *offp, rhlen; 57 | 52 53int 54route6_input(mp, offp, proto) 55 struct mbuf **mp; 56 int *offp, proto; /* proto is unused */ 57{ 58 register struct ip6_hdr *ip6; 59 register struct mbuf *m = *mp; 60 register struct ip6_rthdr *rh; 61 int off = *offp, rhlen; 62 |
63#ifndef PULLDOWN_TEST |
|
58 IP6_EXTHDR_CHECK(m, off, sizeof(*rh), IPPROTO_DONE); 59 ip6 = mtod(m, struct ip6_hdr *); 60 rh = (struct ip6_rthdr *)((caddr_t)ip6 + off); | 64 IP6_EXTHDR_CHECK(m, off, sizeof(*rh), IPPROTO_DONE); 65 ip6 = mtod(m, struct ip6_hdr *); 66 rh = (struct ip6_rthdr *)((caddr_t)ip6 + off); |
67#else 68 ip6 = mtod(m, struct ip6_hdr *); 69 IP6_EXTHDR_GET(rh, struct ip6_rthdr *, m, off, sizeof(*rh)); 70 if (rh == NULL) { 71 ip6stat.ip6s_tooshort++; 72 return IPPROTO_DONE; 73 } 74#endif |
|
61 | 75 |
62 switch(rh->ip6r_type) { 63 case IPV6_RTHDR_TYPE_0: 64 rhlen = (rh->ip6r_len + 1) << 3; 65 IP6_EXTHDR_CHECK(m, off, rhlen, IPPROTO_DONE); 66 if (ip6_rthdr0(m, ip6, (struct ip6_rthdr0 *)rh)) 67 return(IPPROTO_DONE); 68 break; 69 default: 70 /* unknown routing type */ 71 if (rh->ip6r_segleft == 0) { 72 rhlen = (rh->ip6r_len + 1) << 3; 73 break; /* Final dst. Just ignore the header. */ 74 } 75 ip6stat.ip6s_badoptions++; 76 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 77 (caddr_t)&rh->ip6r_type - (caddr_t)ip6); 78 return(IPPROTO_DONE); | 76 switch (rh->ip6r_type) { 77 case IPV6_RTHDR_TYPE_0: 78 rhlen = (rh->ip6r_len + 1) << 3; 79#ifndef PULLDOWN_TEST 80 /* 81 * note on option length: 82 * due to IP6_EXTHDR_CHECK assumption, we cannot handle 83 * very big routing header (max rhlen == 2048). 84 */ 85 IP6_EXTHDR_CHECK(m, off, rhlen, IPPROTO_DONE); 86#else 87 /* 88 * note on option length: 89 * maximum rhlen: 2048 90 * max mbuf m_pulldown can handle: MCLBYTES == usually 2048 91 * so, here we are assuming that m_pulldown can handle 92 * rhlen == 2048 case. this may not be a good thing to 93 * assume - we may want to avoid pulling it up altogether. 94 */ 95 IP6_EXTHDR_GET(rh, struct ip6_rthdr *, m, off, rhlen); 96 if (rh == NULL) { 97 ip6stat.ip6s_tooshort++; 98 return IPPROTO_DONE; 99 } 100#endif 101 if (ip6_rthdr0(m, ip6, (struct ip6_rthdr0 *)rh)) 102 return(IPPROTO_DONE); 103 break; 104 default: 105 /* unknown routing type */ 106 if (rh->ip6r_segleft == 0) { 107 rhlen = (rh->ip6r_len + 1) << 3; 108 break; /* Final dst. Just ignore the header. */ 109 } 110 ip6stat.ip6s_badoptions++; 111 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 112 (caddr_t)&rh->ip6r_type - (caddr_t)ip6); 113 return(IPPROTO_DONE); |
79 } 80 81 *offp += rhlen; 82 return(rh->ip6r_nxt); 83} 84 85/* 86 * Type0 routing header processing --- 30 unchanged lines hidden (view full) --- 117 ip6stat.ip6s_badoptions++; 118 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 119 (caddr_t)&rh0->ip6r0_segleft - (caddr_t)ip6); 120 return(-1); 121 } 122 123 index = addrs - rh0->ip6r0_segleft; 124 rh0->ip6r0_segleft--; | 114 } 115 116 *offp += rhlen; 117 return(rh->ip6r_nxt); 118} 119 120/* 121 * Type0 routing header processing --- 30 unchanged lines hidden (view full) --- 152 ip6stat.ip6s_badoptions++; 153 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 154 (caddr_t)&rh0->ip6r0_segleft - (caddr_t)ip6); 155 return(-1); 156 } 157 158 index = addrs - rh0->ip6r0_segleft; 159 rh0->ip6r0_segleft--; |
125 nextaddr = rh0->ip6r0_addr + index; | 160 nextaddr = ((struct in6_addr *)(rh0 + 1)) + index; |
126 | 161 |
162 /* 163 * reject invalid addresses. be proactive about malicious use of 164 * IPv4 mapped/compat address. 165 * XXX need more checks? 166 */ |
|
127 if (IN6_IS_ADDR_MULTICAST(nextaddr) || | 167 if (IN6_IS_ADDR_MULTICAST(nextaddr) || |
128 IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { | 168 IN6_IS_ADDR_UNSPECIFIED(nextaddr) || 169 IN6_IS_ADDR_V4MAPPED(nextaddr) || 170 IN6_IS_ADDR_V4COMPAT(nextaddr)) { |
129 ip6stat.ip6s_badoptions++; 130 m_freem(m); 131 return(-1); 132 } | 171 ip6stat.ip6s_badoptions++; 172 m_freem(m); 173 return(-1); 174 } |
175 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || 176 IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst) || 177 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst) || 178 IN6_IS_ADDR_V4COMPAT(nextaddr)) { 179 ip6stat.ip6s_badoptions++; 180 m_freem(m); 181 return(-1); 182 } |
|
133 134 /* 135 * Swap the IPv6 destination address and nextaddr. Forward the packet. 136 */ 137 tmpaddr = *nextaddr; 138 *nextaddr = ip6->ip6_dst; 139 if (IN6_IS_ADDR_LINKLOCAL(nextaddr)) 140 nextaddr->s6_addr16[1] = 0; --- 15 unchanged lines hidden --- | 183 184 /* 185 * Swap the IPv6 destination address and nextaddr. Forward the packet. 186 */ 187 tmpaddr = *nextaddr; 188 *nextaddr = ip6->ip6_dst; 189 if (IN6_IS_ADDR_LINKLOCAL(nextaddr)) 190 nextaddr->s6_addr16[1] = 0; --- 15 unchanged lines hidden --- |