in_proto.c revision 264212
14Srgrimes/*-
24Srgrimes * Copyright (c) 1982, 1986, 1993
34Srgrimes *	The Regents of the University of California.  All rights reserved.
44Srgrimes *
54Srgrimes * Redistribution and use in source and binary forms, with or without
64Srgrimes * modification, are permitted provided that the following conditions
74Srgrimes * are met:
84Srgrimes * 1. Redistributions of source code must retain the above copyright
94Srgrimes *    notice, this list of conditions and the following disclaimer.
104Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
114Srgrimes *    notice, this list of conditions and the following disclaimer in the
124Srgrimes *    documentation and/or other materials provided with the distribution.
134Srgrimes * 4. Neither the name of the University nor the names of its contributors
144Srgrimes *    may be used to endorse or promote products derived from this software
154Srgrimes *    without specific prior written permission.
164Srgrimes *
174Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
184Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
194Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
204Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
214Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
224Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
234Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
244Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
254Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
264Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
274Srgrimes * SUCH DAMAGE.
284Srgrimes *
294Srgrimes *	@(#)in_proto.c	8.2 (Berkeley) 2/9/95
304Srgrimes */
314Srgrimes
324Srgrimes#include <sys/cdefs.h>
334Srgrimes__FBSDID("$FreeBSD: head/sys/netinet/in_proto.c 264212 2014-04-07 01:53:03Z kevlo $");
344Srgrimes
354Srgrimes#include "opt_mrouting.h"
364Srgrimes#include "opt_ipsec.h"
374Srgrimes#include "opt_inet.h"
38620Srgrimes#include "opt_inet6.h"
39798Swollman#include "opt_sctp.h"
404Srgrimes#include "opt_mpath.h"
414Srgrimes
424Srgrimes#include <sys/param.h>
434Srgrimes#include <sys/systm.h>
444Srgrimes#include <sys/kernel.h>
454Srgrimes#include <sys/socket.h>
464Srgrimes#include <sys/domain.h>
474Srgrimes#include <sys/proc.h>
484Srgrimes#include <sys/protosw.h>
494Srgrimes#include <sys/queue.h>
504Srgrimes#include <sys/sysctl.h>
514Srgrimes
52718Swollman/*
534Srgrimes * While this file provides the domain and protocol switch tables for IPv4, it
54718Swollman * also provides the sysctl node declarations for net.inet.* often shared with
554Srgrimes * IPv6 for common features or by upper layer protocols.  In case of no IPv4
564Srgrimes * support compile out everything but these sysctl nodes.
574Srgrimes */
584Srgrimes#ifdef INET
594Srgrimes#include <net/if.h>
604Srgrimes#include <net/if_var.h>
614Srgrimes#include <net/route.h>
624Srgrimes#ifdef RADIX_MPATH
634Srgrimes#include <net/radix_mpath.h>
644Srgrimes#endif
654Srgrimes#include <net/vnet.h>
664Srgrimes#endif /* INET */
674Srgrimes
684Srgrimes#if defined(INET) || defined(INET6)
694Srgrimes#include <netinet/in.h>
704Srgrimes#endif
714Srgrimes
724Srgrimes#ifdef INET
734Srgrimes#include <netinet/in_systm.h>
744Srgrimes#include <netinet/in_var.h>
754Srgrimes#include <netinet/ip.h>
76798Swollman#include <netinet/ip_var.h>
774Srgrimes#include <netinet/ip_icmp.h>
784Srgrimes#include <netinet/igmp_var.h>
794Srgrimes#include <netinet/tcp.h>
804Srgrimes#include <netinet/tcp_timer.h>
814Srgrimes#include <netinet/tcp_var.h>
824Srgrimes#include <netinet/udp.h>
834Srgrimes#include <netinet/udp_var.h>
844Srgrimes#include <netinet/ip_encap.h>
854Srgrimes
864Srgrimes/*
874Srgrimes * TCP/IP protocol family: IP, ICMP, UDP, TCP.
884Srgrimes */
894Srgrimes
904Srgrimesstatic struct pr_usrreqs nousrreqs;
914Srgrimes
924Srgrimes#ifdef IPSEC
934Srgrimes#include <netipsec/ipsec.h>
944Srgrimes#endif /* IPSEC */
954Srgrimes
964Srgrimes#ifdef SCTP
974Srgrimes#include <netinet/in_pcb.h>
984Srgrimes#include <netinet/sctp_pcb.h>
994Srgrimes#include <netinet/sctp.h>
1004Srgrimes#include <netinet/sctp_var.h>
1014Srgrimes#endif /* SCTP */
1024Srgrimes
103798SwollmanFEATURE(inet, "Internet Protocol version 4");
1044Srgrimes
1054Srgrimesextern	struct domain inetdomain;
1064Srgrimes
1074Srgrimes/* Spacer for loadable protocols. */
1084Srgrimes#define IPPROTOSPACER   			\
1094Srgrimes{						\
1104Srgrimes	.pr_domain =		&inetdomain,	\
1114Srgrimes	.pr_protocol =		PROTO_SPACER,	\
1124Srgrimes	.pr_usrreqs =		&nousrreqs	\
1134Srgrimes}
1144Srgrimes
115798Swollmanstruct protosw inetsw[] = {
1164Srgrimes{
1174Srgrimes	.pr_type =		0,
1184Srgrimes	.pr_domain =		&inetdomain,
1194Srgrimes	.pr_protocol =		IPPROTO_IP,
1204Srgrimes	.pr_init =		ip_init,
1214Srgrimes#ifdef VIMAGE
1224Srgrimes	.pr_destroy =		ip_destroy,
1234Srgrimes#endif
124629Sdg	.pr_slowtimo =		ip_slowtimo,
1254Srgrimes	.pr_drain =		ip_drain,
1264Srgrimes	.pr_usrreqs =		&nousrreqs
127798Swollman},
1284Srgrimes{
1294Srgrimes	.pr_type =		SOCK_DGRAM,
1304Srgrimes	.pr_domain =		&inetdomain,
131798Swollman	.pr_protocol =		IPPROTO_UDP,
1324Srgrimes	.pr_flags =		PR_ATOMIC|PR_ADDR,
1334Srgrimes	.pr_input =		udp_input,
1344Srgrimes	.pr_ctlinput =		udp_ctlinput,
1354Srgrimes	.pr_ctloutput =		udp_ctloutput,
1364Srgrimes	.pr_init =		udp_init,
1374Srgrimes#ifdef VIMAGE
1384Srgrimes	.pr_destroy =		udp_destroy,
139798Swollman#endif
1404Srgrimes	.pr_usrreqs =		&udp_usrreqs
1414Srgrimes},
1424Srgrimes{
143798Swollman	.pr_type =		SOCK_STREAM,
1444Srgrimes	.pr_domain =		&inetdomain,
1454Srgrimes	.pr_protocol =		IPPROTO_TCP,
1464Srgrimes	.pr_flags =		PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD,
1474Srgrimes	.pr_input =		tcp_input,
1484Srgrimes	.pr_ctlinput =		tcp_ctlinput,
1494Srgrimes	.pr_ctloutput =		tcp_ctloutput,
1504Srgrimes	.pr_init =		tcp_init,
1514Srgrimes#ifdef VIMAGE
1524Srgrimes	.pr_destroy =		tcp_destroy,
1534Srgrimes#endif
154798Swollman	.pr_slowtimo =		tcp_slowtimo,
1554Srgrimes	.pr_drain =		tcp_drain,
1564Srgrimes	.pr_usrreqs =		&tcp_usrreqs
157798Swollman},
1584Srgrimes#ifdef SCTP
159798Swollman{
1604Srgrimes	.pr_type =		SOCK_SEQPACKET,
1614Srgrimes	.pr_domain =		&inetdomain,
1624Srgrimes	.pr_protocol =		IPPROTO_SCTP,
1634Srgrimes	.pr_flags =		PR_WANTRCVD,
1644Srgrimes	.pr_input =		sctp_input,
1654Srgrimes	.pr_ctlinput =		sctp_ctlinput,
1664Srgrimes	.pr_ctloutput =		sctp_ctloutput,
1674Srgrimes	.pr_init =		sctp_init,
1684Srgrimes#ifdef VIMAGE
1694Srgrimes	.pr_destroy =		sctp_finish,
1704Srgrimes#endif
1714Srgrimes	.pr_drain =		sctp_drain,
1724Srgrimes	.pr_usrreqs =		&sctp_usrreqs
1734Srgrimes},
1744Srgrimes{
1754Srgrimes	.pr_type =		SOCK_STREAM,
1764Srgrimes	.pr_domain =		&inetdomain,
1774Srgrimes	.pr_protocol =		IPPROTO_SCTP,
1784Srgrimes	.pr_flags =		PR_WANTRCVD,
1794Srgrimes	.pr_input =		sctp_input,
1804Srgrimes	.pr_ctlinput =		sctp_ctlinput,
1814Srgrimes	.pr_ctloutput =		sctp_ctloutput,
182798Swollman	.pr_drain =		sctp_drain,
1834Srgrimes	.pr_usrreqs =		&sctp_usrreqs
1844Srgrimes},
1854Srgrimes#endif /* SCTP */
1864Srgrimes{
1874Srgrimes	.pr_type =		SOCK_DGRAM,
1884Srgrimes	.pr_domain =		&inetdomain,
1894Srgrimes	.pr_protocol =		IPPROTO_UDPLITE,
1904Srgrimes	.pr_flags =		PR_ATOMIC|PR_ADDR,
1914Srgrimes	.pr_input =		udp_input,
1924Srgrimes	.pr_ctlinput =		udplite_ctlinput,
193798Swollman	.pr_ctloutput =		udp_ctloutput,
1944Srgrimes	.pr_init =		udplite_init,
1954Srgrimes#ifdef VIMAGE
1964Srgrimes	.pr_destroy =		udplite_destroy,
1974Srgrimes#endif
1984Srgrimes	.pr_usrreqs =		&udp_usrreqs
1994Srgrimes},
2004Srgrimes{
201798Swollman	.pr_type =		SOCK_RAW,
2024Srgrimes	.pr_domain =		&inetdomain,
2034Srgrimes	.pr_protocol =		IPPROTO_RAW,
2044Srgrimes	.pr_flags =		PR_ATOMIC|PR_ADDR,
2054Srgrimes	.pr_input =		rip_input,
2064Srgrimes	.pr_ctlinput =		rip_ctlinput,
2074Srgrimes	.pr_ctloutput =		rip_ctloutput,
2084Srgrimes	.pr_usrreqs =		&rip_usrreqs
2094Srgrimes},
2104Srgrimes{
2114Srgrimes	.pr_type =		SOCK_RAW,
2124Srgrimes	.pr_domain =		&inetdomain,
2134Srgrimes	.pr_protocol =		IPPROTO_ICMP,
214718Swollman	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
215718Swollman	.pr_input =		icmp_input,
216718Swollman	.pr_ctloutput =		rip_ctloutput,
217718Swollman	.pr_usrreqs =		&rip_usrreqs
218718Swollman},
219718Swollman{
2204Srgrimes	.pr_type =		SOCK_RAW,
2214Srgrimes	.pr_domain =		&inetdomain,
2224Srgrimes	.pr_protocol =		IPPROTO_IGMP,
223	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
224	.pr_input =		igmp_input,
225	.pr_ctloutput =		rip_ctloutput,
226	.pr_fasttimo =		igmp_fasttimo,
227	.pr_slowtimo =		igmp_slowtimo,
228	.pr_usrreqs =		&rip_usrreqs
229},
230{
231	.pr_type =		SOCK_RAW,
232	.pr_domain =		&inetdomain,
233	.pr_protocol =		IPPROTO_RSVP,
234	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
235	.pr_input =		rsvp_input,
236	.pr_ctloutput =		rip_ctloutput,
237	.pr_usrreqs =		&rip_usrreqs
238},
239#ifdef IPSEC
240{
241	.pr_type =		SOCK_RAW,
242	.pr_domain =		&inetdomain,
243	.pr_protocol =		IPPROTO_AH,
244	.pr_flags =		PR_ATOMIC|PR_ADDR,
245	.pr_input =		ah4_input,
246	.pr_ctlinput =		ah4_ctlinput,
247	.pr_usrreqs =		&nousrreqs
248},
249{
250	.pr_type =		SOCK_RAW,
251	.pr_domain =		&inetdomain,
252	.pr_protocol =		IPPROTO_ESP,
253	.pr_flags =		PR_ATOMIC|PR_ADDR,
254	.pr_input =		esp4_input,
255	.pr_ctlinput =		esp4_ctlinput,
256	.pr_usrreqs =		&nousrreqs
257},
258{
259	.pr_type =		SOCK_RAW,
260	.pr_domain =		&inetdomain,
261	.pr_protocol =		IPPROTO_IPCOMP,
262	.pr_flags =		PR_ATOMIC|PR_ADDR,
263	.pr_input =		ipcomp4_input,
264	.pr_usrreqs =		&nousrreqs
265},
266#endif /* IPSEC */
267{
268	.pr_type =		SOCK_RAW,
269	.pr_domain =		&inetdomain,
270	.pr_protocol =		IPPROTO_IPV4,
271	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
272	.pr_input =		encap4_input,
273	.pr_ctloutput =		rip_ctloutput,
274	.pr_init =		encap_init,
275	.pr_usrreqs =		&rip_usrreqs
276},
277{
278	.pr_type =		SOCK_RAW,
279	.pr_domain =		&inetdomain,
280	.pr_protocol =		IPPROTO_MOBILE,
281	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
282	.pr_input =		encap4_input,
283	.pr_ctloutput =		rip_ctloutput,
284	.pr_init =		encap_init,
285	.pr_usrreqs =		&rip_usrreqs
286},
287{
288	.pr_type =		SOCK_RAW,
289	.pr_domain =		&inetdomain,
290	.pr_protocol =		IPPROTO_ETHERIP,
291	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
292	.pr_input =		encap4_input,
293	.pr_ctloutput =		rip_ctloutput,
294	.pr_init =		encap_init,
295	.pr_usrreqs =		&rip_usrreqs
296},
297{
298	.pr_type =		SOCK_RAW,
299	.pr_domain =		&inetdomain,
300	.pr_protocol =		IPPROTO_GRE,
301	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
302	.pr_input =		encap4_input,
303	.pr_ctloutput =		rip_ctloutput,
304	.pr_init =		encap_init,
305	.pr_usrreqs =		&rip_usrreqs
306},
307# ifdef INET6
308{
309	.pr_type =		SOCK_RAW,
310	.pr_domain =		&inetdomain,
311	.pr_protocol =		IPPROTO_IPV6,
312	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
313	.pr_input =		encap4_input,
314	.pr_ctloutput =		rip_ctloutput,
315	.pr_init =		encap_init,
316	.pr_usrreqs =		&rip_usrreqs
317},
318#endif
319{
320	.pr_type =		SOCK_RAW,
321	.pr_domain =		&inetdomain,
322	.pr_protocol =		IPPROTO_PIM,
323	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
324	.pr_input =		encap4_input,
325	.pr_ctloutput =		rip_ctloutput,
326	.pr_usrreqs =		&rip_usrreqs
327},
328/* Spacer n-times for loadable protocols. */
329IPPROTOSPACER,
330IPPROTOSPACER,
331IPPROTOSPACER,
332IPPROTOSPACER,
333IPPROTOSPACER,
334IPPROTOSPACER,
335IPPROTOSPACER,
336IPPROTOSPACER,
337/* raw wildcard */
338{
339	.pr_type =		SOCK_RAW,
340	.pr_domain =		&inetdomain,
341	.pr_flags =		PR_ATOMIC|PR_ADDR,
342	.pr_input =		rip_input,
343	.pr_ctloutput =		rip_ctloutput,
344	.pr_init =		rip_init,
345#ifdef VIMAGE
346	.pr_destroy =		rip_destroy,
347#endif
348	.pr_usrreqs =		&rip_usrreqs
349},
350};
351
352extern int in_inithead(void **, int);
353extern int in_detachhead(void **, int);
354
355struct domain inetdomain = {
356	.dom_family =		AF_INET,
357	.dom_name =		"internet",
358	.dom_protosw =		inetsw,
359	.dom_protoswNPROTOSW =	&inetsw[sizeof(inetsw)/sizeof(inetsw[0])],
360#ifdef RADIX_MPATH
361	.dom_rtattach =		rn4_mpath_inithead,
362#else
363	.dom_rtattach =		in_inithead,
364#endif
365#ifdef VIMAGE
366	.dom_rtdetach =		in_detachhead,
367#endif
368	.dom_rtoffset =		32,
369	.dom_maxrtkey =		sizeof(struct sockaddr_in),
370	.dom_ifattach =		in_domifattach,
371	.dom_ifdetach =		in_domifdetach
372};
373
374VNET_DOMAIN_SET(inet);
375#endif /* INET */
376
377SYSCTL_NODE(_net,      PF_INET,		inet,	CTLFLAG_RW, 0,
378	"Internet Family");
379
380SYSCTL_NODE(_net_inet, IPPROTO_IP,	ip,	CTLFLAG_RW, 0,	"IP");
381SYSCTL_NODE(_net_inet, IPPROTO_ICMP,	icmp,	CTLFLAG_RW, 0,	"ICMP");
382SYSCTL_NODE(_net_inet, IPPROTO_UDP,	udp,	CTLFLAG_RW, 0,	"UDP");
383SYSCTL_NODE(_net_inet, IPPROTO_TCP,	tcp,	CTLFLAG_RW, 0,	"TCP");
384#ifdef SCTP
385SYSCTL_NODE(_net_inet, IPPROTO_SCTP,	sctp,	CTLFLAG_RW, 0,	"SCTP");
386#endif
387SYSCTL_NODE(_net_inet, IPPROTO_IGMP,	igmp,	CTLFLAG_RW, 0,	"IGMP");
388#ifdef IPSEC
389/* XXX no protocol # to use, pick something "reserved" */
390SYSCTL_NODE(_net_inet, 253,		ipsec,	CTLFLAG_RW, 0,	"IPSEC");
391SYSCTL_NODE(_net_inet, IPPROTO_AH,	ah,	CTLFLAG_RW, 0,	"AH");
392SYSCTL_NODE(_net_inet, IPPROTO_ESP,	esp,	CTLFLAG_RW, 0,	"ESP");
393SYSCTL_NODE(_net_inet, IPPROTO_IPCOMP,	ipcomp,	CTLFLAG_RW, 0,	"IPCOMP");
394SYSCTL_NODE(_net_inet, IPPROTO_IPIP,	ipip,	CTLFLAG_RW, 0,	"IPIP");
395#endif /* IPSEC */
396SYSCTL_NODE(_net_inet, IPPROTO_RAW,	raw,	CTLFLAG_RW, 0,	"RAW");
397