1 /* $OpenBSD: snmp.h,v 1.11 2014/04/14 12:55:10 blambert Exp $ */ 2 3 /* 4 * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #ifndef SNMP_HEADER 20 #define SNMP_HEADER 21 22 #include <sys/types.h> 23 #include <machine/endian.h> 24 25 /* 26 * SNMP IMSG interface 27 */ 28 29 #define SNMP_MAX_OID_STRLEN 128 /* max size of the OID _string_ */ 30 #define SNMP_SOCKET "/var/run/snmpd.sock" 31 #define AGENTX_SOCKET "/var/run/agentx.sock" 32 #define SNMP_RESTRICTED_SOCKET "/var/run/snmpd.rsock" 33 34 enum snmp_type { 35 SNMP_IPADDR = 0, 36 SNMP_COUNTER32 = 1, 37 SNMP_GAUGE32 = 2, 38 SNMP_UNSIGNED32 = 2, 39 SNMP_TIMETICKS = 3, 40 SNMP_OPAQUE = 4, 41 SNMP_NSAPADDR = 5, 42 SNMP_COUNTER64 = 6, 43 SNMP_UINTEGER32 = 7, 44 45 SNMP_INTEGER32 = 100, 46 SNMP_BITSTRING = 101, 47 SNMP_OCTETSTRING = 102, 48 SNMP_NULL = 103, 49 SNMP_OBJECT = 104 50 }; 51 52 enum snmp_imsg_ctl { 53 IMSG_SNMP_DUMMY = 1000, /* something that works everywhere */ 54 IMSG_SNMP_ELEMENT, 55 IMSG_SNMP_END, 56 IMSG_SNMP_LOCK, /* enable restricted mode */ 57 IMSG_SNMP_AGENTX 58 }; 59 60 struct snmp_imsg_hdr { 61 u_int32_t imsg_type; 62 u_int16_t imsg_len; 63 u_int16_t imsg_flags; 64 u_int32_t imsg_peerid; 65 u_int32_t imsg_pid; 66 }; 67 68 struct snmp_imsg { 69 char snmp_oid[SNMP_MAX_OID_STRLEN]; 70 u_int8_t snmp_type; 71 u_int16_t snmp_len; 72 }; 73 74 /* 75 * SNMP BER types 76 */ 77 78 enum snmp_version { 79 SNMP_V1 = 0, 80 SNMP_V2 = 1, /* SNMPv2c */ 81 SNMP_V3 = 3 82 }; 83 84 enum snmp_context { 85 SNMP_C_GETREQ = 0, 86 SNMP_C_GETNEXTREQ = 1, 87 SNMP_C_GETRESP = 2, 88 SNMP_C_SETREQ = 3, 89 SNMP_C_TRAP = 4, 90 91 /* SNMPv2 */ 92 SNMP_C_GETBULKREQ = 5, 93 SNMP_C_INFORMREQ = 6, 94 SNMP_C_TRAPV2 = 7, 95 SNMP_C_REPORT = 8 96 }; 97 98 enum snmp_application { 99 SNMP_T_IPADDR = 0, 100 SNMP_T_COUNTER32 = 1, 101 SNMP_T_GAUGE32 = 2, 102 SNMP_T_UNSIGNED32 = 2, 103 SNMP_T_TIMETICKS = 3, 104 SNMP_T_OPAQUE = 4, 105 SNMP_T_NSAPADDR = 5, 106 SNMP_T_COUNTER64 = 6, 107 SNMP_T_UINTEGER32 = 7 108 }; 109 110 enum snmp_generic_trap { 111 SNMP_TRAP_COLDSTART = 0, 112 SNMP_TRAP_WARMSTART = 1, 113 SNMP_TRAP_LINKDOWN = 2, 114 SNMP_TRAP_LINKUP = 3, 115 SNMP_TRAP_AUTHFAILURE = 4, 116 SNMP_TRAP_EGPNEIGHLOSS = 5, 117 SNMP_TRAP_ENTERPRISE = 6 118 }; 119 120 enum snmp_error { 121 SNMP_ERROR_NONE = 0, 122 SNMP_ERROR_TOOBIG = 1, 123 SNMP_ERROR_NOSUCHNAME = 2, 124 SNMP_ERROR_BADVALUE = 3, 125 SNMP_ERROR_READONLY = 4, 126 SNMP_ERROR_GENERR = 5, 127 128 /* SNMPv2 */ 129 SNMP_ERROR_NOACCESS = 6, 130 SNMP_ERROR_WRONGTYPE = 7, 131 SNMP_ERROR_WRONGLENGTH = 8, 132 SNMP_ERROR_WRONGENC = 9, 133 SNMP_ERROR_WRONGVALUE = 10, 134 SNMP_ERROR_NOCREATION = 11, 135 SNMP_ERROR_INCONVALUE = 12, 136 SNMP_ERROR_RESUNAVAIL = 13, /* EGAIN */ 137 SNMP_ERROR_COMMITFAILED = 14, 138 SNMP_ERROR_UNDOFAILED = 15, 139 SNMP_ERROR_AUTHERROR = 16, 140 SNMP_ERROR_NOTWRITABLE = 17, 141 SNMP_ERROR_INCONNAME = 18 142 }; 143 144 enum snmp_security_model { 145 SNMP_SEC_ANY = 0, 146 SNMP_SEC_SNMPv1 = 1, 147 SNMP_SEC_SNMPv2c = 2, 148 SNMP_SEC_USM = 3, 149 SNMP_SEC_TSM = 4 150 }; 151 152 #define SNMP_MSGFLAG_AUTH 0x01 153 #define SNMP_MSGFLAG_PRIV 0x02 154 #define SNMP_MSGFLAG_SECMASK (SNMP_MSGFLAG_AUTH | SNMP_MSGFLAG_PRIV) 155 #define SNMP_MSGFLAG_REPORT 0x04 156 157 #define SNMP_MAX_TIMEWINDOW 150 /* RFC3414 */ 158 159 #define SNMP_MIN_OID_LEN 2 /* OBJECT */ 160 #define SNMP_MAX_OID_LEN 32 /* OBJECT */ 161 162 struct snmp_oid { 163 u_int32_t o_id[SNMP_MAX_OID_LEN + 1]; 164 size_t o_n; 165 }; 166 167 /* AgentX protocol, as outlined in RFC 2741 */ 168 169 /* version */ 170 #define AGENTX_VERSION 1 171 172 /* type */ 173 #define AGENTX_OPEN 1 174 #define AGENTX_CLOSE 2 175 #define AGENTX_REGISTER 3 176 #define AGENTX_UNREGISTER 4 177 #define AGENTX_GET 5 178 #define AGENTX_GET_NEXT 6 179 #define AGENTX_GET_BULK 7 180 #define AGENTX_TEST_SET 8 181 #define AGENTX_COMMIT_SET 9 182 #define AGENTX_UNDO_SET 10 183 #define AGENTX_CLEANUP_SET 11 184 #define AGENTX_NOTIFY 12 185 #define AGENTX_PING 13 186 #define AGENTX_INDEX_ALLOCATE 14 187 #define AGENTX_INDEX_DEALLOCATE 15 188 #define AGENTX_ADD_AGENT_CAPS 16 189 #define AGENTX_REMOVE_AGENT_CAPS 17 190 #define AGENTX_RESPONSE 18 191 192 /* error return codes */ 193 #define AGENTX_ERR_NONE 0 194 #define AGENTX_ERR_OPEN_FAILED 256 195 #define AGENTX_ERR_NOT_OPEN 257 196 #define AGENTX_ERR_INDEX_WRONG_TYPE 258 197 #define AGENTX_ERR_INDEX_ALREADY_ALLOCATED 259 198 #define AGENTX_ERR_INDEX_NONE_AVAILABLE 260 199 #define AGENTX_ERR_INDEX_NOT_ALLOCATED 261 200 #define AGENTX_ERR_UNSUPPORTED_CONTEXT 262 201 #define AGENTX_ERR_DUPLICATE_REGISTRATION 263 202 #define AGENTX_ERR_UNKNOWN_REGISTRATION 264 203 #define AGENTX_ERR_UNKNOWN_AGENT_CAPS 265 204 #define AGENTX_ERR_PARSE_ERROR 266 205 #define AGENTX_ERR_REQUEST_DENIED 267 206 #define AGENTX_ERR_PROCESSING_ERROR 268 207 208 /* flags */ 209 #define AGENTX_INSTANCE_REGISTRATION 0x01 210 #define AGENTX_NEW_INDEX 0x02 211 #define AGENTX_ANY_INDEX 0x04 212 #define AGENTX_NON_DEFAULT_CONTEXT 0x08 213 #define AGENTX_NETWORK_BYTE_ORDER 0x10 214 #define AGENTX_FLAGS_MASK 0x1f 215 216 /* encoded data types */ 217 #define AGENTX_INTEGER 2 218 #define AGENTX_OCTET_STRING 4 219 #define AGENTX_NULL 5 220 #define AGENTX_OBJECT_IDENTIFIER 6 221 #define AGENTX_IP_ADDRESS 64 222 #define AGENTX_COUNTER32 65 223 #define AGENTX_GAUGE32 66 224 #define AGENTX_TIME_TICKS 67 225 #define AGENTX_OPAQUE 68 226 #define AGENTX_COUNTER64 70 227 #define AGENTX_NO_SUCH_OBJECT 128 228 #define AGENTX_NO_SUCH_INSTANCE 129 229 #define AGENTX_END_OF_MIB_VIEW 130 230 231 /* for registered MIB overlap */ 232 #define AGENTX_REGISTER_PRIO_DEFAULT 127 233 234 /* reasons for request of close */ 235 #define AGENTX_CLOSE_OTHER 1 236 #define AGENTX_CLOSE_PARSE_ERROR 2 237 #define AGENTX_CLOSE_PROTOCOL_ERROR 3 238 #define AGENTX_CLOSE_TIMEOUTS 4 239 #define AGENTX_CLOSE_SHUTDOWN 5 240 #define AGENTX_CLOSE_BY_MANAGER 6 241 242 #define AGENTX_DEFAULT_TIMEOUT 3 243 244 #define MIN_OID_LEN 2 /* OBJECT */ 245 #define MAX_OID_LEN 32 /* OBJECT */ 246 247 /* 248 * Protocol header prefixed to all messages 249 */ 250 struct agentx_hdr { 251 uint8_t version; 252 uint8_t type; 253 uint8_t flags; 254 uint8_t reserved; 255 uint32_t sessionid; /* chosen by agent */ 256 uint32_t transactid; /* chosen by subagent */ 257 uint32_t packetid; /* per-request id */ 258 uint32_t length; 259 } __packed; 260 261 /* 262 * Prefixed to a series of 4-byte values indicating the OID 263 */ 264 struct agentx_oid_hdr { 265 uint8_t n_subid; /* # of oid elements (named in RFC) */ 266 uint8_t prefix; /* if not 0, OID is 1.3.6.1.<prefix> */ 267 uint8_t include; /* ??? */ 268 uint8_t reserved; /* always 0 */ 269 } __packed; 270 271 struct agentx_response_data { 272 uint32_t sysuptime; /* uptime of SNMP context */ 273 uint16_t error; /* status of request */ 274 uint16_t index; /* index of failed variable binding */ 275 } __packed; 276 277 struct agentx_open_timeout { 278 uint8_t timeout; 279 uint8_t reserved[3]; 280 } __packed; 281 282 struct agentx_register_hdr { 283 uint8_t timeout; 284 uint8_t priority; 285 uint8_t subrange; 286 uint8_t reserved; 287 } __packed; 288 289 struct agentx_null_oid { 290 uint8_t padding[4]; 291 } __packed; 292 293 #define AGENTX_NULL_OID { 0, 0, 0, 0 } 294 295 struct agentx_varbind_hdr { 296 uint16_t type; 297 uint16_t reserved; 298 } __packed; 299 300 struct agentx_response { 301 struct agentx_hdr hdr; 302 struct agentx_response_data data; 303 } __packed; 304 305 struct agentx_close_request_data { 306 uint8_t reason; 307 uint8_t padding[3]; 308 } __packed; 309 310 struct agentx_close_request { 311 struct agentx_hdr hdr; 312 struct agentx_close_request_data data; 313 } __packed; 314 315 struct agentx_pdu { 316 uint8_t *buffer; 317 uint8_t *ptr; 318 uint8_t *ioptr; 319 size_t buflen; 320 size_t datalen; 321 struct agentx_hdr *hdr; 322 323 struct agentx_pdu *request; /* request this is a response to */ 324 TAILQ_ENTRY(agentx_pdu) entry; 325 }; 326 TAILQ_HEAD(agentx_pdulist, agentx_pdu); 327 328 struct agentx_handle { 329 int fd; 330 uint32_t sessionid; 331 uint32_t transactid; 332 uint32_t packetid; 333 int timeout; /* in seconds */ 334 int error; 335 int erridx; 336 337 struct agentx_pdulist w; 338 struct agentx_pdulist inflight; 339 340 struct agentx_pdu *r; 341 342 void (*cb)(struct agentx_handle *, struct agentx_pdu *, void *); 343 void *cb_arg; 344 }; 345 346 struct agentx_handle * 347 snmp_agentx_alloc(int); 348 struct agentx_handle * 349 snmp_agentx_open(const char *, char *, struct snmp_oid *); 350 struct agentx_handle * 351 snmp_agentx_fdopen(int, char *, struct snmp_oid *); 352 int snmp_agentx_response(struct agentx_handle *, struct agentx_pdu *); 353 int snmp_agentx_open_response(struct agentx_handle *, struct agentx_pdu *); 354 struct agentx_pdu * 355 snmp_agentx_open_pdu(struct agentx_handle *, char *descr, 356 struct snmp_oid *); 357 void snmp_agentx_set_callback(struct agentx_handle *, 358 void (*)(struct agentx_handle *, struct agentx_pdu *, void *), 359 void *); 360 struct agentx_pdu * 361 snmp_agentx_close_pdu(struct agentx_handle *, uint8_t); 362 int snmp_agentx_close(struct agentx_handle *, uint8_t); 363 void snmp_agentx_free(struct agentx_handle *); 364 int snmp_agentx_ping(struct agentx_handle *); 365 struct agentx_pdu * 366 snmp_agentx_ping_pdu(void); 367 struct agentx_pdu * 368 snmp_agentx_notify_pdu(struct snmp_oid *); 369 struct agentx_pdu * 370 snmp_agentx_request(struct agentx_handle *, struct agentx_pdu *); 371 int snmp_agentx_varbind(struct agentx_pdu *, struct snmp_oid *, int, 372 void *, int); 373 int snmp_agentx_send(struct agentx_handle *, struct agentx_pdu *); 374 struct agentx_pdu * 375 snmp_agentx_recv(struct agentx_handle *); 376 struct agentx_pdu * 377 snmp_agentx_response_pdu(int, int, int); 378 struct agentx_pdu * 379 snmp_agentx_register_pdu(struct snmp_oid *, int, int, int); 380 char *snmp_agentx_read_octetstr(struct agentx_pdu *, int *); 381 int snmp_agentx_read_oid(struct agentx_pdu *, struct snmp_oid *); 382 int snmp_agentx_read_raw(struct agentx_pdu *, void *, int); 383 int snmp_agentx_copy_raw(struct agentx_pdu *, void *, int); 384 char *snmp_agentx_type2name(int); 385 int snmp_agentx_read_int(struct agentx_pdu *, uint32_t *); 386 int snmp_agentx_read_int64(struct agentx_pdu *, uint64_t *); 387 int snmp_agentx_raw(struct agentx_pdu *, void *, int); 388 int snmp_agentx_read_vbhdr(struct agentx_pdu *, struct 389 agentx_varbind_hdr *); 390 struct agentx_pdu *snmp_agentx_pdu_alloc(void); 391 void snmp_agentx_pdu_free(struct agentx_pdu *); 392 393 #if BYTE_ORDER == BIG_ENDIAN 394 395 static __inline int 396 snmp_agentx_byteorder_native(struct agentx_hdr *h) 397 { 398 return ((h->flags & AGENTX_NETWORK_BYTE_ORDER) != 0); 399 } 400 401 #define AGENTX_LOCAL_BYTE_ORDER_FLAG AGENTX_NETWORK_BYTE_ORDER 402 #define snmp_agentx_int_byteswap(_i) htole32(_i) 403 #define snmp_agentx_int16_byteswap(_i) htole16(_i) 404 #define snmp_agentx_int64_byteswap(_i) htole64(_i) 405 406 #elif BYTE_ORDER == LITTLE_ENDIAN 407 408 static __inline int 409 snmp_agentx_byteorder_native(struct agentx_hdr *h) 410 { 411 return ((h->flags & AGENTX_NETWORK_BYTE_ORDER) == 0); 412 } 413 414 #define AGENTX_LOCAL_BYTE_ORDER_FLAG 0 415 #define snmp_agentx_int_byteswap(_i) htobe32(_i) 416 #define snmp_agentx_int16_byteswap(_i) htobe16(_i) 417 #define snmp_agentx_int64_byteswap(_i) htobe64(_i) 418 419 #else 420 #error "Unknown host byte order" 421 #endif 422 423 #endif /* SNMP_HEADER */ 424