1 /* $OpenBSD: agentx_control.c,v 1.1 2020/09/14 11:30:25 martijn Exp $ */ 2 3 /* 4 * Copyright (c) 2020 Martijn van Duren <martijn@openbsd.org> 5 * Copyright (c) 2008 - 2014 Reyk Floeter <reyk@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/types.h> 21 #include <sys/socket.h> 22 #include <sys/queue.h> 23 #include <sys/time.h> 24 #include <sys/un.h> 25 26 #include <netinet/in.h> 27 28 #include <limits.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <stdint.h> 32 #include <errno.h> 33 #include <string.h> 34 #include <syslog.h> 35 #include <unistd.h> 36 #include <event.h> 37 #include <imsg.h> 38 39 #include "relayd.h" 40 #include "subagentx.h" 41 42 #define RELAYD_MIB "1.3.6.1.4.1.30155.3" 43 #define SNMP_ELEMENT(x...) do { \ 44 if (snmp_element(RELAYD_MIB x) == -1) \ 45 goto done; \ 46 } while (0) 47 48 /* 49 static struct snmp_oid hosttrapoid = { 50 { 1, 3, 6, 1, 4, 1, 30155, 3, 1, 0 }, 51 10 52 }; 53 */ 54 55 #define RELAYDINFO SUBAGENTX_ENTERPRISES, 30155, 3, 2 56 #define RELAYDREDIRECTS RELAYDINFO, 1 57 #define RELAYDREDIRECTENTRY RELAYDREDIRECTS, 1 58 #define RELAYDREDIRECTINDEX RELAYDREDIRECTENTRY, 1 59 #define RELAYDREDIRECTSTATUS RELAYDREDIRECTENTRY, 2 60 #define RELAYDREDIRECTNAME RELAYDREDIRECTENTRY, 3 61 #define RELAYDREDIRECTCNT RELAYDREDIRECTENTRY, 4 62 #define RELAYDREDIRECTAVG RELAYDREDIRECTENTRY, 5 63 #define RELAYDREDIRECTLAST RELAYDREDIRECTENTRY, 6 64 #define RELAYDREDIRECTAVGHOUR RELAYDREDIRECTENTRY, 7 65 #define RELAYDREDIRECTLASTHOUR RELAYDREDIRECTENTRY, 8 66 #define RELAYDREDIRECTAVGDAY RELAYDREDIRECTENTRY, 9 67 #define RELAYDREDIRECTLASTDAY RELAYDREDIRECTENTRY, 10 68 #define RELAYDRELAYS RELAYDINFO, 2 69 #define RELAYDRELAYENTRY RELAYDRELAYS, 1 70 #define RELAYDRELAYINDEX RELAYDRELAYENTRY, 1 71 #define RELAYDRELAYSTATUS RELAYDRELAYENTRY, 2 72 #define RELAYDRELAYNAME RELAYDRELAYENTRY, 3 73 #define RELAYDRELAYCNT RELAYDRELAYENTRY, 4 74 #define RELAYDRELAYAVG RELAYDRELAYENTRY, 5 75 #define RELAYDRELAYLAST RELAYDRELAYENTRY, 6 76 #define RELAYDRELAYAVGHOUR RELAYDRELAYENTRY, 7 77 #define RELAYDRELAYLASTHOUR RELAYDRELAYENTRY, 8 78 #define RELAYDRELAYAVGDAY RELAYDRELAYENTRY, 9 79 #define RELAYDRELAYLASTDAY RELAYDRELAYENTRY, 10 80 #define RELAYDROUTERS RELAYDINFO, 3 81 #define RELAYDROUTERENTRY RELAYDROUTERS, 1 82 #define RELAYDROUTERINDEX RELAYDROUTERENTRY, 1 83 #define RELAYDROUTERTABLEINDEX RELAYDROUTERENTRY, 2 84 #define RELAYDROUTERSTATUS RELAYDROUTERENTRY, 3 85 #define RELAYDROUTERNAME RELAYDROUTERENTRY, 4 86 #define RELAYDROUTERLABEL RELAYDROUTERENTRY, 5 87 #define RELAYDROUTERRTABLE RELAYDROUTERENTRY, 6 88 #define RELAYDNETROUTES RELAYDINFO, 4 89 #define RELAYDNETROUTEENTRY RELAYDNETROUTES, 1 90 #define RELAYDNETROUTEINDEX RELAYDNETROUTEENTRY, 1 91 #define RELAYDNETROUTEADDR RELAYDNETROUTEENTRY, 2 92 #define RELAYDNETROUTEADDRTYPE RELAYDNETROUTEENTRY, 3 93 #define RELAYDNETROUTEPREFIXLEN RELAYDNETROUTEENTRY, 4 94 #define RELAYDNETROUTEROUTERINDEX RELAYDNETROUTEENTRY, 5 95 #define RELAYDHOSTS RELAYDINFO, 5 96 #define RELAYDHOSTENTRY RELAYDHOSTS, 1 97 #define RELAYDHOSTINDEX RELAYDHOSTENTRY, 1 98 #define RELAYDHOSTPARENTINDEX RELAYDHOSTENTRY, 2 99 #define RELAYDHOSTTABLEINDEX RELAYDHOSTENTRY, 3 100 #define RELAYDHOSTNAME RELAYDHOSTENTRY, 4 101 #define RELAYDHOSTADDRESS RELAYDHOSTENTRY, 5 102 #define RELAYDHOSTADDRESSTYPE RELAYDHOSTENTRY, 6 103 #define RELAYDHOSTSTATUS RELAYDHOSTENTRY, 7 104 #define RELAYDHOSTCHECKCNT RELAYDHOSTENTRY, 8 105 #define RELAYDHOSTUPCNT RELAYDHOSTENTRY, 9 106 #define RELAYDHOSTERRNO RELAYDHOSTENTRY, 10 107 #define RELAYDSESSIONS RELAYDINFO, 6 108 #define RELAYDSESSIONENTRY RELAYDSESSIONS, 1 109 #define RELAYDSESSIONINDEX RELAYDSESSIONENTRY, 1 110 #define RELAYDSESSIONRELAYINDEX RELAYDSESSIONENTRY, 2 111 #define RELAYDSESSIONINADDR RELAYDSESSIONENTRY, 3 112 #define RELAYDSESSIONINADDRTYPE RELAYDSESSIONENTRY, 4 113 #define RELAYDSESSIONOUTADDR RELAYDSESSIONENTRY, 5 114 #define RELAYDSESSIONOUTADDRTYPE RELAYDSESSIONENTRY, 6 115 #define RELAYDSESSIONPORTIN RELAYDSESSIONENTRY, 7 116 #define RELAYDSESSIONPORTOUT RELAYDSESSIONENTRY, 8 117 #define RELAYDSESSIONAGE RELAYDSESSIONENTRY, 9 118 #define RELAYDSESSIONIDLE RELAYDSESSIONENTRY, 10 119 #define RELAYDSESSIONSTATUS RELAYDSESSIONENTRY, 11 120 #define RELAYDSESSIONPID RELAYDSESSIONENTRY, 12 121 #define RELAYDTABLES RELAYDINFO, 7 122 #define RELAYDTABLEENTRY RELAYDTABLES, 1 123 #define RELAYDTABLEINDEX RELAYDTABLEENTRY, 1 124 #define RELAYDTABLENAME RELAYDTABLEENTRY, 2 125 #define RELAYDTABLESTATUS RELAYDTABLEENTRY, 3 126 127 void agentx_needsock(struct subagentx *, void *, int); 128 129 struct relayd *env; 130 131 struct subagentx *sa = NULL; 132 struct subagentx_index *relaydRedirectIdx, *relaydRelayIdx; 133 struct subagentx_index *relaydRouterIdx, *relaydNetRouteIdx; 134 struct subagentx_index *relaydHostIdx, *relaydSessionRelayIdx; 135 struct subagentx_index *relaydSessionIdx, *relaydTableIdx; 136 137 struct subagentx_object *relaydRedirectIndex, *relaydRedirectStatus; 138 struct subagentx_object *relaydRedirectName, *relaydRedirectCnt; 139 struct subagentx_object *relaydRedirectAvg, *relaydRedirectLast; 140 struct subagentx_object *relaydRedirectAvgHour, *relaydRedirectLastHour; 141 struct subagentx_object *relaydRedirectAvgDay, *relaydRedirectLastDay; 142 143 struct subagentx_object *relaydRelayIndex, *relaydRelayStatus; 144 struct subagentx_object *relaydRelayName, *relaydRelayCnt; 145 struct subagentx_object *relaydRelayAvg, *relaydRelayLast; 146 struct subagentx_object *relaydRelayAvgHour, *relaydRelayLastHour; 147 struct subagentx_object *relaydRelayAvgDay, *relaydRelayLastDay; 148 149 struct subagentx_object *relaydRouterIndex, *relaydRouterTableIndex; 150 struct subagentx_object *relaydRouterStatus, *relaydRouterName; 151 struct subagentx_object *relaydRouterLabel, *relaydRouterRtable; 152 153 struct subagentx_object *relaydNetRouteIndex, *relaydNetRouteAddr; 154 struct subagentx_object *relaydNetRouteAddrType, *relaydNetRoutePrefixLen; 155 struct subagentx_object *relaydNetRouteRouterIndex; 156 157 struct subagentx_object *relaydHostIndex, *relaydHostParentIndex; 158 struct subagentx_object *relaydHostTableIndex, *relaydHostName; 159 struct subagentx_object *relaydHostAddress, *relaydHostAddressType; 160 struct subagentx_object *relaydHostStatus, *relaydHostCheckCnt; 161 struct subagentx_object *relaydHostUpCnt, *relaydHostErrno; 162 163 struct subagentx_object *relaydSessionIndex, *relaydSessionRelayIndex; 164 struct subagentx_object *relaydSessionInAddr, *relaydSessionInAddrType; 165 struct subagentx_object *relaydSessionOutAddr, *relaydSessionOutAddrType; 166 struct subagentx_object *relaydSessionPortIn, *relaydSessionPortOut; 167 struct subagentx_object *relaydSessionAge, *relaydSessionIdle; 168 struct subagentx_object *relaydSessionStatus, *relaydSessionPid; 169 170 struct subagentx_object *relaydTableIndex, *relaydTableName, *relaydTableStatus; 171 172 void *sstodata(struct sockaddr_storage *); 173 size_t sstolen(struct sockaddr_storage *); 174 175 struct rdr *agentx_rdr_byidx(uint32_t, enum subagentx_request_type); 176 void agentx_redirect(struct subagentx_varbind *); 177 struct relay *agentx_relay_byidx(uint32_t, enum subagentx_request_type); 178 void agentx_relay(struct subagentx_varbind *); 179 struct router *agentx_router_byidx(uint32_t, enum subagentx_request_type); 180 void agentx_router(struct subagentx_varbind *); 181 struct netroute *agentx_netroute_byidx(uint32_t, enum subagentx_request_type); 182 void agentx_netroute(struct subagentx_varbind *); 183 struct host *agentx_host_byidx(uint32_t, enum subagentx_request_type); 184 void agentx_host(struct subagentx_varbind *); 185 struct rsession *agentx_session_byidx(uint32_t, uint32_t, 186 enum subagentx_request_type); 187 void agentx_session(struct subagentx_varbind *); 188 struct table *agentx_table_byidx(uint32_t, enum subagentx_request_type); 189 void agentx_table(struct subagentx_varbind *); 190 191 void agentx_sock(int, short, void *); 192 #if 0 193 int snmp_element(const char *, enum snmp_type, void *, int64_t, 194 struct agentx_pdu *); 195 int snmp_string2oid(const char *, struct snmp_oid *); 196 #endif 197 198 void 199 agentx_init(struct relayd *nenv) 200 { 201 struct subagentx_session *sas; 202 struct subagentx_context *sac; 203 struct subagentx_region *sar; 204 struct subagentx_index *session_idxs[2]; 205 206 subagentx_log_fatal = fatalx; 207 subagentx_log_warn = log_warnx; 208 subagentx_log_info = log_info; 209 subagentx_log_debug = log_debug; 210 211 env = nenv; 212 213 if ((env->sc_conf.flags & F_AGENTX) == 0) { 214 if (sa != NULL) 215 subagentx_free(sa); 216 return; 217 } 218 if (sa != NULL) 219 return; 220 221 if ((sa = subagentx(agentx_needsock, NULL)) == NULL) 222 fatal("%s: agentx alloc", __func__); 223 if ((sas = subagentx_session(sa, NULL, 0, "relayd", 0)) == NULL) 224 fatal("%s: agentx session alloc", __func__); 225 if ((sac = subagentx_context(sas, 226 env->sc_conf.agentx_context[0] == '\0' ? NULL : 227 env->sc_conf.agentx_context)) == NULL) 228 fatal("%s: agentx context alloc", __func__); 229 sar = subagentx_region(sac, SUBAGENTX_OID(RELAYDINFO), 0); 230 if (sar == NULL) 231 fatal("%s: agentx region alloc", __func__); 232 if ((relaydRedirectIdx = subagentx_index_integer_dynamic(sar, 233 SUBAGENTX_OID(RELAYDREDIRECTINDEX))) == NULL || 234 (relaydRelayIdx = subagentx_index_integer_dynamic(sar, 235 SUBAGENTX_OID(RELAYDRELAYINDEX))) == NULL || 236 (relaydRouterIdx = subagentx_index_integer_dynamic(sar, 237 SUBAGENTX_OID(RELAYDROUTERINDEX))) == NULL || 238 (relaydNetRouteIdx = subagentx_index_integer_dynamic(sar, 239 SUBAGENTX_OID(RELAYDNETROUTEINDEX))) == NULL || 240 (relaydHostIdx = subagentx_index_integer_dynamic(sar, 241 SUBAGENTX_OID(RELAYDHOSTINDEX))) == NULL || 242 (relaydSessionIdx = subagentx_index_integer_dynamic(sar, 243 SUBAGENTX_OID(RELAYDSESSIONINDEX))) == NULL || 244 (relaydSessionRelayIdx = subagentx_index_integer_dynamic(sar, 245 SUBAGENTX_OID(RELAYDSESSIONRELAYINDEX))) == NULL || 246 (relaydTableIdx = subagentx_index_integer_dynamic(sar, 247 SUBAGENTX_OID(RELAYDTABLEINDEX))) == NULL) 248 fatal("%s: agentx index alloc", __func__); 249 session_idxs[0] = relaydSessionRelayIdx; 250 session_idxs[1] = relaydSessionIdx; 251 if ((relaydRedirectIndex = subagentx_object(sar, 252 SUBAGENTX_OID(RELAYDREDIRECTINDEX), &relaydRedirectIdx, 1, 0, 253 agentx_redirect)) == NULL || 254 (relaydRedirectStatus = subagentx_object(sar, 255 SUBAGENTX_OID(RELAYDREDIRECTSTATUS), &relaydRedirectIdx, 1, 0, 256 agentx_redirect)) == NULL || 257 (relaydRedirectName = subagentx_object(sar, 258 SUBAGENTX_OID(RELAYDREDIRECTNAME), &relaydRedirectIdx, 1, 0, 259 agentx_redirect)) == NULL || 260 (relaydRedirectCnt = subagentx_object(sar, 261 SUBAGENTX_OID(RELAYDREDIRECTCNT), &relaydRedirectIdx, 1, 0, 262 agentx_redirect)) == NULL || 263 (relaydRedirectAvg = subagentx_object(sar, 264 SUBAGENTX_OID(RELAYDREDIRECTAVG), &relaydRedirectIdx, 1, 0, 265 agentx_redirect)) == NULL || 266 (relaydRedirectLast = subagentx_object(sar, 267 SUBAGENTX_OID(RELAYDREDIRECTLAST), &relaydRedirectIdx, 1, 0, 268 agentx_redirect)) == NULL || 269 (relaydRedirectAvgHour = subagentx_object(sar, 270 SUBAGENTX_OID(RELAYDREDIRECTAVGHOUR), &relaydRedirectIdx, 1, 0, 271 agentx_redirect)) == NULL || 272 (relaydRedirectLastHour = subagentx_object(sar, 273 SUBAGENTX_OID(RELAYDREDIRECTLASTHOUR), &relaydRedirectIdx, 1, 0, 274 agentx_redirect)) == NULL || 275 (relaydRedirectAvgDay = subagentx_object(sar, 276 SUBAGENTX_OID(RELAYDREDIRECTAVGDAY), &relaydRedirectIdx, 1, 0, 277 agentx_redirect)) == NULL || 278 (relaydRedirectLastDay = subagentx_object(sar, 279 SUBAGENTX_OID(RELAYDREDIRECTLASTDAY), &relaydRedirectIdx, 1, 0, 280 agentx_redirect)) == NULL || 281 (relaydRelayIndex = subagentx_object(sar, 282 SUBAGENTX_OID(RELAYDRELAYINDEX), &relaydRelayIdx, 1, 0, 283 agentx_relay)) == NULL || 284 (relaydRelayStatus = subagentx_object(sar, 285 SUBAGENTX_OID(RELAYDRELAYSTATUS), &relaydRelayIdx, 1, 0, 286 agentx_relay)) == NULL || 287 (relaydRelayName = subagentx_object(sar, 288 SUBAGENTX_OID(RELAYDRELAYNAME), &relaydRelayIdx, 1, 0, 289 agentx_relay)) == NULL || 290 (relaydRelayCnt = subagentx_object(sar, 291 SUBAGENTX_OID(RELAYDRELAYCNT), &relaydRelayIdx, 1, 0, 292 agentx_relay)) == NULL || 293 (relaydRelayAvg = subagentx_object(sar, 294 SUBAGENTX_OID(RELAYDRELAYAVG), &relaydRelayIdx, 1, 0, 295 agentx_relay)) == NULL || 296 (relaydRelayLast = subagentx_object(sar, 297 SUBAGENTX_OID(RELAYDRELAYLAST), &relaydRelayIdx, 1, 0, 298 agentx_relay)) == NULL || 299 (relaydRelayAvgHour = subagentx_object(sar, 300 SUBAGENTX_OID(RELAYDRELAYAVGHOUR), &relaydRelayIdx, 1, 0, 301 agentx_relay)) == NULL || 302 (relaydRelayLastHour = subagentx_object(sar, 303 SUBAGENTX_OID(RELAYDRELAYLASTHOUR), &relaydRelayIdx, 1, 0, 304 agentx_relay)) == NULL || 305 (relaydRelayAvgDay = subagentx_object(sar, 306 SUBAGENTX_OID(RELAYDRELAYAVGDAY), &relaydRelayIdx, 1, 0, 307 agentx_relay)) == NULL || 308 (relaydRelayLastDay = subagentx_object(sar, 309 SUBAGENTX_OID(RELAYDRELAYLASTDAY), &relaydRelayIdx, 1, 0, 310 agentx_relay)) == NULL || 311 (relaydRouterIndex = subagentx_object(sar, 312 SUBAGENTX_OID(RELAYDROUTERINDEX), &relaydRouterIdx, 1, 0, 313 agentx_router)) == NULL || 314 (relaydRouterTableIndex = subagentx_object(sar, 315 SUBAGENTX_OID(RELAYDROUTERTABLEINDEX), &relaydRouterIdx, 1, 0, 316 agentx_router)) == NULL || 317 (relaydRouterStatus = subagentx_object(sar, 318 SUBAGENTX_OID(RELAYDROUTERSTATUS), &relaydRouterIdx, 1, 0, 319 agentx_router)) == NULL || 320 (relaydRouterName = subagentx_object(sar, 321 SUBAGENTX_OID(RELAYDROUTERNAME), &relaydRouterIdx, 1, 0, 322 agentx_router)) == NULL || 323 (relaydRouterLabel = subagentx_object(sar, 324 SUBAGENTX_OID(RELAYDROUTERLABEL), &relaydRouterIdx, 1, 0, 325 agentx_router)) == NULL || 326 (relaydRouterRtable = subagentx_object(sar, 327 SUBAGENTX_OID(RELAYDROUTERRTABLE), &relaydRouterIdx, 1, 0, 328 agentx_router)) == NULL || 329 (relaydNetRouteIndex = subagentx_object(sar, 330 SUBAGENTX_OID(RELAYDNETROUTEINDEX), &relaydNetRouteIdx, 1, 0, 331 agentx_netroute)) == NULL || 332 (relaydNetRouteAddr = subagentx_object(sar, 333 SUBAGENTX_OID(RELAYDNETROUTEADDR), &relaydNetRouteIdx, 1, 0, 334 agentx_netroute)) == NULL || 335 (relaydNetRouteAddrType = subagentx_object(sar, 336 SUBAGENTX_OID(RELAYDNETROUTEADDRTYPE), &relaydNetRouteIdx, 1, 0, 337 agentx_netroute)) == NULL || 338 (relaydNetRoutePrefixLen = subagentx_object(sar, 339 SUBAGENTX_OID(RELAYDNETROUTEPREFIXLEN), &relaydNetRouteIdx, 1, 0, 340 agentx_netroute)) == NULL || 341 (relaydNetRouteRouterIndex = subagentx_object(sar, 342 SUBAGENTX_OID(RELAYDNETROUTEROUTERINDEX), &relaydNetRouteIdx, 1, 0, 343 agentx_netroute)) == NULL || 344 (relaydHostIndex = subagentx_object(sar, 345 SUBAGENTX_OID(RELAYDHOSTINDEX), &relaydHostIdx, 1, 0, 346 agentx_host)) == NULL || 347 (relaydHostParentIndex = subagentx_object(sar, 348 SUBAGENTX_OID(RELAYDHOSTPARENTINDEX), &relaydHostIdx, 1, 0, 349 agentx_host)) == NULL || 350 (relaydHostTableIndex = subagentx_object(sar, 351 SUBAGENTX_OID(RELAYDHOSTTABLEINDEX), &relaydHostIdx, 1, 0, 352 agentx_host)) == NULL || 353 (relaydHostName = subagentx_object(sar, 354 SUBAGENTX_OID(RELAYDHOSTNAME), &relaydHostIdx, 1, 0, 355 agentx_host)) == NULL || 356 (relaydHostAddress = subagentx_object(sar, 357 SUBAGENTX_OID(RELAYDHOSTADDRESS), &relaydHostIdx, 1, 0, 358 agentx_host)) == NULL || 359 (relaydHostAddressType = subagentx_object(sar, 360 SUBAGENTX_OID(RELAYDHOSTADDRESSTYPE), &relaydHostIdx, 1, 0, 361 agentx_host)) == NULL || 362 (relaydHostStatus = subagentx_object(sar, 363 SUBAGENTX_OID(RELAYDHOSTSTATUS), &relaydHostIdx, 1, 0, 364 agentx_host)) == NULL || 365 (relaydHostCheckCnt = subagentx_object(sar, 366 SUBAGENTX_OID(RELAYDHOSTCHECKCNT), &relaydHostIdx, 1, 0, 367 agentx_host)) == NULL || 368 (relaydHostUpCnt = subagentx_object(sar, 369 SUBAGENTX_OID(RELAYDHOSTUPCNT), &relaydHostIdx, 1, 0, 370 agentx_host)) == NULL || 371 (relaydHostErrno = subagentx_object(sar, 372 SUBAGENTX_OID(RELAYDHOSTERRNO), &relaydHostIdx, 1, 0, 373 agentx_host)) == NULL || 374 (relaydSessionIndex = subagentx_object(sar, 375 SUBAGENTX_OID(RELAYDSESSIONINDEX), session_idxs, 2, 0, 376 agentx_session)) == NULL || 377 (relaydSessionRelayIndex = subagentx_object(sar, 378 SUBAGENTX_OID(RELAYDSESSIONRELAYINDEX), session_idxs, 2, 0, 379 agentx_session)) == NULL || 380 (relaydSessionInAddr = subagentx_object(sar, 381 SUBAGENTX_OID(RELAYDSESSIONINADDR), session_idxs, 2, 0, 382 agentx_session)) == NULL || 383 (relaydSessionInAddrType = subagentx_object(sar, 384 SUBAGENTX_OID(RELAYDSESSIONINADDRTYPE), session_idxs, 2, 0, 385 agentx_session)) == NULL || 386 (relaydSessionOutAddr = subagentx_object(sar, 387 SUBAGENTX_OID(RELAYDSESSIONOUTADDR), session_idxs, 2, 0, 388 agentx_session)) == NULL || 389 (relaydSessionOutAddrType = subagentx_object(sar, 390 SUBAGENTX_OID(RELAYDSESSIONOUTADDRTYPE), session_idxs, 2, 0, 391 agentx_session)) == NULL || 392 (relaydSessionPortIn = subagentx_object(sar, 393 SUBAGENTX_OID(RELAYDSESSIONPORTIN), session_idxs, 2, 0, 394 agentx_session)) == NULL || 395 (relaydSessionPortOut = subagentx_object(sar, 396 SUBAGENTX_OID(RELAYDSESSIONPORTOUT), session_idxs, 2, 0, 397 agentx_session)) == NULL || 398 (relaydSessionAge = subagentx_object(sar, 399 SUBAGENTX_OID(RELAYDSESSIONAGE), session_idxs, 2, 0, 400 agentx_session)) == NULL || 401 (relaydSessionIdle = subagentx_object(sar, 402 SUBAGENTX_OID(RELAYDSESSIONIDLE), session_idxs, 2, 0, 403 agentx_session)) == NULL || 404 (relaydSessionStatus = subagentx_object(sar, 405 SUBAGENTX_OID(RELAYDSESSIONSTATUS), session_idxs, 2, 0, 406 agentx_session)) == NULL || 407 (relaydSessionPid = subagentx_object(sar, 408 SUBAGENTX_OID(RELAYDSESSIONPID), session_idxs, 2, 0, 409 agentx_session)) == NULL || 410 (relaydTableIndex = subagentx_object(sar, 411 SUBAGENTX_OID(RELAYDTABLEINDEX), &relaydTableIdx, 1, 0, 412 agentx_table)) == NULL || 413 (relaydTableName = subagentx_object(sar, 414 SUBAGENTX_OID(RELAYDTABLENAME), &relaydTableIdx, 1, 0, 415 agentx_table)) == NULL || 416 (relaydTableStatus = subagentx_object(sar, 417 SUBAGENTX_OID(RELAYDTABLESTATUS), &relaydTableIdx, 1, 0, 418 agentx_table)) == NULL) 419 fatal("%s: agentx object alloc", __func__); 420 } 421 422 void 423 agentx_needsock(struct subagentx *usa, void *cookie, int fd) 424 { 425 proc_compose(env->sc_ps, PROC_PARENT, IMSG_AGENTXSOCK, NULL, 0); 426 } 427 428 void 429 agentx_setsock(struct relayd *lenv, enum privsep_procid id) 430 { 431 struct sockaddr_un sun; 432 int s = -1; 433 434 if ((s = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1) 435 goto done; 436 437 bzero(&sun, sizeof(sun)); 438 sun.sun_family = AF_UNIX; 439 if (strlcpy(sun.sun_path, lenv->sc_conf.agentx_path, 440 sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) 441 fatalx("invalid socket path"); 442 443 if (connect(s, (struct sockaddr *)&sun, sizeof(sun)) == -1) { 444 close(s); 445 s = -1; 446 } 447 done: 448 proc_compose_imsg(lenv->sc_ps, id, -1, IMSG_AGENTXSOCK, -1, s, NULL, 0); 449 } 450 451 int 452 agentx_getsock(struct imsg *imsg) 453 { 454 struct timeval tv = AGENTX_RECONNECT_TIMEOUT; 455 456 if (imsg->fd == -1) 457 goto retry; 458 459 event_del(&(env->sc_agentxev)); 460 event_set(&(env->sc_agentxev), imsg->fd, EV_READ | EV_PERSIST, 461 agentx_sock, env); 462 event_add(&(env->sc_agentxev), NULL); 463 464 subagentx_connect(sa, imsg->fd); 465 466 return 0; 467 retry: 468 evtimer_set(&env->sc_agentxev, agentx_sock, env); 469 evtimer_add(&env->sc_agentxev, &tv); 470 return 0; 471 } 472 473 void 474 agentx_sock(int fd, short event, void *arg) 475 { 476 if (event & EV_TIMEOUT) { 477 proc_compose(env->sc_ps, PROC_PARENT, IMSG_AGENTXSOCK, NULL, 0); 478 return; 479 } 480 if (event & EV_WRITE) { 481 event_del(&(env->sc_agentxev)); 482 event_set(&(env->sc_agentxev), fd, EV_READ | EV_PERSIST, 483 agentx_sock, NULL); 484 event_add(&(env->sc_agentxev), NULL); 485 subagentx_write(sa); 486 } 487 if (event & EV_READ) 488 subagentx_read(sa); 489 return; 490 } 491 492 void * 493 sstodata(struct sockaddr_storage *ss) 494 { 495 if (ss->ss_family == AF_INET) 496 return &((struct sockaddr_in *)ss)->sin_addr; 497 if (ss->ss_family == AF_INET6) 498 return &((struct sockaddr_in6 *)ss)->sin6_addr; 499 return NULL; 500 } 501 502 size_t 503 sstolen(struct sockaddr_storage *ss) 504 { 505 if (ss->ss_family == AF_INET) 506 return sizeof(((struct sockaddr_in *)ss)->sin_addr); 507 if (ss->ss_family == AF_INET6) 508 return sizeof(((struct sockaddr_in6 *)ss)->sin6_addr); 509 return 0; 510 } 511 512 struct rdr * 513 agentx_rdr_byidx(uint32_t instanceidx, enum subagentx_request_type type) 514 { 515 struct rdr *rdr; 516 517 TAILQ_FOREACH(rdr, env->sc_rdrs, entry) { 518 if (rdr->conf.id == instanceidx) { 519 if (type == SUBAGENTX_REQUEST_TYPE_GET || 520 type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) 521 return rdr; 522 else 523 return TAILQ_NEXT(rdr, entry); 524 } else if (rdr->conf.id > instanceidx) { 525 if (type == SUBAGENTX_REQUEST_TYPE_GET) 526 return NULL; 527 return rdr; 528 } 529 } 530 531 return NULL; 532 } 533 534 535 void 536 agentx_redirect(struct subagentx_varbind *sav) 537 { 538 struct rdr *rdr; 539 540 rdr = agentx_rdr_byidx(subagentx_varbind_get_index_integer(sav, 541 relaydRedirectIdx), subagentx_varbind_request(sav)); 542 if (rdr == NULL) { 543 subagentx_varbind_notfound(sav); 544 return; 545 } 546 subagentx_varbind_set_index_integer(sav, relaydRedirectIdx, 547 rdr->conf.id); 548 if (subagentx_varbind_get_object(sav) == relaydRedirectIndex) 549 subagentx_varbind_integer(sav, rdr->conf.id); 550 else if (subagentx_varbind_get_object(sav) == relaydRedirectStatus) { 551 if (rdr->conf.flags & F_DISABLE) 552 subagentx_varbind_integer(sav, 1); 553 else if (rdr->conf.flags & F_DOWN) 554 subagentx_varbind_integer(sav, 2); 555 else if (rdr->conf.flags & F_BACKUP) 556 subagentx_varbind_integer(sav, 3); 557 else 558 subagentx_varbind_integer(sav, 0); 559 } else if (subagentx_varbind_get_object(sav) == relaydRedirectName) 560 subagentx_varbind_string(sav, rdr->conf.name); 561 else if (subagentx_varbind_get_object(sav) == relaydRedirectCnt) 562 subagentx_varbind_counter64(sav, rdr->stats.cnt); 563 else if (subagentx_varbind_get_object(sav) == relaydRedirectAvg) 564 subagentx_varbind_gauge32(sav, rdr->stats.avg); 565 else if (subagentx_varbind_get_object(sav) == relaydRedirectLast) 566 subagentx_varbind_gauge32(sav, rdr->stats.last); 567 else if (subagentx_varbind_get_object(sav) == relaydRedirectAvgHour) 568 subagentx_varbind_gauge32(sav, rdr->stats.avg_hour); 569 else if (subagentx_varbind_get_object(sav) == relaydRedirectLastHour) 570 subagentx_varbind_gauge32(sav, rdr->stats.last_hour); 571 else if (subagentx_varbind_get_object(sav) == relaydRedirectAvgDay) 572 subagentx_varbind_gauge32(sav, rdr->stats.avg_day); 573 else if (subagentx_varbind_get_object(sav) == relaydRedirectLastDay) 574 subagentx_varbind_gauge32(sav, rdr->stats.last_day); 575 } 576 577 struct relay * 578 agentx_relay_byidx(uint32_t instanceidx, enum subagentx_request_type type) 579 { 580 struct relay *rly; 581 582 TAILQ_FOREACH(rly, env->sc_relays, rl_entry) { 583 if (rly->rl_conf.id == instanceidx) { 584 if (type == SUBAGENTX_REQUEST_TYPE_GET || 585 type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) 586 return rly; 587 else 588 return TAILQ_NEXT(rly, rl_entry); 589 } else if (rly->rl_conf.id > instanceidx) { 590 if (type == SUBAGENTX_REQUEST_TYPE_GET) 591 return NULL; 592 return rly; 593 } 594 } 595 596 return NULL; 597 } 598 599 void 600 agentx_relay(struct subagentx_varbind *sav) 601 { 602 struct relay *rly; 603 uint64_t value = 0; 604 int i, nrelay = env->sc_conf.prefork_relay; 605 606 rly = agentx_relay_byidx(subagentx_varbind_get_index_integer(sav, 607 relaydRelayIdx), subagentx_varbind_request(sav)); 608 if (rly == NULL) { 609 subagentx_varbind_notfound(sav); 610 return; 611 } 612 subagentx_varbind_set_index_integer(sav, relaydRelayIdx, 613 rly->rl_conf.id); 614 if (subagentx_varbind_get_object(sav) == relaydRelayIndex) 615 subagentx_varbind_integer(sav, rly->rl_conf.id); 616 else if (subagentx_varbind_get_object(sav) == relaydRelayStatus) { 617 if (rly->rl_up == HOST_UP) 618 subagentx_varbind_integer(sav, 1); 619 else 620 subagentx_varbind_integer(sav, 0); 621 } else if (subagentx_varbind_get_object(sav) == relaydRelayName) 622 subagentx_varbind_string(sav, rly->rl_conf.name); 623 else if (subagentx_varbind_get_object(sav) == relaydRelayCnt) { 624 for (i = 0; i < nrelay; i++) 625 value += rly->rl_stats[i].cnt; 626 subagentx_varbind_counter64(sav, value); 627 } else if (subagentx_varbind_get_object(sav) == relaydRelayAvg) { 628 for (i = 0; i < nrelay; i++) 629 value += rly->rl_stats[i].avg; 630 subagentx_varbind_gauge32(sav, (uint32_t)value); 631 } else if (subagentx_varbind_get_object(sav) == relaydRelayLast) { 632 for (i = 0; i < nrelay; i++) 633 value += rly->rl_stats[i].last; 634 subagentx_varbind_gauge32(sav, (uint32_t)value); 635 } else if (subagentx_varbind_get_object(sav) == relaydRelayAvgHour) { 636 for (i = 0; i < nrelay; i++) 637 value += rly->rl_stats[i].avg_hour; 638 subagentx_varbind_gauge32(sav, (uint32_t)value); 639 } else if (subagentx_varbind_get_object(sav) == relaydRelayLastHour) { 640 for (i = 0; i < nrelay; i++) 641 value += rly->rl_stats[i].last_hour; 642 subagentx_varbind_gauge32(sav, (uint32_t)value); 643 } else if (subagentx_varbind_get_object(sav) == relaydRelayAvgDay) { 644 for (i = 0; i < nrelay; i++) 645 value += rly->rl_stats[i].avg_day; 646 subagentx_varbind_gauge32(sav, (uint32_t)value); 647 } else if (subagentx_varbind_get_object(sav) == relaydRelayLastDay) { 648 for (i = 0; i < nrelay; i++) 649 value += rly->rl_stats[i].last_day; 650 subagentx_varbind_gauge32(sav, (uint32_t)value); 651 } 652 } 653 654 struct router * 655 agentx_router_byidx(uint32_t instanceidx, enum subagentx_request_type type) 656 { 657 struct router *router; 658 659 TAILQ_FOREACH(router, env->sc_rts, rt_entry) { 660 if (router->rt_conf.id == instanceidx) { 661 if (type == SUBAGENTX_REQUEST_TYPE_GET || 662 type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) 663 return router; 664 else 665 return TAILQ_NEXT(router, rt_entry); 666 } else if (router->rt_conf.id > instanceidx) { 667 if (type == SUBAGENTX_REQUEST_TYPE_GET) 668 return NULL; 669 return router; 670 } 671 } 672 673 return NULL; 674 } 675 676 void 677 agentx_router(struct subagentx_varbind *sav) 678 { 679 struct router *router; 680 681 router = agentx_router_byidx(subagentx_varbind_get_index_integer(sav, 682 relaydRouterIdx), subagentx_varbind_request(sav)); 683 if (router == NULL) { 684 subagentx_varbind_notfound(sav); 685 return; 686 } 687 subagentx_varbind_set_index_integer(sav, relaydRouterIdx, 688 router->rt_conf.id); 689 if (subagentx_varbind_get_object(sav) == relaydRouterIndex) 690 subagentx_varbind_integer(sav, router->rt_conf.id); 691 else if (subagentx_varbind_get_object(sav) == relaydRouterTableIndex) 692 subagentx_varbind_integer(sav, router->rt_conf.gwtable); 693 else if (subagentx_varbind_get_object(sav) == relaydRouterStatus) { 694 if (router->rt_conf.flags & F_DISABLE) 695 subagentx_varbind_integer(sav, 1); 696 else 697 subagentx_varbind_integer(sav, 0); 698 } else if (subagentx_varbind_get_object(sav) == relaydRouterName) 699 subagentx_varbind_string(sav, router->rt_conf.name); 700 else if (subagentx_varbind_get_object(sav) == relaydRouterLabel) 701 subagentx_varbind_string(sav, router->rt_conf.label); 702 else if (subagentx_varbind_get_object(sav) == relaydRouterRtable) 703 subagentx_varbind_integer(sav, router->rt_conf.rtable); 704 } 705 706 struct netroute * 707 agentx_netroute_byidx(uint32_t instanceidx, enum subagentx_request_type type) 708 { 709 struct netroute *nr; 710 711 TAILQ_FOREACH(nr, env->sc_routes, nr_route) { 712 if (nr->nr_conf.id == instanceidx) { 713 if (type == SUBAGENTX_REQUEST_TYPE_GET || 714 type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) 715 return nr; 716 else 717 return TAILQ_NEXT(nr, nr_entry); 718 } else if (nr->nr_conf.id > instanceidx) { 719 if (type == SUBAGENTX_REQUEST_TYPE_GET) 720 return NULL; 721 return nr; 722 } 723 } 724 725 return NULL; 726 } 727 728 void 729 agentx_netroute(struct subagentx_varbind *sav) 730 { 731 struct netroute *nr; 732 733 nr = agentx_netroute_byidx(subagentx_varbind_get_index_integer(sav, 734 relaydNetRouteIdx), subagentx_varbind_request(sav)); 735 if (nr == NULL) { 736 subagentx_varbind_notfound(sav); 737 return; 738 } 739 subagentx_varbind_set_index_integer(sav, relaydNetRouteIdx, 740 nr->nr_conf.id); 741 if (subagentx_varbind_get_object(sav) == relaydNetRouteIndex) 742 subagentx_varbind_integer(sav, nr->nr_conf.id); 743 else if (subagentx_varbind_get_object(sav) == relaydNetRouteAddr) 744 subagentx_varbind_nstring(sav, sstodata(&nr->nr_conf.ss), 745 sstolen(&nr->nr_conf.ss)); 746 else if (subagentx_varbind_get_object(sav) == relaydNetRouteAddrType) { 747 if (nr->nr_conf.ss.ss_family == AF_INET) 748 subagentx_varbind_integer(sav, 1); 749 else if (nr->nr_conf.ss.ss_family == AF_INET6) 750 subagentx_varbind_integer(sav, 2); 751 } else if (subagentx_varbind_get_object(sav) == relaydNetRoutePrefixLen) 752 subagentx_varbind_integer(sav, nr->nr_conf.prefixlen); 753 else if (subagentx_varbind_get_object(sav) == relaydNetRouteRouterIndex) 754 subagentx_varbind_integer(sav, nr->nr_conf.routerid); 755 } 756 757 struct host * 758 agentx_host_byidx(uint32_t instanceidx, enum subagentx_request_type type) 759 { 760 struct host *host; 761 762 TAILQ_FOREACH(host, &(env->sc_hosts), globalentry) { 763 if (host->conf.id == instanceidx) { 764 if (type == SUBAGENTX_REQUEST_TYPE_GET || 765 type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) 766 return host; 767 else 768 return TAILQ_NEXT(host, globalentry); 769 } else if (host->conf.id > instanceidx) { 770 if (type == SUBAGENTX_REQUEST_TYPE_GET) 771 return NULL; 772 return host; 773 } 774 } 775 776 return NULL; 777 } 778 779 void 780 agentx_host(struct subagentx_varbind *sav) 781 { 782 struct host *host; 783 784 host = agentx_host_byidx(subagentx_varbind_get_index_integer(sav, 785 relaydHostIdx), subagentx_varbind_request(sav)); 786 if (host == NULL) { 787 subagentx_varbind_notfound(sav); 788 return; 789 } 790 subagentx_varbind_set_index_integer(sav, relaydHostIdx, 791 host->conf.id); 792 if (subagentx_varbind_get_object(sav) == relaydHostIndex) 793 subagentx_varbind_integer(sav, host->conf.id); 794 else if (subagentx_varbind_get_object(sav) == relaydHostParentIndex) 795 subagentx_varbind_integer(sav, host->conf.parentid); 796 else if (subagentx_varbind_get_object(sav) == relaydHostTableIndex) 797 subagentx_varbind_integer(sav, host->conf.tableid); 798 else if (subagentx_varbind_get_object(sav) == relaydHostName) 799 subagentx_varbind_string(sav, host->conf.name); 800 else if (subagentx_varbind_get_object(sav) == relaydHostAddress) 801 subagentx_varbind_nstring(sav, sstodata(&host->conf.ss), 802 sstolen(&host->conf.ss)); 803 else if (subagentx_varbind_get_object(sav) == relaydHostAddressType) { 804 if (host->conf.ss.ss_family == AF_INET) 805 subagentx_varbind_integer(sav, 1); 806 else if (host->conf.ss.ss_family == AF_INET6) 807 subagentx_varbind_integer(sav, 2); 808 } else if (subagentx_varbind_get_object(sav) == relaydHostStatus) { 809 if (host->flags & F_DISABLE) 810 subagentx_varbind_integer(sav, 1); 811 else if (host->up == HOST_UP) 812 subagentx_varbind_integer(sav, 0); 813 else if (host->up == HOST_DOWN) 814 subagentx_varbind_integer(sav, 2); 815 else 816 subagentx_varbind_integer(sav, 3); 817 } else if (subagentx_varbind_get_object(sav) == relaydHostCheckCnt) 818 subagentx_varbind_counter64(sav, host->check_cnt); 819 else if (subagentx_varbind_get_object(sav) == relaydHostUpCnt) 820 subagentx_varbind_counter64(sav, host->up_cnt); 821 else if (subagentx_varbind_get_object(sav) == relaydHostErrno) 822 subagentx_varbind_integer(sav, host->he); 823 } 824 825 /* 826 * Every session is spawned in one of multiple processes. 827 * However, there is no central session id registration, so not every session 828 * is shown here 829 */ 830 struct rsession * 831 agentx_session_byidx(uint32_t sessidx, uint32_t relayidx, 832 enum subagentx_request_type type) 833 { 834 struct rsession *session; 835 836 TAILQ_FOREACH(session, &(env->sc_sessions), se_entry) { 837 if (session->se_id == sessidx) { 838 if (type == SUBAGENTX_REQUEST_TYPE_GET) { 839 if (relayidx != session->se_relayid) 840 return NULL; 841 return session; 842 } 843 if (type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) { 844 if (relayidx <= session->se_relayid) 845 return session; 846 return TAILQ_NEXT(session, se_entry); 847 } 848 if (relayidx < session->se_relayid) 849 return session; 850 return TAILQ_NEXT(session, se_entry); 851 } else if (session->se_id > sessidx) { 852 if (type == SUBAGENTX_REQUEST_TYPE_GET) 853 return NULL; 854 return session; 855 } 856 } 857 858 return NULL; 859 } 860 861 void 862 agentx_session(struct subagentx_varbind *sav) 863 { 864 struct timeval tv, now; 865 struct rsession *session; 866 867 session = agentx_session_byidx(subagentx_varbind_get_index_integer(sav, 868 relaydSessionIdx), subagentx_varbind_get_index_integer(sav, 869 relaydSessionRelayIdx), subagentx_varbind_request(sav)); 870 if (session == NULL) { 871 subagentx_varbind_notfound(sav); 872 return; 873 } 874 875 subagentx_varbind_set_index_integer(sav, relaydSessionIdx, 876 session->se_id); 877 subagentx_varbind_set_index_integer(sav, relaydSessionRelayIdx, 878 session->se_relayid); 879 if (subagentx_varbind_get_object(sav) == relaydSessionIndex) 880 subagentx_varbind_integer(sav, session->se_id); 881 else if (subagentx_varbind_get_object(sav) == relaydSessionRelayIndex) 882 subagentx_varbind_integer(sav, session->se_relayid); 883 else if (subagentx_varbind_get_object(sav) == relaydSessionInAddr) 884 subagentx_varbind_nstring(sav, sstodata(&(session->se_in.ss)), 885 sstolen(&(session->se_in.ss))); 886 else if (subagentx_varbind_get_object(sav) == relaydSessionInAddrType) { 887 if (session->se_in.ss.ss_family == AF_INET) 888 subagentx_varbind_integer(sav, 1); 889 else if (session->se_in.ss.ss_family == AF_INET6) 890 subagentx_varbind_integer(sav, 2); 891 } else if (subagentx_varbind_get_object(sav) == relaydSessionOutAddr) 892 subagentx_varbind_nstring(sav, sstodata(&(session->se_out.ss)), 893 sstolen(&(session->se_out.ss))); 894 else if (subagentx_varbind_get_object(sav) == relaydSessionOutAddrType) { 895 if (session->se_out.ss.ss_family == AF_INET) 896 subagentx_varbind_integer(sav, 1); 897 else if (session->se_out.ss.ss_family == AF_INET6) 898 subagentx_varbind_integer(sav, 2); 899 else 900 subagentx_varbind_integer(sav, 0); 901 } else if (subagentx_varbind_get_object(sav) == relaydSessionPortIn) 902 subagentx_varbind_integer(sav, session->se_in.port); 903 else if (subagentx_varbind_get_object(sav) == relaydSessionPortOut) 904 subagentx_varbind_integer(sav, session->se_out.port); 905 else if (subagentx_varbind_get_object(sav) == relaydSessionAge) { 906 getmonotime(&now); 907 timersub(&now, &session->se_tv_start, &tv); 908 subagentx_varbind_timeticks(sav, 909 tv.tv_sec * 100 + tv.tv_usec / 10000); 910 } else if (subagentx_varbind_get_object(sav) == relaydSessionIdle) { 911 getmonotime(&now); 912 timersub(&now, &session->se_tv_last, &tv); 913 subagentx_varbind_timeticks(sav, 914 tv.tv_sec * 100 + tv.tv_usec / 10000); 915 } else if (subagentx_varbind_get_object(sav) == relaydSessionStatus) { 916 if (session->se_done) 917 subagentx_varbind_integer(sav, 1); 918 else 919 subagentx_varbind_integer(sav, 0); 920 } else if (subagentx_varbind_get_object(sav) == relaydSessionPid) 921 subagentx_varbind_integer(sav, session->se_pid); 922 } 923 924 struct table * 925 agentx_table_byidx(uint32_t instanceidx, enum subagentx_request_type type) 926 { 927 struct table *table; 928 929 TAILQ_FOREACH(table, env->sc_tables, entry) { 930 if (table->conf.id == instanceidx) { 931 if (type == SUBAGENTX_REQUEST_TYPE_GET || 932 type == SUBAGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) 933 return table; 934 else 935 return TAILQ_NEXT(table, entry); 936 } else if (table->conf.id > instanceidx) { 937 if (type == SUBAGENTX_REQUEST_TYPE_GET) 938 return NULL; 939 return table; 940 } 941 } 942 943 return NULL; 944 } 945 946 void 947 agentx_table(struct subagentx_varbind *sav) 948 { 949 struct table *table; 950 951 table = agentx_table_byidx(subagentx_varbind_get_index_integer(sav, 952 relaydTableIdx), subagentx_varbind_request(sav)); 953 if (table == NULL) { 954 subagentx_varbind_notfound(sav); 955 return; 956 } 957 subagentx_varbind_set_index_integer(sav, relaydTableIdx, 958 table->conf.id); 959 if (subagentx_varbind_get_object(sav) == relaydTableIndex) 960 subagentx_varbind_integer(sav, table->conf.id); 961 else if (subagentx_varbind_get_object(sav) == relaydTableName) 962 subagentx_varbind_string(sav, table->conf.name); 963 else if (subagentx_varbind_get_object(sav) == relaydTableStatus) { 964 if (TAILQ_EMPTY(&table->hosts)) 965 subagentx_varbind_integer(sav, 1); 966 else if (table->conf.flags & F_DISABLE) 967 subagentx_varbind_integer(sav, 2); 968 else 969 subagentx_varbind_integer(sav, 0); 970 } 971 972 } 973 #if 0 974 975 int 976 snmp_element(const char *oidstr, enum snmp_type type, void *buf, int64_t val, 977 struct agentx_pdu *pdu) 978 { 979 u_int32_t d; 980 u_int64_t l; 981 struct snmp_oid oid; 982 983 DPRINTF("%s: oid %s type %d buf %p val %lld", __func__, 984 oidstr, type, buf, val); 985 986 if (snmp_string2oid(oidstr, &oid) == -1) 987 return -1; 988 989 switch (type) { 990 case SNMP_GAUGE32: 991 case SNMP_NSAPADDR: 992 case SNMP_INTEGER32: 993 case SNMP_UINTEGER32: 994 d = (u_int32_t)val; 995 if (snmp_agentx_varbind(pdu, &oid, AGENTX_INTEGER, 996 &d, sizeof(d)) == -1) 997 return -1; 998 break; 999 1000 case SNMP_COUNTER32: 1001 d = (u_int32_t)val; 1002 if (snmp_agentx_varbind(pdu, &oid, AGENTX_COUNTER32, 1003 &d, sizeof(d)) == -1) 1004 return -1; 1005 break; 1006 1007 case SNMP_TIMETICKS: 1008 d = (u_int32_t)val; 1009 if (snmp_agentx_varbind(pdu, &oid, AGENTX_TIME_TICKS, 1010 &d, sizeof(d)) == -1) 1011 return -1; 1012 break; 1013 1014 case SNMP_COUNTER64: 1015 l = (u_int64_t)val; 1016 if (snmp_agentx_varbind(pdu, &oid, AGENTX_COUNTER64, 1017 &l, sizeof(l)) == -1) 1018 return -1; 1019 break; 1020 1021 case SNMP_IPADDR: 1022 case SNMP_OPAQUE: 1023 d = (u_int32_t)val; 1024 if (snmp_agentx_varbind(pdu, &oid, AGENTX_OPAQUE, 1025 buf, strlen(buf)) == -1) 1026 return -1; 1027 break; 1028 1029 case SNMP_OBJECT: { 1030 struct snmp_oid oid1; 1031 1032 if (snmp_string2oid(buf, &oid1) == -1) 1033 return -1; 1034 if (snmp_agentx_varbind(pdu, &oid, AGENTX_OBJECT_IDENTIFIER, 1035 &oid1, sizeof(oid1)) == -1) 1036 return -1; 1037 } 1038 1039 case SNMP_BITSTRING: 1040 case SNMP_OCTETSTRING: 1041 if (snmp_agentx_varbind(pdu, &oid, AGENTX_OCTET_STRING, 1042 buf, strlen(buf)) == -1) 1043 return -1; 1044 break; 1045 1046 case SNMP_NULL: 1047 /* no data beyond the OID itself */ 1048 if (snmp_agentx_varbind(pdu, &oid, AGENTX_NULL, 1049 NULL, 0) == -1) 1050 return -1; 1051 } 1052 1053 return 0; 1054 } 1055 1056 /* 1057 * SNMP traps for relayd 1058 */ 1059 1060 void 1061 snmp_hosttrap(struct relayd *env, struct table *table, struct host *host) 1062 { 1063 struct agentx_pdu *pdu; 1064 1065 if (snmp_agentx == NULL || env->sc_snmp == -1) 1066 return; 1067 1068 /* 1069 * OPENBSD-RELAYD-MIB host status trap 1070 * XXX The trap format needs some tweaks and other OIDs 1071 */ 1072 1073 if ((pdu = snmp_agentx_notify_pdu(&hosttrapoid)) == NULL) 1074 return; 1075 1076 SNMP_ELEMENT(".1.0", SNMP_NULL, NULL, 0, pdu); 1077 SNMP_ELEMENT(".1.1.0", SNMP_OCTETSTRING, host->conf.name, 0, pdu); 1078 SNMP_ELEMENT(".1.2.0", SNMP_INTEGER32, NULL, host->up, pdu); 1079 SNMP_ELEMENT(".1.3.0", SNMP_INTEGER32, NULL, host->last_up, pdu); 1080 SNMP_ELEMENT(".1.4.0", SNMP_INTEGER32, NULL, host->up_cnt, pdu); 1081 SNMP_ELEMENT(".1.5.0", SNMP_INTEGER32, NULL, host->check_cnt, pdu); 1082 SNMP_ELEMENT(".1.6.0", SNMP_OCTETSTRING, table->conf.name, 0, pdu); 1083 SNMP_ELEMENT(".1.7.0", SNMP_INTEGER32, NULL, table->up, pdu); 1084 if (!host->conf.retry) 1085 goto done; 1086 SNMP_ELEMENT(".1.8.0", SNMP_INTEGER32, NULL, host->conf.retry, pdu); 1087 SNMP_ELEMENT(".1.9.0", SNMP_INTEGER32, NULL, host->retry_cnt, pdu); 1088 1089 done: 1090 snmp_agentx_send(snmp_agentx, pdu); 1091 snmp_event_add(env, EV_WRITE); 1092 } 1093 1094 int 1095 snmp_string2oid(const char *oidstr, struct snmp_oid *o) 1096 { 1097 char *sp, *p, str[BUFSIZ]; 1098 const char *errstr; 1099 1100 if (strlcpy(str, oidstr, sizeof(str)) >= sizeof(str)) 1101 return -1; 1102 bzero(o, sizeof(*o)); 1103 1104 for (p = sp = str; p != NULL; sp = p) { 1105 if ((p = strpbrk(p, ".-")) != NULL) 1106 *p++ = '\0'; 1107 o->o_id[o->o_n++] = strtonum(sp, 0, UINT_MAX, &errstr); 1108 if (errstr || o->o_n > SNMP_MAX_OID_LEN) 1109 return -1; 1110 } 1111 1112 return 0; 1113 } 1114 #endif 1115