snmpagent.c (124861) | snmpagent.c (128237) |
---|---|
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 * Redistribution of this software and documentation and use in source and --- 16 unchanged lines hidden (view full) --- 25 * FRAUNHOFER FOKUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 28 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 31 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * | 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 * Redistribution of this software and documentation and use in source and --- 16 unchanged lines hidden (view full) --- 25 * FRAUNHOFER FOKUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 28 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 31 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * |
33 * $Begemot: bsnmp/lib/snmpagent.c,v 1.16 2003/12/03 09:55:58 hbb Exp $ | 33 * $Begemot: bsnmp/lib/snmpagent.c,v 1.17 2004/04/13 14:58:46 novo Exp $ |
34 * 35 * SNMP Agent functions 36 */ 37#include <sys/types.h> 38#include <sys/queue.h> 39#include <stdio.h> 40#include <stdlib.h> 41#include <stddef.h> --- 22 unchanged lines hidden (view full) --- 64 size_t len; /* size of data part */ 65 snmp_depop_t func; 66 struct snmp_dependency dep; 67 u_char data[]; 68}; 69TAILQ_HEAD(depend_list, depend); 70 71/* | 34 * 35 * SNMP Agent functions 36 */ 37#include <sys/types.h> 38#include <sys/queue.h> 39#include <stdio.h> 40#include <stdlib.h> 41#include <stddef.h> --- 22 unchanged lines hidden (view full) --- 64 size_t len; /* size of data part */ 65 snmp_depop_t func; 66 struct snmp_dependency dep; 67 u_char data[]; 68}; 69TAILQ_HEAD(depend_list, depend); 70 71/* |
72 * Structure to hold atfinish functions during SET processing. 73 */ 74struct finish { 75 STAILQ_ENTRY(finish) link; 76 snmp_set_finish_t func; 77 void *arg; 78}; 79STAILQ_HEAD(finish_list, finish); 80 81/* | |
82 * Set context 83 */ 84struct context { 85 struct snmp_context ctx; 86 struct depend_list dlist; | 72 * Set context 73 */ 74struct context { 75 struct snmp_context ctx; 76 struct depend_list dlist; |
87 struct finish_list flist; | |
88 const struct snmp_node *node[SNMP_MAX_BINDINGS]; 89 struct snmp_scratch scratch[SNMP_MAX_BINDINGS]; 90 struct depend *depend; 91}; 92 93#define TR(W) (snmp_trace & SNMP_TRACE_##W) 94u_int snmp_trace = 0; 95 --- 7 unchanged lines hidden (view full) --- 103{ 104 struct context *context; 105 106 if ((context = malloc(sizeof(*context))) == NULL) 107 return (NULL); 108 109 memset(context, 0, sizeof(*context)); 110 TAILQ_INIT(&context->dlist); | 77 const struct snmp_node *node[SNMP_MAX_BINDINGS]; 78 struct snmp_scratch scratch[SNMP_MAX_BINDINGS]; 79 struct depend *depend; 80}; 81 82#define TR(W) (snmp_trace & SNMP_TRACE_##W) 83u_int snmp_trace = 0; 84 --- 7 unchanged lines hidden (view full) --- 92{ 93 struct context *context; 94 95 if ((context = malloc(sizeof(*context))) == NULL) 96 return (NULL); 97 98 memset(context, 0, sizeof(*context)); 99 TAILQ_INIT(&context->dlist); |
111 STAILQ_INIT(&context->flist); | |
112 113 return (&context->ctx); 114} 115 116/* 117 * Find a variable for SET/GET and the first GETBULK pass. 118 * Return the node pointer. If the search fails, set the errp to 119 * the correct SNMPv2 GET exception code. --- 496 unchanged lines hidden (view full) --- 616 asn_oid2str_r(&ctx->dep->idx, idxbuf)); 617 if (ret1 == SNMP_ERR_NOERROR) 618 ret1 = ret; 619 } 620 } 621 return (ret1); 622} 623 | 100 101 return (&context->ctx); 102} 103 104/* 105 * Find a variable for SET/GET and the first GETBULK pass. 106 * Return the node pointer. If the search fails, set the errp to 107 * the correct SNMPv2 GET exception code. --- 496 unchanged lines hidden (view full) --- 604 asn_oid2str_r(&ctx->dep->idx, idxbuf)); 605 if (ret1 == SNMP_ERR_NOERROR) 606 ret1 = ret; 607 } 608 } 609 return (ret1); 610} 611 |
612void 613snmp_dep_finish(struct snmp_context *ctx) 614{ 615 struct context *context = (struct context *)ctx; 616 struct depend *d; 617 618 while ((d = TAILQ_FIRST(&context->dlist)) != NULL) { 619 ctx->dep = &d->dep; 620 (void)d->func(ctx, ctx->dep, SNMP_DEPOP_FINISH); 621 TAILQ_REMOVE(&context->dlist, d, link); 622 free(d); 623 } 624} 625 |
|
624/* 625 * Do a SET operation. 626 */ 627enum snmp_ret 628snmp_set(struct snmp_pdu *pdu, struct asn_buf *resp_b, 629 struct snmp_pdu *resp, void *data) 630{ 631 int ret; 632 u_int i; | 626/* 627 * Do a SET operation. 628 */ 629enum snmp_ret 630snmp_set(struct snmp_pdu *pdu, struct asn_buf *resp_b, 631 struct snmp_pdu *resp, void *data) 632{ 633 int ret; 634 u_int i; |
633 enum snmp_ret code; | |
634 enum asn_err asnerr; 635 struct context context; 636 const struct snmp_node *np; | 635 enum asn_err asnerr; 636 struct context context; 637 const struct snmp_node *np; |
637 struct finish *f; 638 struct depend *d; | |
639 struct snmp_value *b; 640 enum snmp_syntax except; 641 642 memset(&context, 0, sizeof(context)); 643 TAILQ_INIT(&context.dlist); | 638 struct snmp_value *b; 639 enum snmp_syntax except; 640 641 memset(&context, 0, sizeof(context)); 642 TAILQ_INIT(&context.dlist); |
644 STAILQ_INIT(&context.flist); | |
645 context.ctx.data = data; 646 647 memset(resp, 0, sizeof(*resp)); 648 strcpy(resp->community, pdu->community); 649 resp->type = SNMP_PDU_RESPONSE; 650 resp->request_id = pdu->request_id; 651 resp->version = pdu->version; 652 --- 81 unchanged lines hidden (view full) --- 734 pdu->error_index = i + 1; 735 pdu->error_status = SNMP_ERR_GENERR; 736 snmp_pdu_free(resp); 737 return (SNMP_RET_ERR); 738 } 739 resp->nbindings++; 740 } 741 | 643 context.ctx.data = data; 644 645 memset(resp, 0, sizeof(*resp)); 646 strcpy(resp->community, pdu->community); 647 resp->type = SNMP_PDU_RESPONSE; 648 resp->request_id = pdu->request_id; 649 resp->version = pdu->version; 650 --- 81 unchanged lines hidden (view full) --- 732 pdu->error_index = i + 1; 733 pdu->error_status = SNMP_ERR_GENERR; 734 snmp_pdu_free(resp); 735 return (SNMP_RET_ERR); 736 } 737 resp->nbindings++; 738 } 739 |
742 code = SNMP_RET_OK; | 740 context.ctx.code = SNMP_RET_OK; |
743 744 /* 745 * 2. Call the SET method for each node. If a SET fails, rollback 746 * everything. Map error codes depending on the version. 747 */ 748 for (i = 0; i < pdu->nbindings; i++) { 749 b = &pdu->bindings[i]; 750 np = context.node[i]; --- 55 unchanged lines hidden (view full) --- 806 } 807 if (ret != SNMP_ERR_NOERROR) { 808 pdu->error_index = i + 1; 809 pdu->error_status = ret; 810 811 rollback(&context, pdu, i); 812 snmp_pdu_free(resp); 813 | 741 742 /* 743 * 2. Call the SET method for each node. If a SET fails, rollback 744 * everything. Map error codes depending on the version. 745 */ 746 for (i = 0; i < pdu->nbindings; i++) { 747 b = &pdu->bindings[i]; 748 np = context.node[i]; --- 55 unchanged lines hidden (view full) --- 804 } 805 if (ret != SNMP_ERR_NOERROR) { 806 pdu->error_index = i + 1; 807 pdu->error_status = ret; 808 809 rollback(&context, pdu, i); 810 snmp_pdu_free(resp); 811 |
814 code = SNMP_RET_ERR; | 812 context.ctx.code = SNMP_RET_ERR; |
815 816 goto errout; 817 } 818 } 819 820 /* 821 * 3. Call dependencies 822 */ --- 8 unchanged lines hidden (view full) --- 831 if (pdu->version != SNMP_V1) { 832 pdu->error_status = SNMP_ERR_UNDO_FAILED; 833 pdu->error_index = 0; 834 } 835 } 836 rollback(&context, pdu, i); 837 snmp_pdu_free(resp); 838 | 813 814 goto errout; 815 } 816 } 817 818 /* 819 * 3. Call dependencies 820 */ --- 8 unchanged lines hidden (view full) --- 829 if (pdu->version != SNMP_V1) { 830 pdu->error_status = SNMP_ERR_UNDO_FAILED; 831 pdu->error_index = 0; 832 } 833 } 834 rollback(&context, pdu, i); 835 snmp_pdu_free(resp); 836 |
839 code = SNMP_RET_ERR; | 837 context.ctx.code = SNMP_RET_ERR; |
840 841 goto errout; 842 } 843 844 /* 845 * 4. Commit and copy values from the original packet to the response. 846 * This is not the commit operation from RFC 1905 but rather an 847 * 'FREE RESOURCES' operation. It shouldn't fail. --- 15 unchanged lines hidden (view full) --- 863 snmp_error("set: commit failed (%d) on" 864 " variable %s index %u", ret, 865 asn_oid2str_r(&b->var, oidbuf), i); 866 } 867 868 if (snmp_fix_encoding(resp_b, resp) != SNMP_CODE_OK) { 869 snmp_error("set: fix_encoding failed"); 870 snmp_pdu_free(resp); | 838 839 goto errout; 840 } 841 842 /* 843 * 4. Commit and copy values from the original packet to the response. 844 * This is not the commit operation from RFC 1905 but rather an 845 * 'FREE RESOURCES' operation. It shouldn't fail. --- 15 unchanged lines hidden (view full) --- 861 snmp_error("set: commit failed (%d) on" 862 " variable %s index %u", ret, 863 asn_oid2str_r(&b->var, oidbuf), i); 864 } 865 866 if (snmp_fix_encoding(resp_b, resp) != SNMP_CODE_OK) { 867 snmp_error("set: fix_encoding failed"); 868 snmp_pdu_free(resp); |
871 code = SNMP_RET_IGN; | 869 context.ctx.code = SNMP_RET_IGN; |
872 } 873 874 /* 875 * Done 876 */ 877 errout: | 870 } 871 872 /* 873 * Done 874 */ 875 errout: |
878 while ((d = TAILQ_FIRST(&context.dlist)) != NULL) { 879 TAILQ_REMOVE(&context.dlist, d, link); 880 free(d); 881 } | 876 snmp_dep_finish(&context.ctx); |
882 | 877 |
883 /* 884 * call finish function 885 */ 886 while ((f = STAILQ_FIRST(&context.flist)) != NULL) { 887 STAILQ_REMOVE_HEAD(&context.flist, link); 888 (*f->func)(&context.ctx, code != SNMP_RET_OK, f->arg); 889 free(f); 890 } 891 | |
892 if (TR(SET)) | 878 if (TR(SET)) |
893 snmp_debug("set: returning %d", code); | 879 snmp_debug("set: returning %d", context.ctx.code); |
894 | 880 |
895 return (code); | 881 return (context.ctx.code); |
896} 897/* 898 * Lookup a dependency. If it doesn't exist, create one 899 */ 900struct snmp_dependency * 901snmp_dep_lookup(struct snmp_context *ctx, const struct asn_oid *obj, 902 const struct asn_oid *idx, size_t len, snmp_depop_t func) 903{ --- 32 unchanged lines hidden (view full) --- 936 d->func = func; 937 938 TAILQ_INSERT_TAIL(&context->dlist, d, link); 939 940 return (&d->dep); 941} 942 943/* | 882} 883/* 884 * Lookup a dependency. If it doesn't exist, create one 885 */ 886struct snmp_dependency * 887snmp_dep_lookup(struct snmp_context *ctx, const struct asn_oid *obj, 888 const struct asn_oid *idx, size_t len, snmp_depop_t func) 889{ --- 32 unchanged lines hidden (view full) --- 922 d->func = func; 923 924 TAILQ_INSERT_TAIL(&context->dlist, d, link); 925 926 return (&d->dep); 927} 928 929/* |
944 * Register a finish function. 945 */ 946int 947snmp_set_atfinish(struct snmp_context *ctx, snmp_set_finish_t func, void *arg) 948{ 949 struct context *context; 950 struct finish *f; 951 952 context = (struct context *)(void *) 953 ((char *)ctx - offsetof(struct context, ctx)); 954 if ((f = malloc(sizeof(struct finish))) == NULL) 955 return (-1); 956 f->func = func; 957 f->arg = arg; 958 STAILQ_INSERT_TAIL(&context->flist, f, link); 959 960 return (0); 961} 962 963/* | |
964 * Make an error response from a PDU. We do this without decoding the 965 * variable bindings. This means we can sent the junk back to a caller 966 * that has sent us junk in the first place. 967 */ 968enum snmp_ret 969snmp_make_errresp(const struct snmp_pdu *pdu, struct asn_buf *pdu_b, 970 struct asn_buf *resp_b) 971{ --- 60 unchanged lines hidden --- | 930 * Make an error response from a PDU. We do this without decoding the 931 * variable bindings. This means we can sent the junk back to a caller 932 * that has sent us junk in the first place. 933 */ 934enum snmp_ret 935snmp_make_errresp(const struct snmp_pdu *pdu, struct asn_buf *pdu_b, 936 struct asn_buf *resp_b) 937{ --- 60 unchanged lines hidden --- |