xref: /openbsd-src/usr.sbin/relayd/agentx_control.c (revision a1416996f1ed3f656c5fea8ff313e4eda9be6bbf)
1*a1416996Sclaudio /*	$OpenBSD: agentx_control.c,v 1.7 2024/01/17 10:01:24 claudio Exp $	*/
2c26b8e61Smartijn 
3c26b8e61Smartijn /*
4c26b8e61Smartijn  * Copyright (c) 2020 Martijn van Duren <martijn@openbsd.org>
5c26b8e61Smartijn  * Copyright (c) 2008 - 2014 Reyk Floeter <reyk@openbsd.org>
6c26b8e61Smartijn  *
7c26b8e61Smartijn  * Permission to use, copy, modify, and distribute this software for any
8c26b8e61Smartijn  * purpose with or without fee is hereby granted, provided that the above
9c26b8e61Smartijn  * copyright notice and this permission notice appear in all copies.
10c26b8e61Smartijn  *
11c26b8e61Smartijn  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12c26b8e61Smartijn  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13c26b8e61Smartijn  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14c26b8e61Smartijn  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15c26b8e61Smartijn  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16c26b8e61Smartijn  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17c26b8e61Smartijn  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18c26b8e61Smartijn  */
19c26b8e61Smartijn 
20c26b8e61Smartijn #include <sys/types.h>
21c26b8e61Smartijn #include <sys/socket.h>
22c26b8e61Smartijn #include <sys/queue.h>
23c26b8e61Smartijn #include <sys/time.h>
24c26b8e61Smartijn #include <sys/un.h>
25c26b8e61Smartijn 
26c26b8e61Smartijn #include <netinet/in.h>
27c26b8e61Smartijn 
281ae60b2aSmartijn #include <agentx.h>
29c26b8e61Smartijn #include <limits.h>
30c26b8e61Smartijn #include <stdio.h>
31c26b8e61Smartijn #include <stdlib.h>
32c26b8e61Smartijn #include <stdint.h>
33c26b8e61Smartijn #include <errno.h>
34c26b8e61Smartijn #include <string.h>
35c26b8e61Smartijn #include <syslog.h>
36c26b8e61Smartijn #include <unistd.h>
37c26b8e61Smartijn #include <event.h>
38c26b8e61Smartijn #include <imsg.h>
39c26b8e61Smartijn 
40c26b8e61Smartijn #include "relayd.h"
41c26b8e61Smartijn 
42c26b8e61Smartijn #define RELAYD_MIB	"1.3.6.1.4.1.30155.3"
43c26b8e61Smartijn #define SNMP_ELEMENT(x...)	do {				\
44c26b8e61Smartijn 	if (snmp_element(RELAYD_MIB x) == -1)			\
45c26b8e61Smartijn 		goto done;					\
46c26b8e61Smartijn } while (0)
47c26b8e61Smartijn 
48c26b8e61Smartijn /*
49c26b8e61Smartijn static struct snmp_oid	hosttrapoid = {
50c26b8e61Smartijn 	{ 1, 3, 6, 1, 4, 1, 30155, 3, 1, 0 },
51c26b8e61Smartijn 	10
52c26b8e61Smartijn };
53c26b8e61Smartijn */
54c26b8e61Smartijn 
551ae60b2aSmartijn #define RELAYDINFO		AGENTX_ENTERPRISES, 30155, 3, 2
56c26b8e61Smartijn #define RELAYDREDIRECTS		RELAYDINFO, 1
57c26b8e61Smartijn #define RELAYDREDIRECTENTRY	RELAYDREDIRECTS, 1
58c26b8e61Smartijn #define RELAYDREDIRECTINDEX	RELAYDREDIRECTENTRY, 1
59c26b8e61Smartijn #define RELAYDREDIRECTSTATUS	RELAYDREDIRECTENTRY, 2
60c26b8e61Smartijn #define RELAYDREDIRECTNAME	RELAYDREDIRECTENTRY, 3
61c26b8e61Smartijn #define RELAYDREDIRECTCNT	RELAYDREDIRECTENTRY, 4
62c26b8e61Smartijn #define RELAYDREDIRECTAVG	RELAYDREDIRECTENTRY, 5
63c26b8e61Smartijn #define RELAYDREDIRECTLAST	RELAYDREDIRECTENTRY, 6
64c26b8e61Smartijn #define RELAYDREDIRECTAVGHOUR	RELAYDREDIRECTENTRY, 7
65c26b8e61Smartijn #define RELAYDREDIRECTLASTHOUR	RELAYDREDIRECTENTRY, 8
66c26b8e61Smartijn #define RELAYDREDIRECTAVGDAY	RELAYDREDIRECTENTRY, 9
67c26b8e61Smartijn #define RELAYDREDIRECTLASTDAY	RELAYDREDIRECTENTRY, 10
68c26b8e61Smartijn #define RELAYDRELAYS		RELAYDINFO, 2
69c26b8e61Smartijn #define RELAYDRELAYENTRY	RELAYDRELAYS, 1
70c26b8e61Smartijn #define RELAYDRELAYINDEX	RELAYDRELAYENTRY, 1
71c26b8e61Smartijn #define RELAYDRELAYSTATUS	RELAYDRELAYENTRY, 2
72c26b8e61Smartijn #define RELAYDRELAYNAME		RELAYDRELAYENTRY, 3
73c26b8e61Smartijn #define RELAYDRELAYCNT		RELAYDRELAYENTRY, 4
74c26b8e61Smartijn #define RELAYDRELAYAVG		RELAYDRELAYENTRY, 5
75c26b8e61Smartijn #define RELAYDRELAYLAST		RELAYDRELAYENTRY, 6
76c26b8e61Smartijn #define RELAYDRELAYAVGHOUR	RELAYDRELAYENTRY, 7
77c26b8e61Smartijn #define RELAYDRELAYLASTHOUR	RELAYDRELAYENTRY, 8
78c26b8e61Smartijn #define RELAYDRELAYAVGDAY	RELAYDRELAYENTRY, 9
79c26b8e61Smartijn #define RELAYDRELAYLASTDAY	RELAYDRELAYENTRY, 10
80c26b8e61Smartijn #define RELAYDROUTERS		RELAYDINFO, 3
81c26b8e61Smartijn #define RELAYDROUTERENTRY	RELAYDROUTERS, 1
82c26b8e61Smartijn #define RELAYDROUTERINDEX	RELAYDROUTERENTRY, 1
83c26b8e61Smartijn #define RELAYDROUTERTABLEINDEX	RELAYDROUTERENTRY, 2
84c26b8e61Smartijn #define RELAYDROUTERSTATUS	RELAYDROUTERENTRY, 3
85c26b8e61Smartijn #define RELAYDROUTERNAME	RELAYDROUTERENTRY, 4
86c26b8e61Smartijn #define RELAYDROUTERLABEL	RELAYDROUTERENTRY, 5
87c26b8e61Smartijn #define RELAYDROUTERRTABLE	RELAYDROUTERENTRY, 6
88c26b8e61Smartijn #define RELAYDNETROUTES		RELAYDINFO, 4
89c26b8e61Smartijn #define RELAYDNETROUTEENTRY	RELAYDNETROUTES, 1
90c26b8e61Smartijn #define RELAYDNETROUTEINDEX	RELAYDNETROUTEENTRY, 1
91c26b8e61Smartijn #define RELAYDNETROUTEADDR	RELAYDNETROUTEENTRY, 2
92c26b8e61Smartijn #define RELAYDNETROUTEADDRTYPE	RELAYDNETROUTEENTRY, 3
93c26b8e61Smartijn #define RELAYDNETROUTEPREFIXLEN	RELAYDNETROUTEENTRY, 4
94c26b8e61Smartijn #define RELAYDNETROUTEROUTERINDEX RELAYDNETROUTEENTRY, 5
95c26b8e61Smartijn #define RELAYDHOSTS		RELAYDINFO, 5
96c26b8e61Smartijn #define RELAYDHOSTENTRY		RELAYDHOSTS, 1
97c26b8e61Smartijn #define RELAYDHOSTINDEX		RELAYDHOSTENTRY, 1
98c26b8e61Smartijn #define RELAYDHOSTPARENTINDEX	RELAYDHOSTENTRY, 2
99c26b8e61Smartijn #define RELAYDHOSTTABLEINDEX	RELAYDHOSTENTRY, 3
100c26b8e61Smartijn #define RELAYDHOSTNAME		RELAYDHOSTENTRY, 4
101c26b8e61Smartijn #define RELAYDHOSTADDRESS	RELAYDHOSTENTRY, 5
102c26b8e61Smartijn #define RELAYDHOSTADDRESSTYPE	RELAYDHOSTENTRY, 6
103c26b8e61Smartijn #define RELAYDHOSTSTATUS	RELAYDHOSTENTRY, 7
104c26b8e61Smartijn #define RELAYDHOSTCHECKCNT	RELAYDHOSTENTRY, 8
105c26b8e61Smartijn #define RELAYDHOSTUPCNT		RELAYDHOSTENTRY, 9
106c26b8e61Smartijn #define RELAYDHOSTERRNO		RELAYDHOSTENTRY, 10
107c26b8e61Smartijn #define RELAYDSESSIONS		RELAYDINFO, 6
108c26b8e61Smartijn #define RELAYDSESSIONENTRY	RELAYDSESSIONS, 1
109c26b8e61Smartijn #define RELAYDSESSIONINDEX	RELAYDSESSIONENTRY, 1
110c26b8e61Smartijn #define RELAYDSESSIONRELAYINDEX	RELAYDSESSIONENTRY, 2
111c26b8e61Smartijn #define RELAYDSESSIONINADDR	RELAYDSESSIONENTRY, 3
112c26b8e61Smartijn #define RELAYDSESSIONINADDRTYPE	RELAYDSESSIONENTRY, 4
113c26b8e61Smartijn #define RELAYDSESSIONOUTADDR	RELAYDSESSIONENTRY, 5
114c26b8e61Smartijn #define RELAYDSESSIONOUTADDRTYPE RELAYDSESSIONENTRY, 6
115c26b8e61Smartijn #define RELAYDSESSIONPORTIN	RELAYDSESSIONENTRY, 7
116c26b8e61Smartijn #define RELAYDSESSIONPORTOUT	RELAYDSESSIONENTRY, 8
117c26b8e61Smartijn #define RELAYDSESSIONAGE	RELAYDSESSIONENTRY, 9
118c26b8e61Smartijn #define RELAYDSESSIONIDLE	RELAYDSESSIONENTRY, 10
119c26b8e61Smartijn #define RELAYDSESSIONSTATUS	RELAYDSESSIONENTRY, 11
120c26b8e61Smartijn #define RELAYDSESSIONPID	RELAYDSESSIONENTRY, 12
121c26b8e61Smartijn #define RELAYDTABLES		RELAYDINFO, 7
122c26b8e61Smartijn #define RELAYDTABLEENTRY	RELAYDTABLES, 1
123c26b8e61Smartijn #define RELAYDTABLEINDEX	RELAYDTABLEENTRY, 1
124c26b8e61Smartijn #define RELAYDTABLENAME		RELAYDTABLEENTRY, 2
125c26b8e61Smartijn #define RELAYDTABLESTATUS	RELAYDTABLEENTRY, 3
126c26b8e61Smartijn 
127d6e4d72bSmartijn void agentx_nofd(struct agentx *, void *, int);
128c26b8e61Smartijn 
129c26b8e61Smartijn struct relayd *env;
130c26b8e61Smartijn 
1311ae60b2aSmartijn struct agentx *sa = NULL;
1321ae60b2aSmartijn struct agentx_index *relaydRedirectIdx, *relaydRelayIdx;
1331ae60b2aSmartijn struct agentx_index *relaydRouterIdx, *relaydNetRouteIdx;
1341ae60b2aSmartijn struct agentx_index *relaydHostIdx, *relaydSessionRelayIdx;
1351ae60b2aSmartijn struct agentx_index *relaydSessionIdx, *relaydTableIdx;
136c26b8e61Smartijn 
1371ae60b2aSmartijn struct agentx_object *relaydRedirectIndex, *relaydRedirectStatus;
1381ae60b2aSmartijn struct agentx_object *relaydRedirectName, *relaydRedirectCnt;
1391ae60b2aSmartijn struct agentx_object *relaydRedirectAvg, *relaydRedirectLast;
1401ae60b2aSmartijn struct agentx_object *relaydRedirectAvgHour, *relaydRedirectLastHour;
1411ae60b2aSmartijn struct agentx_object *relaydRedirectAvgDay, *relaydRedirectLastDay;
142c26b8e61Smartijn 
1431ae60b2aSmartijn struct agentx_object *relaydRelayIndex, *relaydRelayStatus;
1441ae60b2aSmartijn struct agentx_object *relaydRelayName, *relaydRelayCnt;
1451ae60b2aSmartijn struct agentx_object *relaydRelayAvg, *relaydRelayLast;
1461ae60b2aSmartijn struct agentx_object *relaydRelayAvgHour, *relaydRelayLastHour;
1471ae60b2aSmartijn struct agentx_object *relaydRelayAvgDay, *relaydRelayLastDay;
148c26b8e61Smartijn 
1491ae60b2aSmartijn struct agentx_object *relaydRouterIndex, *relaydRouterTableIndex;
1501ae60b2aSmartijn struct agentx_object *relaydRouterStatus, *relaydRouterName;
1511ae60b2aSmartijn struct agentx_object *relaydRouterLabel, *relaydRouterRtable;
152c26b8e61Smartijn 
1531ae60b2aSmartijn struct agentx_object *relaydNetRouteIndex, *relaydNetRouteAddr;
1541ae60b2aSmartijn struct agentx_object *relaydNetRouteAddrType, *relaydNetRoutePrefixLen;
1551ae60b2aSmartijn struct agentx_object *relaydNetRouteRouterIndex;
156c26b8e61Smartijn 
1571ae60b2aSmartijn struct agentx_object *relaydHostIndex, *relaydHostParentIndex;
1581ae60b2aSmartijn struct agentx_object *relaydHostTableIndex, *relaydHostName;
1591ae60b2aSmartijn struct agentx_object *relaydHostAddress, *relaydHostAddressType;
1601ae60b2aSmartijn struct agentx_object *relaydHostStatus, *relaydHostCheckCnt;
1611ae60b2aSmartijn struct agentx_object *relaydHostUpCnt, *relaydHostErrno;
162c26b8e61Smartijn 
1631ae60b2aSmartijn struct agentx_object *relaydSessionIndex, *relaydSessionRelayIndex;
1641ae60b2aSmartijn struct agentx_object *relaydSessionInAddr, *relaydSessionInAddrType;
1651ae60b2aSmartijn struct agentx_object *relaydSessionOutAddr, *relaydSessionOutAddrType;
1661ae60b2aSmartijn struct agentx_object *relaydSessionPortIn, *relaydSessionPortOut;
1671ae60b2aSmartijn struct agentx_object *relaydSessionAge, *relaydSessionIdle;
1681ae60b2aSmartijn struct agentx_object *relaydSessionStatus, *relaydSessionPid;
169c26b8e61Smartijn 
1701ae60b2aSmartijn struct agentx_object *relaydTableIndex, *relaydTableName, *relaydTableStatus;
171c26b8e61Smartijn 
172c26b8e61Smartijn void	*sstodata(struct sockaddr_storage *);
173c26b8e61Smartijn size_t	 sstolen(struct sockaddr_storage *);
174c26b8e61Smartijn 
1751ae60b2aSmartijn struct rdr *agentxctl_rdr_byidx(uint32_t, enum agentx_request_type);
1761ae60b2aSmartijn void agentxctl_redirect(struct agentx_varbind *);
1771ae60b2aSmartijn struct relay *agentxctl_relay_byidx(uint32_t, enum agentx_request_type);
1781ae60b2aSmartijn void agentxctl_relay(struct agentx_varbind *);
1791ae60b2aSmartijn struct router *agentxctl_router_byidx(uint32_t, enum agentx_request_type);
1801ae60b2aSmartijn void agentxctl_router(struct agentx_varbind *);
1811ae60b2aSmartijn struct netroute *agentxctl_netroute_byidx(uint32_t, enum agentx_request_type);
1821ae60b2aSmartijn void agentxctl_netroute(struct agentx_varbind *);
1831ae60b2aSmartijn struct host *agentxctl_host_byidx(uint32_t, enum agentx_request_type);
1841ae60b2aSmartijn void agentxctl_host(struct agentx_varbind *);
1851ae60b2aSmartijn struct rsession *agentxctl_session_byidx(uint32_t, uint32_t,
1861ae60b2aSmartijn     enum agentx_request_type);
1871ae60b2aSmartijn void agentxctl_session(struct agentx_varbind *);
1881ae60b2aSmartijn struct table *agentxctl_table_byidx(uint32_t, enum agentx_request_type);
1891ae60b2aSmartijn void agentxctl_table(struct agentx_varbind *);
190c26b8e61Smartijn 
191c26b8e61Smartijn void	 agentx_sock(int, short, void *);
192c26b8e61Smartijn #if 0
193c26b8e61Smartijn int	 snmp_element(const char *, enum snmp_type, void *, int64_t,
194c26b8e61Smartijn 	    struct agentx_pdu *);
195c26b8e61Smartijn int	 snmp_string2oid(const char *, struct snmp_oid *);
196c26b8e61Smartijn #endif
197c26b8e61Smartijn 
198c26b8e61Smartijn void
agentx_init(struct relayd * nenv)199c26b8e61Smartijn agentx_init(struct relayd *nenv)
200c26b8e61Smartijn {
2011ae60b2aSmartijn 	struct agentx_session *sas;
2021ae60b2aSmartijn 	struct agentx_context *sac;
2031ae60b2aSmartijn 	struct agentx_region *sar;
2041ae60b2aSmartijn 	struct agentx_index *session_idxs[2];
205d6e4d72bSmartijn 	static int freed;
206c26b8e61Smartijn 
2071ae60b2aSmartijn 	agentx_log_fatal = fatalx;
2081ae60b2aSmartijn 	agentx_log_warn = log_warnx;
2091ae60b2aSmartijn 	agentx_log_info = log_info;
2101ae60b2aSmartijn 	agentx_log_debug = log_debug;
211c26b8e61Smartijn 
212c26b8e61Smartijn 	env = nenv;
213c26b8e61Smartijn 
214c26b8e61Smartijn 	if ((env->sc_conf.flags & F_AGENTX) == 0) {
215d6e4d72bSmartijn 		if (sa != NULL && !freed) {
2161ae60b2aSmartijn 			agentx_free(sa);
217d6e4d72bSmartijn 			freed = 1;
218d6e4d72bSmartijn 		}
219c26b8e61Smartijn 		return;
220c26b8e61Smartijn 	}
221c26b8e61Smartijn 	if (sa != NULL)
222c26b8e61Smartijn 		return;
223c26b8e61Smartijn 
224d6e4d72bSmartijn 	freed = 0;
225d6e4d72bSmartijn 	if ((sa = agentx(agentx_nofd, NULL)) == NULL)
226c26b8e61Smartijn 		fatal("%s: agentx alloc", __func__);
2271ae60b2aSmartijn 	if ((sas = agentx_session(sa, NULL, 0, "relayd", 0)) == NULL)
228c26b8e61Smartijn 		fatal("%s: agentx session alloc", __func__);
2291ae60b2aSmartijn 	if ((sac = agentx_context(sas,
230c26b8e61Smartijn 		env->sc_conf.agentx_context[0] == '\0' ? NULL :
231c26b8e61Smartijn 		env->sc_conf.agentx_context)) == NULL)
232c26b8e61Smartijn 		fatal("%s: agentx context alloc", __func__);
2331ae60b2aSmartijn 	sar = agentx_region(sac, AGENTX_OID(RELAYDINFO), 0);
234c26b8e61Smartijn 	if (sar == NULL)
235c26b8e61Smartijn 		fatal("%s: agentx region alloc", __func__);
2361ae60b2aSmartijn 	if ((relaydRedirectIdx = agentx_index_integer_dynamic(sar,
2371ae60b2aSmartijn 	    AGENTX_OID(RELAYDREDIRECTINDEX))) == NULL ||
2381ae60b2aSmartijn 	    (relaydRelayIdx = agentx_index_integer_dynamic(sar,
2391ae60b2aSmartijn 	    AGENTX_OID(RELAYDRELAYINDEX))) == NULL ||
2401ae60b2aSmartijn 	    (relaydRouterIdx = agentx_index_integer_dynamic(sar,
2411ae60b2aSmartijn 	    AGENTX_OID(RELAYDROUTERINDEX))) == NULL ||
2421ae60b2aSmartijn 	    (relaydNetRouteIdx = agentx_index_integer_dynamic(sar,
2431ae60b2aSmartijn 	    AGENTX_OID(RELAYDNETROUTEINDEX))) == NULL ||
2441ae60b2aSmartijn 	    (relaydHostIdx = agentx_index_integer_dynamic(sar,
2451ae60b2aSmartijn 	    AGENTX_OID(RELAYDHOSTINDEX))) == NULL ||
2461ae60b2aSmartijn 	    (relaydSessionIdx = agentx_index_integer_dynamic(sar,
2471ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONINDEX))) == NULL ||
2481ae60b2aSmartijn 	    (relaydSessionRelayIdx = agentx_index_integer_dynamic(sar,
2491ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONRELAYINDEX))) == NULL ||
2501ae60b2aSmartijn 	    (relaydTableIdx = agentx_index_integer_dynamic(sar,
2511ae60b2aSmartijn 	    AGENTX_OID(RELAYDTABLEINDEX))) == NULL)
252c26b8e61Smartijn 		fatal("%s: agentx index alloc", __func__);
253c26b8e61Smartijn 	session_idxs[0] = relaydSessionRelayIdx;
254c26b8e61Smartijn 	session_idxs[1] = relaydSessionIdx;
2551ae60b2aSmartijn 	if ((relaydRedirectIndex = agentx_object(sar,
2561ae60b2aSmartijn 	    AGENTX_OID(RELAYDREDIRECTINDEX), &relaydRedirectIdx, 1, 0,
2571ae60b2aSmartijn 	    agentxctl_redirect)) == NULL ||
2581ae60b2aSmartijn 	    (relaydRedirectStatus = agentx_object(sar,
2591ae60b2aSmartijn 	    AGENTX_OID(RELAYDREDIRECTSTATUS), &relaydRedirectIdx, 1, 0,
2601ae60b2aSmartijn 	    agentxctl_redirect)) == NULL ||
2611ae60b2aSmartijn 	    (relaydRedirectName = agentx_object(sar,
2621ae60b2aSmartijn 	    AGENTX_OID(RELAYDREDIRECTNAME), &relaydRedirectIdx, 1, 0,
2631ae60b2aSmartijn 	    agentxctl_redirect)) == NULL ||
2641ae60b2aSmartijn 	    (relaydRedirectCnt = agentx_object(sar,
2651ae60b2aSmartijn 	    AGENTX_OID(RELAYDREDIRECTCNT), &relaydRedirectIdx, 1, 0,
2661ae60b2aSmartijn 	    agentxctl_redirect)) == NULL ||
2671ae60b2aSmartijn 	    (relaydRedirectAvg = agentx_object(sar,
2681ae60b2aSmartijn 	    AGENTX_OID(RELAYDREDIRECTAVG), &relaydRedirectIdx, 1, 0,
2691ae60b2aSmartijn 	    agentxctl_redirect)) == NULL ||
2701ae60b2aSmartijn 	    (relaydRedirectLast = agentx_object(sar,
2711ae60b2aSmartijn 	    AGENTX_OID(RELAYDREDIRECTLAST), &relaydRedirectIdx, 1, 0,
2721ae60b2aSmartijn 	    agentxctl_redirect)) == NULL ||
2731ae60b2aSmartijn 	    (relaydRedirectAvgHour = agentx_object(sar,
2741ae60b2aSmartijn 	    AGENTX_OID(RELAYDREDIRECTAVGHOUR), &relaydRedirectIdx, 1, 0,
2751ae60b2aSmartijn 	    agentxctl_redirect)) == NULL ||
2761ae60b2aSmartijn 	    (relaydRedirectLastHour = agentx_object(sar,
2771ae60b2aSmartijn 	    AGENTX_OID(RELAYDREDIRECTLASTHOUR), &relaydRedirectIdx, 1, 0,
2781ae60b2aSmartijn 	    agentxctl_redirect)) == NULL ||
2791ae60b2aSmartijn 	    (relaydRedirectAvgDay = agentx_object(sar,
2801ae60b2aSmartijn 	    AGENTX_OID(RELAYDREDIRECTAVGDAY), &relaydRedirectIdx, 1, 0,
2811ae60b2aSmartijn 	    agentxctl_redirect)) == NULL ||
2821ae60b2aSmartijn 	    (relaydRedirectLastDay = agentx_object(sar,
2831ae60b2aSmartijn 	    AGENTX_OID(RELAYDREDIRECTLASTDAY), &relaydRedirectIdx, 1, 0,
2841ae60b2aSmartijn 	    agentxctl_redirect)) == NULL ||
2851ae60b2aSmartijn 	    (relaydRelayIndex = agentx_object(sar,
2861ae60b2aSmartijn 	    AGENTX_OID(RELAYDRELAYINDEX), &relaydRelayIdx, 1, 0,
2871ae60b2aSmartijn 	    agentxctl_relay)) == NULL ||
2881ae60b2aSmartijn 	    (relaydRelayStatus = agentx_object(sar,
2891ae60b2aSmartijn 	    AGENTX_OID(RELAYDRELAYSTATUS), &relaydRelayIdx, 1, 0,
2901ae60b2aSmartijn 	    agentxctl_relay)) == NULL ||
2911ae60b2aSmartijn 	    (relaydRelayName = agentx_object(sar,
2921ae60b2aSmartijn 	    AGENTX_OID(RELAYDRELAYNAME), &relaydRelayIdx, 1, 0,
2931ae60b2aSmartijn 	    agentxctl_relay)) == NULL ||
2941ae60b2aSmartijn 	    (relaydRelayCnt = agentx_object(sar,
2951ae60b2aSmartijn 	    AGENTX_OID(RELAYDRELAYCNT), &relaydRelayIdx, 1, 0,
2961ae60b2aSmartijn 	    agentxctl_relay)) == NULL ||
2971ae60b2aSmartijn 	    (relaydRelayAvg = agentx_object(sar,
2981ae60b2aSmartijn 	    AGENTX_OID(RELAYDRELAYAVG), &relaydRelayIdx, 1, 0,
2991ae60b2aSmartijn 	    agentxctl_relay)) == NULL ||
3001ae60b2aSmartijn 	    (relaydRelayLast = agentx_object(sar,
3011ae60b2aSmartijn 	    AGENTX_OID(RELAYDRELAYLAST), &relaydRelayIdx, 1, 0,
3021ae60b2aSmartijn 	    agentxctl_relay)) == NULL ||
3031ae60b2aSmartijn 	    (relaydRelayAvgHour = agentx_object(sar,
3041ae60b2aSmartijn 	    AGENTX_OID(RELAYDRELAYAVGHOUR), &relaydRelayIdx, 1, 0,
3051ae60b2aSmartijn 	    agentxctl_relay)) == NULL ||
3061ae60b2aSmartijn 	    (relaydRelayLastHour = agentx_object(sar,
3071ae60b2aSmartijn 	    AGENTX_OID(RELAYDRELAYLASTHOUR), &relaydRelayIdx, 1, 0,
3081ae60b2aSmartijn 	    agentxctl_relay)) == NULL ||
3091ae60b2aSmartijn 	    (relaydRelayAvgDay = agentx_object(sar,
3101ae60b2aSmartijn 	    AGENTX_OID(RELAYDRELAYAVGDAY), &relaydRelayIdx, 1, 0,
3111ae60b2aSmartijn 	    agentxctl_relay)) == NULL ||
3121ae60b2aSmartijn 	    (relaydRelayLastDay = agentx_object(sar,
3131ae60b2aSmartijn 	    AGENTX_OID(RELAYDRELAYLASTDAY), &relaydRelayIdx, 1, 0,
3141ae60b2aSmartijn 	    agentxctl_relay)) == NULL ||
3151ae60b2aSmartijn 	    (relaydRouterIndex = agentx_object(sar,
3161ae60b2aSmartijn 	    AGENTX_OID(RELAYDROUTERINDEX), &relaydRouterIdx, 1, 0,
3171ae60b2aSmartijn 	    agentxctl_router)) == NULL ||
3181ae60b2aSmartijn 	    (relaydRouterTableIndex = agentx_object(sar,
3191ae60b2aSmartijn 	    AGENTX_OID(RELAYDROUTERTABLEINDEX), &relaydRouterIdx, 1, 0,
3201ae60b2aSmartijn 	    agentxctl_router)) == NULL ||
3211ae60b2aSmartijn 	    (relaydRouterStatus = agentx_object(sar,
3221ae60b2aSmartijn 	    AGENTX_OID(RELAYDROUTERSTATUS), &relaydRouterIdx, 1, 0,
3231ae60b2aSmartijn 	    agentxctl_router)) == NULL ||
3241ae60b2aSmartijn 	    (relaydRouterName = agentx_object(sar,
3251ae60b2aSmartijn 	    AGENTX_OID(RELAYDROUTERNAME), &relaydRouterIdx, 1, 0,
3261ae60b2aSmartijn 	    agentxctl_router)) == NULL ||
3271ae60b2aSmartijn 	    (relaydRouterLabel = agentx_object(sar,
3281ae60b2aSmartijn 	    AGENTX_OID(RELAYDROUTERLABEL), &relaydRouterIdx, 1, 0,
3291ae60b2aSmartijn 	    agentxctl_router)) == NULL ||
3301ae60b2aSmartijn 	    (relaydRouterRtable = agentx_object(sar,
3311ae60b2aSmartijn 	    AGENTX_OID(RELAYDROUTERRTABLE), &relaydRouterIdx, 1, 0,
3321ae60b2aSmartijn 	    agentxctl_router)) == NULL ||
3331ae60b2aSmartijn 	    (relaydNetRouteIndex = agentx_object(sar,
3341ae60b2aSmartijn 	    AGENTX_OID(RELAYDNETROUTEINDEX), &relaydNetRouteIdx, 1, 0,
3351ae60b2aSmartijn 	    agentxctl_netroute)) == NULL ||
3361ae60b2aSmartijn 	    (relaydNetRouteAddr = agentx_object(sar,
3371ae60b2aSmartijn 	    AGENTX_OID(RELAYDNETROUTEADDR), &relaydNetRouteIdx, 1, 0,
3381ae60b2aSmartijn 	    agentxctl_netroute)) == NULL ||
3391ae60b2aSmartijn 	    (relaydNetRouteAddrType = agentx_object(sar,
3401ae60b2aSmartijn 	    AGENTX_OID(RELAYDNETROUTEADDRTYPE), &relaydNetRouteIdx, 1, 0,
3411ae60b2aSmartijn 	    agentxctl_netroute)) == NULL ||
3421ae60b2aSmartijn 	    (relaydNetRoutePrefixLen = agentx_object(sar,
3431ae60b2aSmartijn 	    AGENTX_OID(RELAYDNETROUTEPREFIXLEN), &relaydNetRouteIdx, 1, 0,
3441ae60b2aSmartijn 	    agentxctl_netroute)) == NULL ||
3451ae60b2aSmartijn 	    (relaydNetRouteRouterIndex = agentx_object(sar,
3461ae60b2aSmartijn 	    AGENTX_OID(RELAYDNETROUTEROUTERINDEX), &relaydNetRouteIdx, 1, 0,
3471ae60b2aSmartijn 	    agentxctl_netroute)) == NULL ||
3481ae60b2aSmartijn 	    (relaydHostIndex = agentx_object(sar,
3491ae60b2aSmartijn 	    AGENTX_OID(RELAYDHOSTINDEX), &relaydHostIdx, 1, 0,
3501ae60b2aSmartijn 	    agentxctl_host)) == NULL ||
3511ae60b2aSmartijn 	    (relaydHostParentIndex = agentx_object(sar,
3521ae60b2aSmartijn 	    AGENTX_OID(RELAYDHOSTPARENTINDEX), &relaydHostIdx, 1, 0,
3531ae60b2aSmartijn 	    agentxctl_host)) == NULL ||
3541ae60b2aSmartijn 	    (relaydHostTableIndex = agentx_object(sar,
3551ae60b2aSmartijn 	    AGENTX_OID(RELAYDHOSTTABLEINDEX), &relaydHostIdx, 1, 0,
3561ae60b2aSmartijn 	    agentxctl_host)) == NULL ||
3571ae60b2aSmartijn 	    (relaydHostName = agentx_object(sar,
3581ae60b2aSmartijn 	    AGENTX_OID(RELAYDHOSTNAME), &relaydHostIdx, 1, 0,
3591ae60b2aSmartijn 	    agentxctl_host)) == NULL ||
3601ae60b2aSmartijn 	    (relaydHostAddress = agentx_object(sar,
3611ae60b2aSmartijn 	    AGENTX_OID(RELAYDHOSTADDRESS), &relaydHostIdx, 1, 0,
3621ae60b2aSmartijn 	    agentxctl_host)) == NULL ||
3631ae60b2aSmartijn 	    (relaydHostAddressType = agentx_object(sar,
3641ae60b2aSmartijn 	    AGENTX_OID(RELAYDHOSTADDRESSTYPE), &relaydHostIdx, 1, 0,
3651ae60b2aSmartijn 	    agentxctl_host)) == NULL ||
3661ae60b2aSmartijn 	    (relaydHostStatus = agentx_object(sar,
3671ae60b2aSmartijn 	    AGENTX_OID(RELAYDHOSTSTATUS), &relaydHostIdx, 1, 0,
3681ae60b2aSmartijn 	    agentxctl_host)) == NULL ||
3691ae60b2aSmartijn 	    (relaydHostCheckCnt = agentx_object(sar,
3701ae60b2aSmartijn 	    AGENTX_OID(RELAYDHOSTCHECKCNT), &relaydHostIdx, 1, 0,
3711ae60b2aSmartijn 	    agentxctl_host)) == NULL ||
3721ae60b2aSmartijn 	    (relaydHostUpCnt = agentx_object(sar,
3731ae60b2aSmartijn 	    AGENTX_OID(RELAYDHOSTUPCNT), &relaydHostIdx, 1, 0,
3741ae60b2aSmartijn 	    agentxctl_host)) == NULL ||
3751ae60b2aSmartijn 	    (relaydHostErrno = agentx_object(sar,
3761ae60b2aSmartijn 	    AGENTX_OID(RELAYDHOSTERRNO), &relaydHostIdx, 1, 0,
3771ae60b2aSmartijn 	    agentxctl_host)) == NULL ||
3781ae60b2aSmartijn 	    (relaydSessionIndex = agentx_object(sar,
3791ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONINDEX), session_idxs, 2, 0,
3801ae60b2aSmartijn 	    agentxctl_session)) == NULL ||
3811ae60b2aSmartijn 	    (relaydSessionRelayIndex = agentx_object(sar,
3821ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONRELAYINDEX), session_idxs, 2, 0,
3831ae60b2aSmartijn 	    agentxctl_session)) == NULL ||
3841ae60b2aSmartijn 	    (relaydSessionInAddr = agentx_object(sar,
3851ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONINADDR), session_idxs, 2, 0,
3861ae60b2aSmartijn 	    agentxctl_session)) == NULL ||
3871ae60b2aSmartijn 	    (relaydSessionInAddrType = agentx_object(sar,
3881ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONINADDRTYPE), session_idxs, 2, 0,
3891ae60b2aSmartijn 	    agentxctl_session)) == NULL ||
3901ae60b2aSmartijn 	    (relaydSessionOutAddr = agentx_object(sar,
3911ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONOUTADDR), session_idxs, 2, 0,
3921ae60b2aSmartijn 	    agentxctl_session)) == NULL ||
3931ae60b2aSmartijn 	    (relaydSessionOutAddrType = agentx_object(sar,
3941ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONOUTADDRTYPE), session_idxs, 2, 0,
3951ae60b2aSmartijn 	    agentxctl_session)) == NULL ||
3961ae60b2aSmartijn 	    (relaydSessionPortIn = agentx_object(sar,
3971ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONPORTIN), session_idxs, 2, 0,
3981ae60b2aSmartijn 	    agentxctl_session)) == NULL ||
3991ae60b2aSmartijn 	    (relaydSessionPortOut = agentx_object(sar,
4001ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONPORTOUT), session_idxs, 2, 0,
4011ae60b2aSmartijn 	    agentxctl_session)) == NULL ||
4021ae60b2aSmartijn 	    (relaydSessionAge = agentx_object(sar,
4031ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONAGE), session_idxs, 2, 0,
4041ae60b2aSmartijn 	    agentxctl_session)) == NULL ||
4051ae60b2aSmartijn 	    (relaydSessionIdle = agentx_object(sar,
4061ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONIDLE), session_idxs, 2, 0,
4071ae60b2aSmartijn 	    agentxctl_session)) == NULL ||
4081ae60b2aSmartijn 	    (relaydSessionStatus = agentx_object(sar,
4091ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONSTATUS), session_idxs, 2, 0,
4101ae60b2aSmartijn 	    agentxctl_session)) == NULL ||
4111ae60b2aSmartijn 	    (relaydSessionPid = agentx_object(sar,
4121ae60b2aSmartijn 	    AGENTX_OID(RELAYDSESSIONPID), session_idxs, 2, 0,
4131ae60b2aSmartijn 	    agentxctl_session)) == NULL ||
4141ae60b2aSmartijn 	    (relaydTableIndex = agentx_object(sar,
4151ae60b2aSmartijn 	    AGENTX_OID(RELAYDTABLEINDEX), &relaydTableIdx, 1, 0,
4161ae60b2aSmartijn 	    agentxctl_table)) == NULL ||
4171ae60b2aSmartijn 	    (relaydTableName = agentx_object(sar,
4181ae60b2aSmartijn 	    AGENTX_OID(RELAYDTABLENAME), &relaydTableIdx, 1, 0,
4191ae60b2aSmartijn 	    agentxctl_table)) == NULL ||
4201ae60b2aSmartijn 	    (relaydTableStatus = agentx_object(sar,
4211ae60b2aSmartijn 	    AGENTX_OID(RELAYDTABLESTATUS), &relaydTableIdx, 1, 0,
4221ae60b2aSmartijn 	    agentxctl_table)) == NULL)
423c26b8e61Smartijn 		fatal("%s: agentx object alloc", __func__);
424c26b8e61Smartijn }
425c26b8e61Smartijn 
426c26b8e61Smartijn void
agentx_nofd(struct agentx * usa,void * cookie,int close)427d6e4d72bSmartijn agentx_nofd(struct agentx *usa, void *cookie, int close)
428c26b8e61Smartijn {
429d6e4d72bSmartijn 	if (!close)
430c26b8e61Smartijn 		proc_compose(env->sc_ps, PROC_PARENT, IMSG_AGENTXSOCK, NULL, 0);
431d6e4d72bSmartijn 	else {
432d6e4d72bSmartijn 		sa = NULL;
433d6e4d72bSmartijn 		agentx_init(env);
434d6e4d72bSmartijn 		event_del(&(env->sc_agentxev));
435d6e4d72bSmartijn 	}
436c26b8e61Smartijn }
437c26b8e61Smartijn 
438c26b8e61Smartijn void
agentx_setsock(struct relayd * lenv,enum privsep_procid id)439c26b8e61Smartijn agentx_setsock(struct relayd *lenv, enum privsep_procid id)
440c26b8e61Smartijn {
441c26b8e61Smartijn 	struct sockaddr_un	 sun;
442c26b8e61Smartijn 	int			 s = -1;
443c26b8e61Smartijn 
444c26b8e61Smartijn 	if ((s = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1)
445c26b8e61Smartijn 		goto done;
446c26b8e61Smartijn 
447c26b8e61Smartijn 	bzero(&sun, sizeof(sun));
448c26b8e61Smartijn 	sun.sun_family = AF_UNIX;
449c26b8e61Smartijn 	if (strlcpy(sun.sun_path, lenv->sc_conf.agentx_path,
450c26b8e61Smartijn 	    sizeof(sun.sun_path)) >= sizeof(sun.sun_path))
451c26b8e61Smartijn 		fatalx("invalid socket path");
452c26b8e61Smartijn 
453c26b8e61Smartijn 	if (connect(s, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
454c26b8e61Smartijn 		close(s);
455c26b8e61Smartijn 		s = -1;
456c26b8e61Smartijn 	}
457c26b8e61Smartijn  done:
458c26b8e61Smartijn 	proc_compose_imsg(lenv->sc_ps, id, -1, IMSG_AGENTXSOCK, -1, s, NULL, 0);
459c26b8e61Smartijn }
460c26b8e61Smartijn 
4614172793dSdv void
agentx_getsock(struct imsg * imsg)462c26b8e61Smartijn agentx_getsock(struct imsg *imsg)
463c26b8e61Smartijn {
464c26b8e61Smartijn 	struct timeval		 tv = AGENTX_RECONNECT_TIMEOUT;
465*a1416996Sclaudio 	int 			 fd;
466c26b8e61Smartijn 
467*a1416996Sclaudio 	fd = imsg_get_fd(imsg);
468*a1416996Sclaudio 	if (fd == -1)
469c26b8e61Smartijn 		goto retry;
470c26b8e61Smartijn 
471c26b8e61Smartijn 	event_del(&(env->sc_agentxev));
472*a1416996Sclaudio 	event_set(&(env->sc_agentxev), fd, EV_READ | EV_PERSIST,
473c26b8e61Smartijn 	    agentx_sock, env);
474c26b8e61Smartijn 	event_add(&(env->sc_agentxev), NULL);
475c26b8e61Smartijn 
476*a1416996Sclaudio 	agentx_connect(sa, fd);
477c26b8e61Smartijn 
478c26b8e61Smartijn  retry:
479c26b8e61Smartijn 	evtimer_set(&env->sc_agentxev, agentx_sock, env);
480c26b8e61Smartijn 	evtimer_add(&env->sc_agentxev, &tv);
481c26b8e61Smartijn }
482c26b8e61Smartijn 
483c26b8e61Smartijn void
agentx_sock(int fd,short event,void * arg)484c26b8e61Smartijn agentx_sock(int fd, short event, void *arg)
485c26b8e61Smartijn {
486c26b8e61Smartijn 	if (event & EV_TIMEOUT) {
487c26b8e61Smartijn 		proc_compose(env->sc_ps, PROC_PARENT, IMSG_AGENTXSOCK, NULL, 0);
488c26b8e61Smartijn 		return;
489c26b8e61Smartijn 	}
490c26b8e61Smartijn 	if (event & EV_WRITE) {
491c26b8e61Smartijn 		event_del(&(env->sc_agentxev));
492c26b8e61Smartijn 		event_set(&(env->sc_agentxev), fd, EV_READ | EV_PERSIST,
493c26b8e61Smartijn 		    agentx_sock, NULL);
494c26b8e61Smartijn 		event_add(&(env->sc_agentxev), NULL);
4951ae60b2aSmartijn 		agentx_write(sa);
496c26b8e61Smartijn 	}
497c26b8e61Smartijn 	if (event & EV_READ)
4981ae60b2aSmartijn 		agentx_read(sa);
499c26b8e61Smartijn 	return;
500c26b8e61Smartijn }
501c26b8e61Smartijn 
502c26b8e61Smartijn void *
sstodata(struct sockaddr_storage * ss)503c26b8e61Smartijn sstodata(struct sockaddr_storage *ss)
504c26b8e61Smartijn {
505c26b8e61Smartijn 	if (ss->ss_family == AF_INET)
506c26b8e61Smartijn 		return &((struct sockaddr_in *)ss)->sin_addr;
507c26b8e61Smartijn 	if (ss->ss_family == AF_INET6)
508c26b8e61Smartijn 		return &((struct sockaddr_in6 *)ss)->sin6_addr;
509c26b8e61Smartijn 	return NULL;
510c26b8e61Smartijn }
511c26b8e61Smartijn 
512c26b8e61Smartijn size_t
sstolen(struct sockaddr_storage * ss)513c26b8e61Smartijn sstolen(struct sockaddr_storage *ss)
514c26b8e61Smartijn {
515c26b8e61Smartijn 	if (ss->ss_family == AF_INET)
516c26b8e61Smartijn 		return sizeof(((struct sockaddr_in *)ss)->sin_addr);
517c26b8e61Smartijn 	if (ss->ss_family == AF_INET6)
518c26b8e61Smartijn 		return sizeof(((struct sockaddr_in6 *)ss)->sin6_addr);
519c26b8e61Smartijn 	return 0;
520c26b8e61Smartijn }
521c26b8e61Smartijn 
522c26b8e61Smartijn struct rdr *
agentxctl_rdr_byidx(uint32_t instanceidx,enum agentx_request_type type)5231ae60b2aSmartijn agentxctl_rdr_byidx(uint32_t instanceidx, enum agentx_request_type type)
524c26b8e61Smartijn {
525c26b8e61Smartijn 	struct rdr	*rdr;
526c26b8e61Smartijn 
527c26b8e61Smartijn 	TAILQ_FOREACH(rdr, env->sc_rdrs, entry) {
528c26b8e61Smartijn 		if (rdr->conf.id == instanceidx) {
5291ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET ||
5301ae60b2aSmartijn 			    type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE)
531c26b8e61Smartijn 				return rdr;
532c26b8e61Smartijn 			else
533c26b8e61Smartijn 				return TAILQ_NEXT(rdr, entry);
534c26b8e61Smartijn 		} else if (rdr->conf.id > instanceidx) {
5351ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET)
536c26b8e61Smartijn 				return NULL;
537c26b8e61Smartijn 			return rdr;
538c26b8e61Smartijn 		}
539c26b8e61Smartijn 	}
540c26b8e61Smartijn 
541c26b8e61Smartijn 	return NULL;
542c26b8e61Smartijn }
543c26b8e61Smartijn 
544c26b8e61Smartijn 
545c26b8e61Smartijn void
agentxctl_redirect(struct agentx_varbind * sav)5461ae60b2aSmartijn agentxctl_redirect(struct agentx_varbind *sav)
547c26b8e61Smartijn {
548c26b8e61Smartijn 	struct rdr	*rdr;
549c26b8e61Smartijn 
5501ae60b2aSmartijn 	rdr = agentxctl_rdr_byidx(agentx_varbind_get_index_integer(sav,
5511ae60b2aSmartijn 	    relaydRedirectIdx), agentx_varbind_request(sav));
55288936fdbSmartijn 	if (rdr == NULL || rdr->conf.id > INT32_MAX) {
5531ae60b2aSmartijn 		agentx_varbind_notfound(sav);
554c26b8e61Smartijn 		return;
555c26b8e61Smartijn 	}
5561ae60b2aSmartijn 	agentx_varbind_set_index_integer(sav, relaydRedirectIdx,
557c26b8e61Smartijn 	    rdr->conf.id);
5581ae60b2aSmartijn 	if (agentx_varbind_get_object(sav) == relaydRedirectIndex)
5591ae60b2aSmartijn 		agentx_varbind_integer(sav, rdr->conf.id);
5601ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRedirectStatus) {
561c26b8e61Smartijn 		if (rdr->conf.flags & F_DISABLE)
5621ae60b2aSmartijn 			agentx_varbind_integer(sav, 1);
563c26b8e61Smartijn 		else if (rdr->conf.flags & F_DOWN)
5641ae60b2aSmartijn 			agentx_varbind_integer(sav, 2);
565c26b8e61Smartijn 		else if (rdr->conf.flags & F_BACKUP)
5661ae60b2aSmartijn 			agentx_varbind_integer(sav, 3);
567c26b8e61Smartijn 		else
5681ae60b2aSmartijn 			agentx_varbind_integer(sav, 0);
5691ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydRedirectName)
5701ae60b2aSmartijn 		agentx_varbind_string(sav, rdr->conf.name);
5711ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRedirectCnt)
5721ae60b2aSmartijn 		agentx_varbind_counter64(sav, rdr->stats.cnt);
5731ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRedirectAvg)
5741ae60b2aSmartijn 		agentx_varbind_gauge32(sav, rdr->stats.avg);
5751ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRedirectLast)
5761ae60b2aSmartijn 		agentx_varbind_gauge32(sav, rdr->stats.last);
5771ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRedirectAvgHour)
5781ae60b2aSmartijn 		agentx_varbind_gauge32(sav, rdr->stats.avg_hour);
5791ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRedirectLastHour)
5801ae60b2aSmartijn 		agentx_varbind_gauge32(sav, rdr->stats.last_hour);
5811ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRedirectAvgDay)
5821ae60b2aSmartijn 		agentx_varbind_gauge32(sav, rdr->stats.avg_day);
5831ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRedirectLastDay)
5841ae60b2aSmartijn 		agentx_varbind_gauge32(sav, rdr->stats.last_day);
585c26b8e61Smartijn }
586c26b8e61Smartijn 
587c26b8e61Smartijn struct relay *
agentxctl_relay_byidx(uint32_t instanceidx,enum agentx_request_type type)5881ae60b2aSmartijn agentxctl_relay_byidx(uint32_t instanceidx, enum agentx_request_type type)
589c26b8e61Smartijn {
590c26b8e61Smartijn 	struct relay	*rly;
591c26b8e61Smartijn 
592c26b8e61Smartijn 	TAILQ_FOREACH(rly, env->sc_relays, rl_entry) {
593c26b8e61Smartijn 		if (rly->rl_conf.id == instanceidx) {
5941ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET ||
5951ae60b2aSmartijn 			    type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE)
596c26b8e61Smartijn 				return rly;
597c26b8e61Smartijn 			else
598c26b8e61Smartijn 				return TAILQ_NEXT(rly, rl_entry);
599c26b8e61Smartijn 		} else if (rly->rl_conf.id > instanceidx) {
6001ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET)
601c26b8e61Smartijn 				return NULL;
602c26b8e61Smartijn 			return rly;
603c26b8e61Smartijn 		}
604c26b8e61Smartijn 	}
605c26b8e61Smartijn 
606c26b8e61Smartijn 	return NULL;
607c26b8e61Smartijn }
608c26b8e61Smartijn 
609c26b8e61Smartijn void
agentxctl_relay(struct agentx_varbind * sav)6101ae60b2aSmartijn agentxctl_relay(struct agentx_varbind *sav)
611c26b8e61Smartijn {
612c26b8e61Smartijn 	struct relay	*rly;
613c26b8e61Smartijn 	uint64_t	 value = 0;
614c26b8e61Smartijn 	int		 i, nrelay = env->sc_conf.prefork_relay;
615c26b8e61Smartijn 
6161ae60b2aSmartijn 	rly = agentxctl_relay_byidx(agentx_varbind_get_index_integer(sav,
6171ae60b2aSmartijn 	    relaydRelayIdx), agentx_varbind_request(sav));
61888936fdbSmartijn 	if (rly == NULL || rly->rl_conf.id > INT32_MAX) {
6191ae60b2aSmartijn 		agentx_varbind_notfound(sav);
620c26b8e61Smartijn 		return;
621c26b8e61Smartijn 	}
6221ae60b2aSmartijn 	agentx_varbind_set_index_integer(sav, relaydRelayIdx,
623c26b8e61Smartijn 	    rly->rl_conf.id);
6241ae60b2aSmartijn 	if (agentx_varbind_get_object(sav) == relaydRelayIndex)
6251ae60b2aSmartijn 		agentx_varbind_integer(sav, rly->rl_conf.id);
6261ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRelayStatus) {
627c26b8e61Smartijn 		if (rly->rl_up == HOST_UP)
6281ae60b2aSmartijn 			agentx_varbind_integer(sav, 1);
629c26b8e61Smartijn 		else
6301ae60b2aSmartijn 			agentx_varbind_integer(sav, 0);
6311ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydRelayName)
6321ae60b2aSmartijn 		agentx_varbind_string(sav, rly->rl_conf.name);
6331ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRelayCnt) {
634c26b8e61Smartijn 		for (i = 0; i < nrelay; i++)
635c26b8e61Smartijn 			value += rly->rl_stats[i].cnt;
6361ae60b2aSmartijn 		agentx_varbind_counter64(sav, value);
6371ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydRelayAvg) {
638c26b8e61Smartijn 		for (i = 0; i < nrelay; i++)
639c26b8e61Smartijn 			value += rly->rl_stats[i].avg;
6401ae60b2aSmartijn 		agentx_varbind_gauge32(sav, (uint32_t)value);
6411ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydRelayLast) {
642c26b8e61Smartijn 		for (i = 0; i < nrelay; i++)
643c26b8e61Smartijn 			value += rly->rl_stats[i].last;
6441ae60b2aSmartijn 		agentx_varbind_gauge32(sav, (uint32_t)value);
6451ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydRelayAvgHour) {
646c26b8e61Smartijn 		for (i = 0; i < nrelay; i++)
647c26b8e61Smartijn 			value += rly->rl_stats[i].avg_hour;
6481ae60b2aSmartijn 		agentx_varbind_gauge32(sav, (uint32_t)value);
6491ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydRelayLastHour) {
650c26b8e61Smartijn 		for (i = 0; i < nrelay; i++)
651c26b8e61Smartijn 			value += rly->rl_stats[i].last_hour;
6521ae60b2aSmartijn 		agentx_varbind_gauge32(sav, (uint32_t)value);
6531ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydRelayAvgDay) {
654c26b8e61Smartijn 		for (i = 0; i < nrelay; i++)
655c26b8e61Smartijn 			value += rly->rl_stats[i].avg_day;
6561ae60b2aSmartijn 		agentx_varbind_gauge32(sav, (uint32_t)value);
6571ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydRelayLastDay) {
658c26b8e61Smartijn 		for (i = 0; i < nrelay; i++)
659c26b8e61Smartijn 			value += rly->rl_stats[i].last_day;
6601ae60b2aSmartijn 		agentx_varbind_gauge32(sav, (uint32_t)value);
661c26b8e61Smartijn 	}
662c26b8e61Smartijn }
663c26b8e61Smartijn 
664c26b8e61Smartijn struct router *
agentxctl_router_byidx(uint32_t instanceidx,enum agentx_request_type type)6651ae60b2aSmartijn agentxctl_router_byidx(uint32_t instanceidx, enum agentx_request_type type)
666c26b8e61Smartijn {
667c26b8e61Smartijn 	struct router	*router;
668c26b8e61Smartijn 
669c26b8e61Smartijn 	TAILQ_FOREACH(router, env->sc_rts, rt_entry) {
670c26b8e61Smartijn 		if (router->rt_conf.id == instanceidx) {
6711ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET ||
6721ae60b2aSmartijn 			    type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE)
673c26b8e61Smartijn 				return router;
674c26b8e61Smartijn 			else
675c26b8e61Smartijn 				return TAILQ_NEXT(router, rt_entry);
676c26b8e61Smartijn 		} else if (router->rt_conf.id > instanceidx) {
6771ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET)
678c26b8e61Smartijn 				return NULL;
679c26b8e61Smartijn 			return router;
680c26b8e61Smartijn 		}
681c26b8e61Smartijn 	}
682c26b8e61Smartijn 
683c26b8e61Smartijn 	return NULL;
684c26b8e61Smartijn }
685c26b8e61Smartijn 
686c26b8e61Smartijn void
agentxctl_router(struct agentx_varbind * sav)6871ae60b2aSmartijn agentxctl_router(struct agentx_varbind *sav)
688c26b8e61Smartijn {
689c26b8e61Smartijn 	struct router	*router;
690c26b8e61Smartijn 
6911ae60b2aSmartijn 	router = agentxctl_router_byidx(agentx_varbind_get_index_integer(sav,
6921ae60b2aSmartijn 	    relaydRouterIdx), agentx_varbind_request(sav));
69388936fdbSmartijn 	if (router == NULL || router->rt_conf.id > INT32_MAX) {
6941ae60b2aSmartijn 		agentx_varbind_notfound(sav);
695c26b8e61Smartijn 		return;
696c26b8e61Smartijn 	}
6971ae60b2aSmartijn 	agentx_varbind_set_index_integer(sav, relaydRouterIdx,
698c26b8e61Smartijn 	    router->rt_conf.id);
6991ae60b2aSmartijn 	if (agentx_varbind_get_object(sav) == relaydRouterIndex)
7001ae60b2aSmartijn 		agentx_varbind_integer(sav, router->rt_conf.id);
70188936fdbSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRouterTableIndex) {
70288936fdbSmartijn 		if (router->rt_conf.gwtable > INT32_MAX)
70388936fdbSmartijn 			agentx_varbind_integer(sav, -1);
70488936fdbSmartijn 		else
7051ae60b2aSmartijn 			agentx_varbind_integer(sav, router->rt_conf.gwtable);
70688936fdbSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydRouterStatus) {
707c26b8e61Smartijn 		if (router->rt_conf.flags & F_DISABLE)
7081ae60b2aSmartijn 			agentx_varbind_integer(sav, 1);
709c26b8e61Smartijn 		else
7101ae60b2aSmartijn 			agentx_varbind_integer(sav, 0);
7111ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydRouterName)
7121ae60b2aSmartijn 		agentx_varbind_string(sav, router->rt_conf.name);
7131ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRouterLabel)
7141ae60b2aSmartijn 		agentx_varbind_string(sav, router->rt_conf.label);
7151ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydRouterRtable)
7161ae60b2aSmartijn 		agentx_varbind_integer(sav, router->rt_conf.rtable);
717c26b8e61Smartijn }
718c26b8e61Smartijn 
719c26b8e61Smartijn struct netroute *
agentxctl_netroute_byidx(uint32_t instanceidx,enum agentx_request_type type)7201ae60b2aSmartijn agentxctl_netroute_byidx(uint32_t instanceidx, enum agentx_request_type type)
721c26b8e61Smartijn {
722c26b8e61Smartijn 	struct netroute		*nr;
723c26b8e61Smartijn 
724c26b8e61Smartijn 	TAILQ_FOREACH(nr, env->sc_routes, nr_route) {
725c26b8e61Smartijn 		if (nr->nr_conf.id == instanceidx) {
7261ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET ||
7271ae60b2aSmartijn 			    type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE)
728c26b8e61Smartijn 				return nr;
729c26b8e61Smartijn 			else
730c26b8e61Smartijn 				return TAILQ_NEXT(nr, nr_entry);
731c26b8e61Smartijn 		} else if (nr->nr_conf.id > instanceidx) {
7321ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET)
733c26b8e61Smartijn 				return NULL;
734c26b8e61Smartijn 			return nr;
735c26b8e61Smartijn 		}
736c26b8e61Smartijn 	}
737c26b8e61Smartijn 
738c26b8e61Smartijn 	return NULL;
739c26b8e61Smartijn }
740c26b8e61Smartijn 
741c26b8e61Smartijn void
agentxctl_netroute(struct agentx_varbind * sav)7421ae60b2aSmartijn agentxctl_netroute(struct agentx_varbind *sav)
743c26b8e61Smartijn {
744c26b8e61Smartijn 	struct netroute	*nr;
745c26b8e61Smartijn 
7461ae60b2aSmartijn 	nr = agentxctl_netroute_byidx(agentx_varbind_get_index_integer(sav,
7471ae60b2aSmartijn 	    relaydNetRouteIdx), agentx_varbind_request(sav));
74888936fdbSmartijn 	if (nr == NULL || nr->nr_conf.id > INT32_MAX) {
7491ae60b2aSmartijn 		agentx_varbind_notfound(sav);
750c26b8e61Smartijn 		return;
751c26b8e61Smartijn 	}
7521ae60b2aSmartijn 	agentx_varbind_set_index_integer(sav, relaydNetRouteIdx,
753c26b8e61Smartijn 	    nr->nr_conf.id);
7541ae60b2aSmartijn 	if (agentx_varbind_get_object(sav) == relaydNetRouteIndex)
7551ae60b2aSmartijn 		agentx_varbind_integer(sav, nr->nr_conf.id);
7561ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydNetRouteAddr)
7571ae60b2aSmartijn 		agentx_varbind_nstring(sav, sstodata(&nr->nr_conf.ss),
758c26b8e61Smartijn 		    sstolen(&nr->nr_conf.ss));
7591ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydNetRouteAddrType) {
760c26b8e61Smartijn 		if (nr->nr_conf.ss.ss_family == AF_INET)
7611ae60b2aSmartijn 			agentx_varbind_integer(sav, 1);
762c26b8e61Smartijn 		else if (nr->nr_conf.ss.ss_family == AF_INET6)
7631ae60b2aSmartijn 			agentx_varbind_integer(sav, 2);
7641ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydNetRoutePrefixLen)
7651ae60b2aSmartijn 		agentx_varbind_integer(sav, nr->nr_conf.prefixlen);
76688936fdbSmartijn 	else if (agentx_varbind_get_object(sav) == relaydNetRouteRouterIndex) {
76788936fdbSmartijn 		if (nr->nr_conf.routerid > INT32_MAX)
76888936fdbSmartijn 			agentx_varbind_integer(sav, -1);
76988936fdbSmartijn 		else
7701ae60b2aSmartijn 			agentx_varbind_integer(sav, nr->nr_conf.routerid);
771c26b8e61Smartijn 	}
77288936fdbSmartijn }
773c26b8e61Smartijn 
774c26b8e61Smartijn struct host *
agentxctl_host_byidx(uint32_t instanceidx,enum agentx_request_type type)7751ae60b2aSmartijn agentxctl_host_byidx(uint32_t instanceidx, enum agentx_request_type type)
776c26b8e61Smartijn {
777c26b8e61Smartijn 	struct host		*host;
778c26b8e61Smartijn 
779c26b8e61Smartijn 	TAILQ_FOREACH(host, &(env->sc_hosts), globalentry) {
780c26b8e61Smartijn 		if (host->conf.id == instanceidx) {
7811ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET ||
7821ae60b2aSmartijn 			    type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE)
783c26b8e61Smartijn 				return host;
784c26b8e61Smartijn 			else
785c26b8e61Smartijn 				return TAILQ_NEXT(host, globalentry);
786c26b8e61Smartijn 		} else if (host->conf.id > instanceidx) {
7871ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET)
788c26b8e61Smartijn 				return NULL;
789c26b8e61Smartijn 			return host;
790c26b8e61Smartijn 		}
791c26b8e61Smartijn 	}
792c26b8e61Smartijn 
793c26b8e61Smartijn 	return NULL;
794c26b8e61Smartijn }
795c26b8e61Smartijn 
796c26b8e61Smartijn void
agentxctl_host(struct agentx_varbind * sav)7971ae60b2aSmartijn agentxctl_host(struct agentx_varbind *sav)
798c26b8e61Smartijn {
799c26b8e61Smartijn 	struct host	*host;
800c26b8e61Smartijn 
8011ae60b2aSmartijn 	host = agentxctl_host_byidx(agentx_varbind_get_index_integer(sav,
8021ae60b2aSmartijn 	    relaydHostIdx), agentx_varbind_request(sav));
80388936fdbSmartijn 	if (host == NULL || host->conf.id > INT32_MAX) {
8041ae60b2aSmartijn 		agentx_varbind_notfound(sav);
805c26b8e61Smartijn 		return;
806c26b8e61Smartijn 	}
8071ae60b2aSmartijn 	agentx_varbind_set_index_integer(sav, relaydHostIdx,
808c26b8e61Smartijn 	    host->conf.id);
8091ae60b2aSmartijn 	if (agentx_varbind_get_object(sav) == relaydHostIndex)
8101ae60b2aSmartijn 		agentx_varbind_integer(sav, host->conf.id);
81188936fdbSmartijn 	else if (agentx_varbind_get_object(sav) == relaydHostParentIndex) {
81288936fdbSmartijn 		if (host->conf.parentid > INT32_MAX)
81388936fdbSmartijn 			agentx_varbind_integer(sav, -1);
81488936fdbSmartijn 		else
8151ae60b2aSmartijn 			agentx_varbind_integer(sav, host->conf.parentid);
81688936fdbSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydHostTableIndex) {
81788936fdbSmartijn 		if (host->conf.tableid > INT32_MAX)
81888936fdbSmartijn 			agentx_varbind_integer(sav, -1);
81988936fdbSmartijn 		else
8201ae60b2aSmartijn 			agentx_varbind_integer(sav, host->conf.tableid);
82188936fdbSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydHostName)
8221ae60b2aSmartijn 		agentx_varbind_string(sav, host->conf.name);
8231ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydHostAddress)
8241ae60b2aSmartijn 		agentx_varbind_nstring(sav, sstodata(&host->conf.ss),
825c26b8e61Smartijn 		    sstolen(&host->conf.ss));
8261ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydHostAddressType) {
827c26b8e61Smartijn 		if (host->conf.ss.ss_family == AF_INET)
8281ae60b2aSmartijn 			agentx_varbind_integer(sav, 1);
829c26b8e61Smartijn 		else if (host->conf.ss.ss_family == AF_INET6)
8301ae60b2aSmartijn 			agentx_varbind_integer(sav, 2);
8311ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydHostStatus) {
832c26b8e61Smartijn 		if (host->flags & F_DISABLE)
8331ae60b2aSmartijn 			agentx_varbind_integer(sav, 1);
834c26b8e61Smartijn 		else if (host->up == HOST_UP)
8351ae60b2aSmartijn 			agentx_varbind_integer(sav, 0);
836c26b8e61Smartijn 		else if (host->up == HOST_DOWN)
8371ae60b2aSmartijn 			agentx_varbind_integer(sav, 2);
838c26b8e61Smartijn 		else
8391ae60b2aSmartijn 			agentx_varbind_integer(sav, 3);
8401ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydHostCheckCnt)
8411ae60b2aSmartijn 		agentx_varbind_counter64(sav, host->check_cnt);
8421ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydHostUpCnt)
8431ae60b2aSmartijn 		agentx_varbind_counter64(sav, host->up_cnt);
8441ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydHostErrno)
8451ae60b2aSmartijn 		agentx_varbind_integer(sav, host->he);
846c26b8e61Smartijn }
847c26b8e61Smartijn 
848c26b8e61Smartijn /*
849c26b8e61Smartijn  * Every session is spawned in one of multiple processes.
850c26b8e61Smartijn  * However, there is no central session id registration, so not every session
851c26b8e61Smartijn  * is shown here
852c26b8e61Smartijn  */
853c26b8e61Smartijn struct rsession *
agentxctl_session_byidx(uint32_t sessidx,uint32_t relayidx,enum agentx_request_type type)8541ae60b2aSmartijn agentxctl_session_byidx(uint32_t sessidx, uint32_t relayidx,
8551ae60b2aSmartijn     enum agentx_request_type type)
856c26b8e61Smartijn {
857c26b8e61Smartijn 	struct rsession		*session;
858c26b8e61Smartijn 
859c26b8e61Smartijn 	TAILQ_FOREACH(session, &(env->sc_sessions), se_entry) {
860c26b8e61Smartijn 		if (session->se_id == sessidx) {
8611ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET) {
862c26b8e61Smartijn 				if (relayidx != session->se_relayid)
863c26b8e61Smartijn 					return NULL;
864c26b8e61Smartijn 				return session;
865c26b8e61Smartijn 			}
8661ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) {
867c26b8e61Smartijn 				if (relayidx <= session->se_relayid)
868c26b8e61Smartijn 					return session;
869c26b8e61Smartijn 				return TAILQ_NEXT(session, se_entry);
870c26b8e61Smartijn 			}
871c26b8e61Smartijn 			if (relayidx < session->se_relayid)
872c26b8e61Smartijn 				return session;
873c26b8e61Smartijn 			return TAILQ_NEXT(session, se_entry);
874c26b8e61Smartijn 		} else if (session->se_id > sessidx) {
8751ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET)
876c26b8e61Smartijn 				return NULL;
877c26b8e61Smartijn 			return session;
878c26b8e61Smartijn 		}
879c26b8e61Smartijn 	}
880c26b8e61Smartijn 
881c26b8e61Smartijn 	return NULL;
882c26b8e61Smartijn }
883c26b8e61Smartijn 
884c26b8e61Smartijn void
agentxctl_session(struct agentx_varbind * sav)8851ae60b2aSmartijn agentxctl_session(struct agentx_varbind *sav)
886c26b8e61Smartijn {
887c26b8e61Smartijn 	struct timeval	 tv, now;
888c26b8e61Smartijn 	struct rsession	*session;
889c26b8e61Smartijn 
8901ae60b2aSmartijn 	session = agentxctl_session_byidx(agentx_varbind_get_index_integer(sav,
8911ae60b2aSmartijn 	    relaydSessionIdx), agentx_varbind_get_index_integer(sav,
8921ae60b2aSmartijn 	    relaydSessionRelayIdx), agentx_varbind_request(sav));
89388936fdbSmartijn 	if (session == NULL || session->se_id > INT32_MAX ||
89488936fdbSmartijn 	    session->se_relayid > INT32_MAX) {
8951ae60b2aSmartijn 		agentx_varbind_notfound(sav);
896c26b8e61Smartijn 		return;
897c26b8e61Smartijn 	}
898c26b8e61Smartijn 
8991ae60b2aSmartijn 	agentx_varbind_set_index_integer(sav, relaydSessionIdx,
900c26b8e61Smartijn 	    session->se_id);
9011ae60b2aSmartijn 	agentx_varbind_set_index_integer(sav, relaydSessionRelayIdx,
902c26b8e61Smartijn 	    session->se_relayid);
9031ae60b2aSmartijn 	if (agentx_varbind_get_object(sav) == relaydSessionIndex)
9041ae60b2aSmartijn 		agentx_varbind_integer(sav, session->se_id);
9051ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydSessionRelayIndex)
9061ae60b2aSmartijn 		agentx_varbind_integer(sav, session->se_relayid);
9071ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydSessionInAddr)
9081ae60b2aSmartijn 		agentx_varbind_nstring(sav, sstodata(&(session->se_in.ss)),
909c26b8e61Smartijn 		    sstolen(&(session->se_in.ss)));
9101ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydSessionInAddrType) {
911c26b8e61Smartijn 		if (session->se_in.ss.ss_family == AF_INET)
9121ae60b2aSmartijn 			agentx_varbind_integer(sav, 1);
913c26b8e61Smartijn 		else if (session->se_in.ss.ss_family == AF_INET6)
9141ae60b2aSmartijn 			agentx_varbind_integer(sav, 2);
9151ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydSessionOutAddr)
9161ae60b2aSmartijn 		agentx_varbind_nstring(sav, sstodata(&(session->se_out.ss)),
917c26b8e61Smartijn 		    sstolen(&(session->se_out.ss)));
9181ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydSessionOutAddrType) {
919c26b8e61Smartijn 		if (session->se_out.ss.ss_family == AF_INET)
9201ae60b2aSmartijn 			agentx_varbind_integer(sav, 1);
921c26b8e61Smartijn 		else if (session->se_out.ss.ss_family == AF_INET6)
9221ae60b2aSmartijn 			agentx_varbind_integer(sav, 2);
923c26b8e61Smartijn 		else
9241ae60b2aSmartijn 			agentx_varbind_integer(sav, 0);
9251ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydSessionPortIn)
9261ae60b2aSmartijn 		agentx_varbind_integer(sav, session->se_in.port);
9271ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydSessionPortOut)
9281ae60b2aSmartijn 		agentx_varbind_integer(sav, session->se_out.port);
9291ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydSessionAge) {
930c26b8e61Smartijn 		getmonotime(&now);
931c26b8e61Smartijn 		timersub(&now, &session->se_tv_start, &tv);
9321ae60b2aSmartijn 		agentx_varbind_timeticks(sav,
933c26b8e61Smartijn 		    tv.tv_sec * 100 + tv.tv_usec / 10000);
9341ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydSessionIdle) {
935c26b8e61Smartijn 		getmonotime(&now);
936c26b8e61Smartijn 		timersub(&now, &session->se_tv_last, &tv);
9371ae60b2aSmartijn 		agentx_varbind_timeticks(sav,
938c26b8e61Smartijn 		    tv.tv_sec * 100 + tv.tv_usec / 10000);
9391ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydSessionStatus) {
940c26b8e61Smartijn 		if (session->se_done)
9411ae60b2aSmartijn 			agentx_varbind_integer(sav, 1);
942c26b8e61Smartijn 		else
9431ae60b2aSmartijn 			agentx_varbind_integer(sav, 0);
9441ae60b2aSmartijn 	} else if (agentx_varbind_get_object(sav) == relaydSessionPid)
9451ae60b2aSmartijn 		agentx_varbind_integer(sav, session->se_pid);
946c26b8e61Smartijn }
947c26b8e61Smartijn 
948c26b8e61Smartijn struct table *
agentxctl_table_byidx(uint32_t instanceidx,enum agentx_request_type type)9491ae60b2aSmartijn agentxctl_table_byidx(uint32_t instanceidx, enum agentx_request_type type)
950c26b8e61Smartijn {
951c26b8e61Smartijn 	struct table		*table;
952c26b8e61Smartijn 
953c26b8e61Smartijn 	TAILQ_FOREACH(table, env->sc_tables, entry) {
954c26b8e61Smartijn 		if (table->conf.id == instanceidx) {
9551ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET ||
9561ae60b2aSmartijn 			    type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE)
957c26b8e61Smartijn 				return table;
958c26b8e61Smartijn 			else
959c26b8e61Smartijn 				return TAILQ_NEXT(table, entry);
960c26b8e61Smartijn 		} else if (table->conf.id > instanceidx) {
9611ae60b2aSmartijn 			if (type == AGENTX_REQUEST_TYPE_GET)
962c26b8e61Smartijn 				return NULL;
963c26b8e61Smartijn 			return table;
964c26b8e61Smartijn 		}
965c26b8e61Smartijn 	}
966c26b8e61Smartijn 
967c26b8e61Smartijn 	return NULL;
968c26b8e61Smartijn }
969c26b8e61Smartijn 
970c26b8e61Smartijn void
agentxctl_table(struct agentx_varbind * sav)9711ae60b2aSmartijn agentxctl_table(struct agentx_varbind *sav)
972c26b8e61Smartijn {
973c26b8e61Smartijn 	struct table	*table;
974c26b8e61Smartijn 
9751ae60b2aSmartijn 	table = agentxctl_table_byidx(agentx_varbind_get_index_integer(sav,
9761ae60b2aSmartijn 	    relaydTableIdx), agentx_varbind_request(sav));
97788936fdbSmartijn 	if (table == NULL || table->conf.id > INT32_MAX) {
9781ae60b2aSmartijn 		agentx_varbind_notfound(sav);
979c26b8e61Smartijn 		return;
980c26b8e61Smartijn 	}
9811ae60b2aSmartijn 	agentx_varbind_set_index_integer(sav, relaydTableIdx,
982c26b8e61Smartijn 	    table->conf.id);
9831ae60b2aSmartijn 	if (agentx_varbind_get_object(sav) == relaydTableIndex)
9841ae60b2aSmartijn 		agentx_varbind_integer(sav, table->conf.id);
9851ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydTableName)
9861ae60b2aSmartijn 		agentx_varbind_string(sav, table->conf.name);
9871ae60b2aSmartijn 	else if (agentx_varbind_get_object(sav) == relaydTableStatus) {
988c26b8e61Smartijn 		if (TAILQ_EMPTY(&table->hosts))
9891ae60b2aSmartijn 			agentx_varbind_integer(sav, 1);
990c26b8e61Smartijn 		else if (table->conf.flags & F_DISABLE)
9911ae60b2aSmartijn 			agentx_varbind_integer(sav, 2);
992c26b8e61Smartijn 		else
9931ae60b2aSmartijn 			agentx_varbind_integer(sav, 0);
994c26b8e61Smartijn 	}
995c26b8e61Smartijn 
996c26b8e61Smartijn }
997c26b8e61Smartijn #if 0
998c26b8e61Smartijn 
999c26b8e61Smartijn int
1000c26b8e61Smartijn snmp_element(const char *oidstr, enum snmp_type type, void *buf, int64_t val,
1001c26b8e61Smartijn     struct agentx_pdu *pdu)
1002c26b8e61Smartijn {
1003c26b8e61Smartijn 	u_int32_t		 d;
1004c26b8e61Smartijn 	u_int64_t		 l;
1005c26b8e61Smartijn 	struct snmp_oid		 oid;
1006c26b8e61Smartijn 
1007c26b8e61Smartijn 	DPRINTF("%s: oid %s type %d buf %p val %lld", __func__,
1008c26b8e61Smartijn 	    oidstr, type, buf, val);
1009c26b8e61Smartijn 
1010c26b8e61Smartijn 	if (snmp_string2oid(oidstr, &oid) == -1)
1011c26b8e61Smartijn 		return -1;
1012c26b8e61Smartijn 
1013c26b8e61Smartijn 	switch (type) {
1014c26b8e61Smartijn 	case SNMP_GAUGE32:
1015c26b8e61Smartijn 	case SNMP_NSAPADDR:
1016c26b8e61Smartijn 	case SNMP_INTEGER32:
1017c26b8e61Smartijn 	case SNMP_UINTEGER32:
1018c26b8e61Smartijn 		d = (u_int32_t)val;
1019c26b8e61Smartijn 		if (snmp_agentx_varbind(pdu, &oid, AGENTX_INTEGER,
1020c26b8e61Smartijn 		    &d, sizeof(d)) == -1)
1021c26b8e61Smartijn 			return -1;
1022c26b8e61Smartijn 		break;
1023c26b8e61Smartijn 
1024c26b8e61Smartijn 	case SNMP_COUNTER32:
1025c26b8e61Smartijn 		d = (u_int32_t)val;
1026c26b8e61Smartijn 		if (snmp_agentx_varbind(pdu, &oid, AGENTX_COUNTER32,
1027c26b8e61Smartijn 		    &d, sizeof(d)) == -1)
1028c26b8e61Smartijn 			return -1;
1029c26b8e61Smartijn 		break;
1030c26b8e61Smartijn 
1031c26b8e61Smartijn 	case SNMP_TIMETICKS:
1032c26b8e61Smartijn 		d = (u_int32_t)val;
1033c26b8e61Smartijn 		if (snmp_agentx_varbind(pdu, &oid, AGENTX_TIME_TICKS,
1034c26b8e61Smartijn 		    &d, sizeof(d)) == -1)
1035c26b8e61Smartijn 			return -1;
1036c26b8e61Smartijn 		break;
1037c26b8e61Smartijn 
1038c26b8e61Smartijn 	case SNMP_COUNTER64:
1039c26b8e61Smartijn 		l = (u_int64_t)val;
1040c26b8e61Smartijn 		if (snmp_agentx_varbind(pdu, &oid, AGENTX_COUNTER64,
1041c26b8e61Smartijn 		    &l, sizeof(l)) == -1)
1042c26b8e61Smartijn 			return -1;
1043c26b8e61Smartijn 		break;
1044c26b8e61Smartijn 
1045c26b8e61Smartijn 	case SNMP_IPADDR:
1046c26b8e61Smartijn 	case SNMP_OPAQUE:
1047c26b8e61Smartijn 		d = (u_int32_t)val;
1048c26b8e61Smartijn 		if (snmp_agentx_varbind(pdu, &oid, AGENTX_OPAQUE,
1049c26b8e61Smartijn 		    buf, strlen(buf)) == -1)
1050c26b8e61Smartijn 			return -1;
1051c26b8e61Smartijn 		break;
1052c26b8e61Smartijn 
1053c26b8e61Smartijn 	case SNMP_OBJECT: {
1054c26b8e61Smartijn 		struct snmp_oid		oid1;
1055c26b8e61Smartijn 
1056c26b8e61Smartijn 		if (snmp_string2oid(buf, &oid1) == -1)
1057c26b8e61Smartijn 			return -1;
1058c26b8e61Smartijn 		if (snmp_agentx_varbind(pdu, &oid, AGENTX_OBJECT_IDENTIFIER,
1059c26b8e61Smartijn 		    &oid1, sizeof(oid1)) == -1)
1060c26b8e61Smartijn 			return -1;
1061c26b8e61Smartijn 	}
1062c26b8e61Smartijn 
1063c26b8e61Smartijn 	case SNMP_BITSTRING:
1064c26b8e61Smartijn 	case SNMP_OCTETSTRING:
1065c26b8e61Smartijn 		if (snmp_agentx_varbind(pdu, &oid, AGENTX_OCTET_STRING,
1066c26b8e61Smartijn 		    buf, strlen(buf)) == -1)
1067c26b8e61Smartijn 			return -1;
1068c26b8e61Smartijn 		break;
1069c26b8e61Smartijn 
1070c26b8e61Smartijn 	case SNMP_NULL:
1071c26b8e61Smartijn 		/* no data beyond the OID itself */
1072c26b8e61Smartijn 		if (snmp_agentx_varbind(pdu, &oid, AGENTX_NULL,
1073c26b8e61Smartijn 		    NULL, 0) == -1)
1074c26b8e61Smartijn 			return -1;
1075c26b8e61Smartijn 	}
1076c26b8e61Smartijn 
1077c26b8e61Smartijn 	return 0;
1078c26b8e61Smartijn }
1079c26b8e61Smartijn 
1080c26b8e61Smartijn /*
1081c26b8e61Smartijn  * SNMP traps for relayd
1082c26b8e61Smartijn  */
1083c26b8e61Smartijn 
1084c26b8e61Smartijn void
1085c26b8e61Smartijn snmp_hosttrap(struct relayd *env, struct table *table, struct host *host)
1086c26b8e61Smartijn {
1087c26b8e61Smartijn 	struct agentx_pdu *pdu;
1088c26b8e61Smartijn 
1089c26b8e61Smartijn 	if (snmp_agentx == NULL || env->sc_snmp == -1)
1090c26b8e61Smartijn 		return;
1091c26b8e61Smartijn 
1092c26b8e61Smartijn 	/*
1093c26b8e61Smartijn 	 * OPENBSD-RELAYD-MIB host status trap
1094c26b8e61Smartijn 	 * XXX The trap format needs some tweaks and other OIDs
1095c26b8e61Smartijn 	 */
1096c26b8e61Smartijn 
1097c26b8e61Smartijn 	if ((pdu = snmp_agentx_notify_pdu(&hosttrapoid)) == NULL)
1098c26b8e61Smartijn 		return;
1099c26b8e61Smartijn 
1100c26b8e61Smartijn 	SNMP_ELEMENT(".1.0", SNMP_NULL, NULL, 0, pdu);
1101c26b8e61Smartijn 	SNMP_ELEMENT(".1.1.0", SNMP_OCTETSTRING, host->conf.name, 0, pdu);
1102c26b8e61Smartijn 	SNMP_ELEMENT(".1.2.0", SNMP_INTEGER32, NULL, host->up, pdu);
1103c26b8e61Smartijn 	SNMP_ELEMENT(".1.3.0", SNMP_INTEGER32, NULL, host->last_up, pdu);
1104c26b8e61Smartijn 	SNMP_ELEMENT(".1.4.0", SNMP_INTEGER32, NULL, host->up_cnt, pdu);
1105c26b8e61Smartijn 	SNMP_ELEMENT(".1.5.0", SNMP_INTEGER32, NULL, host->check_cnt, pdu);
1106c26b8e61Smartijn 	SNMP_ELEMENT(".1.6.0", SNMP_OCTETSTRING, table->conf.name, 0, pdu);
1107c26b8e61Smartijn 	SNMP_ELEMENT(".1.7.0", SNMP_INTEGER32, NULL, table->up, pdu);
1108c26b8e61Smartijn 	if (!host->conf.retry)
1109c26b8e61Smartijn 		goto done;
1110c26b8e61Smartijn 	SNMP_ELEMENT(".1.8.0", SNMP_INTEGER32, NULL, host->conf.retry, pdu);
1111c26b8e61Smartijn 	SNMP_ELEMENT(".1.9.0", SNMP_INTEGER32, NULL, host->retry_cnt, pdu);
1112c26b8e61Smartijn 
1113c26b8e61Smartijn  done:
1114c26b8e61Smartijn 	snmp_agentx_send(snmp_agentx, pdu);
1115c26b8e61Smartijn 	snmp_event_add(env, EV_WRITE);
1116c26b8e61Smartijn }
1117c26b8e61Smartijn 
1118c26b8e61Smartijn int
1119c26b8e61Smartijn snmp_string2oid(const char *oidstr, struct snmp_oid *o)
1120c26b8e61Smartijn {
1121c26b8e61Smartijn 	char			*sp, *p, str[BUFSIZ];
1122c26b8e61Smartijn 	const char		*errstr;
1123c26b8e61Smartijn 
1124c26b8e61Smartijn 	if (strlcpy(str, oidstr, sizeof(str)) >= sizeof(str))
1125c26b8e61Smartijn 		return -1;
1126c26b8e61Smartijn 	bzero(o, sizeof(*o));
1127c26b8e61Smartijn 
1128c26b8e61Smartijn 	for (p = sp = str; p != NULL; sp = p) {
1129c26b8e61Smartijn 		if ((p = strpbrk(p, ".-")) != NULL)
1130c26b8e61Smartijn 			*p++ = '\0';
1131c26b8e61Smartijn 		o->o_id[o->o_n++] = strtonum(sp, 0, UINT_MAX, &errstr);
1132c26b8e61Smartijn 		if (errstr || o->o_n > SNMP_MAX_OID_LEN)
1133c26b8e61Smartijn 			return -1;
1134c26b8e61Smartijn 	}
1135c26b8e61Smartijn 
1136c26b8e61Smartijn 	return 0;
1137c26b8e61Smartijn }
1138c26b8e61Smartijn #endif
1139