1 /* $NetBSD: in_proto.c,v 1.98 2009/09/14 10:36:50 degroote Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
33 * Copyright (c) 1982, 1986, 1993
34 * The Regents of the University of California. All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
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.
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
60 * @(#)in_proto.c 8.2 (Berkeley) 2/9/95
63 #include <sys/cdefs.h>
64 __KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.98 2009/09/14 10:36:50 degroote Exp $");
66 #include "opt_mrouting.h"
67 #include "opt_eon.h" /* ISO CLNL over IP */
68 #include "opt_iso.h" /* ISO TP tunneled over IP */
70 #include "opt_ipsec.h"
72 #include "opt_gateway.h"
74 #include <sys/param.h>
75 #include <sys/socket.h>
76 #include <sys/protosw.h>
77 #include <sys/domain.h>
81 #include <net/radix.h>
82 #include <net/route.h>
84 #include <netinet/in.h>
85 #include <netinet/in_systm.h>
86 #include <netinet/ip.h>
87 #include <netinet/ip_var.h>
88 #include <netinet/ip_icmp.h>
89 #include <netinet/in_ifattach.h>
90 #include <netinet/in_pcb.h>
91 #include <netinet/in_proto.h>
95 #include <netinet/in.h>
97 #include <netinet/ip6.h>
100 #include <netinet/igmp_var.h>
102 #include <netinet/pim_var.h>
104 #include <netinet/tcp.h>
105 #include <netinet/tcp_fsm.h>
106 #include <netinet/tcp_seq.h>
107 #include <netinet/tcp_timer.h>
108 #include <netinet/tcp_var.h>
109 #include <netinet/tcpip.h>
110 #include <netinet/tcp_debug.h>
111 #include <netinet/udp.h>
112 #include <netinet/udp_var.h>
113 #include <netinet/ip_encap.h>
116 * TCP/IP protocol family: IP, ICMP, UDP, TCP.
120 #include <netinet6/ipsec.h>
121 #include <netinet6/ah.h>
123 #include <netinet6/esp.h>
125 #include <netinet6/ipcomp.h>
129 #include <netipsec/ipsec.h>
130 #include <netipsec/key.h>
131 #endif /* FAST_IPSEC */
134 #include <netiso/tp_param.h>
135 #include <netiso/tp_var.h>
139 #include <netiso/eonvar.h>
144 #include <netinet/ip_carp.h>
149 #include <net/pfvar.h>
150 #include <net/if_pfsync.h>
155 #include <netinet/ip_etherip.h>
158 DOMAIN_DEFINE(inetdomain
); /* forward declare and add to link set */
160 /* Wrappers to acquire kernel_lock. */
162 PR_WRAP_USRREQ(rip_usrreq
)
163 PR_WRAP_USRREQ(udp_usrreq
)
164 PR_WRAP_USRREQ(tcp_usrreq
)
166 #define rip_usrreq rip_usrreq_wrapper
167 #define udp_usrreq udp_usrreq_wrapper
168 #define tcp_usrreq tcp_usrreq_wrapper
170 PR_WRAP_CTLINPUT(rip_ctlinput
)
171 PR_WRAP_CTLINPUT(udp_ctlinput
)
172 PR_WRAP_CTLINPUT(tcp_ctlinput
)
174 #define rip_ctlinput rip_ctlinput_wrapper
175 #define udp_ctlinput udp_ctlinput_wrapper
176 #define tcp_ctlinput tcp_ctlinput_wrapper
178 PR_WRAP_CTLOUTPUT(rip_ctloutput
)
179 PR_WRAP_CTLOUTPUT(udp_ctloutput
)
180 PR_WRAP_CTLOUTPUT(tcp_ctloutput
)
182 #define rip_ctloutput rip_ctloutput_wrapper
183 #define udp_ctloutput udp_ctloutput_wrapper
184 #define tcp_ctloutput tcp_ctloutput_wrapper
186 #if defined(IPSEC) || defined(FAST_IPSEC)
187 PR_WRAP_CTLINPUT(ah4_ctlinput
)
189 #define ah4_ctlinput ah4_ctlinput_wrapper
192 #if defined(IPSEC_ESP) || defined(FAST_IPSEC)
193 PR_WRAP_CTLINPUT(esp4_ctlinput
)
195 #define esp4_ctlinput esp4_ctlinput_wrapper
199 PR_WRAP_CTLOUTPUT(tp_ctloutput
)
201 #define tp_ctloutput tp_ctloutput_wrapper
203 PR_WRAP_CTLINPUT(tpip_ctlinput
)
205 #define tpip_ctlinput tpip_ctlinput_wrapper
209 PR_WRAP_CTLINPUT(eonctlinput
)
211 #define eonctlinput eonctlinput_wrapper
214 const struct protosw inetsw
[] = {
215 { .pr_domain
= &inetdomain
,
217 .pr_output
= ip_output
,
218 .pr_slowtimo
= ip_slowtimo
,
219 .pr_drain
= ip_drain
,
221 { .pr_type
= SOCK_DGRAM
,
222 .pr_domain
= &inetdomain
,
223 .pr_protocol
= IPPROTO_UDP
,
224 .pr_flags
= PR_ATOMIC
|PR_ADDR
|PR_PURGEIF
,
225 .pr_input
= udp_input
,
226 .pr_ctlinput
= udp_ctlinput
,
227 .pr_ctloutput
= udp_ctloutput
,
228 .pr_usrreq
= udp_usrreq
,
231 { .pr_type
= SOCK_STREAM
,
232 .pr_domain
= &inetdomain
,
233 .pr_protocol
= IPPROTO_TCP
,
234 .pr_flags
= PR_CONNREQUIRED
|PR_WANTRCVD
|PR_LISTEN
|PR_ABRTACPTDIS
|PR_PURGEIF
,
235 .pr_input
= tcp_input
,
236 .pr_ctlinput
= tcp_ctlinput
,
237 .pr_ctloutput
= tcp_ctloutput
,
238 .pr_usrreq
= tcp_usrreq
,
240 .pr_slowtimo
= tcp_slowtimo
,
241 .pr_drain
= tcp_drain
,
243 { .pr_type
= SOCK_RAW
,
244 .pr_domain
= &inetdomain
,
245 .pr_protocol
= IPPROTO_RAW
,
246 .pr_flags
= PR_ATOMIC
|PR_ADDR
|PR_PURGEIF
,
247 .pr_input
= rip_input
,
248 .pr_output
= rip_output
,
249 .pr_ctlinput
= rip_ctlinput
,
250 .pr_ctloutput
= rip_ctloutput
,
251 .pr_usrreq
= rip_usrreq
,
253 { .pr_type
= SOCK_RAW
,
254 .pr_domain
= &inetdomain
,
255 .pr_protocol
= IPPROTO_ICMP
,
256 .pr_flags
= PR_ATOMIC
|PR_ADDR
|PR_LASTHDR
,
257 .pr_input
= icmp_input
,
258 .pr_output
= rip_output
,
259 .pr_ctlinput
= rip_ctlinput
,
260 .pr_ctloutput
= rip_ctloutput
,
261 .pr_usrreq
= rip_usrreq
,
262 .pr_init
= icmp_init
,
265 { .pr_domain
= &inetdomain
,
266 .pr_protocol
= IPPROTO_IP
,
267 .pr_slowtimo
= ipflow_slowtimo
,
268 .pr_init
= ipflow_poolinit
,
272 { .pr_type
= SOCK_RAW
,
273 .pr_domain
= &inetdomain
,
274 .pr_protocol
= IPPROTO_AH
,
275 .pr_flags
= PR_ATOMIC
|PR_ADDR
,
276 .pr_input
= ah4_input
,
277 .pr_ctlinput
= ah4_ctlinput
,
281 { .pr_type
= SOCK_RAW
,
282 .pr_domain
= &inetdomain
,
283 .pr_protocol
= IPPROTO_ESP
,
284 .pr_flags
= PR_ATOMIC
|PR_ADDR
,
285 .pr_input
= esp4_input
,
286 .pr_ctlinput
= esp4_ctlinput
,
287 .pr_init
= esp4_init
,
289 #endif /* IPSEC_ESP */
290 { .pr_type
= SOCK_RAW
,
291 .pr_domain
= &inetdomain
,
292 .pr_protocol
= IPPROTO_IPCOMP
,
293 .pr_flags
= PR_ATOMIC
|PR_ADDR
,
294 .pr_input
= ipcomp4_input
,
295 .pr_init
= ipcomp4_init
,
299 { .pr_type
= SOCK_RAW
,
300 .pr_domain
= &inetdomain
,
301 .pr_protocol
= IPPROTO_AH
,
302 .pr_flags
= PR_ATOMIC
|PR_ADDR
,
303 .pr_input
= ipsec4_common_input
,
304 .pr_ctlinput
= ah4_ctlinput
,
306 { .pr_type
= SOCK_RAW
,
307 .pr_domain
= &inetdomain
,
308 .pr_protocol
= IPPROTO_ESP
,
309 .pr_flags
= PR_ATOMIC
|PR_ADDR
,
310 .pr_input
= ipsec4_common_input
,
311 .pr_ctlinput
= esp4_ctlinput
,
313 { .pr_type
= SOCK_RAW
,
314 .pr_domain
= &inetdomain
,
315 .pr_protocol
= IPPROTO_IPCOMP
,
316 .pr_flags
= PR_ATOMIC
|PR_ADDR
,
317 .pr_input
= ipsec4_common_input
,
319 #endif /* FAST_IPSEC */
320 { .pr_type
= SOCK_RAW
,
321 .pr_domain
= &inetdomain
,
322 .pr_protocol
= IPPROTO_IPV4
,
323 .pr_flags
= PR_ATOMIC
|PR_ADDR
|PR_LASTHDR
,
324 .pr_input
= encap4_input
,
325 .pr_output
= rip_output
,
326 .pr_ctlinput
= rip_ctlinput
,
327 .pr_ctloutput
= rip_ctloutput
,
328 .pr_usrreq
= rip_usrreq
,
329 .pr_init
= encap_init
,
332 { .pr_type
= SOCK_RAW
,
333 .pr_domain
= &inetdomain
,
334 .pr_protocol
= IPPROTO_IPV6
,
335 .pr_flags
= PR_ATOMIC
|PR_ADDR
|PR_LASTHDR
,
336 .pr_input
= encap4_input
,
337 .pr_output
= rip_output
,
338 .pr_ctlinput
= rip_ctlinput
,
339 .pr_ctloutput
= rip_ctloutput
,
340 .pr_usrreq
= rip_usrreq
,
341 .pr_init
= encap_init
,
345 { .pr_type
= SOCK_RAW
,
346 .pr_domain
= &inetdomain
,
347 .pr_protocol
= IPPROTO_ETHERIP
,
348 .pr_flags
= PR_ATOMIC
|PR_ADDR
|PR_LASTHDR
,
349 .pr_input
= ip_etherip_input
,
350 .pr_output
= rip_output
,
351 .pr_ctlinput
= rip_ctlinput
,
352 .pr_ctloutput
= rip_ctloutput
,
353 .pr_usrreq
= rip_usrreq
,
355 #endif /* NETHERIP > 0 */
357 { .pr_type
= SOCK_RAW
,
358 .pr_domain
= &inetdomain
,
359 .pr_protocol
= IPPROTO_CARP
,
360 .pr_flags
= PR_ATOMIC
|PR_ADDR
,
361 .pr_input
= carp_proto_input
,
362 .pr_output
= rip_output
,
363 .pr_ctloutput
= rip_ctloutput
,
364 .pr_usrreq
= rip_usrreq
,
365 .pr_init
= carp_init
,
367 #endif /* NCARP > 0 */
369 { .pr_type
= SOCK_RAW
,
370 .pr_domain
= &inetdomain
,
371 .pr_protocol
= IPPROTO_PFSYNC
,
372 .pr_flags
= PR_ATOMIC
|PR_ADDR
,
373 .pr_input
= pfsync_input
,
374 .pr_output
= rip_output
,
375 .pr_ctloutput
= rip_ctloutput
,
376 .pr_usrreq
= rip_usrreq
,
378 #endif /* NPFSYNC > 0 */
379 { .pr_type
= SOCK_RAW
,
380 .pr_domain
= &inetdomain
,
381 .pr_protocol
= IPPROTO_IGMP
,
382 .pr_flags
= PR_ATOMIC
|PR_ADDR
|PR_LASTHDR
,
383 .pr_input
= igmp_input
,
384 .pr_output
= rip_output
,
385 .pr_ctloutput
= rip_ctloutput
,
386 .pr_ctlinput
= rip_ctlinput
,
387 .pr_usrreq
= rip_usrreq
,
388 .pr_fasttimo
= igmp_fasttimo
,
389 .pr_slowtimo
= igmp_slowtimo
,
390 .pr_init
= igmp_init
,
393 { .pr_type
= SOCK_RAW
,
394 .pr_domain
= &inetdomain
,
395 .pr_protocol
= IPPROTO_PIM
,
396 .pr_flags
= PR_ATOMIC
|PR_ADDR
|PR_LASTHDR
,
397 .pr_input
= pim_input
,
398 .pr_output
= rip_output
,
399 .pr_ctloutput
= rip_ctloutput
,
400 .pr_ctlinput
= rip_ctlinput
,
401 .pr_usrreq
= rip_usrreq
,
405 { .pr_type
= SOCK_SEQPACKET
,
406 .pr_domain
= &inetdomain
,
407 .pr_protocol
= IPPROTO_TP
,
408 .pr_flags
= PR_CONNREQUIRED
|PR_WANTRCVD
|PR_LISTEN
|PR_LASTHDR
|PR_ABRTACPTDIS
,
409 .pr_input
= tpip_input
,
410 .pr_ctloutput
= tp_ctloutput
,
411 .pr_ctlinput
= tpip_ctlinput
,
412 .pr_usrreq
= tp_usrreq
,
414 .pr_slowtimo
= tp_slowtimo
,
415 .pr_drain
= tp_drain
,
419 /* EON (ISO CLNL over IP) */
421 { .pr_type
= SOCK_RAW
,
422 .pr_domain
= &inetdomain
,
423 .pr_protocol
= IPPROTO_EON
,
424 .pr_flags
= PR_LASTHDR
,
425 .pr_input
= eoninput
,
426 .pr_ctlinput
= eonctlinput
,
427 .pr_init
= eonprotoinit
,
430 { .pr_type
= SOCK_RAW
,
431 .pr_domain
= &inetdomain
,
432 .pr_protocol
= IPPROTO_EON
,
433 .pr_flags
= PR_ATOMIC
|PR_ADDR
|PR_LASTHDR
,
434 .pr_input
= encap4_input
,
435 .pr_output
= rip_output
,
436 .pr_ctloutput
= rip_ctloutput
,
437 .pr_ctlinput
= rip_ctlinput
,
438 .pr_usrreq
= rip_usrreq
,
439 .pr_init
= encap_init
,
444 { .pr_type
= SOCK_RAW
,
445 .pr_domain
= &inetdomain
,
446 .pr_flags
= PR_ATOMIC
|PR_ADDR
|PR_LASTHDR
,
447 .pr_input
= rip_input
,
448 .pr_output
= rip_output
,
449 .pr_ctloutput
= rip_ctloutput
,
450 .pr_ctlinput
= rip_ctlinput
,
451 .pr_usrreq
= rip_usrreq
,
456 extern struct ifqueue ipintrq
;
458 const struct sockaddr_in in_any
= {
459 .sin_len
= sizeof(struct sockaddr_in
)
460 , .sin_family
= AF_INET
462 , .sin_addr
= {.s_addr
= 0 /* INADDR_ANY */}
465 struct domain inetdomain
= {
466 .dom_family
= PF_INET
, .dom_name
= "internet", .dom_init
= NULL
,
467 .dom_externalize
= NULL
, .dom_dispose
= NULL
,
468 .dom_protosw
= inetsw
,
469 .dom_protoswNPROTOSW
= &inetsw
[__arraycount(inetsw
)],
470 .dom_rtattach
= rn_inithead
,
472 .dom_maxrtkey
= sizeof(struct ip_pack4
),
474 .dom_ifattach
= in_domifattach
,
475 .dom_ifdetach
= in_domifdetach
,
477 .dom_ifattach
= NULL
,
478 .dom_ifdetach
= NULL
,
480 .dom_ifqueues
= { &ipintrq
, NULL
},
481 .dom_link
= { NULL
},
482 .dom_mowner
= MOWNER_INIT("",""),
483 .dom_sa_cmpofs
= offsetof(struct sockaddr_in
, sin_addr
),
484 .dom_sa_cmplen
= sizeof(struct in_addr
),
485 .dom_sa_any
= (const struct sockaddr
*)&in_any
,
486 .dom_sockaddr_const_addr
= sockaddr_in_const_addr
,
487 .dom_sockaddr_addr
= sockaddr_in_addr
,
488 .dom_rtcache
= LIST_HEAD_INITIALIZER(inetdomain
.dom_rtcache
)
491 u_char ip_protox
[IPPROTO_MAX
];
493 int icmperrppslim
= 100; /* 100pps */
496 sockaddr_in_addrlen(const struct sockaddr
*sa
, socklen_t
*slenp
)
503 slen
= sockaddr_getlen(sa
);
504 *slenp
= (socklen_t
)MIN(sizeof(struct in_addr
),
505 slen
- MIN(slen
, offsetof(struct sockaddr_in
, sin_addr
)));
509 sockaddr_in_const_addr(const struct sockaddr
*sa
, socklen_t
*slenp
)
511 const struct sockaddr_in
*sin
;
513 sockaddr_in_addrlen(sa
, slenp
);
514 sin
= (const struct sockaddr_in
*)sa
;
515 return &sin
->sin_addr
;
519 sockaddr_in_addr(struct sockaddr
*sa
, socklen_t
*slenp
)
521 struct sockaddr_in
*sin
;
523 sockaddr_in_addrlen(sa
, slenp
);
524 sin
= (struct sockaddr_in
*)sa
;
525 return &sin
->sin_addr
;
529 sockaddr_in_cmp(const struct sockaddr
*sa1
, const struct sockaddr
*sa2
)
532 const uint_fast8_t addrofs
= offsetof(struct sockaddr_in
, sin_addr
),
533 addrend
= addrofs
+ sizeof(struct in_addr
);
535 const struct sockaddr_in
*sin1
, *sin2
;
537 sin1
= satocsin(sa1
);
538 sin2
= satocsin(sa2
);
540 len
= MIN(addrend
, MIN(sin1
->sin_len
, sin2
->sin_len
));
543 (rc
= memcmp(&sin1
->sin_addr
, &sin2
->sin_addr
,
544 len
- addrofs
)) != 0)
547 return sin1
->sin_len
- sin2
->sin_len
;