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