Deleted Added
full compact
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}