xref: /minix/minix/include/minix/rmib.h (revision 045e0ed3)
1 #ifndef _MINIX_RMIB_H
2 #define _MINIX_RMIB_H
3 
4 /*
5  * This header file is for use by services that use the remote MIB (RMIB)
6  * functionality of libsys.  RMIB allows services to mount and handle certain
7  * subtrees of the MIB service's sysctl tree.
8  */
9 
10 #include <sys/sysctl.h>
11 
12 /*
13  * The maximum number of I/O vector elements that can be passed to the
14  * rmib_vcopyout function.
15  */
16 #define RMIB_IOV_MAX	SCPVEC_NR
17 
18 /*
19  * This structure contains a number of less heavily used parameters for handler
20  * functions, mainly to provide extensibility while limiting argument clutter.
21  */
22 struct rmib_call {
23 	endpoint_t call_endpt;		/* endpoint of the user process */
24 	const int *call_name;		/* remaining part of the name */
25 	unsigned int call_namelen;	/* length of the remaining name part */
26 	unsigned int call_flags;	/* RMIB_FLAG_ call flags */
27 	uint32_t call_rootver;		/* version of all nodes in subtree */
28 	uint32_t call_treever;		/* version of the entire MIB tree */
29 };
30 
31 /*
32  * Call flags.
33  *
34  * TODO: this is effectively a flag used on the wire.  This should be turned
35  * into a proper definition shared with the MIB service.  As long as we have
36  * only one flag anyway, this is not exactly urgent though.
37  */
38 #define RMIB_FLAG_AUTH	0x1	/* user has superuser privileges */
39 
40 struct rmib_node;
41 struct rmib_oldp;
42 struct rmib_newp;
43 
44 typedef ssize_t (*rmib_func_ptr)(struct rmib_call *, struct rmib_node *,
45 	struct rmib_oldp *, struct rmib_newp *);
46 
47 /*
48  * The central structure for remote MIB nodes.  This is essentially a somewhat
49  * cut-down version of the node structure used within the MIB service.  See the
50  * source code of that service for several details that apply here as well.
51  * The 'rnode_' prefix makes it possible to include both this header file and
52  * the MIB service's internal header file at once--neat if useless.
53  */
54 struct rmib_node {
55 	uint32_t rnode_flags;		/* CTLTYPE_ type and CTLFLAG_ flags */
56 	size_t rnode_size;		/* size of associated data */
57 	union ixfer_rnode_val_u {
58 		bool rvu_bool;		/* immediate boolean */
59 		int rvu_int;		/* immediate integer */
60 		u_quad_t rvu_quad;	/* immediate quad */
61 		uint32_t rvu_clen;	/* number of actual children */
62 	} rnode_val_u;
63 	union pxfer_rnode_ptr_u {
64 		void *rpu_data;		/* struct or string data pointer */
65 		struct rmib_node *rpu_cptr;	/* child node array */
66 	} rnode_ptr_u;
67 	rmib_func_ptr rnode_func;	/* handler function */
68 	const char *rnode_name;		/* node name string */
69 	const char *rnode_desc;		/* node description (may be NULL) */
70 };
71 #define rnode_bool	rnode_val_u.rvu_bool
72 #define rnode_int	rnode_val_u.rvu_int
73 #define rnode_quad	rnode_val_u.rvu_quad
74 #define rnode_clen	rnode_val_u.rvu_clen
75 #define rnode_data	rnode_ptr_u.rpu_data
76 #define rnode_cptr	rnode_ptr_u.rpu_cptr
77 
78 /* Various macros to initialize nodes at compile time. */
79 #define RMIB_NODE(f,t,n,d) {						\
80 	.rnode_flags = CTLTYPE_NODE | CTLFLAG_READONLY |		\
81 	    CTLFLAG_PERMANENT | f,					\
82 	.rnode_size = __arraycount(t),					\
83 	.rnode_cptr = t,						\
84 	.rnode_name = n,						\
85 	.rnode_desc = d							\
86 }
87 #define RMIB_FUNC(f,s,fp,n,d) {						\
88 	.rnode_flags = CTLFLAG_PERMANENT | f,				\
89 	.rnode_size = s,						\
90 	.rnode_func = fp,						\
91 	.rnode_name = n,						\
92 	.rnode_desc = d							\
93 }
94 #define RMIB_BOOL(f,b,n,d) {						\
95 	.rnode_flags = CTLTYPE_BOOL | CTLFLAG_PERMANENT | 		\
96 	    CTLFLAG_IMMEDIATE | f,					\
97 	.rnode_size = sizeof(bool),					\
98 	.rnode_bool = b,						\
99 	.rnode_name = n,						\
100 	.rnode_desc = d							\
101 }
102 #define RMIB_INT(f,i,n,d) {						\
103 	.rnode_flags = CTLTYPE_INT | CTLFLAG_PERMANENT | 		\
104 	    CTLFLAG_IMMEDIATE | f,					\
105 	.rnode_size = sizeof(int),					\
106 	.rnode_int = i,							\
107 	.rnode_name = n,						\
108 	.rnode_desc = d							\
109 }
110 #define RMIB_QUAD(f,q,n,d) {						\
111 	.rnode_flags = CTLTYPE_QUAD | CTLFLAG_PERMANENT | 		\
112 	    CTLFLAG_IMMEDIATE | f,					\
113 	.rnode_size = sizeof(u_quad_t),					\
114 	.rnode_quad = q,						\
115 	.rnode_name = n,						\
116 	.rnode_desc = d							\
117 }
118 #define _RMIB_DATA(f,s,p,n,d) {						\
119 	.rnode_flags = CTLFLAG_PERMANENT | f,				\
120 	.rnode_size = s,						\
121 	.rnode_data = __UNCONST(p),					\
122 	.rnode_name = n,						\
123 	.rnode_desc = d							\
124 }
125 /*
126  * The following macros really require a pointer to the proper data type; weird
127  * casts may not trigger compiler warnings but do allow for memory corruption.
128  * The first three need to be passed a pointer to a bool, int, and u_quad_t,
129  * respectively.  RMIB_STRING needs a pointer to a character array, so that
130  * sizeof(array) yields the proper size.  Since RMIB_STRUCT may be given a
131  * pointer to either a structure or an array, it must also be given a size.
132  */
133 #define RMIB_BOOLPTR(f,p,n,d) _RMIB_DATA(CTLTYPE_BOOL | f, sizeof(*p), p, n, d)
134 #define RMIB_INTPTR(f,p,n,d)  _RMIB_DATA(CTLTYPE_INT | f, sizeof(*p), p, n, d)
135 #define RMIB_QUADPTR(f,p,n,d) _RMIB_DATA(CTLTYPE_QUAD | f, sizeof(*p), p, n, d)
136 #define RMIB_STRING(f,p,n,d)  \
137 	_RMIB_DATA(CTLTYPE_STRING | f, sizeof(p), p, n, d)
138 #define RMIB_STRUCT(f,s,p,n,d)  _RMIB_DATA(CTLTYPE_STRUCT | f, s, p, n, d)
139 
140 /* Shortcut flag macros. */
141 #define RMIB_RO	CTLFLAG_READONLY	/* shortcut for read-only nodes */
142 #define RMIB_RW	CTLFLAG_READWRITE	/* shortcut for read-write nodes */
143 
144 /* Function prototypes. */
145 int rmib_register(const int * name, unsigned int namelen, struct rmib_node *);
146 int rmib_deregister(struct rmib_node *);
147 void rmib_reset(void);
148 void rmib_process(const message *, int);
149 
150 int rmib_inrange(struct rmib_oldp *, size_t);
151 size_t rmib_getoldlen(struct rmib_oldp *);
152 ssize_t rmib_copyout(struct rmib_oldp *, size_t, const void * __restrict,
153 	size_t);
154 ssize_t rmib_vcopyout(struct rmib_oldp *, size_t, const iovec_t *,
155 	unsigned int);
156 int rmib_copyin(struct rmib_newp * __restrict, void * __restrict, size_t);
157 ssize_t rmib_readwrite(struct rmib_call *, struct rmib_node *,
158 	struct rmib_oldp *, struct rmib_newp *);
159 
160 #endif /* !_MINIX_RMIB_H */
161