-e4:
- r = fork_and_exec ("/sbin/ip", (char *[])
- {
- "ip", "route", "del", "default", "via", virt_dns,
- "table", "2", NULL});
-e3:
- r = fork_and_exec ("/sbin/ip", (char *[])
- {
- "ip", "rule", "del", "fwmark", "3", "table", "2", NULL});
-e2:
- r = fork_and_exec ("/sbin/iptables", (char *[])
- {
- "iptables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp",
- "--dport", "53", "-j", "MARK", "--set-mark", "3", NULL});
-e1:
- r = fork_and_exec ("/sbin/iptables", (char *[])
- {
- "iptables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp",
- "--sport", localport, "--dport", "53", "-j", "ACCEPT",
- NULL});
- if (!delete)
- r = 0;
+ /* Forward everything from the given local port (with destination
+ to port 53, and only for UDP) without hijacking */
+ {
+ char *const mangle_args[] =
+ {
+ "iptables", "-t", "mangle", "-I", "OUTPUT", "1", "-p",
+ "udp", "--sport", localport, "--dport", DNS_PORT, "-j",
+ "ACCEPT", NULL
+ };
+ if (0 != fork_and_exec (SBIN_IPTABLES, mangle_args))
+ goto cleanup_mangle_1;
+ }
+ /* Mark all of the other DNS traffic using our mark DNS_MARK */
+ {
+ char *const mark_args[] =
+ {
+ "iptables", "-t", "mangle", "-I", "OUTPUT", DNS_TABLE, "-p",
+ "udp", "--dport", DNS_PORT, "-j", "MARK", "--set-mark", DNS_MARK,
+ NULL
+ };
+ if (0 != fork_and_exec (SBIN_IPTABLES, mark_args))
+ goto cleanup_mark_2;
+ }
+ /* Forward all marked DNS traffic to our DNS_TABLE */
+ {
+ char *const forward_args[] =
+ {
+ "ip", "rule", "add", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL
+ };
+ if (0 != fork_and_exec (SBIN_IP, forward_args))
+ goto cleanup_forward_3;
+ }
+ /* Finally, add rule in our forwarding table to pass to our virtual interface */
+ {
+ char *const route_args[] =
+ {
+ "ip", "route", "add", "default", "via", virt_dns,
+ "table", DNS_TABLE, NULL
+ };
+ if (0 != fork_and_exec (SBIN_IP, route_args))
+ goto cleanup_route_4;
+ }