diff options
author | 2020-10-26 16:52:06 +0000 | |
---|---|---|
committer | 2020-10-26 16:52:06 +0000 | |
commit | 1ae60b2abe3fed36e3bc5e7819af3ab1cc2f6944 (patch) | |
tree | aab204c9b3a2dc5abe02f31eeaf3b042f272be7d | |
parent | sync (diff) | |
download | wireguard-openbsd-1ae60b2abe3fed36e3bc5e7819af3ab1cc2f6944.tar.xz wireguard-openbsd-1ae60b2abe3fed36e3bc5e7819af3ab1cc2f6944.zip |
Let relayd make use of libagentx. No functional change intended.
OK tb@
Enthousiasm from Mischa Peters
-rw-r--r-- | usr.sbin/relayd/Makefile | 15 | ||||
-rw-r--r-- | usr.sbin/relayd/agentx.c | 1359 | ||||
-rw-r--r-- | usr.sbin/relayd/agentx.h | 232 | ||||
-rw-r--r-- | usr.sbin/relayd/agentx_control.c | 908 | ||||
-rw-r--r-- | usr.sbin/relayd/parse.y | 6 | ||||
-rw-r--r-- | usr.sbin/relayd/subagentx.c | 4003 | ||||
-rw-r--r-- | usr.sbin/relayd/subagentx.h | 147 | ||||
-rw-r--r-- | usr.sbin/relayd/subagentx_internal.h | 124 | ||||
-rw-r--r-- | usr.sbin/relayd/subagentx_log.c | 316 |
9 files changed, 464 insertions, 6646 deletions
diff --git a/usr.sbin/relayd/Makefile b/usr.sbin/relayd/Makefile index a9e28a278fc..2e1ef449b04 100644 --- a/usr.sbin/relayd/Makefile +++ b/usr.sbin/relayd/Makefile @@ -1,16 +1,15 @@ -# $OpenBSD: Makefile,v 1.34 2020/09/14 11:30:25 martijn Exp $ +# $OpenBSD: Makefile,v 1.35 2020/10/26 16:52:06 martijn Exp $ PROG= relayd SRCS= parse.y -SRCS+= agentx.c agentx_control.c ca.c carp.c check_icmp.c \ - check_script.c check_tcp.c check_tls.c config.c control.c \ - hce.c log.c name2id.c pfe.c pfe_filter.c pfe_route.c proc.c \ - relay.c relay_http.c relay_udp.c relayd.c \ - shuffle.c ssl.c subagentx.c subagentx_log.c util.c +SRCS+= agentx_control.c ca.c carp.c check_icmp.c check_script.c \ + check_tcp.c check_tls.c config.c control.c hce.c log.c \ + name2id.c pfe.c pfe_filter.c pfe_route.c proc.c relay.c \ + relay_http.c relay_udp.c relayd.c shuffle.c ssl.c util.c MAN= relayd.8 relayd.conf.5 -LDADD= -levent -ltls -lssl -lcrypto -lutil -DPADD= ${LIBEVENT} ${LIBSSL} ${LIBCRYPTO} ${LIBUTIL} +LDADD= -lagentx -levent -ltls -lssl -lcrypto -lutil +DPADD= ${LIBAGENTX} ${LIBEVENT} ${LIBSSL} ${LIBCRYPTO} ${LIBUTIL} CFLAGS+= -Wall -I${.CURDIR} CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes CFLAGS+= -Wmissing-declarations diff --git a/usr.sbin/relayd/agentx.c b/usr.sbin/relayd/agentx.c deleted file mode 100644 index b3a746ce61c..00000000000 --- a/usr.sbin/relayd/agentx.c +++ /dev/null @@ -1,1359 +0,0 @@ -/* - * Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include <sys/socket.h> - -#include <arpa/inet.h> - -#include <ctype.h> -#include <endian.h> -#include <errno.h> -#include <inttypes.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <strings.h> -#include <unistd.h> - -#include "agentx.h" - -#define AGENTX_PDU_HEADER 20 - -static int agentx_pdu_need(struct agentx *, size_t); -static int agentx_pdu_header(struct agentx *, - enum agentx_pdu_type, uint8_t, uint32_t, uint32_t, uint32_t, - struct agentx_ostring *); -static uint32_t agentx_packetid(struct agentx *); -static uint32_t agentx_pdu_queue(struct agentx *); -static int agentx_pdu_add_uint16(struct agentx *, uint16_t); -static int agentx_pdu_add_uint32(struct agentx *, uint32_t); -static int agentx_pdu_add_uint64(struct agentx *, uint64_t); -static int agentx_pdu_add_oid(struct agentx *, struct agentx_oid *, int); -static int agentx_pdu_add_str(struct agentx *, struct agentx_ostring *); -static int agentx_pdu_add_varbindlist( struct agentx *, struct agentx_varbind *, - size_t); -static uint16_t agentx_pdutoh16(struct agentx_pdu_header *, uint8_t *); -static uint32_t agentx_pdutoh32(struct agentx_pdu_header *, uint8_t *); -static uint64_t agentx_pdutoh64(struct agentx_pdu_header *, uint8_t *); -static ssize_t agentx_pdutooid(struct agentx_pdu_header *, struct agentx_oid *, - uint8_t *, size_t); -static ssize_t agentx_pdutoostring(struct agentx_pdu_header *, - struct agentx_ostring *, uint8_t *, size_t); -static ssize_t agentx_pdutovarbind(struct agentx_pdu_header *, - struct agentx_varbind *, uint8_t *, size_t); - -struct agentx * -agentx_new(int fd) -{ - struct agentx *ax; - - if (fd == -1) { - errno = EINVAL; - return NULL; - } - - if ((ax = calloc(1, sizeof(*ax))) == NULL) - return NULL; - ax->ax_fd = fd; - if ((ax->ax_rbuf = malloc(512)) == NULL) - goto fail; - ax->ax_rbsize = 512; - ax->ax_byteorder = AGENTX_BYTE_ORDER_NATIVE; - - return ax; - -fail: - free(ax); - return NULL; -} - -void -agentx_free(struct agentx *ax) -{ - if (ax == NULL) - return; - close(ax->ax_fd); - free(ax->ax_rbuf); - free(ax->ax_wbuf); - free(ax->ax_packetids); - free(ax); -} - -struct agentx_pdu * -agentx_recv(struct agentx *ax) -{ - struct agentx_pdu *pdu; - struct agentx_pdu_header header; - struct agentx_pdu_response *response; - struct agentx_varbind *varbind; - struct agentx_pdu_searchrangelist *srl; - struct agentx_pdu_varbindlist *vbl; - struct agentx_searchrange *sr; - size_t rbsize, packetidx = 0, i, rawlen; - ssize_t nread; - uint8_t *u8; - uint8_t *rbuf; - int found; - - /* Only read a single packet at a time to make sure libevent triggers */ - if (ax->ax_rblen < AGENTX_PDU_HEADER) { - if ((nread = read(ax->ax_fd, ax->ax_rbuf + ax->ax_rblen, - AGENTX_PDU_HEADER - ax->ax_rblen)) == 0) { - errno = ECONNRESET; - return NULL; - } - if (nread == -1) - return NULL; - ax->ax_rblen += nread; - if (ax->ax_rblen < AGENTX_PDU_HEADER) { - errno = EAGAIN; - return NULL; - } - } - u8 = ax->ax_rbuf; - header.aph_version = *u8++; - header.aph_type = *u8++; - header.aph_flags = *u8++; - u8++; - header.aph_sessionid = agentx_pdutoh32(&header, u8); - u8 += 4; - header.aph_transactionid = agentx_pdutoh32(&header, u8); - u8 += 4; - header.aph_packetid = agentx_pdutoh32(&header, u8); - u8 += 4; - header.aph_plength = agentx_pdutoh32(&header, u8); - - if (header.aph_version != 1) { - errno = EPROTO; - return NULL; - } - if (ax->ax_rblen < AGENTX_PDU_HEADER + header.aph_plength) { - if (AGENTX_PDU_HEADER + header.aph_plength > ax->ax_rbsize) { - rbsize = (((AGENTX_PDU_HEADER + header.aph_plength) - / 512) + 1) * 512; - if ((rbuf = recallocarray(ax->ax_rbuf, ax->ax_rbsize, - rbsize, sizeof(*rbuf))) == NULL) - return NULL; - ax->ax_rbsize = rbsize; - ax->ax_rbuf = rbuf; - } - nread = read(ax->ax_fd, ax->ax_rbuf + ax->ax_rblen, - header.aph_plength - (ax->ax_rblen - AGENTX_PDU_HEADER)); - if (nread == 0) - errno = ECONNRESET; - if (nread <= 0) - return NULL; - ax->ax_rblen += nread; - if (ax->ax_rblen < AGENTX_PDU_HEADER + header.aph_plength) { - errno = EAGAIN; - return NULL; - } - } - - if ((pdu = calloc(1, sizeof(*pdu))) == NULL) - return NULL; - - memcpy(&(pdu->ap_header), &header, sizeof(header)); - -#if defined(AGENTX_DEBUG) && defined(AGENTX_DEBUG_VERBOSE) - { - char chars[4]; - int print = 1; - - fprintf(stderr, "received packet:\n"); - for (i = 0; i < pdu->ap_header.aph_plength + AGENTX_PDU_HEADER; - i++) { - fprintf(stderr, "%02hhx ", ax->ax_rbuf[i]); - chars[i % 4] = ax->ax_rbuf[i]; - if (!isprint(ax->ax_rbuf[i])) - print = 0; - if (i % 4 == 3) { - if (print) - fprintf(stderr, "%.4s", chars); - fprintf(stderr, "\n"); - print = 1; - } - } - } -#endif - - u8 = (ax->ax_rbuf) + AGENTX_PDU_HEADER; - rawlen = pdu->ap_header.aph_plength; - if (pdu->ap_header.aph_flags & AGENTX_PDU_FLAG_NON_DEFAULT_CONTEXT) { - nread = agentx_pdutoostring(&header, &(pdu->ap_context), u8, - rawlen); - if (nread == -1) - goto fail; - rawlen -= nread; - u8 += nread; - } - - switch (pdu->ap_header.aph_type) { - case AGENTX_PDU_TYPE_GETBULK: - if (rawlen < 4) { - errno = EPROTO; - goto fail; - } - pdu->ap_payload.ap_getbulk.ap_nonrep = - agentx_pdutoh16(&header, u8); - u8 += 2; - pdu->ap_payload.ap_getbulk.ap_maxrep = - agentx_pdutoh16(&header, u8); - u8 += 2; - srl = &(pdu->ap_payload.ap_getbulk.ap_srl); - rawlen -= 4; - /* FALLTHROUGH */ - case AGENTX_PDU_TYPE_GET: - case AGENTX_PDU_TYPE_GETNEXT: - if (pdu->ap_header.aph_type != AGENTX_PDU_TYPE_GETBULK) - srl = &(pdu->ap_payload.ap_srl); - while (rawlen > 0 ) { - srl->ap_nsr++; - sr = reallocarray(srl->ap_sr, srl->ap_nsr, sizeof(*sr)); - if (sr == NULL) - goto fail; - srl->ap_sr = sr; - sr += (srl->ap_nsr - 1); - if ((nread = agentx_pdutooid(&header, &(sr->asr_start), - u8, rawlen)) == -1) - goto fail; - rawlen -= nread; - u8 += nread; - if ((nread = agentx_pdutooid(&header, &(sr->asr_stop), - u8, rawlen)) == -1) - goto fail; - rawlen -= nread; - u8 += nread; - } - break; - case AGENTX_PDU_TYPE_TESTSET: - vbl = &(pdu->ap_payload.ap_vbl); - while (rawlen > 0) { - varbind = recallocarray(vbl->ap_varbind, - vbl->ap_nvarbind, vbl->ap_nvarbind + 1, - sizeof(*(vbl->ap_varbind))); - if (varbind == NULL) - goto fail; - vbl->ap_varbind = varbind; - nread = agentx_pdutovarbind(&header, - &(vbl->ap_varbind[vbl->ap_nvarbind]), u8, rawlen); - if (nread == -1) - goto fail; - vbl->ap_nvarbind++; - u8 += nread; - rawlen -= nread; - } - break; - case AGENTX_PDU_TYPE_COMMITSET: - case AGENTX_PDU_TYPE_UNDOSET: - case AGENTX_PDU_TYPE_CLEANUPSET: - if (rawlen != 0) { - errno = EPROTO; - goto fail; - } - break; - case AGENTX_PDU_TYPE_RESPONSE: - if (ax->ax_packetids != NULL) { - found = 0; - for (i = 0; ax->ax_packetids[i] != 0; i++) { - if (ax->ax_packetids[i] == - pdu->ap_header.aph_packetid) { - packetidx = i; - found = 1; - } - } - if (found) { - ax->ax_packetids[packetidx] = - ax->ax_packetids[i - 1]; - ax->ax_packetids[i - 1] = 0; - } else { - errno = EPROTO; - goto fail; - } - } - if (rawlen < 8) { - errno = EPROTO; - goto fail; - } - response = &(pdu->ap_payload.ap_response); - response->ap_uptime = agentx_pdutoh32(&header, u8); - u8 += 4; - response->ap_error = agentx_pdutoh16(&header, u8); - u8 += 2; - response->ap_index = agentx_pdutoh16(&header, u8); - u8 += 2; - rawlen -= 8; - while (rawlen > 0) { - varbind = recallocarray(response->ap_varbindlist, - response->ap_nvarbind, response->ap_nvarbind + 1, - sizeof(*(response->ap_varbindlist))); - if (varbind == NULL) - goto fail; - response->ap_varbindlist = varbind; - nread = agentx_pdutovarbind(&header, - &(response->ap_varbindlist[response->ap_nvarbind]), - u8, rawlen); - if (nread == -1) - goto fail; - response->ap_nvarbind++; - u8 += nread; - rawlen -= nread; - } - break; - default: - pdu->ap_payload.ap_raw = malloc(pdu->ap_header.aph_plength); - if (pdu == NULL) - goto fail; - memcpy(pdu->ap_payload.ap_raw, ax->ax_rbuf + AGENTX_PDU_HEADER, - pdu->ap_header.aph_plength); - break; - } - - ax->ax_rblen = 0; - - return pdu; -fail: - agentx_pdu_free(pdu); - return NULL; -} - -static int -agentx_pdu_need(struct agentx *ax, size_t need) -{ - uint8_t *wbuf; - size_t wbsize; - - if (ax->ax_wbtlen >= ax->ax_wbsize) { - wbsize = ((ax->ax_wbtlen / 512) + 1) * 512; - wbuf = recallocarray(ax->ax_wbuf, ax->ax_wbsize, wbsize, 1); - if (wbuf == NULL) { - ax->ax_wbtlen = ax->ax_wblen; - return -1; - } - ax->ax_wbsize = wbsize; - ax->ax_wbuf = wbuf; - } - - return 0; -} - -ssize_t -agentx_send(struct agentx *ax) -{ - ssize_t nwrite; - - if (ax->ax_wblen != ax->ax_wbtlen) { - errno = EALREADY; - return -1; - } - - if (ax->ax_wblen == 0) - return 0; - -#if defined(AGENTX_DEBUG) && defined(AGENTX_DEBUG_VERBOSE) - { - size_t i; - char chars[4]; - int print = 1; - - fprintf(stderr, "sending packet:\n"); - for (i = 0; i < ax->ax_wblen; i++) { - fprintf(stderr, "%02hhx ", ax->ax_wbuf[i]); - chars[i % 4] = ax->ax_wbuf[i]; - if (!isprint(ax->ax_wbuf[i])) - print = 0; - if (i % 4 == 3) { - if (print) - fprintf(stderr, "%.4s", chars); - fprintf(stderr, "\n"); - print = 1; - } - } - } -#endif - - if ((nwrite = send(ax->ax_fd, ax->ax_wbuf, ax->ax_wblen, - MSG_NOSIGNAL | MSG_DONTWAIT)) == -1) - return -1; - - memmove(ax->ax_wbuf, ax->ax_wbuf + nwrite, ax->ax_wblen - nwrite); - ax->ax_wblen -= nwrite; - ax->ax_wbtlen = ax->ax_wblen; - - return ax->ax_wblen; -} - -uint32_t -agentx_open(struct agentx *ax, uint8_t timeout, struct agentx_oid *oid, - struct agentx_ostring *descr) -{ - if (agentx_pdu_header(ax, AGENTX_PDU_TYPE_OPEN, 0, 0, 0, 0, - NULL) == -1) - return 0; - agentx_pdu_need(ax, 4); - ax->ax_wbuf[ax->ax_wbtlen++] = timeout; - memset(&(ax->ax_wbuf[ax->ax_wbtlen]), 0, 3); - ax->ax_wbtlen += 3; - if (agentx_pdu_add_oid(ax, oid, 0) == -1) - return 0; - if (agentx_pdu_add_str(ax, descr) == -1) - return 0; - - return agentx_pdu_queue(ax); -} - -uint32_t -agentx_close(struct agentx *ax, uint32_t sessionid, - enum agentx_close_reason reason) -{ - if (agentx_pdu_header(ax, AGENTX_PDU_TYPE_CLOSE, 0, sessionid, 0, 0, - NULL) == -1) - return 0; - - if (agentx_pdu_need(ax, 4) == -1) - return 0; - ax->ax_wbuf[ax->ax_wbtlen++] = (uint8_t)reason; - memset(&(ax->ax_wbuf[ax->ax_wbtlen]), 0, 3); - ax->ax_wbtlen += 3; - - return agentx_pdu_queue(ax); -} - -uint32_t -agentx_indexallocate(struct agentx *ax, uint8_t flags, uint32_t sessionid, - struct agentx_ostring *context, struct agentx_varbind *vblist, size_t nvb) -{ - if (flags & ~(AGENTX_PDU_FLAG_NEW_INDEX | AGENTX_PDU_FLAG_ANY_INDEX)) { - errno = EINVAL; - return 0; - } - - if (agentx_pdu_header(ax, AGENTX_PDU_TYPE_INDEXALLOCATE, flags, - sessionid, 0, 0, context) == -1) - return 0; - - if (agentx_pdu_add_varbindlist(ax, vblist, nvb) == -1) - return 0; - - return agentx_pdu_queue(ax); -} - -uint32_t -agentx_indexdeallocate(struct agentx *ax, uint32_t sessionid, - struct agentx_ostring *context, struct agentx_varbind *vblist, size_t nvb) -{ - if (agentx_pdu_header(ax, AGENTX_PDU_TYPE_INDEXDEALLOCATE, 0, - sessionid, 0, 0, context) == -1) - return 0; - - if (agentx_pdu_add_varbindlist(ax, vblist, nvb) == -1) - return 0; - - return agentx_pdu_queue(ax); -} - -uint32_t -agentx_addagentcaps(struct agentx *ax, uint32_t sessionid, - struct agentx_ostring *context, struct agentx_oid *id, - struct agentx_ostring *descr) -{ - if (agentx_pdu_header(ax, AGENTX_PDU_TYPE_ADDAGENTCAPS, 0, - sessionid, 0, 0, context) == -1) - return 0; - if (agentx_pdu_add_oid(ax, id, 0) == -1) - return 0; - if (agentx_pdu_add_str(ax, descr) == -1) - return 0; - - return agentx_pdu_queue(ax); -} - -uint32_t -agentx_removeagentcaps(struct agentx *ax, uint32_t sessionid, - struct agentx_ostring *context, struct agentx_oid *id) -{ - if (agentx_pdu_header(ax, AGENTX_PDU_TYPE_REMOVEAGENTCAPS, 0, - sessionid, 0, 0, context) == -1) - return 0; - if (agentx_pdu_add_oid(ax, id, 0) == -1) - return 0; - - return agentx_pdu_queue(ax); - -} - -uint32_t -agentx_register(struct agentx *ax, uint8_t flags, uint32_t sessionid, - struct agentx_ostring *context, uint8_t timeout, uint8_t priority, - uint8_t range_subid, struct agentx_oid *subtree, uint32_t upperbound) -{ - if (flags & ~(AGENTX_PDU_FLAG_INSTANCE_REGISTRATION)) { - errno = EINVAL; - return 0; - } - - if (agentx_pdu_header(ax, AGENTX_PDU_TYPE_REGISTER, flags, - sessionid, 0, 0, context) == -1) - return 0; - - if (agentx_pdu_need(ax, 4) == -1) - return 0; - ax->ax_wbuf[ax->ax_wbtlen++] = timeout; - ax->ax_wbuf[ax->ax_wbtlen++] = priority; - ax->ax_wbuf[ax->ax_wbtlen++] = range_subid; - ax->ax_wbuf[ax->ax_wbtlen++] = 0; - if (agentx_pdu_add_oid(ax, subtree, 0) == -1) - return 0; - if (range_subid != 0) { - if (agentx_pdu_add_uint32(ax, upperbound) == -1) - return 0; - } - - return agentx_pdu_queue(ax); -} - -uint32_t -agentx_unregister(struct agentx *ax, uint32_t sessionid, - struct agentx_ostring *context, uint8_t priority, uint8_t range_subid, - struct agentx_oid *subtree, uint32_t upperbound) -{ - if (agentx_pdu_header(ax, AGENTX_PDU_TYPE_UNREGISTER, 0, - sessionid, 0, 0, context) == -1) - return 0; - - if (agentx_pdu_need(ax, 4) == -1) - return 0; - ax->ax_wbuf[ax->ax_wbtlen++] = 0; - ax->ax_wbuf[ax->ax_wbtlen++] = priority; - ax->ax_wbuf[ax->ax_wbtlen++] = range_subid; - ax->ax_wbuf[ax->ax_wbtlen++] = 0; - if (agentx_pdu_add_oid(ax, subtree, 0) == -1) - return 0; - if (range_subid != 0) { - if (agentx_pdu_add_uint32(ax, upperbound) == -1) - return 0; - } - - return agentx_pdu_queue(ax); -} - -int -agentx_response(struct agentx *ax, uint32_t sessionid, uint32_t transactionid, - uint32_t packetid, struct agentx_ostring *context, uint32_t sysuptime, - uint16_t error, uint16_t index, struct agentx_varbind *vblist, size_t nvb) -{ - if (agentx_pdu_header(ax, AGENTX_PDU_TYPE_RESPONSE, 0, sessionid, - transactionid, packetid, context) == -1) - return -1; - - if (agentx_pdu_add_uint32(ax, sysuptime) == -1 || - agentx_pdu_add_uint16(ax, error) == -1 || - agentx_pdu_add_uint16(ax, index) == -1) - return -1; - - if (agentx_pdu_add_varbindlist(ax, vblist, nvb) == -1) - return -1; - if (agentx_pdu_queue(ax) == 0) - return -1; - return 0; -} - -void -agentx_pdu_free(struct agentx_pdu *pdu) -{ - size_t i; - struct agentx_pdu_response *response; - - if (pdu->ap_header.aph_flags & AGENTX_PDU_FLAG_NON_DEFAULT_CONTEXT) - free(pdu->ap_context.aos_string); - - switch (pdu->ap_header.aph_type) { - case AGENTX_PDU_TYPE_GET: - case AGENTX_PDU_TYPE_GETNEXT: - case AGENTX_PDU_TYPE_GETBULK: - free(pdu->ap_payload.ap_srl.ap_sr); - break; - case AGENTX_PDU_TYPE_RESPONSE: - response = &(pdu->ap_payload.ap_response); - for (i = 0; i < response->ap_nvarbind; i++) - agentx_varbind_free(&(response->ap_varbindlist[i])); - free(response->ap_varbindlist); - break; - default: - free(pdu->ap_payload.ap_raw); - break; - } - free(pdu); -} - -void -agentx_varbind_free(struct agentx_varbind *varbind) -{ - switch (varbind->avb_type) { - case AGENTX_DATA_TYPE_OCTETSTRING: - case AGENTX_DATA_TYPE_IPADDRESS: - case AGENTX_DATA_TYPE_OPAQUE: - free(varbind->avb_data.avb_ostring.aos_string); - break; - default: - break; - } -} - -const char * -agentx_error2string(enum agentx_pdu_error error) -{ - static char buffer[64]; - switch (error) { - case AGENTX_PDU_ERROR_NOERROR: - return "No error"; - case AGENTX_PDU_ERROR_GENERR: - return "Generic error"; - case AGENTX_PDU_ERROR_NOACCESS: - return "No access"; - case AGENTX_PDU_ERROR_WRONGTYPE: - return "Wrong type"; - case AGENTX_PDU_ERROR_WRONGLENGTH: - return "Wrong length"; - case AGENTX_PDU_ERROR_WRONGENCODING: - return "Wrong encoding"; - case AGENTX_PDU_ERROR_WRONGVALUE: - return "Wrong value"; - case AGENTX_PDU_ERROR_NOCREATION: - return "No creation"; - case AGENTX_PDU_ERROR_INCONSISTENTVALUE: - return "Inconsistent value"; - case AGENTX_PDU_ERROR_RESOURCEUNAVAILABLE: - return "Resource unavailable"; - case AGENTX_PDU_ERROR_COMMITFAILED: - return "Commit failed"; - case AGENTX_PDU_ERROR_UNDOFAILED: - return "Undo failed"; - case AGENTX_PDU_ERROR_NOTWRITABLE: - return "Not writable"; - case AGENTX_PDU_ERROR_INCONSISTENTNAME: - return "Inconsistent name"; - case AGENTX_PDU_ERROR_OPENFAILED: - return "Open Failed"; - case AGENTX_PDU_ERROR_NOTOPEN: - return "Not open"; - case AGENTX_PDU_ERROR_INDEXWRONGTYPE: - return "Index wrong type"; - case AGENTX_PDU_ERROR_INDEXALREADYALLOCATED: - return "Index already allocated"; - case AGENTX_PDU_ERROR_INDEXNONEAVAILABLE: - return "Index none available"; - case AGENTX_PDU_ERROR_INDEXNOTALLOCATED: - return "Index not allocated"; - case AGENTX_PDU_ERROR_UNSUPPORTEDCONETXT: - return "Unsupported context"; - case AGENTX_PDU_ERROR_DUPLICATEREGISTRATION: - return "Duplicate registration"; - case AGENTX_PDU_ERROR_UNKNOWNREGISTRATION: - return "Unkown registration"; - case AGENTX_PDU_ERROR_UNKNOWNAGENTCAPS: - return "Unknown agent capabilities"; - case AGENTX_PDU_ERROR_PARSEERROR: - return "Parse error"; - case AGENTX_PDU_ERROR_REQUESTDENIED: - return "Request denied"; - case AGENTX_PDU_ERROR_PROCESSINGERROR: - return "Processing error"; - } - snprintf(buffer, sizeof(buffer), "Unknown error: %d", error); - return buffer; -} - -const char * -agentx_pdutype2string(enum agentx_pdu_type type) -{ - static char buffer[64]; - switch(type) { - case AGENTX_PDU_TYPE_OPEN: - return "agentx-Open-PDU"; - case AGENTX_PDU_TYPE_CLOSE: - return "agentx-Close-PDU"; - case AGENTX_PDU_TYPE_REGISTER: - return "agentx-Register-PDU"; - case AGENTX_PDU_TYPE_UNREGISTER: - return "agentx-Unregister-PDU"; - case AGENTX_PDU_TYPE_GET: - return "agentx-Get-PDU"; - case AGENTX_PDU_TYPE_GETNEXT: - return "agentx-GetNext-PDU"; - case AGENTX_PDU_TYPE_GETBULK: - return "agentx-GetBulk-PDU"; - case AGENTX_PDU_TYPE_TESTSET: - return "agentx-TestSet-PDU"; - case AGENTX_PDU_TYPE_COMMITSET: - return "agentx-CommitSet-PDU"; - case AGENTX_PDU_TYPE_UNDOSET: - return "agentx-UndoSet-PDU"; - case AGENTX_PDU_TYPE_CLEANUPSET: - return "agentx-CleanupSet-PDU"; - case AGENTX_PDU_TYPE_NOTIFY: - return "agentx-Notify-PDU"; - case AGENTX_PDU_TYPE_PING: - return "agentx-Ping-PDU"; - case AGENTX_PDU_TYPE_INDEXALLOCATE: - return "agentx-IndexAllocate-PDU"; - case AGENTX_PDU_TYPE_INDEXDEALLOCATE: - return "agentx-IndexDeallocate-PDU"; - case AGENTX_PDU_TYPE_ADDAGENTCAPS: - return "agentx-AddAgentCaps-PDU"; - case AGENTX_PDU_TYPE_REMOVEAGENTCAPS: - return "agentx-RemoveAgentCaps-PDU"; - case AGENTX_PDU_TYPE_RESPONSE: - return "agentx-Response-PDU"; - } - snprintf(buffer, sizeof(buffer), "Unknown type: %d", type); - return buffer; -} - -const char * -agentx_closereason2string(enum agentx_close_reason reason) -{ - static char buffer[64]; - - switch (reason) { - case AGENTX_CLOSE_OTHER: - return "Undefined reason"; - case AGENTX_CLOSEN_PARSEERROR: - return "Too many AgentX parse errors from peer"; - case AGENTX_CLOSE_PROTOCOLERROR: - return "Too many AgentX protocol errors from peer"; - case AGENTX_CLOSE_TIMEOUTS: - return "Too many timeouts waiting for peer"; - case AGENTX_CLOSE_SHUTDOWN: - return "shutting down"; - case AGENTX_CLOSE_BYMANAGER: - return "Manager shuts down"; - } - snprintf(buffer, sizeof(buffer), "Unknown reason: %d", reason); - return buffer; -} - -const char * -agentx_oid2string(struct agentx_oid *oid) -{ - return agentx_oidrange2string(oid, 0, 0); -} - -const char * -agentx_oidrange2string(struct agentx_oid *oid, uint8_t range_subid, - uint32_t upperbound) -{ - static char buf[1024]; - char *p; - size_t i, rest; - int ret; - - rest = sizeof(buf); - p = buf; - for (i = 0; i < oid->aoi_idlen; i++) { - if (range_subid != 0 && range_subid - 1 == (uint8_t)i) - ret = snprintf(p, rest, ".[%u-%u]", oid->aoi_id[i], - upperbound); - else - ret = snprintf(p, rest, ".%u", oid->aoi_id[i]); - if ((size_t) ret >= rest) { - snprintf(buf, sizeof(buf), "Couldn't parse oid"); - return buf; - } - p += ret; - rest -= (size_t) ret; - } - return buf; -} - -const char * -agentx_varbind2string(struct agentx_varbind *vb) -{ - static char buf[1024]; - char tmpbuf[1024]; - size_t i, bufleft; - int ishex = 0; - char *p; - int ret; - - switch (vb->avb_type) { - case AGENTX_DATA_TYPE_INTEGER: - (void) snprintf(buf, sizeof(buf), "%s: (int)%u", - agentx_oid2string(&(vb->avb_oid)), vb->avb_data.avb_uint32); - break; - case AGENTX_DATA_TYPE_OCTETSTRING: - for (i = 0; - i < vb->avb_data.avb_ostring.aos_slen && !ishex; i++) { - if (!isprint(vb->avb_data.avb_ostring.aos_string[i])) - ishex = 1; - } - if (ishex) { - p = tmpbuf; - bufleft = sizeof(tmpbuf); - for (i = 0; - i < vb->avb_data.avb_ostring.aos_slen; i++) { - ret = snprintf(p, bufleft, " %02hhX", - vb->avb_data.avb_ostring.aos_string[i]); - if (ret >= (int) bufleft) { - p = strrchr(p, ' '); - strlcpy(p, "...", 4); - break; - } - p += 3; - bufleft -= 3; - } - ret = snprintf(buf, sizeof(buf), "%s: (hex-string)%s", - agentx_oid2string(&(vb->avb_oid)), tmpbuf); - if (ret >= (int) sizeof(buf)) { - p = strrchr(buf, ' '); - strlcpy(p, "...", 4); - } - } else { - ret = snprintf(buf, sizeof(buf), "%s: (string)", - agentx_oid2string(&(vb->avb_oid))); - if (ret >= (int) sizeof(buf)) { - snprintf(buf, sizeof(buf), "<too large OID>: " - "(string)<too large string>"); - break; - } - p = buf + ret; - bufleft = (int) sizeof(buf) - ret; - if (snprintf(p, bufleft, "%.*s", - vb->avb_data.avb_ostring.aos_slen, - vb->avb_data.avb_ostring.aos_string) >= - (int) bufleft) { - p = buf + sizeof(buf) - 4; - (void) strlcpy(p, "...", 4); - } - } - break; - case AGENTX_DATA_TYPE_NULL: - (void) snprintf(buf, sizeof(buf), "%s: <null>", - agentx_oid2string(&(vb->avb_oid))); - break; - case AGENTX_DATA_TYPE_OID: - (void) strlcpy(tmpbuf, - agentx_oid2string(&(vb->avb_data.avb_oid)), sizeof(tmpbuf)); - snprintf(buf, sizeof(buf), "%s: (oid)%s", - agentx_oid2string(&(vb->avb_oid)), tmpbuf); - break; - case AGENTX_DATA_TYPE_IPADDRESS: - if (vb->avb_data.avb_ostring.aos_slen != 4) { - snprintf(buf, sizeof(buf), "%s: (ipaddress)<invalid>", - agentx_oid2string(&(vb->avb_oid))); - break; - } - if (inet_ntop(PF_INET, vb->avb_data.avb_ostring.aos_string, - tmpbuf, sizeof(tmpbuf)) == NULL) { - snprintf(buf, sizeof(buf), "%s: (ipaddress)" - "<unparseable>: %s", - agentx_oid2string(&(vb->avb_oid)), - strerror(errno)); - break; - } - snprintf(buf, sizeof(buf), "%s: (ipaddress)%s", - agentx_oid2string(&(vb->avb_oid)), tmpbuf); - break; - case AGENTX_DATA_TYPE_COUNTER32: - (void) snprintf(buf, sizeof(buf), "%s: (counter32)%u", - agentx_oid2string(&(vb->avb_oid)), vb->avb_data.avb_uint32); - break; - case AGENTX_DATA_TYPE_GAUGE32: - (void) snprintf(buf, sizeof(buf), "%s: (gauge32)%u", - agentx_oid2string(&(vb->avb_oid)), vb->avb_data.avb_uint32); - break; - case AGENTX_DATA_TYPE_TIMETICKS: - (void) snprintf(buf, sizeof(buf), "%s: (timeticks)%u", - agentx_oid2string(&(vb->avb_oid)), vb->avb_data.avb_uint32); - break; - case AGENTX_DATA_TYPE_OPAQUE: - p = tmpbuf; - bufleft = sizeof(tmpbuf); - for (i = 0; - i < vb->avb_data.avb_ostring.aos_slen; i++) { - ret = snprintf(p, bufleft, " %02hhX", - vb->avb_data.avb_ostring.aos_string[i]); - if (ret >= (int) bufleft) { - p = strrchr(p, ' '); - strlcpy(p, "...", 4); - break; - } - p += 3; - bufleft -= 3; - } - ret = snprintf(buf, sizeof(buf), "%s: (opaque)%s", - agentx_oid2string(&(vb->avb_oid)), tmpbuf); - if (ret >= (int) sizeof(buf)) { - p = strrchr(buf, ' '); - strlcpy(p, "...", 4); - } - break; - case AGENTX_DATA_TYPE_COUNTER64: - (void) snprintf(buf, sizeof(buf), "%s: (counter64)%"PRIu64, - agentx_oid2string(&(vb->avb_oid)), vb->avb_data.avb_uint64); - break; - case AGENTX_DATA_TYPE_NOSUCHOBJECT: - (void) snprintf(buf, sizeof(buf), "%s: <noSuchObject>", - agentx_oid2string(&(vb->avb_oid))); - break; - case AGENTX_DATA_TYPE_NOSUCHINSTANCE: - (void) snprintf(buf, sizeof(buf), "%s: <noSuchInstance>", - agentx_oid2string(&(vb->avb_oid))); - break; - case AGENTX_DATA_TYPE_ENDOFMIBVIEW: - (void) snprintf(buf, sizeof(buf), "%s: <endOfMibView>", - agentx_oid2string(&(vb->avb_oid))); - break; - } - return buf; -} - -int -agentx_oid_cmp(struct agentx_oid *o1, struct agentx_oid *o2) -{ - size_t i, min; - - min = o1->aoi_idlen < o2->aoi_idlen ? o1->aoi_idlen : o2->aoi_idlen; - for (i = 0; i < min; i++) { - if (o1->aoi_id[i] < o2->aoi_id[i]) - return -1; - if (o1->aoi_id[i] > o2->aoi_id[i]) - return 1; - } - /* o1 is parent of o2 */ - if (o1->aoi_idlen < o2->aoi_idlen) - return -2; - /* o1 is child of o2 */ - if (o1->aoi_idlen > o2->aoi_idlen) - return 2; - return 0; -} - -int -agentx_oid_add(struct agentx_oid *oid, uint32_t value) -{ - if (oid->aoi_idlen == AGENTX_OID_MAX_LEN) - return -1; - oid->aoi_id[oid->aoi_idlen++] = value; - return 0; -} - -static uint32_t -agentx_pdu_queue(struct agentx *ax) -{ - struct agentx_pdu_header header; - uint32_t packetid, plength; - size_t wbtlen = ax->ax_wbtlen; - - header.aph_flags = ax->ax_byteorder == AGENTX_BYTE_ORDER_BE ? - AGENTX_PDU_FLAG_NETWORK_BYTE_ORDER : 0; - packetid = agentx_pdutoh32(&header, &(ax->ax_wbuf[ax->ax_wblen + 12])); - plength = (ax->ax_wbtlen - ax->ax_wblen) - AGENTX_PDU_HEADER; - ax->ax_wbtlen = ax->ax_wblen + 16; - (void)agentx_pdu_add_uint32(ax, plength); - - ax->ax_wblen = ax->ax_wbtlen = wbtlen; - - return packetid; -} - -static int -agentx_pdu_header(struct agentx *ax, enum agentx_pdu_type type, uint8_t flags, - uint32_t sessionid, uint32_t transactionid, uint32_t packetid, - struct agentx_ostring *context) -{ - if (ax->ax_wblen != ax->ax_wbtlen) { - errno = EALREADY; - return -1; - } - - ax->ax_wbtlen = ax->ax_wblen; - if (agentx_pdu_need(ax, 4) == -1) - return -1; - ax->ax_wbuf[ax->ax_wbtlen++] = 1; - ax->ax_wbuf[ax->ax_wbtlen++] = (uint8_t) type; - if (context != NULL) - flags |= AGENTX_PDU_FLAG_NON_DEFAULT_CONTEXT; - if (ax->ax_byteorder == AGENTX_BYTE_ORDER_BE) - flags |= AGENTX_PDU_FLAG_NETWORK_BYTE_ORDER; - ax->ax_wbuf[ax->ax_wbtlen++] = flags; - ax->ax_wbuf[ax->ax_wbtlen++] = 0; - if (packetid == 0) - packetid = agentx_packetid(ax); - if (agentx_pdu_add_uint32(ax, sessionid) == -1 || - agentx_pdu_add_uint32(ax, transactionid) == -1 || - agentx_pdu_add_uint32(ax, packetid) == -1 || - agentx_pdu_need(ax, 4) == -1) - return -1; - ax->ax_wbtlen += 4; - if (context != NULL) { - if (agentx_pdu_add_str(ax, context) == -1) - return -1; - } - - return 0; -} - -static uint32_t -agentx_packetid(struct agentx *ax) -{ - uint32_t packetid, *packetids; - size_t npackets = 0, i; - int found; - - if (ax->ax_packetids != NULL) { - for (npackets = 0; ax->ax_packetids[npackets] != 0; npackets++) - continue; - } - if (ax->ax_packetidsize == 0 || npackets == ax->ax_packetidsize - 1) { - packetids = recallocarray(ax->ax_packetids, ax->ax_packetidsize, - ax->ax_packetidsize + 25, sizeof(*packetids)); - if (packetids == NULL) - return 0; - ax->ax_packetidsize += 25; - ax->ax_packetids = packetids; - } - do { - found = 0; - packetid = arc4random(); - for (i = 0; ax->ax_packetids[i] != 0; i++) { - if (ax->ax_packetids[i] == packetid) { - found = 1; - break; - } - } - } while (packetid == 0 || found); - ax->ax_packetids[npackets] = packetid; - - return packetid; -} - -static int -agentx_pdu_add_uint16(struct agentx *ax, uint16_t value) -{ - if (agentx_pdu_need(ax, sizeof(value)) == -1) - return -1; - - if (ax->ax_byteorder == AGENTX_BYTE_ORDER_BE) - value = htobe16(value); - else - value = htole16(value); - memcpy(ax->ax_wbuf + ax->ax_wbtlen, &value, sizeof(value)); - ax->ax_wbtlen += sizeof(value); - return 0; -} - -static int -agentx_pdu_add_uint32(struct agentx *ax, uint32_t value) -{ - if (agentx_pdu_need(ax, sizeof(value)) == -1) - return -1; - - if (ax->ax_byteorder == AGENTX_BYTE_ORDER_BE) - value = htobe32(value); - else - value = htole32(value); - memcpy(ax->ax_wbuf + ax->ax_wbtlen, &value, sizeof(value)); - ax->ax_wbtlen += sizeof(value); - return 0; -} - -static int -agentx_pdu_add_uint64(struct agentx *ax, uint64_t value) -{ - if (agentx_pdu_need(ax, sizeof(value)) == -1) - return -1; - - if (ax->ax_byteorder == AGENTX_BYTE_ORDER_BE) - value = htobe64(value); - else - value = htole64(value); - memcpy(ax->ax_wbuf + ax->ax_wbtlen, &value, sizeof(value)); - ax->ax_wbtlen += sizeof(value); - return 0; -} - - -static int -agentx_pdu_add_oid(struct agentx *ax, struct agentx_oid *oid, int include) -{ - static struct agentx_oid nulloid = {0}; - uint8_t prefix = 0, n_subid, i = 0; - - n_subid = oid->aoi_idlen; - - if (oid == NULL) - oid = &nulloid; - - if (oid->aoi_idlen > 4 && - oid->aoi_id[0] == 1 && oid->aoi_id[1] == 3 && - oid->aoi_id[2] == 6 && oid->aoi_id[3] == 1 && - oid->aoi_id[4] <= UINT8_MAX) { - prefix = oid->aoi_id[4]; - i = 5; - } - - if (agentx_pdu_need(ax, 4) == -1) - return -1; - ax->ax_wbuf[ax->ax_wbtlen++] = n_subid - i; - ax->ax_wbuf[ax->ax_wbtlen++] = prefix; - ax->ax_wbuf[ax->ax_wbtlen++] = !!include; - ax->ax_wbuf[ax->ax_wbtlen++] = 0; - - for (; i < n_subid; i++) { - if (agentx_pdu_add_uint32(ax, oid->aoi_id[i]) == -1) - return -1; - } - - return 0; -} - -static int -agentx_pdu_add_str(struct agentx *ax, struct agentx_ostring *str) -{ - size_t length, zeroes; - - if (agentx_pdu_add_uint32(ax, str->aos_slen) == -1) - return -1; - - if ((zeroes = (4 - (str->aos_slen % 4))) == 4) - zeroes = 0; - length = str->aos_slen + zeroes; - if (agentx_pdu_need(ax, length) == -1) - return -1; - - memcpy(&(ax->ax_wbuf[ax->ax_wbtlen]), str->aos_string, str->aos_slen); - ax->ax_wbtlen += str->aos_slen; - memset(&(ax->ax_wbuf[ax->ax_wbtlen]), 0, zeroes); - ax->ax_wbtlen += zeroes; - return 0; -} - -static int -agentx_pdu_add_varbindlist(struct agentx *ax, - struct agentx_varbind *vblist, size_t nvb) -{ - size_t i; - uint16_t temp; - - for (i = 0; i < nvb; i++) { - temp = (uint16_t) vblist[i].avb_type; - if (agentx_pdu_add_uint16(ax, temp) == -1 || - agentx_pdu_need(ax, 2)) - return -1; - memset(&(ax->ax_wbuf[ax->ax_wbtlen]), 0, 2); - ax->ax_wbtlen += 2; - if (agentx_pdu_add_oid(ax, &(vblist[i].avb_oid), 0) == -1) - return -1; - switch (vblist[i].avb_type) { - case AGENTX_DATA_TYPE_INTEGER: - case AGENTX_DATA_TYPE_COUNTER32: - case AGENTX_DATA_TYPE_GAUGE32: - case AGENTX_DATA_TYPE_TIMETICKS: - if (agentx_pdu_add_uint32(ax, - vblist[i].avb_data.avb_uint32) == -1) - return -1; - break; - case AGENTX_DATA_TYPE_COUNTER64: - if (agentx_pdu_add_uint64(ax, - vblist[i].avb_data.avb_uint64) == -1) - return -1; - break; - case AGENTX_DATA_TYPE_OCTETSTRING: - case AGENTX_DATA_TYPE_IPADDRESS: - case AGENTX_DATA_TYPE_OPAQUE: - if (agentx_pdu_add_str(ax, - &(vblist[i].avb_data.avb_ostring)) == -1) - return -1; - break; - case AGENTX_DATA_TYPE_OID: - if (agentx_pdu_add_oid(ax, - &(vblist[i].avb_data.avb_oid), 1) == -1) - return -1; - break; - case AGENTX_DATA_TYPE_NULL: - case AGENTX_DATA_TYPE_NOSUCHOBJECT: - case AGENTX_DATA_TYPE_NOSUCHINSTANCE: - case AGENTX_DATA_TYPE_ENDOFMIBVIEW: - break; - default: - errno = EINVAL; - return -1; - } - } - return 0; -} - -static uint16_t -agentx_pdutoh16(struct agentx_pdu_header *header, uint8_t *buf) -{ - uint16_t value; - - memcpy(&value, buf, sizeof(value)); - if (header->aph_flags & AGENTX_PDU_FLAG_NETWORK_BYTE_ORDER) - return be16toh(value); - return le16toh(value); -} - -static uint32_t -agentx_pdutoh32(struct agentx_pdu_header *header, uint8_t *buf) -{ - uint32_t value; - - memcpy(&value, buf, sizeof(value)); - if (header->aph_flags & AGENTX_PDU_FLAG_NETWORK_BYTE_ORDER) - return be32toh(value); - return le32toh(value); -} - -static uint64_t -agentx_pdutoh64(struct agentx_pdu_header *header, uint8_t *buf) -{ - uint64_t value; - - memcpy(&value, buf, sizeof(value)); - if (header->aph_flags & AGENTX_PDU_FLAG_NETWORK_BYTE_ORDER) - return be64toh(value); - return le64toh(value); -} - -static ssize_t -agentx_pdutooid(struct agentx_pdu_header *header, struct agentx_oid *oid, - uint8_t *buf, size_t rawlen) -{ - size_t i = 0; - ssize_t nread; - - if (rawlen < 4) - goto fail; - rawlen -= 4; - nread = 4; - oid->aoi_idlen = *buf++; - if (rawlen < (oid->aoi_idlen * 4)) - goto fail; - nread += oid->aoi_idlen * 4; - if (*buf != 0) { - oid->aoi_id[0] = 1; - oid->aoi_id[1] = 3; - oid->aoi_id[2] = 6; - oid->aoi_id[3] = 1; - oid->aoi_id[4] = *buf; - oid->aoi_idlen += 5; - i = 5; - } - buf++; - oid->aoi_include = *buf; - for (buf += 2; i < oid->aoi_idlen; i++, buf += 4) - oid->aoi_id[i] = agentx_pdutoh32(header, buf); - - return nread; - -fail: - errno = EPROTO; - return -1; -} - -static ssize_t -agentx_pdutoostring(struct agentx_pdu_header *header, - struct agentx_ostring *ostring, uint8_t *buf, size_t rawlen) -{ - ssize_t nread; - - if (rawlen < 4) - goto fail; - - ostring->aos_slen = agentx_pdutoh32(header, buf); - rawlen -= 4; - buf += 4; - if (ostring->aos_slen > rawlen) - goto fail; - if ((ostring->aos_string = malloc(ostring->aos_slen + 1)) == NULL) - return -1; - memcpy(ostring->aos_string, buf, ostring->aos_slen); - ostring->aos_string[ostring->aos_slen] = '\0'; - - nread = 4 + ostring->aos_slen; - if (ostring->aos_slen % 4 != 0) - nread += 4 - (ostring->aos_slen % 4); - - return nread; - -fail: - errno = EPROTO; - return -1; -} - -static ssize_t -agentx_pdutovarbind(struct agentx_pdu_header *header, - struct agentx_varbind *varbind, uint8_t *buf, size_t rawlen) -{ - ssize_t nread, rread = 4; - - if (rawlen == 0) - return 0; - - if (rawlen < 8) - goto fail; - varbind->avb_type = agentx_pdutoh16(header, buf); - - buf += 4; - rawlen -= 4; - nread = agentx_pdutooid(header, &(varbind->avb_oid), buf, rawlen); - if (nread == -1) - return -1; - rread += nread; - buf += nread; - rawlen -= nread; - - switch(varbind->avb_type) { - case AGENTX_DATA_TYPE_INTEGER: - case AGENTX_DATA_TYPE_COUNTER32: - case AGENTX_DATA_TYPE_GAUGE32: - case AGENTX_DATA_TYPE_TIMETICKS: - if (rawlen < 4) - goto fail; - varbind->avb_data.avb_uint32 = agentx_pdutoh32(header, buf); - return rread + 4; - case AGENTX_DATA_TYPE_COUNTER64: - if (rawlen < 8) - goto fail; - varbind->avb_data.avb_uint64 = agentx_pdutoh64(header, buf); - return rread + 8; - case AGENTX_DATA_TYPE_OCTETSTRING: - case AGENTX_DATA_TYPE_IPADDRESS: - case AGENTX_DATA_TYPE_OPAQUE: - nread = agentx_pdutoostring(header, - &(varbind->avb_data.avb_ostring), buf, rawlen); - if (rread == -1) - return -1; - return nread + rread; - case AGENTX_DATA_TYPE_OID: - nread = agentx_pdutooid(header, &(varbind->avb_data.avb_oid), - buf, rawlen); - if (rread == -1) - return -1; - return nread + rread; - case AGENTX_DATA_TYPE_NULL: - case AGENTX_DATA_TYPE_NOSUCHOBJECT: - case AGENTX_DATA_TYPE_NOSUCHINSTANCE: - case AGENTX_DATA_TYPE_ENDOFMIBVIEW: - return rread; - } - -fail: - errno = EPROTO; - return -1; -} diff --git a/usr.sbin/relayd/agentx.h b/usr.sbin/relayd/agentx.h deleted file mode 100644 index 8adde286a9b..00000000000 --- a/usr.sbin/relayd/agentx.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stdint.h> - -#define AGENTX_PDU_FLAG_INSTANCE_REGISTRATION (1 << 0) -#define AGENTX_PDU_FLAG_NEW_INDEX (1 << 1) -#define AGENTX_PDU_FLAG_ANY_INDEX (1 << 2) -#define AGENTX_PDU_FLAG_NON_DEFAULT_CONTEXT (1 << 3) -#define AGENTX_PDU_FLAG_NETWORK_BYTE_ORDER (1 << 4) - -#define AGENTX_PRIORITY_DEFAULT 127 - -enum agentx_byte_order { - AGENTX_BYTE_ORDER_BE, - AGENTX_BYTE_ORDER_LE -}; - -#if BYTE_ORDER == BIG_ENDIAN -#define AGENTX_BYTE_ORDER_NATIVE AGENTX_BYTE_ORDER_BE -#else -#define AGENTX_BYTE_ORDER_NATIVE AGENTX_BYTE_ORDER_LE -#endif - -enum agentx_pdu_type { - AGENTX_PDU_TYPE_OPEN = 1, - AGENTX_PDU_TYPE_CLOSE = 2, - AGENTX_PDU_TYPE_REGISTER = 3, - AGENTX_PDU_TYPE_UNREGISTER = 4, - AGENTX_PDU_TYPE_GET = 5, - AGENTX_PDU_TYPE_GETNEXT = 6, - AGENTX_PDU_TYPE_GETBULK = 7, - AGENTX_PDU_TYPE_TESTSET = 8, - AGENTX_PDU_TYPE_COMMITSET = 9, - AGENTX_PDU_TYPE_UNDOSET = 10, - AGENTX_PDU_TYPE_CLEANUPSET = 11, - AGENTX_PDU_TYPE_NOTIFY = 12, - AGENTX_PDU_TYPE_PING = 13, - AGENTX_PDU_TYPE_INDEXALLOCATE = 14, - AGENTX_PDU_TYPE_INDEXDEALLOCATE = 15, - AGENTX_PDU_TYPE_ADDAGENTCAPS = 16, - AGENTX_PDU_TYPE_REMOVEAGENTCAPS = 17, - AGENTX_PDU_TYPE_RESPONSE = 18 -}; - -enum agentx_pdu_error { - AGENTX_PDU_ERROR_NOERROR = 0, - AGENTX_PDU_ERROR_GENERR = 5, - AGENTX_PDU_ERROR_NOACCESS = 6, - AGENTX_PDU_ERROR_WRONGTYPE = 7, - AGENTX_PDU_ERROR_WRONGLENGTH = 8, - AGENTX_PDU_ERROR_WRONGENCODING = 9, - AGENTX_PDU_ERROR_WRONGVALUE = 10, - AGENTX_PDU_ERROR_NOCREATION = 11, - AGENTX_PDU_ERROR_INCONSISTENTVALUE = 12, - AGENTX_PDU_ERROR_RESOURCEUNAVAILABLE = 13, - AGENTX_PDU_ERROR_COMMITFAILED = 14, - AGENTX_PDU_ERROR_UNDOFAILED = 15, - AGENTX_PDU_ERROR_NOTWRITABLE = 17, - AGENTX_PDU_ERROR_INCONSISTENTNAME = 18, - AGENTX_PDU_ERROR_OPENFAILED = 256, - AGENTX_PDU_ERROR_NOTOPEN = 257, - AGENTX_PDU_ERROR_INDEXWRONGTYPE = 258, - AGENTX_PDU_ERROR_INDEXALREADYALLOCATED = 259, - AGENTX_PDU_ERROR_INDEXNONEAVAILABLE = 260, - AGENTX_PDU_ERROR_INDEXNOTALLOCATED = 261, - AGENTX_PDU_ERROR_UNSUPPORTEDCONETXT = 262, - AGENTX_PDU_ERROR_DUPLICATEREGISTRATION = 263, - AGENTX_PDU_ERROR_UNKNOWNREGISTRATION = 264, - AGENTX_PDU_ERROR_UNKNOWNAGENTCAPS = 265, - AGENTX_PDU_ERROR_PARSEERROR = 266, - AGENTX_PDU_ERROR_REQUESTDENIED = 267, - AGENTX_PDU_ERROR_PROCESSINGERROR = 268 -}; - -enum agentx_data_type { - AGENTX_DATA_TYPE_INTEGER = 2, - AGENTX_DATA_TYPE_OCTETSTRING = 4, - AGENTX_DATA_TYPE_NULL = 5, - AGENTX_DATA_TYPE_OID = 6, - AGENTX_DATA_TYPE_IPADDRESS = 64, - AGENTX_DATA_TYPE_COUNTER32 = 65, - AGENTX_DATA_TYPE_GAUGE32 = 66, - AGENTX_DATA_TYPE_TIMETICKS = 67, - AGENTX_DATA_TYPE_OPAQUE = 68, - AGENTX_DATA_TYPE_COUNTER64 = 70, - AGENTX_DATA_TYPE_NOSUCHOBJECT = 128, - AGENTX_DATA_TYPE_NOSUCHINSTANCE = 129, - AGENTX_DATA_TYPE_ENDOFMIBVIEW = 130 -}; - -enum agentx_close_reason { - AGENTX_CLOSE_OTHER = 1, - AGENTX_CLOSEN_PARSEERROR = 2, - AGENTX_CLOSE_PROTOCOLERROR = 3, - AGENTX_CLOSE_TIMEOUTS = 4, - AGENTX_CLOSE_SHUTDOWN = 5, - AGENTX_CLOSE_BYMANAGER = 6 -}; - -struct agentx { - int ax_fd; - enum agentx_byte_order ax_byteorder; - uint8_t *ax_rbuf; - size_t ax_rblen; - size_t ax_rbsize; - uint8_t *ax_wbuf; - size_t ax_wblen; - size_t ax_wbtlen; - size_t ax_wbsize; - uint32_t *ax_packetids; - size_t ax_packetidsize; -}; - -#ifndef AGENTX_PRIMITIVE -#define AGENTX_PRIMITIVE - -#define AGENTX_OID_MAX_LEN 128 - -struct agentx_oid { - uint8_t aoi_include; - uint32_t aoi_id[AGENTX_OID_MAX_LEN]; - size_t aoi_idlen; -}; - -struct agentx_ostring { - unsigned char *aos_string; - uint32_t aos_slen; -}; -#endif - -struct agentx_searchrange { - struct agentx_oid asr_start; - struct agentx_oid asr_stop; -}; - -struct agentx_pdu_header { - uint8_t aph_version; - uint8_t aph_type; - uint8_t aph_flags; - uint8_t aph_reserved; - uint32_t aph_sessionid; - uint32_t aph_transactionid; - uint32_t aph_packetid; - uint32_t aph_plength; -} __packed; - -struct agentx_varbind { - enum agentx_data_type avb_type; - struct agentx_oid avb_oid; - union agentx_data { - uint32_t avb_uint32; - uint64_t avb_uint64; - struct agentx_ostring avb_ostring; - struct agentx_oid avb_oid; - } avb_data; -}; - -struct agentx_pdu { - struct agentx_pdu_header ap_header; - struct agentx_ostring ap_context; - union { - struct agentx_pdu_searchrangelist { - size_t ap_nsr; - struct agentx_searchrange *ap_sr; - } ap_srl; - struct agentx_pdu_getbulk { - uint16_t ap_nonrep; - uint16_t ap_maxrep; - struct agentx_pdu_searchrangelist ap_srl; - } ap_getbulk; - struct agentx_pdu_varbindlist { - struct agentx_varbind *ap_varbind; - size_t ap_nvarbind; - } ap_vbl; - struct agentx_pdu_response { - uint32_t ap_uptime; - enum agentx_pdu_error ap_error; - uint16_t ap_index; - struct agentx_varbind *ap_varbindlist; - size_t ap_nvarbind; - } ap_response; - void *ap_raw; - } ap_payload; -}; - -struct agentx *agentx_new(int); -void agentx_free(struct agentx *); -struct agentx_pdu *agentx_recv(struct agentx *); -ssize_t agentx_send(struct agentx *); -uint32_t agentx_open(struct agentx *, uint8_t, struct agentx_oid *, - struct agentx_ostring *); -uint32_t agentx_close(struct agentx *, uint32_t, enum agentx_close_reason); -uint32_t agentx_indexallocate(struct agentx *, uint8_t, uint32_t, - struct agentx_ostring *, struct agentx_varbind *, size_t); -uint32_t agentx_indexdeallocate(struct agentx *, uint32_t, - struct agentx_ostring *, struct agentx_varbind *, size_t); -uint32_t agentx_addagentcaps(struct agentx *, uint32_t, struct agentx_ostring *, - struct agentx_oid *, struct agentx_ostring *); -uint32_t agentx_removeagentcaps(struct agentx *, uint32_t, - struct agentx_ostring *, struct agentx_oid *); -uint32_t agentx_register(struct agentx *, uint8_t, uint32_t, - struct agentx_ostring *, uint8_t, uint8_t, uint8_t, struct agentx_oid *, - uint32_t); -uint32_t agentx_unregister(struct agentx *, uint32_t, struct agentx_ostring *, - uint8_t, uint8_t, struct agentx_oid *, uint32_t); -int agentx_response(struct agentx *, uint32_t, uint32_t, uint32_t, - struct agentx_ostring *, uint32_t, uint16_t, uint16_t, - struct agentx_varbind *, size_t); -void agentx_pdu_free(struct agentx_pdu *); -void agentx_varbind_free(struct agentx_varbind *); -const char *agentx_error2string(enum agentx_pdu_error); -const char *agentx_pdutype2string(enum agentx_pdu_type); -const char *agentx_oid2string(struct agentx_oid *); -const char *agentx_oidrange2string(struct agentx_oid *, uint8_t, uint32_t); -const char *agentx_varbind2string(struct agentx_varbind *); -const char *agentx_closereason2string(enum agentx_close_reason); -int agentx_oid_cmp(struct agentx_oid *, struct agentx_oid *); -int agentx_oid_add(struct agentx_oid *, uint32_t); diff --git a/usr.sbin/relayd/agentx_control.c b/usr.sbin/relayd/agentx_control.c index edb7667c910..ccc5aa162dd 100644 --- a/usr.sbin/relayd/agentx_control.c +++ b/usr.sbin/relayd/agentx_control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agentx_control.c,v 1.2 2020/10/25 10:17:49 denis Exp $ */ +/* $OpenBSD: agentx_control.c,v 1.3 2020/10/26 16:52:06 martijn Exp $ */ /* * Copyright (c) 2020 Martijn van Duren <martijn@openbsd.org> @@ -25,6 +25,7 @@ #include <netinet/in.h> +#include <agentx.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> @@ -37,7 +38,6 @@ #include <imsg.h> #include "relayd.h" -#include "subagentx.h" #define RELAYD_MIB "1.3.6.1.4.1.30155.3" #define SNMP_ELEMENT(x...) do { \ @@ -52,7 +52,7 @@ static struct snmp_oid hosttrapoid = { }; */ -#define RELAYDINFO SUBAGENTX_ENTERPRISES, 30155, 3, 2 +#define RELAYDINFO AGENTX_ENTERPRISES, 30155, 3, 2 #define RELAYDREDIRECTS RELAYDINFO, 1 #define RELAYDREDIRECTENTRY RELAYDREDIRECTS, 1 #define RELAYDREDIRECTINDEX RELAYDREDIRECTENTRY, 1 @@ -124,69 +124,69 @@ static struct snmp_oid hosttrapoid = { #define RELAYDTABLENAME RELAYDTABLEENTRY, 2 #define RELAYDTABLESTATUS RELAYDTABLEENTRY, 3 -void agentx_needsock(struct subagentx *, void *, int); +void agentx_needsock(struct agentx *, void *, int); struct relayd *env; -struct subagentx *sa = NULL; -struct subagentx_index *relaydRedirectIdx, *relaydRelayIdx; -struct subagentx_index *relaydRouterIdx, *relaydNetRouteIdx; -struct subagentx_index *relaydHostIdx, *relaydSessionRelayIdx; -struct subagentx_index *relaydSessionIdx, *relaydTableIdx; - -struct subagentx_object *relaydRedirectIndex, *relaydRedirectStatus; -struct subagentx_object *relaydRedirectName, *relaydRedirectCnt; -struct subagentx_object *relaydRedirectAvg, *relaydRedirectLast; -struct subagentx_object *relaydRedirectAvgHour, *relaydRedirectLastHour; -struct subagentx_object *relaydRedirectAvgDay, *relaydRedirectLastDay; - -struct subagentx_object *relaydRelayIndex, *relaydRelayStatus; -struct subagentx_object *relaydRelayName, *relaydRelayCnt; -struct subagentx_object *relaydRelayAvg, *relaydRelayLast; -struct subagentx_object *relaydRelayAvgHour, *relaydRelayLastHour; -struct subagentx_object *relaydRelayAvgDay, *relaydRelayLastDay; - -struct subagentx_object *relaydRouterIndex, *relaydRouterTableIndex; -struct subagentx_object *relaydRouterStatus, *relaydRouterName; -struct subagentx_object *relaydRouterLabel, *relaydRouterRtable; - -struct subagentx_object *relaydNetRouteIndex, *relaydNetRouteAddr; -struct subagentx_object *relaydNetRouteAddrType, *relaydNetRoutePrefixLen; -struct subagentx_object *relaydNetRouteRouterIndex; - -struct subagentx_object *relaydHostIndex, *relaydHostParentIndex; -struct subagentx_object *relaydHostTableIndex, *relaydHostName; -struct subagentx_object *relaydHostAddress, *relaydHostAddressType; -struct subagentx_object *relaydHostStatus, *relaydHostCheckCnt; -struct subagentx_object *relaydHostUpCnt, *relaydHostErrno; - -struct subagentx_object *relaydSessionIndex, *relaydSessionRelayIndex; -struct subagentx_object *relaydSessionInAddr, *relaydSessionInAddrType; -struct subagentx_object *relaydSessionOutAddr, *relaydSessionOutAddrType; -struct subagentx_object *relaydSessionPortIn, *relaydSessionPortOut; -struct subagentx_object *relaydSessionAge, *relaydSessionIdle; -struct subagentx_object *relaydSessionStatus, *relaydSessionPid; - -struct subagentx_object *relaydTableIndex, *relaydTableName, *relaydTableStatus; +struct agentx *sa = NULL; +struct agentx_index *relaydRedirectIdx, *relaydRelayIdx; +struct agentx_index *relaydRouterIdx, *relaydNetRouteIdx; +struct agentx_index *relaydHostIdx, *relaydSessionRelayIdx; +struct agentx_index *relaydSessionIdx, *relaydTableIdx; + +struct agentx_object *relaydRedirectIndex, *relaydRedirectStatus; +struct agentx_object *relaydRedirectName, *relaydRedirectCnt; +struct agentx_object *relaydRedirectAvg, *relaydRedirectLast; +struct agentx_object *relaydRedirectAvgHour, *relaydRedirectLastHour; +struct agentx_object *relaydRedirectAvgDay, *relaydRedirectLastDay; + +struct agentx_object *relaydRelayIndex, *relaydRelayStatus; +struct agentx_object *relaydRelayName, *relaydRelayCnt; +struct agentx_object *relaydRelayAvg, *relaydRelayLast; +struct agentx_object *relaydRelayAvgHour, *relaydRelayLastHour; +struct agentx_object *relaydRelayAvgDay, *relaydRelayLastDay; + +struct agentx_object *relaydRouterIndex, *relaydRouterTableIndex; +struct agentx_object *relaydRouterStatus, *relaydRouterName; +struct agentx_object *relaydRouterLabel, *relaydRouterRtable; + +struct agentx_object *relaydNetRouteIndex, *relaydNetRouteAddr; +struct agentx_object *relaydNetRouteAddrType, *relaydNetRoutePrefixLen; +struct agentx_object *relaydNetRouteRouterIndex; + +struct agentx_object *relaydHostIndex, *relaydHostParentIndex; +struct agentx_object *relaydHostTableIndex, *relaydHostName; +struct agentx_object *relaydHostAddress, *relaydHostAddressType; +struct agentx_object *relaydHostStatus, *relaydHostCheckCnt; +struct agentx_object *relaydHostUpCnt, *relaydHostErrno; + +struct agentx_object *relaydSessionIndex, *relaydSessionRelayIndex; +struct agentx_object *relaydSessionInAddr, *relaydSessionInAddrType; +struct agentx_object *relaydSessionOutAddr, *relaydSessionOutAddrType; +struct agentx_object *relaydSessionPortIn, *relaydSessionPortOut; +struct agentx_object *relaydSessionAge, *relaydSessionIdle; +struct agentx_object *relaydSessionStatus, *relaydSessionPid; + +struct agentx_object *relaydTableIndex, *relaydTableName, *relaydTableStatus; void *sstodata(struct sockaddr_storage *); size_t sstolen(struct sockaddr_storage *); -struct rdr *agentx_rdr_byidx(uint32_t, enum subagentx_request_type); -void agentx_redirect(struct subagentx_varbind *); -struct relay *agentx_relay_byidx(uint32_t, enum subagentx_request_type); -void agentx_relay(struct subagentx_varbind *); -struct router *agentx_router_byidx(uint32_t, enum subagentx_request_type); -void agentx_router(struct subagentx_varbind *); -struct netroute *agentx_netroute_byidx(uint32_t, enum subagentx_request_type); -void agentx_netroute(struct subagentx_varbind *); -struct host *agentx_host_byidx(uint32_t, enum subagentx_request_type); -void agentx_host(struct subagentx_varbind *); -struct rsession *agentx_session_byidx(uint32_t, uint32_t, - enum subagentx_request_type); -void agentx_session(struct subagentx_varbind *); -struct table *agentx_table_byidx(uint32_t, enum subagentx_request_type); -void agentx_table(struct subagentx_varbind *); +struct rdr *agentxctl_rdr_byidx(uint32_t, enum agentx_request_type); +void agentxctl_redirect(struct agentx_varbind *); +struct relay *agentxctl_relay_byidx(uint32_t, enum agentx_request_type); +void agentxctl_relay(struct agentx_varbind *); +struct router *agentxctl_router_byidx(uint32_t, enum agentx_request_type); +void agentxctl_router(struct agentx_varbind *); +struct netroute *agentxctl_netroute_byidx(uint32_t, enum agentx_request_type); +void agentxctl_netroute(struct agentx_varbind *); +struct host *agentxctl_host_byidx(uint32_t, enum agentx_request_type); +void agentxctl_host(struct agentx_varbind *); +struct rsession *agentxctl_session_byidx(uint32_t, uint32_t, + enum agentx_request_type); +void agentxctl_session(struct agentx_varbind *); +struct table *agentxctl_table_byidx(uint32_t, enum agentx_request_type); +void agentxctl_table(struct agentx_varbind *); void agentx_sock(int, short, void *); #if 0 @@ -198,229 +198,229 @@ int snmp_string2oid(const char *, struct snmp_oid *); void agentx_init(struct relayd *nenv) { - struct subagentx_session *sas; - struct subagentx_context *sac; - struct subagentx_region *sar; - struct subagentx_index *session_idxs[2]; + struct agentx_session *sas; + struct agentx_context *sac; + struct agentx_region *sar; + struct agentx_index *session_idxs[2]; - subagentx_log_fatal = fatalx; - subagentx_log_warn = log_warnx; - subagentx_log_info = log_info; - subagentx_log_debug = log_debug; + agentx_log_fatal = fatalx; + agentx_log_warn = log_warnx; + agentx_log_info = log_info; + agentx_log_debug = log_debug; env = nenv; if ((env->sc_conf.flags & F_AGENTX) == 0) { if (sa != NULL) - subagentx_free(sa); + agentx_free(sa); return; } if (sa != NULL) return; - if ((sa = subagentx(agentx_needsock, NULL)) == NULL) + if ((sa = agentx(agentx_needsock, NULL)) == NULL) fatal("%s: agentx alloc", __func__); - if ((sas = subagentx_session(sa, NULL, 0, "relayd", 0)) == NULL) + if ((sas = agentx_session(sa, NULL, 0, "relayd", 0)) == NULL) fatal("%s: agentx session alloc", __func__); - if ((sac = subagentx_context(sas, + if ((sac = agentx_context(sas, env->sc_conf.agentx_context[0] == '\0' ? NULL : env->sc_conf.agentx_context)) == NULL) fatal("%s: agentx context alloc", __func__); - sar = subagentx_region(sac, SUBAGENTX_OID(RELAYDINFO), 0); + sar = agentx_region(sac, AGENTX_OID(RELAYDINFO), 0); if (sar == NULL) fatal("%s: agentx region alloc", __func__); - if ((relaydRedirectIdx = subagentx_index_integer_dynamic(sar, - SUBAGENTX_OID(RELAYDREDIRECTINDEX))) == NULL || - (relaydRelayIdx = subagentx_index_integer_dynamic(sar, - SUBAGENTX_OID(RELAYDRELAYINDEX))) == NULL || - (relaydRouterIdx = subagentx_index_integer_dynamic(sar, - SUBAGENTX_OID(RELAYDROUTERINDEX))) == NULL || - (relaydNetRouteIdx = subagentx_index_integer_dynamic(sar, - SUBAGENTX_OID(RELAYDNETROUTEINDEX))) == NULL || - (relaydHostIdx = subagentx_index_integer_dynamic(sar, - SUBAGENTX_OID(RELAYDHOSTINDEX))) == NULL || - (relaydSessionIdx = subagentx_index_integer_dynamic(sar, - SUBAGENTX_OID(RELAYDSESSIONINDEX))) == NULL || - (relaydSessionRelayIdx = subagentx_index_integer_dynamic(sar, - SUBAGENTX_OID(RELAYDSESSIONRELAYINDEX))) == NULL || - (relaydTableIdx = subagentx_index_integer_dynamic(sar, - SUBAGENTX_OID(RELAYDTABLEINDEX))) == NULL) + if ((relaydRedirectIdx = agentx_index_integer_dynamic(sar, + AGENTX_OID(RELAYDREDIRECTINDEX))) == NULL || + (relaydRelayIdx = agentx_index_integer_dynamic(sar, + AGENTX_OID(RELAYDRELAYINDEX))) == NULL || + (relaydRouterIdx = agentx_index_integer_dynamic(sar, + AGENTX_OID(RELAYDROUTERINDEX))) == NULL || + (relaydNetRouteIdx = agentx_index_integer_dynamic(sar, + AGENTX_OID(RELAYDNETROUTEINDEX))) == NULL || + (relaydHostIdx = agentx_index_integer_dynamic(sar, + AGENTX_OID(RELAYDHOSTINDEX))) == NULL || + (relaydSessionIdx = agentx_index_integer_dynamic(sar, + AGENTX_OID(RELAYDSESSIONINDEX))) == NULL || + (relaydSessionRelayIdx = agentx_index_integer_dynamic(sar, + AGENTX_OID(RELAYDSESSIONRELAYINDEX))) == NULL || + (relaydTableIdx = agentx_index_integer_dynamic(sar, + AGENTX_OID(RELAYDTABLEINDEX))) == NULL) fatal("%s: agentx index alloc", __func__); session_idxs[0] = relaydSessionRelayIdx; session_idxs[1] = relaydSessionIdx; - if ((relaydRedirectIndex = subagentx_object(sar, - SUBAGENTX_OID(RELAYDREDIRECTINDEX), &relaydRedirectIdx, 1, 0, - agentx_redirect)) == NULL || - (relaydRedirectStatus = subagentx_object(sar, - SUBAGENTX_OID(RELAYDREDIRECTSTATUS), &relaydRedirectIdx, 1, 0, - agentx_redirect)) == NULL || - (relaydRedirectName = subagentx_object(sar, - SUBAGENTX_OID(RELAYDREDIRECTNAME), &relaydRedirectIdx, 1, 0, - agentx_redirect)) == NULL || - (relaydRedirectCnt = subagentx_object(sar, - SUBAGENTX_OID(RELAYDREDIRECTCNT), &relaydRedirectIdx, 1, 0, - agentx_redirect)) == NULL || - (relaydRedirectAvg = subagentx_object(sar, - SUBAGENTX_OID(RELAYDREDIRECTAVG), &relaydRedirectIdx, 1, 0, - agentx_redirect)) == NULL || - (relaydRedirectLast = subagentx_object(sar, - SUBAGENTX_OID(RELAYDREDIRECTLAST), &relaydRedirectIdx, 1, 0, - agentx_redirect)) == NULL || - (relaydRedirectAvgHour = subagentx_object(sar, - SUBAGENTX_OID(RELAYDREDIRECTAVGHOUR), &relaydRedirectIdx, 1, 0, - agentx_redirect)) == NULL || - (relaydRedirectLastHour = subagentx_object(sar, - SUBAGENTX_OID(RELAYDREDIRECTLASTHOUR), &relaydRedirectIdx, 1, 0, - agentx_redirect)) == NULL || - (relaydRedirectAvgDay = subagentx_object(sar, - SUBAGENTX_OID(RELAYDREDIRECTAVGDAY), &relaydRedirectIdx, 1, 0, - agentx_redirect)) == NULL || - (relaydRedirectLastDay = subagentx_object(sar, - SUBAGENTX_OID(RELAYDREDIRECTLASTDAY), &relaydRedirectIdx, 1, 0, - agentx_redirect)) == NULL || - (relaydRelayIndex = subagentx_object(sar, - SUBAGENTX_OID(RELAYDRELAYINDEX), &relaydRelayIdx, 1, 0, - agentx_relay)) == NULL || - (relaydRelayStatus = subagentx_object(sar, - SUBAGENTX_OID(RELAYDRELAYSTATUS), &relaydRelayIdx, 1, 0, - agentx_relay)) == NULL || - (relaydRelayName = subagentx_object(sar, - SUBAGENTX_OID(RELAYDRELAYNAME), &relaydRelayIdx, 1, 0, - agentx_relay)) == NULL || - (relaydRelayCnt = subagentx_object(sar, - SUBAGENTX_OID(RELAYDRELAYCNT), &relaydRelayIdx, 1, 0, - agentx_relay)) == NULL || - (relaydRelayAvg = subagentx_object(sar, - SUBAGENTX_OID(RELAYDRELAYAVG), &relaydRelayIdx, 1, 0, - agentx_relay)) == NULL || - (relaydRelayLast = subagentx_object(sar, - SUBAGENTX_OID(RELAYDRELAYLAST), &relaydRelayIdx, 1, 0, - agentx_relay)) == NULL || - (relaydRelayAvgHour = subagentx_object(sar, - SUBAGENTX_OID(RELAYDRELAYAVGHOUR), &relaydRelayIdx, 1, 0, - agentx_relay)) == NULL || - (relaydRelayLastHour = subagentx_object(sar, - SUBAGENTX_OID(RELAYDRELAYLASTHOUR), &relaydRelayIdx, 1, 0, - agentx_relay)) == NULL || - (relaydRelayAvgDay = subagentx_object(sar, - SUBAGENTX_OID(RELAYDRELAYAVGDAY), &relaydRelayIdx, 1, 0, - agentx_relay)) == NULL || - (relaydRelayLastDay = subagentx_object(sar, - SUBAGENTX_OID(RELAYDRELAYLASTDAY), &relaydRelayIdx, 1, 0, - agentx_relay)) == NULL || - (relaydRouterIndex = subagentx_object(sar, - SUBAGENTX_OID(RELAYDROUTERINDEX), &relaydRouterIdx, 1, 0, - agentx_router)) == NULL || - (relaydRouterTableIndex = subagentx_object(sar, - SUBAGENTX_OID(RELAYDROUTERTABLEINDEX), &relaydRouterIdx, 1, 0, - agentx_router)) == NULL || - (relaydRouterStatus = subagentx_object(sar, - SUBAGENTX_OID(RELAYDROUTERSTATUS), &relaydRouterIdx, 1, 0, - agentx_router)) == NULL || - (relaydRouterName = subagentx_object(sar, - SUBAGENTX_OID(RELAYDROUTERNAME), &relaydRouterIdx, 1, 0, - agentx_router)) == NULL || - (relaydRouterLabel = subagentx_object(sar, - SUBAGENTX_OID(RELAYDROUTERLABEL), &relaydRouterIdx, 1, 0, - agentx_router)) == NULL || - (relaydRouterRtable = subagentx_object(sar, - SUBAGENTX_OID(RELAYDROUTERRTABLE), &relaydRouterIdx, 1, 0, - agentx_router)) == NULL || - (relaydNetRouteIndex = subagentx_object(sar, - SUBAGENTX_OID(RELAYDNETROUTEINDEX), &relaydNetRouteIdx, 1, 0, - agentx_netroute)) == NULL || - (relaydNetRouteAddr = subagentx_object(sar, - SUBAGENTX_OID(RELAYDNETROUTEADDR), &relaydNetRouteIdx, 1, 0, - agentx_netroute)) == NULL || - (relaydNetRouteAddrType = subagentx_object(sar, - SUBAGENTX_OID(RELAYDNETROUTEADDRTYPE), &relaydNetRouteIdx, 1, 0, - agentx_netroute)) == NULL || - (relaydNetRoutePrefixLen = subagentx_object(sar, - SUBAGENTX_OID(RELAYDNETROUTEPREFIXLEN), &relaydNetRouteIdx, 1, 0, - agentx_netroute)) == NULL || - (relaydNetRouteRouterIndex = subagentx_object(sar, - SUBAGENTX_OID(RELAYDNETROUTEROUTERINDEX), &relaydNetRouteIdx, 1, 0, - agentx_netroute)) == NULL || - (relaydHostIndex = subagentx_object(sar, - SUBAGENTX_OID(RELAYDHOSTINDEX), &relaydHostIdx, 1, 0, - agentx_host)) == NULL || - (relaydHostParentIndex = subagentx_object(sar, - SUBAGENTX_OID(RELAYDHOSTPARENTINDEX), &relaydHostIdx, 1, 0, - agentx_host)) == NULL || - (relaydHostTableIndex = subagentx_object(sar, - SUBAGENTX_OID(RELAYDHOSTTABLEINDEX), &relaydHostIdx, 1, 0, - agentx_host)) == NULL || - (relaydHostName = subagentx_object(sar, - SUBAGENTX_OID(RELAYDHOSTNAME), &relaydHostIdx, 1, 0, - agentx_host)) == NULL || - (relaydHostAddress = subagentx_object(sar, - SUBAGENTX_OID(RELAYDHOSTADDRESS), &relaydHostIdx, 1, 0, - agentx_host)) == NULL || - (relaydHostAddressType = subagentx_object(sar, - SUBAGENTX_OID(RELAYDHOSTADDRESSTYPE), &relaydHostIdx, 1, 0, - agentx_host)) == NULL || - (relaydHostStatus = subagentx_object(sar, - SUBAGENTX_OID(RELAYDHOSTSTATUS), &relaydHostIdx, 1, 0, - agentx_host)) == NULL || - (relaydHostCheckCnt = subagentx_object(sar, - SUBAGENTX_OID(RELAYDHOSTCHECKCNT), &relaydHostIdx, 1, 0, - agentx_host)) == NULL || - (relaydHostUpCnt = subagentx_object(sar, - SUBAGENTX_OID(RELAYDHOSTUPCNT), &relaydHostIdx, 1, 0, - agentx_host)) == NULL || - (relaydHostErrno = subagentx_object(sar, - SUBAGENTX_OID(RELAYDHOSTERRNO), &relaydHostIdx, 1, 0, - agentx_host)) == NULL || - (relaydSessionIndex = subagentx_object(sar, - SUBAGENTX_OID(RELAYDSESSIONINDEX), session_idxs, 2, 0, - agentx_session)) == NULL || - (relaydSessionRelayIndex = subagentx_object(sar, - SUBAGENTX_OID(RELAYDSESSIONRELAYINDEX), session_idxs, 2, 0, - agentx_session)) == NULL || - (relaydSessionInAddr = subagentx_object(sar, - SUBAGENTX_OID(RELAYDSESSIONINADDR), session_idxs, 2, 0, - agentx_session)) == NULL || - (relaydSessionInAddrType = subagentx_object(sar, - SUBAGENTX_OID(RELAYDSESSIONINADDRTYPE), session_idxs, 2, 0, - agentx_session)) == NULL || - (relaydSessionOutAddr = subagentx_object(sar, - SUBAGENTX_OID(RELAYDSESSIONOUTADDR), session_idxs, 2, 0, - agentx_session)) == NULL || - (relaydSessionOutAddrType = subagentx_object(sar, - SUBAGENTX_OID(RELAYDSESSIONOUTADDRTYPE), session_idxs, 2, 0, - agentx_session)) == NULL || - (relaydSessionPortIn = subagentx_object(sar, - SUBAGENTX_OID(RELAYDSESSIONPORTIN), session_idxs, 2, 0, - agentx_session)) == NULL || - (relaydSessionPortOut = subagentx_object(sar, - SUBAGENTX_OID(RELAYDSESSIONPORTOUT), session_idxs, 2, 0, - agentx_session)) == NULL || - (relaydSessionAge = subagentx_object(sar, - SUBAGENTX_OID(RELAYDSESSIONAGE), session_idxs, 2, 0, - agentx_session)) == NULL || - (relaydSessionIdle = subagentx_object(sar, - SUBAGENTX_OID(RELAYDSESSIONIDLE), session_idxs, 2, 0, - agentx_session)) == NULL || - (relaydSessionStatus = subagentx_object(sar, - SUBAGENTX_OID(RELAYDSESSIONSTATUS), session_idxs, 2, 0, - agentx_session)) == NULL || - (relaydSessionPid = subagentx_object(sar, - SUBAGENTX_OID(RELAYDSESSIONPID), session_idxs, 2, 0, - agentx_session)) == NULL || - (relaydTableIndex = subagentx_object(sar, - SUBAGENTX_OID(RELAYDTABLEINDEX), &relaydTableIdx, 1, 0, - agentx_table)) == NULL || - (relaydTableName = subagentx_object(sar, - SUBAGENTX_OID(RELAYDTABLENAME), &relaydTableIdx, 1, 0, - agentx_table)) == NULL || - (relaydTableStatus = subagentx_object(sar, - SUBAGENTX_OID(RELAYDTABLESTATUS), &relaydTableIdx, 1, 0, - agentx_table)) == NULL) + if ((relaydRedirectIndex = agentx_object(sar, + AGENTX_OID(RELAYDREDIRECTINDEX), &relaydRedirectIdx, 1, 0, + agentxctl_redirect)) == NULL || + (relaydRedirectStatus = agentx_object(sar, + AGENTX_OID(RELAYDREDIRECTSTATUS), &relaydRedirectIdx, 1, 0, + agentxctl_redirect)) == NULL || + (relaydRedirectName = agentx_object(sar, + AGENTX_OID(RELAYDREDIRECTNAME), &relaydRedirectIdx, 1, 0, + agentxctl_redirect)) == NULL || + (relaydRedirectCnt = agentx_object(sar, + AGENTX_OID(RELAYDREDIRECTCNT), &relaydRedirectIdx, 1, 0, + agentxctl_redirect)) == NULL || + (relaydRedirectAvg = agentx_object(sar, + AGENTX_OID(RELAYDREDIRECTAVG), &relaydRedirectIdx, 1, 0, + agentxctl_redirect)) == NULL || + (relaydRedirectLast = agentx_object(sar, + AGENTX_OID(RELAYDREDIRECTLAST), &relaydRedirectIdx, 1, 0, + agentxctl_redirect)) == NULL || + (relaydRedirectAvgHour = agentx_object(sar, + AGENTX_OID(RELAYDREDIRECTAVGHOUR), &relaydRedirectIdx, 1, 0, + agentxctl_redirect)) == NULL || + (relaydRedirectLastHour = agentx_object(sar, + AGENTX_OID(RELAYDREDIRECTLASTHOUR), &relaydRedirectIdx, 1, 0, + agentxctl_redirect)) == NULL || + (relaydRedirectAvgDay = agentx_object(sar, + AGENTX_OID(RELAYDREDIRECTAVGDAY), &relaydRedirectIdx, 1, 0, + agentxctl_redirect)) == NULL || + (relaydRedirectLastDay = agentx_object(sar, + AGENTX_OID(RELAYDREDIRECTLASTDAY), &relaydRedirectIdx, 1, 0, + agentxctl_redirect)) == NULL || + (relaydRelayIndex = agentx_object(sar, + AGENTX_OID(RELAYDRELAYINDEX), &relaydRelayIdx, 1, 0, + agentxctl_relay)) == NULL || + (relaydRelayStatus = agentx_object(sar, + AGENTX_OID(RELAYDRELAYSTATUS), &relaydRelayIdx, 1, 0, + agentxctl_relay)) == NULL || + (relaydRelayName = agentx_object(sar, + AGENTX_OID(RELAYDRELAYNAME), &relaydRelayIdx, 1, 0, + agentxctl_relay)) == NULL || + (relaydRelayCnt = agentx_object(sar, + AGENTX_OID(RELAYDRELAYCNT), &relaydRelayIdx, 1, 0, + agentxctl_relay)) == NULL || + (relaydRelayAvg = agentx_object(sar, + AGENTX_OID(RELAYDRELAYAVG), &relaydRelayIdx, 1, 0, + agentxctl_relay)) == NULL || + (relaydRelayLast = agentx_object(sar, + AGENTX_OID(RELAYDRELAYLAST), &relaydRelayIdx, 1, 0, + agentxctl_relay)) == NULL || + (relaydRelayAvgHour = agentx_object(sar, + AGENTX_OID(RELAYDRELAYAVGHOUR), &relaydRelayIdx, 1, 0, + agentxctl_relay)) == NULL || + (relaydRelayLastHour = agentx_object(sar, + AGENTX_OID(RELAYDRELAYLASTHOUR), &relaydRelayIdx, 1, 0, + agentxctl_relay)) == NULL || + (relaydRelayAvgDay = agentx_object(sar, + AGENTX_OID(RELAYDRELAYAVGDAY), &relaydRelayIdx, 1, 0, + agentxctl_relay)) == NULL || + (relaydRelayLastDay = agentx_object(sar, + AGENTX_OID(RELAYDRELAYLASTDAY), &relaydRelayIdx, 1, 0, + agentxctl_relay)) == NULL || + (relaydRouterIndex = agentx_object(sar, + AGENTX_OID(RELAYDROUTERINDEX), &relaydRouterIdx, 1, 0, + agentxctl_router)) == NULL || + (relaydRouterTableIndex = agentx_object(sar, + AGENTX_OID(RELAYDROUTERTABLEINDEX), &relaydRouterIdx, 1, 0, + agentxctl_router)) == NULL || + (relaydRouterStatus = agentx_object(sar, + AGENTX_OID(RELAYDROUTERSTATUS), &relaydRouterIdx, 1, 0, + agentxctl_router)) == NULL || + (relaydRouterName = agentx_object(sar, + AGENTX_OID(RELAYDROUTERNAME), &relaydRouterIdx, 1, 0, + agentxctl_router)) == NULL || + (relaydRouterLabel = agentx_object(sar, + AGENTX_OID(RELAYDROUTERLABEL), &relaydRouterIdx, 1, 0, + agentxctl_router)) == NULL || + (relaydRouterRtable = agentx_object(sar, + AGENTX_OID(RELAYDROUTERRTABLE), &relaydRouterIdx, 1, 0, + agentxctl_router)) == NULL || + (relaydNetRouteIndex = agentx_object(sar, + AGENTX_OID(RELAYDNETROUTEINDEX), &relaydNetRouteIdx, 1, 0, + agentxctl_netroute)) == NULL || + (relaydNetRouteAddr = agentx_object(sar, + AGENTX_OID(RELAYDNETROUTEADDR), &relaydNetRouteIdx, 1, 0, + agentxctl_netroute)) == NULL || + (relaydNetRouteAddrType = agentx_object(sar, + AGENTX_OID(RELAYDNETROUTEADDRTYPE), &relaydNetRouteIdx, 1, 0, + agentxctl_netroute)) == NULL || + (relaydNetRoutePrefixLen = agentx_object(sar, + AGENTX_OID(RELAYDNETROUTEPREFIXLEN), &relaydNetRouteIdx, 1, 0, + agentxctl_netroute)) == NULL || + (relaydNetRouteRouterIndex = agentx_object(sar, + AGENTX_OID(RELAYDNETROUTEROUTERINDEX), &relaydNetRouteIdx, 1, 0, + agentxctl_netroute)) == NULL || + (relaydHostIndex = agentx_object(sar, + AGENTX_OID(RELAYDHOSTINDEX), &relaydHostIdx, 1, 0, + agentxctl_host)) == NULL || + (relaydHostParentIndex = agentx_object(sar, + AGENTX_OID(RELAYDHOSTPARENTINDEX), &relaydHostIdx, 1, 0, + agentxctl_host)) == NULL || + (relaydHostTableIndex = agentx_object(sar, + AGENTX_OID(RELAYDHOSTTABLEINDEX), &relaydHostIdx, 1, 0, + agentxctl_host)) == NULL || + (relaydHostName = agentx_object(sar, + AGENTX_OID(RELAYDHOSTNAME), &relaydHostIdx, 1, 0, + agentxctl_host)) == NULL || + (relaydHostAddress = agentx_object(sar, + AGENTX_OID(RELAYDHOSTADDRESS), &relaydHostIdx, 1, 0, + agentxctl_host)) == NULL || + (relaydHostAddressType = agentx_object(sar, + AGENTX_OID(RELAYDHOSTADDRESSTYPE), &relaydHostIdx, 1, 0, + agentxctl_host)) == NULL || + (relaydHostStatus = agentx_object(sar, + AGENTX_OID(RELAYDHOSTSTATUS), &relaydHostIdx, 1, 0, + agentxctl_host)) == NULL || + (relaydHostCheckCnt = agentx_object(sar, + AGENTX_OID(RELAYDHOSTCHECKCNT), &relaydHostIdx, 1, 0, + agentxctl_host)) == NULL || + (relaydHostUpCnt = agentx_object(sar, + AGENTX_OID(RELAYDHOSTUPCNT), &relaydHostIdx, 1, 0, + agentxctl_host)) == NULL || + (relaydHostErrno = agentx_object(sar, + AGENTX_OID(RELAYDHOSTERRNO), &relaydHostIdx, 1, 0, + agentxctl_host)) == NULL || + (relaydSessionIndex = agentx_object(sar, + AGENTX_OID(RELAYDSESSIONINDEX), session_idxs, 2, 0, + agentxctl_session)) == NULL || + (relaydSessionRelayIndex = agentx_object(sar, + AGENTX_OID(RELAYDSESSIONRELAYINDEX), session_idxs, 2, 0, + agentxctl_session)) == NULL || + (relaydSessionInAddr = agentx_object(sar, + AGENTX_OID(RELAYDSESSIONINADDR), session_idxs, 2, 0, + agentxctl_session)) == NULL || + (relaydSessionInAddrType = agentx_object(sar, + AGENTX_OID(RELAYDSESSIONINADDRTYPE), session_idxs, 2, 0, + agentxctl_session)) == NULL || + (relaydSessionOutAddr = agentx_object(sar, + AGENTX_OID(RELAYDSESSIONOUTADDR), session_idxs, 2, 0, + agentxctl_session)) == NULL || + (relaydSessionOutAddrType = agentx_object(sar, + AGENTX_OID(RELAYDSESSIONOUTADDRTYPE), session_idxs, 2, 0, + agentxctl_session)) == NULL || + (relaydSessionPortIn = agentx_object(sar, + AGENTX_OID(RELAYDSESSIONPORTIN), session_idxs, 2, 0, + agentxctl_session)) == NULL || + (relaydSessionPortOut = agentx_object(sar, + AGENTX_OID(RELAYDSESSIONPORTOUT), session_idxs, 2, 0, + agentxctl_session)) == NULL || + (relaydSessionAge = agentx_object(sar, + AGENTX_OID(RELAYDSESSIONAGE), session_idxs, 2, 0, + agentxctl_session)) == NULL || + (relaydSessionIdle = agentx_object(sar, + AGENTX_OID(RELAYDSESSIONIDLE), session_idxs, 2, 0, + agentxctl_session)) == NULL || + (relaydSessionStatus = agentx_object(sar, + AGENTX_OID(RELAYDSESSIONSTATUS), session_idxs, 2, 0, + agentxctl_session)) == NULL || + (relaydSessionPid = agentx_object(sar, + AGENTX_OID(RELAYDSESSIONPID), session_idxs, 2, 0, + agentxctl_session)) == NULL || + (relaydTableIndex = agentx_object(sar, + AGENTX_OID(RELAYDTABLEINDEX), &relaydTableIdx, 1, 0, + agentxctl_table)) == NULL || + (relaydTableName = agentx_object(sar, + AGENTX_OID(RELAYDTABLENAME), &relaydTableIdx, 1, 0, + agentxctl_table)) == NULL || + (relaydTableStatus = agentx_object(sar, + AGENTX_OID(RELAYDTABLESTATUS), &relaydTableIdx, 1, 0, + agentxctl_table)) == NULL) fatal("%s: agentx object alloc", __func__); } void -agentx_needsock(struct subagentx *usa, void *cookie, int fd) +agentx_needsock(struct agentx *usa, void *cookie, int fd) { proc_compose(env->sc_ps, PROC_PARENT, IMSG_AGENTXSOCK, NULL, 0); } @@ -461,7 +461,7 @@ agentx_getsock(struct imsg *imsg) agentx_sock, env); event_add(&(env->sc_agentxev), NULL); - subagentx_connect(sa, imsg->fd); + agentx_connect(sa, imsg->fd); return 0; retry: @@ -482,10 +482,10 @@ agentx_sock(int fd, short event, void *arg) event_set(&(env->sc_agentxev), fd, EV_READ | EV_PERSIST, agentx_sock, NULL); event_add(&(env->sc_agentxev), NULL); - subagentx_write(sa); + agentx_write(sa); } if (event & EV_READ) - subagentx_read(sa); + agentx_read(sa); return; } @@ -510,19 +510,19 @@ sstolen(struct sockaddr_storage *ss) } struct rdr * -agentx_rdr_byidx(uint32_t instanceidx, enum subagentx_request_type type) +agentxctl_rdr_byidx(uint32_t instanceidx, enum agentx_request_type type) { struct rdr *rdr; TAILQ_FOREACH(rdr, env->sc_rdrs, entry) { if (rdr->conf.id == instanceidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET || - type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) + if (type == AGENTX_REQUEST_TYPE_GET || + type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) return rdr; else return TAILQ_NEXT(rdr, entry); } else if (rdr->conf.id > instanceidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET) + if (type == AGENTX_REQUEST_TYPE_GET) return NULL; return rdr; } @@ -533,61 +533,61 @@ agentx_rdr_byidx(uint32_t instanceidx, enum subagentx_request_type type) void -agentx_redirect(struct subagentx_varbind *sav) +agentxctl_redirect(struct agentx_varbind *sav) { struct rdr *rdr; - rdr = agentx_rdr_byidx(subagentx_varbind_get_index_integer(sav, - relaydRedirectIdx), subagentx_varbind_request(sav)); + rdr = agentxctl_rdr_byidx(agentx_varbind_get_index_integer(sav, + relaydRedirectIdx), agentx_varbind_request(sav)); if (rdr == NULL) { - subagentx_varbind_notfound(sav); + agentx_varbind_notfound(sav); return; } - subagentx_varbind_set_index_integer(sav, relaydRedirectIdx, + agentx_varbind_set_index_integer(sav, relaydRedirectIdx, rdr->conf.id); - if (subagentx_varbind_get_object(sav) == relaydRedirectIndex) - subagentx_varbind_integer(sav, rdr->conf.id); - else if (subagentx_varbind_get_object(sav) == relaydRedirectStatus) { + if (agentx_varbind_get_object(sav) == relaydRedirectIndex) + agentx_varbind_integer(sav, rdr->conf.id); + else if (agentx_varbind_get_object(sav) == relaydRedirectStatus) { if (rdr->conf.flags & F_DISABLE) - subagentx_varbind_integer(sav, 1); + agentx_varbind_integer(sav, 1); else if (rdr->conf.flags & F_DOWN) - subagentx_varbind_integer(sav, 2); + agentx_varbind_integer(sav, 2); else if (rdr->conf.flags & F_BACKUP) - subagentx_varbind_integer(sav, 3); + agentx_varbind_integer(sav, 3); else - subagentx_varbind_integer(sav, 0); - } else if (subagentx_varbind_get_object(sav) == relaydRedirectName) - subagentx_varbind_string(sav, rdr->conf.name); - else if (subagentx_varbind_get_object(sav) == relaydRedirectCnt) - subagentx_varbind_counter64(sav, rdr->stats.cnt); - else if (subagentx_varbind_get_object(sav) == relaydRedirectAvg) - subagentx_varbind_gauge32(sav, rdr->stats.avg); - else if (subagentx_varbind_get_object(sav) == relaydRedirectLast) - subagentx_varbind_gauge32(sav, rdr->stats.last); - else if (subagentx_varbind_get_object(sav) == relaydRedirectAvgHour) - subagentx_varbind_gauge32(sav, rdr->stats.avg_hour); - else if (subagentx_varbind_get_object(sav) == relaydRedirectLastHour) - subagentx_varbind_gauge32(sav, rdr->stats.last_hour); - else if (subagentx_varbind_get_object(sav) == relaydRedirectAvgDay) - subagentx_varbind_gauge32(sav, rdr->stats.avg_day); - else if (subagentx_varbind_get_object(sav) == relaydRedirectLastDay) - subagentx_varbind_gauge32(sav, rdr->stats.last_day); + agentx_varbind_integer(sav, 0); + } else if (agentx_varbind_get_object(sav) == relaydRedirectName) + agentx_varbind_string(sav, rdr->conf.name); + else if (agentx_varbind_get_object(sav) == relaydRedirectCnt) + agentx_varbind_counter64(sav, rdr->stats.cnt); + else if (agentx_varbind_get_object(sav) == relaydRedirectAvg) + agentx_varbind_gauge32(sav, rdr->stats.avg); + else if (agentx_varbind_get_object(sav) == relaydRedirectLast) + agentx_varbind_gauge32(sav, rdr->stats.last); + else if (agentx_varbind_get_object(sav) == relaydRedirectAvgHour) + agentx_varbind_gauge32(sav, rdr->stats.avg_hour); + else if (agentx_varbind_get_object(sav) == relaydRedirectLastHour) + agentx_varbind_gauge32(sav, rdr->stats.last_hour); + else if (agentx_varbind_get_object(sav) == relaydRedirectAvgDay) + agentx_varbind_gauge32(sav, rdr->stats.avg_day); + else if (agentx_varbind_get_object(sav) == relaydRedirectLastDay) + agentx_varbind_gauge32(sav, rdr->stats.last_day); } struct relay * -agentx_relay_byidx(uint32_t instanceidx, enum subagentx_request_type type) +agentxctl_relay_byidx(uint32_t instanceidx, enum agentx_request_type type) { struct relay *rly; TAILQ_FOREACH(rly, env->sc_relays, rl_entry) { if (rly->rl_conf.id == instanceidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET || - type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) + if (type == AGENTX_REQUEST_TYPE_GET || + type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) return rly; else return TAILQ_NEXT(rly, rl_entry); } else if (rly->rl_conf.id > instanceidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET) + if (type == AGENTX_REQUEST_TYPE_GET) return NULL; return rly; } @@ -597,74 +597,74 @@ agentx_relay_byidx(uint32_t instanceidx, enum subagentx_request_type type) } void -agentx_relay(struct subagentx_varbind *sav) +agentxctl_relay(struct agentx_varbind *sav) { struct relay *rly; uint64_t value = 0; int i, nrelay = env->sc_conf.prefork_relay; - rly = agentx_relay_byidx(subagentx_varbind_get_index_integer(sav, - relaydRelayIdx), subagentx_varbind_request(sav)); + rly = agentxctl_relay_byidx(agentx_varbind_get_index_integer(sav, + relaydRelayIdx), agentx_varbind_request(sav)); if (rly == NULL) { - subagentx_varbind_notfound(sav); + agentx_varbind_notfound(sav); return; } - subagentx_varbind_set_index_integer(sav, relaydRelayIdx, + agentx_varbind_set_index_integer(sav, relaydRelayIdx, rly->rl_conf.id); - if (subagentx_varbind_get_object(sav) == relaydRelayIndex) - subagentx_varbind_integer(sav, rly->rl_conf.id); - else if (subagentx_varbind_get_object(sav) == relaydRelayStatus) { + if (agentx_varbind_get_object(sav) == relaydRelayIndex) + agentx_varbind_integer(sav, rly->rl_conf.id); + else if (agentx_varbind_get_object(sav) == relaydRelayStatus) { if (rly->rl_up == HOST_UP) - subagentx_varbind_integer(sav, 1); + agentx_varbind_integer(sav, 1); else - subagentx_varbind_integer(sav, 0); - } else if (subagentx_varbind_get_object(sav) == relaydRelayName) - subagentx_varbind_string(sav, rly->rl_conf.name); - else if (subagentx_varbind_get_object(sav) == relaydRelayCnt) { + agentx_varbind_integer(sav, 0); + } else if (agentx_varbind_get_object(sav) == relaydRelayName) + agentx_varbind_string(sav, rly->rl_conf.name); + else if (agentx_varbind_get_object(sav) == relaydRelayCnt) { for (i = 0; i < nrelay; i++) value += rly->rl_stats[i].cnt; - subagentx_varbind_counter64(sav, value); - } else if (subagentx_varbind_get_object(sav) == relaydRelayAvg) { + agentx_varbind_counter64(sav, value); + } else if (agentx_varbind_get_object(sav) == relaydRelayAvg) { for (i = 0; i < nrelay; i++) value += rly->rl_stats[i].avg; - subagentx_varbind_gauge32(sav, (uint32_t)value); - } else if (subagentx_varbind_get_object(sav) == relaydRelayLast) { + agentx_varbind_gauge32(sav, (uint32_t)value); + } else if (agentx_varbind_get_object(sav) == relaydRelayLast) { for (i = 0; i < nrelay; i++) value += rly->rl_stats[i].last; - subagentx_varbind_gauge32(sav, (uint32_t)value); - } else if (subagentx_varbind_get_object(sav) == relaydRelayAvgHour) { + agentx_varbind_gauge32(sav, (uint32_t)value); + } else if (agentx_varbind_get_object(sav) == relaydRelayAvgHour) { for (i = 0; i < nrelay; i++) value += rly->rl_stats[i].avg_hour; - subagentx_varbind_gauge32(sav, (uint32_t)value); - } else if (subagentx_varbind_get_object(sav) == relaydRelayLastHour) { + agentx_varbind_gauge32(sav, (uint32_t)value); + } else if (agentx_varbind_get_object(sav) == relaydRelayLastHour) { for (i = 0; i < nrelay; i++) value += rly->rl_stats[i].last_hour; - subagentx_varbind_gauge32(sav, (uint32_t)value); - } else if (subagentx_varbind_get_object(sav) == relaydRelayAvgDay) { + agentx_varbind_gauge32(sav, (uint32_t)value); + } else if (agentx_varbind_get_object(sav) == relaydRelayAvgDay) { for (i = 0; i < nrelay; i++) value += rly->rl_stats[i].avg_day; - subagentx_varbind_gauge32(sav, (uint32_t)value); - } else if (subagentx_varbind_get_object(sav) == relaydRelayLastDay) { + agentx_varbind_gauge32(sav, (uint32_t)value); + } else if (agentx_varbind_get_object(sav) == relaydRelayLastDay) { for (i = 0; i < nrelay; i++) value += rly->rl_stats[i].last_day; - subagentx_varbind_gauge32(sav, (uint32_t)value); + agentx_varbind_gauge32(sav, (uint32_t)value); } } struct router * -agentx_router_byidx(uint32_t instanceidx, enum subagentx_request_type type) +agentxctl_router_byidx(uint32_t instanceidx, enum agentx_request_type type) { struct router *router; TAILQ_FOREACH(router, env->sc_rts, rt_entry) { if (router->rt_conf.id == instanceidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET || - type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) + if (type == AGENTX_REQUEST_TYPE_GET || + type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) return router; else return TAILQ_NEXT(router, rt_entry); } else if (router->rt_conf.id > instanceidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET) + if (type == AGENTX_REQUEST_TYPE_GET) return NULL; return router; } @@ -674,49 +674,49 @@ agentx_router_byidx(uint32_t instanceidx, enum subagentx_request_type type) } void -agentx_router(struct subagentx_varbind *sav) +agentxctl_router(struct agentx_varbind *sav) { struct router *router; - router = agentx_router_byidx(subagentx_varbind_get_index_integer(sav, - relaydRouterIdx), subagentx_varbind_request(sav)); + router = agentxctl_router_byidx(agentx_varbind_get_index_integer(sav, + relaydRouterIdx), agentx_varbind_request(sav)); if (router == NULL) { - subagentx_varbind_notfound(sav); + agentx_varbind_notfound(sav); return; } - subagentx_varbind_set_index_integer(sav, relaydRouterIdx, + agentx_varbind_set_index_integer(sav, relaydRouterIdx, router->rt_conf.id); - if (subagentx_varbind_get_object(sav) == relaydRouterIndex) - subagentx_varbind_integer(sav, router->rt_conf.id); - else if (subagentx_varbind_get_object(sav) == relaydRouterTableIndex) - subagentx_varbind_integer(sav, router->rt_conf.gwtable); - else if (subagentx_varbind_get_object(sav) == relaydRouterStatus) { + if (agentx_varbind_get_object(sav) == relaydRouterIndex) + agentx_varbind_integer(sav, router->rt_conf.id); + else if (agentx_varbind_get_object(sav) == relaydRouterTableIndex) + agentx_varbind_integer(sav, router->rt_conf.gwtable); + else if (agentx_varbind_get_object(sav) == relaydRouterStatus) { if (router->rt_conf.flags & F_DISABLE) - subagentx_varbind_integer(sav, 1); + agentx_varbind_integer(sav, 1); else - subagentx_varbind_integer(sav, 0); - } else if (subagentx_varbind_get_object(sav) == relaydRouterName) - subagentx_varbind_string(sav, router->rt_conf.name); - else if (subagentx_varbind_get_object(sav) == relaydRouterLabel) - subagentx_varbind_string(sav, router->rt_conf.label); - else if (subagentx_varbind_get_object(sav) == relaydRouterRtable) - subagentx_varbind_integer(sav, router->rt_conf.rtable); + agentx_varbind_integer(sav, 0); + } else if (agentx_varbind_get_object(sav) == relaydRouterName) + agentx_varbind_string(sav, router->rt_conf.name); + else if (agentx_varbind_get_object(sav) == relaydRouterLabel) + agentx_varbind_string(sav, router->rt_conf.label); + else if (agentx_varbind_get_object(sav) == relaydRouterRtable) + agentx_varbind_integer(sav, router->rt_conf.rtable); } struct netroute * -agentx_netroute_byidx(uint32_t instanceidx, enum subagentx_request_type type) +agentxctl_netroute_byidx(uint32_t instanceidx, enum agentx_request_type type) { struct netroute *nr; TAILQ_FOREACH(nr, env->sc_routes, nr_route) { if (nr->nr_conf.id == instanceidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET || - type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) + if (type == AGENTX_REQUEST_TYPE_GET || + type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) return nr; else return TAILQ_NEXT(nr, nr_entry); } else if (nr->nr_conf.id > instanceidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET) + if (type == AGENTX_REQUEST_TYPE_GET) return NULL; return nr; } @@ -726,48 +726,48 @@ agentx_netroute_byidx(uint32_t instanceidx, enum subagentx_request_type type) } void -agentx_netroute(struct subagentx_varbind *sav) +agentxctl_netroute(struct agentx_varbind *sav) { struct netroute *nr; - nr = agentx_netroute_byidx(subagentx_varbind_get_index_integer(sav, - relaydNetRouteIdx), subagentx_varbind_request(sav)); + nr = agentxctl_netroute_byidx(agentx_varbind_get_index_integer(sav, + relaydNetRouteIdx), agentx_varbind_request(sav)); if (nr == NULL) { - subagentx_varbind_notfound(sav); + agentx_varbind_notfound(sav); return; } - subagentx_varbind_set_index_integer(sav, relaydNetRouteIdx, + agentx_varbind_set_index_integer(sav, relaydNetRouteIdx, nr->nr_conf.id); - if (subagentx_varbind_get_object(sav) == relaydNetRouteIndex) - subagentx_varbind_integer(sav, nr->nr_conf.id); - else if (subagentx_varbind_get_object(sav) == relaydNetRouteAddr) - subagentx_varbind_nstring(sav, sstodata(&nr->nr_conf.ss), + if (agentx_varbind_get_object(sav) == relaydNetRouteIndex) + agentx_varbind_integer(sav, nr->nr_conf.id); + else if (agentx_varbind_get_object(sav) == relaydNetRouteAddr) + agentx_varbind_nstring(sav, sstodata(&nr->nr_conf.ss), sstolen(&nr->nr_conf.ss)); - else if (subagentx_varbind_get_object(sav) == relaydNetRouteAddrType) { + else if (agentx_varbind_get_object(sav) == relaydNetRouteAddrType) { if (nr->nr_conf.ss.ss_family == AF_INET) - subagentx_varbind_integer(sav, 1); + agentx_varbind_integer(sav, 1); else if (nr->nr_conf.ss.ss_family == AF_INET6) - subagentx_varbind_integer(sav, 2); - } else if (subagentx_varbind_get_object(sav) == relaydNetRoutePrefixLen) - subagentx_varbind_integer(sav, nr->nr_conf.prefixlen); - else if (subagentx_varbind_get_object(sav) == relaydNetRouteRouterIndex) - subagentx_varbind_integer(sav, nr->nr_conf.routerid); + agentx_varbind_integer(sav, 2); + } else if (agentx_varbind_get_object(sav) == relaydNetRoutePrefixLen) + agentx_varbind_integer(sav, nr->nr_conf.prefixlen); + else if (agentx_varbind_get_object(sav) == relaydNetRouteRouterIndex) + agentx_varbind_integer(sav, nr->nr_conf.routerid); } struct host * -agentx_host_byidx(uint32_t instanceidx, enum subagentx_request_type type) +agentxctl_host_byidx(uint32_t instanceidx, enum agentx_request_type type) { struct host *host; TAILQ_FOREACH(host, &(env->sc_hosts), globalentry) { if (host->conf.id == instanceidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET || - type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) + if (type == AGENTX_REQUEST_TYPE_GET || + type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) return host; else return TAILQ_NEXT(host, globalentry); } else if (host->conf.id > instanceidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET) + if (type == AGENTX_REQUEST_TYPE_GET) return NULL; return host; } @@ -777,49 +777,49 @@ agentx_host_byidx(uint32_t instanceidx, enum subagentx_request_type type) } void -agentx_host(struct subagentx_varbind *sav) +agentxctl_host(struct agentx_varbind *sav) { struct host *host; - host = agentx_host_byidx(subagentx_varbind_get_index_integer(sav, - relaydHostIdx), subagentx_varbind_request(sav)); + host = agentxctl_host_byidx(agentx_varbind_get_index_integer(sav, + relaydHostIdx), agentx_varbind_request(sav)); if (host == NULL) { - subagentx_varbind_notfound(sav); + agentx_varbind_notfound(sav); return; } - subagentx_varbind_set_index_integer(sav, relaydHostIdx, + agentx_varbind_set_index_integer(sav, relaydHostIdx, host->conf.id); - if (subagentx_varbind_get_object(sav) == relaydHostIndex) - subagentx_varbind_integer(sav, host->conf.id); - else if (subagentx_varbind_get_object(sav) == relaydHostParentIndex) - subagentx_varbind_integer(sav, host->conf.parentid); - else if (subagentx_varbind_get_object(sav) == relaydHostTableIndex) - subagentx_varbind_integer(sav, host->conf.tableid); - else if (subagentx_varbind_get_object(sav) == relaydHostName) - subagentx_varbind_string(sav, host->conf.name); - else if (subagentx_varbind_get_object(sav) == relaydHostAddress) - subagentx_varbind_nstring(sav, sstodata(&host->conf.ss), + if (agentx_varbind_get_object(sav) == relaydHostIndex) + agentx_varbind_integer(sav, host->conf.id); + else if (agentx_varbind_get_object(sav) == relaydHostParentIndex) + agentx_varbind_integer(sav, host->conf.parentid); + else if (agentx_varbind_get_object(sav) == relaydHostTableIndex) + agentx_varbind_integer(sav, host->conf.tableid); + else if (agentx_varbind_get_object(sav) == relaydHostName) + agentx_varbind_string(sav, host->conf.name); + else if (agentx_varbind_get_object(sav) == relaydHostAddress) + agentx_varbind_nstring(sav, sstodata(&host->conf.ss), sstolen(&host->conf.ss)); - else if (subagentx_varbind_get_object(sav) == relaydHostAddressType) { + else if (agentx_varbind_get_object(sav) == relaydHostAddressType) { if (host->conf.ss.ss_family == AF_INET) - subagentx_varbind_integer(sav, 1); + agentx_varbind_integer(sav, 1); else if (host->conf.ss.ss_family == AF_INET6) - subagentx_varbind_integer(sav, 2); - } else if (subagentx_varbind_get_object(sav) == relaydHostStatus) { + agentx_varbind_integer(sav, 2); + } else if (agentx_varbind_get_object(sav) == relaydHostStatus) { if (host->flags & F_DISABLE) - subagentx_varbind_integer(sav, 1); + agentx_varbind_integer(sav, 1); else if (host->up == HOST_UP) - subagentx_varbind_integer(sav, 0); + agentx_varbind_integer(sav, 0); else if (host->up == HOST_DOWN) - subagentx_varbind_integer(sav, 2); + agentx_varbind_integer(sav, 2); else - subagentx_varbind_integer(sav, 3); - } else if (subagentx_varbind_get_object(sav) == relaydHostCheckCnt) - subagentx_varbind_counter64(sav, host->check_cnt); - else if (subagentx_varbind_get_object(sav) == relaydHostUpCnt) - subagentx_varbind_counter64(sav, host->up_cnt); - else if (subagentx_varbind_get_object(sav) == relaydHostErrno) - subagentx_varbind_integer(sav, host->he); + agentx_varbind_integer(sav, 3); + } else if (agentx_varbind_get_object(sav) == relaydHostCheckCnt) + agentx_varbind_counter64(sav, host->check_cnt); + else if (agentx_varbind_get_object(sav) == relaydHostUpCnt) + agentx_varbind_counter64(sav, host->up_cnt); + else if (agentx_varbind_get_object(sav) == relaydHostErrno) + agentx_varbind_integer(sav, host->he); } /* @@ -828,19 +828,19 @@ agentx_host(struct subagentx_varbind *sav) * is shown here */ struct rsession * -agentx_session_byidx(uint32_t sessidx, uint32_t relayidx, - enum subagentx_request_type type) +agentxctl_session_byidx(uint32_t sessidx, uint32_t relayidx, + enum agentx_request_type type) { struct rsession *session; TAILQ_FOREACH(session, &(env->sc_sessions), se_entry) { if (session->se_id == sessidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET) { + if (type == AGENTX_REQUEST_TYPE_GET) { if (relayidx != session->se_relayid) return NULL; return session; } - if (type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) { + if (type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) { if (relayidx <= session->se_relayid) return session; return TAILQ_NEXT(session, se_entry); @@ -849,7 +849,7 @@ agentx_session_byidx(uint32_t sessidx, uint32_t relayidx, return session; return TAILQ_NEXT(session, se_entry); } else if (session->se_id > sessidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET) + if (type == AGENTX_REQUEST_TYPE_GET) return NULL; return session; } @@ -859,82 +859,82 @@ agentx_session_byidx(uint32_t sessidx, uint32_t relayidx, } void -agentx_session(struct subagentx_varbind *sav) +agentxctl_session(struct agentx_varbind *sav) { struct timeval tv, now; struct rsession *session; - session = agentx_session_byidx(subagentx_varbind_get_index_integer(sav, - relaydSessionIdx), subagentx_varbind_get_index_integer(sav, - relaydSessionRelayIdx), subagentx_varbind_request(sav)); + session = agentxctl_session_byidx(agentx_varbind_get_index_integer(sav, + relaydSessionIdx), agentx_varbind_get_index_integer(sav, + relaydSessionRelayIdx), agentx_varbind_request(sav)); if (session == NULL) { - subagentx_varbind_notfound(sav); + agentx_varbind_notfound(sav); return; } - subagentx_varbind_set_index_integer(sav, relaydSessionIdx, + agentx_varbind_set_index_integer(sav, relaydSessionIdx, session->se_id); - subagentx_varbind_set_index_integer(sav, relaydSessionRelayIdx, + agentx_varbind_set_index_integer(sav, relaydSessionRelayIdx, session->se_relayid); - if (subagentx_varbind_get_object(sav) == relaydSessionIndex) - subagentx_varbind_integer(sav, session->se_id); - else if (subagentx_varbind_get_object(sav) == relaydSessionRelayIndex) - subagentx_varbind_integer(sav, session->se_relayid); - else if (subagentx_varbind_get_object(sav) == relaydSessionInAddr) - subagentx_varbind_nstring(sav, sstodata(&(session->se_in.ss)), + if (agentx_varbind_get_object(sav) == relaydSessionIndex) + agentx_varbind_integer(sav, session->se_id); + else if (agentx_varbind_get_object(sav) == relaydSessionRelayIndex) + agentx_varbind_integer(sav, session->se_relayid); + else if (agentx_varbind_get_object(sav) == relaydSessionInAddr) + agentx_varbind_nstring(sav, sstodata(&(session->se_in.ss)), sstolen(&(session->se_in.ss))); - else if (subagentx_varbind_get_object(sav) == relaydSessionInAddrType) { + else if (agentx_varbind_get_object(sav) == relaydSessionInAddrType) { if (session->se_in.ss.ss_family == AF_INET) - subagentx_varbind_integer(sav, 1); + agentx_varbind_integer(sav, 1); else if (session->se_in.ss.ss_family == AF_INET6) - subagentx_varbind_integer(sav, 2); - } else if (subagentx_varbind_get_object(sav) == relaydSessionOutAddr) - subagentx_varbind_nstring(sav, sstodata(&(session->se_out.ss)), + agentx_varbind_integer(sav, 2); + } else if (agentx_varbind_get_object(sav) == relaydSessionOutAddr) + agentx_varbind_nstring(sav, sstodata(&(session->se_out.ss)), sstolen(&(session->se_out.ss))); - else if (subagentx_varbind_get_object(sav) == relaydSessionOutAddrType) { + else if (agentx_varbind_get_object(sav) == relaydSessionOutAddrType) { if (session->se_out.ss.ss_family == AF_INET) - subagentx_varbind_integer(sav, 1); + agentx_varbind_integer(sav, 1); else if (session->se_out.ss.ss_family == AF_INET6) - subagentx_varbind_integer(sav, 2); + agentx_varbind_integer(sav, 2); else - subagentx_varbind_integer(sav, 0); - } else if (subagentx_varbind_get_object(sav) == relaydSessionPortIn) - subagentx_varbind_integer(sav, session->se_in.port); - else if (subagentx_varbind_get_object(sav) == relaydSessionPortOut) - subagentx_varbind_integer(sav, session->se_out.port); - else if (subagentx_varbind_get_object(sav) == relaydSessionAge) { + agentx_varbind_integer(sav, 0); + } else if (agentx_varbind_get_object(sav) == relaydSessionPortIn) + agentx_varbind_integer(sav, session->se_in.port); + else if (agentx_varbind_get_object(sav) == relaydSessionPortOut) + agentx_varbind_integer(sav, session->se_out.port); + else if (agentx_varbind_get_object(sav) == relaydSessionAge) { getmonotime(&now); timersub(&now, &session->se_tv_start, &tv); - subagentx_varbind_timeticks(sav, + agentx_varbind_timeticks(sav, tv.tv_sec * 100 + tv.tv_usec / 10000); - } else if (subagentx_varbind_get_object(sav) == relaydSessionIdle) { + } else if (agentx_varbind_get_object(sav) == relaydSessionIdle) { getmonotime(&now); timersub(&now, &session->se_tv_last, &tv); - subagentx_varbind_timeticks(sav, + agentx_varbind_timeticks(sav, tv.tv_sec * 100 + tv.tv_usec / 10000); - } else if (subagentx_varbind_get_object(sav) == relaydSessionStatus) { + } else if (agentx_varbind_get_object(sav) == relaydSessionStatus) { if (session->se_done) - subagentx_varbind_integer(sav, 1); + agentx_varbind_integer(sav, 1); else - subagentx_varbind_integer(sav, 0); - } else if (subagentx_varbind_get_object(sav) == relaydSessionPid) - subagentx_varbind_integer(sav, session->se_pid); + agentx_varbind_integer(sav, 0); + } else if (agentx_varbind_get_object(sav) == relaydSessionPid) + agentx_varbind_integer(sav, session->se_pid); } struct table * -agentx_table_byidx(uint32_t instanceidx, enum subagentx_request_type type) +agentxctl_table_byidx(uint32_t instanceidx, enum agentx_request_type type) { struct table *table; TAILQ_FOREACH(table, env->sc_tables, entry) { if (table->conf.id == instanceidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET || - type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) + if (type == AGENTX_REQUEST_TYPE_GET || + type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) return table; else return TAILQ_NEXT(table, entry); } else if (table->conf.id > instanceidx) { - if (type == SUBAGENTX_REQUEST_TYPE_GET) + if (type == AGENTX_REQUEST_TYPE_GET) return NULL; return table; } @@ -944,29 +944,29 @@ agentx_table_byidx(uint32_t instanceidx, enum subagentx_request_type type) } void -agentx_table(struct subagentx_varbind *sav) +agentxctl_table(struct agentx_varbind *sav) { struct table *table; - table = agentx_table_byidx(subagentx_varbind_get_index_integer(sav, - relaydTableIdx), subagentx_varbind_request(sav)); + table = agentxctl_table_byidx(agentx_varbind_get_index_integer(sav, + relaydTableIdx), agentx_varbind_request(sav)); if (table == NULL) { - subagentx_varbind_notfound(sav); + agentx_varbind_notfound(sav); return; } - subagentx_varbind_set_index_integer(sav, relaydTableIdx, + agentx_varbind_set_index_integer(sav, relaydTableIdx, table->conf.id); - if (subagentx_varbind_get_object(sav) == relaydTableIndex) - subagentx_varbind_integer(sav, table->conf.id); - else if (subagentx_varbind_get_object(sav) == relaydTableName) - subagentx_varbind_string(sav, table->conf.name); - else if (subagentx_varbind_get_object(sav) == relaydTableStatus) { + if (agentx_varbind_get_object(sav) == relaydTableIndex) + agentx_varbind_integer(sav, table->conf.id); + else if (agentx_varbind_get_object(sav) == relaydTableName) + agentx_varbind_string(sav, table->conf.name); + else if (agentx_varbind_get_object(sav) == relaydTableStatus) { if (TAILQ_EMPTY(&table->hosts)) - subagentx_varbind_integer(sav, 1); + agentx_varbind_integer(sav, 1); else if (table->conf.flags & F_DISABLE) - subagentx_varbind_integer(sav, 2); + agentx_varbind_integer(sav, 2); else - subagentx_varbind_integer(sav, 0); + agentx_varbind_integer(sav, 0); } } diff --git a/usr.sbin/relayd/parse.y b/usr.sbin/relayd/parse.y index 0b75d4781cc..4dde64f2252 100644 --- a/usr.sbin/relayd/parse.y +++ b/usr.sbin/relayd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.247 2020/10/25 10:17:49 denis Exp $ */ +/* $OpenBSD: parse.y,v 1.248 2020/10/26 16:52:06 martijn Exp $ */ /* * Copyright (c) 2007 - 2014 Reyk Floeter <reyk@openbsd.org> @@ -39,6 +39,7 @@ #include <net/pfvar.h> #include <net/route.h> +#include <agentx.h> #include <stdint.h> #include <stdarg.h> #include <stdio.h> @@ -56,7 +57,6 @@ #include "relayd.h" #include "http.h" -#include "subagentx.h" TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files); static struct file { @@ -454,7 +454,7 @@ main : INTERVAL NUMBER { free($3); } else (void)strlcpy(conf->sc_conf.agentx_path, - SUBAGENTX_AGENTX_MASTER, + AGENTX_MASTER_PATH, sizeof(conf->sc_conf.agentx_path)); } | SNMP trap optstring { diff --git a/usr.sbin/relayd/subagentx.c b/usr.sbin/relayd/subagentx.c deleted file mode 100644 index 4d34b28304d..00000000000 --- a/usr.sbin/relayd/subagentx.c +++ /dev/null @@ -1,4003 +0,0 @@ -/* - * Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include <netinet/in.h> - -#include <errno.h> -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <strings.h> -#include <time.h> -#include <unistd.h> - -#include "subagentx_internal.h" -#include "subagentx.h" - -enum subagentx_index_type { - SAI_TYPE_NEW, - SAI_TYPE_ANY, - SAI_TYPE_VALUE, - SAI_TYPE_DYNAMIC -}; - -#define SUBAGENTX_CONTEXT_CTX(sac) (sac->sac_name_default ? NULL : \ - &(sac->sac_name)) - -struct subagentx_agentcaps { - struct subagentx_context *saa_sac; - struct agentx_oid saa_oid; - struct agentx_ostring saa_descr; - enum subagentx_cstate saa_cstate; - enum subagentx_dstate saa_dstate; - TAILQ_ENTRY(subagentx_agentcaps) saa_sac_agentcaps; -}; - -struct subagentx_region { - struct subagentx_context *sar_sac; - struct agentx_oid sar_oid; - uint8_t sar_timeout; - uint8_t sar_priority; - enum subagentx_cstate sar_cstate; - enum subagentx_dstate sar_dstate; - TAILQ_HEAD(, subagentx_index) sar_indices; - TAILQ_HEAD(, subagentx_object) sar_objects; - TAILQ_ENTRY(subagentx_region) sar_sac_regions; -}; - -struct subagentx_index { - struct subagentx_region *sai_sar; - enum subagentx_index_type sai_type; - struct agentx_varbind sai_vb; - struct subagentx_object **sai_object; - size_t sai_objectlen; - size_t sai_objectsize; - enum subagentx_cstate sai_cstate; - enum subagentx_dstate sai_dstate; - TAILQ_ENTRY(subagentx_index) sai_sar_indices; -}; - -struct subagentx_object { - struct subagentx_region *sao_sar; - struct agentx_oid sao_oid; - struct subagentx_index *sao_index[SUBAGENTX_OID_INDEX_MAX_LEN]; - size_t sao_indexlen; - int sao_implied; - uint8_t sao_timeout; - /* Prevent freeing object while in use by get and set requesets */ - uint32_t sao_lock; - void (*sao_get)(struct subagentx_varbind *); - enum subagentx_cstate sao_cstate; - enum subagentx_dstate sao_dstate; - RB_ENTRY(subagentx_object) sao_sac_objects; - TAILQ_ENTRY(subagentx_object) sao_sar_objects; -}; - -struct subagentx_varbind { - struct subagentx_get *sav_sag; - struct subagentx_object *sav_sao; - struct subagentx_varbind_index { - struct subagentx_index *sav_sai; - union agentx_data sav_idata; - uint8_t sav_idatacomplete; - } sav_index[SUBAGENTX_OID_INDEX_MAX_LEN]; - size_t sav_indexlen; - int sav_initialized; - int sav_include; - struct agentx_varbind sav_vb; - struct agentx_oid sav_start; - struct agentx_oid sav_end; - enum agentx_pdu_error sav_error; -}; - -#define SUBAGENTX_GET_CTX(sag) (sag->sag_context_default ? NULL : \ - &(sag->sag_context)) -struct subagentx_request { - uint32_t sar_packetid; - int (*sar_cb)(struct agentx_pdu *, void *); - void *sar_cookie; - RB_ENTRY(subagentx_request) sar_sa_requests; -}; - -static void subagentx_start(struct subagentx *); -static void subagentx_finalize(struct subagentx *, int); -static void subagentx_wantwritenow(struct subagentx *, int); -void (*subagentx_wantwrite)(struct subagentx *, int) = - subagentx_wantwritenow; -static void subagentx_reset(struct subagentx *); -static void subagentx_free_finalize(struct subagentx *); -static int subagentx_session_start(struct subagentx_session *); -static int subagentx_session_finalize(struct agentx_pdu *, void *); -static int subagentx_session_close(struct subagentx_session *, - enum agentx_close_reason); -static int subagentx_session_close_finalize(struct agentx_pdu *, void *); -static void subagentx_session_free_finalize(struct subagentx_session *); -static void subagentx_session_reset(struct subagentx_session *); -static void subagentx_context_start(struct subagentx_context *); -static void subagentx_context_free_finalize(struct subagentx_context *); -static void subagentx_context_reset(struct subagentx_context *); -static int subagentx_agentcaps_start(struct subagentx_agentcaps *); -static int subagentx_agentcaps_finalize(struct agentx_pdu *, void *); -static int subagentx_agentcaps_close(struct subagentx_agentcaps *); -static int subagentx_agentcaps_close_finalize(struct agentx_pdu *, void *); -static void subagentx_agentcaps_free_finalize(struct subagentx_agentcaps *); -static void subagentx_agentcaps_reset(struct subagentx_agentcaps *); -static int subagentx_region_start(struct subagentx_region *); -static int subagentx_region_finalize(struct agentx_pdu *, void *); -static int subagentx_region_close(struct subagentx_region *); -static int subagentx_region_close_finalize(struct agentx_pdu *, void *); -static void subagentx_region_free_finalize(struct subagentx_region *); -static void subagentx_region_reset(struct subagentx_region *); -static struct subagentx_index *subagentx_index(struct subagentx_region *, - struct agentx_varbind *, enum subagentx_index_type); -static int subagentx_index_start(struct subagentx_index *); -static int subagentx_index_finalize(struct agentx_pdu *, void *); -static void subagentx_index_free_finalize(struct subagentx_index *); -static void subagentx_index_reset(struct subagentx_index *); -static int subagentx_index_close(struct subagentx_index *); -static int subagentx_index_close_finalize(struct agentx_pdu *, void *); -static int subagentx_object_start(struct subagentx_object *); -static int subagentx_object_finalize(struct agentx_pdu *, void *); -static int subagentx_object_lock(struct subagentx_object *); -static void subagentx_object_unlock(struct subagentx_object *); -static int subagentx_object_close(struct subagentx_object *); -static int subagentx_object_close_finalize(struct agentx_pdu *, void *); -static void subagentx_object_free_finalize(struct subagentx_object *); -static void subagentx_object_reset(struct subagentx_object *); -static int subagentx_object_cmp(struct subagentx_object *, - struct subagentx_object *); -static void subagentx_get_start(struct subagentx_context *, - struct agentx_pdu *); -static void subagentx_get_finalize(struct subagentx_get *); -static void subagentx_get_free(struct subagentx_get *); -static void subagentx_varbind_start(struct subagentx_varbind *); -static void subagentx_varbind_finalize(struct subagentx_varbind *); -static void subagentx_varbind_nosuchobject(struct subagentx_varbind *); -static void subagentx_varbind_nosuchinstance(struct subagentx_varbind *); -static void subagentx_varbind_endofmibview(struct subagentx_varbind *); -static void subagentx_varbind_error_type(struct subagentx_varbind *, - enum agentx_pdu_error, int); -static int subagentx_request(struct subagentx *, uint32_t, - int (*)(struct agentx_pdu *, void *), void *); -static int subagentx_request_cmp(struct subagentx_request *, - struct subagentx_request *); -static int subagentx_strcat(char **, const char *); - -RB_PROTOTYPE_STATIC(sa_requests, subagentx_request, sar_sa_requests, - subagentx_request_cmp) -RB_PROTOTYPE_STATIC(sac_objects, subagentx_object, sao_sac_objects, - subagentx_object_cmp) - -struct subagentx * -subagentx(void (*nofd)(struct subagentx *, void *, int), void *cookie) -{ - struct subagentx *sa; - - if ((sa = calloc(1, sizeof(*sa))) == NULL) - return NULL; - - sa->sa_nofd = nofd; - sa->sa_cookie = cookie; - sa->sa_fd = -1; - sa->sa_cstate = SA_CSTATE_CLOSE; - sa->sa_dstate = SA_DSTATE_OPEN; - TAILQ_INIT(&(sa->sa_sessions)); - TAILQ_INIT(&(sa->sa_getreqs)); - RB_INIT(&(sa->sa_requests)); - - subagentx_start(sa); - - return sa; -} - -/* - * subagentx_finalize is not a suitable name for a public API, - * but use it internally for consistency - */ -void -subagentx_connect(struct subagentx *sa, int fd) -{ - subagentx_finalize(sa, fd); -} - -static void -subagentx_start(struct subagentx *sa) -{ -#ifdef AGENTX_DEBUG - if (sa->sa_cstate != SA_CSTATE_CLOSE || - sa->sa_dstate != SA_DSTATE_OPEN) - subagentx_log_sa_fatalx(sa, "%s: unexpected connect", __func__); -#endif - sa->sa_cstate = SA_CSTATE_WAITOPEN; - sa->sa_nofd(sa, sa->sa_cookie, 0); -} - -static void -subagentx_finalize(struct subagentx *sa, int fd) -{ - struct subagentx_session *sas; - - if (sa->sa_cstate != SA_CSTATE_WAITOPEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sa_fatalx(sa, "%s: subagentx unexpected connect", - __func__); -#else - subagentx_log_sa_warnx(sa, - "%s: subagentx unexpected connect: ignoring", __func__); - return; -#endif - } - if ((sa->sa_ax = agentx_new(fd)) == NULL) { - subagentx_log_sa_warn(sa, "failed to initialize"); - close(fd); - subagentx_reset(sa); - return; - } - - subagentx_log_sa_info(sa, "new connection: %d", fd); - - sa->sa_fd = fd; - sa->sa_cstate = SA_CSTATE_OPEN; - - TAILQ_FOREACH(sas, &(sa->sa_sessions), sas_sa_sessions) { - if (subagentx_session_start(sas) == -1) - break; - } -} - -static void -subagentx_wantwritenow(struct subagentx *sa, int fd) -{ - subagentx_write(sa); -} - -static void -subagentx_reset(struct subagentx *sa) -{ - struct subagentx_session *sas, *tsas; - struct subagentx_request *sar; - struct subagentx_get *sag; - - agentx_free(sa->sa_ax); - sa->sa_ax = NULL; - sa->sa_fd = -1; - - sa->sa_cstate = SA_CSTATE_CLOSE; - - while ((sar = RB_MIN(sa_requests, &(sa->sa_requests))) != NULL) { - RB_REMOVE(sa_requests, &(sa->sa_requests), sar); - free(sar); - } - TAILQ_FOREACH_SAFE(sas, &(sa->sa_sessions), sas_sa_sessions, tsas) - subagentx_session_reset(sas); - while (!TAILQ_EMPTY(&(sa->sa_getreqs))) { - sag = TAILQ_FIRST(&(sa->sa_getreqs)); - sag->sag_sac = NULL; - TAILQ_REMOVE(&(sa->sa_getreqs), sag, sag_sa_getreqs); - } - - if (sa->sa_dstate == SA_DSTATE_CLOSE) { - subagentx_free_finalize(sa); - return; - } - - subagentx_start(sa); -} - -void -subagentx_free(struct subagentx *sa) -{ - struct subagentx_session *sas, *tsas; - - if (sa == NULL) - return; - - if (sa->sa_dstate == SA_DSTATE_CLOSE) { -/* Malloc throws abort on invalid pointers as well */ - subagentx_log_sa_fatalx(sa, "%s: double free", __func__); - } - sa->sa_dstate = SA_DSTATE_CLOSE; - - if (!TAILQ_EMPTY(&(sa->sa_sessions))) { - TAILQ_FOREACH_SAFE(sas, &(sa->sa_sessions), sas_sa_sessions, - tsas) { - if (sas->sas_dstate != SA_DSTATE_CLOSE) - subagentx_session_free(sas); - } - } else - subagentx_free_finalize(sa); -} - -static void -subagentx_free_finalize(struct subagentx *sa) -{ -#ifdef AGENTX_DEBUG - if (sa->sa_dstate != SA_DSTATE_CLOSE) - subagentx_log_sa_fatalx(sa, "%s: subagentx not closing", - __func__); - if (!TAILQ_EMPTY(&(sa->sa_sessions))) - subagentx_log_sa_fatalx(sa, "%s: subagentx still has sessions", - __func__); - if (!RB_EMPTY(&(sa->sa_requests))) - subagentx_log_sa_fatalx(sa, - "%s: subagentx still has pending requests", __func__); -#endif - - agentx_free(sa->sa_ax); - sa->sa_nofd(sa, sa->sa_cookie, 1); - free(sa); -} - -struct subagentx_session * -subagentx_session(struct subagentx *sa, uint32_t oid[], - size_t oidlen, const char *descr, uint8_t timeout) -{ - struct subagentx_session *sas; - size_t i; - - if (oidlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sa_fatalx(sa, "%s: oidlen > %d", __func__, - SUBAGENTX_OID_MAX_LEN); -#else - errno = EINVAL; - return NULL; -#endif - } - if ((sas = calloc(1, sizeof(*sas))) == NULL) - return NULL; - - sas->sas_sa = sa; - sas->sas_timeout = timeout; - for (i = 0; i < oidlen; i++) - sas->sas_oid.aoi_id[i] = oid[i]; - sas->sas_oid.aoi_idlen = oidlen; - sas->sas_descr.aos_string = (unsigned char *)strdup(descr); - if (sas->sas_descr.aos_string == NULL) { - free(sas); - return NULL; - } - sas->sas_descr.aos_slen = strlen(descr); - sas->sas_cstate = SA_CSTATE_CLOSE; - sas->sas_dstate = SA_DSTATE_OPEN; - TAILQ_INIT(&(sas->sas_contexts)); - TAILQ_INSERT_HEAD(&(sa->sa_sessions), sas, sas_sa_sessions); - - if (sa->sa_cstate == SA_CSTATE_OPEN) - (void) subagentx_session_start(sas); - - return sas; -} - -static int -subagentx_session_start(struct subagentx_session *sas) -{ - struct subagentx *sa = sas->sas_sa; - uint32_t packetid; - -#ifdef AGENTX_DEBUG - if (sa->sa_cstate != SA_CSTATE_OPEN || - sas->sas_cstate != SA_CSTATE_CLOSE || - sas->sas_dstate != SA_DSTATE_OPEN) - subagentx_log_sa_fatalx(sa, "%s: unexpected session open", - __func__); -#endif - packetid = agentx_open(sa->sa_ax, sas->sas_timeout, &(sas->sas_oid), - &(sas->sas_descr)); - if (packetid == 0) { - subagentx_log_sa_warn(sa, "couldn't generate %s", - agentx_pdutype2string(AGENTX_PDU_TYPE_OPEN)); - subagentx_reset(sa); - return -1; - } - sas->sas_packetid = packetid; - subagentx_log_sa_info(sa, "opening session"); - sas->sas_cstate = SA_CSTATE_WAITOPEN; - return subagentx_request(sa, packetid, subagentx_session_finalize, sas); -} - -static int -subagentx_session_finalize(struct agentx_pdu *pdu, void *cookie) -{ - struct subagentx_session *sas = cookie; - struct subagentx *sa = sas->sas_sa; - struct subagentx_context *sac; - -#ifdef AGENTX_DEBUG - if (sas->sas_cstate != SA_CSTATE_WAITOPEN) - subagentx_log_sa_fatalx(sa, "%s: not expecting new session", - __func__); -#endif - - if (pdu->ap_payload.ap_response.ap_error != AGENTX_PDU_ERROR_NOERROR) { - subagentx_log_sa_warnx(sa, "failed to open session: %s", - agentx_error2string(pdu->ap_payload.ap_response.ap_error)); - subagentx_reset(sa); - return -1; - } - - sas->sas_id = pdu->ap_header.aph_sessionid; - sas->sas_cstate = SA_CSTATE_OPEN; - - if (sas->sas_dstate == SA_DSTATE_CLOSE) { - subagentx_session_close(sas, AGENTX_CLOSE_SHUTDOWN); - return 0; - } - - subagentx_log_sas_info(sas, "open"); - - TAILQ_FOREACH(sac, &(sas->sas_contexts), sac_sas_contexts) - subagentx_context_start(sac); - return 0; -} - -static int -subagentx_session_close(struct subagentx_session *sas, - enum agentx_close_reason reason) -{ - struct subagentx *sa = sas->sas_sa; - uint32_t packetid; - -#ifdef AGENTX_DEBUG - if (sas->sas_cstate != SA_CSTATE_OPEN) - subagentx_log_sa_fatalx(sa, "%s: unexpected session close", - __func__); -#endif - if ((packetid = agentx_close(sa->sa_ax, sas->sas_id, reason)) == 0) { - subagentx_log_sas_warn(sas, "couldn't generate %s", - agentx_pdutype2string(AGENTX_PDU_TYPE_CLOSE)); - subagentx_reset(sa); - return -1; - } - - subagentx_log_sas_info(sas, "closing session: %s", - agentx_closereason2string(reason)); - - sas->sas_cstate = SA_CSTATE_WAITCLOSE; - return subagentx_request(sa, packetid, subagentx_session_close_finalize, - sas); -} - -static int -subagentx_session_close_finalize(struct agentx_pdu *pdu, void *cookie) -{ - struct subagentx_session *sas = cookie; - struct subagentx *sa = sas->sas_sa; - struct subagentx_context *sac, *tsac; - -#ifdef AGENTX_DEBUG - if (sas->sas_cstate != SA_CSTATE_WAITCLOSE) - subagentx_log_sas_fatalx(sas, "%s: not expecting session close", - __func__); -#endif - - if (pdu->ap_payload.ap_response.ap_error != AGENTX_PDU_ERROR_NOERROR) { - subagentx_log_sas_warnx(sas, "failed to close session: %s", - agentx_error2string(pdu->ap_payload.ap_response.ap_error)); - subagentx_reset(sa); - return -1; - } - - sas->sas_cstate = SA_CSTATE_CLOSE; - - subagentx_log_sas_info(sas, "closed"); - - TAILQ_FOREACH_SAFE(sac, &(sas->sas_contexts), sac_sas_contexts, tsac) - subagentx_context_reset(sac); - - if (sas->sas_dstate == SA_DSTATE_CLOSE) - subagentx_session_free_finalize(sas); - else { - if (sa->sa_cstate == SA_CSTATE_OPEN) - if (subagentx_session_start(sas) == -1) - return -1; - } - return 0; -} - -void -subagentx_session_free(struct subagentx_session *sas) -{ - struct subagentx_context *sac, *tsac; - - if (sas == NULL) - return; - - if (sas->sas_dstate == SA_DSTATE_CLOSE) - subagentx_log_sas_fatalx(sas, "%s: double free", __func__); - - sas->sas_dstate = SA_DSTATE_CLOSE; - - if (sas->sas_cstate == SA_CSTATE_OPEN) - (void) subagentx_session_close(sas, AGENTX_CLOSE_SHUTDOWN); - - TAILQ_FOREACH_SAFE(sac, &(sas->sas_contexts), sac_sas_contexts, tsac) { - if (sac->sac_dstate != SA_DSTATE_CLOSE) - subagentx_context_free(sac); - } - - if (sas->sas_cstate == SA_CSTATE_CLOSE) - subagentx_session_free_finalize(sas); -} - -static void -subagentx_session_free_finalize(struct subagentx_session *sas) -{ - struct subagentx *sa = sas->sas_sa; - -#ifdef AGENTX_DEBUG - if (sas->sas_cstate != SA_CSTATE_CLOSE) - subagentx_log_sas_fatalx(sas, "%s: free without closing", - __func__); - if (!TAILQ_EMPTY(&(sas->sas_contexts))) - subagentx_log_sas_fatalx(sas, - "%s: subagentx still has contexts", __func__); -#endif - - TAILQ_REMOVE(&(sa->sa_sessions), sas, sas_sa_sessions); - free(sas->sas_descr.aos_string); - free(sas); - - if (TAILQ_EMPTY(&(sa->sa_sessions)) && sa->sa_dstate == SA_DSTATE_CLOSE) - subagentx_free_finalize(sa); -} - -static void -subagentx_session_reset(struct subagentx_session *sas) -{ - struct subagentx_context *sac, *tsac; - - sas->sas_cstate = SA_CSTATE_CLOSE; - - TAILQ_FOREACH_SAFE(sac, &(sas->sas_contexts), sac_sas_contexts, tsac) - subagentx_context_reset(sac); - - if (sas->sas_dstate == SA_DSTATE_CLOSE) - subagentx_session_free_finalize(sas); -} - -struct subagentx_context * -subagentx_context(struct subagentx_session *sas, const char *name) -{ - struct subagentx_context *sac; - - if (sas->sas_dstate == SA_DSTATE_CLOSE) - subagentx_log_sas_fatalx(sas, "%s: use after free", __func__); - - if ((sac = calloc(1, sizeof(*sac))) == NULL) - return NULL; - - sac->sac_sas = sas; - sac->sac_name_default = (name == NULL); - if (name != NULL) { - sac->sac_name.aos_string = (unsigned char *)strdup(name); - if (sac->sac_name.aos_string == NULL) { - free(sac); - return NULL; - } - sac->sac_name.aos_slen = strlen(name); - } - sac->sac_cstate = sas->sas_cstate == SA_CSTATE_OPEN ? - SA_CSTATE_OPEN : SA_CSTATE_CLOSE; - sac->sac_dstate = SA_DSTATE_OPEN; - TAILQ_INIT(&(sac->sac_agentcaps)); - TAILQ_INIT(&(sac->sac_regions)); - - TAILQ_INSERT_HEAD(&(sas->sas_contexts), sac, sac_sas_contexts); - - return sac; -} - -static void -subagentx_context_start(struct subagentx_context *sac) -{ - struct subagentx_agentcaps *saa; - struct subagentx_region *sar; - -#ifdef AGENTX_DEBUG - if (sac->sac_cstate != SA_CSTATE_CLOSE) - subagentx_log_sac_fatalx(sac, "%s: unexpected context start", - __func__); -#endif - sac->sac_cstate = SA_CSTATE_OPEN; - - TAILQ_FOREACH(saa, &(sac->sac_agentcaps), saa_sac_agentcaps) { - if (subagentx_agentcaps_start(saa) == -1) - return; - } - TAILQ_FOREACH(sar, &(sac->sac_regions), sar_sac_regions) { - if (subagentx_region_start(sar) == -1) - return; - } -} - -uint32_t -subagentx_context_uptime(struct subagentx_context *sac) -{ - struct timespec cur, res; - - if (sac->sac_sysuptimespec.tv_sec == 0 && - sac->sac_sysuptimespec.tv_nsec == 0) - return 0; - - (void) clock_gettime(CLOCK_MONOTONIC, &cur); - - timespecsub(&cur, &(sac->sac_sysuptimespec), &res); - - return sac->sac_sysuptime + - (uint32_t) ((res.tv_sec * 100) + (res.tv_nsec / 10000000)); -} - -struct subagentx_object * -subagentx_context_object_find(struct subagentx_context *sac, - const uint32_t oid[], size_t oidlen, int active, int instance) -{ - struct subagentx_object *sao, sao_search; - size_t i; - - for (i = 0; i < oidlen; i++) - sao_search.sao_oid.aoi_id[i] = oid[i]; - sao_search.sao_oid.aoi_idlen = oidlen; - - sao = RB_FIND(sac_objects, &(sac->sac_objects), &sao_search); - while (sao == NULL && !instance && sao_search.sao_oid.aoi_idlen > 0) { - sao = RB_FIND(sac_objects, &(sac->sac_objects), &sao_search); - sao_search.sao_oid.aoi_idlen--; - } - if (active && sao != NULL && sao->sao_cstate != SA_CSTATE_OPEN) - return NULL; - return sao; -} - -struct subagentx_object * -subagentx_context_object_nfind(struct subagentx_context *sac, - const uint32_t oid[], size_t oidlen, int active, int inclusive) -{ - struct subagentx_object *sao, sao_search; - size_t i; - - for (i = 0; i < oidlen; i++) - sao_search.sao_oid.aoi_id[i] = oid[i]; - sao_search.sao_oid.aoi_idlen = oidlen; - - sao = RB_NFIND(sac_objects, &(sac->sac_objects), &sao_search); - if (!inclusive && sao != NULL && - agentx_oid_cmp(&(sao_search.sao_oid), &(sao->sao_oid)) <= 0) { - sao = RB_NEXT(sac_objects, &(sac->sac_objects), sao); - } - - while (active && sao != NULL && sao->sao_cstate != SA_CSTATE_OPEN) - sao = RB_NEXT(sac_objects, &(sac->sac_objects), sao); - return sao; -} - -void -subagentx_context_free(struct subagentx_context *sac) -{ - struct subagentx_agentcaps *saa, *tsaa; - struct subagentx_region *sar, *tsar; - - if (sac == NULL) - return; - -#ifdef AGENTX_DEBUG - if (sac->sac_dstate == SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(sac, "%s: double free", __func__); -#endif - sac->sac_dstate = SA_DSTATE_CLOSE; - - TAILQ_FOREACH_SAFE(saa, &(sac->sac_agentcaps), saa_sac_agentcaps, - tsaa) { - if (saa->saa_dstate != SA_DSTATE_CLOSE) - subagentx_agentcaps_free(saa); - } - TAILQ_FOREACH_SAFE(sar, &(sac->sac_regions), sar_sac_regions, tsar) { - if (sar->sar_dstate != SA_DSTATE_CLOSE) - subagentx_region_free(sar); - } -} - -static void -subagentx_context_free_finalize(struct subagentx_context *sac) -{ - struct subagentx_session *sas = sac->sac_sas; - -#ifdef AGENTX_DEBUG - if (sac->sac_dstate != SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(sac, "%s: unexpected context free", - __func__); -#endif - if (!TAILQ_EMPTY(&(sac->sac_regions)) || - !TAILQ_EMPTY(&(sac->sac_agentcaps))) - return; - TAILQ_REMOVE(&(sas->sas_contexts), sac, sac_sas_contexts); - free(sac->sac_name.aos_string); - free(sac); -} - -static void -subagentx_context_reset(struct subagentx_context *sac) -{ - struct subagentx_agentcaps *saa, *tsaa; - struct subagentx_region *sar, *tsar; - - sac->sac_cstate = SA_CSTATE_CLOSE; - sac->sac_sysuptimespec.tv_sec = 0; - sac->sac_sysuptimespec.tv_nsec = 0; - - TAILQ_FOREACH_SAFE(saa, &(sac->sac_agentcaps), saa_sac_agentcaps, tsaa) - subagentx_agentcaps_reset(saa); - TAILQ_FOREACH_SAFE(sar, &(sac->sac_regions), sar_sac_regions, tsar) - subagentx_region_reset(sar); - - if (sac->sac_dstate == SA_DSTATE_CLOSE) - subagentx_context_free_finalize(sac); -} - -struct subagentx_agentcaps * -subagentx_agentcaps(struct subagentx_context *sac, uint32_t oid[], - size_t oidlen, const char *descr) -{ - struct subagentx_agentcaps *saa; - size_t i; - - if (sac->sac_dstate == SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(sac, "%s: use after free", __func__); - - if ((saa = calloc(1, sizeof(*saa))) == NULL) - return NULL; - - saa->saa_sac = sac; - for (i = 0; i < oidlen; i++) - saa->saa_oid.aoi_id[i] = oid[i]; - saa->saa_oid.aoi_idlen = oidlen; - saa->saa_descr.aos_string = (unsigned char *)strdup(descr); - if (saa->saa_descr.aos_string == NULL) { - free(saa); - return NULL; - } - saa->saa_descr.aos_slen = strlen(descr); - saa->saa_cstate = SA_CSTATE_CLOSE; - saa->saa_dstate = SA_DSTATE_OPEN; - - TAILQ_INSERT_TAIL(&(sac->sac_agentcaps), saa, saa_sac_agentcaps); - - if (sac->sac_cstate == SA_CSTATE_OPEN) - subagentx_agentcaps_start(saa); - - return saa; -} - -static int -subagentx_agentcaps_start(struct subagentx_agentcaps *saa) -{ - struct subagentx_context *sac = saa->saa_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - uint32_t packetid; - -#ifdef AGENTX_DEBUG - if (sac->sac_cstate != SA_CSTATE_OPEN || - saa->saa_cstate != SA_CSTATE_CLOSE || - saa->saa_dstate != SA_DSTATE_OPEN) - subagentx_log_sac_fatalx(sac, - "%s: unexpected region registration", __func__); -#endif - - packetid = agentx_addagentcaps(sa->sa_ax, sas->sas_id, - SUBAGENTX_CONTEXT_CTX(sac), &(saa->saa_oid), &(saa->saa_descr)); - if (packetid == 0) { - subagentx_log_sac_warn(sac, "couldn't generate %s", - agentx_pdutype2string(AGENTX_PDU_TYPE_ADDAGENTCAPS)); - subagentx_reset(sa); - return -1; - } - subagentx_log_sac_info(sac, "agentcaps %s: opening", - agentx_oid2string(&(saa->saa_oid))); - saa->saa_cstate = SA_CSTATE_WAITOPEN; - return subagentx_request(sa, packetid, subagentx_agentcaps_finalize, - saa); -} - -static int -subagentx_agentcaps_finalize(struct agentx_pdu *pdu, void *cookie) -{ - struct subagentx_agentcaps *saa = cookie; - struct subagentx_context *sac = saa->saa_sac; - -#ifdef AGENTX_DEBUG - if (saa->saa_cstate != SA_CSTATE_WAITOPEN) - subagentx_log_sac_fatalx(sac, - "%s: not expecting agentcaps open", __func__); -#endif - - if (pdu->ap_payload.ap_response.ap_error != AGENTX_PDU_ERROR_NOERROR) { - /* Agentcaps failing is nothing too serious */ - subagentx_log_sac_warn(sac, "agentcaps %s: %s", - agentx_oid2string(&(saa->saa_oid)), - agentx_error2string(pdu->ap_payload.ap_response.ap_error)); - saa->saa_cstate = SA_CSTATE_CLOSE; - return 0; - } - - saa->saa_cstate = SA_CSTATE_OPEN; - - subagentx_log_sac_info(sac, "agentcaps %s: open", - agentx_oid2string(&(saa->saa_oid))); - - if (saa->saa_dstate == SA_DSTATE_CLOSE) - subagentx_agentcaps_close(saa); - - return 0; -} - -static int -subagentx_agentcaps_close(struct subagentx_agentcaps *saa) -{ - struct subagentx_context *sac = saa->saa_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - uint32_t packetid; - -#ifdef AGENTX_DEBUG - if (saa->saa_cstate != SA_CSTATE_OPEN) - subagentx_log_sac_fatalx(sac, "%s: unexpected agentcaps close", - __func__); -#endif - - saa->saa_cstate = SA_CSTATE_WAITCLOSE; - if (sas->sas_cstate == SA_CSTATE_WAITCLOSE) - return 0; - - packetid = agentx_removeagentcaps(sa->sa_ax, sas->sas_id, - SUBAGENTX_CONTEXT_CTX(sac), &(saa->saa_oid)); - if (packetid == 0) { - subagentx_log_sac_warn(sac, "couldn't generate %s", - agentx_pdutype2string(AGENTX_PDU_TYPE_REMOVEAGENTCAPS)); - subagentx_reset(sa); - return -1; - } - subagentx_log_sac_info(sac, "agentcaps %s: closing", - agentx_oid2string(&(saa->saa_oid))); - return subagentx_request(sa, packetid, - subagentx_agentcaps_close_finalize, saa); -} - -static int -subagentx_agentcaps_close_finalize(struct agentx_pdu *pdu, void *cookie) -{ - struct subagentx_agentcaps *saa = cookie; - struct subagentx_context *sac = saa->saa_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - -#ifdef AGENTX_DEBUG - if (saa->saa_cstate != SA_CSTATE_WAITCLOSE) - subagentx_log_sac_fatalx(sac, "%s: unexpected agentcaps close", - __func__); -#endif - - if (pdu->ap_payload.ap_response.ap_error != AGENTX_PDU_ERROR_NOERROR) { - subagentx_log_sac_warnx(sac, "agentcaps %s: %s", - agentx_oid2string(&(saa->saa_oid)), - agentx_error2string(pdu->ap_payload.ap_response.ap_error)); - subagentx_reset(sa); - return -1; - } - - saa->saa_cstate = SA_CSTATE_CLOSE; - - subagentx_log_sac_info(sac, "agentcaps %s: closed", - agentx_oid2string(&(saa->saa_oid))); - - if (saa->saa_dstate == SA_DSTATE_CLOSE) { - subagentx_agentcaps_free_finalize(saa); - return 0; - } else { - if (sac->sac_cstate == SA_CSTATE_OPEN) { - if (subagentx_agentcaps_start(saa) == -1) - return -1; - } - } - return 0; -} - -void -subagentx_agentcaps_free(struct subagentx_agentcaps *saa) -{ - if (saa == NULL) - return; - - if (saa->saa_dstate == SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(saa->saa_sac, "%s: double free", - __func__); - - saa->saa_dstate = SA_DSTATE_CLOSE; - - if (saa->saa_cstate == SA_CSTATE_OPEN) { - if (subagentx_agentcaps_close(saa) == -1) - return; - } - - if (saa->saa_cstate == SA_CSTATE_CLOSE) - subagentx_agentcaps_free_finalize(saa); -} - -static void -subagentx_agentcaps_free_finalize(struct subagentx_agentcaps *saa) -{ - struct subagentx_context *sac = saa->saa_sac; - -#ifdef AGENTX_DEBUG - if (saa->saa_dstate != SA_DSTATE_CLOSE || - saa->saa_cstate != SA_CSTATE_CLOSE) - subagentx_log_sac_fatalx(sac, "%s: unexpected free", __func__); -#endif - - TAILQ_REMOVE(&(sac->sac_agentcaps), saa, saa_sac_agentcaps); - free(saa->saa_descr.aos_string); - free(saa); - - if (sac->sac_dstate == SA_DSTATE_CLOSE) - subagentx_context_free_finalize(sac); -} - -static void -subagentx_agentcaps_reset(struct subagentx_agentcaps *saa) -{ - saa->saa_cstate = SA_CSTATE_CLOSE; - - if (saa->saa_dstate == SA_DSTATE_CLOSE) - subagentx_agentcaps_free_finalize(saa); -} - -struct subagentx_region * -subagentx_region(struct subagentx_context *sac, uint32_t oid[], - size_t oidlen, uint8_t timeout) -{ - struct subagentx_region *sar; - struct agentx_oid tmpoid; - size_t i; - - if (sac->sac_dstate == SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(sac, "%s: use after free", __func__); - if (oidlen < 1) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sac, "%s: oidlen == 0", __func__); -#else - errno = EINVAL; - return NULL; -#endif - } - if (oidlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sac, "%s: oidlen > %d", __func__, - SUBAGENTX_OID_MAX_LEN); -#else - errno = EINVAL; - return NULL; -#endif - } - - for (i = 0; i < oidlen; i++) - tmpoid.aoi_id[i] = oid[i]; - tmpoid.aoi_idlen = oidlen; - TAILQ_FOREACH(sar, &(sac->sac_regions), sar_sac_regions) { - if (agentx_oid_cmp(&(sar->sar_oid), &tmpoid) == 0) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sac, - "%s: duplicate region registration", __func__); -#else - errno = EINVAL; - return NULL; -#endif - } - } - - if ((sar = calloc(1, sizeof(*sar))) == NULL) - return NULL; - - sar->sar_sac = sac; - sar->sar_timeout = timeout; - sar->sar_priority = AGENTX_PRIORITY_DEFAULT; - bcopy(&tmpoid, &(sar->sar_oid), sizeof(sar->sar_oid)); - sar->sar_cstate = SA_CSTATE_CLOSE; - sar->sar_dstate = SA_DSTATE_OPEN; - TAILQ_INIT(&(sar->sar_indices)); - TAILQ_INIT(&(sar->sar_objects)); - - TAILQ_INSERT_HEAD(&(sac->sac_regions), sar, sar_sac_regions); - - if (sac->sac_cstate == SA_CSTATE_OPEN) - (void) subagentx_region_start(sar); - - return sar; -} - -static int -subagentx_region_start(struct subagentx_region *sar) -{ - struct subagentx_context *sac = sar->sar_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - uint32_t packetid; - -#ifdef AGENTX_DEBUG - if (sac->sac_cstate != SA_CSTATE_OPEN || - sar->sar_cstate != SA_CSTATE_CLOSE || - sar->sar_dstate != SA_DSTATE_OPEN) - subagentx_log_sac_fatalx(sac, - "%s: unexpected region registration", __func__); -#endif - - packetid = agentx_register(sa->sa_ax, 0, sas->sas_id, - SUBAGENTX_CONTEXT_CTX(sac), sar->sar_timeout, sar->sar_priority, - 0, &(sar->sar_oid), 0); - if (packetid == 0) { - subagentx_log_sac_warn(sac, "couldn't generate %s", - agentx_pdutype2string(AGENTX_PDU_TYPE_REGISTER)); - subagentx_reset(sa); - return -1; - } - subagentx_log_sac_info(sac, "region %s: opening", - agentx_oid2string(&(sar->sar_oid))); - sar->sar_cstate = SA_CSTATE_WAITOPEN; - return subagentx_request(sa, packetid, subagentx_region_finalize, sar); -} - -static int -subagentx_region_finalize(struct agentx_pdu *pdu, void *cookie) -{ - struct subagentx_region *sar = cookie; - struct subagentx_context *sac = sar->sar_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - struct subagentx_index *sai; - struct subagentx_object *sao; - -#ifdef AGENTX_DEBUG - if (sar->sar_cstate != SA_CSTATE_WAITOPEN) - subagentx_log_sac_fatalx(sac, "%s: not expecting region open", - __func__); -#endif - - if (pdu->ap_payload.ap_response.ap_error == AGENTX_PDU_ERROR_NOERROR) { - sar->sar_cstate = SA_CSTATE_OPEN; - subagentx_log_sac_info(sac, "region %s: open", - agentx_oid2string(&(sar->sar_oid))); - } else if (pdu->ap_payload.ap_response.ap_error == - AGENTX_PDU_ERROR_DUPLICATEREGISTRATION) { - sar->sar_cstate = SA_CSTATE_CLOSE; - /* Try at lower priority: first come first serve */ - if ((++sar->sar_priority) != 0) { - subagentx_log_sac_warnx(sac, "region %s: duplicate, " - "reducing priority", - agentx_oid2string(&(sar->sar_oid))); - return subagentx_region_start(sar); - } - subagentx_log_sac_info(sac, "region %s: duplicate, can't " - "reduce priority, ignoring", - agentx_oid2string(&(sar->sar_oid))); - } else if (pdu->ap_payload.ap_response.ap_error == - AGENTX_PDU_ERROR_REQUESTDENIED) { - sar->sar_cstate = SA_CSTATE_CLOSE; - subagentx_log_sac_warnx(sac, "region %s: %s", - agentx_oid2string(&(sar->sar_oid)), - agentx_error2string(pdu->ap_payload.ap_response.ap_error)); - /* - * If we can't register a region, related objects are useless. - * But no need to retry. - */ - return 0; - } else { - subagentx_log_sac_info(sac, "region %s: %s", - agentx_oid2string(&(sar->sar_oid)), - agentx_error2string(pdu->ap_payload.ap_response.ap_error)); - subagentx_reset(sa); - return -1; - } - - if (sar->sar_dstate == SA_DSTATE_CLOSE) { - if (subagentx_region_close(sar) == -1) - return -1; - } else { - TAILQ_FOREACH(sai, &(sar->sar_indices), sai_sar_indices) { - if (subagentx_index_start(sai) == -1) - return -1; - } - TAILQ_FOREACH(sao, &(sar->sar_objects), sao_sar_objects) { - if (subagentx_object_start(sao) == -1) - return -1; - } - } - return 0; -} - -static int -subagentx_region_close(struct subagentx_region *sar) -{ - struct subagentx_context *sac = sar->sar_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - uint32_t packetid; - -#ifdef AGENTX_DEBUG - if (sar->sar_cstate != SA_CSTATE_OPEN) - subagentx_log_sac_fatalx(sac, "%s: unexpected region close", - __func__); -#endif - - sar->sar_cstate = SA_CSTATE_WAITCLOSE; - if (sas->sas_cstate == SA_CSTATE_WAITCLOSE) - return 0; - - packetid = agentx_unregister(sa->sa_ax, sas->sas_id, - SUBAGENTX_CONTEXT_CTX(sac), sar->sar_priority, 0, &(sar->sar_oid), - 0); - if (packetid == 0) { - subagentx_log_sac_warn(sac, "couldn't generate %s", - agentx_pdutype2string(AGENTX_PDU_TYPE_UNREGISTER)); - subagentx_reset(sa); - return -1; - } - subagentx_log_sac_info(sac, "region %s: closing", - agentx_oid2string(&(sar->sar_oid))); - return subagentx_request(sa, packetid, subagentx_region_close_finalize, - sar); -} - -static int -subagentx_region_close_finalize(struct agentx_pdu *pdu, void *cookie) -{ - struct subagentx_region *sar = cookie; - struct subagentx_context *sac = sar->sar_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - -#ifdef AGENTX_DEBUG - if (sar->sar_cstate != SA_CSTATE_WAITCLOSE) - subagentx_log_sac_fatalx(sac, "%s: unexpected region close", - __func__); -#endif - - if (pdu->ap_payload.ap_response.ap_error != AGENTX_PDU_ERROR_NOERROR) { - subagentx_log_sac_warnx(sac, "closing %s: %s", - agentx_oid2string(&(sar->sar_oid)), - agentx_error2string(pdu->ap_payload.ap_response.ap_error)); - subagentx_reset(sa); - return -1; - } - - sar->sar_priority = AGENTX_PRIORITY_DEFAULT; - sar->sar_cstate = SA_CSTATE_CLOSE; - - subagentx_log_sac_info(sac, "region %s: closed", - agentx_oid2string(&(sar->sar_oid))); - - if (sar->sar_dstate == SA_DSTATE_CLOSE) { - subagentx_region_free_finalize(sar); - return 0; - } else { - if (sac->sac_cstate == SA_CSTATE_OPEN) { - if (subagentx_region_start(sar) == -1) - return -1; - } - } - return 0; -} - -void -subagentx_region_free(struct subagentx_region *sar) -{ - struct subagentx_index *sai, *tsai; - struct subagentx_object *sao, *tsao; - - if (sar == NULL) - return; - - if (sar->sar_dstate == SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(sar->sar_sac, "%s: double free", - __func__); - - sar->sar_dstate = SA_DSTATE_CLOSE; - - TAILQ_FOREACH_SAFE(sai, &(sar->sar_indices), sai_sar_indices, tsai) { - if (sai->sai_dstate != SA_DSTATE_CLOSE) - subagentx_index_free(sai); - } - - TAILQ_FOREACH_SAFE(sao, &(sar->sar_objects), sao_sar_objects, tsao) { - if (sao->sao_dstate != SA_DSTATE_CLOSE) - subagentx_object_free(sao); - } - - if (sar->sar_cstate == SA_CSTATE_OPEN) { - if (subagentx_region_close(sar) == -1) - return; - } - - if (sar->sar_cstate == SA_CSTATE_CLOSE) - subagentx_region_free_finalize(sar); -} - -static void -subagentx_region_free_finalize(struct subagentx_region *sar) -{ - struct subagentx_context *sac = sar->sar_sac; - -#ifdef AGENTX_DEBUG - if (sar->sar_dstate != SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(sac, "%s: unexpected free", __func__); -#endif - - if (!TAILQ_EMPTY(&(sar->sar_indices)) || - !TAILQ_EMPTY(&(sar->sar_objects))) - return; - - if (sar->sar_cstate != SA_CSTATE_CLOSE) - return; - - TAILQ_REMOVE(&(sac->sac_regions), sar, sar_sac_regions); - free(sar); - - if (sac->sac_dstate == SA_DSTATE_CLOSE) - subagentx_context_free_finalize(sac); -} - -static void -subagentx_region_reset(struct subagentx_region *sar) -{ - struct subagentx_index *sai, *tsai; - struct subagentx_object *sao, *tsao; - - sar->sar_cstate = SA_CSTATE_CLOSE; - sar->sar_priority = AGENTX_PRIORITY_DEFAULT; - - TAILQ_FOREACH_SAFE(sai, &(sar->sar_indices), sai_sar_indices, tsai) - subagentx_index_reset(sai); - TAILQ_FOREACH_SAFE(sao, &(sar->sar_objects), sao_sar_objects, tsao) - subagentx_object_reset(sao); - - if (sar->sar_dstate == SA_DSTATE_CLOSE) - subagentx_region_free_finalize(sar); -} - -struct subagentx_index * -subagentx_index_integer_new(struct subagentx_region *sar, uint32_t oid[], - size_t oidlen) -{ - struct agentx_varbind vb; - size_t i; - - if (oidlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); - errno = EINVAL; - return NULL; -#endif - } - - vb.avb_type = AGENTX_DATA_TYPE_INTEGER; - for (i = 0; i < oidlen; i++) - vb.avb_oid.aoi_id[i] = oid[i]; - vb.avb_oid.aoi_idlen = oidlen; - vb.avb_data.avb_uint32 = 0; - - return subagentx_index(sar, &vb, SAI_TYPE_NEW); -} - -struct subagentx_index * -subagentx_index_integer_any(struct subagentx_region *sar, uint32_t oid[], - size_t oidlen) -{ - struct agentx_varbind vb; - size_t i; - - if (oidlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); - errno = EINVAL; - return NULL; -#endif - } - - vb.avb_type = AGENTX_DATA_TYPE_INTEGER; - for (i = 0; i < oidlen; i++) - vb.avb_oid.aoi_id[i] = oid[i]; - vb.avb_oid.aoi_idlen = oidlen; - vb.avb_data.avb_uint32 = 0; - - return subagentx_index(sar, &vb, SAI_TYPE_ANY); -} - -struct subagentx_index * -subagentx_index_integer_value(struct subagentx_region *sar, uint32_t oid[], - size_t oidlen, uint32_t value) -{ - struct agentx_varbind vb; - size_t i; - - if (oidlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); - errno = EINVAL; - return NULL; -#endif - } - - vb.avb_type = AGENTX_DATA_TYPE_INTEGER; - for (i = 0; i < oidlen; i++) - vb.avb_oid.aoi_id[i] = oid[i]; - vb.avb_oid.aoi_idlen = oidlen; - vb.avb_data.avb_uint32 = value; - - return subagentx_index(sar, &vb, SAI_TYPE_VALUE); -} - -struct subagentx_index * -subagentx_index_integer_dynamic(struct subagentx_region *sar, uint32_t oid[], - size_t oidlen) -{ - struct agentx_varbind vb; - size_t i; - - if (oidlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); - errno = EINVAL; - return NULL; -#endif - } - - vb.avb_type = AGENTX_DATA_TYPE_INTEGER; - for (i = 0; i < oidlen; i++) - vb.avb_oid.aoi_id[i] = oid[i]; - vb.avb_oid.aoi_idlen = oidlen; - - return subagentx_index(sar, &vb, SAI_TYPE_DYNAMIC); -} - -struct subagentx_index * -subagentx_index_string_dynamic(struct subagentx_region *sar, uint32_t oid[], - size_t oidlen) -{ - struct agentx_varbind vb; - size_t i; - - if (oidlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); - errno = EINVAL; - return NULL; -#endif - } - - vb.avb_type = AGENTX_DATA_TYPE_OCTETSTRING; - for (i = 0; i < oidlen; i++) - vb.avb_oid.aoi_id[i] = oid[i]; - vb.avb_oid.aoi_idlen = oidlen; - vb.avb_data.avb_ostring.aos_slen = 0; - vb.avb_data.avb_ostring.aos_string = NULL; - - return subagentx_index(sar, &vb, SAI_TYPE_DYNAMIC); -} - -struct subagentx_index * -subagentx_index_nstring_dynamic(struct subagentx_region *sar, uint32_t oid[], - size_t oidlen, size_t vlen) -{ - struct agentx_varbind vb; - size_t i; - - if (oidlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); - errno = EINVAL; - return NULL; -#endif - } - if (vlen == 0 || vlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: invalid string " - "length: %zu\n", __func__, vlen); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: invalid string " - "length: %zu\n", __func__, vlen); - errno = EINVAL; - return NULL; -#endif - } - - vb.avb_type = AGENTX_DATA_TYPE_OCTETSTRING; - for (i = 0; i < oidlen; i++) - vb.avb_oid.aoi_id[i] = oid[i]; - vb.avb_oid.aoi_idlen = oidlen; - vb.avb_data.avb_ostring.aos_slen = vlen; - vb.avb_data.avb_ostring.aos_string = NULL; - - return subagentx_index(sar, &vb, SAI_TYPE_DYNAMIC); -} - -struct subagentx_index * -subagentx_index_oid_dynamic(struct subagentx_region *sar, uint32_t oid[], - size_t oidlen) -{ - struct agentx_varbind vb; - size_t i; - - if (oidlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); - errno = EINVAL; - return NULL; -#endif - } - - vb.avb_type = AGENTX_DATA_TYPE_OID; - for (i = 0; i < oidlen; i++) - vb.avb_oid.aoi_id[i] = oid[i]; - vb.avb_oid.aoi_idlen = oidlen; - vb.avb_data.avb_oid.aoi_idlen = 0; - - return subagentx_index(sar, &vb, SAI_TYPE_DYNAMIC); -} - -struct subagentx_index * -subagentx_index_noid_dynamic(struct subagentx_region *sar, uint32_t oid[], - size_t oidlen, size_t vlen) -{ - struct agentx_varbind vb; - size_t i; - - if (oidlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); - errno = EINVAL; - return NULL; -#endif - } - if (vlen == 0 || vlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: invalid string " - "length: %zu\n", __func__, vlen); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: invalid string " - "length: %zu\n", __func__, vlen); - errno = EINVAL; - return NULL; -#endif - } - - vb.avb_type = AGENTX_DATA_TYPE_OID; - for (i = 0; i < oidlen; i++) - vb.avb_oid.aoi_id[i] = oid[i]; - vb.avb_oid.aoi_idlen = oidlen; - vb.avb_data.avb_oid.aoi_idlen = vlen; - - return subagentx_index(sar, &vb, SAI_TYPE_DYNAMIC); -} - -struct subagentx_index * -subagentx_index_ipaddress_dynamic(struct subagentx_region *sar, uint32_t oid[], - size_t oidlen) -{ - struct agentx_varbind vb; - size_t i; - - if (oidlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); - errno = EINVAL; - return NULL; -#endif - } - - vb.avb_type = AGENTX_DATA_TYPE_IPADDRESS; - for (i = 0; i < oidlen; i++) - vb.avb_oid.aoi_id[i] = oid[i]; - vb.avb_data.avb_ostring.aos_string = NULL; - vb.avb_oid.aoi_idlen = oidlen; - - return subagentx_index(sar, &vb, SAI_TYPE_DYNAMIC); -} - -static struct subagentx_index * -subagentx_index(struct subagentx_region *sar, struct agentx_varbind *vb, - enum subagentx_index_type type) -{ - struct subagentx_index *sai; - - if (sar->sar_dstate == SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(sar->sar_sac, "%s: use after free", - __func__); - if (agentx_oid_cmp(&(sar->sar_oid), &(vb->avb_oid)) != -2) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: oid is not child " - "of region %s", __func__, - agentx_oid2string(&(vb->avb_oid))); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: oid is not child of " - "region %s", __func__, agentx_oid2string(&(vb->avb_oid))); - errno = EINVAL; - return NULL; -#endif - } - - if ((sai = calloc(1, sizeof(*sai))) == NULL) - return NULL; - - sai->sai_sar = sar; - sai->sai_type = type; - bcopy(vb, &(sai->sai_vb), sizeof(*vb)); - sai->sai_cstate = SA_CSTATE_CLOSE; - sai->sai_dstate = SA_DSTATE_OPEN; - TAILQ_INSERT_HEAD(&(sar->sar_indices), sai, sai_sar_indices); - - if (sar->sar_cstate == SA_CSTATE_OPEN) - subagentx_index_start(sai); - - return sai; -} - -static int -subagentx_index_start(struct subagentx_index *sai) -{ - struct subagentx_region *sar = sai->sai_sar; - struct subagentx_context *sac = sar->sar_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - uint32_t packetid; - int flags = 0; - -#ifdef AGENTX_DEBUG - if (sar->sar_cstate != SA_CSTATE_OPEN || - sai->sai_cstate != SA_CSTATE_CLOSE || - sai->sai_dstate != SA_DSTATE_OPEN) - subagentx_log_sac_fatalx(sac, "%s: unexpected index allocation", - __func__); -#endif - - sai->sai_cstate = SA_CSTATE_WAITOPEN; - - if (sai->sai_type == SAI_TYPE_NEW) - flags = AGENTX_PDU_FLAG_NEW_INDEX; - else if (sai->sai_type == SAI_TYPE_ANY) - flags = AGENTX_PDU_FLAG_ANY_INDEX; - else if (sai->sai_type == SAI_TYPE_DYNAMIC) { - subagentx_index_finalize(NULL, sai); - return 0; - } - - /* We might be able to bundle, but if we fail we'd have to reorganise */ - packetid = agentx_indexallocate(sa->sa_ax, flags, sas->sas_id, - SUBAGENTX_CONTEXT_CTX(sac), &(sai->sai_vb), 1); - if (packetid == 0) { - subagentx_log_sac_warn(sac, "couldn't generate %s", - agentx_pdutype2string(AGENTX_PDU_TYPE_INDEXDEALLOCATE)); - subagentx_reset(sa); - return -1; - } - if (sai->sai_type == SAI_TYPE_VALUE) - subagentx_log_sac_info(sac, "index %s: allocating '%u'", - agentx_oid2string(&(sai->sai_vb.avb_oid)), - sai->sai_vb.avb_data.avb_uint32); - else if (sai->sai_type == SAI_TYPE_ANY) - subagentx_log_sac_info(sac, "index %s: allocating any index", - agentx_oid2string(&(sai->sai_vb.avb_oid))); - else if (sai->sai_type == SAI_TYPE_NEW) - subagentx_log_sac_info(sac, "index %s: allocating new index", - agentx_oid2string(&(sai->sai_vb.avb_oid))); - - return subagentx_request(sa, packetid, subagentx_index_finalize, sai); -} - -static int -subagentx_index_finalize(struct agentx_pdu *pdu, void *cookie) -{ - struct subagentx_index *sai = cookie; - struct subagentx_region *sar = sai->sai_sar; - struct subagentx_context *sac = sar->sar_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - struct agentx_pdu_response *resp; - size_t i; - -#ifdef AGENTX_DEBUG - if (sai->sai_cstate != SA_CSTATE_WAITOPEN) - subagentx_log_sac_fatalx(sac, - "%s: not expecting index allocate", __func__); -#endif - if (sai->sai_type == SAI_TYPE_DYNAMIC) { - sai->sai_cstate = SA_CSTATE_OPEN; - return 0; - } - - resp = &(pdu->ap_payload.ap_response); - if (resp->ap_error != AGENTX_PDU_ERROR_NOERROR) { - sai->sai_cstate = SA_CSTATE_CLOSE; - subagentx_log_sac_warnx(sac, "index %s: %s", - agentx_oid2string(&(sar->sar_oid)), - agentx_error2string(resp->ap_error)); - return 0; - } - sai->sai_cstate = SA_CSTATE_OPEN; - if (resp->ap_nvarbind != 1) { - subagentx_log_sac_warnx(sac, "index %s: unexpected number of " - "indices", agentx_oid2string(&(sar->sar_oid))); - subagentx_reset(sa); - return -1; - } - if (resp->ap_varbindlist[0].avb_type != sai->sai_vb.avb_type) { - subagentx_log_sac_warnx(sac, "index %s: unexpected index type", - agentx_oid2string(&(sar->sar_oid))); - subagentx_reset(sa); - return -1; - } - if (agentx_oid_cmp(&(resp->ap_varbindlist[0].avb_oid), - &(sai->sai_vb.avb_oid)) != 0) { - subagentx_log_sac_warnx(sac, "index %s: unexpected oid", - agentx_oid2string(&(sar->sar_oid))); - subagentx_reset(sa); - return -1; - } - - switch (sai->sai_vb.avb_type) { - case AGENTX_DATA_TYPE_INTEGER: - if (sai->sai_type == SAI_TYPE_NEW || - sai->sai_type == SAI_TYPE_ANY) - sai->sai_vb.avb_data.avb_uint32 = - resp->ap_varbindlist[0].avb_data.avb_uint32; - else if (sai->sai_vb.avb_data.avb_uint32 != - resp->ap_varbindlist[0].avb_data.avb_uint32) { - subagentx_log_sac_warnx(sac, "index %s: unexpected " - "index value", agentx_oid2string(&(sar->sar_oid))); - subagentx_reset(sa); - return -1; - } - subagentx_log_sac_info(sac, "index %s: allocated '%u'", - agentx_oid2string(&(sai->sai_vb.avb_oid)), - sai->sai_vb.avb_data.avb_uint32); - break; - default: - subagentx_log_sac_fatalx(sac, "%s: Unsupported index type", - __func__); - } - - if (sai->sai_dstate == SA_DSTATE_CLOSE) - return subagentx_index_close(sai); - - /* TODO Make use of range_subid register */ - for (i = 0; i < sai->sai_objectlen; i++) { - if (sai->sai_object[i]->sao_dstate == SA_DSTATE_OPEN) { - if (subagentx_object_start(sai->sai_object[i]) == -1) - return -1; - } - } - return 0; -} - -void -subagentx_index_free(struct subagentx_index *sai) -{ - size_t i; - struct subagentx_object *sao; - - if (sai == NULL) - return; - - if (sai->sai_dstate == SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(sai->sai_sar->sar_sac, - "%s: double free", __func__); - - /* TODO Do a range_subid unregister before freeing */ - for (i = 0; i < sai->sai_objectlen; i++) { - sao = sai->sai_object[i]; - if (sao->sao_dstate != SA_DSTATE_CLOSE) { - subagentx_object_free(sao); - if (sai->sai_object[i] != sao) - i--; - } - } - - sai->sai_dstate = SA_DSTATE_CLOSE; - - if (sai->sai_cstate == SA_CSTATE_OPEN) - (void) subagentx_index_close(sai); - else if (sai->sai_cstate == SA_CSTATE_CLOSE) - subagentx_index_free_finalize(sai); -} - -static void -subagentx_index_free_finalize(struct subagentx_index *sai) -{ - struct subagentx_region *sar = sai->sai_sar; - -#ifdef AGENTX_DEBUG - if (sai->sai_dstate != SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(sar->sar_sac, "%s: unexpected free", - __func__); - if (sai->sai_cstate != SA_CSTATE_CLOSE) - subagentx_log_sac_fatalx(sar->sar_sac, - "%s: free without deallocating", __func__); -#endif - - if (sai->sai_objectlen != 0) - return; - - TAILQ_REMOVE(&(sar->sar_indices), sai, sai_sar_indices); - agentx_varbind_free(&(sai->sai_vb)); - free(sai->sai_object); - free(sai); - if (sar->sar_dstate == SA_DSTATE_CLOSE) - subagentx_region_free_finalize(sar); -} - -static void -subagentx_index_reset(struct subagentx_index *sai) -{ - sai->sai_cstate = SA_CSTATE_CLOSE; - - if (sai->sai_dstate == SA_DSTATE_CLOSE) - subagentx_index_free_finalize(sai); -} - -static int -subagentx_index_close(struct subagentx_index *sai) -{ - struct subagentx_region *sar = sai->sai_sar; - struct subagentx_context *sac = sar->sar_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - uint32_t packetid; - -#ifdef AGENTX_DEBUG - if (sai->sai_cstate != SA_CSTATE_OPEN) - subagentx_log_sac_fatalx(sac, - "%s: unexpected index deallocation", __func__); -#endif - - sai->sai_cstate = SA_CSTATE_WAITCLOSE; - if (sas->sas_cstate == SA_CSTATE_WAITCLOSE) - return 0; - - /* We might be able to bundle, but if we fail we'd have to reorganise */ - packetid = agentx_indexdeallocate(sa->sa_ax, sas->sas_id, - SUBAGENTX_CONTEXT_CTX(sac), &(sai->sai_vb), 1); - if (packetid == 0) { - subagentx_log_sac_warn(sac, "couldn't generate %s", - agentx_pdutype2string(AGENTX_PDU_TYPE_INDEXDEALLOCATE)); - subagentx_reset(sa); - return -1; - } - subagentx_log_sac_info(sac, "index %s: deallocating", - agentx_oid2string(&(sai->sai_vb.avb_oid))); - return subagentx_request(sa, packetid, subagentx_index_close_finalize, - sai); -} - -static int -subagentx_index_close_finalize(struct agentx_pdu *pdu, void *cookie) -{ - struct subagentx_index *sai = cookie; - struct subagentx_region *sar = sai->sai_sar; - struct subagentx_context *sac = sar->sar_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - struct agentx_pdu_response *resp = &(pdu->ap_payload.ap_response); - -#ifdef AGENTX_DEBUG - if (sai->sai_cstate != SA_CSTATE_WAITCLOSE) - subagentx_log_sac_fatalx(sac, "%s: unexpected indexdeallocate", - __func__); -#endif - - if (pdu->ap_payload.ap_response.ap_error != AGENTX_PDU_ERROR_NOERROR) { - subagentx_log_sac_warnx(sac, - "index %s: couldn't deallocate: %s", - agentx_oid2string(&(sai->sai_vb.avb_oid)), - agentx_error2string(resp->ap_error)); - subagentx_reset(sa); - return -1; - } - - if (resp->ap_nvarbind != 1) { - subagentx_log_sac_warnx(sac, - "index %s: unexpected number of indices", - agentx_oid2string(&(sar->sar_oid))); - subagentx_reset(sa); - return -1; - } - if (resp->ap_varbindlist[0].avb_type != sai->sai_vb.avb_type) { - subagentx_log_sac_warnx(sac, "index %s: unexpected index type", - agentx_oid2string(&(sar->sar_oid))); - subagentx_reset(sa); - return -1; - } - if (agentx_oid_cmp(&(resp->ap_varbindlist[0].avb_oid), - &(sai->sai_vb.avb_oid)) != 0) { - subagentx_log_sac_warnx(sac, "index %s: unexpected oid", - agentx_oid2string(&(sar->sar_oid))); - subagentx_reset(sa); - return -1; - } - switch (sai->sai_vb.avb_type) { - case AGENTX_DATA_TYPE_INTEGER: - if (sai->sai_vb.avb_data.avb_uint32 != - resp->ap_varbindlist[0].avb_data.avb_uint32) { - subagentx_log_sac_warnx(sac, - "index %s: unexpected index value", - agentx_oid2string(&(sar->sar_oid))); - subagentx_reset(sa); - return -1; - } - break; - default: - subagentx_log_sac_fatalx(sac, "%s: Unsupported index type", - __func__); - } - - sai->sai_cstate = SA_CSTATE_CLOSE; - - subagentx_log_sac_info(sac, "index %s: deallocated", - agentx_oid2string(&(sai->sai_vb.avb_oid))); - - if (sai->sai_dstate == SA_DSTATE_CLOSE) { - subagentx_index_free_finalize(sai); - } else if (sar->sar_cstate == SA_CSTATE_OPEN) { - if (subagentx_index_start(sai) == -1) - return -1; - } - return 0; -} - -struct subagentx_object * -subagentx_object(struct subagentx_region *sar, uint32_t oid[], size_t oidlen, - struct subagentx_index *sai[], size_t sailen, int implied, - void (*get)(struct subagentx_varbind *)) -{ - struct subagentx_object *sao, **tsao, sao_search; - struct subagentx_index *lsai; - int ready = 1; - size_t i, j; - - if (sar->sar_dstate == SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(sar->sar_sac, "%s: use after free", - __func__); - if (oidlen < 1) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: oidlen == 0", - __func__); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: oidlen == 0", - __func__); - errno = EINVAL; - return NULL; -#endif - } - if (oidlen > SUBAGENTX_OID_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: oidlen > %d", - __func__, SUBAGENTX_OID_MAX_LEN); - errno = EINVAL; - return NULL; -#endif - } - if (sailen > SUBAGENTX_OID_INDEX_MAX_LEN) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: indexlen > %d", - __func__, SUBAGENTX_OID_INDEX_MAX_LEN); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: indexlen > %d", - __func__, SUBAGENTX_OID_INDEX_MAX_LEN); - errno = EINVAL; - return NULL; -#endif - } - - for (i = 0; i < oidlen; i++) - sao_search.sao_oid.aoi_id[i] = oid[i]; - sao_search.sao_oid.aoi_idlen = oidlen; - - do { - if (RB_FIND(sac_objects, &(sar->sar_sac->sac_objects), - &sao_search) != NULL) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: invalid " - "parent child object relationship", __func__); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: invalid " - "parent child object relationship", __func__); - errno = EINVAL; - return NULL; -#endif - } - sao_search.sao_oid.aoi_idlen--; - } while (sao_search.sao_oid.aoi_idlen > 0); - sao_search.sao_oid.aoi_idlen = oidlen; - sao = RB_NFIND(sac_objects, &(sar->sar_sac->sac_objects), &sao_search); - if (sao != NULL && - agentx_oid_cmp(&(sao->sao_oid), &(sao_search.sao_oid)) == 2) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: invalid parent " - "child object relationship", __func__); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: invalid parent " - "child object relationship", __func__); - errno = EINVAL; - return NULL; -#endif - } - if (implied == 1) { - lsai = sai[sailen - 1]; - if (lsai->sai_vb.avb_type == AGENTX_DATA_TYPE_OCTETSTRING) { - if (lsai->sai_vb.avb_data.avb_ostring.aos_slen != 0) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, - "%s: implied can only be used on strings " - "of dynamic length", __func__); -#else - subagentx_log_sac_warnx(sar->sar_sac, - "%s: implied can only be used on strings " - "of dynamic length", __func__); - errno = EINVAL; - return NULL; -#endif - } - } else if (lsai->sai_vb.avb_type == AGENTX_DATA_TYPE_OID) { - if (lsai->sai_vb.avb_data.avb_oid.aoi_idlen != 0) { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, - "%s: implied can only be used on oids of " - "dynamic length", __func__); -#else - subagentx_log_sac_warnx(sar->sar_sac, - "%s: implied can only be used on oids of " - "dynamic length", __func__); - errno = EINVAL; - return NULL; -#endif - } - } else { -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sar->sar_sac, "%s: implied " - "can only be set on oid and string indices", - __func__); -#else - subagentx_log_sac_warnx(sar->sar_sac, "%s: implied can " - "only be set on oid and string indices", __func__); - errno = EINVAL; - return NULL; -#endif - } - } - - ready = sar->sar_cstate == SA_CSTATE_OPEN; - if ((sao = calloc(1, sizeof(*sao))) == NULL) - return NULL; - sao->sao_sar = sar; - bcopy(&(sao_search.sao_oid), &(sao->sao_oid), sizeof(sao->sao_oid)); - for (i = 0; i < sailen; i++) { - sao->sao_index[i] = sai[i]; - if (sai[i]->sai_objectlen == sai[i]->sai_objectsize) { - tsao = recallocarray(sai[i]->sai_object, - sai[i]->sai_objectlen, sai[i]->sai_objectlen + 1, - sizeof(*sai[i]->sai_object)); - if (tsao == NULL) { - free(sao); - return NULL; - } - sai[i]->sai_object = tsao; - sai[i]->sai_objectsize = sai[i]->sai_objectlen + 1; - } - for (j = 0; j < sai[i]->sai_objectlen; j++) { - if (agentx_oid_cmp(&(sao->sao_oid), - &(sai[i]->sai_object[j]->sao_oid)) < 0) { - memmove(&(sai[i]->sai_object[j + 1]), - &(sai[i]->sai_object[j]), - sizeof(*(sai[i]->sai_object)) * - (sai[i]->sai_objectlen - j)); - break; - } - } - sai[i]->sai_object[j] = sao; - sai[i]->sai_objectlen++; - if (sai[i]->sai_cstate != SA_CSTATE_OPEN) - ready = 0; - } - sao->sao_indexlen = sailen; - sao->sao_implied = implied; - sao->sao_timeout = 0; - sao->sao_lock = 0; - sao->sao_get = get; - sao->sao_cstate = SA_CSTATE_CLOSE; - sao->sao_dstate = SA_DSTATE_OPEN; - - TAILQ_INSERT_TAIL(&(sar->sar_objects), sao, sao_sar_objects); - RB_INSERT(sac_objects, &(sar->sar_sac->sac_objects), sao); - - if (ready) - subagentx_object_start(sao); - - return sao; -} - -static int -subagentx_object_start(struct subagentx_object *sao) -{ - struct subagentx_region *sar = sao->sao_sar; - struct subagentx_context *sac = sar->sar_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - struct agentx_oid oid; - char oids[1024]; - size_t i; - int needregister = 0; - uint32_t packetid; - uint8_t flags = AGENTX_PDU_FLAG_INSTANCE_REGISTRATION; - -#ifdef AGENTX_DEBUG - if (sar->sar_cstate != SA_CSTATE_OPEN || - sao->sao_cstate != SA_CSTATE_CLOSE || - sao->sao_dstate != SA_DSTATE_OPEN) - subagentx_log_sac_fatalx(sac, - "%s: unexpected object registration", __func__); -#endif - - if (sao->sao_timeout != 0) - needregister = 1; - for (i = 0; i < sao->sao_indexlen; i++) { - if (sao->sao_index[i]->sai_cstate != SA_CSTATE_OPEN) - return 0; - if (sao->sao_index[i]->sai_type != SAI_TYPE_DYNAMIC) - needregister = 1; - } - if (!needregister) { - sao->sao_cstate = SA_CSTATE_WAITOPEN; - subagentx_object_finalize(NULL, sao); - return 0; - } - - bcopy(&(sao->sao_oid), &(oid), sizeof(oid)); - for (i = 0; i < sao->sao_indexlen; i++) { - if (sao->sao_index[i]->sai_type == SAI_TYPE_DYNAMIC) { - flags = 0; - break; - } -#ifdef AGENTX_DEBUG - if (sao->sao_index[i]->sai_vb.avb_type != - AGENTX_DATA_TYPE_INTEGER) - subagentx_log_sac_fatalx(sac, - "%s: Unsupported allocated index type", __func__); -#endif - oid.aoi_id[oid.aoi_idlen++] = - sao->sao_index[i]->sai_vb.avb_data.avb_uint32; - } - packetid = agentx_register(sa->sa_ax, flags, sas->sas_id, - SUBAGENTX_CONTEXT_CTX(sac), sao->sao_timeout, - AGENTX_PRIORITY_DEFAULT, 0, &oid, 0); - if (packetid == 0) { - subagentx_log_sac_warn(sac, "couldn't generate %s", - agentx_pdutype2string(AGENTX_PDU_TYPE_REGISTER)); - subagentx_reset(sa); - return -1; - } - strlcpy(oids, agentx_oid2string(&(sao->sao_oid)), sizeof(oids)); - subagentx_log_sac_info(sac, "object %s (%s %s): opening", - oids, flags ? "instance" : "region", agentx_oid2string(&(oid))); - sao->sao_cstate = SA_CSTATE_WAITOPEN; - return subagentx_request(sa, packetid, subagentx_object_finalize, sao); -} - -static int -subagentx_object_finalize(struct agentx_pdu *pdu, void *cookie) -{ - struct subagentx_object *sao = cookie; - struct subagentx_context *sac = sao->sao_sar->sar_sac; - struct agentx_oid oid; - char oids[1024]; - size_t i; - uint8_t flags = 1; - -#ifdef AGENTX_DEBUG - if (sao->sao_cstate != SA_CSTATE_WAITOPEN) - subagentx_log_sac_fatalx(sac, "%s: not expecting object open", - __func__); -#endif - - if (pdu == NULL) { - sao->sao_cstate = SA_CSTATE_OPEN; - return 0; - } - - bcopy(&(sao->sao_oid), &oid, sizeof(oid)); - for (i = 0; i < sao->sao_indexlen; i++) { - if (sao->sao_index[i]->sai_type == SAI_TYPE_DYNAMIC) { - flags = 0; - break; - } -#ifdef AGENTX_DEBUG - if (sao->sao_index[i]->sai_vb.avb_type != - AGENTX_DATA_TYPE_INTEGER) - subagentx_log_sac_fatalx(sac, - "%s: Unsupported allocated index type", __func__); -#endif - - oid.aoi_id[oid.aoi_idlen++] = - sao->sao_index[i]->sai_vb.avb_data.avb_uint32; - } - strlcpy(oids, agentx_oid2string(&(sao->sao_oid)), sizeof(oids)); - - /* - * We should only be here for table objects with registered indices. - * If we fail here something is misconfigured and the admin should fix - * it. - */ - if (pdu->ap_payload.ap_response.ap_error != AGENTX_PDU_ERROR_NOERROR) { - sao->sao_cstate = SA_CSTATE_CLOSE; - subagentx_log_sac_info(sac, "object %s (%s %s): %s", - oids, flags ? "instance" : "region", agentx_oid2string(&oid), - agentx_error2string(pdu->ap_payload.ap_response.ap_error)); - if (sao->sao_dstate == SA_DSTATE_CLOSE) - return subagentx_object_close_finalize(NULL, sao); - return 0; - } - sao->sao_cstate = SA_CSTATE_OPEN; - subagentx_log_sac_info(sac, "object %s (%s %s): open", oids, - flags ? "instance" : "region", agentx_oid2string(&oid)); - - if (sao->sao_dstate == SA_DSTATE_CLOSE) - return subagentx_object_close(sao); - - return 0; -} - -static int -subagentx_object_lock(struct subagentx_object *sao) -{ - if (sao->sao_lock == UINT32_MAX) { - subagentx_log_sac_warnx(sao->sao_sar->sar_sac, - "%s: sao_lock == %u", __func__, UINT32_MAX); - return -1; - } - sao->sao_lock++; - return 0; -} - -static void -subagentx_object_unlock(struct subagentx_object *sao) -{ -#ifdef AGENTX_DEBUG - if (sao->sao_lock == 0) - subagentx_log_sac_fatalx(sao->sao_sar->sar_sac, - "%s: sao_lock == 0", __func__); -#endif - sao->sao_lock--; - if (sao->sao_lock == 0 && sao->sao_dstate == SA_DSTATE_CLOSE && - sao->sao_cstate == SA_CSTATE_CLOSE) - subagentx_object_free_finalize(sao); -} - -static int -subagentx_object_close(struct subagentx_object *sao) -{ - struct subagentx_context *sac = sao->sao_sar->sar_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - struct agentx_oid oid; - char oids[1024]; - size_t i; - int needclose = 0; - uint32_t packetid; - uint8_t flags = 1; - -#ifdef AGENTX_DEBUG - if (sao->sao_cstate != SA_CSTATE_OPEN) - subagentx_log_sac_fatalx(sac, "%s: unexpected object close", - __func__); -#endif - - for (i = 0; i < sao->sao_indexlen; i++) { -#ifdef AGENTX_DEBUG - if (sao->sao_index[i]->sai_cstate != SA_CSTATE_OPEN) - subagentx_log_sac_fatalx(sac, - "%s: Object open while index closed", __func__); -#endif - if (sao->sao_index[i]->sai_type != SAI_TYPE_DYNAMIC) - needclose = 1; - } - sao->sao_cstate = SA_CSTATE_WAITCLOSE; - if (sas->sas_cstate == SA_CSTATE_WAITCLOSE) - return 0; - if (!needclose) { - subagentx_object_close_finalize(NULL, sao); - return 0; - } - - bcopy(&(sao->sao_oid), &(oid), sizeof(oid)); - for (i = 0; i < sao->sao_indexlen; i++) { - if (sao->sao_index[i]->sai_type == SAI_TYPE_DYNAMIC) { - flags = 0; - break; - } -#ifdef AGENTX_DEBUG - if (sao->sao_index[i]->sai_vb.avb_type != - AGENTX_DATA_TYPE_INTEGER) - subagentx_log_sac_fatalx(sac, - "%s: Unsupported allocated index type", __func__); -#endif - oid.aoi_id[oid.aoi_idlen++] = - sao->sao_index[i]->sai_vb.avb_data.avb_uint32; - } - packetid = agentx_unregister(sa->sa_ax, sas->sas_id, - SUBAGENTX_CONTEXT_CTX(sac), AGENTX_PRIORITY_DEFAULT, 0, &oid, 0); - if (packetid == 0) { - subagentx_log_sac_warn(sac, "couldn't generate %s", - agentx_pdutype2string(AGENTX_PDU_TYPE_UNREGISTER)); - subagentx_reset(sa); - return -1; - } - strlcpy(oids, agentx_oid2string(&(sao->sao_oid)), sizeof(oids)); - subagentx_log_sac_info(sac, "object %s (%s %s): closing", - oids, flags ? "instance" : "region", agentx_oid2string(&(oid))); - return subagentx_request(sa, packetid, subagentx_object_close_finalize, - sao); -} - -static int -subagentx_object_close_finalize(struct agentx_pdu *pdu, void *cookie) -{ - struct subagentx_object *sao = cookie; - struct subagentx_region *sar = sao->sao_sar; - struct subagentx_context *sac = sar->sar_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - struct agentx_oid oid; - char oids[1024]; - uint8_t flags = 1; - size_t i; - -#ifdef AGENTX_DEBUG - if (sao->sao_cstate != SA_CSTATE_WAITCLOSE) - subagentx_log_sac_fatalx(sac, - "%s: unexpected object unregister", __func__); -#endif - - if (pdu != NULL) { - bcopy(&(sao->sao_oid), &(oid), sizeof(oid)); - for (i = 0; i < sao->sao_indexlen; i++) { - if (sao->sao_index[i]->sai_type == SAI_TYPE_DYNAMIC) { - flags = 0; - break; - } -#ifdef AGENTX_DEBUG - if (sao->sao_index[i]->sai_vb.avb_type != - AGENTX_DATA_TYPE_INTEGER) - subagentx_log_sac_fatalx(sac, - "%s: Unsupported allocated index type", - __func__); -#endif - oid.aoi_id[oid.aoi_idlen++] = - sao->sao_index[i]->sai_vb.avb_data.avb_uint32; - } - strlcpy(oids, agentx_oid2string(&(sao->sao_oid)), sizeof(oids)); - if (pdu->ap_payload.ap_response.ap_error != - AGENTX_PDU_ERROR_NOERROR) { - subagentx_log_sac_warnx(sac, - "closing object %s (%s %s): %s", oids, - flags ? "instance" : "region", - agentx_oid2string(&oid), agentx_error2string( - pdu->ap_payload.ap_response.ap_error)); - subagentx_reset(sa); - return -1; - } - subagentx_log_sac_info(sac, "object %s (%s %s): closed", oids, - flags ? "instance" : "region", agentx_oid2string(&oid)); - } - - if (sao->sao_dstate == SA_DSTATE_CLOSE) - subagentx_object_free_finalize(sao); - else { - if (sar->sar_cstate == SA_CSTATE_OPEN) - if (subagentx_object_start(sao) == -1) - return -1; - } - - return 0; -} - -void -subagentx_object_free(struct subagentx_object *sao) -{ - if (sao == NULL) - return; - - if (sao->sao_dstate == SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(sao->sao_sar->sar_sac, - "%s: double free", __func__); - - sao->sao_dstate = SA_DSTATE_CLOSE; - - if (sao->sao_cstate == SA_CSTATE_OPEN) { - if (subagentx_object_close(sao) == -1) - return; - } - if (sao->sao_cstate == SA_CSTATE_CLOSE) - subagentx_object_free_finalize(sao); -} - -static void -subagentx_object_free_finalize(struct subagentx_object *sao) -{ -#ifdef AGENTX_DEBUG - struct subagentx *sa = sao->sao_sar->sar_sac->sac_sas->sas_sa; -#endif - size_t i, j; - int found; - -#ifdef AGENTX_DEBUG - if (sao->sao_dstate != SA_DSTATE_CLOSE) - subagentx_log_sac_fatalx(sao->sao_sar->sar_sac, - "%s: unexpected free", __func__); -#endif - - if (sao->sao_lock != 0) { -#ifdef AGENTX_DEBUG - if (TAILQ_EMPTY(&(sa->sa_getreqs))) - subagentx_log_sac_fatalx(sao->sao_sar->sar_sac, - "%s: %s sao_lock == %u", __func__, - agentx_oid2string(&(sao->sao_oid)), sao->sao_lock); -#endif - return; - } - - RB_REMOVE(sac_objects, &(sao->sao_sar->sar_sac->sac_objects), sao); - TAILQ_REMOVE(&(sao->sao_sar->sar_objects), sao, sao_sar_objects); - - for (i = 0; i < sao->sao_indexlen; i++) { - found = 0; - for (j = 0; j < sao->sao_index[i]->sai_objectlen; j++) { - if (sao->sao_index[i]->sai_object[j] == sao) - found = 1; - if (found && j + 1 != sao->sao_index[i]->sai_objectlen) - sao->sao_index[i]->sai_object[j] = - sao->sao_index[i]->sai_object[j + 1]; - } -#ifdef AGENTX_DEBUG - if (!found) - subagentx_log_sac_fatalx(sao->sao_sar->sar_sac, - "%s: object not found in index", __func__); -#endif - sao->sao_index[i]->sai_objectlen--; - if (sao->sao_index[i]->sai_dstate == SA_DSTATE_CLOSE && - sao->sao_index[i]->sai_cstate == SA_CSTATE_CLOSE) - subagentx_index_free_finalize(sao->sao_index[i]); - } - - free(sao); -} - -static void -subagentx_object_reset(struct subagentx_object *sao) -{ - sao->sao_cstate = SA_CSTATE_CLOSE; - - if (sao->sao_dstate == SA_DSTATE_CLOSE) - subagentx_object_free_finalize(sao); -} - -static int -subagentx_object_cmp(struct subagentx_object *o1, struct subagentx_object *o2) -{ - return agentx_oid_cmp(&(o1->sao_oid), &(o2->sao_oid)); -} - -static int -subagentx_object_implied(struct subagentx_object *sao, - struct subagentx_index *sai) -{ - size_t i = 0; - - for (i = 0; i < sao->sao_indexlen; i++) { - if (sao->sao_index[i] == sai) { - if (sai->sai_vb.avb_data.avb_ostring.aos_slen != 0) - return 1; - else if (i == sao->sao_indexlen - 1) - return sao->sao_implied; - return 0; - } - } -#ifdef AGENTX_DEBUG - subagentx_log_sac_fatalx(sao->sao_sar->sar_sac, "%s: unsupported index", - __func__); -#endif - return 0; -} - -static void -subagentx_get_start(struct subagentx_context *sac, struct agentx_pdu *pdu) -{ - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - struct subagentx_get *sag, tsag; - struct agentx_pdu_searchrangelist *srl; - char *logmsg = NULL; - size_t i, j; - int fail = 0; - - if ((sag = calloc(1, sizeof(*sag))) == NULL) { - tsag.sag_sessionid = pdu->ap_header.aph_sessionid; - tsag.sag_transactionid = pdu->ap_header.aph_transactionid; - tsag.sag_packetid = pdu->ap_header.aph_packetid; - tsag.sag_context_default = sac->sac_name_default; - tsag.sag_fd = sac->sac_sas->sas_sa->sa_fd; - subagentx_log_sag_warn(&tsag, "Couldn't parse request"); - subagentx_reset(sa); - return; - } - - sag->sag_sessionid = pdu->ap_header.aph_sessionid; - sag->sag_transactionid = pdu->ap_header.aph_transactionid; - sag->sag_packetid = pdu->ap_header.aph_packetid; - sag->sag_context_default = sac->sac_name_default; - sag->sag_fd = sac->sac_sas->sas_sa->sa_fd; - if (!sac->sac_name_default) { - sag->sag_context.aos_string = - (unsigned char *)strdup((char *)sac->sac_name.aos_string); - if (sag->sag_context.aos_string == NULL) { - subagentx_log_sag_warn(sag, "Couldn't parse request"); - free(sag); - subagentx_reset(sa); - return; - } - } - sag->sag_context.aos_slen = sac->sac_name.aos_slen; - sag->sag_type = pdu->ap_header.aph_type; - sag->sag_sac = sac; - TAILQ_INSERT_TAIL(&(sa->sa_getreqs), sag, sag_sa_getreqs); - if (sag->sag_type == AGENTX_PDU_TYPE_GET || - sag->sag_type == AGENTX_PDU_TYPE_GETNEXT) { - srl = &(pdu->ap_payload.ap_srl); - sag->sag_nvarbind = srl->ap_nsr; - } else { - sag->sag_nonrep = pdu->ap_payload.ap_getbulk.ap_nonrep; - sag->sag_maxrep = pdu->ap_payload.ap_getbulk.ap_maxrep; - srl = &(pdu->ap_payload.ap_getbulk.ap_srl); - sag->sag_nvarbind = ((srl->ap_nsr - sag->sag_nonrep) * - sag->sag_maxrep) + sag->sag_nonrep; - } - - if ((sag->sag_varbind = calloc(sag->sag_nvarbind, - sizeof(*(sag->sag_varbind)))) == NULL) { - subagentx_log_sag_warn(sag, "Couldn't parse request"); - subagentx_get_free(sag); - subagentx_reset(sa); - return; - } - - /* XXX net-snmp doesn't use getbulk, so untested */ - /* Two loops: varbind after needs to be initialized */ - for (i = 0; i < srl->ap_nsr; i++) { - if (i < sag->sag_nonrep || - sag->sag_type != AGENTX_PDU_TYPE_GETBULK) - j = i; - else if (sag->sag_maxrep == 0) - break; - else - j = (sag->sag_maxrep * i) + sag->sag_nonrep; - bcopy(&(srl->ap_sr[i].asr_start), - &(sag->sag_varbind[j].sav_vb.avb_oid), - sizeof(srl->ap_sr[i].asr_start)); - bcopy(&(srl->ap_sr[i].asr_start), - &(sag->sag_varbind[j].sav_start), - sizeof(srl->ap_sr[i].asr_start)); - bcopy(&(srl->ap_sr[i].asr_stop), - &(sag->sag_varbind[j].sav_end), - sizeof(srl->ap_sr[i].asr_stop)); - sag->sag_varbind[j].sav_initialized = 1; - sag->sag_varbind[j].sav_sag = sag; - sag->sag_varbind[j].sav_include = - srl->ap_sr[i].asr_start.aoi_include; - if (j == 0) - fail |= subagentx_strcat(&logmsg, " {"); - else - fail |= subagentx_strcat(&logmsg, ",{"); - fail |= subagentx_strcat(&logmsg, - agentx_oid2string(&(srl->ap_sr[i].asr_start))); - if (srl->ap_sr[i].asr_start.aoi_include) - fail |= subagentx_strcat(&logmsg, " (inclusive)"); - if (srl->ap_sr[i].asr_stop.aoi_idlen != 0) { - fail |= subagentx_strcat(&logmsg, " - "); - fail |= subagentx_strcat(&logmsg, - agentx_oid2string(&(srl->ap_sr[i].asr_stop))); - } - fail |= subagentx_strcat(&logmsg, "}"); - if (fail) { - subagentx_log_sag_warn(sag, "Couldn't parse request"); - free(logmsg); - subagentx_get_free(sag); - subagentx_reset(sa); - return; - } - } - - subagentx_log_sag_debug(sag, "%s:%s", - agentx_pdutype2string(sag->sag_type), logmsg); - free(logmsg); - - for (i = 0; i < srl->ap_nsr; i++) { - if (i < sag->sag_nonrep || - sag->sag_type != AGENTX_PDU_TYPE_GETBULK) - j = i; - else if (sag->sag_maxrep == 0) - break; - else - j = (sag->sag_maxrep * i) + sag->sag_nonrep; - subagentx_varbind_start(&(sag->sag_varbind[j])); - } -} - -static void -subagentx_get_finalize(struct subagentx_get *sag) -{ - struct subagentx_context *sac = sag->sag_sac; - struct subagentx_session *sas = sac->sac_sas; - struct subagentx *sa = sas->sas_sa; - size_t i, j, nvarbind = 0; - uint16_t error = 0, index = 0; - struct agentx_varbind *vbl; - char *logmsg = NULL; - int fail = 0; - - for (i = 0; i < sag->sag_nvarbind; i++) { - if (sag->sag_varbind[i].sav_initialized) { - if (sag->sag_varbind[i].sav_vb.avb_type == 0) - return; - nvarbind++; - } - } - - if (sag->sag_sac == NULL) { - subagentx_get_free(sag); - return; - } - - if ((vbl = calloc(nvarbind, sizeof(*vbl))) == NULL) { - subagentx_log_sag_warn(sag, "Couldn't parse request"); - subagentx_get_free(sag); - subagentx_reset(sa); - return; - } - for (i = 0, j = 0; i < sag->sag_nvarbind; i++) { - if (sag->sag_varbind[i].sav_initialized) { - memcpy(&(vbl[j]), &(sag->sag_varbind[i].sav_vb), - sizeof(*vbl)); - if (error == 0 && sag->sag_varbind[i].sav_error != - AGENTX_PDU_ERROR_NOERROR) { - error = sag->sag_varbind[i].sav_error; - index = j + 1; - } - if (j == 0) - fail |= subagentx_strcat(&logmsg, " {"); - else - fail |= subagentx_strcat(&logmsg, ",{"); - fail |= subagentx_strcat(&logmsg, - agentx_varbind2string(&(vbl[j]))); - if (sag->sag_varbind[i].sav_error != - AGENTX_PDU_ERROR_NOERROR) { - fail |= subagentx_strcat(&logmsg, "("); - fail |= subagentx_strcat(&logmsg, - agentx_error2string( - sag->sag_varbind[i].sav_error)); - fail |= subagentx_strcat(&logmsg, ")"); - } - fail |= subagentx_strcat(&logmsg, "}"); - if (fail) { - subagentx_log_sag_warn(sag, - "Couldn't parse request"); - free(logmsg); - subagentx_get_free(sag); - return; - } - j++; - } - } - subagentx_log_sag_debug(sag, "response:%s", logmsg); - free(logmsg); - - if (agentx_response(sa->sa_ax, sas->sas_id, sag->sag_transactionid, - sag->sag_packetid, SUBAGENTX_CONTEXT_CTX(sac), 0, error, index, - vbl, nvarbind) == -1) { - subagentx_log_sag_warn(sag, "Couldn't parse request"); - subagentx_reset(sa); - } else - subagentx_wantwrite(sa, sa->sa_fd); - free(vbl); - subagentx_get_free(sag); -} - -void -subagentx_get_free(struct subagentx_get *sag) -{ - struct subagentx_varbind *sav; - struct subagentx_object *sao; - struct subagentx *sa = sag->sag_sac->sac_sas->sas_sa; - struct subagentx_varbind_index *index; - size_t i, j; - - if (sag->sag_sac != NULL) - TAILQ_REMOVE(&(sa->sa_getreqs), sag, sag_sa_getreqs); - - for (i = 0; i < sag->sag_nvarbind; i++) { - sav = &(sag->sag_varbind[i]); - for (j = 0; sav->sav_sao != NULL && - j < sav->sav_sao->sao_indexlen; j++) { - sao = sav->sav_sao; - index = &(sav->sav_index[j]); - if (sao->sao_index[j]->sai_vb.avb_type == - AGENTX_DATA_TYPE_OCTETSTRING || - sao->sao_index[j]->sai_vb.avb_type == - AGENTX_DATA_TYPE_IPADDRESS) - free(index->sav_idata.avb_ostring.aos_string); - } - agentx_varbind_free(&(sag->sag_varbind[i].sav_vb)); - } - - free(sag->sag_context.aos_string); - free(sag->sag_varbind); - free(sag); -} - -static void -subagentx_varbind_start(struct subagentx_varbind *sav) -{ - struct subagentx_get *sag = sav->sav_sag; - struct subagentx_context *sac = sag->sag_sac; - struct subagentx_object *sao, sao_search; - struct subagentx_varbind_index *index; - struct subagentx_index *sai; - struct agentx_oid *oid; - union agentx_data *data; - struct in_addr *ipaddress; - unsigned char *ipbytes; - size_t i, j, k; - int overflow = 0, dynamic; - -#ifdef AGENTX_DEBUG - if (!sav->sav_initialized) - subagentx_log_sag_fatalx(sav->sav_sag, - "%s: sav_initialized not set", __func__); -#endif - - bcopy(&(sav->sav_vb.avb_oid), &(sao_search.sao_oid), - sizeof(sao_search.sao_oid)); - - do { - sao = RB_FIND(sac_objects, &(sac->sac_objects), &sao_search); - if (sao_search.sao_oid.aoi_idlen > 0) - sao_search.sao_oid.aoi_idlen--; - } while (sao == NULL && sao_search.sao_oid.aoi_idlen > 0); - if (sao == NULL || sao->sao_cstate != SA_CSTATE_OPEN) { - sav->sav_include = 1; - if (sav->sav_sag->sag_type == AGENTX_PDU_TYPE_GET) { - subagentx_varbind_nosuchobject(sav); - return; - } - bcopy(&(sav->sav_vb.avb_oid), &(sao_search.sao_oid), - sizeof(sao_search.sao_oid)); - sao = RB_NFIND(sac_objects, &(sac->sac_objects), &sao_search); -getnext: - while (sao != NULL && sao->sao_cstate != SA_CSTATE_OPEN) - sao = RB_NEXT(sac_objects, &(sac->sac_objects), sao); - if (sao == NULL) { - subagentx_varbind_endofmibview(sav); - return; - } - bcopy(&(sao->sao_oid), &(sav->sav_vb.avb_oid), - sizeof(sao->sao_oid)); - } - sav->sav_sao = sao; - sav->sav_indexlen = sao->sao_indexlen; - if (subagentx_object_lock(sao) == -1) { - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_PROCESSINGERROR, 1); - return; - } - - oid = &(sav->sav_vb.avb_oid); - if (sao->sao_indexlen == 0) { - if (sav->sav_sag->sag_type == AGENTX_PDU_TYPE_GET) { - if (oid->aoi_idlen != sao->sao_oid.aoi_idlen + 1 || - oid->aoi_id[oid->aoi_idlen - 1] != 0) { - subagentx_varbind_nosuchinstance(sav); - return; - } - } else { - if (oid->aoi_idlen == sao->sao_oid.aoi_idlen) { - oid->aoi_id[oid->aoi_idlen++] = 0; - sav->sav_include = 1; - } else { - sav->sav_sao = NULL; - subagentx_object_unlock(sao); - sao = RB_NEXT(sac_objects, &(sac->sac_objects), - sao); - goto getnext; - } - } - } - j = sao->sao_oid.aoi_idlen; -/* - * We can't trust what the client gives us, so sometimes we need to map it to - * index type. - * - AGENTX_PDU_TYPE_GET: we always return AGENTX_DATA_TYPE_NOSUCHINSTANCE - * - AGENTX_PDU_TYPE_GETNEXT: - * - Missing OID digits to match indices will result in the indices to be NUL- - * initialized and the request type will be set to - * SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE - * - An overflow can happen on AGENTX_DATA_TYPE_OCTETSTRING and - * AGENTX_DATA_TYPE_IPADDRESS. This results in request type being set to - * SUBAGENTX_REQUEST_TYPE_GETNEXT and will set the index to its maximum - * value: - * - AGENTX_DATA_TYPE_INTEGER: UINT32_MAX - * - AGENTX_DATA_TYPE_OCTETSTRING: aos_slen = UINT32_MAX and - * aos_string = NULL - * - AGENTX_DATA_TYPE_OID: aoi_idlen = UINT32_MAX and aoi_id[x] = UINT32_MAX - * - AGENTX_DATA_TYPE_IPADDRESS: 255.255.255.255 - */ - for (dynamic = 0, i = 0; i < sao->sao_indexlen; i++) { - index = &(sav->sav_index[i]); - index->sav_sai = sao->sao_index[i]; - data = &(index->sav_idata); - if (sao->sao_index[i]->sai_type == SAI_TYPE_DYNAMIC) - dynamic = 1; - if (j >= sav->sav_vb.avb_oid.aoi_idlen && !overflow && - sao->sao_index[i]->sai_type == SAI_TYPE_DYNAMIC) - continue; - switch (sao->sao_index[i]->sai_vb.avb_type) { - case AGENTX_DATA_TYPE_INTEGER: -/* Dynamic index: normal copy paste */ - if (sao->sao_index[i]->sai_type == SAI_TYPE_DYNAMIC) { - data->avb_uint32 = overflow ? - UINT32_MAX : sav->sav_vb.avb_oid.aoi_id[j]; - j++; - index->sav_idatacomplete = 1; - break; - } - sai = sao->sao_index[i]; -/* With a GET-request we need an exact match */ - if (sav->sav_sag->sag_type == AGENTX_PDU_TYPE_GET) { - if (sai->sai_vb.avb_data.avb_uint32 != - sav->sav_vb.avb_oid.aoi_id[j]) { - subagentx_varbind_nosuchinstance(sav); - return; - } - index->sav_idatacomplete = 1; - j++; - break; - } -/* A higher value automatically moves us to the next value */ - if (overflow || - sav->sav_vb.avb_oid.aoi_id[j] > - sai->sai_vb.avb_data.avb_uint32) { -/* If we're !dynamic up until now the rest of the oid doesn't matter */ - if (!dynamic) { - subagentx_varbind_endofmibview(sav); - return; - } -/* - * Else we just pick the max value and make sure we don't return - * SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE - */ - data->avb_uint32 = UINT32_MAX; - index->sav_idatacomplete = 1; - overflow = 1; - j++; - break; -/* - * A lower value automatically moves to the set value and counts as a short oid - */ - } else if (sav->sav_vb.avb_oid.aoi_id[j] < - sai->sai_vb.avb_data.avb_uint32) { - data->avb_uint32 = - sai->sai_vb.avb_data.avb_uint32; - j = sav->sav_vb.avb_oid.aoi_idlen; - break; - } -/* Normal match, except we already matched overflow at higher value */ - data->avb_uint32 = sav->sav_vb.avb_oid.aoi_id[j]; - j++; - index->sav_idatacomplete = 1; - break; - case AGENTX_DATA_TYPE_OCTETSTRING: - if (!subagentx_object_implied(sao, index->sav_sai)) { - if (overflow || sav->sav_vb.avb_oid.aoi_id[j] > - SUBAGENTX_OID_MAX_LEN - - sav->sav_vb.avb_oid.aoi_idlen) { - overflow = 1; - data->avb_ostring.aos_slen = UINT32_MAX; - index->sav_idatacomplete = 1; - continue; - } - data->avb_ostring.aos_slen = - sav->sav_vb.avb_oid.aoi_id[j++]; - } else { - if (overflow) { - data->avb_ostring.aos_slen = UINT32_MAX; - index->sav_idatacomplete = 1; - continue; - } - data->avb_ostring.aos_slen = - sav->sav_vb.avb_oid.aoi_idlen - j; - } - data->avb_ostring.aos_string = - calloc(data->avb_ostring.aos_slen + 1, 1); - if (data->avb_ostring.aos_string == NULL) { - subagentx_log_sag_warn(sag, - "Failed to bind string index"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_PROCESSINGERROR, 1); - return; - } - for (k = 0; k < data->avb_ostring.aos_slen; k++, j++) { - if (!overflow && - j == sav->sav_vb.avb_oid.aoi_idlen) - break; - - if (sav->sav_vb.avb_oid.aoi_id[j] > 255) - overflow = 1; - - data->avb_ostring.aos_string[k] = overflow ? - 0xff : sav->sav_vb.avb_oid.aoi_id[j]; - } - if (k == data->avb_ostring.aos_slen) - index->sav_idatacomplete = 1; - break; - case AGENTX_DATA_TYPE_OID: - if (!subagentx_object_implied(sao, index->sav_sai)) { - if (overflow || sav->sav_vb.avb_oid.aoi_id[j] > - SUBAGENTX_OID_MAX_LEN - - sav->sav_vb.avb_oid.aoi_idlen) { - overflow = 1; - data->avb_oid.aoi_idlen = UINT32_MAX; - index->sav_idatacomplete = 1; - continue; - } - data->avb_oid.aoi_idlen = - sav->sav_vb.avb_oid.aoi_id[j++]; - } else { - if (overflow) { - data->avb_oid.aoi_idlen = UINT32_MAX; - index->sav_idatacomplete = 1; - continue; - } - data->avb_oid.aoi_idlen = - sav->sav_vb.avb_oid.aoi_idlen - j; - } - for (k = 0; k < data->avb_oid.aoi_idlen; k++, j++) { - if (!overflow && - j == sav->sav_vb.avb_oid.aoi_idlen) { - data->avb_oid.aoi_id[k] = 0; - continue; - } - data->avb_oid.aoi_id[k] = overflow ? - UINT32_MAX : sav->sav_vb.avb_oid.aoi_id[j]; - } - if (j <= sav->sav_vb.avb_oid.aoi_idlen) - index->sav_idatacomplete = 1; - break; - case AGENTX_DATA_TYPE_IPADDRESS: - ipaddress = calloc(1, sizeof(*ipaddress)); - if (ipaddress == NULL) { - subagentx_log_sag_warn(sag, - "Failed to bind ipaddress index"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_PROCESSINGERROR, 1); - return; - } - ipbytes = (unsigned char *)ipaddress; - for (k = 0; k < 4; k++, j++) { - if (!overflow && - j == sav->sav_vb.avb_oid.aoi_idlen) - break; - - if (sav->sav_vb.avb_oid.aoi_id[j] > 255) - overflow = 1; - - ipbytes[k] = overflow ? 255 : - sav->sav_vb.avb_oid.aoi_id[j]; - } - if (j <= sav->sav_vb.avb_oid.aoi_idlen) - index->sav_idatacomplete = 1; - data->avb_ostring.aos_slen = sizeof(*ipaddress); - data->avb_ostring.aos_string = - (unsigned char *)ipaddress; - break; - default: -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sag, - "%s: unexpected index type", __func__); -#else - subagentx_log_sag_warnx(sag, - "%s: unexpected index type", __func__); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_PROCESSINGERROR, 1); - return; -#endif - } - } - if (sav->sav_sag->sag_type == AGENTX_PDU_TYPE_GET) { - if ((sao->sao_indexlen > 0 && - !sav->sav_index[sao->sao_indexlen - 1].sav_idatacomplete) || - j != sav->sav_vb.avb_oid.aoi_idlen || overflow) { - subagentx_varbind_nosuchinstance(sav); - return; - } - } - - if (overflow || j > sav->sav_vb.avb_oid.aoi_idlen) - sav->sav_include = 0; - -/* - * SUBAGENTX_REQUEST_TYPE_GETNEXT request can !dynamic objects can just move to - * the next object - */ - if (subagentx_varbind_request(sav) == SUBAGENTX_REQUEST_TYPE_GETNEXT && - !dynamic) { - subagentx_varbind_endofmibview(sav); - return; - } - - sao->sao_get(sav); -} - -void -subagentx_varbind_integer(struct subagentx_varbind *sav, uint32_t value) -{ - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_INTEGER; - sav->sav_vb.avb_data.avb_uint32 = value; - - subagentx_varbind_finalize(sav); -} - -void -subagentx_varbind_string(struct subagentx_varbind *sav, const char *value) -{ - subagentx_varbind_nstring(sav, (const unsigned char *)value, - strlen(value)); -} - -void -subagentx_varbind_nstring(struct subagentx_varbind *sav, - const unsigned char *value, size_t slen) -{ - sav->sav_vb.avb_data.avb_ostring.aos_string = malloc(slen); - if (sav->sav_vb.avb_data.avb_ostring.aos_string == NULL) { - subagentx_log_sag_warn(sav->sav_sag, "Couldn't bind string"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_PROCESSINGERROR, 1); - return; - } - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_OCTETSTRING; - memcpy(sav->sav_vb.avb_data.avb_ostring.aos_string, value, slen); - sav->sav_vb.avb_data.avb_ostring.aos_slen = slen; - - subagentx_varbind_finalize(sav); -} - -void -subagentx_varbind_printf(struct subagentx_varbind *sav, const char *fmt, ...) -{ - va_list ap; - int r; - - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_OCTETSTRING; - va_start(ap, fmt); - r = vasprintf((char **)&(sav->sav_vb.avb_data.avb_ostring.aos_string), - fmt, ap); - va_end(ap); - if (r == -1) { - sav->sav_vb.avb_data.avb_ostring.aos_string = NULL; - subagentx_log_sag_warn(sav->sav_sag, "Couldn't bind string"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_PROCESSINGERROR, 1); - return; - } - sav->sav_vb.avb_data.avb_ostring.aos_slen = r; - - subagentx_varbind_finalize(sav); -} - -void -subagentx_varbind_null(struct subagentx_varbind *sav) -{ - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_NULL; - - subagentx_varbind_finalize(sav); -} - -void -subagentx_varbind_oid(struct subagentx_varbind *sav, const uint32_t oid[], - size_t oidlen) -{ - size_t i; - - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_OID; - - for (i = 0; i < oidlen; i++) - sav->sav_vb.avb_data.avb_oid.aoi_id[i] = oid[i]; - sav->sav_vb.avb_data.avb_oid.aoi_idlen = oidlen; - - subagentx_varbind_finalize(sav); -} - -void -subagentx_varbind_object(struct subagentx_varbind *sav, - struct subagentx_object *sao) -{ - subagentx_varbind_oid(sav, sao->sao_oid.aoi_id, - sao->sao_oid.aoi_idlen); -} - -void -subagentx_varbind_index(struct subagentx_varbind *sav, - struct subagentx_index *sai) -{ - subagentx_varbind_oid(sav, sai->sai_vb.avb_oid.aoi_id, - sai->sai_vb.avb_oid.aoi_idlen); -} - - -void -subagentx_varbind_ipaddress(struct subagentx_varbind *sav, - const struct in_addr *value) -{ - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_IPADDRESS; - sav->sav_vb.avb_data.avb_ostring.aos_string = malloc(4); - if (sav->sav_vb.avb_data.avb_ostring.aos_string == NULL) { - subagentx_log_sag_warn(sav->sav_sag, "Couldn't bind ipaddress"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_PROCESSINGERROR, 1); - return; - } - memcpy(sav->sav_vb.avb_data.avb_ostring.aos_string, value, 4); - sav->sav_vb.avb_data.avb_ostring.aos_slen = 4; - - subagentx_varbind_finalize(sav); -} - -void -subagentx_varbind_counter32(struct subagentx_varbind *sav, uint32_t value) -{ - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_COUNTER32; - sav->sav_vb.avb_data.avb_uint32 = value; - - subagentx_varbind_finalize(sav); -} - -void -subagentx_varbind_gauge32(struct subagentx_varbind *sav, uint32_t value) -{ - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_GAUGE32; - sav->sav_vb.avb_data.avb_uint32 = value; - - subagentx_varbind_finalize(sav); -} - -void -subagentx_varbind_timeticks(struct subagentx_varbind *sav, uint32_t value) -{ - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_TIMETICKS; - sav->sav_vb.avb_data.avb_uint32 = value; - - subagentx_varbind_finalize(sav); -} - -void -subagentx_varbind_opaque(struct subagentx_varbind *sav, const char *string, - size_t strlen) -{ - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_OPAQUE; - sav->sav_vb.avb_data.avb_ostring.aos_string = malloc(strlen); - if (sav->sav_vb.avb_data.avb_ostring.aos_string == NULL) { - subagentx_log_sag_warn(sav->sav_sag, "Couldn't bind opaque"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_PROCESSINGERROR, 1); - return; - } - memcpy(sav->sav_vb.avb_data.avb_ostring.aos_string, string, strlen); - sav->sav_vb.avb_data.avb_ostring.aos_slen = strlen; - - subagentx_varbind_finalize(sav); -} - -void -subagentx_varbind_counter64(struct subagentx_varbind *sav, uint64_t value) -{ - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_COUNTER64; - sav->sav_vb.avb_data.avb_uint64 = value; - - subagentx_varbind_finalize(sav); -} - -void -subagentx_varbind_notfound(struct subagentx_varbind *sav) -{ - if (sav->sav_indexlen == 0) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "%s invalid call", - __func__); -#else - subagentx_log_sag_warnx(sav->sav_sag, "%s invalid call", - __func__); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_GENERR, 1); -#endif - } else if (sav->sav_sag->sag_type == AGENTX_PDU_TYPE_GET) - subagentx_varbind_nosuchinstance(sav); - else - subagentx_varbind_endofmibview(sav); -} - -void -subagentx_varbind_error(struct subagentx_varbind *sav) -{ - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 1); -} - -static void -subagentx_varbind_error_type(struct subagentx_varbind *sav, - enum agentx_pdu_error error, int done) -{ - if (sav->sav_error == AGENTX_PDU_ERROR_NOERROR) { - sav->sav_error = error; - } - - if (done) { - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_NULL; - - subagentx_varbind_finalize(sav); - } -} - -static void -subagentx_varbind_finalize(struct subagentx_varbind *sav) -{ - struct subagentx_get *sag = sav->sav_sag; - struct agentx_oid oid; - union agentx_data *data; - size_t i, j; - int cmp; - - if (sav->sav_error != AGENTX_PDU_ERROR_NOERROR) { - bcopy(&(sav->sav_start), &(sav->sav_vb.avb_oid), - sizeof(sav->sav_start)); - goto done; - } - bcopy(&(sav->sav_sao->sao_oid), &oid, sizeof(oid)); - if (sav->sav_indexlen == 0) - agentx_oid_add(&oid, 0); - for (i = 0; i < sav->sav_indexlen; i++) { - data = &(sav->sav_index[i].sav_idata); - switch (sav->sav_index[i].sav_sai->sai_vb.avb_type) { - case AGENTX_DATA_TYPE_INTEGER: - if (agentx_oid_add(&oid, data->avb_uint32) == -1) - goto fail; - break; - case AGENTX_DATA_TYPE_OCTETSTRING: - if (!subagentx_object_implied(sav->sav_sao, - sav->sav_index[i].sav_sai)) { - if (agentx_oid_add(&oid, - data->avb_ostring.aos_slen) == -1) - goto fail; - } - for (j = 0; j < data->avb_ostring.aos_slen; j++) { - if (agentx_oid_add(&oid, - (uint8_t)data->avb_ostring.aos_string[j]) == - -1) - goto fail; - } - break; - case AGENTX_DATA_TYPE_OID: - if (!subagentx_object_implied(sav->sav_sao, - sav->sav_index[i].sav_sai)) { - if (agentx_oid_add(&oid, - data->avb_oid.aoi_idlen) == -1) - goto fail; - } - for (j = 0; j < data->avb_oid.aoi_idlen; j++) { - if (agentx_oid_add(&oid, - data->avb_oid.aoi_id[j]) == -1) - goto fail; - } - break; - case AGENTX_DATA_TYPE_IPADDRESS: - for (j = 0; j < 4; j++) { - if (agentx_oid_add(&oid, - data->avb_ostring.aos_string == NULL ? 0 : - (uint8_t)data->avb_ostring.aos_string[j]) == - -1) - goto fail; - } - break; - default: -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sag, - "%s: unsupported index type", __func__); -#else - bcopy(&(sav->sav_start), &(sav->sav_vb.avb_oid), - sizeof(sav->sav_start)); - sav->sav_error = AGENTX_PDU_ERROR_PROCESSINGERROR; - subagentx_object_unlock(sav->sav_sao); - subagentx_get_finalize(sav->sav_sag); - return; -#endif - } - } - cmp = agentx_oid_cmp(&(sav->sav_vb.avb_oid), &oid); - if ((subagentx_varbind_request(sav) == SUBAGENTX_REQUEST_TYPE_GETNEXT && - cmp >= 0) || cmp > 0) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sag, "indices not incremented"); -#else - subagentx_log_sag_warnx(sag, "indices not incremented"); - bcopy(&(sav->sav_start), &(sav->sav_vb.avb_oid), - sizeof(sav->sav_start)); - sav->sav_error = AGENTX_PDU_ERROR_GENERR; -#endif - } else - bcopy(&oid, &(sav->sav_vb.avb_oid), sizeof(oid)); -done: - subagentx_object_unlock(sav->sav_sao); - subagentx_get_finalize(sav->sav_sag); - return; - -fail: - subagentx_log_sag_warnx(sag, "oid too large"); - bcopy(&(sav->sav_start), &(sav->sav_vb.avb_oid), - sizeof(sav->sav_start)); - sav->sav_error = AGENTX_PDU_ERROR_GENERR; - subagentx_object_unlock(sav->sav_sao); - subagentx_get_finalize(sav->sav_sag); -} - -static void -subagentx_varbind_nosuchobject(struct subagentx_varbind *sav) -{ - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_NOSUCHOBJECT; - - if (sav->sav_sao != NULL) - subagentx_object_unlock(sav->sav_sao); - subagentx_get_finalize(sav->sav_sag); -} - -static void -subagentx_varbind_nosuchinstance(struct subagentx_varbind *sav) -{ - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_NOSUCHINSTANCE; - - if (sav->sav_sao != NULL) - subagentx_object_unlock(sav->sav_sao); - subagentx_get_finalize(sav->sav_sag); -} - -static void -subagentx_varbind_endofmibview(struct subagentx_varbind *sav) -{ - struct subagentx_object *sao; - struct agentx_varbind *vb; - struct subagentx_varbind_index *index; - size_t i; - -#ifdef AGENTX_DEBUG - if (sav->sav_sag->sag_type != AGENTX_PDU_TYPE_GETNEXT && - sav->sav_sag->sag_type != AGENTX_PDU_TYPE_GETBULK) - subagentx_log_sag_fatalx(sav->sav_sag, - "%s: invalid request type", __func__); -#endif - - if (sav->sav_sao != NULL && - (sao = RB_NEXT(sac_objects, &(sac->sac_objects), - sav->sav_sao)) != NULL && - agentx_oid_cmp(&(sao->sao_oid), &(sav->sav_end)) < 0) { - bcopy(&(sao->sao_oid), &(sav->sav_vb.avb_oid), - sizeof(sao->sao_oid)); - sav->sav_include = 1; - for (i = 0; i < sav->sav_indexlen; i++) { - index = &(sav->sav_index[i]); - vb = &(index->sav_sai->sai_vb); - if (vb->avb_type == AGENTX_DATA_TYPE_OCTETSTRING || - vb->avb_type == AGENTX_DATA_TYPE_IPADDRESS) - free(index->sav_idata.avb_ostring.aos_string); - } - bzero(&(sav->sav_index), sizeof(sav->sav_index)); - subagentx_object_unlock(sav->sav_sao); - subagentx_varbind_start(sav); - return; - } - - sav->sav_vb.avb_type = AGENTX_DATA_TYPE_ENDOFMIBVIEW; - - if (sav->sav_sao != NULL) - subagentx_object_unlock(sav->sav_sao); - subagentx_get_finalize(sav->sav_sag); -} - -enum subagentx_request_type -subagentx_varbind_request(struct subagentx_varbind *sav) -{ - if (sav->sav_sag->sag_type == AGENTX_PDU_TYPE_GET) - return SUBAGENTX_REQUEST_TYPE_GET; - if (sav->sav_include || - (sav->sav_indexlen > 0 && - !sav->sav_index[sav->sav_indexlen - 1].sav_idatacomplete)) - return SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE; - return SUBAGENTX_REQUEST_TYPE_GETNEXT; -} - -struct subagentx_object * -subagentx_varbind_get_object(struct subagentx_varbind *sav) -{ - return sav->sav_sao; -} - -uint32_t -subagentx_varbind_get_index_integer(struct subagentx_varbind *sav, - struct subagentx_index *sai) -{ - size_t i; - - if (sai->sai_vb.avb_type != AGENTX_DATA_TYPE_INTEGER) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index type"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index type"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); - return 0; -#endif - } - - for (i = 0; i < sav->sav_indexlen; i++) { - if (sav->sav_index[i].sav_sai == sai) - return sav->sav_index[i].sav_idata.avb_uint32; - } -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); - return 0; -#endif -} - -const unsigned char * -subagentx_varbind_get_index_string(struct subagentx_varbind *sav, - struct subagentx_index *sai, size_t *slen, int *implied) -{ - struct subagentx_varbind_index *index; - size_t i; - - if (sai->sai_vb.avb_type != AGENTX_DATA_TYPE_OCTETSTRING) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index type"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index type"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); - *slen = 0; - *implied = 0; - return NULL; -#endif - } - - for (i = 0; i < sav->sav_indexlen; i++) { - if (sav->sav_index[i].sav_sai == sai) { - index = &(sav->sav_index[i]); - *slen = index->sav_idata.avb_ostring.aos_slen; - *implied = subagentx_object_implied(sav->sav_sao, sai); - return index->sav_idata.avb_ostring.aos_string; - } - } - -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); - *slen = 0; - *implied = 0; - return NULL; -#endif -} - -const uint32_t * -subagentx_varbind_get_index_oid(struct subagentx_varbind *sav, - struct subagentx_index *sai, size_t *oidlen, int *implied) -{ - struct subagentx_varbind_index *index; - size_t i; - - if (sai->sai_vb.avb_type != AGENTX_DATA_TYPE_OID) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index type"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index type"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); - *oidlen = 0; - *implied = 0; - return NULL; -#endif - } - - for (i = 0; i < sav->sav_indexlen; i++) { - if (sav->sav_index[i].sav_sai == sai) { - index = &(sav->sav_index[i]); - *oidlen = index->sav_idata.avb_oid.aoi_idlen; - *implied = subagentx_object_implied(sav->sav_sao, sai); - return index->sav_idata.avb_oid.aoi_id; - } - } - -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); - *oidlen = 0; - *implied = 0; - return NULL; -#endif -} - -const struct in_addr * -subagentx_varbind_get_index_ipaddress(struct subagentx_varbind *sav, - struct subagentx_index *sai) -{ - static struct in_addr nuladdr = {0}; - struct subagentx_varbind_index *index; - size_t i; - - if (sai->sai_vb.avb_type != AGENTX_DATA_TYPE_IPADDRESS) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index type"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index type"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); - return NULL; -#endif - } - - for (i = 0; i < sav->sav_indexlen; i++) { - if (sav->sav_index[i].sav_sai == sai) { - index = &(sav->sav_index[i]); - if (index->sav_idata.avb_ostring.aos_string == NULL) - return &nuladdr; - return (struct in_addr *) - index->sav_idata.avb_ostring.aos_string; - } - } - -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); - return NULL; -#endif -} - -void -subagentx_varbind_set_index_integer(struct subagentx_varbind *sav, - struct subagentx_index *sai, uint32_t value) -{ - size_t i; - - if (sai->sai_vb.avb_type != AGENTX_DATA_TYPE_INTEGER) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index type"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index type"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); - return; -#endif - } - - for (i = 0; i < sav->sav_indexlen; i++) { - if (sav->sav_index[i].sav_sai == sai) { - if (sav->sav_sag->sag_type == AGENTX_PDU_TYPE_GET && - sav->sav_index[i].sav_idata.avb_uint32 != value) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, - "can't change index on GET"); -#else - subagentx_log_sag_warnx(sav->sav_sag, - "can't change index on GET"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_GENERR, 0); - return; -#endif - } - sav->sav_index[i].sav_idata.avb_uint32 = value; - return; - } - } -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); -#endif -} - -void -subagentx_varbind_set_index_string(struct subagentx_varbind *sav, - struct subagentx_index *sai, const char *value) -{ - subagentx_varbind_set_index_nstring(sav, sai, - (const unsigned char *)value, strlen(value)); -} - -void -subagentx_varbind_set_index_nstring(struct subagentx_varbind *sav, - struct subagentx_index *sai, const unsigned char *value, size_t slen) -{ - struct agentx_ostring *curvalue; - unsigned char *nstring; - size_t i; - - if (sai->sai_vb.avb_type != AGENTX_DATA_TYPE_OCTETSTRING) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index type"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index type"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); - return; -#endif - } - - for (i = 0; i < sav->sav_indexlen; i++) { - if (sav->sav_index[i].sav_sai == sai) { - if (sai->sai_vb.avb_data.avb_ostring.aos_slen != 0 && - sai->sai_vb.avb_data.avb_ostring.aos_slen != slen) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, - "invalid string length on explicit length " - "string"); -#else - subagentx_log_sag_warnx(sav->sav_sag, - "invalid string length on explicit length " - "string"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_GENERR, 0); - return; -#endif - } - curvalue = &(sav->sav_index[i].sav_idata.avb_ostring); - if (sav->sav_sag->sag_type == AGENTX_PDU_TYPE_GET && - (curvalue->aos_slen != slen || - memcmp(curvalue->aos_string, value, slen) != 0)) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, - "can't change index on GET"); -#else - subagentx_log_sag_warnx(sav->sav_sag, - "can't change index on GET"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_GENERR, 0); - return; -#endif - } - if ((nstring = recallocarray(curvalue->aos_string, - curvalue->aos_slen + 1, slen + 1, 1)) == NULL) { - subagentx_log_sag_warn(sav->sav_sag, - "Failed to bind string index"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_PROCESSINGERROR, 0); - return; - } - curvalue->aos_string = nstring; - memcpy(nstring, value, slen); - curvalue->aos_slen = slen; - return; - } - } -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); -#endif -} - -void -subagentx_varbind_set_index_oid(struct subagentx_varbind *sav, - struct subagentx_index *sai, const uint32_t *value, size_t oidlen) -{ - struct agentx_oid *curvalue, oid; - size_t i; - - if (sai->sai_vb.avb_type != AGENTX_DATA_TYPE_OID) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index type"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index type"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); - return; -#endif - } - - for (i = 0; i < sav->sav_indexlen; i++) { - if (sav->sav_index[i].sav_sai == sai) { - if (sai->sai_vb.avb_data.avb_oid.aoi_idlen != 0 && - sai->sai_vb.avb_data.avb_oid.aoi_idlen != oidlen) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, - "invalid oid length on explicit length " - "oid"); -#else - subagentx_log_sag_warnx(sav->sav_sag, - "invalid oid length on explicit length " - "oid"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_GENERR, 0); - return; -#endif - } - curvalue = &(sav->sav_index[i].sav_idata.avb_oid); - for (i = 0; i < oidlen; i++) - oid.aoi_id[i] = value[i]; - oid.aoi_idlen = oidlen; - if (sav->sav_sag->sag_type == AGENTX_PDU_TYPE_GET && - agentx_oid_cmp(&oid, curvalue) != 0) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, - "can't change index on GET"); -#else - subagentx_log_sag_warnx(sav->sav_sag, - "can't change index on GET"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_GENERR, 0); - return; -#endif - } - for (i = 0; i < oidlen; i++) - curvalue->aoi_id[i] = value[i]; - curvalue->aoi_idlen = oidlen; - return; - } - } -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); -#endif -} - -void -subagentx_varbind_set_index_object(struct subagentx_varbind *sav, - struct subagentx_index *sai, struct subagentx_object *sao) -{ - subagentx_varbind_set_index_oid(sav, sai, sao->sao_oid.aoi_id, - sao->sao_oid.aoi_idlen); -} - -void -subagentx_varbind_set_index_ipaddress(struct subagentx_varbind *sav, - struct subagentx_index *sai, const struct in_addr *addr) -{ - struct agentx_ostring *curvalue; - size_t i; - - if (sai->sai_vb.avb_type != AGENTX_DATA_TYPE_IPADDRESS) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index type"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index type"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); - return; -#endif - } - - for (i = 0; i < sav->sav_indexlen; i++) { - if (sav->sav_index[i].sav_sai == sai) { - curvalue = &(sav->sav_index[i].sav_idata.avb_ostring); - if (curvalue->aos_string == NULL) - curvalue->aos_string = calloc(1, sizeof(*addr)); - if (curvalue->aos_string == NULL) { - subagentx_log_sag_warn(sav->sav_sag, - "Failed to bind ipaddress index"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_PROCESSINGERROR, 0); - return; - } - if (sav->sav_sag->sag_type == AGENTX_PDU_TYPE_GET && - memcmp(addr, curvalue->aos_string, - sizeof(*addr)) != 0) { -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, - "can't change index on GET"); -#else - subagentx_log_sag_warnx(sav->sav_sag, - "can't change index on GET"); - subagentx_varbind_error_type(sav, - AGENTX_PDU_ERROR_GENERR, 0); - return; -#endif - } - bcopy(addr, curvalue->aos_string, sizeof(*addr)); - return; - } - } -#ifdef AGENTX_DEBUG - subagentx_log_sag_fatalx(sav->sav_sag, "invalid index"); -#else - subagentx_log_sag_warnx(sav->sav_sag, "invalid index"); - subagentx_varbind_error_type(sav, AGENTX_PDU_ERROR_GENERR, 0); -#endif -} - -static int -subagentx_request(struct subagentx *sa, uint32_t packetid, - int (*cb)(struct agentx_pdu *, void *), void *cookie) -{ - struct subagentx_request *sar; - -#ifdef AGENTX_DEBUG - if (sa->sa_ax->ax_wblen == 0) - subagentx_log_sa_fatalx(sa, "%s: no data to be written", - __func__); -#endif - - if ((sar = calloc(1, sizeof(*sar))) == NULL) { - subagentx_log_sa_warn(sa, "couldn't create request context"); - subagentx_reset(sa); - return -1; - } - - sar->sar_packetid = packetid; - sar->sar_cb = cb; - sar->sar_cookie = cookie; - if (RB_INSERT(sa_requests, &(sa->sa_requests), sar) != NULL) { -#ifdef AGENTX_DEBUG - subagentx_log_sa_fatalx(sa, "%s: duplicate packetid", __func__); -#else - subagentx_log_sa_warnx(sa, "%s: duplicate packetid", __func__); - free(sar); - subagentx_reset(sa); - return -1; -#endif - } - - subagentx_wantwrite(sa, sa->sa_fd); - return 0; -} - -static int -subagentx_request_cmp(struct subagentx_request *r1, - struct subagentx_request *r2) -{ - return r1->sar_packetid < r2->sar_packetid ? -1 : - r1->sar_packetid > r2->sar_packetid; -} - -static int -subagentx_strcat(char **dst, const char *src) -{ - char *tmp; - size_t dstlen = 0, buflen = 0, srclen, nbuflen; - - if (*dst != NULL) { - dstlen = strlen(*dst); - buflen = ((dstlen / 512) + 1) * 512; - } - - srclen = strlen(src); - if (*dst == NULL || dstlen + srclen > buflen) { - nbuflen = (((dstlen + srclen) / 512) + 1) * 512; - tmp = recallocarray(*dst, buflen, nbuflen, sizeof(*tmp)); - if (tmp == NULL) - return -1; - *dst = tmp; - buflen = nbuflen; - } - - (void)strlcat(*dst, src, buflen); - return 0; -} - -void -subagentx_read(struct subagentx *sa) -{ - struct subagentx_session *sas; - struct subagentx_context *sac; - struct subagentx_request sar_search, *sar; - struct agentx_pdu *pdu; - int error; - - if ((pdu = agentx_recv(sa->sa_ax)) == NULL) { - if (errno == EAGAIN) - return; - subagentx_log_sa_warn(sa, "lost connection"); - subagentx_reset(sa); - return; - } - - TAILQ_FOREACH(sas, &(sa->sa_sessions), sas_sa_sessions) { - if (sas->sas_id == pdu->ap_header.aph_sessionid) - break; - if (sas->sas_cstate == SA_CSTATE_WAITOPEN && - sas->sas_packetid == pdu->ap_header.aph_packetid) - break; - } - if (sas == NULL) { - subagentx_log_sa_warnx(sa, "received unexpected session: %d", - pdu->ap_header.aph_sessionid); - agentx_pdu_free(pdu); - subagentx_reset(sa); - return; - } - TAILQ_FOREACH(sac, &(sas->sas_contexts), sac_sas_contexts) { - if ((pdu->ap_header.aph_flags & - AGENTX_PDU_FLAG_NON_DEFAULT_CONTEXT) == 0 && - sac->sac_name_default == 1) - break; - if (pdu->ap_header.aph_flags & - AGENTX_PDU_FLAG_NON_DEFAULT_CONTEXT && - sac->sac_name_default == 0 && - pdu->ap_context.aos_slen == sac->sac_name.aos_slen && - memcmp(pdu->ap_context.aos_string, - sac->sac_name.aos_string, sac->sac_name.aos_slen) == 0) - break; - } - if (pdu->ap_header.aph_type != AGENTX_PDU_TYPE_RESPONSE) { - if (sac == NULL) { - subagentx_log_sa_warnx(sa, "%s: invalid context", - pdu->ap_context.aos_string); - agentx_pdu_free(pdu); - subagentx_reset(sa); - return; - } - } - - switch (pdu->ap_header.aph_type) { - case AGENTX_PDU_TYPE_GET: - case AGENTX_PDU_TYPE_GETNEXT: - case AGENTX_PDU_TYPE_GETBULK: - subagentx_get_start(sac, pdu); - break; - /* Add stubs for set functions */ - case AGENTX_PDU_TYPE_TESTSET: - case AGENTX_PDU_TYPE_COMMITSET: - case AGENTX_PDU_TYPE_UNDOSET: - if (pdu->ap_header.aph_type == AGENTX_PDU_TYPE_TESTSET) - error = AGENTX_PDU_ERROR_NOTWRITABLE; - else if (pdu->ap_header.aph_type == AGENTX_PDU_TYPE_COMMITSET) - error = AGENTX_PDU_ERROR_COMMITFAILED; - else - error = AGENTX_PDU_ERROR_UNDOFAILED; - - subagentx_log_sac_debug(sac, "unsupported call: %s", - agentx_pdutype2string(pdu->ap_header.aph_type)); - if (agentx_response(sa->sa_ax, sas->sas_id, - pdu->ap_header.aph_transactionid, - pdu->ap_header.aph_packetid, - sac == NULL ? NULL : SUBAGENTX_CONTEXT_CTX(sac), - 0, error, 1, NULL, 0) == -1) - subagentx_log_sac_warn(sac, - "transaction: %u packetid: %u: failed to send " - "reply", pdu->ap_header.aph_transactionid, - pdu->ap_header.aph_packetid); - if (sa->sa_ax->ax_wblen > 0) - subagentx_wantwrite(sa, sa->sa_fd); - break; - case AGENTX_PDU_TYPE_CLEANUPSET: - subagentx_log_sa_debug(sa, "unsupported call: %s", - agentx_pdutype2string(pdu->ap_header.aph_type)); - break; - case AGENTX_PDU_TYPE_RESPONSE: - sar_search.sar_packetid = pdu->ap_header.aph_packetid; - sar = RB_FIND(sa_requests, &(sa->sa_requests), &sar_search); - if (sar == NULL) { - if (sac == NULL) - subagentx_log_sa_warnx(sa, "received " - "response on non-request"); - else - subagentx_log_sac_warnx(sac, "received " - "response on non-request"); - break; - } - if (sac != NULL && pdu->ap_payload.ap_response.ap_error == 0) { - sac->sac_sysuptime = - pdu->ap_payload.ap_response.ap_uptime; - (void) clock_gettime(CLOCK_MONOTONIC, - &(sac->sac_sysuptimespec)); - } - RB_REMOVE(sa_requests, &(sa->sa_requests), sar); - (void) sar->sar_cb(pdu, sar->sar_cookie); - free(sar); - break; - default: - if (sac == NULL) - subagentx_log_sa_warnx(sa, "unsupported call: %s", - agentx_pdutype2string(pdu->ap_header.aph_type)); - else - subagentx_log_sac_warnx(sac, "unsupported call: %s", - agentx_pdutype2string(pdu->ap_header.aph_type)); - subagentx_reset(sa); - break; - } - agentx_pdu_free(pdu); -} - -void -subagentx_write(struct subagentx *sa) -{ - ssize_t send; - - if ((send = agentx_send(sa->sa_ax)) == -1) { - if (errno == EAGAIN) { - subagentx_wantwrite(sa, sa->sa_fd); - return; - } - subagentx_log_sa_warn(sa, "lost connection"); - subagentx_reset(sa); - return; - } - if (send > 0) - subagentx_wantwrite(sa, sa->sa_fd); -} - -RB_GENERATE_STATIC(sa_requests, subagentx_request, sar_sa_requests, - subagentx_request_cmp) -RB_GENERATE_STATIC(sac_objects, subagentx_object, sao_sac_objects, - subagentx_object_cmp) diff --git a/usr.sbin/relayd/subagentx.h b/usr.sbin/relayd/subagentx.h deleted file mode 100644 index 418b86a78c1..00000000000 --- a/usr.sbin/relayd/subagentx.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <netinet/in.h> - -#include <stdint.h> -#include <stddef.h> - -struct subagentx; -struct subagentx_session; -struct subagentx_context; -struct subagentx_agentcaps; -struct subagentx_region; -struct subagentx_index; -struct subagentx_object; -struct subagentx_varbind; - -enum subagentx_request_type { - SUBAGENTX_REQUEST_TYPE_GET, - SUBAGENTX_REQUEST_TYPE_GETNEXT, - SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE -}; - -#define SUBAGENTX_AGENTX_MASTER "/var/agentx/master" -#define SUBAGENTX_OID_MAX_LEN 128 -#define SUBAGENTX_OID_INDEX_MAX_LEN 10 -#define SUBAGENTX_MIB2 1, 3, 6, 1, 2, 1 -#define SUBAGENTX_ENTERPRISES 1, 3, 6, 1, 4, 1 -#define SUBAGENTX_OID(...) (uint32_t []) { __VA_ARGS__ }, \ - (sizeof((uint32_t []) { __VA_ARGS__ }) / sizeof(uint32_t)) - -extern void (*subagentx_log_fatal)(const char *, ...) - __attribute__((__format__ (printf, 1, 2))); -extern void (*subagentx_log_warn)(const char *, ...) - __attribute__((__format__ (printf, 1, 2))); -extern void (*subagentx_log_info)(const char *, ...) - __attribute__((__format__ (printf, 1, 2))); -extern void (*subagentx_log_debug)(const char *, ...) - __attribute__((__format__ (printf, 1, 2))); - -struct subagentx *subagentx(void (*)(struct subagentx *, void *, int), void *); -void subagentx_connect(struct subagentx *, int); -void subagentx_read(struct subagentx *); -void subagentx_write(struct subagentx *); -extern void (*subagentx_wantwrite)(struct subagentx *, int); -void subagentx_free(struct subagentx *); -struct subagentx_session *subagentx_session(struct subagentx *, - uint32_t[], size_t, const char *, uint8_t); -void subagentx_session_free(struct subagentx_session *); -struct subagentx_context *subagentx_context(struct subagentx_session *, - const char *); -struct subagentx_object *subagentx_context_object_find( - struct subagentx_context *, const uint32_t[], size_t, int, int); -struct subagentx_object *subagentx_context_object_nfind( - struct subagentx_context *, const uint32_t[], size_t, int, int); -uint32_t subagentx_context_uptime(struct subagentx_context *); -void subagentx_context_free(struct subagentx_context *); -struct subagentx_agentcaps *subagentx_agentcaps(struct subagentx_context *, - uint32_t[], size_t, const char *); -void subagentx_agentcaps_free(struct subagentx_agentcaps *); -struct subagentx_region *subagentx_region(struct subagentx_context *, - uint32_t[], size_t, uint8_t); -void subagentx_region_free(struct subagentx_region *); -struct subagentx_index *subagentx_index_integer_new(struct subagentx_region *, - uint32_t[], size_t); -struct subagentx_index *subagentx_index_integer_any(struct subagentx_region *, - uint32_t[], size_t); -struct subagentx_index *subagentx_index_integer_value(struct subagentx_region *, - uint32_t[], size_t, uint32_t); -struct subagentx_index *subagentx_index_integer_dynamic( - struct subagentx_region *, uint32_t[], size_t); -struct subagentx_index *subagentx_index_string_dynamic( - struct subagentx_region *, uint32_t[], size_t); -struct subagentx_index *subagentx_index_nstring_dynamic( - struct subagentx_region *, uint32_t[], size_t, size_t); -struct subagentx_index *subagentx_index_oid_dynamic(struct subagentx_region *, - uint32_t[], size_t); -struct subagentx_index *subagentx_index_noid_dynamic(struct subagentx_region *, - uint32_t[], size_t, size_t); -struct subagentx_index *subagentx_index_ipaddress_dynamic( - struct subagentx_region *, uint32_t[], size_t); -void subagentx_index_free(struct subagentx_index *); -struct subagentx_object *subagentx_object(struct subagentx_region *, uint32_t[], - size_t, struct subagentx_index *[], size_t, int, - void (*)(struct subagentx_varbind *)); -void subagentx_object_free(struct subagentx_object *); - -void subagentx_varbind_integer(struct subagentx_varbind *, uint32_t); -void subagentx_varbind_string(struct subagentx_varbind *, const char *); -void subagentx_varbind_nstring(struct subagentx_varbind *, - const unsigned char *, size_t); -void subagentx_varbind_printf(struct subagentx_varbind *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void subagentx_varbind_null(struct subagentx_varbind *); -void subagentx_varbind_oid(struct subagentx_varbind *, const uint32_t[], - size_t); -void subagentx_varbind_object(struct subagentx_varbind *, - struct subagentx_object *); -void subagentx_varbind_index(struct subagentx_varbind *, - struct subagentx_index *); -void subagentx_varbind_ipaddress(struct subagentx_varbind *, - const struct in_addr *); -void subagentx_varbind_counter32(struct subagentx_varbind *, uint32_t); -void subagentx_varbind_gauge32(struct subagentx_varbind *, uint32_t); -void subagentx_varbind_timeticks(struct subagentx_varbind *, uint32_t); -void subagentx_varbind_opaque(struct subagentx_varbind *, const char *, size_t); -void subagentx_varbind_counter64(struct subagentx_varbind *, uint64_t); -void subagentx_varbind_notfound(struct subagentx_varbind *); -void subagentx_varbind_error(struct subagentx_varbind *); - -enum subagentx_request_type subagentx_varbind_request( - struct subagentx_varbind *); -struct subagentx_object * - subagentx_varbind_get_object(struct subagentx_varbind *); -uint32_t subagentx_varbind_get_index_integer(struct subagentx_varbind *, - struct subagentx_index *); -const unsigned char *subagentx_varbind_get_index_string( - struct subagentx_varbind *, struct subagentx_index *, size_t *, int *); -const uint32_t *subagentx_varbind_get_index_oid(struct subagentx_varbind *, - struct subagentx_index *, size_t *, int *); -const struct in_addr *subagentx_varbind_get_index_ipaddress( - struct subagentx_varbind *, struct subagentx_index *); -void subagentx_varbind_set_index_integer(struct subagentx_varbind *, - struct subagentx_index *, uint32_t); -void subagentx_varbind_set_index_string(struct subagentx_varbind *, - struct subagentx_index *, const char *); -void subagentx_varbind_set_index_nstring(struct subagentx_varbind *, - struct subagentx_index *, const unsigned char *, size_t); -void subagentx_varbind_set_index_oid(struct subagentx_varbind *, - struct subagentx_index *, const uint32_t *, size_t); -void subagentx_varbind_set_index_object(struct subagentx_varbind *, - struct subagentx_index *, struct subagentx_object *); -void subagentx_varbind_set_index_ipaddress(struct subagentx_varbind *, - struct subagentx_index *, const struct in_addr *); diff --git a/usr.sbin/relayd/subagentx_internal.h b/usr.sbin/relayd/subagentx_internal.h deleted file mode 100644 index 4dafcf373a4..00000000000 --- a/usr.sbin/relayd/subagentx_internal.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2020 Martijn van Duren <martijn@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include <sys/queue.h> -#include <sys/time.h> -#include <sys/tree.h> - -#include "agentx.h" - -enum subagentx_cstate { /* Current state */ - SA_CSTATE_CLOSE, /* Closed */ - SA_CSTATE_WAITOPEN, /* Connection requested */ - SA_CSTATE_OPEN, /* Open */ - SA_CSTATE_WAITCLOSE /* Close requested */ -}; - -enum subagentx_dstate { /* Desired state */ - SA_DSTATE_OPEN, /* Open */ - SA_DSTATE_CLOSE /* Close/free */ -}; - -struct subagentx { - void (*sa_nofd)(struct subagentx *, void *, int); - void *sa_cookie; - int sa_fd; - enum subagentx_cstate sa_cstate; - enum subagentx_dstate sa_dstate; - struct agentx *sa_ax; - TAILQ_HEAD(, subagentx_session) sa_sessions; - TAILQ_HEAD(, subagentx_get) sa_getreqs; - RB_HEAD(sa_requests, subagentx_request) sa_requests; -}; - -struct subagentx_session { - struct subagentx *sas_sa; - uint32_t sas_id; - uint32_t sas_timeout; - struct agentx_oid sas_oid; - struct agentx_ostring sas_descr; - enum subagentx_cstate sas_cstate; - enum subagentx_dstate sas_dstate; - uint32_t sas_packetid; - TAILQ_HEAD(, subagentx_context) sas_contexts; - TAILQ_ENTRY(subagentx_session) sas_sa_sessions; -}; - -struct subagentx_context { - struct subagentx_session *sac_sas; - int sac_name_default; - struct agentx_ostring sac_name; - uint32_t sac_sysuptime; - struct timespec sac_sysuptimespec; - enum subagentx_cstate sac_cstate; - enum subagentx_dstate sac_dstate; - TAILQ_HEAD(, subagentx_agentcaps) sac_agentcaps; - TAILQ_HEAD(, subagentx_region) sac_regions; - RB_HEAD(sac_objects, subagentx_object) sac_objects; - TAILQ_ENTRY(subagentx_context) sac_sas_contexts; -}; - -struct subagentx_get { - struct subagentx_context *sag_sac; - int sag_fd; /* Only used for logging */ - uint32_t sag_sessionid; - uint32_t sag_transactionid; - uint32_t sag_packetid; - int sag_context_default; - struct agentx_ostring sag_context; - enum agentx_pdu_type sag_type; - uint16_t sag_nonrep; - uint16_t sag_maxrep; - size_t sag_nvarbind; - struct subagentx_varbind *sag_varbind; - TAILQ_ENTRY(subagentx_get) sag_sa_getreqs; -}; - -__dead void subagentx_log_sa_fatalx(struct subagentx *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sa_warn(struct subagentx *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sa_warnx(struct subagentx *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sa_info(struct subagentx *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sa_debug(struct subagentx *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -__dead void subagentx_log_sas_fatalx(struct subagentx_session *, const char *, - ...) __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sas_warnx(struct subagentx_session *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sas_warn(struct subagentx_session *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sas_info(struct subagentx_session *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -__dead void subagentx_log_sac_fatalx(struct subagentx_context *, const char *, - ...) __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sac_warnx(struct subagentx_context *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sac_warn(struct subagentx_context *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sac_info(struct subagentx_context *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sac_debug(struct subagentx_context *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -__dead void subagentx_log_sag_fatalx(struct subagentx_get *, const char *, - ...) __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sag_warnx(struct subagentx_get *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sag_warn(struct subagentx_get *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); -void subagentx_log_sag_debug(struct subagentx_get *, const char *, ...) - __attribute__((__format__ (printf, 2, 3))); diff --git a/usr.sbin/relayd/subagentx_log.c b/usr.sbin/relayd/subagentx_log.c deleted file mode 100644 index d9dcca8e856..00000000000 --- a/usr.sbin/relayd/subagentx_log.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (c) 2020 Martijn van Duren <martijn@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <errno.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "subagentx_internal.h" - -#define SUBAGENTX_CONTEXT_NAME(sac) (sac->sac_name_default ? "<default>" : \ - (char *)sac->sac_name.aos_string) -#define SUBAGENTX_GET_CTXNAME(sag) (sag->sag_context_default ? "<default>" : \ - (char *)sag->sag_context.aos_string) - -enum subagentx_log_type { - SUBAGENTX_LOG_TYPE_FATAL, - SUBAGENTX_LOG_TYPE_WARN, - SUBAGENTX_LOG_TYPE_INFO, - SUBAGENTX_LOG_TYPE_DEBUG -}; - -void (*subagentx_log_fatal)(const char *, ...) - __attribute__((__format__ (printf, 1, 2))) = NULL; -void (*subagentx_log_warn)(const char *, ...) - __attribute__((__format__ (printf, 1, 2))) = NULL; -void (*subagentx_log_info)(const char *, ...) - __attribute__((__format__ (printf, 1, 2))) = NULL; -void (*subagentx_log_debug)(const char *, ...) - __attribute__((__format__ (printf, 1, 2))) = NULL; - - -static void -subagentx_log_do(enum subagentx_log_type, const char *, va_list, int, - struct subagentx *, struct subagentx_session *, struct subagentx_context *, - struct subagentx_get *); - -void -subagentx_log_sa_fatalx(struct subagentx *sa, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_FATAL, fmt, ap, 0, sa, NULL, NULL, - NULL); - va_end(ap); - abort(); -} - -void -subagentx_log_sa_warn(struct subagentx *sa, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_WARN, fmt, ap, 1, sa, NULL, NULL, - NULL); - va_end(ap); -} - -void -subagentx_log_sa_warnx(struct subagentx *sa, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_WARN, fmt, ap, 0, sa, NULL, NULL, - NULL); - va_end(ap); -} - -void -subagentx_log_sa_info(struct subagentx *sa, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_INFO, fmt, ap, 0, sa, NULL, NULL, - NULL); - va_end(ap); -} - -void -subagentx_log_sa_debug(struct subagentx *sa, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_DEBUG, fmt, ap, 0, sa, NULL, NULL, - NULL); - va_end(ap); -} - -void -subagentx_log_sas_fatalx(struct subagentx_session *sas, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_FATAL, fmt, ap, 0, NULL, sas, NULL, - NULL); - va_end(ap); - abort(); -} - -void -subagentx_log_sas_warnx(struct subagentx_session *sas, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_WARN, fmt, ap, 0, NULL, sas, NULL, - NULL); - va_end(ap); -} - -void -subagentx_log_sas_warn(struct subagentx_session *sas, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_WARN, fmt, ap, 1, NULL, sas, NULL, - NULL); - va_end(ap); -} - -void -subagentx_log_sas_info(struct subagentx_session *sas, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_INFO, fmt, ap, 0, NULL, sas, NULL, - NULL); - va_end(ap); -} - -void -subagentx_log_sac_fatalx(struct subagentx_context *sac, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_FATAL, fmt, ap, 0, NULL, NULL, sac, - NULL); - va_end(ap); - abort(); -} - -void -subagentx_log_sac_warnx(struct subagentx_context *sac, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_WARN, fmt, ap, 0, NULL, NULL, sac, - NULL); - va_end(ap); -} - -void -subagentx_log_sac_warn(struct subagentx_context *sac, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_WARN, fmt, ap, 1, NULL, NULL, sac, - NULL); - va_end(ap); -} - -void -subagentx_log_sac_info(struct subagentx_context *sac, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_INFO, fmt, ap, 0, NULL, NULL, sac, - NULL); - va_end(ap); -} - -void -subagentx_log_sac_debug(struct subagentx_context *sac, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_DEBUG, fmt, ap, 0, NULL, NULL, sac, - NULL); - va_end(ap); -} - -void -subagentx_log_sag_fatalx(struct subagentx_get *sag, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_FATAL, fmt, ap, 0, NULL, NULL, NULL, - sag); - va_end(ap); - abort(); -} - -void -subagentx_log_sag_warnx(struct subagentx_get *sag, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_WARN, fmt, ap, 0, NULL, NULL, NULL, - sag); - va_end(ap); -} - -void -subagentx_log_sag_warn(struct subagentx_get *sag, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_WARN, fmt, ap, 1, NULL, NULL, NULL, - sag); - va_end(ap); -} - -void -subagentx_log_sag_debug(struct subagentx_get *sag, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - subagentx_log_do(SUBAGENTX_LOG_TYPE_DEBUG, fmt, ap, 0, NULL, NULL, NULL, - sag); - va_end(ap); -} - -static void -subagentx_log_do(enum subagentx_log_type type, const char *fmt, va_list ap, - int useerrno, struct subagentx *sa, struct subagentx_session *sas, - struct subagentx_context *sac, struct subagentx_get *sag) -{ - void (*subagentx_log)(const char *, ...); - char buf[1500]; - - if (type == SUBAGENTX_LOG_TYPE_FATAL) - subagentx_log = subagentx_log_fatal; - else if (type == SUBAGENTX_LOG_TYPE_WARN) - subagentx_log = subagentx_log_warn; - else if (type == SUBAGENTX_LOG_TYPE_INFO) - subagentx_log = subagentx_log_info; - else - subagentx_log = subagentx_log_debug; - if (subagentx_log == NULL) - return; - - vsnprintf(buf, sizeof(buf), fmt, ap); - - if (sag != NULL) { - if (useerrno) - subagentx_log("[fd:%d sess:%u ctx:%s trid:%u pid:%u]: " - "%s: %s", sag->sag_fd, sag->sag_sessionid, - SUBAGENTX_GET_CTXNAME(sag), sag->sag_transactionid, - sag->sag_packetid, buf, strerror(errno)); - else - subagentx_log("[fd:%d sess:%u ctx:%s trid:%u pid:%u]: " - "%s", sag->sag_fd, sag->sag_sessionid, - SUBAGENTX_GET_CTXNAME(sag), sag->sag_transactionid, - sag->sag_packetid, buf); - } else if (sac != NULL) { - sas = sac->sac_sas; - sa = sas->sas_sa; - if (useerrno) - subagentx_log("[fd:%d sess:%u ctx:%s]: %s: %s", - sa->sa_fd, sas->sas_id, SUBAGENTX_CONTEXT_NAME(sac), - buf, strerror(errno)); - else - subagentx_log("[fd:%d sess:%u ctx:%s]: %s", sa->sa_fd, - sas->sas_id, SUBAGENTX_CONTEXT_NAME(sac), buf); - } else if (sas != NULL) { - sa = sas->sas_sa; - if (useerrno) - subagentx_log("[fd:%d sess:%u]: %s: %s", sa->sa_fd, - sas->sas_id, buf, strerror(errno)); - else - subagentx_log("[fd:%d sess:%u]: %s", sa->sa_fd, - sas->sas_id, buf); - } else if (sa->sa_fd == -1) { - if (useerrno) - subagentx_log("%s: %s", buf, strerror(errno)); - else - subagentx_log("%s", buf); - } else { - if (useerrno) - subagentx_log("[fd:%d]: %s: %s", sa->sa_fd, buf, - strerror(errno)); - else - subagentx_log("[fd:%d]: %s", sa->sa_fd, buf); - } -} |