This is diald.c in view mode; [Download] [Up]
/* ** Copyright (c) 1991 Bolt Beranek and Newman, Inc. ** All rights reserved. ** ** Redistribution and use in source and binary forms are permitted ** provided that: (1) source distributions retain this entire copyright ** notice and comment, and (2) distributions including binaries display ** the following acknowledgement: ``This product includes software ** developed by Bolt Beranek and Newman, Inc. and CREN/CSNET'' in the ** documentation or other materials provided with the distribution and in ** all advertising materials mentioning features or use of this software. ** Neither the name of Bolt Beranek and Newman nor CREN/CSNET may be used ** to endorse or promote products derived from this software without ** specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include <stdio.h> #include <signal.h> #include <errno.h> #include <setjmp.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/ioctl.h> #include <sys/time.h> #include <sys/file.h> #include <sys/param.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <sys/socket.h> #include <net/if.h> #include <net/if_du.h> #include "dialupip.h" #include "diald.h" typedef struct _TABLE { int Protocol; char *Name; } TABLE; static jmp_buf context; static int pleaserescan; static int pleasequit; static char *WHERE = "diald"; static TABLE ProtocolNames[] = { #ifdef IPPROTO_IP { IPPROTO_IP, "IP Dummy" }, #endif #ifdef IPPROTO_ICMP { IPPROTO_ICMP, "ICMP" }, #endif #ifdef IPPROTO_GGP { IPPROTO_GGP, "GGP" }, #endif #ifdef IPPROTO_TCP { IPPROTO_TCP, "TCP" }, #endif #ifdef IPPROTO_EGP { IPPROTO_EGP, "EGP" }, #endif #ifdef IPPROTO_PUP { IPPROTO_PUP, "PUP" }, #endif #ifdef IPPROTO_UDP { IPPROTO_UDP, "UDP" }, #endif #ifdef IPPROTO_IDP { IPPROTO_IDP, "IDP" }, #endif #ifdef IPPROTO_RAW { IPPROTO_RAW, "RAW" }, #endif { 0, NULL } }; static int authorized(rp, pkt) register REMOTE *rp; register struct du_pkt *pkt; { register int i; register TABLE *tp; struct timeval tv; struct tm *tm; /* check protocol */ i = pkt->du_ip.ip_p; if ((rp->Protocols[P_WORD(i)] & P_BIT(i)) == 0) { for (tp = ProtocolNames; tp->Name; tp++) if (i == tp->Protocol) break; d_log(DLOG_INFO, WHERE, "Bad protocol %s (%d)", tp ? tp->Name : "unknown"); return 0; } /* Check time. */ if (gettimeofday(&tv, (struct timezone *)NULL) < 0) { d_log(DLOG_GENERAL, WHERE, "Can't do gettimeofday, %m"); return 0; } if ((tm = localtime(&tv.tv_sec)) == NULL) { d_log(DLOG_GENERAL, WHERE, "Can't do localtime, %m"); return 0; } if ((rp->Times[tm->tm_wday] & (1L << tm->tm_hour)) == 0) { d_log(DLOG_INFO, WHERE, "Bad time to call"); return 0; } /* Check addresses. */ if (rp->AllowCount && !hostinlist(rp->AllowTo, pkt->du_ip.ip_dst)) { d_log(DLOG_INFO, WHERE, "Bad destination address \"%s\"", inet_ntoa(pkt->du_ip.ip_dst)); return 0; } if (rp->DisallowCount && hostinlist(rp->DisallowFrom, pkt->du_ip.ip_src)) { d_log(DLOG_INFO, WHERE, "Bad source address \"%s\"", inet_ntoa(pkt->du_ip.ip_src)); return 0; } /* o.k. to make call */ return 1; } static void catchsigterm() { pleasequit++; longjmp(context, 1); } static void catchsighup() { pleaserescan++; (void)signal(SIGHUP, catchsighup); longjmp(context, 1); } static void catchsigchld() { union wait wstatus; while (wait3(&wstatus, WNOHANG, (struct rusage *)NULL) > 0) ; } static void usage() { (void)fprintf(stderr, "usage: %s [options]\n", progname); d_log(DLOG_GENERAL, WHERE, "Usage error"); exit(1); } main(argc, argv) int argc; char *argv[]; { int f; int dofork; int i; struct du_pkt pkt; REMOTE *rp; char buff[256]; char *configfile; /* Set defaults. */ setprogname(argv[0]); WHERE = progname; dofork = 1; configfile = DIALD_CONFIG; /* Parse flags. */ while ((i = getopt(argc, argv, "c:d:F")) != EOF) switch (i) { default: usage(); /* NOTREACHED */ case 'c': configfile = optarg; break; case 'd': log_level = atoi(optarg); break; case 'F': dofork = 0; break; } argc -= optind; argv += optind; if (argc) usage(); /* Fork us off */ if (dofork) { if ((i = fork()) < 0) { d_log(DLOG_GENERAL, WHERE, "Can't fork, %m"); exit(1); } if (i > 0) exit(0); if (freopen("/dev/console", "w", stderr) == NULL) d_log(DLOG_GENERAL, WHERE, "Can't set stderr to /dev/console, %m"); } /* Read configuration data. */ if (!readconfig(configfile)) exit(1); /* Open the request device. */ if ((f = open(DEVDIAL, O_RDONLY)) < 0) { d_log(DLOG_GENERAL, WHERE, "Can't open \"%s\", %m", DEVDIAL); exit(1); } #ifdef FIOCLEX if (ioctl(f, FIOCLEX, (caddr_t)NULL) < 0) d_log(DLOG_INFO, WHERE, "Can't do FIOCLEX on \"%s\", %m", DEVDIAL); #endif /* FIOCLEX */ /* Tell the log file where are here */ d_log(DLOG_GENERAL, WHERE, "Diald %s started", dip_release()); (void)record_pid(progname); /* Process requests */ (void)signal(SIGHUP, catchsighup); (void)signal(SIGTERM, catchsigterm); (void)signal(SIGCHLD, catchsigchld); for ( ; ; ) { (void)setjmp(context); if (pleasequit) break; if (pleaserescan) { d_log(DLOG_GENERAL, WHERE, "Rescanning config files"); if (!readconfig(configfile)) { unlock_pid(); exit(1); } (void)signal(SIGHUP, catchsighup); pleaserescan = 0; continue; } /* Read the device. */ if ((i = read(f, (char *)&pkt, sizeof pkt)) != sizeof pkt) { if (errno != EINTR) d_log(DLOG_GENERAL, WHERE, "Bad read (%d bytes) from \"%s\", %m", i, DEVDIAL); continue; } /* Find config data for the address. */ (void)sprintf(buff, "%s%d", pkt.du_ifname, pkt.du_ifunit); if ((rp = findconfig(buff)) == NULL) { d_log(DLOG_GENERAL, WHERE, "Address %s not configured", inet_ntoa(pkt.du_sin.sin_addr)); continue; } /* Is this packet is authorized? */ if (pkt.du_checkit && !authorized(rp, &pkt)) { (void)sprintf(buff, "%s not authorized to reach %s", inet_ntoa(pkt.du_ip.ip_src), inet_ntoa(pkt.du_ip.ip_dst)); failcall(rp->Device, buff); continue; } /* Make the call. */ if (!dofork) { makecall(rp); continue; } if ((i = fork()) == 0) { (void)setpgrp(0, getpgrp(0)); makecall(rp); break; } if (i < 0) d_log(DLOG_GENERAL, WHERE, "Can't fork dialing process, %m"); } d_log(DLOG_GENERAL, WHERE, "Diald %s exiting", dip_release()); unlock_pid(); exit(0); /* NOTREACHED */ }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.