faithd.c (69312) | faithd.c (78064) |
---|---|
1/* $KAME: faithd.c,v 1.20 2000/07/01 11:40:45 itojun Exp $ */ | 1/* $KAME: faithd.c,v 1.39 2001/04/25 11:20:42 itojun Exp $ */ |
2 3/* 4 * Copyright (C) 1997 and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: --- 13 unchanged lines hidden (view full) --- 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * | 2 3/* 4 * Copyright (C) 1997 and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: --- 13 unchanged lines hidden (view full) --- 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * |
31 * $FreeBSD: head/usr.sbin/faithd/faithd.c 69312 2000-11-28 18:11:06Z charnier $ | 31 * $FreeBSD: head/usr.sbin/faithd/faithd.c 78064 2001-06-11 12:39:29Z ume $ |
32 */ 33 34/* 35 * User level translator from IPv6 to IPv4. 36 * 37 * Usage: faithd [<port> <progpath> <arg1(progname)> <arg2> ...] 38 * e.g. faithd telnet /usr/local/v6/sbin/telnetd telnetd 39 */ 40#define HAVE_GETIFADDRS 41 42#include <sys/param.h> 43#include <sys/types.h> 44#include <sys/sysctl.h> 45#include <sys/socket.h> 46#include <sys/wait.h> 47#include <sys/stat.h> 48#include <sys/time.h> 49#include <sys/ioctl.h> | 32 */ 33 34/* 35 * User level translator from IPv6 to IPv4. 36 * 37 * Usage: faithd [<port> <progpath> <arg1(progname)> <arg2> ...] 38 * e.g. faithd telnet /usr/local/v6/sbin/telnetd telnetd 39 */ 40#define HAVE_GETIFADDRS 41 42#include <sys/param.h> 43#include <sys/types.h> 44#include <sys/sysctl.h> 45#include <sys/socket.h> 46#include <sys/wait.h> 47#include <sys/stat.h> 48#include <sys/time.h> 49#include <sys/ioctl.h> |
50#ifdef __FreeBSD__ 51#include <libutil.h> 52#endif |
|
50 51#include <stdio.h> 52#include <stdlib.h> 53#include <stdarg.h> 54#include <string.h> 55#include <syslog.h> 56#include <unistd.h> 57#include <errno.h> --- 20 unchanged lines hidden (view full) --- 78#include <resolv.h> 79#include <arpa/nameser.h> 80#ifndef FAITH_NS 81#define FAITH_NS "FAITH_NS" 82#endif 83#endif 84 85#include "faithd.h" | 53 54#include <stdio.h> 55#include <stdlib.h> 56#include <stdarg.h> 57#include <string.h> 58#include <syslog.h> 59#include <unistd.h> 60#include <errno.h> --- 20 unchanged lines hidden (view full) --- 81#include <resolv.h> 82#include <arpa/nameser.h> 83#ifndef FAITH_NS 84#define FAITH_NS "FAITH_NS" 85#endif 86#endif 87 88#include "faithd.h" |
89#include "prefix.h" |
|
86 87char *serverpath = NULL; 88char *serverarg[MAXARGV + 1]; 89static char *faithdname = NULL; 90char logname[BUFSIZ]; 91char procname[BUFSIZ]; 92struct myaddrs { 93 struct myaddrs *next; 94 struct sockaddr *addr; 95}; 96struct myaddrs *myaddrs = NULL; 97static char *service; 98#ifdef USE_ROUTE 99static int sockfd = 0; 100#endif 101int dflag = 0; 102static int pflag = 0; 103static int inetd = 0; | 90 91char *serverpath = NULL; 92char *serverarg[MAXARGV + 1]; 93static char *faithdname = NULL; 94char logname[BUFSIZ]; 95char procname[BUFSIZ]; 96struct myaddrs { 97 struct myaddrs *next; 98 struct sockaddr *addr; 99}; 100struct myaddrs *myaddrs = NULL; 101static char *service; 102#ifdef USE_ROUTE 103static int sockfd = 0; 104#endif 105int dflag = 0; 106static int pflag = 0; 107static int inetd = 0; |
108static char *configfile = NULL; |
|
104 105int main __P((int, char **)); 106static int inetd_main __P((int, char **)); 107static int daemon_main __P((int, char **)); 108static void play_service __P((int)); 109static void play_child __P((int, struct sockaddr *)); 110static int faith_prefix __P((struct sockaddr *)); 111static int map6to4 __P((struct sockaddr_in6 *, struct sockaddr_in *)); 112#ifdef FAITH4 113static int map4to6 __P((struct sockaddr_in *, struct sockaddr_in6 *)); 114#endif 115static void sig_child __P((int)); 116static void sig_terminate __P((int)); 117static void start_daemon __P((void)); | 109 110int main __P((int, char **)); 111static int inetd_main __P((int, char **)); 112static int daemon_main __P((int, char **)); 113static void play_service __P((int)); 114static void play_child __P((int, struct sockaddr *)); 115static int faith_prefix __P((struct sockaddr *)); 116static int map6to4 __P((struct sockaddr_in6 *, struct sockaddr_in *)); 117#ifdef FAITH4 118static int map4to6 __P((struct sockaddr_in *, struct sockaddr_in6 *)); 119#endif 120static void sig_child __P((int)); 121static void sig_terminate __P((int)); 122static void start_daemon __P((void)); |
123static void exit_stderr __P((const char *, ...)) 124 __attribute__((__format__(__printf__, 1, 2))); |
|
118#ifndef HAVE_GETIFADDRS 119static unsigned int if_maxindex __P((void)); 120#endif 121static void grab_myaddrs __P((void)); 122static void free_myaddrs __P((void)); 123static void update_myaddrs __P((void)); 124static void usage __P((void)); 125 --- 25 unchanged lines hidden (view full) --- 151 struct sockaddr_storage me; 152 struct sockaddr_storage from; 153 int melen, fromlen; 154 int i; 155 int error; 156 const int on = 1; 157 char sbuf[NI_MAXSERV], snum[NI_MAXSERV]; 158 | 125#ifndef HAVE_GETIFADDRS 126static unsigned int if_maxindex __P((void)); 127#endif 128static void grab_myaddrs __P((void)); 129static void free_myaddrs __P((void)); 130static void update_myaddrs __P((void)); 131static void usage __P((void)); 132 --- 25 unchanged lines hidden (view full) --- 158 struct sockaddr_storage me; 159 struct sockaddr_storage from; 160 int melen, fromlen; 161 int i; 162 int error; 163 const int on = 1; 164 char sbuf[NI_MAXSERV], snum[NI_MAXSERV]; 165 |
166 if (config_load(configfile) < 0 && configfile) { 167 exit_failure("could not load config file"); 168 /*NOTREACHED*/ 169 } 170 |
|
159 if (strrchr(argv[0], '/') == NULL) 160 snprintf(path, sizeof(path), "%s/%s", DEFAULT_DIR, argv[0]); 161 else 162 snprintf(path, sizeof(path), "%s", argv[0]); 163 164#ifdef USE_ROUTE 165 grab_myaddrs(); 166 167 sockfd = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC); 168 if (sockfd < 0) { | 171 if (strrchr(argv[0], '/') == NULL) 172 snprintf(path, sizeof(path), "%s/%s", DEFAULT_DIR, argv[0]); 173 else 174 snprintf(path, sizeof(path), "%s", argv[0]); 175 176#ifdef USE_ROUTE 177 grab_myaddrs(); 178 179 sockfd = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC); 180 if (sockfd < 0) { |
169 exit_error("socket(PF_ROUTE): %s", ERRSTR); | 181 exit_failure("socket(PF_ROUTE): %s", ERRSTR); |
170 /*NOTREACHED*/ 171 } 172#endif 173 174 melen = sizeof(me); | 182 /*NOTREACHED*/ 183 } 184#endif 185 186 melen = sizeof(me); |
175 if (getsockname(STDIN_FILENO, (struct sockaddr *)&me, &melen) < 0) 176 exit_error("getsockname"); | 187 if (getsockname(STDIN_FILENO, (struct sockaddr *)&me, &melen) < 0) { 188 exit_failure("getsockname: %s", ERRSTR); 189 /*NOTREACHED*/ 190 } |
177 fromlen = sizeof(from); | 191 fromlen = sizeof(from); |
178 if (getpeername(STDIN_FILENO, (struct sockaddr *)&from, &fromlen) < 0) 179 exit_error("getpeername"); | 192 if (getpeername(STDIN_FILENO, (struct sockaddr *)&from, &fromlen) < 0) { 193 exit_failure("getpeername: %s", ERRSTR); 194 /*NOTREACHED*/ 195 } |
180 if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0, 181 sbuf, sizeof(sbuf), NI_NUMERICHOST) == 0) 182 service = sbuf; 183 else 184 service = DEFAULT_PORT_NAME; 185 if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0, 186 snum, sizeof(snum), NI_NUMERICHOST) != 0) 187 snprintf(snum, sizeof(snum), "?"); 188 189 snprintf(logname, sizeof(logname), "faithd %s", snum); 190 snprintf(procname, sizeof(procname), "accepting port %s", snum); 191 openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); 192 | 196 if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0, 197 sbuf, sizeof(sbuf), NI_NUMERICHOST) == 0) 198 service = sbuf; 199 else 200 service = DEFAULT_PORT_NAME; 201 if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0, 202 snum, sizeof(snum), NI_NUMERICHOST) != 0) 203 snprintf(snum, sizeof(snum), "?"); 204 205 snprintf(logname, sizeof(logname), "faithd %s", snum); 206 snprintf(procname, sizeof(procname), "accepting port %s", snum); 207 openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); 208 |
193 if (argc >= MAXARGV) | 209 if (argc >= MAXARGV) { |
194 exit_failure("too many arguments"); | 210 exit_failure("too many arguments"); |
211 /*NOTREACHED*/ 212 } |
|
195 serverarg[0] = serverpath = path; 196 for (i = 1; i < argc; i++) 197 serverarg[i] = argv[i]; 198 serverarg[i] = NULL; 199 200 error = setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &on, 201 sizeof(on)); | 213 serverarg[0] = serverpath = path; 214 for (i = 1; i < argc; i++) 215 serverarg[i] = argv[i]; 216 serverarg[i] = NULL; 217 218 error = setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &on, 219 sizeof(on)); |
202 if (error < 0) 203 exit_error("setsockopt(SO_OOBINLINE): %s", ERRSTR); | 220 if (error < 0) { 221 exit_failure("setsockopt(SO_OOBINLINE): %s", ERRSTR); 222 /*NOTREACHED*/ 223 } |
204 205 play_child(STDIN_FILENO, (struct sockaddr *)&from); 206 exit_failure("should not reach here"); 207 return 0; /*dummy!*/ 208} 209 210static int 211daemon_main(int argc, char **argv) 212{ 213 struct addrinfo hints, *res; 214 int s_wld, error, i, serverargc, on = 1; 215 int family = AF_INET6; 216 int c; 217#ifdef FAITH_NS 218 char *ns; 219#endif /* FAITH_NS */ 220 | 224 225 play_child(STDIN_FILENO, (struct sockaddr *)&from); 226 exit_failure("should not reach here"); 227 return 0; /*dummy!*/ 228} 229 230static int 231daemon_main(int argc, char **argv) 232{ 233 struct addrinfo hints, *res; 234 int s_wld, error, i, serverargc, on = 1; 235 int family = AF_INET6; 236 int c; 237#ifdef FAITH_NS 238 char *ns; 239#endif /* FAITH_NS */ 240 |
221 while ((c = getopt(argc, argv, "dp46")) != -1) { | 241 while ((c = getopt(argc, argv, "df:p46")) != -1) { |
222 switch (c) { 223 case 'd': 224 dflag++; 225 break; | 242 switch (c) { 243 case 'd': 244 dflag++; 245 break; |
246 case 'f': 247 configfile = optarg; 248 break; |
|
226 case 'p': 227 pflag++; 228 break; 229#ifdef FAITH4 230 case '4': 231 family = AF_INET; 232 break; 233 case '6': 234 family = AF_INET6; 235 break; 236#endif 237 default: 238 usage(); | 249 case 'p': 250 pflag++; 251 break; 252#ifdef FAITH4 253 case '4': 254 family = AF_INET; 255 break; 256 case '6': 257 family = AF_INET6; 258 break; 259#endif 260 default: 261 usage(); |
239 break; | 262 /*NOTREACHED*/ |
240 } 241 } 242 argc -= optind; 243 argv += optind; 244 | 263 } 264 } 265 argc -= optind; 266 argv += optind; 267 |
268 if (config_load(configfile) < 0 && configfile) { 269 exit_failure("could not load config file"); 270 /*NOTREACHED*/ 271 } 272 |
|
245#ifdef FAITH_NS 246 if ((ns = getenv(FAITH_NS)) != NULL) { 247 struct sockaddr_storage ss; 248 struct addrinfo hints, *res; 249 char serv[NI_MAXSERV]; 250 251 memset(&ss, 0, sizeof(ss)); 252 memset(&hints, 0, sizeof(hints)); --- 8 unchanged lines hidden (view full) --- 261#endif /* FAITH_NS */ 262 263#ifdef USE_ROUTE 264 grab_myaddrs(); 265#endif 266 267 switch (argc) { 268 case 0: | 273#ifdef FAITH_NS 274 if ((ns = getenv(FAITH_NS)) != NULL) { 275 struct sockaddr_storage ss; 276 struct addrinfo hints, *res; 277 char serv[NI_MAXSERV]; 278 279 memset(&ss, 0, sizeof(ss)); 280 memset(&hints, 0, sizeof(hints)); --- 8 unchanged lines hidden (view full) --- 289#endif /* FAITH_NS */ 290 291#ifdef USE_ROUTE 292 grab_myaddrs(); 293#endif 294 295 switch (argc) { 296 case 0: |
269 serverpath = DEFAULT_PATH; 270 serverarg[0] = DEFAULT_NAME; 271 serverarg[1] = NULL; 272 service = DEFAULT_PORT_NAME; 273 break; | 297 usage(); 298 /*NOTREACHED*/ |
274 default: 275 serverargc = argc - NUMARG; 276 if (serverargc >= MAXARGV) | 299 default: 300 serverargc = argc - NUMARG; 301 if (serverargc >= MAXARGV) |
277 exit_error("too many augments"); | 302 exit_stderr("too many arguments"); |
278 279 serverpath = malloc(strlen(argv[NUMPRG]) + 1); 280 strcpy(serverpath, argv[NUMPRG]); 281 for (i = 0; i < serverargc; i++) { 282 serverarg[i] = malloc(strlen(argv[i + NUMARG]) + 1); 283 strcpy(serverarg[i], argv[i + NUMARG]); 284 } 285 serverarg[i] = NULL; --- 9 unchanged lines hidden (view full) --- 295 296 memset(&hints, 0, sizeof(hints)); 297 hints.ai_flags = AI_PASSIVE; 298 hints.ai_family = family; 299 hints.ai_socktype = SOCK_STREAM; 300 hints.ai_protocol = 0; 301 error = getaddrinfo(NULL, service, &hints, &res); 302 if (error) | 303 304 serverpath = malloc(strlen(argv[NUMPRG]) + 1); 305 strcpy(serverpath, argv[NUMPRG]); 306 for (i = 0; i < serverargc; i++) { 307 serverarg[i] = malloc(strlen(argv[i + NUMARG]) + 1); 308 strcpy(serverarg[i], argv[i + NUMARG]); 309 } 310 serverarg[i] = NULL; --- 9 unchanged lines hidden (view full) --- 320 321 memset(&hints, 0, sizeof(hints)); 322 hints.ai_flags = AI_PASSIVE; 323 hints.ai_family = family; 324 hints.ai_socktype = SOCK_STREAM; 325 hints.ai_protocol = 0; 326 error = getaddrinfo(NULL, service, &hints, &res); 327 if (error) |
303 exit_error("getaddrinfo: %s", gai_strerror(error)); | 328 exit_stderr("getaddrinfo: %s", gai_strerror(error)); |
304 305 s_wld = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 306 if (s_wld == -1) | 329 330 s_wld = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 331 if (s_wld == -1) |
307 exit_error("socket: %s", ERRSTR); | 332 exit_stderr("socket: %s", ERRSTR); |
308 309#ifdef IPV6_FAITH 310 if (res->ai_family == AF_INET6) { 311 error = setsockopt(s_wld, IPPROTO_IPV6, IPV6_FAITH, &on, sizeof(on)); 312 if (error == -1) | 333 334#ifdef IPV6_FAITH 335 if (res->ai_family == AF_INET6) { 336 error = setsockopt(s_wld, IPPROTO_IPV6, IPV6_FAITH, &on, sizeof(on)); 337 if (error == -1) |
313 exit_error("setsockopt(IPV6_FAITH): %s", ERRSTR); | 338 exit_stderr("setsockopt(IPV6_FAITH): %s", ERRSTR); |
314 } 315#endif 316#ifdef FAITH4 317#ifdef IP_FAITH 318 if (res->ai_family == AF_INET) { 319 error = setsockopt(s_wld, IPPROTO_IP, IP_FAITH, &on, sizeof(on)); 320 if (error == -1) | 339 } 340#endif 341#ifdef FAITH4 342#ifdef IP_FAITH 343 if (res->ai_family == AF_INET) { 344 error = setsockopt(s_wld, IPPROTO_IP, IP_FAITH, &on, sizeof(on)); 345 if (error == -1) |
321 exit_error("setsockopt(IP_FAITH): %s", ERRSTR); | 346 exit_stderr("setsockopt(IP_FAITH): %s", ERRSTR); |
322 } 323#endif 324#endif /* FAITH4 */ 325 326 error = setsockopt(s_wld, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); 327 if (error == -1) | 347 } 348#endif 349#endif /* FAITH4 */ 350 351 error = setsockopt(s_wld, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); 352 if (error == -1) |
328 exit_error("setsockopt(SO_REUSEADDR): %s", ERRSTR); | 353 exit_stderr("setsockopt(SO_REUSEADDR): %s", ERRSTR); |
329 330 error = setsockopt(s_wld, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)); 331 if (error == -1) | 354 355 error = setsockopt(s_wld, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)); 356 if (error == -1) |
332 exit_error("setsockopt(SO_OOBINLINE): %s", ERRSTR); | 357 exit_stderr("setsockopt(SO_OOBINLINE): %s", ERRSTR); |
333 334 error = bind(s_wld, (struct sockaddr *)res->ai_addr, res->ai_addrlen); 335 if (error == -1) | 358 359 error = bind(s_wld, (struct sockaddr *)res->ai_addr, res->ai_addrlen); 360 if (error == -1) |
336 exit_error("bind: %s", ERRSTR); | 361 exit_stderr("bind: %s", ERRSTR); |
337 338 error = listen(s_wld, 5); 339 if (error == -1) | 362 363 error = listen(s_wld, 5); 364 if (error == -1) |
340 exit_error("listen: %s", ERRSTR); | 365 exit_stderr("listen: %s", ERRSTR); |
341 342#ifdef USE_ROUTE 343 sockfd = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC); 344 if (sockfd < 0) { | 366 367#ifdef USE_ROUTE 368 sockfd = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC); 369 if (sockfd < 0) { |
345 exit_error("socket(PF_ROUTE): %s", ERRSTR); | 370 exit_stderr("socket(PF_ROUTE): %s", ERRSTR); |
346 /*NOTREACHED*/ 347 } 348#endif 349 350 /* 351 * Everything is OK. 352 */ 353 354 start_daemon(); 355 356 snprintf(logname, sizeof(logname), "faithd %s", service); 357 snprintf(procname, sizeof(procname), "accepting port %s", service); 358 openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); 359 syslog(LOG_INFO, "Staring faith daemon for %s port", service); 360 361 play_service(s_wld); | 371 /*NOTREACHED*/ 372 } 373#endif 374 375 /* 376 * Everything is OK. 377 */ 378 379 start_daemon(); 380 381 snprintf(logname, sizeof(logname), "faithd %s", service); 382 snprintf(procname, sizeof(procname), "accepting port %s", service); 383 openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); 384 syslog(LOG_INFO, "Staring faith daemon for %s port", service); 385 386 play_service(s_wld); |
362 /*NOTREACHED*/ | 387 /* NOTREACHED */ |
363 exit(1); /*pacify gcc*/ 364} 365 366static void 367play_service(int s_wld) 368{ 369 struct sockaddr_storage srcaddr; 370 int len; --- 31 unchanged lines hidden (view full) --- 402 if (FD_ISSET(sockfd, &rfds)) { 403 update_myaddrs(); 404 } 405#endif 406 if (FD_ISSET(s_wld, &rfds)) { 407 len = sizeof(srcaddr); 408 s_src = accept(s_wld, (struct sockaddr *)&srcaddr, 409 &len); | 388 exit(1); /*pacify gcc*/ 389} 390 391static void 392play_service(int s_wld) 393{ 394 struct sockaddr_storage srcaddr; 395 int len; --- 31 unchanged lines hidden (view full) --- 427 if (FD_ISSET(sockfd, &rfds)) { 428 update_myaddrs(); 429 } 430#endif 431 if (FD_ISSET(s_wld, &rfds)) { 432 len = sizeof(srcaddr); 433 s_src = accept(s_wld, (struct sockaddr *)&srcaddr, 434 &len); |
410 if (s_src == -1) | 435 if (s_src == -1) { |
411 exit_failure("socket: %s", ERRSTR); | 436 exit_failure("socket: %s", ERRSTR); |
437 /*NOTREACHED*/ 438 } |
|
412 413 child_pid = fork(); 414 415 if (child_pid == 0) { 416 /* child process */ 417 close(s_wld); 418 closelog(); 419 openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); 420 play_child(s_src, (struct sockaddr *)&srcaddr); 421 exit_failure("should never reach here"); | 439 440 child_pid = fork(); 441 442 if (child_pid == 0) { 443 /* child process */ 444 close(s_wld); 445 closelog(); 446 openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); 447 play_child(s_src, (struct sockaddr *)&srcaddr); 448 exit_failure("should never reach here"); |
449 /*NOTREACHED*/ |
|
422 } else { 423 /* parent process */ 424 close(s_src); 425 if (child_pid == -1) 426 syslog(LOG_ERR, "can't fork"); 427 } 428 } 429 goto again; --- 6 unchanged lines hidden (view full) --- 436 struct sockaddr_storage dstaddr4; 437 char src[MAXHOSTNAMELEN]; 438 char dst6[MAXHOSTNAMELEN]; 439 char dst4[MAXHOSTNAMELEN]; 440 int len = sizeof(dstaddr6); 441 int s_dst, error, hport, nresvport, on = 1; 442 struct timeval tv; 443 struct sockaddr *sa4; | 450 } else { 451 /* parent process */ 452 close(s_src); 453 if (child_pid == -1) 454 syslog(LOG_ERR, "can't fork"); 455 } 456 } 457 goto again; --- 6 unchanged lines hidden (view full) --- 464 struct sockaddr_storage dstaddr4; 465 char src[MAXHOSTNAMELEN]; 466 char dst6[MAXHOSTNAMELEN]; 467 char dst4[MAXHOSTNAMELEN]; 468 int len = sizeof(dstaddr6); 469 int s_dst, error, hport, nresvport, on = 1; 470 struct timeval tv; 471 struct sockaddr *sa4; |
472 const struct config *conf; |
|
444 445 tv.tv_sec = 1; 446 tv.tv_usec = 0; 447 448 getnameinfo(srcaddr, srcaddr->sa_len, 449 src, sizeof(src), NULL, 0, NI_NUMERICHOST); 450 syslog(LOG_INFO, "accepted a client from %s", src); 451 452 error = getsockname(s_src, (struct sockaddr *)&dstaddr6, &len); | 473 474 tv.tv_sec = 1; 475 tv.tv_usec = 0; 476 477 getnameinfo(srcaddr, srcaddr->sa_len, 478 src, sizeof(src), NULL, 0, NI_NUMERICHOST); 479 syslog(LOG_INFO, "accepted a client from %s", src); 480 481 error = getsockname(s_src, (struct sockaddr *)&dstaddr6, &len); |
453 if (error == -1) | 482 if (error == -1) { |
454 exit_failure("getsockname: %s", ERRSTR); | 483 exit_failure("getsockname: %s", ERRSTR); |
484 /*NOTREACHED*/ 485 } |
|
455 456 getnameinfo((struct sockaddr *)&dstaddr6, len, 457 dst6, sizeof(dst6), NULL, 0, NI_NUMERICHOST); 458 syslog(LOG_INFO, "the client is connecting to %s", dst6); 459 460 if (!faith_prefix((struct sockaddr *)&dstaddr6)) { 461 if (serverpath) { 462 /* --- 19 unchanged lines hidden (view full) --- 482 * Act as a translator 483 */ 484 485 switch (((struct sockaddr *)&dstaddr6)->sa_family) { 486 case AF_INET6: 487 if (!map6to4((struct sockaddr_in6 *)&dstaddr6, 488 (struct sockaddr_in *)&dstaddr4)) { 489 close(s_src); | 486 487 getnameinfo((struct sockaddr *)&dstaddr6, len, 488 dst6, sizeof(dst6), NULL, 0, NI_NUMERICHOST); 489 syslog(LOG_INFO, "the client is connecting to %s", dst6); 490 491 if (!faith_prefix((struct sockaddr *)&dstaddr6)) { 492 if (serverpath) { 493 /* --- 19 unchanged lines hidden (view full) --- 513 * Act as a translator 514 */ 515 516 switch (((struct sockaddr *)&dstaddr6)->sa_family) { 517 case AF_INET6: 518 if (!map6to4((struct sockaddr_in6 *)&dstaddr6, 519 (struct sockaddr_in *)&dstaddr4)) { 520 close(s_src); |
490 exit_error("map6to4 failed"); | 521 exit_failure("map6to4 failed"); 522 /*NOTREACHED*/ |
491 } 492 syslog(LOG_INFO, "translating from v6 to v4"); 493 break; 494#ifdef FAITH4 495 case AF_INET: 496 if (!map4to6((struct sockaddr_in *)&dstaddr6, 497 (struct sockaddr_in6 *)&dstaddr4)) { 498 close(s_src); | 523 } 524 syslog(LOG_INFO, "translating from v6 to v4"); 525 break; 526#ifdef FAITH4 527 case AF_INET: 528 if (!map4to6((struct sockaddr_in *)&dstaddr6, 529 (struct sockaddr_in6 *)&dstaddr4)) { 530 close(s_src); |
499 exit_error("map4to6 failed"); | 531 exit_failure("map4to6 failed"); 532 /*NOTREACHED*/ |
500 } 501 syslog(LOG_INFO, "translating from v4 to v6"); 502 break; 503#endif 504 default: 505 close(s_src); | 533 } 534 syslog(LOG_INFO, "translating from v4 to v6"); 535 break; 536#endif 537 default: 538 close(s_src); |
506 exit_error("family not supported"); | 539 exit_failure("family not supported"); |
507 /*NOTREACHED*/ 508 } 509 510 sa4 = (struct sockaddr *)&dstaddr4; 511 getnameinfo(sa4, sa4->sa_len, 512 dst4, sizeof(dst4), NULL, 0, NI_NUMERICHOST); | 540 /*NOTREACHED*/ 541 } 542 543 sa4 = (struct sockaddr *)&dstaddr4; 544 getnameinfo(sa4, sa4->sa_len, 545 dst4, sizeof(dst4), NULL, 0, NI_NUMERICHOST); |
546 547 conf = config_match(srcaddr, sa4); 548 if (!conf || !conf->permit) { 549 close(s_src); 550 if (conf) { 551 exit_failure("translation to %s not permitted for %s", 552 dst4, prefix_string(&conf->match)); 553 /*NOTREACHED*/ 554 } else { 555 exit_failure("translation to %s not permitted", dst4); 556 /*NOTREACHED*/ 557 } 558 } 559 |
|
513 syslog(LOG_INFO, "the translator is connecting to %s", dst4); 514 515 setproctitle("port %s, %s -> %s", service, src, dst4); 516 517 if (sa4->sa_family == AF_INET6) 518 hport = ntohs(((struct sockaddr_in6 *)&dstaddr4)->sin6_port); 519 else /* AF_INET */ 520 hport = ntohs(((struct sockaddr_in *)&dstaddr4)->sin_port); --- 5 unchanged lines hidden (view full) --- 526 break; 527 default: 528 if (pflag) 529 s_dst = rresvport_af(&nresvport, sa4->sa_family); 530 else 531 s_dst = socket(sa4->sa_family, SOCK_STREAM, 0); 532 break; 533 } | 560 syslog(LOG_INFO, "the translator is connecting to %s", dst4); 561 562 setproctitle("port %s, %s -> %s", service, src, dst4); 563 564 if (sa4->sa_family == AF_INET6) 565 hport = ntohs(((struct sockaddr_in6 *)&dstaddr4)->sin6_port); 566 else /* AF_INET */ 567 hport = ntohs(((struct sockaddr_in *)&dstaddr4)->sin_port); --- 5 unchanged lines hidden (view full) --- 573 break; 574 default: 575 if (pflag) 576 s_dst = rresvport_af(&nresvport, sa4->sa_family); 577 else 578 s_dst = socket(sa4->sa_family, SOCK_STREAM, 0); 579 break; 580 } |
534 if (s_dst == -1) | 581 if (s_dst < 0) { |
535 exit_failure("socket: %s", ERRSTR); | 582 exit_failure("socket: %s", ERRSTR); |
583 /*NOTREACHED*/ 584 } |
|
536 | 585 |
586 if (conf->src.a.ss_family) { 587 if (bind(s_dst, (struct sockaddr *)&conf->src.a, 588 conf->src.a.ss_len) < 0) { 589 exit_failure("bind: %s", ERRSTR); 590 /*NOTREACHED*/ 591 } 592 } 593 |
|
537 error = setsockopt(s_dst, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)); | 594 error = setsockopt(s_dst, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)); |
538 if (error == -1) 539 exit_error("setsockopt(SO_OOBINLINE): %s", ERRSTR); | 595 if (error < 0) { 596 exit_failure("setsockopt(SO_OOBINLINE): %s", ERRSTR); 597 /*NOTREACHED*/ 598 } |
540 541 error = setsockopt(s_src, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); | 599 600 error = setsockopt(s_src, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); |
542 if (error == -1) 543 exit_error("setsockopt(SO_SNDTIMEO): %s", ERRSTR); | 601 if (error < 0) { 602 exit_failure("setsockopt(SO_SNDTIMEO): %s", ERRSTR); 603 /*NOTREACHED*/ 604 } |
544 error = setsockopt(s_dst, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); | 605 error = setsockopt(s_dst, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); |
545 if (error == -1) 546 exit_error("setsockopt(SO_SNDTIMEO): %s", ERRSTR); | 606 if (error < 0) { 607 exit_failure("setsockopt(SO_SNDTIMEO): %s", ERRSTR); 608 /*NOTREACHED*/ 609 } |
547 548 error = connect(s_dst, sa4, sa4->sa_len); | 610 611 error = connect(s_dst, sa4, sa4->sa_len); |
549 if (error == -1) | 612 if (error < 0) { |
550 exit_failure("connect: %s", ERRSTR); | 613 exit_failure("connect: %s", ERRSTR); |
614 /*NOTREACHED*/ 615 } |
|
551 552 switch (hport) { 553 case FTP_PORT: 554 ftp_relay(s_src, s_dst); 555 break; 556 case RSH_PORT: | 616 617 switch (hport) { 618 case FTP_PORT: 619 ftp_relay(s_src, s_dst); 620 break; 621 case RSH_PORT: |
622 syslog(LOG_WARNING, 623 "WARINNG: it is insecure to relay rsh port"); |
|
557 rsh_relay(s_src, s_dst); 558 break; | 624 rsh_relay(s_src, s_dst); 625 break; |
626 case RLOGIN_PORT: 627 syslog(LOG_WARNING, 628 "WARINNG: it is insecure to relay rlogin port"); 629 /*FALLTHROUGH*/ |
|
559 default: 560 tcp_relay(s_src, s_dst, service); 561 break; 562 } 563 564 /* NOTREACHED */ 565} 566 --- 9 unchanged lines hidden (view full) --- 576 if (dst->sa_family != AF_INET6) 577 return 0; 578 579 mib[0] = CTL_NET; 580 mib[1] = PF_INET6; 581 mib[2] = IPPROTO_IPV6; 582 mib[3] = IPV6CTL_FAITH_PREFIX; 583 size = sizeof(struct in6_addr); | 630 default: 631 tcp_relay(s_src, s_dst, service); 632 break; 633 } 634 635 /* NOTREACHED */ 636} 637 --- 9 unchanged lines hidden (view full) --- 647 if (dst->sa_family != AF_INET6) 648 return 0; 649 650 mib[0] = CTL_NET; 651 mib[1] = PF_INET6; 652 mib[2] = IPPROTO_IPV6; 653 mib[3] = IPV6CTL_FAITH_PREFIX; 654 size = sizeof(struct in6_addr); |
584 if (sysctl(mib, 4, &faith_prefix, &size, NULL, 0) < 0) 585 exit_error("sysctl: %s", ERRSTR); | 655 if (sysctl(mib, 4, &faith_prefix, &size, NULL, 0) < 0) { 656 exit_failure("sysctl: %s", ERRSTR); 657 /*NOTREACHED*/ 658 } |
586 587 if (memcmp(dst, &faith_prefix, 588 sizeof(struct in6_addr) - sizeof(struct in_addr) == 0) { 589 return 1; 590 } 591 return 0; 592#else 593 struct myaddrs *p; --- 50 unchanged lines hidden (view full) --- 644 dst4->sin_len = sizeof(*dst4); 645 dst4->sin_family = AF_INET; 646 dst4->sin_port = dst6->sin6_port; 647 memcpy(&dst4->sin_addr, &dst6->sin6_addr.s6_addr[12], 648 sizeof(dst4->sin_addr)); 649 650 if (dst4->sin_addr.s_addr == INADDR_ANY 651 || dst4->sin_addr.s_addr == INADDR_BROADCAST | 659 660 if (memcmp(dst, &faith_prefix, 661 sizeof(struct in6_addr) - sizeof(struct in_addr) == 0) { 662 return 1; 663 } 664 return 0; 665#else 666 struct myaddrs *p; --- 50 unchanged lines hidden (view full) --- 717 dst4->sin_len = sizeof(*dst4); 718 dst4->sin_family = AF_INET; 719 dst4->sin_port = dst6->sin6_port; 720 memcpy(&dst4->sin_addr, &dst6->sin6_addr.s6_addr[12], 721 sizeof(dst4->sin_addr)); 722 723 if (dst4->sin_addr.s_addr == INADDR_ANY 724 || dst4->sin_addr.s_addr == INADDR_BROADCAST |
652 || IN_MULTICAST(dst4->sin_addr.s_addr)) | 725 || IN_MULTICAST(ntohl(dst4->sin_addr.s_addr))) |
653 return 0; 654 655 return 1; 656} 657 658#ifdef FAITH4 659/* 0: non faith, 1: faith */ 660static int --- 29 unchanged lines hidden (view full) --- 690 691static void 692sig_child(int sig) 693{ 694 int status; 695 pid_t pid; 696 697 pid = wait3(&status, WNOHANG, (struct rusage *)0); | 726 return 0; 727 728 return 1; 729} 730 731#ifdef FAITH4 732/* 0: non faith, 1: faith */ 733static int --- 29 unchanged lines hidden (view full) --- 763 764static void 765sig_child(int sig) 766{ 767 int status; 768 pid_t pid; 769 770 pid = wait3(&status, WNOHANG, (struct rusage *)0); |
698 if (pid && status) | 771 if (pid && WEXITSTATUS(status)) |
699 syslog(LOG_WARNING, "child %d exit status 0x%x", pid, status); 700} 701 702void 703sig_terminate(int sig) 704{ 705 syslog(LOG_INFO, "Terminating faith daemon"); 706 exit(EXIT_SUCCESS); 707} 708 709static void 710start_daemon(void) 711{ | 772 syslog(LOG_WARNING, "child %d exit status 0x%x", pid, status); 773} 774 775void 776sig_terminate(int sig) 777{ 778 syslog(LOG_INFO, "Terminating faith daemon"); 779 exit(EXIT_SUCCESS); 780} 781 782static void 783start_daemon(void) 784{ |
785#ifdef SA_NOCLDWAIT 786 struct sigaction sa; 787#endif 788 |
|
712 if (daemon(0, 0) == -1) | 789 if (daemon(0, 0) == -1) |
713 exit_error("daemon: %s", ERRSTR); | 790 exit_stderr("daemon: %s", ERRSTR); |
714 | 791 |
715 if (signal(SIGCHLD, sig_child) == SIG_ERR) | 792#ifdef SA_NOCLDWAIT 793 memset(&sa, 0, sizeof(sa)); 794 sa.sa_handler = sig_child; 795 sa.sa_flags = SA_NOCLDWAIT; 796 sigemptyset(&sa.sa_mask); 797 sigaction(SIGCHLD, &sa, (struct sigaction *)0); 798#else 799 if (signal(SIGCHLD, sig_child) == SIG_ERR) { |
716 exit_failure("signal CHLD: %s", ERRSTR); | 800 exit_failure("signal CHLD: %s", ERRSTR); |
801 /*NOTREACHED*/ 802 } 803#endif |
|
717 | 804 |
718 if (signal(SIGTERM, sig_terminate) == SIG_ERR) | 805 if (signal(SIGTERM, sig_terminate) == SIG_ERR) { |
719 exit_failure("signal TERM: %s", ERRSTR); | 806 exit_failure("signal TERM: %s", ERRSTR); |
807 /*NOTREACHED*/ 808 } |
|
720} 721 | 809} 810 |
722void 723exit_error(const char *fmt, ...) | 811static void 812exit_stderr(const char *fmt, ...) |
724{ 725 va_list ap; 726 char buf[BUFSIZ]; 727 728 va_start(ap, fmt); 729 vsnprintf(buf, sizeof(buf), fmt, ap); 730 va_end(ap); 731 fprintf(stderr, "%s\n", buf); --- 240 unchanged lines hidden (view full) --- 972 free_myaddrs(); 973 grab_myaddrs(); 974} 975#endif /*USE_ROUTE*/ 976 977static void 978usage() 979{ | 813{ 814 va_list ap; 815 char buf[BUFSIZ]; 816 817 va_start(ap, fmt); 818 vsnprintf(buf, sizeof(buf), fmt, ap); 819 va_end(ap); 820 fprintf(stderr, "%s\n", buf); --- 240 unchanged lines hidden (view full) --- 1061 free_myaddrs(); 1062 grab_myaddrs(); 1063} 1064#endif /*USE_ROUTE*/ 1065 1066static void 1067usage() 1068{ |
980 fprintf(stderr, "usage: %s [-dp] [service [serverpath [serverargs]]]\n", | 1069 fprintf(stderr, "usage: %s [-dp] [-f conf] service [serverpath [serverargs]]\n", |
981 faithdname); 982 exit(0); 983} | 1070 faithdname); 1071 exit(0); 1072} |