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.