2 * Copyright (c) 2018, JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of JANET(UK) nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 * OF THE POSSIBILITY OF SUCH DAMAGE.
35 /* Handlers for monitoring "show" requests */
41 #include <mon_internal.h>
42 #include "mons_handlers.h"
44 typedef json_t *(MONS_SHOW_FUNC)(MONS_INSTANCE *mons);
46 /* prototypes for the dispatch table */
47 static json_t *handle_show_version(MONS_INSTANCE *mons);
49 struct dispatch_table_entry {
50 MON_OPT_TYPE opt_type;
51 MONS_SHOW_FUNC *handler;
54 struct dispatch_table_entry dispatch_table[] = {
55 {OPT_TYPE_SHOW_VERSION, handle_show_version},
56 {OPT_TYPE_SHOW_SERIAL, NULL},
57 {OPT_TYPE_SHOW_UPTIME, NULL},
58 {OPT_TYPE_SHOW_TID_REQ_COUNT, NULL},
59 {OPT_TYPE_SHOW_TID_REQ_PENDING, NULL},
60 {OPT_TYPE_SHOW_ROUTES, NULL},
61 {OPT_TYPE_SHOW_COMMUNITIES, NULL},
62 {OPT_TYPE_UNKNOWN} /* must be the last entry */
66 * Should we include this opt_type in our response to this request?
68 * Returns 1 if the opt_type is in the options list, or if the options list
73 * @return 1 if the opt_type should be included, else 0
75 static int opt_requested(MON_OPT_TYPE opt_type, MON_REQ *req)
79 /* empty options list is a wildcard - return everything */
80 if (mon_req_opt_count(req) == 0)
83 /* check whether this opt_type is in the list */
84 for (ii=0; ii<mon_req_opt_count(req); ii++) {
85 if (opt_type == mon_req_opt_index(req, ii)->type)
91 MON_RESP *mons_handle_show(TALLOC_CTX *mem_ctx, MONS_INSTANCE *mons, MON_REQ *req)
93 struct dispatch_table_entry *entry = NULL;
94 MON_RESP *resp = NULL;
95 json_t *payload = NULL; /* entire payload */
96 json_t *payload_item = NULL; /* payload for a single option */
98 tr_debug("mons_handle_show: Handling a request");
100 /* Start off by allocating our response with a generic error message */
101 resp = mon_resp_new(mem_ctx,
103 "Error processing show request",
106 /* we can't respond, just return */
107 tr_crit("mons_handle_show: Error allocating response structure.");
111 /* Now get a JSON object for our return payload */
112 payload = json_object();
113 if (payload == NULL) {
114 tr_crit("mons_handle_show: Error allocating response payload.");
115 goto cleanup; /* This will return the generic error message set earlier */
118 tr_debug("mons_handle_show: Processing options");
120 /* Now step through the dispatch table. Call each requested option type. */
121 for (entry = dispatch_table; entry->opt_type != OPT_TYPE_UNKNOWN; entry++) {
122 if (! opt_requested(entry->opt_type, req)) {
123 tr_debug("mons_handle_show: Not including %s in response",
124 mon_opt_type_to_string(entry->opt_type));
126 /* This option is needed. Add its response to our payload. */
127 if (entry->handler == NULL) {
128 tr_debug("mons_handle_show: Would include %s in response, but its handler is null",
129 mon_opt_type_to_string(entry->opt_type));
133 tr_debug("mons_handle_show: Including %s in response",
134 mon_opt_type_to_string(entry->opt_type));
136 payload_item = entry->handler(mons);
137 if (payload_item == NULL) {
138 tr_err("mons_handle_show: Error processing option %s", mon_opt_type_to_string(entry->opt_type));
141 /* this steals the reference to payload_item */
142 json_object_set_new(payload,
143 mon_opt_type_to_string(entry->opt_type),
148 /* If we get here, then we successfully processed the request. Return a successful reply. */
149 if (mon_resp_set_message(resp, "success") == 0) {
150 /* Failed to set the response message to success - fail ironically */
151 tr_crit("mons_handle_show: Error setting response message to 'success'");
155 /* Attach the accumulated payload to the response */
156 if (json_object_size(payload) > 0)
157 mon_resp_set_payload(resp, payload);
159 resp->code = MON_RESP_SUCCESS; /* at last... */
163 json_decref(payload);
168 static json_t *handle_show_version(MONS_INSTANCE *mons)
170 return json_string(PACKAGE_VERSION);