-static GHashTable *g_firewalls = NULL;
-static int g_lock_state = FIREWALL_UNKONWN;
-static uint g_chain_priority = 0;
-
-static void __fw_rule_copy(firewall_rule_s *rule,
- const firewall_rule_s *info)
-{
- if (info->chain) {
- FREE(rule->chain);
- rule->chain = g_strdup(info->chain);
- }
-
- rule->direction = info->direction;
- rule->s_ip_type = info->s_ip_type;
- rule->d_ip_type = info->d_ip_type;
- rule->s_port_type = info->s_port_type;
- rule->d_port_type = info->d_port_type;
- rule->protocol = info->protocol;
- rule->family = info->family;
-
- rule->s_ip1 = info->s_ip1;
- rule->s_ip2 = info->s_ip2;
- rule->d_ip1 = info->d_ip1;
- rule->d_ip2 = info->d_ip2;
-
- rule->s_port1 = info->s_port1;
- rule->s_port2 = info->s_port2;
- rule->d_port1 = info->d_port1;
- rule->d_port2 = info->d_port2;
-
- if (info->ifname) {
- FREE(rule->ifname);
- rule->ifname = g_strdup(info->ifname);
- }
-
- rule->target = info->target;
-
- if (info->target_str) {
- FREE(rule->target_str);
- rule->target_str = g_strdup(info->target_str);
- }
-
- rule->log_level = info->log_level;
-
- if (info->log_prefix) {
- FREE(rule->log_prefix);
- rule->log_prefix = g_strdup(info->log_prefix);
- }
-
- rule->nflog_group = info->nflog_group;
- rule->nflog_range = info->nflog_range;
- rule->nflog_threshold = info->nflog_threshold;
-
- if (info->nflog_prefix) {
- FREE(rule->nflog_prefix);
- rule->nflog_prefix = g_strdup(info->nflog_prefix);
- }
-
- if (info->identifier) {
- FREE(rule->identifier);
- rule->identifier = g_strdup(info->identifier);
- }
-
- rule->key = info->key;
-}
-
-static void __fw_rule_make_key(firewall_rule_s *rule,
- firewall_rule_s *info)
-{
- GString *str;
-
- if (!rule->chain)
- return;
-
- str = g_string_sized_new(IDENTIFIER_LEN);
- if (!str)
- return;
-
- g_string_append_printf(str, "%s", rule->chain);
-
- g_string_append_printf(str, "_%u%u%u%u%u%u%u", rule->direction,
- rule->s_ip_type, rule->d_ip_type, rule->s_port_type,
- rule->d_port_type, rule->protocol, rule->family);
-
- if (rule->family == STC_FW_FAMILY_V4) {
- g_string_append_printf(str, "_");
- g_string_append_printf(str, "%08x", rule->s_ip1.Ipv4.s_addr);
- g_string_append_printf(str, "%08x", rule->s_ip2.Ipv4.s_addr);
-
- g_string_append_printf(str, "_");
- g_string_append_printf(str, "%08x", rule->d_ip1.Ipv4.s_addr);
- g_string_append_printf(str, "%08x", rule->d_ip2.Ipv4.s_addr);
- } else if (rule->family == STC_FW_FAMILY_V6) {
- g_string_append_printf(str, "_");
- g_string_append_printf(str, "%08x", rule->s_ip1.Ipv6.s6_addr32[0]);
- g_string_append_printf(str, "%08x", rule->s_ip1.Ipv6.s6_addr32[1]);
- g_string_append_printf(str, "%08x", rule->s_ip1.Ipv6.s6_addr32[2]);
- g_string_append_printf(str, "%08x", rule->s_ip1.Ipv6.s6_addr32[3]);
- g_string_append_printf(str, "%08x", rule->s_ip2.Ipv6.s6_addr32[0]);
- g_string_append_printf(str, "%08x", rule->s_ip2.Ipv6.s6_addr32[1]);
- g_string_append_printf(str, "%08x", rule->s_ip2.Ipv6.s6_addr32[2]);
- g_string_append_printf(str, "%08x", rule->s_ip2.Ipv6.s6_addr32[3]);
-
- g_string_append_printf(str, "_");
- g_string_append_printf(str, "%08x", rule->d_ip1.Ipv6.s6_addr32[0]);
- g_string_append_printf(str, "%08x", rule->d_ip1.Ipv6.s6_addr32[1]);
- g_string_append_printf(str, "%08x", rule->d_ip1.Ipv6.s6_addr32[2]);
- g_string_append_printf(str, "%08x", rule->d_ip1.Ipv6.s6_addr32[3]);
- g_string_append_printf(str, "%08x", rule->d_ip2.Ipv6.s6_addr32[0]);
- g_string_append_printf(str, "%08x", rule->d_ip2.Ipv6.s6_addr32[1]);
- g_string_append_printf(str, "%08x", rule->d_ip2.Ipv6.s6_addr32[2]);
- g_string_append_printf(str, "%08x", rule->d_ip2.Ipv6.s6_addr32[3]);
- }
-
- g_string_append_printf(str, "_%04x", rule->s_port1);
- g_string_append_printf(str, "%04x", rule->s_port2);
-
- g_string_append_printf(str, "_%04x", rule->d_port1);
- g_string_append_printf(str, "%04x", rule->d_port2);
-
- g_string_append_printf(str, "_%s", (rule->ifname) ? rule->ifname : "");
- g_string_append_printf(str, "_%u", rule->target);
-
- switch (rule->target) {
- case STC_FW_RULE_TARGET_LOG:
- g_string_append_printf(str, "_%u", rule->log_level);
- g_string_append_printf(str, "_%s", rule->log_prefix);
- break;
- case STC_FW_RULE_TARGET_NFLOG:
- g_string_append_printf(str, "_%u", rule->nflog_group);
- g_string_append_printf(str, "_%s", rule->nflog_prefix);
- g_string_append_printf(str, "_%u", rule->nflog_range);
- g_string_append_printf(str, "_%u", rule->nflog_threshold);
- break;
- default:
- break;
- }
-
- FREE(rule->identifier);
- rule->identifier = g_string_free(str, FALSE);
- rule->key = g_str_hash(rule->identifier);
-
- FREE(info->identifier);
- info->identifier = g_strdup(rule->identifier);
- info->key = rule->key;
-
- if (STC_DEBUG_LOG && STC_FW_LOG) {
- STC_LOGD("Identifier [%s]", rule->identifier);
- STC_LOGD("Key [%u]", rule->key);
- }
-}
-
-static void __fw_rule_free(void *data)
-{
- firewall_rule_s *rule = (firewall_rule_s *)data;
-
- FREE(rule->chain);
- FREE(rule->ifname);
- FREE(rule->target_str);
- FREE(rule->log_prefix);
- FREE(rule->nflog_prefix);
- FREE(rule->identifier);
- FREE(rule);
-}
-
-static void __fw_data_free(gpointer value)
-{
- stc_fw_data_s *data = (stc_fw_data_s *)value;
-
- g_slist_free_full(data->rules, __fw_rule_free);
- data->rules = NULL;
-
- FREE(data);
-}
-
-static gint __fw_rule_comp(gconstpointer a, gconstpointer b)
-{
- firewall_rule_s *data = (firewall_rule_s *)a;
- firewall_rule_s *rule = (firewall_rule_s *)b;
-
- if ((data->key == rule->key) &&
- (g_strcmp0(data->identifier, rule->identifier) == 0))
- return 0;
-
- return -1;
-}
-
-static stc_error_e __fw_chain_add(const char *chain)
-{
- stc_fw_data_s *data;
- stc_fw_data_s *lookup;
-
- ret_value_msg_if(g_firewalls == NULL,
- STC_ERROR_FAIL,
- "firewall is not initialized!");
-
- lookup = g_hash_table_lookup(g_firewalls, chain);
- if (lookup) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGD("chain already present");
- return STC_ERROR_ALREADY_DATA;
- }
-
- data = MALLOC0(stc_fw_data_s, 1);
- if (!data) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("data allocation failed");
- return STC_ERROR_OUT_OF_MEMORY;
- }
-
- data->target = STC_FW_CHAIN_TARGET_NONE;
- data->priority = 0;
- data->rules = NULL;
-
- g_hash_table_insert(g_firewalls, g_strdup(chain), data);
-
- return STC_ERROR_NONE;
-}
-
-static stc_error_e __fw_chain_remove(const char *chain)
-{
- stc_fw_data_s *lookup;
-
- ret_value_msg_if(g_firewalls == NULL,
- STC_ERROR_FAIL,
- "firewall is not initialized!");
-
- lookup = g_hash_table_lookup(g_firewalls, chain);
- if (!lookup) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("chain not found");
- return STC_ERROR_NO_DATA;
- }
-
- if (lookup->target != STC_FW_CHAIN_TARGET_NONE) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("can't be applied bcz chain is set");
- return STC_ERROR_INVALID_PARAMETER;
- }
-
- g_slist_free_full(lookup->rules, __fw_rule_free);
- lookup->rules = NULL;
-
- g_hash_table_remove(g_firewalls, chain);
-
- return STC_ERROR_NONE;
-}
-
-static stc_error_e __fw_chain_flush(const char *chain)
-{
- stc_fw_data_s *lookup;
-
- ret_value_msg_if(g_firewalls == NULL,
- STC_ERROR_FAIL,
- "firewall is not initialized!");
-
- lookup = g_hash_table_lookup(g_firewalls, chain);
- if (!lookup) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("chain not found");
- return STC_ERROR_NO_DATA;
- }
-
- if (lookup->target != STC_FW_CHAIN_TARGET_NONE) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("can't be applied bcz chain is set");
- return STC_ERROR_INVALID_PARAMETER;
- }
-
- g_slist_free_full(lookup->rules, __fw_rule_free);
- lookup->rules = NULL;
-
- return STC_ERROR_NONE;
-}
-
-static stc_error_e __fw_chain_set(const char *chain, stc_fw_data_s value)
-{
- stc_fw_data_s *lookup;
-
- ret_value_msg_if(g_firewalls == NULL,
- STC_ERROR_FAIL,
- "firewall is not initialized!");
-
- lookup = g_hash_table_lookup(g_firewalls, chain);
- if (!lookup) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("chain not found");
- return STC_ERROR_NO_DATA;
- }
-
- lookup->target = value.target;
- lookup->priority = value.priority;
-
- return STC_ERROR_NONE;
-}
-
-static stc_fw_data_s *__fw_chain_get(const char *chain)
-{
- stc_fw_data_s *lookup;
-
- ret_value_msg_if(g_firewalls == NULL, NULL,
- "firewall is not initialized!");
-
- lookup = g_hash_table_lookup(g_firewalls, chain);
- if (!lookup) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("chain not found");
- return NULL;
- }
-
- return lookup;
-}
-
-static stc_error_e __fw_chain_unset(const char *chain)
-{
- stc_error_e ret = STC_ERROR_NONE;
- stc_fw_data_s *lookup;
-
- ret_value_msg_if(g_firewalls == NULL,
- STC_ERROR_FAIL,
- "firewall is not initialized!");
-
- lookup = g_hash_table_lookup(g_firewalls, chain);
- if (!lookup) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("chain not found");
- return STC_ERROR_NO_DATA;
- }
-
- lookup->target = STC_FW_CHAIN_TARGET_NONE;
- lookup->priority = 0;
-
- return ret;
-}
-
-static void __fw_chain_make_params(gpointer key, gpointer value,
- gpointer user_data)
-{
- char *chain = (char *)key;
- stc_fw_data_s *data = (stc_fw_data_s *)value;
- GVariantBuilder *builder = (GVariantBuilder *)user_data;
- GVariantBuilder sub_builder;
-
- g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
-
- g_variant_builder_add(&sub_builder, "{sv}", CHAIN_NAME,
- g_variant_new_string(chain));
-
- g_variant_builder_add(&sub_builder, "{sv}", CHAIN_PRIORITY,
- g_variant_new_uint32(data->priority));
-
- g_variant_builder_add(&sub_builder, "{sv}", CHAIN_TARGET,
- g_variant_new_uint16(data->target));
-
- g_variant_builder_add_value(builder, g_variant_builder_end(&sub_builder));
-}
-
-static void __fw_rule_make_params(gpointer data, gpointer user_data)
-{
- firewall_rule_s *rule = (firewall_rule_s *)data;
- GVariantBuilder *builder = (GVariantBuilder *)user_data;
- GVariantBuilder sub_builder;
-
- g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
-
- g_variant_builder_add(&sub_builder, "{sv}", RULE_CHAIN,
- g_variant_new_string(rule->chain));
-
- if (rule->direction != STC_FW_DIRECTION_NONE)
- g_variant_builder_add(&sub_builder, "{sv}", RULE_DIRECTION,
- g_variant_new_uint16(rule->direction));
-
- if (rule->s_ip_type != STC_FW_IP_NONE)
- g_variant_builder_add(&sub_builder, "{sv}", RULE_SIPTYPE,
- g_variant_new_uint16(rule->s_ip_type));
-
- if (rule->d_ip_type != STC_FW_IP_NONE)
- g_variant_builder_add(&sub_builder, "{sv}", RULE_DIPTYPE,
- g_variant_new_uint16(rule->d_ip_type));
-
- if (rule->s_port_type != STC_FW_PORT_NONE)
- g_variant_builder_add(&sub_builder, "{sv}", RULE_SPORTTYPE,
- g_variant_new_uint16(rule->s_port_type));
-
- if (rule->d_port_type != STC_FW_PORT_NONE)
- g_variant_builder_add(&sub_builder, "{sv}", RULE_DPORTTYPE,
- g_variant_new_uint16(rule->d_port_type));
-
- if (rule->protocol != STC_FW_PROTOCOL_NONE)
- g_variant_builder_add(&sub_builder, "{sv}", RULE_PROTOCOL,
- g_variant_new_uint16(rule->protocol));
-
- if (rule->family != STC_FW_FAMILY_NONE)
- g_variant_builder_add(&sub_builder, "{sv}", RULE_FAMILY,
- g_variant_new_uint16(rule->family));
-
- if (rule->family == STC_FW_FAMILY_V4) {
- char *addr = NULL;
-
- switch (rule->s_ip_type) {
- case STC_FW_IP_RANGE:
- /* fall through */
- case STC_FW_IP_MASK:
- addr = g_try_malloc0(INET_ADDRSTRLEN);
- if (addr) {
- inet_ntop(AF_INET, &(rule->s_ip2.Ipv4), addr, INET_ADDRSTRLEN);
- g_variant_builder_add(&sub_builder, "{sv}", RULE_SIP2,
- g_variant_new_string(addr));
- FREE(addr);
- }
- /* fall through */
- case STC_FW_IP_SINGLE:
- addr = g_try_malloc0(INET_ADDRSTRLEN);
- if (addr) {
- inet_ntop(AF_INET, &(rule->s_ip1.Ipv4), addr, INET_ADDRSTRLEN);
- g_variant_builder_add(&sub_builder, "{sv}", RULE_SIP1,
- g_variant_new_string(addr));
- FREE(addr);
- }
- break;
- default:
- break;
- }
-
- switch (rule->d_ip_type) {
- case STC_FW_IP_RANGE:
- /* fall through */
- case STC_FW_IP_MASK:
- addr = g_try_malloc0(INET_ADDRSTRLEN);
- if (addr) {
- inet_ntop(AF_INET, &(rule->d_ip2.Ipv4), addr, INET_ADDRSTRLEN);
- g_variant_builder_add(&sub_builder, "{sv}", RULE_DIP2,
- g_variant_new_string(addr));
- FREE(addr);
- }
- /* fall through */
- case STC_FW_IP_SINGLE:
- addr = g_try_malloc0(INET_ADDRSTRLEN);
- if (addr) {
- inet_ntop(AF_INET, &(rule->d_ip1.Ipv4), addr, INET_ADDRSTRLEN);
- g_variant_builder_add(&sub_builder, "{sv}", RULE_DIP1,
- g_variant_new_string(addr));
- FREE(addr);
- }
- break;
- default:
- break;
- }
- } else if (rule->family == STC_FW_FAMILY_V6) {
- char *addr = NULL;
-
- switch (rule->s_ip_type) {
- case STC_FW_IP_RANGE:
- /* fall through */
- case STC_FW_IP_MASK:
- addr = g_try_malloc0(INET6_ADDRSTRLEN);
- if (addr) {
- inet_ntop(AF_INET6, &(rule->s_ip2.Ipv6), addr, INET6_ADDRSTRLEN);
- g_variant_builder_add(&sub_builder, "{sv}", RULE_SIP2,
- g_variant_new_string(addr));
- FREE(addr);
- }
- /* fall through */
- case STC_FW_IP_SINGLE:
- addr = g_try_malloc0(INET6_ADDRSTRLEN);
- if (addr) {
- inet_ntop(AF_INET6, &(rule->s_ip1.Ipv6), addr, INET6_ADDRSTRLEN);
- g_variant_builder_add(&sub_builder, "{sv}", RULE_SIP1,
- g_variant_new_string(addr));
- FREE(addr);
- }
- break;
- default:
- break;
- }
-
- switch (rule->d_ip_type) {
- case STC_FW_IP_RANGE:
- /* fall through */
- case STC_FW_IP_MASK:
- addr = g_try_malloc0(INET6_ADDRSTRLEN);
- if (addr) {
- inet_ntop(AF_INET6, &(rule->d_ip2.Ipv6), addr, INET6_ADDRSTRLEN);
- g_variant_builder_add(&sub_builder, "{sv}", RULE_DIP2,
- g_variant_new_string(addr));
- FREE(addr);
- }
- /* fall through */
- case STC_FW_IP_SINGLE:
- addr = g_try_malloc0(INET6_ADDRSTRLEN);
- if (addr) {
- inet_ntop(AF_INET6, &(rule->d_ip1.Ipv6), addr, INET6_ADDRSTRLEN);
- g_variant_builder_add(&sub_builder, "{sv}", RULE_DIP1,
- g_variant_new_string(addr));
- FREE(addr);
- }
- break;
- default:
- break;
- }
- }
-
- g_variant_builder_add(&sub_builder, "{sv}", RULE_SPORT1,
- g_variant_new_uint32(rule->s_port1));
-
- g_variant_builder_add(&sub_builder, "{sv}", RULE_SPORT2,
- g_variant_new_uint32(rule->s_port2));
-
- g_variant_builder_add(&sub_builder, "{sv}", RULE_DPORT1,
- g_variant_new_uint32(rule->d_port1));
-
- g_variant_builder_add(&sub_builder, "{sv}", RULE_DPORT2,
- g_variant_new_uint32(rule->d_port2));
-
- if (rule->ifname)
- g_variant_builder_add(&sub_builder, "{sv}", RULE_IFNAME,
- g_variant_new_string(rule->ifname));
-
- if (rule->target != STC_FW_RULE_TARGET_NONE)
- g_variant_builder_add(&sub_builder, "{sv}", RULE_TARGET,
- g_variant_new_uint16(rule->target));
-
- switch (rule->target) {
- case STC_FW_RULE_TARGET_LOG:
- g_variant_builder_add(&sub_builder, "{sv}", RULE_LOG_LEVEL,
- g_variant_new_uint16(rule->log_level));
-
- if (rule->log_prefix)
- g_variant_builder_add(&sub_builder, "{sv}", RULE_LOG_PREFIX,
- g_variant_new_string(rule->log_prefix));
- break;
- case STC_FW_RULE_TARGET_NFLOG:
- g_variant_builder_add(&sub_builder, "{sv}", RULE_NFLOG_GROUP,
- g_variant_new_uint16(rule->nflog_group));
-
- if (rule->nflog_prefix)
- g_variant_builder_add(&sub_builder, "{sv}", RULE_NFLOG_PREFIX,
- g_variant_new_string(rule->nflog_prefix));
-
- g_variant_builder_add(&sub_builder, "{sv}", RULE_NFLOG_RANGE,
- g_variant_new_uint16(rule->nflog_range));
-
- g_variant_builder_add(&sub_builder, "{sv}", RULE_NFLOG_THRESHOLD,
- g_variant_new_uint16(rule->nflog_threshold));
- break;
- default:
- break;
- }
-
- g_variant_builder_add(&sub_builder, "{sv}", RULE_IDENTIFIER,
- g_variant_new_string(rule->identifier));
-
- g_variant_builder_add(&sub_builder, "{sv}", RULE_KEY,
- g_variant_new_uint32(rule->key));
-
- g_variant_builder_add_value(builder, g_variant_builder_end(&sub_builder));
-}
-
-static void __fw_rule_set_to_chain(gpointer data, gpointer user_data)
-{
- firewall_rule_s *rule = (firewall_rule_s *)data;
- char *chain = (char *)user_data;
-
- if (chain && (g_strcmp0(rule->chain, chain) != 0))
- return;
-
- switch (rule->target) {
- case STC_FW_RULE_TARGET_ACCEPT:
- FREE(rule->target_str);
- rule->target_str = g_strdup(FIREWALL_RULE_TARGET_ACCEPT);
- break;
- case STC_FW_RULE_TARGET_DROP:
- FREE(rule->target_str);
- rule->target_str = g_strdup(FIREWALL_RULE_TARGET_DROP);
- break;
- case STC_FW_RULE_TARGET_LOG:
- FREE(rule->target_str);
- rule->target_str = g_strdup(FIREWALL_RULE_TARGET_LOG);
- break;
- case STC_FW_RULE_TARGET_NFLOG:
- FREE(rule->target_str);
- rule->target_str = g_strdup(FIREWALL_RULE_TARGET_NFLOG);
- break;
- default:
- break;
- }
-
- firewall_rule_append(rule);
-}
-
-static void __fw_rule_print_rules(gpointer data, gpointer user_data)
-{
- firewall_rule_s *rule = (firewall_rule_s *)data;
-
- STC_LOGD("[%s][%d][%s][%d][%d][%04x][%04x]"
- "[%d][%04x][%04x][%d][%s][%d][%s][%d][%d]",
- rule->chain, rule->direction, rule->ifname,
- rule->protocol,
- rule->s_port_type, rule->s_port1, rule->s_port2,
- rule->d_port_type, rule->d_port1, rule->d_port2,
- rule->target, rule->target_str,
- rule->nflog_group, rule->nflog_prefix,
- rule->nflog_range, rule->nflog_threshold);
-
- switch (rule->family) {
- case STC_FW_FAMILY_V4:
- STC_LOGD("[%d][%d][%08x][%08x][%d][%08x][%08x]",
- rule->family,
- rule->s_ip_type, rule->s_ip1.Ipv4.s_addr, rule->s_ip2.Ipv4.s_addr,
- rule->d_ip_type, rule->d_ip1.Ipv4.s_addr, rule->d_ip2.Ipv4.s_addr);
- break;
- case STC_FW_FAMILY_V6:
- STC_LOGD("[%d][%d][%08x:%08x:%08x:%08x]"
- "[%d][%08x:%08x:%08x:%08x]",
- rule->family,
- rule->s_ip_type,
- rule->s_ip1.Ipv6.s6_addr32[0], rule->s_ip1.Ipv6.s6_addr32[1],
- rule->s_ip1.Ipv6.s6_addr32[2], rule->s_ip1.Ipv6.s6_addr32[3],
- rule->d_ip_type,
- rule->d_ip1.Ipv6.s6_addr32[0], rule->d_ip1.Ipv6.s6_addr32[1],
- rule->d_ip1.Ipv6.s6_addr32[2], rule->d_ip1.Ipv6.s6_addr32[3]);
- break;
- default:
- break;
- }
-}
-
-static void __fw_foreach_to_print_rule(gpointer key, gpointer value,
- gpointer user_data)
-{
- stc_fw_data_s *data = (stc_fw_data_s *)value;
-
- g_slist_foreach(data->rules, __fw_rule_print_rules, user_data);
-}
-
-static void __fw_foreach_to_make_rule_param(gpointer key, gpointer value,
- gpointer user_data)
-{
- stc_fw_data_s *data = (stc_fw_data_s *)value;
-
- g_slist_foreach(data->rules, __fw_rule_make_params, user_data);
-}
-
-static void __fw_foreach_to_set_rule_to_chain(gpointer key, gpointer value,
- gpointer user_data)
-{
- stc_fw_data_s *data = (stc_fw_data_s *)value;
- char *chain = (char *)user_data;
-
- if (chain || (data->target != STC_FW_CHAIN_TARGET_NONE))
- g_slist_foreach(data->rules, __fw_rule_set_to_chain, user_data);
-}
-
-static void __fw_foreach_to_set_chain(gpointer key, gpointer value,
- gpointer user_data)
-{
- char *chain = (char *)key;
- stc_fw_data_s *data = (stc_fw_data_s *)value;
-
- if (data->target != STC_FW_CHAIN_TARGET_NONE) {
- firewall_chain_s info;
- memset(&info, 0, sizeof(firewall_chain_s));
- info.chain = chain;
- info.target = data->target;
- info.priority = data->priority;
- firewall_chain_set(&info);
- }
-}
-
-static void __fw_foreach_to_add_chain(gpointer key, gpointer value,
- gpointer user_data)
-{
- char *chain = (char *)key;
- stc_fw_data_s *data = (stc_fw_data_s *)value;
-
- if (data->target != STC_FW_CHAIN_TARGET_NONE) {
- firewall_chain_s info;
- memset(&info, 0, sizeof(firewall_chain_s));
- info.chain = chain;
- info.target = data->target;
- info.priority = data->priority;
- firewall_chain_add(&info);
- }
-}
-
-static void __fw_chain_foreach(GHFunc func, void *user_data)
-{
- g_hash_table_foreach(g_firewalls, func, user_data);
-}
-
-stc_cb_ret_e __fw_table_chain_info_cb(const firewall_chain_s *info,
- void *user_data)
-{
- stc_fw_data_s *data;
-
- data = MALLOC0(stc_fw_data_s, 1);
- if (!data) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("data allocation failed");
- return STC_CONTINUE;
- }
-
- data->target = info->target;
- data->priority = info->priority;
- data->rules = NULL;
-
- g_hash_table_insert(g_firewalls, g_strdup(info->chain), data);
-
- return STC_CONTINUE;
-}
-
-stc_cb_ret_e __fw_table_rule_info_cb(const firewall_rule_s *info,
- void *user_data)
-{
- stc_fw_data_s *lookup;
- firewall_rule_s *rule;
-
- lookup = g_hash_table_lookup(g_firewalls, info->chain);
- if (!lookup) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("chain not found");
- return STC_CONTINUE;
- }
-
- rule = MALLOC0(firewall_rule_s, 1);
- if (!rule) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("rule allocation failed");
- return STC_CONTINUE;
- }
-
- memset(rule, 0, sizeof(firewall_rule_s));
- __fw_rule_copy(rule, info);
-
- lookup->rules = g_slist_append(lookup->rules, rule);
-
- return STC_CONTINUE;
-}
-
-static stc_error_e __fw_rule_add(firewall_rule_s *info)
-{
- stc_fw_data_s *lookup;
- firewall_rule_s *rule;
- GSList *comp;
-
- ret_value_msg_if(g_firewalls == NULL,
- STC_ERROR_FAIL,
- "firewall is not initialized!");
-
- lookup = g_hash_table_lookup(g_firewalls, info->chain);
- if (!lookup) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("chain not found");
- return STC_ERROR_NO_DATA;
- }
-
- if (lookup->target != STC_FW_CHAIN_TARGET_NONE) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("can't be applied bcz chain is set");
- return STC_ERROR_INVALID_PARAMETER;
- }
-
- rule = MALLOC0(firewall_rule_s, 1);
- if (!rule) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("rule allocation failed");
- return STC_ERROR_OUT_OF_MEMORY;
- }
-
- memset(rule, 0, sizeof(firewall_rule_s));
- __fw_rule_copy(rule, info);
- __fw_rule_make_key(rule, info);
-
- comp = g_slist_find_custom(lookup->rules, rule, __fw_rule_comp);
- if (comp) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGD("rule already present");
- __fw_rule_free(rule);
- return STC_ERROR_ALREADY_DATA;
- }
-
- lookup->rules = g_slist_append(lookup->rules, rule);
-
- return STC_ERROR_NONE;
-}
-
-static stc_error_e __fw_rule_remove(const firewall_rule_s *info)
-{
- stc_fw_data_s *lookup;
- GSList *rule_list;
- GSList *comp;
- firewall_rule_s *rule;
-
- ret_value_msg_if(g_firewalls == NULL,
- STC_ERROR_FAIL,
- "firewall is not initialized!");
-
- lookup = g_hash_table_lookup(g_firewalls, info->chain);
- if (!lookup) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("chain not found");
- return STC_ERROR_NO_DATA;
- }
-
- if (lookup->target != STC_FW_CHAIN_TARGET_NONE) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("can't be applied bcz chain is set");
- return STC_ERROR_INVALID_PARAMETER;
- }
-
- rule_list = lookup->rules;
- comp = g_slist_find_custom(rule_list, info, __fw_rule_comp);
- if (!comp) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGD("rule not found");
- return STC_ERROR_NO_DATA;
- }
-
- rule = comp->data;
- lookup->rules = g_slist_remove(lookup->rules, rule);
- __fw_rule_free(rule);
-
- return STC_ERROR_NONE;
-}
-
-static stc_error_e __fw_rule_update(firewall_rule_s *info)
-{
- stc_fw_data_s *lookup;
- GSList *rule_list;
- GSList *comp;
- firewall_rule_s *origin_rule;
- firewall_rule_s *update_rule;
-
- ret_value_msg_if(g_firewalls == NULL,
- STC_ERROR_FAIL,
- "firewall is not initialized!");
-
- lookup = g_hash_table_lookup(g_firewalls, info->chain);
- if (!lookup) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("chain not found");
- return STC_ERROR_NO_DATA;
- }
-
- if (lookup->target != STC_FW_CHAIN_TARGET_NONE) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("can't be applied bcz chain is set");
- return STC_ERROR_INVALID_PARAMETER;
- }
-
- rule_list = lookup->rules;
- comp = g_slist_find_custom(rule_list, info, __fw_rule_comp);
- if (!comp) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGD("rule not found");
- return STC_ERROR_NO_DATA;
- }
-
- origin_rule = comp->data;
-
- update_rule = MALLOC0(firewall_rule_s, 1);
- if (!update_rule) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGE("rule allocation failed");
- return STC_ERROR_OUT_OF_MEMORY;
- }
-
- memset(update_rule, 0, sizeof(firewall_rule_s));
- __fw_rule_copy(update_rule, info);
- __fw_rule_make_key(update_rule, info);
-
- comp = g_slist_find_custom(lookup->rules, update_rule, __fw_rule_comp);
- if (comp) {
- if (STC_DEBUG_LOG && STC_FW_LOG)
- STC_LOGD("rule already present");
- __fw_rule_free(update_rule);
- return STC_ERROR_ALREADY_DATA;
- }
-
- lookup->rules = g_slist_remove(lookup->rules, origin_rule);
- __fw_rule_free(origin_rule);
-
- lookup->rules = g_slist_append(lookup->rules, update_rule);
-
- return STC_ERROR_NONE;
-}
-
-static void __fw_rule_extract(const char *key, GVariant *value,
- void *user_data)
-{
- firewall_rule_s *rule = (firewall_rule_s *)user_data;
- if (rule == NULL) {
- __STC_LOG_FUNC_EXIT__;
- return;
- }
-
- if (g_strcmp0(key, RULE_CHAIN) == 0) {
- guint str_length;
- const gchar *str = g_variant_get_string(value, &str_length);
- rule->chain = g_strdup(str);
- STC_LOGD("%s: [%s]", RULE_CHAIN, rule->chain);
-
- } else if (g_strcmp0(key, RULE_DIRECTION) == 0) {
- rule->direction = g_variant_get_uint16(value);
- STC_LOGD("%s: [%u]", RULE_DIRECTION, rule->direction);
-
- } else if (g_strcmp0(key, RULE_SIPTYPE) == 0) {
- rule->s_ip_type = g_variant_get_uint16(value);
- STC_LOGD("%s: [%u]", RULE_SIPTYPE, rule->s_ip_type);
-
- } else if (g_strcmp0(key, RULE_DIPTYPE) == 0) {
- rule->d_ip_type = g_variant_get_uint16(value);
- STC_LOGD("%s: [%u]", RULE_DIPTYPE, rule->d_ip_type);
-
- } else if (g_strcmp0(key, RULE_SPORTTYPE) == 0) {
- rule->s_port_type = g_variant_get_uint16(value);
- STC_LOGD("%s: [%u]", RULE_SPORTTYPE, rule->s_port_type);
-
- } else if (g_strcmp0(key, RULE_DPORTTYPE) == 0) {
- rule->d_port_type = g_variant_get_uint16(value);
- STC_LOGD("%s: [%u]", RULE_DPORTTYPE, rule->d_port_type);
-
- } else if (g_strcmp0(key, RULE_PROTOCOL) == 0) {
- rule->protocol = g_variant_get_uint16(value);
- STC_LOGD("%s: [%u]", RULE_PROTOCOL, rule->protocol);
-
- } else if (g_strcmp0(key, RULE_FAMILY) == 0) {
- rule->family = g_variant_get_uint16(value);
- STC_LOGD("%s: [%u]", RULE_FAMILY, rule->family);
-
- } else if (g_strcmp0(key, RULE_SIP1) == 0) {
- if (rule->s_ip_type != STC_FW_IP_NONE) {
- guint str_length;
- const gchar *str = g_variant_get_string(value, &str_length);
- if (rule->family == STC_FW_FAMILY_V4) {
- inet_pton(AF_INET, str, &(rule->s_ip1.Ipv4));
- STC_LOGD("%s: [%08x]", RULE_SIP1, rule->s_ip1.Ipv4.s_addr);
- } else if (rule->family == STC_FW_FAMILY_V6) {
- inet_pton(AF_INET6, str, &(rule->s_ip1.Ipv6));
- STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_SIP1,
- rule->s_ip1.Ipv6.s6_addr32[0], rule->s_ip1.Ipv6.s6_addr32[1],
- rule->s_ip1.Ipv6.s6_addr32[2], rule->s_ip1.Ipv6.s6_addr32[3]);
- }
- }
-
- } else if (g_strcmp0(key, RULE_SIP2) == 0) {
- if (rule->s_ip_type != STC_FW_IP_NONE) {
- guint str_length;
- const gchar *str = g_variant_get_string(value, &str_length);
- if (rule->family == STC_FW_FAMILY_V4) {
- inet_pton(AF_INET, str, &(rule->s_ip2.Ipv4));
- STC_LOGD("%s: [%08x]", RULE_SIP2, rule->s_ip2.Ipv4.s_addr);
- } else if (rule->family == STC_FW_FAMILY_V6) {
- inet_pton(AF_INET6, str, &(rule->s_ip2.Ipv6));
- STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_SIP2,
- rule->s_ip2.Ipv6.s6_addr32[0], rule->s_ip2.Ipv6.s6_addr32[1],
- rule->s_ip2.Ipv6.s6_addr32[2], rule->s_ip2.Ipv6.s6_addr32[3]);
- }
- }
-
- } else if (g_strcmp0(key, RULE_DIP1) == 0) {
- if (rule->d_ip_type != STC_FW_IP_NONE) {
- guint str_length;
- const gchar *str = g_variant_get_string(value, &str_length);
- if (rule->family == STC_FW_FAMILY_V4) {
- inet_pton(AF_INET, str, &(rule->d_ip1.Ipv4));
- STC_LOGD("%s: [%08x]", RULE_DIP1, rule->d_ip1.Ipv4.s_addr);
- } else if (rule->family == STC_FW_FAMILY_V6) {
- inet_pton(AF_INET6, str, &(rule->d_ip1.Ipv6));
- STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_DIP1,
- rule->d_ip1.Ipv6.s6_addr32[0], rule->d_ip1.Ipv6.s6_addr32[1],
- rule->d_ip1.Ipv6.s6_addr32[2], rule->d_ip1.Ipv6.s6_addr32[3]);
- }
- }
-
- } else if (g_strcmp0(key, RULE_DIP2) == 0) {
- if (rule->d_ip_type != STC_FW_IP_NONE) {
- guint str_length;
- const gchar *str = g_variant_get_string(value, &str_length);
- if (rule->family == STC_FW_FAMILY_V4) {
- inet_pton(AF_INET, str, &(rule->d_ip2.Ipv4));
- STC_LOGD("%s: [%08x]", RULE_DIP2, rule->d_ip2.Ipv4.s_addr);
- } else if (rule->family == STC_FW_FAMILY_V6) {
- inet_pton(AF_INET6, str, &(rule->d_ip2.Ipv6));
- STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_DIP2,
- rule->d_ip2.Ipv6.s6_addr32[0], rule->d_ip2.Ipv6.s6_addr32[1],
- rule->d_ip2.Ipv6.s6_addr32[2], rule->d_ip2.Ipv6.s6_addr32[3]);
- }
- }
-
- } else if (g_strcmp0(key, RULE_SPORT1) == 0) {
- if (rule->s_port_type != STC_FW_PORT_NONE) {
- rule->s_port1 = g_variant_get_uint32(value);
- STC_LOGD("%s: [%04x]", RULE_SPORT1, rule->s_port1);
- }
-
- } else if (g_strcmp0(key, RULE_SPORT2) == 0) {
- if (rule->s_port_type != STC_FW_PORT_NONE) {
- rule->s_port2 = g_variant_get_uint32(value);
- STC_LOGD("%s: [%04x]", RULE_SPORT2, rule->s_port2);
- }
-
- } else if (g_strcmp0(key, RULE_DPORT1) == 0) {
- if (rule->d_port_type != STC_FW_PORT_NONE) {
- rule->d_port1 = g_variant_get_uint32(value);
- STC_LOGD("%s: [%04x]", RULE_DPORT1, rule->d_port1);
- }
-
- } else if (g_strcmp0(key, RULE_DPORT2) == 0) {
- if (rule->d_port_type != STC_FW_PORT_NONE) {
- rule->d_port2 = g_variant_get_uint32(value);
- STC_LOGD("%s: [%04x]", RULE_DPORT2, rule->d_port2);
- }
-
- } else if (g_strcmp0(key, RULE_IFNAME) == 0) {
- if (rule->direction != STC_FW_DIRECTION_NONE) {
- guint str_length;
- const gchar *str = g_variant_get_string(value, &str_length);
- rule->ifname = g_strdup(str);
- STC_LOGD("%s: [%s]", RULE_IFNAME, rule->ifname);
- }
-
- } else if (g_strcmp0(key, RULE_TARGET) == 0) {
- rule->target = g_variant_get_uint16(value);
- STC_LOGD("%s: [%u]", RULE_TARGET, rule->target);
-
- } else if (g_strcmp0(key, RULE_LOG_LEVEL) == 0) {
- if (rule->target == STC_FW_RULE_TARGET_LOG) {
- rule->log_level = g_variant_get_uint16(value);
- STC_LOGD("%s: [%u]", RULE_LOG_LEVEL, rule->log_level);
- }
-
- } else if (g_strcmp0(key, RULE_LOG_PREFIX) == 0) {
- if (rule->target == STC_FW_RULE_TARGET_LOG) {
- guint str_length;
- const gchar *str = g_variant_get_string(value, &str_length);
- rule->log_prefix = g_strdup(str);
- STC_LOGD("%s: [%s]", RULE_LOG_PREFIX, rule->log_prefix);
- }
-
- } else if (g_strcmp0(key, RULE_NFLOG_GROUP) == 0) {
- if (rule->target == STC_FW_RULE_TARGET_NFLOG) {
- rule->nflog_group = g_variant_get_uint16(value);
- STC_LOGD("%s: [%u]", RULE_NFLOG_GROUP, rule->nflog_group);
- }
-
- } else if (g_strcmp0(key, RULE_NFLOG_PREFIX) == 0) {
- if (rule->target == STC_FW_RULE_TARGET_NFLOG) {
- guint str_length;
- const gchar *str = g_variant_get_string(value, &str_length);
- rule->nflog_prefix = g_strdup(str);
- STC_LOGD("%s: [%s]", RULE_NFLOG_PREFIX, rule->nflog_prefix);
- }
-
- } else if (g_strcmp0(key, RULE_NFLOG_RANGE) == 0) {
- if (rule->target == STC_FW_RULE_TARGET_NFLOG) {
- rule->nflog_range = g_variant_get_uint16(value);
- STC_LOGD("%s: [%u]", RULE_NFLOG_RANGE, rule->nflog_range);
- }
-
- } else if (g_strcmp0(key, RULE_NFLOG_THRESHOLD) == 0) {
- if (rule->target == STC_FW_RULE_TARGET_NFLOG) {
- rule->nflog_threshold = g_variant_get_uint16(value);
- STC_LOGD("%s: [%u]", RULE_NFLOG_THRESHOLD, rule->nflog_threshold);
- }
-
- } else if (g_strcmp0(key, RULE_IDENTIFIER) == 0) {
- guint str_length;
- const gchar *str = g_variant_get_string(value, &str_length);
- rule->identifier = g_strdup(str);
- STC_LOGD("%s: [%s]", RULE_IDENTIFIER, rule->identifier);
-
- } else if (g_strcmp0(key, RULE_KEY) == 0) {
- rule->key = g_variant_get_uint32(value);
- STC_LOGD("%s: [%u]", RULE_KEY, rule->key);
-
- } else {
- STC_LOGD("Unknown rule [%s]", key);
- }
-}
-
-gboolean __validate_fw_rule(firewall_rule_s *rule)
-{
- __STC_LOG_FUNC_ENTER__;
-
- if (rule == NULL) {
- __STC_LOG_FUNC_EXIT__;
- return FALSE;
- }
-
- if (rule->chain == NULL) {
- __STC_LOG_FUNC_EXIT__;
- return FALSE;
- }
-
- if (rule->direction > STC_FW_DIRECTION_OUT) {
- __STC_LOG_FUNC_EXIT__;
- return FALSE;
- }
-
- if (rule->s_ip_type > STC_FW_IP_RANGE) {
- __STC_LOG_FUNC_EXIT__;
- return FALSE;
- }
-
- if (rule->d_ip_type > STC_FW_IP_RANGE) {
- __STC_LOG_FUNC_EXIT__;
- return FALSE;
- }
-
- if (rule->s_port_type > STC_FW_PORT_RANGE) {
- __STC_LOG_FUNC_EXIT__;
- return FALSE;
- }
-
- if (rule->d_port_type > STC_FW_PORT_RANGE) {
- __STC_LOG_FUNC_EXIT__;
- return FALSE;
- }
-
- if (rule->protocol > STC_FW_PROTOCOL_ALL) {
- __STC_LOG_FUNC_EXIT__;
- return FALSE;
- }
-
- if (rule->family > STC_FW_FAMILY_V6) {
- __STC_LOG_FUNC_EXIT__;
- return FALSE;
- }
-
- if (rule->target >= STC_FW_RULE_TARGET_MAX) {
- __STC_LOG_FUNC_EXIT__;
- return FALSE;
- }
-
- if (rule->target == STC_FW_RULE_TARGET_LOG &&
- (rule->log_prefix == NULL ||
- rule->log_prefix[0] == '\0')) {
- __STC_LOG_FUNC_EXIT__;
- return FALSE;
- }
-
- if (rule->target == STC_FW_RULE_TARGET_NFLOG &&
- (rule->nflog_prefix == NULL ||
- rule->nflog_prefix[0] == '\0')) {
- __STC_LOG_FUNC_EXIT__;
- return FALSE;
- }
-
- __STC_LOG_FUNC_EXIT__;
- return TRUE;
-}
-
-void stc_firewall_init(void)
-{
- __STC_LOG_FUNC_ENTER__;
-
- int ret = STC_ERROR_NONE;
-
- g_firewalls = g_hash_table_new_full(g_str_hash,
- g_str_equal, g_free, __fw_data_free);
-
- ret = table_firewall_get_lock(LOCK_NAME, &g_lock_state);
- if (ret != STC_ERROR_NONE)
- table_firewall_insert_lock(LOCK_NAME, FIREWALL_UNLOCKED);
-
- if (g_lock_state == FIREWALL_UNKONWN)
- g_lock_state = FIREWALL_UNLOCKED;
-
- table_firewall_foreach_chain(__fw_table_chain_info_cb, NULL);
- table_firewall_foreach_rule(__fw_table_rule_info_cb, NULL);
-
- __STC_LOG_FUNC_EXIT__;
-}
-
-API void stc_firewall_update(void)
-{
- __STC_LOG_FUNC_ENTER__;
-
- __fw_chain_foreach(__fw_foreach_to_add_chain, NULL);
- __fw_chain_foreach(__fw_foreach_to_set_rule_to_chain, NULL);
- __fw_chain_foreach(__fw_foreach_to_set_chain, NULL);
-
- __STC_LOG_FUNC_EXIT__;
-}
-
-void stc_firewall_deinit(void)
-{
- __STC_LOG_FUNC_ENTER__;
-
- if (g_firewalls) {
- g_hash_table_destroy(g_firewalls);
- g_firewalls = NULL;
- }
-
- __STC_LOG_FUNC_EXIT__;
-}
-