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