2 * Copyright (C) 2015-2020 Tobias Brunner
3 * Copyright (C) 2015-2018 Andreas Steffen
4 * Copyright (C) 2014 Martin Willi
6 * Copyright (C) secunet Security Networks AG
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * Copyright (C) 2014 Timo Teräs <timo.teras@iki.fi>
22 * Permission is hereby granted, free of charge, to any person obtaining a copy
23 * of this software and associated documentation files (the "Software"), to deal
24 * in the Software without restriction, including without limitation the rights
25 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26 * copies of the Software, and to permit persons to whom the Software is
27 * furnished to do so, subject to the following conditions:
29 * The above copyright notice and this permission notice shall be included in
30 * all copies or substantial portions of the Software.
32 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41 #include "vici_query.h"
42 #include "vici_builder.h"
43 #include "vici_cert_info.h"
48 #include <sys/utsname.h>
50 #if defined(HAVE_MALLINFO2) || defined (HAVE_MALLINFO)
55 #include <asn1/asn1.h>
56 #include <credentials/certificates/certificate.h>
57 #include <credentials/certificates/x509.h>
58 #include <counters_query.h>
60 ENUM(vici_counter_type_names
,
61 COUNTER_INIT_IKE_SA_REKEY
, COUNTER_OUT_INFORMATIONAL_RSP
,
75 "create-child-in-req",
76 "create-child-in-resp",
77 "create-child-out-req",
78 "create-child-out-resp",
85 typedef struct private_vici_query_t private_vici_query_t
;
88 * Private data of an vici_query_t object.
90 struct private_vici_query_t
{
93 * Public vici_query_t interface.
100 vici_dispatcher_t
*dispatcher
;
103 * Query interface for counters
105 counters_query_t
*counters
;
108 * Daemon startup timestamp
114 * Add the given mark/mask to the message using the provided labels
116 static void add_mark(vici_builder_t
*b
, mark_t mark
,
117 char *label
, char *mask_label
)
119 if (mark
.value
| mark
.mask
)
121 b
->add_kv(b
, label
, "%.8x", mark
.value
);
124 b
->add_kv(b
, mask_label
, "%.8x", mark
.mask
);
130 * List the mode of a CHILD_SA or config
132 static void list_mode(vici_builder_t
*b
, child_sa_t
*child
, child_cfg_t
*cfg
)
141 cfg
= child
->get_config(child
);
143 mode
= child
? child
->get_mode(child
) : cfg
->get_mode(cfg
);
144 if (mode
== MODE_TRANSPORT
&& cfg
->has_option(cfg
, OPT_PROXY_MODE
))
145 { /* only report this if the negotiated mode is actually TRANSPORT */
148 b
->add_kv(b
, "mode", "%N%s", ipsec_mode_names
, mode
, sub_mode
);
153 * List the security label of a CHILD_SA or config
155 static void list_label(vici_builder_t
*b
, child_sa_t
*child
, child_cfg_t
*cfg
)
157 sec_label_t
*label
= NULL
;
162 label
= child
->get_label(child
);
166 label
= cfg
->get_label(cfg
);
170 enc
= label
->get_encoding(label
);
171 b
->add_kv(b
, "label", "%+B", &enc
);
176 * List IPsec-related details about a CHILD_SA
178 static void list_child_ipsec(vici_builder_t
*b
, child_sa_t
*child
)
180 proposal_t
*proposal
;
184 b
->add_kv(b
, "protocol", "%N", protocol_id_names
,
185 child
->get_protocol(child
));
186 if (child
->has_encap(child
))
188 b
->add_kv(b
, "encap", "yes");
190 b
->add_kv(b
, "spi-in", "%.8x", ntohl(child
->get_spi(child
, TRUE
)));
191 b
->add_kv(b
, "spi-out", "%.8x", ntohl(child
->get_spi(child
, FALSE
)));
193 if (child
->get_ipcomp(child
) != IPCOMP_NONE
)
195 b
->add_kv(b
, "cpi-in", "%.4x", ntohs(child
->get_cpi(child
, TRUE
)));
196 b
->add_kv(b
, "cpi-out", "%.4x", ntohs(child
->get_cpi(child
, FALSE
)));
198 add_mark(b
, child
->get_mark(child
, TRUE
), "mark-in", "mark-mask-in");
199 add_mark(b
, child
->get_mark(child
, FALSE
), "mark-out", "mark-mask-out");
201 if_id
= child
->get_if_id(child
, TRUE
);
204 b
->add_kv(b
, "if-id-in", "%.8x", if_id
);
206 if_id
= child
->get_if_id(child
, FALSE
);
209 b
->add_kv(b
, "if-id-out", "%.8x", if_id
);
212 proposal
= child
->get_proposal(child
);
215 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
,
216 &alg
, &ks
) && alg
!= ENCR_UNDEFINED
)
218 b
->add_kv(b
, "encr-alg", "%N", encryption_algorithm_names
, alg
);
221 b
->add_kv(b
, "encr-keysize", "%u", ks
);
224 if (proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
,
225 &alg
, &ks
) && alg
!= AUTH_UNDEFINED
)
227 b
->add_kv(b
, "integ-alg", "%N", integrity_algorithm_names
, alg
);
230 b
->add_kv(b
, "integ-keysize", "%u", ks
);
233 if (proposal
->get_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
,
236 b
->add_kv(b
, "dh-group", "%N", diffie_hellman_group_names
, alg
);
238 if (proposal
->get_algorithm(proposal
, EXTENDED_SEQUENCE_NUMBERS
,
239 &alg
, NULL
) && alg
== EXT_SEQ_NUMBERS
)
241 b
->add_kv(b
, "esn", "1");
247 * List usage and lifetime stats of a CHILD_SA
249 static void list_child_stats(vici_builder_t
*b
, child_sa_t
*child
, time_t now
)
251 uint64_t bytes
, packets
;
254 child
->get_usestats(child
, TRUE
, &t
, &bytes
, &packets
);
255 b
->add_kv(b
, "bytes-in", "%" PRIu64
, bytes
);
256 b
->add_kv(b
, "packets-in", "%" PRIu64
, packets
);
259 b
->add_kv(b
, "use-in", "%"PRIu64
, (uint64_t)(now
- t
));
262 child
->get_usestats(child
, FALSE
, &t
, &bytes
, &packets
);
263 b
->add_kv(b
, "bytes-out", "%"PRIu64
, bytes
);
264 b
->add_kv(b
, "packets-out", "%"PRIu64
, packets
);
267 b
->add_kv(b
, "use-out", "%"PRIu64
, (uint64_t)(now
- t
));
270 t
= child
->get_lifetime(child
, FALSE
);
273 b
->add_kv(b
, "rekey-time", "%"PRId64
, (int64_t)(t
- now
));
275 t
= child
->get_lifetime(child
, TRUE
);
278 b
->add_kv(b
, "life-time", "%"PRId64
, (int64_t)(t
- now
));
280 t
= child
->get_installtime(child
);
281 b
->add_kv(b
, "install-time", "%"PRId64
, (int64_t)(now
- t
));
285 * List details of a CHILD_SA
287 static void list_child(private_vici_query_t
*this, vici_builder_t
*b
,
288 child_sa_t
*child
, time_t now
)
290 enumerator_t
*enumerator
;
291 traffic_selector_t
*ts
;
292 child_sa_state_t state
;
294 b
->add_kv(b
, "name", "%s", child
->get_name(child
));
295 b
->add_kv(b
, "uniqueid", "%u", child
->get_unique_id(child
));
296 b
->add_kv(b
, "reqid", "%u", child
->get_reqid(child
));
297 state
= child
->get_state(child
);
298 b
->add_kv(b
, "state", "%N", child_sa_state_names
, state
);
299 list_mode(b
, child
, NULL
);
300 list_label(b
, child
, NULL
);
304 case CHILD_INSTALLED
:
309 list_child_ipsec(b
, child
);
310 list_child_stats(b
, child
, now
);
316 b
->begin_list(b
, "local-ts");
317 enumerator
= child
->create_ts_enumerator(child
, TRUE
);
318 while (enumerator
->enumerate(enumerator
, &ts
))
320 b
->add_li(b
, "%R", ts
);
322 enumerator
->destroy(enumerator
);
323 b
->end_list(b
/* local-ts */);
325 b
->begin_list(b
, "remote-ts");
326 enumerator
= child
->create_ts_enumerator(child
, FALSE
);
327 while (enumerator
->enumerate(enumerator
, &ts
))
329 b
->add_li(b
, "%R", ts
);
331 enumerator
->destroy(enumerator
);
332 b
->end_list(b
/* remote-ts */);
336 * List tasks in a specific queue
338 static void list_task_queue(private_vici_query_t
*this, vici_builder_t
*b
,
339 ike_sa_t
*ike_sa
, task_queue_t q
, char *name
)
341 enumerator_t
*enumerator
;
345 enumerator
= ike_sa
->create_task_enumerator(ike_sa
, q
);
346 while (enumerator
->enumerate(enumerator
, &task
))
350 b
->begin_list(b
, name
);
353 b
->add_li(b
, "%N", task_type_names
, task
->get_type(task
));
355 enumerator
->destroy(enumerator
);
363 * Add an IKE_SA condition to the given builder
365 static void add_condition(vici_builder_t
*b
, ike_sa_t
*ike_sa
,
366 char *key
, ike_condition_t cond
)
368 if (ike_sa
->has_condition(ike_sa
, cond
))
370 b
->add_kv(b
, key
, "yes");
377 static void list_vips(private_vici_query_t
*this, vici_builder_t
*b
,
378 ike_sa_t
*ike_sa
, bool local
, char *name
)
380 enumerator_t
*enumerator
;
384 enumerator
= ike_sa
->create_virtual_ip_enumerator(ike_sa
, local
);
385 while (enumerator
->enumerate(enumerator
, &vip
))
389 b
->begin_list(b
, name
);
392 b
->add_li(b
, "%H", vip
);
394 enumerator
->destroy(enumerator
);
402 * List details of an IKE_SA
404 static void list_ike(private_vici_query_t
*this, vici_builder_t
*b
,
405 ike_sa_t
*ike_sa
, time_t now
)
409 identification_t
*eap
;
410 proposal_t
*proposal
;
415 b
->add_kv(b
, "uniqueid", "%u", ike_sa
->get_unique_id(ike_sa
));
416 b
->add_kv(b
, "version", "%u", ike_sa
->get_version(ike_sa
));
417 b
->add_kv(b
, "state", "%N", ike_sa_state_names
, ike_sa
->get_state(ike_sa
));
419 host
= ike_sa
->get_my_host(ike_sa
);
420 b
->add_kv(b
, "local-host", "%H", host
);
421 b
->add_kv(b
, "local-port", "%d", host
->get_port(host
));
422 b
->add_kv(b
, "local-id", "%Y", ike_sa
->get_my_id(ike_sa
));
424 host
= ike_sa
->get_other_host(ike_sa
);
425 b
->add_kv(b
, "remote-host", "%H", host
);
426 b
->add_kv(b
, "remote-port", "%d", host
->get_port(host
));
427 b
->add_kv(b
, "remote-id", "%Y", ike_sa
->get_other_id(ike_sa
));
429 eap
= ike_sa
->get_other_eap_id(ike_sa
);
431 if (!eap
->equals(eap
, ike_sa
->get_other_id(ike_sa
)))
433 if (ike_sa
->get_version(ike_sa
) == IKEV1
)
435 b
->add_kv(b
, "remote-xauth-id", "%Y", eap
);
439 b
->add_kv(b
, "remote-eap-id", "%Y", eap
);
443 id
= ike_sa
->get_id(ike_sa
);
444 if (id
->is_initiator(id
))
446 b
->add_kv(b
, "initiator", "yes");
448 b
->add_kv(b
, "initiator-spi", "%.16"PRIx64
,
449 be64toh(id
->get_initiator_spi(id
)));
450 b
->add_kv(b
, "responder-spi", "%.16"PRIx64
,
451 be64toh(id
->get_responder_spi(id
)));
453 add_condition(b
, ike_sa
, "nat-local", COND_NAT_HERE
);
454 add_condition(b
, ike_sa
, "nat-remote", COND_NAT_THERE
);
455 add_condition(b
, ike_sa
, "nat-fake", COND_NAT_FAKE
);
456 add_condition(b
, ike_sa
, "nat-any", COND_NAT_ANY
);
458 if_id
= ike_sa
->get_if_id(ike_sa
, TRUE
);
461 b
->add_kv(b
, "if-id-in", "%.8x", if_id
);
463 if_id
= ike_sa
->get_if_id(ike_sa
, FALSE
);
466 b
->add_kv(b
, "if-id-out", "%.8x", if_id
);
469 proposal
= ike_sa
->get_proposal(ike_sa
);
472 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
, &alg
, &ks
))
474 b
->add_kv(b
, "encr-alg", "%N", encryption_algorithm_names
, alg
);
477 b
->add_kv(b
, "encr-keysize", "%u", ks
);
480 if (proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
, &alg
, &ks
))
482 b
->add_kv(b
, "integ-alg", "%N", integrity_algorithm_names
, alg
);
485 b
->add_kv(b
, "integ-keysize", "%u", ks
);
488 if (proposal
->get_algorithm(proposal
, PSEUDO_RANDOM_FUNCTION
, &alg
, NULL
))
490 b
->add_kv(b
, "prf-alg", "%N", pseudo_random_function_names
, alg
);
492 if (proposal
->get_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
, &alg
, NULL
))
494 b
->add_kv(b
, "dh-group", "%N", diffie_hellman_group_names
, alg
);
497 add_condition(b
, ike_sa
, "ppk", COND_PPK
);
499 if (ike_sa
->get_state(ike_sa
) == IKE_ESTABLISHED
)
501 t
= ike_sa
->get_statistic(ike_sa
, STAT_ESTABLISHED
);
502 b
->add_kv(b
, "established", "%"PRId64
, (int64_t)(now
- t
));
503 t
= ike_sa
->get_statistic(ike_sa
, STAT_REKEY
);
506 b
->add_kv(b
, "rekey-time", "%"PRId64
, (int64_t)(t
- now
));
508 t
= ike_sa
->get_statistic(ike_sa
, STAT_REAUTH
);
511 b
->add_kv(b
, "reauth-time", "%"PRId64
, (int64_t)(t
- now
));
515 list_vips(this, b
, ike_sa
, TRUE
, "local-vips");
516 list_vips(this, b
, ike_sa
, FALSE
, "remote-vips");
518 list_task_queue(this, b
, ike_sa
, TASK_QUEUE_QUEUED
, "tasks-queued");
519 list_task_queue(this, b
, ike_sa
, TASK_QUEUE_ACTIVE
, "tasks-active");
520 list_task_queue(this, b
, ike_sa
, TASK_QUEUE_PASSIVE
, "tasks-passive");
523 CALLBACK(list_sas
, vici_message_t
*,
524 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
527 enumerator_t
*isas
, *csas
;
529 child_sa_t
*child_sa
;
532 u_int ike_id
, child_id
;
536 bl
= request
->get_str(request
, NULL
, "noblock") == NULL
;
537 ike
= request
->get_str(request
, NULL
, "ike");
538 ike_id
= request
->get_int(request
, 0, "ike-id");
539 child
= request
->get_str(request
, NULL
, "child");
540 child_id
= request
->get_int(request
, 0, "child-id");
542 isas
= charon
->controller
->create_ike_sa_enumerator(charon
->controller
, bl
);
543 while (isas
->enumerate(isas
, &ike_sa
))
545 if (ike
&& !streq(ike
, ike_sa
->get_name(ike_sa
)))
549 if (ike_id
&& ike_id
!= ike_sa
->get_unique_id(ike_sa
))
554 now
= time_monotonic(NULL
);
556 b
= vici_builder_create();
557 b
->begin_section(b
, ike_sa
->get_name(ike_sa
));
559 list_ike(this, b
, ike_sa
, now
);
561 b
->begin_section(b
, "child-sas");
562 csas
= ike_sa
->create_child_sa_enumerator(ike_sa
);
563 while (csas
->enumerate(csas
, &child_sa
))
565 if (child
&& !streq(child
, child_sa
->get_name(child_sa
)))
569 if (child_id
&& child_sa
->get_unique_id(child_sa
) != child_id
)
574 snprintf(buf
, sizeof(buf
), "%s-%u", child_sa
->get_name(child_sa
),
575 child_sa
->get_unique_id(child_sa
));
576 b
->begin_section(b
, buf
);
577 list_child(this, b
, child_sa
, now
);
581 b
->end_section(b
/* child-sas */ );
585 this->dispatcher
->raise_event(this->dispatcher
, "list-sa", id
,
590 b
= vici_builder_create();
591 return b
->finalize(b
);
595 * Raise a list-policy event for given CHILD_SA
597 static void raise_policy(private_vici_query_t
*this, u_int id
, char *ike
,
600 enumerator_t
*enumerator
;
601 traffic_selector_t
*ts
;
605 b
= vici_builder_create();
606 snprintf(buf
, sizeof(buf
), "%s/%s", ike
, child
->get_name(child
));
607 b
->begin_section(b
, buf
);
608 b
->add_kv(b
, "child", "%s", child
->get_name(child
));
609 b
->add_kv(b
, "ike", "%s", ike
);
611 list_mode(b
, child
, NULL
);
612 list_label(b
, child
, NULL
);
614 b
->begin_list(b
, "local-ts");
615 enumerator
= child
->create_ts_enumerator(child
, TRUE
);
616 while (enumerator
->enumerate(enumerator
, &ts
))
618 b
->add_li(b
, "%R", ts
);
620 enumerator
->destroy(enumerator
);
621 b
->end_list(b
/* local-ts */);
623 b
->begin_list(b
, "remote-ts");
624 enumerator
= child
->create_ts_enumerator(child
, FALSE
);
625 while (enumerator
->enumerate(enumerator
, &ts
))
627 b
->add_li(b
, "%R", ts
);
629 enumerator
->destroy(enumerator
);
630 b
->end_list(b
/* remote-ts */);
634 this->dispatcher
->raise_event(this->dispatcher
, "list-policy", id
,
639 * Raise a list-policy event for given CHILD_SA config
641 static void raise_policy_cfg(private_vici_query_t
*this, u_int id
, char *ike
,
644 enumerator_t
*enumerator
;
646 traffic_selector_t
*ts
;
650 b
= vici_builder_create();
651 snprintf(buf
, sizeof(buf
), "%s%s%s", ike
? ike
: "", ike
? "/" : "",
653 b
->begin_section(b
, buf
);
654 b
->add_kv(b
, "child", "%s", cfg
->get_name(cfg
));
657 b
->add_kv(b
, "ike", "%s", ike
);
660 list_mode(b
, NULL
, cfg
);
661 list_label(b
, NULL
, cfg
);
663 b
->begin_list(b
, "local-ts");
664 list
= cfg
->get_traffic_selectors(cfg
, TRUE
, NULL
, NULL
, FALSE
);
665 enumerator
= list
->create_enumerator(list
);
666 while (enumerator
->enumerate(enumerator
, &ts
))
668 b
->add_li(b
, "%R", ts
);
670 enumerator
->destroy(enumerator
);
671 list
->destroy_offset(list
, offsetof(traffic_selector_t
, destroy
));
672 b
->end_list(b
/* local-ts */);
674 b
->begin_list(b
, "remote-ts");
675 list
= cfg
->get_traffic_selectors(cfg
, FALSE
, NULL
, NULL
, FALSE
);
676 enumerator
= list
->create_enumerator(list
);
677 while (enumerator
->enumerate(enumerator
, &ts
))
679 b
->add_li(b
, "%R", ts
);
681 enumerator
->destroy(enumerator
);
682 list
->destroy_offset(list
, offsetof(traffic_selector_t
, destroy
));
683 b
->end_list(b
/* remote-ts */);
687 this->dispatcher
->raise_event(this->dispatcher
, "list-policy", id
,
691 CALLBACK(list_policies
, vici_message_t
*,
692 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
694 enumerator_t
*enumerator
;
696 child_sa_t
*child_sa
;
697 peer_cfg_t
*peer_cfg
;
698 child_cfg_t
*child_cfg
;
699 bool drop
, pass
, trap
;
700 char *child
, *ike
, *ns
;
702 drop
= request
->get_str(request
, NULL
, "drop") != NULL
;
703 pass
= request
->get_str(request
, NULL
, "pass") != NULL
;
704 trap
= request
->get_str(request
, NULL
, "trap") != NULL
;
705 child
= request
->get_str(request
, NULL
, "child");
706 ike
= request
->get_str(request
, NULL
, "ike");
710 enumerator
= charon
->traps
->create_enumerator(charon
->traps
);
711 while (enumerator
->enumerate(enumerator
, &peer_cfg
, &child_sa
))
713 if ((ike
&& !streq(ike
, peer_cfg
->get_name(peer_cfg
))) ||
714 (child
&& !streq(child
, child_sa
->get_name(child_sa
))))
718 raise_policy(this, id
, peer_cfg
->get_name(peer_cfg
), child_sa
);
720 enumerator
->destroy(enumerator
);
725 enumerator
= charon
->shunts
->create_enumerator(charon
->shunts
);
726 while (enumerator
->enumerate(enumerator
, &ns
, &child_cfg
))
728 if ((ike
&& !streq(ike
, ns
)) ||
729 (child
&& !streq(child
, child_cfg
->get_name(child_cfg
))))
733 switch (child_cfg
->get_mode(child_cfg
))
738 raise_policy_cfg(this, id
, ns
, child_cfg
);
744 raise_policy_cfg(this, id
, ns
, child_cfg
);
751 enumerator
->destroy(enumerator
);
754 b
= vici_builder_create();
755 return b
->finalize(b
);
759 * Build sections for auth configs, local or remote
761 static void build_auth_cfgs(peer_cfg_t
*peer_cfg
, bool local
, vici_builder_t
*b
)
763 enumerator_t
*enumerator
, *rules
;
768 identification_t
*id
;
775 enumerator
= peer_cfg
->create_auth_cfg_enumerator(peer_cfg
, local
);
776 while (enumerator
->enumerate(enumerator
, &auth
))
778 snprintf(buf
, sizeof(buf
), "%s-%d", local
? "local" : "remote", ++i
);
779 b
->begin_section(b
, buf
);
781 rules
= auth
->create_enumerator(auth
);
782 while (rules
->enumerate(rules
, &rule
, &v
))
786 case AUTH_RULE_AUTH_CLASS
:
787 b
->add_kv(b
, "class", "%N", auth_class_names
, v
.u
);
789 case AUTH_RULE_EAP_TYPE
:
790 b
->add_kv(b
, "eap-type", "%N", eap_type_names
, v
.u
);
792 case AUTH_RULE_EAP_VENDOR
:
793 b
->add_kv(b
, "eap-vendor", "%u", v
.u
);
795 case AUTH_RULE_XAUTH_BACKEND
:
796 b
->add_kv(b
, "xauth", "%s", v
.str
);
798 case AUTH_RULE_CRL_VALIDATION
:
799 b
->add_kv(b
, "revocation", "%N", cert_validation_names
, v
.u
);
801 case AUTH_RULE_IDENTITY
:
802 b
->add_kv(b
, "id", "%Y", v
.id
);
804 case AUTH_RULE_CA_IDENTITY
:
805 b
->add_kv(b
, "ca_id", "%Y", v
.id
);
807 case AUTH_RULE_AAA_IDENTITY
:
808 b
->add_kv(b
, "aaa_id", "%Y", v
.id
);
810 case AUTH_RULE_EAP_IDENTITY
:
811 b
->add_kv(b
, "eap_id", "%Y", v
.id
);
813 case AUTH_RULE_XAUTH_IDENTITY
:
814 b
->add_kv(b
, "xauth_id", "%Y", v
.id
);
820 rules
->destroy(rules
);
822 b
->begin_list(b
, "groups");
823 rules
= auth
->create_enumerator(auth
);
824 while (rules
->enumerate(rules
, &rule
, &v
))
826 if (rule
== AUTH_RULE_GROUP
)
828 b
->add_li(b
, "%Y", v
.id
);
831 rules
->destroy(rules
);
834 b
->begin_list(b
, "cert_policy");
835 rules
= auth
->create_enumerator(auth
);
836 while (rules
->enumerate(rules
, &rule
, &v
))
838 if (rule
== AUTH_RULE_CERT_POLICY
)
840 b
->add_li(b
, "%s", v
.str
);
843 rules
->destroy(rules
);
846 b
->begin_list(b
, "certs");
847 rules
= auth
->create_enumerator(auth
);
848 while (rules
->enumerate(rules
, &rule
, &v
))
850 if (rule
== AUTH_RULE_SUBJECT_CERT
)
852 b
->add_li(b
, "%Y", v
.cert
->get_subject(v
.cert
));
855 rules
->destroy(rules
);
858 b
->begin_list(b
, "cacerts");
859 rules
= auth
->create_enumerator(auth
);
860 while (rules
->enumerate(rules
, &rule
, &v
))
862 if (rule
== AUTH_RULE_CA_CERT
)
864 b
->add_li(b
, "%Y", v
.cert
->get_subject(v
.cert
));
867 rules
->destroy(rules
);
872 enumerator
->destroy(enumerator
);
875 CALLBACK(list_conns
, vici_message_t
*,
876 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
878 enumerator_t
*enumerator
, *tokens
, *selectors
, *children
;
879 peer_cfg_t
*peer_cfg
;
881 child_cfg_t
*child_cfg
;
882 char *ike
, *str
, *interface
;
883 uint32_t manual_prio
, dpd_delay
, dpd_timeout
;
884 identification_t
*ppk_id
;
886 traffic_selector_t
*ts
;
890 ike
= request
->get_str(request
, NULL
, "ike");
892 enumerator
= charon
->backends
->create_peer_cfg_enumerator(charon
->backends
,
893 NULL
, NULL
, NULL
, NULL
, IKE_ANY
);
894 while (enumerator
->enumerate(enumerator
, &peer_cfg
))
896 if (ike
&& !streq(ike
, peer_cfg
->get_name(peer_cfg
)))
901 b
= vici_builder_create();
902 b
->begin_section(b
, peer_cfg
->get_name(peer_cfg
));
904 ike_cfg
= peer_cfg
->get_ike_cfg(peer_cfg
);
906 b
->begin_list(b
, "local_addrs");
907 str
= ike_cfg
->get_my_addr(ike_cfg
);
908 tokens
= enumerator_create_token(str
, ",", " ");
909 while (tokens
->enumerate(tokens
, &str
))
911 b
->add_li(b
, "%s", str
);
913 tokens
->destroy(tokens
);
916 b
->begin_list(b
, "remote_addrs");
917 str
= ike_cfg
->get_other_addr(ike_cfg
);
918 tokens
= enumerator_create_token(str
, ",", " ");
919 while (tokens
->enumerate(tokens
, &str
))
921 b
->add_li(b
, "%s", str
);
923 tokens
->destroy(tokens
);
926 b
->add_kv(b
, "version", "%N", ike_version_names
,
927 peer_cfg
->get_ike_version(peer_cfg
));
928 b
->add_kv(b
, "reauth_time", "%u",
929 peer_cfg
->get_reauth_time(peer_cfg
, FALSE
));
930 b
->add_kv(b
, "rekey_time", "%u",
931 peer_cfg
->get_rekey_time(peer_cfg
, FALSE
));
932 b
->add_kv(b
, "unique", "%N", unique_policy_names
,
933 peer_cfg
->get_unique_policy(peer_cfg
));
935 dpd_delay
= peer_cfg
->get_dpd(peer_cfg
);
938 b
->add_kv(b
, "dpd_delay", "%u", dpd_delay
);
941 dpd_timeout
= peer_cfg
->get_dpd_timeout(peer_cfg
);
944 b
->add_kv(b
, "dpd_timeout", "%u", dpd_timeout
);
947 ppk_id
= peer_cfg
->get_ppk_id(peer_cfg
);
950 b
->add_kv(b
, "ppk_id", "%Y", ppk_id
);
952 if (peer_cfg
->ppk_required(peer_cfg
))
954 b
->add_kv(b
, "ppk_required", "yes");
957 build_auth_cfgs(peer_cfg
, TRUE
, b
);
958 build_auth_cfgs(peer_cfg
, FALSE
, b
);
960 b
->begin_section(b
, "children");
962 children
= peer_cfg
->create_child_cfg_enumerator(peer_cfg
);
963 while (children
->enumerate(children
, &child_cfg
))
965 b
->begin_section(b
, child_cfg
->get_name(child_cfg
));
967 list_mode(b
, NULL
, child_cfg
);
968 list_label(b
, NULL
, child_cfg
);
970 lft
= child_cfg
->get_lifetime(child_cfg
, FALSE
);
971 b
->add_kv(b
, "rekey_time", "%"PRIu64
, lft
->time
.rekey
);
972 b
->add_kv(b
, "rekey_bytes", "%"PRIu64
, lft
->bytes
.rekey
);
973 b
->add_kv(b
, "rekey_packets", "%"PRIu64
, lft
->packets
.rekey
);
976 b
->add_kv(b
, "dpd_action", "%N", action_names
,
977 child_cfg
->get_dpd_action(child_cfg
));
978 b
->add_kv(b
, "close_action", "%N", action_names
,
979 child_cfg
->get_close_action(child_cfg
));
981 b
->begin_list(b
, "local-ts");
982 list
= child_cfg
->get_traffic_selectors(child_cfg
, TRUE
, NULL
,
984 selectors
= list
->create_enumerator(list
);
985 while (selectors
->enumerate(selectors
, &ts
))
987 b
->add_li(b
, "%R", ts
);
989 selectors
->destroy(selectors
);
990 list
->destroy_offset(list
, offsetof(traffic_selector_t
, destroy
));
991 b
->end_list(b
/* local-ts */);
993 b
->begin_list(b
, "remote-ts");
994 list
= child_cfg
->get_traffic_selectors(child_cfg
, FALSE
, NULL
,
996 selectors
= list
->create_enumerator(list
);
997 while (selectors
->enumerate(selectors
, &ts
))
999 b
->add_li(b
, "%R", ts
);
1001 selectors
->destroy(selectors
);
1002 list
->destroy_offset(list
, offsetof(traffic_selector_t
, destroy
));
1003 b
->end_list(b
/* remote-ts */);
1005 interface
= child_cfg
->get_interface(child_cfg
);
1008 b
->add_kv(b
, "interface", "%s", interface
);
1011 manual_prio
= child_cfg
->get_manual_prio(child_cfg
);
1014 b
->add_kv(b
, "priority", "%u", manual_prio
);
1019 children
->destroy(children
);
1021 b
->end_section(b
); /* children */
1023 b
->end_section(b
); /* name */
1025 this->dispatcher
->raise_event(this->dispatcher
, "list-conn", id
,
1028 enumerator
->destroy(enumerator
);
1030 b
= vici_builder_create();
1031 return b
->finalize(b
);
1035 * Do we have a private key for given certificate
1037 static bool has_privkey(certificate_t
*cert
)
1039 private_key_t
*private;
1040 public_key_t
*public;
1041 identification_t
*keyid
;
1045 public = cert
->get_public_key(cert
);
1048 if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1
, &chunk
))
1050 keyid
= identification_create_from_encoding(ID_KEY_ID
, chunk
);
1051 private = lib
->credmgr
->get_private(lib
->credmgr
,
1052 public->get_type(public), keyid
, NULL
);
1056 private->destroy(private);
1058 keyid
->destroy(keyid
);
1060 public->destroy(public);
1066 * Store cert filter data
1069 certificate_type_t type
;
1071 identification_t
*subject
;
1075 * Enumerate all X.509 certificates with a given flag
1077 static void enum_x509(private_vici_query_t
*this, u_int id
,
1078 linked_list_t
*certs
, cert_filter_t
*filter
,
1081 enumerator_t
*enumerator
;
1082 certificate_t
*cert
;
1087 if (filter
->type
!= CERT_ANY
&& filter
->flag
!= X509_ANY
&&
1088 filter
->flag
!= flag
)
1093 enumerator
= certs
->create_enumerator(certs
);
1094 while (enumerator
->enumerate(enumerator
, &cert
))
1096 x509
= (x509_t
*)cert
;
1097 if ((x509
->get_flags(x509
) & X509_ANY
) != flag
)
1102 if (cert
->get_encoding(cert
, CERT_ASN1_DER
, &encoding
))
1104 b
= vici_builder_create();
1105 b
->add_kv(b
, "type", "%N", certificate_type_names
, CERT_X509
);
1106 b
->add_kv(b
, "flag", "%N", x509_flag_names
, flag
);
1107 if (has_privkey(cert
))
1109 b
->add_kv(b
, "has_privkey", "yes");
1111 b
->add(b
, VICI_KEY_VALUE
, "data", encoding
);
1114 this->dispatcher
->raise_event(this->dispatcher
, "list-cert", id
,
1118 enumerator
->destroy(enumerator
);
1122 * Enumerate all non-X.509 certificate types
1124 static void enum_others(private_vici_query_t
*this, u_int id
,
1125 linked_list_t
*certs
, certificate_type_t type
)
1127 enumerator_t
*enumerator
;
1128 certificate_t
*cert
;
1130 chunk_t encoding
, t_ch
;
1131 cred_encoding_type_t encoding_type
;
1132 identification_t
*subject
;
1133 time_t not_before
, not_after
;
1135 encoding_type
= (type
== CERT_TRUSTED_PUBKEY
) ? PUBKEY_SPKI_ASN1_DER
:
1138 enumerator
= certs
->create_enumerator(certs
);
1139 while (enumerator
->enumerate(enumerator
, &cert
))
1141 if (cert
->get_encoding(cert
, encoding_type
, &encoding
))
1143 b
= vici_builder_create();
1144 b
->add_kv(b
, "type", "%N", certificate_type_names
, type
);
1145 if (has_privkey(cert
))
1147 b
->add_kv(b
, "has_privkey", "yes");
1149 b
->add(b
, VICI_KEY_VALUE
, "data", encoding
);
1152 if (type
== CERT_TRUSTED_PUBKEY
)
1154 subject
= cert
->get_subject(cert
);
1155 if (subject
->get_type(subject
) != ID_KEY_ID
)
1157 b
->add_kv(b
, "subject", "%Y", cert
->get_subject(cert
));
1159 cert
->get_validity(cert
, NULL
, ¬_before
, ¬_after
);
1160 if (not_before
!= UNDEFINED_TIME
)
1162 t_ch
= asn1_from_time(¬_before
, ASN1_GENERALIZEDTIME
);
1163 b
->add(b
, VICI_KEY_VALUE
, "not-before", chunk_skip(t_ch
, 2));
1166 if (not_after
!= UNDEFINED_TIME
)
1168 t_ch
= asn1_from_time(¬_after
, ASN1_GENERALIZEDTIME
);
1169 b
->add(b
, VICI_KEY_VALUE
, "not-after", chunk_skip(t_ch
, 2));
1173 this->dispatcher
->raise_event(this->dispatcher
, "list-cert", id
,
1177 enumerator
->destroy(enumerator
);
1181 * Enumerate all certificates of a given type
1183 static void enum_certs(private_vici_query_t
*this, u_int id
,
1184 cert_filter_t
*filter
, certificate_type_t type
)
1186 enumerator_t
*e1
, *e2
;
1187 certificate_t
*cert
, *current
;
1188 linked_list_t
*certs
;
1191 if (filter
->type
!= CERT_ANY
&& filter
->type
!= type
)
1195 certs
= linked_list_create();
1197 e1
= lib
->credmgr
->create_cert_enumerator(lib
->credmgr
, type
, KEY_ANY
,
1198 filter
->subject
, FALSE
);
1199 while (e1
->enumerate(e1
, &cert
))
1203 e2
= certs
->create_enumerator(certs
);
1204 while (e2
->enumerate(e2
, ¤t
))
1206 if (current
->equals(current
, cert
))
1216 certs
->insert_last(certs
, cert
->get_ref(cert
));
1221 if (type
== CERT_X509
)
1223 enum_x509(this, id
, certs
, filter
, X509_NONE
);
1224 enum_x509(this, id
, certs
, filter
, X509_CA
);
1225 enum_x509(this, id
, certs
, filter
, X509_AA
);
1226 enum_x509(this, id
, certs
, filter
, X509_OCSP_SIGNER
);
1230 enum_others(this, id
, certs
, type
);
1232 certs
->destroy_offset(certs
, offsetof(certificate_t
, destroy
));
1235 CALLBACK(list_certs
, vici_message_t
*,
1236 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
1238 cert_filter_t filter
= {
1246 str
= request
->get_str(request
, "ANY", "type");
1247 if (enum_from_name(certificate_type_names
, str
, &filter
.type
))
1249 if (filter
.type
== CERT_X509
)
1251 str
= request
->get_str(request
, "ANY", "flag");
1252 if (!enum_from_name(x509_flag_names
, str
, &filter
.flag
))
1254 DBG1(DBG_CFG
, "invalid certificate flag '%s'", str
);
1259 else if (!vici_cert_info_from_str(str
, &filter
.type
, &filter
.flag
))
1261 DBG1(DBG_CFG
, "invalid certificate type '%s'", str
);
1265 str
= request
->get_str(request
, NULL
, "subject");
1268 filter
.subject
= identification_create_from_string(str
);
1271 enum_certs(this, id
, &filter
, CERT_TRUSTED_PUBKEY
);
1272 enum_certs(this, id
, &filter
, CERT_X509
);
1273 enum_certs(this, id
, &filter
, CERT_X509_AC
);
1274 enum_certs(this, id
, &filter
, CERT_X509_CRL
);
1275 enum_certs(this, id
, &filter
, CERT_X509_OCSP_RESPONSE
);
1276 DESTROY_IF(filter
.subject
);
1279 b
= vici_builder_create();
1280 return b
->finalize(b
);
1284 * Add a key/value pair of ALG => plugin
1286 static void add_algorithm(vici_builder_t
*b
, enum_name_t
*alg_names
,
1287 int alg_type
, const char *plugin_name
)
1289 char alg_name
[BUF_LEN
];
1291 sprintf(alg_name
, "%N", alg_names
, alg_type
);
1292 b
->add_kv(b
, alg_name
, (char*)plugin_name
);
1295 CALLBACK(get_algorithms
, vici_message_t
*,
1296 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
1299 enumerator_t
*enumerator
;
1300 encryption_algorithm_t encryption
;
1301 integrity_algorithm_t integrity
;
1302 hash_algorithm_t hash
;
1303 pseudo_random_function_t prf
;
1304 ext_out_function_t xof
;
1305 key_derivation_function_t kdf
;
1307 diffie_hellman_group_t group
;
1308 rng_quality_t quality
;
1309 const char *plugin_name
;
1311 b
= vici_builder_create();
1313 b
->begin_section(b
, "encryption");
1314 enumerator
= lib
->crypto
->create_crypter_enumerator(lib
->crypto
);
1315 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
1317 add_algorithm(b
, encryption_algorithm_names
, encryption
, plugin_name
);
1319 enumerator
->destroy(enumerator
);
1322 b
->begin_section(b
, "integrity");
1323 enumerator
= lib
->crypto
->create_signer_enumerator(lib
->crypto
);
1324 while (enumerator
->enumerate(enumerator
, &integrity
, &plugin_name
))
1326 add_algorithm(b
, integrity_algorithm_names
, integrity
, plugin_name
);
1328 enumerator
->destroy(enumerator
);
1331 b
->begin_section(b
, "aead");
1332 enumerator
= lib
->crypto
->create_aead_enumerator(lib
->crypto
);
1333 while (enumerator
->enumerate(enumerator
, &encryption
, &plugin_name
))
1335 add_algorithm(b
, encryption_algorithm_names
, encryption
, plugin_name
);
1337 enumerator
->destroy(enumerator
);
1340 b
->begin_section(b
, "hasher");
1341 enumerator
= lib
->crypto
->create_hasher_enumerator(lib
->crypto
);
1342 while (enumerator
->enumerate(enumerator
, &hash
, &plugin_name
))
1344 add_algorithm(b
, hash_algorithm_names
, hash
, plugin_name
);
1346 enumerator
->destroy(enumerator
);
1349 b
->begin_section(b
, "prf");
1350 enumerator
= lib
->crypto
->create_prf_enumerator(lib
->crypto
);
1351 while (enumerator
->enumerate(enumerator
, &prf
, &plugin_name
))
1353 add_algorithm(b
, pseudo_random_function_names
, prf
, plugin_name
);
1355 enumerator
->destroy(enumerator
);
1358 b
->begin_section(b
, "xof");
1359 enumerator
= lib
->crypto
->create_xof_enumerator(lib
->crypto
);
1360 while (enumerator
->enumerate(enumerator
, &xof
, &plugin_name
))
1362 add_algorithm(b
, ext_out_function_names
, xof
, plugin_name
);
1364 enumerator
->destroy(enumerator
);
1367 b
->begin_section(b
, "kdf");
1368 enumerator
= lib
->crypto
->create_kdf_enumerator(lib
->crypto
);
1369 while (enumerator
->enumerate(enumerator
, &kdf
, &plugin_name
))
1371 add_algorithm(b
, key_derivation_function_names
, kdf
, plugin_name
);
1373 enumerator
->destroy(enumerator
);
1376 b
->begin_section(b
, "drbg");
1377 enumerator
= lib
->crypto
->create_drbg_enumerator(lib
->crypto
);
1378 while (enumerator
->enumerate(enumerator
, &drbg
, &plugin_name
))
1380 add_algorithm(b
, drbg_type_names
, drbg
, plugin_name
);
1382 enumerator
->destroy(enumerator
);
1385 b
->begin_section(b
, "dh");
1386 enumerator
= lib
->crypto
->create_dh_enumerator(lib
->crypto
);
1387 while (enumerator
->enumerate(enumerator
, &group
, &plugin_name
))
1389 add_algorithm(b
, diffie_hellman_group_names
, group
, plugin_name
);
1391 enumerator
->destroy(enumerator
);
1394 b
->begin_section(b
, "rng");
1395 enumerator
= lib
->crypto
->create_rng_enumerator(lib
->crypto
);
1396 while (enumerator
->enumerate(enumerator
, &quality
, &plugin_name
))
1398 add_algorithm(b
, rng_quality_names
, quality
, plugin_name
);
1400 enumerator
->destroy(enumerator
);
1403 b
->begin_section(b
, "nonce-gen");
1404 enumerator
= lib
->crypto
->create_nonce_gen_enumerator(lib
->crypto
);
1405 while (enumerator
->enumerate(enumerator
, &plugin_name
))
1407 b
->add_kv(b
, "NONCE_GEN", (char*)plugin_name
);
1409 enumerator
->destroy(enumerator
);
1412 return b
->finalize(b
);
1416 * Make sure we have the counters query interface
1418 static inline bool ensure_counters(private_vici_query_t
*this)
1424 return (this->counters
= lib
->get(lib
, "counters")) != NULL
;
1428 * Add a single set of counters to the message
1430 * Frees the array of counter values
1432 static void add_counters(vici_builder_t
*b
, char *name
, uint64_t *counters
)
1437 b
->begin_section(b
, name
?: "");
1438 for (i
= 0; i
< COUNTER_MAX
; i
++)
1440 snprintf(buf
, sizeof(buf
), "%N", vici_counter_type_names
, i
);
1441 b
->add_kv(b
, buf
, "%"PRIu64
, counters
[i
]);
1447 CALLBACK(get_counters
, vici_message_t
*,
1448 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
1451 enumerator_t
*enumerator
;
1453 char *conn
, *errmsg
= NULL
;
1456 b
= vici_builder_create();
1458 if (ensure_counters(this))
1460 conn
= request
->get_str(request
, NULL
, "name");
1461 all
= request
->get_bool(request
, FALSE
, "all");
1463 b
->begin_section(b
, "counters");
1466 enumerator
= this->counters
->get_names(this->counters
);
1467 while (enumerator
->enumerate(enumerator
, &conn
))
1469 counters
= this->counters
->get_all(this->counters
, conn
);
1472 add_counters(b
, conn
, counters
);
1475 enumerator
->destroy(enumerator
);
1479 counters
= this->counters
->get_all(this->counters
, conn
);
1482 add_counters(b
, conn
, counters
);
1486 errmsg
= "no counters found for this connection";
1493 errmsg
= "no counters available (plugin missing?)";
1496 b
->add_kv(b
, "success", errmsg
? "no" : "yes");
1499 b
->add_kv(b
, "errmsg", "%s", errmsg
);
1501 return b
->finalize(b
);
1504 CALLBACK(reset_counters
, vici_message_t
*,
1505 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
1508 char *conn
, *errmsg
= NULL
;
1511 b
= vici_builder_create();
1513 if (ensure_counters(this))
1515 conn
= request
->get_str(request
, NULL
, "name");
1516 all
= request
->get_bool(request
, FALSE
, "all");
1520 this->counters
->reset_all(this->counters
);
1524 this->counters
->reset(this->counters
, conn
);
1529 errmsg
= "no counters available (plugin missing?)";
1532 b
->add_kv(b
, "success", errmsg
? "no" : "yes");
1535 b
->add_kv(b
, "errmsg", "%s", errmsg
);
1537 return b
->finalize(b
);
1540 CALLBACK(version
, vici_message_t
*,
1541 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
1545 b
= vici_builder_create();
1546 b
->add_kv(b
, "daemon", "%s", lib
->ns
);
1547 b
->add_kv(b
, "version", "%s", VERSION
);
1551 OSVERSIONINFOEX osvie
;
1553 memset(&osvie
, 0, sizeof(osvie
));
1554 osvie
.dwOSVersionInfoSize
= sizeof(osvie
);
1556 if (GetVersionEx((LPOSVERSIONINFO
)&osvie
))
1558 b
->add_kv(b
, "sysname", "Windows %s",
1559 osvie
.wProductType
== VER_NT_WORKSTATION
? "Client" : "Server");
1560 b
->add_kv(b
, "release", "%d.%d.%d (SP %d.%d)",
1561 osvie
.dwMajorVersion
, osvie
.dwMinorVersion
, osvie
.dwBuildNumber
,
1562 osvie
.wServicePackMajor
, osvie
.wServicePackMinor
);
1563 b
->add_kv(b
, "machine", "%s",
1573 struct utsname utsname
;
1575 if (uname(&utsname
) == 0)
1577 b
->add_kv(b
, "sysname", "%s", utsname
.sysname
);
1578 b
->add_kv(b
, "release", "%s", utsname
.release
);
1579 b
->add_kv(b
, "machine", "%s", utsname
.machine
);
1583 return b
->finalize(b
);
1586 CALLBACK(stats
, vici_message_t
*,
1587 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
1590 enumerator_t
*enumerator
;
1595 b
= vici_builder_create();
1597 now
= time_monotonic(NULL
);
1598 since
= time(NULL
) - (now
- this->uptime
);
1600 b
->begin_section(b
, "uptime");
1601 b
->add_kv(b
, "running", "%V", &now
, &this->uptime
);
1602 b
->add_kv(b
, "since", "%T", &since
, FALSE
);
1605 b
->begin_section(b
, "workers");
1606 b
->add_kv(b
, "total", "%d",
1607 lib
->processor
->get_total_threads(lib
->processor
));
1608 b
->add_kv(b
, "idle", "%d",
1609 lib
->processor
->get_idle_threads(lib
->processor
));
1610 b
->begin_section(b
, "active");
1611 for (i
= 0; i
< JOB_PRIO_MAX
; i
++)
1613 b
->add_kv(b
, enum_to_name(job_priority_names
, i
), "%d",
1614 lib
->processor
->get_working_threads(lib
->processor
, i
));
1619 b
->begin_section(b
, "queues");
1620 for (i
= 0; i
< JOB_PRIO_MAX
; i
++)
1622 b
->add_kv(b
, enum_to_name(job_priority_names
, i
), "%d",
1623 lib
->processor
->get_job_load(lib
->processor
, i
));
1627 b
->add_kv(b
, "scheduled", "%d",
1628 lib
->scheduler
->get_job_load(lib
->scheduler
));
1630 b
->begin_section(b
, "ikesas");
1631 b
->add_kv(b
, "total", "%u",
1632 charon
->ike_sa_manager
->get_count(charon
->ike_sa_manager
));
1633 b
->add_kv(b
, "half-open", "%u",
1634 charon
->ike_sa_manager
->get_half_open_count(charon
->ike_sa_manager
,
1638 b
->begin_list(b
, "plugins");
1639 enumerator
= lib
->plugins
->create_plugin_enumerator(lib
->plugins
);
1640 while (enumerator
->enumerate(enumerator
, &plugin
, NULL
))
1642 b
->add_li(b
, "%s", plugin
->get_name(plugin
));
1644 enumerator
->destroy(enumerator
);
1649 DWORD lasterr
= ERROR_INVALID_HANDLE
;
1656 b
->begin_section(b
, "mem");
1657 count
= GetProcessHeaps(countof(heaps
), heaps
);
1658 for (i
= 0; i
< count
; i
++)
1660 PROCESS_HEAP_ENTRY entry
= {};
1661 size_t heap_total
= 0;
1662 int heap_allocs
= 0;
1664 if (HeapLock(heaps
[i
]))
1666 while (HeapWalk(heaps
[i
], &entry
))
1668 if (entry
.wFlags
& PROCESS_HEAP_ENTRY_BUSY
)
1670 heap_total
+= entry
.cbData
;
1674 lasterr
= GetLastError();
1675 HeapUnlock(heaps
[i
]);
1677 if (lasterr
!= ERROR_NO_MORE_ITEMS
)
1681 snprintf(buf
, sizeof(buf
), "heap-%d", i
);
1682 b
->begin_section(b
, buf
);
1683 b
->add_kv(b
, "total", "%zu", heap_total
);
1684 b
->add_kv(b
, "allocs", "%d", heap_allocs
);
1687 total
+= heap_total
;
1688 allocs
+= heap_allocs
;
1690 if (lasterr
== ERROR_NO_MORE_ITEMS
)
1692 b
->add_kv(b
, "total", "%zu", total
);
1693 b
->add_kv(b
, "allocs", "%d", allocs
);
1700 #ifdef HAVE_MALLINFO2
1701 struct mallinfo2 mi
= mallinfo2();
1703 b
->begin_section(b
, "mallinfo");
1704 b
->add_kv(b
, "sbrk", "%zu", mi
.arena
);
1705 b
->add_kv(b
, "mmap", "%zu", mi
.hblkhd
);
1706 b
->add_kv(b
, "used", "%zu", mi
.uordblks
);
1707 b
->add_kv(b
, "free", "%zu", mi
.fordblks
);
1709 #elif defined(HAVE_MALLINFO)
1710 struct mallinfo mi
= mallinfo();
1712 b
->begin_section(b
, "mallinfo");
1713 b
->add_kv(b
, "sbrk", "%u", mi
.arena
);
1714 b
->add_kv(b
, "mmap", "%u", mi
.hblkhd
);
1715 b
->add_kv(b
, "used", "%u", mi
.uordblks
);
1716 b
->add_kv(b
, "free", "%u", mi
.fordblks
);
1718 #endif /* HAVE_MALLINFO(2) */
1721 return b
->finalize(b
);
1724 static void manage_command(private_vici_query_t
*this,
1725 char *name
, vici_command_cb_t cb
, bool reg
)
1727 this->dispatcher
->manage_command(this->dispatcher
, name
,
1728 reg
? cb
: NULL
, this);
1732 * (Un-)register dispatcher functions
1734 static void manage_commands(private_vici_query_t
*this, bool reg
)
1736 this->dispatcher
->manage_event(this->dispatcher
, "list-sa", reg
);
1737 this->dispatcher
->manage_event(this->dispatcher
, "list-policy", reg
);
1738 this->dispatcher
->manage_event(this->dispatcher
, "list-conn", reg
);
1739 this->dispatcher
->manage_event(this->dispatcher
, "list-cert", reg
);
1740 this->dispatcher
->manage_event(this->dispatcher
, "ike-updown", reg
);
1741 this->dispatcher
->manage_event(this->dispatcher
, "ike-rekey", reg
);
1742 this->dispatcher
->manage_event(this->dispatcher
, "ike-update", reg
);
1743 this->dispatcher
->manage_event(this->dispatcher
, "child-updown", reg
);
1744 this->dispatcher
->manage_event(this->dispatcher
, "child-rekey", reg
);
1745 manage_command(this, "list-sas", list_sas
, reg
);
1746 manage_command(this, "list-policies", list_policies
, reg
);
1747 manage_command(this, "list-conns", list_conns
, reg
);
1748 manage_command(this, "list-certs", list_certs
, reg
);
1749 manage_command(this, "get-algorithms", get_algorithms
, reg
);
1750 manage_command(this, "get-counters", get_counters
, reg
);
1751 manage_command(this, "reset-counters", reset_counters
, reg
);
1752 manage_command(this, "version", version
, reg
);
1753 manage_command(this, "stats", stats
, reg
);
1756 METHOD(listener_t
, ike_updown
, bool,
1757 private_vici_query_t
*this, ike_sa_t
*ike_sa
, bool up
)
1762 if (!this->dispatcher
->has_event_listeners(this->dispatcher
, "ike-updown"))
1767 now
= time_monotonic(NULL
);
1769 b
= vici_builder_create();
1773 b
->add_kv(b
, "up", "yes");
1776 b
->begin_section(b
, ike_sa
->get_name(ike_sa
));
1777 list_ike(this, b
, ike_sa
, now
);
1780 this->dispatcher
->raise_event(this->dispatcher
,
1781 "ike-updown", 0, b
->finalize(b
));
1786 METHOD(listener_t
, ike_rekey
, bool,
1787 private_vici_query_t
*this, ike_sa_t
*old
, ike_sa_t
*new)
1792 if (!this->dispatcher
->has_event_listeners(this->dispatcher
, "ike-rekey"))
1797 now
= time_monotonic(NULL
);
1799 b
= vici_builder_create();
1800 b
->begin_section(b
, old
->get_name(old
));
1801 b
->begin_section(b
, "old");
1802 list_ike(this, b
, old
, now
);
1804 b
->begin_section(b
, "new");
1805 list_ike(this, b
, new, now
);
1809 this->dispatcher
->raise_event(this->dispatcher
,
1810 "ike-rekey", 0, b
->finalize(b
));
1815 METHOD(listener_t
, ike_update
, bool,
1816 private_vici_query_t
*this, ike_sa_t
*ike_sa
, host_t
*local
, host_t
*remote
)
1821 if (!this->dispatcher
->has_event_listeners(this->dispatcher
, "ike-update"))
1826 now
= time_monotonic(NULL
);
1828 b
= vici_builder_create();
1830 b
->add_kv(b
, "local-host", "%H", local
);
1831 b
->add_kv(b
, "local-port", "%d", local
->get_port(local
));
1832 b
->add_kv(b
, "remote-host", "%H", remote
);
1833 b
->add_kv(b
, "remote-port", "%d", remote
->get_port(remote
));
1835 b
->begin_section(b
, ike_sa
->get_name(ike_sa
));
1836 list_ike(this, b
, ike_sa
, now
);
1839 this->dispatcher
->raise_event(this->dispatcher
,
1840 "ike-update", 0, b
->finalize(b
));
1845 METHOD(listener_t
, child_updown
, bool,
1846 private_vici_query_t
*this, ike_sa_t
*ike_sa
, child_sa_t
*child_sa
, bool up
)
1852 if (!this->dispatcher
->has_event_listeners(this->dispatcher
, "child-updown"))
1857 now
= time_monotonic(NULL
);
1858 b
= vici_builder_create();
1862 b
->add_kv(b
, "up", "yes");
1865 b
->begin_section(b
, ike_sa
->get_name(ike_sa
));
1866 list_ike(this, b
, ike_sa
, now
);
1867 b
->begin_section(b
, "child-sas");
1869 snprintf(buf
, sizeof(buf
), "%s-%u", child_sa
->get_name(child_sa
),
1870 child_sa
->get_unique_id(child_sa
));
1872 b
->begin_section(b
, buf
);
1873 list_child(this, b
, child_sa
, now
);
1879 this->dispatcher
->raise_event(this->dispatcher
,
1880 "child-updown", 0, b
->finalize(b
));
1885 METHOD(listener_t
, child_rekey
, bool,
1886 private_vici_query_t
*this, ike_sa_t
*ike_sa
, child_sa_t
*old
,
1892 if (!this->dispatcher
->has_event_listeners(this->dispatcher
, "child-rekey"))
1897 now
= time_monotonic(NULL
);
1898 b
= vici_builder_create();
1900 b
->begin_section(b
, ike_sa
->get_name(ike_sa
));
1901 list_ike(this, b
, ike_sa
, now
);
1902 b
->begin_section(b
, "child-sas");
1904 b
->begin_section(b
, old
->get_name(old
));
1906 b
->begin_section(b
, "old");
1907 list_child(this, b
, old
, now
);
1909 b
->begin_section(b
, "new");
1910 list_child(this, b
, new, now
);
1918 this->dispatcher
->raise_event(this->dispatcher
,
1919 "child-rekey", 0, b
->finalize(b
));
1924 METHOD(vici_query_t
, destroy
, void,
1925 private_vici_query_t
*this)
1927 manage_commands(this, FALSE
);
1934 vici_query_t
*vici_query_create(vici_dispatcher_t
*dispatcher
)
1936 private_vici_query_t
*this;
1941 .ike_updown
= _ike_updown
,
1942 .ike_rekey
= _ike_rekey
,
1943 .ike_update
= _ike_update
,
1944 .child_updown
= _child_updown
,
1945 .child_rekey
= _child_rekey
,
1947 .destroy
= _destroy
,
1949 .dispatcher
= dispatcher
,
1950 .uptime
= time_monotonic(NULL
),
1953 manage_commands(this, TRUE
);
1955 return &this->public;