aboutsummaryrefslogtreecommitdiff
path: root/src/exit/gnunet-helper-exit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exit/gnunet-helper-exit.c')
-rw-r--r--src/exit/gnunet-helper-exit.c964
1 files changed, 482 insertions, 482 deletions
diff --git a/src/exit/gnunet-helper-exit.c b/src/exit/gnunet-helper-exit.c
index cda38710f..297a17813 100644
--- a/src/exit/gnunet-helper-exit.c
+++ b/src/exit/gnunet-helper-exit.c
@@ -16,7 +16,7 @@
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file exit/gnunet-helper-exit.c 22 * @file exit/gnunet-helper-exit.c
@@ -81,8 +81,7 @@ static const char *sbin_iptables;
81/** 81/**
82 * This is in linux/include/net/ipv6.h, but not always exported... 82 * This is in linux/include/net/ipv6.h, but not always exported...
83 */ 83 */
84struct in6_ifreq 84struct in6_ifreq {
85{
86 struct in6_addr ifr6_addr; 85 struct in6_addr ifr6_addr;
87 uint32_t ifr6_prefixlen; /* __u32 in the original */ 86 uint32_t ifr6_prefixlen; /* __u32 in the original */
88 int ifr6_ifindex; 87 int ifr6_ifindex;
@@ -98,22 +97,22 @@ struct in6_ifreq
98 * @param flags open flags (O_RDONLY, O_WRONLY) 97 * @param flags open flags (O_RDONLY, O_WRONLY)
99 */ 98 */
100static void 99static void
101open_dev_null (int target_fd, 100open_dev_null(int target_fd,
102 int flags) 101 int flags)
103{ 102{
104 int fd; 103 int fd;
105 104
106 fd = open ("/dev/null", flags); 105 fd = open("/dev/null", flags);
107 if (-1 == fd) 106 if (-1 == fd)
108 abort (); 107 abort();
109 if (fd == target_fd) 108 if (fd == target_fd)
110 return; 109 return;
111 if (-1 == dup2 (fd, target_fd)) 110 if (-1 == dup2(fd, target_fd))
112 { 111 {
113 (void) close (fd); 112 (void)close(fd);
114 abort (); 113 abort();
115 } 114 }
116 (void) close (fd); 115 (void)close(fd);
117} 116}
118 117
119 118
@@ -125,49 +124,50 @@ open_dev_null (int target_fd,
125 * @return 0 on success, 1 on any error 124 * @return 0 on success, 1 on any error
126 */ 125 */
127static int 126static int
128fork_and_exec (const char *file, 127fork_and_exec(const char *file,
129 char *const cmd[]) 128 char *const cmd[])
130{ 129{
131 int status; 130 int status;
132 pid_t pid; 131 pid_t pid;
133 pid_t ret; 132 pid_t ret;
134 133
135 pid = fork (); 134 pid = fork();
136 if (-1 == pid) 135 if (-1 == pid)
137 { 136 {
138 fprintf (stderr, 137 fprintf(stderr,
139 "fork failed: %s\n", 138 "fork failed: %s\n",
140 strerror (errno)); 139 strerror(errno));
141 return 1; 140 return 1;
142 } 141 }
143 if (0 == pid) 142 if (0 == pid)
144 { 143 {
145 /* we are the child process */ 144 /* we are the child process */
146 /* close stdin/stdout to not cause interference 145 /* close stdin/stdout to not cause interference
147 with the helper's main protocol! */ 146 with the helper's main protocol! */
148 (void) close (0); 147 (void)close(0);
149 open_dev_null (0, O_RDONLY); 148 open_dev_null(0, O_RDONLY);
150 (void) close (1); 149 (void)close(1);
151 open_dev_null (1, O_WRONLY); 150 open_dev_null(1, O_WRONLY);
152 (void) execv (file, cmd); 151 (void)execv(file, cmd);
153 /* can only get here on error */ 152 /* can only get here on error */
154 fprintf (stderr, 153 fprintf(stderr,
155 "exec `%s' failed: %s\n", 154 "exec `%s' failed: %s\n",
156 file, 155 file,
157 strerror (errno)); 156 strerror(errno));
158 _exit (1); 157 _exit(1);
159 } 158 }
160 /* keep running waitpid as long as the only error we get is 'EINTR' */ 159 /* keep running waitpid as long as the only error we get is 'EINTR' */
161 while ( (-1 == (ret = waitpid (pid, &status, 0))) && 160 while ((-1 == (ret = waitpid(pid, &status, 0))) &&
162 (errno == EINTR) ); 161 (errno == EINTR))
162 ;
163 if (-1 == ret) 163 if (-1 == ret)
164 { 164 {
165 fprintf (stderr, 165 fprintf(stderr,
166 "waitpid failed: %s\n", 166 "waitpid failed: %s\n",
167 strerror (errno)); 167 strerror(errno));
168 return 1; 168 return 1;
169 } 169 }
170 if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)))) 170 if (!(WIFEXITED(status) && (0 == WEXITSTATUS(status))))
171 return 1; 171 return 1;
172 /* child process completed and returned success, we're happy */ 172 /* child process completed and returned success, we're happy */
173 return 0; 173 return 0;
@@ -182,46 +182,46 @@ fork_and_exec (const char *file,
182 * @return the fd to the tun or -1 on error 182 * @return the fd to the tun or -1 on error
183 */ 183 */
184static int 184static int
185init_tun (char *dev) 185init_tun(char *dev)
186{ 186{
187 struct ifreq ifr; 187 struct ifreq ifr;
188 int fd; 188 int fd;
189 189
190 if (NULL == dev) 190 if (NULL == dev)
191 { 191 {
192 errno = EINVAL; 192 errno = EINVAL;
193 return -1; 193 return -1;
194 } 194 }
195 195
196 if (-1 == (fd = open ("/dev/net/tun", O_RDWR))) 196 if (-1 == (fd = open("/dev/net/tun", O_RDWR)))
197 { 197 {
198 fprintf (stderr, "Error opening `%s': %s\n", "/dev/net/tun", 198 fprintf(stderr, "Error opening `%s': %s\n", "/dev/net/tun",
199 strerror (errno)); 199 strerror(errno));
200 return -1; 200 return -1;
201 } 201 }
202 202
203 if (fd >= FD_SETSIZE) 203 if (fd >= FD_SETSIZE)
204 { 204 {
205 fprintf (stderr, "File descriptor to large: %d", fd); 205 fprintf(stderr, "File descriptor to large: %d", fd);
206 (void) close (fd); 206 (void)close(fd);
207 return -1; 207 return -1;
208 } 208 }
209 209
210 memset (&ifr, 0, sizeof (ifr)); 210 memset(&ifr, 0, sizeof(ifr));
211 ifr.ifr_flags = IFF_TUN; 211 ifr.ifr_flags = IFF_TUN;
212 212
213 if ('\0' != *dev) 213 if ('\0' != *dev)
214 strncpy (ifr.ifr_name, dev, IFNAMSIZ); 214 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
215 215
216 if (-1 == ioctl (fd, TUNSETIFF, (void *) &ifr)) 216 if (-1 == ioctl(fd, TUNSETIFF, (void *)&ifr))
217 { 217 {
218 fprintf (stderr, 218 fprintf(stderr,
219 "Error with ioctl on `%s': %s\n", "/dev/net/tun", 219 "Error with ioctl on `%s': %s\n", "/dev/net/tun",
220 strerror (errno)); 220 strerror(errno));
221 (void) close (fd); 221 (void)close(fd);
222 return -1; 222 return -1;
223 } 223 }
224 strcpy (dev, ifr.ifr_name); 224 strcpy(dev, ifr.ifr_name);
225 return fd; 225 return fd;
226} 226}
227 227
@@ -234,7 +234,7 @@ init_tun (char *dev)
234 * @param prefix_len the length of the network-prefix 234 * @param prefix_len the length of the network-prefix
235 */ 235 */
236static void 236static void
237set_address6 (const char *dev, const char *address, unsigned long prefix_len) 237set_address6(const char *dev, const char *address, unsigned long prefix_len)
238{ 238{
239 struct ifreq ifr; 239 struct ifreq ifr;
240 struct sockaddr_in6 sa6; 240 struct sockaddr_in6 sa6;
@@ -244,34 +244,34 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len)
244 /* 244 /*
245 * parse the new address 245 * parse the new address
246 */ 246 */
247 memset (&sa6, 0, sizeof (struct sockaddr_in6)); 247 memset(&sa6, 0, sizeof(struct sockaddr_in6));
248 sa6.sin6_family = AF_INET6; 248 sa6.sin6_family = AF_INET6;
249 if (1 != inet_pton (AF_INET6, address, &sa6.sin6_addr)) 249 if (1 != inet_pton(AF_INET6, address, &sa6.sin6_addr))
250 { 250 {
251 fprintf (stderr, "Failed to parse address `%s': %s\n", address, 251 fprintf(stderr, "Failed to parse address `%s': %s\n", address,
252 strerror (errno)); 252 strerror(errno));
253 exit (1); 253 exit(1);
254 } 254 }
255 255
256 if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0))) 256 if (-1 == (fd = socket(PF_INET6, SOCK_DGRAM, 0)))
257 { 257 {
258 fprintf (stderr, "Error creating socket: %s\n", strerror (errno)); 258 fprintf(stderr, "Error creating socket: %s\n", strerror(errno));
259 exit (1); 259 exit(1);
260 } 260 }
261 261
262 memset (&ifr, 0, sizeof (struct ifreq)); 262 memset(&ifr, 0, sizeof(struct ifreq));
263 /* 263 /*
264 * Get the index of the if 264 * Get the index of the if
265 */ 265 */
266 strncpy (ifr.ifr_name, dev, IFNAMSIZ); 266 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
267 if (-1 == ioctl (fd, SIOGIFINDEX, &ifr)) 267 if (-1 == ioctl(fd, SIOGIFINDEX, &ifr))
268 { 268 {
269 fprintf (stderr, "ioctl failed at %d: %s\n", __LINE__, strerror (errno)); 269 fprintf(stderr, "ioctl failed at %d: %s\n", __LINE__, strerror(errno));
270 (void) close (fd); 270 (void)close(fd);
271 exit (1); 271 exit(1);
272 } 272 }
273 273
274 memset (&ifr6, 0, sizeof (struct in6_ifreq)); 274 memset(&ifr6, 0, sizeof(struct in6_ifreq));
275 ifr6.ifr6_addr = sa6.sin6_addr; 275 ifr6.ifr6_addr = sa6.sin6_addr;
276 ifr6.ifr6_ifindex = ifr.ifr_ifindex; 276 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
277 ifr6.ifr6_prefixlen = prefix_len; 277 ifr6.ifr6_prefixlen = prefix_len;
@@ -279,42 +279,42 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len)
279 /* 279 /*
280 * Set the address 280 * Set the address
281 */ 281 */
282 if (-1 == ioctl (fd, SIOCSIFADDR, &ifr6)) 282 if (-1 == ioctl(fd, SIOCSIFADDR, &ifr6))
283 { 283 {
284 fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__, 284 fprintf(stderr, "ioctl failed at line %d: %s\n", __LINE__,
285 strerror (errno)); 285 strerror(errno));
286 (void) close (fd); 286 (void)close(fd);
287 exit (1); 287 exit(1);
288 } 288 }
289 289
290 /* 290 /*
291 * Get the flags 291 * Get the flags
292 */ 292 */
293 if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) 293 if (-1 == ioctl(fd, SIOCGIFFLAGS, &ifr))
294 { 294 {
295 fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__, 295 fprintf(stderr, "ioctl failed at line %d: %s\n", __LINE__,
296 strerror (errno)); 296 strerror(errno));
297 (void) close (fd); 297 (void)close(fd);
298 exit (1); 298 exit(1);
299 } 299 }
300 300
301 /* 301 /*
302 * Add the UP and RUNNING flags 302 * Add the UP and RUNNING flags
303 */ 303 */
304 ifr.ifr_flags |= IFF_UP | IFF_RUNNING; 304 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
305 if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) 305 if (-1 == ioctl(fd, SIOCSIFFLAGS, &ifr))
306 { 306 {
307 fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__, 307 fprintf(stderr, "ioctl failed at line %d: %s\n", __LINE__,
308 strerror (errno)); 308 strerror(errno));
309 (void) close (fd); 309 (void)close(fd);
310 exit (1); 310 exit(1);
311 } 311 }
312 312
313 if (0 != close (fd)) 313 if (0 != close(fd))
314 { 314 {
315 fprintf (stderr, "close failed: %s\n", strerror (errno)); 315 fprintf(stderr, "close failed: %s\n", strerror(errno));
316 exit (1); 316 exit(1);
317 } 317 }
318} 318}
319 319
320 320
@@ -326,96 +326,96 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len)
326 * @param mask the netmask 326 * @param mask the netmask
327 */ 327 */
328static void 328static void
329set_address4 (const char *dev, const char *address, const char *mask) 329set_address4(const char *dev, const char *address, const char *mask)
330{ 330{
331 int fd; 331 int fd;
332 struct sockaddr_in *addr; 332 struct sockaddr_in *addr;
333 struct ifreq ifr; 333 struct ifreq ifr;
334 334
335 memset (&ifr, 0, sizeof (struct ifreq)); 335 memset(&ifr, 0, sizeof(struct ifreq));
336 addr = (struct sockaddr_in *) &(ifr.ifr_addr); 336 addr = (struct sockaddr_in *)&(ifr.ifr_addr);
337 addr->sin_family = AF_INET; 337 addr->sin_family = AF_INET;
338 338
339 /* 339 /*
340 * Parse the address 340 * Parse the address
341 */ 341 */
342 if (1 != inet_pton (AF_INET, address, &addr->sin_addr.s_addr)) 342 if (1 != inet_pton(AF_INET, address, &addr->sin_addr.s_addr))
343 { 343 {
344 fprintf (stderr, "Failed to parse address `%s': %s\n", address, 344 fprintf(stderr, "Failed to parse address `%s': %s\n", address,
345 strerror (errno)); 345 strerror(errno));
346 exit (1); 346 exit(1);
347 } 347 }
348 348
349 if (-1 == (fd = socket (PF_INET, SOCK_DGRAM, 0))) 349 if (-1 == (fd = socket(PF_INET, SOCK_DGRAM, 0)))
350 { 350 {
351 fprintf (stderr, "Error creating socket: %s\n", strerror (errno)); 351 fprintf(stderr, "Error creating socket: %s\n", strerror(errno));
352 exit (1); 352 exit(1);
353 } 353 }
354 354
355 strncpy (ifr.ifr_name, dev, IFNAMSIZ); 355 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
356 356
357 /* 357 /*
358 * Set the address 358 * Set the address
359 */ 359 */
360 if (-1 == ioctl (fd, SIOCSIFADDR, &ifr)) 360 if (-1 == ioctl(fd, SIOCSIFADDR, &ifr))
361 { 361 {
362 fprintf (stderr, "ioctl failed at %d: %s\n", __LINE__, strerror (errno)); 362 fprintf(stderr, "ioctl failed at %d: %s\n", __LINE__, strerror(errno));
363 (void) close (fd); 363 (void)close(fd);
364 exit (1); 364 exit(1);
365 } 365 }
366 366
367 /* 367 /*
368 * Parse the netmask 368 * Parse the netmask
369 */ 369 */
370 addr = (struct sockaddr_in *) &(ifr.ifr_netmask); 370 addr = (struct sockaddr_in *)&(ifr.ifr_netmask);
371 if (1 != inet_pton (AF_INET, mask, &addr->sin_addr.s_addr)) 371 if (1 != inet_pton(AF_INET, mask, &addr->sin_addr.s_addr))
372 { 372 {
373 fprintf (stderr, "Failed to parse address `%s': %s\n", mask, 373 fprintf(stderr, "Failed to parse address `%s': %s\n", mask,
374 strerror (errno)); 374 strerror(errno));
375 (void) close (fd); 375 (void)close(fd);
376 exit (1); 376 exit(1);
377 } 377 }
378 378
379 /* 379 /*
380 * Set the netmask 380 * Set the netmask
381 */ 381 */
382 if (-1 == ioctl (fd, SIOCSIFNETMASK, &ifr)) 382 if (-1 == ioctl(fd, SIOCSIFNETMASK, &ifr))
383 { 383 {
384 fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__, 384 fprintf(stderr, "ioctl failed at line %d: %s\n", __LINE__,
385 strerror (errno)); 385 strerror(errno));
386 (void) close (fd); 386 (void)close(fd);
387 exit (1); 387 exit(1);
388 } 388 }
389 389
390 /* 390 /*
391 * Get the flags 391 * Get the flags
392 */ 392 */
393 if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) 393 if (-1 == ioctl(fd, SIOCGIFFLAGS, &ifr))
394 { 394 {
395 fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__, 395 fprintf(stderr, "ioctl failed at line %d: %s\n", __LINE__,
396 strerror (errno)); 396 strerror(errno));
397 (void) close (fd); 397 (void)close(fd);
398 exit (1); 398 exit(1);
399 } 399 }
400 400
401 /* 401 /*
402 * Add the UP and RUNNING flags 402 * Add the UP and RUNNING flags
403 */ 403 */
404 ifr.ifr_flags |= IFF_UP | IFF_RUNNING; 404 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
405 if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) 405 if (-1 == ioctl(fd, SIOCSIFFLAGS, &ifr))
406 { 406 {
407 fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__, 407 fprintf(stderr, "ioctl failed at line %d: %s\n", __LINE__,
408 strerror (errno)); 408 strerror(errno));
409 (void) close (fd); 409 (void)close(fd);
410 exit (1); 410 exit(1);
411 } 411 }
412 412
413 if (0 != close (fd)) 413 if (0 != close(fd))
414 { 414 {
415 fprintf (stderr, "close failed: %s\n", strerror (errno)); 415 fprintf(stderr, "close failed: %s\n", strerror(errno));
416 (void) close (fd); 416 (void)close(fd);
417 exit (1); 417 exit(1);
418 } 418 }
419} 419}
420 420
421 421
@@ -425,7 +425,7 @@ set_address4 (const char *dev, const char *address, const char *mask)
425 * @param fd_tun tunnel FD 425 * @param fd_tun tunnel FD
426 */ 426 */
427static void 427static void
428run (int fd_tun) 428run(int fd_tun)
429{ 429{
430 /* 430 /*
431 * The buffer filled by reading from fd_tun 431 * The buffer filled by reading from fd_tun
@@ -452,188 +452,188 @@ run (int fd_tun)
452 int write_open = 1; 452 int write_open = 1;
453 453
454 while ((1 == read_open) && (1 == write_open)) 454 while ((1 == read_open) && (1 == write_open))
455 { 455 {
456 FD_ZERO (&fds_w); 456 FD_ZERO(&fds_w);
457 FD_ZERO (&fds_r); 457 FD_ZERO(&fds_r);
458 458
459 /* 459 /*
460 * We are supposed to read and the buffer is empty 460 * We are supposed to read and the buffer is empty
461 * -> select on read from tun 461 * -> select on read from tun
462 */ 462 */
463 if (read_open && (0 == buftun_size)) 463 if (read_open && (0 == buftun_size))
464 FD_SET (fd_tun, &fds_r); 464 FD_SET(fd_tun, &fds_r);
465 465
466 /* 466 /*
467 * We are supposed to read and the buffer is not empty 467 * We are supposed to read and the buffer is not empty
468 * -> select on write to stdout 468 * -> select on write to stdout
469 */ 469 */
470 if (read_open && (0 != buftun_size)) 470 if (read_open && (0 != buftun_size))
471 FD_SET (1, &fds_w); 471 FD_SET(1, &fds_w);
472 472
473 /* 473 /*
474 * We are supposed to write and the buffer is empty 474 * We are supposed to write and the buffer is empty
475 * -> select on read from stdin 475 * -> select on read from stdin
476 */ 476 */
477 if (write_open && (NULL == bufin_read)) 477 if (write_open && (NULL == bufin_read))
478 FD_SET (0, &fds_r); 478 FD_SET(0, &fds_r);
479 479
480 /* 480 /*
481 * We are supposed to write and the buffer is not empty 481 * We are supposed to write and the buffer is not empty
482 * -> select on write to tun 482 * -> select on write to tun
483 */ 483 */
484 if (write_open && (NULL != bufin_read)) 484 if (write_open && (NULL != bufin_read))
485 FD_SET (fd_tun, &fds_w); 485 FD_SET(fd_tun, &fds_w);
486 486
487 int r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL); 487 int r = select(fd_tun + 1, &fds_r, &fds_w, NULL, NULL);
488 488
489 if (-1 == r) 489 if (-1 == r)
490 {
491 if (EINTR == errno)
492 continue;
493 fprintf (stderr, "select failed: %s\n", strerror (errno));
494 exit (1);
495 }
496
497 if (r > 0)
498 {
499 if (FD_ISSET (fd_tun, &fds_r))
500 {
501 buftun_size =
502 read (fd_tun, buftun + sizeof (struct GNUNET_MessageHeader),
503 MAX_SIZE - sizeof (struct GNUNET_MessageHeader));
504 if (-1 == buftun_size)
505 { 490 {
506 fprintf (stderr, 491 if (EINTR == errno)
507 "read-error: %s\n", 492 continue;
508 strerror (errno)); 493 fprintf(stderr, "select failed: %s\n", strerror(errno));
509 shutdown (fd_tun, SHUT_RD); 494 exit(1);
510 shutdown (1, SHUT_WR);
511 read_open = 0;
512 buftun_size = 0;
513 } 495 }
514 else if (0 == buftun_size) 496
497 if (r > 0)
515 { 498 {
499 if (FD_ISSET(fd_tun, &fds_r))
500 {
501 buftun_size =
502 read(fd_tun, buftun + sizeof(struct GNUNET_MessageHeader),
503 MAX_SIZE - sizeof(struct GNUNET_MessageHeader));
504 if (-1 == buftun_size)
505 {
506 fprintf(stderr,
507 "read-error: %s\n",
508 strerror(errno));
509 shutdown(fd_tun, SHUT_RD);
510 shutdown(1, SHUT_WR);
511 read_open = 0;
512 buftun_size = 0;
513 }
514 else if (0 == buftun_size)
515 {
516#if DEBUG 516#if DEBUG
517 fprintf (stderr, "EOF on tun\n"); 517 fprintf(stderr, "EOF on tun\n");
518#endif 518#endif
519 shutdown (fd_tun, SHUT_RD); 519 shutdown(fd_tun, SHUT_RD);
520 shutdown (1, SHUT_WR); 520 shutdown(1, SHUT_WR);
521 read_open = 0; 521 read_open = 0;
522 buftun_size = 0; 522 buftun_size = 0;
523 } 523 }
524 else 524 else
525 { 525 {
526 buftun_read = buftun; 526 buftun_read = buftun;
527 struct GNUNET_MessageHeader *hdr = 527 struct GNUNET_MessageHeader *hdr =
528 (struct GNUNET_MessageHeader *) buftun; 528 (struct GNUNET_MessageHeader *)buftun;
529 buftun_size += sizeof (struct GNUNET_MessageHeader); 529 buftun_size += sizeof(struct GNUNET_MessageHeader);
530 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 530 hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
531 hdr->size = htons (buftun_size); 531 hdr->size = htons(buftun_size);
532 } 532 }
533 } 533 }
534 else if (FD_ISSET (1, &fds_w)) 534 else if (FD_ISSET(1, &fds_w))
535 { 535 {
536 ssize_t written = write (1, buftun_read, buftun_size); 536 ssize_t written = write(1, buftun_read, buftun_size);
537 537
538 if (-1 == written) 538 if (-1 == written)
539 { 539 {
540#if !DEBUG 540#if !DEBUG
541 if (errno != EPIPE) 541 if (errno != EPIPE)
542#endif 542#endif
543 fprintf (stderr, 543 fprintf(stderr,
544 "write-error to stdout: %s\n", 544 "write-error to stdout: %s\n",
545 strerror (errno)); 545 strerror(errno));
546 shutdown (fd_tun, SHUT_RD); 546 shutdown(fd_tun, SHUT_RD);
547 shutdown (1, SHUT_WR); 547 shutdown(1, SHUT_WR);
548 read_open = 0; 548 read_open = 0;
549 buftun_size = 0; 549 buftun_size = 0;
550 } 550 }
551 else if (0 == written) 551 else if (0 == written)
552 { 552 {
553 fprintf (stderr, "write returned 0!?\n"); 553 fprintf(stderr, "write returned 0!?\n");
554 exit (1); 554 exit(1);
555 } 555 }
556 else 556 else
557 { 557 {
558 buftun_size -= written; 558 buftun_size -= written;
559 buftun_read += written; 559 buftun_read += written;
560 } 560 }
561 } 561 }
562 562
563 if (FD_ISSET (0, &fds_r)) 563 if (FD_ISSET(0, &fds_r))
564 { 564 {
565 bufin_size = read (0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos); 565 bufin_size = read(0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos);
566 if (-1 == bufin_size) 566 if (-1 == bufin_size)
567 { 567 {
568 fprintf (stderr, "read-error: %s\n", strerror (errno)); 568 fprintf(stderr, "read-error: %s\n", strerror(errno));
569 shutdown (0, SHUT_RD); 569 shutdown(0, SHUT_RD);
570 shutdown (fd_tun, SHUT_WR); 570 shutdown(fd_tun, SHUT_WR);
571 write_open = 0; 571 write_open = 0;
572 bufin_size = 0; 572 bufin_size = 0;
573 } 573 }
574 else if (0 == bufin_size) 574 else if (0 == bufin_size)
575 { 575 {
576#if DEBUG 576#if DEBUG
577 fprintf (stderr, "EOF on stdin\n"); 577 fprintf(stderr, "EOF on stdin\n");
578#endif 578#endif
579 shutdown (0, SHUT_RD); 579 shutdown(0, SHUT_RD);
580 shutdown (fd_tun, SHUT_WR); 580 shutdown(fd_tun, SHUT_WR);
581 write_open = 0; 581 write_open = 0;
582 bufin_size = 0; 582 bufin_size = 0;
583 } 583 }
584 else 584 else
585 { 585 {
586 struct GNUNET_MessageHeader *hdr; 586 struct GNUNET_MessageHeader *hdr;
587 587
588PROCESS_BUFFER: 588PROCESS_BUFFER:
589 bufin_rpos += bufin_size; 589 bufin_rpos += bufin_size;
590 if (bufin_rpos < sizeof (struct GNUNET_MessageHeader)) 590 if (bufin_rpos < sizeof(struct GNUNET_MessageHeader))
591 continue; 591 continue;
592 hdr = (struct GNUNET_MessageHeader *) bufin; 592 hdr = (struct GNUNET_MessageHeader *)bufin;
593 if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) 593 if (ntohs(hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
594 { 594 {
595 fprintf (stderr, "protocol violation!\n"); 595 fprintf(stderr, "protocol violation!\n");
596 exit (1); 596 exit(1);
597 } 597 }
598 if (ntohs (hdr->size) > bufin_rpos) 598 if (ntohs(hdr->size) > bufin_rpos)
599 continue; 599 continue;
600 bufin_read = bufin + sizeof (struct GNUNET_MessageHeader); 600 bufin_read = bufin + sizeof(struct GNUNET_MessageHeader);
601 bufin_size = ntohs (hdr->size) - sizeof (struct GNUNET_MessageHeader); 601 bufin_size = ntohs(hdr->size) - sizeof(struct GNUNET_MessageHeader);
602 bufin_rpos -= bufin_size + sizeof (struct GNUNET_MessageHeader); 602 bufin_rpos -= bufin_size + sizeof(struct GNUNET_MessageHeader);
603 } 603 }
604 } 604 }
605 else if (FD_ISSET (fd_tun, &fds_w)) 605 else if (FD_ISSET(fd_tun, &fds_w))
606 { 606 {
607 ssize_t written = write (fd_tun, bufin_read, bufin_size); 607 ssize_t written = write(fd_tun, bufin_read, bufin_size);
608 608
609 if (-1 == written) 609 if (-1 == written)
610 { 610 {
611 fprintf (stderr, "write-error to tun: %s\n", strerror (errno)); 611 fprintf(stderr, "write-error to tun: %s\n", strerror(errno));
612 shutdown (0, SHUT_RD); 612 shutdown(0, SHUT_RD);
613 shutdown (fd_tun, SHUT_WR); 613 shutdown(fd_tun, SHUT_WR);
614 write_open = 0; 614 write_open = 0;
615 bufin_size = 0; 615 bufin_size = 0;
616 }
617 else if (0 == written)
618 {
619 fprintf(stderr, "write returned 0!?\n");
620 exit(1);
621 }
622 else
623 {
624 bufin_size -= written;
625 bufin_read += written;
626 if (0 == bufin_size)
627 {
628 memmove(bufin, bufin_read, bufin_rpos);
629 bufin_read = NULL; /* start reading again */
630 bufin_size = 0;
631 goto PROCESS_BUFFER;
632 }
633 }
634 }
616 } 635 }
617 else if (0 == written)
618 {
619 fprintf (stderr, "write returned 0!?\n");
620 exit (1);
621 }
622 else
623 {
624 bufin_size -= written;
625 bufin_read += written;
626 if (0 == bufin_size)
627 {
628 memmove (bufin, bufin_read, bufin_rpos);
629 bufin_read = NULL; /* start reading again */
630 bufin_size = 0;
631 goto PROCESS_BUFFER;
632 }
633 }
634 }
635 } 636 }
636 }
637} 637}
638 638
639 639
@@ -651,166 +651,166 @@ PROCESS_BUFFER:
651 * 6: IPv4 netmask ("255.255.0.0") [ignored if #4 is "-"] 651 * 6: IPv4 netmask ("255.255.0.0") [ignored if #4 is "-"]
652 */ 652 */
653int 653int
654main (int argc, char **argv) 654main(int argc, char **argv)
655{ 655{
656 char dev[IFNAMSIZ]; 656 char dev[IFNAMSIZ];
657 int fd_tun; 657 int fd_tun;
658 int global_ret; 658 int global_ret;
659 659
660 if (7 != argc) 660 if (7 != argc)
661 { 661 {
662 fprintf (stderr, "Fatal: must supply 6 arguments!\n"); 662 fprintf(stderr, "Fatal: must supply 6 arguments!\n");
663 return 1;
664 }
665 if ( (0 == strcmp (argv[3], "-")) &&
666 (0 == strcmp (argv[5], "-")) )
667 {
668 fprintf (stderr, "Fatal: disabling both IPv4 and IPv6 makes no sense.\n");
669 return 1;
670 }
671 if (0 != strcmp (argv[2], "-"))
672 {
673#ifdef IPTABLES
674 if (0 == access (IPTABLES, X_OK))
675 sbin_iptables = IPTABLES;
676 else
677#endif
678 if (0 == access ("/sbin/iptables", X_OK))
679 sbin_iptables = "/sbin/iptables";
680 else if (0 == access ("/usr/sbin/iptables", X_OK))
681 sbin_iptables = "/usr/sbin/iptables";
682 else
683 {
684 fprintf (stderr,
685 "Fatal: executable iptables not found in approved directories: %s\n",
686 strerror (errno));
687 return 1; 663 return 1;
688 } 664 }
665 if ((0 == strcmp(argv[3], "-")) &&
666 (0 == strcmp(argv[5], "-")))
667 {
668 fprintf(stderr, "Fatal: disabling both IPv4 and IPv6 makes no sense.\n");
669 return 1;
670 }
671 if (0 != strcmp(argv[2], "-"))
672 {
673#ifdef IPTABLES
674 if (0 == access(IPTABLES, X_OK))
675 sbin_iptables = IPTABLES;
676 else
677#endif
678 if (0 == access("/sbin/iptables", X_OK))
679 sbin_iptables = "/sbin/iptables";
680 else if (0 == access("/usr/sbin/iptables", X_OK))
681 sbin_iptables = "/usr/sbin/iptables";
682 else
683 {
684 fprintf(stderr,
685 "Fatal: executable iptables not found in approved directories: %s\n",
686 strerror(errno));
687 return 1;
688 }
689#ifdef SYSCTL 689#ifdef SYSCTL
690 if (0 == access (SYSCTL, X_OK)) 690 if (0 == access(SYSCTL, X_OK))
691 sbin_sysctl = SYSCTL; 691 sbin_sysctl = SYSCTL;
692 else 692 else
693#endif 693#endif
694 if (0 == access ("/sbin/sysctl", X_OK)) 694 if (0 == access("/sbin/sysctl", X_OK))
695 sbin_sysctl = "/sbin/sysctl"; 695 sbin_sysctl = "/sbin/sysctl";
696 else if (0 == access ("/usr/sbin/sysctl", X_OK)) 696 else if (0 == access("/usr/sbin/sysctl", X_OK))
697 sbin_sysctl = "/usr/sbin/sysctl"; 697 sbin_sysctl = "/usr/sbin/sysctl";
698 else 698 else
699 { 699 {
700 fprintf (stderr, 700 fprintf(stderr,
701 "Fatal: executable sysctl not found in approved directories: %s\n", 701 "Fatal: executable sysctl not found in approved directories: %s\n",
702 strerror (errno)); 702 strerror(errno));
703 return 1; 703 return 1;
704 }
704 } 705 }
705 }
706 706
707 strncpy (dev, argv[1], IFNAMSIZ); 707 strncpy(dev, argv[1], IFNAMSIZ);
708 dev[IFNAMSIZ - 1] = '\0'; 708 dev[IFNAMSIZ - 1] = '\0';
709 709
710 if (-1 == (fd_tun = init_tun (dev))) 710 if (-1 == (fd_tun = init_tun(dev)))
711 {
712 fprintf (stderr,
713 "Fatal: could not initialize tun-interface `%s' with IPv6 %s/%s and IPv4 %s/%s\n",
714 dev,
715 argv[3],
716 argv[4],
717 argv[5],
718 argv[6]);
719 return 1;
720 }
721
722 if (0 != strcmp (argv[3], "-"))
723 {
724 { 711 {
725 const char *address = argv[3]; 712 fprintf(stderr,
726 long prefix_len = atol (argv[4]); 713 "Fatal: could not initialize tun-interface `%s' with IPv6 %s/%s and IPv4 %s/%s\n",
727 714 dev,
728 if ((prefix_len < 1) || (prefix_len > 127)) 715 argv[3],
729 { 716 argv[4],
730 fprintf (stderr, "Fatal: prefix_len out of range\n"); 717 argv[5],
731 return 1; 718 argv[6]);
732 } 719 return 1;
733 set_address6 (dev, address, prefix_len);
734 } 720 }
735 if (0 != strcmp (argv[2], "-")) 721
722 if (0 != strcmp(argv[3], "-"))
736 { 723 {
737 char *const sysctl_args[] =
738 {
739 "sysctl", "-w", "net.ipv6.conf.all.forwarding=1", NULL
740 };
741 if (0 != fork_and_exec (sbin_sysctl,
742 sysctl_args))
743 { 724 {
744 fprintf (stderr, 725 const char *address = argv[3];
745 "Failed to enable IPv6 forwarding. Will continue anyway.\n"); 726 long prefix_len = atol(argv[4]);
727
728 if ((prefix_len < 1) || (prefix_len > 127))
729 {
730 fprintf(stderr, "Fatal: prefix_len out of range\n");
731 return 1;
732 }
733 set_address6(dev, address, prefix_len);
746 } 734 }
735 if (0 != strcmp(argv[2], "-"))
736 {
737 char *const sysctl_args[] =
738 {
739 "sysctl", "-w", "net.ipv6.conf.all.forwarding=1", NULL
740 };
741 if (0 != fork_and_exec(sbin_sysctl,
742 sysctl_args))
743 {
744 fprintf(stderr,
745 "Failed to enable IPv6 forwarding. Will continue anyway.\n");
746 }
747 }
747 } 748 }
748 }
749 749
750 if (0 != strcmp (argv[5], "-")) 750 if (0 != strcmp(argv[5], "-"))
751 {
752 {
753 const char *address = argv[5];
754 const char *mask = argv[6];
755
756 set_address4 (dev, address, mask);
757 }
758 if (0 != strcmp (argv[2], "-"))
759 { 751 {
760 { 752 {
761 char *const sysctl_args[] = 753 const char *address = argv[5];
762 { 754 const char *mask = argv[6];
763 "sysctl", "-w", "net.ipv4.ip_forward=1", NULL 755
764 }; 756 set_address4(dev, address, mask);
765 if (0 != fork_and_exec (sbin_sysctl,
766 sysctl_args))
767 {
768 fprintf (stderr,
769 "Failed to enable IPv4 forwarding. Will continue anyway.\n");
770 }
771 } 757 }
772 { 758 if (0 != strcmp(argv[2], "-"))
773 char *const iptables_args[] =
774 {
775 "iptables", "-t", "nat", "-A", "POSTROUTING", "-o", argv[2], "-j", "MASQUERADE", NULL
776 };
777 if (0 != fork_and_exec (sbin_iptables,
778 iptables_args))
779 { 759 {
780 fprintf (stderr, 760 {
781 "Failed to enable IPv4 masquerading (NAT). Will continue anyway.\n"); 761 char *const sysctl_args[] =
762 {
763 "sysctl", "-w", "net.ipv4.ip_forward=1", NULL
764 };
765 if (0 != fork_and_exec(sbin_sysctl,
766 sysctl_args))
767 {
768 fprintf(stderr,
769 "Failed to enable IPv4 forwarding. Will continue anyway.\n");
770 }
771 }
772 {
773 char *const iptables_args[] =
774 {
775 "iptables", "-t", "nat", "-A", "POSTROUTING", "-o", argv[2], "-j", "MASQUERADE", NULL
776 };
777 if (0 != fork_and_exec(sbin_iptables,
778 iptables_args))
779 {
780 fprintf(stderr,
781 "Failed to enable IPv4 masquerading (NAT). Will continue anyway.\n");
782 }
783 }
782 } 784 }
783 }
784 } 785 }
785 }
786 786
787 uid_t uid = getuid (); 787 uid_t uid = getuid();
788#ifdef HAVE_SETRESUID 788#ifdef HAVE_SETRESUID
789 if (0 != setresuid (uid, uid, uid)) 789 if (0 != setresuid(uid, uid, uid))
790 { 790 {
791 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); 791 fprintf(stderr, "Failed to setresuid: %s\n", strerror(errno));
792 global_ret = 2; 792 global_ret = 2;
793 goto cleanup; 793 goto cleanup;
794 } 794 }
795#else 795#else
796 if (0 != (setuid (uid) | seteuid (uid))) 796 if (0 != (setuid(uid) | seteuid(uid)))
797 { 797 {
798 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno)); 798 fprintf(stderr, "Failed to setuid: %s\n", strerror(errno));
799 global_ret = 2; 799 global_ret = 2;
800 goto cleanup; 800 goto cleanup;
801 } 801 }
802#endif 802#endif
803 803
804 if (SIG_ERR == signal (SIGPIPE, SIG_IGN)) 804 if (SIG_ERR == signal(SIGPIPE, SIG_IGN))
805 { 805 {
806 fprintf (stderr, "Failed to protect against SIGPIPE: %s\n", 806 fprintf(stderr, "Failed to protect against SIGPIPE: %s\n",
807 strerror (errno)); 807 strerror(errno));
808 /* no exit, we might as well die with SIGPIPE should it ever happen */ 808 /* no exit, we might as well die with SIGPIPE should it ever happen */
809 } 809 }
810 run (fd_tun); 810 run(fd_tun);
811 global_ret = 0; 811 global_ret = 0;
812 cleanup: 812cleanup:
813 (void) close (fd_tun); 813 (void)close(fd_tun);
814 return global_ret; 814 return global_ret;
815} 815}
816 816