1 /* $OpenBSD: application_blocklist.c,v 1.1 2022/06/30 11:28:36 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 <event.h> 20 #include <stdlib.h> 21 22 #include "application.h" 23 #include "snmpd.h" 24 25 struct appl_varbind *appl_blocklist_response(size_t); 26 void appl_blocklist_get(struct appl_backend *, int32_t, int32_t, const char *, 27 struct appl_varbind *); 28 void appl_blocklist_getnext(struct appl_backend *, int32_t, int32_t, 29 const char *, struct appl_varbind *); 30 31 struct appl_backend_functions appl_blocklist_functions = { 32 .ab_get = appl_blocklist_get, 33 .ab_getnext = appl_blocklist_getnext, 34 .ab_getbulk = NULL, 35 }; 36 37 struct appl_backend appl_blocklist = { 38 .ab_name = "blocklist", 39 .ab_cookie = NULL, 40 .ab_retries = 0, 41 .ab_fn = &appl_blocklist_functions 42 }; 43 44 static struct appl_varbind *response = NULL; 45 static size_t responsesz = 0; 46 47 struct appl_varbind * 48 appl_blocklist_response(size_t nvarbind) 49 { 50 struct appl_varbind *tmp; 51 size_t i; 52 53 if (responsesz < nvarbind) { 54 if ((tmp = recallocarray(response, responsesz, nvarbind, 55 sizeof(*response))) == NULL) { 56 log_warn(NULL); 57 return NULL; 58 } 59 responsesz = nvarbind; 60 response = tmp; 61 } 62 for (i = 0; i < nvarbind; i++) 63 response[i].av_next = i + 1 == nvarbind ? 64 NULL : &(response[i + 1]); 65 return response; 66 } 67 68 void 69 appl_blocklist_init(void) 70 { 71 extern struct snmpd *snmpd_env; 72 size_t i; 73 74 for (i = 0; i < snmpd_env->sc_nblocklist; i++) 75 appl_register(NULL, 150, 1, &(snmpd_env->sc_blocklist[i]), 76 0, 1, 0, 0, &appl_blocklist); 77 } 78 79 void 80 appl_blocklist_shutdown(void) 81 { 82 appl_close(&appl_blocklist); 83 free(response); 84 } 85 86 void 87 appl_blocklist_get(struct appl_backend *backend, __unused int32_t transactionid, 88 int32_t requestid, __unused const char *ctx, struct appl_varbind *vblist) 89 { 90 struct appl_varbind *vb, *rvb, *rvblist; 91 size_t i; 92 93 for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next) 94 i++; 95 if ((rvblist = appl_blocklist_response(i)) == NULL) 96 goto fail; 97 rvb = rvblist; 98 for (vb = vblist; vb != NULL; vb = vb->av_next, rvb = rvb->av_next) { 99 rvb->av_oid = vb->av_oid; 100 rvb->av_value = appl_exception(APPL_EXC_NOSUCHOBJECT); 101 if (rvb->av_value == NULL) 102 goto fail; 103 } 104 105 appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, rvblist); 106 return; 107 fail: 108 for (rvb = rvblist; rvb != NULL && rvb->av_value != NULL; 109 rvb = rvb->av_next) 110 ober_free_elements(rvb->av_value); 111 appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vb); 112 } 113 114 void 115 appl_blocklist_getnext(struct appl_backend *backend, 116 __unused int32_t transactionid, int32_t requestid, __unused const char *ctx, 117 struct appl_varbind *vblist) 118 { 119 struct appl_varbind *vb, *rvb, *rvblist; 120 size_t i; 121 122 for (i = 0, vb = vblist; vb != NULL; vb = vb->av_next) 123 i++; 124 if ((rvblist = appl_blocklist_response(i)) == NULL) 125 goto fail; 126 rvb = rvblist; 127 for (vb = vblist; vb != NULL; vb = vb->av_next, rvb = rvb->av_next) { 128 rvb->av_oid = vb->av_oid; 129 rvb->av_value = appl_exception(APPL_EXC_ENDOFMIBVIEW); 130 if (rvb->av_value == NULL) 131 goto fail; 132 } 133 134 appl_response(backend, requestid, APPL_ERROR_NOERROR, 0, rvblist); 135 return; 136 fail: 137 for (rvb = rvblist; rvb != NULL && rvb->av_value != NULL; 138 rvb = rvb->av_next) 139 ober_free_elements(rvb->av_value); 140 appl_response(backend, requestid, APPL_ERROR_GENERR, 1, vb); 141 } 142