in system/iptables/iptables_utils.c [221:501]
int iptables_parse(FAR struct iptables_args_s *args,
int argc, FAR char *argv[])
{
bool inv = false;
int i;
bzero(args, sizeof(struct iptables_args_s));
args->hook = NF_INET_NUMHOOKS;
/* Parse arguments. */
for (i = 1; i < argc; i++)
{
/* Table */
if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--table") == 0)
{
if (++i >= argc)
{
printf("Missing table name!\n");
return -EINVAL;
}
args->table = argv[i];
continue;
}
/* Commands */
if (iptables_parse_cmd(argv[i], &args->cmd))
{
/* The chain name is following the command */
if (i + 1 < argc)
{
args->hook = iptables_parse_hook(argv[i + 1]);
}
if (args->hook != NF_INET_NUMHOOKS)
{
i++; /* Success to parse as hook. */
}
else if (args->cmd != COMMAND_LIST && args->cmd != COMMAND_FLUSH)
{
printf("Wrong chain name %s!\n", argv[i + 1]);
return -EINVAL;
}
/* Insert or delete command may have rule number */
if (args->cmd == COMMAND_INSERT || args->cmd == COMMAND_DELETE)
{
if (i + 1 < argc)
{
args->rulenum = atoi(argv[i + 1]);
}
if (args->rulenum >= 1)
{
i++;
}
else if (args->cmd == COMMAND_INSERT)
{
/* Default insert position is 1 */
args->rulenum = 1;
}
}
/* Policy command should have target */
if (args->cmd == COMMAND_POLICY)
{
if (++i >= argc)
{
printf("Missing target name!\n");
return -EINVAL;
}
args->target = iptables_parse_target(argv[i], &args->verdict);
if (args->verdict == 0)
{
printf("Invalid target name %s!\n", argv[i]);
return -EINVAL;
}
}
continue;
}
/* Target */
if (strcmp(argv[i], "-j") == 0 || strcmp(argv[i], "--jump") == 0)
{
if (++i >= argc)
{
printf("Missing target name!\n");
return -EINVAL;
}
args->target = iptables_parse_target(argv[i], &args->verdict);
continue;
}
/* Invert */
if (strcmp(argv[i], "!") == 0)
{
inv = true;
continue;
}
/* Protocol */
if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--protocol") == 0)
{
if (++i >= argc)
{
printf("Missing protocol name!\n");
return -EINVAL;
}
args->protocol = iptables_parse_proto(argv[i]);
if (inv)
{
args->ipinv |= IPT_INV_PROTO;
inv = false;
}
continue;
}
/* Source address */
if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--source") == 0)
{
if (++i >= argc)
{
printf("Missing source address!\n");
return -EINVAL;
}
args->saddr = argv[i];
if (inv)
{
args->ipinv |= IPT_INV_SRCIP;
inv = false;
}
continue;
}
/* Destination address */
if (strcmp(argv[i], "-d") == 0 ||
strcmp(argv[i], "--destination") == 0)
{
if (++i >= argc)
{
printf("Missing destination address!\n");
return -EINVAL;
}
args->daddr = argv[i];
if (inv)
{
args->ipinv |= IPT_INV_DSTIP;
inv = false;
}
continue;
}
/* Source port */
if (strcmp(argv[i], "--sport") == 0 ||
strcmp(argv[i], "--source-port") == 0)
{
if (++i >= argc)
{
printf("Missing source port!\n");
return -EINVAL;
}
args->sport = argv[i];
if (inv)
{
args->tcpudpinv |= XT_TCP_INV_SRCPT;
inv = false;
}
continue;
}
/* Destination port */
if (strcmp(argv[i], "--dport") == 0 ||
strcmp(argv[i], "--destination-port") == 0)
{
if (++i >= argc)
{
printf("Missing destination port!\n");
return -EINVAL;
}
args->dport = argv[i];
if (inv)
{
args->tcpudpinv |= XT_TCP_INV_DSTPT;
inv = false;
}
continue;
}
/* In interface */
if (strcmp(argv[i], "-i") == 0 ||
strcmp(argv[i], "--in-interface") == 0)
{
if (++i >= argc)
{
printf("Missing in-interface name!\n");
return -EINVAL;
}
args->inifname = argv[i];
if (inv)
{
args->ipinv |= IPT_INV_VIA_IN;
inv = false;
}
continue;
}
/* Out interface */
if (strcmp(argv[i], "-o") == 0 ||
strcmp(argv[i], "--out-interface") == 0)
{
if (++i >= argc)
{
printf("Missing out-interface name!\n");
return -EINVAL;
}
args->outifname = argv[i];
if (inv)
{
args->ipinv |= IPT_INV_VIA_OUT;
inv = false;
}
continue;
}
/* ICMP type */
if (strcmp(argv[i], "--icmp-type") == 0 ||
strcmp(argv[i], "--icmpv6-type") == 0)
{
if (++i >= argc)
{
printf("Missing ICMP type!\n");
return -EINVAL;
}
args->icmp_type = argv[i];
if (inv)
{
args->icmpinv |= IPT_ICMP_INV;
inv = false;
}
continue;
}
}
return OK;
}