in6_proto.c revision 55009
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 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the project nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 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. 28 * 29 * $FreeBSD: head/sys/netinet6/in6_proto.c 55009 1999-12-22 19:13:38Z shin $ 30 */ 31 32/* 33 * Copyright (c) 1982, 1986, 1993 34 * The Regents of the University of California. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. All advertising materials mentioning features or use of this software 45 * must display the following acknowledgement: 46 * This product includes software developed by the University of 47 * California, Berkeley and its contributors. 48 * 4. Neither the name of the University nor the names of its contributors 49 * may be used to endorse or promote products derived from this software 50 * without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * SUCH DAMAGE. 63 * 64 * @(#)in_proto.c 8.1 (Berkeley) 6/10/93 65 */ 66 67#include "opt_ipsec.h" 68 69#include <sys/param.h> 70#include <sys/socket.h> 71#include <sys/socketvar.h> 72#include <sys/protosw.h> 73#include <sys/kernel.h> 74#include <sys/domain.h> 75#include <sys/mbuf.h> 76#include <sys/systm.h> 77#include <sys/sysctl.h> 78 79#include <net/if.h> 80#include <net/radix.h> 81#include <net/route.h> 82 83#include <netinet/in.h> 84#include <netinet/in_systm.h> 85#include <netinet/in_var.h> 86#include <netinet/ip.h> 87#include <netinet/ip_var.h> 88#include <netinet6/ip6.h> 89#include <netinet6/ip6_var.h> 90#include <netinet6/icmp6.h> 91 92#include <netinet/tcp.h> 93#include <netinet/tcp_timer.h> 94#include <netinet/tcp_var.h> 95#include <netinet/udp.h> 96#include <netinet/udp_var.h> 97#include <netinet6/tcp6_var.h> 98#include <netinet6/udp6_var.h> 99 100#include <netinet6/pim6_var.h> 101 102#include <netinet6/nd6.h> 103#include <netinet6/in6_prefix.h> 104 105#ifdef IPSEC 106#include <netinet6/ipsec.h> 107#include <netinet6/ah.h> 108#include <netinet6/ipsec6.h> 109#include <netinet6/ah6.h> 110#ifdef IPSEC_ESP 111#include <netinet6/esp.h> 112#include <netinet6/esp6.h> 113#endif 114#endif /*IPSEC*/ 115 116#include <netinet6/ip6protosw.h> 117 118#include "gif.h" 119#if NGIF > 0 120#include <netinet6/in6_gif.h> 121#endif 122 123#include <net/net_osdep.h> 124 125#define offsetof(type, member) ((size_t)(&((type *)0)->member)) 126 127/* 128 * TCP/IP protocol family: IP6, ICMP6, UDP, TCP. 129 */ 130 131extern struct domain inet6domain; 132static struct pr_usrreqs nousrreqs; 133 134struct ip6protosw inet6sw[] = { 135{ 0, &inet6domain, IPPROTO_IPV6, 0, 136 0, 0, 0, 0, 137 0, 138 ip6_init, 0, frag6_slowtimo, frag6_drain, 139 &nousrreqs, 140}, 141{ SOCK_DGRAM, &inet6domain, IPPROTO_UDP, PR_ATOMIC | PR_ADDR, 142 udp6_input, 0, udp6_ctlinput, ip6_ctloutput, 143 0, 144 0, 0, 0, 0, 145 &udp6_usrreqs, 146}, 147{ SOCK_RAW, &inet6domain, IPPROTO_RAW, PR_ATOMIC | PR_ADDR, 148 rip6_input, rip6_output, 0, rip6_ctloutput, 149 0, 150 0, 0, 0, 0, 151 &rip6_usrreqs 152}, 153{ SOCK_RAW, &inet6domain, IPPROTO_ICMPV6, PR_ATOMIC | PR_ADDR, 154 icmp6_input, rip6_output, 0, rip6_ctloutput, 155 0, 156 icmp6_init, icmp6_fasttimo, 0, 0, 157 &rip6_usrreqs 158}, 159{ SOCK_RAW, &inet6domain, IPPROTO_DSTOPTS,PR_ATOMIC|PR_ADDR, 160 dest6_input, 0, 0, 0, 161 0, 162 0, 0, 0, 0, 163 &nousrreqs 164}, 165{ SOCK_RAW, &inet6domain, IPPROTO_ROUTING,PR_ATOMIC|PR_ADDR, 166 route6_input, 0, 0, 0, 167 0, 168 0, 0, 0, 0, 169 &nousrreqs 170}, 171{ SOCK_RAW, &inet6domain, IPPROTO_FRAGMENT,PR_ATOMIC|PR_ADDR, 172 frag6_input, 0, 0, 0, 173 0, 174 0, 0, 0, 0, 175 &nousrreqs 176}, 177#ifdef IPSEC 178{ SOCK_RAW, &inet6domain, IPPROTO_AH, PR_ATOMIC|PR_ADDR, 179 ah6_input, 0, 0, 0, 180 0, 181 0, 0, 0, 0, 182 &nousrreqs, 183}, 184#ifdef IPSEC_ESP 185{ SOCK_RAW, &inet6domain, IPPROTO_ESP, PR_ATOMIC|PR_ADDR, 186 esp6_input, 0, 0, 0, 187 0, 188 0, 0, 0, 0, 189 &nousrreqs, 190}, 191#endif 192#endif /* IPSEC */ 193#if NGIF > 0 194{ SOCK_RAW, &inet6domain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR, 195 in6_gif_input,0, 0, 0, 196 0, 197 0, 0, 0, 0, 198 &nousrreqs 199}, 200{ SOCK_RAW, &inet6domain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR, 201 in6_gif_input,0, 0, 0, 202 0, 203 0, 0, 0, 0, 204 &nousrreqs 205}, 206#endif /* GIF */ 207/* raw wildcard */ 208{ SOCK_RAW, &inet6domain, 0, PR_ATOMIC | PR_ADDR, 209 rip6_input, rip6_output, 0, rip6_ctloutput, 210 0, 211 0, 0, 0, 0, 212 &rip6_usrreqs 213}, 214}; 215 216extern int in6_inithead __P((void **, int)); 217 218struct domain inet6domain = 219 { AF_INET6, "internet6", 0, 0, 0, 220 (struct protosw *)inet6sw, 221 (struct protosw *)&inet6sw[sizeof(inet6sw)/sizeof(inet6sw[0])], 0, 222 in6_inithead, 223 offsetof(struct sockaddr_in6, sin6_addr) << 3, 224 sizeof(struct sockaddr_in6) }; 225 226DOMAIN_SET(inet6); 227 228/* 229 * Internet configuration info 230 */ 231#ifndef IPV6FORWARDING 232#ifdef GATEWAY6 233#define IPV6FORWARDING 1 /* forward IP6 packets not for us */ 234#else 235#define IPV6FORWARDING 0 /* don't forward IP6 packets not for us */ 236#endif /* GATEWAY6 */ 237#endif /* !IPV6FORWARDING */ 238 239#ifndef IPV6_SENDREDIRECTS 240#define IPV6_SENDREDIRECTS 1 241#endif 242 243int ip6_forwarding = IPV6FORWARDING; /* act as router? */ 244int ip6_sendredirects = IPV6_SENDREDIRECTS; 245int ip6_defhlim = IPV6_DEFHLIM; 246int ip6_defmcasthlim = IPV6_DEFAULT_MULTICAST_HOPS; 247int ip6_accept_rtadv = 0; /* "IPV6FORWARDING ? 0 : 1" is dangerous */ 248int ip6_maxfragpackets = 200; 249int ip6_log_interval = 5; 250int ip6_hdrnestlimit = 50; /* appropriate? */ 251int ip6_dad_count = 1; /* DupAddrDetectionTransmits */ 252u_int32_t ip6_flow_seq; 253int ip6_auto_flowlabel = 1; 254#if NGIF > 0 255int ip6_gif_hlim = GIF_HLIM; 256#else 257int ip6_gif_hlim = 0; 258#endif 259int ip6_use_deprecated = 1; /* allow deprecated addr (RFC2462 5.5.4) */ 260int ip6_rr_prune = 5; /* router renumbering prefix 261 * walk list every 5 sec. */ 262int ip6_mapped_addr_on = 1; 263 264u_int32_t ip6_id = 0UL; 265int ip6_keepfaith = 0; 266time_t ip6_log_time = (time_t)0L; 267 268/* icmp6 */ 269/* 270 * BSDI4 defines these variables in in_proto.c... 271 * XXX: what if we don't define INET? Should we define pmtu6_expire 272 * or so? (jinmei@kame.net 19990310) 273 */ 274int pmtu_expire = 60*10; 275int pmtu_probe = 60*2; 276 277/* raw IP6 parameters */ 278/* 279 * Nominal space allocated to a raw ip socket. 280 */ 281#define RIPV6SNDQ 8192 282#define RIPV6RCVQ 8192 283 284u_long rip6_sendspace = RIPV6SNDQ; 285u_long rip6_recvspace = RIPV6RCVQ; 286 287/* ICMPV6 parameters */ 288int icmp6_rediraccept = 1; /* accept and process redirects */ 289int icmp6_redirtimeout = 10 * 60; /* 10 minutes */ 290u_int icmp6errratelim = 1000; /* 1000usec = 1msec */ 291 292/* UDP on IP6 parameters */ 293int udp6_sendspace = 9216; /* really max datagram size */ 294int udp6_recvspace = 40 * (1024 + sizeof(struct sockaddr_in6)); 295 /* 40 1K datagrams */ 296 297/* 298 * sysctl related items. 299 */ 300SYSCTL_NODE(_net, PF_INET6, inet6, CTLFLAG_RW, 0, 301 "Internet6 Family"); 302 303/* net.inet6 */ 304SYSCTL_NODE(_net_inet6, IPPROTO_IPV6, ip6, CTLFLAG_RW, 0, "IP6"); 305SYSCTL_NODE(_net_inet6, IPPROTO_ICMPV6, icmp6, CTLFLAG_RW, 0, "ICMP6"); 306SYSCTL_NODE(_net_inet6, IPPROTO_UDP, udp6, CTLFLAG_RW, 0, "UDP6"); 307SYSCTL_NODE(_net_inet6, IPPROTO_TCP, tcp6, CTLFLAG_RW, 0, "TCP6"); 308#ifdef IPSEC 309SYSCTL_NODE(_net_inet6, IPPROTO_ESP, ipsec6, CTLFLAG_RW, 0, "IPSEC6"); 310#endif /* IPSEC */ 311 312/* net.inet6.ip6 */ 313static int 314sysctl_ip6_forwarding SYSCTL_HANDLER_ARGS 315{ 316 int error = 0; 317 int old_ip6_forwarding; 318 int changed; 319 320 error = SYSCTL_OUT(req, arg1, sizeof(int)); 321 if (error || !req->newptr) 322 return (error); 323 old_ip6_forwarding = ip6_forwarding; 324 error = SYSCTL_IN(req, arg1, sizeof(int)); 325 if (error != 0) 326 return (error); 327 changed = (ip6_forwarding ? 1 : 0) ^ (old_ip6_forwarding ? 1 : 0); 328 if (changed == 0) 329 return (error); 330 if (ip6_forwarding != 0) { /* host becomes router */ 331 int s = splnet(); 332 struct nd_prefix *pr, *next; 333 334 for (pr = LIST_FIRST(&nd_prefix); pr; pr = next) { 335 next = LIST_NEXT(pr, ndpr_entry); 336 if (!IN6_IS_ADDR_UNSPECIFIED(&pr->ndpr_addr)) 337 in6_ifdel(pr->ndpr_ifp, &pr->ndpr_addr); 338 prelist_remove(pr); 339 } 340 splx(s); 341 } else { /* router becomes host */ 342 struct socket so; 343 344 /* XXX: init dummy so */ 345 bzero(&so, sizeof(so)); 346 while(!LIST_EMPTY(&rr_prefix)) 347 delete_each_prefix(&so, LIST_FIRST(&rr_prefix), 348 PR_ORIG_KERNEL); 349 } 350 351 return (error); 352} 353 354SYSCTL_OID(_net_inet6_ip6, IPV6CTL_FORWARDING, forwarding, 355 CTLTYPE_INT|CTLFLAG_RW, &ip6_forwarding, 0, sysctl_ip6_forwarding, 356 "I", ""); 357SYSCTL_INT(_net_inet6_ip6, IPV6CTL_SENDREDIRECTS, 358 redirect, CTLFLAG_RW, &ip6_sendredirects, 0, ""); 359SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFHLIM, 360 hlim, CTLFLAG_RW, &ip6_defhlim, 0, ""); 361SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGPACKETS, 362 maxfragpackets, CTLFLAG_RW, &ip6_maxfragpackets, 0, ""); 363SYSCTL_INT(_net_inet6_ip6, IPV6CTL_ACCEPT_RTADV, 364 accept_rtadv, CTLFLAG_RW, &ip6_accept_rtadv, 0, ""); 365SYSCTL_INT(_net_inet6_ip6, IPV6CTL_KEEPFAITH, 366 keepfaith, CTLFLAG_RW, &ip6_keepfaith, 0, ""); 367SYSCTL_INT(_net_inet6_ip6, IPV6CTL_LOG_INTERVAL, 368 log_interval, CTLFLAG_RW, &ip6_log_interval, 0, ""); 369SYSCTL_INT(_net_inet6_ip6, IPV6CTL_HDRNESTLIMIT, 370 hdrnestlimit, CTLFLAG_RW, &ip6_hdrnestlimit, 0, ""); 371SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DAD_COUNT, 372 dad_count, CTLFLAG_RW, &ip6_dad_count, 0, ""); 373SYSCTL_INT(_net_inet6_ip6, IPV6CTL_AUTO_FLOWLABEL, 374 auto_flowlabel, CTLFLAG_RW, &ip6_auto_flowlabel, 0, ""); 375SYSCTL_INT(_net_inet6_ip6, IPV6CTL_DEFMCASTHLIM, 376 defmcasthlim, CTLFLAG_RW, &ip6_defmcasthlim, 0, ""); 377SYSCTL_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM, 378 gifhlim, CTLFLAG_RW, &ip6_gif_hlim, 0, ""); 379SYSCTL_STRING(_net_inet6_ip6, IPV6CTL_KAME_VERSION, 380 kame_version, CTLFLAG_RD, __KAME_VERSION, 0, ""); 381SYSCTL_INT(_net_inet6_ip6, IPV6CTL_USE_DEPRECATED, 382 use_deprecated, CTLFLAG_RW, &ip6_use_deprecated, 0, ""); 383SYSCTL_INT(_net_inet6_ip6, IPV6CTL_RR_PRUNE, 384 rr_prune, CTLFLAG_RW, &ip6_rr_prune, 0, ""); 385SYSCTL_INT(_net_inet6_ip6, IPV6CTL_MAPPED_ADDR, 386 mapped_addr, CTLFLAG_RW, &ip6_mapped_addr_on, 0, ""); 387 388/* net.inet6.icmp6 */ 389SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRACCEPT, 390 rediraccept, CTLFLAG_RW, &icmp6_rediraccept, 0, ""); 391SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRTIMEOUT, 392 redirtimeout, CTLFLAG_RW, &icmp6_redirtimeout, 0, ""); 393SYSCTL_STRUCT(_net_inet6_icmp6, ICMPV6CTL_STATS, stats, CTLFLAG_RD, 394 &icmp6stat, icmp6stat, ""); 395SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ERRRATELIMIT, 396 errratelimit, CTLFLAG_RW, &icmp6errratelim, 0, ""); 397SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_PRUNE, 398 nd6_prune, CTLFLAG_RW, &nd6_prune, 0, ""); 399SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_DELAY, 400 nd6_delay, CTLFLAG_RW, &nd6_delay, 0, ""); 401SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_UMAXTRIES, 402 nd6_umaxtries, CTLFLAG_RW, &nd6_umaxtries, 0, ""); 403SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MMAXTRIES, 404 nd6_mmaxtries, CTLFLAG_RW, &nd6_mmaxtries, 0, ""); 405SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_USELOOPBACK, 406 nd6_useloopback, CTLFLAG_RW, &nd6_useloopback, 0, ""); 407SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_PROXYALL, 408 nd6_proxyall, CTLFLAG_RW, &nd6_proxyall, 0, ""); 409