summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/iked/config.c9
-rw-r--r--sbin/iked/control.c4
-rw-r--r--sbin/iked/iked.h39
-rw-r--r--sbin/iked/ikev2.c54
-rw-r--r--sbin/iked/ikev2_msg.c14
-rw-r--r--sbin/iked/ikev2_pld.c16
-rw-r--r--sbin/iked/policy.c24
-rw-r--r--sbin/iked/types.h5
-rw-r--r--usr.sbin/ikectl/ikectl.c62
-rw-r--r--usr.sbin/ikectl/parser.c3
-rw-r--r--usr.sbin/ikectl/parser.h5
11 files changed, 214 insertions, 21 deletions
diff --git a/sbin/iked/config.c b/sbin/iked/config.c
index 25caf3d3e15..dd1c865a77b 100644
--- a/sbin/iked/config.c
+++ b/sbin/iked/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.86 2022/07/08 19:51:11 tobhe Exp $ */
+/* $OpenBSD: config.c,v 1.87 2022/09/19 20:54:02 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -60,6 +60,7 @@ config_new_sa(struct iked *env, int initiator)
gettimeofday(&sa->sa_timecreated, NULL);
memcpy(&sa->sa_timeused, &sa->sa_timecreated, sizeof(sa->sa_timeused));
+ ikestat_inc(env, ikes_sa_created);
return (sa);
}
@@ -181,6 +182,11 @@ config_free_sa(struct iked *env, struct iked_sa *sa)
free(sa->sa_cp_dns);
free(sa->sa_tag);
+
+ if (sa->sa_state == IKEV2_STATE_ESTABLISHED)
+ ikestat_dec(env, ikes_sa_established_current);
+ ikestat_inc(env, ikes_sa_removed);
+
free(sa);
}
@@ -333,6 +339,7 @@ config_free_childsas(struct iked *env, struct iked_childsas *head,
childsa_free(ipcomp);
}
childsa_free(csa);
+ ikestat_inc(env, ikes_csa_removed);
}
}
diff --git a/sbin/iked/control.c b/sbin/iked/control.c
index 828d68e7a71..f88b9bf806c 100644
--- a/sbin/iked/control.c
+++ b/sbin/iked/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.32 2021/11/21 22:44:08 tobhe Exp $ */
+/* $OpenBSD: control.c,v 1.33 2022/09/19 20:54:02 tobhe Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -311,6 +311,7 @@ control_dispatch_imsg(int fd, short event, void *arg)
proc_forward_imsg(&env->sc_ps, &imsg, PROC_IKEV2, -1);
break;
case IMSG_CTL_SHOW_SA:
+ case IMSG_CTL_SHOW_STATS:
proc_forward_imsg(&env->sc_ps, &imsg, PROC_IKEV2, -1);
c->flags |= CTL_CONN_NOTIFY;
break;
@@ -346,6 +347,7 @@ control_dispatch_ikev2(int fd, struct privsep_proc *p, struct imsg *imsg)
{
switch (imsg->hdr.type) {
case IMSG_CTL_SHOW_SA:
+ case IMSG_CTL_SHOW_STATS:
control_imsg_forward(imsg);
return (0);
default:
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h
index 9873bc36f71..e6805b86c91 100644
--- a/sbin/iked/iked.h
+++ b/sbin/iked/iked.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: iked.h,v 1.206 2022/07/22 15:53:33 tobhe Exp $ */
+/* $OpenBSD: iked.h,v 1.207 2022/09/19 20:54:02 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -540,6 +540,41 @@ RB_HEAD(iked_dstid_sas, iked_sa);
RB_HEAD(iked_addrpool, iked_sa);
RB_HEAD(iked_addrpool6, iked_sa);
+/* stats */
+
+struct iked_stats {
+ uint64_t ikes_sa_created;
+ uint64_t ikes_sa_established_total;
+ uint64_t ikes_sa_established_current; /* gauge */
+ uint64_t ikes_sa_established_failures;
+ uint64_t ikes_sa_proposals_negotiate_failures;
+ uint64_t ikes_sa_rekeyed;
+ uint64_t ikes_sa_removed;
+ uint64_t ikes_csa_created;
+ uint64_t ikes_csa_removed;
+ uint64_t ikes_msg_sent;
+ uint64_t ikes_msg_send_failures;
+ uint64_t ikes_msg_rcvd;
+ uint64_t ikes_msg_rcvd_busy;
+ uint64_t ikes_msg_rcvd_dropped;
+ uint64_t ikes_retransmit_request;
+ uint64_t ikes_retransmit_response;
+ uint64_t ikes_retransmit_limit;
+ uint64_t ikes_frag_sent;
+ uint64_t ikes_frag_send_failures;
+ uint64_t ikes_frag_rcvd;
+ uint64_t ikes_frag_rcvd_drop;
+ uint64_t ikes_frag_reass_ok;
+ uint64_t ikes_frag_reass_drop;
+ uint64_t ikes_update_addresses_sent;
+ uint64_t ikes_dpd_sent;
+ uint64_t ikes_keepalive_sent;
+};
+
+#define ikestat_add(env, c, n) do { env->sc_stats.c += (n); } while(0)
+#define ikestat_inc(env, c) ikestat_add(env, c, 1)
+#define ikestat_dec(env, c) ikestat_add(env, c, -1)
+
struct iked_certreq {
struct ibuf *cr_data;
uint8_t cr_type;
@@ -765,6 +800,8 @@ struct iked {
struct iked_flows sc_activeflows;
struct iked_users sc_users;
+ struct iked_stats sc_stats;
+
void *sc_priv; /* per-process */
int sc_pfkey; /* ike process */
diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c
index 6f07d4f35a0..3f718b7a186 100644
--- a/sbin/iked/ikev2.c
+++ b/sbin/iked/ikev2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2.c,v 1.351 2022/09/14 13:07:49 tobhe Exp $ */
+/* $OpenBSD: ikev2.c,v 1.352 2022/09/19 20:54:02 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -187,6 +187,7 @@ int ikev2_resp_informational(struct iked *, struct iked_sa *,
void ikev2_ctl_reset_id(struct iked *, struct imsg *, unsigned int);
void ikev2_ctl_show_sa(struct iked *);
+void ikev2_ctl_show_stats(struct iked *);
static struct privsep_proc procs[] = {
{ "parent", PROC_PARENT, ikev2_dispatch_parent },
@@ -519,6 +520,9 @@ ikev2_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
case IMSG_CTL_SHOW_SA:
ikev2_ctl_show_sa(env);
break;
+ case IMSG_CTL_SHOW_STATS:
+ ikev2_ctl_show_stats(env);
+ break;
default:
return (-1);
}
@@ -579,6 +583,13 @@ ikev2_ctl_show_sa(struct iked *env)
ikev2_info(env, 0);
}
+void
+ikev2_ctl_show_stats(struct iked *env)
+{
+ proc_compose(&env->sc_ps, PROC_CONTROL, IMSG_CTL_SHOW_STATS,
+ &env->sc_stats, sizeof(env->sc_stats));
+}
+
struct iked_sa *
ikev2_getimsgdata(struct iked *env, struct imsg *imsg, struct iked_sahdr *sh,
uint8_t *type, uint8_t **buf, size_t *size)
@@ -642,6 +653,8 @@ ikev2_recv(struct iked *env, struct iked_message *msg)
(betoh32(hdr->ike_length) - msg->msg_offset))
return;
+ ikestat_inc(env, ikes_msg_rcvd);
+
initiator = (hdr->ike_flags & IKEV2_FLAG_INITIATOR) ? 0 : 1;
msg->msg_response = (hdr->ike_flags & IKEV2_FLAG_RESPONSE) ? 1 : 0;
msg->msg_exchange = hdr->ike_exchange;
@@ -649,8 +662,10 @@ ikev2_recv(struct iked *env, struct iked_message *msg)
betoh64(hdr->ike_ispi), betoh64(hdr->ike_rspi),
initiator);
msg->msg_msgid = betoh32(hdr->ike_msgid);
- if (policy_lookup(env, msg, NULL, NULL, 0) != 0)
+ if (policy_lookup(env, msg, NULL, NULL, 0) != 0) {
+ ikestat_inc(env, ikes_msg_rcvd_dropped);
return;
+ }
logit(hdr->ike_exchange == IKEV2_EXCHANGE_INFORMATIONAL ?
LOG_DEBUG : LOG_INFO,
@@ -679,20 +694,28 @@ ikev2_recv(struct iked *env, struct iked_message *msg)
if (hdr->ike_exchange != IKEV2_EXCHANGE_IKE_SA_INIT &&
hdr->ike_nextpayload != IKEV2_PAYLOAD_SK &&
- hdr->ike_nextpayload != IKEV2_PAYLOAD_SKF)
+ hdr->ike_nextpayload != IKEV2_PAYLOAD_SKF) {
+ ikestat_inc(env, ikes_msg_rcvd_dropped);
return;
+ }
if (msg->msg_response) {
- if (msg->msg_msgid > sa->sa_reqid)
+ if (msg->msg_msgid > sa->sa_reqid) {
+ ikestat_inc(env, ikes_msg_rcvd_dropped);
return;
+ }
mr = ikev2_msg_lookup(env, &sa->sa_requests, msg,
hdr->ike_exchange);
if (hdr->ike_exchange != IKEV2_EXCHANGE_INFORMATIONAL &&
- mr == NULL && sa->sa_fragments.frag_count == 0)
+ mr == NULL && sa->sa_fragments.frag_count == 0) {
+ ikestat_inc(env, ikes_msg_rcvd_dropped);
return;
+ }
if (flag) {
- if ((sa->sa_stateflags & flag) == 0)
+ if ((sa->sa_stateflags & flag) == 0) {
+ ikestat_inc(env, ikes_msg_rcvd_dropped);
return;
+ }
/*
* We have initiated this exchange, even if
* we are not the initiator of the IKE SA.
@@ -723,8 +746,10 @@ ikev2_recv(struct iked *env, struct iked_message *msg)
msg->msg_sa = sa = NULL;
goto done;
}
- if (msg->msg_msgid < sa->sa_msgid)
+ if (msg->msg_msgid < sa->sa_msgid) {
+ ikestat_inc(env, ikes_msg_rcvd_dropped);
return;
+ }
if (flag)
initiator = 0;
/*
@@ -745,6 +770,7 @@ ikev2_recv(struct iked *env, struct iked_message *msg)
* Response is being worked on, most likely we're
* waiting for the CA process to get back to us
*/
+ ikestat_inc(env, ikes_msg_rcvd_busy);
return;
}
sa->sa_msgid_current = msg->msg_msgid;
@@ -753,8 +779,10 @@ ikev2_recv(struct iked *env, struct iked_message *msg)
if (sa_address(sa, &sa->sa_peer, (struct sockaddr *)&msg->msg_peer)
== -1 ||
sa_address(sa, &sa->sa_local, (struct sockaddr *)&msg->msg_local)
- == -1)
+ == -1) {
+ ikestat_inc(env, ikes_msg_rcvd_dropped);
return;
+ }
sa->sa_fd = msg->msg_fd;
@@ -1033,6 +1061,7 @@ ikev2_ike_auth_recv(struct iked *env, struct iked_sa *sa,
0, -1) != 0) {
log_info("%s: no proposal chosen", __func__);
msg->msg_error = IKEV2_N_NO_PROPOSAL_CHOSEN;
+ ikestat_inc(env, ikes_sa_proposals_negotiate_failures);
return (-1);
} else
sa_stateflags(sa, IKED_REQ_SA);
@@ -4378,6 +4407,7 @@ ikev2_init_create_child_sa(struct iked *env, struct iked_message *msg)
if (proposals_negotiate(&sa->sa_proposals, &sa->sa_proposals,
&msg->msg_proposals, 1, -1) != 0) {
log_info("%s: no proposal chosen", SPI_SA(sa, __func__));
+ ikestat_inc(env, ikes_sa_proposals_negotiate_failures);
return (-1);
}
@@ -4710,6 +4740,8 @@ ikev2_ikesa_enable(struct iked *env, struct iked_sa *sa, struct iked_sa *nsa)
sa_state(env, nsa, IKEV2_STATE_ESTABLISHED);
ikev2_enable_timer(env, nsa);
+ ikestat_inc(env, ikes_sa_rekeyed);
+
nsa->sa_stateflags = nsa->sa_statevalid; /* XXX */
/* unregister DPD keep alive timer & rekey first */
@@ -4887,6 +4919,7 @@ ikev2_resp_create_child_sa(struct iked *env, struct iked_message *msg)
1, msg->msg_dhgroup) != 0) {
log_info("%s: no proposal chosen", __func__);
msg->msg_error = IKEV2_N_NO_PROPOSAL_CHOSEN;
+ ikestat_inc(env, ikes_sa_proposals_negotiate_failures);
goto fail;
}
@@ -5176,6 +5209,7 @@ ikev2_ike_sa_alive(struct iked *env, void *arg)
ikev2_send_ike_e(env, sa, NULL, IKEV2_PAYLOAD_NONE,
IKEV2_EXCHANGE_INFORMATIONAL, 0);
sa->sa_stateflags |= IKED_REQ_INF;
+ ikestat_inc(env, ikes_dpd_sent);
}
/* re-register */
@@ -5199,6 +5233,7 @@ ikev2_ike_sa_keepalive(struct iked *env, void *arg)
log_debug("%s: peer %s local %s", __func__,
print_host((struct sockaddr *)&sa->sa_peer.addr, NULL, 0),
print_host((struct sockaddr *)&sa->sa_local.addr, NULL, 0));
+ ikestat_inc(env, ikes_keepalive_sent);
timer_add(env, &sa->sa_keepalive, IKED_IKE_SA_KEEPALIVE_TIMEOUT);
}
@@ -5399,6 +5434,7 @@ ikev2_sa_negotiate_common(struct iked *env, struct iked_sa *sa, struct iked_mess
if (proposals_negotiate(&sa->sa_proposals,
&msg->msg_policy->pol_proposals, &msg->msg_proposals, 0, -1) != 0) {
log_info("%s: proposals_negotiate", __func__);
+ ikestat_inc(env, ikes_sa_proposals_negotiate_failures);
return (-1);
}
if (sa_stateok(sa, IKEV2_STATE_SA_INIT))
@@ -6361,6 +6397,7 @@ ikev2_childsa_negotiate(struct iked *env, struct iked_sa *sa,
TAILQ_INSERT_TAIL(&sa->sa_childsas, csa, csa_entry);
TAILQ_INSERT_TAIL(&sa->sa_childsas, csb, csa_entry);
+ ikestat_add(env, ikes_csa_created, 2);
csa->csa_peersa = csb;
csb->csa_peersa = csa;
@@ -6609,6 +6646,7 @@ ikev2_childsa_delete(struct iked *env, struct iked_sa *sa, uint8_t saproto,
childsa_free(ipcomp);
}
TAILQ_REMOVE(&sa->sa_childsas, csa, csa_entry);
+ ikestat_inc(env, ikes_csa_removed);
childsa_free(csa);
}
diff --git a/sbin/iked/ikev2_msg.c b/sbin/iked/ikev2_msg.c
index feab4aa7730..c36ba5a24f5 100644
--- a/sbin/iked/ikev2_msg.c
+++ b/sbin/iked/ikev2_msg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2_msg.c,v 1.85 2022/03/14 12:58:55 tobhe Exp $ */
+/* $OpenBSD: ikev2_msg.c,v 1.86 2022/09/19 20:54:02 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -307,7 +307,9 @@ ikev2_msg_send(struct iked *env, struct iked_message *msg)
timer_add(env, &sa->sa_timer,
IKED_IKE_SA_DELETE_TIMEOUT);
}
- }
+ ikestat_inc(env, ikes_msg_send_failures);
+ } else
+ ikestat_inc(env, ikes_msg_sent);
if (sa == NULL)
return (0);
@@ -892,6 +894,8 @@ ikev2_send_encrypted_fragments(struct iked *env, struct iked_sa *sa,
if (ikev2_msg_send(env, &resp) == -1)
goto done;
+ ikestat_inc(env, ikes_frag_sent);
+
offset += MINIMUM(left, max_len);
left -= MINIMUM(left, max_len);
frag_num++;
@@ -908,6 +912,7 @@ ikev2_send_encrypted_fragments(struct iked *env, struct iked_sa *sa,
done:
ikev2_msg_cleanup(env, &resp);
ibuf_release(e);
+ ikestat_inc(env, ikes_frag_send_failures);
return ret;
}
@@ -1268,6 +1273,7 @@ ikev2_msg_retransmit_response(struct iked *env, struct iked_sa *sa,
(struct sockaddr *)&m->msg_peer, m->msg_peerlen,
(struct sockaddr *)&m->msg_local, m->msg_locallen) == -1) {
log_warn("%s: sendtofrom", __func__);
+ ikestat_inc(env, ikes_msg_send_failures);
return (-1);
}
log_info("%sretransmit %s res %u local %s peer %s",
@@ -1279,6 +1285,7 @@ ikev2_msg_retransmit_response(struct iked *env, struct iked_sa *sa,
}
timer_add(env, &mr->mrt_timer, IKED_RESPONSE_TIMEOUT);
+ ikestat_inc(env, ikes_retransmit_response);
return (0);
}
@@ -1309,6 +1316,7 @@ ikev2_msg_retransmit_timeout(struct iked *env, void *arg)
log_warn("%s: sendtofrom", __func__);
ikev2_ike_sa_setreason(sa, "retransmit failed");
sa_free(env, sa);
+ ikestat_inc(env, ikes_msg_send_failures);
return;
}
log_info("%sretransmit %d %s req %u peer %s "
@@ -1321,10 +1329,12 @@ ikev2_msg_retransmit_timeout(struct iked *env, void *arg)
/* Exponential timeout */
timer_add(env, &mr->mrt_timer,
IKED_RETRANSMIT_TIMEOUT * (2 << (mr->mrt_tries++)));
+ ikestat_inc(env, ikes_retransmit_request);
} else {
log_debug("%s: retransmit limit reached for req %u",
__func__, msg->msg_msgid);
ikev2_ike_sa_setreason(sa, "retransmit limit reached");
+ ikestat_inc(env, ikes_retransmit_limit);
sa_free(env, sa);
}
}
diff --git a/sbin/iked/ikev2_pld.c b/sbin/iked/ikev2_pld.c
index d2ec6bd6423..af4f255a328 100644
--- a/sbin/iked/ikev2_pld.c
+++ b/sbin/iked/ikev2_pld.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2_pld.c,v 1.124 2022/07/04 09:23:15 tobhe Exp $ */
+/* $OpenBSD: ikev2_pld.c,v 1.125 2022/09/19 20:54:02 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -1605,6 +1605,7 @@ ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld,
size_t frag_num, frag_total;
size_t len;
int ret = -1;
+ int processed = 0;
ssize_t elen;
buf = msgbuf + offset;
@@ -1616,6 +1617,8 @@ ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld,
buf = msgbuf + offset;
len = left - sizeof(frag);
+ ikestat_inc(env, ikes_frag_rcvd);
+
/* Limit number of total fragments to avoid DOS */
if (frag_total > IKED_FRAG_TOTAL_MAX ) {
log_debug("%s: Total Fragments too big %zu",
@@ -1701,10 +1704,15 @@ ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld,
} else {
ret = 0;
}
+ processed = 1;
+
done:
+ if (!processed)
+ ikestat_inc(env, ikes_frag_rcvd_drop);
ibuf_release(e);
return (ret);
dropall:
+ ikestat_add(env, ikes_frag_rcvd_drop, sa_frag->frag_count + 1);
config_free_fragments(sa_frag);
ibuf_release(e);
return -1;
@@ -1722,6 +1730,7 @@ ikev2_frags_reassemble(struct iked *env, struct ikev2_payload *pld,
size_t i;
struct iked_message emsg;
int ret = -1;
+ int processed = 0;
/* Reassemble fragments to single buffer */
if ((e = ibuf_new(NULL, sa_frag->frag_total_size)) == NULL) {
@@ -1765,7 +1774,12 @@ ikev2_frags_reassemble(struct iked *env, struct ikev2_payload *pld,
ret = ikev2_pld_payloads(env, &emsg, 0, ibuf_size(e),
sa_frag->frag_nextpayload);
+ processed = 1;
done:
+ if (processed)
+ ikestat_add(env, ikes_frag_reass_ok, sa_frag->frag_total);
+ else
+ ikestat_add(env, ikes_frag_reass_drop, sa_frag->frag_total);
config_free_fragments(sa_frag);
ibuf_release(e);
diff --git a/sbin/iked/policy.c b/sbin/iked/policy.c
index ad2b1dc2ccc..a4cdc277355 100644
--- a/sbin/iked/policy.c
+++ b/sbin/iked/policy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: policy.c,v 1.90 2022/09/14 13:07:50 tobhe Exp $ */
+/* $OpenBSD: policy.c,v 1.91 2022/09/19 20:54:02 tobhe Exp $ */
/*
* Copyright (c) 2020-2021 Tobias Heider <tobhe@openbsd.org>
@@ -414,6 +414,28 @@ sa_state(struct iked *env, struct iked_sa *sa, int state)
}
}
+ if (ostate != sa->sa_state) {
+ switch (sa->sa_state) {
+ case IKEV2_STATE_ESTABLISHED:
+ ikestat_inc(env, ikes_sa_established_total);
+ ikestat_inc(env, ikes_sa_established_current);
+ break;
+ case IKEV2_STATE_CLOSED:
+ case IKEV2_STATE_CLOSING:
+ switch (ostate) {
+ case IKEV2_STATE_ESTABLISHED:
+ ikestat_dec(env, ikes_sa_established_current);
+ break;
+ case IKEV2_STATE_CLOSED:
+ case IKEV2_STATE_CLOSING:
+ break;
+ default:
+ ikestat_inc(env, ikes_sa_established_failures);
+ break;
+ }
+ break;
+ }
+ }
}
void
diff --git a/sbin/iked/types.h b/sbin/iked/types.h
index 14f5ca57b27..d4fc55cba76 100644
--- a/sbin/iked/types.h
+++ b/sbin/iked/types.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: types.h,v 1.50 2022/07/22 15:53:33 tobhe Exp $ */
+/* $OpenBSD: types.h,v 1.51 2022/09/19 20:54:02 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -130,7 +130,8 @@ enum imsg_type {
IMSG_AUTH,
IMSG_PRIVKEY,
IMSG_PUBKEY,
- IMSG_CTL_SHOW_CERTSTORE
+ IMSG_CTL_SHOW_CERTSTORE,
+ IMSG_CTL_SHOW_STATS
};
enum privsep_procid {
diff --git a/usr.sbin/ikectl/ikectl.c b/usr.sbin/ikectl/ikectl.c
index 6ba3b25ebe3..cc10c628b50 100644
--- a/usr.sbin/ikectl/ikectl.c
+++ b/usr.sbin/ikectl/ikectl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikectl.c,v 1.27 2021/11/21 22:44:08 tobhe Exp $ */
+/* $OpenBSD: ikectl.c,v 1.28 2022/09/19 20:54:02 tobhe Exp $ */
/*
* Copyright (c) 2007-2013 Reyk Floeter <reyk@openbsd.org>
@@ -49,6 +49,7 @@ void monitor_id(struct imsg *);
int monitor(struct imsg *);
int show_string(struct imsg *);
+int show_stats(struct imsg *, int);
int ca_opt(struct parse_result *);
@@ -303,6 +304,10 @@ main(int argc, char *argv[])
imsg_compose(ibuf, IMSG_CTL_SHOW_SA, 0, 0, -1, NULL, 0);
done = 0;
break;
+ case SHOW_STATS:
+ imsg_compose(ibuf, IMSG_CTL_SHOW_STATS, 0, 0, -1, NULL, 0);
+ done = 0;
+ break;
case SHOW_CERTSTORE:
imsg_compose(ibuf, IMSG_CTL_SHOW_CERTSTORE, 0, 0, -1, NULL, 0);
done = 0;
@@ -354,6 +359,9 @@ main(int argc, char *argv[])
case MONITOR:
done = monitor(&imsg);
break;
+ case SHOW_STATS:
+ done = show_stats(&imsg, quiet);
+ break;
case SHOW_SA:
case SHOW_CERTSTORE:
done = show_string(&imsg);
@@ -421,3 +429,55 @@ show_string(struct imsg *imsg)
return (done);
}
+
+static char *
+plural(u_int64_t n)
+{
+ return (n != 1 ? "s" : "");
+}
+
+/*
+ * Dump IKE statistics structure.
+ */
+int
+show_stats(struct imsg *imsg, int quiet)
+{
+ struct iked_stats *stat;
+ int done = 1;
+
+ if (IMSG_DATA_SIZE(imsg) != sizeof(*stat))
+ return (done);
+ stat = imsg->data;
+ printf("ike:\n");
+#define p(f, m) if (stat->f || !quiet) \
+ printf(m, stat->f, plural(stat->f))
+
+ p(ikes_sa_created, "\t%llu IKE SA%s created\n");
+ p(ikes_sa_established_total, "\t%llu IKE SA%s established\n");
+ p(ikes_sa_established_current, "\t%llu IKE SA%s currently established\n");
+ p(ikes_sa_established_failures, "\t%llu IKE SA%s failed to establish\n");
+ p(ikes_sa_proposals_negotiate_failures, "\t%llu failed proposal negotiation%s\n");
+ p(ikes_sa_rekeyed, "\t%llu IKE SA%s rekeyed\n");
+ p(ikes_sa_removed, "\t%llu IKE SA%s removed\n");
+ p(ikes_csa_created, "\t%llu Child SA%s created\n");
+ p(ikes_csa_removed, "\t%llu Child SA%s removed\n");
+ p(ikes_msg_sent, "\t%llu message%s sent\n");
+ p(ikes_msg_send_failures, "\t%llu message%s could not be sent\n");
+ p(ikes_msg_rcvd, "\t%llu message%s received\n");
+ p(ikes_msg_rcvd_dropped, "\t%llu message%s dropped\n");
+ p(ikes_msg_rcvd_busy, "\t%llu request%s dropped, response being worked on\n");
+ p(ikes_retransmit_response, "\t%llu response%s retransmitted\n");
+ p(ikes_retransmit_request, "\t%llu request%s retransmitted\n");
+ p(ikes_retransmit_limit, "\t%llu request%s timed out\n");
+ p(ikes_frag_sent, "\t%llu fragment%s sent\n");
+ p(ikes_frag_send_failures, "\t%llu fragment%s could not be sent\n");
+ p(ikes_frag_rcvd, "\t%llu fragment%s received\n");
+ p(ikes_frag_rcvd_drop, "\t%llu fragment%s dropped\n");
+ p(ikes_frag_reass_ok, "\t%llu fragment%s reassembled\n");
+ p(ikes_frag_reass_drop, "\t%llu fragment%s could not be reassembled\n");
+ p(ikes_update_addresses_sent, "\t%llu update addresses request%s sent\n");
+ p(ikes_dpd_sent, "\t%llu dpd request%s sent\n");
+ p(ikes_keepalive_sent, "\t%llu keepalive message%s sent\n");
+#undef p
+ return (done);
+}
diff --git a/usr.sbin/ikectl/parser.c b/usr.sbin/ikectl/parser.c
index 008f986ba6f..008bff43483 100644
--- a/usr.sbin/ikectl/parser.c
+++ b/usr.sbin/ikectl/parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.c,v 1.20 2021/11/21 22:44:08 tobhe Exp $ */
+/* $OpenBSD: parser.c,v 1.21 2022/09/19 20:54:02 tobhe Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -215,6 +215,7 @@ static const struct token t_show[] = {
{ KEYWORD, "ca", SHOW_CA, t_show_ca },
{ KEYWORD, "sa", SHOW_SA, NULL },
{ KEYWORD, "certstore", SHOW_CERTSTORE,NULL },
+ { KEYWORD, "stats", SHOW_STATS, NULL },
{ ENDTOKEN, "", NONE, NULL }
};
diff --git a/usr.sbin/ikectl/parser.h b/usr.sbin/ikectl/parser.h
index cd20e793fef..2e06e357a95 100644
--- a/usr.sbin/ikectl/parser.h
+++ b/usr.sbin/ikectl/parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.h,v 1.17 2021/11/21 22:44:08 tobhe Exp $ */
+/* $OpenBSD: parser.h,v 1.18 2022/09/19 20:54:02 tobhe Exp $ */
/*
* Copyright (c) 2007-2013 Reyk Floeter <reyk@openbsd.org>
@@ -57,7 +57,8 @@ enum actions {
SHOW_CA_CERTIFICATES,
SHOW_SA,
RESET_ID,
- SHOW_CERTSTORE
+ SHOW_CERTSTORE,
+ SHOW_STATS
};
struct parse_result {