1 /* $OpenBSD: main.c,v 1.5 2021/01/13 17:00:20 martijn Exp $ */ 2 3 /* 4 * Copyright (c) 2019 Martijn van Duren <martijn@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/socket.h> 20 #include <sys/types.h> 21 #include <sys/un.h> 22 23 #include <arpa/inet.h> 24 25 #include <event.h> 26 #include <signal.h> 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <unistd.h> 31 32 #include "log.h" 33 #include <agentx.h> 34 35 #define LINKDOWN 1, 3, 6, 1, 6, 3, 1, 1, 5, 3 36 #define IFINDEX 1, 3, 6, 1, 2, 1, 2, 2, 1, 1 37 #define IFADMINSTATUS 1, 3, 6, 1, 2, 1, 2, 2, 1, 7 38 #define IFOPERSTATUS 1, 3, 6, 1, 2, 1, 2, 2, 1, 8 39 40 void regress_fd(struct agentx *, void *, int); 41 void regress_tryconnect(int, short, void *); 42 void regress_shutdown(void); 43 void regress_read(int, short, void *); 44 void regress_usr1(int, short, void *); 45 void regress_usr2(int, short, void *); 46 void regress_scalarinteger(struct agentx_varbind *); 47 void regress_scalarstring(struct agentx_varbind *); 48 void regress_scalarnull(struct agentx_varbind *); 49 void regress_scalaroid(struct agentx_varbind *); 50 void regress_scalaripaddress(struct agentx_varbind *); 51 void regress_scalarcounter32(struct agentx_varbind *); 52 void regress_scalargauge32(struct agentx_varbind *); 53 void regress_scalartimeticks(struct agentx_varbind *); 54 void regress_scalaropaque(struct agentx_varbind *); 55 void regress_scalarcounter64(struct agentx_varbind *); 56 void regress_scalarerror(struct agentx_varbind *); 57 58 void regress_intindex(struct agentx_varbind *); 59 void regress_intindex2(struct agentx_varbind *); 60 61 void regress_strindex(struct agentx_varbind *); 62 void regress_implstrindex(struct agentx_varbind *); 63 void regress_strindex2(struct agentx_varbind *); 64 65 void regress_oidimplindex(struct agentx_varbind *); 66 67 void regress_ipaddressindex(struct agentx_varbind *); 68 69 void regress_intindexstaticvalueint(struct agentx_varbind *); 70 void regress_intindexstaticvaluestring(struct agentx_varbind *); 71 void regress_intindexstaticanyint(struct agentx_varbind *); 72 void regress_intindexstaticanystring(struct agentx_varbind *); 73 void regress_intindexstaticnewint(struct agentx_varbind *); 74 void regress_intindexstaticnewstring(struct agentx_varbind *); 75 76 struct agentx *sa; 77 struct agentx_session *sas; 78 struct agentx_context *sac; 79 struct agentx_agentcaps *saa; 80 struct agentx_region *regress; 81 82 struct agentx_index *regressidx_int; 83 struct agentx_index *regressidx_int2; 84 85 struct agentx_index *regressidx_str; 86 struct agentx_index *regressidx_str2; 87 88 struct agentx_index *regressidx_oid; 89 90 struct agentx_index *regressidx_ipaddress; 91 92 struct agentx_index *regressidx_new; 93 struct agentx_index *regressidx_any; 94 struct agentx_index *regressidx_value; 95 96 struct agentx_object *regressobj_scalarinteger; 97 struct agentx_object *regressobj_scalarstring; 98 struct agentx_object *regressobj_scalarnull; 99 struct agentx_object *regressobj_scalaroid; 100 struct agentx_object *regressobj_scalaripaddress; 101 struct agentx_object *regressobj_scalarcounter32; 102 struct agentx_object *regressobj_scalargauge32; 103 struct agentx_object *regressobj_scalartimeticks; 104 struct agentx_object *regressobj_scalaropaque; 105 struct agentx_object *regressobj_scalarcounter64; 106 107 struct agentx_object *regressobj_intindexint; 108 struct agentx_object *regressobj_intindexint2; 109 110 struct agentx_object *regressobj_strindexstr; 111 struct agentx_object *regressobj_implstrindexstr; 112 struct agentx_object *regressobj_strindexstr2; 113 114 struct agentx_object *regressobj_oidimplindexoid; 115 116 struct agentx_object *regressobj_ipaddressindexipaddress; 117 118 struct agentx_object *regressobj_intindexstaticvalueint; 119 struct agentx_object *regressobj_intindexstaticvaluestring; 120 struct agentx_object *regressobj_intindexstaticanyint; 121 struct agentx_object *regressobj_intindexstaticanystring; 122 struct agentx_object *regressobj_intindexstaticnewint; 123 struct agentx_object *regressobj_intindexstaticnewstring; 124 125 struct agentx_object *regressobj_scalarerror; 126 127 char *path = AGENTX_MASTER_PATH; 128 int fd = -1; 129 struct event rev; 130 struct event intev, usr1ev, usr2ev, connev; 131 132 int 133 main(int argc, char *argv[]) 134 { 135 struct agentx_index *idx[AGENTX_OID_INDEX_MAX_LEN]; 136 int ch; 137 int dflag = 0; 138 139 log_init(2, 1); 140 141 while ((ch = getopt(argc, argv, "d")) != -1) { 142 switch (ch) { 143 case 'd': 144 dflag = 1; 145 break; 146 default: 147 exit(1); 148 } 149 } 150 151 argc -= optind; 152 argv += optind; 153 154 if (argc >= 1) 155 path = argv[0]; 156 157 bzero(&rev, sizeof(rev)); 158 159 agentx_log_fatal = fatalx; 160 agentx_log_warn = log_warnx; 161 agentx_log_info = log_info; 162 agentx_log_debug = log_debug; 163 164 if ((sa = agentx(regress_fd, (void *)path)) == NULL) 165 fatal("agentx"); 166 sas = agentx_session(sa, NULL, 0, "OpenAgentX regress", 0); 167 if (sas == NULL) 168 fatal("agentx_session"); 169 if ((sac = agentx_context(sas, NULL)) == NULL) 170 fatal("agentx_context"); 171 if ((saa = agentx_agentcaps(sac, 172 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 50, 1), 173 "OpenBSD AgentX regress")) == NULL) 174 fatal("agentx_agentcaps"); 175 if ((regress = agentx_region(sac, 176 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100), 0)) == NULL) 177 fatal("agentx_region application"); 178 if ((regressobj_scalarinteger = agentx_object(regress, 179 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 1), NULL, 0, 180 0, regress_scalarinteger)) == NULL) 181 fatal("agentx_object"); 182 if ((regressobj_scalarstring = agentx_object(regress, 183 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 2), NULL, 0, 184 0, regress_scalarstring)) == NULL) 185 fatal("agentx_object"); 186 /* netsnmp doesn't return NULL-objects */ 187 /* 188 if ((regressobj_scalarnull = agentx_object(regress, 189 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 3), NULL, 0, 190 0, regress_scalarnull)) == NULL) 191 fatal("agentx_object"); 192 */ 193 if ((regressobj_scalaroid = agentx_object(regress, 194 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 4), NULL, 0, 195 0, regress_scalaroid)) == NULL) 196 fatal("agentx_object"); 197 if ((regressobj_scalaripaddress = agentx_object(regress, 198 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 5), NULL, 0, 199 0, regress_scalaripaddress)) == NULL) 200 fatal("agentx_object"); 201 if ((regressobj_scalarcounter32 = agentx_object(regress, 202 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 6), NULL, 0, 203 0, regress_scalarcounter32)) == NULL) 204 fatal("agentx_object"); 205 if ((regressobj_scalargauge32 = agentx_object(regress, 206 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 7), NULL, 0, 207 0, regress_scalargauge32)) == NULL) 208 fatal("agentx_object"); 209 if ((regressobj_scalartimeticks = agentx_object(regress, 210 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 8), NULL, 0, 211 0, regress_scalartimeticks)) == NULL) 212 fatal("agentx_object"); 213 if ((regressobj_scalaropaque = agentx_object(regress, 214 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 9), NULL, 0, 215 0, regress_scalaropaque)) == NULL) 216 fatal("agentx_object"); 217 if ((regressobj_scalarcounter64 = agentx_object(regress, 218 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 10), NULL, 0, 219 0, regress_scalarcounter64)) == NULL) 220 fatal("agentx_object"); 221 222 if ((regressidx_int = agentx_index_integer_dynamic(regress, 223 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 11, 1, 1))) == NULL) 224 fatal("agentx_index_integer_dynamic"); 225 if ((regressobj_intindexint = agentx_object(regress, 226 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 11, 1, 1), 227 ®ressidx_int, 1, 0, regress_intindex)) == NULL) 228 fatal("agentx_object"); 229 230 if ((regressidx_int2 = agentx_index_integer_dynamic(regress, 231 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 12, 1, 1))) == NULL) 232 fatal("agentx_index_integer_dynamic"); 233 idx[0] = regressidx_int; 234 idx[1] = regressidx_int2; 235 if ((regressobj_intindexint2 = agentx_object(regress, 236 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 12, 1, 1), 237 idx, 2, 0, regress_intindex2)) == NULL) 238 fatal("agentx_object"); 239 240 if ((regressidx_str = agentx_index_string_dynamic(regress, 241 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 13, 1, 1))) == NULL) 242 fatal("agentx_index_string_dynamic"); 243 if ((regressobj_strindexstr = agentx_object(regress, 244 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 13, 1, 1), 245 ®ressidx_str, 1, 0, regress_strindex)) == NULL) 246 fatal("agentx_object"); 247 if ((regressobj_implstrindexstr = agentx_object(regress, 248 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 14, 1, 1), 249 ®ressidx_str, 1, 1, regress_implstrindex)) == NULL) 250 fatal("agentx_object"); 251 if ((regressidx_str2 = agentx_index_string_dynamic(regress, 252 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 15, 1, 1))) == NULL) 253 fatal("agentx_index_string_dynamic"); 254 idx[0] = regressidx_str; 255 idx[1] = regressidx_str2; 256 if ((regressobj_strindexstr = agentx_object(regress, 257 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 15, 1, 1), 258 idx, 2, 0, regress_strindex2)) == NULL) 259 fatal("agentx_object"); 260 261 if ((regressidx_oid = agentx_index_oid_dynamic(regress, 262 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 16, 1, 1))) == NULL) 263 fatal("agentx_index_oid_dynamic"); 264 if ((regressobj_oidimplindexoid = agentx_object(regress, 265 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 16, 1, 1), 266 ®ressidx_oid, 1, 1, regress_oidimplindex)) == NULL) 267 fatal("agentx_object"); 268 269 if ((regressidx_ipaddress = agentx_index_ipaddress_dynamic(regress, 270 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 17, 1, 1))) == NULL) 271 fatal("agentx_index_oid_dynamic"); 272 if ((regressobj_oidimplindexoid = agentx_object(regress, 273 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 17, 1, 1), 274 ®ressidx_ipaddress, 1, 0, regress_ipaddressindex)) == NULL) 275 fatal("agentx_object"); 276 277 if ((regressidx_value = agentx_index_integer_value(regress, 278 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 18, 1, 1), 5)) == NULL) 279 fatal("agentx_index_oid_dynamic"); 280 if ((regressobj_intindexstaticvalueint = agentx_object(regress, 281 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 18, 1, 1), 282 ®ressidx_value, 1, 0, regress_intindexstaticvalueint)) == NULL) 283 fatal("agentx_object"); 284 if ((regressobj_intindexstaticvaluestring = agentx_object(regress, 285 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 18, 1, 2), 286 ®ressidx_value, 1, 0, regress_intindexstaticvaluestring)) == NULL) 287 fatal("agentx_object"); 288 289 if ((regressidx_any = agentx_index_integer_any(regress, 290 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 19, 1, 1))) == NULL) 291 fatal("agentx_index_oid_dynamic"); 292 if ((regressobj_intindexstaticanyint = agentx_object(regress, 293 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 19, 1, 1), 294 ®ressidx_any, 1, 0, regress_intindexstaticanyint)) == NULL) 295 fatal("agentx_object"); 296 if ((regressobj_intindexstaticanystring = agentx_object(regress, 297 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 19, 1, 2), 298 ®ressidx_any, 1, 0, regress_intindexstaticanystring)) == NULL) 299 fatal("agentx_object"); 300 301 if ((regressidx_new = agentx_index_integer_new(regress, 302 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 20, 1, 1))) == NULL) 303 fatal("agentx_index_oid_dynamic"); 304 if ((regressobj_intindexstaticnewint = agentx_object(regress, 305 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 20, 1, 1), 306 ®ressidx_new, 1, 0, regress_intindexstaticnewint)) == NULL) 307 fatal("agentx_object"); 308 if ((regressobj_intindexstaticnewstring = agentx_object(regress, 309 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, 20, 1, 2), 310 ®ressidx_new, 1, 0, regress_intindexstaticnewstring)) == NULL) 311 fatal("agentx_object"); 312 313 if ((regressobj_scalarerror = agentx_object(regress, 314 AGENTX_OID(AGENTX_ENTERPRISES, 30155, 100, UINT32_MAX), NULL, 315 0, 0, regress_scalarerror)) == NULL) 316 fatal("agentx_object"); 317 318 if (!dflag) { 319 if (daemon(0, 0) == -1) 320 fatalx("daemon"); 321 } 322 323 event_init(); 324 325 event_set(&rev, fd, EV_READ|EV_PERSIST, regress_read, NULL); 326 if (event_add(&rev, NULL) == -1) 327 fatal("event_add"); 328 329 event_dispatch(); 330 return 0; 331 } 332 333 void 334 regress_fd(struct agentx *sa2, void *cookie, int close) 335 { 336 static int init = 0; 337 struct sockaddr_un sun; 338 339 /* For ease of cleanup we take the single run approach */ 340 if (init) 341 regress_shutdown(); 342 else { 343 sun.sun_family = AF_UNIX; 344 strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 345 346 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 || 347 connect(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) { 348 fatal("connect"); 349 } 350 agentx_connect(sa2, fd); 351 init = 1; 352 } 353 } 354 355 void 356 regress_read(int fd, short event, void *cookie) 357 { 358 agentx_read(sa); 359 } 360 361 void 362 regress_shutdown(void) 363 { 364 agentx_free(sa); 365 evtimer_del(&connev); 366 } 367 368 #ifdef notyet 369 370 void 371 regress_usr1(int fd, short event, void *cookie) 372 { 373 struct agentx_notify *san; 374 375 if ((san = agentx_notify(sac, AGENTX_OID(LINKDOWN))) == NULL) 376 fatal("agentx_notify"); 377 378 agentx_notify_integer(san, AGENTX_OID(IFINDEX), 1); 379 agentx_notify_integer(san, AGENTX_OID(IFADMINSTATUS), 3); 380 agentx_notify_integer(san, AGENTX_OID(IFOPERSTATUS), 6); 381 agentx_notify_send(san); 382 } 383 384 #endif 385 386 void 387 regress_usr2(int fd, short event, void *cookie) 388 { 389 } 390 391 void 392 regress_scalarstring(struct agentx_varbind *vb) 393 { 394 agentx_varbind_string(vb, "scalar-string"); 395 } 396 397 void 398 regress_scalarinteger(struct agentx_varbind *vb) 399 { 400 agentx_varbind_integer(vb, 1); 401 } 402 403 void 404 regress_scalarnull(struct agentx_varbind *vb) 405 { 406 agentx_varbind_null(vb); 407 } 408 409 void 410 regress_scalaroid(struct agentx_varbind *vb) 411 { 412 agentx_varbind_oid(vb, AGENTX_OID(AGENTX_ENTERPRISES, 30155)); 413 } 414 415 void 416 regress_scalaripaddress(struct agentx_varbind *vb) 417 { 418 struct in_addr addr; 419 420 inet_aton("127.0.0.1", &addr); 421 422 agentx_varbind_ipaddress(vb, &addr); 423 } 424 425 void 426 regress_scalarcounter32(struct agentx_varbind *vb) 427 { 428 agentx_varbind_counter32(vb, 1); 429 } 430 431 void 432 regress_scalargauge32(struct agentx_varbind *vb) 433 { 434 agentx_varbind_gauge32(vb, 1); 435 } 436 437 void 438 regress_scalartimeticks(struct agentx_varbind *vb) 439 { 440 agentx_varbind_timeticks(vb, 1); 441 } 442 443 void 444 regress_scalaropaque(struct agentx_varbind *vb) 445 { 446 agentx_varbind_opaque(vb, "abc", 3); 447 } 448 449 void 450 regress_scalarcounter64(struct agentx_varbind *vb) 451 { 452 agentx_varbind_counter64(vb, 1); 453 } 454 455 void 456 regress_intindex(struct agentx_varbind *vb) 457 { 458 uint32_t idx; 459 460 idx = agentx_varbind_get_index_integer(vb, regressidx_int); 461 if (agentx_varbind_request(vb) == AGENTX_REQUEST_TYPE_GETNEXT) 462 idx++; 463 if (idx > 0xf) 464 agentx_varbind_notfound(vb); 465 else { 466 agentx_varbind_set_index_integer(vb, regressidx_int, idx); 467 agentx_varbind_integer(vb, idx); 468 } 469 } 470 471 void 472 regress_intindex2(struct agentx_varbind *vb) 473 { 474 uint32_t idx1, idx2; 475 476 idx1 = agentx_varbind_get_index_integer(vb, regressidx_int); 477 idx2 = agentx_varbind_get_index_integer(vb, regressidx_int2); 478 if (agentx_varbind_request(vb) == AGENTX_REQUEST_TYPE_GETNEXT) { 479 if (++idx2 > 1) { 480 idx1++; 481 idx2 = 0; 482 } 483 } 484 if (idx1 > 8) 485 agentx_varbind_notfound(vb); 486 else { 487 agentx_varbind_set_index_integer(vb, regressidx_int, idx1); 488 agentx_varbind_set_index_integer(vb, regressidx_int2, idx2); 489 agentx_varbind_integer(vb, (idx1 << 1) + idx2); 490 } 491 } 492 493 void 494 regress_strindex(struct agentx_varbind *vb) 495 { 496 const unsigned char *idx; 497 size_t slen; 498 int implied; 499 enum agentx_request_type request = agentx_varbind_request(vb); 500 501 idx = agentx_varbind_get_index_string(vb, regressidx_str, &slen, 502 &implied); 503 504 if (implied) 505 fatalx("%s: string length should not be implied", __func__); 506 507 if (slen == 0) { 508 if (request == AGENTX_REQUEST_TYPE_GET) 509 fatalx("%s: 0 index should be handled in agentx.c", 510 __func__); 511 } 512 /* !implied first needs a length check before content check */ 513 if (slen > 1) { 514 agentx_varbind_notfound(vb); 515 return; 516 } 517 if (request == AGENTX_REQUEST_TYPE_GETNEXT) { 518 if (idx[0] == 'a') 519 idx = (unsigned char *)"b"; 520 else if (idx[0] == 'b') 521 idx = (unsigned char *)"c"; 522 else if (idx[0] >= 'c') { 523 agentx_varbind_notfound(vb); 524 return; 525 } 526 } 527 if (idx == NULL || idx[0] < 'a') 528 idx = (unsigned char *)"a"; 529 530 agentx_varbind_set_index_string(vb, regressidx_str, 531 (const char *)idx); 532 agentx_varbind_string(vb, (const char *)idx); 533 } 534 535 void 536 regress_implstrindex(struct agentx_varbind *vb) 537 { 538 const unsigned char *idx; 539 size_t slen; 540 int implied; 541 enum agentx_request_type request = agentx_varbind_request(vb); 542 543 idx = agentx_varbind_get_index_string(vb, regressidx_str, &slen, 544 &implied); 545 546 if (!implied) 547 fatalx("%s: string length should be implied", __func__); 548 549 if (slen == 0) { 550 if (request == AGENTX_REQUEST_TYPE_GET) 551 fatalx("%s: 0 index should be handled in agentx.c", 552 __func__); 553 } 554 if (request == AGENTX_REQUEST_TYPE_GET && (slen != 1 || 555 (idx[0] != 'a' && idx[0] != 'b' && idx[0] != 'c'))) { 556 agentx_varbind_notfound(vb); 557 return; 558 } 559 /* implied doesn't needs a length check before content check */ 560 if (request == AGENTX_REQUEST_TYPE_GETNEXT) { 561 if (idx[0] == 'a') 562 idx = (const unsigned char *)"b"; 563 else if (idx[0] == 'b') 564 idx = (const unsigned char *)"c"; 565 else if (idx[0] >= 'c') { 566 agentx_varbind_notfound(vb); 567 return; 568 } 569 } 570 if (idx == NULL || idx[0] < 'a') 571 idx = (const unsigned char *)"a"; 572 573 agentx_varbind_set_index_string(vb, regressidx_str, 574 (const char *)idx); 575 agentx_varbind_string(vb, (const char *)idx); 576 } 577 578 void 579 regress_strindex2(struct agentx_varbind *vb) 580 { 581 /* Opt is !implied sorted */ 582 const char *opt1[] = {"a", "b", "c"}; 583 const char *opt2[] = {"b", "aa", "bb"}; 584 size_t opt1len, opt2len; 585 size_t opt1i, opt2i; 586 const unsigned char *idx1, *idx2; 587 size_t slen1, slen2; 588 int implied1, implied2; 589 enum agentx_request_type request = agentx_varbind_request(vb); 590 int match; 591 592 idx1 = agentx_varbind_get_index_string(vb, regressidx_str, &slen1, 593 &implied1); 594 idx2 = agentx_varbind_get_index_string(vb, regressidx_str2, &slen2, 595 &implied2); 596 597 /* agentx.c debugging checks */ 598 if (implied1 || implied2) 599 fatalx("%s: string length should not be implied", __func__); 600 if (slen1 == 0 || slen2 == 0) { 601 if (request == AGENTX_REQUEST_TYPE_GET) 602 fatalx("%s: 0 index should be handled in agentx.c", 603 __func__); 604 } 605 606 opt1len = sizeof(opt1) / sizeof(*opt1); 607 match = 0; 608 for (opt1i = 0; opt1i < opt1len; opt1i++) { 609 if (strlen(opt1[opt1i]) < slen1 || 610 (strlen(opt1[opt1i]) == slen1 && 611 memcmp(opt1[opt1i], idx1, slen1) < 0)) { 612 continue; 613 } 614 if (strlen(opt1[opt1i]) == slen1 && 615 memcmp(opt1[opt1i], idx1, slen1) == 0) 616 match = 1; 617 break; 618 } 619 if (opt1i == opt1len) { 620 agentx_varbind_notfound(vb); 621 return; 622 } 623 opt2len = sizeof(opt2) / sizeof(*opt2); 624 for (opt2i = 0; opt2i < opt2len; opt2i++) { 625 if (!match) 626 break; 627 if (strlen(opt2[opt2i]) < slen2 || 628 (strlen(opt2[opt2i]) == slen2 && 629 memcmp(opt2[opt2i], idx2, slen2) < 0)) { 630 continue; 631 } 632 if (strlen(opt2[opt2i]) != slen2 || 633 memcmp(opt2[opt2i], idx2, slen2) > 0) 634 match = 0; 635 break; 636 } 637 if (request == AGENTX_REQUEST_TYPE_GET) { 638 if (!match) { 639 agentx_varbind_notfound(vb); 640 return; 641 } 642 } else { 643 if (AGENTX_REQUEST_TYPE_GETNEXT && match) 644 opt2i++; 645 if (opt2i >= opt2len) { 646 if (++opt1i == opt1len) { 647 agentx_varbind_notfound(vb); 648 return; 649 } 650 opt2i = 0; 651 } 652 } 653 654 agentx_varbind_set_index_string(vb, regressidx_str, opt1[opt1i]); 655 agentx_varbind_set_index_string(vb, regressidx_str2, opt2[opt2i]); 656 agentx_varbind_printf(vb, "%s - %s", opt1[opt1i], opt2[opt2i]); 657 } 658 659 void 660 regress_oidimplindex(struct agentx_varbind *vb) 661 { 662 struct agentx_object *obj; 663 const uint32_t *idx; 664 size_t oidlen; 665 int implied; 666 enum agentx_request_type request = agentx_varbind_request(vb); 667 668 idx = agentx_varbind_get_index_oid(vb, regressidx_oid, &oidlen, 669 &implied); 670 671 if (!implied) 672 fatalx("%s: string length should be implied", __func__); 673 674 if (request == AGENTX_REQUEST_TYPE_GET) 675 obj = agentx_context_object_find(sac, idx, oidlen, 1, 0); 676 else 677 obj = agentx_context_object_nfind(sac, idx, oidlen, 1, 678 request == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE); 679 680 if (obj == NULL) { 681 agentx_varbind_notfound(vb); 682 return; 683 } 684 685 agentx_varbind_set_index_object(vb, regressidx_oid, obj); 686 agentx_varbind_object(vb, obj); 687 } 688 689 void 690 regress_ipaddressindex(struct agentx_varbind *vb) 691 { 692 const struct in_addr *addr; 693 struct in_addr addrlist[4]; 694 enum agentx_request_type request = agentx_varbind_request(vb); 695 size_t i; 696 int cmp; 697 698 inet_pton(AF_INET, "10.0.0.0", &(addrlist[0])); 699 inet_pton(AF_INET, "127.0.0.1", &(addrlist[1])); 700 inet_pton(AF_INET, "172.16.0.0", &(addrlist[2])); 701 inet_pton(AF_INET, "192.168.0.0", &(addrlist[3])); 702 703 addr = agentx_varbind_get_index_ipaddress(vb, regressidx_ipaddress); 704 705 for (i = 0; i < 4; i++) { 706 if ((cmp = memcmp(&(addrlist[i]), addr, sizeof(*addr))) == 0) { 707 if (request == AGENTX_REQUEST_TYPE_GET || 708 request == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) 709 break; 710 } else if (cmp > 0) { 711 if (request == AGENTX_REQUEST_TYPE_GET) { 712 agentx_varbind_notfound(vb); 713 return; 714 } 715 break; 716 } 717 } 718 if (i == 4) { 719 agentx_varbind_notfound(vb); 720 return; 721 } 722 723 agentx_varbind_set_index_ipaddress(vb, regressidx_ipaddress, 724 &(addrlist[i])); 725 agentx_varbind_ipaddress(vb, &(addrlist[i])); 726 } 727 728 void 729 regress_intindexstaticvalueint(struct agentx_varbind *vb) 730 { 731 uint32_t idx; 732 733 idx = agentx_varbind_get_index_integer(vb, regressidx_value); 734 agentx_varbind_integer(vb, idx); 735 } 736 737 void 738 regress_intindexstaticvaluestring(struct agentx_varbind *vb) 739 { 740 uint32_t idx; 741 742 idx = agentx_varbind_get_index_integer(vb, regressidx_value); 743 agentx_varbind_printf(vb, "%u", idx); 744 } 745 746 void 747 regress_intindexstaticanyint(struct agentx_varbind *vb) 748 { 749 uint32_t idx; 750 751 idx = agentx_varbind_get_index_integer(vb, regressidx_any); 752 agentx_varbind_integer(vb, idx); 753 } 754 755 void 756 regress_intindexstaticanystring(struct agentx_varbind *vb) 757 { 758 uint32_t idx; 759 760 idx = agentx_varbind_get_index_integer(vb, regressidx_any); 761 agentx_varbind_printf(vb, "%u", idx); 762 } 763 764 void 765 regress_intindexstaticnewint(struct agentx_varbind *vb) 766 { 767 uint32_t idx; 768 769 idx = agentx_varbind_get_index_integer(vb, regressidx_new); 770 agentx_varbind_integer(vb, idx); 771 } 772 773 void 774 regress_intindexstaticnewstring(struct agentx_varbind *vb) 775 { 776 uint32_t idx; 777 778 idx = agentx_varbind_get_index_integer(vb, regressidx_new); 779 agentx_varbind_printf(vb, "%u", idx); 780 } 781 782 void 783 regress_scalarerror(struct agentx_varbind *vb) 784 { 785 agentx_varbind_error(vb); 786 } 787