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