summaryrefslogtreecommitdiff
path: root/cleopatre/application/libspid/src/maclimit_eoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'cleopatre/application/libspid/src/maclimit_eoc.c')
-rw-r--r--cleopatre/application/libspid/src/maclimit_eoc.c500
1 files changed, 500 insertions, 0 deletions
diff --git a/cleopatre/application/libspid/src/maclimit_eoc.c b/cleopatre/application/libspid/src/maclimit_eoc.c
new file mode 100644
index 0000000000..b67995de09
--- /dev/null
+++ b/cleopatre/application/libspid/src/maclimit_eoc.c
@@ -0,0 +1,500 @@
+
+/* SPC300 bundle {{{
+ *
+ * Copyright (C) 2012 MStar
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file application/libspid/src/maclimit_eoc.c
+ * \brief Functions specific to mac limitation
+ * \ingroup libspid
+ *
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <syslog.h>
+#include <assert.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/netlink.h>
+#include <ctype.h>
+
+#include "libspid.h"
+#include "libmme.h"
+
+
+/**
+ * Returns get the maclimit default number
+ * \param num default maclimitation
+ * \return error type (LIBSPID_SUCCESS if success)
+ * \return LIBSPID_ERROR_PARAM: bad input parameters
+ */
+extern libspid_error_t
+libspid_eoc_maclimit_get_defaultnum (int *num)
+{
+ int ret;
+ char buffer[LIBSPID_LINE_MAX_LEN];
+
+ if (num == NULL)
+ return LIBSPID_ERROR_PARAM;
+
+ ret = libspid_config_read_item (LIBSPID_SLAVE_CONF_PATH,
+ LIBSPID_SLAVE_CONF_LABEL_MAC_LIMITATION,
+ buffer, LIBSPID_LINE_MAX_LEN);
+
+ if (LIBSPID_SUCCESS != ret)
+ {
+ LIBSPID_EOC_LOG_2 ("%s: get MAC limitation fail "
+ "buffers (errno=%d)", __FUNCTION__, errno);
+ *num = LIBSPID_MAC_LIMIT_DEFAULT_NUM;
+ }
+ else
+ {
+ if (1 != sscanf (buffer, "%d", num))
+ {
+ *num = LIBSPID_MAC_LIMIT_DEFAULT_NUM;
+ }
+ }
+
+ return LIBSPID_SUCCESS;
+}
+
+/**
+ * Returns the mac entry for the given slave MAC address
+ * \param mac_address slave MAC address
+ * \param entry maclimit entry
+ * \return error type (LIBSPID_SUCCESS if success)
+ * \return LIBSPID_ERROR_PARAM: bad input parameters
+ * \return LIBSPID_ERROR_SYSTEM: system error, see errno for details
+ * \return LIBSPID_ERROR_NOT_FOUND: can not find the entry by this Mac
+ */
+extern libspid_error_t
+libspid_eoc_maclimit_get (char *mac_address,
+ libspid_eoc_maclimit_entry_t * entry)
+{
+ const char delimiters[2] = LIBSPID_PORT_CONF_DELIMITER "\0";
+ char key[LIBSPID_CONFIG_KEY_MAX_LEN] = { 0 };
+ unsigned int elt_number = LIBSPID_CONFIG_ELT_MAX_NB;
+ char *elt[LIBSPID_CONFIG_ELT_MAX_NB] = { 0 };
+ char buffer[LIBSPID_CONFIG_LINE_MAX_LEN] = { 0 };
+ libspid_error_t error;
+ int i;
+
+ /* check input parameters */
+ if ((mac_address == NULL) || (entry == NULL))
+ return LIBSPID_ERROR_PARAM;
+
+ memset (entry, 0x0, sizeof (entry));
+
+ for (i = 0; i < LIBSPID_MAC_STR_LEN; i++)
+ {
+ mac_address[i] = tolower (mac_address[i]);
+ }
+
+ /* use slave MAC to compose key */
+ /* for line in configuration file */
+ strcpy (key, mac_address);
+ strcpy (entry->mac_addr, mac_address);
+
+ error = libspid_config_read_line (LIBSPID_MAC_LIMITATION_CONF_PATH,
+ delimiters, key,
+ &elt_number, elt, buffer,
+ LIBSPID_CONFIG_LINE_MAX_LEN);
+
+ if (LIBSPID_SUCCESS != error)
+ return error;
+
+
+ if (elt_number < LIBSPID_EOC_MACLIMIT_PARAM_NUM)
+ {
+ strcpy (entry->mac_limitation_num, "");
+ }
+ else
+ {
+ strcpy (entry->mac_limitation_num, elt[0]);
+ }
+
+ return LIBSPID_SUCCESS;
+}
+
+/**
+ * Returns the whole maclimit list from configuration file in a
+ * pointer to an array of maclimit entries.<BR>
+ * \param entry pointer to an array of maclimit entries
+ * \param count pointer to an integer for number of maclimit entries
+ * \return error type (LIBSPID_SUCCESS if success)
+ * \return LIBSPID_ERROR_NOT_FOUND: entry not found
+ * \return LIBSPID_ERROR_PARAM: bad input parameters
+ * \return LIBSPID_ERROR_SYSTEM: system error, see errno for details
+ */
+extern libspid_error_t
+libspid_eoc_maclimit_get_list (libspid_eoc_maclimit_entry_t * entry,
+ int *count)
+{
+ const char delimiters[2] = LIBSPID_PORT_CONF_DELIMITER "\0";
+ char key[LIBSPID_CONFIG_KEY_MAX_LEN] = { 0 };
+ unsigned int elt_number = LIBSPID_CONFIG_ELT_MAX_NB;
+ char *elt[LIBSPID_CONFIG_ELT_MAX_NB] = { 0 };
+ char buffer[LIBSPID_CONFIG_LINE_MAX_LEN] = { 0 };
+ libspid_error_t error;
+ libspid_eoc_maclimit_entry_t *entry_ptr;
+
+
+ void *user_data = NULL;
+
+ /* check input parameters */
+ if ((entry == NULL) || (count == NULL))
+ return LIBSPID_ERROR_PARAM;
+
+ *count = 0;
+ memset (key, 0x0, sizeof (key));
+ memset (entry, 0x0, sizeof (entry));
+ entry_ptr = entry;
+ /* get the first key */
+ error =
+ libspid_config_read_line_repetitive (LIBSPID_MAC_LIMITATION_CONF_PATH,
+ delimiters, key, &elt_number,
+ elt, buffer,
+ LIBSPID_CONFIG_LINE_MAX_LEN,
+ &user_data);
+
+ if (LIBSPID_SUCCESS != error)
+ return error;
+
+ for (; *count < LIBSPID_PORT_TOTAL_MAX && strcmp (key, ""); (*count)++)
+ {
+ /* Get a line from the conf file */
+ elt_number = LIBSPID_CONFIG_ELT_MAX_NB;
+ error =
+ libspid_config_read_line_repetitive
+ (LIBSPID_MAC_LIMITATION_CONF_PATH, delimiters, key, &elt_number,
+ elt, buffer, LIBSPID_CONFIG_LINE_MAX_LEN, &user_data);
+
+ if (LIBSPID_SUCCESS != error)
+ return error;;
+
+ strcpy (entry_ptr->mac_addr, buffer);
+
+ if (elt_number < LIBSPID_EOC_MACLIMIT_PARAM_NUM)
+ {
+ strcpy (entry_ptr->mac_limitation_num, "");
+ }
+ else
+ {
+ strcpy (entry_ptr->mac_limitation_num, elt[0]);
+ }
+
+ entry_ptr++;
+ }
+
+ libspid_config_read_line_repetitive (0, 0, 0, 0, 0, 0, 0, &user_data);
+ return LIBSPID_SUCCESS;
+}
+
+/**
+ * Set maclimit entry with the given slave MAC address<BR>
+ * \param mac_address slave MAC address
+ * \param entry maclimit entry
+ * \return error type (LIBSPID_SUCCESS if success)
+ * \return LIBSPID_ERROR_PARAM: bad input parameters
+ * \return LIBSPID_ERROR_SYSTEM: system error, see errno for details
+ * \return LIBSPID_ERROR_NO_SPACE: there no space for new entry
+ */
+extern libspid_error_t
+libspid_eoc_maclimit_set (char *mac_address,
+ libspid_eoc_maclimit_entry_t * entry)
+{
+ const char delimiter = LIBSPID_PORT_CONF_DELIMITER[0];
+ char key[LIBSPID_CONFIG_KEY_MAX_LEN] = { 0 };
+ char *elt[LIBSPID_EOC_MACLIMIT_PARAM_NUM];
+ libspid_error_t ret;
+ libspid_eoc_maclimit_entry_t maclimit_get_entry;
+ int i;
+
+ /* check input parameters */
+ if ((mac_address == NULL) || (entry == NULL))
+ return LIBSPID_ERROR_PARAM;
+
+ /* check that MAC address and port index already exist */
+ ret = libspid_eoc_maclimit_get (mac_address, &maclimit_get_entry);
+
+ if (LIBSPID_SUCCESS != ret)
+ {
+ return ret;
+ }
+
+ /* use slave MAC and port index to compose */
+ /* key for line in configuration file */
+ strcpy (key, mac_address);
+
+ /* allocate buffers */
+ for (i = 0; i < LIBSPID_EOC_MACLIMIT_PARAM_NUM; i++)
+ {
+ elt[i] = (char *) malloc (5 * sizeof (char));
+
+ if (NULL != elt[i])
+ memset (elt[i], 0, 5);
+ else
+ {
+ LIBSPID_EOC_LOG_2 ("%s: error allocating element "
+ "buffers (errno=%d)", __FUNCTION__, errno);
+ return LIBSPID_ERROR_SYSTEM;
+ }
+ }
+
+ strcpy (elt[0], entry->mac_limitation_num);
+ ret = libspid_config_write_line (LIBSPID_MAC_LIMITATION_CONF_PATH,
+ delimiter, key,
+ LIBSPID_EOC_MACLIMIT_PARAM_NUM, elt);
+
+ /* free element buffers */
+ for (i = 0; i < LIBSPID_EOC_MACLIMIT_PARAM_NUM; i++)
+ {
+ if (elt[i])
+ {
+ free (elt[i]);
+ elt[i] = NULL;
+ }
+ }
+
+ if (ret != LIBSPID_SUCCESS)
+ {
+ LIBSPID_EOC_LOG_2 ("%s: cannot write port entry (errno=%d)",
+ __FUNCTION__, errno);
+ return ret;
+ }
+
+ return LIBSPID_SUCCESS;
+}
+
+
+/** internal helper function for checking parameters of maclimitation.conf */
+int
+maclimit_check_input_parameters (libspid_eoc_maclimit_entry_t *
+ maclimit_entry,
+ libspid_eoc_maclimit_entry_t *
+ maclimit_entries_cnf, int maclimit_count_cnf,
+ libspid_maclimit_check_error_t * error_types)
+{
+ int error_number = 0;
+ int i = 0, value = 0;
+ int ret = 0;
+ char *pnumber;
+
+ if (maclimit_entry == NULL || maclimit_entries_cnf == NULL ||
+ error_types == NULL)
+ {
+ return -1;
+ }
+
+ /** check MAC address*/
+ if (strlen (maclimit_entry->mac_addr) != LIBSPID_MAC_STR_LEN - 1)
+ ret = -1;
+
+ for (i = 0; i < LIBSPID_MAC_STR_LEN - 1; i++)
+ {
+ maclimit_entry->mac_addr[i] = tolower (maclimit_entry->mac_addr[i]);
+
+ if (!((maclimit_entry->mac_addr[i] >= '0'
+ && maclimit_entry->mac_addr[i] <= '9')
+ || (maclimit_entry->mac_addr[i] >= 'a'
+ && maclimit_entry->mac_addr[i] <= 'f')
+ || maclimit_entry->mac_addr[i] == ':'))
+ ret = -1;
+
+ if ((i % 3) == 2 && maclimit_entry->mac_addr[i] != ':')
+ ret = -1;
+ }
+
+ if (ret != 0)
+ {
+ error_types[error_number] = LIBSPID_ERROR_MACLIMIT_MAC_FORMAT;
+ error_number++;
+ ret = 0;
+ }
+
+ /** check mac limitation value */
+ value = strtol (maclimit_entry->mac_limitation_num, &pnumber, 10);
+
+ if (*pnumber != '\0'
+ || strcmp (maclimit_entry->mac_limitation_num, "") == 0)
+ ret = -1;
+ else
+ ret = (value < 0 || value < LIBSPID_EOC_WL_EXT_MAC_LIMIT_MIN
+ || value > LIBSPID_EOC_WL_EXT_MAC_LIMIT_MAX) ? -1 : 0;
+
+ if (ret != 0)
+ {
+ error_types[error_number] = LIBSPID_ERROR_MACLIMIT_NUM;
+ error_number++;
+ ret = 0;
+ }
+
+ return error_number;
+}
+
+/** internal function for compare the mac*/
+static int
+cmp_string_mac (const void *p1, const void *p2)
+{
+ return strcmp (((libspid_eoc_maclimit_entry_t *) p1)->mac_addr,
+ ((libspid_eoc_maclimit_entry_t *) p2)->mac_addr);
+}
+
+
+/**
+ * Check maclimitation.conf file
+ * \return error type (LIBSPID_SUCCESS if success)
+ * \return LIBSPID_ERROR_PARAM: bad input parameters
+ * \return LIBSPID_ERROR_CHECK: check utility failed
+ */
+extern libspid_error_t
+libspid_eoc_maclimit_check (void)
+{
+ int maclimit_count_cnf = 0, wl_count_cnf = 0;;
+ int ret = -1;
+ int i = 0;
+ libspid_eoc_maclimit_entry_t maclimit_entries_cnf[LIBSPID_PORT_TOTAL_MAX];
+ libspid_eoc_maclimit_entry_t
+ maclimit_entries_cnf_sort[LIBSPID_PORT_TOTAL_MAX];
+ libspid_eoc_wl_entry_t
+ wl_entries_cnf_sort[LIBSPID_WHITE_LIST_MAX_STA_NUM];
+ libspid_eoc_maclimit_entry_t maclimit_entry;
+ char key_not_unique[LIBSPID_MAC_STR_LEN];
+ LIBSPID_EOC_LOG_1 ("%s: Check maclimitation.conf...", __FUNCTION__);
+ /** obtain the maclimitation list from configuration file */
+ ret = libspid_eoc_maclimit_get_list (maclimit_entries_cnf,
+ &maclimit_count_cnf);
+
+ if (ret != LIBSPID_SUCCESS)
+ {
+ return ret;
+ }
+
+ ret = libspid_eoc_wl_get_list (wl_entries_cnf_sort, &wl_count_cnf);
+
+ if (ret != LIBSPID_SUCCESS)
+ {
+ return ret;
+ }
+
+ memcpy (maclimit_entries_cnf_sort, maclimit_entries_cnf,
+ maclimit_count_cnf * sizeof (libspid_eoc_maclimit_entry_t));
+ /* sort maclimitation.conf */
+ qsort (maclimit_entries_cnf_sort, maclimit_count_cnf,
+ sizeof (libspid_eoc_maclimit_entry_t), cmp_string_mac);
+
+ /* check if MAC is unique key */
+ for (i = 0; i < maclimit_count_cnf - 1; i++)
+ {
+ if (strcmp (maclimit_entries_cnf_sort[i].mac_addr,
+ maclimit_entries_cnf_sort[i + 1].mac_addr) == 0)
+ {
+ strcpy (key_not_unique, maclimit_entries_cnf_sort[i].mac_addr);
+ break;
+ }
+ }
+
+ /* sort white_list.conf */
+ qsort (wl_entries_cnf_sort, wl_count_cnf,
+ sizeof (libspid_eoc_wl_entry_t), cmp_string_mac);
+
+ for (i = 0; i < maclimit_count_cnf; i++)
+ {
+ int number_of_error = 0;
+ libspid_maclimit_check_error_t
+ error_types[LIBSPID_MAC_LIMIT_ERROR_TYPES_NUM];
+ libspid_eoc_maclimit_entry_t *res;
+ maclimit_entry = maclimit_entries_cnf_sort[i];
+ /* Check dependency between maclimitation.conf
+ * and white_list.conf file */
+ /* check if MAC defined in maclimitation.conf
+ * but not in white_list.conf */
+ res = bsearch (&maclimit_entry, wl_entries_cnf_sort, wl_count_cnf,
+ sizeof (libspid_eoc_wl_entry_t), cmp_string_mac);
+
+ if (res == NULL)
+ {
+ LIBSPID_EOC_LOG_1
+ ("MAC (%s) defined in maclimitation.conf but not "
+ "in white_list.conf", maclimit_entry.mac_addr);
+ ret = LIBSPID_ERROR_CHECK;
+ }
+
+ /** check format of the input parameters */
+ number_of_error = maclimit_check_input_parameters (&maclimit_entry,
+ maclimit_entries_cnf,
+ maclimit_count_cnf,
+ error_types);
+ /* if MAC is not unique key */
+ /* find error line */
+ if (strcmp (key_not_unique, maclimit_entry.mac_addr) == 0)
+ {
+ number_of_error += 1;
+ error_types[number_of_error - 1] =
+ LIBSPID_ERROR_MACLIMIT_MAC_DUPLICATE;
+ }
+
+ if (number_of_error > 0)
+ {
+ int j = 0;
+ libspid_boolean_t unique_address = LIBSPID_TRUE;
+ ret = LIBSPID_ERROR_CHECK;
+ LIBSPID_EOC_LOG_1 ("Error in line:%d\n", i + 2);
+
+ for (j = 0; j < number_of_error; j++)
+ {
+ switch (error_types[j])
+ {
+ case LIBSPID_ERROR_MACLIMIT_MAC_FORMAT:
+ LIBSPID_EOC_LOG_0 ("Malformed MAC address.");
+ break;
+ case LIBSPID_ERROR_MACLIMIT_NUM:
+ LIBSPID_EOC_LOG_0 ("Wrong maclimit num.");
+ break;
+ case LIBSPID_ERROR_MACLIMIT_MAC_DUPLICATE:
+ LIBSPID_EOC_LOG_1 ("MAC address %s is not "
+ "unique key.",key_not_unique );
+ unique_address = LIBSPID_FALSE;
+ break;
+ default:
+ break;
+ }
+ }
+ if (unique_address == LIBSPID_FALSE)
+ return ret;
+ }
+ else if (number_of_error == -1)
+ return LIBSPID_ERROR_PARAM;
+ }
+
+ /* Check dependency between maclimitation.conf and white_list.conf file */
+ /* check if MAC defined in white_list.conf but not in port.conf */
+ for (i = 0; i < wl_count_cnf; i++)
+ {
+ libspid_eoc_wl_entry_t *res;
+ libspid_eoc_wl_entry_t wl_entry;
+ wl_entry = wl_entries_cnf_sort[i];
+ res = bsearch (&wl_entry, maclimit_entries_cnf_sort,
+ maclimit_count_cnf,
+ sizeof (libspid_eoc_maclimit_entry_t), cmp_string_mac);
+
+ if (res == NULL)
+ {
+ LIBSPID_EOC_LOG_1 ("MAC (%s) defined in white_list.conf "
+ "but not in maclimitation.conf",
+ wl_entry.mac_addr);
+ ret = LIBSPID_ERROR_CHECK;
+ }
+ }
+
+ return ret;
+}