1 /* 2 * Copyright (c) 2001-2003 3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4 * All rights reserved. 5 * 6 * Author: Harti Brandt <harti@freebsd.org> 7 * 8 * Copyright (c) 2010 The FreeBSD Foundation 9 * All rights reserved. 10 * 11 * Portions of this software were developed by Shteryana Sotirova Shopova 12 * under sponsorship from the FreeBSD Foundation. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * $Begemot: bsnmp/snmpd/snmpmod.h,v 1.32 2006/02/14 09:04:20 brandt_h Exp $ 36 * 37 * SNMP daemon data and functions exported to modules. 38 */ 39 #ifndef snmpmod_h_ 40 #define snmpmod_h_ 41 42 #include <sys/types.h> 43 #include <sys/queue.h> 44 #include <sys/socket.h> 45 #include <net/if.h> 46 #include <netinet/in.h> 47 #include "asn1.h" 48 #include "snmp.h" 49 #include "snmpagent.h" 50 51 #define MAX_MOD_ARGS 16 52 53 /* 54 * These macros help to handle object lists for SNMP tables. They use 55 * tail queues to hold the objects in ascending order in the list. 56 * ordering can be done either on an integer/unsigned field, an asn_oid 57 * or an ordering function. 58 */ 59 #define INSERT_OBJECT_OID_LINK_INDEX(PTR, LIST, LINK, INDEX) do { \ 60 __typeof (PTR) _lelem; \ 61 \ 62 TAILQ_FOREACH(_lelem, (LIST), LINK) \ 63 if (asn_compare_oid(&_lelem->INDEX, &(PTR)->INDEX) > 0) \ 64 break; \ 65 if (_lelem == NULL) \ 66 TAILQ_INSERT_TAIL((LIST), (PTR), LINK); \ 67 else \ 68 TAILQ_INSERT_BEFORE(_lelem, (PTR), LINK); \ 69 } while (0) 70 71 #define INSERT_OBJECT_INT_LINK_INDEX(PTR, LIST, LINK, INDEX) do { \ 72 __typeof (PTR) _lelem; \ 73 \ 74 TAILQ_FOREACH(_lelem, (LIST), LINK) \ 75 if ((asn_subid_t)_lelem->INDEX > (asn_subid_t)(PTR)->INDEX)\ 76 break; \ 77 if (_lelem == NULL) \ 78 TAILQ_INSERT_TAIL((LIST), (PTR), LINK); \ 79 else \ 80 TAILQ_INSERT_BEFORE(_lelem, (PTR), LINK); \ 81 } while (0) 82 83 #define INSERT_OBJECT_FUNC_LINK(PTR, LIST, LINK, FUNC) do { \ 84 __typeof (PTR) _lelem; \ 85 \ 86 TAILQ_FOREACH(_lelem, (LIST), LINK) \ 87 if ((FUNC)(_lelem, (PTR)) > 0) \ 88 break; \ 89 if (_lelem == NULL) \ 90 TAILQ_INSERT_TAIL((LIST), (PTR), LINK); \ 91 else \ 92 TAILQ_INSERT_BEFORE(_lelem, (PTR), LINK); \ 93 } while (0) 94 95 #define INSERT_OBJECT_FUNC_LINK_REV(PTR, LIST, HEAD, LINK, FUNC) do { \ 96 __typeof (PTR) _lelem; \ 97 \ 98 TAILQ_FOREACH_REVERSE(_lelem, (LIST), HEAD, LINK) \ 99 if ((FUNC)(_lelem, (PTR)) < 0) \ 100 break; \ 101 if (_lelem == NULL) \ 102 TAILQ_INSERT_HEAD((LIST), (PTR), LINK); \ 103 else \ 104 TAILQ_INSERT_AFTER((LIST), _lelem, (PTR), LINK); \ 105 } while (0) 106 107 #define FIND_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, LINK, INDEX) ({ \ 108 __typeof (TAILQ_FIRST(LIST)) _lelem; \ 109 \ 110 TAILQ_FOREACH(_lelem, (LIST), LINK) \ 111 if (index_compare(OID, SUB, &_lelem->INDEX) == 0) \ 112 break; \ 113 (_lelem); \ 114 }) 115 116 #define NEXT_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, LINK, INDEX) ({ \ 117 __typeof (TAILQ_FIRST(LIST)) _lelem; \ 118 \ 119 TAILQ_FOREACH(_lelem, (LIST), LINK) \ 120 if (index_compare(OID, SUB, &_lelem->INDEX) < 0) \ 121 break; \ 122 (_lelem); \ 123 }) 124 125 #define FIND_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, LINK, INDEX) ({ \ 126 __typeof (TAILQ_FIRST(LIST)) _lelem; \ 127 \ 128 if ((OID)->len - SUB != 1) \ 129 _lelem = NULL; \ 130 else \ 131 TAILQ_FOREACH(_lelem, (LIST), LINK) \ 132 if ((OID)->subs[SUB] == (asn_subid_t)_lelem->INDEX)\ 133 break; \ 134 (_lelem); \ 135 }) 136 137 #define NEXT_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, LINK, INDEX) ({ \ 138 __typeof (TAILQ_FIRST(LIST)) _lelem; \ 139 \ 140 if ((OID)->len - SUB == 0) \ 141 _lelem = TAILQ_FIRST(LIST); \ 142 else \ 143 TAILQ_FOREACH(_lelem, (LIST), LINK) \ 144 if ((OID)->subs[SUB] < (asn_subid_t)_lelem->INDEX)\ 145 break; \ 146 (_lelem); \ 147 }) 148 149 #define FIND_OBJECT_FUNC_LINK(LIST, OID, SUB, LINK, FUNC) ({ \ 150 __typeof (TAILQ_FIRST(LIST)) _lelem; \ 151 \ 152 TAILQ_FOREACH(_lelem, (LIST), LINK) \ 153 if ((FUNC)(OID, SUB, _lelem) == 0) \ 154 break; \ 155 (_lelem); \ 156 }) 157 158 #define NEXT_OBJECT_FUNC_LINK(LIST, OID, SUB, LINK, FUNC) ({ \ 159 __typeof (TAILQ_FIRST(LIST)) _lelem; \ 160 \ 161 TAILQ_FOREACH(_lelem, (LIST), LINK) \ 162 if ((FUNC)(OID, SUB, _lelem) < 0) \ 163 break; \ 164 (_lelem); \ 165 }) 166 167 /* 168 * Macros for the case where the index field is called 'index' 169 */ 170 #define INSERT_OBJECT_OID_LINK(PTR, LIST, LINK) \ 171 INSERT_OBJECT_OID_LINK_INDEX(PTR, LIST, LINK, index) 172 173 #define INSERT_OBJECT_INT_LINK(PTR, LIST, LINK) do { \ 174 INSERT_OBJECT_INT_LINK_INDEX(PTR, LIST, LINK, index) 175 176 #define FIND_OBJECT_OID_LINK(LIST, OID, SUB, LINK) \ 177 FIND_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, LINK, index) 178 179 #define NEXT_OBJECT_OID_LINK(LIST, OID, SUB, LINK) \ 180 NEXT_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, LINK, index) 181 182 #define FIND_OBJECT_INT_LINK(LIST, OID, SUB, LINK) \ 183 FIND_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, LINK, index) 184 185 #define NEXT_OBJECT_INT_LINK(LIST, OID, SUB, LINK) \ 186 NEXT_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, LINK, index) 187 188 /* 189 * Macros for the case where the index field is called 'index' and the 190 * link field 'link'. 191 */ 192 #define INSERT_OBJECT_OID(PTR, LIST) \ 193 INSERT_OBJECT_OID_LINK_INDEX(PTR, LIST, link, index) 194 195 #define INSERT_OBJECT_INT(PTR, LIST) \ 196 INSERT_OBJECT_INT_LINK_INDEX(PTR, LIST, link, index) 197 198 #define INSERT_OBJECT_FUNC_REV(PTR, LIST, HEAD, FUNC) \ 199 INSERT_OBJECT_FUNC_LINK_REV(PTR, LIST, HEAD, link, FUNC) 200 201 #define FIND_OBJECT_OID(LIST, OID, SUB) \ 202 FIND_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, link, index) 203 204 #define FIND_OBJECT_INT(LIST, OID, SUB) \ 205 FIND_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, link, index) 206 207 #define FIND_OBJECT_FUNC(LIST, OID, SUB, FUNC) \ 208 FIND_OBJECT_FUNC_LINK(LIST, OID, SUB, link, FUNC) 209 210 #define NEXT_OBJECT_OID(LIST, OID, SUB) \ 211 NEXT_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, link, index) 212 213 #define NEXT_OBJECT_INT(LIST, OID, SUB) \ 214 NEXT_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, link, index) 215 216 #define NEXT_OBJECT_FUNC(LIST, OID, SUB, FUNC) \ 217 NEXT_OBJECT_FUNC_LINK(LIST, OID, SUB, link, FUNC) 218 219 struct lmodule; 220 221 /* The tick when the program was started. This is the absolute time of 222 * the start in 100th of a second. */ 223 extern uint64_t start_tick; 224 225 /* The tick when the current packet was received. This is the absolute 226 * time in 100th of second. */ 227 extern uint64_t this_tick; 228 229 /* Get the current absolute time in 100th of a second. */ 230 uint64_t get_ticks(void); 231 232 /* 233 * Return code for proxy function 234 */ 235 enum snmpd_proxy_err { 236 /* proxy code will process the PDU */ 237 SNMPD_PROXY_OK, 238 /* proxy code does not process PDU */ 239 SNMPD_PROXY_REJ, 240 /* drop this PDU */ 241 SNMPD_PROXY_DROP, 242 /* drop because of bad community */ 243 SNMPD_PROXY_BADCOMM, 244 /* drop because of bad community use */ 245 SNMPD_PROXY_BADCOMMUSE 246 }; 247 248 /* 249 * Input handling 250 */ 251 enum snmpd_input_err { 252 /* proceed with packet */ 253 SNMPD_INPUT_OK, 254 /* fatal error in packet, ignore it */ 255 SNMPD_INPUT_FAILED, 256 /* value encoding has wrong length in a SET operation */ 257 SNMPD_INPUT_VALBADLEN, 258 /* value encoding is out of range */ 259 SNMPD_INPUT_VALRANGE, 260 /* value has bad encoding */ 261 SNMPD_INPUT_VALBADENC, 262 /* need more data (truncated packet) */ 263 SNMPD_INPUT_TRUNC, 264 /* unknown community */ 265 SNMPD_INPUT_BAD_COMM, 266 }; 267 268 /* 269 * Every loadable module must have one of this structures with 270 * the external name 'config'. 271 */ 272 struct snmp_module { 273 /* a comment describing what this module implements */ 274 const char *comment; 275 276 /* the initialization function */ 277 int (*init)(struct lmodule *, int argc, char *argv[]); 278 279 /* the finalisation function */ 280 int (*fini)(void); 281 282 /* the idle function */ 283 void (*idle)(void); 284 285 /* the dump function */ 286 void (*dump)(void); 287 288 /* re-configuration function */ 289 void (*config)(void); 290 291 /* start operation */ 292 void (*start)(void); 293 294 /* proxy a PDU */ 295 enum snmpd_proxy_err (*proxy)(struct snmp_pdu *, void *, 296 const struct asn_oid *, const struct sockaddr *, socklen_t, 297 enum snmpd_input_err, int32_t, int); 298 299 /* the tree this module is going to server */ 300 const struct snmp_node *tree; 301 u_int tree_size; 302 303 /* function called, when another module was unloaded/loaded */ 304 void (*loading)(const struct lmodule *, int); 305 }; 306 307 /* 308 * Stuff exported to modules 309 */ 310 311 /* 312 * The system group. 313 */ 314 struct systemg { 315 u_char *descr; 316 struct asn_oid object_id; 317 u_char *contact; 318 u_char *name; 319 u_char *location; 320 uint32_t services; 321 uint32_t or_last_change; 322 }; 323 extern struct systemg systemg; 324 325 /* 326 * Community support. 327 * 328 * We have 2 fixed communities for SNMP read and write access. Modules 329 * can create their communities dynamically. They are deleted automatically 330 * if the module is unloaded. 331 */ 332 #define COMM_INITIALIZE 0 333 #define COMM_READ 1 334 #define COMM_WRITE 2 335 336 u_int comm_define(u_int, const char *descr, struct lmodule *, const char *str); 337 struct community *comm_define_ordered(u_int priv, const char *descr, 338 struct asn_oid *index, struct lmodule *owner, const char *str); 339 const char * comm_string(u_int); 340 341 /* community for current packet */ 342 extern u_int community; 343 344 /* 345 * SNMP User-based Security Model data. Modified via the snmp_usm(3) module. 346 */ 347 struct snmpd_usmstat { 348 uint32_t unsupported_seclevels; 349 uint32_t not_in_time_windows; 350 uint32_t unknown_users; 351 uint32_t unknown_engine_ids; 352 uint32_t wrong_digests; 353 uint32_t decrypt_errors; 354 }; 355 356 extern struct snmpd_usmstat snmpd_usmstats; 357 struct snmpd_usmstat *bsnmpd_get_usm_stats(void); 358 void bsnmpd_reset_usm_stats(void); 359 360 struct usm_user { 361 struct snmp_user suser; 362 uint8_t user_engine_id[SNMP_ENGINE_ID_SIZ]; 363 uint32_t user_engine_len; 364 char user_public[SNMP_ADM_STR32_SIZ]; 365 uint32_t user_public_len; 366 int32_t status; 367 int32_t type; 368 SLIST_ENTRY(usm_user) up; 369 }; 370 371 SLIST_HEAD(usm_userlist, usm_user); 372 struct usm_user *usm_first_user(void); 373 struct usm_user *usm_next_user(struct usm_user *); 374 struct usm_user *usm_find_user(uint8_t *, uint32_t, char *); 375 struct usm_user *usm_new_user(uint8_t *, uint32_t, char *); 376 void usm_delete_user(struct usm_user *); 377 void usm_flush_users(void); 378 379 /* USM user for current packet */ 380 extern struct usm_user *usm_user; 381 382 /* 383 * SNMP View-based Access Control Model data. Modified via the snmp_vacm(3) module. 384 */ 385 struct vacm_group; 386 387 struct vacm_user { 388 /* Security user name from USM */ 389 char secname[SNMP_ADM_STR32_SIZ]; 390 int32_t sec_model; 391 /* Back pointer to user assigned group name */ 392 struct vacm_group *group; 393 int32_t type; 394 int32_t status; 395 SLIST_ENTRY(vacm_user) vvu; 396 SLIST_ENTRY(vacm_user) vvg; 397 }; 398 399 SLIST_HEAD(vacm_userlist, vacm_user); 400 401 struct vacm_group { 402 char groupname[SNMP_ADM_STR32_SIZ]; 403 struct vacm_userlist group_users; 404 SLIST_ENTRY(vacm_group) vge; 405 }; 406 407 SLIST_HEAD(vacm_grouplist, vacm_group); 408 409 struct vacm_access { 410 /* The group name is index, not a column in the table */ 411 struct vacm_group *group; 412 char ctx_prefix[SNMP_ADM_STR32_SIZ]; 413 int32_t sec_model; 414 int32_t sec_level; 415 int32_t ctx_match; 416 struct vacm_view *read_view; 417 struct vacm_view *write_view; 418 struct vacm_view *notify_view; 419 int32_t type; 420 int32_t status; 421 TAILQ_ENTRY(vacm_access) vva; 422 }; 423 424 TAILQ_HEAD(vacm_accesslist, vacm_access); 425 426 struct vacm_view { 427 char viewname[SNMP_ADM_STR32_SIZ]; /* key */ 428 struct asn_oid subtree; /* key */ 429 uint8_t mask[16]; 430 uint8_t exclude; 431 int32_t type; 432 int32_t status; 433 SLIST_ENTRY(vacm_view) vvl; 434 }; 435 436 SLIST_HEAD(vacm_viewlist, vacm_view); 437 438 struct vacm_context { 439 /* The ID of the module that registered this context */ 440 int32_t regid; 441 char ctxname[SNMP_ADM_STR32_SIZ]; 442 SLIST_ENTRY(vacm_context) vcl; 443 }; 444 445 SLIST_HEAD(vacm_contextlist, vacm_context); 446 447 void vacm_groups_init(void); 448 struct vacm_user *vacm_first_user(void); 449 struct vacm_user *vacm_next_user(struct vacm_user *); 450 struct vacm_user *vacm_new_user(int32_t, char *); 451 int vacm_delete_user(struct vacm_user *); 452 int vacm_user_set_group(struct vacm_user *, u_char *, u_int); 453 struct vacm_access *vacm_first_access_rule(void); 454 struct vacm_access *vacm_next_access_rule(struct vacm_access *); 455 struct vacm_access *vacm_new_access_rule(char *, char *, int32_t, int32_t); 456 int vacm_delete_access_rule(struct vacm_access *); 457 struct vacm_view *vacm_first_view(void); 458 struct vacm_view *vacm_next_view(struct vacm_view *); 459 struct vacm_view *vacm_new_view(char *, struct asn_oid *); 460 int vacm_delete_view(struct vacm_view *); 461 struct vacm_context *vacm_first_context(void); 462 struct vacm_context *vacm_next_context(struct vacm_context *); 463 struct vacm_context *vacm_add_context(char *, int32_t); 464 void vacm_flush_contexts(int32_t); 465 466 /* 467 * RFC 3413 SNMP Management Target & Notification MIB 468 */ 469 470 struct snmpd_target_stats { 471 uint32_t unavail_contexts; 472 uint32_t unknown_contexts; 473 }; 474 475 #define SNMP_UDP_ADDR_SIZ 6 476 #define SNMP_TAG_SIZ (255 + 1) 477 478 struct target_address { 479 char name[SNMP_ADM_STR32_SIZ]; 480 uint8_t address[SNMP_UDP_ADDR_SIZ]; 481 int32_t timeout; 482 int32_t retry; 483 char taglist[SNMP_TAG_SIZ]; 484 char paramname[SNMP_ADM_STR32_SIZ]; 485 int32_t type; 486 int32_t socket; 487 int32_t status; 488 SLIST_ENTRY(target_address) ta; 489 }; 490 491 SLIST_HEAD(target_addresslist, target_address); 492 493 struct target_param { 494 char name[SNMP_ADM_STR32_SIZ]; 495 int32_t mpmodel; 496 int32_t sec_model; 497 char secname[SNMP_ADM_STR32_SIZ]; 498 enum snmp_usm_level sec_level; 499 int32_t type; 500 int32_t status; 501 SLIST_ENTRY(target_param) tp; 502 }; 503 504 SLIST_HEAD(target_paramlist, target_param); 505 506 struct target_notify { 507 char name[SNMP_ADM_STR32_SIZ]; 508 char taglist[SNMP_TAG_SIZ]; 509 int32_t notify_type; 510 int32_t type; 511 int32_t status; 512 SLIST_ENTRY(target_notify) tn; 513 }; 514 515 SLIST_HEAD(target_notifylist, target_notify); 516 517 extern struct snmpd_target_stats snmpd_target_stats; 518 struct snmpd_target_stats *bsnmpd_get_target_stats(void); 519 struct target_address *target_first_address(void); 520 struct target_address *target_next_address(struct target_address *); 521 struct target_address *target_new_address(char *); 522 int target_activate_address(struct target_address *); 523 int target_delete_address(struct target_address *); 524 struct target_param *target_first_param(void); 525 struct target_param *target_next_param(struct target_param *); 526 struct target_param *target_new_param(char *); 527 int target_delete_param(struct target_param *); 528 struct target_notify *target_first_notify(void); 529 struct target_notify *target_next_notify(struct target_notify *); 530 struct target_notify *target_new_notify(char *); 531 int target_delete_notify (struct target_notify *); 532 void target_flush_all(void); 533 534 /* 535 * Well known OIDs 536 */ 537 extern const struct asn_oid oid_zeroDotZero; 538 539 /* SNMPv3 Engine Discovery */ 540 extern const struct asn_oid oid_usmUnknownEngineIDs; 541 extern const struct asn_oid oid_usmNotInTimeWindows; 542 543 /* 544 * Request ID ranges. 545 * 546 * A module can request a range of request ids and associate them with a 547 * type field. All ranges are deleted if a module is unloaded. 548 */ 549 u_int reqid_allocate(int size, struct lmodule *); 550 int32_t reqid_next(u_int type); 551 int32_t reqid_base(u_int type); 552 int reqid_istype(int32_t reqid, u_int type); 553 u_int reqid_type(int32_t reqid); 554 555 /* 556 * Timers. 557 */ 558 void *timer_start(u_int, void (*)(void *), void *, struct lmodule *); 559 void *timer_start_repeat(u_int, u_int, void (*)(void *), void *, 560 struct lmodule *); 561 void timer_stop(void *); 562 563 /* 564 * File descriptors 565 */ 566 void *fd_select(int, void (*)(int, void *), void *, struct lmodule *); 567 void fd_deselect(void *); 568 void fd_suspend(void *); 569 int fd_resume(void *); 570 571 /* 572 * Object resources 573 */ 574 u_int or_register(const struct asn_oid *, const char *, struct lmodule *); 575 void or_unregister(u_int); 576 577 /* 578 * Buffers 579 */ 580 void *buf_alloc(int tx); 581 size_t buf_size(int tx); 582 583 /* decode PDU and find community */ 584 enum snmpd_input_err snmp_input_start(const u_char *, size_t, const char *, 585 struct snmp_pdu *, int32_t *, size_t *); 586 587 /* process the pdu. returns either _OK or _FAILED */ 588 enum snmpd_input_err snmp_input_finish(struct snmp_pdu *, const u_char *, 589 size_t, u_char *, size_t *, const char *, enum snmpd_input_err, int32_t, 590 void *); 591 592 void snmp_output(struct snmp_pdu *, u_char *, size_t *, const char *); 593 void snmp_send_port(void *, const struct asn_oid *, struct snmp_pdu *, 594 const struct sockaddr *, socklen_t); 595 enum snmp_code snmp_pdu_auth_access(struct snmp_pdu *, int32_t *); 596 597 /* sending traps */ 598 void snmp_send_trap(const struct asn_oid *, ...); 599 600 /* 601 * Action support 602 */ 603 int string_save(struct snmp_value *, struct snmp_context *, ssize_t, u_char **); 604 void string_commit(struct snmp_context *); 605 void string_rollback(struct snmp_context *, u_char **); 606 int string_get(struct snmp_value *, const u_char *, ssize_t); 607 int string_get_max(struct snmp_value *, const u_char *, ssize_t, size_t); 608 void string_free(struct snmp_context *); 609 610 int ip_save(struct snmp_value *, struct snmp_context *, u_char *); 611 void ip_rollback(struct snmp_context *, u_char *); 612 void ip_commit(struct snmp_context *); 613 int ip_get(struct snmp_value *, u_char *); 614 615 int oid_save(struct snmp_value *, struct snmp_context *, struct asn_oid *); 616 void oid_rollback(struct snmp_context *, struct asn_oid *); 617 void oid_commit(struct snmp_context *); 618 int oid_get(struct snmp_value *, const struct asn_oid *); 619 620 int index_decode(const struct asn_oid *oid, u_int sub, u_int code, ...); 621 int index_compare(const struct asn_oid *, u_int, const struct asn_oid *); 622 int index_compare_off(const struct asn_oid *, u_int, const struct asn_oid *, 623 u_int); 624 void index_append(struct asn_oid *, u_int, const struct asn_oid *); 625 void index_append_off(struct asn_oid *, u_int, const struct asn_oid *, u_int); 626 627 #endif 628