1 /* $OpenBSD: main.c,v 1.6 2021/04/20 11:19:54 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_oid_dynamic"); 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_oid_dynamic"); 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 if (agentx_varbind_request(vb) == AGENTX_REQUEST_TYPE_GETNEXT) 457 idx++; 458 if (idx > 0xf) 459 agentx_varbind_notfound(vb); 460 else { 461 agentx_varbind_set_index_integer(vb, regressidx_int, idx); 462 agentx_varbind_integer(vb, idx); 463 } 464 } 465 466 void 467 regress_intindex2(struct agentx_varbind *vb) 468 { 469 uint32_t idx1, idx2; 470 471 idx1 = agentx_varbind_get_index_integer(vb, regressidx_int); 472 idx2 = agentx_varbind_get_index_integer(vb, regressidx_int2); 473 if (agentx_varbind_request(vb) == AGENTX_REQUEST_TYPE_GETNEXT) { 474 if (++idx2 > 1) { 475 idx1++; 476 idx2 = 0; 477 } 478 } 479 if (idx1 > 8) 480 agentx_varbind_notfound(vb); 481 else { 482 agentx_varbind_set_index_integer(vb, regressidx_int, idx1); 483 agentx_varbind_set_index_integer(vb, regressidx_int2, idx2); 484 agentx_varbind_integer(vb, (idx1 << 1) + idx2); 485 } 486 } 487 488 void 489 regress_strindex(struct agentx_varbind *vb) 490 { 491 const unsigned char *idx; 492 size_t slen; 493 int implied; 494 enum agentx_request_type request = agentx_varbind_request(vb); 495 496 idx = agentx_varbind_get_index_string(vb, regressidx_str, &slen, 497 &implied); 498 499 if (implied) 500 fatalx("%s: string length should not be implied", __func__); 501 502 if (slen == 0) { 503 if (request == AGENTX_REQUEST_TYPE_GET) 504 fatalx("%s: 0 index should be handled in agentx.c", 505 __func__); 506 } 507 /* !implied first needs a length check before content check */ 508 if (slen > 1) { 509 agentx_varbind_notfound(vb); 510 return; 511 } 512 if (request == AGENTX_REQUEST_TYPE_GETNEXT) { 513 if (idx[0] == 'a') 514 idx = (unsigned char *)"b"; 515 else if (idx[0] == 'b') 516 idx = (unsigned char *)"c"; 517 else if (idx[0] >= 'c') { 518 agentx_varbind_notfound(vb); 519 return; 520 } 521 } 522 if (idx == NULL || idx[0] < 'a') 523 idx = (unsigned char *)"a"; 524 525 agentx_varbind_set_index_string(vb, regressidx_str, 526 (const char *)idx); 527 agentx_varbind_string(vb, (const char *)idx); 528 } 529 530 void 531 regress_implstrindex(struct agentx_varbind *vb) 532 { 533 const unsigned char *idx; 534 size_t slen; 535 int implied; 536 enum agentx_request_type request = agentx_varbind_request(vb); 537 538 idx = agentx_varbind_get_index_string(vb, regressidx_str, &slen, 539 &implied); 540 541 if (!implied) 542 fatalx("%s: string length should be implied", __func__); 543 544 if (slen == 0) { 545 if (request == AGENTX_REQUEST_TYPE_GET) 546 fatalx("%s: 0 index should be handled in agentx.c", 547 __func__); 548 } 549 if (request == AGENTX_REQUEST_TYPE_GET && (slen != 1 || 550 (idx[0] != 'a' && idx[0] != 'b' && idx[0] != 'c'))) { 551 agentx_varbind_notfound(vb); 552 return; 553 } 554 /* implied doesn't needs a length check before content check */ 555 if (request == AGENTX_REQUEST_TYPE_GETNEXT) { 556 if (idx[0] == 'a') 557 idx = (const unsigned char *)"b"; 558 else if (idx[0] == 'b') 559 idx = (const unsigned char *)"c"; 560 else if (idx[0] >= 'c') { 561 agentx_varbind_notfound(vb); 562 return; 563 } 564 } 565 if (idx == NULL || idx[0] < 'a') 566 idx = (const unsigned char *)"a"; 567 568 agentx_varbind_set_index_string(vb, regressidx_str, 569 (const char *)idx); 570 agentx_varbind_string(vb, (const char *)idx); 571 } 572 573 void 574 regress_strindex2(struct agentx_varbind *vb) 575 { 576 /* Opt is !implied sorted */ 577 const char *opt1[] = {"a", "b", "c"}; 578 const char *opt2[] = {"b", "aa", "bb"}; 579 size_t opt1len, opt2len; 580 size_t opt1i, opt2i; 581 const unsigned char *idx1, *idx2; 582 size_t slen1, slen2; 583 int implied1, implied2; 584 enum agentx_request_type request = agentx_varbind_request(vb); 585 int match; 586 587 idx1 = agentx_varbind_get_index_string(vb, regressidx_str, &slen1, 588 &implied1); 589 idx2 = agentx_varbind_get_index_string(vb, regressidx_str2, &slen2, 590 &implied2); 591 592 /* agentx.c debugging checks */ 593 if (implied1 || implied2) 594 fatalx("%s: string length should not be implied", __func__); 595 if (slen1 == 0 || slen2 == 0) { 596 if (request == AGENTX_REQUEST_TYPE_GET) 597 fatalx("%s: 0 index should be handled in agentx.c", 598 __func__); 599 } 600 601 opt1len = sizeof(opt1) / sizeof(*opt1); 602 match = 0; 603 for (opt1i = 0; opt1i < opt1len; opt1i++) { 604 if (strlen(opt1[opt1i]) < slen1 || 605 (strlen(opt1[opt1i]) == slen1 && 606 memcmp(opt1[opt1i], idx1, slen1) < 0)) { 607 continue; 608 } 609 if (strlen(opt1[opt1i]) == slen1 && 610 memcmp(opt1[opt1i], idx1, slen1) == 0) 611 match = 1; 612 break; 613 } 614 if (opt1i == opt1len) { 615 agentx_varbind_notfound(vb); 616 return; 617 } 618 opt2len = sizeof(opt2) / sizeof(*opt2); 619 for (opt2i = 0; opt2i < opt2len; opt2i++) { 620 if (!match) 621 break; 622 if (strlen(opt2[opt2i]) < slen2 || 623 (strlen(opt2[opt2i]) == slen2 && 624 memcmp(opt2[opt2i], idx2, slen2) < 0)) { 625 continue; 626 } 627 if (strlen(opt2[opt2i]) != slen2 || 628 memcmp(opt2[opt2i], idx2, slen2) > 0) 629 match = 0; 630 break; 631 } 632 if (request == AGENTX_REQUEST_TYPE_GET) { 633 if (!match) { 634 agentx_varbind_notfound(vb); 635 return; 636 } 637 } else { 638 if (AGENTX_REQUEST_TYPE_GETNEXT && match) 639 opt2i++; 640 if (opt2i >= opt2len) { 641 if (++opt1i == opt1len) { 642 agentx_varbind_notfound(vb); 643 return; 644 } 645 opt2i = 0; 646 } 647 } 648 649 agentx_varbind_set_index_string(vb, regressidx_str, opt1[opt1i]); 650 agentx_varbind_set_index_string(vb, regressidx_str2, opt2[opt2i]); 651 agentx_varbind_printf(vb, "%s - %s", opt1[opt1i], opt2[opt2i]); 652 } 653 654 void 655 regress_oidimplindex(struct agentx_varbind *vb) 656 { 657 struct agentx_object *obj; 658 const uint32_t *idx; 659 size_t oidlen; 660 int implied; 661 enum agentx_request_type request = agentx_varbind_request(vb); 662 663 idx = agentx_varbind_get_index_oid(vb, regressidx_oid, &oidlen, 664 &implied); 665 666 if (!implied) 667 fatalx("%s: string length should be implied", __func__); 668 669 if (request == AGENTX_REQUEST_TYPE_GET) 670 obj = agentx_context_object_find(sac, idx, oidlen, 1, 0); 671 else 672 obj = agentx_context_object_nfind(sac, idx, oidlen, 1, 673 request == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE); 674 675 if (obj == NULL) { 676 agentx_varbind_notfound(vb); 677 return; 678 } 679 680 agentx_varbind_set_index_object(vb, regressidx_oid, obj); 681 agentx_varbind_object(vb, obj); 682 } 683 684 void 685 regress_ipaddressindex(struct agentx_varbind *vb) 686 { 687 const struct in_addr *addr; 688 struct in_addr addrlist[4]; 689 enum agentx_request_type request = agentx_varbind_request(vb); 690 size_t i; 691 int cmp; 692 693 inet_pton(AF_INET, "10.0.0.0", &(addrlist[0])); 694 inet_pton(AF_INET, "127.0.0.1", &(addrlist[1])); 695 inet_pton(AF_INET, "172.16.0.0", &(addrlist[2])); 696 inet_pton(AF_INET, "192.168.0.0", &(addrlist[3])); 697 698 addr = agentx_varbind_get_index_ipaddress(vb, regressidx_ipaddress); 699 700 for (i = 0; i < 4; i++) { 701 if ((cmp = memcmp(&(addrlist[i]), addr, sizeof(*addr))) == 0) { 702 if (request == AGENTX_REQUEST_TYPE_GET || 703 request == AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE) 704 break; 705 } else if (cmp > 0) { 706 if (request == AGENTX_REQUEST_TYPE_GET) { 707 agentx_varbind_notfound(vb); 708 return; 709 } 710 break; 711 } 712 } 713 if (i == 4) { 714 agentx_varbind_notfound(vb); 715 return; 716 } 717 718 agentx_varbind_set_index_ipaddress(vb, regressidx_ipaddress, 719 &(addrlist[i])); 720 agentx_varbind_ipaddress(vb, &(addrlist[i])); 721 } 722 723 void 724 regress_intindexstaticvalueint(struct agentx_varbind *vb) 725 { 726 uint32_t idx; 727 728 idx = agentx_varbind_get_index_integer(vb, regressidx_value); 729 agentx_varbind_integer(vb, idx); 730 } 731 732 void 733 regress_intindexstaticvaluestring(struct agentx_varbind *vb) 734 { 735 uint32_t idx; 736 737 idx = agentx_varbind_get_index_integer(vb, regressidx_value); 738 agentx_varbind_printf(vb, "%u", idx); 739 } 740 741 void 742 regress_intindexstaticanyint(struct agentx_varbind *vb) 743 { 744 uint32_t idx; 745 746 idx = agentx_varbind_get_index_integer(vb, regressidx_any); 747 agentx_varbind_integer(vb, idx); 748 } 749 750 void 751 regress_intindexstaticanystring(struct agentx_varbind *vb) 752 { 753 uint32_t idx; 754 755 idx = agentx_varbind_get_index_integer(vb, regressidx_any); 756 agentx_varbind_printf(vb, "%u", idx); 757 } 758 759 void 760 regress_intindexstaticnewint(struct agentx_varbind *vb) 761 { 762 uint32_t idx; 763 764 idx = agentx_varbind_get_index_integer(vb, regressidx_new); 765 agentx_varbind_integer(vb, idx); 766 } 767 768 void 769 regress_intindexstaticnewstring(struct agentx_varbind *vb) 770 { 771 uint32_t idx; 772 773 idx = agentx_varbind_get_index_integer(vb, regressidx_new); 774 agentx_varbind_printf(vb, "%u", idx); 775 } 776 777 void 778 regress_scalarerror(struct agentx_varbind *vb) 779 { 780 agentx_varbind_error(vb); 781 } 782