diff options
-rw-r--r-- | sbin/iked/config.c | 9 | ||||
-rw-r--r-- | sbin/iked/control.c | 4 | ||||
-rw-r--r-- | sbin/iked/iked.h | 39 | ||||
-rw-r--r-- | sbin/iked/ikev2.c | 54 | ||||
-rw-r--r-- | sbin/iked/ikev2_msg.c | 14 | ||||
-rw-r--r-- | sbin/iked/ikev2_pld.c | 16 | ||||
-rw-r--r-- | sbin/iked/policy.c | 24 | ||||
-rw-r--r-- | sbin/iked/types.h | 5 | ||||
-rw-r--r-- | usr.sbin/ikectl/ikectl.c | 62 | ||||
-rw-r--r-- | usr.sbin/ikectl/parser.c | 3 | ||||
-rw-r--r-- | usr.sbin/ikectl/parser.h | 5 |
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 { |