diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-02-02 09:04:42 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-02-02 09:04:42 +0000 |
commit | 3b3eb36e3a01c7046fe4c9a3c4bb7834d83442d6 (patch) | |
tree | e9bc242ae37f3393d5939dbfafaeca32bcc95ebb /src/vpn/gnunet-helper-vpn.c | |
parent | aefe648c889dd71ba942ccb235fe9eec477f2b53 (diff) | |
download | gnunet-3b3eb36e3a01c7046fe4c9a3c4bb7834d83442d6.tar.gz gnunet-3b3eb36e3a01c7046fe4c9a3c4bb7834d83442d6.zip |
fixing bugs, declaring safe
Diffstat (limited to 'src/vpn/gnunet-helper-vpn.c')
-rw-r--r-- | src/vpn/gnunet-helper-vpn.c | 241 |
1 files changed, 154 insertions, 87 deletions
diff --git a/src/vpn/gnunet-helper-vpn.c b/src/vpn/gnunet-helper-vpn.c index 06f07f542..37ec71868 100644 --- a/src/vpn/gnunet-helper-vpn.c +++ b/src/vpn/gnunet-helper-vpn.c | |||
@@ -24,8 +24,15 @@ | |||
24 | * sends data received on the if to stdout, sends data received on stdin to the | 24 | * sends data received on the if to stdout, sends data received on stdin to the |
25 | * interface | 25 | * interface |
26 | * @author Philipp Tölke | 26 | * @author Philipp Tölke |
27 | * | ||
28 | * The following list of people have reviewed this code and considered | ||
29 | * it safe since the last modification (if you reviewed it, please | ||
30 | * have your name added to the list): | ||
31 | * | ||
32 | * - Philipp Tölke | ||
33 | * - Christian Grothoff | ||
27 | */ | 34 | */ |
28 | #include <platform.h> | 35 | #include "platform.h" |
29 | #include <linux/if_tun.h> | 36 | #include <linux/if_tun.h> |
30 | 37 | ||
31 | /** | 38 | /** |
@@ -82,7 +89,7 @@ init_tun (char *dev) | |||
82 | 89 | ||
83 | if (fd >= FD_SETSIZE) | 90 | if (fd >= FD_SETSIZE) |
84 | { | 91 | { |
85 | fprintf (stderr, "Filedescriptor to large: %d", fd); | 92 | fprintf (stderr, "File descriptor to large: %d", fd); |
86 | return -1; | 93 | return -1; |
87 | } | 94 | } |
88 | 95 | ||
@@ -113,24 +120,19 @@ init_tun (char *dev) | |||
113 | * @param prefix_len the length of the network-prefix | 120 | * @param prefix_len the length of the network-prefix |
114 | */ | 121 | */ |
115 | static void | 122 | static void |
116 | set_address6 (const char *dev, const char *address, unsigned long prefix_len) | 123 | set_address6 (const char *dev, |
124 | const char *address, | ||
125 | unsigned long prefix_len) | ||
117 | { | 126 | { |
118 | struct ifreq ifr; | 127 | struct ifreq ifr; |
119 | struct in6_ifreq ifr6; | 128 | struct in6_ifreq ifr6; |
120 | struct sockaddr_in6 sa6; | 129 | struct sockaddr_in6 sa6; |
121 | int fd; | 130 | int fd; |
122 | 131 | ||
123 | if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0))) | ||
124 | { | ||
125 | fprintf (stderr, "Error creating socket: %s\n", strerror (errno)); | ||
126 | exit (1); | ||
127 | } | ||
128 | memset (&sa6, 0, sizeof (struct sockaddr_in6)); | ||
129 | sa6.sin6_family = AF_INET6; | ||
130 | |||
131 | /* | 132 | /* |
132 | * parse the new address | 133 | * parse the new address |
133 | */ | 134 | */ |
135 | memset (&sa6, 0, sizeof (struct sockaddr_in6)); | ||
134 | if (1 != inet_pton (AF_INET6, address, sa6.sin6_addr.s6_addr)) | 136 | if (1 != inet_pton (AF_INET6, address, sa6.sin6_addr.s6_addr)) |
135 | { | 137 | { |
136 | fprintf (stderr, | 138 | fprintf (stderr, |
@@ -138,7 +140,19 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len) | |||
138 | address, strerror (errno)); | 140 | address, strerror (errno)); |
139 | exit (1); | 141 | exit (1); |
140 | } | 142 | } |
141 | memcpy (&ifr6.ifr6_addr, &sa6.sin6_addr, sizeof (struct in6_addr)); | 143 | |
144 | if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0))) | ||
145 | { | ||
146 | fprintf (stderr, | ||
147 | "Error creating socket: %s\n", | ||
148 | strerror (errno)); | ||
149 | exit (1); | ||
150 | } | ||
151 | |||
152 | sa6.sin6_family = AF_INET6; | ||
153 | memcpy (&ifr6.ifr6_addr, | ||
154 | &sa6.sin6_addr, | ||
155 | sizeof (struct in6_addr)); | ||
142 | 156 | ||
143 | 157 | ||
144 | /* | 158 | /* |
@@ -148,7 +162,9 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len) | |||
148 | if (-1 == ioctl (fd, SIOGIFINDEX, &ifr)) | 162 | if (-1 == ioctl (fd, SIOGIFINDEX, &ifr)) |
149 | { | 163 | { |
150 | fprintf (stderr, | 164 | fprintf (stderr, |
151 | "ioctl failed at %d: %s\n", __LINE__, strerror (errno)); | 165 | "ioctl failed at %d: %s\n", |
166 | __LINE__, | ||
167 | strerror (errno)); | ||
152 | exit (1); | 168 | exit (1); |
153 | } | 169 | } |
154 | ifr6.ifr6_ifindex = ifr.ifr_ifindex; | 170 | ifr6.ifr6_ifindex = ifr.ifr_ifindex; |
@@ -202,9 +218,11 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len) | |||
202 | * @param mask the netmask | 218 | * @param mask the netmask |
203 | */ | 219 | */ |
204 | static void | 220 | static void |
205 | set_address4 (char *dev, char *address, char *mask) | 221 | set_address4 (const char *dev, |
222 | const char *address, | ||
223 | const char *mask) | ||
206 | { | 224 | { |
207 | int fd = 0; | 225 | int fd; |
208 | struct sockaddr_in *addr; | 226 | struct sockaddr_in *addr; |
209 | struct ifreq ifr; | 227 | struct ifreq ifr; |
210 | 228 | ||
@@ -217,18 +235,21 @@ set_address4 (char *dev, char *address, char *mask) | |||
217 | /* | 235 | /* |
218 | * Parse the address | 236 | * Parse the address |
219 | */ | 237 | */ |
220 | int r = inet_pton (AF_INET, address, &addr->sin_addr.s_addr); | 238 | if (1 != inet_pton (AF_INET, address, &addr->sin_addr.s_addr)) |
221 | if (r < 0) | ||
222 | { | 239 | { |
223 | fprintf (stderr, "error at inet_pton: %m\n"); | 240 | fprintf (stderr, |
241 | "Failed to parse address `%s': %s\n", | ||
242 | address, strerror (errno)); | ||
224 | exit (1); | 243 | exit (1); |
225 | } | 244 | } |
226 | 245 | ||
227 | fd = socket (PF_INET, SOCK_DGRAM, 0); | 246 | |
228 | if (fd < 0) | 247 | if (-1 == (fd = socket (PF_INET, SOCK_DGRAM, 0))) |
229 | { | 248 | { |
230 | perror ("socket()"); | 249 | fprintf (stderr, |
231 | return; | 250 | "Error creating socket: %s\n", |
251 | strerror (errno)); | ||
252 | exit (1); | ||
232 | } | 253 | } |
233 | 254 | ||
234 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); | 255 | strncpy (ifr.ifr_name, dev, IFNAMSIZ); |
@@ -236,32 +257,36 @@ set_address4 (char *dev, char *address, char *mask) | |||
236 | /* | 257 | /* |
237 | * Set the address | 258 | * Set the address |
238 | */ | 259 | */ |
239 | if (ioctl (fd, SIOCSIFADDR, &ifr) != 0) | 260 | if (-1 == ioctl (fd, SIOCSIFADDR, &ifr)) |
240 | { | 261 | { |
241 | perror ("SIOCSIFADDR"); | 262 | fprintf (stderr, |
242 | close (fd); | 263 | "ioctl failed at %d: %s\n", |
243 | return; | 264 | __LINE__, |
265 | strerror (errno)); | ||
266 | exit (1); | ||
244 | } | 267 | } |
245 | 268 | ||
246 | /* | 269 | /* |
247 | * Parse the netmask | 270 | * Parse the netmask |
248 | */ | 271 | */ |
249 | addr = (struct sockaddr_in *) &(ifr.ifr_netmask); | 272 | addr = (struct sockaddr_in *) &(ifr.ifr_netmask); |
250 | r = inet_pton (AF_INET, mask, &addr->sin_addr.s_addr); | 273 | if (1 != inet_pton (AF_INET, mask, &addr->sin_addr.s_addr)) |
251 | if (r < 0) | ||
252 | { | 274 | { |
253 | fprintf (stderr, "error at inet_pton: %m\n"); | 275 | fprintf (stderr, |
276 | "Failed to parse address `%s': %s\n", | ||
277 | mask, | ||
278 | strerror (errno)); | ||
254 | exit (1); | 279 | exit (1); |
255 | } | 280 | } |
256 | 281 | ||
257 | /* | 282 | /* |
258 | * Set the netmask | 283 | * Set the netmask |
259 | */ | 284 | */ |
260 | if (ioctl (fd, SIOCSIFNETMASK, &ifr) != 0) | 285 | if (-1 == ioctl (fd, SIOCSIFNETMASK, &ifr)) |
261 | { | 286 | { |
262 | perror ("SIOCSIFNETMASK"); | 287 | fprintf (stderr, |
263 | close (fd); | 288 | "ioctl failed at line %d: %s\n", __LINE__, strerror (errno)); |
264 | return; | 289 | exit (1); |
265 | } | 290 | } |
266 | 291 | ||
267 | /* | 292 | /* |
@@ -301,22 +326,25 @@ run (int fd_tun) | |||
301 | */ | 326 | */ |
302 | unsigned char buftun[MAX_SIZE]; | 327 | unsigned char buftun[MAX_SIZE]; |
303 | ssize_t buftun_size = 0; | 328 | ssize_t buftun_size = 0; |
304 | unsigned char *buftun_read = 0; | 329 | unsigned char *buftun_read; |
305 | 330 | ||
306 | /* | 331 | /* |
307 | * The buffer filled by reading from stdin | 332 | * The buffer filled by reading from stdin |
308 | */ | 333 | */ |
309 | unsigned char bufin[MAX_SIZE]; | 334 | unsigned char bufin[MAX_SIZE]; |
310 | ssize_t bufin_size = 0; | 335 | ssize_t bufin_size = 0; |
311 | unsigned char *bufin_write = 0; | 336 | size_t bufin_rpos = 0; |
337 | unsigned char *bufin_read = NULL; | ||
312 | 338 | ||
313 | fd_set fds_w; | 339 | fd_set fds_w; |
314 | fd_set fds_r; | 340 | fd_set fds_r; |
315 | 341 | ||
316 | int rea = 1; | 342 | /* read refers to reading from fd_tun, writing to stdout */ |
317 | int wri = 1; | 343 | int read_open = 1; |
344 | /* write refers to reading from stdin, writing to fd_tun */ | ||
345 | int write_open = 1; | ||
318 | 346 | ||
319 | while ((1 == rea) || (1 == wri)) | 347 | while ((1 == read_open) || (1 == write_open)) |
320 | { | 348 | { |
321 | FD_ZERO (&fds_w); | 349 | FD_ZERO (&fds_w); |
322 | FD_ZERO (&fds_r); | 350 | FD_ZERO (&fds_r); |
@@ -325,41 +353,35 @@ run (int fd_tun) | |||
325 | * We are supposed to read and the buffer is empty | 353 | * We are supposed to read and the buffer is empty |
326 | * -> select on read from tun | 354 | * -> select on read from tun |
327 | */ | 355 | */ |
328 | if (rea && (0 == buftun_size)) | 356 | if (read_open && (0 == buftun_size)) |
329 | { | 357 | FD_SET (fd_tun, &fds_r); |
330 | FD_SET (fd_tun, &fds_r); | ||
331 | } | ||
332 | 358 | ||
333 | /* | 359 | /* |
334 | * We are supposed to read and the buffer is not empty | 360 | * We are supposed to read and the buffer is not empty |
335 | * -> select on write to stdout | 361 | * -> select on write to stdout |
336 | */ | 362 | */ |
337 | if (rea && (0 != buftun_size)) | 363 | if (read_open && (0 != buftun_size)) |
338 | { | 364 | FD_SET (1, &fds_w); |
339 | FD_SET (1, &fds_w); | ||
340 | } | ||
341 | 365 | ||
342 | /* | 366 | /* |
343 | * We are supposed to write and the buffer is empty | 367 | * We are supposed to write and the buffer is empty |
344 | * -> select on read from stdin | 368 | * -> select on read from stdin |
345 | */ | 369 | */ |
346 | if (wri && (0 == bufin_size)) | 370 | if (write_open && (NULL == bufin_read)) |
347 | { | 371 | FD_SET (0, &fds_r); |
348 | FD_SET (0, &fds_r); | ||
349 | } | ||
350 | 372 | ||
351 | /* | 373 | /* |
352 | * We are supposed to write and the buffer is not empty | 374 | * We are supposed to write and the buffer is not empty |
353 | * -> select on write to tun | 375 | * -> select on write to tun |
354 | */ | 376 | */ |
355 | if (wri && (0 != bufin_size)) | 377 | if (write_open && (NULL != bufin_read)) |
356 | { | 378 | FD_SET (fd_tun, &fds_w); |
357 | FD_SET (fd_tun, &fds_w); | ||
358 | } | ||
359 | 379 | ||
360 | int r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL); | 380 | int r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL); |
361 | if (-1 == r) | 381 | if (-1 == r) |
362 | { | 382 | { |
383 | if (EINTR == errno) | ||
384 | continue; | ||
363 | fprintf (stderr, "select failed: %s\n", strerror (errno)); | 385 | fprintf (stderr, "select failed: %s\n", strerror (errno)); |
364 | exit (1); | 386 | exit (1); |
365 | } | 387 | } |
@@ -370,22 +392,21 @@ run (int fd_tun) | |||
370 | { | 392 | { |
371 | buftun_size = | 393 | buftun_size = |
372 | read (fd_tun, buftun + sizeof (struct GNUNET_MessageHeader), | 394 | read (fd_tun, buftun + sizeof (struct GNUNET_MessageHeader), |
373 | MAX_SIZE - sizeof (struct GNUNET_MessageHeader)) + | 395 | MAX_SIZE - sizeof (struct GNUNET_MessageHeader)); |
374 | sizeof (struct GNUNET_MessageHeader); | ||
375 | if (-1 == buftun_size) | 396 | if (-1 == buftun_size) |
376 | { | 397 | { |
377 | fprintf (stderr, "read-error: %s\n", strerror (errno)); | 398 | fprintf (stderr, "read-error: %s\n", strerror (errno)); |
378 | shutdown (fd_tun, SHUT_RD); | 399 | shutdown (fd_tun, SHUT_RD); |
379 | shutdown (1, SHUT_WR); | 400 | shutdown (1, SHUT_WR); |
380 | rea = 0; | 401 | read_open = 0; |
381 | buftun_size = 0; | 402 | buftun_size = 0; |
382 | } | 403 | } |
383 | else if (0 == buftun_size) | 404 | else if (0 == buftun_size) |
384 | { | 405 | { |
385 | fprintf (stderr, "eof on tun\n"); | 406 | fprintf (stderr, "EOF on tun\n"); |
386 | shutdown (fd_tun, SHUT_RD); | 407 | shutdown (fd_tun, SHUT_RD); |
387 | shutdown (1, SHUT_WR); | 408 | shutdown (1, SHUT_WR); |
388 | rea = 0; | 409 | read_open = 0; |
389 | buftun_size = 0; | 410 | buftun_size = 0; |
390 | } | 411 | } |
391 | else | 412 | else |
@@ -393,6 +414,7 @@ run (int fd_tun) | |||
393 | buftun_read = buftun; | 414 | buftun_read = buftun; |
394 | struct GNUNET_MessageHeader *hdr = | 415 | struct GNUNET_MessageHeader *hdr = |
395 | (struct GNUNET_MessageHeader *) buftun; | 416 | (struct GNUNET_MessageHeader *) buftun; |
417 | buftun_size += sizeof (struct GNUNET_MessageHeader); | ||
396 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | 418 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); |
397 | hdr->size = htons (buftun_size); | 419 | hdr->size = htons (buftun_size); |
398 | } | 420 | } |
@@ -402,65 +424,102 @@ run (int fd_tun) | |||
402 | ssize_t written = write (1, buftun_read, buftun_size); | 424 | ssize_t written = write (1, buftun_read, buftun_size); |
403 | if (-1 == written) | 425 | if (-1 == written) |
404 | { | 426 | { |
405 | fprintf (stderr, "write-error to stdout: %s\n", | 427 | fprintf (stderr, |
428 | "write-error to stdout: %s\n", | ||
406 | strerror (errno)); | 429 | strerror (errno)); |
407 | shutdown (fd_tun, SHUT_RD); | 430 | shutdown (fd_tun, SHUT_RD); |
408 | shutdown (1, SHUT_WR); | 431 | shutdown (1, SHUT_WR); |
409 | rea = 0; | 432 | read_open = 0; |
410 | buftun_size = 0; | 433 | buftun_size = 0; |
411 | } | 434 | } |
412 | buftun_size -= written; | 435 | else if (0 == written) |
413 | buftun_read += written; | 436 | { |
437 | fprintf (stderr, | ||
438 | "write returned 0!?\n"); | ||
439 | exit (1); | ||
440 | } | ||
441 | else | ||
442 | { | ||
443 | buftun_size -= written; | ||
444 | buftun_read += written; | ||
445 | } | ||
414 | } | 446 | } |
415 | 447 | ||
416 | if (FD_ISSET (0, &fds_r)) | 448 | if (FD_ISSET (0, &fds_r)) |
417 | { | 449 | { |
418 | bufin_size = read (0, bufin, MAX_SIZE); | 450 | bufin_size = read (0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos); |
419 | if (-1 == bufin_size) | 451 | if (-1 == bufin_size) |
420 | { | 452 | { |
421 | fprintf (stderr, "read-error: %s\n", strerror (errno)); | 453 | fprintf (stderr, |
454 | "read-error: %s\n", | ||
455 | strerror (errno)); | ||
422 | shutdown (0, SHUT_RD); | 456 | shutdown (0, SHUT_RD); |
423 | shutdown (fd_tun, SHUT_WR); | 457 | shutdown (fd_tun, SHUT_WR); |
424 | wri = 0; | 458 | write_open = 0; |
425 | bufin_size = 0; | 459 | bufin_size = 0; |
426 | } | 460 | } |
427 | else if (0 == bufin_size) | 461 | else if (0 == bufin_size) |
428 | { | 462 | { |
429 | fprintf (stderr, "eof on stdin\n"); | 463 | fprintf (stderr, |
464 | "EOF on stdin\n"); | ||
430 | shutdown (0, SHUT_RD); | 465 | shutdown (0, SHUT_RD); |
431 | shutdown (fd_tun, SHUT_WR); | 466 | shutdown (fd_tun, SHUT_WR); |
432 | wri = 0; | 467 | write_open = 0; |
433 | bufin_size = 0; | 468 | bufin_size = 0; |
434 | } | 469 | } |
435 | else | 470 | else |
436 | { | 471 | { |
437 | struct GNUNET_MessageHeader *hdr = | 472 | struct GNUNET_MessageHeader *hdr; |
438 | (struct GNUNET_MessageHeader *) bufin; | 473 | |
439 | if ((bufin_size < sizeof (struct GNUNET_MessageHeader)) | 474 | PROCESS_BUFFER: |
440 | || (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) | 475 | bufin_rpos += bufin_size; |
441 | || (ntohs (hdr->size) != bufin_size)) | 476 | if (bufin_rpos < sizeof (struct GNUNET_MessageHeader)) |
477 | continue; | ||
478 | hdr = (struct GNUNET_MessageHeader *) bufin; | ||
479 | if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) | ||
442 | { | 480 | { |
443 | fprintf (stderr, "protocol violation!\n"); | 481 | fprintf (stderr, "protocol violation!\n"); |
444 | exit (1); | 482 | exit (1); |
445 | } | 483 | } |
446 | bufin_write = bufin + sizeof (struct GNUNET_MessageHeader); | 484 | if (ntohs (hdr->size) > bufin_rpos) |
447 | bufin_size -= sizeof (struct GNUNET_MessageHeader); | 485 | continue; |
486 | bufin_read = bufin + sizeof (struct GNUNET_MessageHeader); | ||
487 | bufin_size = ntohs (hdr->size) - sizeof (struct GNUNET_MessageHeader); | ||
488 | bufin_rpos -= bufin_size + sizeof (struct GNUNET_MessageHeader); | ||
448 | } | 489 | } |
449 | } | 490 | } |
450 | else if (FD_ISSET (fd_tun, &fds_w)) | 491 | else if (FD_ISSET (fd_tun, &fds_w)) |
451 | { | 492 | { |
452 | ssize_t written = write (fd_tun, bufin_write, bufin_size); | 493 | ssize_t written = write (fd_tun, bufin_read, bufin_size); |
453 | if (-1 == written) | 494 | if (-1 == written) |
454 | { | 495 | { |
455 | fprintf (stderr, "write-error to tun: %s\n", | 496 | fprintf (stderr, "write-error to tun: %s\n", |
456 | strerror (errno)); | 497 | strerror (errno)); |
457 | shutdown (0, SHUT_RD); | 498 | shutdown (0, SHUT_RD); |
458 | shutdown (fd_tun, SHUT_WR); | 499 | shutdown (fd_tun, SHUT_WR); |
459 | wri = 0; | 500 | write_open = 0; |
460 | bufin_size = 0; | 501 | bufin_size = 0; |
461 | } | 502 | } |
462 | bufin_size -= written; | 503 | else if (0 == written) |
463 | bufin_write += written; | 504 | { |
505 | fprintf (stderr, | ||
506 | "write returned 0!?\n"); | ||
507 | exit (1); | ||
508 | } | ||
509 | else | ||
510 | { | ||
511 | bufin_size -= written; | ||
512 | bufin_read += written; | ||
513 | if (0 == bufin_size) | ||
514 | { | ||
515 | memmove (bufin, | ||
516 | bufin_read, | ||
517 | bufin_rpos); | ||
518 | bufin_read = NULL; /* start reading again */ | ||
519 | bufin_size = 0; | ||
520 | goto PROCESS_BUFFER; | ||
521 | } | ||
522 | } | ||
464 | } | 523 | } |
465 | } | 524 | } |
466 | } | 525 | } |
@@ -476,21 +535,23 @@ main (int argc, char **argv) | |||
476 | memset (dev, 0, IFNAMSIZ); | 535 | memset (dev, 0, IFNAMSIZ); |
477 | if (-1 == (fd_tun = init_tun (dev))) | 536 | if (-1 == (fd_tun = init_tun (dev))) |
478 | { | 537 | { |
479 | fprintf (stderr, "Fatal: could not initialize tun-interface\n"); | 538 | fprintf (stderr, |
539 | "Fatal: could not initialize tun-interface\n"); | ||
480 | return 1; | 540 | return 1; |
481 | } | 541 | } |
482 | 542 | ||
483 | if (5 != argc) | 543 | if (5 != argc) |
484 | { | 544 | { |
485 | fprintf(stderr, "Fatal: must supply 4 arguments!\n"); | 545 | fprintf (stderr, |
546 | "Fatal: must supply 4 arguments!\n"); | ||
486 | return 1; | 547 | return 1; |
487 | } | 548 | } |
488 | 549 | ||
489 | { | 550 | { |
490 | char *address = argv[1]; | 551 | const char *address = argv[1]; |
491 | long prefix_len = atol(argv[2]); | 552 | long prefix_len = atol(argv[2]); |
492 | 553 | ||
493 | if (prefix_len < 1 || prefix_len > 127) | 554 | if ( (prefix_len < 1) || (prefix_len > 127) ) |
494 | { | 555 | { |
495 | fprintf(stderr, "Fatal: prefix_len out of range\n"); | 556 | fprintf(stderr, "Fatal: prefix_len out of range\n"); |
496 | return 1; | 557 | return 1; |
@@ -498,17 +559,23 @@ main (int argc, char **argv) | |||
498 | 559 | ||
499 | set_address6 (dev, address, prefix_len); | 560 | set_address6 (dev, address, prefix_len); |
500 | } | 561 | } |
501 | 562 | ||
502 | { | 563 | { |
503 | char *address = argv[3]; | 564 | const char *address = argv[3]; |
504 | char *mask = argv[4]; | 565 | const char *mask = argv[4]; |
505 | 566 | ||
506 | set_address4 (dev, address, mask); | 567 | set_address4 (dev, address, mask); |
507 | } | 568 | } |
508 | 569 | ||
509 | uid_t uid = getuid (); | 570 | uid_t uid = getuid (); |
510 | if (0 != setresuid (uid, uid, uid)) | 571 | if (0 != setresuid (uid, uid, uid)) |
511 | fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); | 572 | fprintf (stderr, |
573 | "Failed to setresuid: %s\n", | ||
574 | strerror (errno)); | ||
575 | if (SIG_ERR == signal (SIGPIPE, SIG_IGN)) | ||
576 | fprintf (stderr, | ||
577 | "Failed to protect against SIGPIPE: %s\n", | ||
578 | strerror (errno)); | ||
512 | run (fd_tun); | 579 | run (fd_tun); |
513 | close (fd_tun); | 580 | close (fd_tun); |
514 | return 0; | 581 | return 0; |