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 u_int32_t services; 321 u_int32_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 const char * comm_string(u_int); 338 339 /* community for current packet */ 340 extern u_int community; 341 342 /* 343 * SNMP User-based Security Model data. Modified via the snmp_usm(3) module. 344 */ 345 struct snmpd_usmstat { 346 uint32_t unsupported_seclevels; 347 uint32_t not_in_time_windows; 348 uint32_t unknown_users; 349 uint32_t unknown_engine_ids; 350 uint32_t wrong_digests; 351 uint32_t decrypt_errors; 352 }; 353 354 extern struct snmpd_usmstat snmpd_usmstats; 355 struct snmpd_usmstat *bsnmpd_get_usm_stats(void); 356 void bsnmpd_reset_usm_stats(void); 357 358 struct usm_user { 359 struct snmp_user suser; 360 uint8_t user_engine_id[SNMP_ENGINE_ID_SIZ]; 361 uint32_t user_engine_len; 362 char user_public[SNMP_ADM_STR32_SIZ]; 363 uint32_t user_public_len; 364 int32_t status; 365 int32_t type; 366 SLIST_ENTRY(usm_user) up; 367 }; 368 369 SLIST_HEAD(usm_userlist, usm_user); 370 struct usm_user *usm_first_user(void); 371 struct usm_user *usm_next_user(struct usm_user *); 372 struct usm_user *usm_find_user(uint8_t *, uint32_t, char *); 373 struct usm_user *usm_new_user(uint8_t *, uint32_t, char *); 374 void usm_delete_user(struct usm_user *); 375 void usm_flush_users(void); 376 377 /* USM user for current packet */ 378 extern struct usm_user *usm_user; 379 380 /* 381 * SNMP View-based Access Control Model data. Modified via the snmp_vacm(3) module. 382 */ 383 struct vacm_group; 384 385 struct vacm_user { 386 /* Security user name from USM */ 387 char secname[SNMP_ADM_STR32_SIZ]; 388 int32_t sec_model; 389 /* Back pointer to user assigned group name */ 390 struct vacm_group *group; 391 int32_t type; 392 int32_t status; 393 SLIST_ENTRY(vacm_user) vvu; 394 SLIST_ENTRY(vacm_user) vvg; 395 }; 396 397 SLIST_HEAD(vacm_userlist, vacm_user); 398 399 struct vacm_group { 400 char groupname[SNMP_ADM_STR32_SIZ]; 401 struct vacm_userlist group_users; 402 SLIST_ENTRY(vacm_group) vge; 403 }; 404 405 SLIST_HEAD(vacm_grouplist, vacm_group); 406 407 struct vacm_access { 408 /* The group name is index, not a column in the table */ 409 struct vacm_group *group; 410 char ctx_prefix[SNMP_ADM_STR32_SIZ]; 411 int32_t sec_model; 412 int32_t sec_level; 413 int32_t ctx_match; 414 struct vacm_view *read_view; 415 struct vacm_view *write_view; 416 struct vacm_view *notify_view; 417 int32_t type; 418 int32_t status; 419 TAILQ_ENTRY(vacm_access) vva; 420 }; 421 422 TAILQ_HEAD(vacm_accesslist, vacm_access); 423 424 struct vacm_view { 425 char viewname[SNMP_ADM_STR32_SIZ]; /* key */ 426 struct asn_oid subtree; /* key */ 427 uint8_t mask[16]; 428 uint8_t exclude; 429 int32_t type; 430 int32_t status; 431 SLIST_ENTRY(vacm_view) vvl; 432 }; 433 434 SLIST_HEAD(vacm_viewlist, vacm_view); 435 436 struct vacm_context { 437 /* The ID of the module that registered this context */ 438 int32_t regid; 439 char ctxname[SNMP_ADM_STR32_SIZ]; 440 SLIST_ENTRY(vacm_context) vcl; 441 }; 442 443 SLIST_HEAD(vacm_contextlist, vacm_context); 444 445 void vacm_groups_init(void); 446 struct vacm_user *vacm_first_user(void); 447 struct vacm_user *vacm_next_user(struct vacm_user *); 448 struct vacm_user *vacm_new_user(int32_t, char *); 449 int vacm_delete_user(struct vacm_user *); 450 int vacm_user_set_group(struct vacm_user *, u_char *, u_int); 451 struct vacm_access *vacm_first_access_rule(void); 452 struct vacm_access *vacm_next_access_rule(struct vacm_access *); 453 struct vacm_access *vacm_new_access_rule(char *, char *, int32_t, int32_t); 454 int vacm_delete_access_rule(struct vacm_access *); 455 struct vacm_view *vacm_first_view(void); 456 struct vacm_view *vacm_next_view(struct vacm_view *); 457 struct vacm_view *vacm_new_view(char *, struct asn_oid *); 458 int vacm_delete_view(struct vacm_view *); 459 struct vacm_context *vacm_first_context(void); 460 struct vacm_context *vacm_next_context(struct vacm_context *); 461 struct vacm_context *vacm_add_context(char *, int32_t); 462 void vacm_flush_contexts(int32_t); 463 464 /* 465 * RFC 3413 SNMP Management Target & Notification MIB 466 */ 467 468 struct snmpd_target_stats { 469 uint32_t unavail_contexts; 470 uint32_t unknown_contexts; 471 }; 472 473 #define SNMP_UDP_ADDR_SIZ 6 474 #define SNMP_TAG_SIZ (255 + 1) 475 476 struct target_address { 477 char name[SNMP_ADM_STR32_SIZ]; 478 uint8_t address[SNMP_UDP_ADDR_SIZ]; 479 int32_t timeout; 480 int32_t retry; 481 char taglist[SNMP_TAG_SIZ]; 482 char paramname[SNMP_ADM_STR32_SIZ]; 483 int32_t type; 484 int32_t socket; 485 int32_t status; 486 SLIST_ENTRY(target_address) ta; 487 }; 488 489 SLIST_HEAD(target_addresslist, target_address); 490 491 struct target_param { 492 char name[SNMP_ADM_STR32_SIZ]; 493 int32_t mpmodel; 494 int32_t sec_model; 495 char secname[SNMP_ADM_STR32_SIZ]; 496 enum snmp_usm_level sec_level; 497 int32_t type; 498 int32_t status; 499 SLIST_ENTRY(target_param) tp; 500 }; 501 502 SLIST_HEAD(target_paramlist, target_param); 503 504 struct target_notify { 505 char name[SNMP_ADM_STR32_SIZ]; 506 char taglist[SNMP_TAG_SIZ]; 507 int32_t notify_type; 508 int32_t type; 509 int32_t status; 510 SLIST_ENTRY(target_notify) tn; 511 }; 512 513 SLIST_HEAD(target_notifylist, target_notify); 514 515 extern struct snmpd_target_stats snmpd_target_stats; 516 struct snmpd_target_stats *bsnmpd_get_target_stats(void); 517 struct target_address *target_first_address(void); 518 struct target_address *target_next_address(struct target_address *); 519 struct target_address *target_new_address(char *); 520 int target_activate_address(struct target_address *); 521 int target_delete_address(struct target_address *); 522 struct target_param *target_first_param(void); 523 struct target_param *target_next_param(struct target_param *); 524 struct target_param *target_new_param(char *); 525 int target_delete_param(struct target_param *); 526 struct target_notify *target_first_notify(void); 527 struct target_notify *target_next_notify(struct target_notify *); 528 struct target_notify *target_new_notify(char *); 529 int target_delete_notify (struct target_notify *); 530 void target_flush_all(void); 531 532 /* 533 * Well known OIDs 534 */ 535 extern const struct asn_oid oid_zeroDotZero; 536 537 /* SNMPv3 Engine Discovery */ 538 extern const struct asn_oid oid_usmUnknownEngineIDs; 539 extern const struct asn_oid oid_usmNotInTimeWindows; 540 541 /* 542 * Request ID ranges. 543 * 544 * A module can request a range of request ids and associate them with a 545 * type field. All ranges are deleted if a module is unloaded. 546 */ 547 u_int reqid_allocate(int size, struct lmodule *); 548 int32_t reqid_next(u_int type); 549 int32_t reqid_base(u_int type); 550 int reqid_istype(int32_t reqid, u_int type); 551 u_int reqid_type(int32_t reqid); 552 553 /* 554 * Timers. 555 */ 556 void *timer_start(u_int, void (*)(void *), void *, struct lmodule *); 557 void *timer_start_repeat(u_int, u_int, void (*)(void *), void *, 558 struct lmodule *); 559 void timer_stop(void *); 560 561 /* 562 * File descriptors 563 */ 564 void *fd_select(int, void (*)(int, void *), void *, struct lmodule *); 565 void fd_deselect(void *); 566 void fd_suspend(void *); 567 int fd_resume(void *); 568 569 /* 570 * Object resources 571 */ 572 u_int or_register(const struct asn_oid *, const char *, struct lmodule *); 573 void or_unregister(u_int); 574 575 /* 576 * Buffers 577 */ 578 void *buf_alloc(int tx); 579 size_t buf_size(int tx); 580 581 /* decode PDU and find community */ 582 enum snmpd_input_err snmp_input_start(const u_char *, size_t, const char *, 583 struct snmp_pdu *, int32_t *, size_t *); 584 585 /* process the pdu. returns either _OK or _FAILED */ 586 enum snmpd_input_err snmp_input_finish(struct snmp_pdu *, const u_char *, 587 size_t, u_char *, size_t *, const char *, enum snmpd_input_err, int32_t, 588 void *); 589 590 void snmp_output(struct snmp_pdu *, u_char *, size_t *, const char *); 591 void snmp_send_port(void *, const struct asn_oid *, struct snmp_pdu *, 592 const struct sockaddr *, socklen_t); 593 enum snmp_code snmp_pdu_auth_access(struct snmp_pdu *, int32_t *); 594 595 /* sending traps */ 596 void snmp_send_trap(const struct asn_oid *, ...); 597 598 /* 599 * Action support 600 */ 601 int string_save(struct snmp_value *, struct snmp_context *, ssize_t, u_char **); 602 void string_commit(struct snmp_context *); 603 void string_rollback(struct snmp_context *, u_char **); 604 int string_get(struct snmp_value *, const u_char *, ssize_t); 605 int string_get_max(struct snmp_value *, const u_char *, ssize_t, size_t); 606 void string_free(struct snmp_context *); 607 608 int ip_save(struct snmp_value *, struct snmp_context *, u_char *); 609 void ip_rollback(struct snmp_context *, u_char *); 610 void ip_commit(struct snmp_context *); 611 int ip_get(struct snmp_value *, u_char *); 612 613 int oid_save(struct snmp_value *, struct snmp_context *, struct asn_oid *); 614 void oid_rollback(struct snmp_context *, struct asn_oid *); 615 void oid_commit(struct snmp_context *); 616 int oid_get(struct snmp_value *, const struct asn_oid *); 617 618 int index_decode(const struct asn_oid *oid, u_int sub, u_int code, ...); 619 int index_compare(const struct asn_oid *, u_int, const struct asn_oid *); 620 int index_compare_off(const struct asn_oid *, u_int, const struct asn_oid *, 621 u_int); 622 void index_append(struct asn_oid *, u_int, const struct asn_oid *); 623 void index_append_off(struct asn_oid *, u_int, const struct asn_oid *, u_int); 624 625 #endif 626