aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-09-08 11:59:00 +0200
committerMartin Willi <martin@revosec.ch>2010-09-08 12:00:57 +0200
commit30cd31fb69e2f7e8ce1b1b09a4b6f1f03cc81393 (patch)
tree6e2cdce0a6c0fcbf5a576c3496ddd9738aa08c12 /src/libcharon
parent51b385d44d4dffb4c337bb559131da0bfad317d3 (diff)
downloadstrongswan-30cd31fb69e2f7e8ce1b1b09a4b6f1f03cc81393.tar.bz2
strongswan-30cd31fb69e2f7e8ce1b1b09a4b6f1f03cc81393.tar.xz
Added a simple led plugin to control Linux LEDs based on IKE activity
Diffstat (limited to 'src/libcharon')
-rw-r--r--src/libcharon/Makefile.am7
-rw-r--r--src/libcharon/plugins/led/Makefile.am16
-rw-r--r--src/libcharon/plugins/led/led_listener.c241
-rw-r--r--src/libcharon/plugins/led/led_listener.h49
-rw-r--r--src/libcharon/plugins/led/led_plugin.c67
-rw-r--r--src/libcharon/plugins/led/led_plugin.h42
6 files changed, 422 insertions, 0 deletions
diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am
index ef5f9f499..5b5bd1dc4 100644
--- a/src/libcharon/Makefile.am
+++ b/src/libcharon/Makefile.am
@@ -354,6 +354,13 @@ if MONOLITHIC
endif
endif
+if USE_LED
+ SUBDIRS += plugins/led
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/led/libstrongswan-led.la
+endif
+endif
+
if USE_UCI
SUBDIRS += plugins/uci
if MONOLITHIC
diff --git a/src/libcharon/plugins/led/Makefile.am b/src/libcharon/plugins/led/Makefile.am
new file mode 100644
index 000000000..6428361fc
--- /dev/null
+++ b/src/libcharon/plugins/led/Makefile.am
@@ -0,0 +1,16 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-led.la
+else
+plugin_LTLIBRARIES = libstrongswan-led.la
+endif
+
+libstrongswan_led_la_SOURCES = led_plugin.h led_plugin.c \
+ led_listener.h led_listener.c
+
+libstrongswan_led_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/led/led_listener.c b/src/libcharon/plugins/led/led_listener.c
new file mode 100644
index 000000000..18def8005
--- /dev/null
+++ b/src/libcharon/plugins/led/led_listener.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "led_listener.h"
+
+#include <errno.h>
+
+#include <daemon.h>
+#include <threading/mutex.h>
+#include <processing/jobs/callback_job.h>
+
+typedef struct private_led_listener_t private_led_listener_t;
+
+/**
+ * Private data of an led_listener_t object.
+ */
+struct private_led_listener_t {
+
+ /**
+ * Public led_listener_t interface.
+ */
+ led_listener_t public;
+
+ /**
+ * Mutex
+ */
+ mutex_t *mutex;
+
+ /**
+ * Number of established IKE_SAs
+ */
+ int count;
+
+ /**
+ * LED blink on/off time, in ms
+ */
+ int blink_time;
+
+ /**
+ * Activity LED fd, if any
+ */
+ FILE *activity;
+
+ /**
+ * Activity LED maximum brightness
+ */
+ int activity_max;
+};
+
+/**
+ * Open a LED brightness control file, get max brightness
+ */
+static FILE *open_led(char *name, int *max_brightness)
+{
+ char path[PATH_MAX];
+ FILE *f;
+
+ if (!name)
+ {
+ return NULL;
+ }
+
+ *max_brightness = 1;
+ snprintf(path, sizeof(path), "/sys/class/leds/%s/max_brightness", name);
+ f = fopen(path, "r");
+ if (f)
+ {
+ if (fscanf(f, "%d\n", max_brightness) != 1)
+ {
+ DBG1(DBG_CFG, "reading max brightness for '%s' failed: %s, using 1",
+ name, strerror(errno));
+ }
+ fclose(f);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "reading max_brightness for '%s' failed: %s, using 1",
+ name, strerror(errno));
+ }
+
+ snprintf(path, sizeof(path), "/sys/class/leds/%s/brightness", name);
+ f = fopen(path, "w");
+ if (!f)
+ {
+ DBG1(DBG_CFG, "opening LED file '%s' failed: %s", path, strerror(errno));
+ }
+ return f;
+}
+
+/**
+ * Set a LED to a given brightness
+ */
+static void set_led(FILE *led, int brightness)
+{
+ if (led)
+ {
+ if (fprintf(led, "%d\n", brightness) <= 0 ||
+ fflush(led) != 0)
+ {
+ DBG1(DBG_CFG, "setting LED brightness failed: %s", strerror(errno));
+ }
+ }
+}
+
+/**
+ * Plugin unloaded?
+ */
+static bool plugin_gone = FALSE;
+
+/**
+ * Reset activity LED after timeout
+ */
+static job_requeue_t reset_activity_led(private_led_listener_t *this)
+{
+ if (!plugin_gone)
+ { /* TODO: fix race */
+ this->mutex->lock(this->mutex);
+ if (this->count)
+ {
+ set_led(this->activity, this->activity_max);
+ }
+ else
+ {
+ set_led(this->activity, 0);
+ }
+ this->mutex->unlock(this->mutex);
+ }
+ return JOB_REQUEUE_NONE;
+}
+
+/**
+ * Blink the activity LED
+ */
+static void blink_activity(private_led_listener_t *this)
+{
+ if (this->activity)
+ {
+ this->mutex->lock(this->mutex);
+ if (this->count)
+ {
+ set_led(this->activity, 0);
+ }
+ else
+ {
+ set_led(this->activity, this->activity_max);
+ }
+ lib->scheduler->schedule_job_ms(lib->scheduler,
+ (job_t*)callback_job_create((callback_job_cb_t)reset_activity_led,
+ this, NULL, NULL), this->blink_time);
+ this->mutex->unlock(this->mutex);
+ }
+}
+
+METHOD(listener_t, ike_state_change, bool,
+ private_led_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state)
+{
+ this->mutex->lock(this->mutex);
+ if (state == IKE_ESTABLISHED && ike_sa->get_state(ike_sa) != IKE_ESTABLISHED)
+ {
+ this->count++;
+ if (this->count == 1)
+ {
+ set_led(this->activity, this->activity_max);
+ }
+ }
+ if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED && state != IKE_ESTABLISHED)
+ {
+ this->count--;
+ if (this->count == 0)
+ {
+ set_led(this->activity, 0);
+ }
+ }
+ this->mutex->unlock(this->mutex);
+ return TRUE;
+}
+
+METHOD(listener_t, message_hook, bool,
+ private_led_listener_t *this, ike_sa_t *ike_sa,
+ message_t *message, bool incoming)
+{
+ if (incoming || message->get_request(message))
+ {
+ blink_activity(this);
+ }
+ return TRUE;
+}
+
+METHOD(led_listener_t, destroy, void,
+ private_led_listener_t *this)
+{
+ this->mutex->lock(this->mutex);
+ set_led(this->activity, 0);
+ plugin_gone = TRUE;
+ this->mutex->unlock(this->mutex);
+ if (this->activity)
+ {
+ fclose(this->activity);
+ }
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/**
+ * See header
+ */
+led_listener_t *led_listener_create()
+{
+ private_led_listener_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .ike_state_change = _ike_state_change,
+ .message = _message_hook,
+ },
+ .destroy = _destroy,
+ },
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .blink_time = lib->settings->get_int(lib->settings,
+ "charon.plugins.led.blink_time", 50),
+ );
+
+ this->activity = open_led(lib->settings->get_str(lib->settings,
+ "charon.plugins.led.activity_led", NULL), &this->activity_max);
+ set_led(this->activity, 0);
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/led/led_listener.h b/src/libcharon/plugins/led/led_listener.h
new file mode 100644
index 000000000..74af5bf05
--- /dev/null
+++ b/src/libcharon/plugins/led/led_listener.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup led_listener led_listener
+ * @{ @ingroup led
+ */
+
+#ifndef LED_LISTENER_H_
+#define LED_LISTENER_H_
+
+#include <bus/listeners/listener.h>
+
+typedef struct led_listener_t led_listener_t;
+
+/**
+ * Listener to register the set of IPs we spoof ARP responses for.
+ */
+struct led_listener_t {
+
+ /**
+ * Implements listener_t interface.
+ */
+ listener_t listener;
+
+ /**
+ * Destroy a led_listener_t.
+ */
+ void (*destroy)(led_listener_t *this);
+};
+
+/**
+ * Create a led_listener instance.
+ */
+led_listener_t *led_listener_create();
+
+#endif /** LED_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/led/led_plugin.c b/src/libcharon/plugins/led/led_plugin.c
new file mode 100644
index 000000000..322d198ff
--- /dev/null
+++ b/src/libcharon/plugins/led/led_plugin.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "led_plugin.h"
+
+#include "led_listener.h"
+
+#include <daemon.h>
+
+typedef struct private_led_plugin_t private_led_plugin_t;
+
+/**
+ * private data of led plugin
+ */
+struct private_led_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ led_plugin_t public;
+
+ /**
+ * Listener controlling LEDs
+ */
+ led_listener_t *listener;
+};
+
+METHOD(plugin_t, destroy, void,
+ private_led_plugin_t *this)
+{
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ this->listener->destroy(this->listener);
+ free(this);
+}
+
+/**
+ * Plugin constructor
+ */
+plugin_t *led_plugin_create()
+{
+ private_led_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
+ .listener = led_listener_create(),
+ );
+
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/led/led_plugin.h b/src/libcharon/plugins/led/led_plugin.h
new file mode 100644
index 000000000..a7449addd
--- /dev/null
+++ b/src/libcharon/plugins/led/led_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup led led
+ * @ingroup cplugins
+ *
+ * @defgroup led_plugin led_plugin
+ * @{ @ingroup led
+ */
+
+#ifndef LED_PLUGIN_H_
+#define LED_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct led_plugin_t led_plugin_t;
+
+/**
+ * Linux LED control based on IKE activity/state.
+ */
+struct led_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** LED_PLUGIN_H_ @}*/