HEX
Server: Apache/2.4.6 (CentOS) PHP/5.6.39
System: Linux izj6c6ukj0hyugxsgmuxz3z 3.10.0-514.6.2.el7.x86_64 #1 SMP Thu Feb 23 03:04:39 UTC 2017 x86_64
User: root (0)
PHP: 5.6.39
Disabled: NONE
Upload Files
File: //bin/firewall-cmd
#!/usr/bin/python -Es
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2014 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@redhat.com>
# Jiri Popelka <jpopelka@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

from gi.repository import GObject
import sys
sys.modules['gobject'] = GObject

import argparse
import dbus
import os

from firewall.client import *
from firewall.errors import *
from firewall.functions import joinArgs, splitArgs

def __print(msg=None):
    if msg and not a.quiet:
        print(msg)

def __print_and_exit(msg=None, exit_code=0):
    FAIL = '\033[91m'
    OK =   '\033[92m'
    END =  '\033[00m'
    if exit_code > 1:
        __print(FAIL + msg + END)
        if "COMMAND_FAILED" in msg and "tables" in msg:
            __print(_("Failed to apply rules. A firewall reload might solve the issue if the firewall has been modified using ip*tables or ebtables."))
    else:
        __print(msg)
        #__print(OK + msg + END)
    sys.exit(exit_code)

def __fail(msg=None):
    __print_and_exit(msg, 2)

def __print_if_verbose(msg=None):
    if msg and a.verbose:
        print(msg)

def __usage():
    print ("""
Usage: firewall-cmd [OPTIONS...]

General Options
  -h, --help           Prints a short help text and exists
  -V, --version        Print the version string of firewalld
  -q, --quiet          Do not print status messages

Status Options
  --state              Return and print firewalld state
  --reload             Reload firewall and keep state information
  --complete-reload    Reload firewall and loose state information
  --runtime-to-permanent
                       Create permanent from runtime configuration

Permanent Options
  --permanent          Set an option permanently
                       Usable for options maked with [P]

Zone Options
  --get-default-zone   Print default zone for connections and interfaces
  --set-default-zone=<zone>
                       Set default zone
  --get-active-zones   Print currently active zones
  --get-zones          Print predefined zones [P]
  --get-services       Print predefined services [P]
  --get-icmptypes      Print predefined icmptypes [P]
  --get-zone-of-interface=<interface>
                       Print name of the zone the interface is bound to [P]
  --get-zone-of-source=<source>[/<mask>]
                       Print name of the zone the source[/mask] is bound to [P]
  --list-all-zones     List everything added for or enabled in all zones [P]
  --new-zone=<zone>    Add a new zone [P only]
  --delete-zone=<zone> Delete an existing zone [P only]
  --zone=<zone>        Use this zone to set or query options, else default zone
                       Usable for options maked with [Z]
  --get-target         Get the zone target [P] [Z]
  --set-target=<target>
                       Set the zone target [P] [Z]

IcmpType Options
  --new-icmptype=<icmptype>
                       Add a new icmptype [P only]
  --delete-icmptype=<icmptype>
                       Delete and existing icmptype [P only]

Service Options
  --new-service=<service>
                       Add a new service [P only]
  --delete-service=<service>
                       Delete and existing service [P only]

Options to Adapt and Query Zones
  --list-all           List everything added for or enabled in a zone [P] [Z]
  --list-services      List services added for a zone [P] [Z]
  --timeout=<timeval>  Enable an option for timeval time, where timeval is
                       a number followed by one of letters 's' or 'm' or 'h'
                       Usable for options maked with [T]
  --add-service=<service>
                       Add a service for a zone [P] [Z] [T]
  --remove-service=<service>
                       Remove a service from a zone [P] [Z]
  --query-service=<service>
                       Return whether service has been added for a zone [P] [Z]
  --list-ports         List ports added for a zone [P] [Z]
  --add-port=<portid>[-<portid>]/<protocol>
                       Add the port for a zone [P] [Z] [T]
  --remove-port=<portid>[-<portid>]/<protocol>
                       Remove the port from a zone [P] [Z]
  --query-port=<portid>[-<portid>]/<protocol>
                       Return whether the port has been added for zone [P] [Z]
  --list-icmp-blocks   List Internet ICMP type blocks added for a zone [P] [Z]
  --add-icmp-block=<icmptype>
                       Add an ICMP block for a zone [P] [Z] [T]
  --remove-icmp-block=<icmptype>
                       Remove the ICMP block from a zone [P] [Z]
  --query-icmp-block=<icmptype>
                       Return whether an ICMP block has been added for a zone
                       [P] [Z]
  --list-forward-ports List IPv4 forward ports added for a zone [P] [Z]
  --add-forward-port=port=<portid>[-<portid>]:proto=<protocol>[:toport=<portid>[-<portid>]][:toaddr=<address>[/<mask>]]
                       Add the IPv4 forward port for a zone [P] [Z] [T]
  --remove-forward-port=port=<portid>[-<portid>]:proto=<protocol>[:toport=<portid>[-<portid>]][:toaddr=<address>[/<mask>]]
                       Remove the IPv4 forward port from a zone [P] [Z]


  --query-forward-port=port=<portid>[-<portid>]:proto=<protocol>[:toport=<portid>[-<portid>]][:toaddr=<address>[/<mask>]]
                       Return whether the IPv4 forward port has been added for
                       a zone [P] [Z]
  --add-masquerade     Enable IPv4 masquerade for a zone [P] [Z] [T]
  --remove-masquerade  Disable IPv4 masquerade for a zone [P] [Z]
  --query-masquerade   Return whether IPv4 masquerading has been enabled for a
                       zone [P] [Z]
  --list-rich-rules    List rich language rules added for a zone [P] [Z]
  --add-rich-rule=<rule>
                       Add rich language rule 'rule' for a zone [P] [Z] [T]
  --remove-rich-rule=<rule>
                       Remove rich language rule 'rule' from a zone [P] [Z]
  --query-rich-rule=<rule>
                       Return whether a rich language rule 'rule' has been
                       added for a zone [P] [Z]

Options to Handle Bindings of Interfaces
  --list-interfaces    List interfaces that are bound to a zone [P] [Z]
  --add-interface=<interface>
                       Bind the <interface> to a zone [P] [Z]
  --change-interface=<interface>
                       Change zone the <interface> is bound to [Z]
  --query-interface=<interface>
                       Query whether <interface> is bound to a zone [P] [Z]
  --remove-interface=<interface>
                       Remove binding of <interface> from a zone [P] [Z]

Options to Handle Bindings of Sources
  --list-sources       List sources that are bound to a zone [P] [Z]
  --add-source=<source>[/<mask>]
                       Bind <source>[/<mask>] to a zone [P] [Z]
  --change-source=<source>[/<mask>]
                       Change zone the <source>[/<mask>] is bound to [Z]
  --query-source=<source>[/<mask>]
                       Query whether <source>[/<mask>] is bound to a zone
                       [P] [Z]
  --remove-source=<source>[/<mask>]
                       Remove binding of <source>[/<mask>] from a zone [P] [Z]

Direct Options
  --direct             First option for all direct options
  --get-all-chains
                       Get all chains [P]
  --get-chains {ipv4|ipv6|eb} <table>
                       Get all chains added to the table [P]
  --add-chain {ipv4|ipv6|eb} <table> <chain>
                       Add a new chain to the table [P]
  --remove-chain {ipv4|ipv6|eb} <table> <chain>
                       Remove the chain from the table [P]
  --query-chain {ipv4|ipv6|eb} <table> <chain>
                       Return whether the chain has been added to the table [P]
  --get-all-rules
                       Get all rules [P]
  --get-rules {ipv4|ipv6|eb} <table> <chain>
                       Get all rules added to chain in table [P]
  --add-rule {ipv4|ipv6|eb} <table> <chain> <priority> <arg>...
                       Add rule to chain in table [P]
  --remove-rule {ipv4|ipv6|eb} <table> <chain> <priority> <arg>...
                       Remove rule with priority from chain in table [P]
  --remove-rules {ipv4|ipv6|eb} <table> <chain>
                       Remove rules from chain in table [P]
  --query-rule {ipv4|ipv6|eb} <table> <chain> <priority> <arg>...
                       Return whether a rule with priority has been added to
                       chain in table [P]
  --passthrough {ipv4|ipv6|eb} <arg>...
                       Pass a command through (untracked by firewalld)
  --get-all-passthroughs
                       Get all tracked passthrough rules [P]
  --get-passthroughs {ipv4|ipv6|eb} <arg>...
                       Get tracked passthrough rules [P]
  --add-passthrough {ipv4|ipv6|eb} <arg>...
                       Add a new tracked passthrough rule [P]
  --remove-passthrough {ipv4|ipv6|eb} <arg>...
                       Remove a tracked passthrough rule [P]
  --query-passthrough {ipv4|ipv6|eb} <arg>...
                       Return whether the tracked passthrough rule has been
                       added [P]

Lockdown Options
  --lockdown-on        Enable lockdown.
  --lockdown-off       Disable lockdown.
  --query-lockdown     Query whether lockdown is enabled

Lockdown Whitelist Options
  --list-lockdown-whitelist-commands
                       List all command lines that are on the whitelist [P]
  --add-lockdown-whitelist-command=<command>
                       Add the command to the whitelist [P]
  --remove-lockdown-whitelist-command=<command>
                       Remove the command from the whitelist [P]
  --query-lockdown-whitelist-command=<command>
                       Query whether the command is on the whitelist [P]
  --list-lockdown-whitelist-contexts
                       List all contexts that are on the whitelist [P]
  --add-lockdown-whitelist-context=<context>
                       Add the context context to the whitelist [P]
  --remove-lockdown-whitelist-context=<context>
                       Remove the context from the whitelist [P]
  --query-lockdown-whitelist-context=<context>
                       Query whether the context is on the whitelist [P]
  --list-lockdown-whitelist-uids
                       List all user ids that are on the whitelist [P]
  --add-lockdown-whitelist-uid=<uid>
                       Add the user id uid to the whitelist [P]
  --remove-lockdown-whitelist-uid=<uid>
                       Remove the user id uid from the whitelist [P]
  --query-lockdown-whitelist-uid=<uid>
                       Query whether the user id uid is on the whitelist [P]
  --list-lockdown-whitelist-users
                       List all user names that are on the whitelist [P]
  --add-lockdown-whitelist-user=<user>
                       Add the user name user to the whitelist [P]
  --remove-lockdown-whitelist-user=<user>
                       Remove the user name user from the whitelist [P]
  --query-lockdown-whitelist-user=<user>
                       Query whether the user name user is on the whitelist [P]

Panic Options
  --panic-on           Enable panic mode
  --panic-off          Disable panic mode
  --query-panic        Query whether panic mode is enabled
""")

def __parse_port(value):
    try:
        (port, proto) = value.split("/")
    except Exception as e:
        __fail("bad port (most likely missing protocol), correct syntax is portid[-portid]/protocol")
    return (port, proto)

def __parse_forward_port(value):
    port = None
    protocol = None
    toport = None
    toaddr = None
    args = value.split(":")
    for arg in args:
        try:
            (opt,val) = arg.split("=")
            if opt == "port":
                port = val
            elif opt == "proto":
                protocol = val
            elif opt == "toport":
                toport = val
            elif opt == "toaddr":
                toaddr = val
        except:
            __fail("invalid forward port arg '%s'" % (arg))
    if not port:
        __fail("missing port")
    if not protocol:
        __fail("missing protocol")
    if not (toport or toaddr):
        __fail("missing destination")
    return (port, protocol, toport, toaddr)

def _check_ipv(value):
    if value != "ipv4" and value != "ipv6" and value != "eb":
        __fail("invalid argument: %s (choose from 'ipv4', 'ipv6', 'eb')" % value)
    return value

def __print_all(zone, interfaces, sources, services, ports, masquerade, forward_ports, icmp_blocks, rules):
    attributes = []
    if zone == fw.getDefaultZone():
        attributes.append("default")
    if interfaces:
        attributes.append("active")
    if attributes:
        zone = zone + " (%s)" % ", ".join(attributes)
    __print(zone)
    __print("  interfaces: " + " ".join(interfaces))
    __print("  sources: " + " ".join(sources))
    __print("  services: " + " ".join(services))
    __print("  ports: " + " ".join(["%s/%s" % (port[0], port[1]) for port in ports]))
    __print("  masquerade: %s" % ("yes" if masquerade else "no"))
    __print("  forward-ports: " + "\n\t".join(["port=%s:proto=%s:toport=%s:toaddr=%s" % (port, protocol, toport, toaddr) for (port, protocol, toport, toaddr) in forward_ports]))
    __print("  icmp-blocks: " + " ".join(icmp_blocks))
    __print("  rich rules: \n\t" + "\n\t".join(rules))

def __list_all(fw, zone):
    interfaces = fw.getInterfaces(zone)
    sources = fw.getSources(zone)
    services = fw.getServices(zone)
    ports = fw.getPorts(zone)
    masquerade = fw.queryMasquerade(zone)
    forward_ports = fw.getForwardPorts(zone)
    icmp_blocks = fw.getIcmpBlocks(zone)
    rules = fw.getRichRules(zone)
    __print_all(zone, interfaces, sources, services, ports, masquerade, forward_ports, icmp_blocks, rules)

def __list_all_permanent(fw_settings, zone):
    interfaces = fw_settings.getInterfaces()
    sources = fw_settings.getSources()
    services = fw_settings.getServices()
    ports = fw_settings.getPorts()
    masquerade = fw_settings.getMasquerade()
    forward_ports = fw_settings.getForwardPorts()
    icmp_blocks = fw_settings.getIcmpBlocks()
    rules = fw_settings.getRichRules()
    __print_all(zone, interfaces, sources, services, ports, masquerade, forward_ports, icmp_blocks, rules)

def __print_query_result(value):
    if value:
        __print_and_exit("yes")
    else:
        __print_and_exit("no", 1)

def __exception_handler(exception_message):
    if "NotAuthorizedException" in exception_message:
        __print ("Authorization failed.")
        __print ("Make sure polkit agent is running or run the application as superuser.")
        sys.exit(NOT_AUTHORIZED)
    else:
        code = FirewallError.get_code(exception_message)
        if code in [ ALREADY_ENABLED, NOT_ENABLED, ZONE_ALREADY_SET ]:
            __print_and_exit("Warning: %s" % exception_message)
        else:
            __print_and_exit("Error: %s" % exception_message, code)

parser = argparse.ArgumentParser(usage="see firewall-cmd man page",
                                 add_help=False)

parser_group_output = parser.add_mutually_exclusive_group()
parser_group_output.add_argument("-v", "--verbose", action="store_true")
parser_group_output.add_argument("-q", "--quiet", action="store_true")

parser_group_standalone = parser.add_mutually_exclusive_group()
parser_group_standalone.add_argument("-h", "--help",
                                     action="store_true")
parser_group_standalone.add_argument("-V", "--version", action="store_true")
parser_group_standalone.add_argument("--state", action="store_true")
parser_group_standalone.add_argument("--reload", action="store_true")
parser_group_standalone.add_argument("--complete-reload", action="store_true")
parser_group_standalone.add_argument("--runtime-to-permanent",
                                     action="store_true")
parser_group_standalone.add_argument("--panic-on", action="store_true")
parser_group_standalone.add_argument("--panic-off", action="store_true")
parser_group_standalone.add_argument("--query-panic", action="store_true")
parser_group_standalone.add_argument("--lockdown-on", action="store_true")
parser_group_standalone.add_argument("--lockdown-off", action="store_true")
parser_group_standalone.add_argument("--query-lockdown", action="store_true")

parser_group_standalone.add_argument("--get-default-zone", action="store_true")
parser_group_standalone.add_argument("--set-default-zone", metavar="<zone>")
parser_group_standalone.add_argument("--get-zones", action="store_true")
parser_group_standalone.add_argument("--get-services", action="store_true")
parser_group_standalone.add_argument("--get-icmptypes", action="store_true")
parser_group_standalone.add_argument("--get-active-zones", action="store_true")
parser_group_standalone.add_argument("--get-zone-of-interface", metavar="<iface>")
parser_group_standalone.add_argument("--get-zone-of-source", metavar="<source>")
parser_group_standalone.add_argument("--list-all-zones", action="store_true")

parser_group_config = parser.add_mutually_exclusive_group()
parser_group_config.add_argument("--new-icmptype", metavar="<icmptype>")
parser_group_config.add_argument("--delete-icmptype", metavar="<icmptype>")
parser_group_config.add_argument("--new-service", metavar="<service>")
parser_group_config.add_argument("--delete-service", metavar="<service>")
parser_group_config.add_argument("--new-zone", metavar="<zone>")
parser_group_config.add_argument("--delete-zone", metavar="<zone>")

parser_group_lockdown_whitelist = parser.add_mutually_exclusive_group()
parser_group_lockdown_whitelist.add_argument("--list-lockdown-whitelist-commands", action="store_true")
parser_group_lockdown_whitelist.add_argument("--add-lockdown-whitelist-command", metavar="<command>")
parser_group_lockdown_whitelist.add_argument("--remove-lockdown-whitelist-command", metavar="<command>")
parser_group_lockdown_whitelist.add_argument("--query-lockdown-whitelist-command", metavar="<command>")

parser_group_lockdown_whitelist.add_argument("--list-lockdown-whitelist-contexts", action="store_true")
parser_group_lockdown_whitelist.add_argument("--add-lockdown-whitelist-context", metavar="<context>")
parser_group_lockdown_whitelist.add_argument("--remove-lockdown-whitelist-context", metavar="<context>")
parser_group_lockdown_whitelist.add_argument("--query-lockdown-whitelist-context", metavar="<context>")

parser_group_lockdown_whitelist.add_argument("--list-lockdown-whitelist-uids", action="store_true")
parser_group_lockdown_whitelist.add_argument("--add-lockdown-whitelist-uid", metavar="<uid>", type=int)
parser_group_lockdown_whitelist.add_argument("--remove-lockdown-whitelist-uid", metavar="<uid>", type=int)
parser_group_lockdown_whitelist.add_argument("--query-lockdown-whitelist-uid", metavar="<uid>", type=int)

parser_group_lockdown_whitelist.add_argument("--list-lockdown-whitelist-users", action="store_true")
parser_group_lockdown_whitelist.add_argument("--add-lockdown-whitelist-user", metavar="<user>")
parser_group_lockdown_whitelist.add_argument("--remove-lockdown-whitelist-user", metavar="<user>")
parser_group_lockdown_whitelist.add_argument("--query-lockdown-whitelist-user", metavar="<user>")

parser.add_argument("--permanent", action="store_true")
parser.add_argument("--zone", default="", metavar="<zone>")
parser.add_argument("--timeout", default="0", metavar="<seconds>")

parser_group_zone = parser.add_mutually_exclusive_group()
parser_group_zone.add_argument("--add-interface", metavar="<iface>")
parser_group_zone.add_argument("--remove-interface", metavar="<iface>")
parser_group_zone.add_argument("--query-interface", metavar="<iface>")
parser_group_zone.add_argument("--change-interface", "--change-zone", metavar="<iface>")
parser_group_zone.add_argument("--list-interfaces", action="store_true")
parser_group_zone.add_argument("--add-source", metavar="<source>")
parser_group_zone.add_argument("--remove-source", metavar="<source>")
parser_group_zone.add_argument("--query-source", metavar="<source>")
parser_group_zone.add_argument("--change-source", metavar="<source>")
parser_group_zone.add_argument("--list-sources", action="store_true")
parser_group_zone.add_argument("--add-rich-rule", metavar="<rule>", action='append')
parser_group_zone.add_argument("--remove-rich-rule", metavar="<rule>", action='append')
parser_group_zone.add_argument("--query-rich-rule", metavar="<rule>")
parser_group_zone.add_argument("--add-service", metavar="<service>", action='append')
parser_group_zone.add_argument("--remove-service", metavar="<zone>", action='append')
parser_group_zone.add_argument("--query-service", metavar="<zone>")
parser_group_zone.add_argument("--add-port", metavar="<port>", action='append')
parser_group_zone.add_argument("--remove-port", metavar="<port>", action='append')
parser_group_zone.add_argument("--query-port", metavar="<port>")
parser_group_zone.add_argument("--add-masquerade", action="store_true")
parser_group_zone.add_argument("--remove-masquerade", action="store_true")
parser_group_zone.add_argument("--query-masquerade", action="store_true")
parser_group_zone.add_argument("--add-icmp-block", metavar="<icmptype>", action='append')
parser_group_zone.add_argument("--remove-icmp-block", metavar="<icmptype>", action='append')
parser_group_zone.add_argument("--query-icmp-block", metavar="<icmptype>")
parser_group_zone.add_argument("--add-forward-port", metavar="<port>", action='append')
parser_group_zone.add_argument("--remove-forward-port", metavar="<port>", action='append')
parser_group_zone.add_argument("--query-forward-port", metavar="<port>")
parser_group_zone.add_argument("--list-rich-rules", action="store_true")
parser_group_zone.add_argument("--list-services", action="store_true")
parser_group_zone.add_argument("--list-ports", action="store_true")
parser_group_zone.add_argument("--list-icmp-blocks", action="store_true")
parser_group_zone.add_argument("--list-forward-ports", action="store_true")
parser_group_zone.add_argument("--list-all", action="store_true")
parser_group_zone.add_argument("--get-target", action="store_true")
parser_group_zone.add_argument("--set-target", metavar="<target>")

parser.add_argument("--direct", action="store_true")

parser_direct = parser.add_mutually_exclusive_group()
parser_direct.add_argument("--passthrough", nargs=argparse.REMAINDER,
                    metavar=("{ ipv4 | ipv6 | eb }", "<args>"))
parser_direct.add_argument("--add-passthrough", nargs=argparse.REMAINDER,
                    metavar=("{ ipv4 | ipv6 | eb }", "<args>"))
parser_direct.add_argument("--remove-passthrough", nargs=argparse.REMAINDER,
                    metavar=("{ ipv4 | ipv6 | eb }", "<args>"))
parser_direct.add_argument("--query-passthrough", nargs=argparse.REMAINDER,
                    metavar=("{ ipv4 | ipv6 | eb }", "<args>"))
parser_direct.add_argument("--get-passthroughs", nargs=1,
                    metavar=("{ ipv4 | ipv6 | eb }"))
parser_direct.add_argument("--get-all-passthroughs", action="store_true")
parser_direct.add_argument("--add-chain", nargs=3,
                    metavar=("{ ipv4 | ipv6 | eb }", "<table>", "<chain>"))
parser_direct.add_argument("--remove-chain", nargs=3,
                        metavar=("{ ipv4 | ipv6 | eb }", "<table>", "<chain>"))
parser_direct.add_argument("--query-chain", nargs=3,
                        metavar=("{ ipv4 | ipv6 | eb }", "<table>", "<chain>"))
parser_direct.add_argument("--get-all-chains", action="store_true")
parser_direct.add_argument("--get-chains", nargs=2,
                        metavar=("{ ipv4 | ipv6 | eb }", "<table>"))
parser_direct.add_argument("--add-rule", nargs=argparse.REMAINDER,
                        metavar=("{ ipv4 | ipv6 | eb }", "<table> <chain> <priority> <args>"))
parser_direct.add_argument("--remove-rule", nargs=argparse.REMAINDER,
                        metavar=("{ ipv4 | ipv6 | eb }", "<table> <chain> <priority> <args>"))
parser_direct.add_argument("--remove-rules", nargs=3,
                        metavar=("{ ipv4 | ipv6 | eb }", "<table> <chain>"))
parser_direct.add_argument("--query-rule", nargs=argparse.REMAINDER,
                        metavar=("{ ipv4 | ipv6 | eb }", "<table> <chain> <priority> <args>"))
parser_direct.add_argument("--get-rules", nargs=3,
                        metavar=("{ ipv4 | ipv6 | eb }", "<table>", "<chain>"))
parser_direct.add_argument("--get-all-rules", action="store_true")

i = -1
args = sys.argv[1:]
if '--passthrough' in args:
  i = args.index('--passthrough') + 1
elif '--add-passthrough' in args:
  i = args.index('--add-passthrough') + 1
elif '--remove-passthrough' in args:
  i = args.index('--remove-passthrough') + 1
elif '--query-passthrough' in args:
  i = args.index('--query-passthrough') + 1
elif '--add-rule' in args:
  i = args.index('--add-rule') + 4
elif '--remove-rule' in args:
  i = args.index('--remove-rule') + 4
elif '--query-rule' in args:
  i = args.index('--query-rule') + 4
# join <args> into one argument to prevent parser from parsing each iptables
# option, because they can conflict with firewall-cmd options
# # e.g. --delete (iptables) and --delete-* (firewall-cmd)
if (i > -1) and (i < len(args) - 1):
    aux_args = args[:]
    args = aux_args[:i+1] # all but not <args>
    args.append(joinArgs(aux_args[i+1:])) # add <args> as one arg

a = parser.parse_args(args)


options_standalone = a.help or a.version or \
    a.state or a.reload or a.complete_reload or a.runtime_to_permanent or \
    a.panic_on or a.panic_off or a.query_panic or \
    a.lockdown_on or a.lockdown_off or a.query_lockdown or \
    a.get_default_zone or a.set_default_zone or \
    a.get_active_zones

options_lockdown_whitelist = \
    a.list_lockdown_whitelist_commands or a.add_lockdown_whitelist_command or \
    a.remove_lockdown_whitelist_command or \
    a.query_lockdown_whitelist_command or \
    a.list_lockdown_whitelist_contexts or a.add_lockdown_whitelist_context or \
    a.remove_lockdown_whitelist_context or \
    a.query_lockdown_whitelist_context or \
    a.list_lockdown_whitelist_uids or a.add_lockdown_whitelist_uid != None or \
    a.remove_lockdown_whitelist_uid != None or \
    a.query_lockdown_whitelist_uid != None or \
    a.list_lockdown_whitelist_users or a.add_lockdown_whitelist_user or \
    a.remove_lockdown_whitelist_user or \
    a.query_lockdown_whitelist_user

options_config = a.get_zones or a.get_services or a.get_icmptypes or \
                 options_lockdown_whitelist or a.list_all_zones or \
                 a.get_zone_of_interface or a.get_zone_of_source

options_zone_action_action = \
    a.add_service or a.remove_service or a.query_service or \
    a.add_port or a.remove_port or a.query_port or \
    a.add_icmp_block or a.remove_icmp_block or a.query_icmp_block or \
    a.add_forward_port or a.remove_forward_port or a.query_forward_port

options_zone_interfaces_sources = \
    a.list_interfaces or a.change_interface or \
    a.add_interface or a.remove_interface or a.query_interface or \
    a.list_sources or a.change_source or \
    a.add_source or a.remove_source or a.query_source

options_zone_adapt_query = \
    a.add_rich_rule or a.remove_rich_rule or a.query_rich_rule or \
    a.add_masquerade or a.remove_masquerade or a.query_masquerade or \
    a.list_services or a.list_ports or a.list_icmp_blocks or \
    a.list_forward_ports or a.list_rich_rules or a.list_all or \
    a.get_target or a.set_target

options_zone_ops = options_zone_interfaces_sources or \
               options_zone_action_action or options_zone_adapt_query

options_zone = a.zone or a.timeout != "0" or options_zone_ops

options_permanent = a.permanent or options_config or a.zone or options_zone_ops

options_permanent_only = a.new_icmptype or a.delete_icmptype or \
                         a.new_service or a.delete_service or \
                         a.new_zone or a.delete_zone

options_direct = a.passthrough or \
           a.add_chain or a.remove_chain or a.query_chain or \
           a.get_chains or a.get_all_chains or \
           a.add_rule or a.remove_rule or a.remove_rules or a.query_rule or \
           a.get_rules or a.get_all_rules or \
           a.add_passthrough or a.remove_passthrough or a.query_passthrough or \
           a.get_passthroughs or a.get_all_passthroughs

options_require_permanent = options_permanent_only \
                            or a.get_target or a.set_target

# these are supposed to only write out some output
options_list_get = a.help or a.version or a.list_all or a.list_all_zones or \
 a.list_lockdown_whitelist_commands or a.list_lockdown_whitelist_contexts or \
 a.list_lockdown_whitelist_uids or a.list_lockdown_whitelist_users or \
 a.list_services or a.list_ports or a.list_icmp_blocks or a.list_forward_ports \
 or a.list_rich_rules or a.list_interfaces or a.list_sources or \
 a.get_default_zone or a.get_active_zones or a.get_zone_of_interface or \
 a.get_zone_of_source or a.get_zones or a.get_services or a.get_icmptypes or \
 a.get_target

# Check various impossible combinations of options

if not (options_standalone or options_zone or \
        options_permanent or options_direct or \
        options_permanent_only):
    __fail(parser.format_usage() + "No option specified.")

if options_standalone and (options_zone or options_permanent or \
                           options_direct or options_permanent_only):
    __fail(parser.format_usage() +
           "Can't use stand-alone options with other options.")

if (options_direct or options_permanent_only) and (options_zone):
    __fail(parser.format_usage() +
           "Can't be used with --zone.")

if (a.direct and not options_direct) or \
        (options_direct and not a.direct):
    __fail(parser.format_usage() +
           "Wrong usage of 'direct' options.")

if options_permanent_only and not a.permanent:
    __fail(parser.format_usage() +
           "Option can be used only with --permanent.")

if options_require_permanent and not a.permanent:
    __fail(parser.format_usage() +
           "Option can be used only with --permanent.")

if options_config and options_zone:
    __fail(parser.format_usage() +
           "Wrong usage of --get-zones | --get-services | --get-icmptypes.")

if a.timeout != "0":
    value = 0
    unit = 's'
    if len(a.timeout) < 1:
        __fail(parser.format_usage() +
               "'%s' is wrong timeout value. Use for example '2m' or '1h'" % a.timeout)
    elif len(a.timeout) == 1:
        if a.timeout.isdigit():
            value = int (a.timeout[0])
        else:
            __fail(parser.format_usage() +
               "'%s' is wrong timeout value. Use for example '2m' or '1h'" % a.timeout)
    elif len(a.timeout) > 1:
        if a.timeout.isdigit():
            value = int(a.timeout)
            unit = 's'
        else:
            if a.timeout[:-1].isdigit():
                value = int (a.timeout[:-1])
            else:
                __fail(parser.format_usage() +
                   "'%s' is wrong timeout value. Use for example '2m' or '1h'" % a.timeout)
            unit = a.timeout[-1:].lower()
    if unit == 's':
        a.timeout = value
    elif unit == 'm':
        a.timeout = value * 60
    elif unit == 'h':
        a.timeout = value * 60 * 60
    else:
        __fail(parser.format_usage() +
               "'%s' is wrong timeout value. Use for example '2m' or '1h'" % a.timeout)
else:
    a.timeout = 0

if a.timeout and not (a.add_service or a.add_port or a.add_icmp_block or \
                      a.add_forward_port or a.add_masquerade or \
                      a.add_rich_rule):
    __fail(parser.format_usage() + "Wrong --timeout usage")

if a.permanent:
    if a.timeout:
        __fail(parser.format_usage() +
               "Can't specify timeout for permanent action.")
    if options_config and not a.zone:
        pass
    elif options_permanent:
        pass
    else:
        __fail(parser.format_usage() + "Wrong --permanent usage.")

if a.quiet and options_list_get:
    # it makes no sense to use --quiet with these options
    a.quiet = False
    __fail("-q/--quiet can't be used with this option(s)")

if a.help:
    __usage()
    sys.exit(0)

zone = a.zone
fw = FirewallClient()
fw.setExceptionHandler(__exception_handler)
if fw.connected == False:
    if a.state:
        __print_and_exit ("not running", NOT_RUNNING)
    else:
        __print_and_exit ("FirewallD is not running", NOT_RUNNING)

if options_zone_ops and not zone:
    default = fw.getDefaultZone()
    __print_if_verbose("No zone specified, using default zone, i.e. '%s'" % default)
    active = list(fw.getActiveZones().keys())
    if active and default not in active:
        __print ("""You're performing an operation over default zone ('%s'),
but your connections/interfaces are in zone '%s' (see --get-active-zones)
You most likely need to use --zone=%s option.\n""" % (default, ",".join(active), active[0]))

if a.permanent:
    if a.get_zones:
        zones = fw.config().listZones()
        l = [fw.config().getZone(z).get_property("name") for z in zones]
        __print_and_exit(" ".join(sorted(l)))
    elif a.get_services:
        services = fw.config().listServices()
        l = [fw.config().getService(s).get_property("name") for s in services]
        __print_and_exit(" ".join(sorted(l)))
    elif a.get_icmptypes:
        icmptypes = fw.config().listIcmpTypes()
        l = [fw.config().getIcmpType(i).get_property("name") for i in icmptypes]
        __print_and_exit(" ".join(sorted(l)))

    elif a.new_zone:
        config = fw.config()
        config.addZone(a.new_zone, FirewallClientZoneSettings())

    elif a.delete_zone:
        zone = fw.config().getZoneByName(a.delete_zone)
        zone.remove()

    elif a.new_service:
        config = fw.config()
        config.addService(a.new_service, FirewallClientServiceSettings())

    elif a.delete_service:
        service = fw.config().getServiceByName(a.delete_service)
        service.remove()

    elif a.new_icmptype:
        config = fw.config()
        config.addIcmpType(a.new_icmptype, FirewallClientIcmpTypeSettings())

    elif a.delete_icmptype:
        icmptype = fw.config().getIcmpTypeByName(a.delete_icmptype)
        icmptype.remove()

    # lockdown whitelist

    elif options_lockdown_whitelist:
        whitelist = fw.config().policies().getLockdownWhitelist()

        # commands
        if a.list_lockdown_whitelist_commands:
            l = whitelist.getCommands()
            __print_and_exit("\n".join(l))
        elif a.add_lockdown_whitelist_command:
            whitelist.addCommand(a.add_lockdown_whitelist_command)
        elif a.remove_lockdown_whitelist_command:
            whitelist.removeCommand(a.remove_lockdown_whitelist_command)
        elif a.query_lockdown_whitelist_command:
            __print_query_result(whitelist.queryCommand( \
                                 a.query_lockdown_whitelist_command))

        # contexts
        elif a.list_lockdown_whitelist_contexts:
            l = whitelist.getContexts()
            __print_and_exit("\n".join(l))
        elif a.add_lockdown_whitelist_context:
            whitelist.addContext(a.add_lockdown_whitelist_context)
        elif a.remove_lockdown_whitelist_context:
            whitelist.removeContext(a.remove_lockdown_whitelist_context)
        elif a.query_lockdown_whitelist_context:
            __print_query_result(whitelist.queryContext( \
                                 a.query_lockdown_whitelist_context))

        # uids
        elif a.list_lockdown_whitelist_uids:
            l = whitelist.getUids()
            __print_and_exit(" ".join(map(str, l)))
        elif a.add_lockdown_whitelist_uid != None:
            whitelist.addUid(a.add_lockdown_whitelist_uid)
        elif a.remove_lockdown_whitelist_uid != None:
            whitelist.removeUid(a.remove_lockdown_whitelist_uid)
        elif a.query_lockdown_whitelist_uid != None:
            __print_query_result(whitelist.queryUid( \
                                 a.query_lockdown_whitelist_uid))

        # users
        elif a.list_lockdown_whitelist_users:
            l = whitelist.getUsers()
            __print_and_exit("\n".join(l))
        elif a.add_lockdown_whitelist_user:
            whitelist.addUser(a.add_lockdown_whitelist_user)
        elif a.remove_lockdown_whitelist_user:
            whitelist.removeUser(a.remove_lockdown_whitelist_user)
        elif a.query_lockdown_whitelist_user:
            __print_query_result(whitelist.queryUser( \
                                 a.query_lockdown_whitelist_user))

        # apply whitelist changes
        fw.config().policies().setLockdownWhitelist(whitelist)

    elif options_direct:
        settings = fw.config().direct().getSettings()

        if a.passthrough:
            if len (a.passthrough) < 2:
                __fail("usage: --permanent --direct --passthrough { ipv4 | ipv6 | eb } <args>")
            __print(settings.addPassthrough(_check_ipv(a.passthrough[0]),
                                                       splitArgs(a.passthrough[1])))

        if a.add_passthrough:
            if len (a.add_passthrough) < 2:
                __fail("usage: --permanent --direct --add-passthrough { ipv4 | ipv6 | eb } <args>")
            __print(settings.addPassthrough(_check_ipv(a.add_passthrough[0]),
                                            splitArgs(a.add_passthrough[1])))

        elif a.remove_passthrough:
            if len (a.remove_passthrough) < 2:
                __fail("usage: --permanent --direct --remove-passthrough { ipv4 | ipv6 | eb } <args>")
            settings.removePassthrough(_check_ipv(a.remove_passthrough[0]),
                                       splitArgs(a.remove_passthrough[1]))
        elif a.query_passthrough:
            if len (a.query_passthrough) < 2:
                __fail("usage: --permanent --direct --query-passthrough { ipv4 | ipv6 | eb } <args>")
            __print_query_result(
                settings.queryPassthrough(_check_ipv(a.query_passthrough[0]),
                                          splitArgs(a.query_passthrough[1])))
            sys.exit(0)
        elif a.get_passthroughs:
            rules = settings.getPassthroughs(_check_ipv(a.get_passthroughs[0]))
            for rule in rules:
                __print(joinArgs(rule))
            sys.exit(0)
        elif a.get_all_passthroughs:
            for (ipv,rule) in settings.getAllPassthroughs():
                __print("%s %s" % (ipv, joinArgs(rule)))
            sys.exit(0)

        elif a.add_chain:
            settings.addChain(_check_ipv(a.add_chain[0]),
                              a.add_chain[1], a.add_chain[2])
        elif a.remove_chain:
            settings.removeChain(_check_ipv(a.remove_chain[0]),
                                 a.remove_chain[1], a.remove_chain[2])
        elif a.query_chain:
            __print_query_result(
                settings.queryChain(_check_ipv(a.query_chain[0]),
                                    a.query_chain[1], a.query_chain[2]))
            sys.exit(0)
        elif a.get_chains:
            __print_and_exit(
                    " ".join(settings.getChains(_check_ipv(a.get_chains[0]),
                                                           a.get_chains[1])))
            sys.exit(0)
        elif a.get_all_chains:
            chains = settings.getAllChains()
            for (ipv, table, chain) in chains:
                __print("%s %s %s" % (ipv, table, chain))
            sys.exit(0)
        elif a.add_rule:
            if len (a.add_rule) < 5:
                __fail("usage: --permanent --direct --add-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>")
            try:
                priority = int(a.add_rule[3])
            except ValueError:
                __fail("wrong priority\nusage: --permanent --direct --add-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>")
            settings.addRule(_check_ipv(a.add_rule[0]), a.add_rule[1],
                             a.add_rule[2], priority, splitArgs(a.add_rule[4]))
        elif a.remove_rule:
            if len (a.remove_rule) < 5:
                __fail("usage: --permanent --direct --remove-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>")
            try:
                priority = int(a.remove_rule[3])
            except ValueError:
                __fail("usage: --permanent --direct --remove-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>")
            settings.removeRule(_check_ipv(a.remove_rule[0]), a.remove_rule[1],
                                a.remove_rule[2], priority, splitArgs(a.remove_rule[4]))
        elif a.remove_rules:
            if len (a.remove_rules) < 3:
                __fail("usage: --permanent --direct --remove-rules { ipv4 | ipv6 | eb } <table> <chain>")
            settings.removeRules(_check_ipv(a.remove_rules[0]),
                                 a.remove_rules[1], a.remove_rules[2])
        elif a.query_rule:
            if len (a.query_rule) < 5:
                __fail("usage: --permanent --direct --query-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>")
            try:
                priority = int(a.query_rule[3])
            except ValueError:
                __fail("usage: --permanent --direct --query-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>")
            __print_query_result(
                    settings.queryRule(_check_ipv(a.query_rule[0]),
                                       a.query_rule[1], a.query_rule[2],
                                       priority, splitArgs(a.query_rule[4])))
            sys.exit(0)
        elif a.get_rules:
            rules = settings.getRules(_check_ipv(a.get_rules[0]),
                                      a.get_rules[1], a.get_rules[2])
            for (priority, rule) in rules:
                __print("%d %s" % (priority, joinArgs(rule)))
            sys.exit(0)
        elif a.get_all_rules:
            rules = settings.getAllRules()
            for (ipv, table, chain, priority, rule) in rules:
                __print("%s %s %s %d %s" % (ipv, table, chain, priority,
                                            joinArgs(rule)))
            sys.exit(0)

        fw.config().direct().update(settings)

    else:
        if zone == "":
            zone = fw.getDefaultZone()
        fw_zone = fw.config().getZoneByName(zone)
        fw_settings = fw_zone.getSettings()

        # interface
        if a.list_interfaces:
            l = fw_settings.getInterfaces()
            __print_and_exit(" ".join(l))
        elif a.get_zone_of_interface:
            zone = fw.config().getZoneOfInterface(a.get_zone_of_interface)
            if zone:
                __print_and_exit(zone)
            else:
                __print_and_exit("no zone", 2)
        elif a.change_interface:
            old_zone_name = fw.config().getZoneOfInterface(a.change_interface)
            if old_zone_name != zone:
                if old_zone_name:
                    old_zone_obj = fw.config().getZoneByName(old_zone_name)
                    old_zone_settings = old_zone_obj.getSettings()
                    old_zone_settings.removeInterface(a.change_interface) # remove from old
                    old_zone_obj.update(old_zone_settings)
                fw_settings.addInterface(a.change_interface)              # add to new
        elif a.add_interface:
            fw_settings.addInterface(a.add_interface)
        elif a.remove_interface:
            fw_settings.removeInterface(a.remove_interface)
        elif a.query_interface:
            __print_query_result(fw_settings.queryInterface(a.query_interface))

        # source
        if a.list_sources:
            sources = fw_settings.getSources()
            __print_and_exit(" ".join(sources))
        elif a.get_zone_of_source:
            zone = fw.config().getZoneOfSource(a.get_zone_of_source)
            if zone:
                __print_and_exit(zone)
            else:
                __print_and_exit("no zone", 2)
        elif a.change_source:
            old_zone_name = fw.config().getZoneOfSource(a.change_source)
            old_zone_obj = fw.config().getZoneByName(old_zone_name)
            old_zone_settings = old_zone_obj.getSettings()
            old_zone_settings.removeSource(a.change_source)  # remove from old
            old_zone_obj.update(old_zone_settings)
            fw_settings.addSource(a.change_source)           # add to new
        elif a.add_source:
            fw_settings.addSource(a.add_source)
        elif a.remove_source:
            fw_settings.removeSource(a.remove_source)
        elif a.query_source:
            __print_query_result(fw_settings.querySource(a.query_source))

        # rich rules
        if a.list_rich_rules:
            l = fw_settings.getRichRules()
            __print_and_exit("\n".join(l))
        elif a.add_rich_rule:
            for s in a.add_rich_rule:
                fw_settings.addRichRule(s)
        elif a.remove_rich_rule:
            for s in a.remove_rich_rule:
                fw_settings.removeRichRule(s)
        elif a.query_rich_rule:
            __print_query_result(fw_settings.queryRichRule(a.query_rich_rule))

        # service
        if a.list_services:
            l = fw_settings.getServices()
            __print_and_exit(" ".join(l))
        elif a.add_service:
            for s in a.add_service:
                fw_settings.addService(s)
        elif a.remove_service:
            for s in a.remove_service:
                fw_settings.removeService(s)
        elif a.query_service:
            __print_query_result(fw_settings.queryService(a.query_service))

        # port
        elif a.list_ports:
            l = fw_settings.getPorts()
            __print_and_exit(" ".join(["%s/%s" % (port[0], port[1]) for port in l]))
        elif a.add_port:
            for port_proto in a.add_port:
                (port, proto) = __parse_port(port_proto)
                fw_settings.addPort(port, proto)
        elif a.remove_port:
            for port_proto in a.remove_port:
                (port, proto) = __parse_port(port_proto)
                fw_settings.removePort(port, proto)
        elif a.query_port:
            (port, proto) = __parse_port(a.query_port)
            __print_query_result(fw_settings.queryPort(port, proto))

        # masquerade
        elif a.add_masquerade:
            fw_settings.setMasquerade(True)
        elif a.remove_masquerade:
            fw_settings.setMasquerade(False)
        elif a.query_masquerade:
            __print_query_result(fw_settings.getMasquerade())

        # forward port
        elif a.list_forward_ports:
            l = fw_settings.getForwardPorts()
            __print_and_exit("\n".join(["port=%s:proto=%s:toport=%s:toaddr=%s" % (port, protocol, toport, toaddr) for (port, protocol, toport, toaddr) in l]))
        elif a.add_forward_port:
            for fp in a.add_forward_port:
                (port, protocol, toport, toaddr) = __parse_forward_port(fp)
                fw_settings.addForwardPort(port, protocol, toport, toaddr)
        elif a.remove_forward_port:
            for fp in a.remove_forward_port:
                (port, protocol, toport, toaddr) = __parse_forward_port(fp)
                fw_settings.removeForwardPort(port, protocol, toport, toaddr)
        elif a.query_forward_port:
            (port, protocol, toport, toaddr) = __parse_forward_port(a.query_forward_port)
            __print_query_result(fw_settings.queryForwardPort(port, protocol, toport, toaddr))

        # block icmp
        elif a.list_icmp_blocks:
            l = fw_settings.getIcmpBlocks()
            __print_and_exit(" ".join(l))
        elif a.add_icmp_block:
            for ib in a.add_icmp_block:
                fw_settings.addIcmpBlock(ib)
        elif a.remove_icmp_block:
            for ib in a.remove_icmp_block:
                fw_settings.removeIcmpBlock(ib)
        elif a.query_icmp_block:
            __print_query_result(fw_settings.queryIcmpBlock(a.query_icmp_block))

        # zone target
        elif a.get_target:
            __print_and_exit(fw_settings.getTarget())
        elif a.set_target:
            fw_settings.setTarget(a.set_target)

        # list all zone settings
        elif a.list_all:
            __list_all_permanent(fw_settings, zone if zone else fw.getDefaultZone())
            sys.exit(0)

        # list everything
        elif a.list_all_zones:
            zones = fw.config().listZones()
            names = [fw.config().getZone(z).get_property("name") for z in zones]
            for zone in sorted(names):
                fw_zone = fw.config().getZoneByName(zone)
                fw_settings = fw_zone.getSettings()
                __list_all_permanent(fw_settings, zone)
                __print("")
            sys.exit(0)

        fw_zone.update(fw_settings)

elif a.version:
    __print_and_exit(fw.get_property("version"))
elif a.state:
    state = fw.get_property("state")
    if state == "RUNNING":
        __print_and_exit ("running")
    else:
        __print_and_exit ("not running", NOT_RUNNING)
elif a.reload:
    fw.reload()
elif a.complete_reload:
    fw.complete_reload()
elif a.runtime_to_permanent:
    fw.runtimeToPermanent()
elif a.direct:
    if a.passthrough:
        if len (a.passthrough) < 2:
            __fail("usage: --direct --passthrough { ipv4 | ipv6 | eb } <args>")
        msg = fw.passthrough(_check_ipv(a.passthrough[0]), splitArgs(a.passthrough[1]))
        if msg:
            print(msg)

    elif a.add_passthrough:
        if len (a.add_passthrough) < 2:
            __fail("usage: --direct --add-passthrough { ipv4 | ipv6 | eb } <args>")
        fw.addPassthrough(_check_ipv(a.add_passthrough[0]),
                          splitArgs(a.add_passthrough[1]))
    elif a.remove_passthrough:
        if len (a.remove_passthrough) < 2:
            __fail("usage: --direct --remove-passthrough { ipv4 | ipv6 | eb } <args>")
        fw.removePassthrough(_check_ipv(a.remove_passthrough[0]),
                             splitArgs(a.remove_passthrough[1]))
    elif a.query_passthrough:
        if len (a.query_passthrough) < 2:
            __fail("usage: --direct --query-passthrough { ipv4 | ipv6 | eb } <args>")
        __print_query_result(
            fw.queryPassthrough(_check_ipv(a.query_passthrough[0]),
                                splitArgs(a.query_passthrough[1])))
    elif a.get_passthroughs:
        rules = fw.getPassthroughs(_check_ipv(a.get_passthroughs[0]))
        for rule in rules:
            __print(joinArgs(rule))
        sys.exit(0)
    elif a.get_all_passthroughs:
        for (ipv,rule) in fw.getAllPassthroughs():
            __print("%s %s" % (ipv, joinArgs(rule)))
        sys.exit(0)
    elif a.add_chain:
        fw.addChain(_check_ipv(a.add_chain[0]), a.add_chain[1], a.add_chain[2])
    elif a.remove_chain:
        fw.removeChain(_check_ipv(a.remove_chain[0]),
                       a.remove_chain[1], a.remove_chain[2])
    elif a.query_chain:
        __print_query_result(fw.queryChain(_check_ipv(a.query_chain[0]),
                                           a.query_chain[1], a.query_chain[2]))
    elif a.get_chains:
        __print_and_exit(" ".join(fw.getChains(_check_ipv(a.get_chains[0]),
                                  a.get_chains[1])))
    elif a.get_all_chains:
        chains = fw.getAllChains()
        for (ipv, table, chain) in chains:
            __print("%s %s %s" % (ipv, table, chain))
        sys.exit(0)
    elif a.add_rule:
        if len (a.add_rule) < 5:
            __fail("usage: --direct --add-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>")
        try:
            priority = int(a.add_rule[3])
        except ValueError:
            __fail("wrong priority\nusage: --direct --add-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>")
        fw.addRule(_check_ipv(a.add_rule[0]), a.add_rule[1], a.add_rule[2],
                   priority, splitArgs(a.add_rule[4]))
    elif a.remove_rule:
        if len (a.remove_rule) < 5:
            __fail("usage: --direct --remove-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>")
        try:
            priority = int(a.remove_rule[3])
        except ValueError:
            __fail("usage: --direct --remove-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>")
        fw.removeRule(_check_ipv(a.remove_rule[0]),
                      a.remove_rule[1], a.remove_rule[2], priority, splitArgs(a.remove_rule[4]))
    elif a.remove_rules:
        if len (a.remove_rules) < 3:
            __fail("usage: --direct --remove-rules { ipv4 | ipv6 | eb } <table> <chain>")
        fw.removeRules(_check_ipv(a.remove_rules[0]),
                       a.remove_rules[1], a.remove_rules[2])
    elif a.query_rule:
        if len (a.query_rule) < 5:
            __fail("usage: --direct --query-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>")
        try:
            priority = int(a.query_rule[3])
        except ValueError:
            __fail("usage: --direct --query-rule { ipv4 | ipv6 | eb } <table> <chain> <priority> <args>")
        __print_query_result(fw.queryRule(_check_ipv(a.query_rule[0]),
                                          a.query_rule[1], a.query_rule[2], priority, splitArgs(a.query_rule[4])))
    elif a.get_rules:
        rules = fw.getRules(_check_ipv(a.get_rules[0]),
                            a.get_rules[1], a.get_rules[2])
        for (priority, rule) in rules:
            __print("%d %s" % (priority, joinArgs(rule)))
        sys.exit(0)
    elif a.get_all_rules:
        rules = fw.getAllRules()
        for (ipv, table, chain, priority, rule) in rules:
            __print("%s %s %s %d %s" % (ipv, table, chain, priority,
                                        joinArgs(rule)))
        sys.exit(0)

elif a.get_default_zone:
    __print_and_exit(fw.getDefaultZone())
elif a.set_default_zone:
    fw.setDefaultZone(a.set_default_zone)
elif a.get_zones:
    __print_and_exit(" ".join(fw.getZones()))
elif a.get_active_zones:
    zones = fw.getActiveZones()
    for zone in zones:
        __print("%s" % (zone))
        for x in [ "interfaces", "sources" ]:
            if x in zones[zone]:
                __print("  %s: %s" % (x, " ".join(zones[zone][x])))
    sys.exit(0)
elif a.get_services:
    l = fw.listServices()
    __print_and_exit(" ".join(l))
elif a.get_icmptypes:
    l = fw.listIcmpTypes()
    __print_and_exit(" ".join(l))

# panic
elif a.panic_on:
    fw.enablePanicMode()
elif a.panic_off:
    fw.disablePanicMode()
elif a.query_panic:
    __print_query_result(fw.queryPanicMode())

# lockdown
elif a.lockdown_on:
    fw.config().set_property("Lockdown", "yes")   # permanent
    fw.enableLockdown()                           # runtime
elif a.lockdown_off:
    fw.config().set_property("Lockdown", "no")    # permanent
    fw.disableLockdown()                          # runtime
elif a.query_lockdown:
    __print_query_result(fw.queryLockdown())      # runtime
    #lockdown = fw.config().get_property("Lockdown")
    #__print_query_result(lockdown.lower() in [ "yes", "true" ])

# lockdown whitelist

# commands
elif a.list_lockdown_whitelist_commands:
    l = fw.getLockdownWhitelistCommands()
    __print_and_exit("\n".join(l))
elif a.add_lockdown_whitelist_command:
    fw.addLockdownWhitelistCommand(a.add_lockdown_whitelist_command)
elif a.remove_lockdown_whitelist_command:
    fw.removeLockdownWhitelistCommand(a.remove_lockdown_whitelist_command)
elif a.query_lockdown_whitelist_command:
    __print_query_result(fw.queryLockdownWhitelistCommand( \
                         a.query_lockdown_whitelist_command))

# contexts
elif a.list_lockdown_whitelist_contexts:
    l = fw.getLockdownWhitelistContexts()
    __print_and_exit("\n".join(l))
elif a.add_lockdown_whitelist_context:
    fw.addLockdownWhitelistContext(a.add_lockdown_whitelist_context)
elif a.remove_lockdown_whitelist_context:
    fw.removeLockdownWhitelistContext(a.remove_lockdown_whitelist_context)
elif a.query_lockdown_whitelist_context:
    __print_query_result(fw.queryLockdownWhitelistContext( \
                         a.query_lockdown_whitelist_context))

# uids
elif a.list_lockdown_whitelist_uids:
    l = fw.getLockdownWhitelistUids()
    __print_and_exit(" ".join(map(str, l)))
elif a.add_lockdown_whitelist_uid != None:
    fw.addLockdownWhitelistUid(a.add_lockdown_whitelist_uid)
elif a.remove_lockdown_whitelist_uid != None:
    fw.removeLockdownWhitelistUid(a.remove_lockdown_whitelist_uid)
elif a.query_lockdown_whitelist_uid != None:
    __print_query_result(fw.queryLockdownWhitelistUid( \
                         a.query_lockdown_whitelist_uid))

# users
elif a.list_lockdown_whitelist_users:
    l = fw.getLockdownWhitelistUsers()
    __print_and_exit(" ".join(l))
elif a.add_lockdown_whitelist_user:
    fw.addLockdownWhitelistUser(a.add_lockdown_whitelist_user)
elif a.remove_lockdown_whitelist_user:
    fw.removeLockdownWhitelistUser(a.remove_lockdown_whitelist_user)
elif a.query_lockdown_whitelist_user:
    __print_query_result(fw.queryLockdownWhitelistUser( \
                         a.query_lockdown_whitelist_user))

# interface
elif a.list_interfaces:
    l = fw.getInterfaces(zone)
    __print_and_exit(" ".join(l))
elif a.get_zone_of_interface:
    zone = fw.getZoneOfInterface(a.get_zone_of_interface)
    if zone:
        __print_and_exit(zone)
    else:
        __print_and_exit("no zone", 2)
elif a.add_interface:
    fw.addInterface(zone, a.add_interface)
elif a.change_interface:
    fw.changeZoneOfInterface(zone, a.change_interface)
elif a.remove_interface:
    fw.removeInterface(zone, a.remove_interface)
elif a.query_interface:
    __print_query_result(fw.queryInterface(zone, a.query_interface))

# source
elif a.list_sources:
    sources = fw.getSources(zone)
    __print_and_exit(" ".join(sources))
elif a.get_zone_of_source:
    zone = fw.getZoneOfSource(a.get_zone_of_source)
    if zone:
        __print_and_exit(zone)
    else:
        __print_and_exit("no zone", 2)
elif a.add_source:
    fw.addSource(zone, a.add_source)
elif a.change_source:
    fw.changeZoneOfSource(zone, a.change_source)
elif a.remove_source:
    fw.removeSource(zone, a.remove_source)
elif a.query_source:
    __print_query_result(fw.querySource(zone, a.query_source))

# rich rules
elif a.list_rich_rules:
    l = fw.getRichRules(zone)
    __print_and_exit("\n".join(l))
elif a.add_rich_rule:
    for s in a.add_rich_rule:
        fw.addRichRule(zone, s, a.timeout)
elif a.remove_rich_rule:
    for s in a.remove_rich_rule:
        fw.removeRichRule(zone, s)
elif a.query_rich_rule:
    __print_query_result(fw.queryRichRule(zone, a.query_rich_rule))

# service
elif a.list_services:
    l = fw.getServices(zone)
    __print_and_exit(" ".join(l))
elif a.add_service:
    for s in a.add_service:
        fw.addService(zone, s, a.timeout)
elif a.remove_service:
    for s in a.remove_service:
        fw.removeService(zone, s)
elif a.query_service:
    __print_query_result(fw.queryService(zone, a.query_service))

# port
elif a.list_ports:
    l = fw.getPorts(zone)
    __print_and_exit(" ".join(["%s/%s" % (port[0], port[1]) for port in l]))
elif a.add_port:
    for port_proto in a.add_port:
        (port, proto) = __parse_port(port_proto)
        fw.addPort(zone, port, proto, a.timeout)
elif a.remove_port:
    for port_proto in a.remove_port:
        (port, proto) = __parse_port(port_proto)
        fw.removePort(zone, port, proto)
elif a.query_port:
    (port, proto) = __parse_port(a.query_port)
    __print_query_result(fw.queryPort(zone, port, proto))

# masquerade
elif a.add_masquerade:
    fw.addMasquerade(zone, a.timeout)
elif a.remove_masquerade:
    fw.removeMasquerade(zone)
elif a.query_masquerade:
    __print_query_result(fw.queryMasquerade(zone))

# forward port
elif a.list_forward_ports:
    l = fw.getForwardPorts(zone)
    __print_and_exit("\n".join(["port=%s:proto=%s:toport=%s:toaddr=%s" % (port, protocol, toport, toaddr) for (port, protocol, toport, toaddr) in l]))
elif a.add_forward_port:
    for fp in a.add_forward_port:
        (port, protocol, toport, toaddr) = __parse_forward_port(fp)
        fw.addForwardPort(zone, port, protocol, toport, toaddr, a.timeout)
elif a.remove_forward_port:
    for fp in a.remove_forward_port:
        (port, protocol, toport, toaddr) = __parse_forward_port(fp)
        fw.removeForwardPort(zone, port, protocol, toport, toaddr)
elif a.query_forward_port:
    (port, protocol, toport, toaddr) = __parse_forward_port(a.query_forward_port)
    __print_query_result(fw.queryForwardPort(zone, port, protocol, toport, toaddr))

# block icmp
elif a.list_icmp_blocks:
    l = fw.getIcmpBlocks(zone)
    __print_and_exit(" ".join(l))
elif a.add_icmp_block:
    for ib in a.add_icmp_block:
        fw.addIcmpBlock(zone, ib, a.timeout)
elif a.remove_icmp_block:
    for ib in a.remove_icmp_block:
        fw.removeIcmpBlock(zone, ib)
elif a.query_icmp_block:
    __print_query_result(fw.queryIcmpBlock(zone, a.query_icmp_block))

# zone target
elif a.get_target:
    __print_and_exit(fw.getZoneSettings(zone).getTarget())

# list all
elif a.list_all:
    __list_all(fw, zone if zone else fw.getDefaultZone())
    sys.exit(0)

# list everything
elif a.list_all_zones:
    for zone in fw.getZones():
        __list_all(fw, zone)
        __print("")
    sys.exit(0)

__print_and_exit("success")