2 * Copyright (C) 2014 Martin Willi
3 * Copyright (C) 2014 revosec AG
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "vici_query.h"
17 #include "vici_builder.h"
22 #include <sys/utsname.h>
30 typedef struct private_vici_query_t private_vici_query_t
;
33 * Private data of an vici_query_t object.
35 struct private_vici_query_t
{
38 * Public vici_query_t interface.
45 vici_dispatcher_t
*dispatcher
;
48 * Daemon startup timestamp
54 * List details of a CHILD_SA
56 static void list_child(private_vici_query_t
*this, vici_builder_t
*b
,
57 child_sa_t
*child
, time_t now
)
60 u_int64_t bytes
, packets
;
63 enumerator_t
*enumerator
;
64 traffic_selector_t
*ts
;
66 b
->add_kv(b
, "uniqueid", "%u", child
->get_unique_id(child
));
67 b
->add_kv(b
, "reqid", "%u", child
->get_reqid(child
));
68 b
->add_kv(b
, "state", "%N", child_sa_state_names
, child
->get_state(child
));
69 b
->add_kv(b
, "mode", "%N", ipsec_mode_names
, child
->get_mode(child
));
70 if (child
->get_state(child
) == CHILD_INSTALLED
||
71 child
->get_state(child
) == CHILD_REKEYING
)
73 b
->add_kv(b
, "protocol", "%N", protocol_id_names
,
74 child
->get_protocol(child
));
75 if (child
->has_encap(child
))
77 b
->add_kv(b
, "encap", "yes");
79 b
->add_kv(b
, "spi-in", "%.8x", ntohl(child
->get_spi(child
, TRUE
)));
80 b
->add_kv(b
, "spi-out", "%.8x", ntohl(child
->get_spi(child
, FALSE
)));
82 if (child
->get_ipcomp(child
) != IPCOMP_NONE
)
84 b
->add_kv(b
, "cpi-in", "%.4x", ntohs(child
->get_cpi(child
, TRUE
)));
85 b
->add_kv(b
, "cpi-out", "%.4x", ntohs(child
->get_cpi(child
, FALSE
)));
87 proposal
= child
->get_proposal(child
);
90 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
,
91 &alg
, &ks
) && alg
!= ENCR_UNDEFINED
)
93 b
->add_kv(b
, "encr-alg", "%N", encryption_algorithm_names
, alg
);
96 b
->add_kv(b
, "encr-keysize", "%u", ks
);
99 if (proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
,
100 &alg
, &ks
) && alg
!= ENCR_UNDEFINED
)
102 b
->add_kv(b
, "integ-alg", "%N", integrity_algorithm_names
, alg
);
105 b
->add_kv(b
, "integ-keysize", "%u", ks
);
108 if (proposal
->get_algorithm(proposal
, PSEUDO_RANDOM_FUNCTION
,
111 b
->add_kv(b
, "prf-alg", "%N", pseudo_random_function_names
, alg
);
113 if (proposal
->get_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
,
116 b
->add_kv(b
, "dh-group", "%N", diffie_hellman_group_names
, alg
);
118 if (proposal
->get_algorithm(proposal
, EXTENDED_SEQUENCE_NUMBERS
,
119 &alg
, NULL
) && alg
== EXT_SEQ_NUMBERS
)
121 b
->add_kv(b
, "esn", "1");
125 child
->get_usestats(child
, TRUE
, &t
, &bytes
, &packets
);
126 b
->add_kv(b
, "bytes-in", "%" PRIu64
, bytes
);
127 b
->add_kv(b
, "packets-in", "%" PRIu64
, packets
);
130 b
->add_kv(b
, "use-in", "%"PRIu64
, (u_int64_t
)(now
- t
));
133 child
->get_usestats(child
, FALSE
, &t
, &bytes
, &packets
);
134 b
->add_kv(b
, "bytes-out", "%"PRIu64
, bytes
);
135 b
->add_kv(b
, "packets-out", "%"PRIu64
, packets
);
138 b
->add_kv(b
, "use-out", "%"PRIu64
, (u_int64_t
)(now
- t
));
141 t
= child
->get_lifetime(child
, FALSE
);
144 b
->add_kv(b
, "rekey-time", "%"PRId64
, (int64_t)(t
- now
));
146 t
= child
->get_lifetime(child
, TRUE
);
149 b
->add_kv(b
, "life-time", "%"PRId64
, (int64_t)(t
- now
));
151 t
= child
->get_installtime(child
);
152 b
->add_kv(b
, "install-time", "%"PRId64
, (int64_t)(now
- t
));
155 b
->begin_list(b
, "local-ts");
156 enumerator
= child
->create_ts_enumerator(child
, TRUE
);
157 while (enumerator
->enumerate(enumerator
, &ts
))
159 b
->add_li(b
, "%R", ts
);
161 enumerator
->destroy(enumerator
);
162 b
->end_list(b
/* local-ts */);
164 b
->begin_list(b
, "remote-ts");
165 enumerator
= child
->create_ts_enumerator(child
, FALSE
);
166 while (enumerator
->enumerate(enumerator
, &ts
))
168 b
->add_li(b
, "%R", ts
);
170 enumerator
->destroy(enumerator
);
171 b
->end_list(b
/* remote-ts */);
175 * List tasks in a specific queue
177 static void list_task_queue(private_vici_query_t
*this, vici_builder_t
*b
,
178 ike_sa_t
*ike_sa
, task_queue_t q
, char *name
)
180 enumerator_t
*enumerator
;
184 enumerator
= ike_sa
->create_task_enumerator(ike_sa
, q
);
185 while (enumerator
->enumerate(enumerator
, &task
))
189 b
->begin_list(b
, name
);
192 b
->add_li(b
, "%N", task_type_names
, task
->get_type(task
));
194 enumerator
->destroy(enumerator
);
202 * List details of an IKE_SA
204 static void list_ike(private_vici_query_t
*this, vici_builder_t
*b
,
205 ike_sa_t
*ike_sa
, time_t now
)
209 identification_t
*eap
;
210 proposal_t
*proposal
;
213 b
->add_kv(b
, "uniqueid", "%u", ike_sa
->get_unique_id(ike_sa
));
214 b
->add_kv(b
, "version", "%u", ike_sa
->get_version(ike_sa
));
215 b
->add_kv(b
, "state", "%N", ike_sa_state_names
, ike_sa
->get_state(ike_sa
));
217 b
->add_kv(b
, "local-host", "%H", ike_sa
->get_my_host(ike_sa
));
218 b
->add_kv(b
, "local-id", "%Y", ike_sa
->get_my_id(ike_sa
));
220 b
->add_kv(b
, "remote-host", "%H", ike_sa
->get_other_host(ike_sa
));
221 b
->add_kv(b
, "remote-id", "%Y", ike_sa
->get_other_id(ike_sa
));
223 eap
= ike_sa
->get_other_eap_id(ike_sa
);
225 if (!eap
->equals(eap
, ike_sa
->get_other_id(ike_sa
)))
227 if (ike_sa
->get_version(ike_sa
) == IKEV1
)
229 b
->add_kv(b
, "remote-xauth-id", "%Y", eap
);
233 b
->add_kv(b
, "remote-eap-id", "%Y", eap
);
237 id
= ike_sa
->get_id(ike_sa
);
238 if (id
->is_initiator(id
))
240 b
->add_kv(b
, "initiator", "yes");
242 b
->add_kv(b
, "initiator-spi", "%.16"PRIx64
, id
->get_initiator_spi(id
));
243 b
->add_kv(b
, "responder-spi", "%.16"PRIx64
, id
->get_responder_spi(id
));
245 proposal
= ike_sa
->get_proposal(ike_sa
);
248 if (proposal
->get_algorithm(proposal
, ENCRYPTION_ALGORITHM
, &alg
, &ks
))
250 b
->add_kv(b
, "encr-alg", "%N", encryption_algorithm_names
, alg
);
253 b
->add_kv(b
, "encr-keysize", "%u", ks
);
256 if (proposal
->get_algorithm(proposal
, INTEGRITY_ALGORITHM
, &alg
, &ks
))
258 b
->add_kv(b
, "integ-alg", "%N", integrity_algorithm_names
, alg
);
261 b
->add_kv(b
, "integ-keysize", "%u", ks
);
264 if (proposal
->get_algorithm(proposal
, PSEUDO_RANDOM_FUNCTION
, &alg
, NULL
))
266 b
->add_kv(b
, "prf-alg", "%N", pseudo_random_function_names
, alg
);
268 if (proposal
->get_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
, &alg
, NULL
))
270 b
->add_kv(b
, "dh-group", "%N", diffie_hellman_group_names
, alg
);
274 if (ike_sa
->get_state(ike_sa
) == IKE_ESTABLISHED
)
276 t
= ike_sa
->get_statistic(ike_sa
, STAT_ESTABLISHED
);
277 b
->add_kv(b
, "established", "%"PRId64
, (int64_t)(now
- t
));
278 t
= ike_sa
->get_statistic(ike_sa
, STAT_REKEY
);
281 b
->add_kv(b
, "rekey-time", "%"PRId64
, (int64_t)(t
- now
));
283 t
= ike_sa
->get_statistic(ike_sa
, STAT_REAUTH
);
286 b
->add_kv(b
, "reauth-time", "%"PRId64
, (int64_t)(t
- now
));
290 list_task_queue(this, b
, ike_sa
, TASK_QUEUE_QUEUED
, "tasks-queued");
291 list_task_queue(this, b
, ike_sa
, TASK_QUEUE_ACTIVE
, "tasks-active");
292 list_task_queue(this, b
, ike_sa
, TASK_QUEUE_PASSIVE
, "tasks-passive");
295 CALLBACK(list_sas
, vici_message_t
*,
296 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
299 enumerator_t
*isas
, *csas
;
301 child_sa_t
*child_sa
;
307 bl
= request
->get_str(request
, NULL
, "noblock") == NULL
;
308 ike
= request
->get_str(request
, NULL
, "ike");
309 ike_id
= request
->get_int(request
, 0, "ike-id");
311 isas
= charon
->controller
->create_ike_sa_enumerator(charon
->controller
, bl
);
312 while (isas
->enumerate(isas
, &ike_sa
))
314 if (ike
&& !streq(ike
, ike_sa
->get_name(ike_sa
)))
318 if (ike_id
&& ike_id
!= ike_sa
->get_unique_id(ike_sa
))
323 now
= time_monotonic(NULL
);
325 b
= vici_builder_create();
326 b
->begin_section(b
, ike_sa
->get_name(ike_sa
));
328 list_ike(this, b
, ike_sa
, now
);
330 b
->begin_section(b
, "child-sas");
331 csas
= ike_sa
->create_child_sa_enumerator(ike_sa
);
332 while (csas
->enumerate(csas
, &child_sa
))
334 b
->begin_section(b
, child_sa
->get_name(child_sa
));
335 list_child(this, b
, child_sa
, now
);
339 b
->end_section(b
/* child-sas */ );
343 this->dispatcher
->raise_event(this->dispatcher
, "list-sa", id
,
348 b
= vici_builder_create();
349 return b
->finalize(b
);
353 * Raise a list-policy event for given CHILD_SA
355 static void raise_policy(private_vici_query_t
*this, u_int id
, child_sa_t
*child
)
357 enumerator_t
*enumerator
;
358 traffic_selector_t
*ts
;
361 b
= vici_builder_create();
362 b
->begin_section(b
, child
->get_name(child
));
364 b
->add_kv(b
, "mode", "%N", ipsec_mode_names
, child
->get_mode(child
));
366 b
->begin_list(b
, "local-ts");
367 enumerator
= child
->create_ts_enumerator(child
, TRUE
);
368 while (enumerator
->enumerate(enumerator
, &ts
))
370 b
->add_li(b
, "%R", ts
);
372 enumerator
->destroy(enumerator
);
373 b
->end_list(b
/* local-ts */);
375 b
->begin_list(b
, "remote-ts");
376 enumerator
= child
->create_ts_enumerator(child
, FALSE
);
377 while (enumerator
->enumerate(enumerator
, &ts
))
379 b
->add_li(b
, "%R", ts
);
381 enumerator
->destroy(enumerator
);
382 b
->end_list(b
/* remote-ts */);
386 this->dispatcher
->raise_event(this->dispatcher
, "list-policy", id
,
391 * Raise a list-policy event for given CHILD_SA config
393 static void raise_policy_cfg(private_vici_query_t
*this, u_int id
,
396 enumerator_t
*enumerator
;
398 traffic_selector_t
*ts
;
401 b
= vici_builder_create();
402 b
->begin_section(b
, cfg
->get_name(cfg
));
404 b
->add_kv(b
, "mode", "%N", ipsec_mode_names
, cfg
->get_mode(cfg
));
406 b
->begin_list(b
, "local-ts");
407 list
= cfg
->get_traffic_selectors(cfg
, TRUE
, NULL
, NULL
);
408 enumerator
= list
->create_enumerator(list
);
409 while (enumerator
->enumerate(enumerator
, &ts
))
411 b
->add_li(b
, "%R", ts
);
413 enumerator
->destroy(enumerator
);
414 list
->destroy_offset(list
, offsetof(traffic_selector_t
, destroy
));
415 b
->end_list(b
/* local-ts */);
417 b
->begin_list(b
, "remote-ts");
418 list
= cfg
->get_traffic_selectors(cfg
, FALSE
, NULL
, NULL
);
419 enumerator
= list
->create_enumerator(list
);
420 while (enumerator
->enumerate(enumerator
, &ts
))
422 b
->add_li(b
, "%R", ts
);
424 enumerator
->destroy(enumerator
);
425 list
->destroy_offset(list
, offsetof(traffic_selector_t
, destroy
));
426 b
->end_list(b
/* remote-ts */);
430 this->dispatcher
->raise_event(this->dispatcher
, "list-policy", id
,
434 CALLBACK(list_policies
, vici_message_t
*,
435 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
437 enumerator_t
*enumerator
;
439 child_sa_t
*child_sa
;
440 child_cfg_t
*child_cfg
;
441 bool drop
, pass
, trap
;
444 drop
= request
->get_str(request
, NULL
, "drop") != NULL
;
445 pass
= request
->get_str(request
, NULL
, "pass") != NULL
;
446 trap
= request
->get_str(request
, NULL
, "trap") != NULL
;
447 child
= request
->get_str(request
, NULL
, "child");
451 enumerator
= charon
->traps
->create_enumerator(charon
->traps
);
452 while (enumerator
->enumerate(enumerator
, NULL
, &child_sa
))
454 if (child
&& !streq(child
, child_sa
->get_name(child_sa
)))
458 raise_policy(this, id
, child_sa
);
460 enumerator
->destroy(enumerator
);
465 enumerator
= charon
->shunts
->create_enumerator(charon
->shunts
);
466 while (enumerator
->enumerate(enumerator
, &child_cfg
))
468 if (child
&& !streq(child
, child_cfg
->get_name(child_cfg
)))
472 switch (child_cfg
->get_mode(child_cfg
))
477 raise_policy_cfg(this, id
, child_cfg
);
483 raise_policy_cfg(this, id
, child_cfg
);
490 enumerator
->destroy(enumerator
);
493 b
= vici_builder_create();
494 return b
->finalize(b
);
498 * Build sections for auth configs, local or remote
500 static void build_auth_cfgs(peer_cfg_t
*peer_cfg
, bool local
, vici_builder_t
*b
)
502 enumerator_t
*enumerator
, *rules
;
507 identification_t
*id
;
512 enumerator
= peer_cfg
->create_auth_cfg_enumerator(peer_cfg
, local
);
513 while (enumerator
->enumerate(enumerator
, &auth
))
515 b
->begin_section(b
, local ?
"local" : "remote");
517 rules
= auth
->create_enumerator(auth
);
518 while (rules
->enumerate(rules
, &rule
, &v
))
522 case AUTH_RULE_AUTH_CLASS
:
523 b
->add_kv(b
, "class", "%N", auth_class_names
, v
.u
);
525 case AUTH_RULE_EAP_TYPE
:
526 b
->add_kv(b
, "eap-type", "%N", eap_type_names
, v
.u
);
528 case AUTH_RULE_EAP_VENDOR
:
529 b
->add_kv(b
, "eap-vendor", "%u", v
.u
);
531 case AUTH_RULE_XAUTH_BACKEND
:
532 b
->add_kv(b
, "xauth", "%s", v
.str
);
534 case AUTH_RULE_CRL_VALIDATION
:
535 b
->add_kv(b
, "revocation", "%N", cert_validation_names
, v
.u
);
537 case AUTH_RULE_IDENTITY
:
538 b
->add_kv(b
, "id", "%Y", v
.id
);
540 case AUTH_RULE_AAA_IDENTITY
:
541 b
->add_kv(b
, "aaa_id", "%Y", v
.id
);
543 case AUTH_RULE_EAP_IDENTITY
:
544 b
->add_kv(b
, "eap_id", "%Y", v
.id
);
546 case AUTH_RULE_XAUTH_IDENTITY
:
547 b
->add_kv(b
, "xauth_id", "%Y", v
.id
);
553 rules
->destroy(rules
);
555 b
->begin_list(b
, "groups");
556 rules
= auth
->create_enumerator(auth
);
557 while (rules
->enumerate(rules
, &rule
, &v
))
559 if (rule
== AUTH_RULE_GROUP
)
561 b
->add_li(b
, "%Y", v
.id
);
564 rules
->destroy(rules
);
567 b
->begin_list(b
, "certs");
568 rules
= auth
->create_enumerator(auth
);
569 while (rules
->enumerate(rules
, &rule
, &v
))
571 if (rule
== AUTH_RULE_SUBJECT_CERT
)
573 b
->add_li(b
, "%Y", v
.cert
->get_subject(v
.cert
));
576 rules
->destroy(rules
);
579 b
->begin_list(b
, "cacerts");
580 rules
= auth
->create_enumerator(auth
);
581 while (rules
->enumerate(rules
, &rule
, &v
))
583 if (rule
== AUTH_RULE_CA_CERT
)
585 b
->add_li(b
, "%Y", v
.cert
->get_subject(v
.cert
));
588 rules
->destroy(rules
);
593 enumerator
->destroy(enumerator
);
596 CALLBACK(list_conns
, vici_message_t
*,
597 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
599 enumerator_t
*enumerator
, *tokens
, *selectors
, *children
;
600 peer_cfg_t
*peer_cfg
;
602 child_cfg_t
*child_cfg
;
605 traffic_selector_t
*ts
;
608 ike
= request
->get_str(request
, NULL
, "ike");
610 enumerator
= charon
->backends
->create_peer_cfg_enumerator(charon
->backends
,
611 NULL
, NULL
, NULL
, NULL
, IKE_ANY
);
612 while (enumerator
->enumerate(enumerator
, &peer_cfg
))
614 if (ike
&& !streq(ike
, peer_cfg
->get_name(peer_cfg
)))
619 b
= vici_builder_create();
620 b
->begin_section(b
, peer_cfg
->get_name(peer_cfg
));
622 ike_cfg
= peer_cfg
->get_ike_cfg(peer_cfg
);
624 b
->begin_list(b
, "local_addrs");
625 str
= ike_cfg
->get_my_addr(ike_cfg
);
626 tokens
= enumerator_create_token(str
, ",", " ");
627 while (tokens
->enumerate(tokens
, &str
))
629 b
->add_li(b
, "%s", str
);
631 tokens
->destroy(tokens
);
634 b
->begin_list(b
, "remote_addrs");
635 str
= ike_cfg
->get_other_addr(ike_cfg
);
636 tokens
= enumerator_create_token(str
, ",", " ");
637 while (tokens
->enumerate(tokens
, &str
))
639 b
->add_li(b
, "%s", str
);
641 tokens
->destroy(tokens
);
644 b
->add_kv(b
, "version", "%N", ike_version_names
,
645 peer_cfg
->get_ike_version(peer_cfg
));
647 build_auth_cfgs(peer_cfg
, TRUE
, b
);
648 build_auth_cfgs(peer_cfg
, FALSE
, b
);
650 b
->begin_section(b
, "children");
652 children
= peer_cfg
->create_child_cfg_enumerator(peer_cfg
);
653 while (children
->enumerate(children
, &child_cfg
))
655 b
->begin_section(b
, child_cfg
->get_name(child_cfg
));
657 b
->add_kv(b
, "mode", "%N", ipsec_mode_names
,
658 child_cfg
->get_mode(child_cfg
));
660 b
->begin_list(b
, "local-ts");
661 list
= child_cfg
->get_traffic_selectors(child_cfg
, TRUE
, NULL
, NULL
);
662 selectors
= list
->create_enumerator(list
);
663 while (selectors
->enumerate(selectors
, &ts
))
665 b
->add_li(b
, "%R", ts
);
667 selectors
->destroy(selectors
);
668 list
->destroy_offset(list
, offsetof(traffic_selector_t
, destroy
));
669 b
->end_list(b
/* local-ts */);
671 b
->begin_list(b
, "remote-ts");
672 list
= child_cfg
->get_traffic_selectors(child_cfg
, FALSE
, NULL
, NULL
);
673 selectors
= list
->create_enumerator(list
);
674 while (selectors
->enumerate(selectors
, &ts
))
676 b
->add_li(b
, "%R", ts
);
678 selectors
->destroy(selectors
);
679 list
->destroy_offset(list
, offsetof(traffic_selector_t
, destroy
));
680 b
->end_list(b
/* remote-ts */);
684 children
->destroy(children
);
686 b
->end_section(b
); /* children */
688 b
->end_section(b
); /* name */
690 this->dispatcher
->raise_event(this->dispatcher
, "list-conn", id
,
693 enumerator
->destroy(enumerator
);
695 b
= vici_builder_create();
696 return b
->finalize(b
);
700 * Do we have a private key for given certificate
702 static bool has_privkey(private_vici_query_t
*this, certificate_t
*cert
)
704 private_key_t
*private;
705 public_key_t
*public;
706 identification_t
*keyid
;
710 public = cert
->get_public_key(cert
);
713 if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1
, &chunk
))
715 keyid
= identification_create_from_encoding(ID_KEY_ID
, chunk
);
716 private = lib
->credmgr
->get_private(lib
->credmgr
,
717 public->get_type(public), keyid
, NULL
);
721 private->destroy(private);
723 keyid
->destroy(keyid
);
725 public->destroy(public);
730 CALLBACK(list_certs
, vici_message_t
*,
731 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
733 enumerator_t
*enumerator
, *added
;
735 certificate_t
*cert
, *current
;
737 identification_t
*subject
= NULL
;
743 str
= request
->get_str(request
, "ANY", "type");
744 if (!enum_from_name(certificate_type_names
, str
, &type
))
746 b
= vici_builder_create();
747 return b
->finalize(b
);
749 str
= request
->get_str(request
, NULL
, "subject");
752 subject
= identification_create_from_string(str
);
755 list
= linked_list_create();
756 enumerator
= lib
->credmgr
->create_cert_enumerator(lib
->credmgr
,
757 type
, KEY_ANY
, subject
, FALSE
);
758 while (enumerator
->enumerate(enumerator
, &cert
))
761 added
= list
->create_enumerator(list
);
762 while (added
->enumerate(added
, ¤t
))
764 if (current
->equals(current
, cert
))
770 added
->destroy(added
);
772 if (!found
&& cert
->get_encoding(cert
, CERT_ASN1_DER
, &encoding
))
774 b
= vici_builder_create();
775 b
->add_kv(b
, "type", "%N",
776 certificate_type_names
, cert
->get_type(cert
));
777 if (has_privkey(this, cert
))
779 b
->add_kv(b
, "has_privkey", "yes");
781 b
->add(b
, VICI_KEY_VALUE
, "data", encoding
);
784 this->dispatcher
->raise_event(this->dispatcher
, "list-cert", id
,
786 list
->insert_last(list
, cert
->get_ref(cert
));
789 enumerator
->destroy(enumerator
);
791 list
->destroy_offset(list
, offsetof(certificate_t
, destroy
));
794 b
= vici_builder_create();
795 return b
->finalize(b
);
798 CALLBACK(version
, vici_message_t
*,
799 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
803 b
= vici_builder_create();
805 b
->add_kv(b
, "daemon", "%s", lib
->ns
);
806 b
->add_kv(b
, "version", "%s", VERSION
);
810 OSVERSIONINFOEX osvie
;
812 memset(&osvie
, 0, sizeof(osvie
));
813 osvie
.dwOSVersionInfoSize
= sizeof(osvie
);
815 if (GetVersionEx((LPOSVERSIONINFO
)&osvie
))
817 b
->add_kv(b
, "sysname", "Windows %s",
818 osvie
.wProductType
== VER_NT_WORKSTATION ?
"Client" : "Server");
819 b
->add_kv(b
, "release", "%d.%d.%d (SP %d.%d)",
820 osvie
.dwMajorVersion
, osvie
.dwMinorVersion
, osvie
.dwBuildNumber
,
821 osvie
.wServicePackMajor
, osvie
.wServicePackMinor
);
822 b
->add_kv(b
, "machine", "%s",
832 struct utsname utsname
;
834 if (uname(&utsname
) == 0)
836 b
->add_kv(b
, "sysname", "%s", utsname
.sysname
);
837 b
->add_kv(b
, "release", "%s", utsname
.release
);
838 b
->add_kv(b
, "machine", "%s", utsname
.machine
);
842 return b
->finalize(b
);
846 * Callback function for memusage summary
848 CALLBACK(sum_usage
, void,
849 vici_builder_t
*b
, int count
, size_t bytes
, int whitelisted
)
851 b
->begin_section(b
, "mem");
852 b
->add_kv(b
, "total", "%zu", bytes
);
853 b
->add_kv(b
, "allocs", "%d", count
);
857 CALLBACK(stats
, vici_message_t
*,
858 private_vici_query_t
*this, char *name
, u_int id
, vici_message_t
*request
)
861 enumerator_t
*enumerator
;
866 b
= vici_builder_create();
868 now
= time_monotonic(NULL
);
869 since
= time(NULL
) - (now
- this->uptime
);
871 b
->begin_section(b
, "uptime");
872 b
->add_kv(b
, "running", "%V", &now
, &this->uptime
);
873 b
->add_kv(b
, "since", "%T", &since
, FALSE
);
876 b
->begin_section(b
, "workers");
877 b
->add_kv(b
, "total", "%d",
878 lib
->processor
->get_total_threads(lib
->processor
));
879 b
->add_kv(b
, "idle", "%d",
880 lib
->processor
->get_idle_threads(lib
->processor
));
881 b
->begin_section(b
, "active");
882 for (i
= 0; i
< JOB_PRIO_MAX
; i
++)
884 b
->add_kv(b
, enum_to_name(job_priority_names
, i
), "%d",
885 lib
->processor
->get_working_threads(lib
->processor
, i
));
890 b
->begin_section(b
, "queues");
891 for (i
= 0; i
< JOB_PRIO_MAX
; i
++)
893 b
->add_kv(b
, enum_to_name(job_priority_names
, i
), "%d",
894 lib
->processor
->get_job_load(lib
->processor
, i
));
898 b
->add_kv(b
, "scheduled", "%d",
899 lib
->scheduler
->get_job_load(lib
->scheduler
));
901 b
->begin_section(b
, "ikesas");
902 b
->add_kv(b
, "total", "%u",
903 charon
->ike_sa_manager
->get_count(charon
->ike_sa_manager
));
904 b
->add_kv(b
, "half-open", "%u",
905 charon
->ike_sa_manager
->get_half_open_count(charon
->ike_sa_manager
,
909 b
->begin_list(b
, "plugins");
910 enumerator
= lib
->plugins
->create_plugin_enumerator(lib
->plugins
);
911 while (enumerator
->enumerate(enumerator
, &plugin
, NULL
))
913 b
->add_li(b
, "%s", plugin
->get_name(plugin
));
915 enumerator
->destroy(enumerator
);
918 if (lib
->leak_detective
)
920 lib
->leak_detective
->usage(lib
->leak_detective
, NULL
, sum_usage
, b
);
925 DWORD lasterr
= ERROR_INVALID_HANDLE
;
932 b
->begin_section(b
, "mem");
933 count
= GetProcessHeaps(countof(heaps
), heaps
);
934 for (i
= 0; i
< count
; i
++)
936 PROCESS_HEAP_ENTRY entry
= {};
937 size_t heap_total
= 0;
940 if (HeapLock(heaps
[i
]))
942 while (HeapWalk(heaps
[i
], &entry
))
944 if (entry
.wFlags
& PROCESS_HEAP_ENTRY_BUSY
)
946 heap_total
+= entry
.cbData
;
950 lasterr
= GetLastError();
951 HeapUnlock(heaps
[i
]);
953 if (lasterr
!= ERROR_NO_MORE_ITEMS
)
957 snprintf(buf
, sizeof(buf
), "heap-%d", i
);
958 b
->begin_section(b
, buf
);
959 b
->add_kv(b
, "total", "%zu", heap_total
);
960 b
->add_kv(b
, "allocs", "%d", heap_allocs
);
964 allocs
+= heap_allocs
;
966 if (lasterr
== ERROR_NO_MORE_ITEMS
)
968 b
->add_kv(b
, "total", "%zu", total
);
969 b
->add_kv(b
, "allocs", "%d", allocs
);
977 struct mallinfo mi
= mallinfo();
979 b
->begin_section(b
, "mallinfo");
980 b
->add_kv(b
, "sbrk", "%u", mi
.arena
);
981 b
->add_kv(b
, "mmap", "%u", mi
.hblkhd
);
982 b
->add_kv(b
, "used", "%u", mi
.uordblks
);
983 b
->add_kv(b
, "free", "%u", mi
.fordblks
);
986 #endif /* HAVE_MALLINFO */
988 return b
->finalize(b
);
991 static void manage_command(private_vici_query_t
*this,
992 char *name
, vici_command_cb_t cb
, bool reg
)
994 this->dispatcher
->manage_command(this->dispatcher
, name
,
995 reg ? cb
: NULL
, this);
999 * (Un-)register dispatcher functions
1001 static void manage_commands(private_vici_query_t
*this, bool reg
)
1003 this->dispatcher
->manage_event(this->dispatcher
, "list-sa", reg
);
1004 this->dispatcher
->manage_event(this->dispatcher
, "list-policy", reg
);
1005 this->dispatcher
->manage_event(this->dispatcher
, "list-conn", reg
);
1006 this->dispatcher
->manage_event(this->dispatcher
, "list-cert", reg
);
1007 manage_command(this, "list-sas", list_sas
, reg
);
1008 manage_command(this, "list-policies", list_policies
, reg
);
1009 manage_command(this, "list-conns", list_conns
, reg
);
1010 manage_command(this, "list-certs", list_certs
, reg
);
1011 manage_command(this, "version", version
, reg
);
1012 manage_command(this, "stats", stats
, reg
);
1015 METHOD(vici_query_t
, destroy
, void,
1016 private_vici_query_t
*this)
1018 manage_commands(this, FALSE
);
1025 vici_query_t
*vici_query_create(vici_dispatcher_t
*dispatcher
)
1027 private_vici_query_t
*this;
1031 .destroy
= _destroy
,
1033 .dispatcher
= dispatcher
,
1034 .uptime
= time_monotonic(NULL
),
1037 manage_commands(this, TRUE
);
1039 return &this->public;