From a17e555c2c3755105dc62a6c96f6d49556aff1d5 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 10 Aug 1995 06:48:39 +0000 Subject: [PATCH] Additions to support NeXTStep systems. --- README.NeXT | 381 +++++++++++ chat/Makefile.NeXT | 43 ++ pppd/Makefile.NeXT | 81 +++ pppd/sys-NeXT.c | 1351 ++++++++++++++++++++++++++++++++++++++++ pppstats/Makefile.NeXT | 45 ++ 5 files changed, 1901 insertions(+) create mode 100644 README.NeXT create mode 100644 chat/Makefile.NeXT create mode 100644 pppd/Makefile.NeXT create mode 100644 pppd/sys-NeXT.c create mode 100644 pppstats/Makefile.NeXT diff --git a/README.NeXT b/README.NeXT new file mode 100644 index 0000000..fe1ec2b --- /dev/null +++ b/README.NeXT @@ -0,0 +1,381 @@ +# +# $Id: README.NeXT,v 1.1 1995/08/10 06:48:23 paulus Exp $ +# + +This distribution contains a port of PPP-2.2 for NeXT. The full +source code is available as well as an MAB installer package. Since +this project is a continuing effort, you are encouraged to check out +the WWW page to see if you have the latest software. This is +especially true if you find you have problems with the version you +presently use. For more information on the NeXT PPP port see: + http://www.thoughtport.com:8080/PPP/ + -or- + ftp://ftp.thoughtport.com/pub/next/ppp/ + +For more information on PPP in general, you might want to check out: + http://cs.uni-bonn.de/ppp/faq.html + -and- + ftp://morningstar.com/pub/papers/ppp-white-paper.ps.gz + -and- + http://www.cis.ohio-state.edu/hypertext/faq/usenet/pdial/faq.html + (This last is a list of internet providers) + + +See the file ./README for general information regarding PPP-2.2 for + all computer systems. +See the file ./SETUP for general setup information for all computer systems. +See the file ./NeXT/INSTALL for NeXT Specific installation instructions. +See the file ./NeXT/README.NeXT for bugs. + +New to release 0.4.5 (LKS version 4.9 release1) +====================================== + + * This release is based on the third beta release of + PPP-2.2 (ppp-2.2b3.tar.gz) by Paul Mackerras. It will + probably be the version released along with PPP-2.2. + + * Some enhancements to the Example ip-up and ip-down + scripts. + + * Several documentation enhancements to support the + actual release. + + * Removed the new locking code. Temporarily, we continue + to rely on the old mechanism. + + * This program runs on Intel, Moto, and Sparc. It apparently + runs fine on HP until shutdown. Then there appear to be problems. + Due to time constraints, this will have to be corrected as a patch. + As usual, this will be available on ftp.thoughtport.com:/pub/next/ppp/. + + +New to release 0.4.4 (LKS version 4.5) +====================================== + + * The netbuf queueing mechanism was significantly + simplified. It is hoped that some HP memory + alignment problems were also solved. This may + help solve some of the mysterious panics others have + seen. + + * A new locking mechanism was implemented that + may simplify the spl() calls. + + * Memory allocation in BSD Compress code was cleaned up in + an attempt to solve HP alignment problems. + + * Thanks go to Pete French for all the + above modifications + +New to release 0.4.3 (LKS version 4.4) +====================================== + + * This release fixes some problems regarding + HP and SPARC support. It is said to now run + on Sparc. I would hope HP also but havn't heard + yet. Thanks to Dave Hess + for finding the problems for Sparc. + + * Minor documentation fixes. + + +New to release 0.4.0 (LKS version 4.1 - summerb2) +================================================= + + * This release is based on the second beta release + of PPP-2.2 (ppp-2.2b2). + + * The default chat is now the one supplied in the beta + PPP release. This chat will compile fine using Dev 3.3. + However, if you are running Dev 3.2, you will not be able + to compile the default chat (POSIX problems). In this case, + you may use the old chat (renamed as ./chat/chat.c.3.2). + + + +New to release 0.4.0 (LKS version 4.0 - summerb1) +================================================= + + * This release is based on the first beta release + of PPP-2.2 (ppp-2.2b1). + + * Chat was updated in the new beta. However, because + of broken posix functionality under NeXTSTEP (3.2) it + will not compile properly. Therefore, the old chat + is being used. The newer chat is backed up as + ./chat/chat.c.orig. Those with Dev 3.3 may wish to + try to compile to see if the posix problems were fixed. + + * Support for the Microsoft Call Back Configuration Protocol. + See the file ./README.cbcp. + + + +New to release 0.3.0 (LKS version 3.0 - summera51) +===================================== + + * This release is the first to be based on the fifth alpha + release of PPP-2.2 (ppp-2.2a5). + + * Major kernel revision. This release attempts to merge + the LKS written by Perkins and that written by Prindeville/French. + The hope is that this new merged kernel will allow us to maintain + one set of sources. This kernel, or a variant thereof, will + probably be the one that is released with the PPP-2.2 beta + distribution. + + * Fixed a bug that caused problems with NXFax's capability + to determine port usage. + + * Added support for the Berkley Packet Filter (BPF) and tcpdump. + Use of BPF requires special installation instructions. See + the installation file for more info. + + * Fixed a header include problem that kept sources from compiling + under NS 3.3 Dev. for m68k. *Sigh* I guess support for m68k + continues to falter... :( + + * Officially changed the name of the log file from: + /usr/adm/ppp2.2.debug + -to- + /usr/adm/ppp2.2.log + If you are upgrading, you should change the name of the file + in /etc/syslog.conf. Remember to watch out for the tab character + and remember to create the initial file. For more information see + ./NeXT/INSTALL. + + This change was done so that the file could be opened from the + workspace. There was a naming conflict with the .debug extension. + Note also, that this name is a bit different than that suggested in + the ./SETUP file. + + * Fixed a problem with the pppd option 'local'. + +As part of a5: + + * Fixed a bug in pppd that would allow service (under some circumstances) + to peers who refuse to authenticate. + + * Fixed a bug with CCP negotiation. + + * Fixed a bug that caused negotation with an NT RAS PPP server to fail. + + +New to release 1.9 (LKS version 2.1) +===================================== + + * Support for NS Sparc has been added. Sparc users note, the SUN + serial driver in the pre-release was not very robust at high speeds. + This has been fixed for the final release. This could cause problems + with testing on Sparc. Low bps rates should be OK...like 2400 to + maybe 9600 with low system activity. Thanks go to + John Landwehr for this work. + + * Fixed a nasty little bug that degraded performance of multiple + interfaces on Intel systems. + + * Added support for IP address filtering. This allows + detection and prevetion of IP address spoofing. Check out + the new ./pppexclude directory. Thanks to + Lawrence E. Freil for this code. + + * More support for multiple ppp connections to different + hosts. Check out ./Examples/ppp_multiple_hosts.tar.gz. + Thanks to Jonathan Adams for this + code. + + * Modified lock file for better UUCP interaction. Special + thanks to Kim Shrier for this code. + + * Fixed the new 3.3 multicast warning. + + * Improved installation documentation. + + +New to release 1.8 (LKS version 1.3) +===================================== + + * Moved to ppp-2.2a4, the fourth alpha release + from Paul Mackerras . + + * Fixed a bug that I introduced in 1.7 that could cause + kernel panics when BSD compression was used in conjunction + with VJ header compression. + + * LKS Numbering Scheme changed (due to my screwup with a4 and CVS). + + * Removed support for extra pppd option 'usepty'. Can be done + with an external program if desired. + + * Included the old modified pppstats.c that shows compression + statistics. + +New to release 1.7 (LKS version 1.31) +===================================== + + * Moved packet compression outside the interrupt handler. + Previously, only packet decompression was done outside. + + * Made many enhancements as suggested by Paul Mackerras. + + * Fixed a bug that sometimes caused "bad fcs" errors to panic + the machine. + + * Fixed a problem that caused NFS traffic to force + compression to exit (and sometimes hang NFS). + NFS traffic works properly now (regardless of the buffer size + set via the NFSManager.app). + + * Fixed a timeout problem in pppd that could sometimes cause + negotiations to loop endlessly. This fix should eventually make + it into ppp2.2a4. + + * Split code into multiple files for better organization. + + * Fixed pppstats to show compression ratios on the proper + side. Left side is for incoming packets and right side is + for outgoing packets. + + * Added some suggested enhancements to + pppd. These suggestions were brought up + on the ports mailing list and will probably + be included in ppp2.2a4. I added them for + the interrim. They basically involve better permissions + for running the ip-up and ip-down scripts. They are now run + as the effective user-id of pppd. So if you run pppd suid, + root, then ip-up and ip-down are run as root. + + * Corrected several minor documentation problems. + + +New to release 1.6 (LKS version 1.24) +===================================== + + * Added support for HP-PA systems. Many thanks go to + Alain Fauconnet for his efforts in this + work. + + * Added further performance enhancements to the LKS. This resulted + in fewer "silo overflows", and thus dropped packets, when operating + at high speed (>= 38.4KBS) sustained bidirectional transfers over + multiple interfaces. + + * Updated the installation instructions. + + +New to release 1.5 (LKS version 1.22) +===================================== + + * Not a real release. Used for distributing + tests to HPPA users. + + +New to release 1.4 (LKS version 1.18) +===================================== + + * Fixed problem that delayed many PPP protcol packets from timely + delivery to pppd. + + * Added compression statistics support for pppstats. + + * Cleaned up processor priority levels. + + * Added better support for netbuf queue monitoring. + + +New to release 1.3 (LKS version 1.16) +===================================== + + * At compile time, you have the option to decompress VJ/BSD + packets either inside or outside the interrupt handler. + See the DECOMP_OUT flag in ./NeXT/Makefile. The old + functionality was to do the work inside the interrupt + handler. It is probably more appropriate to do it + outside. Thanks to Pete French for + discussion on this topic. + + * Added initial support for operation over pseudo + ttys. See the USEPTY flag in ./pppd/Makefile.NeXT. + This adds a new option to pppd, "usepty ". + If this option is used, pppd will fire up an rlogin + session to . You may then use chat as normal + to start the remote ppp. Thereafter, the packets flow + over the rlogin session. This may potentially be used + to start a new ppp session over an open ppp session. + + * Added enhancements and changes suggested for ppp-2.2a3. + This includes some fixes to the BSD compression code + that caused it to turn off compression inappropriately + under error conditions. + + * Patched pppd to better support code that sleeps but never + wakes in ip-up scripts. Thanks to longyear@netcom.com + (Al Longyear) and Bill Hay . + + * Did more verification with the full version of NXFAX installed. + Seems to work flawlessly! Thanks to Rick Damon + at Black and White for his help in the matter. + + * Added a new 'Examples' directory to the hierarchy. This + will become a collecting place for user info. + + + +New to release 1.2 (LKS version 1.13) +===================================== + + * The system now supports BSD Packet compression using the new CCP. + Of course, both ends must negotiate this option. + + +New to release 1.1 +================== + + * The system now works with the MuX serial driver V1.5. Probably + version 1.4 also. No changes need to be made to the MuX buffer + (and DOUBLE_BUFFER) values. + + * The system now works when NXFax is installed. + + * There have been some internal optimizations for those + who use the NeXT supplied serial drivers. + + +New to release 1.0 +================== + + * On Intel systems, some ioctl calls did not return the proper value. + This turned out to be a bug in the OS. A true workaround has been + implemented. The ioctl return value macro is now only used to + check for return value errors. Flags are now correctly set without + the macro. + + * Multiple interfaces now work properly. The ioctl fix above solved + the problem of a second interface "stealing" the first interface. + + * lcp-echo-failure works. + + * We are now using the default pppstats. This was modified to + use an ioctl to get information. One less program we have to + support. pppstats no longer requires the SUID bit or the loadable. + + * We are now using the default VJ compression code. Another + file we do not have to support. + + * PPP-2.2 uses a new mechanism for determining when to kill pppd. + This should solve the process group problems we have been + experiencing. + + * Compression is not yet implemented. This release should give you + the same (but more stable) functionality as the ppp-2.1.2 release. + + + +For problems, please mail nextppp@listproc.thoughtport.com. Make +sure you read the TROUBLESHOOTING section in ./NeXT/INSTALL so that +you send all the appropriate information. Further, there is an +extensive FAQ available at: + http://www.thoughtport.com:8080/PPP/ + + + diff --git a/chat/Makefile.NeXT b/chat/Makefile.NeXT new file mode 100644 index 0000000..799371f --- /dev/null +++ b/chat/Makefile.NeXT @@ -0,0 +1,43 @@ +# +# Makefile for chat on NeXTs +# +# $Id: Makefile.NeXT,v 1.1 1995/08/10 06:48:28 paulus Exp $ +# + +ARCHFLAGS = -arch i386 -arch m68k +BINDIR = /usr/local/ppp/bin +MANDIR = /usr/local/ppp/man + +CFLAGS= -O -posix $(ARCHFLAGS) + +SRCS = chat.c +OBJS = chat.o + +MANPAGES = chat.8 + + +# +# Load dependencies +# +all: chat + +chat: $(OBJS) + $(CC) -o chat $(CFLAGS) $(OBJS) + +install: + /bin/mkdirs $(MANDIR)/man8 $(BINDIR) + install -c -s -m 555 -o root -g wheel chat $(BINDIR)/chat + install -c -m 444 -o root -g wheel chat.8 $(MANDIR)/man8 + +clean: + rm -f *~ *.o chat .depend + +depend: + cc -M $(CFLAGS) $(SRCS) > .depend + +#.depend: $(SRCS) +# @echo Check dependencies if needed + +# cc -M $(CFLAGS) $(SRCS) > .depend + +#include .depend diff --git a/pppd/Makefile.NeXT b/pppd/Makefile.NeXT new file mode 100644 index 0000000..7e8ab81 --- /dev/null +++ b/pppd/Makefile.NeXT @@ -0,0 +1,81 @@ +# +# pppd makefile for NeXT +# +# $Orignial: Makefile.ultrix,v 1.4 1994/09/01 00:40:40 paulus Exp $ +# $Id: Makefile.NeXT,v 1.1 1995/08/10 06:48:33 paulus Exp $ +# + +ARCHFLAGS = -arch i386 -arch m68k -arch hppa -arch sparc +#ARCHFLAGS = -arch i386 -arch m68k +BINDIR = /usr/local/ppp/bin +MANDIR = /usr/local/ppp/man + +PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ + auth.c options.c sys-bsd.c sys-str.c sys-ultrix.c \ + sys-linux.c lock.c +HEADERS = callout.h pathnames.h patchlevel.h chap.h md5.h +MANPAGES = pppd.8 + +PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ + auth.o options.o sys-NeXT.o + +# CC = gcc +DEBUG_FLAGS = -O -posix $(ARCHFLAGS) + + +# +# If you use white hardware, uncomment this line to get +# around an apparent bug with ioctl. See sys-NeXT.c for +# more information. OK on black, but not necessary. +# Further, only necessary if you are using the NeXT supplied +# serial drivers. The MuX driver works flawlessly (and faster). +# The new NeXT serial drivers put on NeXTAnswers also work flawlessly. +# +# For HPPA and SPARC, define FIXSIGS to get around posix bugs in +# OS release 3.2. Problems are supposed to be fixed +# in release 3.3 (but at least for Sparc don't appear to be). +# +# + +COMPILE_FLAGS = -DNO_DRAND48 -DHAS_BROKEN_IOCTL \ + -DDEBUGUPAP -DDEBUGCHAP -DDEBUGLCP -DDEBUGIPCP \ + -DFIXSIGS + + +COPTS = -O +LIBS = + +CFLAGS = -I../NeXT -I.. $(COPTS) $(DEBUG_FLAGS) $(COMPILE_FLAGS) + +SOURCE= RELNOTES Makefile \ + $(PPPDSRCS) $(HEADERS) $(MANPAGES) + +all: pppd + +install: + /bin/mkdirs $(MANDIR)/man8 $(BINDIR) + install -c -s -m 4511 -o root -g daemon pppd $(BINDIR)/pppd + install -c -m 444 -o root -g wheel pppd.8 $(MANDIR)/man8 + +pppd: $(PPPDOBJS) + $(CC) $(CFLAGS) -o pppd $(PPPDOBJS) $(LIBS) + +pppd.tar: $(SOURCE) + tar -cvf pppd.tar $(SOURCE) + +pppd.tar.Z: pppd.tar + compress pppd.tar + +clean: + rm -f $(PPPDOBJS) pppd *~ #* core + +depend: + cpp -M $(CFLAGS) $(PPPDSRCS) >.depend +# makedepend $(CFLAGS) $(PPPDSRCS) + +saber_pppd: + #setopt load_flags $(CFLAGS) + #setopt ansi + #suppress 452 md5.c + #load $(PPPDSRCS) + diff --git a/pppd/sys-NeXT.c b/pppd/sys-NeXT.c new file mode 100644 index 0000000..a23f611 --- /dev/null +++ b/pppd/sys-NeXT.c @@ -0,0 +1,1351 @@ +/* + * sys-next.c - System-dependent procedures for setting up + * PPP interfaces on NeXT 3.2/3.3 systems + * + * Copyright (c) 1989 Carnegie Mellon University. + * Copyright (c) 1994 Philippe-Andre Prindeville. + * 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 Carnegie Mellon 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. + */ + +#ifndef lint +static char rcsid[] = "$Id: sys-NeXT.c,v 1.1 1995/08/10 06:48:34 paulus Exp $"; +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "pppd.h" + +static int initdisc = -1; /* Initial TTY discipline */ + +extern int errno; + +static int restore_term; /* 1 => we've munged the terminal */ +static struct termios inittermios; /* Initial TTY termios */ + +static char *lock_file; + +int sockfd; /* socket for doing interface ioctls */ + +#if defined(i386) && defined(HAS_BROKEN_IOCTL) +#define ioctl myioctl +#endif + +/* + * sys_init - System-dependent initialization. + */ +void +sys_init() +{ + openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); + setlogmask(LOG_UPTO(LOG_INFO)); + if (debug) + setlogmask(LOG_UPTO(LOG_DEBUG)); + + /* Get an internet socket for doing socket ioctl's on. */ + if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + syslog(LOG_ERR, "Couldn't create IP socket: %m"); + die(1); + } +} + +/* + * note_debug_level - note a change in the debug level. + */ +void +note_debug_level() +{ + if (debug) { + syslog(LOG_INFO, "Debug turned ON, Level %d", debug); + setlogmask(LOG_UPTO(LOG_DEBUG)); + } else { + setlogmask(LOG_UPTO(LOG_WARNING)); + } +} + +/* + * ppp_available - check whether the system has any ppp interfaces + * (in fact we check whether we can do an ioctl on ppp0). + */ +int +ppp_available() +{ + int s, ok; + struct ifreq ifr; + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + return 1; /* can't tell - maybe we're not root */ + + strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); + ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; + close(s); + + return ok; +} + +/* + * establish_ppp - Turn the serial port into a ppp interface. + */ +void +establish_ppp() +{ + int pppdisc = PPPDISC; + int x; + + if (ioctl(fd, TIOCGETD, &initdisc) < 0) { + syslog(LOG_ERR, "ioctl(TIOCGETD): %m"); + die(1); + } + if (ioctl(fd, TIOCSETD, &pppdisc) < 0) { + syslog(LOG_ERR, "ioctl(establish TIOCSETD): %m"); + die(1); + } + + /* + * Find out which interface we were given. + */ + if (ioctl(fd, PPPIOCGUNIT, &ifunit) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m"); + die(1); + } + + /* + * Enable debug in the driver if requested. + */ + if (kdebugflag) { + if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_WARNING, "ioctl(PPPIOCGFLAGS): %m"); + } else { + x |= (kdebugflag & 0xFF) * SC_DEBUG; + if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) + syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %m"); + } + } +} + + +/* + * disestablish_ppp - Restore the serial port to normal operation. + * This shouldn't call die() because it's called from die(). + */ +void +disestablish_ppp() +{ + int x; + char *s; + + if (initdisc >= 0) { + /* + * Check whether the link seems not to be 8-bit clean. + */ + if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) { + s = NULL; + switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) { + case SC_RCV_B7_0: + s = "bit 7 set to 1"; + break; + case SC_RCV_B7_1: + s = "bit 7 set to 0"; + break; + case SC_RCV_EVNP: + s = "odd parity"; + break; + case SC_RCV_ODDP: + s = "even parity"; + break; + } + if (s != NULL) { + syslog(LOG_WARNING, "Serial link is not 8-bit clean:"); + syslog(LOG_WARNING, "All received characters had %s", s); + } + } + if (ioctl(fd, TIOCSETD, &initdisc) < 0) + syslog(LOG_ERR, "ioctl(disestablish TIOCSETD): %m"); + } +} + +/* + * List of valid speeds. + */ +struct speed { + int speed_int, speed_val; +} speeds[] = { +#ifdef B50 + { 50, B50 }, +#endif +#ifdef B75 + { 75, B75 }, +#endif +#ifdef B110 + { 110, B110 }, +#endif +#ifdef B134 + { 134, B134 }, +#endif +#ifdef B150 + { 150, B150 }, +#endif +#ifdef B200 + { 200, B200 }, +#endif +#ifdef B300 + { 300, B300 }, +#endif +#ifdef B600 + { 600, B600 }, +#endif +#ifdef B1200 + { 1200, B1200 }, +#endif +#ifdef B1800 + { 1800, B1800 }, +#endif +#ifdef B2000 + { 2000, B2000 }, +#endif +#ifdef B2400 + { 2400, B2400 }, +#endif +#ifdef B3600 + { 3600, B3600 }, +#endif +#ifdef B4800 + { 4800, B4800 }, +#endif +#ifdef B7200 + { 7200, B7200 }, +#endif +#ifdef B9600 + { 9600, B9600 }, +#endif +#ifdef B19200 + { 19200, B19200 }, +#endif +#ifdef B38400 + { 38400, B38400 }, +#endif +#ifdef EXTA + { 19200, EXTA }, +#endif +#ifdef EXTB + { 38400, EXTB }, +#endif +#ifdef B14400 + { 14400, B14400 }, +#endif +#ifdef B28800 + { 28800, B28800 }, +#endif +#ifdef B43200 + { 43200, B43200 }, +#endif +#ifdef B57600 + { 57600, B57600 }, +#endif +#ifdef B115200 + { 115200, B115200 }, +#endif + { 0, 0 } +}; + +/* + * Translate from bits/second to a speed_t. + */ +int +translate_speed(bps) + int bps; +{ + struct speed *speedp; + + if (bps == 0) + return 0; + for (speedp = speeds; speedp->speed_int; speedp++) + if (bps == speedp->speed_int) + return speedp->speed_val; + syslog(LOG_WARNING, "speed %d not supported", bps); + return 0; +} + +/* + * Translate from a speed_t to bits/second. + */ +int +baud_rate_of(speed) + int speed; +{ + struct speed *speedp; + + if (speed == 0) + return 0; + for (speedp = speeds; speedp->speed_int; speedp++) + if (speed == speedp->speed_val) + return speedp->speed_int; + return 0; +} + + +/* + * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity, + * at the requested speed, etc. If `local' is true, set CLOCAL + * regardless of whether the modem option was specified. + */ +set_up_tty(fd, local) + int fd, local; +{ + int speed, x, modembits; + struct termios tios; + + if (tcgetattr(fd, &tios) < 0) { + syslog(LOG_ERR, "tcgetattr: %m"); + die(1); + } + + if (!restore_term) + inittermios = tios; + + tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); + + tios.c_cflag |= CS8 | CREAD | HUPCL; + if (local || !modem) + tios.c_cflag |= CLOCAL; + tios.c_iflag = IGNBRK | IGNPAR; + tios.c_oflag = 0; + tios.c_lflag = 0; + tios.c_cc[VMIN] = 1; + tios.c_cc[VTIME] = 0; + + if (crtscts == 2) { + tios.c_iflag |= IXOFF; + tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ + tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ + } + + speed = translate_speed(inspeed); + if (speed) { + cfsetospeed(&tios, speed); + cfsetispeed(&tios, speed); + } else { + speed = cfgetospeed(&tios); + } + + if (modem) { + modembits = TIOCM_RTS | TIOCM_CTS; + if (ioctl(fd, (crtscts ? TIOCMBIS : TIOCMBIC), &modembits) < 0) + syslog(LOG_ERR, "ioctl: TIOCMBIS/BIC: %m"); + } + + if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { + syslog(LOG_ERR, "tcsetattr: %m"); + die(1); + } + + baud_rate = inspeed = baud_rate_of(speed); + restore_term = 1; +} + +/* + * restore_tty - restore the terminal to the saved settings. + */ +void +restore_tty() +{ + if (restore_term) { + if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) + if (errno != ENXIO) + syslog(LOG_WARNING, "tcsetattr: %m"); + restore_term = 0; + } +} + +/* + * setdtr - control the DTR line on the serial port. + * This is called from die(), so it shouldn't call die(). + * + * The write hack is to get NXFax to recognize that there is + * activity on the port. Not using the write nukes + * NXFax's capability to determine port usage. + * + */ +setdtr(fd, on) +int fd, on; +{ + int modembits = TIOCM_DTR; + + if (!on) + { + write(fd, " ", 1); + sleep(1); + } + +/* ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits); */ + ioctl(fd, (on? TIOCSDTR: TIOCCDTR), 0); +} + + +/* + * output - Output PPP packet. + */ +void +output(unit, p, len) + int unit; + u_char *p; + int len; +{ + if (unit != 0) + MAINDEBUG((LOG_WARNING, "output: unit != 0!")); + if (debug) + log_packet(p, len, "sent "); + + if (write(fd, p, len) < 0) { + syslog(LOG_ERR, "write: %m"); + die(1); + } +} + + +/* + * wait_input - wait until there is data available on fd, + * for the length of time specified by *timo (indefinite + * if timo is NULL). + */ +wait_input(timo) + struct timeval *timo; +{ + fd_set ready; + int n; + + FD_ZERO(&ready); + FD_SET(fd, &ready); + n = select(fd+1, &ready, NULL, &ready, timo); + if (n < 0 && errno != EINTR) { + syslog(LOG_ERR, "select: %m"); + die(1); + } +} + + +/* + * read_packet - get a PPP packet from the serial device. + */ +int +read_packet(buf) + u_char *buf; +{ + int len; + + if ((len = read(fd, buf, PPP_MTU + PPP_HDRLEN)) < 0) { + if (errno == EWOULDBLOCK || errno == EINTR) { + MAINDEBUG((LOG_DEBUG, "read(fd): %m")); + return -1; + } + syslog(LOG_ERR, "read(fd): %m"); + die(1); + } + return len; +} + + +/* + * ppp_send_config - configure the transmit characteristics of + * the ppp interface. + */ +void +ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) + int unit, mtu; + u_int32_t asyncmap; + int pcomp, accomp; +{ + u_int x; + struct ifreq ifr; + + strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + ifr.ifr_mtu = mtu; + if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0) { + syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m"); + quit(); + } + + if (ioctl(fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCSASYNCMAP): %m"); + quit(); + } + + if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCGFLAGS): %m"); + quit(); + } + x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT; + x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC; + if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); + quit(); + } +} + + +/* + * ppp_set_xaccm - set the extended transmit ACCM for the interface. + */ +void +ppp_set_xaccm(unit, accm) + int unit; + ext_accm accm; +{ + if (ioctl(fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) + syslog(LOG_WARNING, "ioctl(PPPIOCSXASYNCMAP): %m"); +} + + +/* + * ppp_recv_config - configure the receive-side characteristics of + * the ppp interface. + */ +void +ppp_recv_config(unit, mru, asyncmap, pcomp, accomp) + int unit, mru; + u_int32_t asyncmap; + int pcomp, accomp; +{ + int x; + + if (ioctl(fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %m"); + quit(); + } + if (ioctl(fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCSRASYNCMAP): %m"); + quit(); + } + if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCGFLAGS): %m"); + quit(); + } + x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC; + if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); + quit(); + } +} + +/* + * ccp_test - ask kernel whether a given compression method + * is acceptable for use. + */ +ccp_test(unit, opt_ptr, opt_len, for_transmit) + int unit, opt_len, for_transmit; + u_char *opt_ptr; +{ + struct ppp_option_data data; + + data.ptr = opt_ptr; + data.length = opt_len; + data.transmit = for_transmit; + return ioctl(fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0; +} + +/* + * ccp_flags_set - inform kernel about the current state of CCP. + */ +void +ccp_flags_set(unit, isopen, isup) + int unit, isopen, isup; +{ + int x; + + if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCGFLAGS): %m"); + return; + } + x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN; + x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP; + if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) + syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); +} + +/* + * ccp_fatal_error - returns 1 if decompression was disabled as a + * result of an error detected after decompression of a packet, + * 0 otherwise. This is necessary because of patent nonsense. + */ +int +ccp_fatal_error(unit) + int unit; +{ + int x; + + if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCGFLAGS): %m"); + return 0; + } + return x & SC_DC_FERROR; +} + +/* + * sifvjcomp - config tcp header compression + */ +int +sifvjcomp(u, vjcomp, cidcomp, maxcid) + int u, vjcomp, cidcomp, maxcid; +{ + u_int x; + + if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_ERR, "ioctl(PPIOCGFLAGS): %m"); + return 0; + } + x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP; + x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID; + if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); + return 0; + } + if (ioctl(fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); + return 0; + } + return 1; +} + +/* + * sifup - Config the interface up and enable IP packets to pass. + */ +#ifndef SC_ENABLE_IP +#define SC_ENABLE_IP 0x100 /* compat for old versions of kernel code */ +#endif + +int +sifup(u) + int u; +{ + struct ifreq ifr; + u_int x; + struct npioctl npi; + + strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { + syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); + return 0; + } + ifr.ifr_flags |= IFF_UP; + if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { + syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); + return 0; + } + npi.protocol = PPP_IP; + npi.mode = NPMODE_PASS; + if (ioctl(fd, PPPIOCSNPMODE, &npi) < 0) { + if (errno != ENOTTY) { + syslog(LOG_ERR, "ioctl(PPPIOCSNPMODE): %m"); + return 0; + } + /* for backwards compatibility */ + if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); + return 0; + } + x |= SC_ENABLE_IP; + if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); + return 0; + } + } + return 1; +} + +/* + * sifdown - Config the interface down and disable IP. + */ +int +sifdown(u) + int u; +{ + struct ifreq ifr; + u_int x; + int rv; + struct npioctl npi; + + rv = 1; + npi.protocol = PPP_IP; + npi.mode = NPMODE_ERROR; + if (ioctl(fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) { + if (errno != ENOTTY) { + syslog(LOG_ERR, "ioctl(PPPIOCSNPMODE): %m"); + rv = 0; + } else { + /* backwards compatibility */ + if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); + rv = 0; + } else { + x &= ~SC_ENABLE_IP; + if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) < 0) { + syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); + rv = 0; + } + } + } + } + + strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { + syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); + rv = 0; + } else { + ifr.ifr_flags &= ~IFF_UP; + if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { + syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); + rv = 0; + } + } + return rv; +} + +/* + * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, + * if it exists. + */ +#define SET_SA_FAMILY(addr, family) \ + BZERO((char *) &(addr), sizeof(addr)); \ + addr.sa_family = (family); + +/* + * sifaddr - Config the interface IP addresses and netmask. + */ +int +sifaddr(u, o, h, m) + int u; + u_int32_t o, h, m; +{ + int ret; + struct ifreq ifr; + + ret = 1; + strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + SET_SA_FAMILY(ifr.ifr_addr, AF_INET); + ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o; + if (ioctl(sockfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { + syslog(LOG_ERR, "ioctl(SIOCAIFADDR): %m"); + ret = 0; + } + ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = h; + if (ioctl(sockfd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { + syslog(LOG_ERR, "ioctl(SIOCSIFDSTADDR): %m"); + ret = 0; + } + if (m != 0) { + ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = m; + syslog(LOG_INFO, "Setting interface mask to %s\n", ip_ntoa(m)); + if (ioctl(sockfd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { + syslog(LOG_ERR, "ioctl(SIOCSIFNETMASK): %m"); + ret = 0; + } + } + return ret; +} + +/* + * cifaddr - Clear the interface IP addresses, and delete routes + * through the interface if possible. + * + * N.B.: under NextStep, you can't *delete* an address on an interface, + * so we change it to 0.0.0.0... A real hack. But it simplifies + * reconnection on the server side. + */ +int +cifaddr(u, o, h) + int u; + u_int32_t o, h; +{ + struct rtentry rt; + +#if 1 + h = o = 0L; + (void) sifaddr(u, o, h, 0L); +#endif + SET_SA_FAMILY(rt.rt_dst, AF_INET); + ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = h; + SET_SA_FAMILY(rt.rt_gateway, AF_INET); + ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = o; + rt.rt_flags = RTF_HOST; + if (ioctl(sockfd, SIOCDELRT, (caddr_t) &rt) < 0) { + syslog(LOG_ERR, "ioctl(SIOCDELRT): %m"); + return 0; + } + return 1; +} + +/* + * sifdefaultroute - assign a default route through the address given. + */ +int +sifdefaultroute(u, g) + int u; + u_int32_t g; +{ + return dodefaultroute(g, 's'); +} + +/* + * cifdefaultroute - delete a default route through the address given. + */ +int +cifdefaultroute(u, g) + int u; + u_int32_t g; +{ + return dodefaultroute(g, 'c'); +} + +/* + * dodefaultroute - talk to a routing socket to add/delete a default route. + */ +int +dodefaultroute(g, cmd) + u_int32_t g; + int cmd; +{ + struct rtentry rt; + + SET_SA_FAMILY(rt.rt_dst, AF_INET); + ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = 0L; + SET_SA_FAMILY(rt.rt_gateway, AF_INET); + ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = g; + rt.rt_flags = RTF_GATEWAY; + if (ioctl(sockfd, (cmd == 's') ? SIOCADDRT : SIOCDELRT, &rt) < 0) { + syslog(LOG_ERR, "%cifdefaultroute: ioctl(%s): %m", cmd, + (cmd == 's') ? "SIOCADDRT" : "SIOCDELRT"); + return 0; + } + return 1; +} + +/* + * sifproxyarp - Make a proxy ARP entry for the peer. + */ +int +sifproxyarp(unit, hisaddr) + int unit; + u_int32_t hisaddr; +{ + struct arpreq arpreq; + + BZERO(&arpreq, sizeof(arpreq)); + + /* + * Get the hardware address of an interface on the same subnet + * as our local address. + */ + if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) { + syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); + return 0; + } + + SET_SA_FAMILY(arpreq.arp_pa, AF_INET); + ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; + arpreq.arp_flags = ATF_PERM | ATF_PUBL; + if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) { + syslog(LOG_ERR, "ioctl(SIOCSARP): %m"); + return 0; + } + + return 1; +} + +/* + * cifproxyarp - Delete the proxy ARP entry for the peer. + */ +int +cifproxyarp(unit, hisaddr) + int unit; + u_int32_t hisaddr; +{ + struct arpreq arpreq; + + BZERO(&arpreq, sizeof(arpreq)); + SET_SA_FAMILY(arpreq.arp_pa, AF_INET); + ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; + if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) { + syslog(LOG_WARNING, "ioctl(SIOCDARP): %m"); + return 0; + } + return 1; +} + +/* + * get_ether_addr - get the hardware address of an interface on the + * the same subnet as ipaddr. + */ +#define MAX_IFS 32 + +int +get_ether_addr(ipaddr, hwaddr) + u_int32_t ipaddr; + struct sockaddr *hwaddr; +{ + struct ifreq *ifr, *ifend, *ifp; + u_int32_t ina, mask; + struct ether_addr dla; + struct ifreq ifreq; + struct ifconf ifc; + struct ifreq ifs[MAX_IFS]; + struct hostent *hostent; + + ifc.ifc_len = sizeof(ifs); + ifc.ifc_req = ifs; + if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { + syslog(LOG_ERR, "ioctl(SIOCGIFCONF): %m"); + return 0; + } + + /* + * Scan through looking for an interface with an Internet + * address on the same subnet as `ipaddr'. + */ + ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); + for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *) + ((char *)&ifr->ifr_addr + sizeof(struct sockaddr))) { + if (ifr->ifr_addr.sa_family == AF_INET) { + ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; + strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + /* + * Check that the interface is up, and not point-to-point + * or loopback. + */ + if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) + continue; + if ((ifreq.ifr_flags & + (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) + != (IFF_UP|IFF_BROADCAST)) + continue; + /* + * Get its netmask and check that it's on the right subnet. + */ + if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0) + continue; + mask = ((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr.s_addr; + if ((ipaddr & mask) != (ina & mask)) + continue; + + break; + } + } + + if (ifr >= ifend) + return 0; + syslog(LOG_INFO, "found interface %s for proxy arp", ifr->ifr_name); + + /* + * Get the hostname and look for an entry using the ethers database. + * Under NeXTStep this is the best we can do for now. + */ + if ((hostent = gethostbyaddr((char*)&ina, sizeof(ina), AF_INET)) == NULL) + return 0; + + if (ether_by_host(hostent->h_name, &dla)) { + syslog(LOG_INFO, "Add entry for %s in /etc/ethers", hostent->h_name); + return 0; /* it's not there */ + } + hwaddr->sa_family = AF_UNSPEC; + BCOPY(&dla, hwaddr->sa_data, sizeof(dla)); + return 1; +} + +int +ether_by_host(hostname, etherptr) + char *hostname; + struct ether_addr *etherptr; +{ + struct ether_addr *thisptr; + void *conn; + ni_id root; + ni_namelist val; + char path[256]; + + if (!ether_hostton(hostname, etherptr)) + return 0; + /* + * We shall now try and + * find the address in the + * top domain of netinfo. + */ + strcat(strcpy(path, "/machines/"), hostname); + + if (ni_open((void *)0, "/", &conn) + || ni_root(conn, &root) + || ni_pathsearch(conn, &root, path) + || ni_lookupprop(conn, &root, "en_address", &val)) + return 1; + + /* + * Now we can convert the returned string into an ethernet address. + */ + strcpy(path, val.ni_namelist_val[0]); + ni_free(conn); + if ((thisptr = (struct ether_addr*)ether_aton(path)) == NULL) + return 1; + BCOPY(thisptr, etherptr, sizeof(struct ether_addr)); + return 0; +} + + + +/* + * Return user specified netmask, modified by any mask we might determine + * for address `addr' (in network byte order). + * Here we scan through the system's list of interfaces, looking for + * any non-point-to-point interfaces which might appear to be on the same + * network as `addr'. If we find any, we OR in their netmask to the + * user-specified netmask. + */ +u_int32_t +GetMask(addr) + u_int32_t addr; +{ + u_int32_t mask, nmask, ina; + struct ifreq *ifr, *ifend, ifreq; + struct ifconf ifc; + struct ifreq ifs[MAX_IFS]; + + addr = ntohl(addr); + if (IN_CLASSA(addr)) /* determine network mask for address class */ + nmask = IN_CLASSA_NET; + else if (IN_CLASSB(addr)) + nmask = IN_CLASSB_NET; + else + nmask = IN_CLASSC_NET; + /* class D nets are disallowed by bad_ip_adrs */ + mask = netmask | htonl(nmask); + + /* + * Scan through the system's network interfaces. + */ + ifc.ifc_len = sizeof(ifs); + ifc.ifc_req = ifs; + if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { + syslog(LOG_WARNING, "ioctl(SIOCGIFCONF): %m"); + return mask; + } + ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); + for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *) + ((char *)&ifr->ifr_addr + sizeof(struct sockaddr))) { + /* + * Check the interface's internet address. + */ + if (ifr->ifr_addr.sa_family != AF_INET) + continue; + ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; + if ((ntohl(ina) & nmask) != (addr & nmask)) + continue; + /* + * Check that the interface is up, and not point-to-point or loopback. + */ + strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) + continue; + if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) + != IFF_UP) + continue; + /* + * Get its netmask and OR it into our mask. + */ + if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0) + continue; + mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr; + } + + return mask; +} + + + +/* + * daemon - Detach us from the terminal session. + */ +int +daemon(nochdir, noclose) + int nochdir, noclose; +{ + int pid; + + if ((pid = fork()) < 0) + return -1; + if (pid != 0) + exit(0); /* parent dies */ + (void)setsid(); + if (!nochdir) + chdir("/"); + if (!noclose) { + fclose(stdin); /* don't need stdin, stdout, stderr */ + fclose(stdout); + fclose(stderr); + } + return 0; +} + + +char * +strdup(s) + const char *s; +{ + char *d = malloc(strlen(s) + 1); + + if (d) strcpy(d, s); + return d; +} + +/* + * This logwtmp() implementation is subject to the following copyright: + * + * Copyright (c) 1988 The Regents of the University of California. + * 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 the University of California, Berkeley. 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. + */ + +#define WTMPFILE "/usr/adm/wtmp" + +int +logwtmp(line, name, host) + char *line, *name, *host; +{ + int fd; + struct stat buf; + struct utmp ut; + + if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) + return; + if (!fstat(fd, &buf)) { + (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); + (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); + (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); + (void)time(&ut.ut_time); + if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp)) + (void)ftruncate(fd, buf.st_size); + } + close(fd); +} + +/* + * Routines for locking and unlocking the serial device, moved here + * from chat.c. + */ + +#define LOCK_PREFIX "/usr/spool/uucp/LCK/LCK.." + +/* + * lock - create a lock file for the named device + */ +int +lock(dev) + char *dev; +{ + int fd, pid, n; + char *p; + + if ((p = strrchr(dev, '/')) != NULL) + dev = p + 1; + lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1); + if (lock_file == NULL) + novm("lock file name"); + strcat(strcpy(lock_file, LOCK_PREFIX), dev); + + while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { + if (errno == EEXIST + && (fd = open(lock_file, O_RDONLY, 0)) >= 0) { + /* Read the lock file to find out who has the device locked */ + n = read(fd, &pid, sizeof(pid)); + if (n <= 0) { + syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file); + close(fd); + } else { + if (kill(pid, 0) == -1 && errno == ESRCH) { + /* pid no longer exists - remove the lock file */ + if (unlink(lock_file) == 0) { + close(fd); + syslog(LOG_NOTICE, "Removed stale lock on %s (pid %d)", + dev, pid); + continue; + } else + syslog(LOG_WARNING, "Couldn't remove stale lock on %s", + dev); + } else + syslog(LOG_NOTICE, "Device %s is locked by pid %d", + dev, pid); + } + close(fd); + } else + syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file); + free(lock_file); + lock_file = NULL; + return -1; + } + + pid = getpid(); + write(fd, &pid, sizeof pid); + + close(fd); + return 0; +} + +/* + * unlock - remove our lockfile + */ +void +unlock() +{ + if (lock_file) { + unlink(lock_file); + free(lock_file); + lock_file = NULL; + } +} + +#if defined(i386) && defined(HAS_BROKEN_IOCTL) +int +ioctl(fd, cmd, c) + int fd, cmd; + caddr_t c; +{ +#undef ioctl + int ret; + +#ifdef DEBUGIOCTL + int serrno; + u_char let, code, size; + + size = (cmd >> 16) & IOCPARM_MASK; + let = (cmd >> 8); + code = cmd; + + if (let == 't' && (75 <= code && code <= 90)) + syslog(LOG_INFO, "ioctl(%d, 0x%x ('%c', %d, %d), 0x%x)\n", fd, cmd, + let, code, size, c); +#endif + + ret = ioctl(fd, cmd, c); + +#ifdef DEBUGIOCTL + serrno = errno; + if (ret == -1) + syslog(LOG_INFO, "ioctl('%c', %d, %d) errno = %d (%m)\n", + let, code, size, errno); + if (let == 't' && (75 <= code && code <= 90) && (cmd & IOC_OUT)) { + int i, len = ((cmd >> 16) & IOCPARM_MASK); + for (i = 0; i < len / 4; ++i) + syslog(LOG_INFO, "word[%d] @ 0x%06x = 0x%x\n", + i, &((int *) c)[i],((int *)c)[i]); + } + errno = serrno; +#endif + + if (ret == -1 && errno == EPERM) + errno = ret = 0; + return ret; +} +#endif /* HAS_BROKEN_IOCTL */ + + +#if defined(FIXSIGS) && (defined (hppa) || defined(sparc)) + +/* + * These redefinitions of Posix functions are necessary + * because HPPA systems have an OS bug that causes + * sigaction to core dump: + * + * AlainF 9-Nov-1994 HACK FOR HP-PA/NEXTSTEP + * sigaction(3) seems broken in the HP-PA NeXTSTEP 3.2 + * Posix lib. This causes pppd to SIGBUS at the expiration + * of the first timeout (_sigtramp seems to invoke + * the SIGALRM handler at an unreasonably low address). + * All calls so sigaction(3) have been changed to calls + * to sigvec(2) and sigprocmask(SIG_BLOCK,...) to + * sigblock(2). + * This is kind of a hack, especially since there are + * other routines of the Posix lib still used, but + * it worked for me. + * + * Dave Hess noted that 3.3 Sparc seems to + * have the same bug. Thus this fix has been enabled for SPARC also. + * + * + */ + +int sigemptyset(sigset_t *mask) +{ + *mask = 0; +} + +sigaddset(sigset_t *mask, int which_sig) +{ + *mask |= sigmask(which_sig); +} + + +int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) +{ + struct sigvec sv; + static int in = 0; + + sv.sv_handler = act->sa_handler; + sv.sv_mask = act->sa_mask; + sv.sv_flags = 0; + + if (!in) + { + in = 1; + syslog(LOG_WARNING, "PPPD: Inside modified HP and SPARC sigaction\n"); + } + + return sigvec(sig, &sv, NULL); +} + +#endif diff --git a/pppstats/Makefile.NeXT b/pppstats/Makefile.NeXT new file mode 100644 index 0000000..f56650f --- /dev/null +++ b/pppstats/Makefile.NeXT @@ -0,0 +1,45 @@ +# +# pppstats makefile +# $Id: Makefile.NeXT,v 1.1 1995/08/10 06:48:39 paulus Exp $ +# + +ARCHFLAGS = -arch i386 -arch m68k +BINDIR = /usr/local/ppp/bin +MANDIR = /usr/local/ppp/man + +PPPSTATSRCS = pppstats.c +PPPSTATOBJS = pppstats.o + +#CC = gcc + +COPTS = -O -posix $(ARCHFLAGS) +COMPILE_FLAGS = +LIBS = + +# +# The VJC/PPP_COMPRESS flag is required to ensure correct sizing of +# some of the structures +# +CFLAGS = -I.. $(COPTS) $(COMPILE_FLAGS) #-DVJC -DPPP_COMPRESS -DDECOMP_OUT + +all: pppstats + +install: + /bin/mkdirs $(BINDIR) $(MANDIR)/man8 + install -c -s -m 555 -o root -g daemon pppstats $(BINDIR)/pppstats + install -c -m 444 -o root -g wheel pppstats.8 $(MANDIR)/man8 + + +pppstats: $(PPPSTATSRCS) + $(CC) $(CFLAGS) -o pppstats pppstats.c $(LIBS) + +clean: + rm -f pppstats *~ #* core + +depend: + cpp -M $(CFLAGS) $(PPPSTATSRCS) >.depend +# makedepend $(CFLAGS) $(PPPSTATSRCS) + +saber_pppstats: + #setopt load_flags $(CFLAGS) + #load $(PPPSTATSRCS) -- 2.39.2