1 /* $NetBSD: in_proto.c,v 1.130 2018/09/14 05:09:51 maxv Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 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. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * @(#)in_proto.c 8.2 (Berkeley) 2/9/95 61 */ 62 63 #include <sys/cdefs.h> 64 __KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.130 2018/09/14 05:09:51 maxv Exp $"); 65 66 #ifdef _KERNEL_OPT 67 #include "opt_mrouting.h" 68 #include "opt_inet.h" 69 #include "opt_ipsec.h" 70 #include "opt_pim.h" 71 #include "opt_gateway.h" 72 #include "opt_dccp.h" 73 #include "opt_sctp.h" 74 #include "opt_compat_netbsd.h" 75 #include "opt_net_mpsafe.h" 76 #endif 77 78 #include <sys/param.h> 79 #include <sys/socket.h> 80 #include <sys/protosw.h> 81 #include <sys/domain.h> 82 #include <sys/mbuf.h> 83 84 #include <net/if.h> 85 86 #include <netinet/in.h> 87 #include <netinet/in_systm.h> 88 #include <netinet/in_var.h> 89 #include <netinet/ip.h> 90 #include <netinet/ip_var.h> 91 #include <netinet/ip_icmp.h> 92 #include <netinet/in_ifattach.h> 93 #include <netinet/in_pcb.h> 94 #include <netinet/in_proto.h> 95 96 #ifdef INET6 97 #ifndef INET 98 #include <netinet/in.h> 99 #endif 100 #include <netinet/ip6.h> 101 #endif 102 103 #include <netinet/igmp_var.h> 104 #ifdef PIM 105 #include <netinet/pim_var.h> 106 #endif 107 #include <netinet/tcp.h> 108 #include <netinet/tcp_fsm.h> 109 #include <netinet/tcp_seq.h> 110 #include <netinet/tcp_timer.h> 111 #include <netinet/tcp_var.h> 112 #include <netinet/tcp_debug.h> 113 #include <netinet/udp.h> 114 #include <netinet/udp_var.h> 115 #include <netinet/ip_encap.h> 116 117 #ifdef DCCP 118 #include <netinet/dccp.h> 119 #include <netinet/dccp_var.h> 120 #endif 121 122 #ifdef SCTP 123 #include <netinet/sctp.h> 124 #include <netinet/sctp_var.h> 125 #endif 126 127 /* 128 * TCP/IP protocol family: IP, ICMP, UDP, TCP. 129 */ 130 131 #ifdef IPSEC 132 #include <netipsec/ipsec.h> 133 #include <netipsec/key.h> 134 #endif /* IPSEC */ 135 136 #include "carp.h" 137 #if NCARP > 0 138 #include <netinet/ip_carp.h> 139 #endif 140 141 #include "pfsync.h" 142 #if NPFSYNC > 0 143 #include <net/pfvar.h> 144 #include <net/if_pfsync.h> 145 #endif 146 147 DOMAIN_DEFINE(inetdomain); /* forward declare and add to link set */ 148 149 /* Wrappers to acquire kernel_lock. */ 150 151 PR_WRAP_CTLINPUT(rip_ctlinput) 152 PR_WRAP_CTLINPUT(udp_ctlinput) 153 PR_WRAP_CTLINPUT(tcp_ctlinput) 154 155 #define rip_ctlinput rip_ctlinput_wrapper 156 #define udp_ctlinput udp_ctlinput_wrapper 157 #define tcp_ctlinput tcp_ctlinput_wrapper 158 159 PR_WRAP_CTLOUTPUT(rip_ctloutput) 160 PR_WRAP_CTLOUTPUT(udp_ctloutput) 161 PR_WRAP_CTLOUTPUT(tcp_ctloutput) 162 163 #define rip_ctloutput rip_ctloutput_wrapper 164 #define udp_ctloutput udp_ctloutput_wrapper 165 #define tcp_ctloutput tcp_ctloutput_wrapper 166 167 #ifdef DCCP 168 PR_WRAP_CTLINPUT(dccp_ctlinput) 169 PR_WRAP_CTLOUTPUT(dccp_ctloutput) 170 171 #define dccp_ctlinput dccp_ctlinput_wrapper 172 #define dccp_ctloutput dccp_ctloutput_wrapper 173 #endif 174 175 #ifdef SCTP 176 PR_WRAP_CTLINPUT(sctp_ctlinput) 177 PR_WRAP_CTLOUTPUT(sctp_ctloutput) 178 179 #define sctp_ctlinput sctp_ctlinput_wrapper 180 #define sctp_ctloutput sctp_ctloutput_wrapper 181 #endif 182 183 #ifdef NET_MPSAFE 184 PR_WRAP_INPUT(udp_input) 185 PR_WRAP_INPUT(tcp_input) 186 #ifdef DCCP 187 PR_WRAP_INPUT(dccp_input) 188 #endif 189 #ifdef SCTP 190 PR_WRAP_INPUT(sctp_input) 191 #endif 192 PR_WRAP_INPUT(rip_input) 193 #if NPFSYNC > 0 194 PR_WRAP_INPUT(pfsync_input) 195 #endif 196 PR_WRAP_INPUT(igmp_input) 197 #ifdef PIM 198 PR_WRAP_INPUT(pim_input) 199 #endif 200 201 #define udp_input udp_input_wrapper 202 #define tcp_input tcp_input_wrapper 203 #define dccp_input dccp_input_wrapper 204 #define sctp_input sctp_input_wrapper 205 #define rip_input rip_input_wrapper 206 #define pfsync_input pfsync_input_wrapper 207 #define igmp_input igmp_input_wrapper 208 #define pim_input pim_input_wrapper 209 #endif 210 211 #if defined(IPSEC) 212 213 #ifdef IPSEC_RUMPKERNEL 214 /* 215 * .pr_input = ipsec4_common_input won't be resolved on loading 216 * the ipsec shared library. We need a wrapper anyway. 217 */ 218 static void 219 ipsec4_common_input_wrapper(struct mbuf *m, int off, int proto) 220 { 221 222 if (ipsec_enabled) { 223 ipsec4_common_input(m, off, proto); 224 } else { 225 m_freem(m); 226 } 227 } 228 #define ipsec4_common_input ipsec4_common_input_wrapper 229 230 /* The ctlinput functions may not be loaded */ 231 #define IPSEC_WRAP_CTLINPUT(name) \ 232 static void * \ 233 name##_wrapper(int a, const struct sockaddr *b, void *c)\ 234 { \ 235 void *rv; \ 236 KERNEL_LOCK(1, NULL); \ 237 if (ipsec_enabled) \ 238 rv = name(a, b, c); \ 239 else \ 240 rv = NULL; \ 241 KERNEL_UNLOCK_ONE(NULL); \ 242 return rv; \ 243 } 244 IPSEC_WRAP_CTLINPUT(ah4_ctlinput) 245 IPSEC_WRAP_CTLINPUT(esp4_ctlinput) 246 247 #else /* !IPSEC_RUMPKERNEL */ 248 249 PR_WRAP_CTLINPUT(ah4_ctlinput) 250 PR_WRAP_CTLINPUT(esp4_ctlinput) 251 252 #endif /* !IPSEC_RUMPKERNEL */ 253 254 #define ah4_ctlinput ah4_ctlinput_wrapper 255 #define esp4_ctlinput esp4_ctlinput_wrapper 256 257 #endif /* IPSEC */ 258 259 const struct protosw inetsw[] = { 260 { .pr_domain = &inetdomain, 261 .pr_init = ip_init, 262 .pr_fasttimo = ip_fasttimo, 263 .pr_slowtimo = ip_slowtimo, 264 .pr_drain = ip_drainstub, 265 }, 266 { .pr_type = SOCK_RAW, 267 .pr_domain = &inetdomain, 268 .pr_protocol = IPPROTO_ICMP, 269 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, 270 .pr_input = icmp_input, 271 .pr_ctlinput = rip_ctlinput, 272 .pr_ctloutput = rip_ctloutput, 273 .pr_usrreqs = &rip_usrreqs, 274 .pr_init = icmp_init, 275 }, 276 { .pr_type = SOCK_DGRAM, 277 .pr_domain = &inetdomain, 278 .pr_protocol = IPPROTO_UDP, 279 .pr_flags = PR_ATOMIC|PR_ADDR|PR_PURGEIF, 280 .pr_input = udp_input, 281 .pr_ctlinput = udp_ctlinput, 282 .pr_ctloutput = udp_ctloutput, 283 .pr_usrreqs = &udp_usrreqs, 284 .pr_init = udp_init, 285 }, 286 { .pr_type = SOCK_STREAM, 287 .pr_domain = &inetdomain, 288 .pr_protocol = IPPROTO_TCP, 289 .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_LISTEN|PR_ABRTACPTDIS|PR_PURGEIF, 290 .pr_input = tcp_input, 291 .pr_ctlinput = tcp_ctlinput, 292 .pr_ctloutput = tcp_ctloutput, 293 .pr_usrreqs = &tcp_usrreqs, 294 .pr_init = tcp_init, 295 .pr_fasttimo = tcp_fasttimo, 296 .pr_drain = tcp_drainstub, 297 }, 298 #ifdef DCCP 299 { .pr_type = SOCK_CONN_DGRAM, 300 .pr_domain = &inetdomain, 301 .pr_protocol = IPPROTO_DCCP, 302 .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_ATOMIC|PR_LISTEN|PR_ABRTACPTDIS, 303 .pr_input = dccp_input, 304 .pr_ctlinput = dccp_ctlinput, 305 .pr_ctloutput = dccp_ctloutput, 306 .pr_usrreqs = &dccp_usrreqs, 307 .pr_init = dccp_init, 308 }, 309 #endif 310 #ifdef SCTP 311 { .pr_type = SOCK_DGRAM, 312 .pr_domain = &inetdomain, 313 .pr_protocol = IPPROTO_SCTP, 314 .pr_flags = PR_ADDR_OPT|PR_WANTRCVD, 315 .pr_input = sctp_input, 316 .pr_ctlinput = sctp_ctlinput, 317 .pr_ctloutput = sctp_ctloutput, 318 .pr_usrreqs = &sctp_usrreqs, 319 .pr_init = sctp_init, 320 .pr_drain = sctp_drain 321 }, 322 { .pr_type = SOCK_SEQPACKET, 323 .pr_domain = &inetdomain, 324 .pr_protocol = IPPROTO_SCTP, 325 .pr_flags = PR_ADDR_OPT|PR_WANTRCVD, 326 .pr_input = sctp_input, 327 .pr_ctlinput = sctp_ctlinput, 328 .pr_ctloutput = sctp_ctloutput, 329 .pr_usrreqs = &sctp_usrreqs, 330 .pr_drain = sctp_drain 331 }, 332 { .pr_type = SOCK_STREAM, 333 .pr_domain = &inetdomain, 334 .pr_protocol = IPPROTO_SCTP, 335 .pr_flags = PR_CONNREQUIRED|PR_ADDR_OPT|PR_WANTRCVD|PR_LISTEN, 336 .pr_input = sctp_input, 337 .pr_ctlinput = sctp_ctlinput, 338 .pr_ctloutput = sctp_ctloutput, 339 .pr_usrreqs = &sctp_usrreqs, 340 .pr_drain = sctp_drain 341 }, 342 #endif /* SCTP */ 343 { .pr_type = SOCK_RAW, 344 .pr_domain = &inetdomain, 345 .pr_protocol = IPPROTO_RAW, 346 .pr_flags = PR_ATOMIC|PR_ADDR|PR_PURGEIF, 347 .pr_input = rip_input, 348 .pr_ctlinput = rip_ctlinput, 349 .pr_ctloutput = rip_ctloutput, 350 .pr_usrreqs = &rip_usrreqs, 351 }, 352 #ifdef GATEWAY 353 { .pr_domain = &inetdomain, 354 .pr_protocol = IPPROTO_IP, 355 .pr_slowtimo = ipflow_slowtimo, 356 .pr_init = ipflow_poolinit, 357 }, 358 #endif /* GATEWAY */ 359 #ifdef IPSEC 360 { .pr_type = SOCK_RAW, 361 .pr_domain = &inetdomain, 362 .pr_protocol = IPPROTO_AH, 363 .pr_flags = PR_ATOMIC|PR_ADDR, 364 .pr_input = ipsec4_common_input, 365 .pr_ctlinput = ah4_ctlinput, 366 }, 367 { .pr_type = SOCK_RAW, 368 .pr_domain = &inetdomain, 369 .pr_protocol = IPPROTO_ESP, 370 .pr_flags = PR_ATOMIC|PR_ADDR, 371 .pr_input = ipsec4_common_input, 372 .pr_ctlinput = esp4_ctlinput, 373 }, 374 { .pr_type = SOCK_RAW, 375 .pr_domain = &inetdomain, 376 .pr_protocol = IPPROTO_IPCOMP, 377 .pr_flags = PR_ATOMIC|PR_ADDR, 378 .pr_input = ipsec4_common_input, 379 }, 380 #endif /* IPSEC */ 381 { .pr_type = SOCK_RAW, 382 .pr_domain = &inetdomain, 383 .pr_protocol = IPPROTO_IPV4, 384 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, 385 .pr_input = encap4_input, 386 .pr_ctlinput = rip_ctlinput, 387 .pr_ctloutput = rip_ctloutput, 388 .pr_usrreqs = &rip_usrreqs, 389 .pr_init = encap_init, 390 }, 391 #ifdef INET6 392 { .pr_type = SOCK_RAW, 393 .pr_domain = &inetdomain, 394 .pr_protocol = IPPROTO_IPV6, 395 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, 396 .pr_input = encap4_input, 397 .pr_ctlinput = rip_ctlinput, 398 .pr_ctloutput = rip_ctloutput, 399 .pr_usrreqs = &rip_usrreqs, 400 .pr_init = encap_init, 401 }, 402 #endif /* INET6 */ 403 #if NCARP > 0 404 { .pr_type = SOCK_RAW, 405 .pr_domain = &inetdomain, 406 .pr_protocol = IPPROTO_CARP, 407 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, 408 .pr_input = carp_proto_input, 409 .pr_ctloutput = rip_ctloutput, 410 .pr_usrreqs = &rip_usrreqs, 411 .pr_init = carp_init, 412 }, 413 #endif /* NCARP > 0 */ 414 { .pr_type = SOCK_RAW, 415 .pr_domain = &inetdomain, 416 .pr_protocol = IPPROTO_L2TP, 417 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, 418 .pr_input = encap4_input, 419 .pr_ctlinput = rip_ctlinput, 420 .pr_ctloutput = rip_ctloutput, 421 .pr_usrreqs = &rip_usrreqs, /*XXX*/ 422 .pr_init = encap_init, 423 }, 424 #if NPFSYNC > 0 425 { .pr_type = SOCK_RAW, 426 .pr_domain = &inetdomain, 427 .pr_protocol = IPPROTO_PFSYNC, 428 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, 429 .pr_input = pfsync_input, 430 .pr_ctloutput = rip_ctloutput, 431 .pr_usrreqs = &rip_usrreqs, 432 }, 433 #endif /* NPFSYNC > 0 */ 434 { .pr_type = SOCK_RAW, 435 .pr_domain = &inetdomain, 436 .pr_protocol = IPPROTO_IGMP, 437 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, 438 .pr_input = igmp_input, 439 .pr_ctloutput = rip_ctloutput, 440 .pr_ctlinput = rip_ctlinput, 441 .pr_usrreqs = &rip_usrreqs, 442 .pr_fasttimo = igmp_fasttimo, 443 .pr_slowtimo = igmp_slowtimo, 444 .pr_init = igmp_init, 445 }, 446 #ifdef PIM 447 { .pr_type = SOCK_RAW, 448 .pr_domain = &inetdomain, 449 .pr_protocol = IPPROTO_PIM, 450 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, 451 .pr_input = pim_input, 452 .pr_ctloutput = rip_ctloutput, 453 .pr_ctlinput = rip_ctlinput, 454 .pr_usrreqs = &rip_usrreqs, 455 }, 456 #endif /* PIM */ 457 /* raw wildcard */ 458 { .pr_type = SOCK_RAW, 459 .pr_domain = &inetdomain, 460 .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, 461 .pr_input = rip_input, 462 .pr_ctloutput = rip_ctloutput, 463 .pr_ctlinput = rip_ctlinput, 464 .pr_usrreqs = &rip_usrreqs, 465 .pr_init = rip_init, 466 }, 467 }; 468 469 const struct sockaddr_in in_any = { 470 .sin_len = sizeof(struct sockaddr_in) 471 , .sin_family = AF_INET 472 , .sin_port = 0 473 , .sin_addr = {.s_addr = 0 /* INADDR_ANY */} 474 }; 475 476 struct domain inetdomain = { 477 .dom_family = PF_INET, .dom_name = "internet", .dom_init = NULL, 478 .dom_externalize = NULL, .dom_dispose = NULL, 479 .dom_protosw = inetsw, 480 .dom_protoswNPROTOSW = &inetsw[__arraycount(inetsw)], 481 .dom_rtattach = rt_inithead, 482 .dom_rtoffset = 32, 483 .dom_maxrtkey = sizeof(struct ip_pack4), 484 .dom_if_up = in_if_up, 485 .dom_if_down = in_if_down, 486 .dom_ifattach = in_domifattach, 487 .dom_ifdetach = in_domifdetach, 488 .dom_if_link_state_change = in_if_link_state_change, 489 .dom_ifqueues = { NULL, NULL }, 490 .dom_link = { NULL }, 491 .dom_mowner = MOWNER_INIT("",""), 492 .dom_sa_cmpofs = offsetof(struct sockaddr_in, sin_addr), 493 .dom_sa_cmplen = sizeof(struct in_addr), 494 .dom_sa_any = (const struct sockaddr *)&in_any, 495 .dom_sockaddr_const_addr = sockaddr_in_const_addr, 496 .dom_sockaddr_addr = sockaddr_in_addr, 497 }; 498 499 u_char ip_protox[IPPROTO_MAX]; 500 501 static void 502 sockaddr_in_addrlen(const struct sockaddr *sa, socklen_t *slenp) 503 { 504 socklen_t slen; 505 506 if (slenp == NULL) 507 return; 508 509 slen = sockaddr_getlen(sa); 510 *slenp = (socklen_t)MIN(sizeof(struct in_addr), 511 slen - MIN(slen, offsetof(struct sockaddr_in, sin_addr))); 512 } 513 514 const void * 515 sockaddr_in_const_addr(const struct sockaddr *sa, socklen_t *slenp) 516 { 517 const struct sockaddr_in *sin; 518 519 sockaddr_in_addrlen(sa, slenp); 520 sin = (const struct sockaddr_in *)sa; 521 return &sin->sin_addr; 522 } 523 524 void * 525 sockaddr_in_addr(struct sockaddr *sa, socklen_t *slenp) 526 { 527 struct sockaddr_in *sin; 528 529 sockaddr_in_addrlen(sa, slenp); 530 sin = (struct sockaddr_in *)sa; 531 return &sin->sin_addr; 532 } 533 534 int 535 sockaddr_in_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2) 536 { 537 uint_fast8_t len; 538 const uint_fast8_t addrofs = offsetof(struct sockaddr_in, sin_addr), 539 addrend = addrofs + sizeof(struct in_addr); 540 int rc; 541 const struct sockaddr_in *sin1, *sin2; 542 543 sin1 = satocsin(sa1); 544 sin2 = satocsin(sa2); 545 546 len = MIN(addrend, MIN(sin1->sin_len, sin2->sin_len)); 547 548 if (len > addrofs && 549 (rc = memcmp(&sin1->sin_addr, &sin2->sin_addr, 550 len - addrofs)) != 0) 551 return rc; 552 553 return sin1->sin_len - sin2->sin_len; 554 } 555