def rule(cmd, a, &block)
      # Evaluate a block expression and return early if it evaluates to false.
      # If no block is passed it is equivalent to the block: { true }.
      return self if block_given? && !instance_eval(&block)

      raise ArgumentError, 'chain is a required argument' unless a[:chain]
      assert_valid_ipaddr(a[:src]) if a[:src]
      assert_valid_ipaddr(a[:dst]) if a[:dst]

      # Map of commands for rules
      cmds = {
        add: '-A', delete: '-D', insert: '-I', replace: '-R',
        check: '-C'
      }

      a[:proto] ||= 'tcp'
      table = build_option('-t', @table)
      jump = build_option('-j', a[:jump])
      goto = build_option('-g', a[:goto])
      proto = build_option('-p', a[:proto])
      inface = build_option('-i', a[:in])
      outface = build_option('-o', a[:out])
      src = build_option('-s', a[:src])
      dst = build_option('-d', a[:dst])
      match = build_option('-m', a[:match] || @match)
      ports = build_option('--dport', @ports)
      to_port = build_option('--to-port', a[:to_port])
      @buffer << [
        'iptables', table, cmds[cmd], a[:chain], src, dst, outface,
        inface, proto, match, ports, jump || goto, to_port
      ].compact.join(' ') << "\n"
      self
    end
def rule(cmd, a, &block)
      # Evaluate a block expression and return early if it evaluates to false.
      # If no block is passed it is equivalent to the block: { true }.
      return self if block_given? && !instance_eval(&block)

      raise ArgumentError, 'chain is a required argument' unless a[:chain]
      assert_valid_ipaddr(a[:src]) if a[:src]
      assert_valid_ipaddr(a[:dst]) if a[:dst]

      # Map of commands for rules
      cmds = {
        add: '-A', delete: '-D', insert: '-I', replace: '-R',
        check: '-C'
      }

      a[:proto] ||= 'tcp'
      table = build_option('-t', @table)
      jump = build_option('-j', a[:jump])
      goto = build_option('-g', a[:goto])
      proto = build_option('-p', a[:proto])
      inface = build_option('-i', a[:in])
      outface = build_option('-o', a[:out])
      src = build_option('-s', a[:src])
      dst = build_option('-d', a[:dst])
      match = build_option('-m', a[:match] || @match)
      ports = build_option('--dport', @ports)
      to_port = build_option('--to-port', a[:to_port])
      @buffer << [
        'iptables', table, cmds[cmd], a[:chain], src, dst, outface,
        inface, proto, match, ports, jump || goto, to_port
      ].compact.join(' ') << "\n"
      self
    end
Create, flush and delete chains
 @param [String] cmd the operation to perform (add, delete, insert, etc.)
 @param [String] chain name of the chain (e.g. INPUT, CATFLAP-DENY, etc.)
 @return self