xref: /minix3/minix/include/minix/rmib.h (revision 0f03189a6a8bafe2a370ea990cf2cbb19da81b70)
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_oname;		/* original full name of the request */
25 	const int *call_name;		/* remaining part of the name */
26 	unsigned int call_namelen;	/* length of the remaining name part */
27 	unsigned int call_flags;	/* RMIB_FLAG_ call flags */
28 	uint32_t call_rootver;		/* version of all nodes in subtree */
29 	uint32_t call_treever;		/* version of the entire MIB tree */
30 };
31 
32 /*
33  * Call flags.
34  *
35  * TODO: this is effectively a flag used on the wire.  This should be turned
36  * into a proper definition shared with the MIB service.  As long as we have
37  * only one flag anyway, this is not exactly urgent though.
38  */
39 #define RMIB_FLAG_AUTH	0x1	/* user has superuser privileges */
40 
41 struct rmib_node;
42 struct rmib_oldp;
43 struct rmib_newp;
44 
45 typedef ssize_t (*rmib_func_ptr)(struct rmib_call *, struct rmib_node *,
46 	struct rmib_oldp *, struct rmib_newp *);
47 
48 /*
49  * Indirect node, used for sparse nodes.  Sparse nodes are node-type nodes with
50  * the CTLFLAG_SPARSE flag set.  A sparse node points not to an array of child
51  * nodes (using rnode_cptr), but to a array of {id,child pointer} elements
52  * (using rnode_icptr).  At the cost of O(n) lookups, sparse nodes save memory.
53  * Currently for presentation reasons only, indirect lists must be sorted
54  * ascending by node identifiers. They may also not have ID duplicates, may not
55  * have NULL node pointers, and may not point to nodes with zero flags fields.
56  */
57 #define CTLFLAG_SPARSE	CTLFLAG_ROOT	/* overloaded NetBSD flag */
58 
59 struct rmib_indir {
60 	unsigned int rindir_id;		/* node identifier */
61 	struct rmib_node *rindir_node;	/* pointer to actual node */
62 };
63 
64 /*
65  * The central structure for remote MIB nodes.  This is essentially a somewhat
66  * cut-down version of the node structure used within the MIB service.  See the
67  * source code of that service for several details that apply here as well.
68  * The 'rnode_' prefix makes it possible to include both this header file and
69  * the MIB service's internal header file at once--neat if useless.
70  */
71 struct rmib_node {
72 	uint32_t rnode_flags;		/* CTLTYPE_ type and CTLFLAG_ flags */
73 	size_t rnode_size;		/* size of associated data */
74 	union ixfer_rnode_val_u {
75 		bool rvu_bool;		/* immediate boolean */
76 		int rvu_int;		/* immediate integer */
77 		u_quad_t rvu_quad;	/* immediate quad */
78 		uint32_t rvu_clen;	/* number of actual children */
79 	} rnode_val_u;
80 	union pxfer_rnode_ptr_u {
81 		void *rpu_data;		/* struct or string data pointer */
82 		struct rmib_node *rpu_cptr;	/* child node array */
83 		struct rmib_indir *rpu_icptr;	/* indirect child node array */
84 	} rnode_ptr_u;
85 	rmib_func_ptr rnode_func;	/* handler function */
86 	const char *rnode_name;		/* node name string */
87 	const char *rnode_desc;		/* node description (may be NULL) */
88 };
89 #define rnode_bool	rnode_val_u.rvu_bool
90 #define rnode_int	rnode_val_u.rvu_int
91 #define rnode_quad	rnode_val_u.rvu_quad
92 #define rnode_clen	rnode_val_u.rvu_clen
93 #define rnode_data	rnode_ptr_u.rpu_data
94 #define rnode_cptr	rnode_ptr_u.rpu_cptr
95 #define rnode_icptr	rnode_ptr_u.rpu_icptr
96 
97 /* Various macros to initialize nodes at compile time. */
98 #define RMIB_NODE(f,t,n,d) {						\
99 	.rnode_flags = CTLTYPE_NODE | CTLFLAG_READONLY |		\
100 	    CTLFLAG_PERMANENT | f,					\
101 	.rnode_size = __arraycount(t),					\
102 	.rnode_cptr = t,						\
103 	.rnode_name = n,						\
104 	.rnode_desc = d							\
105 }
106 #define RMIB_SNODE(f,t,n,d) {						\
107 	.rnode_flags = CTLTYPE_NODE | CTLFLAG_READONLY |		\
108 	    CTLFLAG_PERMANENT | CTLFLAG_SPARSE | f,			\
109 	.rnode_size = 0,						\
110 	.rnode_icptr = t,						\
111 	.rnode_name = n,						\
112 	.rnode_desc = d							\
113 }
114 #define RMIB_FUNC(f,s,fp,n,d) {						\
115 	.rnode_flags = CTLFLAG_PERMANENT | f,				\
116 	.rnode_size = s,						\
117 	.rnode_func = fp,						\
118 	.rnode_name = n,						\
119 	.rnode_desc = d							\
120 }
121 #define RMIB_BOOL(f,b,n,d) {						\
122 	.rnode_flags = CTLTYPE_BOOL | CTLFLAG_PERMANENT | 		\
123 	    CTLFLAG_IMMEDIATE | f,					\
124 	.rnode_size = sizeof(bool),					\
125 	.rnode_bool = b,						\
126 	.rnode_name = n,						\
127 	.rnode_desc = d							\
128 }
129 #define RMIB_INT(f,i,n,d) {						\
130 	.rnode_flags = CTLTYPE_INT | CTLFLAG_PERMANENT | 		\
131 	    CTLFLAG_IMMEDIATE | f,					\
132 	.rnode_size = sizeof(int),					\
133 	.rnode_int = i,							\
134 	.rnode_name = n,						\
135 	.rnode_desc = d							\
136 }
137 #define RMIB_QUAD(f,q,n,d) {						\
138 	.rnode_flags = CTLTYPE_QUAD | CTLFLAG_PERMANENT | 		\
139 	    CTLFLAG_IMMEDIATE | f,					\
140 	.rnode_size = sizeof(u_quad_t),					\
141 	.rnode_quad = q,						\
142 	.rnode_name = n,						\
143 	.rnode_desc = d							\
144 }
145 #define _RMIB_DATA(f,s,p,n,d) {						\
146 	.rnode_flags = CTLFLAG_PERMANENT | f,				\
147 	.rnode_size = s,						\
148 	.rnode_data = __UNCONST(p),					\
149 	.rnode_name = n,						\
150 	.rnode_desc = d							\
151 }
152 /*
153  * The following macros really require a pointer to the proper data type; weird
154  * casts may not trigger compiler warnings but do allow for memory corruption.
155  * The first three need to be passed a pointer to a bool, int, and u_quad_t,
156  * respectively.  RMIB_STRING needs a pointer to a character array, so that
157  * sizeof(array) yields the proper size.  Since RMIB_STRUCT may be given a
158  * pointer to either a structure or an array, it must also be given a size.
159  */
160 #define RMIB_BOOLPTR(f,p,n,d) _RMIB_DATA(CTLTYPE_BOOL | f, sizeof(*p), p, n, d)
161 #define RMIB_INTPTR(f,p,n,d)  _RMIB_DATA(CTLTYPE_INT | f, sizeof(*p), p, n, d)
162 #define RMIB_QUADPTR(f,p,n,d) _RMIB_DATA(CTLTYPE_QUAD | f, sizeof(*p), p, n, d)
163 #define RMIB_STRING(f,p,n,d)  \
164 	_RMIB_DATA(CTLTYPE_STRING | f, sizeof(p), p, n, d)
165 #define RMIB_STRUCT(f,s,p,n,d)  _RMIB_DATA(CTLTYPE_STRUCT | f, s, p, n, d)
166 
167 /* Shortcut flag macros. */
168 #define RMIB_RO	CTLFLAG_READONLY	/* shortcut for read-only nodes */
169 #define RMIB_RW	CTLFLAG_READWRITE	/* shortcut for read-write nodes */
170 
171 /* Function prototypes. */
172 int rmib_register(const int * name, unsigned int namelen, struct rmib_node *);
173 int rmib_deregister(struct rmib_node *);
174 void rmib_reregister(void);
175 void rmib_reset(void);
176 void rmib_process(const message *, int);
177 
178 int rmib_inrange(struct rmib_oldp *, size_t);
179 size_t rmib_getoldlen(struct rmib_oldp *);
180 ssize_t rmib_copyout(struct rmib_oldp *, size_t, const void * __restrict,
181 	size_t);
182 ssize_t rmib_vcopyout(struct rmib_oldp *, size_t, const iovec_t *,
183 	unsigned int);
184 int rmib_copyin(struct rmib_newp * __restrict, void * __restrict, size_t);
185 ssize_t rmib_readwrite(struct rmib_call *, struct rmib_node *,
186 	struct rmib_oldp *, struct rmib_newp *);
187 
188 #endif /* !_MINIX_RMIB_H */
189