1*a9292d2aSmartijn /* $OpenBSD: application_blocklist.c,v 1.2 2023/12/21 12:43:31 martijn Exp $ */
2614c3698Smartijn
3614c3698Smartijn /*
4614c3698Smartijn * Copyright (c) 2022 Martijn van Duren <martijn@openbsd.org>
5614c3698Smartijn *
6614c3698Smartijn * Permission to use, copy, modify, and distribute this software for any
7614c3698Smartijn * purpose with or without fee is hereby granted, provided that the above
8614c3698Smartijn * copyright notice and this permission notice appear in all copies.
9614c3698Smartijn *
10614c3698Smartijn * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11614c3698Smartijn * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12614c3698Smartijn * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13614c3698Smartijn * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14614c3698Smartijn * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15614c3698Smartijn * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16614c3698Smartijn * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17614c3698Smartijn */
18614c3698Smartijn
19*a9292d2aSmartijn #include <sys/types.h>
20*a9292d2aSmartijn
21*a9292d2aSmartijn #include <stddef.h>
22*a9292d2aSmartijn
23*a9292d2aSmartijn #include <ber.h>
24*a9292d2aSmartijn #include <stdint.h>
25614c3698Smartijn #include <stdlib.h>
26614c3698Smartijn
27614c3698Smartijn #include "application.h"
28*a9292d2aSmartijn #include "log.h"
29614c3698Smartijn #include "snmpd.h"
30614c3698Smartijn
31614c3698Smartijn struct appl_varbind *appl_blocklist_response(size_t);
32614c3698Smartijn void appl_blocklist_get(struct appl_backend *, int32_t, int32_t, const char *,
33614c3698Smartijn struct appl_varbind *);
34614c3698Smartijn void appl_blocklist_getnext(struct appl_backend *, int32_t, int32_t,
35614c3698Smartijn const char *, struct appl_varbind *);
36614c3698Smartijn
37614c3698Smartijn struct appl_backend_functions appl_blocklist_functions = {
38614c3698Smartijn .ab_get = appl_blocklist_get,
39614c3698Smartijn .ab_getnext = appl_blocklist_getnext,
40614c3698Smartijn .ab_getbulk = NULL,
41614c3698Smartijn };
42614c3698Smartijn
43614c3698Smartijn struct appl_backend appl_blocklist = {
44614c3698Smartijn .ab_name = "blocklist",
45614c3698Smartijn .ab_cookie = NULL,
46614c3698Smartijn .ab_retries = 0,
47614c3698Smartijn .ab_fn = &appl_blocklist_functions
48614c3698Smartijn };
49614c3698Smartijn
50614c3698Smartijn static struct appl_varbind *response = NULL;
51614c3698Smartijn static size_t responsesz = 0;
52614c3698Smartijn
53614c3698Smartijn struct appl_varbind *
appl_blocklist_response(size_t nvarbind)54614c3698Smartijn appl_blocklist_response(size_t nvarbind)
55614c3698Smartijn {
56614c3698Smartijn struct appl_varbind *tmp;
57614c3698Smartijn size_t i;
58614c3698Smartijn
59614c3698Smartijn if (responsesz < nvarbind) {
60614c3698Smartijn if ((tmp = recallocarray(response, responsesz, nvarbind,
61614c3698Smartijn sizeof(*response))) == NULL) {
62614c3698Smartijn log_warn(NULL);
63614c3698Smartijn return NULL;
64614c3698Smartijn }
65614c3698Smartijn responsesz = nvarbind;
66614c3698Smartijn response = tmp;
67614c3698Smartijn }
68614c3698Smartijn for (i = 0; i < nvarbind; i++)
69614c3698Smartijn response[i].av_next = i + 1 == nvarbind ?
70614c3698Smartijn NULL : &(response[i + 1]);
71614c3698Smartijn return response;
72614c3698Smartijn }
73614c3698Smartijn
74614c3698Smartijn void
appl_blocklist_init(void)75614c3698Smartijn appl_blocklist_init(void)
76614c3698Smartijn {
77614c3698Smartijn extern struct snmpd *snmpd_env;
78614c3698Smartijn size_t i;
79614c3698Smartijn
80614c3698Smartijn for (i = 0; i < snmpd_env->sc_nblocklist; i++)
81614c3698Smartijn appl_register(NULL, 150, 1, &(snmpd_env->sc_blocklist[i]),
82614c3698Smartijn 0, 1, 0, 0, &appl_blocklist);
83614c3698Smartijn }
84614c3698Smartijn
85614c3698Smartijn void
appl_blocklist_shutdown(void)86614c3698Smartijn appl_blocklist_shutdown(void)
87614c3698Smartijn {
88614c3698Smartijn appl_close(&appl_blocklist);
89614c3698Smartijn free(response);
90614c3698Smartijn }
91614c3698Smartijn
92614c3698Smartijn void
appl_blocklist_get(struct appl_backend * backend,__unused int32_t transactionid,int32_t requestid,__unused const char * ctx,struct appl_varbind * vblist)93614c3698Smartijn appl_blocklist_get(struct appl_backend *backend, __unused int32_t transactionid,
94614c3698Smartijn int32_t requestid, __unused const char *ctx, struct appl_varbind *vblist)
95614c3698Smartijn {
96614c3698Smartijn struct appl_varbind *vb, *rvb, *rvblist;
97614c3698Smartijn size_t i;
98614c3698Smartijn
99614c3698Smartijn for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next)
100614c3698Smartijn i++;
101614c3698Smartijn if ((rvblist = appl_blocklist_response(i)) == NULL)
102614c3698Smartijn goto fail;
103614c3698Smartijn rvb = rvblist;
104614c3698Smartijn for (vb = vblist; vb != NULL; vb = vb->av_next, rvb = rvb->av_next) {
105614c3698Smartijn rvb->av_oid = vb->av_oid;
106614c3698Smartijn rvb->av_value = appl_exception(APPL_EXC_NOSUCHOBJECT);
107614c3698Smartijn if (rvb->av_value == NULL)
108614c3698Smartijn goto fail;
109614c3698Smartijn }
110614c3698Smartijn
111614c3698Smartijn appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, rvblist);
112614c3698Smartijn return;
113614c3698Smartijn fail:
114614c3698Smartijn for (rvb = rvblist; rvb != NULL && rvb->av_value != NULL;
115614c3698Smartijn rvb = rvb->av_next)
116614c3698Smartijn ober_free_elements(rvb->av_value);
117614c3698Smartijn appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vb);
118614c3698Smartijn }
119614c3698Smartijn
120614c3698Smartijn void
appl_blocklist_getnext(struct appl_backend * backend,__unused int32_t transactionid,int32_t requestid,__unused const char * ctx,struct appl_varbind * vblist)121614c3698Smartijn appl_blocklist_getnext(struct appl_backend *backend,
122614c3698Smartijn __unused int32_t transactionid, int32_t requestid, __unused const char *ctx,
123614c3698Smartijn struct appl_varbind *vblist)
124614c3698Smartijn {
125614c3698Smartijn struct appl_varbind *vb, *rvb, *rvblist;
126614c3698Smartijn size_t i;
127614c3698Smartijn
128614c3698Smartijn for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next)
129614c3698Smartijn i++;
130614c3698Smartijn if ((rvblist = appl_blocklist_response(i)) == NULL)
131614c3698Smartijn goto fail;
132614c3698Smartijn rvb = rvblist;
133614c3698Smartijn for (vb = vblist; vb != NULL; vb = vb->av_next, rvb = rvb->av_next) {
134614c3698Smartijn rvb->av_oid = vb->av_oid;
135614c3698Smartijn rvb->av_value = appl_exception(APPL_EXC_ENDOFMIBVIEW);
136614c3698Smartijn if (rvb->av_value == NULL)
137614c3698Smartijn goto fail;
138614c3698Smartijn }
139614c3698Smartijn
140614c3698Smartijn appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, rvblist);
141614c3698Smartijn return;
142614c3698Smartijn fail:
143614c3698Smartijn for (rvb = rvblist; rvb != NULL && rvb->av_value != NULL;
144614c3698Smartijn rvb = rvb->av_next)
145614c3698Smartijn ober_free_elements(rvb->av_value);
146614c3698Smartijn appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vb);
147614c3698Smartijn }
148