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