1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1982, 1986, 1990, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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 University 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.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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
29 * SUCH DAMAGE.
30 *
31 *	@(#)socketvar.h	8.3 (Berkeley) 2/19/95
32 *
33 * $FreeBSD$
34 */
35
36#ifndef _SYS_SOCKETVAR_H_
37#define _SYS_SOCKETVAR_H_
38
39/*
40 * Socket generation count type.  Also used in xinpcb, xtcpcb, xunpcb.
41 */
42typedef uint64_t so_gen_t;
43
44#if defined(_KERNEL) || defined(_WANT_SOCKET)
45#include <sys/queue.h>			/* for TAILQ macros */
46#include <sys/selinfo.h>		/* for struct selinfo */
47#include <sys/_lock.h>
48#include <sys/_mutex.h>
49#include <sys/osd.h>
50#include <sys/_sx.h>
51#include <sys/sockbuf.h>
52#ifdef _KERNEL
53#include <sys/caprights.h>
54#include <sys/sockopt.h>
55#endif
56
57struct vnet;
58
59/*
60 * Kernel structure per socket.
61 * Contains send and receive buffer queues,
62 * handle on protocol and pointer to protocol
63 * private data and error information.
64 */
65typedef	int so_upcall_t(struct socket *, void *, int);
66typedef	void so_dtor_t(struct socket *);
67
68struct socket;
69
70enum socket_qstate {
71	SQ_NONE = 0,
72	SQ_INCOMP = 0x0800,	/* on sol_incomp */
73	SQ_COMP = 0x1000,	/* on sol_comp */
74};
75
76/*-
77 * Locking key to struct socket:
78 * (a) constant after allocation, no locking required.
79 * (b) locked by SOCK_LOCK(so).
80 * (cr) locked by SOCKBUF_LOCK(&so->so_rcv).
81 * (cs) locked by SOCKBUF_LOCK(&so->so_snd).
82 * (e) locked by SOLISTEN_LOCK() of corresponding listening socket.
83 * (f) not locked since integer reads/writes are atomic.
84 * (g) used only as a sleep/wakeup address, no value.
85 * (h) locked by global mutex so_global_mtx.
86 * (k) locked by KTLS workqueue mutex
87 */
88TAILQ_HEAD(accept_queue, socket);
89struct socket {
90	struct mtx	so_lock;
91	volatile u_int	so_count;	/* (b / refcount) */
92	struct selinfo	so_rdsel;	/* (b/cr) for so_rcv/so_comp */
93	struct selinfo	so_wrsel;	/* (b/cs) for so_snd */
94	short	so_type;		/* (a) generic type, see socket.h */
95	int	so_options;		/* (b) from socket call, see socket.h */
96	short	so_linger;		/* time to linger close(2) */
97	short	so_state;		/* (b) internal state flags SS_* */
98	void	*so_pcb;		/* protocol control block */
99	struct	vnet *so_vnet;		/* (a) network stack instance */
100	struct	protosw *so_proto;	/* (a) protocol handle */
101	short	so_timeo;		/* (g) connection timeout */
102	u_short	so_error;		/* (f) error affecting connection */
103	struct	sigio *so_sigio;	/* [sg] information for async I/O or
104					   out of band data (SIGURG) */
105	struct	ucred *so_cred;		/* (a) user credentials */
106	struct	label *so_label;	/* (b) MAC label for socket */
107	/* NB: generation count must not be first. */
108	so_gen_t so_gencnt;		/* (h) generation count */
109	void	*so_emuldata;		/* (b) private data for emulators */
110	so_dtor_t *so_dtor;		/* (b) optional destructor */
111	struct	osd	osd;		/* Object Specific extensions */
112	/*
113	 * so_fibnum, so_user_cookie and friends can be used to attach
114	 * some user-specified metadata to a socket, which then can be
115	 * used by the kernel for various actions.
116	 * so_user_cookie is used by ipfw/dummynet.
117	 */
118	int so_fibnum;		/* routing domain for this socket */
119	uint32_t so_user_cookie;
120
121	int so_ts_clock;	/* type of the clock used for timestamps */
122	uint32_t so_max_pacing_rate;	/* (f) TX rate limit in bytes/s */
123	union {
124		/* Regular (data flow) socket. */
125		struct {
126			/* (cr, cs) Receive and send buffers. */
127			struct sockbuf		so_rcv, so_snd;
128
129			/* (e) Our place on accept queue. */
130			TAILQ_ENTRY(socket)	so_list;
131			struct socket		*so_listen;	/* (b) */
132			enum socket_qstate so_qstate;		/* (b) */
133			/* (b) cached MAC label for peer */
134			struct	label		*so_peerlabel;
135			u_long	so_oobmark;	/* chars to oob mark */
136
137			/* (k) Our place on KTLS RX work queue. */
138			STAILQ_ENTRY(socket)	so_ktls_rx_list;
139		};
140		/*
141		 * Listening socket, where accepts occur, is so_listen in all
142		 * subsidiary sockets.  If so_listen is NULL, socket is not
143		 * related to an accept.  For a listening socket itself
144		 * sol_incomp queues partially completed connections, while
145		 * sol_comp is a queue of connections ready to be accepted.
146		 * If a connection is aborted and it has so_listen set, then
147		 * it has to be pulled out of either sol_incomp or sol_comp.
148		 * We allow connections to queue up based on current queue
149		 * lengths and limit on number of queued connections for this
150		 * socket.
151		 */
152		struct {
153			/* (e) queue of partial unaccepted connections */
154			struct accept_queue	sol_incomp;
155			/* (e) queue of complete unaccepted connections */
156			struct accept_queue	sol_comp;
157			u_int	sol_qlen;    /* (e) sol_comp length */
158			u_int	sol_incqlen; /* (e) sol_incomp length */
159			u_int	sol_qlimit;  /* (e) queue limit */
160
161			/* accept_filter(9) optional data */
162			struct	accept_filter	*sol_accept_filter;
163			void	*sol_accept_filter_arg;	/* saved filter args */
164			char	*sol_accept_filter_str;	/* saved user args */
165
166			/* Optional upcall, for kernel socket. */
167			so_upcall_t	*sol_upcall;	/* (e) */
168			void		*sol_upcallarg;	/* (e) */
169
170			/* Socket buffer parameters, to be copied to
171			 * dataflow sockets, accepted from this one. */
172			int		sol_sbrcv_lowat;
173			int		sol_sbsnd_lowat;
174			u_int		sol_sbrcv_hiwat;
175			u_int		sol_sbsnd_hiwat;
176			short		sol_sbrcv_flags;
177			short		sol_sbsnd_flags;
178			sbintime_t	sol_sbrcv_timeo;
179			sbintime_t	sol_sbsnd_timeo;
180
181			/* Information tracking listen queue overflows. */
182			struct timeval	sol_lastover;	/* (e) */
183			int		sol_overcount;	/* (e) */
184		};
185	};
186};
187#endif	/* defined(_KERNEL) || defined(_WANT_SOCKET) */
188
189/*
190 * Socket state bits.
191 *
192 * Historically, these bits were all kept in the so_state field.
193 * They are now split into separate, lock-specific fields.
194 * so_state maintains basic socket state protected by the socket lock.
195 * so_qstate holds information about the socket accept queues.
196 * Each socket buffer also has a state field holding information
197 * relevant to that socket buffer (can't send, rcv).
198 * Many fields will be read without locks to improve performance and avoid
199 * lock order issues.  However, this approach must be used with caution.
200 */
201#define	SS_NOFDREF		0x0001	/* no file table ref any more */
202#define	SS_ISCONNECTED		0x0002	/* socket connected to a peer */
203#define	SS_ISCONNECTING		0x0004	/* in process of connecting to peer */
204#define	SS_ISDISCONNECTING	0x0008	/* in process of disconnecting */
205#define	SS_NBIO			0x0100	/* non-blocking ops */
206#define	SS_ASYNC		0x0200	/* async i/o notify */
207#define	SS_ISCONFIRMING		0x0400	/* deciding to accept connection req */
208#define	SS_ISDISCONNECTED	0x2000	/* socket disconnected from peer */
209
210/*
211 * Protocols can mark a socket as SS_PROTOREF to indicate that, following
212 * pru_detach, they still want the socket to persist, and will free it
213 * themselves when they are done.  Protocols should only ever call sofree()
214 * following setting this flag in pru_detach(), and never otherwise, as
215 * sofree() bypasses socket reference counting.
216 */
217#define	SS_PROTOREF		0x4000	/* strong protocol reference */
218
219#ifdef _KERNEL
220
221#define	SOCK_MTX(so)		(&(so)->so_lock)
222#define	SOCK_LOCK(so)		mtx_lock(&(so)->so_lock)
223#define	SOCK_OWNED(so)		mtx_owned(&(so)->so_lock)
224#define	SOCK_UNLOCK(so)		mtx_unlock(&(so)->so_lock)
225#define	SOCK_LOCK_ASSERT(so)	mtx_assert(&(so)->so_lock, MA_OWNED)
226#define	SOCK_UNLOCK_ASSERT(so)	mtx_assert(&(so)->so_lock, MA_NOTOWNED)
227
228#define	SOLISTENING(sol)	(((sol)->so_options & SO_ACCEPTCONN) != 0)
229#define	SOLISTEN_LOCK(sol)	do {					\
230	mtx_lock(&(sol)->so_lock);					\
231	KASSERT(SOLISTENING(sol),					\
232	    ("%s: %p not listening", __func__, (sol)));			\
233} while (0)
234#define	SOLISTEN_TRYLOCK(sol)	mtx_trylock(&(sol)->so_lock)
235#define	SOLISTEN_UNLOCK(sol)	do {					\
236	KASSERT(SOLISTENING(sol),					\
237	    ("%s: %p not listening", __func__, (sol)));			\
238	mtx_unlock(&(sol)->so_lock);					\
239} while (0)
240#define	SOLISTEN_LOCK_ASSERT(sol)	do {				\
241	mtx_assert(&(sol)->so_lock, MA_OWNED);				\
242	KASSERT(SOLISTENING(sol),					\
243	    ("%s: %p not listening", __func__, (sol)));			\
244} while (0)
245
246/*
247 * Macros for sockets and socket buffering.
248 */
249
250/*
251 * Flags to sblock().
252 */
253#define	SBL_WAIT	0x00000001	/* Wait if not immediately available. */
254#define	SBL_NOINTR	0x00000002	/* Force non-interruptible sleep. */
255#define	SBL_VALID	(SBL_WAIT | SBL_NOINTR)
256
257/*
258 * Do we need to notify the other side when I/O is possible?
259 */
260#define	sb_notify(sb)	(((sb)->sb_flags & (SB_WAIT | SB_SEL | SB_ASYNC | \
261    SB_UPCALL | SB_AIO | SB_KNOTE)) != 0)
262
263/* do we have to send all at once on a socket? */
264#define	sosendallatonce(so) \
265    ((so)->so_proto->pr_flags & PR_ATOMIC)
266
267/* can we read something from so? */
268#define	soreadabledata(so) \
269	(sbavail(&(so)->so_rcv) >= (so)->so_rcv.sb_lowat ||  (so)->so_error)
270#define	soreadable(so) \
271	(soreadabledata(so) || ((so)->so_rcv.sb_state & SBS_CANTRCVMORE))
272
273/* can we write something to so? */
274#define	sowriteable(so) \
275    ((sbspace(&(so)->so_snd) >= (so)->so_snd.sb_lowat && \
276	(((so)->so_state&SS_ISCONNECTED) || \
277	  ((so)->so_proto->pr_flags&PR_CONNREQUIRED)==0)) || \
278     ((so)->so_snd.sb_state & SBS_CANTSENDMORE) || \
279     (so)->so_error)
280
281/*
282 * soref()/sorele() ref-count the socket structure.
283 * soref() may be called without owning socket lock, but in that case a
284 * caller must own something that holds socket, and so_count must be not 0.
285 * Note that you must still explicitly close the socket, but the last ref
286 * count will free the structure.
287 */
288#define	soref(so)	refcount_acquire(&(so)->so_count)
289#define	sorele(so) do {							\
290	SOCK_LOCK_ASSERT(so);						\
291	if (refcount_release(&(so)->so_count))				\
292		sofree(so);						\
293	else								\
294		SOCK_UNLOCK(so);					\
295} while (0)
296
297/*
298 * In sorwakeup() and sowwakeup(), acquire the socket buffer lock to
299 * avoid a non-atomic test-and-wakeup.  However, sowakeup is
300 * responsible for releasing the lock if it is called.  We unlock only
301 * if we don't call into sowakeup.  If any code is introduced that
302 * directly invokes the underlying sowakeup() primitives, it must
303 * maintain the same semantics.
304 */
305#define	sorwakeup_locked(so) do {					\
306	SOCKBUF_LOCK_ASSERT(&(so)->so_rcv);				\
307	if (sb_notify(&(so)->so_rcv))					\
308		sowakeup((so), &(so)->so_rcv);	 			\
309	else								\
310		SOCKBUF_UNLOCK(&(so)->so_rcv);				\
311} while (0)
312
313#define	sorwakeup(so) do {						\
314	SOCKBUF_LOCK(&(so)->so_rcv);					\
315	sorwakeup_locked(so);						\
316} while (0)
317
318#define	sowwakeup_locked(so) do {					\
319	SOCKBUF_LOCK_ASSERT(&(so)->so_snd);				\
320	if (sb_notify(&(so)->so_snd))					\
321		sowakeup((so), &(so)->so_snd); 				\
322	else								\
323		SOCKBUF_UNLOCK(&(so)->so_snd);				\
324} while (0)
325
326#define	sowwakeup(so) do {						\
327	SOCKBUF_LOCK(&(so)->so_snd);					\
328	sowwakeup_locked(so);						\
329} while (0)
330
331struct accept_filter {
332	char	accf_name[16];
333	int	(*accf_callback)
334		(struct socket *so, void *arg, int waitflag);
335	void *	(*accf_create)
336		(struct socket *so, char *arg);
337	void	(*accf_destroy)
338		(struct socket *so);
339	SLIST_ENTRY(accept_filter) accf_next;
340};
341
342#define	ACCEPT_FILTER_DEFINE(modname, filtname, cb, create, destroy, ver) \
343	static struct accept_filter modname##_filter = {		\
344		.accf_name = filtname,					\
345		.accf_callback = cb,					\
346		.accf_create = create,					\
347		.accf_destroy = destroy,				\
348	};								\
349	static moduledata_t modname##_mod = {				\
350		.name = __XSTRING(modname),				\
351		.evhand = accept_filt_generic_mod_event,		\
352		.priv = &modname##_filter,				\
353	};								\
354	DECLARE_MODULE(modname, modname##_mod, SI_SUB_DRIVERS,		\
355	    SI_ORDER_MIDDLE);						\
356	MODULE_VERSION(modname, ver)
357
358#ifdef MALLOC_DECLARE
359MALLOC_DECLARE(M_ACCF);
360MALLOC_DECLARE(M_PCB);
361MALLOC_DECLARE(M_SONAME);
362#endif
363
364/*
365 * Socket specific helper hook point identifiers
366 * Do not leave holes in the sequence, hook registration is a loop.
367 */
368#define HHOOK_SOCKET_OPT		0
369#define HHOOK_SOCKET_CREATE		1
370#define HHOOK_SOCKET_RCV 		2
371#define HHOOK_SOCKET_SND		3
372#define HHOOK_FILT_SOREAD		4
373#define HHOOK_FILT_SOWRITE		5
374#define HHOOK_SOCKET_CLOSE		6
375#define HHOOK_SOCKET_LAST		HHOOK_SOCKET_CLOSE
376
377struct socket_hhook_data {
378	struct socket	*so;
379	struct mbuf	*m;
380	void		*hctx;		/* hook point specific data*/
381	int		status;
382};
383
384extern int	maxsockets;
385extern u_long	sb_max;
386extern so_gen_t so_gencnt;
387
388struct file;
389struct filecaps;
390struct filedesc;
391struct mbuf;
392struct sockaddr;
393struct ucred;
394struct uio;
395
396/* 'which' values for socket upcalls. */
397#define	SO_RCV		1
398#define	SO_SND		2
399
400/* Return values for socket upcalls. */
401#define	SU_OK		0
402#define	SU_ISCONNECTED	1
403
404/*
405 * From uipc_socket and friends
406 */
407int	getsockaddr(struct sockaddr **namp, const struct sockaddr *uaddr,
408	    size_t len);
409int	getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
410	    struct file **fpp, u_int *fflagp, struct filecaps *havecaps);
411void	soabort(struct socket *so);
412int	soaccept(struct socket *so, struct sockaddr **nam);
413void	soaio_enqueue(struct task *task);
414void	soaio_rcv(void *context, int pending);
415void	soaio_snd(void *context, int pending);
416int	socheckuid(struct socket *so, uid_t uid);
417int	sobind(struct socket *so, struct sockaddr *nam, struct thread *td);
418int	sobindat(int fd, struct socket *so, struct sockaddr *nam,
419	    struct thread *td);
420int	soclose(struct socket *so);
421int	soconnect(struct socket *so, struct sockaddr *nam, struct thread *td);
422int	soconnectat(int fd, struct socket *so, struct sockaddr *nam,
423	    struct thread *td);
424int	soconnect2(struct socket *so1, struct socket *so2);
425int	socreate(int dom, struct socket **aso, int type, int proto,
426	    struct ucred *cred, struct thread *td);
427int	sodisconnect(struct socket *so);
428void	sodtor_set(struct socket *, so_dtor_t *);
429struct	sockaddr *sodupsockaddr(const struct sockaddr *sa, int mflags);
430void	sofree(struct socket *so);
431void	sohasoutofband(struct socket *so);
432int	solisten(struct socket *so, int backlog, struct thread *td);
433void	solisten_proto(struct socket *so, int backlog);
434int	solisten_proto_check(struct socket *so);
435int	solisten_dequeue(struct socket *, struct socket **, int);
436struct socket *
437	sonewconn(struct socket *head, int connstatus);
438struct socket *
439	sopeeloff(struct socket *);
440int	sopoll(struct socket *so, int events, struct ucred *active_cred,
441	    struct thread *td);
442int	sopoll_generic(struct socket *so, int events,
443	    struct ucred *active_cred, struct thread *td);
444int	soreceive(struct socket *so, struct sockaddr **paddr, struct uio *uio,
445	    struct mbuf **mp0, struct mbuf **controlp, int *flagsp);
446int	soreceive_stream(struct socket *so, struct sockaddr **paddr,
447	    struct uio *uio, struct mbuf **mp0, struct mbuf **controlp,
448	    int *flagsp);
449int	soreceive_dgram(struct socket *so, struct sockaddr **paddr,
450	    struct uio *uio, struct mbuf **mp0, struct mbuf **controlp,
451	    int *flagsp);
452int	soreceive_generic(struct socket *so, struct sockaddr **paddr,
453	    struct uio *uio, struct mbuf **mp0, struct mbuf **controlp,
454	    int *flagsp);
455int	soreserve(struct socket *so, u_long sndcc, u_long rcvcc);
456void	sorflush(struct socket *so);
457int	sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
458	    struct mbuf *top, struct mbuf *control, int flags,
459	    struct thread *td);
460int	sosend_dgram(struct socket *so, struct sockaddr *addr,
461	    struct uio *uio, struct mbuf *top, struct mbuf *control,
462	    int flags, struct thread *td);
463int	sosend_generic(struct socket *so, struct sockaddr *addr,
464	    struct uio *uio, struct mbuf *top, struct mbuf *control,
465	    int flags, struct thread *td);
466int	soshutdown(struct socket *so, int how);
467void	soupcall_clear(struct socket *, int);
468void	soupcall_set(struct socket *, int, so_upcall_t, void *);
469void	solisten_upcall_set(struct socket *, so_upcall_t, void *);
470void	sowakeup(struct socket *so, struct sockbuf *sb);
471void	sowakeup_aio(struct socket *so, struct sockbuf *sb);
472void	solisten_wakeup(struct socket *);
473int	selsocket(struct socket *so, int events, struct timeval *tv,
474	    struct thread *td);
475void	soisconnected(struct socket *so);
476void	soisconnecting(struct socket *so);
477void	soisdisconnected(struct socket *so);
478void	soisdisconnecting(struct socket *so);
479void	socantrcvmore(struct socket *so);
480void	socantrcvmore_locked(struct socket *so);
481void	socantsendmore(struct socket *so);
482void	socantsendmore_locked(struct socket *so);
483
484/*
485 * Accept filter functions (duh).
486 */
487int	accept_filt_add(struct accept_filter *filt);
488int	accept_filt_del(char *name);
489struct	accept_filter *accept_filt_get(char *name);
490#ifdef ACCEPT_FILTER_MOD
491#ifdef SYSCTL_DECL
492SYSCTL_DECL(_net_inet_accf);
493#endif
494int	accept_filt_generic_mod_event(module_t mod, int event, void *data);
495#endif
496
497#endif /* _KERNEL */
498
499/*
500 * Structure to export socket from kernel to utilities, via sysctl(3).
501 */
502struct xsocket {
503	ksize_t		xso_len;	/* length of this structure */
504	kvaddr_t	xso_so;		/* kernel address of struct socket */
505	kvaddr_t	so_pcb;		/* kernel address of struct inpcb */
506	uint64_t	so_oobmark;
507	int64_t		so_spare64[8];
508	int32_t		xso_protocol;
509	int32_t		xso_family;
510	uint32_t	so_qlen;
511	uint32_t	so_incqlen;
512	uint32_t	so_qlimit;
513	pid_t		so_pgid;
514	uid_t		so_uid;
515	int32_t		so_spare32[8];
516	int16_t		so_type;
517	int16_t		so_options;
518	int16_t		so_linger;
519	int16_t		so_state;
520	int16_t		so_timeo;
521	uint16_t	so_error;
522	struct xsockbuf {
523		uint32_t	sb_cc;
524		uint32_t	sb_hiwat;
525		uint32_t	sb_mbcnt;
526		uint32_t	sb_mcnt;
527		uint32_t	sb_ccnt;
528		uint32_t	sb_mbmax;
529		int32_t		sb_lowat;
530		int32_t		sb_timeo;
531		int16_t		sb_flags;
532	} so_rcv, so_snd;
533};
534
535#ifdef _KERNEL
536void	sotoxsocket(struct socket *so, struct xsocket *xso);
537void	sbtoxsockbuf(struct sockbuf *sb, struct xsockbuf *xsb);
538#endif
539
540/*
541 * Socket buffer state bits.  Exported via libprocstat(3).
542 */
543#define	SBS_CANTSENDMORE	0x0010	/* can't send more data to peer */
544#define	SBS_CANTRCVMORE		0x0020	/* can't receive more data from peer */
545#define	SBS_RCVATMARK		0x0040	/* at mark on input */
546
547#endif /* !_SYS_SOCKETVAR_H_ */
548