void log_state(struct state *st, enum state_kind new_state) { char buf[1024]; struct log_conn_info lc; struct connection *conn; const char *tun = NULL, *p1 = NULL, *p2 = NULL; enum state_kind save_state; if (pluto_stats_binary == NULL) return; if (st == NULL) { DBG(DBG_CONTROLMORE, DBG_log( "log_state() called without state")); return; } conn = st->st_connection; if (conn == NULL || st->st_connection->name == NULL) { DBG(DBG_CONTROLMORE, DBG_log("log_state() called without st->st_connection or without st->st_connection->name")); return; } DBG(DBG_CONTROLMORE, DBG_log("log_state called for state update for connection %s ", conn->name)); zero(&lc); lc.conn = conn; save_state = st->st_state; st->st_state = new_state; for_each_state(connection_state, &lc); st->st_state = save_state; if (conn->statsval == (IPsecSAref2NFmark(st->st_ref) | LOG_CONN_STATSVAL(&lc))) { DBG(DBG_CONTROLMORE, DBG_log("log_state for connection %s state change signature (%d) matches last one - skip logging", conn->name, conn->statsval)); return; } conn->statsval = IPsecSAref2NFmark(st->st_ref) | LOG_CONN_STATSVAL(&lc); DBG(DBG_CONTROLMORE, DBG_log("log_state set state change signature for connection %s to %d", conn->name, conn->statsval)); switch (lc.tunnel) { case tun_phase1: tun = "phase1"; break; case tun_phase1up: tun = "phase1up"; break; case tun_phase15: tun = "phase15"; break; case tun_phase2: tun = "phase2"; break; case tun_up: tun = "up"; break; case tun_down: tun = "down"; break; default: tun = "unchanged"; break; } switch (lc.phase1) { case p1_init: p1 = "init"; break; case p1_encrypt: p1 = "encrypt"; break; case p1_auth: p1 = "auth"; break; case p1_up: p1 = "up"; break; case p1_down: p1 = "down"; break; default: p1 = "unchanged"; break; } switch (lc.phase2) { case p2_neg: p2 = "neg"; break; case p2_up: p2 = "up"; break; default: p2 = "down"; break; } DBG(DBG_CONTROLMORE, DBG_log("log_state calling %s for connection %s with tunnel(%s) phase1(%s) phase2(%s)", pluto_stats_binary, conn->name, tun, p1, p2)); snprintf(buf, sizeof(buf), "%s " "%s ipsec-tunnel-%s if_stats /proc/net/dev/%s \\; " "%s ipsec-tunnel-%s tunnel %s \\; " "%s ipsec-tunnel-%s phase1 %s \\; " "%s ipsec-tunnel-%s phase2 %s \\; " "%s ipsec-tunnel-%s nfmark-me/him 0x%x/0x%x", pluto_stats_binary, conn->interface ? "push" : "drop", conn->name, conn->interface ? conn->interface->ip_dev->id_vname : "", tun ? "push" : "drop", conn->name, tun ? tun : "", p1 ? "push" : "drop", conn->name, p1 ? p1 : "", p2 ? "push" : "drop", conn->name, p2 ? p2 : "", (st->st_ref || st->st_refhim) ? "push" : "drop", conn->name, st->st_ref == IPSEC_SAREF_NA ? IPSEC_SAREF_NA : st->st_ref == IPSEC_SAREF_NULL ? 0u : IPsecSAref2NFmark(st->st_ref) | IPSEC_NFMARK_IS_SAREF_BIT , st->st_refhim == IPSEC_SAREF_NA ? IPSEC_SAREF_NA : st->st_refhim == IPSEC_SAREF_NULL ? 0u : IPsecSAref2NFmark(st->st_refhim) | IPSEC_NFMARK_IS_SAREF_BIT); if (system(buf) == -1) { loglog(RC_LOG_SERIOUS,"statsbin= failed to send status update notification"); } DBG(DBG_CONTROLMORE, DBG_log("log_state for connection %s completed", conn->name)); }
void log_state(struct state *st, enum state_kind new_state) { char buf[1024]; struct log_conn_info lc; struct connection *conn; const char *tun = NULL, *p1 = NULL, *p2 = NULL; enum state_kind save_state; if (!st || !st->st_connection || !st->st_connection->name) { DBG(DBG_CONTROLMORE, DBG_log("log_state() called without state")); return; } conn = st->st_connection; if (!conn) { DBG(DBG_CONTROLMORE, DBG_log("log_state() called without st->st_connection (this line cannot fire)")); return; } DBG(DBG_CONTROLMORE, DBG_log("log_state called for state update for connection %s ", conn->name)); memset(&lc, 0, sizeof(lc)); lc.conn = conn; save_state = st->st_state; st->st_state = new_state; for_each_state((void *)connection_state, &lc); st->st_state = save_state; if (conn->statsval == (IPsecSAref2NFmark(st->st_ref) | LOG_CONN_STATSVAL(&lc))) { DBG(DBG_CONTROLMORE, DBG_log("log_state for connection %s state change signature (%d) matches last one - skip logging", conn->name, conn->statsval)); return; } conn->statsval = IPsecSAref2NFmark(st->st_ref) | LOG_CONN_STATSVAL(&lc); DBG(DBG_CONTROLMORE, DBG_log("log_state set state change signature for connection %s to %d", conn->name, conn->statsval)); switch (lc.tunnel) { case tun_phase1: tun = "phase1"; break; case tun_phase1up:tun = "phase1up";break; case tun_phase15: tun = "phase15"; break; case tun_phase2: tun = "phase2"; break; case tun_up: tun = "up"; break; case tun_down: tun = "down"; break; /* not set anywhere, default */ default: tun = "unchanged"; break; } switch (lc.phase1) { case p1_init: p1 = "init"; break; case p1_encrypt: p1 = "encrypt"; break; case p1_auth: p1 = "auth"; break; case p1_up: p1 = "up"; break; case p1_down: p1 = "down"; break; default: p1 = "unchanged"; break; } switch (lc.phase2) { case p2_neg: p2 = "neg"; break; case p2_up: p2 = "up"; break; default: p2 = "down"; break; } DBG(DBG_CONTROLMORE, DBG_log("log_state calling openswan-statsd for connection %s with tunnel(%s) phase1(%s) phase2(%s)", conn->name, tun, p1, p2)); snprintf(buf, sizeof(buf), "/bin/openswan-statsd " "%s ipsec-tunnel-%s if_stats /proc/net/dev/%s \\; " "%s ipsec-tunnel-%s tunnel %s \\; " "%s ipsec-tunnel-%s phase1 %s \\; " "%s ipsec-tunnel-%s phase2 %s \\; " "%s ipsec-tunnel-%s nfmark-me/him 0x%x/0x%x", conn->interface ? "push" : "drop", conn->name, conn->interface ? conn->interface->ip_dev->id_vname : "", tun ? "push" : "drop", conn->name, tun ? tun : "", p1 ? "push" : "drop", conn->name, p1 ? p1 : "", p2 ? "push" : "drop", conn->name, p2 ? p2 : "", (st->st_ref || st->st_refhim) ? "push" : "drop", conn->name, st->st_ref == IPSEC_SAREF_NA ? IPSEC_SAREF_NA : st->st_ref == IPSEC_SAREF_NULL ? 0u : IPsecSAref2NFmark(st->st_ref) | IPSEC_NFMARK_IS_SAREF_BIT , st->st_refhim == IPSEC_SAREF_NA ? IPSEC_SAREF_NA : st->st_refhim == IPSEC_SAREF_NULL ? 0u : IPsecSAref2NFmark(st->st_refhim) | IPSEC_NFMARK_IS_SAREF_BIT ); system(buf); DBG(DBG_CONTROLMORE, DBG_log("log_state for connection %s completed", conn->name)); }