aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/sa/child_sa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/sa/child_sa.c')
-rw-r--r--src/charon/sa/child_sa.c264
1 files changed, 121 insertions, 143 deletions
diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c
index 3a5929759..271bca78a 100644
--- a/src/charon/sa/child_sa.c
+++ b/src/charon/sa/child_sa.c
@@ -22,25 +22,22 @@
* for more details.
*/
+#define _GNU_SOURCE
#include "child_sa.h"
#include <stdio.h>
#include <string.h>
+#include <printf.h>
#include <daemon.h>
-
-/**
- * String mappings for child_sa_state_t.
- */
-mapping_t child_sa_state_m[] = {
- {CHILD_CREATED, "CREATED"},
- {CHILD_INSTALLED, "INSTALLED"},
- {CHILD_ROUTED, "ROUTED"},
- {CHILD_REKEYING, "REKEYING"},
- {CHILD_DELETING, "DELETNG"},
- {MAPPING_END, NULL}
-};
+ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DELETING,
+ "CREATED",
+ "ROUTED",
+ "INSTALLED",
+ "REKEYING",
+ "DELETING",
+);
typedef struct sa_policy_t sa_policy_t;
@@ -170,11 +167,6 @@ struct private_child_sa_t {
* Specifies if NAT traversal is used
*/
bool use_natt;
-
- /**
- * CHILD_SAs own logger
- */
- logger_t *logger;
};
/**
@@ -254,18 +246,15 @@ static void updown(private_child_sa_t *this, bool up)
sa_policy_t *policy;
char command[1024];
char *ifname = NULL;
- char *my_str, *other_str;
char *my_client, *other_client, *my_client_mask, *other_client_mask;
char *pos;
FILE *shell;
/* get ts strings */
iterator->current(iterator, (void**)&policy);
- my_str = policy->my_ts->get_string(policy->my_ts);
- other_str = policy->other_ts->get_string(policy->other_ts);
/* get subnet/bits from string */
- my_client = strdup(my_str);
+ asprintf(&my_client, "%R", policy->my_ts);
pos = strchr(my_client, '/');
*pos = '\0';
my_client_mask = pos + 1;
@@ -274,7 +263,7 @@ static void updown(private_child_sa_t *this, bool up)
{
*pos = '\0';
}
- other_client = strdup(other_str);
+ asprintf(&other_client, "%R", policy->other_ts);
pos = strchr(other_client, '/');
*pos = '\0';
other_client_mask = pos + 1;
@@ -313,8 +302,8 @@ static void updown(private_child_sa_t *this, bool up)
"%s"
"%s",
up ? "up" : "down",
- /* TODO: fix it: streq(this->me.addr->get_string(this->me.addr),
- my_client) ? "-host" :*/ "-client",
+ policy->my_ts->is_host(policy->my_ts,
+ this->me.addr) ? "-host" : "-client",
this->me.addr->get_family(this->me.addr) == AF_INET ? "" : "-ipv6",
this->name,
ifname,
@@ -341,9 +330,7 @@ static void updown(private_child_sa_t *this, bool up)
if (shell == NULL)
{
- this->logger->log(this->logger, ERROR,
- "could not execute updown script '%s'",
- this->script);
+ DBG1(SIG_DBG_CHD, "could not execute updown script '%s'", this->script);
return;
}
@@ -355,8 +342,7 @@ static void updown(private_child_sa_t *this, bool up)
{
if (ferror(shell))
{
- this->logger->log(this->logger, ERROR,
- "error reading output from updown script");
+ DBG1(SIG_DBG_CHD, "error reading output from updown script");
return;
}
else
@@ -371,7 +357,7 @@ static void updown(private_child_sa_t *this, bool up)
{ /* trim trailing '\n' */
e[-1] = '\0';
}
- this->logger->log(this->logger, ERROR, "updown: %s", resp);
+ DBG1(SIG_DBG_CHD, "updown: %s", resp);
}
}
pclose(shell);
@@ -507,15 +493,14 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
dst = this->other.addr;
}
- this->logger->log(this->logger, CONTROL|LEVEL1, "adding %s %s SA",
- mine ? "inbound" : "outbound",
- mapping_find(protocol_id_m, this->protocol));
+ DBG2(SIG_DBG_CHD, "adding %s %N SA", mine ? "inbound" : "outbound",
+ protocol_id_names, this->protocol);
/* select encryption algo */
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &enc_algo))
{
- this->logger->log(this->logger, CONTROL|LEVEL2, " using %s for encryption",
- mapping_find(encryption_algorithm_m, enc_algo->algorithm));
+ DBG2(SIG_DBG_CHD, " using %N for encryption",
+ encryption_algorithm_names, enc_algo->algorithm);
}
else
{
@@ -525,8 +510,8 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
/* select integrity algo */
if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &int_algo))
{
- this->logger->log(this->logger, CONTROL|LEVEL2, " using %s for integrity",
- mapping_find(integrity_algorithm_m, int_algo->algorithm));
+ DBG2(SIG_DBG_CHD, " using %N for integrity",
+ integrity_algorithm_names, int_algo->algorithm);
}
else
{
@@ -547,9 +532,7 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
/* send SA down to the kernel */
- this->logger->log(this->logger, CONTROL|LEVEL2,
- " SPI 0x%.8x, src %H dst %H",
- ntohl(spi), src, dst);
+ DBG2(SIG_DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
status = charon->kernel_interface->add_sa(charon->kernel_interface,
src, dst,
spi, this->protocol,
@@ -645,8 +628,8 @@ static status_t add_policies(private_child_sa_t *this, linked_list_t *my_ts_list
if (my_ts->get_type(my_ts) != other_ts->get_type(other_ts))
{
- this->logger->log(this->logger, CONTROL|LEVEL1,
- "CHILD_SA policy uses two different IP families, ignored");
+ DBG2(SIG_DBG_CHD,
+ "CHILD_SA policy uses two different IP families, ignored");
continue;
}
@@ -654,8 +637,8 @@ static status_t add_policies(private_child_sa_t *this, linked_list_t *my_ts_list
if (my_ts->get_protocol(my_ts) != other_ts->get_protocol(other_ts) &&
my_ts->get_protocol(my_ts) && other_ts->get_protocol(other_ts))
{
- this->logger->log(this->logger, CONTROL|LEVEL1,
- "CHILD_SA policy uses two different protocols, ignored");
+ DBG2(SIG_DBG_CHD,
+ "CHILD_SA policy uses two different protocols, ignored");
continue;
}
@@ -774,134 +757,133 @@ static status_t get_use_time(private_child_sa_t *this, bool inbound, time_t *use
}
/**
- * Implementation of child_sa_t.log_status.
+ * output handler in printf()
*/
-static void log_status(private_child_sa_t *this, logger_t *logger)
+static int print(FILE *stream, const struct printf_info *info,
+ const void *const *args)
{
+ private_child_sa_t *this = *((private_child_sa_t**)(args[0]));
iterator_t *iterator;
- char use_in_str[12] = "unused";
- char use_out_str[12] = "unused";
- char rekey_str[12] = "disabled";
- char enc_str[32] = "";
- char int_str[32] = "";
- u_int32_t use_in, use_out, use_fwd, now, rekeying;
+ sa_policy_t *policy;
+ u_int32_t now, rekeying, use;
status_t status;
+ size_t written, total_written = 0;
+#define fprintf_sum(...) { written = fprintf(__VA_ARGS__); if (written < 0) return written; total_written += written; }
- if (logger == NULL)
+ if (this == NULL)
{
- logger = this->logger;
+ return fprintf(stream, "(null)");
}
+
now = (u_int32_t)time(NULL);
+ fprintf_sum(stream, "%10s: %N, reqid: %d", this->name,
+ child_sa_state_names, this->state, this->reqid);
+
if (this->state == CHILD_INSTALLED)
{
- /* query SA times */
- status = charon->kernel_interface->query_sa(charon->kernel_interface,
- this->me.addr, this->me.spi, this->protocol, &use_in);
- if (status == SUCCESS && use_in)
- {
- snprintf(use_in_str, sizeof(use_in_str), "%ds", now - use_in);
- }
- status = charon->kernel_interface->query_sa(charon->kernel_interface,
- this->other.addr, this->other.spi, this->protocol, &use_out);
- if (status == SUCCESS && use_out)
- {
- snprintf(use_out_str, sizeof(use_out_str), "%ds", now - use_out);
- }
-
- /* calculate rekey times */
- if (this->soft_lifetime)
- {
- rekeying = this->soft_lifetime - (now - this->install_time);
- snprintf(rekey_str, sizeof(rekey_str), "%ds", (int)rekeying);
- }
+ fprintf_sum(stream, ", %N, SPIs (in/out): 0x%x/0x%x",
+ protocol_id_names, this->protocol,
+ htonl(this->me.spi), htonl(this->other.spi));
- /* algorithms used */
- if (this->protocol == PROTO_ESP)
+ if (info->alt)
{
- if (this->encryption.key_size)
+ fprintf_sum(stream, "\n%10s: ", this->name);
+
+ if (this->protocol == PROTO_ESP)
{
- snprintf(enc_str, sizeof(enc_str), "%s-%d,",
- mapping_find(encryption_algorithm_m, this->encryption.algorithm),
- this->encryption.key_size);
+ fprintf_sum(stream, "%N",
+ encryption_algorithm_names, this->encryption.algorithm);
+
+ if (this->encryption.key_size)
+ {
+ fprintf_sum(stream, "-%d", this->encryption.key_size);
+ }
+ fprintf_sum(stream, "/");
+ }
+
+ fprintf_sum(stream, "%N",
+ integrity_algorithm_names, this->integrity.algorithm);
+ if (this->integrity.key_size)
+ {
+ fprintf_sum(stream, "-%d", this->integrity.key_size);
+ }
+ fprintf_sum(stream, ", rekeying: ");
+
+ /* calculate rekey times */
+ if (this->soft_lifetime)
+ {
+ rekeying = this->soft_lifetime - (now - this->install_time);
+ fprintf_sum(stream, "%ds", rekeying);
}
else
{
- snprintf(enc_str, sizeof(enc_str), "%s,",
- mapping_find(encryption_algorithm_m, this->encryption.algorithm));
+ fprintf_sum(stream, "disabled");
}
}
- if (this->integrity.key_size)
- {
- snprintf(int_str, sizeof(int_str), "%s-%d",
- mapping_find(integrity_algorithm_m, this->integrity.algorithm),
- this->integrity.key_size);
- }
- else
- {
- snprintf(int_str, sizeof(int_str), "%s",
- mapping_find(integrity_algorithm_m, this->integrity.algorithm));
- }
-
- logger->log(logger, CONTROL|LEVEL1,
- " \"%s\": state: %s, reqid: %d, ",
- this->name, mapping_find(child_sa_state_m, this->state), this->reqid);
- logger->log(logger, CONTROL|LEVEL1,
- " \"%s\": %s (%s%s), SPIs (in/out): 0x%x/0x%x",
- this->name, this->protocol == PROTO_ESP ? "ESP" : "AH",
- enc_str, int_str,
- htonl(this->me.spi), htonl(this->other.spi));
- logger->log(logger, CONTROL|LEVEL1,
- " \"%s\": rekeying: %s, key age (in/out): %s/%s",
- this->name, rekey_str, use_in_str, use_out_str);
}
- else
- {
- logger->log(logger, CONTROL|LEVEL1, " \"%s\": state: %s, reqid: %d",
- this->name, mapping_find(child_sa_state_m, this->state),
- this->reqid);
- }
-
+#undef fprintf_sum
+#define fprintf_sum(...) { written = fprintf(__VA_ARGS__); if (written < 0) { iterator->destroy(iterator); return written; } total_written += written; }
iterator = this->policies->create_iterator(this->policies, TRUE);
- while (iterator->has_next(iterator))
+ while (iterator->iterate(iterator, (void**)&policy))
{
- sa_policy_t *policy;
- char *my_str;
- char *other_str;
- char pol_in_str[12] = "unused";
- char pol_out_str[12] = "unused";
- char pol_fwd_str[12] = "unused";
-
- /* get ts strings */
- iterator->current(iterator, (void**)&policy);
- my_str = policy->my_ts->get_string(policy->my_ts);
- other_str = policy->other_ts->get_string(policy->other_ts);
+ fprintf_sum(stream, "\n%10s: %R===%R, last use (in/out/fwd): ",
+ this->name, policy->my_ts, policy->other_ts);
/* query policy times */
status = charon->kernel_interface->query_policy(charon->kernel_interface,
- policy->other_ts, policy->my_ts, POLICY_IN, &use_in);
- if (status == SUCCESS && use_in)
+ policy->other_ts, policy->my_ts, POLICY_IN, &use);
+ if (status == SUCCESS && use)
+ {
+ fprintf_sum(stream, "%ds/", now - use);
+ }
+ else
{
- snprintf(pol_in_str, sizeof(pol_in_str), "%ds", now - use_in);
+ fprintf_sum(stream, "unused/");
}
status = charon->kernel_interface->query_policy(charon->kernel_interface,
- policy->my_ts, policy->other_ts, POLICY_OUT, &use_out);
- if (status == SUCCESS && use_out)
+ policy->my_ts, policy->other_ts, POLICY_OUT, &use);
+ if (status == SUCCESS && use)
+ {
+ fprintf_sum(stream, "%ds/", now - use);
+ }
+ else
{
- snprintf(pol_out_str, sizeof(pol_out_str), "%ds", now - use_out);
+ fprintf_sum(stream, "unused/");
}
status = charon->kernel_interface->query_policy(charon->kernel_interface,
- policy->other_ts, policy->my_ts, POLICY_FWD, &use_fwd);
- if (status == SUCCESS && use_fwd)
+ policy->other_ts, policy->my_ts, POLICY_FWD, &use);
+ if (status == SUCCESS && use)
{
- snprintf(pol_fwd_str, sizeof(pol_fwd_str), "%ds", now - use_fwd);
+ fprintf_sum(stream, "%ds", now - use);
+ }
+ else
+ {
+ fprintf_sum(stream, "unused");
}
-
- logger->log(logger, CONTROL,
- " \"%s\": %s====%s, last use (in/out/fwd): %s/%s/%s",
- this->name, my_str, other_str, pol_in_str, pol_out_str, pol_fwd_str);
}
iterator->destroy(iterator);
+ return total_written;
+}
+
+/**
+ * arginfo handler in printf()
+ */
+static int print_arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+ if (n > 0)
+ {
+ argtypes[0] = PA_POINTER;
+ }
+ return 1;
+}
+
+/**
+ * register printf() handlers
+ */
+static void __attribute__ ((constructor))print_register()
+{
+ register_printf_function(CHILD_SA_PRINTF_SPEC, print, print_arginfo);
}
/**
@@ -936,10 +918,8 @@ static status_t update_sa_hosts(private_child_sa_t *this, host_t *new_me, host_t
spi = this->me.spi;
}
- this->logger->log(this->logger, CONTROL|LEVEL1,
- "updating %s SA 0x%x, from %#H..#H to %#H..%#H",
- mapping_find(protocol_id_m, this->protocol), ntohl(spi),
- src, dst, new_src, new_dst);
+ DBG2(SIG_DBG_CHD, "updating %N SA 0x%x, from %#H..#H to %#H..%#H",
+ protocol_id_names, this->protocol, ntohl(spi), src, dst, new_src, new_dst);
status = charon->kernel_interface->update_sa(charon->kernel_interface,
dst, spi, this->protocol,
@@ -1138,11 +1118,9 @@ child_sa_t * child_sa_create(u_int32_t rekey, host_t *me, host_t* other,
this->public.get_rekeying_transaction = (void* (*)(child_sa_t*))get_rekeying_transaction;
this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state;
this->public.get_state = (child_sa_state_t(*)(child_sa_t*))get_state;
- this->public.log_status = (void (*)(child_sa_t*, logger_t*))log_status;
this->public.destroy = (void(*)(child_sa_t*))destroy;
/* private data */
- this->logger = logger_manager->get_logger(logger_manager, CHILD_SA);
this->name = strdup("(uninitialized)");
this->me.addr = me->clone(me);
this->other.addr = other->clone(other);