diff options
Diffstat (limited to 'src/vpn/gnunet-helper-hijack-dns.c')
-rw-r--r-- | src/vpn/gnunet-helper-hijack-dns.c | 185 |
1 files changed, 120 insertions, 65 deletions
diff --git a/src/vpn/gnunet-helper-hijack-dns.c b/src/vpn/gnunet-helper-hijack-dns.c index ee7ae1873..e6912323b 100644 --- a/src/vpn/gnunet-helper-hijack-dns.c +++ b/src/vpn/gnunet-helper-hijack-dns.c | |||
@@ -27,75 +27,130 @@ | |||
27 | 27 | ||
28 | #include "gnunet_common.h" | 28 | #include "gnunet_common.h" |
29 | 29 | ||
30 | int fork_and_exec(char* file, char* cmd[]) { | 30 | int |
31 | pid_t pid = fork(); | 31 | fork_and_exec (char *file, char *cmd[]) |
32 | if (pid < 0) { | 32 | { |
33 | fprintf(stderr, "could not fork: %s\n", strerror(errno)); | 33 | pid_t pid = fork (); |
34 | return GNUNET_SYSERR; | 34 | |
35 | } | 35 | if (pid < 0) |
36 | 36 | { | |
37 | int st = 0; | 37 | fprintf (stderr, "could not fork: %s\n", strerror (errno)); |
38 | 38 | return GNUNET_SYSERR; | |
39 | if (pid == 0) { | 39 | } |
40 | execv(file, cmd); | 40 | |
41 | } else { | 41 | int st = 0; |
42 | waitpid(pid, &st, 0); | 42 | |
43 | } | 43 | if (pid == 0) |
44 | return WIFEXITED(st) && (WEXITSTATUS(st) == 0); | 44 | { |
45 | execv (file, cmd); | ||
46 | } | ||
47 | else | ||
48 | { | ||
49 | waitpid (pid, &st, 0); | ||
50 | } | ||
51 | return WIFEXITED (st) && (WEXITSTATUS (st) == 0); | ||
45 | } | 52 | } |
46 | 53 | ||
47 | int main(int argc, char** argv) { | 54 | int |
48 | int delete = 0; | 55 | main (int argc, char **argv) |
49 | int port = 0; | 56 | { |
50 | char* virt_dns; | 57 | int delete = 0; |
51 | if (argc < 3) return GNUNET_SYSERR; | 58 | int port = 0; |
52 | 59 | char *virt_dns; | |
53 | if (strncmp(argv[1], "-d", 2) == 0) { | 60 | |
54 | if (argc < 3) return GNUNET_SYSERR; | 61 | if (argc < 3) |
55 | delete = 1; | 62 | return GNUNET_SYSERR; |
56 | port = atoi(argv[2]); | 63 | |
57 | virt_dns = argv[3]; | 64 | if (strncmp (argv[1], "-d", 2) == 0) |
58 | } else { | 65 | { |
59 | port = atoi(argv[1]); | 66 | if (argc < 3) |
60 | virt_dns = argv[2]; | 67 | return GNUNET_SYSERR; |
61 | } | 68 | delete = 1; |
62 | 69 | port = atoi (argv[2]); | |
63 | if (port == 0) return GNUNET_SYSERR; | 70 | virt_dns = argv[3]; |
64 | 71 | } | |
65 | struct stat s; | 72 | else |
66 | if (stat("/sbin/iptables", &s) < 0) { | 73 | { |
67 | fprintf(stderr, "stat on /sbin/iptables failed: %s\n", strerror(errno)); | 74 | port = atoi (argv[1]); |
68 | return GNUNET_SYSERR; | 75 | virt_dns = argv[2]; |
69 | } | 76 | } |
70 | if (stat("/sbin/ip", &s) < 0) { | 77 | |
71 | fprintf(stderr, "stat on /sbin/ip failed: %s\n", strerror(errno)); | 78 | if (port == 0) |
72 | return GNUNET_SYSERR; | 79 | return GNUNET_SYSERR; |
73 | } | 80 | |
74 | 81 | struct stat s; | |
75 | char localport[7]; | 82 | |
76 | snprintf(localport, 7, "%d", port); | 83 | if (stat ("/sbin/iptables", &s) < 0) |
77 | 84 | { | |
78 | int r; | 85 | fprintf (stderr, "stat on /sbin/iptables failed: %s\n", strerror (errno)); |
79 | if (delete) { | 86 | return GNUNET_SYSERR; |
87 | } | ||
88 | if (stat ("/sbin/ip", &s) < 0) | ||
89 | { | ||
90 | fprintf (stderr, "stat on /sbin/ip failed: %s\n", strerror (errno)); | ||
91 | return GNUNET_SYSERR; | ||
92 | } | ||
93 | |||
94 | char localport[7]; | ||
95 | |||
96 | snprintf (localport, 7, "%d", port); | ||
97 | |||
98 | int r; | ||
99 | |||
100 | if (delete) | ||
101 | { | ||
80 | e4: | 102 | e4: |
81 | r = fork_and_exec("/sbin/ip", (char*[]){"ip", "route", "del", "default", "via", virt_dns,"table","2", NULL}); | 103 | r = fork_and_exec ("/sbin/ip", (char *[]) |
104 | { | ||
105 | "ip", "route", "del", "default", "via", virt_dns, | ||
106 | "table", "2", NULL}); | ||
82 | e3: | 107 | e3: |
83 | r = fork_and_exec("/sbin/ip", (char*[]){"ip", "rule", "del", "fwmark", "3", "table","2", NULL}); | 108 | r = fork_and_exec ("/sbin/ip", (char *[]) |
109 | { | ||
110 | "ip", "rule", "del", "fwmark", "3", "table", "2", NULL}); | ||
84 | e2: | 111 | e2: |
85 | r = fork_and_exec("/sbin/iptables", (char*[]){"iptables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp", "--dport", "53", "-j", "MARK", "--set-mark", "3", NULL}); | 112 | r = fork_and_exec ("/sbin/iptables", (char *[]) |
113 | { | ||
114 | "iptables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp", | ||
115 | "--dport", "53", "-j", "MARK", "--set-mark", "3", NULL}); | ||
86 | e1: | 116 | e1: |
87 | r = fork_and_exec("/sbin/iptables", (char*[]){"iptables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp", "--sport", localport, "--dport", "53", "-j", "ACCEPT", NULL}); | 117 | r = fork_and_exec ("/sbin/iptables", (char *[]) |
88 | if (!delete) r = 0; | 118 | { |
89 | } else { | 119 | "iptables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp", |
90 | r = fork_and_exec("/sbin/iptables", (char*[]){"iptables", "-t", "mangle", "-I", "OUTPUT", "1", "-p", "udp", "--sport", localport, "--dport", "53", "-j", "ACCEPT", NULL}); | 120 | "--sport", localport, "--dport", "53", "-j", "ACCEPT", |
91 | if (!r) goto e1; | 121 | NULL}); |
92 | r = fork_and_exec("/sbin/iptables", (char*[]){"iptables", "-t", "mangle", "-I", "OUTPUT", "2", "-p", "udp", "--dport", "53", "-j", "MARK", "--set-mark", "3", NULL}); | 122 | if (!delete) |
93 | if (!r) goto e2; | 123 | r = 0; |
94 | r = fork_and_exec("/sbin/ip", (char*[]){"ip", "rule", "add", "fwmark", "3", "table","2", NULL}); | 124 | } |
95 | if (!r) goto e3; | 125 | else |
96 | r = fork_and_exec("/sbin/ip", (char*[]){"ip", "route", "add", "default", "via", virt_dns, "table","2", NULL}); | 126 | { |
97 | if (!r) goto e4; | 127 | r = fork_and_exec ("/sbin/iptables", (char *[]) |
98 | } | 128 | { |
99 | if (r) return GNUNET_YES; | 129 | "iptables", "-t", "mangle", "-I", "OUTPUT", "1", "-p", |
100 | return GNUNET_SYSERR; | 130 | "udp", "--sport", localport, "--dport", "53", "-j", |
131 | "ACCEPT", NULL}); | ||
132 | if (!r) | ||
133 | goto e1; | ||
134 | r = fork_and_exec ("/sbin/iptables", (char *[]) | ||
135 | { | ||
136 | "iptables", "-t", "mangle", "-I", "OUTPUT", "2", "-p", | ||
137 | "udp", "--dport", "53", "-j", "MARK", "--set-mark", "3", | ||
138 | NULL}); | ||
139 | if (!r) | ||
140 | goto e2; | ||
141 | r = fork_and_exec ("/sbin/ip", (char *[]) | ||
142 | { | ||
143 | "ip", "rule", "add", "fwmark", "3", "table", "2", NULL}); | ||
144 | if (!r) | ||
145 | goto e3; | ||
146 | r = fork_and_exec ("/sbin/ip", (char *[]) | ||
147 | { | ||
148 | "ip", "route", "add", "default", "via", virt_dns, | ||
149 | "table", "2", NULL}); | ||
150 | if (!r) | ||
151 | goto e4; | ||
152 | } | ||
153 | if (r) | ||
154 | return GNUNET_YES; | ||
155 | return GNUNET_SYSERR; | ||
101 | } | 156 | } |