1 /* 2 * Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <stdint.h> 18 19 #define AGENTX_PDU_FLAG_INSTANCE_REGISTRATION (1 << 0) 20 #define AGENTX_PDU_FLAG_NEW_INDEX (1 << 1) 21 #define AGENTX_PDU_FLAG_ANY_INDEX (1 << 2) 22 #define AGENTX_PDU_FLAG_NON_DEFAULT_CONTEXT (1 << 3) 23 #define AGENTX_PDU_FLAG_NETWORK_BYTE_ORDER (1 << 4) 24 25 #define AGENTX_PRIORITY_DEFAULT 127 26 27 enum agentx_byte_order { 28 AGENTX_BYTE_ORDER_BE, 29 AGENTX_BYTE_ORDER_LE 30 }; 31 32 #if BYTE_ORDER == BIG_ENDIAN 33 #define AGENTX_BYTE_ORDER_NATIVE AGENTX_BYTE_ORDER_BE 34 #else 35 #define AGENTX_BYTE_ORDER_NATIVE AGENTX_BYTE_ORDER_LE 36 #endif 37 38 enum agentx_pdu_type { 39 AGENTX_PDU_TYPE_OPEN = 1, 40 AGENTX_PDU_TYPE_CLOSE = 2, 41 AGENTX_PDU_TYPE_REGISTER = 3, 42 AGENTX_PDU_TYPE_UNREGISTER = 4, 43 AGENTX_PDU_TYPE_GET = 5, 44 AGENTX_PDU_TYPE_GETNEXT = 6, 45 AGENTX_PDU_TYPE_GETBULK = 7, 46 AGENTX_PDU_TYPE_TESTSET = 8, 47 AGENTX_PDU_TYPE_COMMITSET = 9, 48 AGENTX_PDU_TYPE_UNDOSET = 10, 49 AGENTX_PDU_TYPE_CLEANUPSET = 11, 50 AGENTX_PDU_TYPE_NOTIFY = 12, 51 AGENTX_PDU_TYPE_PING = 13, 52 AGENTX_PDU_TYPE_INDEXALLOCATE = 14, 53 AGENTX_PDU_TYPE_INDEXDEALLOCATE = 15, 54 AGENTX_PDU_TYPE_ADDAGENTCAPS = 16, 55 AGENTX_PDU_TYPE_REMOVEAGENTCAPS = 17, 56 AGENTX_PDU_TYPE_RESPONSE = 18 57 }; 58 59 enum agentx_pdu_error { 60 AGENTX_PDU_ERROR_NOERROR = 0, 61 AGENTX_PDU_ERROR_GENERR = 5, 62 AGENTX_PDU_ERROR_NOACCESS = 6, 63 AGENTX_PDU_ERROR_WRONGTYPE = 7, 64 AGENTX_PDU_ERROR_WRONGLENGTH = 8, 65 AGENTX_PDU_ERROR_WRONGENCODING = 9, 66 AGENTX_PDU_ERROR_WRONGVALUE = 10, 67 AGENTX_PDU_ERROR_NOCREATION = 11, 68 AGENTX_PDU_ERROR_INCONSISTENTVALUE = 12, 69 AGENTX_PDU_ERROR_RESOURCEUNAVAILABLE = 13, 70 AGENTX_PDU_ERROR_COMMITFAILED = 14, 71 AGENTX_PDU_ERROR_UNDOFAILED = 15, 72 AGENTX_PDU_ERROR_NOTWRITABLE = 17, 73 AGENTX_PDU_ERROR_INCONSISTENTNAME = 18, 74 AGENTX_PDU_ERROR_OPENFAILED = 256, 75 AGENTX_PDU_ERROR_NOTOPEN = 257, 76 AGENTX_PDU_ERROR_INDEXWRONGTYPE = 258, 77 AGENTX_PDU_ERROR_INDEXALREADYALLOCATED = 259, 78 AGENTX_PDU_ERROR_INDEXNONEAVAILABLE = 260, 79 AGENTX_PDU_ERROR_INDEXNOTALLOCATED = 261, 80 AGENTX_PDU_ERROR_UNSUPPORTEDCONETXT = 262, 81 AGENTX_PDU_ERROR_DUPLICATEREGISTRATION = 263, 82 AGENTX_PDU_ERROR_UNKNOWNREGISTRATION = 264, 83 AGENTX_PDU_ERROR_UNKNOWNAGENTCAPS = 265, 84 AGENTX_PDU_ERROR_PARSEERROR = 266, 85 AGENTX_PDU_ERROR_REQUESTDENIED = 267, 86 AGENTX_PDU_ERROR_PROCESSINGERROR = 268 87 }; 88 89 enum agentx_data_type { 90 AGENTX_DATA_TYPE_INTEGER = 2, 91 AGENTX_DATA_TYPE_OCTETSTRING = 4, 92 AGENTX_DATA_TYPE_NULL = 5, 93 AGENTX_DATA_TYPE_OID = 6, 94 AGENTX_DATA_TYPE_IPADDRESS = 64, 95 AGENTX_DATA_TYPE_COUNTER32 = 65, 96 AGENTX_DATA_TYPE_GAUGE32 = 66, 97 AGENTX_DATA_TYPE_TIMETICKS = 67, 98 AGENTX_DATA_TYPE_OPAQUE = 68, 99 AGENTX_DATA_TYPE_COUNTER64 = 70, 100 AGENTX_DATA_TYPE_NOSUCHOBJECT = 128, 101 AGENTX_DATA_TYPE_NOSUCHINSTANCE = 129, 102 AGENTX_DATA_TYPE_ENDOFMIBVIEW = 130 103 }; 104 105 enum agentx_close_reason { 106 AGENTX_CLOSE_OTHER = 1, 107 AGENTX_CLOSEN_PARSEERROR = 2, 108 AGENTX_CLOSE_PROTOCOLERROR = 3, 109 AGENTX_CLOSE_TIMEOUTS = 4, 110 AGENTX_CLOSE_SHUTDOWN = 5, 111 AGENTX_CLOSE_BYMANAGER = 6 112 }; 113 114 struct agentx { 115 int ax_fd; 116 enum agentx_byte_order ax_byteorder; 117 uint8_t *ax_rbuf; 118 size_t ax_rblen; 119 size_t ax_rbsize; 120 uint8_t *ax_wbuf; 121 size_t ax_wblen; 122 size_t ax_wbtlen; 123 size_t ax_wbsize; 124 uint32_t *ax_packetids; 125 size_t ax_packetidsize; 126 }; 127 128 #ifndef AGENTX_PRIMITIVE 129 #define AGENTX_PRIMITIVE 130 131 #define AGENTX_OID_MAX_LEN 128 132 133 struct agentx_oid { 134 uint8_t aoi_include; 135 uint32_t aoi_id[AGENTX_OID_MAX_LEN]; 136 size_t aoi_idlen; 137 }; 138 139 struct agentx_ostring { 140 unsigned char *aos_string; 141 uint32_t aos_slen; 142 }; 143 #endif 144 145 struct agentx_searchrange { 146 struct agentx_oid asr_start; 147 struct agentx_oid asr_stop; 148 }; 149 150 struct agentx_pdu_header { 151 uint8_t aph_version; 152 uint8_t aph_type; 153 uint8_t aph_flags; 154 uint8_t aph_reserved; 155 uint32_t aph_sessionid; 156 uint32_t aph_transactionid; 157 uint32_t aph_packetid; 158 uint32_t aph_plength; 159 }; 160 161 struct agentx_varbind { 162 enum agentx_data_type avb_type; 163 struct agentx_oid avb_oid; 164 union agentx_data { 165 uint32_t avb_uint32; 166 uint64_t avb_uint64; 167 struct agentx_ostring avb_ostring; 168 struct agentx_oid avb_oid; 169 } avb_data; 170 }; 171 172 struct agentx_pdu { 173 struct agentx_pdu_header ap_header; 174 struct agentx_ostring ap_context; 175 union { 176 struct agentx_pdu_searchrangelist { 177 size_t ap_nsr; 178 struct agentx_searchrange *ap_sr; 179 } ap_srl; 180 struct agentx_pdu_getbulk { 181 uint16_t ap_nonrep; 182 uint16_t ap_maxrep; 183 struct agentx_pdu_searchrangelist ap_srl; 184 } ap_getbulk; 185 struct agentx_pdu_varbindlist { 186 struct agentx_varbind *ap_varbind; 187 size_t ap_nvarbind; 188 } ap_vbl; 189 struct agentx_pdu_response { 190 uint32_t ap_uptime; 191 enum agentx_pdu_error ap_error; 192 uint16_t ap_index; 193 struct agentx_varbind *ap_varbindlist; 194 size_t ap_nvarbind; 195 } ap_response; 196 void *ap_raw; 197 } ap_payload; 198 }; 199 200 struct agentx *agentx_new(int); 201 void agentx_free(struct agentx *); 202 struct agentx_pdu *agentx_recv(struct agentx *); 203 ssize_t agentx_send(struct agentx *); 204 uint32_t agentx_open(struct agentx *, uint8_t, struct agentx_oid *, 205 struct agentx_ostring *); 206 uint32_t agentx_close(struct agentx *, uint32_t, enum agentx_close_reason); 207 uint32_t agentx_indexallocate(struct agentx *, uint8_t, uint32_t, 208 struct agentx_ostring *, struct agentx_varbind *, size_t); 209 uint32_t agentx_indexdeallocate(struct agentx *, uint32_t, 210 struct agentx_ostring *, struct agentx_varbind *, size_t); 211 uint32_t agentx_addagentcaps(struct agentx *, uint32_t, struct agentx_ostring *, 212 struct agentx_oid *, struct agentx_ostring *); 213 uint32_t agentx_removeagentcaps(struct agentx *, uint32_t, 214 struct agentx_ostring *, struct agentx_oid *); 215 uint32_t agentx_register(struct agentx *, uint8_t, uint32_t, 216 struct agentx_ostring *, uint8_t, uint8_t, uint8_t, struct agentx_oid *, 217 uint32_t); 218 uint32_t agentx_unregister(struct agentx *, uint32_t, struct agentx_ostring *, 219 uint8_t, uint8_t, struct agentx_oid *, uint32_t); 220 int agentx_response(struct agentx *, uint32_t, uint32_t, uint32_t, 221 struct agentx_ostring *, uint32_t, uint16_t, uint16_t, 222 struct agentx_varbind *, size_t); 223 void agentx_pdu_free(struct agentx_pdu *); 224 void agentx_varbind_free(struct agentx_varbind *); 225 const char *agentx_error2string(enum agentx_pdu_error); 226 const char *agentx_pdutype2string(enum agentx_pdu_type); 227 const char *agentx_oid2string(struct agentx_oid *); 228 const char *agentx_oidrange2string(struct agentx_oid *, uint8_t, uint32_t); 229 const char *agentx_varbind2string(struct agentx_varbind *); 230 const char *agentx_closereason2string(enum agentx_close_reason); 231 int agentx_oid_cmp(struct agentx_oid *, struct agentx_oid *); 232 int agentx_oid_add(struct agentx_oid *, uint32_t); 233