summaryrefslogtreecommitdiff
path: root/src/vpn/gnunet-helper-vpn.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vpn/gnunet-helper-vpn.c')
-rw-r--r--src/vpn/gnunet-helper-vpn.c897
1 files changed, 448 insertions, 449 deletions
diff --git a/src/vpn/gnunet-helper-vpn.c b/src/vpn/gnunet-helper-vpn.c
index e621b8716..4b4073418 100644
--- a/src/vpn/gnunet-helper-vpn.c
+++ b/src/vpn/gnunet-helper-vpn.c
@@ -11,12 +11,12 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
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 vpn/gnunet-helper-vpn.c 22 * @file vpn/gnunet-helper-vpn.c
@@ -61,8 +61,7 @@
61/** 61/**
62 * This is in linux/include/net/ipv6.h, but not always exported... 62 * This is in linux/include/net/ipv6.h, but not always exported...
63 */ 63 */
64struct in6_ifreq 64struct in6_ifreq {
65{
66 struct in6_addr ifr6_addr; 65 struct in6_addr ifr6_addr;
67 uint32_t ifr6_prefixlen; 66 uint32_t ifr6_prefixlen;
68 unsigned int ifr6_ifindex; 67 unsigned int ifr6_ifindex;
@@ -78,55 +77,55 @@ struct in6_ifreq
78 * @return the fd to the tun or -1 on error 77 * @return the fd to the tun or -1 on error
79 */ 78 */
80static int 79static int
81init_tun (char *dev) 80init_tun(char *dev)
82{ 81{
83 struct ifreq ifr; 82 struct ifreq ifr;
84 int fd; 83 int fd;
85 84
86 if (NULL == dev) 85 if (NULL == dev)
87 { 86 {
88 errno = EINVAL; 87 errno = EINVAL;
89 return -1; 88 return -1;
90 } 89 }
91 90
92 if (-1 == (fd = open ("/dev/net/tun", O_RDWR))) 91 if (-1 == (fd = open("/dev/net/tun", O_RDWR)))
93 { 92 {
94 fprintf (stderr, 93 fprintf(stderr,
95 "Error opening `%s': %s\n", 94 "Error opening `%s': %s\n",
96 "/dev/net/tun", 95 "/dev/net/tun",
97 strerror (errno)); 96 strerror(errno));
98 return -1; 97 return -1;
99 } 98 }
100 99
101 if (fd >= FD_SETSIZE) 100 if (fd >= FD_SETSIZE)
102 { 101 {
103 fprintf (stderr, 102 fprintf(stderr,
104 "File descriptor to large: %d", 103 "File descriptor to large: %d",
105 fd); 104 fd);
106 (void) close (fd); 105 (void)close(fd);
107 return -1; 106 return -1;
108 } 107 }
109 108
110 memset (&ifr, 0, sizeof (ifr)); 109 memset(&ifr, 0, sizeof(ifr));
111 ifr.ifr_flags = IFF_TUN; 110 ifr.ifr_flags = IFF_TUN;
112 111
113 if ('\0' != *dev) 112 if ('\0' != *dev)
114 strncpy (ifr.ifr_name, 113 strncpy(ifr.ifr_name,
115 dev, 114 dev,
116 IFNAMSIZ); 115 IFNAMSIZ);
117 116
118 if (-1 == ioctl (fd, 117 if (-1 == ioctl(fd,
119 TUNSETIFF, 118 TUNSETIFF,
120 (void *) &ifr)) 119 (void *)&ifr))
121 { 120 {
122 fprintf (stderr, 121 fprintf(stderr,
123 "Error with ioctl on `%s': %s\n", 122 "Error with ioctl on `%s': %s\n",
124 "/dev/net/tun", 123 "/dev/net/tun",
125 strerror (errno)); 124 strerror(errno));
126 (void) close (fd); 125 (void)close(fd);
127 return -1; 126 return -1;
128 } 127 }
129 strcpy (dev, ifr.ifr_name); 128 strcpy(dev, ifr.ifr_name);
130 return fd; 129 return fd;
131} 130}
132 131
@@ -139,9 +138,9 @@ init_tun (char *dev)
139 * @param prefix_len the length of the network-prefix 138 * @param prefix_len the length of the network-prefix
140 */ 139 */
141static void 140static void
142set_address6 (const char *dev, 141set_address6(const char *dev,
143 const char *address, 142 const char *address,
144 unsigned long prefix_len) 143 unsigned long prefix_len)
145{ 144{
146 struct ifreq ifr; 145 struct ifreq ifr;
147 struct in6_ifreq ifr6; 146 struct in6_ifreq ifr6;
@@ -151,44 +150,44 @@ set_address6 (const char *dev,
151 /* 150 /*
152 * parse the new address 151 * parse the new address
153 */ 152 */
154 memset (&sa6, 0, sizeof (struct sockaddr_in6)); 153 memset(&sa6, 0, sizeof(struct sockaddr_in6));
155 sa6.sin6_family = AF_INET6; 154 sa6.sin6_family = AF_INET6;
156 if (1 != inet_pton (AF_INET6, address, sa6.sin6_addr.s6_addr)) 155 if (1 != inet_pton(AF_INET6, address, sa6.sin6_addr.s6_addr))
157 { 156 {
158 fprintf (stderr, 157 fprintf(stderr,
159 "Failed to parse IPv6 address `%s'\n", 158 "Failed to parse IPv6 address `%s'\n",
160 address); 159 address);
161 exit (1); 160 exit(1);
162 } 161 }
163 162
164 if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0))) 163 if (-1 == (fd = socket(PF_INET6, SOCK_DGRAM, 0)))
165 { 164 {
166 fprintf (stderr, 165 fprintf(stderr,
167 "Error creating socket: %s\n", 166 "Error creating socket: %s\n",
168 strerror (errno)); 167 strerror(errno));
169 exit (1); 168 exit(1);
170 } 169 }
171 170
172 memset (&ifr, 0, sizeof (struct ifreq)); 171 memset(&ifr, 0, sizeof(struct ifreq));
173 /* 172 /*
174 * Get the index of the if 173 * Get the index of the if
175 */ 174 */
176 strncpy (ifr.ifr_name, 175 strncpy(ifr.ifr_name,
177 dev, 176 dev,
178 IFNAMSIZ); 177 IFNAMSIZ);
179 if (-1 == ioctl (fd, 178 if (-1 == ioctl(fd,
180 SIOGIFINDEX, 179 SIOGIFINDEX,
181 &ifr)) 180 &ifr))
182 { 181 {
183 fprintf (stderr, 182 fprintf(stderr,
184 "ioctl failed at %d: %s\n", 183 "ioctl failed at %d: %s\n",
185 __LINE__, 184 __LINE__,
186 strerror (errno)); 185 strerror(errno));
187 (void) close (fd); 186 (void)close(fd);
188 exit (1); 187 exit(1);
189 } 188 }
190 189
191 memset (&ifr6, 0, sizeof (struct in6_ifreq)); 190 memset(&ifr6, 0, sizeof(struct in6_ifreq));
192 ifr6.ifr6_addr = sa6.sin6_addr; 191 ifr6.ifr6_addr = sa6.sin6_addr;
193 ifr6.ifr6_ifindex = ifr.ifr_ifindex; 192 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
194 ifr6.ifr6_prefixlen = prefix_len; 193 ifr6.ifr6_prefixlen = prefix_len;
@@ -196,56 +195,56 @@ set_address6 (const char *dev,
196 /* 195 /*
197 * Set the address 196 * Set the address
198 */ 197 */
199 if (-1 == ioctl (fd, 198 if (-1 == ioctl(fd,
200 SIOCSIFADDR, 199 SIOCSIFADDR,
201 &ifr6)) 200 &ifr6))
202 { 201 {
203 fprintf (stderr, 202 fprintf(stderr,
204 "ioctl failed at line %d: %s\n", 203 "ioctl failed at line %d: %s\n",
205 __LINE__, 204 __LINE__,
206 strerror (errno)); 205 strerror(errno));
207 (void) close (fd); 206 (void)close(fd);
208 exit (1); 207 exit(1);
209 } 208 }
210 209
211 /* 210 /*
212 * Get the flags 211 * Get the flags
213 */ 212 */
214 if (-1 == ioctl (fd, 213 if (-1 == ioctl(fd,
215 SIOCGIFFLAGS, 214 SIOCGIFFLAGS,
216 &ifr)) 215 &ifr))
217 { 216 {
218 fprintf (stderr, 217 fprintf(stderr,
219 "ioctl failed at line %d: %s\n", 218 "ioctl failed at line %d: %s\n",
220 __LINE__, 219 __LINE__,
221 strerror (errno)); 220 strerror(errno));
222 (void) close (fd); 221 (void)close(fd);
223 exit (1); 222 exit(1);
224 } 223 }
225 224
226 /* 225 /*
227 * Add the UP and RUNNING flags 226 * Add the UP and RUNNING flags
228 */ 227 */
229 ifr.ifr_flags |= IFF_UP | IFF_RUNNING; 228 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
230 if (-1 == ioctl (fd, 229 if (-1 == ioctl(fd,
231 SIOCSIFFLAGS, 230 SIOCSIFFLAGS,
232 &ifr)) 231 &ifr))
233 { 232 {
234 fprintf (stderr, 233 fprintf(stderr,
235 "ioctl failed at line %d: %s\n", 234 "ioctl failed at line %d: %s\n",
236 __LINE__, 235 __LINE__,
237 strerror (errno)); 236 strerror(errno));
238 (void) close (fd); 237 (void)close(fd);
239 exit (1); 238 exit(1);
240 } 239 }
241 240
242 if (0 != close (fd)) 241 if (0 != close(fd))
243 { 242 {
244 fprintf (stderr, 243 fprintf(stderr,
245 "close failed: %s\n", 244 "close failed: %s\n",
246 strerror (errno)); 245 strerror(errno));
247 exit (1); 246 exit(1);
248 } 247 }
249} 248}
250 249
251 250
@@ -257,117 +256,117 @@ set_address6 (const char *dev,
257 * @param mask the netmask 256 * @param mask the netmask
258 */ 257 */
259static void 258static void
260set_address4 (const char *dev, 259set_address4(const char *dev,
261 const char *address, 260 const char *address,
262 const char *mask) 261 const char *mask)
263{ 262{
264 int fd; 263 int fd;
265 struct sockaddr_in *addr; 264 struct sockaddr_in *addr;
266 struct ifreq ifr; 265 struct ifreq ifr;
267 266
268 memset (&ifr, 0, sizeof (struct ifreq)); 267 memset(&ifr, 0, sizeof(struct ifreq));
269 addr = (struct sockaddr_in *) &(ifr.ifr_addr); 268 addr = (struct sockaddr_in *)&(ifr.ifr_addr);
270 addr->sin_family = AF_INET; 269 addr->sin_family = AF_INET;
271 270
272 /* 271 /*
273 * Parse the address 272 * Parse the address
274 */ 273 */
275 if (1 != inet_pton (AF_INET, 274 if (1 != inet_pton(AF_INET,
276 address, 275 address,
277 &addr->sin_addr.s_addr)) 276 &addr->sin_addr.s_addr))
278 { 277 {
279 fprintf (stderr, 278 fprintf(stderr,
280 "Failed to parse IPv4 address `%s'\n", 279 "Failed to parse IPv4 address `%s'\n",
281 address); 280 address);
282 exit (1); 281 exit(1);
283 } 282 }
284 283
285 if (-1 == (fd = socket (PF_INET, SOCK_DGRAM, 0))) 284 if (-1 == (fd = socket(PF_INET, SOCK_DGRAM, 0)))
286 { 285 {
287 fprintf (stderr, 286 fprintf(stderr,
288 "Error creating socket: %s\n", 287 "Error creating socket: %s\n",
289 strerror (errno)); 288 strerror(errno));
290 exit (1); 289 exit(1);
291 } 290 }
292 291
293 strncpy (ifr.ifr_name, dev, IFNAMSIZ); 292 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
294 293
295 /* 294 /*
296 * Set the address 295 * Set the address
297 */ 296 */
298 if (-1 == ioctl (fd, SIOCSIFADDR, &ifr)) 297 if (-1 == ioctl(fd, SIOCSIFADDR, &ifr))
299 { 298 {
300 fprintf (stderr, 299 fprintf(stderr,
301 "ioctl failed at %d: %s\n", 300 "ioctl failed at %d: %s\n",
302 __LINE__, 301 __LINE__,
303 strerror (errno)); 302 strerror(errno));
304 (void) close (fd); 303 (void)close(fd);
305 exit (1); 304 exit(1);
306 } 305 }
307 306
308 /* 307 /*
309 * Parse the netmask 308 * Parse the netmask
310 */ 309 */
311 addr = (struct sockaddr_in *) &(ifr.ifr_netmask); 310 addr = (struct sockaddr_in *)&(ifr.ifr_netmask);
312 if (1 != inet_pton (AF_INET, 311 if (1 != inet_pton(AF_INET,
313 mask, 312 mask,
314 &addr->sin_addr.s_addr)) 313 &addr->sin_addr.s_addr))
315 { 314 {
316 fprintf (stderr, 315 fprintf(stderr,
317 "Failed to parse IPv4 address mask `%s'\n", 316 "Failed to parse IPv4 address mask `%s'\n",
318 mask); 317 mask);
319 (void) close (fd); 318 (void)close(fd);
320 exit (1); 319 exit(1);
321 } 320 }
322 321
323 /* 322 /*
324 * Set the netmask 323 * Set the netmask
325 */ 324 */
326 if (-1 == ioctl (fd, SIOCSIFNETMASK, &ifr)) 325 if (-1 == ioctl(fd, SIOCSIFNETMASK, &ifr))
327 { 326 {
328 fprintf (stderr, 327 fprintf(stderr,
329 "ioctl failed at line %d: %s\n", 328 "ioctl failed at line %d: %s\n",
330 __LINE__, 329 __LINE__,
331 strerror (errno)); 330 strerror(errno));
332 (void) close (fd); 331 (void)close(fd);
333 exit (1); 332 exit(1);
334 } 333 }
335 334
336 /* 335 /*
337 * Get the flags 336 * Get the flags
338 */ 337 */
339 if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr)) 338 if (-1 == ioctl(fd, SIOCGIFFLAGS, &ifr))
340 { 339 {
341 fprintf (stderr, 340 fprintf(stderr,
342 "ioctl failed at line %d: %s\n", 341 "ioctl failed at line %d: %s\n",
343 __LINE__, 342 __LINE__,
344 strerror (errno)); 343 strerror(errno));
345 (void) close (fd); 344 (void)close(fd);
346 exit (1); 345 exit(1);
347 } 346 }
348 347
349 /* 348 /*
350 * Add the UP and RUNNING flags 349 * Add the UP and RUNNING flags
351 */ 350 */
352 ifr.ifr_flags |= IFF_UP | IFF_RUNNING; 351 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
353 if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr)) 352 if (-1 == ioctl(fd, SIOCSIFFLAGS, &ifr))
354 { 353 {
355 fprintf (stderr, 354 fprintf(stderr,
356 "ioctl failed at line %d: %s\n", 355 "ioctl failed at line %d: %s\n",
357 __LINE__, 356 __LINE__,
358 strerror (errno)); 357 strerror(errno));
359 (void) close (fd); 358 (void)close(fd);
360 exit (1); 359 exit(1);
361 } 360 }
362 361
363 if (0 != close (fd)) 362 if (0 != close(fd))
364 { 363 {
365 fprintf (stderr, 364 fprintf(stderr,
366 "close failed: %s\n", 365 "close failed: %s\n",
367 strerror (errno)); 366 strerror(errno));
368 (void) close (fd); 367 (void)close(fd);
369 exit (1); 368 exit(1);
370 } 369 }
371} 370}
372 371
373 372
@@ -377,7 +376,7 @@ set_address4 (const char *dev,
377 * @param fd_tun tunnel FD 376 * @param fd_tun tunnel FD
378 */ 377 */
379static void 378static void
380run (int fd_tun) 379run(int fd_tun)
381{ 380{
382 /* 381 /*
383 * The buffer filled by reading from fd_tun 382 * The buffer filled by reading from fd_tun
@@ -404,198 +403,198 @@ run (int fd_tun)
404 int write_open = 1; 403 int write_open = 1;
405 404
406 while ((1 == read_open) && (1 == write_open)) 405 while ((1 == read_open) && (1 == write_open))
407 {
408 FD_ZERO (&fds_w);
409 FD_ZERO (&fds_r);
410
411 /*
412 * We are supposed to read and the buffer is empty
413 * -> select on read from tun
414 */
415 if (read_open && (0 == buftun_size))
416 FD_SET (fd_tun, &fds_r);
417
418 /*
419 * We are supposed to read and the buffer is not empty
420 * -> select on write to stdout
421 */
422 if (read_open && (0 != buftun_size))
423 FD_SET (1, &fds_w);
424
425 /*
426 * We are supposed to write and the buffer is empty
427 * -> select on read from stdin
428 */
429 if (write_open && (NULL == bufin_read))
430 FD_SET (0, &fds_r);
431
432 /*
433 * We are supposed to write and the buffer is not empty
434 * -> select on write to tun
435 */
436 if (write_open && (NULL != bufin_read))
437 FD_SET (fd_tun, &fds_w);
438
439 int r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL);
440
441 if (-1 == r)
442 {
443 if (EINTR == errno)
444 continue;
445 fprintf (stderr,
446 "select failed: %s\n",
447 strerror (errno));
448 exit (1);
449 }
450
451 if (r > 0)
452 { 406 {
453 if (FD_ISSET (fd_tun, &fds_r)) 407 FD_ZERO(&fds_w);
454 { 408 FD_ZERO(&fds_r);
455 buftun_size = 409
456 read (fd_tun, buftun + sizeof (struct GNUNET_MessageHeader), 410 /*
457 MAX_SIZE - sizeof (struct GNUNET_MessageHeader)); 411 * We are supposed to read and the buffer is empty
458 if (-1 == buftun_size) 412 * -> select on read from tun
459 { 413 */
460 fprintf (stderr, 414 if (read_open && (0 == buftun_size))
461 "read-error: %s\n", 415 FD_SET(fd_tun, &fds_r);
462 strerror (errno)); 416
463 shutdown (fd_tun, SHUT_RD); 417 /*
464 shutdown (1, SHUT_WR); 418 * We are supposed to read and the buffer is not empty
465 read_open = 0; 419 * -> select on write to stdout
466 buftun_size = 0; 420 */
467 } 421 if (read_open && (0 != buftun_size))
468 else if (0 == buftun_size) 422 FD_SET(1, &fds_w);
469 { 423
470 fprintf (stderr, "EOF on tun\n"); 424 /*
471 shutdown (fd_tun, SHUT_RD); 425 * We are supposed to write and the buffer is empty
472 shutdown (1, SHUT_WR); 426 * -> select on read from stdin
473 read_open = 0; 427 */
474 buftun_size = 0; 428 if (write_open && (NULL == bufin_read))
475 } 429 FD_SET(0, &fds_r);
476 else 430
431 /*
432 * We are supposed to write and the buffer is not empty
433 * -> select on write to tun
434 */
435 if (write_open && (NULL != bufin_read))
436 FD_SET(fd_tun, &fds_w);
437
438 int r = select(fd_tun + 1, &fds_r, &fds_w, NULL, NULL);
439
440 if (-1 == r)
477 { 441 {
478 buftun_read = buftun; 442 if (EINTR == errno)
479 struct GNUNET_MessageHeader *hdr = 443 continue;
480 (struct GNUNET_MessageHeader *) buftun; 444 fprintf(stderr,
481 buftun_size += sizeof (struct GNUNET_MessageHeader); 445 "select failed: %s\n",
482 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 446 strerror(errno));
483 hdr->size = htons (buftun_size); 447 exit(1);
484 } 448 }
485 } 449
486 else if (FD_ISSET (1, &fds_w)) 450 if (r > 0)
487 {
488 ssize_t written = write (1,
489 buftun_read,
490 buftun_size);
491
492 if (-1 == written)
493 { 451 {
452 if (FD_ISSET(fd_tun, &fds_r))
453 {
454 buftun_size =
455 read(fd_tun, buftun + sizeof(struct GNUNET_MessageHeader),
456 MAX_SIZE - sizeof(struct GNUNET_MessageHeader));
457 if (-1 == buftun_size)
458 {
459 fprintf(stderr,
460 "read-error: %s\n",
461 strerror(errno));
462 shutdown(fd_tun, SHUT_RD);
463 shutdown(1, SHUT_WR);
464 read_open = 0;
465 buftun_size = 0;
466 }
467 else if (0 == buftun_size)
468 {
469 fprintf(stderr, "EOF on tun\n");
470 shutdown(fd_tun, SHUT_RD);
471 shutdown(1, SHUT_WR);
472 read_open = 0;
473 buftun_size = 0;
474 }
475 else
476 {
477 buftun_read = buftun;
478 struct GNUNET_MessageHeader *hdr =
479 (struct GNUNET_MessageHeader *)buftun;
480 buftun_size += sizeof(struct GNUNET_MessageHeader);
481 hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
482 hdr->size = htons(buftun_size);
483 }
484 }
485 else if (FD_ISSET(1, &fds_w))
486 {
487 ssize_t written = write(1,
488 buftun_read,
489 buftun_size);
490
491 if (-1 == written)
492 {
494#if !DEBUG 493#if !DEBUG
495 if (errno != EPIPE) 494 if (errno != EPIPE)
496#endif 495#endif
497 fprintf (stderr, 496 fprintf(stderr,
498 "write-error to stdout: %s\n", 497 "write-error to stdout: %s\n",
499 strerror (errno)); 498 strerror(errno));
500 shutdown (fd_tun, SHUT_RD); 499 shutdown(fd_tun, SHUT_RD);
501 shutdown (1, SHUT_WR); 500 shutdown(1, SHUT_WR);
502 read_open = 0; 501 read_open = 0;
503 buftun_size = 0; 502 buftun_size = 0;
504 } 503 }
505 else if (0 == written) 504 else if (0 == written)
506 { 505 {
507 fprintf (stderr, 506 fprintf(stderr,
508 "write returned 0!?\n"); 507 "write returned 0!?\n");
509 exit (1); 508 exit(1);
510 } 509 }
511 else 510 else
512 { 511 {
513 buftun_size -= written; 512 buftun_size -= written;
514 buftun_read += written; 513 buftun_read += written;
515 } 514 }
516 } 515 }
517 516
518 if (FD_ISSET (0, &fds_r)) 517 if (FD_ISSET(0, &fds_r))
519 { 518 {
520 bufin_size = read (0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos); 519 bufin_size = read(0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos);
521 if (-1 == bufin_size) 520 if (-1 == bufin_size)
522 { 521 {
523 fprintf (stderr, 522 fprintf(stderr,
524 "read-error: %s\n", 523 "read-error: %s\n",
525 strerror (errno)); 524 strerror(errno));
526 shutdown (0, SHUT_RD); 525 shutdown(0, SHUT_RD);
527 shutdown (fd_tun, SHUT_WR); 526 shutdown(fd_tun, SHUT_WR);
528 write_open = 0; 527 write_open = 0;
529 bufin_size = 0; 528 bufin_size = 0;
530 } 529 }
531 else if (0 == bufin_size) 530 else if (0 == bufin_size)
532 { 531 {
533#if DEBUG 532#if DEBUG
534 fprintf (stderr, "EOF on stdin\n"); 533 fprintf(stderr, "EOF on stdin\n");
535#endif 534#endif
536 shutdown (0, SHUT_RD); 535 shutdown(0, SHUT_RD);
537 shutdown (fd_tun, SHUT_WR); 536 shutdown(fd_tun, SHUT_WR);
538 write_open = 0; 537 write_open = 0;
539 bufin_size = 0; 538 bufin_size = 0;
540 } 539 }
541 else 540 else
542 { 541 {
543 struct GNUNET_MessageHeader *hdr; 542 struct GNUNET_MessageHeader *hdr;
544 543
545PROCESS_BUFFER: 544PROCESS_BUFFER:
546 bufin_rpos += bufin_size; 545 bufin_rpos += bufin_size;
547 if (bufin_rpos < sizeof (struct GNUNET_MessageHeader)) 546 if (bufin_rpos < sizeof(struct GNUNET_MessageHeader))
548 continue; 547 continue;
549 hdr = (struct GNUNET_MessageHeader *) bufin; 548 hdr = (struct GNUNET_MessageHeader *)bufin;
550 if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) 549 if (ntohs(hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
551 { 550 {
552 fprintf (stderr, 551 fprintf(stderr,
553 "protocol violation!\n"); 552 "protocol violation!\n");
554 exit (1); 553 exit(1);
555 } 554 }
556 if (ntohs (hdr->size) > bufin_rpos) 555 if (ntohs(hdr->size) > bufin_rpos)
557 continue; 556 continue;
558 bufin_read = bufin + sizeof (struct GNUNET_MessageHeader); 557 bufin_read = bufin + sizeof(struct GNUNET_MessageHeader);
559 bufin_size = ntohs (hdr->size) - sizeof (struct GNUNET_MessageHeader); 558 bufin_size = ntohs(hdr->size) - sizeof(struct GNUNET_MessageHeader);
560 bufin_rpos -= bufin_size + sizeof (struct GNUNET_MessageHeader); 559 bufin_rpos -= bufin_size + sizeof(struct GNUNET_MessageHeader);
560 }
561 }
562 else if (FD_ISSET(fd_tun, &fds_w))
563 {
564 ssize_t written = write(fd_tun,
565 bufin_read,
566 bufin_size);
567
568 if (-1 == written)
569 {
570 fprintf(stderr,
571 "write-error to tun: %s\n",
572 strerror(errno));
573 shutdown(0, SHUT_RD);
574 shutdown(fd_tun, SHUT_WR);
575 write_open = 0;
576 bufin_size = 0;
577 }
578 else if (0 == written)
579 {
580 fprintf(stderr, "write returned 0!?\n");
581 exit(1);
582 }
583 else
584 {
585 bufin_size -= written;
586 bufin_read += written;
587 if (0 == bufin_size)
588 {
589 memmove(bufin, bufin_read, bufin_rpos);
590 bufin_read = NULL; /* start reading again */
591 bufin_size = 0;
592 goto PROCESS_BUFFER;
593 }
594 }
595 }
561 } 596 }
562 }
563 else if (FD_ISSET (fd_tun, &fds_w))
564 {
565 ssize_t written = write (fd_tun,
566 bufin_read,
567 bufin_size);
568
569 if (-1 == written)
570 {
571 fprintf (stderr,
572 "write-error to tun: %s\n",
573 strerror (errno));
574 shutdown (0, SHUT_RD);
575 shutdown (fd_tun, SHUT_WR);
576 write_open = 0;
577 bufin_size = 0;
578 }
579 else if (0 == written)
580 {
581 fprintf (stderr, "write returned 0!?\n");
582 exit (1);
583 }
584 else
585 {
586 bufin_size -= written;
587 bufin_read += written;
588 if (0 == bufin_size)
589 {
590 memmove (bufin, bufin_read, bufin_rpos);
591 bufin_read = NULL; /* start reading again */
592 bufin_size = 0;
593 goto PROCESS_BUFFER;
594 }
595 }
596 }
597 } 597 }
598 }
599} 598}
600 599
601 600
@@ -611,92 +610,92 @@ PROCESS_BUFFER:
611 * 5: IPv4 netmask (255.255.0.0), ignored if #4 is "-" 610 * 5: IPv4 netmask (255.255.0.0), ignored if #4 is "-"
612 */ 611 */
613int 612int
614main (int argc, char **argv) 613main(int argc, char **argv)
615{ 614{
616 char dev[IFNAMSIZ]; 615 char dev[IFNAMSIZ];
617 int fd_tun; 616 int fd_tun;
618 int global_ret; 617 int global_ret;
619 618
620 if (6 != argc) 619 if (6 != argc)
621 { 620 {
622 fprintf (stderr, "Fatal: must supply 5 arguments!\n"); 621 fprintf(stderr, "Fatal: must supply 5 arguments!\n");
623 return 1; 622 return 1;
624 } 623 }
625 624
626 strncpy (dev, 625 strncpy(dev,
627 argv[1], 626 argv[1],
628 IFNAMSIZ); 627 IFNAMSIZ);
629 dev[IFNAMSIZ - 1] = '\0'; 628 dev[IFNAMSIZ - 1] = '\0';
630 629
631 if (-1 == (fd_tun = init_tun (dev))) 630 if (-1 == (fd_tun = init_tun(dev)))
632 {
633 fprintf (stderr,
634 "Fatal: could not initialize tun-interface `%s' with IPv6 %s/%s and IPv4 %s/%s\n",
635 dev,
636 argv[2],
637 argv[3],
638 argv[4],
639 argv[5]);
640 return 1;
641 }
642
643 if (0 != strcmp (argv[2], "-"))
644 {
645 const char *address = argv[2];
646 long prefix_len = atol (argv[3]);
647
648 if ((prefix_len < 1) || (prefix_len > 127))
649 { 631 {
650 fprintf (stderr, 632 fprintf(stderr,
651 "Fatal: prefix_len out of range\n"); 633 "Fatal: could not initialize tun-interface `%s' with IPv6 %s/%s and IPv4 %s/%s\n",
652 close (fd_tun); 634 dev,
635 argv[2],
636 argv[3],
637 argv[4],
638 argv[5]);
653 return 1; 639 return 1;
654 } 640 }
655 641
656 set_address6 (dev, 642 if (0 != strcmp(argv[2], "-"))
657 address, 643 {
658 prefix_len); 644 const char *address = argv[2];
659 } 645 long prefix_len = atol(argv[3]);
646
647 if ((prefix_len < 1) || (prefix_len > 127))
648 {
649 fprintf(stderr,
650 "Fatal: prefix_len out of range\n");
651 close(fd_tun);
652 return 1;
653 }
654
655 set_address6(dev,
656 address,
657 prefix_len);
658 }
660 659
661 if (0 != strcmp (argv[4], "-")) 660 if (0 != strcmp(argv[4], "-"))
662 { 661 {
663 const char *address = argv[4]; 662 const char *address = argv[4];
664 const char *mask = argv[5]; 663 const char *mask = argv[5];
665 664
666 set_address4 (dev, address, mask); 665 set_address4(dev, address, mask);
667 } 666 }
668 667
669 uid_t uid = getuid (); 668 uid_t uid = getuid();
670#ifdef HAVE_SETRESUID 669#ifdef HAVE_SETRESUID
671 if (0 != setresuid (uid, uid, uid)) 670 if (0 != setresuid(uid, uid, uid))
672 { 671 {
673 fprintf (stderr, 672 fprintf(stderr,
674 "Failed to setresuid: %s\n", 673 "Failed to setresuid: %s\n",
675 strerror (errno)); 674 strerror(errno));
676 global_ret = 2; 675 global_ret = 2;
677 goto cleanup; 676 goto cleanup;
678 } 677 }
679#else 678#else
680 if (0 != (setuid (uid) | seteuid (uid))) 679 if (0 != (setuid(uid) | seteuid(uid)))
681 { 680 {
682 fprintf (stderr, 681 fprintf(stderr,
683 "Failed to setuid: %s\n", 682 "Failed to setuid: %s\n",
684 strerror (errno)); 683 strerror(errno));
685 global_ret = 2; 684 global_ret = 2;
686 goto cleanup; 685 goto cleanup;
687 } 686 }
688#endif 687#endif
689 688
690 if (SIG_ERR == signal (SIGPIPE, SIG_IGN)) 689 if (SIG_ERR == signal(SIGPIPE, SIG_IGN))
691 { 690 {
692 fprintf (stderr, 691 fprintf(stderr,
693 "Failed to protect against SIGPIPE: %s\n", 692 "Failed to protect against SIGPIPE: %s\n",
694 strerror (errno)); 693 strerror(errno));
695 /* no exit, we might as well die with SIGPIPE should it ever happen */ 694 /* no exit, we might as well die with SIGPIPE should it ever happen */
696 } 695 }
697 run (fd_tun); 696 run(fd_tun);
698 global_ret = 0; 697 global_ret = 0;
699 cleanup: 698cleanup:
700 close (fd_tun); 699 close(fd_tun);
701 return global_ret; 700 return global_ret;
702} 701}