1 /* $OpenBSD: agentx_control.c,v 1.4 2020/10/27 18:48:07 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 <agentx.h> 29 #include <limits.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <stdint.h> 33 #include <errno.h> 34 #include <string.h> 35 #include <syslog.h> 36 #include <unistd.h> 37 #include <event.h> 38 #include <imsg.h> 39 40 #include "relayd.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 AGENTX_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 agentx *, void *, int); 128 129 struct relayd *env; 130 131 struct agentx *sa = NULL; 132 struct agentx_index *relaydRedirectIdx, *relaydRelayIdx; 133 struct agentx_index *relaydRouterIdx, *relaydNetRouteIdx; 134 struct agentx_index *relaydHostIdx, *relaydSessionRelayIdx; 135 struct agentx_index *relaydSessionIdx, *relaydTableIdx; 136 137 struct agentx_object *relaydRedirectIndex, *relaydRedirectStatus; 138 struct agentx_object *relaydRedirectName, *relaydRedirectCnt; 139 struct agentx_object *relaydRedirectAvg, *relaydRedirectLast; 140 struct agentx_object *relaydRedirectAvgHour, *relaydRedirectLastHour; 141 struct agentx_object *relaydRedirectAvgDay, *relaydRedirectLastDay; 142 143 struct agentx_object *relaydRelayIndex, *relaydRelayStatus; 144 struct agentx_object *relaydRelayName, *relaydRelayCnt; 145 struct agentx_object *relaydRelayAvg, *relaydRelayLast; 146 struct agentx_object *relaydRelayAvgHour, *relaydRelayLastHour; 147 struct agentx_object *relaydRelayAvgDay, *relaydRelayLastDay; 148 149 struct agentx_object *relaydRouterIndex, *relaydRouterTableIndex; 150 struct agentx_object *relaydRouterStatus, *relaydRouterName; 151 struct agentx_object *relaydRouterLabel, *relaydRouterRtable; 152 153 struct agentx_object *relaydNetRouteIndex, *relaydNetRouteAddr; 154 struct agentx_object *relaydNetRouteAddrType, *relaydNetRoutePrefixLen; 155 struct agentx_object *relaydNetRouteRouterIndex; 156 157 struct agentx_object *relaydHostIndex, *relaydHostParentIndex; 158 struct agentx_object *relaydHostTableIndex, *relaydHostName; 159 struct agentx_object *relaydHostAddress, *relaydHostAddressType; 160 struct agentx_object *relaydHostStatus, *relaydHostCheckCnt; 161 struct agentx_object *relaydHostUpCnt, *relaydHostErrno; 162 163 struct agentx_object *relaydSessionIndex, *relaydSessionRelayIndex; 164 struct agentx_object *relaydSessionInAddr, *relaydSessionInAddrType; 165 struct agentx_object *relaydSessionOutAddr, *relaydSessionOutAddrType; 166 struct agentx_object *relaydSessionPortIn, *relaydSessionPortOut; 167 struct agentx_object *relaydSessionAge, *relaydSessionIdle; 168 struct agentx_object *relaydSessionStatus, *relaydSessionPid; 169 170 struct agentx_object *relaydTableIndex, *relaydTableName, *relaydTableStatus; 171 172 void *sstodata(struct sockaddr_storage *); 173 size_t sstolen(struct sockaddr_storage *); 174 175 struct rdr *agentxctl_rdr_byidx(uint32_t, enum agentx_request_type); 176 void agentxctl_redirect(struct agentx_varbind *); 177 struct relay *agentxctl_relay_byidx(uint32_t, enum agentx_request_type); 178 void agentxctl_relay(struct agentx_varbind *); 179 struct router *agentxctl_router_byidx(uint32_t, enum agentx_request_type); 180 void agentxctl_router(struct agentx_varbind *); 181 struct netroute *agentxctl_netroute_byidx(uint32_t, enum agentx_request_type); 182 void agentxctl_netroute(struct agentx_varbind *); 183 struct host *agentxctl_host_byidx(uint32_t, enum agentx_request_type); 184 void agentxctl_host(struct agentx_varbind *); 185 struct rsession *agentxctl_session_byidx(uint32_t, uint32_t, 186 enum agentx_request_type); 187 void agentxctl_session(struct agentx_varbind *); 188 struct table *agentxctl_table_byidx(uint32_t, enum agentx_request_type); 189 void agentxctl_table(struct agentx_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 agentx_session *sas; 202 struct agentx_context *sac; 203 struct agentx_region *sar; 204 struct agentx_index *session_idxs[2]; 205 206 agentx_log_fatal = fatalx; 207 agentx_log_warn = log_warnx; 208 agentx_log_info = log_info; 209 agentx_log_debug = log_debug; 210 211 env = nenv; 212 213 if ((env->sc_conf.flags & F_AGENTX) == 0) { 214 if (sa != NULL) 215 agentx_free(sa); 216 return; 217 } 218 if (sa != NULL) 219 return; 220 221 if ((sa = agentx(agentx_needsock, NULL)) == NULL) 222 fatal("%s: agentx alloc", __func__); 223 if ((sas = agentx_session(sa, NULL, 0, "relayd", 0)) == NULL) 224 fatal("%s: agentx session alloc", __func__); 225 if ((sac = agentx_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 = agentx_region(sac, AGENTX_OID(RELAYDINFO), 0); 230 if (sar == NULL) 231 fatal("%s: agentx region alloc", __func__); 232 if ((relaydRedirectIdx = agentx_index_integer_dynamic(sar, 233 AGENTX_OID(RELAYDREDIRECTINDEX))) == NULL || 234 (relaydRelayIdx = agentx_index_integer_dynamic(sar, 235 AGENTX_OID(RELAYDRELAYINDEX))) == NULL || 236 (relaydRouterIdx = agentx_index_integer_dynamic(sar, 237 AGENTX_OID(RELAYDROUTERINDEX))) == NULL || 238 (relaydNetRouteIdx = agentx_index_integer_dynamic(sar, 239 AGENTX_OID(RELAYDNETROUTEINDEX))) == NULL || 240 (relaydHostIdx = agentx_index_integer_dynamic(sar, 241 AGENTX_OID(RELAYDHOSTINDEX))) == NULL || 242 (relaydSessionIdx = agentx_index_integer_dynamic(sar, 243 AGENTX_OID(RELAYDSESSIONINDEX))) == NULL || 244 (relaydSessionRelayIdx = agentx_index_integer_dynamic(sar, 245 AGENTX_OID(RELAYDSESSIONRELAYINDEX))) == NULL || 246 (relaydTableIdx = agentx_index_integer_dynamic(sar, 247 AGENTX_OID(RELAYDTABLEINDEX))) == NULL) 248 fatal("%s: agentx index alloc", __func__); 249 session_idxs[0] = relaydSessionRelayIdx; 250 session_idxs[1] = relaydSessionIdx; 251 if ((relaydRedirectIndex = agentx_object(sar, 252 AGENTX_OID(RELAYDREDIRECTINDEX), &relaydRedirectIdx, 1, 0, 253 agentxctl_redirect)) == NULL || 254 (relaydRedirectStatus = agentx_object(sar, 255 AGENTX_OID(RELAYDREDIRECTSTATUS), &relaydRedirectIdx, 1, 0, 256 agentxctl_redirect)) == NULL || 257 (relaydRedirectName = agentx_object(sar, 258 AGENTX_OID(RELAYDREDIRECTNAME), &relaydRedirectIdx, 1, 0, 259 agentxctl_redirect)) == NULL || 260 (relaydRedirectCnt = agentx_object(sar, 261 AGENTX_OID(RELAYDREDIRECTCNT), &relaydRedirectIdx, 1, 0, 262 agentxctl_redirect)) == NULL || 263 (relaydRedirectAvg = agentx_object(sar, 264 AGENTX_OID(RELAYDREDIRECTAVG), &relaydRedirectIdx, 1, 0, 265 agentxctl_redirect)) == NULL || 266 (relaydRedirectLast = agentx_object(sar, 267 AGENTX_OID(RELAYDREDIRECTLAST), &relaydRedirectIdx, 1, 0, 268 agentxctl_redirect)) == NULL || 269 (relaydRedirectAvgHour = agentx_object(sar, 270 AGENTX_OID(RELAYDREDIRECTAVGHOUR), &relaydRedirectIdx, 1, 0, 271 agentxctl_redirect)) == NULL || 272 (relaydRedirectLastHour = agentx_object(sar, 273 AGENTX_OID(RELAYDREDIRECTLASTHOUR), &relaydRedirectIdx, 1, 0, 274 agentxctl_redirect)) == NULL || 275 (relaydRedirectAvgDay = agentx_object(sar, 276 AGENTX_OID(RELAYDREDIRECTAVGDAY), &relaydRedirectIdx, 1, 0, 277 agentxctl_redirect)) == NULL || 278 (relaydRedirectLastDay = agentx_object(sar, 279 AGENTX_OID(RELAYDREDIRECTLASTDAY), &relaydRedirectIdx, 1, 0, 280 agentxctl_redirect)) == NULL || 281 (relaydRelayIndex = agentx_object(sar, 282 AGENTX_OID(RELAYDRELAYINDEX), &relaydRelayIdx, 1, 0, 283 agentxctl_relay)) == NULL || 284 (relaydRelayStatus = agentx_object(sar, 285 AGENTX_OID(RELAYDRELAYSTATUS), &relaydRelayIdx, 1, 0, 286 agentxctl_relay)) == NULL || 287 (relaydRelayName = agentx_object(sar, 288 AGENTX_OID(RELAYDRELAYNAME), &relaydRelayIdx, 1, 0, 289 agentxctl_relay)) == NULL || 290 (relaydRelayCnt = agentx_object(sar, 291 AGENTX_OID(RELAYDRELAYCNT), &relaydRelayIdx, 1, 0, 292 agentxctl_relay)) == NULL || 293 (relaydRelayAvg = agentx_object(sar, 294 AGENTX_OID(RELAYDRELAYAVG), &relaydRelayIdx, 1, 0, 295 agentxctl_relay)) == NULL || 296 (relaydRelayLast = agentx_object(sar, 297 AGENTX_OID(RELAYDRELAYLAST), &relaydRelayIdx, 1, 0, 298 agentxctl_relay)) == NULL || 299 (relaydRelayAvgHour = agentx_object(sar, 300 AGENTX_OID(RELAYDRELAYAVGHOUR), &relaydRelayIdx, 1, 0, 301 agentxctl_relay)) == NULL || 302 (relaydRelayLastHour = agentx_object(sar, 303 AGENTX_OID(RELAYDRELAYLASTHOUR), &relaydRelayIdx, 1, 0, 304 agentxctl_relay)) == NULL || 305 (relaydRelayAvgDay = agentx_object(sar, 306 AGENTX_OID(RELAYDRELAYAVGDAY), &relaydRelayIdx, 1, 0, 307 agentxctl_relay)) == NULL || 308 (relaydRelayLastDay = agentx_object(sar, 309 AGENTX_OID(RELAYDRELAYLASTDAY), &relaydRelayIdx, 1, 0, 310 agentxctl_relay)) == NULL || 311 (relaydRouterIndex = agentx_object(sar, 312 AGENTX_OID(RELAYDROUTERINDEX), &relaydRouterIdx, 1, 0, 313 agentxctl_router)) == NULL || 314 (relaydRouterTableIndex = agentx_object(sar, 315 AGENTX_OID(RELAYDROUTERTABLEINDEX), &relaydRouterIdx, 1, 0, 316 agentxctl_router)) == NULL || 317 (relaydRouterStatus = agentx_object(sar, 318 AGENTX_OID(RELAYDROUTERSTATUS), &relaydRouterIdx, 1, 0, 319 agentxctl_router)) == NULL || 320 (relaydRouterName = agentx_object(sar, 321 AGENTX_OID(RELAYDROUTERNAME), &relaydRouterIdx, 1, 0, 322 agentxctl_router)) == NULL || 323 (relaydRouterLabel = agentx_object(sar, 324 AGENTX_OID(RELAYDROUTERLABEL), &relaydRouterIdx, 1, 0, 325 agentxctl_router)) == NULL || 326 (relaydRouterRtable = agentx_object(sar, 327 AGENTX_OID(RELAYDROUTERRTABLE), &relaydRouterIdx, 1, 0, 328 agentxctl_router)) == NULL || 329 (relaydNetRouteIndex = agentx_object(sar, 330 AGENTX_OID(RELAYDNETROUTEINDEX), &relaydNetRouteIdx, 1, 0, 331 agentxctl_netroute)) == NULL || 332 (relaydNetRouteAddr = agentx_object(sar, 333 AGENTX_OID(RELAYDNETROUTEADDR), &relaydNetRouteIdx, 1, 0, 334 agentxctl_netroute)) == NULL || 335 (relaydNetRouteAddrType = agentx_object(sar, 336 AGENTX_OID(RELAYDNETROUTEADDRTYPE), &relaydNetRouteIdx, 1, 0, 337 agentxctl_netroute)) == NULL || 338 (relaydNetRoutePrefixLen = agentx_object(sar, 339 AGENTX_OID(RELAYDNETROUTEPREFIXLEN), &relaydNetRouteIdx, 1, 0, 340 agentxctl_netroute)) == NULL || 341 (relaydNetRouteRouterIndex = agentx_object(sar, 342 AGENTX_OID(RELAYDNETROUTEROUTERINDEX), &relaydNetRouteIdx, 1, 0, 343 agentxctl_netroute)) == NULL || 344 (relaydHostIndex = agentx_object(sar, 345 AGENTX_OID(RELAYDHOSTINDEX), &relaydHostIdx, 1, 0, 346 agentxctl_host)) == NULL || 347 (relaydHostParentIndex = agentx_object(sar, 348 AGENTX_OID(RELAYDHOSTPARENTINDEX), &relaydHostIdx, 1, 0, 349 agentxctl_host)) == NULL || 350 (relaydHostTableIndex = agentx_object(sar, 351 AGENTX_OID(RELAYDHOSTTABLEINDEX), &relaydHostIdx, 1, 0, 352 agentxctl_host)) == NULL || 353 (relaydHostName = agentx_object(sar, 354 AGENTX_OID(RELAYDHOSTNAME), &relaydHostIdx, 1, 0, 355 agentxctl_host)) == NULL || 356 (relaydHostAddress = agentx_object(sar, 357 AGENTX_OID(RELAYDHOSTADDRESS), &relaydHostIdx, 1, 0, 358 agentxctl_host)) == NULL || 359 (relaydHostAddressType = agentx_object(sar, 360 AGENTX_OID(RELAYDHOSTADDRESSTYPE), &relaydHostIdx, 1, 0, 361 agentxctl_host)) == NULL || 362 (relaydHostStatus = agentx_object(sar, 363 AGENTX_OID(RELAYDHOSTSTATUS), &relaydHostIdx, 1, 0, 364 agentxctl_host)) == NULL || 365 (relaydHostCheckCnt = agentx_object(sar, 366 AGENTX_OID(RELAYDHOSTCHECKCNT), &relaydHostIdx, 1, 0, 367 agentxctl_host)) == NULL || 368 (relaydHostUpCnt = agentx_object(sar, 369 AGENTX_OID(RELAYDHOSTUPCNT), &relaydHostIdx, 1, 0, 370 agentxctl_host)) == NULL || 371 (relaydHostErrno = agentx_object(sar, 372 AGENTX_OID(RELAYDHOSTERRNO), &relaydHostIdx, 1, 0, 373 agentxctl_host)) == NULL || 374 (relaydSessionIndex = agentx_object(sar, 375 AGENTX_OID(RELAYDSESSIONINDEX), session_idxs, 2, 0, 376 agentxctl_session)) == NULL || 377 (relaydSessionRelayIndex = agentx_object(sar, 378 AGENTX_OID(RELAYDSESSIONRELAYINDEX), session_idxs, 2, 0, 379 agentxctl_session)) == NULL || 380 (relaydSessionInAddr = agentx_object(sar, 381 AGENTX_OID(RELAYDSESSIONINADDR), session_idxs, 2, 0, 382 agentxctl_session)) == NULL || 383 (relaydSessionInAddrType = agentx_object(sar, 384 AGENTX_OID(RELAYDSESSIONINADDRTYPE), session_idxs, 2, 0, 385 agentxctl_session)) == NULL || 386 (relaydSessionOutAddr = agentx_object(sar, 387 AGENTX_OID(RELAYDSESSIONOUTADDR), session_idxs, 2, 0, 388 agentxctl_session)) == NULL || 389 (relaydSessionOutAddrType = agentx_object(sar, 390 AGENTX_OID(RELAYDSESSIONOUTADDRTYPE), session_idxs, 2, 0, 391 agentxctl_session)) == NULL || 392 (relaydSessionPortIn = agentx_object(sar, 393 AGENTX_OID(RELAYDSESSIONPORTIN), session_idxs, 2, 0, 394 agentxctl_session)) == NULL || 395 (relaydSessionPortOut = agentx_object(sar, 396 AGENTX_OID(RELAYDSESSIONPORTOUT), session_idxs, 2, 0, 397 agentxctl_session)) == NULL || 398 (relaydSessionAge = agentx_object(sar, 399 AGENTX_OID(RELAYDSESSIONAGE), session_idxs, 2, 0, 400 agentxctl_session)) == NULL || 401 (relaydSessionIdle = agentx_object(sar, 402 AGENTX_OID(RELAYDSESSIONIDLE), session_idxs, 2, 0, 403 agentxctl_session)) == NULL || 404 (relaydSessionStatus = agentx_object(sar, 405 AGENTX_OID(RELAYDSESSIONSTATUS), session_idxs, 2, 0, 406 agentxctl_session)) == NULL || 407 (relaydSessionPid = agentx_object(sar, 408 AGENTX_OID(RELAYDSESSIONPID), session_idxs, 2, 0, 409 agentxctl_session)) == NULL || 410 (relaydTableIndex = agentx_object(sar, 411 AGENTX_OID(RELAYDTABLEINDEX), &relaydTableIdx, 1, 0, 412 agentxctl_table)) == NULL || 413 (relaydTableName = agentx_object(sar, 414 AGENTX_OID(RELAYDTABLENAME), &relaydTableIdx, 1, 0, 415 agentxctl_table)) == NULL || 416 (relaydTableStatus = agentx_object(sar, 417 AGENTX_OID(RELAYDTABLESTATUS), &relaydTableIdx, 1, 0, 418 agentxctl_table)) == NULL) 419 fatal("%s: agentx object alloc", __func__); 420 } 421 422 void 423 agentx_needsock(struct agentx *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 agentx_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 agentx_write(sa); 486 } 487 if (event & EV_READ) 488 agentx_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 agentxctl_rdr_byidx(uint32_t instanceidx, enum agentx_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 == AGENTX_REQUEST_TYPE_GET || 520 type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) 521 return rdr; 522 else 523 return TAILQ_NEXT(rdr, entry); 524 } else if (rdr->conf.id > instanceidx) { 525 if (type == AGENTX_REQUEST_TYPE_GET) 526 return NULL; 527 return rdr; 528 } 529 } 530 531 return NULL; 532 } 533 534 535 void 536 agentxctl_redirect(struct agentx_varbind *sav) 537 { 538 struct rdr *rdr; 539 540 rdr = agentxctl_rdr_byidx(agentx_varbind_get_index_integer(sav, 541 relaydRedirectIdx), agentx_varbind_request(sav)); 542 if (rdr == NULL || rdr->conf.id > INT32_MAX) { 543 agentx_varbind_notfound(sav); 544 return; 545 } 546 agentx_varbind_set_index_integer(sav, relaydRedirectIdx, 547 rdr->conf.id); 548 if (agentx_varbind_get_object(sav) == relaydRedirectIndex) 549 agentx_varbind_integer(sav, rdr->conf.id); 550 else if (agentx_varbind_get_object(sav) == relaydRedirectStatus) { 551 if (rdr->conf.flags & F_DISABLE) 552 agentx_varbind_integer(sav, 1); 553 else if (rdr->conf.flags & F_DOWN) 554 agentx_varbind_integer(sav, 2); 555 else if (rdr->conf.flags & F_BACKUP) 556 agentx_varbind_integer(sav, 3); 557 else 558 agentx_varbind_integer(sav, 0); 559 } else if (agentx_varbind_get_object(sav) == relaydRedirectName) 560 agentx_varbind_string(sav, rdr->conf.name); 561 else if (agentx_varbind_get_object(sav) == relaydRedirectCnt) 562 agentx_varbind_counter64(sav, rdr->stats.cnt); 563 else if (agentx_varbind_get_object(sav) == relaydRedirectAvg) 564 agentx_varbind_gauge32(sav, rdr->stats.avg); 565 else if (agentx_varbind_get_object(sav) == relaydRedirectLast) 566 agentx_varbind_gauge32(sav, rdr->stats.last); 567 else if (agentx_varbind_get_object(sav) == relaydRedirectAvgHour) 568 agentx_varbind_gauge32(sav, rdr->stats.avg_hour); 569 else if (agentx_varbind_get_object(sav) == relaydRedirectLastHour) 570 agentx_varbind_gauge32(sav, rdr->stats.last_hour); 571 else if (agentx_varbind_get_object(sav) == relaydRedirectAvgDay) 572 agentx_varbind_gauge32(sav, rdr->stats.avg_day); 573 else if (agentx_varbind_get_object(sav) == relaydRedirectLastDay) 574 agentx_varbind_gauge32(sav, rdr->stats.last_day); 575 } 576 577 struct relay * 578 agentxctl_relay_byidx(uint32_t instanceidx, enum agentx_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 == AGENTX_REQUEST_TYPE_GET || 585 type == AGENTX_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 == AGENTX_REQUEST_TYPE_GET) 591 return NULL; 592 return rly; 593 } 594 } 595 596 return NULL; 597 } 598 599 void 600 agentxctl_relay(struct agentx_varbind *sav) 601 { 602 struct relay *rly; 603 uint64_t value = 0; 604 int i, nrelay = env->sc_conf.prefork_relay; 605 606 rly = agentxctl_relay_byidx(agentx_varbind_get_index_integer(sav, 607 relaydRelayIdx), agentx_varbind_request(sav)); 608 if (rly == NULL || rly->rl_conf.id > INT32_MAX) { 609 agentx_varbind_notfound(sav); 610 return; 611 } 612 agentx_varbind_set_index_integer(sav, relaydRelayIdx, 613 rly->rl_conf.id); 614 if (agentx_varbind_get_object(sav) == relaydRelayIndex) 615 agentx_varbind_integer(sav, rly->rl_conf.id); 616 else if (agentx_varbind_get_object(sav) == relaydRelayStatus) { 617 if (rly->rl_up == HOST_UP) 618 agentx_varbind_integer(sav, 1); 619 else 620 agentx_varbind_integer(sav, 0); 621 } else if (agentx_varbind_get_object(sav) == relaydRelayName) 622 agentx_varbind_string(sav, rly->rl_conf.name); 623 else if (agentx_varbind_get_object(sav) == relaydRelayCnt) { 624 for (i = 0; i < nrelay; i++) 625 value += rly->rl_stats[i].cnt; 626 agentx_varbind_counter64(sav, value); 627 } else if (agentx_varbind_get_object(sav) == relaydRelayAvg) { 628 for (i = 0; i < nrelay; i++) 629 value += rly->rl_stats[i].avg; 630 agentx_varbind_gauge32(sav, (uint32_t)value); 631 } else if (agentx_varbind_get_object(sav) == relaydRelayLast) { 632 for (i = 0; i < nrelay; i++) 633 value += rly->rl_stats[i].last; 634 agentx_varbind_gauge32(sav, (uint32_t)value); 635 } else if (agentx_varbind_get_object(sav) == relaydRelayAvgHour) { 636 for (i = 0; i < nrelay; i++) 637 value += rly->rl_stats[i].avg_hour; 638 agentx_varbind_gauge32(sav, (uint32_t)value); 639 } else if (agentx_varbind_get_object(sav) == relaydRelayLastHour) { 640 for (i = 0; i < nrelay; i++) 641 value += rly->rl_stats[i].last_hour; 642 agentx_varbind_gauge32(sav, (uint32_t)value); 643 } else if (agentx_varbind_get_object(sav) == relaydRelayAvgDay) { 644 for (i = 0; i < nrelay; i++) 645 value += rly->rl_stats[i].avg_day; 646 agentx_varbind_gauge32(sav, (uint32_t)value); 647 } else if (agentx_varbind_get_object(sav) == relaydRelayLastDay) { 648 for (i = 0; i < nrelay; i++) 649 value += rly->rl_stats[i].last_day; 650 agentx_varbind_gauge32(sav, (uint32_t)value); 651 } 652 } 653 654 struct router * 655 agentxctl_router_byidx(uint32_t instanceidx, enum agentx_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 == AGENTX_REQUEST_TYPE_GET || 662 type == AGENTX_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 == AGENTX_REQUEST_TYPE_GET) 668 return NULL; 669 return router; 670 } 671 } 672 673 return NULL; 674 } 675 676 void 677 agentxctl_router(struct agentx_varbind *sav) 678 { 679 struct router *router; 680 681 router = agentxctl_router_byidx(agentx_varbind_get_index_integer(sav, 682 relaydRouterIdx), agentx_varbind_request(sav)); 683 if (router == NULL || router->rt_conf.id > INT32_MAX) { 684 agentx_varbind_notfound(sav); 685 return; 686 } 687 agentx_varbind_set_index_integer(sav, relaydRouterIdx, 688 router->rt_conf.id); 689 if (agentx_varbind_get_object(sav) == relaydRouterIndex) 690 agentx_varbind_integer(sav, router->rt_conf.id); 691 else if (agentx_varbind_get_object(sav) == relaydRouterTableIndex) { 692 if (router->rt_conf.gwtable > INT32_MAX) 693 agentx_varbind_integer(sav, -1); 694 else 695 agentx_varbind_integer(sav, router->rt_conf.gwtable); 696 } else if (agentx_varbind_get_object(sav) == relaydRouterStatus) { 697 if (router->rt_conf.flags & F_DISABLE) 698 agentx_varbind_integer(sav, 1); 699 else 700 agentx_varbind_integer(sav, 0); 701 } else if (agentx_varbind_get_object(sav) == relaydRouterName) 702 agentx_varbind_string(sav, router->rt_conf.name); 703 else if (agentx_varbind_get_object(sav) == relaydRouterLabel) 704 agentx_varbind_string(sav, router->rt_conf.label); 705 else if (agentx_varbind_get_object(sav) == relaydRouterRtable) 706 agentx_varbind_integer(sav, router->rt_conf.rtable); 707 } 708 709 struct netroute * 710 agentxctl_netroute_byidx(uint32_t instanceidx, enum agentx_request_type type) 711 { 712 struct netroute *nr; 713 714 TAILQ_FOREACH(nr, env->sc_routes, nr_route) { 715 if (nr->nr_conf.id == instanceidx) { 716 if (type == AGENTX_REQUEST_TYPE_GET || 717 type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) 718 return nr; 719 else 720 return TAILQ_NEXT(nr, nr_entry); 721 } else if (nr->nr_conf.id > instanceidx) { 722 if (type == AGENTX_REQUEST_TYPE_GET) 723 return NULL; 724 return nr; 725 } 726 } 727 728 return NULL; 729 } 730 731 void 732 agentxctl_netroute(struct agentx_varbind *sav) 733 { 734 struct netroute *nr; 735 736 nr = agentxctl_netroute_byidx(agentx_varbind_get_index_integer(sav, 737 relaydNetRouteIdx), agentx_varbind_request(sav)); 738 if (nr == NULL || nr->nr_conf.id > INT32_MAX) { 739 agentx_varbind_notfound(sav); 740 return; 741 } 742 agentx_varbind_set_index_integer(sav, relaydNetRouteIdx, 743 nr->nr_conf.id); 744 if (agentx_varbind_get_object(sav) == relaydNetRouteIndex) 745 agentx_varbind_integer(sav, nr->nr_conf.id); 746 else if (agentx_varbind_get_object(sav) == relaydNetRouteAddr) 747 agentx_varbind_nstring(sav, sstodata(&nr->nr_conf.ss), 748 sstolen(&nr->nr_conf.ss)); 749 else if (agentx_varbind_get_object(sav) == relaydNetRouteAddrType) { 750 if (nr->nr_conf.ss.ss_family == AF_INET) 751 agentx_varbind_integer(sav, 1); 752 else if (nr->nr_conf.ss.ss_family == AF_INET6) 753 agentx_varbind_integer(sav, 2); 754 } else if (agentx_varbind_get_object(sav) == relaydNetRoutePrefixLen) 755 agentx_varbind_integer(sav, nr->nr_conf.prefixlen); 756 else if (agentx_varbind_get_object(sav) == relaydNetRouteRouterIndex) { 757 if (nr->nr_conf.routerid > INT32_MAX) 758 agentx_varbind_integer(sav, -1); 759 else 760 agentx_varbind_integer(sav, nr->nr_conf.routerid); 761 } 762 } 763 764 struct host * 765 agentxctl_host_byidx(uint32_t instanceidx, enum agentx_request_type type) 766 { 767 struct host *host; 768 769 TAILQ_FOREACH(host, &(env->sc_hosts), globalentry) { 770 if (host->conf.id == instanceidx) { 771 if (type == AGENTX_REQUEST_TYPE_GET || 772 type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) 773 return host; 774 else 775 return TAILQ_NEXT(host, globalentry); 776 } else if (host->conf.id > instanceidx) { 777 if (type == AGENTX_REQUEST_TYPE_GET) 778 return NULL; 779 return host; 780 } 781 } 782 783 return NULL; 784 } 785 786 void 787 agentxctl_host(struct agentx_varbind *sav) 788 { 789 struct host *host; 790 791 host = agentxctl_host_byidx(agentx_varbind_get_index_integer(sav, 792 relaydHostIdx), agentx_varbind_request(sav)); 793 if (host == NULL || host->conf.id > INT32_MAX) { 794 agentx_varbind_notfound(sav); 795 return; 796 } 797 agentx_varbind_set_index_integer(sav, relaydHostIdx, 798 host->conf.id); 799 if (agentx_varbind_get_object(sav) == relaydHostIndex) 800 agentx_varbind_integer(sav, host->conf.id); 801 else if (agentx_varbind_get_object(sav) == relaydHostParentIndex) { 802 if (host->conf.parentid > INT32_MAX) 803 agentx_varbind_integer(sav, -1); 804 else 805 agentx_varbind_integer(sav, host->conf.parentid); 806 } else if (agentx_varbind_get_object(sav) == relaydHostTableIndex) { 807 if (host->conf.tableid > INT32_MAX) 808 agentx_varbind_integer(sav, -1); 809 else 810 agentx_varbind_integer(sav, host->conf.tableid); 811 } else if (agentx_varbind_get_object(sav) == relaydHostName) 812 agentx_varbind_string(sav, host->conf.name); 813 else if (agentx_varbind_get_object(sav) == relaydHostAddress) 814 agentx_varbind_nstring(sav, sstodata(&host->conf.ss), 815 sstolen(&host->conf.ss)); 816 else if (agentx_varbind_get_object(sav) == relaydHostAddressType) { 817 if (host->conf.ss.ss_family == AF_INET) 818 agentx_varbind_integer(sav, 1); 819 else if (host->conf.ss.ss_family == AF_INET6) 820 agentx_varbind_integer(sav, 2); 821 } else if (agentx_varbind_get_object(sav) == relaydHostStatus) { 822 if (host->flags & F_DISABLE) 823 agentx_varbind_integer(sav, 1); 824 else if (host->up == HOST_UP) 825 agentx_varbind_integer(sav, 0); 826 else if (host->up == HOST_DOWN) 827 agentx_varbind_integer(sav, 2); 828 else 829 agentx_varbind_integer(sav, 3); 830 } else if (agentx_varbind_get_object(sav) == relaydHostCheckCnt) 831 agentx_varbind_counter64(sav, host->check_cnt); 832 else if (agentx_varbind_get_object(sav) == relaydHostUpCnt) 833 agentx_varbind_counter64(sav, host->up_cnt); 834 else if (agentx_varbind_get_object(sav) == relaydHostErrno) 835 agentx_varbind_integer(sav, host->he); 836 } 837 838 /* 839 * Every session is spawned in one of multiple processes. 840 * However, there is no central session id registration, so not every session 841 * is shown here 842 */ 843 struct rsession * 844 agentxctl_session_byidx(uint32_t sessidx, uint32_t relayidx, 845 enum agentx_request_type type) 846 { 847 struct rsession *session; 848 849 TAILQ_FOREACH(session, &(env->sc_sessions), se_entry) { 850 if (session->se_id == sessidx) { 851 if (type == AGENTX_REQUEST_TYPE_GET) { 852 if (relayidx != session->se_relayid) 853 return NULL; 854 return session; 855 } 856 if (type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) { 857 if (relayidx <= session->se_relayid) 858 return session; 859 return TAILQ_NEXT(session, se_entry); 860 } 861 if (relayidx < session->se_relayid) 862 return session; 863 return TAILQ_NEXT(session, se_entry); 864 } else if (session->se_id > sessidx) { 865 if (type == AGENTX_REQUEST_TYPE_GET) 866 return NULL; 867 return session; 868 } 869 } 870 871 return NULL; 872 } 873 874 void 875 agentxctl_session(struct agentx_varbind *sav) 876 { 877 struct timeval tv, now; 878 struct rsession *session; 879 880 session = agentxctl_session_byidx(agentx_varbind_get_index_integer(sav, 881 relaydSessionIdx), agentx_varbind_get_index_integer(sav, 882 relaydSessionRelayIdx), agentx_varbind_request(sav)); 883 if (session == NULL || session->se_id > INT32_MAX || 884 session->se_relayid > INT32_MAX) { 885 agentx_varbind_notfound(sav); 886 return; 887 } 888 889 agentx_varbind_set_index_integer(sav, relaydSessionIdx, 890 session->se_id); 891 agentx_varbind_set_index_integer(sav, relaydSessionRelayIdx, 892 session->se_relayid); 893 if (agentx_varbind_get_object(sav) == relaydSessionIndex) 894 agentx_varbind_integer(sav, session->se_id); 895 else if (agentx_varbind_get_object(sav) == relaydSessionRelayIndex) 896 agentx_varbind_integer(sav, session->se_relayid); 897 else if (agentx_varbind_get_object(sav) == relaydSessionInAddr) 898 agentx_varbind_nstring(sav, sstodata(&(session->se_in.ss)), 899 sstolen(&(session->se_in.ss))); 900 else if (agentx_varbind_get_object(sav) == relaydSessionInAddrType) { 901 if (session->se_in.ss.ss_family == AF_INET) 902 agentx_varbind_integer(sav, 1); 903 else if (session->se_in.ss.ss_family == AF_INET6) 904 agentx_varbind_integer(sav, 2); 905 } else if (agentx_varbind_get_object(sav) == relaydSessionOutAddr) 906 agentx_varbind_nstring(sav, sstodata(&(session->se_out.ss)), 907 sstolen(&(session->se_out.ss))); 908 else if (agentx_varbind_get_object(sav) == relaydSessionOutAddrType) { 909 if (session->se_out.ss.ss_family == AF_INET) 910 agentx_varbind_integer(sav, 1); 911 else if (session->se_out.ss.ss_family == AF_INET6) 912 agentx_varbind_integer(sav, 2); 913 else 914 agentx_varbind_integer(sav, 0); 915 } else if (agentx_varbind_get_object(sav) == relaydSessionPortIn) 916 agentx_varbind_integer(sav, session->se_in.port); 917 else if (agentx_varbind_get_object(sav) == relaydSessionPortOut) 918 agentx_varbind_integer(sav, session->se_out.port); 919 else if (agentx_varbind_get_object(sav) == relaydSessionAge) { 920 getmonotime(&now); 921 timersub(&now, &session->se_tv_start, &tv); 922 agentx_varbind_timeticks(sav, 923 tv.tv_sec * 100 + tv.tv_usec / 10000); 924 } else if (agentx_varbind_get_object(sav) == relaydSessionIdle) { 925 getmonotime(&now); 926 timersub(&now, &session->se_tv_last, &tv); 927 agentx_varbind_timeticks(sav, 928 tv.tv_sec * 100 + tv.tv_usec / 10000); 929 } else if (agentx_varbind_get_object(sav) == relaydSessionStatus) { 930 if (session->se_done) 931 agentx_varbind_integer(sav, 1); 932 else 933 agentx_varbind_integer(sav, 0); 934 } else if (agentx_varbind_get_object(sav) == relaydSessionPid) 935 agentx_varbind_integer(sav, session->se_pid); 936 } 937 938 struct table * 939 agentxctl_table_byidx(uint32_t instanceidx, enum agentx_request_type type) 940 { 941 struct table *table; 942 943 TAILQ_FOREACH(table, env->sc_tables, entry) { 944 if (table->conf.id == instanceidx) { 945 if (type == AGENTX_REQUEST_TYPE_GET || 946 type == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) 947 return table; 948 else 949 return TAILQ_NEXT(table, entry); 950 } else if (table->conf.id > instanceidx) { 951 if (type == AGENTX_REQUEST_TYPE_GET) 952 return NULL; 953 return table; 954 } 955 } 956 957 return NULL; 958 } 959 960 void 961 agentxctl_table(struct agentx_varbind *sav) 962 { 963 struct table *table; 964 965 table = agentxctl_table_byidx(agentx_varbind_get_index_integer(sav, 966 relaydTableIdx), agentx_varbind_request(sav)); 967 if (table == NULL || table->conf.id > INT32_MAX) { 968 agentx_varbind_notfound(sav); 969 return; 970 } 971 agentx_varbind_set_index_integer(sav, relaydTableIdx, 972 table->conf.id); 973 if (agentx_varbind_get_object(sav) == relaydTableIndex) 974 agentx_varbind_integer(sav, table->conf.id); 975 else if (agentx_varbind_get_object(sav) == relaydTableName) 976 agentx_varbind_string(sav, table->conf.name); 977 else if (agentx_varbind_get_object(sav) == relaydTableStatus) { 978 if (TAILQ_EMPTY(&table->hosts)) 979 agentx_varbind_integer(sav, 1); 980 else if (table->conf.flags & F_DISABLE) 981 agentx_varbind_integer(sav, 2); 982 else 983 agentx_varbind_integer(sav, 0); 984 } 985 986 } 987 #if 0 988 989 int 990 snmp_element(const char *oidstr, enum snmp_type type, void *buf, int64_t val, 991 struct agentx_pdu *pdu) 992 { 993 u_int32_t d; 994 u_int64_t l; 995 struct snmp_oid oid; 996 997 DPRINTF("%s: oid %s type %d buf %p val %lld", __func__, 998 oidstr, type, buf, val); 999 1000 if (snmp_string2oid(oidstr, &oid) == -1) 1001 return -1; 1002 1003 switch (type) { 1004 case SNMP_GAUGE32: 1005 case SNMP_NSAPADDR: 1006 case SNMP_INTEGER32: 1007 case SNMP_UINTEGER32: 1008 d = (u_int32_t)val; 1009 if (snmp_agentx_varbind(pdu, &oid, AGENTX_INTEGER, 1010 &d, sizeof(d)) == -1) 1011 return -1; 1012 break; 1013 1014 case SNMP_COUNTER32: 1015 d = (u_int32_t)val; 1016 if (snmp_agentx_varbind(pdu, &oid, AGENTX_COUNTER32, 1017 &d, sizeof(d)) == -1) 1018 return -1; 1019 break; 1020 1021 case SNMP_TIMETICKS: 1022 d = (u_int32_t)val; 1023 if (snmp_agentx_varbind(pdu, &oid, AGENTX_TIME_TICKS, 1024 &d, sizeof(d)) == -1) 1025 return -1; 1026 break; 1027 1028 case SNMP_COUNTER64: 1029 l = (u_int64_t)val; 1030 if (snmp_agentx_varbind(pdu, &oid, AGENTX_COUNTER64, 1031 &l, sizeof(l)) == -1) 1032 return -1; 1033 break; 1034 1035 case SNMP_IPADDR: 1036 case SNMP_OPAQUE: 1037 d = (u_int32_t)val; 1038 if (snmp_agentx_varbind(pdu, &oid, AGENTX_OPAQUE, 1039 buf, strlen(buf)) == -1) 1040 return -1; 1041 break; 1042 1043 case SNMP_OBJECT: { 1044 struct snmp_oid oid1; 1045 1046 if (snmp_string2oid(buf, &oid1) == -1) 1047 return -1; 1048 if (snmp_agentx_varbind(pdu, &oid, AGENTX_OBJECT_IDENTIFIER, 1049 &oid1, sizeof(oid1)) == -1) 1050 return -1; 1051 } 1052 1053 case SNMP_BITSTRING: 1054 case SNMP_OCTETSTRING: 1055 if (snmp_agentx_varbind(pdu, &oid, AGENTX_OCTET_STRING, 1056 buf, strlen(buf)) == -1) 1057 return -1; 1058 break; 1059 1060 case SNMP_NULL: 1061 /* no data beyond the OID itself */ 1062 if (snmp_agentx_varbind(pdu, &oid, AGENTX_NULL, 1063 NULL, 0) == -1) 1064 return -1; 1065 } 1066 1067 return 0; 1068 } 1069 1070 /* 1071 * SNMP traps for relayd 1072 */ 1073 1074 void 1075 snmp_hosttrap(struct relayd *env, struct table *table, struct host *host) 1076 { 1077 struct agentx_pdu *pdu; 1078 1079 if (snmp_agentx == NULL || env->sc_snmp == -1) 1080 return; 1081 1082 /* 1083 * OPENBSD-RELAYD-MIB host status trap 1084 * XXX The trap format needs some tweaks and other OIDs 1085 */ 1086 1087 if ((pdu = snmp_agentx_notify_pdu(&hosttrapoid)) == NULL) 1088 return; 1089 1090 SNMP_ELEMENT(".1.0", SNMP_NULL, NULL, 0, pdu); 1091 SNMP_ELEMENT(".1.1.0", SNMP_OCTETSTRING, host->conf.name, 0, pdu); 1092 SNMP_ELEMENT(".1.2.0", SNMP_INTEGER32, NULL, host->up, pdu); 1093 SNMP_ELEMENT(".1.3.0", SNMP_INTEGER32, NULL, host->last_up, pdu); 1094 SNMP_ELEMENT(".1.4.0", SNMP_INTEGER32, NULL, host->up_cnt, pdu); 1095 SNMP_ELEMENT(".1.5.0", SNMP_INTEGER32, NULL, host->check_cnt, pdu); 1096 SNMP_ELEMENT(".1.6.0", SNMP_OCTETSTRING, table->conf.name, 0, pdu); 1097 SNMP_ELEMENT(".1.7.0", SNMP_INTEGER32, NULL, table->up, pdu); 1098 if (!host->conf.retry) 1099 goto done; 1100 SNMP_ELEMENT(".1.8.0", SNMP_INTEGER32, NULL, host->conf.retry, pdu); 1101 SNMP_ELEMENT(".1.9.0", SNMP_INTEGER32, NULL, host->retry_cnt, pdu); 1102 1103 done: 1104 snmp_agentx_send(snmp_agentx, pdu); 1105 snmp_event_add(env, EV_WRITE); 1106 } 1107 1108 int 1109 snmp_string2oid(const char *oidstr, struct snmp_oid *o) 1110 { 1111 char *sp, *p, str[BUFSIZ]; 1112 const char *errstr; 1113 1114 if (strlcpy(str, oidstr, sizeof(str)) >= sizeof(str)) 1115 return -1; 1116 bzero(o, sizeof(*o)); 1117 1118 for (p = sp = str; p != NULL; sp = p) { 1119 if ((p = strpbrk(p, ".-")) != NULL) 1120 *p++ = '\0'; 1121 o->o_id[o->o_n++] = strtonum(sp, 0, UINT_MAX, &errstr); 1122 if (errstr || o->o_n > SNMP_MAX_OID_LEN) 1123 return -1; 1124 } 1125 1126 return 0; 1127 } 1128 #endif 1129