1/*	$OpenBSD: protosw.h,v 1.66 2024/04/14 20:46:27 bluhm Exp $	*/
2/*	$NetBSD: protosw.h,v 1.10 1996/04/09 20:55:32 cgd Exp $	*/
3
4/*-
5 * Copyright (c) 1982, 1986, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 *	@(#)protosw.h	8.1 (Berkeley) 6/2/93
33 */
34
35/*
36 * Protocol switch table.
37 *
38 * Each protocol has a handle initializing one of these structures,
39 * which is used for protocol-protocol and system-protocol communication.
40 *
41 * A protocol is called through the pr_init entry before any other.
42 * Thereafter it is called every 200ms through the pr_fasttimo entry and
43 * every 500ms through the pr_slowtimo for timer based actions.
44 *
45 * Protocols pass data between themselves as chains of mbufs using
46 * the pr_input and pr_send hooks.  Pr_input passes data up (towards
47 * UNIX) and pr_send passes it down (towards the imps); control
48 * information passes up and down on pr_ctlinput and pr_ctloutput.
49 * The protocol is responsible for the space occupied by any the
50 * arguments to these entries and must dispose it.
51 *
52 * The userreq routine interfaces protocols to the system and is
53 * described below.
54 */
55
56#ifndef _SYS_PROTOSW_H_
57#define _SYS_PROTOSW_H_
58
59struct mbuf;
60struct sockaddr;
61struct socket;
62struct domain;
63struct proc;
64struct stat;
65struct ifnet;
66
67struct pr_usrreqs {
68	int	(*pru_attach)(struct socket *, int, int);
69	int	(*pru_detach)(struct socket *);
70	void	(*pru_lock)(struct socket *);
71	void	(*pru_unlock)(struct socket *);
72	int	(*pru_locked)(struct socket *so);
73	int	(*pru_bind)(struct socket *, struct mbuf *, struct proc *);
74	int	(*pru_listen)(struct socket *);
75	int	(*pru_connect)(struct socket *, struct mbuf *);
76	int	(*pru_accept)(struct socket *, struct mbuf *);
77	int	(*pru_disconnect)(struct socket *);
78	int	(*pru_shutdown)(struct socket *);
79	void	(*pru_rcvd)(struct socket *);
80	int	(*pru_send)(struct socket *, struct mbuf *, struct mbuf *,
81		    struct mbuf *);
82	void	(*pru_abort)(struct socket *);
83	int	(*pru_control)(struct socket *, u_long, caddr_t,
84		    struct ifnet *);
85	int	(*pru_sense)(struct socket *, struct stat *);
86	int	(*pru_rcvoob)(struct socket *, struct mbuf *, int);
87	int	(*pru_sendoob)(struct socket *, struct mbuf *, struct mbuf *,
88		    struct mbuf *);
89	int	(*pru_sockaddr)(struct socket *, struct mbuf *);
90	int	(*pru_peeraddr)(struct socket *, struct mbuf *);
91	int	(*pru_connect2)(struct socket *, struct socket *);
92};
93
94struct protosw {
95	short	pr_type;		/* socket type used for */
96	const	struct domain *pr_domain; /* domain protocol a member of */
97	short	pr_protocol;		/* protocol number */
98	short	pr_flags;		/* see below */
99
100/* protocol-protocol hooks */
101					/* input to protocol (from below) */
102	int	(*pr_input)(struct mbuf **, int *, int, int);
103					/* control input (from below) */
104	void	(*pr_ctlinput)(int, struct sockaddr *, u_int, void *);
105					/* control output (from above) */
106	int	(*pr_ctloutput)(int, struct socket *, int, int, struct mbuf *);
107
108/* user-protocol hooks */
109	const	struct pr_usrreqs *pr_usrreqs;
110
111/* utility hooks */
112	void	(*pr_init)(void);	/* initialization hook */
113	void	(*pr_fasttimo)(void);	/* fast timeout (200ms) */
114	void	(*pr_slowtimo)(void);	/* slow timeout (500ms) */
115					/* sysctl for protocol */
116	int	(*pr_sysctl)(int *, u_int, void *, size_t *, void *, size_t);
117};
118
119#define PR_SLOWHZ	2		/* 2 slow timeouts per second */
120#define PR_FASTHZ	5		/* 5 fast timeouts per second */
121
122/*
123 * Values for pr_flags.
124 * PR_ADDR requires PR_ATOMIC;
125 * PR_ADDR and PR_CONNREQUIRED are mutually exclusive.
126 */
127#define PR_ATOMIC	0x0001		/* exchange atomic messages only */
128#define PR_ADDR		0x0002		/* addresses given with messages */
129#define PR_CONNREQUIRED	0x0004		/* connection required by protocol */
130#define PR_WANTRCVD	0x0008		/* want PRU_RCVD calls */
131#define PR_RIGHTS	0x0010		/* passes capabilities */
132#define PR_ABRTACPTDIS	0x0020		/* abort on accept(2) to disconnected
133					   socket */
134#define PR_SPLICE	0x0040		/* socket splicing is possible */
135#define PR_MPINPUT	0x0080		/* input runs with shared netlock */
136
137/*
138 * The arguments to usrreq are:
139 *	(*protosw[].pr_usrreq)(up, req, m, nam, opt);
140 * where up is a (struct socket *), req is one of these requests,
141 * m is a optional mbuf chain containing a message,
142 * nam is an optional mbuf chain containing an address,
143 * and opt is a pointer to a socketopt structure or nil.
144 * The protocol is responsible for disposal of the mbuf chain m,
145 * the caller is responsible for any space held by nam and opt.
146 * A non-zero return from usrreq gives an
147 * UNIX error number which should be passed to higher level software.
148 */
149#define	PRU_ATTACH		0	/* attach protocol to up */
150#define	PRU_DETACH		1	/* detach protocol from up */
151#define	PRU_BIND		2	/* bind socket to address */
152#define	PRU_LISTEN		3	/* listen for connection */
153#define	PRU_CONNECT		4	/* establish connection to peer */
154#define	PRU_ACCEPT		5	/* accept connection from peer */
155#define	PRU_DISCONNECT		6	/* disconnect from peer */
156#define	PRU_SHUTDOWN		7	/* won't send any more data */
157#define	PRU_RCVD		8	/* have taken data; more room now */
158#define	PRU_SEND		9	/* send this data */
159#define	PRU_ABORT		10	/* abort (fast DISCONNECT, DETACH) */
160#define	PRU_CONTROL		11	/* control operations on protocol */
161#define	PRU_SENSE		12	/* return status into m */
162#define	PRU_RCVOOB		13	/* retrieve out of band data */
163#define	PRU_SENDOOB		14	/* send out of band data */
164#define	PRU_SOCKADDR		15	/* fetch socket's address */
165#define	PRU_PEERADDR		16	/* fetch peer's address */
166#define	PRU_CONNECT2		17	/* connect two sockets */
167/* begin for protocols internal use */
168#define	PRU_FASTTIMO		18	/* 200ms timeout */
169#define	PRU_SLOWTIMO		19	/* 500ms timeout */
170#define	PRU_PROTORCV		20	/* receive from below */
171#define	PRU_PROTOSEND		21	/* send to below */
172
173#define	PRU_NREQ		22
174
175#ifdef PRUREQUESTS
176const char *prurequests[] = {
177	"ATTACH",	"DETACH",	"BIND",		"LISTEN",
178	"CONNECT",	"ACCEPT",	"DISCONNECT",	"SHUTDOWN",
179	"RCVD",		"SEND",		"ABORT",	"CONTROL",
180	"SENSE",	"RCVOOB",	"SENDOOB",	"SOCKADDR",
181	"PEERADDR",	"CONNECT2",	"FASTTIMO",	"SLOWTIMO",
182	"PROTORCV",	"PROTOSEND",
183};
184#endif
185
186/*
187 * The arguments to the ctlinput routine are
188 *	(*protosw[].pr_ctlinput)(cmd, sa, arg);
189 * where cmd is one of the commands below, sa is a pointer to a sockaddr,
190 * and arg is an optional caddr_t argument used within a protocol family.
191 */
192#define	PRC_IFDOWN		0	/* interface transition */
193#define	PRC_ROUTEDEAD		1	/* select new route if possible ??? */
194#define	PRC_MTUINC		2	/* increase in mtu to host */
195#define	PRC_QUENCH2		3	/* DEC congestion bit says slow down */
196#define	PRC_QUENCH		4	/* some one said to slow down */
197#define	PRC_MSGSIZE		5	/* message size forced drop */
198#define	PRC_HOSTDEAD		6	/* host appears to be down */
199#define	PRC_HOSTUNREACH		7	/* deprecated (use PRC_UNREACH_HOST) */
200#define	PRC_UNREACH_NET		8	/* no route to network */
201#define	PRC_UNREACH_HOST	9	/* no route to host */
202#define	PRC_UNREACH_PROTOCOL	10	/* dst says bad protocol */
203#define	PRC_UNREACH_PORT	11	/* bad port # */
204/* was	PRC_UNREACH_NEEDFRAG	12	   (use PRC_MSGSIZE) */
205#define	PRC_UNREACH_SRCFAIL	13	/* source route failed */
206#define	PRC_REDIRECT_NET	14	/* net routing redirect */
207#define	PRC_REDIRECT_HOST	15	/* host routing redirect */
208#define	PRC_REDIRECT_TOSNET	16	/* redirect for type of service & net */
209#define	PRC_REDIRECT_TOSHOST	17	/* redirect for tos & host */
210#define	PRC_TIMXCEED_INTRANS	18	/* packet lifetime expired in transit */
211#define	PRC_TIMXCEED_REASS	19	/* lifetime expired on reass q */
212#define	PRC_PARAMPROB		20	/* header incorrect */
213
214#define	PRC_NCMDS		21
215
216#define	PRC_IS_REDIRECT(cmd)	\
217	((cmd) >= PRC_REDIRECT_NET && (cmd) <= PRC_REDIRECT_TOSHOST)
218
219#ifdef PRCREQUESTS
220char	*prcrequests[] = {
221	"IFDOWN", "ROUTEDEAD", "MTUINC", "DEC-BIT-QUENCH2",
222	"QUENCH", "MSGSIZE", "HOSTDEAD", "#7",
223	"NET-UNREACH", "HOST-UNREACH", "PROTO-UNREACH", "PORT-UNREACH",
224	"#12", "SRCFAIL-UNREACH", "NET-REDIRECT", "HOST-REDIRECT",
225	"TOSNET-REDIRECT", "TOSHOST-REDIRECT", "TX-INTRANS", "TX-REASS",
226	"PARAMPROB"
227};
228#endif
229
230/*
231 * The arguments to ctloutput are:
232 *	(*protosw[].pr_ctloutput)(req, so, level, optname, optval);
233 * req is one of the actions listed below, so is a (struct socket *),
234 * level is an indication of which protocol layer the option is intended.
235 * optname is a protocol dependent socket option request,
236 * optval is a pointer to a mbuf-chain pointer, for value-return results.
237 * The protocol is responsible for disposal of the mbuf chain *optval
238 * if supplied,
239 * the caller is responsible for any space held by *optval, when returned.
240 * A non-zero return from usrreq gives an
241 * UNIX error number which should be passed to higher level software.
242 */
243#define	PRCO_GETOPT	0
244#define	PRCO_SETOPT	1
245
246#define	PRCO_NCMDS	2
247
248#ifdef PRCOREQUESTS
249char	*prcorequests[] = {
250	"GETOPT", "SETOPT",
251};
252#endif
253
254#ifdef _KERNEL
255
256#include <sys/mbuf.h>
257#include <sys/socketvar.h>
258#include <sys/systm.h>
259
260struct ifnet;
261struct sockaddr;
262const struct protosw *pffindproto(int, int, int);
263const struct protosw *pffindtype(int, int);
264const struct domain *pffinddomain(int);
265void pfctlinput(int, struct sockaddr *);
266
267extern u_char ip_protox[];
268extern const struct protosw inetsw[];
269
270#ifdef INET6
271extern u_char ip6_protox[];
272extern const struct protosw inet6sw[];
273#endif /* INET6 */
274
275static inline int
276pru_attach(struct socket *so, int proto, int wait)
277{
278	return (*so->so_proto->pr_usrreqs->pru_attach)(so, proto, wait);
279}
280
281static inline int
282pru_detach(struct socket *so)
283{
284	return (*so->so_proto->pr_usrreqs->pru_detach)(so);
285}
286
287static inline void
288pru_lock(struct socket *so)
289{
290	if (so->so_proto->pr_usrreqs->pru_lock)
291		(*so->so_proto->pr_usrreqs->pru_lock)(so);
292}
293
294static inline void
295pru_unlock(struct socket *so)
296{
297	if (so->so_proto->pr_usrreqs->pru_unlock)
298		(*so->so_proto->pr_usrreqs->pru_unlock)(so);
299}
300
301static inline int
302pru_locked(struct socket *so)
303{
304	if (so->so_proto->pr_usrreqs->pru_locked)
305		return (*so->so_proto->pr_usrreqs->pru_locked)(so);
306	return (0);
307}
308
309static inline int
310pru_bind(struct socket *so, struct mbuf *nam, struct proc *p)
311{
312	if (so->so_proto->pr_usrreqs->pru_bind)
313		return (*so->so_proto->pr_usrreqs->pru_bind)(so, nam, p);
314	return (EOPNOTSUPP);
315}
316
317static inline int
318pru_listen(struct socket *so)
319{
320	if (so->so_proto->pr_usrreqs->pru_listen)
321		return (*so->so_proto->pr_usrreqs->pru_listen)(so);
322	return (EOPNOTSUPP);
323}
324
325static inline int
326pru_connect(struct socket *so, struct mbuf *nam)
327{
328	if (so->so_proto->pr_usrreqs->pru_connect)
329		return (*so->so_proto->pr_usrreqs->pru_connect)(so, nam);
330	return (EOPNOTSUPP);
331}
332
333static inline int
334pru_accept(struct socket *so, struct mbuf *nam)
335{
336	if (so->so_proto->pr_usrreqs->pru_accept)
337		return (*so->so_proto->pr_usrreqs->pru_accept)(so, nam);
338	return (EOPNOTSUPP);
339}
340
341static inline int
342pru_disconnect(struct socket *so)
343{
344	if (so->so_proto->pr_usrreqs->pru_disconnect)
345		return (*so->so_proto->pr_usrreqs->pru_disconnect)(so);
346	return (EOPNOTSUPP);
347}
348
349static inline int
350pru_shutdown(struct socket *so)
351{
352	return (*so->so_proto->pr_usrreqs->pru_shutdown)(so);
353}
354
355static inline void
356pru_rcvd(struct socket *so)
357{
358	(*so->so_proto->pr_usrreqs->pru_rcvd)(so);
359}
360
361static inline int
362pru_send(struct socket *so, struct mbuf *top, struct mbuf *addr,
363    struct mbuf *control)
364{
365	return (*so->so_proto->pr_usrreqs->pru_send)(so, top, addr, control);
366}
367
368static inline void
369pru_abort(struct socket *so)
370{
371	(*so->so_proto->pr_usrreqs->pru_abort)(so);
372}
373
374static inline int
375pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
376{
377	if (so->so_proto->pr_usrreqs->pru_control)
378		return (*so->so_proto->pr_usrreqs->pru_control)(so,
379		    cmd, data, ifp);
380	return (EOPNOTSUPP);
381}
382
383static inline int
384pru_sense(struct socket *so, struct stat *ub)
385{
386	if (so->so_proto->pr_usrreqs->pru_sense)
387		return (*so->so_proto->pr_usrreqs->pru_sense)(so, ub);
388	return (0);
389}
390
391static inline int
392pru_rcvoob(struct socket *so, struct mbuf *m, int flags)
393{
394	if (so->so_proto->pr_usrreqs->pru_rcvoob)
395		return (*so->so_proto->pr_usrreqs->pru_rcvoob)(so, m, flags);
396	return (EOPNOTSUPP);
397}
398
399static inline int
400pru_sendoob(struct socket *so, struct mbuf *top, struct mbuf *addr,
401    struct mbuf *control)
402{
403	if (so->so_proto->pr_usrreqs->pru_sendoob)
404		return (*so->so_proto->pr_usrreqs->pru_sendoob)(so,
405		    top, addr, control);
406	m_freem(top);
407	m_freem(control);
408	return (EOPNOTSUPP);
409}
410
411static inline int
412pru_sockaddr(struct socket *so, struct mbuf *addr)
413{
414	return (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, addr);
415}
416
417static inline int
418pru_peeraddr(struct socket *so, struct mbuf *addr)
419{
420	return (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, addr);
421}
422
423static inline int
424pru_connect2(struct socket *so1, struct socket *so2)
425{
426	if (so1->so_proto->pr_usrreqs->pru_connect2)
427		return (*so1->so_proto->pr_usrreqs->pru_connect2)(so1, so2);
428	return (EOPNOTSUPP);
429}
430
431#endif
432
433#endif /* _SYS_PROTOSW_H_ */
434