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