int iptables_parse()

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;
}