Deleted Added
full compact
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 ---