1139823Simp/*-
22788Sdg * Copyright (c) 1982, 1986, 1993
32788Sdg *	The Regents of the University of California.  All rights reserved.
42788Sdg *
52788Sdg * Redistribution and use in source and binary forms, with or without
62788Sdg * modification, are permitted provided that the following conditions
72788Sdg * are met:
82788Sdg * 1. Redistributions of source code must retain the above copyright
92788Sdg *    notice, this list of conditions and the following disclaimer.
102788Sdg * 2. Redistributions in binary form must reproduce the above copyright
112788Sdg *    notice, this list of conditions and the following disclaimer in the
122788Sdg *    documentation and/or other materials provided with the distribution.
132788Sdg * 4. Neither the name of the University nor the names of its contributors
142788Sdg *    may be used to endorse or promote products derived from this software
152788Sdg *    without specific prior written permission.
162788Sdg *
172788Sdg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
182788Sdg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
192788Sdg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
202788Sdg * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
212788Sdg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
222788Sdg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
232788Sdg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
242788Sdg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
252788Sdg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
262788Sdg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
272788Sdg * SUCH DAMAGE.
282788Sdg *
2910941Swollman *	@(#)in_proto.c	8.2 (Berkeley) 2/9/95
302788Sdg */
311541Srgrimes
32172467Ssilby#include <sys/cdefs.h>
33172467Ssilby__FBSDID("$FreeBSD$");
34172467Ssilby
3531742Seivind#include "opt_ipx.h"
36118622Shsu#include "opt_mrouting.h"
3755009Sshin#include "opt_ipsec.h"
38220746Sbz#include "opt_inet.h"
3955009Sshin#include "opt_inet6.h"
40163953Srrs#include "opt_sctp.h"
41178167Sqingli#include "opt_mpath.h"
4230966Sjoerg
432788Sdg#include <sys/param.h>
44111145Sjlemon#include <sys/systm.h>
458426Swollman#include <sys/kernel.h>
462788Sdg#include <sys/socket.h>
472788Sdg#include <sys/domain.h>
48185895Szec#include <sys/proc.h>
4912426Sphk#include <sys/protosw.h>
5044078Sdfr#include <sys/queue.h>
5112172Sphk#include <sys/sysctl.h>
521541Srgrimes
53220746Sbz/*
54220746Sbz * While this file provides the domain and protocol switch tables for IPv4, it
55220746Sbz * also provides the sysctl node declarations for net.inet.* often shared with
56220746Sbz * IPv6 for common features or by upper layer protocols.  In case of no IPv4
57220746Sbz * support compile out everything but these sysctl nodes.
58220746Sbz */
59220746Sbz#ifdef INET
602788Sdg#include <net/if.h>
612788Sdg#include <net/route.h>
62178167Sqingli#ifdef RADIX_MPATH
63178167Sqingli#include <net/radix_mpath.h>
64178167Sqingli#endif
65196019Srwatson#include <net/vnet.h>
66221021Sbz#endif /* INET */
671541Srgrimes
68221021Sbz#if defined(INET) || defined(INET6)
692788Sdg#include <netinet/in.h>
70221021Sbz#endif
71221021Sbz
72221021Sbz#ifdef INET
732788Sdg#include <netinet/in_systm.h>
74186119Sqingli#include <netinet/in_var.h>
752788Sdg#include <netinet/ip.h>
762788Sdg#include <netinet/ip_var.h>
772788Sdg#include <netinet/ip_icmp.h>
782788Sdg#include <netinet/igmp_var.h>
792788Sdg#include <netinet/tcp.h>
802788Sdg#include <netinet/tcp_timer.h>
812788Sdg#include <netinet/tcp_var.h>
822788Sdg#include <netinet/udp.h>
832788Sdg#include <netinet/udp_var.h>
8462587Sitojun#include <netinet/ip_encap.h>
8555009Sshin
862788Sdg/*
872788Sdg * TCP/IP protocol family: IP, ICMP, UDP, TCP.
882788Sdg */
891541Srgrimes
90148918Sobrienstatic struct pr_usrreqs nousrreqs;
91148918Sobrien
92171167Sgnn#ifdef IPSEC
93105199Ssam#include <netipsec/ipsec.h>
94171167Sgnn#endif /* IPSEC */
95105199Ssam
96163953Srrs#ifdef SCTP
97163953Srrs#include <netinet/in_pcb.h>
98163953Srrs#include <netinet/sctp_pcb.h>
99163953Srrs#include <netinet/sctp.h>
100163953Srrs#include <netinet/sctp_var.h>
101163953Srrs#endif /* SCTP */
102163953Srrs
103222272SbzFEATURE(inet, "Internet Protocol version 4");
104222272Sbz
1052788Sdgextern	struct domain inetdomain;
1062531Swollman
107136695Sandre/* Spacer for loadable protocols. */
108152242Sru#define IPPROTOSPACER   			\
109152242Sru{						\
110152242Sru	.pr_domain =		&inetdomain,	\
111152242Sru	.pr_protocol =		PROTO_SPACER,	\
112152242Sru	.pr_usrreqs =		&nousrreqs	\
113136695Sandre}
114136695Sandre
11582884Sjulianstruct protosw inetsw[] = {
116152242Sru{
117152242Sru	.pr_type =		0,
118152242Sru	.pr_domain =		&inetdomain,
119152242Sru	.pr_protocol =		IPPROTO_IP,
120152242Sru	.pr_init =		ip_init,
121204140Sbz#ifdef VIMAGE
122204140Sbz	.pr_destroy =		ip_destroy,
123204140Sbz#endif
124152242Sru	.pr_slowtimo =		ip_slowtimo,
125152242Sru	.pr_drain =		ip_drain,
126152242Sru	.pr_usrreqs =		&nousrreqs
1272788Sdg},
128152242Sru{
129152242Sru	.pr_type =		SOCK_DGRAM,
130152242Sru	.pr_domain =		&inetdomain,
131152242Sru	.pr_protocol =		IPPROTO_UDP,
132152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR,
133152242Sru	.pr_input =		udp_input,
134152242Sru	.pr_ctlinput =		udp_ctlinput,
135194062Svanhu	.pr_ctloutput =		udp_ctloutput,
136152242Sru	.pr_init =		udp_init,
137193731Szec#ifdef VIMAGE
138193731Szec	.pr_destroy =		udp_destroy,
139193731Szec#endif
140152242Sru	.pr_usrreqs =		&udp_usrreqs
1412788Sdg},
142152242Sru{
143152242Sru	.pr_type =		SOCK_STREAM,
144152242Sru	.pr_domain =		&inetdomain,
145152242Sru	.pr_protocol =		IPPROTO_TCP,
146152242Sru	.pr_flags =		PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD,
147152242Sru	.pr_input =		tcp_input,
148152242Sru	.pr_ctlinput =		tcp_ctlinput,
149152242Sru	.pr_ctloutput =		tcp_ctloutput,
150152242Sru	.pr_init =		tcp_init,
151193731Szec#ifdef VIMAGE
152193731Szec	.pr_destroy =		tcp_destroy,
153193731Szec#endif
154152242Sru	.pr_slowtimo =		tcp_slowtimo,
155152242Sru	.pr_drain =		tcp_drain,
156152242Sru	.pr_usrreqs =		&tcp_usrreqs
1572788Sdg},
158163953Srrs#ifdef SCTP
159163953Srrs{
160223963Stuexen	.pr_type =		SOCK_SEQPACKET,
161197326Stuexen	.pr_domain =		&inetdomain,
162197326Stuexen	.pr_protocol =		IPPROTO_SCTP,
163197326Stuexen	.pr_flags =		PR_WANTRCVD,
164197326Stuexen	.pr_input =		sctp_input,
165197326Stuexen	.pr_ctlinput =		sctp_ctlinput,
166197326Stuexen	.pr_ctloutput =		sctp_ctloutput,
167197326Stuexen	.pr_init =		sctp_init,
168197326Stuexen#ifdef VIMAGE
169197326Stuexen	.pr_destroy =		sctp_finish,
170197326Stuexen#endif
171197326Stuexen	.pr_drain =		sctp_drain,
172197326Stuexen	.pr_usrreqs =		&sctp_usrreqs
173163953Srrs},
174163953Srrs{
175197326Stuexen	.pr_type =		SOCK_STREAM,
176197326Stuexen	.pr_domain =		&inetdomain,
177197326Stuexen	.pr_protocol =		IPPROTO_SCTP,
178197326Stuexen	.pr_flags =		PR_WANTRCVD,
179197326Stuexen	.pr_input =		sctp_input,
180197326Stuexen	.pr_ctlinput =		sctp_ctlinput,
181197326Stuexen	.pr_ctloutput =		sctp_ctloutput,
182197326Stuexen	.pr_drain =		sctp_drain,
183197326Stuexen	.pr_usrreqs =		&sctp_usrreqs
184163953Srrs},
185163953Srrs#endif /* SCTP */
186163953Srrs{
187265946Skevlo	.pr_type =		SOCK_DGRAM,
188265946Skevlo	.pr_domain =		&inetdomain,
189265946Skevlo	.pr_protocol =		IPPROTO_UDPLITE,
190265946Skevlo	.pr_flags =		PR_ATOMIC|PR_ADDR,
191265946Skevlo	.pr_input =		udp_input,
192265946Skevlo	.pr_ctlinput =		udplite_ctlinput,
193265946Skevlo	.pr_ctloutput =		udp_ctloutput,
194265946Skevlo	.pr_init =		udplite_init,
195265946Skevlo#ifdef VIMAGE
196265946Skevlo	.pr_destroy =		udplite_destroy,
197265946Skevlo#endif
198265946Skevlo	.pr_usrreqs =		&udp_usrreqs
199265946Skevlo},
200265946Skevlo{
201152242Sru	.pr_type =		SOCK_RAW,
202152242Sru	.pr_domain =		&inetdomain,
203152242Sru	.pr_protocol =		IPPROTO_RAW,
204152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR,
205152242Sru	.pr_input =		rip_input,
206152242Sru	.pr_ctlinput =		rip_ctlinput,
207152242Sru	.pr_ctloutput =		rip_ctloutput,
208152242Sru	.pr_usrreqs =		&rip_usrreqs
2092788Sdg},
210152242Sru{
211152242Sru	.pr_type =		SOCK_RAW,
212152242Sru	.pr_domain =		&inetdomain,
213152242Sru	.pr_protocol =		IPPROTO_ICMP,
214152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
215152242Sru	.pr_input =		icmp_input,
216152242Sru	.pr_ctloutput =		rip_ctloutput,
217152242Sru	.pr_usrreqs =		&rip_usrreqs
2182788Sdg},
219152242Sru{
220152242Sru	.pr_type =		SOCK_RAW,
221152242Sru	.pr_domain =		&inetdomain,
222152242Sru	.pr_protocol =		IPPROTO_IGMP,
223152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
224152242Sru	.pr_input =		igmp_input,
225152242Sru	.pr_ctloutput =		rip_ctloutput,
226152242Sru	.pr_fasttimo =		igmp_fasttimo,
227152242Sru	.pr_slowtimo =		igmp_slowtimo,
228152242Sru	.pr_usrreqs =		&rip_usrreqs
2292788Sdg},
230152242Sru{
231152242Sru	.pr_type =		SOCK_RAW,
232152242Sru	.pr_domain =		&inetdomain,
233152242Sru	.pr_protocol =		IPPROTO_RSVP,
234152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
235152242Sru	.pr_input =		rsvp_input,
236152242Sru	.pr_ctloutput =		rip_ctloutput,
237152242Sru	.pr_usrreqs =		&rip_usrreqs
2382788Sdg},
239171167Sgnn#ifdef IPSEC
240152242Sru{
241152242Sru	.pr_type =		SOCK_RAW,
242152242Sru	.pr_domain =		&inetdomain,
243152242Sru	.pr_protocol =		IPPROTO_AH,
244152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR,
245152242Sru	.pr_input =		ah4_input,
246152242Sru	.pr_ctlinput =		ah4_ctlinput,
247152242Sru	.pr_usrreqs =		&nousrreqs
248106680Ssam},
249152242Sru{
250152242Sru	.pr_type =		SOCK_RAW,
251152242Sru	.pr_domain =		&inetdomain,
252152242Sru	.pr_protocol =		IPPROTO_ESP,
253152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR,
254152242Sru	.pr_input =		esp4_input,
255152242Sru	.pr_ctlinput =		esp4_ctlinput,
256152242Sru	.pr_usrreqs =		&nousrreqs
257106680Ssam},
258152242Sru{
259152242Sru	.pr_type =		SOCK_RAW,
260152242Sru	.pr_domain =		&inetdomain,
261152242Sru	.pr_protocol =		IPPROTO_IPCOMP,
262152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR,
263152242Sru	.pr_input =		ipcomp4_input,
264152242Sru	.pr_usrreqs =		&nousrreqs
265106680Ssam},
266171167Sgnn#endif /* IPSEC */
267152242Sru{
268152242Sru	.pr_type =		SOCK_RAW,
269152242Sru	.pr_domain =		&inetdomain,
270152242Sru	.pr_protocol =		IPPROTO_IPV4,
271152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
272152242Sru	.pr_input =		encap4_input,
273152242Sru	.pr_ctloutput =		rip_ctloutput,
274152242Sru	.pr_init =		encap_init,
275152242Sru	.pr_usrreqs =		&rip_usrreqs
27654263Sshin},
277152242Sru{
278152242Sru	.pr_type =		SOCK_RAW,
279152242Sru	.pr_domain =		&inetdomain,
280152242Sru	.pr_protocol =		IPPROTO_MOBILE,
281152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
282152242Sru	.pr_input =		encap4_input,
283152242Sru	.pr_ctloutput =		rip_ctloutput,
284152242Sru	.pr_init =		encap_init,
285152242Sru	.pr_usrreqs =		&rip_usrreqs
286103026Ssobomax},
287152242Sru{
288152242Sru	.pr_type =		SOCK_RAW,
289152242Sru	.pr_domain =		&inetdomain,
290153621Sthompsa	.pr_protocol =		IPPROTO_ETHERIP,
291153621Sthompsa	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
292153621Sthompsa	.pr_input =		encap4_input,
293153621Sthompsa	.pr_ctloutput =		rip_ctloutput,
294153621Sthompsa	.pr_init =		encap_init,
295153621Sthompsa	.pr_usrreqs =		&rip_usrreqs
296153621Sthompsa},
297153621Sthompsa{
298153621Sthompsa	.pr_type =		SOCK_RAW,
299153621Sthompsa	.pr_domain =		&inetdomain,
300152242Sru	.pr_protocol =		IPPROTO_GRE,
301152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
302152242Sru	.pr_input =		encap4_input,
303152242Sru	.pr_ctloutput =		rip_ctloutput,
304152242Sru	.pr_init =		encap_init,
305152242Sru	.pr_usrreqs =		&rip_usrreqs
306103026Ssobomax},
30754263Sshin# ifdef INET6
308152242Sru{
309152242Sru	.pr_type =		SOCK_RAW,
310152242Sru	.pr_domain =		&inetdomain,
311152242Sru	.pr_protocol =		IPPROTO_IPV6,
312152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
313152242Sru	.pr_input =		encap4_input,
314152242Sru	.pr_ctloutput =		rip_ctloutput,
315152242Sru	.pr_init =		encap_init,
316152242Sru	.pr_usrreqs =		&rip_usrreqs
31754263Sshin},
31854263Sshin#endif
319152242Sru{
320152242Sru	.pr_type =		SOCK_RAW,
321152242Sru	.pr_domain =		&inetdomain,
322152242Sru	.pr_protocol =		IPPROTO_PIM,
323152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
324166622Sbms	.pr_input =		encap4_input,
325152242Sru	.pr_ctloutput =		rip_ctloutput,
326152242Sru	.pr_usrreqs =		&rip_usrreqs
327118622Shsu},
328136695Sandre/* Spacer n-times for loadable protocols. */
329136695SandreIPPROTOSPACER,
330136695SandreIPPROTOSPACER,
331136695SandreIPPROTOSPACER,
332136695SandreIPPROTOSPACER,
333136695SandreIPPROTOSPACER,
334136695SandreIPPROTOSPACER,
335136695SandreIPPROTOSPACER,
336136695SandreIPPROTOSPACER,
337136695Sandre/* raw wildcard */
338152242Sru{
339152242Sru	.pr_type =		SOCK_RAW,
340152242Sru	.pr_domain =		&inetdomain,
341152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR,
342152242Sru	.pr_input =		rip_input,
343152242Sru	.pr_ctloutput =		rip_ctloutput,
344152242Sru	.pr_init =		rip_init,
345193731Szec#ifdef VIMAGE
346193731Szec	.pr_destroy =		rip_destroy,
347193731Szec#endif
348152242Sru	.pr_usrreqs =		&rip_usrreqs
3491541Srgrimes},
3501541Srgrimes};
3511541Srgrimes
35292723Salfredextern int in_inithead(void **, int);
353193731Szecextern int in_detachhead(void **, int);
3544073Swollman
355152242Srustruct domain inetdomain = {
356152242Sru	.dom_family =		AF_INET,
357152242Sru	.dom_name =		"internet",
358152242Sru	.dom_protosw =		inetsw,
359152242Sru	.dom_protoswNPROTOSW =	&inetsw[sizeof(inetsw)/sizeof(inetsw[0])],
360178167Sqingli#ifdef RADIX_MPATH
361178167Sqingli	.dom_rtattach =		rn4_mpath_inithead,
362178167Sqingli#else
363152242Sru	.dom_rtattach =		in_inithead,
364178167Sqingli#endif
365193731Szec#ifdef VIMAGE
366193731Szec	.dom_rtdetach =		in_detachhead,
367193731Szec#endif
368152242Sru	.dom_rtoffset =		32,
369186119Sqingli	.dom_maxrtkey =		sizeof(struct sockaddr_in),
370186119Sqingli	.dom_ifattach =		in_domifattach,
371186119Sqingli	.dom_ifdetach =		in_domifdetach
372152242Sru};
3731541Srgrimes
374195837SrwatsonVNET_DOMAIN_SET(inet);
375220746Sbz#endif /* INET */
3768426Swollman
37712942SwollmanSYSCTL_NODE(_net,      PF_INET,		inet,	CTLFLAG_RW, 0,
37812942Swollman	"Internet Family");
37912172Sphk
38012942SwollmanSYSCTL_NODE(_net_inet, IPPROTO_IP,	ip,	CTLFLAG_RW, 0,	"IP");
38112942SwollmanSYSCTL_NODE(_net_inet, IPPROTO_ICMP,	icmp,	CTLFLAG_RW, 0,	"ICMP");
38212942SwollmanSYSCTL_NODE(_net_inet, IPPROTO_UDP,	udp,	CTLFLAG_RW, 0,	"UDP");
38312942SwollmanSYSCTL_NODE(_net_inet, IPPROTO_TCP,	tcp,	CTLFLAG_RW, 0,	"TCP");
384163953Srrs#ifdef SCTP
385163953SrrsSYSCTL_NODE(_net_inet, IPPROTO_SCTP,	sctp,	CTLFLAG_RW, 0,	"SCTP");
386163953Srrs#endif
38712942SwollmanSYSCTL_NODE(_net_inet, IPPROTO_IGMP,	igmp,	CTLFLAG_RW, 0,	"IGMP");
388171167Sgnn#ifdef IPSEC
389105199Ssam/* XXX no protocol # to use, pick something "reserved" */
390105199SsamSYSCTL_NODE(_net_inet, 253,		ipsec,	CTLFLAG_RW, 0,	"IPSEC");
391105199SsamSYSCTL_NODE(_net_inet, IPPROTO_AH,	ah,	CTLFLAG_RW, 0,	"AH");
392105199SsamSYSCTL_NODE(_net_inet, IPPROTO_ESP,	esp,	CTLFLAG_RW, 0,	"ESP");
393105199SsamSYSCTL_NODE(_net_inet, IPPROTO_IPCOMP,	ipcomp,	CTLFLAG_RW, 0,	"IPCOMP");
394105199SsamSYSCTL_NODE(_net_inet, IPPROTO_IPIP,	ipip,	CTLFLAG_RW, 0,	"IPIP");
395171167Sgnn#endif /* IPSEC */
39622900SwollmanSYSCTL_NODE(_net_inet, IPPROTO_RAW,	raw,	CTLFLAG_RW, 0,	"RAW");
397