Annotation of src/libexec/identd/identd.c, Revision 1.11
1.11 ! wiz 1: /* $NetBSD: identd.c,v 1.10 1999/05/18 04:49:41 jwise Exp $ */
1.8 mrg 2:
1.1 cgd 3: /*
4: ** identd.c A TCP/IP link identification protocol server
5: **
6: ** This program is in the public domain and may be used freely by anyone
7: ** who wants to.
8: **
1.9 msaitoh 9: ** Last update: 7 Oct 1993
1.1 cgd 10: **
11: ** Please send bug fixes/bug reports to: Peter Eriksson <pen@lysator.liu.se>
12: */
13:
1.9 msaitoh 14: #if !defined(__STDC__) && !defined(_AIX)
15: #define void int
16: #endif
17:
18: #if defined(IRIX) || defined(SVR4) || defined(NeXT) || (defined(sco) && sco >= 42) || defined(_AIX4) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(ultrix)
1.1 cgd 19: # define SIGRETURN_TYPE void
20: # define SIGRETURN_TYPE_IS_VOID
21: #else
22: # define SIGRETURN_TYPE int
23: #endif
24:
25: #ifdef SVR4
26: # define STRNET
27: #endif
28:
1.9 msaitoh 29: #ifdef NeXT31
30: # include <libc.h>
31: #endif
32:
33: #ifdef sco
34: # define USE_SIGALARM
35: #endif
36:
37: #include <stdio.h>
38: #include <ctype.h>
39: #include <errno.h>
40: #include <netdb.h>
41: #include <signal.h>
42: #include <fcntl.h>
43:
1.1 cgd 44: #include <sys/types.h>
45: #include <sys/param.h>
46: #include <sys/ioctl.h>
47: #include <sys/socket.h>
48: #ifndef _AUX_SOURCE
49: # include <sys/file.h>
50: #endif
51: #include <sys/time.h>
52: #include <sys/wait.h>
53:
54: #include <pwd.h>
55: #include <grp.h>
56:
57: #include <netinet/in.h>
58:
59: #ifndef HPUX7
60: # include <arpa/inet.h>
61: #endif
62:
1.9 msaitoh 63: #ifdef _AIX32
64: # include <sys/select.h>
65: #endif
66:
1.1 cgd 67: #if defined(MIPS) || defined(BSD43)
68: extern int errno;
69: #endif
70:
1.9 msaitoh 71: #if defined(SOLARIS) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__) || defined(_AIX)
72: # include <unistd.h>
73: # include <stdlib.h>
74: # include <string.h>
75: #endif
76:
1.1 cgd 77: #include "identd.h"
78: #include "error.h"
1.9 msaitoh 79: #include "paths.h"
80:
1.1 cgd 81:
82: /* Antique unixes do not have these things defined... */
83: #ifndef FD_SETSIZE
84: # define FD_SETSIZE 256
85: #endif
86:
87: #ifndef FD_SET
88: # ifndef NFDBITS
89: # define NFDBITS (sizeof(int) * NBBY) /* bits per mask */
90: # endif
91: # define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
92: #endif
93:
94: #ifndef FD_ZERO
95: # define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
96: #endif
97:
98:
1.9 msaitoh 99: char *path_unix = (char *) NULL;
100: char *path_kmem = (char *) NULL;
1.1 cgd 101:
102: int verbose_flag = 0;
103: int debug_flag = 0;
104: int syslog_flag = 0;
105: int multi_flag = 0;
106: int other_flag = 0;
107: int unknown_flag = 0;
108: int noident_flag = 0;
1.9 msaitoh 109: int crypto_flag = 0;
1.10 jwise 110: int liar_flag = 0;
1.1 cgd 111:
112: int lport = 0;
113: int fport = 0;
114:
1.9 msaitoh 115: char *charset_name = (char *) NULL;
116: char *indirect_host = (char *) NULL;
117: char *indirect_password = (char *) NULL;
1.10 jwise 118: char *lie_string = (char *) NULL;
1.9 msaitoh 119:
120: #ifdef ALLOW_FORMAT
121: int format_flag = 0;
122: char *format = "%u";
123: #endif
1.1 cgd 124:
125: static int child_pid;
126:
127: #ifdef LOG_DAEMON
128: static int syslog_facility = LOG_DAEMON;
129: #endif
130:
1.9 msaitoh 131: static int comparemem __P((void *, void *, int));
132: char *clearmem __P((void *, int));
133: static SIGRETURN_TYPE child_handler __P((int));
1.8 mrg 134: int main __P((int, char *[]));
135:
1.1 cgd 136: /*
137: ** The structure passing convention for GCC is incompatible with
138: ** Suns own C compiler, so we define our own inet_ntoa() function.
139: ** (This should only affect GCC version 1 I think, a well, this works
140: ** for version 2 also so why bother.. :-)
141: */
1.9 msaitoh 142: #if defined(__GNUC__) && defined(__sparc__) && !defined(NeXT)
1.1 cgd 143:
144: #ifdef inet_ntoa
145: #undef inet_ntoa
146: #endif
147:
148: char *inet_ntoa(ad)
1.9 msaitoh 149: struct in_addr ad;
1.1 cgd 150: {
1.9 msaitoh 151: unsigned long int s_ad;
152: int a, b, c, d;
153: static char addr[20];
154:
155: s_ad = ad.s_addr;
156: d = s_ad % 256;
157: s_ad /= 256;
158: c = s_ad % 256;
159: s_ad /= 256;
160: b = s_ad % 256;
161: a = s_ad / 256;
162: sprintf(addr, "%d.%d.%d.%d", a, b, c, d);
163:
164: return addr;
1.1 cgd 165: }
166: #endif
167:
1.9 msaitoh 168: static int comparemem(vp1, vp2, len)
169: void *vp1;
170: void *vp2;
171: int len;
172: {
173: unsigned char *p1 = (unsigned char *) vp1;
174: unsigned char *p2 = (unsigned char *) vp2;
175: int c;
176:
177: while (len-- > 0)
178: if ((c = (int) *p1++ - (int) *p2++) != 0)
179: return c;
180:
181: return 0;
182: }
1.1 cgd 183:
184: /*
185: ** Return the name of the connecting host, or the IP number as a string.
186: */
187: char *gethost(addr)
1.9 msaitoh 188: struct in_addr *addr;
1.1 cgd 189: {
1.9 msaitoh 190: int i;
191: struct hostent *hp;
1.1 cgd 192:
193:
1.9 msaitoh 194: hp = gethostbyaddr((char *) addr, sizeof(struct in_addr), AF_INET);
195: if (hp)
196: {
197: char *hname = strdup(hp->h_name);
198:
199: if (! hname) {
200: syslog(LOG_ERR, "strdup(%s): %m", hp->h_name);
201: exit(1);
202: }
203: /* Found a IP -> Name match, now try the reverse for security reasons */
204: hp = gethostbyname(hname);
205: (void) free(hname);
206: if (hp)
207: #ifdef h_addr
208: for (i = 0; hp->h_addr_list[i]; i++)
209: if (comparemem(hp->h_addr_list[i],
210: (unsigned char *) addr,
211: (int) sizeof(struct in_addr)) == 0)
212: return (char *) hp->h_name;
213: #else
214: if (comparemem(hp->h_addr, addr, sizeof(struct in_addr)) == 0)
215: return hp->h_name;
216: #endif
217: }
218:
219: return inet_ntoa(*addr);
1.1 cgd 220: }
221:
1.9 msaitoh 222: #ifdef USE_SIGALARM
1.1 cgd 223: /*
224: ** Exit cleanly after our time's up.
225: */
226: static SIGRETURN_TYPE
1.9 msaitoh 227: alarm_handler(int s)
1.1 cgd 228: {
1.9 msaitoh 229: if (syslog_flag)
230: syslog(LOG_DEBUG, "SIGALRM triggered, exiting");
231:
232: exit(0);
1.1 cgd 233: }
1.9 msaitoh 234: #endif
235:
1.1 cgd 236:
1.9 msaitoh 237: #if !defined(hpux) && !defined(__hpux) && !defined(SVR4) && \
238: !defined(_CRAY) && !defined(sco) && !defined(LINUX)
1.1 cgd 239: /*
240: ** This is used to clean up zombie child processes
241: ** if the -w or -b options are used.
242: */
243: static SIGRETURN_TYPE
1.9 msaitoh 244: child_handler(dummy)
245: int dummy;
1.1 cgd 246: {
1.9 msaitoh 247: #if defined(NeXT) || (defined(__sgi) && defined(__SVR3))
248: union wait status;
1.1 cgd 249: #else
1.9 msaitoh 250: int status;
1.1 cgd 251: #endif
1.9 msaitoh 252: int saved_errno = errno;
253:
254: while (wait3(&status, WNOHANG, NULL) > 0)
255: ;
1.1 cgd 256:
1.9 msaitoh 257: errno = saved_errno;
258:
1.1 cgd 259: #ifndef SIGRETURN_TYPE_IS_VOID
1.9 msaitoh 260: return 0;
1.1 cgd 261: #endif
262: }
263: #endif
264:
1.9 msaitoh 265:
266: char *clearmem(vbp, len)
267: void *vbp;
268: int len;
1.1 cgd 269: {
1.9 msaitoh 270: char *bp = (char *) vbp;
271: char *cp;
1.1 cgd 272:
1.9 msaitoh 273: cp = bp;
274: while (len-- > 0)
275: *cp++ = 0;
276:
277: return bp;
1.1 cgd 278: }
279:
280:
281: /*
282: ** Main entry point into this daemon
283: */
284: int main(argc,argv)
1.9 msaitoh 285: int argc;
286: char *argv[];
1.1 cgd 287: {
1.9 msaitoh 288: int i, len;
289: struct sockaddr_in sin;
290: struct in_addr laddr, faddr;
291: #ifndef USE_SIGALARM
292: struct timeval tv;
293: #endif
294: int one = 1;
295:
296: int background_flag = 0;
297: int timeout = 0;
298: char *portno = "113";
299: char *bind_address = (char *) NULL;
300: int set_uid = 0;
301: int set_gid = 0;
302: int inhibit_default_config = 0;
303: int opt_count = 0; /* Count of option flags */
1.1 cgd 304:
305: #ifdef __convex__
1.9 msaitoh 306: argc--; /* get rid of extra argument passed by inetd */
1.1 cgd 307: #endif
308:
1.9 msaitoh 309:
310: if (isatty(0))
311: background_flag = 1;
312:
313: /*
314: ** Prescan the arguments for "-f<config-file>" switches
315: */
316: inhibit_default_config = 0;
317: for (i = 1; i < argc && argv[i][0] == '-'; i++)
318: if (argv[i][1] == 'f')
319: inhibit_default_config = 1;
320:
321: /*
322: ** Parse the default config file - if it exists
323: */
324: if (!inhibit_default_config)
325: parse_config(NULL, 1);
1.1 cgd 326:
1.9 msaitoh 327: /*
328: ** Parse the command line arguments
329: */
330: for (i = 1; i < argc && argv[i][0] == '-'; i++) {
331: opt_count++;
332: switch (argv[i][1])
333: {
334: case 'b': /* Start as standalone daemon */
335: background_flag = 1;
336: break;
337:
338: case 'w': /* Start from Inetd, wait mode */
339: background_flag = 2;
340: break;
341:
342: case 'i': /* Start from Inetd, nowait mode */
343: background_flag = 0;
344: break;
345:
346: case 't':
347: timeout = atoi(argv[i]+2);
348: break;
349:
350: case 'p':
351: portno = argv[i]+2;
352: break;
353:
354: case 'a':
355: bind_address = argv[i]+2;
356: break;
357:
358: case 'u':
359: if (isdigit(argv[i][2]))
360: set_uid = atoi(argv[i]+2);
361: else
362: {
363: struct passwd *pwd;
364:
365: pwd = getpwnam(argv[i]+2);
366: if (!pwd)
367: ERROR1("no such user (%s) for -u option", argv[i]+2);
368: else
369: {
370: set_uid = pwd->pw_uid;
371: set_gid = pwd->pw_gid;
372: }
373: }
374: break;
375:
376: case 'g':
377: if (isdigit(argv[i][2]))
378: set_gid = atoi(argv[i]+2);
379: else
380: {
381: struct group *grp;
382:
383: grp = getgrnam(argv[i]+2);
384: if (!grp)
385: ERROR1("no such group (%s) for -g option", argv[i]+2);
386: else
387: set_gid = grp->gr_gid;
388: }
389: break;
390:
391: case 'c':
392: charset_name = argv[i]+2;
393: break;
394:
395: case 'r':
396: indirect_host = argv[i]+2;
397: break;
398:
399: case 'l': /* Use the Syslog daemon for logging */
400: syslog_flag++;
401: #ifdef LOG_DAEMON
402: openlog("identd", LOG_PID, syslog_facility);
403: #else
404: openlog("identd", LOG_PID);
405: #endif
406: break;
407:
408: case 'o':
409: other_flag = 1;
410: break;
411:
412: case 'e':
413: unknown_flag = 1;
414: break;
415:
416: case 'V': /* Give version of this daemon */
417: printf("[in.identd, version %s]\r\n", version);
418: exit(0);
419: break;
420:
421: case 'v': /* Be verbose */
422: verbose_flag++;
423: break;
424:
425: case 'd': /* Enable debugging */
426: debug_flag++;
427: break;
428:
429: case 'm': /* Enable multiline queries */
430: multi_flag++;
431: break;
432:
433: case 'N': /* Enable users ".noident" files */
434: noident_flag++;
435: break;
436:
437: #ifdef INCLUDE_CRYPT
438: case 'C': /* Enable encryption. */
439: {
440: FILE *keyfile;
441:
442: if (argv[i][2])
443: keyfile = fopen(argv[i]+2, "r");
444: else
445: keyfile = fopen(PATH_DESKEY, "r");
446:
447: if (keyfile == NULL)
448: {
449: ERROR("cannot open key file for option -C");
450: }
451: else
452: {
453: char buf[1024];
454:
455: if (fgets(buf, 1024, keyfile) == NULL)
456: {
457: ERROR("cannot read key file for option -C");
458: }
459: else
460: {
461: init_encryption(buf);
462: crypto_flag++;
463: }
464: fclose(keyfile);
465: }
466: }
467: break;
468: #endif
469:
470: #ifdef ALLOW_FORMAT
471: case 'n': /* Compatibility flag - just send the user number */
472: format_flag = 1;
473: format = "%U";
474: break;
475:
476: case 'F': /* Output format */
477: format_flag = 1;
478: format = argv[i]+2;
479: break;
480: #endif
1.10 jwise 481:
482: case 'L': /* lie brazenly */
483: liar_flag = 1;
484: if (*(argv[i]+2) != '\0')
485: lie_string = argv[i]+2;
486: else
487: #ifdef DEFAULT_LIE_USER
488: lie_string = DEFAULT_LIE_USER;
489: #else
490: ERROR("-L specified with no user name");
491: #endif
492: break;
1.9 msaitoh 493:
494: default:
495: ERROR1("Bad option %s", argv[i]);
496: break;
497: }
498: }
499:
500: #if defined(_AUX_SOURCE) || defined (SUNOS35)
501: /* A/UX 2.0* & SunOS 3.5 calls us with an argument XXXXXXXX.YYYY
502: ** where XXXXXXXXX is the hexadecimal version of the callers
503: ** IP number, and YYYY is the port/socket or something.
504: ** It seems to be impossible to pass arguments to a daemon started
505: ** by inetd.
506: **
507: ** Just in case it is started from something else, then we only
508: ** skip the argument if no option flags have been seen.
509: */
510: if (opt_count == 0)
511: argc--;
512: #endif
513:
514: /*
515: ** Path to kernel namelist file specified on command line
516: */
517: if (i < argc)
518: path_unix = argv[i++];
519:
520: /*
521: ** Path to kernel memory device specified on command line
522: */
523: if (i < argc)
524: path_kmem = argv[i++];
525:
526:
527: if (i < argc)
528: ERROR1("Too many arguments: ignored from %s", argv[i]);
529:
530:
531: /*
532: ** We used to call k_open here. But then the file descriptor
533: ** kd->fd open on /dev/kmem is shared by all child processes.
534: ** From the fork(2) man page:
535: ** o The child process has its own copy of the parent's descriptors. These
536: ** descriptors reference the same underlying objects. For instance, file
537: ** pointers in file objects are shared between the child and the parent
538: ** so that an lseek(2) on a descriptor in the child process can affect a
539: ** subsequent read(2) or write(2) by the parent.
540: ** Thus with concurrent (simultaneous) identd client processes,
541: ** they step on each other's toes when they use kvm_read.
542: **
543: ** Calling k_open here was a mistake for another reason too: we
544: ** did not yet honor -u and -g options. Presumably we are
545: ** running as root (unless the in.identd file is setuid), and
546: ** then we can open kmem regardless of -u and -g values.
547: **
548: **
549: ** Open the kernel memory device and read the nlist table
550: **
551: ** if (k_open() < 0)
552: ** ERROR("main: k_open");
553: */
554:
555: /*
556: ** Do the special handling needed for the "-b" flag
557: */
558: if (background_flag == 1)
1.1 cgd 559: {
1.9 msaitoh 560: struct sockaddr_in addr;
561: struct servent *sp;
562: int fd;
563:
564:
565: if (!debug_flag)
566: {
567: if (fork())
568: exit(0);
569:
570: close(0);
571: close(1);
572: close(2);
573:
574: if (fork())
575: exit(0);
576: }
577:
578: fd = socket(AF_INET, SOCK_STREAM, 0);
579: if (fd == -1)
580: ERROR("main: socket");
581:
582: if (fd != 0)
583: dup2(fd, 0);
584:
585: clearmem((void *) &addr, (int) sizeof(addr));
586:
587: addr.sin_family = AF_INET;
588: if (bind_address == (char *) NULL)
589: addr.sin_addr.s_addr = htonl(INADDR_ANY);
1.1 cgd 590: else
1.9 msaitoh 591: {
592: if (isdigit(bind_address[0]))
593: addr.sin_addr.s_addr = inet_addr(bind_address);
594: else
595: {
596: struct hostent *hp;
597:
598: hp = gethostbyname(bind_address);
599: if (!hp)
600: ERROR1("no such address (%s) for -a switch", bind_address);
601:
602: /* This is ugly, should use memcpy() or bcopy() but... */
603: addr.sin_addr.s_addr = * (unsigned long *) (hp->h_addr);
604: }
1.1 cgd 605: }
606:
1.9 msaitoh 607: if (isdigit(portno[0]))
608: addr.sin_port = htons(atoi(portno));
1.1 cgd 609: else
1.9 msaitoh 610: {
611: sp = getservbyname(portno, "tcp");
612: if (sp == (struct servent *) NULL)
613: ERROR1("main: getservbyname: %s", portno);
614: addr.sin_port = sp->s_port;
615: }
1.1 cgd 616:
1.9 msaitoh 617: #ifdef SO_REUSEADDR
618: setsockopt(0, SOL_SOCKET, SO_REUSEADDR, (void *) &one, sizeof(one));
619: #endif
1.1 cgd 620:
1.9 msaitoh 621: if (bind(0, (struct sockaddr *) &addr, sizeof(addr)) < 0)
622: ERROR("main: bind");
1.1 cgd 623: }
1.9 msaitoh 624:
625: if (background_flag)
626: {
627: if (listen(0, 3) < 0)
628: ERROR("main: listen");
629: }
630:
631: if (set_gid)
1.1 cgd 632: {
1.9 msaitoh 633: if (setgid(set_gid) == -1)
634: ERROR("main: setgid");
635: /* Call me paranoid... PSz */
636: if (getgid() != set_gid)
637: ERROR2("main: setgid failed: wanted %d, got GID %d", set_gid, getgid());
638: if (getegid() != set_gid)
639: ERROR2("main: setgid failed: wanted %d, got EGID %d", set_gid, getegid());
1.1 cgd 640: }
1.9 msaitoh 641:
642: if (set_uid)
1.1 cgd 643: {
1.9 msaitoh 644: if (setuid(set_uid) == -1)
645: ERROR("main: setuid");
646: /* Call me paranoid... PSz */
647: if (getuid() != set_uid)
648: ERROR2("main: setuid failed: wanted %d, got UID %d", set_uid, getuid());
649: if (geteuid() != set_uid)
650: ERROR2("main: setuid failed: wanted %d, got EUID %d", set_uid, geteuid());
1.1 cgd 651: }
652:
653: /*
1.9 msaitoh 654: ** Do some special handling if the "-b" or "-w" flags are used
655: */
656: if (background_flag)
657: {
658: int nfds, fd;
659: fd_set read_set;
660: struct sockaddr sad;
661: int sadlen;
662:
663:
664: /*
665: ** Set up the SIGCHLD signal child termination handler so
666: ** that we can avoid zombie processes hanging around and
667: ** handle childs terminating before being able to complete the
668: ** handshake.
669: */
670: #if (defined(SVR4) || defined(hpux) || defined(__hpux) || defined(IRIX) || \
671: defined(_CRAY) || defined(_AUX_SOURCE) || defined(sco) || \
672: defined(LINUX))
673: signal(SIGCHLD, SIG_IGN);
1.1 cgd 674: #else
1.9 msaitoh 675: signal(SIGCHLD, child_handler);
1.1 cgd 676: #endif
677:
1.9 msaitoh 678: /*
679: ** Loop and dispatch client handling processes
680: */
681: do
682: {
683: #ifdef USE_SIGALARM
684: /*
685: ** Terminate if we've been idle for 'timeout' seconds
686: */
687: if (background_flag == 2 && timeout)
688: {
689: signal(SIGALRM, alarm_handler);
690: alarm(timeout);
691: }
692: #endif
1.1 cgd 693:
1.9 msaitoh 694: /*
695: ** Wait for a connection request to occur.
696: ** Ignore EINTR (Interrupted System Call).
697: */
698: do
699: {
700: FD_ZERO(&read_set);
701: FD_SET(0, &read_set);
702:
703: #ifndef USE_SIGALARM
704: if (timeout)
705: {
706: tv.tv_sec = timeout;
707: tv.tv_usec = 0;
708: #ifdef __hpux
709: nfds = select(FD_SETSIZE,
710: (int *) &read_set, NULL, NULL, &tv);
711: #else
712: nfds = select(FD_SETSIZE, &read_set, NULL, NULL, &tv);
713: #endif
714: }
715: else
716: #endif
1.1 cgd 717:
1.9 msaitoh 718: #ifdef __hpux
719: nfds = select(FD_SETSIZE, (int *) &read_set, NULL, NULL, NULL);
720: #else
721: nfds = select(FD_SETSIZE, &read_set, NULL, NULL, NULL);
722: #endif
723: } while (nfds < 0 && errno == EINTR);
724:
725: /*
1.11 ! wiz 726: ** An error occurred in select? Just die
1.9 msaitoh 727: */
728: if (nfds < 0)
729: ERROR("main: select");
730:
731: /*
732: ** Timeout limit reached. Exit nicely
733: */
734: if (nfds == 0)
735: exit(0);
1.1 cgd 736:
1.9 msaitoh 737: #ifdef USE_SIGALARM
738: /*
739: ** Disable the alarm timeout
740: */
741: alarm(0);
742: #endif
1.1 cgd 743:
1.9 msaitoh 744: /*
745: ** Accept the new client
746: */
747: sadlen = sizeof(sad);
748: errno = 0;
749: fd = accept(0, &sad, &sadlen);
750: if (fd == -1)
751: ERROR1("main: accept. errno = %d", errno);
1.1 cgd 752:
1.9 msaitoh 753: /*
754: ** And fork, then close the fd if we are the parent.
755: */
756: child_pid = fork();
757: } while (child_pid && (close(fd), 1));
758:
759: /*
760: ** We are now in child, the parent has returned to "do" above.
761: */
762: if (dup2(fd, 0) == -1)
763: ERROR("main: dup2: failed fd 0");
764:
765: if (dup2(fd, 1) == -1)
766: ERROR("main: dup2: failed fd 1");
767:
768: if (dup2(fd, 2) == -1)
769: ERROR("main: dup2: failed fd 2");
770: }
771:
1.1 cgd 772: /*
1.9 msaitoh 773: ** Get foreign internet address
1.1 cgd 774: */
1.9 msaitoh 775: len = sizeof(sin);
776: if (getpeername(0, (struct sockaddr *) &sin, &len) == -1)
777: {
778: /*
779: ** A user has tried to start us from the command line or
780: ** the network link died, in which case this message won't
781: ** reach to other end anyway, so lets give the poor user some
782: ** errors.
783: */
784: perror("in.identd: getpeername()");
785: exit(1);
786: }
787:
788: faddr = sin.sin_addr;
1.1 cgd 789:
790:
1.9 msaitoh 791: #ifdef STRONG_LOG
792: if (syslog_flag)
793: syslog(LOG_INFO, "Connection from %s", gethost(&faddr));
794: #endif
1.1 cgd 795:
1.9 msaitoh 796:
797: /*
798: ** Get local internet address
1.1 cgd 799: */
1.9 msaitoh 800: len = sizeof(sin);
801: #ifdef ATTSVR4
802: if (t_getsockname(0, (struct sockaddr *) &sin, &len) == -1)
1.1 cgd 803: #else
1.9 msaitoh 804: if (getsockname(0, (struct sockaddr *) &sin, &len) == -1)
1.1 cgd 805: #endif
1.9 msaitoh 806: {
807: /*
808: ** We can just die here, because if this fails then the
809: ** network has died and we haven't got anyone to return
810: ** errors to.
811: */
812: exit(1);
813: }
814: laddr = sin.sin_addr;
1.1 cgd 815:
816:
817: /*
1.9 msaitoh 818: ** Get the local/foreign port pair from the luser
1.1 cgd 819: */
1.9 msaitoh 820: parse(stdin, &laddr, &faddr);
1.1 cgd 821:
1.9 msaitoh 822: exit(0);
1.1 cgd 823: }
CVSweb <webmaster@jp.NetBSD.org>