]> Kevux Git Server - fll/commitdiff
Feature: add support for ipv6 firewall via new 'tool' option
authorKevin Day <kevin@kevux.org>
Sun, 10 Jun 2012 18:24:18 +0000 (13:24 -0500)
committerKevin Day <kevin@kevux.org>
Sun, 10 Jun 2012 18:24:18 +0000 (13:24 -0500)
This adds the 'tool' option that can assign one of the following values:
- iptables
- ip6tables
- ip46tables

This adds support for ipv6 firewalling.
The default firewall rules enables iptables and ip6tables via the option called ip46tables.

Also, future versions will include support for the tool 'ipset'.

level_3/firewall/c/firewall.c
level_3/firewall/c/firewall.h
level_3/firewall/c/private-firewall.c
level_3/firewall/data/settings/example-device-firewall
level_3/firewall/data/settings/firewall-first
level_3/firewall/data/settings/firewall-last
level_3/firewall/data/settings/firewall-other

index 7e5bbf9833b8cc75691fb62874cc96e0dec55578..0ecbc8c1ac39d21994051c2ac4a68b3dfc47f3d5 100644 (file)
@@ -260,7 +260,7 @@ extern "C"{
 
             arguments.used = 7;
 
-            arguments.array[0].string = (f_string) firewall_program_name;
+            arguments.array[0].string = (f_string) firewall_tool_iptables;
             arguments.array[1].string = (f_string) "-x";
             arguments.array[2].string = (f_string) "-v";
             arguments.array[3].string = (f_string) "-t";
@@ -268,7 +268,7 @@ extern "C"{
             arguments.array[5].string = (f_string) "--numeric";
             arguments.array[6].string = (f_string) "--list";
 
-            arguments.array[0].used = firewall_program_name_length;
+            arguments.array[0].used = firewall_tool_iptables_length;
             arguments.array[1].used = 2;
             arguments.array[2].used = 2;
             arguments.array[3].used = 2;
@@ -276,7 +276,7 @@ extern "C"{
             arguments.array[5].used = 9;
             arguments.array[6].used = 6;
 
-            status = fll_execute_program((f_string) firewall_program_name, arguments, &results);
+            status = fll_execute_program((f_string) firewall_tool_iptables, arguments, &results);
 
             fprintf(f_standard_output, "\n");
             fflush(f_standard_output);
@@ -290,7 +290,7 @@ extern "C"{
 
             arguments.used = 7;
 
-            arguments.array[0].string = (f_string) firewall_program_name;
+            arguments.array[0].string = (f_string) firewall_tool_iptables;
             arguments.array[1].string = (f_string) "-x";
             arguments.array[2].string = (f_string) "-v";
             arguments.array[3].string = (f_string) "-t";
@@ -298,7 +298,7 @@ extern "C"{
             arguments.array[5].string = (f_string) "--numeric";
             arguments.array[6].string = (f_string) "--list";
 
-            arguments.array[0].used = firewall_program_name_length;
+            arguments.array[0].used = firewall_tool_iptables_length;
             arguments.array[1].used = 2;
             arguments.array[2].used = 2;
             arguments.array[3].used = 2;
@@ -306,7 +306,7 @@ extern "C"{
             arguments.array[5].used = 9;
             arguments.array[6].used = 6;
 
-            status = fll_execute_program((f_string) firewall_program_name, arguments, &results);
+            status = fll_execute_program((f_string) firewall_tool_iptables, arguments, &results);
 
             fprintf(f_standard_output, "\n");
             fflush(f_standard_output);
@@ -320,19 +320,19 @@ extern "C"{
 
             arguments.used = 5;
 
-            arguments.array[0].string = (f_string) firewall_program_name;
+            arguments.array[0].string = (f_string) firewall_tool_iptables;
             arguments.array[1].string = (f_string) "-x";
             arguments.array[2].string = (f_string) "-v";
             arguments.array[3].string = (f_string) "--numeric";
             arguments.array[4].string = (f_string) "--list";
 
-            arguments.array[0].used = firewall_program_name_length;
+            arguments.array[0].used = firewall_tool_iptables_length;
             arguments.array[1].used = 2;
             arguments.array[2].used = 2;
             arguments.array[3].used = 9;
             arguments.array[4].used = 6;
 
-            status = fll_execute_program((f_string) firewall_program_name, arguments, &results);
+            status = fll_execute_program((f_string) firewall_tool_iptables, arguments, &results);
 
             fprintf(f_standard_output, "\n");
             fflush(f_standard_output);
@@ -344,7 +344,7 @@ extern "C"{
             if (f_macro_test_for_allocation_errors(status)) {
               fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory");
             } else {
-              fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Failed to perform requested %s operation:", firewall_program_name);
+              fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Failed to perform requested %s operation:", firewall_tool_iptables);
               fprintf(f_standard_error, "  ");
 
               f_string_length i = 0;
index 30cb26e6ba455a1715c948e6fb98ef0a1d09df85..2064fa6fc95f8eadd9900325a9499341f648f713 100644 (file)
@@ -61,7 +61,6 @@ extern "C"{
   #define firewall_file_last    "firewall-last"
   #define firewall_file_other   "firewall-other"
   #define firewall_file_suffix  "-firewall"
-  #define firewall_program_name "iptables"
 
   #define network_path_length          13
   #define network_devices_length       15
@@ -69,7 +68,6 @@ extern "C"{
   #define firewall_file_last_length    13
   #define firewall_file_other_length   14
   #define firewall_file_suffix_length  9
-  #define firewall_program_name_length 8
 #endif // _di_firewall_paths_
 
 #ifndef _di_firewall_default_allocation_step_
@@ -77,6 +75,18 @@ extern "C"{
 #endif // _di_firewall_default_allocation_step_
 
 #ifndef _di_firewall_defines_
+  #define firewall_tool            "tool"
+  #define firewall_tool_iptables   "iptables"
+  #define firewall_tool_ip6tables  "ip6tables"
+  #define firewall_tool_ip46tables "ip46tables"
+  #define firewall_tool_ipset      "ipset"
+
+  #define firewall_tool_length            4
+  #define firewall_tool_iptables_length   8
+  #define firewall_tool_ip6tables_length  9
+  #define firewall_tool_ip46tables_length 10
+  #define firewall_tool_ipset_length      5
+
   #define firewall_group_stop "stop"
   #define firewall_group_lock "lock"
   #define firewall_group_main "main"
@@ -206,6 +216,13 @@ extern "C"{
   #define firewall_chain_create_command_length 2
   #define firewall_chain_unchain_command_length 2
 
+  enum {
+    firewall_program_none,
+    firewall_program_iptables,
+    firewall_program_ip6tables,
+    firewall_program_ip46tables,
+    firewall_program_ipset,
+  };
 
   enum {
     firewall_parameter_help,
index 24bf28d7299f0ac9bb8340def7d41ac5907997a8..d142ef5e97d7747801d92887dda1f3945ddfcf95 100644 (file)
     f_bool device_all = f_false;
     f_bool ip_list_direction = f_false; // false = source, true = destination
     f_bool use_protocol = f_false;
+    uint8_t tool = firewall_program_ip46tables;
+
+    f_array_length repeat = 2;
+    f_array_length r = 0;
+
+    f_string current_tool = firewall_tool_iptables;
+    f_string_length current_tool_length = firewall_tool_iptables_length;
 
     f_string_length direction = firewall_direction_none_id;
     f_dynamic_string device = f_dynamic_string_initialize;
 
           continue;
         }
+      } else if (length >= firewall_tool_length && fl_compare_strings(local.buffer.string + local.rule_objects.array[i].start, (f_string) firewall_tool, length, firewall_tool_length) == f_equal_to) {
+        length = (local.rule_contents.array[i].array[0].stop - local.rule_contents.array[i].array[0].start) + 1;
+
+        if (local.rule_contents.array[i].used <= 0 || local.rule_contents.array[i].used > 1) {
+          invalid = f_true;
+        } else {
+          if (fl_compare_strings(local.buffer.string + local.rule_contents.array[i].array[0].start, (f_string) firewall_tool_iptables, length, firewall_tool_iptables_length) == f_equal_to) {
+            tool = firewall_program_iptables;
+            current_tool = firewall_tool_iptables;
+            current_tool_length = firewall_tool_iptables_length;
+            repeat = 1;
+          } else if (fl_compare_strings(local.buffer.string + local.rule_contents.array[i].array[0].start, (f_string) firewall_tool_ip6tables, length, firewall_tool_ip6tables_length) == f_equal_to) {
+            tool = firewall_program_ip6tables;
+            current_tool = firewall_tool_ip6tables;
+            current_tool_length = firewall_tool_ip6tables_length;
+            repeat = 1;
+          } else if (fl_compare_strings(local.buffer.string + local.rule_contents.array[i].array[0].start, (f_string) firewall_tool_ip46tables, length, firewall_tool_ip46tables_length) == f_equal_to) {
+            tool = firewall_program_ip46tables;
+            current_tool = firewall_tool_iptables;
+            current_tool_length = firewall_tool_iptables_length;
+            repeat = 2;
+          } else {
+            invalid = f_true;
+          }
+
+          if (!invalid) continue;
+        }
       } else if (length < firewall_rule_length || fl_compare_strings(local.buffer.string + local.rule_objects.array[i].start, (f_string) firewall_rule, length, firewall_rule_length) == f_not_equal_to) {
         if (length > 0) {
           fl_print_color_code(f_standard_warning, data.context.warning);
         continue;
       }
 
-      // first add the program name
-      f_delete_dynamic_strings(status, arguments);
-      f_resize_dynamic_strings(status, arguments, arguments.used + 1);
-
-      if (f_error_is_error(status)) break;
-
-      f_resize_dynamic_string(status, argument, firewall_program_name_length);
-
-      if (f_error_is_error(status)) break;
-
-      strncat(argument.string, firewall_program_name, firewall_program_name_length);
-      argument.used = firewall_program_name_length;
-
-      arguments.array[arguments.used].string = argument.string;
-      arguments.array[arguments.used].size   = argument.size;
-      arguments.array[arguments.used].used   = argument.used;
-      arguments.used++;
-      argument.string = f_null;
-      argument.size   = 0;
-      argument.used   = 0;
-
-
-      // FIXME: (this issue is probably everywhere) Implement an strncat function for dynamic strings or if I already have one implement, make sure it is used in every applicable place
-      //        (this way I can automatically handle updating the used buffer)
-      //        also look into auto-allocated space if necessary with the said function
-      if (action == firewall_action_append_id) {
-        f_resize_dynamic_string(status, argument, firewall_action_append_command_length);
+      for (r = repeat; r > 0; r--) {
+        // first add the program name
+        f_delete_dynamic_strings(status, arguments);
+        f_resize_dynamic_strings(status, arguments, arguments.used + 1);
 
         if (f_error_is_error(status)) break;
 
-        strncat(argument.string, firewall_action_append_command, firewall_action_append_command_length);
-        argument.used = firewall_action_append_command_length;
-      } else if (action == firewall_action_insert_id) {
-        f_resize_dynamic_string(status, argument, firewall_action_insert_command_length);
-
-        if (f_error_is_error(status)) break;
+        if (tool == firewall_program_ip46tables) {
+          if (r == 2) {
+            current_tool = firewall_tool_iptables;
+            current_tool_length = firewall_tool_iptables_length;
+          } else {
+            current_tool = firewall_tool_ip6tables;
+            current_tool_length = firewall_tool_ip6tables_length;
+          }
+        }
 
-        strncat(argument.string, firewall_action_insert_command, firewall_action_insert_command_length);
-        argument.used = firewall_action_insert_command_length;
-      } else if (action == firewall_action_policy_id) {
-        f_resize_dynamic_string(status, argument, firewall_action_policy_command_length);
+        f_resize_dynamic_string(status, argument, current_tool_length);
 
         if (f_error_is_error(status)) break;
 
-        strncat(argument.string, firewall_action_policy_command, firewall_action_policy_command_length);
-        argument.used = firewall_action_policy_command_length;
-      }
-
-      if (argument.used > 0) {
-        f_resize_dynamic_strings(status, arguments, arguments.used + 1);
-
-        if (f_error_is_error(status)) break;
+        strncat(argument.string, current_tool, current_tool_length);
+        argument.used = current_tool_length;
 
         arguments.array[arguments.used].string = argument.string;
         arguments.array[arguments.used].size   = argument.size;
         argument.string = f_null;
         argument.size   = 0;
         argument.used   = 0;
-      }
 
 
-      if (action != firewall_action_none_id) {
-        if (!(local.is_main || local.is_stop || local.is_lock)) {
-          f_resize_dynamic_string(status, argument, data.chains.array[local.chain_ids.array[local.chain]].used);
+        // FIXME: (this issue is probably everywhere) Implement an strncat function for dynamic strings or if I already have one implement, make sure it is used in every applicable place
+        //        (this way I can automatically handle updating the used buffer)
+        //        also look into auto-allocated space if necessary with the said function
+        if (action == firewall_action_append_id) {
+          f_resize_dynamic_string(status, argument, firewall_action_append_command_length);
 
           if (f_error_is_error(status)) break;
 
-          strncat(argument.string, data.chains.array[local.chain_ids.array[local.chain]].string, data.chains.array[local.chain_ids.array[local.chain]].used);
-          argument.used = data.chains.array[local.chain].used;
-
-        } else if (direction == firewall_direction_forward_id) {
-          f_resize_dynamic_string(status, argument, firewall_direction_forward_command_length);
+          strncat(argument.string, firewall_action_append_command, firewall_action_append_command_length);
+          argument.used = firewall_action_append_command_length;
+        } else if (action == firewall_action_insert_id) {
+          f_resize_dynamic_string(status, argument, firewall_action_insert_command_length);
 
           if (f_error_is_error(status)) break;
 
-          strncat(argument.string, firewall_direction_forward_command, firewall_direction_forward_command_length);
-          argument.used = firewall_direction_forward_command_length;
-        } else if (direction == firewall_direction_postrouting_id) {
-          f_resize_dynamic_string(status, argument, firewall_direction_postrouting_command_length);
+          strncat(argument.string, firewall_action_insert_command, firewall_action_insert_command_length);
+          argument.used = firewall_action_insert_command_length;
+        } else if (action == firewall_action_policy_id) {
+          f_resize_dynamic_string(status, argument, firewall_action_policy_command_length);
 
           if (f_error_is_error(status)) break;
 
-          strncat(argument.string, firewall_direction_postrouting_command, firewall_direction_postrouting_command_length);
-          argument.used += firewall_direction_postrouting_command_length;
-        } else if (direction == firewall_direction_prerouting_id) {
-          f_resize_dynamic_string(status, argument, firewall_direction_prerouting_command_length);
+          strncat(argument.string, firewall_action_policy_command, firewall_action_policy_command_length);
+          argument.used = firewall_action_policy_command_length;
+        }
+
+        if (argument.used > 0) {
+          f_resize_dynamic_strings(status, arguments, arguments.used + 1);
 
           if (f_error_is_error(status)) break;
 
-          strncat(argument.string, firewall_direction_prerouting_command, firewall_direction_prerouting_command_length);
-          argument.used = firewall_direction_prerouting_command_length;
-        } else if (direction_input) {
-          f_resize_dynamic_string(status, argument, firewall_direction_input_command_length);
+          arguments.array[arguments.used].string = argument.string;
+          arguments.array[arguments.used].size   = argument.size;
+          arguments.array[arguments.used].used   = argument.used;
+          arguments.used++;
+          argument.string = f_null;
+          argument.size   = 0;
+          argument.used   = 0;
+        }
 
-          if (f_error_is_error(status)) break;
 
-          strncat(argument.string, firewall_direction_input_command, firewall_direction_input_command_length);
-          argument.used = firewall_direction_input_command_length;
-        } else if (direction_output) {
-          f_resize_dynamic_string(status, argument, firewall_direction_output_command_length);
+        if (action != firewall_action_none_id) {
+          if (!(local.is_main || local.is_stop || local.is_lock)) {
+            f_resize_dynamic_string(status, argument, data.chains.array[local.chain_ids.array[local.chain]].used);
 
-          if (f_error_is_error(status)) break;
+            if (f_error_is_error(status)) break;
 
-          strncat(argument.string, firewall_direction_output_command, firewall_direction_output_command_length);
-          argument.used = firewall_direction_output_command_length;
-        }
-      }
+            strncat(argument.string, data.chains.array[local.chain_ids.array[local.chain]].string, data.chains.array[local.chain_ids.array[local.chain]].used);
+            argument.used = data.chains.array[local.chain].used;
 
-      if (argument.used > 0) {
-        f_resize_dynamic_strings(status, arguments, arguments.used + 1);
+          } else if (direction == firewall_direction_forward_id) {
+            f_resize_dynamic_string(status, argument, firewall_direction_forward_command_length);
 
-        if (f_error_is_error(status)) break;
+            if (f_error_is_error(status)) break;
 
-        arguments.array[arguments.used].string = argument.string;
-        arguments.array[arguments.used].size   = argument.size;
-        arguments.array[arguments.used].used   = argument.used;
-        arguments.used++;
-        argument.string = f_null;
-        argument.size   = 0;
-        argument.used   = 0;
-      }
+            strncat(argument.string, firewall_direction_forward_command, firewall_direction_forward_command_length);
+            argument.used = firewall_direction_forward_command_length;
+          } else if (direction == firewall_direction_postrouting_id) {
+            f_resize_dynamic_string(status, argument, firewall_direction_postrouting_command_length);
+
+            if (f_error_is_error(status)) break;
+
+            strncat(argument.string, firewall_direction_postrouting_command, firewall_direction_postrouting_command_length);
+            argument.used += firewall_direction_postrouting_command_length;
+          } else if (direction == firewall_direction_prerouting_id) {
+            f_resize_dynamic_string(status, argument, firewall_direction_prerouting_command_length);
+
+            if (f_error_is_error(status)) break;
+
+            strncat(argument.string, firewall_direction_prerouting_command, firewall_direction_prerouting_command_length);
+            argument.used = firewall_direction_prerouting_command_length;
+          } else if (direction_input) {
+            f_resize_dynamic_string(status, argument, firewall_direction_input_command_length);
 
-      if (device.used > 0) {
-        if (length < firewall_device_all_length || fl_compare_strings(local.buffer.string + local.rule_contents.array[i].array[0].start, (f_string) firewall_device_all, length, firewall_device_all_length) == f_not_equal_to) {
-          if (direction_input) {
-            f_resize_dynamic_string(status, argument, firewall_device_input_command_length);
             if (f_error_is_error(status)) break;
 
-            strncat(argument.string, firewall_device_input_command, firewall_device_input_command_length);
-            argument.used = firewall_device_input_command_length;
+            strncat(argument.string, firewall_direction_input_command, firewall_direction_input_command_length);
+            argument.used = firewall_direction_input_command_length;
           } else if (direction_output) {
-            f_resize_dynamic_string(status, argument, firewall_device_output_command_length);
+            f_resize_dynamic_string(status, argument, firewall_direction_output_command_length);
+
             if (f_error_is_error(status)) break;
 
-            strncat(argument.string, firewall_device_output_command, firewall_device_output_command_length);
-            argument.used = firewall_device_output_command_length;
+            strncat(argument.string, firewall_direction_output_command, firewall_direction_output_command_length);
+            argument.used = firewall_direction_output_command_length;
           }
         }
 
           argument.used   = 0;
         }
 
-        if (direction_input || direction_output) {
-          f_resize_dynamic_string(status, argument, device.used);
-          if (f_error_is_error(status)) break;
+        if (device.used > 0) {
+          if (length < firewall_device_all_length || fl_compare_strings(local.buffer.string + local.rule_contents.array[i].array[0].start, (f_string) firewall_device_all, length, firewall_device_all_length) == f_not_equal_to) {
+            if (direction_input) {
+              f_resize_dynamic_string(status, argument, firewall_device_input_command_length);
+              if (f_error_is_error(status)) break;
 
-          strncat(argument.string, device.string, device.used);
-          argument.used = device.used;
-        }
-      }
+              strncat(argument.string, firewall_device_input_command, firewall_device_input_command_length);
+              argument.used = firewall_device_input_command_length;
+            } else if (direction_output) {
+              f_resize_dynamic_string(status, argument, firewall_device_output_command_length);
+              if (f_error_is_error(status)) break;
 
-      if (argument.used > 0) {
-        f_resize_dynamic_strings(status, arguments, arguments.used + 1);
+              strncat(argument.string, firewall_device_output_command, firewall_device_output_command_length);
+              argument.used = firewall_device_output_command_length;
+            }
+          }
 
-        if (f_error_is_error(status)) break;
+          if (argument.used > 0) {
+            f_resize_dynamic_strings(status, arguments, arguments.used + 1);
 
-        arguments.array[arguments.used].string = argument.string;
-        arguments.array[arguments.used].size   = argument.size;
-        arguments.array[arguments.used].used   = argument.used;
-        arguments.used++;
-        argument.string = f_null;
-        argument.size   = 0;
-        argument.used   = 0;
-      }
+            if (f_error_is_error(status)) break;
 
-      if (use_protocol) {
-        f_resize_dynamic_string(status, argument, firewall_protocol_command_length);
-        if (f_error_is_error(status)) break;
+            arguments.array[arguments.used].string = argument.string;
+            arguments.array[arguments.used].size   = argument.size;
+            arguments.array[arguments.used].used   = argument.used;
+            arguments.used++;
+            argument.string = f_null;
+            argument.size   = 0;
+            argument.used   = 0;
+          }
+
+          if (direction_input || direction_output) {
+            f_resize_dynamic_string(status, argument, device.used);
+            if (f_error_is_error(status)) break;
 
-        strncat(argument.string, firewall_protocol_command, firewall_protocol_command_length);
-        argument.used = firewall_protocol_command_length;
+            strncat(argument.string, device.string, device.used);
+            argument.used = device.used;
+          }
+        }
 
         if (argument.used > 0) {
           f_resize_dynamic_strings(status, arguments, arguments.used + 1);
           argument.used   = 0;
         }
 
-        f_resize_dynamic_string(status, argument, protocol.used);
-        if (f_error_is_error(status)) break;
-
-        strncat(argument.string, protocol.string, protocol.used);
-        argument.used = protocol.used;
-      }
-
-      if (argument.used > 0) {
-        f_resize_dynamic_strings(status, arguments, arguments.used + 1);
-
-        if (f_error_is_error(status)) break;
-
-        arguments.array[arguments.used].string = argument.string;
-        arguments.array[arguments.used].size   = argument.size;
-        arguments.array[arguments.used].used   = argument.used;
-        arguments.used++;
-        argument.string = f_null;
-        argument.size   = 0;
-        argument.used   = 0;
-      }
-
-      // last up is the "rule"
-      if ((!is_ip_list && local.rule_contents.array[i].used > 0) || (is_ip_list && local.rule_contents.array[i].used > 1)) {
-        f_string_length subcounter = 0;
-
-        if (is_ip_list) {
-          // skip past the direction
-          subcounter++;
-
-          length = (local.rule_contents.array[i].array[subcounter].stop - local.rule_contents.array[i].array[subcounter].start) + 1;
-
-          f_resize_dynamic_string(status, ip_list, length);
-
-          if (f_error_is_error(status)) {
-            subcounter = local.rule_contents.array[i].used;
-          } else {
-            strncat(ip_list.string, local.buffer.string + local.rule_contents.array[i].array[subcounter].start, length);
-            ip_list.used = length;
-
-            subcounter++;
-          }
-        }
-
-        for (; subcounter < local.rule_contents.array[i].used; subcounter++) {
-          length = (local.rule_contents.array[i].array[subcounter].stop - local.rule_contents.array[i].array[subcounter].start) + 1;
-
-          f_resize_dynamic_string(status, argument, length);
-
+        if (use_protocol) {
+          f_resize_dynamic_string(status, argument, firewall_protocol_command_length);
           if (f_error_is_error(status)) break;
 
-          strncat(argument.string, local.buffer.string + local.rule_contents.array[i].array[subcounter].start, length);
-          argument.used = length;
+          strncat(argument.string, firewall_protocol_command, firewall_protocol_command_length);
+          argument.used = firewall_protocol_command_length;
 
-          if (length > 0) {
+          if (argument.used > 0) {
             f_resize_dynamic_strings(status, arguments, arguments.used + 1);
 
             if (f_error_is_error(status)) break;
             argument.size   = 0;
             argument.used   = 0;
           }
+
+          f_resize_dynamic_string(status, argument, protocol.used);
+          if (f_error_is_error(status)) break;
+
+          strncat(argument.string, protocol.string, protocol.used);
+          argument.used = protocol.used;
         }
-      } else {
-        length = (local.rule_objects.array[i].stop - local.rule_objects.array[i].start) + 1;
 
-        fl_print_color_code(f_standard_warning, data.context.warning);
-        fprintf(f_standard_warning, "WARNING: At line %u, the object '", (unsigned int) i);
-        f_print_string(f_standard_warning, local.buffer.string + local.rule_objects.array[i].start, local.rule_objects.array[i].stop - local.rule_objects.array[i].start + 1);
-        fprintf(f_standard_warning, "' has no content");
-        fl_print_color_code(f_standard_warning, data.context.reset);
-        fprintf(f_standard_warning, "\n");
+        if (argument.used > 0) {
+          f_resize_dynamic_strings(status, arguments, arguments.used + 1);
 
-        break;
-      }
+          if (f_error_is_error(status)) break;
 
-      if (arguments.used > 1) {
-        if (is_ip_list) {
-          f_file           file          = f_file_initialize;
-          f_dynamic_string file_path     = f_dynamic_string_initialize;
-          f_dynamic_string local_buffer  = f_dynamic_string_initialize;
-          f_file_position  file_position = f_file_position_initialize;
+          arguments.array[arguments.used].string = argument.string;
+          arguments.array[arguments.used].size   = argument.size;
+          arguments.array[arguments.used].used   = argument.used;
+          arguments.used++;
+          argument.string = f_null;
+          argument.size   = 0;
+          argument.used   = 0;
+        }
 
-          f_fss_objects  basic_objects  = f_fss_objects_initialize;
-          f_fss_contents basic_contents = f_fss_objects_initialize;
+        // last up is the "rule"
+        if ((!is_ip_list && local.rule_contents.array[i].used > 0) || (is_ip_list && local.rule_contents.array[i].used > 1)) {
+          f_string_length subcounter = 0;
 
-          f_resize_dynamic_string(status, file_path, network_path_length + ip_list.used + 1);
+          if (is_ip_list) {
+            // skip past the direction
+            subcounter++;
 
-          if (status == f_none) {
-            strncat(file_path.string, network_path, network_path_length);
-            strncat(file_path.string + network_path_length, ip_list.string, ip_list.used);
-            file_path.used = file_path.size;
-            file_path.string[file_path.used] = 0;
+            length = (local.rule_contents.array[i].array[subcounter].stop - local.rule_contents.array[i].array[subcounter].start) + 1;
 
-            status = f_file_open(&file, file_path.string);
-          }
+            f_resize_dynamic_string(status, ip_list, length);
 
-          if (f_error_is_error(status)) {
-            status = f_error_unmask(status);
-
-            if (status == f_invalid_parameter) {
-              fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling f_file_open()");
-            } else if (status == f_file_not_found) {
-              // the file does not have to exist
-              fl_print_color_line(f_standard_warning, data.context.warning, data.context.reset, "WARNING: Cannot find the file '%s'", file_path.string);
-              status = f_none;
-            } else if (status == f_file_open_error) {
-              fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Unable to open the file '%s'", file_path.string);
-            } else if (status == f_file_descriptor_error) {
-              fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: File descriptor error while trying to open the file '%s'", file_path.string);
-            } else if (f_macro_test_for_allocation_errors(status)) {
-              fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory");
+            if (f_error_is_error(status)) {
+              subcounter = local.rule_contents.array[i].used;
             } else {
-              fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling f_file_open()", f_error_set_error(status));
-            }
+              strncat(ip_list.string, local.buffer.string + local.rule_contents.array[i].array[subcounter].start, length);
+              ip_list.used = length;
 
-            if (status != f_file_not_found) {
-              status = f_error_set_error(status);
+              subcounter++;
             }
+          }
 
-            f_file_close(&file);
-          } else {
-            if (file_position.total_elements == 0) {
-              fseek(file.file, 0, SEEK_END);
-              file_position.total_elements = ftell(file.file);
-              fseek(file.file, 0, SEEK_SET);
+          for (; subcounter < local.rule_contents.array[i].used; subcounter++) {
+            length = (local.rule_contents.array[i].array[subcounter].stop - local.rule_contents.array[i].array[subcounter].start) + 1;
+
+            f_resize_dynamic_string(status, argument, length);
+
+            if (f_error_is_error(status)) break;
+
+            strncat(argument.string, local.buffer.string + local.rule_contents.array[i].array[subcounter].start, length);
+            argument.used = length;
+
+            if (length > 0) {
+              f_resize_dynamic_strings(status, arguments, arguments.used + 1);
+
+              if (f_error_is_error(status)) break;
+
+              arguments.array[arguments.used].string = argument.string;
+              arguments.array[arguments.used].size   = argument.size;
+              arguments.array[arguments.used].used   = argument.used;
+              arguments.used++;
+              argument.string = f_null;
+              argument.size   = 0;
+              argument.used   = 0;
             }
+          } // for
+        } else {
+          length = (local.rule_objects.array[i].stop - local.rule_objects.array[i].start) + 1;
+
+          fl_print_color_code(f_standard_warning, data.context.warning);
+          fprintf(f_standard_warning, "WARNING: At line %u, the object '", (unsigned int) i);
+          f_print_string(f_standard_warning, local.buffer.string + local.rule_objects.array[i].start, local.rule_objects.array[i].stop - local.rule_objects.array[i].start + 1);
+          fprintf(f_standard_warning, "' has no content");
+          fl_print_color_code(f_standard_warning, data.context.reset);
+          fprintf(f_standard_warning, "\n");
 
-            status = fl_file_read(file, file_position, &local_buffer);
+          break;
+        }
+
+        if (arguments.used > 1) {
+          if (is_ip_list) {
+            f_file           file          = f_file_initialize;
+            f_dynamic_string file_path     = f_dynamic_string_initialize;
+            f_dynamic_string local_buffer  = f_dynamic_string_initialize;
+            f_file_position  file_position = f_file_position_initialize;
+
+            f_fss_objects  basic_objects  = f_fss_objects_initialize;
+            f_fss_contents basic_contents = f_fss_objects_initialize;
+
+            f_resize_dynamic_string(status, file_path, network_path_length + ip_list.used + 1);
 
-            f_file_close(&file);
+            if (status == f_none) {
+              strncat(file_path.string, network_path, network_path_length);
+              strncat(file_path.string + network_path_length, ip_list.string, ip_list.used);
+              file_path.used = file_path.size;
+              file_path.string[file_path.used] = 0;
+
+              status = f_file_open(&file, file_path.string);
+            }
 
             if (f_error_is_error(status)) {
               status = f_error_unmask(status);
 
               if (status == f_invalid_parameter) {
-                fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling fl_file_read()");
-              } else if (status == f_overflow) {
-                fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Integer overflow while trying to buffer the file '%s'", file_path.string);
-              } else if (status == f_file_not_open) {
-                fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: The file '%s' is no longer open", file_path.string);
-              } else if (status == f_file_seek_error) {
-                fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: A seek error occurred while accessing the file '%s'", file_path.string);
-              } else if (status == f_file_read_error) {
-                fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: A read error occurred while accessing the file '%s'", file_path.string);
+                fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling f_file_open()");
+              } else if (status == f_file_not_found) {
+                // the file does not have to exist
+                fl_print_color_line(f_standard_warning, data.context.warning, data.context.reset, "WARNING: Cannot find the file '%s'", file_path.string);
+                status = f_none;
+              } else if (status == f_file_open_error) {
+                fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Unable to open the file '%s'", file_path.string);
+              } else if (status == f_file_descriptor_error) {
+                fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: File descriptor error while trying to open the file '%s'", file_path.string);
               } else if (f_macro_test_for_allocation_errors(status)) {
                 fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory");
               } else {
-                fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fl_file_read()", f_error_set_error(status));
+                fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling f_file_open()", f_error_set_error(status));
+              }
+
+              if (status != f_file_not_found) {
+                status = f_error_set_error(status);
               }
 
-              status = f_error_set_error(status);
+              f_file_close(&file);
             } else {
-              {
-                f_string_location input = f_string_location_initialize;
+              if (file_position.total_elements == 0) {
+                fseek(file.file, 0, SEEK_END);
+                file_position.total_elements = ftell(file.file);
+                fseek(file.file, 0, SEEK_SET);
+              }
 
-                input.stop = local_buffer.used - 1;
+              status = fl_file_read(file, file_position, &local_buffer);
 
-                status = fll_fss_basic_read(&local_buffer, &input, &basic_objects, &basic_contents);
-              }
+              f_file_close(&file);
 
-              if (f_error_set_error(status)) {
+              if (f_error_is_error(status)) {
                 status = f_error_unmask(status);
 
                 if (status == f_invalid_parameter) {
-                  fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_read() for the file '%s'", file_path.string);
-                } else if (status == f_no_data_on_eos || status == f_no_data || status == f_no_data_on_stop) {
-                  // empty files are to be silently ignored
+                  fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling fl_file_read()");
+                } else if (status == f_overflow) {
+                  fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Integer overflow while trying to buffer the file '%s'", file_path.string);
+                } else if (status == f_file_not_open) {
+                  fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: The file '%s' is no longer open", file_path.string);
+                } else if (status == f_file_seek_error) {
+                  fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: A seek error occurred while accessing the file '%s'", file_path.string);
+                } else if (status == f_file_read_error) {
+                  fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: A read error occurred while accessing the file '%s'", file_path.string);
                 } else if (f_macro_test_for_allocation_errors(status)) {
                   fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory");
                 } else {
-                  fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_read() for the file '%s'", f_error_set_error(status), file_path.string);
+                  fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fl_file_read()", f_error_set_error(status));
                 }
 
                 status = f_error_set_error(status);
               } else {
-                f_string_length  buffer_counter = 0;
-                f_string_length  ip_length      = 0;
-                f_dynamic_string ip_argument    = f_dynamic_string_initialize;
-                f_dynamic_string ip_list_action = f_dynamic_string_initialize;
-
-                if (ip_list_direction) {
-                  f_resize_dynamic_string(status, ip_list_action, firewall_ip_list_destination_action_length + 1);
-                  strncat(ip_list_action.string, firewall_ip_list_destination_action, firewall_ip_list_destination_action_length);
-                } else {
-                  f_resize_dynamic_string(status, ip_list_action, firewall_ip_list_source_action_length + 1);
-                  strncat(ip_list_action.string, firewall_ip_list_source_action, firewall_ip_list_source_action_length);
+                {
+                  f_string_location input = f_string_location_initialize;
+
+                  input.stop = local_buffer.used - 1;
+
+                  status = fll_fss_basic_read(&local_buffer, &input, &basic_objects, &basic_contents);
                 }
 
-                ip_list_action.used = ip_list_action.size;
-                ip_list_action.string[ip_list_action.used] = 0;
+                if (f_error_set_error(status)) {
+                  status = f_error_unmask(status);
 
-                if (f_error_is_error(status)) {
-                  fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory");
+                  if (status == f_invalid_parameter) {
+                    fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_read() for the file '%s'", file_path.string);
+                  } else if (status == f_no_data_on_eos || status == f_no_data || status == f_no_data_on_stop) {
+                    // empty files are to be silently ignored
+                  } else if (f_macro_test_for_allocation_errors(status)) {
+                    fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory");
+                  } else {
+                    fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_read() for the file '%s'", f_error_set_error(status), file_path.string);
+                  }
+
+                  status = f_error_set_error(status);
                 } else {
-                  ip_list_action.used = ip_list_action.size;
+                  f_string_length  buffer_counter = 0;
+                  f_string_length  ip_length      = 0;
+                  f_dynamic_string ip_argument    = f_dynamic_string_initialize;
+                  f_dynamic_string ip_list_action = f_dynamic_string_initialize;
+
+                  if (ip_list_direction) {
+                    f_resize_dynamic_string(status, ip_list_action, firewall_ip_list_destination_action_length + 1);
+                    strncat(ip_list_action.string, firewall_ip_list_destination_action, firewall_ip_list_destination_action_length);
+                  } else {
+                    f_resize_dynamic_string(status, ip_list_action, firewall_ip_list_source_action_length + 1);
+                    strncat(ip_list_action.string, firewall_ip_list_source_action, firewall_ip_list_source_action_length);
+                  }
 
-                  f_resize_dynamic_strings(status, arguments, arguments.used + 2);
+                  ip_list_action.used = ip_list_action.size;
+                  ip_list_action.string[ip_list_action.used] = 0;
 
                   if (f_error_is_error(status)) {
                     fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory");
                   } else {
-                    arguments.array[arguments.used].string = ip_list_action.string;
-                    arguments.array[arguments.used].size   = ip_list_action.size;
-                    arguments.array[arguments.used].used   = ip_list_action.used;
-                    arguments.used++;
+                    ip_list_action.used = ip_list_action.size;
 
-                    // the ip_list file contains objects and no content, all objects are what matter an nothing else
-                    for (; buffer_counter < basic_objects.used; buffer_counter++) {
-                      ip_length = (basic_objects.array[buffer_counter].stop - basic_objects.array[buffer_counter].start) + 1;
+                    f_resize_dynamic_strings(status, arguments, arguments.used + 2);
 
-                      f_resize_dynamic_string(status, ip_argument, ip_length);
+                    if (f_error_is_error(status)) {
+                      fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory");
+                    } else {
+                      arguments.array[arguments.used].string = ip_list_action.string;
+                      arguments.array[arguments.used].size   = ip_list_action.size;
+                      arguments.array[arguments.used].used   = ip_list_action.used;
+                      arguments.used++;
 
-                      if (f_error_is_error(status)) {
-                        fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory");
-                        break;
-                      }
+                      // the ip_list file contains objects and no content, all objects are what matter an nothing else
+                      for (; buffer_counter < basic_objects.used; buffer_counter++) {
+                        ip_length = (basic_objects.array[buffer_counter].stop - basic_objects.array[buffer_counter].start) + 1;
 
-                      strncat(ip_argument.string, local_buffer.string + basic_objects.array[buffer_counter].start, ip_length);
-                      ip_argument.used = ip_argument.size;
-                      ip_argument.string[ip_argument.used] = 0;
+                        f_resize_dynamic_string(status, ip_argument, ip_length);
 
-                      arguments.array[arguments.used].string = ip_argument.string;
-                      arguments.array[arguments.used].size   = ip_argument.size;
-                      arguments.array[arguments.used].used   = ip_argument.used;
-                      arguments.used++;
+                        if (f_error_is_error(status)) {
+                          fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory");
+                          break;
+                        }
 
-                      status = fll_execute_program((f_string) firewall_program_name, arguments, &results);
+                        strncat(ip_argument.string, local_buffer.string + basic_objects.array[buffer_counter].start, ip_length);
+                        ip_argument.used = ip_argument.size;
+                        ip_argument.string[ip_argument.used] = 0;
 
-                      if (status == f_failure) {
-                        fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Failed to perform requested %s operation:", firewall_program_name);
-                        fprintf(f_standard_error, "  ");
+                        arguments.array[arguments.used].string = ip_argument.string;
+                        arguments.array[arguments.used].size   = ip_argument.size;
+                        arguments.array[arguments.used].used   = ip_argument.used;
+                        arguments.used++;
 
-                        f_string_length i = 0;
+                        status = fll_execute_program((f_string) current_tool, arguments, &results);
 
-                        fl_print_color_code(f_standard_error, data.context.error);
+                        if (status == f_failure) {
+                          fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Failed to perform requested %s operation:", current_tool);
+                          fprintf(f_standard_error, "  ");
 
-                        for (; i < arguments.used; i++) {
-                          fprintf(f_standard_error, "%s ", arguments.array[i].string);
-                        }
+                          f_string_length i = 0;
 
-                        fl_print_color_code(f_standard_error, data.context.reset);
-                        fprintf(f_standard_error, "\n");
+                          fl_print_color_code(f_standard_error, data.context.error);
 
-                        arguments.used--;
-                        arguments.array[arguments.used].string = 0;
-                        arguments.array[arguments.used].size   = 0;
-                        arguments.array[arguments.used].used   = 0;
+                          for (; i < arguments.used; i++) {
+                            fprintf(f_standard_error, "%s ", arguments.array[i].string);
+                          }
+
+                          fl_print_color_code(f_standard_error, data.context.reset);
+                          fprintf(f_standard_error, "\n");
+
+                          arguments.used--;
+                          arguments.array[arguments.used].string = 0;
+                          arguments.array[arguments.used].size   = 0;
+                          arguments.array[arguments.used].used   = 0;
 
-                        break;
-                      } else if (status == f_invalid_parameter) {
-                        fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling fl_execute_path()");
+                          break;
+                        } else if (status == f_invalid_parameter) {
+                          fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling fl_execute_path()");
+
+                          arguments.used--;
+                          arguments.array[arguments.used].string = 0;
+                          arguments.array[arguments.used].size   = 0;
+                          arguments.array[arguments.used].used   = 0;
+
+                          break;
+                        }
 
                         arguments.used--;
                         arguments.array[arguments.used].string = 0;
                         arguments.array[arguments.used].size   = 0;
                         arguments.array[arguments.used].used   = 0;
 
-                        break;
+                        f_delete_dynamic_string(status2, ip_argument);
                       }
-
-                      arguments.used--;
-                      arguments.array[arguments.used].string = 0;
-                      arguments.array[arguments.used].size   = 0;
-                      arguments.array[arguments.used].used   = 0;
-
-                      f_delete_dynamic_string(status2, ip_argument);
                     }
                   }
-                }
 
-                f_delete_dynamic_string(status2, ip_argument);
-                f_delete_dynamic_string(status2, ip_list_action);
+                  f_delete_dynamic_string(status2, ip_argument);
+                  f_delete_dynamic_string(status2, ip_list_action);
 
-                arguments.used--;
-                arguments.array[arguments.used].string = 0;
-                arguments.array[arguments.used].size   = 0;
-                arguments.array[arguments.used].used   = 0;
+                  arguments.used--;
+                  arguments.array[arguments.used].string = 0;
+                  arguments.array[arguments.used].size   = 0;
+                  arguments.array[arguments.used].used   = 0;
+                }
               }
             }
-          }
 
-          f_delete_dynamic_string(status2, local_buffer);
-          f_delete_dynamic_string(status2, file_path);
-          f_delete_fss_objects(status2, basic_objects);
-          f_delete_fss_contents(status2, basic_contents);
+            f_delete_dynamic_string(status2, local_buffer);
+            f_delete_dynamic_string(status2, file_path);
+            f_delete_fss_objects(status2, basic_objects);
+            f_delete_fss_contents(status2, basic_contents);
 
-          if (status == f_failure || status == f_invalid_parameter) break;
-        } else {
-          status = fll_execute_program((f_string) firewall_program_name, arguments, &results);
+            if (status == f_failure || status == f_invalid_parameter) break;
+          } else {
+            status = fll_execute_program(current_tool, arguments, &results);
 
-          if (status == f_failure) {
-            fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Failed to perform requested %s operation:", firewall_program_name);
-            fprintf(f_standard_error, "  ");
+            if (status == f_failure) {
+              fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Failed to perform requested %s operation:", current_tool);
+              fprintf(f_standard_error, "  ");
 
-            f_string_length i = 0;
+              f_string_length i = 0;
 
-            fl_print_color_code(f_standard_error, data.context.error);
+              fl_print_color_code(f_standard_error, data.context.error);
 
-            for (; i < arguments.used; i++) {
-              fprintf(f_standard_error, "%s ", arguments.array[i].string);
-            }
+              for (; i < arguments.used; i++) {
+                fprintf(f_standard_error, "%s ", arguments.array[i].string);
+              }
 
-            fl_print_color_code(f_standard_error, data.context.reset);
-            fprintf(f_standard_error, "\n");
+              fl_print_color_code(f_standard_error, data.context.reset);
+              fprintf(f_standard_error, "\n");
 
-            break;
-          } else if (status == f_invalid_parameter) {
-            fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling fl_execute_path()");
-            break;
+              break;
+            } else if (status == f_invalid_parameter) {
+              fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling fl_execute_path()");
+              break;
+            }
           }
-        }
+        } // for
       }
     }
 
     f_status status = f_none;
     f_status status2 = f_none;
 
+    uint8_t tool = firewall_program_iptables;
     f_bool new_chain = f_false;
     f_s_int results = 0;
 
       return status;
     }
 
-    f_resize_dynamic_string(status, arguments.array[0], firewall_program_name_length);
+    f_resize_dynamic_string(status, arguments.array[0], firewall_tool_ip6tables_length);
 
     if (f_error_is_error(status)) {
       f_delete_dynamic_strings(status2, arguments);
     reserved->has_stop = f_false;
     reserved->has_main = f_false;
 
-    strncat(arguments.array[0].string, firewall_program_name, firewall_program_name_length);
+    strncat(arguments.array[0].string, firewall_tool_iptables, firewall_tool_iptables_length);
     strncat(arguments.array[1].string, firewall_chain_create_command, firewall_chain_create_command_length);
-    arguments.array[0].used = firewall_program_name_length;
+    arguments.array[0].used = firewall_tool_iptables_length;
     arguments.array[1].used = firewall_chain_create_command_length;
     arguments.used = 3;
 
           return status;
         }
 
-        status = fll_execute_program((f_string) firewall_program_name, arguments, &results);
+        tool = firewall_program_iptables;
+        status = fll_execute_program((f_string) firewall_tool_iptables, arguments, &results);
+
+        if (f_error_is_not_error(status)) {
+          memset(arguments.array[0].string, 0, sizeof(f_autochar) * firewall_tool_iptables_length);
+          strncat(arguments.array[0].string, firewall_tool_iptables, firewall_tool_ip6tables_length);
+          arguments.array[0].used = firewall_tool_ip6tables_length;
+          arguments.used = 3;
+
+          tool = firewall_program_ip6tables;
+          status = fll_execute_program((f_string) firewall_tool_ip6tables, arguments, &results);
+        }
 
         if (f_error_is_error(status)) {
           status = f_error_unmask(status);
 
           if (status == f_failure) {
-            fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Failed to perform requested %s operation:", firewall_program_name);
+            if (tool == firewall_program_iptables) {
+              fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Failed to perform requested %s operation:", firewall_tool_iptables);
+            } else if (tool == firewall_program_ip6tables) {
+              fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Failed to perform requested %s operation:", firewall_tool_ip6tables);
+            }
+
             fprintf(f_standard_error, "  ");
 
             f_string_length i = 0;
index 0d7f0695874cd7ef8e29bad1266c119131032130..1e58e13e075377dec1e3920a34b11cd2e71550ac 100644 (file)
@@ -1,4 +1,9 @@
 # fss-0002
+# valid tool: iptables, ip6tables, ip46tables (ip46tables = both ip4 and ip6 tables, which is the default)
+# valid direction: input, output, forward, postrouting, postrouting-output, postrouting-input, prerouting, prerouting-output, prerouting-input, none
+# valid device: all, this, (any device name goes here without parenthesis)
+# valid action: append, insert, policy, none
+# valid procotol: none, (any valid iptables protocol type, such as tcp, udp, and icmp)
 
 main:
   device this
@@ -21,8 +26,10 @@ input-tcp:
   #rule --dport 80 -m state --state NEW -j ACCEPT
 
   ## Http / Web redirect to Https / Secure Web
+  #tool iptables
   #direction prerouting-input
   #rule -t nat --dport 80 -m state --state NEW -j REDIRECT --to-port 443
+  #tool ip46tables
   #direction input
 
   ## Https / Secure Web
index fbba54772d23d3b480271404509bca7629964152..56d862cb472f489ec7585da12134184d966ceac4 100644 (file)
@@ -1,8 +1,4 @@
 # fss-0002
-# valid direction: input, output, forward, postrouting, postrouting-output, postrouting-input, prerouting, prerouting-output, prerouting-input, none
-# valid device: all, this, (any device name goes here without parenthesis)
-# valid action: append, insert, policy, none
-# valid procotol: none, (any valid iptables protocol type, such as tcp, udp, and icmp)
 
 main:
   # initialize the firewall
@@ -31,8 +27,10 @@ main:
   # the above loopback rules should catch all true loopback connections
   # the following loopback rules will only catch anything if a loopback spoofing is happending
   # therefore, do not allow spoof by DROPing
+  #tool iptables
   #rule -s 127.0.0.1 -j DROP
   #rule -d 127.0.0.1 -j DROP
+  #tool ip46tables
 
 
   # Drop all INVALID packets so they aren't even processed
@@ -94,7 +92,9 @@ input-udp:
   protocol udp
 
   # Allow dhcp client renewals. If these are blocked, you will not be able to renew easily
+  tool iptables
   rule -s 0.0.0.0 --sport 67 -d 255.255.255.255 --dport 68 -j ACCEPT
+  tool ip46tables
 
 
 input-icmp:
index 5c027c93383262e65361016c5663a81d8c5e99d3..eb0f5434258461027ed2971b150e55c0ab70a4da 100644 (file)
@@ -1,8 +1,4 @@
 # fss-0002
-# valid direction: input, output, forward, postrouting, postrouting-output, postrouting-input, prerouting, prerouting-output, prerouting-input, none
-# valid device: all, this, (any device name goes here without parenthesis)
-# valid action: append, insert, policy, none
-# valid procotol: none, (any valid iptables protocol type, such as tcp, udp, and icmp)
 
 main:
   direction input
@@ -111,6 +107,9 @@ input-icmp:
   # allow all icmp input, such as pings
   #rule -m state --state NEW -j ACCEPT
 
+  # ip6tables does not support --icmp-type with its icmp packets
+  tool iptables
+
   # allow icmp: echo reply (outbound ping)
   #rule --icmp-type 0 -m state --state NEW -j ACCEPT
 
index 9698f3e8e8803125eecd563bfd8e46ae88108bf0..5009f2a0b35154193208d2f89b9dee708580a765 100644 (file)
@@ -1,8 +1,4 @@
 # fss-0002
-# valid direction: input, output, forward, postrouting, postrouting-output, postrouting-input, prerouting, prerouting-output, prerouting-input, none
-# valid device: all, this, (any device name goes here without parenthesis)
-# valid action: append, insert, policy, none
-# valid procotol: none, (any valid iptables protocol type, such as tcp, udp, and icmp)
 
 stop:
   action policy
@@ -19,11 +15,18 @@ stop:
   direction none
   action none
   rule --flush
+
+  tool iptables
   rule -t nat --flush
   rule -t mangle --flush
+  tool ip46tables
+
   rule --delete-chain
+
+  tool iptables
   rule -t nat --delete-chain
   rule -t mangle --delete-chain
+  tool ip46tables
 
 lock:
   action policy
@@ -40,15 +43,20 @@ lock:
   direction none
   action none
   rule --flush
+
+  tool iptables
   rule -t nat --flush
   rule -t mangle --flush
+  tool ip46tables
+
   rule --delete-chain
+
+  tool iptables
   rule -t nat --delete-chain
   rule -t mangle --delete-chain
+  tool ip46tables
 
   action insert
   direction input
   device lo
   rule -j ACCEPT
-
-  direction output