add_value_attr(req, str, strlen(str) + 1, type);
}
-static void add_uint64_attr(struct genl *req, const uint64_t v, int type)
+static void add_uint64_attr(struct genl *req, const long long unsigned int v, int type)
{
add_value_attr(req, &v, sizeof(v), type);
}
add_uint64_attr(req, 0, NFACCT_BYTES);
//LCOV_EXCL_START
if (counter->quota) {
- STC_LOGD("quota bytes %"PRId64, counter->quota);
+ STC_LOGD("quota bytes %lld", counter->quota);
add_uint32_attr(req, htobe32(NFACCT_F_QUOTA_BYTES),
NFACCT_FLAGS);
NFACCT_F_QUOTA_BYTES);
}
-stc_error_e nfacct_send_get_all(struct counter_arg *carg)
+API stc_error_e nfacct_send_get_all(struct counter_arg *carg)
{
/* get and reset everything, used when quiting */
return internal_nfacct_send_get(carg, NFNL_MSG_ACCT_GET_CTRZERO, NULL,
type > STC_IFACE_UNKNOWN) ? type : STC_IFACE_UNKNOWN;
}
-bool recreate_counter_by_name(char *cnt_name, nfacct_rule_s *cnt)
+API bool recreate_counter_by_name(char *cnt_name, nfacct_rule_s *cnt)
{
char *iftype_part;
char *classid_part;
params->post_eval_attr(carg);
}
-netlink_serialization_command *
+API netlink_serialization_command *
netlink_create_command(struct netlink_serialization_params *params)
{
static netlink_serialization_command command = {0,};
return "";
}
-static char *get_iptables_chain(const nfacct_rule_direction iotype)
+static char *get_iptables_chain(uint32_t classid,
+ const nfacct_rule_direction iotype,
+ const stc_app_state_e app_state,
+ const nfacct_rule_intend intend)
{
- if (iotype == NFACCT_COUNTER_IN)
- return STC_IN_CHAIN;
- else if (iotype == NFACCT_COUNTER_OUT)
- return STC_OUT_CHAIN;
- else if (iotype == NFACCT_COUNTER_FORWARD) //LCOV_EXCL_LINE
- return STC_FRWD_CHAIN; //LCOV_EXCL_LINE
+ if (iotype == NFACCT_COUNTER_IN) {
+ if (intend == NFACCT_COUNTER ||
+ intend == NFACCT_TETH_COUNTER) {
+ if (app_state == STC_APP_STATE_FOREGROUND)
+ return STC_IN_FG_CHAIN;
+ else
+ return STC_IN_BG_CHAIN;
+ } else if (intend == NFACCT_ALLOW ||
+ intend == NFACCT_TETH_ALLOW) {
+ return STC_IN_ACCEPT_CHAIN;
+ } else {
+ if (classid == STC_BACKGROUND_APP_CLASSID)
+ return STC_IN_BG_DROP_CHAIN;
+ else
+ return STC_IN_DROP_CHAIN;
+ }
+ } else if (iotype == NFACCT_COUNTER_OUT) {
+ if (intend == NFACCT_COUNTER ||
+ intend == NFACCT_TETH_COUNTER) {
+ if (app_state == STC_APP_STATE_FOREGROUND)
+ return STC_OUT_FG_CHAIN;
+ else
+ return STC_OUT_BG_CHAIN;
+ } else if (intend == NFACCT_ALLOW ||
+ intend == NFACCT_TETH_ALLOW) {
+ return STC_OUT_ACCEPT_CHAIN;
+ } else {
+ if (classid == STC_BACKGROUND_APP_CLASSID)
+ return STC_OUT_BG_DROP_CHAIN;
+ else
+ return STC_OUT_DROP_CHAIN;
+ }
+ } else if (iotype == NFACCT_COUNTER_FORWARD)
+ return STC_FRWD_CHAIN;
return "";
}
rule->intend == NFACCT_TETH_BLOCK)
iptables_rule.chain = g_strdup(STC_TETHER_CHAIN);
else
- iptables_rule.chain = g_strdup(get_iptables_chain(rule->iotype));
+ iptables_rule.chain = g_strdup(get_iptables_chain(rule->classid,
+ rule->iotype, rule->app_state, rule->intend));
- iptables_rule.classid = rule->classid;
+ if (rule->classid < STC_RESERVED_CLASSID_MAX)
+ iptables_rule.classid = STC_UNKNOWN_CLASSID;
+ else
+ iptables_rule.classid = rule->classid;
iptables_rule.direction = (rule->iotype & NFACCT_COUNTER_IN) ?
IPTABLES_DIRECTION_IN : IPTABLES_DIRECTION_OUT;
iptype = (iptables_ip_type_e)rule->iptype;
/* specify source and destination ip address if any */
if (rule->src_ip1) {
- if (!inet_aton(rule->src_ip1, &iptables_rule.s_ip1))
- STC_LOGE("Failed to inet aton [%s]", rule->src_ip1);
+ if (!inet_aton(rule->src_ip1, &iptables_rule.s_ip1)) {
+ ret = STC_ERROR_INVALID_PARAMETER;
+ goto free;
+ }
}
+
if (rule->src_ip2) {
- if (!inet_aton(rule->src_ip2, &iptables_rule.s_ip2))
- STC_LOGE("Failed to inet aton [%s]", rule->src_ip2);
+ if (!inet_aton(rule->src_ip2, &iptables_rule.s_ip2)) {
+ ret = STC_ERROR_INVALID_PARAMETER;
+ goto free;
+ }
}
+
if (rule->dst_ip1) {
- if (!inet_aton(rule->dst_ip1, &iptables_rule.d_ip1))
- STC_LOGE("Failed to inet aton [%s]", rule->dst_ip1);
+ if (!inet_aton(rule->dst_ip1, &iptables_rule.d_ip1)) {
+ ret = STC_ERROR_INVALID_PARAMETER;
+ goto free;
+ }
}
+
if (rule->dst_ip2) {
- if (!inet_aton(rule->dst_ip2, &iptables_rule.d_ip2))
- STC_LOGE("Failed to inet aton [%s]", rule->dst_ip2);
+ if (!inet_aton(rule->dst_ip2, &iptables_rule.d_ip2)) {
+ ret = STC_ERROR_INVALID_PARAMETER;
+ goto free;
+ }
}
if (rule->action == NFACCT_ACTION_DELETE) {
ret = iptables_add(&iptables_rule, iptype);
}
+free:
g_free(iptables_rule.nfacct_name);
g_free(iptables_rule.ifname);
g_free(iptables_rule.target);
char *jump_cmd = get_iptables_jump(rule->jump);
char nfacct_buf[sizeof(NFACCT_NAME_MOD) +
3*MAX_DEC_SIZE(int) + 4 + 1];
- uint32_t classid = rule->classid;
stc_error_e ret;
if (rule->iotype & NFACCT_COUNTER_IN) {
ret_value_msg_if(ret > sizeof(nfacct_buf) || ret < 0,
STC_ERROR_FAIL, "Not enought buffer");
- classid = rule->classid;
- rule->classid = 0;
-
ret = exec_iptables_cmd(rule);
ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
"Can't set conditional block for ingress"
//LCOV_EXCL_STOP
}
- rule->classid = classid;
-
if (rule->iotype & NFACCT_COUNTER_OUT) {
/* outcome part */
rule->iotype = NFACCT_COUNTER_OUT;
ret_value_msg_if(ret > sizeof(nfacct_buf) || ret < 0,
STC_ERROR_FAIL, "Not enough buffer");
- classid = rule->classid;
- rule->classid = 0;
-
ret = exec_iptables_cmd(rule);
ret_value_msg_if(ret != STC_ERROR_NONE, STC_ERROR_FAIL,
"Can't set conditional block for "
}
//LCOV_EXCL_STOP
}
+
return STC_ERROR_NONE;
}
-stc_error_e produce_net_rule(nfacct_rule_s *rule)
+API stc_error_e produce_net_rule(nfacct_rule_s *rule)
{
stc_error_e ret = STC_ERROR_NONE;
if (rule->classid != STC_ALL_APP_CLASSID &&
rule->classid != STC_TETHERING_APP_CLASSID &&
+ rule->classid != STC_BACKGROUND_APP_CLASSID &&
rule->classid != STC_TOTAL_DATACALL_CLASSID &&
rule->classid != STC_TOTAL_WIFI_CLASSID &&
rule->classid != STC_TOTAL_BLUETOOTH_CLASSID &&
return ret;
}
+static stc_error_e append_iptables_cmd(GSList **iptables_list, nfacct_rule_s *rule)
+{
+ iptables_rule_s *iptables_rule = NULL;
+
+ iptables_rule = MALLOC0(iptables_rule_s, 1);
+ if (!iptables_rule)
+ return STC_ERROR_OUT_OF_MEMORY;
+
+ iptables_rule->nfacct_name = g_strdup(rule->name);
+ iptables_rule->ifname = g_strdup(rule->ifname);
+ iptables_rule->target = g_strdup(get_iptables_jump(rule->jump));
+ iptables_rule->chain = g_strdup(get_iptables_chain(rule->classid,
+ rule->iotype, rule->app_state, rule->intend));
+ if (rule->classid < STC_RESERVED_CLASSID_MAX)
+ iptables_rule->classid = STC_UNKNOWN_CLASSID;
+ else
+ iptables_rule->classid = rule->classid;
+ iptables_rule->direction = (rule->iotype & NFACCT_COUNTER_IN) ?
+ IPTABLES_DIRECTION_IN : IPTABLES_DIRECTION_OUT;
+
+ *iptables_list = g_slist_append(*iptables_list, iptables_rule);
+
+ return STC_ERROR_NONE;
+}
+
+static void iptables_list_free(gpointer value)
+{
+ iptables_rule_s *iptables_rule = (iptables_rule_s *)value;
+
+ g_free(iptables_rule->chain);
+ g_free(iptables_rule->nfacct_name);
+ g_free(iptables_rule->ifname);
+ g_free(iptables_rule->target);
+ g_free(iptables_rule);
+}
+
+API stc_error_e produce_net_list(GSList *rule_list,
+ nfacct_rule_iptype iptype, nfacct_rule_action action)
+{
+ GSList *list = NULL;
+ GSList *iptables_list = NULL;
+ stc_error_e ret = STC_ERROR_NONE;
+
+ for (list = rule_list; list; list = list->next) {
+ nfacct_rule_s *rule = list->data;
+
+ if (rule->action == NFACCT_ACTION_APPEND &&
+ rule->intend == NFACCT_WARN &&
+ !rule->send_limit && !rule->rcv_limit)
+ continue;
+
+ generate_counter_name(rule);
+ if (rule->action != NFACCT_ACTION_DELETE) {
+ ret = nfacct_send_del(rule);
+ if (ret != STC_ERROR_NONE)
+ continue;
+
+ ret = nfacct_send_new(rule);
+ if (ret != STC_ERROR_NONE)
+ continue;
+ }
+
+ append_iptables_cmd(&iptables_list, rule);
+ }
+
+ if (action == NFACCT_ACTION_INSERT ||
+ action == NFACCT_ACTION_APPEND)
+ ret = iptables_add_list(iptables_list, iptype);
+ else if (action == NFACCT_ACTION_DELETE)
+ ret = iptables_remove_list(iptables_list, iptype);
+
+ for (list = rule_list; list; list = list->next) {
+ nfacct_rule_s *rule = list->data;
+
+ if (rule->action == NFACCT_ACTION_DELETE)
+ nfacct_send_del(rule);
+ }
+
+ g_slist_free_full(iptables_list, iptables_list_free);
+ return ret;
+}
+
void generate_counter_name(nfacct_rule_s *counter)
{
char warn_symbol = 'c';