in_proto.c revision 193744
11849Swollman/*-
21849Swollman * Copyright (c) 1982, 1986, 1993
31849Swollman *	The Regents of the University of California.  All rights reserved.
41849Swollman *
51849Swollman * Redistribution and use in source and binary forms, with or without
61849Swollman * modification, are permitted provided that the following conditions
71849Swollman * are met:
81849Swollman * 1. Redistributions of source code must retain the above copyright
91849Swollman *    notice, this list of conditions and the following disclaimer.
101849Swollman * 2. Redistributions in binary form must reproduce the above copyright
111849Swollman *    notice, this list of conditions and the following disclaimer in the
121849Swollman *    documentation and/or other materials provided with the distribution.
131849Swollman * 4. Neither the name of the University nor the names of its contributors
141849Swollman *    may be used to endorse or promote products derived from this software
151849Swollman *    without specific prior written permission.
161849Swollman *
171849Swollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181849Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191849Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201849Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211849Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221849Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231849Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241849Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251849Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261849Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271849Swollman * SUCH DAMAGE.
281849Swollman *
291849Swollman *	@(#)in_proto.c	8.2 (Berkeley) 2/9/95
301849Swollman */
311849Swollman
325790Sdg#include <sys/cdefs.h>
3350476Speter__FBSDID("$FreeBSD: head/sys/netinet/in_proto.c 193744 2009-06-08 19:57:35Z bz $");
341849Swollman
351849Swollman#include "opt_ipx.h"
3685437Speter#include "opt_mrouting.h"
371849Swollman#include "opt_ipsec.h"
381849Swollman#include "opt_inet6.h"
391849Swollman#include "opt_pf.h"
401849Swollman#include "opt_carp.h"
411849Swollman#include "opt_sctp.h"
421849Swollman#include "opt_mpath.h"
431849Swollman
441849Swollman#include <sys/param.h>
451849Swollman#include <sys/systm.h>
461849Swollman#include <sys/kernel.h>
471849Swollman#include <sys/socket.h>
481849Swollman#include <sys/domain.h>
491849Swollman#include <sys/proc.h>
501849Swollman#include <sys/protosw.h>
511849Swollman#include <sys/queue.h>
521849Swollman#include <sys/sysctl.h>
531849Swollman
541849Swollman#include <net/if.h>
551849Swollman#include <net/route.h>
565243Sbde#ifdef RADIX_MPATH
575243Sbde#include <net/radix_mpath.h>
581849Swollman#endif
591849Swollman
601849Swollman#include <netinet/in.h>
611849Swollman#include <netinet/in_systm.h>
621849Swollman#include <netinet/in_var.h>
631849Swollman#include <netinet/ip.h>
641849Swollman#include <netinet/ip_var.h>
651849Swollman#include <netinet/ip_icmp.h>
661849Swollman#include <netinet/igmp_var.h>
671849Swollman#include <netinet/tcp.h>
681849Swollman#include <netinet/tcp_timer.h>
691849Swollman#include <netinet/tcp_var.h>
701849Swollman#include <netinet/udp.h>
711849Swollman#include <netinet/udp_var.h>
721849Swollman#include <netinet/ip_encap.h>
731849Swollman
741849Swollman/*
751849Swollman * TCP/IP protocol family: IP, ICMP, UDP, TCP.
761849Swollman */
771849Swollman
781849Swollmanstatic struct pr_usrreqs nousrreqs;
795243Sbde
805243Sbde#ifdef IPSEC
815243Sbde#include <netipsec/ipsec.h>
825243Sbde#endif /* IPSEC */
835243Sbde
845243Sbde#ifdef SCTP
855243Sbde#include <netinet/in_pcb.h>
865243Sbde#include <netinet/sctp_pcb.h>
875243Sbde#include <netinet/sctp.h>
885243Sbde#include <netinet/sctp_var.h>
895243Sbde#endif /* SCTP */
905243Sbde
911849Swollman#ifdef DEV_PFSYNC
921849Swollman#include <net/pfvar.h>
931849Swollman#include <net/if_pfsync.h>
941849Swollman#endif
951849Swollman
961849Swollman#ifdef DEV_CARP
971849Swollman#include <netinet/ip_carp.h>
981849Swollman#endif
991849Swollman
1001849Swollmanextern	struct domain inetdomain;
1011849Swollman
1021849Swollman/* Spacer for loadable protocols. */
1031849Swollman#define IPPROTOSPACER   			\
1041849Swollman{						\
1051849Swollman	.pr_domain =		&inetdomain,	\
1061849Swollman	.pr_protocol =		PROTO_SPACER,	\
1071849Swollman	.pr_usrreqs =		&nousrreqs	\
1081849Swollman}
1091849Swollman
1101849Swollmanstruct protosw inetsw[] = {
1111849Swollman{
1121849Swollman	.pr_type =		0,
1131849Swollman	.pr_domain =		&inetdomain,
1141849Swollman	.pr_protocol =		IPPROTO_IP,
1151849Swollman	.pr_init =		ip_init,
1161849Swollman	.pr_slowtimo =		ip_slowtimo,
1171849Swollman	.pr_drain =		ip_drain,
1181849Swollman	.pr_usrreqs =		&nousrreqs
1191849Swollman},
1201849Swollman{
1211849Swollman	.pr_type =		SOCK_DGRAM,
1221849Swollman	.pr_domain =		&inetdomain,
1231849Swollman	.pr_protocol =		IPPROTO_UDP,
1241849Swollman	.pr_flags =		PR_ATOMIC|PR_ADDR,
1251849Swollman	.pr_input =		udp_input,
1261849Swollman	.pr_ctlinput =		udp_ctlinput,
1271849Swollman	.pr_ctloutput =		ip_ctloutput,
1281849Swollman	.pr_init =		udp_init,
1291849Swollman#ifdef VIMAGE
1301849Swollman	.pr_destroy =		udp_destroy,
1311849Swollman#endif
1321849Swollman	.pr_usrreqs =		&udp_usrreqs
1331849Swollman},
1341849Swollman{
1351849Swollman	.pr_type =		SOCK_STREAM,
1361849Swollman	.pr_domain =		&inetdomain,
1371849Swollman	.pr_protocol =		IPPROTO_TCP,
1381849Swollman	.pr_flags =		PR_CONNREQUIRED|PR_IMPLOPCL|PR_WANTRCVD,
1391849Swollman	.pr_input =		tcp_input,
1401849Swollman	.pr_ctlinput =		tcp_ctlinput,
1411849Swollman	.pr_ctloutput =		tcp_ctloutput,
1421849Swollman	.pr_init =		tcp_init,
1431849Swollman#ifdef VIMAGE
1441849Swollman	.pr_destroy =		tcp_destroy,
1451849Swollman#endif
1461849Swollman	.pr_slowtimo =		tcp_slowtimo,
1471849Swollman	.pr_drain =		tcp_drain,
1481849Swollman	.pr_usrreqs =		&tcp_usrreqs
1491849Swollman},
1501849Swollman#ifdef SCTP
1511849Swollman{
1521849Swollman	.pr_type = 	SOCK_DGRAM,
1531849Swollman	.pr_domain =  	&inetdomain,
1541849Swollman        .pr_protocol = 	IPPROTO_SCTP,
1551849Swollman        .pr_flags = 	PR_WANTRCVD,
1561849Swollman        .pr_input = 	sctp_input,
1571849Swollman        .pr_ctlinput =  sctp_ctlinput,
1581849Swollman        .pr_ctloutput = sctp_ctloutput,
1591849Swollman        .pr_init = 	sctp_init,
1601849Swollman        .pr_drain = 	sctp_drain,
1611849Swollman        .pr_usrreqs = 	&sctp_usrreqs
1625243Sbde},
1631849Swollman{
1641849Swollman	.pr_type = 	SOCK_SEQPACKET,
1651849Swollman	.pr_domain =  	&inetdomain,
1661849Swollman        .pr_protocol = 	IPPROTO_SCTP,
1671849Swollman        .pr_flags = 	PR_WANTRCVD,
1681849Swollman        .pr_input = 	sctp_input,
1691849Swollman        .pr_ctlinput =  sctp_ctlinput,
1701849Swollman        .pr_ctloutput = sctp_ctloutput,
171        .pr_drain = 	sctp_drain,
172        .pr_usrreqs = 	&sctp_usrreqs
173},
174
175{
176	.pr_type = 	SOCK_STREAM,
177	.pr_domain =  	&inetdomain,
178        .pr_protocol = 	IPPROTO_SCTP,
179        .pr_flags = 	PR_WANTRCVD,
180        .pr_input = 	sctp_input,
181        .pr_ctlinput =  sctp_ctlinput,
182        .pr_ctloutput = sctp_ctloutput,
183        .pr_drain = 	sctp_drain,
184        .pr_usrreqs = 	&sctp_usrreqs
185},
186#endif /* SCTP */
187{
188	.pr_type =		SOCK_RAW,
189	.pr_domain =		&inetdomain,
190	.pr_protocol =		IPPROTO_RAW,
191	.pr_flags =		PR_ATOMIC|PR_ADDR,
192	.pr_input =		rip_input,
193	.pr_ctlinput =		rip_ctlinput,
194	.pr_ctloutput =		rip_ctloutput,
195	.pr_usrreqs =		&rip_usrreqs
196},
197{
198	.pr_type =		SOCK_RAW,
199	.pr_domain =		&inetdomain,
200	.pr_protocol =		IPPROTO_ICMP,
201	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
202	.pr_input =		icmp_input,
203	.pr_ctloutput =		rip_ctloutput,
204	.pr_init =		icmp_init,
205	.pr_usrreqs =		&rip_usrreqs
206},
207{
208	.pr_type =		SOCK_RAW,
209	.pr_domain =		&inetdomain,
210	.pr_protocol =		IPPROTO_IGMP,
211	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
212	.pr_input =		igmp_input,
213	.pr_ctloutput =		rip_ctloutput,
214	.pr_fasttimo =		igmp_fasttimo,
215	.pr_slowtimo =		igmp_slowtimo,
216	.pr_usrreqs =		&rip_usrreqs
217},
218{
219	.pr_type =		SOCK_RAW,
220	.pr_domain =		&inetdomain,
221	.pr_protocol =		IPPROTO_RSVP,
222	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
223	.pr_input =		rsvp_input,
224	.pr_ctloutput =		rip_ctloutput,
225	.pr_usrreqs =		&rip_usrreqs
226},
227#ifdef IPSEC
228{
229	.pr_type =		SOCK_RAW,
230	.pr_domain =		&inetdomain,
231	.pr_protocol =		IPPROTO_AH,
232	.pr_flags =		PR_ATOMIC|PR_ADDR,
233	.pr_input =		ah4_input,
234	.pr_ctlinput =		ah4_ctlinput,
235	.pr_usrreqs =		&nousrreqs
236},
237{
238	.pr_type =		SOCK_RAW,
239	.pr_domain =		&inetdomain,
240	.pr_protocol =		IPPROTO_ESP,
241	.pr_flags =		PR_ATOMIC|PR_ADDR,
242	.pr_input =		esp4_input,
243	.pr_ctlinput =		esp4_ctlinput,
244	.pr_usrreqs =		&nousrreqs
245},
246{
247	.pr_type =		SOCK_RAW,
248	.pr_domain =		&inetdomain,
249	.pr_protocol =		IPPROTO_IPCOMP,
250	.pr_flags =		PR_ATOMIC|PR_ADDR,
251	.pr_input =		ipcomp4_input,
252	.pr_usrreqs =		&nousrreqs
253},
254#endif /* IPSEC */
255{
256	.pr_type =		SOCK_RAW,
257	.pr_domain =		&inetdomain,
258	.pr_protocol =		IPPROTO_IPV4,
259	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
260	.pr_input =		encap4_input,
261	.pr_ctloutput =		rip_ctloutput,
262	.pr_init =		encap_init,
263	.pr_usrreqs =		&rip_usrreqs
264},
265{
266	.pr_type =		SOCK_RAW,
267	.pr_domain =		&inetdomain,
268	.pr_protocol =		IPPROTO_MOBILE,
269	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
270	.pr_input =		encap4_input,
271	.pr_ctloutput =		rip_ctloutput,
272	.pr_init =		encap_init,
273	.pr_usrreqs =		&rip_usrreqs
274},
275{
276	.pr_type =		SOCK_RAW,
277	.pr_domain =		&inetdomain,
278	.pr_protocol =		IPPROTO_ETHERIP,
279	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
280	.pr_input =		encap4_input,
281	.pr_ctloutput =		rip_ctloutput,
282	.pr_init =		encap_init,
283	.pr_usrreqs =		&rip_usrreqs
284},
285{
286	.pr_type =		SOCK_RAW,
287	.pr_domain =		&inetdomain,
288	.pr_protocol =		IPPROTO_GRE,
289	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
290	.pr_input =		encap4_input,
291	.pr_ctloutput =		rip_ctloutput,
292	.pr_init =		encap_init,
293	.pr_usrreqs =		&rip_usrreqs
294},
295# ifdef INET6
296{
297	.pr_type =		SOCK_RAW,
298	.pr_domain =		&inetdomain,
299	.pr_protocol =		IPPROTO_IPV6,
300	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
301	.pr_input =		encap4_input,
302	.pr_ctloutput =		rip_ctloutput,
303	.pr_init =		encap_init,
304	.pr_usrreqs =		&rip_usrreqs
305},
306#endif
307{
308	.pr_type =		SOCK_RAW,
309	.pr_domain =		&inetdomain,
310	.pr_protocol =		IPPROTO_PIM,
311	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
312	.pr_input =		encap4_input,
313	.pr_ctloutput =		rip_ctloutput,
314	.pr_usrreqs =		&rip_usrreqs
315},
316#ifdef DEV_PFSYNC
317{
318	.pr_type =		SOCK_RAW,
319	.pr_domain =		&inetdomain,
320	.pr_protocol =		IPPROTO_PFSYNC,
321	.pr_flags =		PR_ATOMIC|PR_ADDR,
322	.pr_input =		pfsync_input,
323	.pr_ctloutput =		rip_ctloutput,
324	.pr_usrreqs =		&rip_usrreqs
325},
326#endif	/* DEV_PFSYNC */
327#ifdef DEV_CARP
328{
329	.pr_type =		SOCK_RAW,
330	.pr_domain =		&inetdomain,
331	.pr_protocol =		IPPROTO_CARP,
332	.pr_flags =		PR_ATOMIC|PR_ADDR,
333	.pr_input =		carp_input,
334	.pr_output =		(pr_output_t*)rip_output,
335	.pr_ctloutput =		rip_ctloutput,
336	.pr_usrreqs =		&rip_usrreqs
337},
338#endif /* DEV_CARP */
339/* Spacer n-times for loadable protocols. */
340IPPROTOSPACER,
341IPPROTOSPACER,
342IPPROTOSPACER,
343IPPROTOSPACER,
344IPPROTOSPACER,
345IPPROTOSPACER,
346IPPROTOSPACER,
347IPPROTOSPACER,
348/* raw wildcard */
349{
350	.pr_type =		SOCK_RAW,
351	.pr_domain =		&inetdomain,
352	.pr_flags =		PR_ATOMIC|PR_ADDR,
353	.pr_input =		rip_input,
354	.pr_ctloutput =		rip_ctloutput,
355	.pr_init =		rip_init,
356#ifdef VIMAGE
357	.pr_destroy =		rip_destroy,
358#endif
359	.pr_usrreqs =		&rip_usrreqs
360},
361};
362
363extern int in_inithead(void **, int);
364extern int in_detachhead(void **, int);
365
366struct domain inetdomain = {
367	.dom_family =		AF_INET,
368	.dom_name =		"internet",
369	.dom_protosw =		inetsw,
370	.dom_protoswNPROTOSW =	&inetsw[sizeof(inetsw)/sizeof(inetsw[0])],
371#ifdef RADIX_MPATH
372	.dom_rtattach =		rn4_mpath_inithead,
373#else
374	.dom_rtattach =		in_inithead,
375#endif
376#ifdef VIMAGE
377	.dom_rtdetach =		in_detachhead,
378#endif
379	.dom_rtoffset =		32,
380	.dom_maxrtkey =		sizeof(struct sockaddr_in),
381	.dom_ifattach =		in_domifattach,
382	.dom_ifdetach =		in_domifdetach
383};
384
385DOMAIN_SET(inet);
386
387SYSCTL_NODE(_net,      PF_INET,		inet,	CTLFLAG_RW, 0,
388	"Internet Family");
389
390SYSCTL_NODE(_net_inet, IPPROTO_IP,	ip,	CTLFLAG_RW, 0,	"IP");
391SYSCTL_NODE(_net_inet, IPPROTO_ICMP,	icmp,	CTLFLAG_RW, 0,	"ICMP");
392SYSCTL_NODE(_net_inet, IPPROTO_UDP,	udp,	CTLFLAG_RW, 0,	"UDP");
393SYSCTL_NODE(_net_inet, IPPROTO_TCP,	tcp,	CTLFLAG_RW, 0,	"TCP");
394#ifdef SCTP
395SYSCTL_NODE(_net_inet, IPPROTO_SCTP,	sctp,	CTLFLAG_RW, 0,	"SCTP");
396#endif
397SYSCTL_NODE(_net_inet, IPPROTO_IGMP,	igmp,	CTLFLAG_RW, 0,	"IGMP");
398#ifdef IPSEC
399/* XXX no protocol # to use, pick something "reserved" */
400SYSCTL_NODE(_net_inet, 253,		ipsec,	CTLFLAG_RW, 0,	"IPSEC");
401SYSCTL_NODE(_net_inet, IPPROTO_AH,	ah,	CTLFLAG_RW, 0,	"AH");
402SYSCTL_NODE(_net_inet, IPPROTO_ESP,	esp,	CTLFLAG_RW, 0,	"ESP");
403SYSCTL_NODE(_net_inet, IPPROTO_IPCOMP,	ipcomp,	CTLFLAG_RW, 0,	"IPCOMP");
404SYSCTL_NODE(_net_inet, IPPROTO_IPIP,	ipip,	CTLFLAG_RW, 0,	"IPIP");
405#endif /* IPSEC */
406SYSCTL_NODE(_net_inet, IPPROTO_RAW,	raw,	CTLFLAG_RW, 0,	"RAW");
407#ifdef DEV_PFSYNC
408SYSCTL_NODE(_net_inet, IPPROTO_PFSYNC,	pfsync,	CTLFLAG_RW, 0,	"PFSYNC");
409#endif
410#ifdef DEV_CARP
411SYSCTL_NODE(_net_inet, IPPROTO_CARP,	carp,	CTLFLAG_RW, 0,	"CARP");
412#endif
413