home *** CD-ROM | disk | FTP | other *** search
- /*
- ** 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.
- */
- /*
- * Copyright (c) 1992 Purdue University
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Purdue University. The name of the University may not 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Note: this copyright applies to portions of this software developed
- * at Purdue beyond the software covered by the original copyright.
- */
- #include <stdio.h>
- #include <ctype.h>
- #include <netdb.h>
- #include <memory.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/socket.h>
- #include <sys/stream.h>
- #include <sys/ioctl.h>
- #include <netinet/in_systm.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <net/if.h>
- #include <arpa/inet.h>
- #include "dp_str.h"
- #include "dp.h"
- #include "dpd.h"
- #include "dpconf.h"
-
-
- /*
- ** Some systems don't have these in their <netinet/in.h>
- */
- #ifndef IPPROTO_EGP
- #define IPPROTO_EGP 8
- #endif /* IPPROTO_EGP */
- #ifndef IPPROTO_RDP
- #define IPPROTO_RDP 27
- #endif /* IPPROTO_EGP */
-
-
- #define EQ(a, b) (strcmp((a), (b)) == 0)
- #define nexttok() strtok((char *)NULL, SEPARATORS)
-
-
- static int errorcount;
- static int linenum;
- static char SEPARATORS[] = " \t";
- static REMOTE *RemoteTable;
- static MODEM *ModemTable;
- static int RemoteCount;
- static int ModemCount;
- static char WHERE[] = "readconfig";
- static void d_vlog();
-
- extern long strtol();
-
- /*
- ** Find this interface in our list.
- */
- REMOTE *
- findconfig(device)
- register char *device;
- {
- register REMOTE *rp;
- register int i;
-
- for (rp = RemoteTable, i = RemoteCount; --i >= 0; rp++)
- if (strcmp(device, rp->Device) == 0)
- return rp;
- return NULL;
- }
-
- /*
- ** Find this interface in our list by login name.
- */
- REMOTE *
- findlogin(login)
- register char *login;
- {
- register REMOTE *rp;
- register int i;
-
- for (rp = RemoteTable, i = RemoteCount; --i >= 0; rp++)
- if (strcmp(login, rp->Login) == 0)
- return rp;
- return NULL;
- }
-
- /*
- ** Find this modem or modem rotary in our list.
- */
- MODEM *
- findmodem(modem)
- register char *modem;
- {
- register MODEM *mp;
- register int i;
-
- for (mp = ModemTable, i = ModemCount; --i >= 0; mp++)
- if (strcmp(modem, mp->Name) == 0)
- return mp;
- return NULL;
- }
-
-
- /*
- * Functions to de-allocate memory that is allocated for each configuration
- */
- free_remotes()
- {
- REMOTE *rp;
- int i;
- if (RemoteTable) {
- for (rp = RemoteTable, i = RemoteCount; --i >= 0; rp++)
- free_remote(rp);
- free((char *)RemoteTable);
- }
- RemoteCount = 0;
- }
-
- free_remote(rp)
- REMOTE *rp;
- {
- if (rp->Sitename)
- (void)free(rp->Sitename);
- if (rp->Login)
- (void)free(rp->Login);
- if (rp->Phone)
- (void)free(rp->Phone);
- if (rp->Script)
- (void)free(rp->Script);
- if (rp->ScriptArgs) {
- if (rp->ScriptArgs[0])
- (void)free(rp->ScriptArgs[0]);
- (void)free((char *)rp->ScriptArgs);
- }
- if (rp->Transcript)
- (void)free(rp->Transcript);
- if (rp->PppArgs) {
- if (rp->PppArgs[0])
- (void)free(rp->PppArgs[0]);
- (void)free((char *)rp->PppArgs);
- }
- if (rp->Modems)
- (void)free((char *)rp->Modems);
- if (rp->AuxProgram)
- (void)free(rp->AuxProgram);
- if (rp->AuxArgs) {
- if (rp->AuxArgs[0])
- (void)free(rp->AuxArgs[0]);
- (void)free((char *)rp->AuxArgs);
- }
- }
-
- free_modems()
- {
- MODEM *mp;
- int i;
- if (ModemTable) {
- for (mp = ModemTable, i = ModemCount; --i >= 0; mp++)
- free_modem(mp);
- free((char *)ModemTable);
- }
- ModemCount = 0;
- }
-
- free_modem(mp)
- MODEM *mp;
- {
- if (mp->Name)
- (void)free(mp->Name);
- if (mp->Line)
- (void)free(mp->Line);
- if (mp->DialScript)
- (void)free(mp->DialScript);
- if (mp->DialCharMap)
- (void)free(mp->DialCharMap);
- if (mp->Modems)
- (void)free((char *)mp->Modems);
- }
-
- /*
- ** Is the host (or its network) on the list of hosts and networks?
- */
- int
- hostinlist(list, addr)
- struct in_addr *list;
- struct in_addr addr;
- {
- register int i;
- register int j;
-
- j = i = addr.s_addr % MAXHOSTS;
-
- do {
- if (list[j].s_addr == 0)
- return 0;
- if (list[j].s_addr == addr.s_addr)
- return 1;
- if (inet_lnaof(list[j]) == 0
- && inet_netof(list[j]) == inet_netof(addr))
- return 1;
-
- if (++j == MAXHOSTS)
- j = 0;
- } while (j != i);
-
- return 0;
- }
-
-
- #include <varargs.h>
-
- void
- yyerror(va_alist)
- va_dcl
- {
- va_list ap;
- char *path,
- *fmt,
- buff[256];
-
- va_start(ap);
- path = va_arg(ap, char *);
- fmt = va_arg(ap, char *);
- (void)sprintf(buff, "Error near line %d of\n\t\"%s\": %s",
- linenum, path, fmt);
- d_vlog(DLOG_GENERAL, WHERE, buff, ap);
- va_end(ap);
- errorcount++;
- }
-
-
- static void
- parseprotocols(path, lp, set)
- char *path;
- u_long *lp;
- int set;
- {
- char *p;
- int i;
- struct protoent *pe;
-
- setprotoent(1);
- while (p = nexttok()) {
- if (pe = getprotobyname(p))
- i = pe->p_proto;
- else {
- yyerror(path, "Bad protocol \"%s\"", p);
- continue;
- }
- if (set == P_SET)
- lp[P_WORD(i)] |= P_BIT(i);
- else
- lp[P_WORD(i)] &= ~P_BIT(i);
- }
- endprotoent();
- }
-
-
- static int
- positivenumber(p)
- char *p;
- {
- if (*p == '\0')
- return 0;
- for ( ; *p; p++)
- if (!isdigit(*p))
- return 0;
- return 1;
- }
-
-
- static long
- parsetime(path)
- char *path;
- {
- long l;
- int i;
- char *p;
-
- for (l = 0; p = nexttok(); )
- if (!positivenumber(p) || (i = atoi(p)) < 0 || i > 23)
- yyerror(path, "Bad hour \"%s\"", p);
- else
- l |= (1L << i);
- return l;
- }
-
-
- static int
- addhosttolist(list, addr)
- struct in_addr *list;
- struct in_addr addr;
- {
- register int i;
- register int j;
-
- j = i = addr.s_addr % MAXHOSTS;
- do {
- if (list[j].s_addr == 0) {
- list[j] = addr;
- return 1;
- }
- if (++j == MAXHOSTS)
- j = 0;
- } while (j != i);
-
- return 0;
- }
-
-
-
- static int
- parseaddresslist(path, list)
- char *path;
- struct in_addr *list;
- {
- char *p;
- struct in_addr new;
- int i;
- struct hostent *hp;
- struct netent *np;
- struct in_addr in;
-
- for (i = 0; p = nexttok(); i++) {
- if ((new.s_addr = inet_addr(p)) != -1)
- ;
- else if (np = getnetbyname(p)) {
- in.s_addr = np->n_net;
- new = inet_makeaddr(in, 0);
- }
- else if (hp = gethostbyname(p))
- bcopy(hp->h_addr, (caddr_t)&new, sizeof new);
- else {
- yyerror(path, "Bad IP address \"%s\"", p);
- continue;
- }
- if (!hostinlist(list, new) && !addhosttolist(list, new))
- yyerror(path, "Can't add \"%s\" to address list", p);
- }
- return i;
- }
-
- char TOK_SEP[] = " \t";
- #define issep(c) strchr(TOK_SEP, (c))
-
- char *
- skip_sep(s)
- char *s;
- {
- while (*s && issep(*s))
- s++;
- return s;
- }
-
- char *
- next_tok(path, s)
- char *path,
- *s;
- {
- int inst = 0;
- char *s0 = s,
- *s1 = s,
- ch;
- s = skip_sep(s);
- if (*s == '#') {
- *s1++ = *s++;
- *s1 = '\0';
- return ++s;
- }
- for ( s1 = s ; ; s++)
- if ((!inst && strchr(TOK_SEP, *s)) || !*s) {
- if (inst)
- yyerror(path, "Unterminated string: %s\n", s0);
- *s1 = '\0';
- return ++s;
- }
- else
- switch (*s) {
- case '\\':
- s++;
- if (isdigit(*s)) {
- int i = 3;
- ch = 0;
- for ( ; *s && isdigit(*s) && i-- > 0 ; s++ )
- ch = (ch << 3) | (*s - '0');
- }
- else {
- switch (*s) {
- case 'b': ch = '\b'; break;
- case 'f': ch = '\f'; break;
- case 'n': ch = '\n'; break;
- case 'r': ch = '\r'; break;
- case 't': ch = '\t'; break;
- default: ch = *s; break;
- }
- }
- *s1++ = ch;
- break;
- case '"':
- inst = !inst;
- break;
- default:
- *s1++ = *s;
- break;
- }
- }
-
- static fln;
-
- char *
- fgetln(buf, bufsz, f)
- char *buf;
- int bufsz;
- FILE *f;
- {
- char *e, *b;
- b = fgets(buf, bufsz, f);
- if (b) {
- e = buf + strlen(buf) - 1;
- if (*e == '\n') {
- fln++;
- *e = '\0';
- }
- }
- else {
- fln = 0;
- buf[0] = '\0';
- if (ferror(f))
- perror("read");
- }
- return b;
- }
-
- sprascii(b, s)
- char *b,
- *s;
- {
- char c;
- while (c = *s++)
- if (!isascii(c)) {
- (void)sprintf(b, "\\%03o", c & 0xff);
- b += 4;
- }
- else if (!isprint(c)) {
- (void)sprintf(b, "^%c", c ^ 0x40);
- b += 2;
- }
- else
- *b++ = c;
- *b = '\0';
- }
-
- parse_ln(path, vv, t)
- char *path;
- var_val *vv;
- char *t;
- {
- int nv = 0;
- char *nt;
- for ( ; *t ; t = nt) {
- t = skip_sep(t);
- if (!*t || *t == '#')
- break;
- nt = next_tok(path, t);
- vv->var = malloc((unsigned)strlen(t)+1);
- (void)strcpy(vv->var, t);
- if (vv->val = strchr(vv->var, '=')) {
- *(vv->val)++ = '\0';
- nv++;
- vv++;
- }
- else {
- char buf[256];
- sprascii(buf, t);
- yyerror(path, "Bad configuration option \"%s\"\n", buf);
- }
- }
- return nv;
- }
-
- #define MAXCONFLN 1024
- #define MAXVARS 32
-
- var_val *
- readconf(path, cf)
- char *path;
- FILE *cf;
- {
- static char lnbuf[MAXCONFLN];
- static var_val vv[MAXVARS+1];
- var_val *vp;
- int n;
- int nv = 0;
- char *l;
- int line = 0;
-
- /*
- * De-allocate variable/value pairs from last time.
- */
- for (vp = vv ; vp->var ; vp++) {
- (void)free(vp->var);
- vp->var = vp->val = (char *)0;
- vp->used = 0;
- }
- vp = vv;
- linenum = 0;
-
- /*
- * Skip over any blank or comment lines..
- */
- l = skip_sep(lnbuf);
- while (*l == '#' || *l == '\0') {
- if (!fgetln(lnbuf, sizeof(lnbuf), cf))
- return (var_val *)0;
- l = skip_sep(lnbuf);
- }
-
- linenum = fln;
- /*
- * Definitions must start in column 0.
- */
- if (l != lnbuf) {
- yyerror(path, "Config entries must start in the first column: %s",
- lnbuf);
- }
-
- /*
- * We should be here with l pointing to a non-comment, non-blank line,
- * starting in column 0. Process lines until we either run into
- * a blank line, EOF, or another line starting in column 0.
- */
- do {
- if (*l != '#') {
- /*
- * Parse anything but a comment line.
- *
- * If we have read a line (line > 0), and something is in the
- * first column, it is a new definition.
- */
- if (line && l == lnbuf)
- break;
- n = parse_ln(path, vp, l);
- nv += n;
- vp += n;
- line++;
- }
- if (!fgetln(lnbuf, sizeof(lnbuf), cf))
- break;
- l = skip_sep(lnbuf);
- } while (*l);
-
- return nv ? vv : (var_val *)0;
- }
-
- int
- readconfig(path)
- char *path;
- {
- var_val *v;
- int nr = 0, nmr = 0, nm = 0;
- char *cfn;
- FILE *cf;
- #if 0
- path = "dp-conf";
- #endif
- cfn = expand_dir_file("$DPCONF_DIR", path);
- if (!(cf = fopen(cfn, "r"))) {
- perror(cfn);
- (void)free(cfn);
- return 0;
- }
- /*
- * Scan the file so we can allocate memory for our configuration.
- */
- while (v = readconf(cfn, cf))
- if (strcmp(v->var, "IF") == 0)
- nr++;
- else if (strcmp(v->var, "ROTARY") == 0)
- nmr++;
- else if (strcmp(v->var, "MODEM") == 0) {
- nmr++;
- nm++;
- }
- else
- yyerror(cfn, "unknown configuration option: \"%s\"\n", v->var);
-
- if (nr == 0)
- yyerror(cfn, "No Interfaces defined\n");
- if (nm == 0)
- yyerror(cfn, "No Modems defined\n");
-
- if (errorcount)
- return 0;
-
- free_remotes();
- RemoteTable = (REMOTE *)malloc((unsigned int)nr * sizeof(*RemoteTable));
- if (RemoteTable == NULL) {
- yyerror(cfn, "Can't allocate Remote table, %m");
- (void)free(cfn);
- return 0;
- }
- (void)memset((char *)RemoteTable, 0, nr * sizeof(*RemoteTable));
- free_modems();
- ModemTable = (MODEM *)malloc((unsigned int)nmr * sizeof(*ModemTable));
- if (ModemTable == NULL) {
- yyerror(cfn, "Can't allocate Modem table, %m");
- (void)free(cfn);
- return 0;
- }
- (void)memset((char *)ModemTable, 0, nmr * sizeof (*ModemTable));
- /*
- * Scan the file once for each type of configuration info.
- */
- rewind(cf);
- while (v = readconf(cfn, cf))
- if (strcmp(v->var, "MODEM") == 0)
- def_modem(cfn, v);
- rewind(cf);
- while (v = readconf(cfn, cf))
- if (strcmp(v->var, "ROTARY") == 0)
- def_rotary(cfn, v);
- rewind(cf);
- while (v = readconf(cfn, cf))
- if (strcmp(v->var, "IF") == 0)
- def_if(cfn, v);
-
- (void)fclose(cf);
- (void)free(cfn);
-
- return errorcount == 0;
- }
-
- char *
- savestr(s)
- char *s;
- {
- char *m = malloc((unsigned)strlen(s)+1);
- (void)strcpy(m, s);
- return m;
- }
-
- char **
- saveargs(path, s)
- char *path;
- char *s;
- {
- char *m, *nm;
- char **a;
- int n;
-
- if (!*s)
- return (char **)0;
- s = savestr(s);
- for (n = 0, m = s ; m ; m = ((m = strchr(m, ',')) ? m+1 : (char *)0))
- n++;
- a = (char **)malloc((unsigned)(n+1) * sizeof(char **));
- if (!a) {
- yyerror(path, "Can't allocate Argument list");
- return (char **)0;
- }
- n = 0;
- for (m = s; m ; m = nm) {
- if (nm = strchr(m, ','))
- *nm++ = '\0';
- a[n++] = m;
- }
- a[n] = (char *)0;
- return a;
- }
-
- char *
- find_val(v, var)
- var_val *v;
- char *var;
- {
- for ( ; v->var ; v++)
- if (strcmp(v->var, var) == 0) {
- v->used++;
- return v->val;
- }
- return (char *)0;
- }
-
-
- unused_vals(path, type, name, v)
- char *path,
- *type,
- *name;
- var_val *v;
- {
- for ( ; v->var ; v++)
- if (!v->used) {
- yyerror(path, "Unrecognized definition in %s %s: %s=%s",
- name, type, v->var, v->val);
- }
- }
-
- MODEM **
- modem_list(path, list, nmp, type, name)
- char *path, *list;
- int *nmp;
- char *type, *name;
- {
- MODEM **mpp, *mmp;
- char *m, *nm;
- int n;
- for (n = 0, m = list ; m ; m = ((m = strchr(m, ',')) ? m+1 : (char *)0))
- n++;
- mpp = (MODEM **)malloc((unsigned)n * sizeof(MODEM *));
- if (!mpp)
- yyerror(path, "Can't allocate Modem list");
- else {
- n = 0;
- for (m = list; m ; m = nm) {
- if (nm = strchr(m, ','))
- *nm++ = '\0';
- if (mmp = findmodem(m)) {
- mpp[n++] = mmp;
- }
- else
- yyerror(path, "Unknown MODEM \"%s\" in %s \"%s\"",
- m, type, name);
- }
- }
- *nmp = n;
- return mpp;
- }
-
- def_modem(path, v)
- char *path;
- var_val *v;
- {
- MODEM *mp;
- char *val;
-
- if (!(val = find_val(v, "MODEM")))
- yyerror(path, "MODEM definition must have MODEM defined");
- else {
- if (mp = findmodem(val)) {
- yyerror(path, "MODEM \"%s\" defined more than once");
- free_modem(mp);
- }
- else
- mp = &ModemTable[ModemCount++];
- mp->Name = savestr(val);
- }
- mp->NModems = 0; /* No rotary modems defined */
- if (!(val = find_val(v, "DEV")))
- yyerror(path, "MODEM definition must have DEV defined");
- else
- mp->Line = savestr(val);
-
- /*
- * Interpret common definitions for modems and rotaries.
- */
- def_modem_rotary(path, mp, v);
- /*
- * Make sure we used everything that was given.
- */
- unused_vals(path, "MODEM", mp->Name, v);
- }
-
- def_rotary(path, v)
- char *path;
- var_val *v;
- {
- MODEM *mp, **mpp;
- char *val;
-
- if (!(val = find_val(v, "ROTARY")))
- yyerror(path, "ROTARY definition must have ROTARY defined");
- else {
- if (mp = findmodem(val)) {
- yyerror(path, "ROTARY \"%s\" defined more than once", mp->Name);
- free_modem(mp);
- }
- else
- mp = &ModemTable[ModemCount++];
- mp->Name = savestr(val);
- }
-
- /*
- * Interpret common definitions for modems and rotaries.
- */
- def_modem_rotary(path, mp, v);
- /*
- * Extract and verify list of modems.
- */
- if (!(val = find_val(v, "MODEMS")))
- yyerror(path, "ROTARY definition must have MODEMS defined");
- else {
- int n;
- mp->Modems = modem_list(path, val, &mp->NModems, "ROTARY", mp->Name);
- if (!mp->DialScript)
- for (n = mp->NModems, mpp = mp->Modems; n-- ; mpp++)
- if (!(*mpp)->DialScript)
- yyerror(path, "ROTARY/MODEM %s/%s has no dialing script",
- mp->Name, (*mpp)->Name);
- if (!mp->Speed)
- for (n = mp->NModems, mpp = mp->Modems; n-- ; mpp++)
- if (!(*mpp)->Speed)
- yyerror(path, "ROTARY/MODEM %s/%s has no baud rate set",
- mp->Name, (*mpp)->Name);
- }
-
- /*
- * Make sure we used everything that was given.
- */
- unused_vals(path, "ROTARY", mp->Name, v);
- }
-
-
- def_modem_rotary(path, mp, v)
- char *path;
- MODEM *mp;
- var_val *v;
- {
- char *val;
-
- if (val = find_val(v, "BAUD"))
- switch (mp->Speed = atoi(val)) {
- case 1200:
- case 2400:
- case 4800:
- case 9600:
- case 19200:
- case 38400:
- #ifdef STS
- case 57600:
- #endif STS
- #ifdef FASTZS
- case 76800:
- #endif FASTZS
- break;
- default:
- yyerror(path, "Bad MODEM speed \"%s\"\n", val);
- break;
- }
-
- if (val = find_val(v, "DIAL_SCRIPT"))
- mp->DialScript = savestr(val);
-
- if (val = find_val(v, "DIAL_CHARMAP"))
- mp->DialCharMap = savestr(val);
-
- if (val = find_val(v, "ASYNC_MAP"))
- mp->AsyncMap = strtol(val, (char **)0, 16);
- }
-
- def_if(path, v)
- char *path;
- var_val *v;
- {
- REMOTE *rp;
- char *val;
-
- if (!(val = find_val(v, "IF")))
- yyerror(path, "IF definition must have IF defined");
- else {
- if (rp = findconfig(val)) {
- yyerror(path, "IF \"%s\" defined more than once", rp->Sitename);
- free_remote(rp);
- }
- else
- rp = &RemoteTable[RemoteCount++];
- if (strlen(val) > MAXDEVLEN)
- yyerror(path, "IF \"%s\" name too long (> %d)",
- rp->Sitename, MAXDEVLEN);
- else {
- (void)strcpy(rp->Device, val);
- while (*val && !isdigit(*val))
- val++;
- if ((rp->Unit = atoi(val)) < 0) {
- yyerror(path, "IF \"%s\" bad unit number (%d)",
- rp->Sitename, rp->Unit);
- }
- }
- }
-
- if (!if_addrs(rp))
- return;
-
- if (val = find_val(v, "SYS"))
- rp->Sitename = savestr(val);
- else {
- struct hostent *hp = gethostbyaddr((char *)&rp->DstAddress,
- sizeof(rp->DstAddress), AF_INET);
- rp->Sitename = savestr(hp ? hp->h_name : inet_ntoa(rp->DstAddress));
- }
-
- if (!(val = find_val(v, "MODEMS")))
- yyerror(path, "IF definition must have MODEMS defined");
- else
- rp->Modems = modem_list(path, val, &rp->NModems, "IF", rp->Sitename);
-
- if (val = find_val(v, "LOGIN_SCRIPT"))
- rp->Script = savestr(val);
- if (val = find_val(v, "LOGIN_ARGS"))
- rp->ScriptArgs = saveargs(path, val);
-
- if (val = find_val(v, "LOGIN"))
- rp->Login = savestr(val);
-
- if (val = find_val(v, "PHONE"))
- rp->Phone = savestr(val);
-
- if (val = find_val(v, "ASYNC_MAP"))
- rp->AsyncMap = strtol(val, (char **)0, 16);
-
- if (val = find_val(v, "LOG_LEVEL"))
- rp->LogLevel = atoi(val);
-
- if (val = find_val(v, "TRACE")) {
- char *p;
- if ((p = strchr(val, '@')) && isdigit(p[1]) && p[2] == '\0')
- rp->Transtyle = *++p == '0' ? TS_LOW : TS_HIGH;
- else
- rp->Transtyle = TS_LOW;
- rp->Transcript = expand_dir_file("$DPTRACE_DIR", val);
- }
-
- if (val = find_val(v, "PPP_ARGS"))
- rp->PppArgs = saveargs(path, val);
-
- if (val = find_val(v, "AUX"))
- rp->AuxProgram = savestr(val);
- if (val = find_val(v, "AUX_ARGS"))
- rp->AuxArgs = saveargs(path, val);
-
- if (val = find_val(v, "ACCESS"))
- (void)readaccess(path, val, rp);
-
- /*
- * Make sure we used everything that was given.
- */
- unused_vals(path, "IF", rp->Sitename, v);
- }
-
- readaccess(cpath, path, rp)
- char *cpath,
- *path;
- REMOTE *rp;
- {
- int i;
- FILE *F;
- char *p, *word;
- char buff[BUFSIZ];
- long *timeouts;
-
- /* Set access defaults. */
- for (i = 0; i < 7; i++)
- rp->Times[i] = ~0;
- for (i = 0; i < 8; i++)
- rp->Protocols[i] = ~0;
- for (rp->AllowCount = 0, i = 0; i < MAXHOSTS; i++)
- rp->AllowTo[i].s_addr = 0;
- for (rp->DisallowCount = 0, i = 0; i < MAXHOSTS; i++)
- rp->DisallowFrom[i].s_addr = 0;
- for (i = 0 ; i < DP_NTIMEOUTS ; i++)
- rp->DTimeouts[i] = rp->ATimeouts[i] = DP_NO_TIMEOUT;
-
- /* Field five, the access file. */
- if (*path == '\0')
- return errorcount == 0;
-
- path = expand_dirs_file("$DPCONF_DIR:$DPACCESS_DIR", path);
- if ((F = fopen(path, "r")) == NULL) {
- yyerror(cpath, "Can't open access file \"%s\"", path);
- (void)free(path);
- return 0;
- }
-
- /* Read lines. */
- for (linenum = 1; fgets(buff, sizeof buff, F); linenum++) {
- if ((p = strchr(buff, '\n')) == NULL) {
- yyerror(buff, "Line too long", (char *)NULL);
- (void)fclose(F);
- (void)free(path);
- return 0;
- }
- *p = '\0';
- if ((word = strtok(buff, SEPARATORS)) == NULL)
- continue;
- if (*word == '#')
- continue;
- /*
- * Allow the setting of Dial out or Answer call timeouts seperately.
- * This should also be done for allowable call times, etc., but that
- * has not yet been implemented.
- */
- timeouts = rp->DTimeouts;
- if (strncmp(word, "answer:", sizeof("answer:")-1) == 0) {
- word += sizeof("answer:")-1;
- timeouts = rp->ATimeouts;
- }
- else if (strncmp(word, "dial:", sizeof("dial:")-1) == 0)
- word += sizeof("dial:")-1;
-
- /*
- * Dispatch on the word to fill in the fields.
- */
- if (EQ(word, "allowto") || EQ(word, "gooddstaddresses"))
- rp->AllowCount += parseaddresslist(path, rp->AllowTo);
- else if (EQ(word, "disallowfrom") || EQ(word, "badsrcaddresses"))
- rp->DisallowCount += parseaddresslist(path, rp->DisallowFrom);
- else if (EQ(word, "protocols") || EQ(word, "goodprotocols")) {
- /*
- * specific protocols to allow
- * disallow all protocols first, then allow the specific ones
- * on the `protocols' line
- */
- for (i = 0 ;
- i < sizeof(rp->Protocols)/sizeof(rp->Protocols[0]) ;
- i++)
- rp->Protocols[i] = 0;
- parseprotocols(path, rp->Protocols, P_SET);
- }
- else if (EQ(word, "badprotocols")) {
- /*
- * specific protocols to disallow
- * start either with all enabled by default or with the ones
- * enabled by protocols or goodprotocols line
- */
- parseprotocols(path, rp->Protocols, P_RESET);
- }
- else if (EQ(word, "inactivity")) {
- if (p = nexttok())
- if (!positivenumber(p))
- yyerror(path, "Bad number \"%s\"", p);
- else
- timeouts[DP_ATIMEO] = atoi(p);
- }
- else if (EQ(word, "last_close")) {
- if (p = nexttok())
- if (!positivenumber(p))
- yyerror(path, "Bad number \"%s\"", p);
- else
- timeouts[DP_CTIMEO] = atoi(p);
- }
- else if (EQ(word, "non_tcp")) {
- if (p = nexttok())
- if (!positivenumber(p))
- yyerror(path, "Bad number \"%s\"", p);
- else
- timeouts[DP_UTIMEO] = atoi(p);
- }
- else if (EQ(word, "failedcall")) {
- if (p = nexttok())
- if (!positivenumber(p))
- yyerror(path, "Bad number \"%s\"", p);
- else
- timeouts[DP_FTIMEO] = atoi(p);
- }
- else if (EQ(word, "callwait")) {
- if (p = nexttok())
- if (!positivenumber(p))
- yyerror(path, "Bad number \"%s\"", p);
- else
- timeouts[DP_WTIMEO] = atoi(p);
- }
- else if (EQ(word, "weekdays"))
- rp->Times[1] = rp->Times[2] = rp->Times[3] =
- rp->Times[4] = rp->Times[5] = parsetime(path);
- else if (EQ(word, "weekends"))
- rp->Times[0] = rp->Times[6] = parsetime(path);
- else if (EQ(word, "sun") || EQ(word, "sunday"))
- rp->Times[0] = parsetime(path);
- else if (EQ(word, "mon") || EQ(word, "monday"))
- rp->Times[1] = parsetime(path);
- else if (EQ(word, "tue") || EQ(word, "tuesday"))
- rp->Times[2] = parsetime(path);
- else if (EQ(word, "wed") || EQ(word, "wednesday"))
- rp->Times[3] = parsetime(path);
- else if (EQ(word, "thu") || EQ(word, "thursday"))
- rp->Times[4] = parsetime(path);
- else if (EQ(word, "fri") || EQ(word, "friday"))
- rp->Times[5] = parsetime(path);
- else if (EQ(word, "sat") || EQ(word, "saturday"))
- rp->Times[6] = parsetime(path);
- else
- yyerror(path, "Bad parameter \"%s\"", word);
- }
-
- (void)free(path);
- (void)fclose(F);
- return errorcount == 0;
- }
-
-
- set_if_timeouts()
- {
- REMOTE *rp;
- int i;
-
- for (rp = RemoteTable, i = RemoteCount; --i >= 0; rp++)
- if (!if_dtimeouts(rp))
- return 0;
- return 1;
- }
-
- /*
- * Get the internet addresses from the kernel for the given interface.
- */
- if_addrs(rp)
- REMOTE *rp;
- {
- static char WHERE[] = "if_addrs";
- int s;
- struct ifreq ifr;
-
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- d_log(DLOG_GENERAL, WHERE,
- "Can't create socket to read interface addresses for \"%s\", %m",
- rp->Device);
- return 0;
- }
- (void)strcpy(ifr.ifr_name, rp->Device);
- if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
- d_log(DLOG_GENERAL, WHERE,
- "Can't get interface address for \"%s\", %m", rp->Device);
- (void)close(s);
- return 0;
- }
- rp->Address = ((struct sockaddr_in *)(&ifr.ifr_addr))->sin_addr;
- if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
- d_log(DLOG_GENERAL, WHERE,
- "Can't get interface destination address for \"%s\", %m",
- rp->Device);
- (void)close(s);
- return 0;
- }
- rp->DstAddress = ((struct sockaddr_in *)(&ifr.ifr_dstaddr))->sin_addr;
- (void)close(s);
- if (rp->Address.s_addr == INADDR_ANY) {
- d_log(DLOG_GENERAL, WHERE,
- "Interface address for \"%s\" not configured, %m",
- rp->Device);
- return 0;
- }
- if (rp->DstAddress.s_addr == INADDR_ANY) {
- d_log(DLOG_GENERAL, WHERE,
- "Destination interface address for \"%s\" not configured, %m",
- rp->Device);
- return 0;
- }
- return 1;
- }
-
- if_dtimeouts(rp)
- REMOTE *rp;
- {
- static char WHERE[] = "if_dtimeouts";
- int s;
- struct ifreq ifr;
- #define to ((u_long *)(ifr.ifr_data))
-
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- d_log(DLOG_GENERAL, WHERE,
- "Can't create socket to configure timeouts for \"%s\", %m",
- rp->Device);
- return 0;
- }
- (void)strcpy(ifr.ifr_name, rp->Device);
- (void)memcpy((caddr_t)to, (char *)&rp->DTimeouts[DP_ATIMEOUTS],
- DP_NATIMEOUTS * sizeof(rp->DTimeouts[0]));
- if (ioctl(s, SIOCSDPIATIMEO, (caddr_t)&ifr) < 0) {
- d_log(DLOG_GENERAL, WHERE,
- "Can't set Dial Activity Timeouts on \"%s\", %m", rp->Device);
- (void)close(s);
- return 0;
- }
- (void)strcpy(ifr.ifr_name, rp->Device);
- (void)memcpy((caddr_t)to, (char *)&rp->DTimeouts[DP_CTIMEOUTS],
- DP_NCTIMEOUTS * sizeof(rp->DTimeouts[0]));
- if (ioctl(s, SIOCSDPICTIMEO, (caddr_t)&ifr) < 0) {
- d_log(DLOG_GENERAL, WHERE,
- "Can't set Dial Call Timeouts on \"%s\", %m", rp->Device);
- (void)close(s);
- return 0;
- }
- d_log(DLOG_ALL, WHERE, "Set Dial Timeouts for \"%s\"", rp->Device);
- (void)close(s);
- return 1;
- }
-
- if_atimeouts(rp)
- REMOTE *rp;
- {
- static char WHERE[] = "if_atimeouts";
- int s;
- struct ifreq ifr;
- #define to ((u_long *)(ifr.ifr_data))
-
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- d_log(DLOG_GENERAL, WHERE,
- "Can't create socket to configure timeouts for \"%s\", %m",
- rp->Device);
- return 0;
- }
- (void)strcpy(ifr.ifr_name, rp->Device);
- (void)memcpy((caddr_t)to, (char *)&rp->ATimeouts[DP_ATIMEOUTS],
- DP_NATIMEOUTS * sizeof(rp->ATimeouts[0]));
- if (ioctl(s, SIOCSDPIATIMEO, (caddr_t)&ifr) < 0) {
- d_log(DLOG_GENERAL, WHERE,
- "Can't set Answer Activity Timeouts on \"%s\", %m", rp->Device);
- (void)close(s);
- return 0;
- }
- d_log(DLOG_ALL, WHERE, "Set Answer Timeouts for \"%s\"", rp->Device);
- (void)close(s);
- return 1;
- }
-