1 /* $OpenBSD: application_blocklist.c,v 1.2 2023/12/21 12:43:31 martijn Exp $ */ 2 3 /* 4 * Copyright (c) 2022 Martijn van Duren <martijn@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 21 #include <stddef.h> 22 23 #include <ber.h> 24 #include <stdint.h> 25 #include <stdlib.h> 26 27 #include "application.h" 28 #include "log.h" 29 #include "snmpd.h" 30 31 struct appl_varbind *appl_blocklist_response(size_t); 32 void appl_blocklist_get(struct appl_backend *, int32_t, int32_t, const char *, 33 struct appl_varbind *); 34 void appl_blocklist_getnext(struct appl_backend *, int32_t, int32_t, 35 const char *, struct appl_varbind *); 36 37 struct appl_backend_functions appl_blocklist_functions = { 38 .ab_get = appl_blocklist_get, 39 .ab_getnext = appl_blocklist_getnext, 40 .ab_getbulk = NULL, 41 }; 42 43 struct appl_backend appl_blocklist = { 44 .ab_name = "blocklist", 45 .ab_cookie = NULL, 46 .ab_retries = 0, 47 .ab_fn = &appl_blocklist_functions 48 }; 49 50 static struct appl_varbind *response = NULL; 51 static size_t responsesz = 0; 52 53 struct appl_varbind * 54 appl_blocklist_response(size_t nvarbind) 55 { 56 struct appl_varbind *tmp; 57 size_t i; 58 59 if (responsesz < nvarbind) { 60 if ((tmp = recallocarray(response, responsesz, nvarbind, 61 sizeof(*response))) == NULL) { 62 log_warn(NULL); 63 return NULL; 64 } 65 responsesz = nvarbind; 66 response = tmp; 67 } 68 for (i = 0; i < nvarbind; i++) 69 response[i].av_next = i + 1 == nvarbind ? 70 NULL : &(response[i + 1]); 71 return response; 72 } 73 74 void 75 appl_blocklist_init(void) 76 { 77 extern struct snmpd *snmpd_env; 78 size_t i; 79 80 for (i = 0; i < snmpd_env->sc_nblocklist; i++) 81 appl_register(NULL, 150, 1, &(snmpd_env->sc_blocklist[i]), 82 0, 1, 0, 0, &appl_blocklist); 83 } 84 85 void 86 appl_blocklist_shutdown(void) 87 { 88 appl_close(&appl_blocklist); 89 free(response); 90 } 91 92 void 93 appl_blocklist_get(struct appl_backend *backend, __unused int32_t transactionid, 94 int32_t requestid, __unused const char *ctx, struct appl_varbind *vblist) 95 { 96 struct appl_varbind *vb, *rvb, *rvblist; 97 size_t i; 98 99 for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next) 100 i++; 101 if ((rvblist = appl_blocklist_response(i)) == NULL) 102 goto fail; 103 rvb = rvblist; 104 for (vb = vblist; vb != NULL; vb = vb->av_next, rvb = rvb->av_next) { 105 rvb->av_oid = vb->av_oid; 106 rvb->av_value = appl_exception(APPL_EXC_NOSUCHOBJECT); 107 if (rvb->av_value == NULL) 108 goto fail; 109 } 110 111 appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, rvblist); 112 return; 113 fail: 114 for (rvb = rvblist; rvb != NULL && rvb->av_value != NULL; 115 rvb = rvb->av_next) 116 ober_free_elements(rvb->av_value); 117 appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vb); 118 } 119 120 void 121 appl_blocklist_getnext(struct appl_backend *backend, 122 __unused int32_t transactionid, int32_t requestid, __unused const char *ctx, 123 struct appl_varbind *vblist) 124 { 125 struct appl_varbind *vb, *rvb, *rvblist; 126 size_t i; 127 128 for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next) 129 i++; 130 if ((rvblist = appl_blocklist_response(i)) == NULL) 131 goto fail; 132 rvb = rvblist; 133 for (vb = vblist; vb != NULL; vb = vb->av_next, rvb = rvb->av_next) { 134 rvb->av_oid = vb->av_oid; 135 rvb->av_value = appl_exception(APPL_EXC_ENDOFMIBVIEW); 136 if (rvb->av_value == NULL) 137 goto fail; 138 } 139 140 appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, rvblist); 141 return; 142 fail: 143 for (rvb = rvblist; rvb != NULL && rvb->av_value != NULL; 144 rvb = rvb->av_next) 145 ober_free_elements(rvb->av_value); 146 appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vb); 147 } 148