xref: /openbsd/usr.sbin/snmpd/ax.h (revision 3bef86f7)
1 /*	$OpenBSD: ax.h,v 1.3 2023/12/21 12:43:31 martijn Exp $ */
2 /*
3  * Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/types.h>
19 
20 #include <endian.h>
21 #include <stdint.h>
22 
23 #define AX_PDU_FLAG_INSTANCE_REGISTRATION (1 << 0)
24 #define AX_PDU_FLAG_NEW_INDEX (1 << 1)
25 #define AX_PDU_FLAG_ANY_INDEX (1 << 2)
26 #define AX_PDU_FLAG_NON_DEFAULT_CONTEXT (1 << 3)
27 #define AX_PDU_FLAG_NETWORK_BYTE_ORDER (1 << 4)
28 
29 #define AX_PRIORITY_DEFAULT 127
30 
31 enum ax_byte_order {
32 	AX_BYTE_ORDER_BE,
33 	AX_BYTE_ORDER_LE
34 };
35 
36 #if BYTE_ORDER == BIG_ENDIAN
37 #define AX_BYTE_ORDER_NATIVE AX_BYTE_ORDER_BE
38 #else
39 #define AX_BYTE_ORDER_NATIVE AX_BYTE_ORDER_LE
40 #endif
41 
42 enum ax_pdu_type {
43 	AX_PDU_TYPE_OPEN		= 1,
44 	AX_PDU_TYPE_CLOSE		= 2,
45 	AX_PDU_TYPE_REGISTER		= 3,
46 	AX_PDU_TYPE_UNREGISTER		= 4,
47 	AX_PDU_TYPE_GET			= 5,
48 	AX_PDU_TYPE_GETNEXT		= 6,
49 	AX_PDU_TYPE_GETBULK		= 7,
50 	AX_PDU_TYPE_TESTSET		= 8,
51 	AX_PDU_TYPE_COMMITSET		= 9,
52 	AX_PDU_TYPE_UNDOSET		= 10,
53 	AX_PDU_TYPE_CLEANUPSET		= 11,
54 	AX_PDU_TYPE_NOTIFY		= 12,
55 	AX_PDU_TYPE_PING		= 13,
56 	AX_PDU_TYPE_INDEXALLOCATE	= 14,
57 	AX_PDU_TYPE_INDEXDEALLOCATE	= 15,
58 	AX_PDU_TYPE_ADDAGENTCAPS	= 16,
59 	AX_PDU_TYPE_REMOVEAGENTCAPS	= 17,
60 	AX_PDU_TYPE_RESPONSE		= 18
61 };
62 
63 enum ax_pdu_error {
64 	AX_PDU_ERROR_NOERROR			= 0,
65 	AX_PDU_ERROR_GENERR			= 5,
66 	AX_PDU_ERROR_NOACCESS			= 6,
67 	AX_PDU_ERROR_WRONGTYPE			= 7,
68 	AX_PDU_ERROR_WRONGLENGTH		= 8,
69 	AX_PDU_ERROR_WRONGENCODING		= 9,
70 	AX_PDU_ERROR_WRONGVALUE			= 10,
71 	AX_PDU_ERROR_NOCREATION			= 11,
72 	AX_PDU_ERROR_INCONSISTENTVALUE		= 12,
73 	AX_PDU_ERROR_RESOURCEUNAVAILABLE	= 13,
74 	AX_PDU_ERROR_COMMITFAILED		= 14,
75 	AX_PDU_ERROR_UNDOFAILED			= 15,
76 	AX_PDU_ERROR_NOTWRITABLE		= 17,
77 	AX_PDU_ERROR_INCONSISTENTNAME		= 18,
78 	AX_PDU_ERROR_OPENFAILED			= 256,
79 	AX_PDU_ERROR_NOTOPEN			= 257,
80 	AX_PDU_ERROR_INDEXWRONGTYPE		= 258,
81 	AX_PDU_ERROR_INDEXALREADYALLOCATED	= 259,
82 	AX_PDU_ERROR_INDEXNONEAVAILABLE		= 260,
83 	AX_PDU_ERROR_INDEXNOTALLOCATED		= 261,
84 	AX_PDU_ERROR_UNSUPPORTEDCONETXT		= 262,
85 	AX_PDU_ERROR_DUPLICATEREGISTRATION	= 263,
86 	AX_PDU_ERROR_UNKNOWNREGISTRATION	= 264,
87 	AX_PDU_ERROR_UNKNOWNAGENTCAPS		= 265,
88 	AX_PDU_ERROR_PARSEERROR			= 266,
89 	AX_PDU_ERROR_REQUESTDENIED		= 267,
90 	AX_PDU_ERROR_PROCESSINGERROR		= 268
91 };
92 
93 enum ax_data_type {
94 	AX_DATA_TYPE_INTEGER		= 2,
95 	AX_DATA_TYPE_OCTETSTRING	= 4,
96 	AX_DATA_TYPE_NULL		= 5,
97 	AX_DATA_TYPE_OID		= 6,
98 	AX_DATA_TYPE_IPADDRESS		= 64,
99 	AX_DATA_TYPE_COUNTER32		= 65,
100 	AX_DATA_TYPE_GAUGE32		= 66,
101 	AX_DATA_TYPE_TIMETICKS		= 67,
102 	AX_DATA_TYPE_OPAQUE		= 68,
103 	AX_DATA_TYPE_COUNTER64		= 70,
104 	AX_DATA_TYPE_NOSUCHOBJECT	= 128,
105 	AX_DATA_TYPE_NOSUCHINSTANCE	= 129,
106 	AX_DATA_TYPE_ENDOFMIBVIEW	= 130
107 };
108 
109 enum ax_close_reason {
110 	AX_CLOSE_OTHER			= 1,
111 	AX_CLOSEN_PARSEERROR		= 2,
112 	AX_CLOSE_PROTOCOLERROR		= 3,
113 	AX_CLOSE_TIMEOUTS		= 4,
114 	AX_CLOSE_SHUTDOWN		= 5,
115 	AX_CLOSE_BYMANAGER		= 6
116 };
117 
118 struct ax {
119 	int ax_fd;
120 	enum ax_byte_order ax_byteorder;
121 	uint8_t *ax_rbuf;
122 	size_t ax_rblen;
123 	size_t ax_rbsize;
124 	uint8_t *ax_wbuf;
125 	size_t ax_wblen;
126 	size_t ax_wbtlen;
127 	size_t ax_wbsize;
128 	uint32_t *ax_packetids;
129 	size_t ax_packetidsize;
130 };
131 
132 #ifndef AX_PRIMITIVE
133 #define AX_PRIMITIVE
134 
135 #define AX_OID_MAX_LEN 128
136 
137 struct ax_oid {
138 	uint8_t aoi_include;
139 	uint32_t aoi_id[AX_OID_MAX_LEN];
140 	size_t aoi_idlen;
141 };
142 
143 struct ax_ostring {
144 	unsigned char *aos_string;
145 	uint32_t aos_slen;
146 };
147 #endif
148 
149 struct ax_searchrange {
150 	struct ax_oid asr_start;
151 	struct ax_oid asr_stop;
152 };
153 
154 struct ax_pdu_header {
155 	uint8_t	aph_version;
156 	uint8_t	aph_type;
157 	uint8_t	aph_flags;
158 	uint8_t	aph_reserved;
159 	uint32_t aph_sessionid;
160 	uint32_t aph_transactionid;
161 	uint32_t aph_packetid;
162 	uint32_t aph_plength;
163 };
164 
165 struct ax_varbind {
166 	enum ax_data_type avb_type;
167 	struct ax_oid avb_oid;
168 	union ax_data {
169 		int32_t avb_int32;
170 		uint32_t avb_uint32;
171 		uint64_t avb_uint64;
172 		struct ax_ostring avb_ostring;
173 		struct ax_oid avb_oid;
174 	} avb_data;
175 };
176 
177 struct ax_pdu {
178 	struct ax_pdu_header ap_header;
179 	struct ax_ostring ap_context;
180 	union {
181 		struct ax_pdu_open {
182 			uint8_t ap_timeout;
183 			struct ax_oid ap_oid;
184 			struct ax_ostring ap_descr;
185 		} ap_open;
186 		struct ax_pdu_close {
187 			enum ax_close_reason ap_reason;
188 		} ap_close;
189 		struct ax_pdu_register {
190 			uint8_t ap_timeout;
191 			uint8_t ap_priority;
192 			uint8_t ap_range_subid;
193 			struct ax_oid ap_subtree;
194 			uint32_t ap_upper_bound;
195 		} ap_register;
196 		struct ax_pdu_unregister {
197 			uint8_t ap_priority;
198 			uint8_t ap_range_subid;
199 			struct ax_oid ap_subtree;
200 			uint32_t ap_upper_bound;
201 		} ap_unregister;
202 		struct ax_pdu_searchrangelist {
203 			size_t ap_nsr;
204 			struct ax_searchrange *ap_sr;
205 		} ap_srl;
206 		struct ax_pdu_getbulk {
207 			uint16_t ap_nonrep;
208 			uint16_t ap_maxrep;
209 			struct ax_pdu_searchrangelist ap_srl;
210 		} ap_getbulk;
211 		struct ax_pdu_varbindlist {
212 			struct ax_varbind *ap_varbind;
213 			size_t ap_nvarbind;
214 		} ap_vbl;
215 		struct ax_pdu_addagentcaps {
216 			struct ax_oid ap_oid;
217 			struct ax_ostring ap_descr;
218 		} ap_addagentcaps;
219 		struct ax_pdu_removeagentcaps {
220 			struct ax_oid ap_oid;
221 		} ap_removeagentcaps;
222 		struct ax_pdu_response {
223 			uint32_t ap_uptime;
224 			enum ax_pdu_error ap_error;
225 			uint16_t ap_index;
226 			struct ax_varbind *ap_varbindlist;
227 			size_t ap_nvarbind;
228 		} ap_response;
229 	} ap_payload;
230 };
231 
232 struct ax *ax_new(int);
233 void ax_free(struct ax *);
234 struct ax_pdu *ax_recv(struct ax *);
235 ssize_t ax_send(struct ax *);
236 uint32_t ax_open(struct ax *, uint8_t, struct ax_oid *,
237     struct ax_ostring *);
238 uint32_t ax_close(struct ax *, uint32_t, enum ax_close_reason);
239 int ax_get(struct ax *, uint32_t, uint32_t, uint32_t, struct ax_ostring *,
240     struct ax_searchrange *, size_t);
241 int ax_getnext(struct ax *, uint32_t, uint32_t, uint32_t, struct ax_ostring *,
242     struct ax_searchrange *, size_t);
243 uint32_t ax_indexallocate(struct ax *, uint8_t, uint32_t,
244     struct ax_ostring *, struct ax_varbind *, size_t);
245 uint32_t ax_indexdeallocate(struct ax *, uint32_t,
246     struct ax_ostring *, struct ax_varbind *, size_t);
247 uint32_t ax_addagentcaps(struct ax *, uint32_t, struct ax_ostring *,
248     struct ax_oid *, struct ax_ostring *);
249 uint32_t ax_removeagentcaps(struct ax *, uint32_t,
250     struct ax_ostring *, struct ax_oid *);
251 uint32_t ax_register(struct ax *, uint8_t, uint32_t,
252     struct ax_ostring *, uint8_t, uint8_t, uint8_t, struct ax_oid *,
253     uint32_t);
254 uint32_t ax_unregister(struct ax *, uint32_t, struct ax_ostring *,
255     uint8_t, uint8_t, struct ax_oid *, uint32_t);
256 int ax_response(struct ax *, uint32_t, uint32_t, uint32_t,
257     uint32_t, uint16_t, uint16_t, struct ax_varbind *, size_t);
258 void ax_pdu_free(struct ax_pdu *);
259 void ax_varbind_free(struct ax_varbind *);
260 const char *ax_error2string(enum ax_pdu_error);
261 const char *ax_pdutype2string(enum ax_pdu_type);
262 const char *ax_oid2string(struct ax_oid *);
263 const char *ax_oidrange2string(struct ax_oid *, uint8_t, uint32_t);
264 const char *ax_varbind2string(struct ax_varbind *);
265 const char *ax_closereason2string(enum ax_close_reason);
266 int ax_oid_cmp(struct ax_oid *, struct ax_oid *);
267 int ax_oid_add(struct ax_oid *, uint32_t);
268