diff options
author | Mystery Man <unknown@mandriva.org> | 2002-07-18 17:04:07 +0000 |
---|---|---|
committer | Mystery Man <unknown@mandriva.org> | 2002-07-18 17:04:07 +0000 |
commit | 427da37597ce1818756dbe3e2482135886fa80ca (patch) | |
tree | 560d65515b02387e636d045df233e641aabf5c24 /mdk-stage1/ppp | |
parent | 53b3ee0964e09fa0a1ebf1f721485388afd8fa20 (diff) | |
download | drakx-427da37597ce1818756dbe3e2482135886fa80ca.tar drakx-427da37597ce1818756dbe3e2482135886fa80ca.tar.gz drakx-427da37597ce1818756dbe3e2482135886fa80ca.tar.bz2 drakx-427da37597ce1818756dbe3e2482135886fa80ca.tar.xz drakx-427da37597ce1818756dbe3e2482135886fa80ca.zip |
This commit was manufactured by cvs2svn to create tag 'V1_1_8_7mdk'.V1_1_8_7mdk
Diffstat (limited to 'mdk-stage1/ppp')
187 files changed, 0 insertions, 74078 deletions
diff --git a/mdk-stage1/ppp/.cvsignore b/mdk-stage1/ppp/.cvsignore deleted file mode 100644 index c258b925d..000000000 --- a/mdk-stage1/ppp/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -pppd-bin diff --git a/mdk-stage1/ppp/Changes-2.3 b/mdk-stage1/ppp/Changes-2.3 deleted file mode 100644 index f5c954b4b..000000000 --- a/mdk-stage1/ppp/Changes-2.3 +++ /dev/null @@ -1,441 +0,0 @@ -What was new in ppp-2.3.11. -*************************** - -* Support for Solaris 8 has been added, including support for - replumbing and IPV6. - -* The Solaris `snoop' utility should now work on ppp interfaces. - -* New hooks have been added - pap_logout_hook, ip_up_hook, and - ip_down_hook. - -* A new `passprompt' plugin is included, thanks to Alan Curry, which - makes it possible for pppd to call an external program to get the - PAP password to send to the peer. - -* The error messages for the situation where authentication is - required because the system has a default route have been improved. - -* There is a new connect_delay option which specifies how long pppd - should pause after the connect script finishes. Previously this - delay was fixed at 1 second. (This delay terminates as soon as pppd - sees a valid PPP frame from the peer.) - -* The `hide-password' option is now the default, and there is a new - `show-password' option to enable the printing of password strings in - the debug output. - -* A fairly complete list of the names of PPP protocols has been added - so that when pppd rejects a frame because its protocol is not - supported, it can print the name of the unsupported protocol. - -* Synchronous serial lines are supported under Linux 2.3.x. - -* The bug where pppd would not recognize a modem hangup under Linux - 2.3.x kernels has been fixed. - - -What was new in ppp-2.3.10. -*************************** - -* Pppd now supports `plugins', which are pieces of code (packaged as - shared libraries) which can be loaded into pppd at runtime and which - can affect its behaviour. The intention is that plugins provide a - way for people to customize the behaviour of pppd for their own - needs without needing to change the base pppd source. I have added - some hooks into pppd (places where pppd will call a function - pointer, if non-zero, to replace some of pppd's code) and I will be - receptive to suggestions about places to add more hooks. Plugins - are supported under Linux and Solaris at present. - -* We have a new maintainer for the Solaris port, Adi Masputra of Sun - Microsystems, and he has updated the Solaris port so that it should - work on 64-bit machines under Solaris 7 and later. - -* Pppd now has an `allow-ip' option, which takes an argument which is - an IP address (or subnet) which peers are permitted to use without - authenticating themselves. The argument takes the same form as each - element of the allowed IP address list in the secrets files. The - allow-ip option is privileged and may be specified multiple times. - Using the allow-ip option should be cleaner than putting a line like - `"" * "" address' in /etc/ppp/pap-secrets. - -* Chat can now substitute environment variables into the script. This - is enabled by the -E flag. (Thanks to Andreas Arens for the patch.) - -* If the PAP username and password from the peer contains unprintable - characters, they will be translated to a printable form before - looking in the pap-secrets file. Characters >= 0x80 are translated - to a M- form, and characters from 0 to 0x1f (and 0x7f as well) are - translated to a ^X form. If this change causes you grief, let me - know what would be a better translation. It appears that some peers - send nulls or other control characters in their usernames and - passwords. - -* Pppd has new `ktune' and `noktune' options, which enable/disable - it to change kernel settings as appropriate. This is only - implemented under Linux, and requires the /proc filesystem to be - mounted. Under Linux, with the ktune option, pppd will enable IP - forwarding in the kernel if the proxyarp option is used, and will - enable the dynamic IP address kernel option in demand mode if the - local IP address changes. - -* Pppd no longer requires a remote address to be specified for demand - dialling. If none is specified, it will use a default value of - 10.112.112.112+unit_number. (It will not propose this default to - the peer.) - -* The default holdoff is now 0 if no connect script is given. - -* The IPV6 code from Tommi Komulainen, which I unfortunately only - partially merged in to ppp-2.3.9, has been fixed and updated. - -* The linux compilation glitches should be fixed now. - - -What was new in ppp-2.3.9. -************************** - -* Support for the new generic PPP layer under development for the - Linux kernel. - -* You can now place extra options to apply to specific users at the - end of the line with their password in the pap-secrets or - chap-secrets file, separated from the IP address(es) with a "--" - separator. These options are parsed after the peer is authenticated - but before network protocol (IPCP, IPXCP) or CCP negotiation - commences. - -* Pppd will apply the holdoff period if the link was terminated by the - peer. It doesn't apply it if the link was terminated because the - local pppd thought it was idle. - -* Synchronous support for Solaris has been added, thanks to John - Morrison, and for FreeBSD, thanks to Paul Fulghum. - -* IPV6 support has been merged in, from Tommi Komulainen. At the - moment it only supports Linux and it is not tested by me. - -* The `nodefaultip' option can be used in demand mode to say that pppd - should not suggest its local IP address to the peer. - -* The `init' option has been added; this causes pppd to run a script - to initialize the serial device (e.g. by sending an init string to - the modem). Unlike the connect option, this can be used in a - dial-in situation. (Thanks to Tobias Ringstrom.) - -* There is a new `logfile' option to send log messages to a file as - well as syslog. - -* There is a new, privileged `linkname' option which sets a logical - name for the link. Pppd will create a /var/run/ppp-<linkname>.pid - file containing its process ID. - -* There is a new `maxfail' option which specifies how many consecutive - failed connection attempts are permitted before pppd will exit. The - default value is 10, and 0 means infinity. :-) - -* Sundry bugs fixed. - - -What was new in ppp-2.3.8. -************************** - -* The exit status of pppd will now indicate whether the link was - successfully established, or if not, what error was encountered. - -* Pppd has two new options: fdlog <n> will send log messages to file - descriptor <n> instead of standard output, and nofdlog will stop log - messages from being sent to any file descriptor (they will still be - sent to syslog). Pppd now will not send log messages to a file - descriptor if the serial port is open on that file descriptor. - -* Pppd sets an environment variable called PPPLOGNAME for scripts that - it runs, indicating the login name of the user who invoked pppd. - -* Pppd sets environment variables CONNECT_TIME, BYTES_SENT and - BYTES_RCVD for the ip-down and auth-down scripts indicating the - statistics for the connection just terminated. (CONNECT_TIME is in - seconds.) - -* If the user has the serial device open on standard input and - specifies a symbolic link to the serial device on the command line, - pppd will detect this and behave correctly (i.e. not detach from its - controlling terminal). Furthermore, if the serial port is open for - reading and writing on standard input, pppd will assume that it is - locked by its invoker and not lock it itself. - -* Chat now has a feature where if a string to be sent begins with an - at sign (@), the rest of the string is taken as the name of a file - (regular file or named pipe), and the actual string to send is taken - from that file. - -* Support for FreeBSD-2.2.8 and 3.0 has been added, thanks to Paul - Fulghum. - -* The Tru64 (aka Digital Unix aka OSF/1) port has been updated. - -* The system panics on Solaris SMP systems related to PPP connections - being established and terminated should no longer occur. - -* Fixed quite a few bugs. - - -What was new in ppp-2.3.7. -************************** - -* Pppd can now automatically allocate itself a pseudo-tty to use as - the serial device. This has made three new options possible: - - - `pty script' will run `script' with its standard input and output - connected to the master side of the pty. For example: - pppd pty 'ssh -t server.my.net pppd' - is a basic command for setting up a PPP link (tunnel) over ssh. - (In practice you may need to specify other options such as IP - addresses, etc.) - - - `notty' tells pppd to communicate over its standard input and - output, which do not have to be a terminal device. - - - `record filename' tells pppd to record all of the characters sent - and received over the serial device to a file called `filename'. - The data is recorded in a tagged format with timestamps, which can - be printed in a readable form with the pppdump program, which is - included in this distribution. - -* Pppd now logs the connect time and number of bytes sent and received - (at the level of the serial device) when the connection is - terminated. - -* If you use the updetach or nodetach option, pppd will print its - messages to standard output as well as logging them with syslog - (provided of course pppd isn't using its standard input or output as - its serial device). - -* There is a new `privgroup groupname' option (a privileged option). - If the user running pppd is in group `groupname', s/he can use - privileged options without restriction. - -* There is a new `receive-all' option, which causes pppd to accept all - control characters, even the ones that the peer should be escaping - (i.e. the receive asyncmap is 0). This is useful with some buggy - peers. - -* The default asyncmap is now 0. - -* There is a new `sync' option, currently only implemented under - Linux, which allows pppd to run on synchronous HDLC devices. - -* If a value for the device name or for the connect, disconnect, - welcome or pty option is given in a privileged option file - (i.e. /etc/ppp/options or a file loaded with the `call' option), it - cannot be overridden by a non-privileged user. - -* Many bugs have been fixed, notably: - - signals are not blocked unnecessarily, as they were in 2.3.6. - - the usepeerdns option should work now. - - the SPEED environment variable for scripts is set correctly. - - the /etc/ppp/auth-down script is not run until auth-up completes. - - the device is opened as root if it is the device on standard - input. - - pppd doesn't die with the ioctl(PPPIOCSASYNCMAP) error under linux - if a hangup occurs at the wrong time. - -* Some error messages have been changed to be clearer (I hope :-) - - -What was new in ppp-2.3.6. -************************** - -* Pppd now opens the tty device as the user (rather than as root) if - the device name was given by the user, i.e. on the command line or - in the ~/.ppprc file. If the device name was given in - /etc/ppp/options or in a file loaded with the `call' option, the - device is opened as root. - -* The default behaviour of pppd is now to let a peer which has not - authenticated itself (e.g. your ISP) use any IP address to which the - system does not already have a route. (This is currently only - supported under Linux, Solaris and Digital Unix; on the other - systems, the peer must now authenticate itself unless the noauth - option is used.) - -* Added new option `usepeerdns', thanks to Nick Walker - <nickwalker@email.com>. If the peer supplies DNS addresses, these - will be written to /etc/ppp/resolv.conf. The ip-up script can then - be used to add these addresses to /etc/resolv.conf if desired (see - the ip-up.local.add and ip-down.local.add files in the scripts - directory). - -* The Solaris ppp driver should now work correctly on SMP systems. - -* Minor corrections so that the code can compile under Solaris 7, - and under Linux with glibc-2.1. - -* The Linux kernel driver has been restructured for improved - performance. - -* Pppd now won't start the ip-down script until the ip-up script has - finished. - - -What was new in ppp-2.3.5. -************************** - -* Minor corrections to the Digital UNIX and NetBSD ports. - -* A workaround to avoid tickling a bug in the `se' serial port driver -on Sun PCI Ultra machines running Solaris. - -* Fixed a bug in the negotiation of the Microsoft WINS server address -option. - -* Fixed a bug in the Linux port where it would fail for kernel -versions above 2.1.99. - - -What was new in ppp-2.3.4. -************************** - -* The NeXT port has been updated, thanks to Steve Perkins. - -* ppp-2.3.4 compiles and works under Solaris 2.6, using either gcc or -cc. - -* With the Solaris, SVR4 and SunOS ports, you can control the choice -of C compiler, C compiler options, and installation directories by -editing the svr4/Makedefs or sunos4/Makedefs file. - -* Until now, we have been using the number 24 to identify Deflate -compression in the CCP negotiations, which was the number in the draft -RFC describing Deflate. The number actually assigned to Deflate is -26. The code has been changed to use 26, but to allow the use of 24 -for now for backwards compatibility. (This can be disabled with the -`nodeflatedraft' option to pppd.) - -* Fixed some bugs in the linux driver and deflate compressor which -were causing compression problems, including corrupting long -incompressible packets sometimes. - -* Fixes to the PAM and shadow password support in pppd, from Al -Longyear and others. - -* Pppd now sets some environment variables for scripts it invokes -(ip-up/down, auth-ip/down), giving information about the connection. -The variables it sets are PEERNAME, IPLOCAL, IPREMOTE, UID, DEVICE, -SPEED, and IFNAME. - -* Pppd now has an `updetach' option, which will cause it to detach -from its controlling terminal once the link has come up (i.e. once it -is available for IP traffic). - - -What was new in ppp-2.3.3. -************************** - -* Fixed compilation problems under SunOS. - -* Fixed a bug introduced into chat in 2.3.2, and compilation problems -introduced into the MS-CHAP implementation in 2.3.2. - -* The linux kernel driver has been updated for recent 2.1-series -kernel changes, and it now will ask kerneld to load compression -modules when required, if the kernel is configured to support kerneld. - -* Pppd should now compile correctly under linux on systems with glibc. - - -What was new in ppp-2.3.2. -************************** - -* In 2.3.1, I made a change which was intended to make pppd able to -detect loss of CD during or immediately after the connection script -runs. Unfortunately, this had the side-effect that the connection -script wouldn't work at all on some systems. This change has been -reversed. - -* Fix compilation problems in the Linux kernel driver. - - -What was new in ppp-2.3.1. -************************** - -* Enhancements to chat, thanks to Francis Demierre. Chat can now -accept comments in the chat script file, and has new SAY, HANGUP, -CLR_ABORT and CLR_REPORT keywords. - -* Fixed a bug which causes 2.3.0 to crash Solaris systems. - -* Bug-fixes and restructuring of the Linux kernel driver. - -* The holdoff behaviour of pppd has been changed slightly: now, if -the link comes up for IP (or other network protocol) traffic, we -consider that the link has been successfully established, and don't -enforce the holdoff period after the link goes down. - -* Pppd should now correctly wait for CD (carrier detect) from the -modem, even when the serial port initially had CLOCAL set, and it -should also detect loss of CD during or immediately after the -connection script runs. - -* Under linux, pppd will work with older 2.2.0* version kernel -drivers, although demand-dialling is not supported with them. - -* Minor bugfixes for pppd. - - -What was new in ppp-2.3. -************************ - -* Demand-dialling. Pppd now has a mode where it will establish the -network interface immediately when it starts, but not actually bring -the link up until it sees some data to be sent. Look for the demand -option description in the pppd man page. Demand-dialling is not -supported under Ultrix or NeXTStep. - -* Idle timeout. Pppd will optionally terminate the link if no data -packets are sent or received within a certain time interval. - -* Pppd now runs the /etc/ppp/auth-up script, if it exists, when the -peer successfully authenticates itself, and /etc/ppp/auth-down when -the connection is subsequently terminated. This can be useful for -accounting purposes. - -* A new packet compression scheme, Deflate, has been implemented. -This uses the same compression method as `gzip'. This method is free -of patent or copyright restrictions, and it achieves better -compression than BSD-Compress. It does consume more CPU cycles for -compression than BSD-Compress, but this shouldn't be a problem for -links running at 100kbit/s or less. - -* There is no code in this distribution which is covered by Brad -Clements' restrictive copyright notice. The STREAMS modules for SunOS -and OSF/1 have been rewritten, based on the Solaris 2 modules, which -were written from scratch without any Clements code. - -* Pppstats has been reworked to clean up the output format somewhat. -It also has a new -d option which displays data rate in kbyte/s for -those columns which would normally display bytes. - -* Pppd options beginning with - or + have been renamed, e.g. -ip -became noip, +chap became require-chap, etc. The old options are -still accepted for compatibility but may be removed in future. - -* Pppd now has some options (such as the new `noauth' option) which -can only be specified if it is being run by root, or in an -"privileged" options file: /etc/ppp/options or an options file in the -/etc/ppp/peers directory. There is a new "call" option to read -options from a file in /etc/ppp/peers, making it possible for non-root -users to make unauthenticated connections, but only to certain trusted -peers. My intention is to make the `auth' option the default in a -future release. - -* Several minor new features have been added to pppd, including the -maxconnect and welcome options. Pppd will now terminate the -connection when there are no network control protocols running. The -allowed IP address(es) field in the secrets files can now specify -subnets (with a notation like 123.45.67.89/24) and addresses which are -not acceptable (put a ! on the front). - -* Numerous bugs have been fixed (no doubt some have been introduced :-) -Thanks to those who reported bugs in ppp-2.2. diff --git a/mdk-stage1/ppp/FAQ b/mdk-stage1/ppp/FAQ deleted file mode 100644 index 96bc5c708..000000000 --- a/mdk-stage1/ppp/FAQ +++ /dev/null @@ -1,634 +0,0 @@ -This is a list of Frequently Asked Questions about using ppp-2.x and -their answers. - - ------------------------------------------------------------------------- - -Q: Can you give me an example of how I might set up my machine to dial -out to an ISP? - -A: Here's an example for dialling out to an ISP via a modem on -/dev/tty02. The modem uses hardware (CTS/RTS) flow control, and the -serial port is run at 38400 baud. The ISP assigns our IP address. - -To configure pppd for this connection, create a file under -/etc/ppp/peers called (say) my-isp containing the following: - -tty02 crtscts 38400 -connect 'chat -v -f /etc/ppp/chat/my-isp' -defaultroute - -The ppp connection is then initiated using the following command: - -pppd call my-isp - -Of course, if the directory containing pppd is not in your path, you -will need to give the full pathname for pppd, for example, -/usr/sbin/pppd. - -When you run this, pppd will use the chat program to dial the ISP and -invoke its ppp service. Chat will read the file specified with -f, -namely /etc/ppp/chat/my-isp, to find a list of strings to expect to -receive, and strings to send. This file would contain something like -this: - -ABORT "NO CARRIER" -ABORT "NO DIALTONE" -ABORT "ERROR" -ABORT "NO ANSWER" -ABORT "BUSY" -ABORT "Username/Password Incorrect" -"" "at" -OK "at&d2&c1" -OK "atdt2479381" -"name:" "^Uusername" -"word:" "\qpassword" -"annex" "\q^Uppp" -"Switching to PPP-ppp-Switching to PPP" - -You will need to change the details here. The first string on each -line is a string to expect to receive; the second is the string to -send. You can add or delete lines according to the dialog required to -access your ISP's system. This example is for a modem with a standard -AT command set, dialling out to an Annex terminal server. The \q -toggles "quiet" mode; when quiet mode is on, the strings to be sent -are replaced by ?????? in the log. You may need to go through the -dialog manually using kermit or tip first to determine what should go -in the script. - -To terminate the link, run the following script, called (say) -kill-ppp: - -#!/bin/sh -unit=ppp${1-0} -piddir=/var/run -if [ -f $piddir/$unit.pid ]; then - kill -1 `cat $piddir/$unit.pid` -fi - -On some systems (SunOS, Solaris, Ultrix), you will need to change -/var/run to /etc/ppp. - - ------------------------------------------------------------------------- - -Q: Can you give me an example of how I could set up my office machine -so I can dial in to it from home? - -A: Let's assume that the office machine is called "office" and is on a -local ethernet subnet. Call the home machine "home" and give it an IP -address on the same subnet as "office". We'll require both machines -to authenticate themselves to each other. - -Set up the files on "office" as follows: - -/etc/ppp/options contains: - -auth # require the peer to authenticate itself -lock -# other options can go here if desired - -/etc/ppp/chap-secrets contains: - -home office "beware the frub-jub" home -office home "bird, my son!%&*" - - -Set up a modem on a serial port so that users can dial in to the -modem and get a login prompt. - -On "home", set up the files as follows: - -/etc/ppp/options contains the same as on "office". - -/etc/ppp/chap-secrets contains: - -home office "beware the frub-jub" - -office home "bird, my son!%&*" office - -Create a file called /etc/ppp/peers/office containing the following: - -tty02 crtscts 38400 -connect 'chat -v -f /etc/ppp/chat/office' -defaultroute - -(You may need to change some of the details here.) - -Create the /etc/ppp/chat/office file containing the following: - -ABORT "NO CARRIER" -ABORT "NO DIALTONE" -ABORT "ERROR" -ABORT "NO ANSWER" -ABORT "BUSY" -ABORT "ogin incorrect" -"" "at" -OK "at&d2&c1" -OK "atdt2479381" -"name:" "^Uusername" -"word:" "\qpassword" -"$" "\q^U/usr/sbin/pppd proxyarp" -"~" - -You will need to change the details. Note that the "$" in the -second-last line is expecting the shell prompt after a successful -login - you may need to change it to "%" or something else. - -You then initiate the connection (from home) with the command: - -pppd call office - ------------------------------------------------------------------------- - -Q: When I try to establish a connection, the modem successfully dials -the remote system, but then hangs up a few seconds later. How do I -find out what's going wrong? - -A: There are a number of possible problems here. The first thing to -do is to ensure that pppd's messages are visible. Pppd uses the -syslog facility to log messages which help to identify specific -problems. Messages from pppd have facility "daemon" and levels -ranging from "debug" to "error". - -Usually it is useful to see messages of level "notice" or higher on -the console. To see these, find the line in /etc/syslog.conf which -has /dev/console on the right-hand side, and add "daemon.notice" in -the list on the left. The line will end up looking something like -this: - -*.err;kern.debug;auth.notice;mail.crit;daemon.notice /dev/console - -Note that the whitespace is tabs, *not* spaces. - -If you are having problems, it may be useful to see messages of level -"info" as well, in which case you would change "daemon.notice" to -"daemon.info". - -In addition, it is useful to collect pppd's debugging output in a -file - the debug option to pppd causes it to log the contents of all -control packets sent and received in human-readable form. To do this, -add a line like this to /etc/syslog.conf: - -daemon,local2.debug /etc/ppp/log - -and create an empty /etc/ppp/log file. - -When you change syslog.conf, you will need to send a HUP signal to -syslogd to causes it to re-read syslog.conf. You can do this with a -command like this (as root): - - kill -HUP `cat /etc/syslogd.pid` - -(On some systems, you need to use /var/run/syslog.pid instead of -/etc/syslogd.pid.) - -After setting up syslog like this, you can use the -v flag to chat and -the `debug' option to pppd to get more information. Try initiating -the connection again; when it fails, inspect /etc/ppp/log to see what -happened and where the connection failed. - - ------------------------------------------------------------------------- - -Q: When I try to establish a connection, I get an error message saying -"Serial link is not 8-bit clean". Why? - -A: The most common cause is that your connection script hasn't -successfully dialled out to the remote system and invoked ppp service -there. Instead, pppd is talking to something (a shell or login -process on the remote machine, or maybe just the modem) which is only -outputting 7-bit characters. - -This can also arise with a modem which uses an AT command set if the -dial command is issued before pppd is invoked, rather than within a -connect script started by pppd. If the serial port is set to 7 -bits/character plus parity when the last AT command is issued, the -modem serial port will be set to the same setting. - -Note that pppd *always* sets the local serial port to 8 bits per -character, with no parity and 1 stop bit. So you shouldn't need to -issue an stty command before invoking pppd. - - ------------------------------------------------------------------------- - -Q: When I try to establish a connection, I get an error message saying -"Serial line is looped back". Why? - -A: Probably your connection script hasn't successfully dialled out to -the remote system and invoked ppp service there. Instead, pppd is -talking to something which is just echoing back the characters it -receives. The -v option to chat can help you find out what's going -on. It can be useful to include "~" as the last expect string to -chat, so chat won't return until it's seen the start of the first PPP -frame from the remote system. - -Another possibility is that your phone connection has dropped for some -obscure reason and the modem is echoing the characters it receives -from your system. - - ------------------------------------------------------------------------- - -Q: I installed pppd successfully, but when I try to run it, I get a -message saying something like "peer authentication required but no -authentication files accessible". - -A: When pppd is used on a machine which already has a connection to -the Internet (or to be more precise, one which has a default route in -its routing table), it will require all peers to authenticate -themselves. The reason for this is that if you don't require -authentication, you have a security hole, because the peer can -basically choose any IP address it wants, even the IP address of some -trusted host (for example, a host mentioned in some .rhosts file). - -On machines which don't have a default route, pppd does not require -the peer to authenticate itself. The reason is that such machines -would mostly be using pppd to dial out to an ISP which will refuse to -authenticate itself. In that case the peer can use any IP address as -long as the system does not already have a route to that address. -For example, if you have a local ethernet network, the peer can't use -an address on that network. (In fact it could if it authenticated -itself and it was permitted to use that address by the pap-secrets or -chap-secrets file.) - -There are 3 ways around the problem: - -1. If possible, arrange for the peer to authenticate itself, and -create the necessary secrets files (/etc/ppp/pap-secrets and/or -/etc/ppp/chap-secrets). - -2. If the peer refuses to authenticate itself, and will always be -using the same IP address, or one of a small set of IP addresses, you -can create an entry in the /etc/ppp/pap-secrets file like this: - - "" * "" his-ip.his-domain his-other-ip.other-domain - -(that is, using the empty string for the client name and password -fields). Of couse, you replace the 4th and following fields in the -example above with the IP address(es) that the peer may use. You can -use either hostnames or numeric IP addresses. - -3. You can add the `noauth' option to the /etc/ppp/options file. -Pppd will then not ask the peer to authenticate itself. If you do -this, I *strongly* recommend that you remove the set-uid bit from the -permissions on the pppd executable, with a command like this: - - chmod u-s /usr/sbin/pppd - -Then, an intruder could only use pppd maliciously if they had already -become root, in which case they couldn't do any more damage using pppd -than they could anyway. - - ------------------------------------------------------------------------- - -Q: What do I need to put in the secrets files? - -A: Three things: - - secrets (i.e. passwords) to use for authenticating this host to - other hosts (i.e., for proving our identity to others); - - secrets which other hosts can use for authenticating themselves - to us (i.e., so that they can prove their identity to us); and - - information about which IP addresses other hosts may use, once - they have authenticated themselves. - -There are two authentication files: /etc/ppp/pap-secrets, which -contains secrets for use with PAP (the Password Authentication -Protocol), and /etc/ppp/chap-secrets, which contains secrets for use -with CHAP (the Challenge Handshake Authentication Protocol). Both -files have the same simple format, which is as follows: - -- The file contains a series of entries, each of which contains a -secret for authenticating one machine to another. - -- Each entry is contained on a single logical line. A logical line -may be continued across several lines by placing a backslash (\) at -the end of each line except the last. - -- Each entry has 3 or more fields, separated by whitespace (spaces -and/or tabs). These fields are, in order: - * The name of the machine that is authenticating itself - (the "client"). - * The name of the machine that is authenticating the client - (the "server"). - * The secret to be used for authenticating that client to that - server. If this field begins with the at-sign `@', the rest - of the field is taken as the name of a file containing the - actual secret. - * The 4th and any following fields list the IP address(es) - that the client may use. - -- The file may contain comments, which begin with a `#' and continue -to the end of the line. - -- Double quotes `"' should be used around a field if it contains -characters with special significance, such as space, tab, `#', etc. - -- The backslash `\' may be used before characters with special -significance (space, tab, `#', `\', etc.) to remove that significance. - -Some important points to note: - -* A machine can be *both* a "client" and a "server" for the purposes -of authentication - this happens when both peers require the other to -authenticate itself. So A would authenticate itself to B, and B would -also authenticate itself to A (possibly using a different -authentication protocol). - -* If both the "client" and the "server" are running ppp-2.x, they need -to have a similar entry in the appropriate secrets file; the first two -fields are *not* swapped on the client, compared to the server. So -the client might have an entry like this: - - ay bee "our little secret" - - -and the corresponding entry on the server could look like this: - - ay bee "our little secret" 123.45.67.89 - - ------------------------------------------------------------------------- - -Q: Explain about PAP and CHAP? - -PAP stands for the Password Authentication Protocol. With this -protocol, the "client" (the machine that needs to authenticate itself) -sends its name and a password, in clear text, to the "server". The -server returns a message indicating whether the name and password are -valid. - -CHAP stands for the Challenge Handshake Authentication Protocol. It -is designed to address some of the deficiencies and vulnerabilities of -PAP. Like PAP, it is based on the client and server having a shared -secret, but the secret is never passed in clear text over the link. -Instead, the server sends a "challenge" - an arbitrary string of -bytes, and the client must prove it knows the shared secret by -generating a hash value from the challenge combined with the shared -secret, and sending the hash value back to the server. The server -also generates the hash value and compares it with the value received -from the client. - -At a practical level, CHAP can be slightly easier to configure than -PAP because the server sends its name with the challenge. Thus, when -finding the appropriate secret in the secrets file, the client knows -the server's name. In contrast, with PAP, the client has to find its -password (i.e. the shared secret) before it has received anything from -the server. Thus, it may be necessary to use the `remotename' option -to pppd when using PAP authentication so that it can select the -appropriate secret from /etc/ppp/pap-secrets. - -Microsoft also has a variant of CHAP which uses a different hashing -arrangement from normal CHAP. There is a client-side implementation -of Microsoft's CHAP in ppp-2.3; see README.MSCHAP80. - - ------------------------------------------------------------------------- - -Q: When the modem hangs up, without the remote system having -terminated the connection properly, pppd does not notice the hangup, -but just keeps running. How do I get pppd to notice the hangup and -exit? - -A: Pppd detects modem hangup by looking for an end-of-file indication -from the serial driver, which should be generated when the CD (carrier -detect) signal on the serial port is deasserted. For this to work: - -- The modem has to be set to assert CD when the connection is made and -deassert it when the phone line hangs up. Usually the AT&C1 modem -command sets this mode. - -- The cable from the modem to the serial port must connect the CD -signal (on pin 8). - -- Some serial drivers have a "software carrier detect" mode, which -must be *disabled*. The method of doing this varies between systems. -Under SunOS, use the ttysoftcar command. Under NetBSD, edit /etc/ttys -to remove the "softcar" flag from the line for the serial port, and -run ttyflags. - - ------------------------------------------------------------------------- - -Q: Why should I use PPP compression (BSD-Compress or Deflate) when my -modem already does V.42 compression? Won't it slow the CPU down a -lot? - -A: Using PPP compression is preferable, especially when using modems -over phone lines, for the following reasons: - -- The V.42 compression in the modem isn't very strong - it's an LZW -technique (same as BSD-Compress) with a 10, 11 or 12 bit code size. -With BSD-Compress you can use a code size of up to 15 bits and get -much better compression, or you can use Deflate and get even better -compression ratios. - -- I have found that enabling V.42 compression in my 14.4k modem -increases the round-trip time for a character to be sent, echoed and -returned by around 40ms, from 160ms to 200ms (with error correction -enabled). This is enough to make it feel less responsive on rlogin or -telnet sessions. Using PPP compression adds less than 5ms (small -enough that I couldn't measure it reliably). I admit my modem is a -cheapie and other modems may well perform better. - -- While compression and decompression do require some CPU time, they -reduce the amount of time spent in the serial driver to transmit a -given amount of data. Many machines require an interrupt for each -character sent or received, and the interrupt handler can take a -significant amount of CPU time. So the increase in CPU load isn't as -great as you might think. My measurements indicate that a system with -a 33MHz 486 CPU should be able to do Deflate compression for serial -link speeds of up to 100kb/s or more. It depends somewhat on the type -of data, of course; for example, when compressing a string of nulls -with Deflate, it's hard to get a high output data rate from the -compressor, simply because it compresses strings of nulls so well that -it has to eat a very large amount of input data to get each byte of -output. - - ------------------------------------------------------------------------- - -Q: I get messages saying "Unsupported protocol (...) received". What do -these mean? - -A: If you only get one or two when pppd starts negotiating with the -peer, they mean that the peer wanted to negotiate some PPP protocol -that pppd doesn't understand. This doesn't represent a problem, it -simply means that there is some functionality that the peer supports -that pppd doesn't, so that functionality can't be used. - -If you get them sporadically while the link is operating, or if the -protocol numbers (in parentheses) don't correspond to any valid PPP -protocol that the peer might be using, then the problem is probably -that characters are getting corrupted on the receive side, or that -extra characters are being inserted into the receive stream somehow. -If this is happening, most packets that get corrupted should get -discarded by the FCS (Frame Check Sequence, a 16-bit CRC) check, but a -small number may get through. - -One possibility may be that you are receiving broadcast messages on -the remote system which are being sent over your serial link. Another -possibility is that your modem is set for XON/XOFF (software) flow -control and is inserting ^Q and ^S characters into the receive data -stream. - - ------------------------------------------------------------------------- - -Q: I get messages saying "Protocol-Reject for unsupported protocol ...". -What do these mean? - -A: This is the other side of the previous question. If characters are -getting corrupted on the way to the peer, or if your system is -inserting extra bogus characters into the transmit data stream, the -peer may send protocol-reject messages to you, resulting in the above -message (since your pppd doesn't recognize the protocol number -either.) - - ------------------------------------------------------------------------- - -Q: I get a message saying something like "ioctl(TIOCSETD): Operation -not permitted". How do I fix this? - -A: This is because pppd is not running as root. If you have not -installed pppd setuid-root, you will have to be root to run it. If -you have installed pppd setuid-root and you still get this message, it -is probably because your shell is using some other copy of pppd than -the installed one - for example, if you are in the pppd directory -where you've just built pppd and your $PATH has . before /usr/sbin (or -wherever pppd gets installed). - - ------------------------------------------------------------------------- - -Q: Has your package been ported to HP/UX or IRIX or AIX? - -A: No. I don't have access to systems running HP/UX or AIX. No-one -has volunteered to port it to HP/UX. I had someone who did a port for -AIX 4.x, but who is no longer able to maintain it. And apparently AIX -3.x is quite different, so it would need a separate port. - -IRIX includes a good PPP implementation in the standard distribution, -as far as I know. - - ------------------------------------------------------------------------- - -Q: Under SunOS 4, when I try to modload the ppp modules, I get the -message "can't open /dev/vd: No such device". - -A: First check in /dev that there is an entry like this: - -crw-r--r-- 1 root 57, 0 Oct 2 1991 vd - -If not, make one (mknod /dev/vd c 57 0). If the problem still exists, -probably your kernel has been configured without the vd driver -included. The vd driver is needed for loadable module support. - -First, identify the config file that was used. When you boot your -machine, or if you run /etc/dmesg, you'll see a line that looks -something like this: - -SunOS Release 4.1.3_U1 (CAP_XBOX) #7: Thu Mar 21 15:31:56 EST 1996 - ^^^^^^^^ - this is the config file name - -The config file will be in the /sys/`arch -k`/conf directory (arch -k -should return sun4m for a SparcStation 10, sun3x for a Sun 3/80, -etc.). Look in there for a line saying "options VDDRV". If that line -isn't present (or is commented out), add it (or uncomment it). - -You then need to rebuild the kernel as described in the SunOS -manuals. Basically you need to run config and make like this: - - /usr/etc/config CAP_XBOX - cd ../CAP_XBOX - make - -(replacing the string CAP_XBOX by the name of the config file for your -kernel, of course). - -Then copy the new kernel to /: - - mv /vmunix /vmunix.working - cp vmunix / - -and reboot. Modload should then work. - - ------------------------------------------------------------------------- - -Q: I'm running Linux (or NetBSD or FreeBSD), and my system comes with -PPP already. Should I consider installing this package? Why? - -A: The PPP that is already installed in your system is (or is derived -from) some version of this PPP package. You can find out what version -of this package is already installed with the command "pppd --help". -If this is older than the latest version, you may wish to install the -latest version so that you can take advantage of the new features or -bug fixes. - - ------------------------------------------------------------------------- - -Q: I'm running pppd in demand mode, and I find that pppd often dials -out unnecessarily when I try to make a connection within my local -machine or with a machine on my local LAN. What can I do about this? - -A: Very often the cause of this is that a program is trying to contact -a nameserver to resolve a hostname, and the nameserver (specified in -/etc/resolv.conf, usually) is on the far side of the ppp link. You -can try executing a command such as `ping myhost' (where myhost is the -name of the local machine, or some other machine on a local LAN), to -see whether that starts the ppp link. If it does, check the setup of -your /etc/hosts file to make sure you have the local machine and any -hosts on your local LAN listed, and /etc/resolv.conf and/or -/etc/nsswitch.conf files to make sure you resolve hostnames from -/etc/hosts if possible before trying to contact a nameserver. - - ------------------------------------------------------------------------- - -Q: Since I installed ppp-2.3.6, dialin users to my server have been -getting this message when they run pppd: - -peer authentication required but no suitable secret(s) found for -authenticating any peer to us (ispserver) - -A: In 2.3.6, the default is to let an unauthenticated peer only use IP -addresses to which the machine doesn't already have a route. So on a -machine with a default route, everyone has to authenticate. If you -really don't want that, you can put `noauth' in the /etc/ppp/options -file. Note that there is then no check on who is using which IP -address. IMHO, this is undesirably insecure, but I guess it may be -tolerable as long as you don't use any .rhosts files or anything like -that. I recommend that you require dialin users to authenticate, even -if just with PAP using their login password (using the `login' option -to pppd). If you do use `noauth', you should at least have a pppusers -group and set the permissions on pppd to allow only user and group to -execute it. - ------------------------------------------------------------------------- - -Q: When running pppd as a dial-in server, I often get the message -"LCP: timeout sending Config-Requests" from pppd. It seems to be -random, but dial-out always works fine. What is wrong? - -A: Most modern modems auto-detects the speed of the serial line -between the modem and the computer. This auto-detection occurs when -the computer sends characters to the modem, when the modem is in -command mode. It does not occur when the modem is in data mode. -Thus, if you send commands to the modem at 2400 bps, and then change -the serial port speed to 115200 bps, the modem will not detect this -change until something is transmitted from the computer to the modem. -When running pppd in dial-in mode (i.e. without a connect script), -pppd sets the speed of the serial port, but does not transmit -anything. If the modem was already running at the specified speed, -everything is fine, but if not, you will just receive garbage from the -modem. To cure this, use an init script such as the following: - - pppd ttyS0 115200 modem crtscts init "chat '' AT OK" - -To reset the modem and enable auto-answer, use: - - pppd ttyS0 115200 modem crtscts init "chat '' ATZ OK ATS0=1 OK" diff --git a/mdk-stage1/ppp/PLUGINS b/mdk-stage1/ppp/PLUGINS deleted file mode 100644 index 0eeabe249..000000000 --- a/mdk-stage1/ppp/PLUGINS +++ /dev/null @@ -1,131 +0,0 @@ -Starting with version 2.3.10, pppd includes support for `plugins' - -pieces of code which can be loaded into pppd at runtime and which can -affect its behaviour in various ways. The idea of plugins is to -provide a way for people to customize the behaviour of pppd without -having to either apply local patches to each version or get their -patches accepted into the standard distribution. My aim is that -plugins will be able to be used with successive versions of pppd -without needing to recompile the plugins. - -A plugin is a standard shared library object, typically with a name -ending in .so. They are loaded using the standard dlopen() library -call, so plugins are only supported on systems which support shared -libraries and the dlopen call. At present pppd is compiled with -plugin support only under Linux and Solaris. - -Plugins are loaded into pppd using the `plugin' option, which takes -one argument, the name of a shared object file. The plugin option is -a privileged option. I suggest that you give the full path name of -the shared object file; if you don't, it may be possible for -unscrupulous users to substitute another shared object file for the -one you mean to load, e.g. by setting the LD_LIBRARY_PATH variable. - -Plugins are usually written in C and compiled and linked to a shared -object file in the appropriate manner for your platform. Using gcc -under Linux, a plugin called `xyz' could be compiled and linked with -the following commands: - - gcc -c -O xyz.c - gcc -shared -o xyz.so xyz.o - -There are some example plugins in the pppd/plugins directory in the -ppp distribution. Currently there is one example, minconn.c, which -implements a `minconnect' option, which specifies a minimum connect -time before the idle timeout applies. - -Plugins can access global variables within pppd, so it is useful for -them to #include "pppd.h" from the pppd source directory. - -Every plugin must contain a global procedure called `plugin_init'. -This procedure will get called (with no arguments) immediately after -the plugin is loaded. - -Plugins can affect the behaviour of pppd in at least three ways: - -1. They can add extra options which pppd will then recognize. This is - done by calling the add_options() procedure with a pointer to an - array of option_t structures. The last entry in the array must - have its name field set to NULL. - -2. Pppd contains `hook' variables which are procedure pointers. If a - given hook is not NULL, pppd will call the procedure it points to - at the appropriate point in its processing. The plugin can set any - of these hooks to point to its own procedures. See below for a - description of the hooks which are currently implemented. - -3. Plugin code can call any global procedures and access any global - variables in pppd. - -Here is a list of the currently implemented hooks in pppd. - - -int (*idle_time_hook)(struct ppp_idle *idlep); - -The idle_time_hook is called when the link first comes up (i.e. when -the first network protocol comes up) and at intervals thereafter. On -the first call, the idlep parameter is NULL, and the return value is -the number of seconds before pppd should check the link activity, or 0 -if there is to be no idle timeout. - -On subsequent calls, idlep points to a structure giving the number of -seconds since the last packets were sent and received. If the return -value is > 0, pppd will wait that many seconds before checking again. -If it is <= 0, that indicates that the link should be terminated due -to lack of activity. - - -int (*holdoff_hook)(void); - -The holdoff_hook is called when an attempt to bring up the link fails, -or the link is terminated, and the persist or demand option was used. -It returns the number of seconds that pppd should wait before trying -to reestablish the link (0 means immediately). - - -int (*pap_check_hook)(void); -int (*pap_passwd_hook)(char *user, char *passwd); -int (*pap_auth_hook)(char *user, int userlen, - char *passwd, int passlen, - char **msgp, int *msglenp, - struct wordlist **paddrs, - struct wordlist **popts); - -These hooks are designed to allow a plugin to replace the normal PAP -password processing in pppd with something different (e.g. contacting -an external server). - -The pap_check_hook is called to check whether there is any possibility -that the peer could authenticate itself to us. If it returns 1, pppd -will ask the peer to authenticate itself. If it returns 0, pppd will -not ask the peer to authenticate itself (but if authentication is -required, pppd may exit, or terminate the link before network protocol -negotiation). If it returns -1, pppd will look in the pap-secrets -file as it would normally. - -The pap_passwd_hook is called to determine what username and password -pppd should use in authenticating itself to the peer with PAP. The -user string will already be initialized, by the `user' option, the -`name' option, or from the hostname, but can be changed if necessary. -MAXNAMELEN bytes of space are available at *user, and MAXSECRETLEN -bytes of space at *passwd. If this hook returns 0, pppd will use the -values at *user and *passwd; if it returns -1, pppd will look in the -pap-secrets file, or use the value from the +ua or password option, as -it would normally. - -The pap_auth_hook is called to determine whether the username and -password supplied by the peer are valid. user and passwd point to -null-terminated strings containing the username and password supplied -by the peer, with non-printable characters converted to a printable -form. The pap_auth_hook function should set msg to a string to be -returned to the peer and return 1 if the username/password was valid -and 0 if not. If the hook returns -1, pppd will look in the -pap-secrets file as usual. - -If the username/password was valid, the hook can set *paddrs to point -to a wordlist containing the IP address(es) which the peer is -permitted to use, formatted as in the pap-secrets file. It can also -set *popts to a wordlist containing any extra options for this user -which pppd should apply at this point. - - -## $Id$ ## diff --git a/mdk-stage1/ppp/README b/mdk-stage1/ppp/README deleted file mode 100644 index aa1e5f9c2..000000000 --- a/mdk-stage1/ppp/README +++ /dev/null @@ -1,168 +0,0 @@ -This is the README file for ppp-2.4, a package which implements the -Point-to-Point Protocol (PPP) to provide Internet connections over -serial lines. - - -Introduction. -************* - -The Point-to-Point Protocol (PPP) provides a standard way to establish -a network connection over a serial link. At present, this package -supports IP and the protocols layered above IP, such as TCP and UDP. -The Linux and Solaris ports of this package have optional support for -IPV6; the Linux port of this package also has support for IPX. - -This software consists of two parts: - -- Kernel code, which establishes a network interface and passes -packets between the serial port, the kernel networking code and the -PPP daemon (pppd). This code is implemented using STREAMS modules on -SunOS 4.x and Solaris, and as a line discipline under Linux and FreeBSD. - -- The PPP daemon (pppd), which negotiates with the peer to establish -the link and sets up the ppp network interface. Pppd includes support -for authentication, so you can control which other systems may make a -PPP connection and what IP addresses they may use. - -The primary platforms supported by this package are Linux and Solaris. -Code for SunOS 4.x is included here but is largely untested. I have -code for NeXTStep, FreeBSD, SVR4, Tru64 (Digital Unix), AIX and Ultrix -but no active maintainers for these platforms. Code for all of these -except AIX is included in the ppp-2.3.11 release. - - -Installation. -************* - -The file SETUP contains general information about setting up your -system for using PPP. There is also a README file for each supported -system, which contains more specific details for installing PPP on -that system. The supported systems, and the corresponding README -files, are: - - Linux README.linux - Solaris 2 README.sol2 - SunOS 4.x README.sunos4 - -In each case you start by running the ./configure script. This works -out which operating system you are using and creates symbolic links to -the appropriate makefiles. You then run `make' to compile the -user-level code, and (as root) `make install' to install the -user-level programs pppd, chat and pppstats. - -N.B. Since 2.3.0, leaving the permitted IP addresses column of the -pap-secrets or chap-secrets file empty means that no addresses are -permitted. You need to put a "*" in that column to allow the peer to -use any IP address. (This only applies where the peer is -authenticating itself to you, of course.) - - -What's new in ppp-2.4.1. -************************ - -* Pppd can now print out the set of options that are in effect. The - new `dump' option causes pppd to print out the option values after - option parsing is complete. The `dryrun' option causes pppd to - print the options and then exit. - -* The option parsing code has been fixed so that options in the - per-tty options file are parsed correctly, and don't override values - from the command line in most cases. - -* The plugin option now looks in /usr/lib/pppd/<pppd-version> (for - example, /usr/lib/pppd/2.4.1b1) for shared objects for plugins if - there is no slash in the plugin name. - -* When loading a plugin, pppd will now check the version of pppd for - which the plugin was compiled, and refuse to load it if it is - different to pppd's version string. To enable this, the plugin - source needs to #include "pppd.h" and have a line saying: - char pppd_version[] = VERSION; - -* There is a bug in zlib, discovered by James Carlson, which can cause - kernel memory corruption if Deflate is used with the lowest setting, - 8. As a workaround pppd will now insist on using at least 9. - -* Pppd should compile on Solaris and SunOS again. - -* Pppd should now set the MTU correctly on demand-dialled interfaces. - - -What was new in ppp-2.4.0. -************************** - -* Multilink: this package now allows you to combine multiple serial - links into one logical link or `bundle', for increased bandwidth and - reduced latency. This is currently only supported under the - Linux-2.3.99pre5 or later kernels. - -* All the pppd processes running on a system now write information - into a common database. I used the `tdb' code from samba for this. - -* New hooks have been added. - -For a list of the changes made during the 2.3 series releases of this -package, see the Changes-2.3 file. - - -Compression methods. -******************** - -This package supports two packet compression methods: Deflate and -BSD-Compress. Other compression methods which are in common use -include Predictor, LZS, and MPPC. These methods are not supported for -two reasons - they are patent-encumbered, and they cause some packets -to expand slightly, which pppd doesn't currently allow for. -BSD-Compress is also patent-encumbered (its inclusion in this package -can be considered a historical anomaly :-) but it doesn't ever expand -packets. Neither does Deflate, which uses the same algorithm as gzip. - - -Patents. -******** - -The BSD-Compress algorithm used for packet compression is the same as -that used in the Unix "compress" command. It is apparently covered by -U.S. patents 4,814,746 (owned by IBM) and 4,558,302 (owned by Unisys), -and corresponding patents in various other countries (but not -Australia). If this is of concern, you can build the package without -including BSD-Compress. To do this, edit net/ppp-comp.h to change the -definition of DO_BSD_COMPRESS to 0. The bsd-comp.c files are then no -longer needed, so the references to bsd-comp.o may optionally be -removed from the Makefiles. - - -Contacts. -********* - -The comp.protocols.ppp newsgroup is a useful place to get help if you -have trouble getting your ppp connections to work. Please do not send -me questions of the form "please help me get connected to my ISP" - -I'm sorry, but I simply do not have the time to answer all the -questions like this that I get. - -If you find bugs in this package, please report them to the maintainer -for the port for the operating system you are using: - -Linux Paul Mackerras <paulus@linuxcare.com> -Solaris 2 James Carlson <james.d.carlson@east.sun.com> -SunOS 4.x Adi Masputra <adi.masputra@sun.com> - - -Copyrights: -*********** - -All of the code can be freely used and redistributed. The individual -source files each have their own copyright and permission notice; some -have a BSD-style notice and some are under the GPL. - - -Distribution: -************* - -The primary site for releases of this software is: - - ftp://linuxcare.com.au/pub/ppp/ - - -($Id$) diff --git a/mdk-stage1/ppp/README.MSCHAP80 b/mdk-stage1/ppp/README.MSCHAP80 deleted file mode 100644 index d3ed291b7..000000000 --- a/mdk-stage1/ppp/README.MSCHAP80 +++ /dev/null @@ -1,284 +0,0 @@ -PPP Client Support for Microsoft's CHAP-80 -========================================== - -Eric Rosenquist rosenqui@strataware.com -(updated by Paul Mackerras) -(updated by Al Longyear) -(updated by Farrell Woods) - -INTRODUCTION - -Microsoft has introduced an extension to the Challenge/Handshake -Authentication Protocol (CHAP) which avoids storing cleartext -passwords on a server. (Unfortunately, this is not as secure as it -sounds, because the encrypted password stored on a server can be used -by a bogus client to gain access to the server just as easily as if -the password were stored in cleartext.) The details of the Microsoft -extensions can be found in the document: - - <ftp://ftp.microsoft.com/developr/rfc/chapexts.txt> - -In short, MS-CHAP is identified as <auth chap 80> since the hex value -of 80 is used to designate Microsoft's scheme. Standard PPP CHAP uses -a value of 5. If you enable PPP debugging with the "debug" option and -see something like the following in your logs, the remote server is -requesting MS-CHAP: - - rcvd [LCP ConfReq id=0x2 <asyncmap 0x0> <auth chap 80> <magic 0x46a3>] - ^^^^^^^^^^^^ - -The standard pppd implementation will indicate its lack of support for -MS-CHAP by NAKing it: - - sent [LCP ConfNak id=0x2 <auth chap 05>] - -Windows NT Server systems are often configured to "Accept only -Microsoft Authentication" (this is intended to enhance security). Up -until now, that meant that you couldn't use this version of PPPD to -connect to such a system. I've managed to get a client-only -implementation of MS-CHAP working; it will authenticate itself to -another system using MS-CHAP, but if you're using PPPD as a dial-in -server, you won't be able to use MS-CHAP to authenticate the clients. -This would not be a lot of extra work given that the framework is in -place, but I didn't need it myself so I didn't implement it. - - -BUILDING THE PPPD - -MS-CHAP uses a combination of MD4 hashing and DES encryption for -authentication. You may need to get Eric Young's libdes library in -order to use my MS-CHAP extensions. A lot of UNIX systems already -have DES encryption available via the crypt(3), encrypt(3) and -setkey(3) interfaces. Some may (such as that on Digital UNIX) -provide only the encryption mechanism and will not perform -decryption. This is okay. We only need to encrypt to perform -MS-CHAP authentication. - -If you have encrypt/setkey available, then hopefully you need only -define these two things in your Makefile: -DUSE_CRYPT and -DCHAPMS. -Skip the paragraphs below about obtaining and building libdes. Do -the "make clean" and "make" as described below. Linux users -should not need to modify their Makefiles. Instead, -just do "make CHAPMS=1 USE_CRYPT=1". - -If you don't have encrypt and setkey, you will need Eric Young's -libdes library. You can find it in: - -ftp://ftp.funet.fi/pub/crypt/mirrors/ftp.psy.uq.oz.au/DES/libdes-3.06.tar.gz - -Australian residents can get libdes from Eric Young's site: - -ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-3.06.tar.gz - -It is also available on many other sites (ask Archie). - -I used libdes-3.06, but hopefully anything newer than that will work -also. Get the library, build and test it on your system, and install -it somewhere (typically /usr/local/lib and /usr/local/include). - - - -You should now be ready to (re)compile the PPPD. Go to the pppd -subdirectory and make sure the Makefile contains "-DCHAPMS" in the -CFLAGS or COMPILE_FLAGS macro, and that the LIBS macro (or LDADD for -BSD systems) contains "-ldes". Depending on your system and where the -DES library was installed, you may also need to alter the include and -library paths used by your compiler. - -Do a "make clean" and then a "make" to rebuild pppd. Assuming all -goes well, install the new pppd and move on to the CONFIGURATION -section. - - -CONFIGURATION - -If you've never used PPPD with CHAP before, read the man page (type -"man pppd") and read the description in there. Basically, you need to -edit the "chap-secrets" file typically named /etc/ppp/chap-secrets. -This should contain the following two lines for each system with which -you use CHAP (with no leading blanks): - - RemoteHost Account Secret - Account RemoteHost Secret - -Note that you need both lines and that item 1 and 2 are swapped in the -second line. I'm not sure why you need it twice, but it works and I didn't -have time to look into it further. The "RemoteHost" is a somewhat -arbitrary name for the remote Windows NT system you're dialing. It doesn't -have to match the NT system's name, but it *does* have to match what you -use with the "remotename" parameter. The "Account" is the Windows NT -account name you have been told to use when dialing, and the "Secret" is -the password for that account. For example, if your service provider calls -their machine "DialupNT" and tells you your account and password are -"customer47" and "foobar", add the following to your chap-secrets file: - - DialupNT customer47 foobar - customer47 DialupNT foobar - -The only other thing you need to do for MS-CHAP (compared to normal CHAP) -is to always use the "remotename" option, either on the command line or in -your "options" file (see the pppd man page for details). In the case of -the above example, you would need to use the following command line: - - pppd name customer47 remotename DialupNT <other options> - -or add: - - name customer47 - remotename DialupNT - -to your PPPD "options" file. - -The "remotename" option is required for MS-CHAP since Microsoft PPP servers -don't send their system name in the CHAP challenge packet. - - -E=691 (AUTHENTICATION_FAILURE) ERRORS WHEN YOU HAVE THE VALID SECRET (PASSWORD) - -If your RAS server is not the domain controller and is not a 'stand-alone' -server then it must make a query to the domain controller for your domain. - -You need to specify the domain name with the user name when you attempt to -use this type of a configuration. The domain name is specified with the -local name in the chap-secrets file and with the option for the 'name' -parameter. - -For example, the previous example would become: - - DialupNT domain\\customer47 foobar - domain\\customer47 DialupNT foobar - -and - - pppd name 'domain\\customer47' remotename DialupNT <other options> - -or add: - - name domain\\customer47 - remotename DialupNT - -when the Windows NT domain name is simply called 'domain'. - - -TROUBLESHOOTING - -Assuming that everything else has been configured correctly for PPP and -CHAP, the MS-CHAP-specific problems you're likely to encounter are mostly -related to your Windows NT account and its settings. A Microsoft server -returns error codes in its CHAP response. The following are extracted from -Microsoft's "chapexts.txt" file referenced above: - - 646 ERROR_RESTRICTED_LOGON_HOURS - 647 ERROR_ACCT_DISABLED - 648 ERROR_PASSWD_EXPIRED - 649 ERROR_NO_DIALIN_PERMISSION - 691 ERROR_AUTHENTICATION_FAILURE - 709 ERROR_CHANGING_PASSWORD - -You'll see these in your pppd log as a line similar to: - - Remote message: E=649 R=0 - -The "E=" is the error number from the table above, and the "R=" flag -indicates whether the error is transient and the client should retry. If -you consistently get error 691, then either you're using the wrong account -name/password, or the DES library or MD4 hashing (in md4.c) aren't working -properly. Verify your account name and password (use a Windows NT or -Windows 95 system to dial-in if you have one available). If that checks -out, test the DES library with the "destest" program included with the DES -library. If DES checks out, the md4.c routines are probably failing -(system byte ordering may be a problem) or my code is screwing up. I've -only got access to a Linux system, so you're on your own for anything else. - -Another thing that might cause problems is that some RAS servers won't -respond at all to LCP config requests without seeing the word "CLIENT" -from the other end. If you see pppd sending out LCP config requests -without getting any reply, try putting something in your chat script -to send the word CLIENT after the modem has connected. - -If everything compiles cleanly, but fails at authentication time, then -it might be a case of the MD4 or DES code screwing up. The following -small program can be used to test the MS-CHAP code to see if it -produces a known response: - ------------------ -#include <stdio.h> - -#include "pppd.h" -#include "chap.h" -#include "chap_ms.h" - -int main(argc, argv) - int argc; - char *argv[]; -{ - u_char challenge[8]; - int challengeInt[sizeof(challenge)]; - chap_state cstate; - int i; - - if (argc != 3) { - fprintf(stderr, "Usage: %s <16-hexchar challenge> <password>\n", - argv[0]); exit(1); - } - - sscanf(argv[1], "%2x%2x%2x%2x%2x%2x%2x%2x", - challengeInt + 0, challengeInt + 1, challengeInt + 2, - challengeInt + 3, challengeInt + 4, challengeInt + 5, - challengeInt + 6, challengeInt + 7); - - for (i = 0; i < sizeof(challenge); i++) - challenge[i] = (u_char)challengeInt[i]; - - ChapMS(&cstate, challenge, sizeof(challenge), argv[2], strlen(argv[2])); - printf("Response length is %d, response is:", cstate.resp_length); - - for (i = 0; i < cstate.resp_length; i++) { - if (i % 8 == 0) - putchar('\n'); - printf("%02X ", (unsigned int)cstate.response[i]); - } - - putchar('\n'); - - exit(0); -} -------------- - -This needs to link against chap_ms.o, md4.o, and the DES library. When -you run it with the command line: - - $ testchap 00000000000000000000000000000000 hello - -it should output the following: - - Response length is 49, response is: - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - F4 D9 9D AF 82 64 DC 3C - 53 F9 BC 92 14 B5 5D 9E - 78 C4 21 48 9D B7 A8 B4 - 01 - -if not, then either the DES library is not working, the MD4 code isn't -working, or there are some problems with the port of the code in -chap_ms.c. - - -STILL TO DO - -A site using only MS-CHAP to authenticate has no need to store cleartext -passwords in the "chap-secrets" file. A utility that spits out the ASCII -hex MD4 hash of a given password would be nice, and would allow that hash -to be used in chap-secrets in place of the password. The code to do this -could quite easily be lifted from chap_ms.c (you have to convert the -password to Unicode before hashing it). The chap_ms.c file would also have -to be changed to recognize a password hash (16 binary bytes == 32 ASCII hex -characters) and skip the hashing stage. - -A server implementation would allow MS-CHAP to be used with Windows NT and -Windows 95 clients for enhanced security. Some new command-line options -would be required, as would code to generate the Challenge packet and -verify the response. Most of the helper functions are in place, so this -shouldn't be too hard for someone to add. diff --git a/mdk-stage1/ppp/README.cbcp b/mdk-stage1/ppp/README.cbcp deleted file mode 100644 index 6f7b7685e..000000000 --- a/mdk-stage1/ppp/README.cbcp +++ /dev/null @@ -1,97 +0,0 @@ - Microsoft Call Back Configuration Protocol. - by Pedro Roque Marques - (updated by Paul Mackerras) - -The CBCP is a method by which the Microsoft Windows NT Server may -implement additional security. It is possible to configure the server -in such a manner so as to require that the client systems which -connect with it are required that following a valid authentication to -leave a method by which the number may be returned call. - -It is a requirement of servers so configured that the protocol be -exchanged. - -So, this set of patches may be applied to the pppd process to enable -the cbcp client *only* portion of the specification. It is primarily -meant to permit connection with Windows NT Servers. - -The ietf-working specification may be obtained from ftp.microsoft.com -in the developr/rfc directory. - -The ietf task group has decided to recommend that the LCP sequence be -extended to permit the callback operation. For this reason, these -patches are not 'part' of pppd but are an adjunct to the code. - -To enable CBCP support, all that is required is to change the -appropriate Makefile in the pppd subdirectory to add "-DCBCP_SUPPORT" -to the CFLAGS definition and add cbcp.o to the list of object files, -and then recompile pppd. The patch below does this for Makefile.bsd -and Makefile.linux. - - ---------------------------------cut here------------------------------- -diff -r -c ppp-2.3.orig/pppd/Makefile.bsd ppp-2.3/pppd/Makefile.bsd -*** ppp-2.3.orig/pppd/Makefile.bsd Tue Oct 8 13:33:33 1996 ---- ppp-2.3/pppd/Makefile.bsd Fri Apr 11 23:59:15 1997 -*************** -*** 4,14 **** - # -D_BITYPES is for FreeBSD, which doesn't define anything to - # tell us that u_int32_t gets defined if <sys/types.h> is included. - # Remove for older *BSD systems for which this isn't true. -! CFLAGS+= -g -I.. -DHAVE_PATHS_H -D_BITYPES - - PROG= pppd - SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ -! demand.c auth.c options.c sys-bsd.c - MAN= pppd.cat8 - MAN8= pppd.8 - BINMODE=4555 ---- 4,14 ---- - # -D_BITYPES is for FreeBSD, which doesn't define anything to - # tell us that u_int32_t gets defined if <sys/types.h> is included. - # Remove for older *BSD systems for which this isn't true. -! CFLAGS+= -I.. -DHAVE_PATHS_H -D_BITYPES -DCBCP_SUPPORT - - PROG= pppd - SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ -! demand.c auth.c options.c sys-bsd.c cbcp.c - MAN= pppd.cat8 - MAN8= pppd.8 - BINMODE=4555 -diff -r -c ppp-2.3.orig/pppd/Makefile.linux ppp-2.3/pppd/Makefile.linux -*** ppp-2.3.orig/pppd/Makefile.linux Tue Oct 8 15:42:41 1996 ---- ppp-2.3/pppd/Makefile.linux Sat Apr 12 00:02:28 1997 -*************** -*** 14,20 **** - ipxcp.h cbcp.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 demand.o sys-linux.o ipxcp.o - - all: pppd - ---- 14,20 ---- - ipxcp.h cbcp.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 demand.o sys-linux.o ipxcp.o cbcp.o - - all: pppd - -*************** -*** 36,42 **** - #INCLUDE_DIRS= -I/usr/include -I.. - INCLUDE_DIRS= - -! COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE - - CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) - ---- 36,42 ---- - #INCLUDE_DIRS= -I/usr/include -I.. - INCLUDE_DIRS= - -! COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DCBCP_SUPPORT - - CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) - diff --git a/mdk-stage1/ppp/README.linux b/mdk-stage1/ppp/README.linux deleted file mode 100644 index 62ed9ca7f..000000000 --- a/mdk-stage1/ppp/README.linux +++ /dev/null @@ -1,297 +0,0 @@ - PPP for Linux - ------------- - - Paul Mackerras - 8 March 2001 - - for ppp-2.4.1 - -1. Introduction ---------------- - -The Linux PPP implementation includes both kernel and user-level -parts. This package contains the user-level part, which consists of -the PPP daemon (pppd) and associated utilities. In the past this -package has contained updated kernel drivers. This is no longer -necessary, as the current 2.2 and 2.4 kernel sources contain -up-to-date drivers. - -The Linux PPP implementation is capable of being used both for -initiating PPP connections (as a `client') or for handling incoming -PPP connections (as a `server'). Note that this is an operational -distinction, based on how the connection is created, rather than a -distinction that is made in the PPP protocols themselves. - -Mostly this package is used for PPP connections over modems connected -via asynchronous serial ports, so this guide concentrates on this -situation. - -The PPP protocol consists of two parts. One is a scheme for framing -and encoding packets, the other is a series of protocols called LCP, -IPCP, PAP and CHAP, for negotiating link options and for -authentication. This package similarly consists of two parts: a -kernel module which handles PPP's low-level framing protocol, and a -user-level program called pppd which implements PPP's negotiation -protocols. - -The kernel module assembles/disassembles PPP frames, handles error -detection, and forwards packets between the serial port and either the -kernel network code or the user-level program pppd. IP packets go -directly to the kernel network code. So once pppd has negotiated the -link, it in practice lies completely dormant until you want to take -the link down, when it negotiates a graceful disconnect. - - -2. Installation ---------------- - -2.1 Kernel driver - -Assuming you are running a recent 2.2 or 2.4 (or later) series kernel, -the kernel source code will contain an up-to-date kernel PPP driver. -If the PPP driver was included in your kernel configuration when your -kernel was built, then you only need to install the user-level -programs. Otherwise you will need to get the source tree for your -kernel version, configure it with PPP included, and recompile. Most -Linux distribution vendors ship kernels with PPP included in the -configuration. - -The PPP driver can be either compiled into the kernel or compiled as a -kernel module. If it is compiled into the kernel, the PPP driver is -included in the kernel image which is loaded at boot time. If it is -compiled as a module, the PPP driver is present in one or more files -under /lib/modules and is loaded into the kernel when needed. - -The 2.2 series kernels contain an older version of the kernel PPP -driver, one which doesn't support multilink. If you want multilink, -you need to run the latest 2.4 series kernel. The kernel PPP driver -was completely rewritten for the 2.4 series kernels to support -multilink and to allow it to operate over diverse kinds of -communication medium (the 2.2 driver only operates over serial ports -and devices which look like serial ports, such as pseudo-ttys). - -Under the 2.2 kernels, if PPP is compiled as a module, the PPP driver -modules should be present in the /lib/modules/`uname -r`/net directory -(where `uname -r` represents the kernel version number). The PPP -driver module itself is called ppp.o, and there will usually be -compression modules there, ppp_deflate.o and bsd_comp.o, as well as -slhc.o, which handles TCP/IP header compression. If the PPP driver is -compiled into the kernel, the compression code will still be compiled -as modules, for kernels before 2.2.17pre12. For 2.2.17pre12 and later, -if the PPP driver is compiled in, the compression code will also. - -Under the 2.4 kernels, there are two PPP modules, ppp_generic.o and -ppp_async.o, plus the compression modules (ppp_deflate.o, bsd_comp.o -and slhc.o). If the PPP generic driver is compiled into the kernel, -the other four can then be present either as modules or compiled into -the kernel. There is a sixth module, ppp_synctty.o, which is used for -synchronous tty devices such as high-speed WAN adaptors. - - -2.2 User-level programs - -If you obtained this package in .rpm or .deb format, you simply follow -the usual procedure for installing the package. - -If you are using the .tar.gz form of this package, then cd into the -ppp-2.4.1b1 directory you obtained by unpacking the archive and issue -the following commands: - -$ ./configure -$ make -# make install - -The `make install' has to be done as root. This makes and installs -four programs and their man pages: pppd, chat, pppstats and pppdump. -If the /etc/ppp configuration directory doesn't exist, the `make -install' step will create it and install some default configuration -files. - - -2.3 System setup for 2.4 kernels - -Under the 2.4 series kernels, pppd needs to be able to open /dev/ppp, -character device (108,0). If you are using devfs (the device -filesystem), the /dev/ppp node will automagically appear when the -ppp_generic module is loaded, or at startup if ppp_generic is compiled -in. - -If you have ppp_generic as a module, and you are using devfsd (the -devfs daemon), you will need to add a line like this to your -/etc/devfsd.conf: - -LOOKUP ppp MODLOAD - -Otherwise you will need to create a /dev/ppp device node with the -commands: - -# mknod /dev/ppp c 108 0 -# chmod 600 /dev/ppp - -If you use module autoloading and have PPP as a module, you will need -to add the following to your /etc/modules.conf or /etc/conf.modules: - -alias /dev/ppp ppp_generic -alias char-major-108 ppp_generic -alias tty-ldisc-3 ppp_async -alias tty-ldisc-14 ppp_synctty -alias ppp-compress-21 bsd_comp -alias ppp-compress-24 ppp_deflate -alias ppp-compress-26 ppp_deflate - - -2.4 System setup under 2.2 series kernels - -Under the 2.2 series kernels, you should add the following to your -/etc/modules.conf or /etc/conf.modules: - -alias tty-ldisc-3 ppp -alias ppp-compress-21 bsd_comp -alias ppp-compress-24 ppp_deflate -alias ppp-compress-26 ppp_deflate - - -3. Getting help with problems ------------------------------ - -If you have problems with your PPP setup, or you just want to ask some -questions, or better yet if you can help others with their PPP -questions, then you should join the linux-ppp mailing list. Send an -email to majordomo@vger.kernel.org with a line in the body saying - -subscribe linux-ppp - -To leave the mailing list, send an email to majordomo@vger.kernel.org -with a line in the body saying - -unsubscribe linux-ppp - -To send a message to the list, email it to linux-ppp@vger.kernel.org. -You don't have to be subscribed to send messages to the list. - -You can also email me (paulus@linuxcare.com.au) but I am overloaded -with email and I can't respond to most messages I get in a timely -fashion. - -There are also several relevant news groups, such as comp.protocols.ppp, -comp.os.linux.networking, or comp.os.linux.setup. - - -4. Configuring your dial-out PPP connections --------------------------------------------- - -Some Linux distribution makers include tools in their distributions -for setting up PPP connections. For example, for Red Hat Linux and -derivatives, you should probably use linuxconf or netcfg to set up -your PPP connections. - -The two main windowing environments for Linux, KDE and Gnome, both -come with GUI utilities for configuring and controlling PPP dial-out -connections. They are convenient and relatively easy to configure. - -A third alternative is to use a PPP front-end package such as wvdial -or ezppp. These also will handle most of the details of talking to -the modem and setting up the PPP connection for you. - -Assuming that you don't want to use any of these tools, you want to -set up the configuration manually yourself, then read on. This -document gives a brief description and example. More details can be -found by reading the pppd and chat man pages and the PPP-HOWTO. - -We assume that you have a modem that uses the Hayes-compatible AT -command set connected to an async serial port (e.g. /dev/ttyS0) and -that you are dialling out to an ISP. - -The trickiest and most variable part of setting up a dial-out PPP -connection is the part which involves getting the modem to dial and -then invoking PPP service at the far end. Generally, once both ends -are talking PPP the rest is relatively straightforward. - -Now in fact pppd doesn't know anything about how to get modems to dial -or what you have to say to the system at the far end to get it to talk -PPP. That's handled by an external program such as chat, specified -with the connect option to pppd. Chat takes a series of strings to -expect from the modem interleaved with a series of strings to send to -the modem. See the chat man page for more information. Here is a -simple example for connecting to an ISP, assuming that the ISP's -system starts talking PPP as soon as it answers the phone: - -pppd connect 'chat -v "" AT OK ATDT5551212 ~' \ - /dev/ttyS0 57600 crtscts debug defaultroute - -Going through pppd's options in order: - connect 'chat ...' This gives a command to run to contact the - PPP server. Here the supplied 'chat' program is used to dial a - remote computer. The whole command is enclosed in single quotes - because pppd expects a one-word argument for the 'connect' option. - The options to 'chat' itself are: - - -v verbose mode; log what we do to syslog - "" don't wait for any prompt, but instead... - AT send the string "AT" - OK expect the response "OK", then - ATDT5551212 dial the modem, then - ~ wait for a ~ character, indicating the start - of a PPP frame from the server - - /dev/ttyS0 specifies which serial port the modem is connected to - 57600 specifies the baud rate to use - crtscts use hardware flow control using the RTS & CTS signals - debug log the PPP negotiation with syslog - defaultroute add default network route via the PPP link - -Pppd will write error messages and debugging logs to the syslogd -daemon using the facility name "daemon". These messages may already -be logged to the console or to a file like /var/log/messages; consult -your /etc/syslog.conf file to see. If you want to make all pppd -messages go to a file such as /var/log/ppp-debug, add the line - -daemon.* /var/log/ppp-debug - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - This is one or more tabs. Do not use spaces. - -to syslog.conf; make sure to put one or more TAB characters (not -spaces!) between the two fields. Then you need to create an empty -/var/log/ppp-debug file with a command such as - - touch /var/log/ppp-debug - -and then restart syslogd, usually by sending it a SIGHUP signal with a -command like this: - - killall -HUP syslogd - - -4.1 Is the link up? - -The main way to tell if your PPP link is up and operational is the -ifconfig ("interface configuration") command. Type - - /sbin/ifconfig - -at a shell prompt. It should print a list of interfaces including one -like this example: - -ppp0 Link encap Point-to-Point Protocol - inet addr 192.76.32.3 P-t-P 129.67.1.165 Mask 255.255.255.0 - UP POINTOPOINT RUNNING MTU 1500 Metric 1 - RX packets 33 errors 0 dropped 0 overrun 0 - TX packets 42 errors 0 dropped 0 overrun 0 - -Assuming that ifconfig shows the ppp network interface, you can test -the link using the ping command like this: - - /sbin/ping -c 3 129.67.1.165 - -where the address you give is the address shown as the P-t-P address -in the ifconfig output. If the link is operating correctly, you -should see output like this: - - PING 129.67.1.165 (129.67.1.165): 56 data bytes - 64 bytes from 129.67.1.165: icmp_seq=0 ttl=255 time=268 ms - 64 bytes from 129.67.1.165: icmp_seq=1 ttl=255 time=247 ms - 64 bytes from 129.67.1.165: icmp_seq=2 ttl=255 time=266 ms - --- 129.67.1.165 ping statistics --- - 3 packets transmitted, 3 packets received, 0% packet loss - round-trip min/avg/max = 247/260/268 ms - diff --git a/mdk-stage1/ppp/README.sol2 b/mdk-stage1/ppp/README.sol2 deleted file mode 100644 index 4c862208f..000000000 --- a/mdk-stage1/ppp/README.sol2 +++ /dev/null @@ -1,220 +0,0 @@ -This file describes the installation process for ppp-2.3 on systems -running Solaris 2. The Solaris 2 and SVR4 ports share a lot of code -but are not identical. The STREAMS kernel modules and driver for -Solaris 2 are in the svr4 directory (and use some code from the -modules directory). - -NOTE: Although the kernel driver and modules have been designed to -operate correctly on SMP systems, they have not been extensively -tested on SMP machines. Some users of SMP Solaris x86 systems have -reported system problems apparently linked to the use of previous -versions of this software. I believe these problems have been fixed. - - -Installation. -************* - -1. Run the configure script and make the user-level programs and the -kernel modules. - - ./configure - make - -If you wish to use gcc (or another compiler) instead of Sun's cc, edit -the svr4/Makedefs file and uncomment the definition of CC. You can -also change the options passed to the C compiler by editing the COPTS -definition. - -2. Install the programs and kernel modules: as root, do - - make install - -This installs pppd, chat and pppstats in /usr/local/bin and the kernel -modules in /kernel/drv and /kernel/strmod, and creates the /etc/ppp -directory and populates it with default configuration files. You can -change the installation directories by editing svr4/Makedefs. - -If your system normally has only one network interface, the default -Solaris 2 system startup scripts will disable IP forwarding in the IP -kernel module. This will prevent the remote machine from using the -local machine as a gateway to access other hosts. The solution is to -create an /etc/ppp/ip-up script containing something like this: - - #!/bin/sh - /usr/sbin/ndd -set /dev/ip ip_forwarding 1 - -See the man page for ip(7p) for details. - -Dynamic STREAMS Re-Plumbing Support. -************************************ - -Solaris 8 includes dynamic re-plumbing support. With this, modules -below ip can be inserted, or removed, without having the ip stream be -unplumbed, and re-plumbed again. All states in ip for an interface -will therefore now be preserved. Users can install (or upgrade) -modules like firewall, bandwidth manager, cache manager, tunneling, -etc., without shutting the machine down. - -To support this, ppp driver now uses /dev/udp instead of /dev/ip for -the ip stream. The interface stream (where ip module pushed on top of -ppp) is then I_PLINK'ed below the ip stream. /dev/udp is used because -STREAMS will not let a driver be PLINK'ed under itself, and /dev/ip is -typically the driver at the bottom of the tunneling interfaces -stream. The mux ids of the ip streams are then added using -SIOCSxIFMUXID ioctl. - -Users will be able to see the modules on the interface stream by, for -example: - - pikapon% ifconfig ppp modlist - 0 ip - 1 ppp - -Or arbitrarily if bandwidth manager and firewall modules are installed: - - pikapon% ifconfig hme0 modlist - 0 arp - 1 ip - 2 ipqos - 3 firewall - 4 hme - -Snoop Support. -************** - -This version includes support for /usr/sbin/snoop. Tests has been done -on both Solaris 7 and 8. Only IPv4 and IPv6 packets will be sent up to -stream(s) marked as promiscuous, e.g, snoop et al. - -Users will be able to see the packets on the ppp interface by, for example: - - snoop -d ppp0 - -See the man page for snoop(1M) for details. - -IPv6 Support. -************* - -This is for Solaris 8 and later. - -This version has been tested under Solaris 8 running IPv6. As of now, -interoperability testing has only been done between Solaris machines -in terms of the IPV6 NCP. An additional command line option for the -pppd daemon has been added: ipv6cp-use-persistent. - -By default, compilation for IPv6 support is not enabled. Uncomment -the necessary lines in pppd/Makefile.sol2 to enable it. Once done, the -quickest way to get IPv6 running is to add the following somewhere in -the command line option: - - +ipv6 ipv6cp-use-persistent - -The persistent id for the link-local address was added to conform to -RFC 2472; such that if there's an EUI-48 available, use that to make -up the EUI-64. As of now, the Solaris implementation extracts the -EUI-48 id from the Ethernet's MAC address (the ethernet interface -needs to be up). Future works might support other ways of obtaining a -unique yet persistent id, such as EEPROM serial numbers, etc. - -There need not be any up/down scripts for ipv6, e.g. /etc/ppp/ipv6-up -or /etc/ppp/ipv6-down, to trigger IPv6 neighbor discovery for auto -configuration and routing. The in.ndpd daemon will perform all of the -necessary jobs in the background. /etc/inet/ndpd.conf can be further -customized to enable the machine as an IPv6 router. See the man page -for in.ndpd(1M) and ndpd.conf(4) for details. - -Below is a sample output of "ifconfig -a" with persistent link-local -address. Note the UNNUMBERED flag is set because hme0 and ppp0 both -have identical link-local IPv6 addresses: - -lo0: flags=1000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4> mtu 8232 index 1 - inet 127.0.0.1 netmask ff000000 -hme0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2 - inet 129.146.86.248 netmask ffffff00 broadcast 129.146.86.255 - ether 8:0:20:8d:38:c1 -lo0: flags=2000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv6> mtu 8252 index 1 - inet6 ::1/128 -hme0: flags=2000841<UP,RUNNING,MULTICAST,IPv6> mtu 1500 index 2 - ether 8:0:20:8d:38:c1 - inet6 fe80::a00:20ff:fe8d:38c1/10 -hme0:1: flags=2080841<UP,RUNNING,MULTICAST,ADDRCONF,IPv6> mtu 1500 index 2 - inet6 fec0::56:a00:20ff:fe8d:38c1/64 -hme0:2: flags=2080841<UP,RUNNING,MULTICAST,ADDRCONF,IPv6> mtu 1500 index 2 - inet6 2000::56:a00:20ff:fe8d:38c1/64 -hme0:3: flags=2080841<UP,RUNNING,MULTICAST,ADDRCONF,IPv6> mtu 1500 index 2 - inet6 2::56:a00:20ff:fe8d:38c1/64 -ppp0: flags=10008d1<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST,IPv4> mtu 1500 index 12 - inet 172.16.1.1 --> 172.16.1.2 netmask ffffff00 -ppp0: flags=2202851<UP,POINTOPOINT,RUNNING,MULTICAST,UNNUMBERED,NONUD,IPv6> mtu 1500 index 12 - inet6 fe80::a00:20ff:fe8d:38c1/10 --> fe80::a00:20ff:fe7a:24fb - -Note also that a plumbed ipv6 interface stream will exist throughout -the entire PPP session in the case where the peer rejects IPV6CP, -which further causes the interface state to stay down. Unplumbing will -happen when the daemon exits. This is done by design and is not a bug. - -64-bit Support. -*************** - -This version has been tested under Solaris 7 (and Solaris 8 ) in both -32- and 64-bits environments (Ultra class machines). Installing the -package by executing "make install" will result in additional files -residing in /kernel/drv/sparcv9 and /kernel/strmod/sparcv9 -subdirectories. - -64-bit modules and driver have been compiled and tested using Sun's cc. - -Synchronous Serial Support. -*************************** - -This version has working but limited support for the on-board -synchronous HDLC interfaces. It has been tested with the /dev/se_hdlc -and /dev/zsh drivers. Synchronous mode was tested with a Cisco -router. - -There ppp daemon does not directly support controlling the serial -interface. It relies on the /usr/sbin/syncinit command to initialize -HDLC mode and clocking. - -Some bugs remain: large sized frames are not sent/received properly, -and may be related to the IP mtu. This may be due to bugs in pppd -itself, bugs in Solaris or the serial drivers. The /dev/zsh driver -seems more larger and can send/receive larger frames than the -/dev/se_hdlc driver. There is a confirmed bug with NRZ/NRZI mode in -the /dev/se_hdlc driver, and Solaris patch 104596-11 is needed to -correct it. (However this patch seems to introduce other serial -problems. If you don't apply the patch, the workaround is to change -the nrzi mode to yes or no, whichever works) - -How to start pppd with synchronous support: - -#!/bin/sh - -local=1.1.1.1 # your ip address here -baud=38400 # needed, but ignored by serial driver - -# Change to the correct serial driver/port -#dev=/dev/zsh0 -dev=/dev/se_hdlc0 - -# Change the driver, nrzi mode, speed and clocking to match your setup -# This configuration is for external clocking from the DCE -connect="syncinit se_hdlc0 nrzi=no speed=64000 txc=rxc rxc=rxc" - -/usr/sbin/pppd $dev sync $baud novj noauth $local: connect "$connect" - - -Sample Cisco router config excerpt: - -! -! Cisco router setup as DCE with RS-232 DCE cable -! -! -interface Serial0 - ip address 1.1.1.2 255.255.255.0 - encapsulation ppp - clockrate 64000 - no nrzi-encoding - no shutdown -! - diff --git a/mdk-stage1/ppp/README.sunos4 b/mdk-stage1/ppp/README.sunos4 deleted file mode 100644 index b48aec377..000000000 --- a/mdk-stage1/ppp/README.sunos4 +++ /dev/null @@ -1,62 +0,0 @@ -This file describes the installation process for ppp-2.3 on systems -running SunOS 4.1.x (or the equivalent). - -The STREAMS modules in the sunos4 directory provide kernel support for -PPP on SunOS 4.1.x systems. They have been tested under SunOS 4.1.3 -on a SparcStation 1+. They should work under earlier SunOS 4.1.x -systems, but no guarantees are given. - -These modules are designed to be loaded into the running kernel using -the `modload' command. - - -Installation. -************* - -1. Run the configure script and make the user-level programs and the -kernel modules. - - ./configure - make - -If you wish to compile using gcc instead of cc, edit the -sunos4/Makedefs file and uncomment the line saying "CC = gcc". You -can also change the C compiler options by editing the COPTS -definition. - -2. Install the pppd, pppstats and chat programs and the loadable -module object files (you need to be root to do this): - - make install - -By default, the programs and the loadable module object files go into -/usr/local/etc. Doing `make install' also copies a script called -ppp.INSTALL into /dev, and makes ppp.LOAD, ppp.UNLOAD, ppp.MKDEV and -ppp.RMDEV links to it. You can change the installation directories by -editing sunos4/Makedefs. - -3. Load the ppp modules (you need to be root for this too): - - /dev/ppp.LOAD - -You will want to do this in your /etc/rc.local file once you have -everything installed. I suggest you put something like the following -in /etc/rc.local (or /etc/loadable, if you have one): - - if [ -f /dev/ppp.AUTOLOAD ]; then - /dev/ppp.LOAD - fi - -and then create a /dev/ppp.AUTOLOAD file with the command - - touch /dev/ppp.AUTOLOAD - -It is not advisable to unload the "if_ppp" module, because it creates -network interface units, and SunOS does not provide any way to destroy -network interfaces once created. If you do unload it, the system will -probably crash at some later stage. - -If you have previously had ppp-2.2 installed, you may have statements -in your /etc/rc.local to load the ppp module. You will need to remove -those. Having done this, you will need to reboot to remove the old -ppp module and load the new modules. diff --git a/mdk-stage1/ppp/SETUP b/mdk-stage1/ppp/SETUP deleted file mode 100644 index fb28a2138..000000000 --- a/mdk-stage1/ppp/SETUP +++ /dev/null @@ -1,111 +0,0 @@ - Configuring a PPP link. - -After you have compiled and installed this package, there are some -configuration files which will generally need to be set up. The -pppd(8) man page is the best reference for the full details; this file -outlines the configuration process for the most common case, where -this package is being used to enable a machine to dial an ISP and -connect to the internet. The FAQ and README.linux files also provide -useful information about setting up PPP. - -Dialling an ISP. -**************** - -Usually, an ISP will assign an IP address to your machine, and will -refuse to authenticate itself to you. Some ISPs require a username -and password to be entered before PPP service commences, while others -use PPP authentication (using either the PAP or CHAP protocols). - -The recommended way to set up to dial an ISP is for the system -administrator to create a file under /etc/ppp/peers, named for the ISP -that you will be dialling. For example, suppose the file is called -/etc/ppp/peers/isp. This file would contain something like this: - -cua0 # modem is connected to /dev/cua0 -38400 # run the serial port at 38400 baud -crtscts # use hardware flow control -noauth # don't require the ISP to authenticate itself -defaultroute # use the ISP as our default route -connect '/usr/sbin/chat -v -f /etc/ppp/chat-isp' - -If there are any other pppd options that should apply when calling -this ISP, they can also be placed in this file. - -The /etc/ppp/chat-isp file named in the last line contains the script -for chat(8) to use to dial the ISP and go through any username/ -password authentication required before PPP service starts. Here is -an example (for dialling an Annex terminal server): - -ABORT "NO CARRIER" -ABORT "NO DIALTONE" -ABORT "ERROR" -ABORT "NO ANSWER" -ABORT "BUSY" -ABORT "Username/Password Incorrect" -"" "at" -OK "at&d2&c1" -OK "atdt2479381" -"name:" "^Uusername" -"word:" "\qpassword" -"annex" "ppp" -"Switching to PPP-ppp-Switching to PPP" - -See the chat(8) man page for details of the script. If you are not -sure how the initial dialog with your ISP will go, you could use -a terminal emulator such as kermit or minicom to go through the -process manually. - -If your ISP requires PAP or CHAP authentication, you will have to -create a line in /etc/ppp/pap-secrets or /etc/ppp/chap-secrets like -this: - -myhostname * "password" - -(Replace myhostname with the hostname of your machine.) - -At this point, you can initiate the link with the command: - -/usr/sbin/pppd call isp - -(N.B.: pppd might be installed in a different directory on some -systems). - -This will return to the shell prompt immediately, as pppd will detach -itself from its controlling terminal. (If you don't want it to do -this, use the "nodetach" option.) - -Pppd will log messages describing the progress of the connection and -any errors using the syslog facility (see the syslogd(8) and -syslog.conf(5) man pages). Pppd issues messages using syslog facility -daemon (or local2 if it has been compiled with debugging enabled); -chat uses facility local2. It is often useful to see messages of -priority notice or higher on the console. To see these, find the line -in /etc/syslog.conf which has /dev/console on the right-hand side, and -add `daemon.notice' on the left. This line should end up something -like this: - -*.err;kern.debug;daemon,local2,auth.notice;mail.crit /dev/console - -If you want to see more messages from pppd, request messages of -priority info or higher for facility daemon, like this: - -*.err;kern.debug;daemon.info;local2,auth.notice;mail.crit /dev/console - -It is also useful to add a line like this: - -daemon,local2.debug /etc/ppp/ppp-log - -If you do this, you will need to create an empty /etc/ppp/ppp-log -file. - -After modifying syslog.conf, you will then need to send a HUP signal -to syslogd (or reboot). - -When you wish terminate the PPP link, you should send a TERM or INTR -signal to pppd. Pppd writes its process ID to a file called -ppp<n>.pid in /var/run (or /etc/ppp on older systems such as SunOS or -Ultrix). Here <n> is the PPP interface unit number, which will be 0 -unless you have more than one PPP link running simultaneously. Thus -you can terminate the link with a command like - - kill `cat /var/run/ppp0.pid` diff --git a/mdk-stage1/ppp/chat/Makefile.linux b/mdk-stage1/ppp/chat/Makefile.linux deleted file mode 100644 index 586cbd876..000000000 --- a/mdk-stage1/ppp/chat/Makefile.linux +++ /dev/null @@ -1,27 +0,0 @@ -# $Id$ - -CDEF1= -DTERMIOS # Use the termios structure -CDEF2= -DSIGTYPE=void # Standard definition -CDEF3= -UNO_SLEEP # Use the usleep function -CDEF4= -DFNDELAY=O_NDELAY # Old name value -CDEFS= $(CDEF1) $(CDEF2) $(CDEF3) $(CDEF4) - -CFLAGS= $(RPM_OPT_FLAGS) $(CDEFS) - -INSTALL= install - -all: chat - -chat: chat.o - $(CC) -o chat chat.o - -chat.o: chat.c - $(CC) -c $(CFLAGS) -o chat.o chat.c - -install: chat - mkdir -p $(BINDIR) - $(INSTALL) -s -c chat $(BINDIR) - $(INSTALL) -c -m 644 chat.8 $(MANDIR)/man8 - -clean: - rm -f chat.o chat *~ diff --git a/mdk-stage1/ppp/chat/Makefile.linux.makeopt b/mdk-stage1/ppp/chat/Makefile.linux.makeopt deleted file mode 100644 index 974680a93..000000000 --- a/mdk-stage1/ppp/chat/Makefile.linux.makeopt +++ /dev/null @@ -1,27 +0,0 @@ -# $Id$ - -CDEF1= -DTERMIOS # Use the termios structure -CDEF2= -DSIGTYPE=void # Standard definition -CDEF3= -UNO_SLEEP # Use the usleep function -CDEF4= -DFNDELAY=O_NDELAY # Old name value -CDEFS= $(CDEF1) $(CDEF2) $(CDEF3) $(CDEF4) - -CFLAGS= -O2 -g -pipe $(CDEFS) - -INSTALL= install - -all: chat - -chat: chat.o - $(CC) -o chat chat.o - -chat.o: chat.c - $(CC) -c $(CFLAGS) -o chat.o chat.c - -install: chat - mkdir -p $(BINDIR) - $(INSTALL) -s -c chat $(BINDIR) - $(INSTALL) -c -m 644 chat.8 $(MANDIR)/man8 - -clean: - rm -f chat.o chat *~ diff --git a/mdk-stage1/ppp/chat/Makefile.sol2 b/mdk-stage1/ppp/chat/Makefile.sol2 deleted file mode 100644 index f566cc68b..000000000 --- a/mdk-stage1/ppp/chat/Makefile.sol2 +++ /dev/null @@ -1,19 +0,0 @@ -# -# Makefile for chat on Solaris 2 -# - -include ../solaris/Makedefs - -CFLAGS = $(COPTS) -DNO_USLEEP -DSOL2 - -all: chat - -chat: chat.o - $(CC) -o chat chat.o - -install: chat - $(INSTALL) -f $(BINDIR) chat - $(INSTALL) -m 444 -f $(MANDIR)/man8 chat.8 - -clean: - rm -f *~ *.o chat diff --git a/mdk-stage1/ppp/chat/Makefile.sunos4 b/mdk-stage1/ppp/chat/Makefile.sunos4 deleted file mode 100644 index b3507360e..000000000 --- a/mdk-stage1/ppp/chat/Makefile.sunos4 +++ /dev/null @@ -1,19 +0,0 @@ -# -# Makefile for chat on suns -# - -include ../sunos4/Makedefs - -CFLAGS = -DSUNOS $(COPTS) - -all: chat - -chat: chat.o - $(CC) -o chat chat.o - -install: chat - $(INSTALL) -c chat $(BINDIR)/chat - $(INSTALL) -c -m 444 chat.8 $(MANDIR)/man8/chat.8 - -clean: - rm -f *~ *.o chat diff --git a/mdk-stage1/ppp/chat/chat.8 b/mdk-stage1/ppp/chat/chat.8 deleted file mode 100644 index 8d2029609..000000000 --- a/mdk-stage1/ppp/chat/chat.8 +++ /dev/null @@ -1,515 +0,0 @@ -.\" -*- nroff -*- -.\" manual page [] for chat 1.8 -.\" $Id$ -.\" SH section heading -.\" SS subsection heading -.\" LP paragraph -.\" IP indented paragraph -.\" TP hanging label -.TH CHAT 8 "22 May 1999" "Chat Version 1.22" -.SH NAME -chat \- Automated conversational script with a modem -.SH SYNOPSIS -.B chat -[ -.I options -] -.I script -.SH DESCRIPTION -.LP -The \fIchat\fR program defines a conversational exchange between the -computer and the modem. Its primary purpose is to establish the -connection between the Point-to-Point Protocol Daemon (\fIpppd\fR) and -the remote's \fIpppd\fR process. -.SH OPTIONS -.TP -.B -f \fI<chat file> -Read the chat script from the chat \fIfile\fR. The use of this option -is mutually exclusive with the chat script parameters. The user must -have read access to the file. Multiple lines are permitted in the -file. Space or horizontal tab characters should be used to separate -the strings. -.TP -.B -t \fI<timeout> -Set the timeout for the expected string to be received. If the string -is not received within the time limit then the reply string is not -sent. An alternate reply may be sent or the script will fail if there -is no alternate reply string. A failed script will cause the -\fIchat\fR program to terminate with a non-zero error code. -.TP -.B -r \fI<report file> -Set the file for output of the report strings. If you use the keyword -\fIREPORT\fR, the resulting strings are written to this file. If this -option is not used and you still use \fIREPORT\fR keywords, the -\fIstderr\fR file is used for the report strings. -.TP -.B -e -Start with the echo option turned on. Echoing may also be turned on -or off at specific points in the chat script by using the \fIECHO\fR -keyword. When echoing is enabled, all output from the modem is echoed -to \fIstderr\fR. -.TP -.B -E -Enables environment variable substituion within chat scripts using the -standard \fI$xxx\fR syntax. -.TP -.B -v -Request that the \fIchat\fR script be executed in a verbose mode. The -\fIchat\fR program will then log the execution state of the chat -script as well as all text received from the modem and the output -strings sent to the modem. The default is to log through the SYSLOG; -the logging method may be altered with the -S and -s flags. -.TP -.B -V -Request that the \fIchat\fR script be executed in a stderr verbose -mode. The \fIchat\fR program will then log all text received from the -modem and the output strings sent to the modem to the stderr device. This -device is usually the local console at the station running the chat or -pppd program. -.TP -.B -s -Use stderr. All log messages from '-v' and all error messages will be -sent to stderr. -.TP -.B -S -Do not use the SYSLOG. By default, error messages are sent to the -SYSLOG. The use of -S will prevent both log messages from '-v' and -error messages from being sent to the SYSLOG. -.TP -.B -T \fI<phone number> -Pass in an arbitary string, usually a phone number, that will be -substituted for the \\T substitution metacharacter in a send string. -.TP -.B -U \fI<phone number 2> -Pass in a second string, usually a phone number, that will be -substituted for the \\U substitution metacharacter in a send string. -This is useful when dialing an ISDN terminal adapter that requires two -numbers. -.TP -.B script -If the script is not specified in a file with the \fI-f\fR option then -the script is included as parameters to the \fIchat\fR program. -.SH CHAT SCRIPT -.LP -The \fIchat\fR script defines the communications. -.LP -A script consists of one or more "expect-send" pairs of strings, -separated by spaces, with an optional "subexpect-subsend" string pair, -separated by a dash as in the following example: -.IP -ogin:-BREAK-ogin: ppp ssword: hello2u2 -.LP -This line indicates that the \fIchat\fR program should expect the string -"ogin:". If it fails to receive a login prompt within the time interval -allotted, it is to send a break sequence to the remote and then expect the -string "ogin:". If the first "ogin:" is received then the break sequence is -not generated. -.LP -Once it received the login prompt the \fIchat\fR program will send the -string ppp and then expect the prompt "ssword:". When it receives the -prompt for the password, it will send the password hello2u2. -.LP -A carriage return is normally sent following the reply string. It is not -expected in the "expect" string unless it is specifically requested by using -the \\r character sequence. -.LP -The expect sequence should contain only what is needed to identify the -string. Since it is normally stored on a disk file, it should not contain -variable information. It is generally not acceptable to look for time -strings, network identification strings, or other variable pieces of data as -an expect string. -.LP -To help correct for characters which may be corrupted during the initial -sequence, look for the string "ogin:" rather than "login:". It is possible -that the leading "l" character may be received in error and you may never -find the string even though it was sent by the system. For this reason, -scripts look for "ogin:" rather than "login:" and "ssword:" rather than -"password:". -.LP -A very simple script might look like this: -.IP -ogin: ppp ssword: hello2u2 -.LP -In other words, expect ....ogin:, send ppp, expect ...ssword:, send hello2u2. -.LP -In actual practice, simple scripts are rare. At the vary least, you -should include sub-expect sequences should the original string not be -received. For example, consider the following script: -.IP -ogin:--ogin: ppp ssword: hello2u2 -.LP -This would be a better script than the simple one used earlier. This would look -for the same login: prompt, however, if one was not received, a single -return sequence is sent and then it will look for login: again. Should line -noise obscure the first login prompt then sending the empty line will -usually generate a login prompt again. -.SH COMMENTS -Comments can be embedded in the chat script. A comment is a line which -starts with the \fB#\fR (hash) character in column 1. Such comment -lines are just ignored by the chat program. If a '#' character is to -be expected as the first character of the expect sequence, you should -quote the expect string. -If you want to wait for a prompt that starts with a # (hash) -character, you would have to write something like this: -.IP -# Now wait for the prompt and send logout string -.br -\'# ' logout -.LP - -.SH SENDING DATA FROM A FILE -If the string to send starts with an at sign (@), the rest of the -string is taken to be the name of a file to read to get the string to -send. If the last character of the data read is a newline, it is -removed. The file can be a named pipe (or fifo) instead of a regular -file. This provides a way for \fBchat\fR to communicate with another -program, for example, a program to prompt the user and receive a -password typed in. -.LP - -.SH ABORT STRINGS -Many modems will report the status of the call as a string. These -strings may be \fBCONNECTED\fR or \fBNO CARRIER\fR or \fBBUSY\fR. It -is often desirable to terminate the script should the modem fail to -connect to the remote. The difficulty is that a script would not know -exactly which modem string it may receive. On one attempt, it may -receive \fBBUSY\fR while the next time it may receive \fBNO CARRIER\fR. -.LP -These "abort" strings may be specified in the script using the \fIABORT\fR -sequence. It is written in the script as in the following example: -.IP -ABORT BUSY ABORT 'NO CARRIER' '' ATZ OK ATDT5551212 CONNECT -.LP -This sequence will expect nothing; and then send the string ATZ. The -expected response to this is the string \fIOK\fR. When it receives \fIOK\fR, -the string ATDT5551212 to dial the telephone. The expected string is -\fICONNECT\fR. If the string \fICONNECT\fR is received the remainder of the -script is executed. However, should the modem find a busy telephone, it will -send the string \fIBUSY\fR. This will cause the string to match the abort -character sequence. The script will then fail because it found a match to -the abort string. If it received the string \fINO CARRIER\fR, it will abort -for the same reason. Either string may be received. Either string will -terminate the \fIchat\fR script. -.SH CLR_ABORT STRINGS -This sequence allows for clearing previously set \fBABORT\fR strings. -\fBABORT\fR strings are kept in an array of a pre-determined size (at -compilation time); \fBCLR_ABORT\fR will reclaim the space for cleared -entries so that new strings can use that space. -.SH SAY STRINGS -The \fBSAY\fR directive allows the script to send strings to the user -at the terminal via standard error. If \fBchat\fR is being run by -pppd, and pppd is running as a daemon (detached from its controlling -terminal), standard error will normally be redirected to the file -/etc/ppp/connect-errors. -.LP -\fBSAY\fR strings must be enclosed in single or double quotes. If -carriage return and line feed are needed in the string to be output, -you must explicitely add them to your string. -.LP -The SAY strings could be used to give progress messages in sections of -the script where you want to have 'ECHO OFF' but still let the user -know what is happening. An example is: -.IP -ABORT BUSY -.br -ECHO OFF -.br -SAY "Dialling your ISP...\\n" -.br -\'' ATDT5551212 -.br -TIMEOUT 120 -.br -SAY "Waiting up to 2 minutes for connection ... " -.br -CONNECT '' -.br -SAY "Connected, now logging in ...\n" -.br -ogin: account -.br -ssword: pass -.br -$ \c -SAY "Logged in OK ...\n" -\fIetc ...\fR -.LP -This sequence will only present the SAY strings to the user and all -the details of the script will remain hidden. For example, if the -above script works, the user will see: -.IP -Dialling your ISP... -.br -Waiting up to 2 minutes for connection ... Connected, now logging in ... -.br -Logged in OK ... -.LP - -.SH REPORT STRINGS -A \fBreport\fR string is similar to the ABORT string. The difference -is that the strings, and all characters to the next control character -such as a carriage return, are written to the report file. -.LP -The report strings may be used to isolate the transmission rate of the -modem's connect string and return the value to the chat user. The -analysis of the report string logic occurs in conjunction with the -other string processing such as looking for the expect string. The use -of the same string for a report and abort sequence is probably not -very useful, however, it is possible. -.LP -The report strings to no change the completion code of the program. -.LP -These "report" strings may be specified in the script using the \fIREPORT\fR -sequence. It is written in the script as in the following example: -.IP -REPORT CONNECT ABORT BUSY '' ATDT5551212 CONNECT '' ogin: account -.LP -This sequence will expect nothing; and then send the string -ATDT5551212 to dial the telephone. The expected string is -\fICONNECT\fR. If the string \fICONNECT\fR is received the remainder -of the script is executed. In addition the program will write to the -expect-file the string "CONNECT" plus any characters which follow it -such as the connection rate. -.SH CLR_REPORT STRINGS -This sequence allows for clearing previously set \fBREPORT\fR strings. -\fBREPORT\fR strings are kept in an array of a pre-determined size (at -compilation time); \fBCLR_REPORT\fR will reclaim the space for cleared -entries so that new strings can use that space. -.SH ECHO -The echo options controls whether the output from the modem is echoed -to \fIstderr\fR. This option may be set with the \fI-e\fR option, but -it can also be controlled by the \fIECHO\fR keyword. The "expect-send" -pair \fIECHO\fR \fION\fR enables echoing, and \fIECHO\fR \fIOFF\fR -disables it. With this keyword you can select which parts of the -conversation should be visible. For instance, with the following -script: -.IP -ABORT 'BUSY' -.br -ABORT 'NO CARRIER' -.br -'' ATZ -.br -OK\\r\\n ATD1234567 -.br -\\r\\n \\c -.br -ECHO ON -.br -CONNECT \\c -.br -ogin: account -.LP -all output resulting from modem configuration and dialing is not visible, -but starting with the \fICONNECT\fR (or \fIBUSY\fR) message, everything -will be echoed. -.SH HANGUP -The HANGUP options control whether a modem hangup should be considered -as an error or not. This option is useful in scripts for dialling -systems which will hang up and call your system back. The HANGUP -options can be \fBON\fR or \fBOFF\fR. -.br -When HANGUP is set OFF and the modem hangs up (e.g., after the first -stage of logging in to a callback system), \fBchat\fR will continue -running the script (e.g., waiting for the incoming call and second -stage login prompt). As soon as the incoming call is connected, you -should use the \fBHANGUP ON\fR directive to reinstall normal hang up -signal behavior. Here is an (simple) example script: -.IP -ABORT 'BUSY' -.br -'' ATZ -.br -OK\\r\\n ATD1234567 -.br -\\r\\n \\c -.br -CONNECT \\c -.br -\'Callback login:' call_back_ID -.br -HANGUP OFF -.br -ABORT "Bad Login" -.br -\'Callback Password:' Call_back_password -.br -TIMEOUT 120 -.br -CONNECT \\c -.br -HANGUP ON -.br -ABORT "NO CARRIER" -.br -ogin:--BREAK--ogin: real_account -.br -\fIetc ...\fR -.LP -.SH TIMEOUT -The initial timeout value is 45 seconds. This may be changed using the \fB-t\fR -parameter. -.LP -To change the timeout value for the next expect string, the following -example may be used: -.IP -ATZ OK ATDT5551212 CONNECT TIMEOUT 10 ogin:--ogin: TIMEOUT 5 assword: hello2u2 -.LP -This will change the timeout to 10 seconds when it expects the login: -prompt. The timeout is then changed to 5 seconds when it looks for the -password prompt. -.LP -The timeout, once changed, remains in effect until it is changed again. -.SH SENDING EOT -The special reply string of \fIEOT\fR indicates that the chat program -should send an EOT character to the remote. This is normally the -End-of-file character sequence. A return character is not sent -following the EOT. -.PR -The EOT sequence may be embedded into the send string using the -sequence \fI^D\fR. -.SH GENERATING BREAK -The special reply string of \fIBREAK\fR will cause a break condition -to be sent. The break is a special signal on the transmitter. The -normal processing on the receiver is to change the transmission rate. -It may be used to cycle through the available transmission rates on -the remote until you are able to receive a valid login prompt. -.PR -The break sequence may be embedded into the send string using the -\fI\\K\fR sequence. -.SH ESCAPE SEQUENCES -The expect and reply strings may contain escape sequences. All of the -sequences are legal in the reply string. Many are legal in the expect. -Those which are not valid in the expect sequence are so indicated. -.TP -.B '' -Expects or sends a null string. If you send a null string then it will still -send the return character. This sequence may either be a pair of apostrophe -or quote characters. -.TP -.B \\\\b -represents a backspace character. -.TP -.B \\\\c -Suppresses the newline at the end of the reply string. This is the only -method to send a string without a trailing return character. It must -be at the end of the send string. For example, -the sequence hello\\c will simply send the characters h, e, l, l, o. -.I (not valid in expect.) -.TP -.B \\\\d -Delay for one second. The program uses sleep(1) which will delay to a -maximum of one second. -.I (not valid in expect.) -.TP -.B \\\\K -Insert a BREAK -.I (not valid in expect.) -.TP -.B \\\\n -Send a newline or linefeed character. -.TP -.B \\\\N -Send a null character. The same sequence may be represented by \\0. -.I (not valid in expect.) -.TP -.B \\\\p -Pause for a fraction of a second. The delay is 1/10th of a second. -.I (not valid in expect.) -.TP -.B \\\\q -Suppress writing the string to the SYSLOG file. The string ?????? is -written to the log in its place. -.I (not valid in expect.) -.TP -.B \\\\r -Send or expect a carriage return. -.TP -.B \\\\s -Represents a space character in the string. This may be used when it -is not desirable to quote the strings which contains spaces. The -sequence 'HI TIM' and HI\\sTIM are the same. -.TP -.B \\\\t -Send or expect a tab character. -.TP -.B \\\\T -Send the phone number string as specified with the \fI-T\fR option -.I (not valid in expect.) -.TP -.B \\\\U -Send the phone number 2 string as specified with the \fI-U\fR option -.I (not valid in expect.) -.TP -.B \\\\\\\\ -Send or expect a backslash character. -.TP -.B \\\\ddd -Collapse the octal digits (ddd) into a single ASCII character and send that -character. -.I (some characters are not valid in expect.) -.TP -.B \^^C -Substitute the sequence with the control character represented by C. -For example, the character DC1 (17) is shown as \^^Q. -.I (some characters are not valid in expect.) -.SH ENVIRONMENT VARIABLES -Environment variables are available within chat scripts, if the \fI-E\fR -option was specified in the command line. The metacharacter \fI$\fR is used -to introduce the name of the environment variable to substitute. If the -substition fails, because the requested environment variable is not set, -\fInothing\fR is replaced for the variable. -.SH TERMINATION CODES -The \fIchat\fR program will terminate with the following completion -codes. -.TP -.B 0 -The normal termination of the program. This indicates that the script -was executed without error to the normal conclusion. -.TP -.B 1 -One or more of the parameters are invalid or an expect string was too -large for the internal buffers. This indicates that the program as not -properly executed. -.TP -.B 2 -An error occurred during the execution of the program. This may be due -to a read or write operation failing for some reason or chat receiving -a signal such as SIGINT. -.TP -.B 3 -A timeout event occurred when there was an \fIexpect\fR string without -having a "-subsend" string. This may mean that you did not program the -script correctly for the condition or that some unexpected event has -occurred and the expected string could not be found. -.TP -.B 4 -The first string marked as an \fIABORT\fR condition occurred. -.TP -.B 5 -The second string marked as an \fIABORT\fR condition occurred. -.TP -.B 6 -The third string marked as an \fIABORT\fR condition occurred. -.TP -.B 7 -The fourth string marked as an \fIABORT\fR condition occurred. -.TP -.B ... -The other termination codes are also strings marked as an \fIABORT\fR -condition. -.LP -Using the termination code, it is possible to determine which event -terminated the script. It is possible to decide if the string "BUSY" -was received from the modem as opposed to "NO DIAL TONE". While the -first event may be retried, the second will probably have little -chance of succeeding during a retry. -.SH SEE ALSO -Additional information about \fIchat\fR scripts may be found with UUCP -documentation. The \fIchat\fR script was taken from the ideas proposed -by the scripts used by the \fIuucico\fR program. -.LP -uucico(1), uucp(1) -.SH COPYRIGHT -The \fIchat\fR program is in public domain. This is not the GNU public -license. If it breaks then you get to keep both pieces. diff --git a/mdk-stage1/ppp/chat/chat.c b/mdk-stage1/ppp/chat/chat.c deleted file mode 100644 index 1b22907a8..000000000 --- a/mdk-stage1/ppp/chat/chat.c +++ /dev/null @@ -1,1756 +0,0 @@ -/* - * Chat -- a program for automatic session establishment (i.e. dial - * the phone and log in). - * - * Standard termination codes: - * 0 - successful completion of the script - * 1 - invalid argument, expect string too large, etc. - * 2 - error on an I/O operation or fatal error condition. - * 3 - timeout waiting for a simple string. - * 4 - the first string declared as "ABORT" - * 5 - the second string declared as "ABORT" - * 6 - ... and so on for successive ABORT strings. - * - * This software is in the public domain. - * - * ----------------- - * 22-May-99 added environment substitutuion, enabled with -E switch. - * Andreas Arens <andras@cityweb.de>. - * - * 12-May-99 added a feature to read data to be sent from a file, - * if the send string starts with @. Idea from gpk <gpk@onramp.net>. - * - * added -T and -U option and \T and \U substitution to pass a phone - * number into chat script. Two are needed for some ISDN TA applications. - * Keith Dart <kdart@cisco.com> - * - * - * Added SAY keyword to send output to stderr. - * This allows to turn ECHO OFF and to output specific, user selected, - * text to give progress messages. This best works when stderr - * exists (i.e.: pppd in nodetach mode). - * - * Added HANGUP directives to allow for us to be called - * back. When HANGUP is set to NO, chat will not hangup at HUP signal. - * We rely on timeouts in that case. - * - * Added CLR_ABORT to clear previously set ABORT string. This has been - * dictated by the HANGUP above as "NO CARRIER" (for example) must be - * an ABORT condition until we know the other host is going to close - * the connection for call back. As soon as we have completed the - * first stage of the call back sequence, "NO CARRIER" is a valid, non - * fatal string. As soon as we got called back (probably get "CONNECT"), - * we should re-arm the ABORT "NO CARRIER". Hence the CLR_ABORT command. - * Note that CLR_ABORT packs the abort_strings[] array so that we do not - * have unused entries not being reclaimed. - * - * In the same vein as above, added CLR_REPORT keyword. - * - * Allow for comments. Line starting with '#' are comments and are - * ignored. If a '#' is to be expected as the first character, the - * expect string must be quoted. - * - * - * Francis Demierre <Francis@SwissMail.Com> - * Thu May 15 17:15:40 MET DST 1997 - * - * - * Added -r "report file" switch & REPORT keyword. - * Robert Geer <bgeer@xmission.com> - * - * Added -s "use stderr" and -S "don't use syslog" switches. - * June 18, 1997 - * Karl O. Pinc <kop@meme.com> - * - * - * Added -e "echo" switch & ECHO keyword - * Dick Streefland <dicks@tasking.nl> - * - * - * Considerable updates and modifications by - * Al Longyear <longyear@pobox.com> - * Paul Mackerras <paulus@cs.anu.edu.au> - * - * - * The original author is: - * - * Karl Fox <karl@MorningStar.Com> - * Morning Star Technologies, Inc. - * 1760 Zollinger Road - * Columbus, OH 43221 - * (614)451-1883 - * - */ - -#ifndef __STDC__ -#define const -#endif - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <stdio.h> -#include <ctype.h> -#include <time.h> -#include <fcntl.h> -#include <signal.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <syslog.h> - -#ifndef TERMIO -#undef TERMIOS -#define TERMIOS -#endif - -#ifdef TERMIO -#include <termio.h> -#endif -#ifdef TERMIOS -#include <termios.h> -#endif - -#define STR_LEN 1024 - -#ifndef SIGTYPE -#define SIGTYPE void -#endif - -#undef __P -#undef __V - -#ifdef __STDC__ -#include <stdarg.h> -#define __V(x) x -#define __P(x) x -#else -#include <varargs.h> -#define __V(x) (va_alist) va_dcl -#define __P(x) () -#define const -#endif - -#ifndef O_NONBLOCK -#define O_NONBLOCK O_NDELAY -#endif - -#ifdef SUNOS -extern int sys_nerr; -extern char *sys_errlist[]; -#define memmove(to, from, n) bcopy(from, to, n) -#define strerror(n) ((unsigned)(n) < sys_nerr? sys_errlist[(n)] :\ - "unknown error") -#endif - -/*************** Micro getopt() *********************************************/ -#define OPTION(c,v) (_O&2&&**v?*(*v)++:!c||_O&4?0:(!(_O&1)&& \ - (--c,++v),_O=4,c&&**v=='-'&&v[0][1]?*++*v=='-'\ - &&!v[0][1]?(--c,++v,0):(_O=2,*(*v)++):0)) -#define OPTARG(c,v) (_O&2?**v||(++v,--c)?(_O=1,--c,*v++): \ - (_O=4,(char*)0):(char*)0) -#define OPTONLYARG(c,v) (_O&2&&**v?(_O=1,--c,*v++):(char*)0) -#define ARG(c,v) (c?(--c,*v++):(char*)0) - -static int _O = 0; /* Internal state */ -/*************** Micro getopt() *********************************************/ - -char *program_name; - -#define MAX_ABORTS 50 -#define MAX_REPORTS 50 -#define DEFAULT_CHAT_TIMEOUT 45 - -int echo = 0; -int verbose = 0; -int to_log = 1; -int to_stderr = 0; -int Verbose = 0; -int quiet = 0; -int report = 0; -int use_env = 0; -int exit_code = 0; -FILE* report_fp = (FILE *) 0; -char *report_file = (char *) 0; -char *chat_file = (char *) 0; -char *phone_num = (char *) 0; -char *phone_num2 = (char *) 0; -int timeout = DEFAULT_CHAT_TIMEOUT; - -int have_tty_parameters = 0; - -#ifdef TERMIO -#define term_parms struct termio -#define get_term_param(param) ioctl(0, TCGETA, param) -#define set_term_param(param) ioctl(0, TCSETA, param) -struct termio saved_tty_parameters; -#endif - -#ifdef TERMIOS -#define term_parms struct termios -#define get_term_param(param) tcgetattr(0, param) -#define set_term_param(param) tcsetattr(0, TCSANOW, param) -struct termios saved_tty_parameters; -#endif - -char *abort_string[MAX_ABORTS], *fail_reason = (char *)0, - fail_buffer[50]; -int n_aborts = 0, abort_next = 0, timeout_next = 0, echo_next = 0; -int clear_abort_next = 0; - -char *report_string[MAX_REPORTS] ; -char report_buffer[50] ; -int n_reports = 0, report_next = 0, report_gathering = 0 ; -int clear_report_next = 0; - -int say_next = 0, hup_next = 0; - -void *dup_mem __P((void *b, size_t c)); -void *copy_of __P((char *s)); -void usage __P((void)); -void logf __P((const char *fmt, ...)); -void fatal __P((int code, const char *fmt, ...)); -SIGTYPE sigalrm __P((int signo)); -SIGTYPE sigint __P((int signo)); -SIGTYPE sigterm __P((int signo)); -SIGTYPE sighup __P((int signo)); -void unalarm __P((void)); -void init __P((void)); -void set_tty_parameters __P((void)); -void echo_stderr __P((int)); -void break_sequence __P((void)); -void terminate __P((int status)); -void do_file __P((char *chat_file)); -int get_string __P((register char *string)); -int put_string __P((register char *s)); -int write_char __P((int c)); -int put_char __P((int c)); -int get_char __P((void)); -void chat_send __P((register char *s)); -char *character __P((int c)); -void chat_expect __P((register char *s)); -char *clean __P((register char *s, int sending)); -void break_sequence __P((void)); -void terminate __P((int status)); -void pack_array __P((char **array, int end)); -char *expect_strtok __P((char *, char *)); -int vfmtmsg __P((char *, int, const char *, va_list)); /* vsprintf++ */ - -int main __P((int, char *[])); - -void *dup_mem(b, c) -void *b; -size_t c; -{ - void *ans = malloc (c); - if (!ans) - fatal(2, "memory error!"); - - memcpy (ans, b, c); - return ans; -} - -void *copy_of (s) -char *s; -{ - return dup_mem (s, strlen (s) + 1); -} - -/* - * chat [ -v ] [ -E ] [ -T number ] [ -U number ] [ -t timeout ] [ -f chat-file ] \ - * [ -r report-file ] \ - * [...[[expect[-say[-expect...]] say expect[-say[-expect]] ...]]] - * - * Perform a UUCP-dialer-like chat script on stdin and stdout. - */ -int -main(argc, argv) - int argc; - char **argv; -{ - int option; - char *arg; - - program_name = *argv; - tzset(); - - while ((option = OPTION(argc, argv)) != 0) { - switch (option) { - case 'e': - ++echo; - break; - - case 'E': - ++use_env; - break; - - case 'v': - ++verbose; - break; - - case 'V': - ++Verbose; - break; - - case 's': - ++to_stderr; - break; - - case 'S': - to_log = 0; - break; - - case 'f': - if ((arg = OPTARG(argc, argv)) != NULL) - chat_file = copy_of(arg); - else - usage(); - break; - - case 't': - if ((arg = OPTARG(argc, argv)) != NULL) - timeout = atoi(arg); - else - usage(); - break; - - case 'r': - arg = OPTARG (argc, argv); - if (arg) { - if (report_fp != NULL) - fclose (report_fp); - report_file = copy_of (arg); - report_fp = fopen (report_file, "a"); - if (report_fp != NULL) { - if (verbose) - fprintf (report_fp, "Opening \"%s\"...\n", - report_file); - report = 1; - } - } - break; - - case 'T': - if ((arg = OPTARG(argc, argv)) != NULL) - phone_num = copy_of(arg); - else - usage(); - break; - - case 'U': - if ((arg = OPTARG(argc, argv)) != NULL) - phone_num2 = copy_of(arg); - else - usage(); - break; - - default: - usage(); - break; - } - } -/* - * Default the report file to the stderr location - */ - if (report_fp == NULL) - report_fp = stderr; - - if (to_log) { -#ifdef ultrix - openlog("chat", LOG_PID); -#else - openlog("chat", LOG_PID | LOG_NDELAY, LOG_LOCAL2); - - if (verbose) - setlogmask(LOG_UPTO(LOG_INFO)); - else - setlogmask(LOG_UPTO(LOG_WARNING)); -#endif - } - - init(); - - if (chat_file != NULL) { - arg = ARG(argc, argv); - if (arg != NULL) - usage(); - else - do_file (chat_file); - } else { - while ((arg = ARG(argc, argv)) != NULL) { - chat_expect(arg); - - if ((arg = ARG(argc, argv)) != NULL) - chat_send(arg); - } - } - - terminate(0); - return 0; -} - -/* - * Process a chat script when read from a file. - */ - -void do_file (chat_file) -char *chat_file; -{ - int linect, sendflg; - char *sp, *arg, quote; - char buf [STR_LEN]; - FILE *cfp; - - cfp = fopen (chat_file, "r"); - if (cfp == NULL) - fatal(1, "%s -- open failed: %m", chat_file); - - linect = 0; - sendflg = 0; - - while (fgets(buf, STR_LEN, cfp) != NULL) { - sp = strchr (buf, '\n'); - if (sp) - *sp = '\0'; - - linect++; - sp = buf; - - /* lines starting with '#' are comments. If a real '#' - is to be expected, it should be quoted .... */ - if ( *sp == '#' ) - continue; - - while (*sp != '\0') { - if (*sp == ' ' || *sp == '\t') { - ++sp; - continue; - } - - if (*sp == '"' || *sp == '\'') { - quote = *sp++; - arg = sp; - while (*sp != quote) { - if (*sp == '\0') - fatal(1, "unterminated quote (line %d)", linect); - - if (*sp++ == '\\') { - if (*sp != '\0') - ++sp; - } - } - } - else { - arg = sp; - while (*sp != '\0' && *sp != ' ' && *sp != '\t') - ++sp; - } - - if (*sp != '\0') - *sp++ = '\0'; - - if (sendflg) - chat_send (arg); - else - chat_expect (arg); - sendflg = !sendflg; - } - } - fclose (cfp); -} - -/* - * We got an error parsing the command line. - */ -void usage() -{ - fprintf(stderr, "\ -Usage: %s [-e] [-E] [-v] [-V] [-t timeout] [-r report-file]\n\ - [-T phone-number] [-U phone-number2] {-f chat-file | chat-script}\n", program_name); - exit(1); -} - -char line[1024]; - -/* - * Send a message to syslog and/or stderr. - */ -void logf __V((const char *fmt, ...)) -{ - va_list args; - -#ifdef __STDC__ - va_start(args, fmt); -#else - char *fmt; - va_start(args); - fmt = va_arg(args, char *); -#endif - - vfmtmsg(line, sizeof(line), fmt, args); - if (to_log) - syslog(LOG_INFO, "%s", line); - if (to_stderr) - fprintf(stderr, "%s\n", line); -} - -/* - * Print an error message and terminate. - */ - -void fatal __V((int code, const char *fmt, ...)) -{ - va_list args; - -#ifdef __STDC__ - va_start(args, fmt); -#else - int code; - char *fmt; - va_start(args); - code = va_arg(args, int); - fmt = va_arg(args, char *); -#endif - - vfmtmsg(line, sizeof(line), fmt, args); - if (to_log) - syslog(LOG_ERR, "%s", line); - if (to_stderr) - fprintf(stderr, "%s\n", line); - terminate(code); -} - -int alarmed = 0; - -SIGTYPE sigalrm(signo) -int signo; -{ - int flags; - - alarm(1); - alarmed = 1; /* Reset alarm to avoid race window */ - signal(SIGALRM, sigalrm); /* that can cause hanging in read() */ - - if ((flags = fcntl(0, F_GETFL, 0)) == -1) - fatal(2, "Can't get file mode flags on stdin: %m"); - - if (fcntl(0, F_SETFL, flags | O_NONBLOCK) == -1) - fatal(2, "Can't set file mode flags on stdin: %m"); - - if (verbose) - logf("alarm"); -} - -void unalarm() -{ - int flags; - - if ((flags = fcntl(0, F_GETFL, 0)) == -1) - fatal(2, "Can't get file mode flags on stdin: %m"); - - if (fcntl(0, F_SETFL, flags & ~O_NONBLOCK) == -1) - fatal(2, "Can't set file mode flags on stdin: %m"); -} - -SIGTYPE sigint(signo) -int signo; -{ - fatal(2, "SIGINT"); -} - -SIGTYPE sigterm(signo) -int signo; -{ - fatal(2, "SIGTERM"); -} - -SIGTYPE sighup(signo) -int signo; -{ - fatal(2, "SIGHUP"); -} - -void init() -{ - signal(SIGINT, sigint); - signal(SIGTERM, sigterm); - signal(SIGHUP, sighup); - - set_tty_parameters(); - signal(SIGALRM, sigalrm); - alarm(0); - alarmed = 0; -} - -void set_tty_parameters() -{ -#if defined(get_term_param) - term_parms t; - - if (get_term_param (&t) < 0) - fatal(2, "Can't get terminal parameters: %m"); - - saved_tty_parameters = t; - have_tty_parameters = 1; - - t.c_iflag |= IGNBRK | ISTRIP | IGNPAR; - t.c_oflag = 0; - t.c_lflag = 0; - t.c_cc[VERASE] = - t.c_cc[VKILL] = 0; - t.c_cc[VMIN] = 1; - t.c_cc[VTIME] = 0; - - if (set_term_param (&t) < 0) - fatal(2, "Can't set terminal parameters: %m"); -#endif -} - -void break_sequence() -{ -#ifdef TERMIOS - tcsendbreak (0, 0); -#endif -} - -void terminate(status) -int status; -{ - static int terminating = 0; - - if (terminating) - exit(status); - terminating = 1; - echo_stderr(-1); -/* - * Allow the last of the report string to be gathered before we terminate. - */ - if (report_gathering) { - int c, rep_len; - - rep_len = strlen(report_buffer); - while (rep_len + 1 <= sizeof(report_buffer)) { - alarm(1); - c = get_char(); - alarm(0); - if (c < 0 || iscntrl(c)) - break; - report_buffer[rep_len] = c; - ++rep_len; - } - report_buffer[rep_len] = 0; - fprintf (report_fp, "chat: %s\n", report_buffer); - } - if (report_file != (char *) 0 && report_fp != (FILE *) NULL) { - if (verbose) - fprintf (report_fp, "Closing \"%s\".\n", report_file); - fclose (report_fp); - report_fp = (FILE *) NULL; - } - -#if defined(get_term_param) - if (have_tty_parameters) { - if (set_term_param (&saved_tty_parameters) < 0) - fatal(2, "Can't restore terminal parameters: %m"); - } -#endif - - exit(status); -} - -/* - * 'Clean up' this string. - */ -char *clean(s, sending) -register char *s; -int sending; /* set to 1 when sending (putting) this string. */ -{ - char temp[STR_LEN], env_str[STR_LEN], cur_chr; - register char *s1, *phchar; - int add_return = sending; -#define isoctal(chr) (((chr) >= '0') && ((chr) <= '7')) -#define isalnumx(chr) ((((chr) >= '0') && ((chr) <= '9')) \ - || (((chr) >= 'a') && ((chr) <= 'z')) \ - || (((chr) >= 'A') && ((chr) <= 'Z')) \ - || (chr) == '_') - - s1 = temp; - while (*s) { - cur_chr = *s++; - if (cur_chr == '^') { - cur_chr = *s++; - if (cur_chr == '\0') { - *s1++ = '^'; - break; - } - cur_chr &= 0x1F; - if (cur_chr != 0) { - *s1++ = cur_chr; - } - continue; - } - - if (use_env && cur_chr == '$') { /* ARI */ - phchar = env_str; - while (isalnumx(*s)) - *phchar++ = *s++; - *phchar = '\0'; - phchar = getenv(env_str); - if (phchar) - while (*phchar) - *s1++ = *phchar++; - continue; - } - - if (cur_chr != '\\') { - *s1++ = cur_chr; - continue; - } - - cur_chr = *s++; - if (cur_chr == '\0') { - if (sending) { - *s1++ = '\\'; - *s1++ = '\\'; - } - break; - } - - switch (cur_chr) { - case 'b': - *s1++ = '\b'; - break; - - case 'c': - if (sending && *s == '\0') - add_return = 0; - else - *s1++ = cur_chr; - break; - - case '\\': - case 'K': - case 'p': - case 'd': - if (sending) - *s1++ = '\\'; - *s1++ = cur_chr; - break; - - case 'T': - if (sending && phone_num) { - for (phchar = phone_num; *phchar != '\0'; phchar++) - *s1++ = *phchar; - } - else { - *s1++ = '\\'; - *s1++ = 'T'; - } - break; - - case 'U': - if (sending && phone_num2) { - for (phchar = phone_num2; *phchar != '\0'; phchar++) - *s1++ = *phchar; - } - else { - *s1++ = '\\'; - *s1++ = 'U'; - } - break; - - case 'q': - quiet = 1; - break; - - case 'r': - *s1++ = '\r'; - break; - - case 'n': - *s1++ = '\n'; - break; - - case 's': - *s1++ = ' '; - break; - - case 't': - *s1++ = '\t'; - break; - - case 'N': - if (sending) { - *s1++ = '\\'; - *s1++ = '\0'; - } - else - *s1++ = 'N'; - break; - - case '$': /* ARI */ - if (use_env) { - *s1++ = cur_chr; - break; - } - /* FALL THROUGH */ - - default: - if (isoctal (cur_chr)) { - cur_chr &= 0x07; - if (isoctal (*s)) { - cur_chr <<= 3; - cur_chr |= *s++ - '0'; - if (isoctal (*s)) { - cur_chr <<= 3; - cur_chr |= *s++ - '0'; - } - } - - if (cur_chr != 0 || sending) { - if (sending && (cur_chr == '\\' || cur_chr == 0)) - *s1++ = '\\'; - *s1++ = cur_chr; - } - break; - } - - if (sending) - *s1++ = '\\'; - *s1++ = cur_chr; - break; - } - } - - if (add_return) - *s1++ = '\r'; - - *s1++ = '\0'; /* guarantee closure */ - *s1++ = '\0'; /* terminate the string */ - return dup_mem (temp, (size_t) (s1 - temp)); /* may have embedded nuls */ -} - -/* - * A modified version of 'strtok'. This version skips \ sequences. - */ - -char *expect_strtok (s, term) - char *s, *term; -{ - static char *str = ""; - int escape_flag = 0; - char *result; - -/* - * If a string was specified then do initial processing. - */ - if (s) - str = s; - -/* - * If this is the escape flag then reset it and ignore the character. - */ - if (*str) - result = str; - else - result = (char *) 0; - - while (*str) { - if (escape_flag) { - escape_flag = 0; - ++str; - continue; - } - - if (*str == '\\') { - ++str; - escape_flag = 1; - continue; - } - -/* - * If this is not in the termination string, continue. - */ - if (strchr (term, *str) == (char *) 0) { - ++str; - continue; - } - -/* - * This is the terminator. Mark the end of the string and stop. - */ - *str++ = '\0'; - break; - } - return (result); -} - -/* - * Process the expect string - */ - -void chat_expect (s) -char *s; -{ - char *expect; - char *reply; - - if (strcmp(s, "HANGUP") == 0) { - ++hup_next; - return; - } - - if (strcmp(s, "ABORT") == 0) { - ++abort_next; - return; - } - - if (strcmp(s, "CLR_ABORT") == 0) { - ++clear_abort_next; - return; - } - - if (strcmp(s, "REPORT") == 0) { - ++report_next; - return; - } - - if (strcmp(s, "CLR_REPORT") == 0) { - ++clear_report_next; - return; - } - - if (strcmp(s, "TIMEOUT") == 0) { - ++timeout_next; - return; - } - - if (strcmp(s, "ECHO") == 0) { - ++echo_next; - return; - } - - if (strcmp(s, "SAY") == 0) { - ++say_next; - return; - } - -/* - * Fetch the expect and reply string. - */ - for (;;) { - expect = expect_strtok (s, "-"); - s = (char *) 0; - - if (expect == (char *) 0) - return; - - reply = expect_strtok (s, "-"); - -/* - * Handle the expect string. If successful then exit. - */ - if (get_string (expect)) - return; - -/* - * If there is a sub-reply string then send it. Otherwise any condition - * is terminal. - */ - if (reply == (char *) 0 || exit_code != 3) - break; - - chat_send (reply); - } - -/* - * The expectation did not occur. This is terminal. - */ - if (fail_reason) - logf("Failed (%s)", fail_reason); - else - logf("Failed"); - terminate(exit_code); -} - -/* - * Translate the input character to the appropriate string for printing - * the data. - */ - -char *character(c) -int c; -{ - static char string[10]; - char *meta; - - meta = (c & 0x80) ? "M-" : ""; - c &= 0x7F; - - if (c < 32) - sprintf(string, "%s^%c", meta, (int)c + '@'); - else if (c == 127) - sprintf(string, "%s^?", meta); - else - sprintf(string, "%s%c", meta, c); - - return (string); -} - -/* - * process the reply string - */ -void chat_send (s) -register char *s; -{ - char file_data[STR_LEN]; - - if (say_next) { - say_next = 0; - s = clean(s, 1); - write(2, s, strlen(s)); - free(s); - return; - } - - if (hup_next) { - hup_next = 0; - if (strcmp(s, "OFF") == 0) - signal(SIGHUP, SIG_IGN); - else - signal(SIGHUP, sighup); - return; - } - - if (echo_next) { - echo_next = 0; - echo = (strcmp(s, "ON") == 0); - return; - } - - if (abort_next) { - char *s1; - - abort_next = 0; - - if (n_aborts >= MAX_ABORTS) - fatal(2, "Too many ABORT strings"); - - s1 = clean(s, 0); - - if (strlen(s1) > strlen(s) - || strlen(s1) + 1 > sizeof(fail_buffer)) - fatal(1, "Illegal or too-long ABORT string ('%v')", s); - - abort_string[n_aborts++] = s1; - - if (verbose) - logf("abort on (%v)", s); - return; - } - - if (clear_abort_next) { - char *s1; - int i; - int old_max; - int pack = 0; - - clear_abort_next = 0; - - s1 = clean(s, 0); - - if (strlen(s1) > strlen(s) - || strlen(s1) + 1 > sizeof(fail_buffer)) - fatal(1, "Illegal or too-long CLR_ABORT string ('%v')", s); - - old_max = n_aborts; - for (i=0; i < n_aborts; i++) { - if ( strcmp(s1,abort_string[i]) == 0 ) { - free(abort_string[i]); - abort_string[i] = NULL; - pack++; - n_aborts--; - if (verbose) - logf("clear abort on (%v)", s); - } - } - free(s1); - if (pack) - pack_array(abort_string,old_max); - return; - } - - if (report_next) { - char *s1; - - report_next = 0; - if (n_reports >= MAX_REPORTS) - fatal(2, "Too many REPORT strings"); - - s1 = clean(s, 0); - - if (strlen(s1) > strlen(s) || strlen(s1) > sizeof fail_buffer - 1) - fatal(1, "Illegal or too-long REPORT string ('%v')", s); - - report_string[n_reports++] = s1; - - if (verbose) - logf("report (%v)", s); - return; - } - - if (clear_report_next) { - char *s1; - int i; - int old_max; - int pack = 0; - - clear_report_next = 0; - - s1 = clean(s, 0); - - if (strlen(s1) > strlen(s) || strlen(s1) > sizeof fail_buffer - 1) - fatal(1, "Illegal or too-long REPORT string ('%v')", s); - - old_max = n_reports; - for (i=0; i < n_reports; i++) { - if ( strcmp(s1,report_string[i]) == 0 ) { - free(report_string[i]); - report_string[i] = NULL; - pack++; - n_reports--; - if (verbose) - logf("clear report (%v)", s); - } - } - free(s1); - if (pack) - pack_array(report_string,old_max); - - return; - } - - if (timeout_next) { - timeout_next = 0; - timeout = atoi(s); - - if (timeout <= 0) - timeout = DEFAULT_CHAT_TIMEOUT; - - if (verbose) - logf("timeout set to %d seconds", timeout); - - return; - } - - /* - * The syntax @filename means read the string to send from the - * file `filename'. - */ - if (s[0] == '@') { - /* skip the @ and any following white-space */ - char *fn = s; - while (*++fn == ' ' || *fn == '\t') - ; - - if (*fn != 0) { - FILE *f; - int n = 0; - - /* open the file and read until STR_LEN-1 bytes or end-of-file */ - f = fopen(fn, "r"); - if (f == NULL) - fatal(1, "%s -- open failed: %m", fn); - while (n < STR_LEN - 1) { - int nr = fread(&file_data[n], 1, STR_LEN - 1 - n, f); - if (nr < 0) - fatal(1, "%s -- read error", fn); - if (nr == 0) - break; - n += nr; - } - fclose(f); - - /* use the string we got as the string to send, - but trim off the final newline if any. */ - if (n > 0 && file_data[n-1] == '\n') - --n; - file_data[n] = 0; - s = file_data; - } - } - - if (strcmp(s, "EOT") == 0) - s = "^D\\c"; - else if (strcmp(s, "BREAK") == 0) - s = "\\K\\c"; - - if (!put_string(s)) - fatal(1, "Failed"); -} - -int get_char() -{ - int status; - char c; - - status = read(0, &c, 1); - - switch (status) { - case 1: - return ((int)c & 0x7F); - - default: - logf("warning: read() on stdin returned %d", status); - - case -1: - if ((status = fcntl(0, F_GETFL, 0)) == -1) - fatal(2, "Can't get file mode flags on stdin: %m"); - - if (fcntl(0, F_SETFL, status & ~O_NONBLOCK) == -1) - fatal(2, "Can't set file mode flags on stdin: %m"); - - return (-1); - } -} - -int put_char(c) -int c; -{ - int status; - char ch = c; - - usleep(10000); /* inter-character typing delay (?) */ - - status = write(1, &ch, 1); - - switch (status) { - case 1: - return (0); - - default: - logf("warning: write() on stdout returned %d", status); - - case -1: - if ((status = fcntl(0, F_GETFL, 0)) == -1) - fatal(2, "Can't get file mode flags on stdin, %m"); - - if (fcntl(0, F_SETFL, status & ~O_NONBLOCK) == -1) - fatal(2, "Can't set file mode flags on stdin: %m"); - - return (-1); - } -} - -int write_char (c) -int c; -{ - if (alarmed || put_char(c) < 0) { - alarm(0); - alarmed = 0; - - if (verbose) { - if (errno == EINTR || errno == EWOULDBLOCK) - logf(" -- write timed out"); - else - logf(" -- write failed: %m"); - } - return (0); - } - return (1); -} - -int put_string (s) -register char *s; -{ - quiet = 0; - s = clean(s, 1); - - if (verbose) { - if (quiet) - logf("send (??????)"); - else - logf("send (%v)", s); - } - - alarm(timeout); alarmed = 0; - - while (*s) { - register char c = *s++; - - if (c != '\\') { - if (!write_char (c)) - return 0; - continue; - } - - c = *s++; - switch (c) { - case 'd': - sleep(1); - break; - - case 'K': - break_sequence(); - break; - - case 'p': - usleep(10000); /* 1/100th of a second (arg is microseconds) */ - break; - - default: - if (!write_char (c)) - return 0; - break; - } - } - - alarm(0); - alarmed = 0; - return (1); -} - -/* - * Echo a character to stderr. - * When called with -1, a '\n' character is generated when - * the cursor is not at the beginning of a line. - */ -void echo_stderr(n) -int n; -{ - static int need_lf; - char *s; - - switch (n) { - case '\r': /* ignore '\r' */ - break; - case -1: - if (need_lf == 0) - break; - /* fall through */ - case '\n': - write(2, "\n", 1); - need_lf = 0; - break; - default: - s = character(n); - write(2, s, strlen(s)); - need_lf = 1; - break; - } -} - -/* - * 'Wait for' this string to appear on this file descriptor. - */ -int get_string(string) -register char *string; -{ - char temp[STR_LEN]; - int c, printed = 0, len, minlen; - register char *s = temp, *end = s + STR_LEN; - char *logged = temp; - - fail_reason = (char *)0; - string = clean(string, 0); - len = strlen(string); - minlen = (len > sizeof(fail_buffer)? len: sizeof(fail_buffer)) - 1; - - if (verbose) - logf("expect (%v)", string); - - if (len > STR_LEN) { - logf("expect string is too long"); - exit_code = 1; - return 0; - } - - if (len == 0) { - if (verbose) - logf("got it"); - return (1); - } - - alarm(timeout); - alarmed = 0; - - while ( ! alarmed && (c = get_char()) >= 0) { - int n, abort_len, report_len; - - if (echo) - echo_stderr(c); - if (verbose && c == '\n') { - if (s == logged) - logf(""); /* blank line */ - else - logf("%0.*v", s - logged, logged); - logged = s + 1; - } - - *s++ = c; - - if (verbose && s >= logged + 80) { - logf("%0.*v", s - logged, logged); - logged = s; - } - - if (Verbose) { - if (c == '\n') - fputc( '\n', stderr ); - else if (c != '\r') - fprintf( stderr, "%s", character(c) ); - } - - if (!report_gathering) { - for (n = 0; n < n_reports; ++n) { - if ((report_string[n] != (char*) NULL) && - s - temp >= (report_len = strlen(report_string[n])) && - strncmp(s - report_len, report_string[n], report_len) == 0) { - time_t time_now = time ((time_t*) NULL); - struct tm* tm_now = localtime (&time_now); - - strftime (report_buffer, 20, "%b %d %H:%M:%S ", tm_now); - strcat (report_buffer, report_string[n]); - - report_string[n] = (char *) NULL; - report_gathering = 1; - break; - } - } - } - else { - if (!iscntrl (c)) { - int rep_len = strlen (report_buffer); - report_buffer[rep_len] = c; - report_buffer[rep_len + 1] = '\0'; - } - else { - report_gathering = 0; - fprintf (report_fp, "chat: %s\n", report_buffer); - } - } - - if (s - temp >= len && - c == string[len - 1] && - strncmp(s - len, string, len) == 0) { - if (verbose) { - if (s > logged) - logf("%0.*v", s - logged, logged); - logf(" -- got it\n"); - } - - alarm(0); - alarmed = 0; - return (1); - } - - for (n = 0; n < n_aborts; ++n) { - if (s - temp >= (abort_len = strlen(abort_string[n])) && - strncmp(s - abort_len, abort_string[n], abort_len) == 0) { - if (verbose) { - if (s > logged) - logf("%0.*v", s - logged, logged); - logf(" -- failed"); - } - - alarm(0); - alarmed = 0; - exit_code = n + 4; - strcpy(fail_reason = fail_buffer, abort_string[n]); - return (0); - } - } - - if (s >= end) { - if (logged < s - minlen) { - if (verbose) - logf("%0.*v", s - logged, logged); - logged = s; - } - s -= minlen; - memmove(temp, s, minlen); - logged = temp + (logged - s); - s = temp + minlen; - } - - if (alarmed && verbose) - logf("warning: alarm synchronization problem"); - } - - alarm(0); - - if (verbose && printed) { - if (alarmed) - logf(" -- read timed out"); - else - logf(" -- read failed: %m"); - } - - exit_code = 3; - alarmed = 0; - return (0); -} - -/* - * Gross kludge to handle Solaris versions >= 2.6 having usleep. - */ -#ifdef SOL2 -#include <sys/param.h> -#if MAXUID > 65536 /* then this is Solaris 2.6 or later */ -#undef NO_USLEEP -#endif -#endif /* SOL2 */ - -#ifdef NO_USLEEP -#include <sys/types.h> -#include <sys/time.h> - -/* - usleep -- support routine for 4.2BSD system call emulations - last edit: 29-Oct-1984 D A Gwyn - */ - -extern int select(); - -int -usleep( usec ) /* returns 0 if ok, else -1 */ - long usec; /* delay in microseconds */ -{ - static struct { /* `timeval' */ - long tv_sec; /* seconds */ - long tv_usec; /* microsecs */ - } delay; /* _select() timeout */ - - delay.tv_sec = usec / 1000000L; - delay.tv_usec = usec % 1000000L; - - return select(0, (long *)0, (long *)0, (long *)0, &delay); -} -#endif - -void -pack_array (array, end) - char **array; /* The address of the array of string pointers */ - int end; /* The index of the next free entry before CLR_ */ -{ - int i, j; - - for (i = 0; i < end; i++) { - if (array[i] == NULL) { - for (j = i+1; j < end; ++j) - if (array[j] != NULL) - array[i++] = array[j]; - for (; i < end; ++i) - array[i] = NULL; - break; - } - } -} - -/* - * vfmtmsg - format a message into a buffer. Like vsprintf except we - * also specify the length of the output buffer, and we handle the - * %m (error message) format. - * Doesn't do floating-point formats. - * Returns the number of chars put into buf. - */ -#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) - -int -vfmtmsg(buf, buflen, fmt, args) - char *buf; - int buflen; - const char *fmt; - va_list args; -{ - int c, i, n; - int width, prec, fillch; - int base, len, neg, quoted; - unsigned long val = 0; - char *str, *buf0; - const char *f; - unsigned char *p; - char num[32]; - static char hexchars[] = "0123456789abcdef"; - - buf0 = buf; - --buflen; - while (buflen > 0) { - for (f = fmt; *f != '%' && *f != 0; ++f) - ; - if (f > fmt) { - len = f - fmt; - if (len > buflen) - len = buflen; - memcpy(buf, fmt, len); - buf += len; - buflen -= len; - fmt = f; - } - if (*fmt == 0) - break; - c = *++fmt; - width = prec = 0; - fillch = ' '; - if (c == '0') { - fillch = '0'; - c = *++fmt; - } - if (c == '*') { - width = va_arg(args, int); - c = *++fmt; - } else { - while (isdigit(c)) { - width = width * 10 + c - '0'; - c = *++fmt; - } - } - if (c == '.') { - c = *++fmt; - if (c == '*') { - prec = va_arg(args, int); - c = *++fmt; - } else { - while (isdigit(c)) { - prec = prec * 10 + c - '0'; - c = *++fmt; - } - } - } - str = 0; - base = 0; - neg = 0; - ++fmt; - switch (c) { - case 'd': - i = va_arg(args, int); - if (i < 0) { - neg = 1; - val = -i; - } else - val = i; - base = 10; - break; - case 'o': - val = va_arg(args, unsigned int); - base = 8; - break; - case 'x': - val = va_arg(args, unsigned int); - base = 16; - break; - case 'p': - val = (unsigned long) va_arg(args, void *); - base = 16; - neg = 2; - break; - case 's': - str = va_arg(args, char *); - break; - case 'c': - num[0] = va_arg(args, int); - num[1] = 0; - str = num; - break; - case 'm': - str = strerror(errno); - break; - case 'v': /* "visible" string */ - case 'q': /* quoted string */ - quoted = c == 'q'; - p = va_arg(args, unsigned char *); - if (fillch == '0' && prec > 0) { - n = prec; - } else { - n = strlen((char *)p); - if (prec > 0 && prec < n) - n = prec; - } - while (n > 0 && buflen > 0) { - c = *p++; - --n; - if (!quoted && c >= 0x80) { - OUTCHAR('M'); - OUTCHAR('-'); - c -= 0x80; - } - if (quoted && (c == '"' || c == '\\')) - OUTCHAR('\\'); - if (c < 0x20 || (0x7f <= c && c < 0xa0)) { - if (quoted) { - OUTCHAR('\\'); - switch (c) { - case '\t': OUTCHAR('t'); break; - case '\n': OUTCHAR('n'); break; - case '\b': OUTCHAR('b'); break; - case '\f': OUTCHAR('f'); break; - default: - OUTCHAR('x'); - OUTCHAR(hexchars[c >> 4]); - OUTCHAR(hexchars[c & 0xf]); - } - } else { - if (c == '\t') - OUTCHAR(c); - else { - OUTCHAR('^'); - OUTCHAR(c ^ 0x40); - } - } - } else - OUTCHAR(c); - } - continue; - default: - *buf++ = '%'; - if (c != '%') - --fmt; /* so %z outputs %z etc. */ - --buflen; - continue; - } - if (base != 0) { - str = num + sizeof(num); - *--str = 0; - while (str > num + neg) { - *--str = hexchars[val % base]; - val = val / base; - if (--prec <= 0 && val == 0) - break; - } - switch (neg) { - case 1: - *--str = '-'; - break; - case 2: - *--str = 'x'; - *--str = '0'; - break; - } - len = num + sizeof(num) - 1 - str; - } else { - len = strlen(str); - if (prec > 0 && len > prec) - len = prec; - } - if (width > 0) { - if (width > buflen) - width = buflen; - if ((n = width - len) > 0) { - buflen -= n; - for (; n > 0; --n) - *buf++ = fillch; - } - } - if (len > buflen) - len = buflen; - memcpy(buf, str, len); - buf += len; - buflen -= len; - } - *buf = 0; - return buf - buf0; -} diff --git a/mdk-stage1/ppp/common/zlib.c b/mdk-stage1/ppp/common/zlib.c deleted file mode 100644 index 503076886..000000000 --- a/mdk-stage1/ppp/common/zlib.c +++ /dev/null @@ -1,5376 +0,0 @@ -/* - * This file is derived from various .h and .c files from the zlib-1.0.4 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. See zlib.h for conditions of - * distribution and use. - * - * Changes that have been made include: - * - added Z_PACKET_FLUSH (see zlib.h for details) - * - added inflateIncomp and deflateOutputPending - * - allow strm->next_out to be NULL, meaning discard the output - * - * $Id$ - */ - -/* - * ==FILEVERSION 971210== - * - * This marker is used by the Linux installation script to determine - * whether an up-to-date version of this file is already installed. - */ - -#define NO_DUMMY_DECL -#define NO_ZCFUNCS -#define MY_ZCALLOC - -#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL)) -#define inflate inflate_ppp /* FreeBSD already has an inflate :-( */ -#endif - - -/* +++ zutil.h */ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-1996 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* From: zutil.h,v 1.16 1996/07/24 13:41:13 me Exp $ */ - -#ifndef _Z_UTIL_H -#define _Z_UTIL_H - -#include "zlib.h" - -#if defined(KERNEL) || defined(_KERNEL) -/* Assume this is a *BSD or SVR4 kernel */ -#include <sys/types.h> -#include <sys/time.h> -#include <sys/systm.h> -#undef u -# define HAVE_MEMCPY -# define memcpy(d, s, n) bcopy((s), (d), (n)) -# define memset(d, v, n) bzero((d), (n)) -# define memcmp bcmp - -#else -#if defined(__KERNEL__) -/* Assume this is a Linux kernel */ -#include <linux/string.h> -#define HAVE_MEMCPY - -#else /* not kernel */ - -#if defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS) -# include <stddef.h> -# include <errno.h> -#else - extern int errno; -#endif -#ifdef STDC -# include <string.h> -# include <stdlib.h> -#endif -#endif /* __KERNEL__ */ -#endif /* _KERNEL || KERNEL */ - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#ifdef MSDOS -# define OS_CODE 0x00 -# ifdef __TURBOC__ -# include <alloc.h> -# else /* MSC or DJGPP */ -# include <malloc.h> -# endif -#endif - -#ifdef OS2 -# define OS_CODE 0x06 -#endif - -#ifdef WIN32 /* Window 95 & Windows NT */ -# define OS_CODE 0x0b -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define FOPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#ifdef AMIGA -# define OS_CODE 0x01 -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 -#endif - -#ifdef MACOS -# define OS_CODE 0x07 -#endif - -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0F -#endif - -#ifdef TOPS20 -# define OS_CODE 0x0a -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - - /* Common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef FOPEN -# define FOPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#ifdef HAVE_STRERROR - extern char *strerror OF((int)); -# define zstrerror(errnum) strerror(errnum) -#else -# define zstrerror(errnum) "" -#endif - -#if defined(pyr) -# define NO_MEMCPY -#endif -#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(_MSC_VER) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - extern void zmemcpy OF((Bytef* dest, Bytef* source, uInt len)); - extern int zmemcmp OF((Bytef* s1, Bytef* s2, uInt len)); - extern void zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef DEBUG_ZLIB -# include <stdio.h> -# ifndef verbose -# define verbose 0 -# endif - extern void z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len)); - -voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); -void zcfree OF((voidpf opaque, voidpf ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -#endif /* _Z_UTIL_H */ -/* --- zutil.h */ - -/* +++ deflate.h */ -/* deflate.h -- internal compression state - * Copyright (C) 1995-1996 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* From: deflate.h,v 1.10 1996/07/02 12:41:00 me Exp $ */ - -#ifndef _DEFLATE_H -#define _DEFLATE_H - -/* #include "zutil.h" */ - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define INIT_STATE 42 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct deflate_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - int pending; /* nb of bytes in the pending buffer */ - int noheader; /* suppress zlib header and adler32 */ - Byte data_type; /* UNKNOWN, BINARY or ASCII */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to supress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - ulg compressed_len; /* total bit length of compressed file */ - uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ - -#ifdef DEBUG_ZLIB - ulg bits_sent; /* bit length of the compressed data */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - - /* in trees.c */ -void _tr_init OF((deflate_state *s)); -int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -ulg _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_align OF((deflate_state *s)); -void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_stored_type_only OF((deflate_state *)); - -#endif -/* --- deflate.h */ - -/* +++ deflate.c */ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-1996 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in ftp://ds.internic.net/rfc/rfc1951.txt - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* From: deflate.c,v 1.15 1996/07/24 13:40:58 me Exp $ */ - -/* #include "deflate.h" */ - -char deflate_copyright[] = " deflate 1.0.4 Copyright 1995-1996 Jean-loup Gailly "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -local block_state deflate_slow OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, charf *buf, unsigned size)); -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif - -#ifdef DEBUG_ZLIB -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -local config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int noheader = 0; - static char* my_version = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; -#ifndef NO_ZCFUNCS - if (strm->zalloc == Z_NULL) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == Z_NULL) strm->zfree = zcfree; -#endif - - if (level == Z_DEFAULT_COMPRESSION) level = 6; - - if (windowBits < 0) { /* undocumented feature: suppress zlib header */ - noheader = 1; - windowBits = -windowBits; - } - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_HUFFMAN_ONLY) { - return Z_STREAM_ERROR; - } - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->noheader = noheader; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt length = dictLength; - uInt n; - IPos hash_head = 0; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) - return Z_STREAM_ERROR; - - s = (deflate_state *) strm->state; - if (s->status != INIT_STATE) return Z_STREAM_ERROR; - - strm->adler = adler32(strm->adler, dictionary, dictLength); - - if (length < MIN_MATCH) return Z_OK; - if (length > MAX_DIST(s)) { - length = MAX_DIST(s); -#ifndef USE_DICT_HEAD - dictionary += dictLength - length; /* use the tail of the dictionary */ -#endif - } - zmemcpy((charf *)s->window, dictionary, length); - s->strstart = length; - s->block_start = (long)length; - - /* Insert all strings in the hash table (except for the last two bytes). - * s->lookahead stays null, so s->ins_h will be recomputed at the next - * call of fill_window. - */ - s->ins_h = s->window[0]; - UPDATE_HASH(s, s->ins_h, s->window[1]); - for (n = 0; n <= length - MIN_MATCH; n++) { - INSERT_STRING(s, n, hash_head); - } - if (hash_head) hash_head = 0; /* to make compiler happy */ - return Z_OK; -} - -/* ========================================================================= */ -int deflateReset (strm) - z_streamp strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->noheader < 0) { - s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ - } - s->status = s->noheader ? BUSY_STATE : INIT_STATE; - strm->adler = 1; - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - lm_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = (deflate_state *) strm->state; - - if (level == Z_DEFAULT_COMPRESSION) { - level = 6; - } - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if (func != configuration_table[level].func && strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_PARTIAL_FLUSH); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - deflate_state *s = (deflate_state *) strm->state; - unsigned len = s->pending; - - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - if (strm->next_out != Z_NULL) { - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - } - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* ========================================================================= */ -int deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_FINISH || flush < 0) { - return Z_STREAM_ERROR; - } - s = (deflate_state *) strm->state; - - if ((strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the zlib header */ - if (s->status == INIT_STATE) { - - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags = (s->level-1) >> 1; - - if (level_flags > 3) level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = 1L; - } - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUFF_ERROR. - */ - } else if (strm->avail_in == 0 && flush <= old_flush && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush == Z_PACKET_FLUSH) { - /* Output just the 3-bit `stored' block type value, - but not a zero length. */ - _tr_stored_type_only(s); - } else { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->noheader) return Z_STREAM_END; - - /* Write the zlib trailer (adler32) */ - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - s->noheader = -1; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int deflateEnd (strm) - z_streamp strm; -{ - int status; - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = (deflate_state *) strm->state; - - status = s->status; - if (status != INIT_STATE && status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, s->pending_buf); - TRY_FREE(strm, s->head); - TRY_FREE(strm, s->prev); - TRY_FREE(strm, s->window); - - ZFREE(strm, s); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - */ -int deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) - return Z_STREAM_ERROR; - ss = (deflate_state *) source->state; - - zmemcpy(dest, source, sizeof(*dest)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy(ds, ss, sizeof(*ds)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* ??? following zmemcpy doesn't work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -} - -/* =========================================================================== - * Return the number of bytes of output which are immediately available - * for output from the decompressor. - */ -int deflateOutputPending (strm) - z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return 0; - - return ((deflate_state *)(strm->state))->pending; -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf(strm, buf, size) - z_streamp strm; - charf *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - if (!((deflate_state *)(strm->state))->noheader) { - strm->adler = adler32(strm->adler, strm->next_in, len); - } - zmemcpy(buf, strm->next_in, len); - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -} - -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2: - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return best_len; - return s->lookahead; -} -#endif /* ASMV */ - -#ifdef DEBUG_ZLIB -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp((charf *)s->window + match, - (charf *)s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if strstart == 0 - * and lookahead == 1 (input done one byte at time) - */ - more--; - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - } else if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy((charf *)s->window, (charf *)s->window+wsize, - (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); - more += wsize; - } - if (s->strm->avail_in == 0) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, (charf *)s->window + s->strstart + s->lookahead, - more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, eof) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (eof)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, eof) { \ - FLUSH_BLOCK_ONLY(s, eof); \ - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy != Z_HUFFMAN_ONLY) { - s->match_length = longest_match (s, hash_head); - } - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - bflush = _tr_tally(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in hash table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - bflush = _tr_tally (s, 0, s->window[s->strstart]); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy != Z_HUFFMAN_ONLY) { - s->match_length = longest_match (s, hash_head); - } - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED || - (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR))) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - bflush = _tr_tally(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - if (_tr_tally (s, 0, s->window[s->strstart-1])) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally (s, 0, s->window[s->strstart-1]); - s->match_available = 0; - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -/* --- deflate.c */ - -/* +++ trees.c */ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-1996 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */ - -/* #include "deflate.h" */ - -#ifdef DEBUG_ZLIB -# include <ctype.h> -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -local uch dist_code[512]; -/* distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -local uch length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -struct static_tree_desc_s { - ct_data *static_tree; /* static tree or NULL */ - intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local void set_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifndef DEBUG_ZLIB -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG_ZLIB */ -# define send_code(s, c, tree) \ - { if (verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -#define d_code(dist) \ - ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. dist_code[256] and dist_code[257] are never - * used. - */ - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG_ZLIB -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (value << s->bi_valid); - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG_ZLIB */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (val << s->bi_valid);\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG_ZLIB */ - - -#define MAX(a,b) (a >= b ? a : b) -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. In a multi-threaded environment, - * this function may be called by two threads concurrently, but this is - * harmless since both invocations do exactly the same thing. - */ -local void tr_static_init() -{ - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1<<extra_lbits[code]); n++) { - length_code[length++] = (uch)code; - } - } - Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - length_code[length-1] = (uch)code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<<extra_dbits[code]); n++) { - dist_code[dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; -} - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->compressed_len = 0L; - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ -#ifdef DEBUG_ZLIB - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - ct_data *stree = desc->stat_desc->static_tree; - intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if (tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, - "inconsistent bit counts"); - Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].Code = bi_reverse(next_code[len]++, len); - - Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); - } -} - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -local void build_tree(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void _tr_stored_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; - - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* Send just the `stored block' type code without any length bytes or data. - */ -void _tr_stored_type_only(s) - deflate_state *s; -{ - send_bits(s, (STORED_BLOCK << 1), 3); - bi_windup(s); - s->compressed_len = (s->compressed_len + 3) & ~7L; -} - - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only. - */ -void _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ - bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the last real code (before - * the EOB of the previous block) was thus at least one plus the length - * of the EOB plus what we have just sent of the empty static block. - */ - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); - s->compressed_len += 10L; - bi_flush(s); - } - s->last_eob_len = 7; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. This function - * returns the total compressed length for the file so far. - */ -ulg _tr_flush_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is ascii or binary */ - if (s->data_type == Z_UNKNOWN) set_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute first the block length in bytes*/ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - - /* If compression failed and this is the first and last block, - * and if the .zip file can be seeked (to rewrite the local header), - * the whole file is transformed into a stored file: - */ -#ifdef STORED_FILE_OK -# ifdef FORCE_STORED_FILE - if (eof && s->compressed_len == 0L) { /* force stored file */ -# else - if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { -# endif - /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ - if (buf == (charf*)0) error ("block vanished"); - - copy_block(s, buf, (unsigned)stored_len, 0); /* without header */ - s->compressed_len = stored_len << 3; - s->method = STORED; - } else -#endif /* STORED_FILE_OK */ - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, eof); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+eof, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); - s->compressed_len += 3 + s->static_len; - } else { - send_bits(s, (DYN_TREES<<1)+eof, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); - s->compressed_len += 3 + s->opt_len; - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - init_block(s); - - if (eof) { - bi_windup(s); - s->compressed_len += 7; /* align on byte boundary */ - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*eof)); - - return s->compressed_len >> 3; -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - - /* Try to guess if it is profitable to stop the current block here */ - if (s->level > 2 && (s->last_lit & 0xfff) == 0) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; -} - -/* =========================================================================== - * Set the data type to ASCII or BINARY, using a crude approximation: - * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. - * IN assertion: the fields freq of dyn_ltree are set and the total of all - * frequencies does not exceed 64K (to fit in an int on 16 bit machines). - */ -local void set_data_type(s) - deflate_state *s; -{ - int n = 0; - unsigned ascii_freq = 0; - unsigned bin_freq = 0; - while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; - while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; - while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; - s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG_ZLIB - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG_ZLIB - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG_ZLIB - s->bits_sent += (ulg)len<<3; -#endif - /* bundle up the put_byte(s, *buf++) calls */ - zmemcpy(&s->pending_buf[s->pending], buf, len); - s->pending += len; -} -/* --- trees.c */ - -/* +++ inflate.c */ -/* inflate.c -- zlib interface to inflate modules - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ - -/* +++ infblock.h */ -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_blocks_state; -typedef struct inflate_blocks_state FAR inflate_blocks_statef; - -extern inflate_blocks_statef * inflate_blocks_new OF(( - z_streamp z, - check_func c, /* check function */ - uInt w)); /* window size */ - -extern int inflate_blocks OF(( - inflate_blocks_statef *, - z_streamp , - int)); /* initial return code */ - -extern void inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_streamp , - uLongf *)); /* check value on output */ - -extern int inflate_blocks_free OF(( - inflate_blocks_statef *, - z_streamp , - uLongf *)); /* check value on output */ - -extern void inflate_set_dictionary OF(( - inflate_blocks_statef *s, - const Bytef *d, /* dictionary */ - uInt n)); /* dictionary length */ - -extern int inflate_addhistory OF(( - inflate_blocks_statef *, - z_streamp)); - -extern int inflate_packet_flush OF(( - inflate_blocks_statef *)); -/* --- infblock.h */ - -#ifndef NO_DUMMY_DECL -struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ -#endif - -/* inflate private state */ -struct internal_state { - - /* mode */ - enum { - METHOD, /* waiting for method byte */ - FLAG, /* waiting for flag byte */ - DICT4, /* four dictionary check bytes to go */ - DICT3, /* three dictionary check bytes to go */ - DICT2, /* two dictionary check bytes to go */ - DICT1, /* one dictionary check byte to go */ - DICT0, /* waiting for inflateSetDictionary */ - BLOCKS, /* decompressing blocks */ - CHECK4, /* four check bytes to go */ - CHECK3, /* three check bytes to go */ - CHECK2, /* two check bytes to go */ - CHECK1, /* one check byte to go */ - DONE, /* finished check, done */ - BAD} /* got an error--stay here */ - mode; /* current inflate mode */ - - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ - - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ - -}; - - -int inflateReset(z) -z_streamp z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? BLOCKS : METHOD; - inflate_blocks_reset(z->state->blocks, z, &c); - Trace((stderr, "inflate: reset\n")); - return Z_OK; -} - - -int inflateEnd(z) -z_streamp z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->blocks != Z_NULL) - inflate_blocks_free(z->state->blocks, z, &c); - ZFREE(z, z->state); - z->state = Z_NULL; - Trace((stderr, "inflate: end\n")); - return Z_OK; -} - - -int inflateInit2_(z, w, version, stream_size) -z_streamp z; -int w; -const char *version; -int stream_size; -{ - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != sizeof(z_stream)) - return Z_VERSION_ERROR; - - /* initialize state */ - if (z == Z_NULL) - return Z_STREAM_ERROR; - z->msg = Z_NULL; -#ifndef NO_ZCFUNCS - if (z->zalloc == Z_NULL) - { - z->zalloc = zcalloc; - z->opaque = (voidpf)0; - } - if (z->zfree == Z_NULL) z->zfree = zcfree; -#endif - if ((z->state = (struct internal_state FAR *) - ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) - return Z_MEM_ERROR; - z->state->blocks = Z_NULL; - - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if (w < 0) - { - w = - w; - z->state->nowrap = 1; - } - - /* set window size */ - if (w < 8 || w > 15) - { - inflateEnd(z); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; - - /* create inflate_blocks state */ - if ((z->state->blocks = - inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) - == Z_NULL) - { - inflateEnd(z); - return Z_MEM_ERROR; - } - Trace((stderr, "inflate: allocated\n")); - - /* reset state */ - inflateReset(z); - return Z_OK; -} - - -int inflateInit_(z, version, stream_size) -z_streamp z; -const char *version; -int stream_size; -{ - return inflateInit2_(z, DEF_WBITS, version, stream_size); -} - - -#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} -#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) - -int inflate(z, f) -z_streamp z; -int f; -{ - int r; - uInt b; - - if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0) - return Z_STREAM_ERROR; - r = Z_BUF_ERROR; - while (1) switch (z->state->mode) - { - case METHOD: - NEEDBYTE - if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) - { - z->state->mode = BAD; - z->msg = (char*)"unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ((z->state->sub.method >> 4) + 8 > z->state->wbits) - { - z->state->mode = BAD; - z->msg = (char*)"invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = FLAG; - case FLAG: - NEEDBYTE - b = NEXTBYTE; - if (((z->state->sub.method << 8) + b) % 31) - { - z->state->mode = BAD; - z->msg = (char*)"incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib header ok\n")); - if (!(b & PRESET_DICT)) - { - z->state->mode = BLOCKS; - break; - } - z->state->mode = DICT4; - case DICT4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = DICT3; - case DICT3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = DICT2; - case DICT2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = DICT1; - case DICT1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - z->adler = z->state->sub.check.need; - z->state->mode = DICT0; - return Z_NEED_DICT; - case DICT0: - z->state->mode = BAD; - z->msg = (char*)"need dictionary"; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_STREAM_ERROR; - case BLOCKS: - r = inflate_blocks(z->state->blocks, z, r); - if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) - r = inflate_packet_flush(z->state->blocks); - if (r == Z_DATA_ERROR) - { - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if (r != Z_STREAM_END) - return r; - r = Z_OK; - inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); - if (z->state->nowrap) - { - z->state->mode = DONE; - break; - } - z->state->mode = CHECK4; - case CHECK4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = CHECK3; - case CHECK3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = CHECK2; - case CHECK2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = CHECK1; - case CHECK1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - - if (z->state->sub.check.was != z->state->sub.check.need) - { - z->state->mode = BAD; - z->msg = (char*)"incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib check ok\n")); - z->state->mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } - - empty: - if (f != Z_PACKET_FLUSH) - return r; - z->state->mode = BAD; - z->msg = (char *)"need more for packet flush"; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_DATA_ERROR; -} - - -int inflateSetDictionary(z, dictionary, dictLength) -z_streamp z; -const Bytef *dictionary; -uInt dictLength; -{ - uInt length = dictLength; - - if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) - return Z_STREAM_ERROR; - - if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; - z->adler = 1L; - - if (length >= ((uInt)1<<z->state->wbits)) - { - length = (1<<z->state->wbits)-1; - dictionary += dictLength - length; - } - inflate_set_dictionary(z->state->blocks, dictionary, length); - z->state->mode = BLOCKS; - return Z_OK; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ - -int inflateIncomp(z) -z_stream *z; -{ - if (z->state->mode != BLOCKS) - return Z_DATA_ERROR; - return inflate_addhistory(z->state->blocks, z); -} - - -int inflateSync(z) -z_streamp z; -{ - uInt n; /* number of bytes to look at */ - Bytef *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ - - /* set up */ - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->mode != BAD) - { - z->state->mode = BAD; - z->state->sub.marker = 0; - } - if ((n = z->avail_in) == 0) - return Z_BUF_ERROR; - p = z->next_in; - m = z->state->sub.marker; - - /* search */ - while (n && m < 4) - { - if (*p == (Byte)(m < 2 ? 0 : 0xff)) - m++; - else if (*p) - m = 0; - else - m = 4 - m; - p++, n--; - } - - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; - - /* return no joy or set up to restart on a new block */ - if (m != 4) - return Z_DATA_ERROR; - r = z->total_in; w = z->total_out; - inflateReset(z); - z->total_in = r; z->total_out = w; - z->state->mode = BLOCKS; - return Z_OK; -} - -#undef NEEDBYTE -#undef NEXTBYTE -/* --- inflate.c */ - -/* +++ infblock.c */ -/* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "infblock.h" */ - -/* +++ inftrees.h */ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). */ - -typedef struct inflate_huft_s FAR inflate_huft; - -struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit machines) */ - union { - uInt Base; /* literal, length base, or distance base */ - inflate_huft *Next; /* pointer to next level of table */ - } more; -}; - -#ifdef DEBUG_ZLIB - extern uInt inflate_hufts; -#endif - -extern int inflate_trees_bits OF(( - uIntf *, /* 19 code lengths */ - uIntf *, /* bits tree desired/actual depth */ - inflate_huft * FAR *, /* bits tree result */ - z_streamp )); /* for zalloc, zfree functions */ - -extern int inflate_trees_dynamic OF(( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uIntf *, /* that many (total) code lengths */ - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ - z_streamp )); /* for zalloc, zfree functions */ - -extern int inflate_trees_fixed OF(( - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *)); /* distance tree result */ - -extern int inflate_trees_free OF(( - inflate_huft *, /* tables to free */ - z_streamp )); /* for zfree function */ - -/* --- inftrees.h */ - -/* +++ infcodes.h */ -/* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_codes_state; -typedef struct inflate_codes_state FAR inflate_codes_statef; - -extern inflate_codes_statef *inflate_codes_new OF(( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_streamp )); - -extern int inflate_codes OF(( - inflate_blocks_statef *, - z_streamp , - int)); - -extern void inflate_codes_free OF(( - inflate_codes_statef *, - z_streamp )); - -/* --- infcodes.h */ - -/* +++ infutil.h */ -/* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -#ifndef _INFUTIL_H -#define _INFUTIL_H - -typedef enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONEB, /* finished last block, done */ - BADB} /* got a data error--stuck here */ -inflate_block_mode; - -/* inflate blocks semi-private state */ -struct inflate_blocks_state { - - /* mode */ - inflate_block_mode mode; /* current inflate_block mode */ - - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uIntf *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_huft *tl; - inflate_huft *td; /* trees to free */ - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ - - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - Bytef *window; /* sliding window */ - Bytef *end; /* one byte after sliding window */ - Bytef *read; /* window read pointer */ - Bytef *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ - -}; - - -/* defines for inflate input/output */ -/* update pointers and return */ -#define UPDBITS {s->bitb=b;s->bitk=k;} -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -#define UPDOUT {s->write=q;} -#define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush(s,z,r);} -/* get bytes and bits */ -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -#define NEXTBYTE (n--,*p++) -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} -#define DUMPBITS(j) {b>>=(j);k-=(j);} -/* output bytes */ -#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} -#define WWRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} -#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WWRAP if(m==0){FLUSH WWRAP if(m==0) LEAVE}}r=Z_OK;} -#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -/* load local pointers */ -#define LOAD {LOADIN LOADOUT} - -/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ -extern uInt inflate_mask[17]; - -/* copy as much as possible from the sliding window to the output area */ -extern int inflate_flush OF(( - inflate_blocks_statef *, - z_streamp , - int)); - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -#endif -/* --- infutil.h */ - -#ifndef NO_DUMMY_DECL -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ -#endif - -/* Table for deflate from PKZIP's appnote.txt. */ -local const uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - - -void inflate_blocks_reset(s, z, c) -inflate_blocks_statef *s; -z_streamp z; -uLongf *c; -{ - if (s->checkfn != Z_NULL) - *c = s->check; - if (s->mode == BTREE || s->mode == DTREE) - ZFREE(z, s->sub.trees.blens); - if (s->mode == CODES) - { - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - } - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0); - Trace((stderr, "inflate: blocks reset\n")); -} - - -inflate_blocks_statef *inflate_blocks_new(z, c, w) -z_streamp z; -check_func c; -uInt w; -{ - inflate_blocks_statef *s; - - if ((s = (inflate_blocks_statef *)ZALLOC - (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) - return s; - if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) - { - ZFREE(z, s); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Trace((stderr, "inflate: blocks allocated\n")); - inflate_blocks_reset(s, z, &s->check); - return s; -} - - -#ifdef DEBUG_ZLIB - extern uInt inflate_hufts; -#endif -int inflate_blocks(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input based on current state */ - while (1) switch (s->mode) - { - case TYPE: - NEEDBITS(3) - t = (uInt)b & 7; - s->last = t & 1; - switch (t >> 1) - { - case 0: /* stored */ - Trace((stderr, "inflate: stored block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - t = k & 7; /* go to byte boundary */ - DUMPBITS(t) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Trace((stderr, "inflate: fixed codes block%s\n", - s->last ? " (last)" : "")); - { - uInt bl, bd; - inflate_huft *tl, *td; - - inflate_trees_fixed(&bl, &bd, &tl, &td); - s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.decode.codes == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.tl = Z_NULL; /* don't try to free these */ - s->sub.decode.td = Z_NULL; - } - DUMPBITS(3) - s->mode = CODES; - break; - case 2: /* dynamic */ - Trace((stderr, "inflate: dynamic codes block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS(3) - s->mode = BADB; - z->msg = (char*)"invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS(32) - if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) - { - s->mode = BADB; - z->msg = (char*)"invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); - s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); - break; - case STORED: - if (n == 0) - LEAVE - NEEDOUT - t = s->sub.left; - if (t > n) t = n; - if (t > m) t = m; - zmemcpy(q, p, t); - p += t; n -= t; - q += t; m -= t; - if ((s->sub.left -= t) != 0) - break; - Tracev((stderr, "inflate: stored end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS(14) - s->sub.trees.table = t = (uInt)b & 0x3fff; -#ifndef PKZIP_BUG_WORKAROUND - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - s->mode = BADB; - z->msg = (char*)"too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } -#endif - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if (t < 19) - t = 19; - if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - DUMPBITS(14) - s->sub.trees.index = 0; - Tracev((stderr, "inflate: table sizes ok\n")); - s->mode = BTREE; - case BTREE: - while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) - { - NEEDBITS(3) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS(3) - } - while (s->sub.trees.index < 19) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, z); - if (t != Z_OK) - { - ZFREE(z, s->sub.trees.blens); - r = t; - if (r == Z_DATA_ERROR) - s->mode = BADB; - LEAVE - } - s->sub.trees.index = 0; - Tracev((stderr, "inflate: bits tree ok\n")); - s->mode = DTREE; - case DTREE: - while (t = s->sub.trees.table, - s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) - { - inflate_huft *h; - uInt i, j, c; - - t = s->sub.trees.bb; - NEEDBITS(t) - h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); - t = h->word.what.Bits; - c = h->more.Base; - if (c < 16) - { - DUMPBITS(t) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS(t + i) - DUMPBITS(t) - j += (uInt)b & inflate_mask[i]; - DUMPBITS(i) - i = s->sub.trees.index; - t = s->sub.trees.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)) - { - inflate_trees_free(s->sub.trees.tb, z); - ZFREE(z, s->sub.trees.blens); - s->mode = BADB; - z->msg = (char*)"invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while (--j); - s->sub.trees.index = i; - } - } - inflate_trees_free(s->sub.trees.tb, z); - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; - - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; -#ifdef DEBUG_ZLIB - inflate_hufts = 0; -#endif - t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), - s->sub.trees.blens, &bl, &bd, &tl, &td, z); - ZFREE(z, s->sub.trees.blens); - if (t != Z_OK) - { - if (t == (uInt)Z_DATA_ERROR) - s->mode = BADB; - r = t; - LEAVE - } - Tracev((stderr, "inflate: trees ok, %d * %d bytes used\n", - inflate_hufts, sizeof(inflate_huft))); - if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) - { - inflate_trees_free(td, z); - inflate_trees_free(tl, z); - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.codes = c; - s->sub.decode.tl = tl; - s->sub.decode.td = td; - } - s->mode = CODES; - case CODES: - UPDATE - if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) - return inflate_flush(s, z, r); - r = Z_OK; - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - LOAD - Tracev((stderr, "inflate: codes end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - if (!s->last) - { - s->mode = TYPE; - break; - } - if (k > 7) /* return unused byte, if any */ - { - Assert(k < 16, "inflate_codes grabbed too many bytes") - k -= 8; - n++; - p--; /* can always return one */ - } - s->mode = DRY; - case DRY: - FLUSH - if (s->read != s->write) - LEAVE - s->mode = DONEB; - case DONEB: - r = Z_STREAM_END; - LEAVE - case BADB: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -int inflate_blocks_free(s, z, c) -inflate_blocks_statef *s; -z_streamp z; -uLongf *c; -{ - inflate_blocks_reset(s, z, c); - ZFREE(z, s->window); - ZFREE(z, s); - Trace((stderr, "inflate: blocks freed\n")); - return Z_OK; -} - - -void inflate_set_dictionary(s, d, n) -inflate_blocks_statef *s; -const Bytef *d; -uInt n; -{ - zmemcpy((charf *)s->window, d, n); - s->read = s->write = s->window + n; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ -int inflate_addhistory(s, z) -inflate_blocks_statef *s; -z_stream *z; -{ - uLong b; /* bit buffer */ /* NOT USED HERE */ - uInt k; /* bits in bit buffer */ /* NOT USED HERE */ - uInt t; /* temporary storage */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - if (s->read != s->write) - return Z_STREAM_ERROR; - if (s->mode != TYPE) - return Z_DATA_ERROR; - - /* we're ready to rock */ - LOAD - /* while there is input ready, copy to output buffer, moving - * pointers as needed. - */ - while (n) { - t = n; /* how many to do */ - /* is there room until end of buffer? */ - if (t > m) t = m; - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, t); - zmemcpy(q, p, t); - q += t; - p += t; - n -= t; - z->total_out += t; - s->read = q; /* drag read pointer forward */ -/* WWRAP */ /* expand WWRAP macro by hand to handle s->read */ - if (q == s->end) { - s->read = q = s->window; - m = WAVAIL; - } - } - UPDATE - return Z_OK; -} - - -/* - * At the end of a Deflate-compressed PPP packet, we expect to have seen - * a `stored' block type value but not the (zero) length bytes. - */ -int inflate_packet_flush(s) - inflate_blocks_statef *s; -{ - if (s->mode != LENS) - return Z_DATA_ERROR; - s->mode = TYPE; - return Z_OK; -} -/* --- infblock.c */ - -/* +++ inftrees.c */ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "inftrees.h" */ - -char inflate_copyright[] = " inflate 1.0.4 Copyright 1995-1996 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - - -local int huft_build OF(( - uIntf *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - const uIntf *, /* list of base values for non-simple codes */ - const uIntf *, /* list of extra bits for non-simple codes */ - inflate_huft * FAR*,/* result: starting table */ - uIntf *, /* maximum lookup bits (returns actual) */ - z_streamp )); /* for zalloc function */ - -local voidpf falloc OF(( - voidpf, /* opaque pointer (not used) */ - uInt, /* number of items */ - uInt)); /* size of item */ - -/* Tables for deflate from PKZIP's appnote.txt. */ -local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* see note #13 above about 258 */ -local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ -local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577}; -local const uInt cpdext[30] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - is not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ -#define BMAX 15 /* maximum bit length of any code */ -#define N_MAX 288 /* maximum number of codes in any set */ - -#ifdef DEBUG_ZLIB - uInt inflate_hufts; -#endif - -local int huft_build(b, n, s, d, e, t, m, zs) -uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ -uInt n; /* number of codes (assumed <= N_MAX) */ -uInt s; /* number of simple-valued codes (0..s-1) */ -const uIntf *d; /* list of base values for non-simple codes */ -const uIntf *e; /* list of extra bits for non-simple codes */ -inflate_huft * FAR *t; /* result: starting table */ -uIntf *m; /* maximum lookup bits, returns actual */ -z_streamp zs; /* for zalloc function */ -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - if the given code set is incomplete (the tables are still built in this - case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of - lengths), or Z_MEM_ERROR if not enough memory. */ -{ - - uInt a; /* counter for codes of length k */ - uInt c[BMAX+1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - register uIntf *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - uInt v[N_MAX]; /* values in order of bit length */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX+1]; /* bit offsets, then code stack */ - uIntf *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - p = c; -#define C0 *p++ = 0; -#define C2 C0 C0 C0 C0 -#define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_OK; - } - - - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((uInt)l < j) - l = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((uInt)l > i) - l = i; - *m = l; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return Z_DATA_ERROR; - if ((y -= c[i]) < 0) - return Z_DATA_ERROR; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - n = x[g]; /* set n to length of v */ - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l) - { - h++; - w += l; /* previous table always l bits */ - - /* compute minimum size table less than or equal to l bits */ - z = g - w; - z = z > (uInt)l ? l : z; /* table size upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if (j < z) - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - z = 1 << j; /* table entries for j-bit table */ - - /* allocate and link in new table */ - if ((q = (inflate_huft *)ZALLOC - (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) - { - if (h) - inflate_trees_free(u[0], zs); - return Z_MEM_ERROR; /* not enough memory */ - } -#ifdef DEBUG_ZLIB - inflate_hufts += z + 1; -#endif - *t = q + 1; /* link to list for huft_free() */ - *(t = &(q->next)) = Z_NULL; - u[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - r.next = q; /* pointer to this table */ - j = i >> (w - l); /* (get around Turbo C bug) */ - u[h-1][j] = r; /* connect to last table */ - } - } - - /* set up table entry in r */ - r.bits = (Byte)(k - w); - if (p >= v + n) - r.exop = 128 + 64; /* out of values--invalid code */ - else if (*p < s) - { - r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != x[h]) - { - h--; /* don't need to update q */ - w -= l; - } - } - } - - - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -} - - -int inflate_trees_bits(c, bb, tb, z) -uIntf *c; /* 19 code lengths */ -uIntf *bb; /* bits tree desired/actual depth */ -inflate_huft * FAR *tb; /* bits tree result */ -z_streamp z; /* for zfree function */ -{ - int r; - - r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed dynamic bit lengths tree"; - else if (r == Z_BUF_ERROR || *bb == 0) - { - inflate_trees_free(*tb, z); - z->msg = (char*)"incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - return r; -} - - -int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) -uInt nl; /* number of literal/length codes */ -uInt nd; /* number of distance codes */ -uIntf *c; /* that many (total) code lengths */ -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -z_streamp z; /* for zfree function */ -{ - int r; - - /* build literal/length tree */ - r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z); - if (r != Z_OK || *bl == 0) - { - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed literal/length tree"; - else if (r != Z_MEM_ERROR) - { - inflate_trees_free(*tl, z); - z->msg = (char*)"incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - return r; - } - - /* build distance tree */ - r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z); - if (r != Z_OK || (*bd == 0 && nl > 257)) - { - if (r == Z_DATA_ERROR) - z->msg = (char*)"oversubscribed distance tree"; - else if (r == Z_BUF_ERROR) { -#ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } -#else - inflate_trees_free(*td, z); - z->msg = (char*)"incomplete distance tree"; - r = Z_DATA_ERROR; - } - else if (r != Z_MEM_ERROR) - { - z->msg = (char*)"empty distance tree with lengths"; - r = Z_DATA_ERROR; - } - inflate_trees_free(*tl, z); - return r; -#endif - } - - /* done */ - return Z_OK; -} - - -/* build fixed tables only once--keep them here */ -local int fixed_built = 0; -#define FIXEDH 530 /* number of hufts used by fixed tables */ -local inflate_huft fixed_mem[FIXEDH]; -local uInt fixed_bl; -local uInt fixed_bd; -local inflate_huft *fixed_tl; -local inflate_huft *fixed_td; - - -local voidpf falloc(q, n, s) -voidpf q; /* opaque pointer */ -uInt n; /* number of items */ -uInt s; /* size of item */ -{ - Assert(s == sizeof(inflate_huft) && n <= *(intf *)q, - "inflate_trees falloc overflow"); - *(intf *)q -= n+s-s; /* s-s to avoid warning */ - return (voidpf)(fixed_mem + *(intf *)q); -} - - -int inflate_trees_fixed(bl, bd, tl, td) -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -{ - /* build fixed tables if not already (multiple overlapped executions ok) */ - if (!fixed_built) - { - int k; /* temporary variable */ - unsigned c[288]; /* length list for huft_build */ - z_stream z; /* for falloc function */ - int f = FIXEDH; /* number of hufts left in fixed_mem */ - - /* set up fake z_stream for memory routines */ - z.zalloc = falloc; - z.zfree = Z_NULL; - z.opaque = (voidpf)&f; - - /* literal table */ - for (k = 0; k < 144; k++) - c[k] = 8; - for (; k < 256; k++) - c[k] = 9; - for (; k < 280; k++) - c[k] = 7; - for (; k < 288; k++) - c[k] = 8; - fixed_bl = 7; - huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); - - /* distance table */ - for (k = 0; k < 30; k++) - c[k] = 5; - fixed_bd = 5; - huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); - - /* done */ - Assert(f == 0, "invalid build of fixed tables"); - fixed_built = 1; - } - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; -} - - -int inflate_trees_free(t, z) -inflate_huft *t; /* table to free */ -z_streamp z; /* for zfree function */ -/* Free the malloc'ed tables built by huft_build(), which makes a linked - list of the tables it made, with the links in a dummy first entry of - each table. */ -{ - register inflate_huft *p, *q, *r; - - /* Reverse linked list */ - p = Z_NULL; - q = t; - while (q != Z_NULL) - { - r = (q - 1)->next; - (q - 1)->next = p; - p = q; - q = r; - } - /* Go through linked list, freeing from the malloced (t[-1]) address. */ - while (p != Z_NULL) - { - q = (--p)->next; - ZFREE(z,p); - p = q; - } - return Z_OK; -} -/* --- inftrees.c */ - -/* +++ infcodes.c */ -/* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "inftrees.h" */ -/* #include "infblock.h" */ -/* #include "infcodes.h" */ -/* #include "infutil.h" */ - -/* +++ inffast.h */ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -extern int inflate_fast OF(( - uInt, - uInt, - inflate_huft *, - inflate_huft *, - inflate_blocks_statef *, - z_streamp )); -/* --- inffast.h */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* inflate codes private state */ -struct inflate_codes_state { - - /* mode */ - enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE} /* x: got error */ - mode; /* current inflate_codes mode */ - - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ - - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ - -}; - - -inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) -uInt bl, bd; -inflate_huft *tl; -inflate_huft *td; /* need separate declaration for Borland C++ */ -z_streamp z; -{ - inflate_codes_statef *c; - - if ((c = (inflate_codes_statef *) - ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) - { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - Tracev((stderr, "inflate: codes new\n")); - } - return c; -} - - -int inflate_codes(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Bytef *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input and output based on current state */ - while (1) switch (c->mode) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ -#ifndef SLOW - if (m >= 258 && n >= 10) - { - UPDATE - r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); - LOAD - if (r != Z_OK) - { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } -#endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e == 0) /* literal */ - { - c->sub.lit = t->base; - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", t->base)); - c->mode = LIT; - break; - } - if (e & 16) /* length */ - { - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - if (e & 32) /* end of block */ - { - Tracevv((stderr, "inflate: end of block\n")); - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS(j) - c->len += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - Tracevv((stderr, "inflate: length %u\n", c->len)); - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e & 16) /* distance */ - { - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = (char*)"invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS(j) - c->sub.copy.dist += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ -#ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)(q - s->window) < c->sub.copy.dist ? - s->end - (c->sub.copy.dist - (q - s->window)) : - q - c->sub.copy.dist; -#else - f = q - c->sub.copy.dist; - if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); -#endif - while (c->len) - { - NEEDOUT - OUTBYTE(*f++) - if (f == s->end) - f = s->window; - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE(c->sub.lit) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - FLUSH - if (s->read != s->write) - LEAVE - c->mode = END; - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -void inflate_codes_free(c, z) -inflate_codes_statef *c; -z_streamp z; -{ - ZFREE(z, c); - Tracev((stderr, "inflate: codes free\n")); -} -/* --- infcodes.c */ - -/* +++ infutil.c */ -/* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "infblock.h" */ -/* #include "inftrees.h" */ -/* #include "infcodes.h" */ -/* #include "infutil.h" */ - -#ifndef NO_DUMMY_DECL -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ -#endif - -/* And'ing with mask[n] masks the lower n bits */ -uInt inflate_mask[17] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - - -/* copy as much as possible from the sliding window to the output area */ -int inflate_flush(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt n; - Bytef *p; - Bytef *q; - - /* local copies of source and destination pointers */ - p = z->next_out; - q = s->read; - - /* compute number of bytes to copy as far as end of window */ - n = (uInt)((q <= s->write ? s->write : s->end) - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(s->check, q, n); - - /* copy as far as end of window */ - if (p != Z_NULL) { - zmemcpy(p, q, n); - p += n; - } - q += n; - - /* see if more to copy at beginning of window */ - if (q == s->end) - { - /* wrap pointers */ - q = s->window; - if (s->write == s->end) - s->write = s->window; - - /* compute bytes to copy */ - n = (uInt)(s->write - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(s->check, q, n); - - /* copy */ - if (p != Z_NULL) { - zmemcpy(p, q, n); - p += n; - } - q += n; - } - - /* update pointers */ - z->next_out = p; - s->read = q; - - /* done */ - return r; -} -/* --- infutil.c */ - -/* +++ inffast.c */ -/* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* #include "zutil.h" */ -/* #include "inftrees.h" */ -/* #include "infblock.h" */ -/* #include "infcodes.h" */ -/* #include "infutil.h" */ -/* #include "inffast.h" */ - -#ifndef NO_DUMMY_DECL -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ -#endif - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} -#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;} - -/* Called with number of bytes left to write in window at least 258 - (the maximum string length) and number of input bytes available - at least ten. The ten bytes are six bytes for the longest length/ - distance pair plus four bytes for overloading the bit buffer. */ - -int inflate_fast(bl, bd, tl, td, s, z) -uInt bl, bd; -inflate_huft *tl; -inflate_huft *td; /* need separate declaration for Borland C++ */ -inflate_blocks_statef *s; -z_streamp z; -{ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Bytef *r; /* copy source pointer */ - - /* load input, output, bit values */ - LOAD - - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; - - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits for length */ - e &= 15; - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * length %u\n", c)); - - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - e = (t = td + ((uInt)b & md))->exop; - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS(e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* offset before dest */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (uInt)(q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > e) /* if source crosses, */ - { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); - break; - } - else if ((e & 64) == 0) - e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; - else - { - z->msg = (char*)"invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - break; - } - if ((e & 64) == 0) - { - if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - break; - } - } - else if (e & 32) - { - Tracevv((stderr, "inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = (char*)"invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - } while (m >= 258 && n >= 10); - - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; -} -/* --- inffast.c */ - -/* +++ zutil.c */ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-1996 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zutil.c,v 1.17 1996/07/24 13:41:12 me Exp $ */ - -#ifdef DEBUG_ZLIB -#include <stdio.h> -#endif - -/* #include "zutil.h" */ - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -#ifndef STDC -extern void exit OF((int)); -#endif - -const char *z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - - -const char *zlibVersion() -{ - return ZLIB_VERSION; -} - -#ifdef DEBUG_ZLIB -void z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -#ifndef HAVE_MEMCPY - -void zmemcpy(dest, source, len) - Bytef* dest; - Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int zmemcmp(s1, s2, len) - Bytef* s1; - Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - -#ifdef __TURBOC__ -#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) -/* Small and medium model in Turbo C are for now limited to near allocation - * with reduced MAX_WBITS and MAX_MEM_LEVEL - */ -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} -#endif -#endif /* __TURBOC__ */ - - -#if defined(M_I86) && !defined(__32BIT__) -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER < 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* MSC */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - if (opaque) items += size - size; /* make compiler happy */ - return (voidpf)calloc(items, size); -} - -void zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ -/* --- zutil.c */ - -/* +++ adler32.c */ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-1996 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */ - -/* #include "zlib.h" */ - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* ========================================================================= */ -uLong adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == Z_NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - buf += 16; - k -= 16; - } - if (k != 0) do { - s1 += *buf++; - s2 += s1; - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} -/* --- adler32.c */ diff --git a/mdk-stage1/ppp/common/zlib.h b/mdk-stage1/ppp/common/zlib.h deleted file mode 100644 index 188ddaff9..000000000 --- a/mdk-stage1/ppp/common/zlib.h +++ /dev/null @@ -1,1010 +0,0 @@ -/* $Id$ */ - -/* - * This file is derived from zlib.h and zconf.h from the zlib-1.0.4 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. - */ - -/* - * ==FILEVERSION 971127== - * - * This marker is used by the Linux installation script to determine - * whether an up-to-date version of this file is already installed. - */ - - -/* +++ zlib.h */ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.0.4, Jul 24th, 1996. - - Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - gzip@prep.ai.mit.edu madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef _ZLIB_H -#define _ZLIB_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* +++ zconf.h */ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-1996 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zconf.h,v 1.20 1996/07/02 15:09:28 me Exp $ */ - -#ifndef _ZCONF_H -#define _ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateReset z_inflateReset -# define compress z_compress -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table - -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) -# define WIN32 -#endif -#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) -# ifndef __32BIT__ -# define __32BIT__ -# endif -#endif -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#if defined(MSDOS) && !defined(__32BIT__) -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) -# define STDC -#endif -#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC) -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - 1 << (windowBits+2) + 1 << (memLevel+9) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR __far -# else -# define FAR far -# endif -#endif -#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) -# ifndef __32BIT__ -# define SMALL_MEDIUM -# define FAR __far -# endif -#endif -#ifndef FAR -# define FAR -#endif - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#if defined(__BORLANDC__) && defined(SMALL_MEDIUM) - /* Borland C/C++ ignores FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - - -/* Compile with -DZLIB_DLL for Windows DLL support */ -#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL) -# include <windows.h> -# define EXPORT WINAPI -#else -# define EXPORT -#endif - -#endif /* _ZCONF_H */ -/* --- zconf.h */ - -#define ZLIB_VERSION "1.0.4P" - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms may be added later and will have the same - stream interface. - - For compression the application must provide the output buffer and - may optionally provide the input buffer for optimization. For decompression, - the application must provide the input buffer and may optionally provide - the output buffer for optimization. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. - - The library does not install any signal handler. It is recommended to - add at least a handler for SIGSEGV when decompressing; the library checks - the consistency of the input data whenever possible but may go nuts - for some forms of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: ascii or binary */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_PACKET_FLUSH 2 -#define Z_SYNC_FLUSH 3 -#define Z_FULL_FLUSH 4 -#define Z_FINISH 5 -/* Allowed flush values; see deflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_ASCII 1 -#define Z_UNKNOWN 2 -/* Possible values of the data_type field */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - /* basic functions */ - -extern const char * EXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - -/* -extern int EXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -extern int EXPORT deflate OF((z_streamp strm, int flush)); -/* - Performs one or both of the following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. - - If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression - block is terminated and flushed to the output buffer so that the - decompressor can get all input data available so far. For method 9, a future - variant on method 8, the current block will be flushed but not terminated. - Z_SYNC_FLUSH has the same effect as partial flush except that the compressed - output is byte aligned (the compressor can clear its internal bit buffer) - and the current block is always terminated; this can be useful if the - compressor has to be restarted from scratch after an interruption (in which - case the internal state of the compressor may be lost). - If flush is set to Z_FULL_FLUSH, the compression block is terminated, a - special marker is output and the compression dictionary is discarded; this - is useful to allow the decompressor to synchronize if one compressed block - has been damaged (see inflateSync below). Flushing degrades compression and - so should be used only when necessary. Using Z_FULL_FLUSH too often can - seriously degrade the compression. If deflate returns with avail_out == 0, - this function must be called again with the same value of the flush - parameter and more output space (updated avail_out), until the flush is - complete (deflate returns with non-zero avail_out). - - If the parameter flush is set to Z_PACKET_FLUSH, the compression - block is terminated, and a zero-length stored block is output, - omitting the length bytes (the effect of this is that the 3-bit type - code 000 for a stored block is output, and the output is then - byte-aligned). This is designed for use at the end of a PPP packet. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - 0.1% larger than avail_in plus 12 bytes. If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() may update data_type if it can make a good guess about - the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible. -*/ - - -extern int EXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -extern int EXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, inflateInit updates them to use default - allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_VERSION_ERROR if the zlib library version is incompatible - with the version assumed by the caller. msg is set to null if there is no - error message. inflateInit does not perform any decompression: this will be - done by inflate(). -*/ - - -extern int EXPORT inflate OF((z_streamp strm, int flush)); -/* - Performs one or both of the following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. - - If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, - inflate flushes as much output as possible to the output buffer. The - flushing behavior of inflate is not specified for values of the flush - parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the - current implementation actually flushes as much output as possible - anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data - has been consumed, it is expecting to see the length field of a stored - block; if not, it returns Z_DATA_ERROR. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. - - inflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if the end of the - compressed data has been reached and all uncompressed output has been - produced, Z_NEED_DICT if a preset dictionary is needed at this point (see - inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted, - Z_STREAM_ERROR if the stream structure was inconsistent (for example if - next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in - the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the - application may then call inflateSync to look for a good compression block. - In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the - dictionary chosen by the compressor. -*/ - - -extern int EXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -extern int EXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. (Method 9 will allow a 64K history buffer and - partial block flushes.) - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library (the value 16 will be allowed for method 9). Larger - values of this parameter result in better compression at the expense of - memory usage. The default value is 15 if deflateInit is used instead. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match). Filtered data consists mostly of small values with a - somewhat random distribution. In this case, the compression algorithm is - tuned to compress them better. The effect of Z_FILTERED is to force more - Huffman coding and less string matching; it is somewhat intermediate - between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects - the compression ratio but not the correctness of the compressed output even - if it is not set appropriately. - - If next_in is not null, the library will use this buffer to hold also - some history information; the buffer must either hold the entire input - data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in - is null, the library will allocate its own history buffer (and leave next_in - null). next_out need not be provided here but must be provided by the - application for the next call of deflate(). - - If the history buffer is provided by the application, next_in must - must never be changed by the application since the compressor maintains - information inside this buffer from call to call; the application - must provide more input only by increasing avail_in. next_in is always - reset by the library in this case. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was - not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as - an invalid method). msg is set to null if there is no error message. - deflateInit2 does not perform any compression: this will be done by - deflate(). -*/ - -extern int EXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary (history buffer) from the given - byte sequence without producing any compressed output. This function must - be called immediately after deflateInit or deflateInit2, before any call - of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and - can be predicted with good accuracy; the data can then be compressed better - than with the default empty dictionary. In this version of the library, - only the last 32K bytes of the dictionary are used. - Upon return of this function, strm->adler is set to the Adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state - is inconsistent (for example if deflate has already been called for this - stream). deflateSetDictionary does not perform any compression: this will - be done by deflate(). -*/ - -extern int EXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. If - the source stream is using an application-supplied history buffer, a new - buffer is allocated for the destination stream. The compressed output - buffer is always application-supplied. It's the responsibility of the - application to provide the correct values of next_out and avail_out for the - next call of deflate. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -extern int EXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy)); -/* - Dynamically update the compression level and compression strategy. - This can be used to switch between compression and straight copy of - the input data, or to switch to a different kind of input data requiring - a different strategy. If the compression level is changed, the input - available so far is compressed with the old level (and may be flushed); - the new level will take effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. -*/ - -extern int EXPORT deflateOutputPending OF((z_streamp strm)); -/* - Returns the number of bytes of output which are immediately - available from the compressor (i.e. without any further input - or flush). -*/ - -/* -extern int EXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with more compression options. The - fields next_out, zalloc, zfree and opaque must be initialized before by - the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library (the value 16 will be allowed soon). The - default value is 15 if inflateInit is used instead. If a compressed stream - with a larger window size is given as input, inflate() will return with - the error code Z_DATA_ERROR instead of trying to allocate a larger window. - - If next_out is not null, the library will use this buffer for the history - buffer; the buffer must either be large enough to hold the entire output - data, or have at least 1<<windowBits bytes. If next_out is null, the - library will allocate its own buffer (and leave next_out null). next_in - need not be provided here but must be provided by the application for the - next call of inflate(). - - If the history buffer is provided by the application, next_out must - never be changed by the application since the decompressor maintains - history information inside this buffer from call to call; the application - can only reset next_out to the beginning of the history buffer when - avail_out is zero and all output has been consumed. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was - not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as - windowBits < 8). msg is set to null if there is no error message. - inflateInit2 does not perform any decompression: this will be done by - inflate(). -*/ - -extern int EXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary (history buffer) from the given - uncompressed byte sequence. This function must be called immediately after - a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen - by the compressor can be determined from the Adler32 value returned by this - call of inflate. The compressor and decompressor must use exactly the same - dictionary (see deflateSetDictionary). - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect Adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -extern int EXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until the special marker (see deflate() - above) can be found, or until all available input is skipped. No output - is provided. - - inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no marker has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -extern int EXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -extern int inflateIncomp OF((z_stream *strm)); -/* - This function adds the data at next_in (avail_in bytes) to the output - history without performing any output. There must be no pending output, - and the decompressor must be expecting to see the start of a block. - Calling this function is equivalent to decompressing a stored block - containing the data at next_in (except that the data is not output). -*/ - - /* utility functions */ - -/* - The following utility functions are implemented on top of the - basic stream-oriented functions. To simplify the interface, some - default options are assumed (compression level, window size, - standard memory allocation functions). The source code of these - utility functions can easily be modified if you need special options. -*/ - -extern int EXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be at least 0.1% larger than - sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the - compressed buffer. - This function can be used to compress a whole file at once if the - input file is mmap'ed. - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -extern int EXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. -*/ - - -typedef voidp gzFile; - -extern gzFile EXPORT gzopen OF((const char *path, const char *mode)); -/* - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb") but can also include a compression level - ("wb9"). gzopen can be used to read a file which is not in gzip format; - in this case gzread will directly read from the file without decompression. - gzopen returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). -*/ - -extern gzFile EXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen() associates a gzFile with the file descriptor fd. File - descriptors are obtained from calls like open, dup, creat, pipe or - fileno (in the file has been previously opened with fopen). - The mode parameter is as in gzopen. - The next call of gzclose on the returned gzFile will also close the - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). - gzdopen returns NULL if there was insufficient memory to allocate - the (de)compression state. -*/ - -extern int EXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. - If the input file was not in gzip format, gzread copies the given number - of bytes into the buffer. - gzread returns the number of uncompressed bytes actually read (0 for - end of file, -1 for error). */ - -extern int EXPORT gzwrite OF((gzFile file, const voidp buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes actually written - (0 in case of error). -*/ - -extern int EXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. The return value is the zlib - error number (see function gzerror below). gzflush returns Z_OK if - the flush parameter is Z_FINISH and all output could be flushed. - gzflush should be called only when strictly necessary because it can - degrade compression. -*/ - -extern int EXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. The return value is the zlib - error number (see function gzerror below). -*/ - -extern const char * EXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the - compression library. -*/ - -extern uLong EXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); - -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -extern uLong EXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running crc with the bytes buf[0..len-1] and return the updated - crc. If buf is NULL, this function returns the required initial value - for the crc. Pre- and post-conditioning (one's complement) is performed - within this function so it shouldn't be done by the application. - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -extern int EXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -extern int EXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -extern int EXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, int strategy, - const char *version, int stream_size)); -extern int EXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) - -#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; /* hack for buggy compilers */ -#endif - -uLongf *get_crc_table OF((void)); /* can be used by asm versions of crc32() */ - -#ifdef __cplusplus -} -#endif - -#endif /* _ZLIB_H */ -/* --- zlib.h */ diff --git a/mdk-stage1/ppp/configure b/mdk-stage1/ppp/configure deleted file mode 100755 index 544fb0d71..000000000 --- a/mdk-stage1/ppp/configure +++ /dev/null @@ -1,141 +0,0 @@ -#!/bin/sh -# $Id$ - -# if [ -d /NextApps ]; then -# system="NeXTStep" -# else - system=`uname -s` - release=`uname -r` - machine=`uname -p` - arch=`uname -m` -# fi -state="unknown" - -case $system in - Linux) - makext="linux"; - ksrc="linux"; - state="known";; - SunOS) - case $release in -# [0-3]*) state="ancient";; -# 4*) state="known"; ksrc="sunos4"; makext="sunos4";; - 5.[1-6]*) state="known"; ksrc="solaris"; makext="sol2";; - 5.[7-9]*) state="known"; ksrc="solaris"; makext="sol2"; - case $arch in - sun4u) lp64='y';; - *) ;; - esac;; - esac;; - NetBSD|FreeBSD|ULTRIX|OSF1|NeXTStep|SINIX-?|UNIX_SV|UNIX_System_V) - state="notincluded";; -# NetBSD) -# makext="bsd"; -# case $release in -# 0.*) state="ancient";; -# 1.0*) state="ancient";; -# 1.1*) state="known"; ksrc="netbsd-1.1";; -# 1.2*) state="known"; ksrc="netbsd-1.2"; makext="netbsd-1.2";; -# 1.[3-9]*|[2-9]*) -# state="late"; ksrc="netbsd-1.2";; -# esac;; -# ULTRIX) -# makext="ultrix"; -# case $release in -# [0-3]*) state="ancient";; -# 4.[01]*) state="early"; ksrc="ultrix";; -# 4.[234]) state="known"; ksrc="ultrix";; -# esac;; -# OSF1) -# makext="osf"; -# case $release in -# V1.*) state="neolithic"; ksrc="osf1";; -# V[23].*) state="neolithic"; ksrc="osf1";; -# V4.*) state="known"; ksrc="osf1";; -# V[5-9]*) state="late"; ksrc="osf1";; -# esac;; -# FreeBSD) -# makext="bsd"; -# case $release in -# 1.*) state="known"; ksrc="freebsd-old";; -# 2.[01]*) state="known"; ksrc="freebsd-2.0";; -# 2.2.[2-7]*) state="late"; ksrc="freebsd-2.0";; -# 2.2.8*) state="known"; ksrc="freebsd-2.2.8";; -# 3.[0-1]*) state="known"; ksrc="freebsd-3.0";; -# esac;; -# NeXTStep) -# makext="NeXT"; -# ksrc="NeXT"; -# state="known";; -# SINIX-?) -# case $release in -# 5.4[01]) state=known; ksrc=svr4; makext=svr4;; -# 5.4[2-9]) state=late; ksrc=svr4; makext=svr4;; -# esac;; -# # Intel SVR4 systems come with a bug in the uname program. Unless -# # your provider fixed the bug, or you get a fix for it, uname -S will -# # overwrite the system name with the node name! -# UNIX_SV|UNIX_System_V|`uname -n`) -# case $release in -# 4.0) state=known; ksrc=svr4; makext=svr4;; -# 4.2) state=late; ksrc=svr4; makext=svr4;; -# esac;; -esac - -if [ -d "$ksrc" ]; then :; else - state="notincluded" - unset ksrc -fi - -case $state in - neolithic) - echo "This is a newer release on an outdated OS ($system)." - echo " This software may or may not work on this OS." - echo " You may want to download an older version of PPP for this OS.";; - ancient) - echo "This is an old release of a supported OS ($system)." - echo "This software cannot be used as-is on this system," - echo "but you may be able to port it. Good luck!" - exit;; - early) - echo "This is an old release of a supported OS ($system)." - echo "This software should install and run on this system," - echo "but it hasn't been tested.";; - late) - echo "This is a newer release of $system than is supported by" - echo "this software. It may or may not work.";; - unknown) - echo "This software has not been ported to this system. Sorry.";; - notincluded) - echo "Support for this system has not been included" - echo "in this distribution. Sorry.";; -esac - -orig_makext=$makext - -if [ -d "$ksrc" ]; then - echo "Creating links to Makefiles." - rm -f Makefile - ln -s $ksrc/Makefile.top Makefile - echo " Makefile -> $ksrc/Makefile.top" - if [ "$ksrc" = solaris ]; then - # Point to 64-bit Makefile extension - if [ "$lp64" = y ]; then - makext=$makext-64 - fi - rm -f $ksrc/Makefile - ln -s Makefile.$makext $ksrc/Makefile - echo " $ksrc/Makefile -> Makefile.$makext" - # Restore extension - if [ "$lp64" = y ]; then - makext=$orig_makext - fi - fi - for dir in pppd pppstats chat pppdump; do - rm -f $dir/Makefile - if [ -f $dir/Makefile.$makext ]; then - ln -s Makefile.$makext $dir/Makefile - echo " $dir/Makefile -> Makefile.$makext" - fi - done -fi diff --git a/mdk-stage1/ppp/contrib/pppgetpass/Makefile.linux b/mdk-stage1/ppp/contrib/pppgetpass/Makefile.linux deleted file mode 100644 index 7eb217dac..000000000 --- a/mdk-stage1/ppp/contrib/pppgetpass/Makefile.linux +++ /dev/null @@ -1,16 +0,0 @@ -all: pppgetpass.vt pppgetpass.gtk - -pppgetpass.vt: pppgetpass.vt.o - -pppgetpass.gtk: pppgetpass.gtk.o - $(CC) $(LDFLAGS) pppgetpass.gtk.o `gtk-config --libs` -o pppgetpass.gtk -pppgetpass.gtk.o: pppgetpass.gtk.c - $(CC) $(CFLAGS) -c pppgetpass.gtk.c `gtk-config --cflags` - -install: all - install -m 755 pppgetpass.sh /usr/bin/pppgetpass - install -m 4755 -o root -g root pppgetpass.vt /usr/bin/ - install -m 755 -o root -g root pppgetpass.gtk /usr/X11/bin/ - -clean: - rm -f *.o pppgetpass.gtk pppgetpass.vt core diff --git a/mdk-stage1/ppp/contrib/pppgetpass/pppgetpass.8 b/mdk-stage1/ppp/contrib/pppgetpass/pppgetpass.8 deleted file mode 100644 index ade576970..000000000 --- a/mdk-stage1/ppp/contrib/pppgetpass/pppgetpass.8 +++ /dev/null @@ -1,18 +0,0 @@ -.TH PPPGETPASS 8 "26 Sep 1999" -.SH NAME -pppgetpass \- prompt for PAP password -.SH SYNOPSIS -.B pppgetpass -.I client server fd -.SH DESCRIPTION -.B pppgetpass -the outer half of a plugin for PAP password prompting in pppd. -If the peer requires PAP, and the -.B passprompt.so -plugin is loaded into pppd, it will run -.B /usr/sbin/pppgetpass -(or another program specified by the -.B promptprog -option) to prompt the user for the password. -.SH SEE ALSO -pppd(8) diff --git a/mdk-stage1/ppp/contrib/pppgetpass/pppgetpass.gtk.c b/mdk-stage1/ppp/contrib/pppgetpass/pppgetpass.gtk.c deleted file mode 100644 index 48ca04202..000000000 --- a/mdk-stage1/ppp/contrib/pppgetpass/pppgetpass.gtk.c +++ /dev/null @@ -1,92 +0,0 @@ -#include <glib.h> -#include <gdk/gdk.h> -#include <gtk/gtkwindow.h> -#include <gtk/gtkmain.h> -#include <gtk/gtkbutton.h> -#include <gtk/gtkvbox.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkentry.h> -#include <gtk/gtksignal.h> - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <syslog.h> - -int outfd; -int err; - -static void okpressed(void *widget, void *clientdata) -{ - GtkWidget *answer=clientdata; - gchar *pass; - int passlen; - ssize_t wrote; - (void)widget; - - pass=gtk_entry_get_text(GTK_ENTRY(answer)); - - passlen=strlen(pass); - if(!passlen) - return; - - if((wrote=write(outfd, pass, passlen))!=passlen) { - if(wrote<0) - syslog(LOG_ERR, "write error on outpipe: %m"); - else - syslog(LOG_ERR, "short write on outpipe"); - err=1; - } - gtk_main_quit(); -} - -int main(int argc, char **argv) -{ - GtkWidget *mainwindow, *vbox, *question, *answer, *ok; - char buf[1024]; - gtk_init(&argc, &argv); - - openlog(argv[0], LOG_PID, LOG_DAEMON); - if(argc!=4) { - syslog(LOG_WARNING, "Usage error"); - return 1; - } - outfd=atoi(argv[3]); - mainwindow=gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(mainwindow), "pppgetpass"); - gtk_signal_connect(GTK_OBJECT(mainwindow), "destroy", - GTK_SIGNAL_FUNC(gtk_main_quit), 0); - - vbox=gtk_vbox_new(FALSE, 5); - gtk_container_add(GTK_CONTAINER(mainwindow), vbox); - gtk_widget_show(vbox); - - if(argv[1][0] && argv[2][0]) - snprintf(buf, sizeof buf, "Password for PPP client %s on server %s: ", argv[1], argv[2]); - else if(argv[1][0] && !argv[2][0]) - snprintf(buf, sizeof buf, "Password for PPP client %s: ", argv[1]); - else if(!argv[1][0] && argv[2][0]) - snprintf(buf, sizeof buf, "Password for PPP on server %s: ", argv[2]); - else - snprintf(buf, sizeof buf, "Enter PPP password: "); - question=gtk_label_new(buf); - gtk_box_pack_start(GTK_BOX(vbox), question, FALSE, TRUE, 0); - gtk_widget_show(question); - - answer=gtk_entry_new(); - gtk_entry_set_visibility(GTK_ENTRY(answer), 0); - gtk_box_pack_start(GTK_BOX(vbox), answer, FALSE, TRUE, 0); - gtk_widget_show(answer); - - ok=gtk_button_new_with_label("OK"); - gtk_box_pack_start(GTK_BOX(vbox), ok, FALSE, TRUE, 0); - gtk_signal_connect(GTK_OBJECT(ok), "clicked", - GTK_SIGNAL_FUNC(okpressed), answer); - gtk_widget_show(ok); - - gtk_widget_show(mainwindow); - gtk_main(); - - return err; -} diff --git a/mdk-stage1/ppp/contrib/pppgetpass/pppgetpass.sh b/mdk-stage1/ppp/contrib/pppgetpass/pppgetpass.sh deleted file mode 100644 index 09c480519..000000000 --- a/mdk-stage1/ppp/contrib/pppgetpass/pppgetpass.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -if [ -z "$DISPLAY" ]; then - exec pppgetpass.vt "$@" -else - exec pppgetpass.gtk "$@" -fi diff --git a/mdk-stage1/ppp/contrib/pppgetpass/pppgetpass.vt.c b/mdk-stage1/ppp/contrib/pppgetpass/pppgetpass.vt.c deleted file mode 100644 index a1520883c..000000000 --- a/mdk-stage1/ppp/contrib/pppgetpass/pppgetpass.vt.c +++ /dev/null @@ -1,218 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <syslog.h> -#include <termios.h> -#include <sys/vt.h> - -static int console_owner(uid_t, int); - -int main(int argc, char **argv) -{ - int console; - uid_t uid; - struct vt_stat origstate; - int openvtnum; - char openvtname[256]; - int openvt; - gid_t gid; - int chowned; - FILE *fp; - struct termios t; - char pass[256], *nl; - int outfd, passlen; - ssize_t wrote; - console=open("/dev/console", O_RDWR); - - uid=getuid(); - gid=getgid(); - seteuid(uid); - - openlog(argv[0], LOG_PID, LOG_DAEMON); - - if(argc!=4) { - syslog(LOG_WARNING, "Usage error"); - return 1; - } - - if(console<0) { - syslog(LOG_ERR, "open(/dev/console): %m"); - return 1; - } - - if(ioctl(console, VT_GETSTATE, &origstate)<0) { - syslog(LOG_ERR, "VT_GETSTATE: %m"); - return 1; - } - - if(uid) { - if(!console_owner(uid, origstate.v_active)) { - int i; - for(i=0;i<64;++i) { - if(i!=origstate.v_active && console_owner(uid, i)) - break; - } - if(i==64) { - syslog(LOG_WARNING, "run by uid %lu not at console", (unsigned long)uid); - return 1; - } - } - } - - if(ioctl(console, VT_OPENQRY, &openvtnum)<0) { - syslog(LOG_ERR, "VT_OPENQRY: %m"); - return 1; - } - if(openvtnum==-1) { - syslog(LOG_ERR, "No free VTs"); - return 1; - } - - snprintf(openvtname, sizeof openvtname, "/dev/tty%d", openvtnum); - seteuid(0); - openvt=open(openvtname, O_RDWR); - if(openvt<0) { - seteuid(uid); - syslog(LOG_ERR, "open(%s): %m", openvtname); - return 1; - } - - chowned=fchown(openvt, uid, gid); - if(chowned<0) { - seteuid(uid); - syslog(LOG_ERR, "fchown(%s): %m", openvtname); - return 1; - } - - close(console); - - if(ioctl(openvt, VT_ACTIVATE, openvtnum)<0) { - seteuid(uid); - syslog(LOG_ERR, "VT_ACTIVATE(%d): %m", openvtnum); - return 1; - } - - while(ioctl(openvt, VT_WAITACTIVE, openvtnum)<0) { - if(errno!=EINTR) { - ioctl(openvt, VT_ACTIVATE, origstate.v_active); - seteuid(uid); - syslog(LOG_ERR, "VT_WAITACTIVE(%d): %m", openvtnum); - return 1; - } - } - - seteuid(uid); - fp=fdopen(openvt, "r+"); - if(!fp) { - seteuid(0); - ioctl(openvt, VT_ACTIVATE, origstate.v_active); - seteuid(uid); - syslog(LOG_ERR, "fdopen(%s): %m", openvtname); - return 1; - } - - if(tcgetattr(openvt, &t)<0) { - seteuid(0); - ioctl(openvt, VT_ACTIVATE, origstate.v_active); - seteuid(uid); - syslog(LOG_ERR, "tcgetattr(%s): %m", openvtname); - return 1; - } - t.c_lflag &= ~ECHO; - if(tcsetattr(openvt, TCSANOW, &t)<0) { - seteuid(0); - ioctl(openvt, VT_ACTIVATE, origstate.v_active); - seteuid(uid); - syslog(LOG_ERR, "tcsetattr(%s): %m", openvtname); - return 1; - } - - if(fprintf(fp, "\033[2J\033[H")<0) { - seteuid(0); - ioctl(openvt, VT_ACTIVATE, origstate.v_active); - seteuid(uid); - syslog(LOG_ERR, "write error on %s: %m", openvtname); - return 1; - } - if(argv[1][0] && argv[2][0]) { - if(fprintf(fp, "Password for PPP client %s on server %s: ", argv[1], argv[2])<0) { - seteuid(0); - ioctl(openvt, VT_ACTIVATE, origstate.v_active); - seteuid(uid); - syslog(LOG_ERR, "write error on %s: %m", openvtname); - return 1; - } - } else if(argv[1][0] && !argv[2][0]) { - if(fprintf(fp, "Password for PPP client %s: ", argv[1])<0) { - syslog(LOG_ERR, "write error on %s: %m", openvtname); - seteuid(0); - ioctl(openvt, VT_ACTIVATE, origstate.v_active); - seteuid(uid); - return 1; - } - } else if(!argv[1][0] && argv[2][0]) { - if(fprintf(fp, "Password for PPP on server %s: ", argv[2])<0) { - seteuid(0); - ioctl(openvt, VT_ACTIVATE, origstate.v_active); - seteuid(uid); - syslog(LOG_ERR, "write error on %s: %m", openvtname); - return 1; - } - } else { - if(fprintf(fp, "Enter PPP password: ")<0) { - seteuid(0); - ioctl(openvt, VT_ACTIVATE, origstate.v_active); - seteuid(uid); - syslog(LOG_ERR, "write error on %s: %m", openvtname); - return 1; - } - } - - if(!fgets(pass, sizeof pass, fp)) { - seteuid(0); - ioctl(openvt, VT_ACTIVATE, origstate.v_active); - seteuid(uid); - if(ferror(fp)) { - syslog(LOG_ERR, "read error on %s: %m", openvtname); - } - return 1; - } - if((nl=strchr(pass, '\n'))) - *nl=0; - passlen=strlen(pass); - - outfd=atoi(argv[3]); - if((wrote=write(outfd, pass, passlen))!=passlen) { - seteuid(0); - ioctl(openvt, VT_ACTIVATE, origstate.v_active); - seteuid(uid); - if(wrote<0) - syslog(LOG_ERR, "write error on outpipe: %m"); - else - syslog(LOG_ERR, "short write on outpipe"); - return 1; - } - - seteuid(0); - ioctl(openvt, VT_ACTIVATE, origstate.v_active); - seteuid(uid); - return 0; -} - -static int console_owner(uid_t uid, int cons) -{ - char name[256]; - struct stat st; - snprintf(name, sizeof name, "/dev/tty%d", cons); - if(stat(name, &st)<0) { - if(errno!=ENOENT) - syslog(LOG_ERR, "stat(%s): %m", name); - return 0; - } - return uid==st.st_uid; -} diff --git a/mdk-stage1/ppp/etc.ppp/chap-secrets b/mdk-stage1/ppp/etc.ppp/chap-secrets deleted file mode 100644 index 7d1c3cd7c..000000000 --- a/mdk-stage1/ppp/etc.ppp/chap-secrets +++ /dev/null @@ -1,2 +0,0 @@ -# Secrets for authentication using CHAP -# client server secret IP addresses diff --git a/mdk-stage1/ppp/etc.ppp/options b/mdk-stage1/ppp/etc.ppp/options deleted file mode 100644 index 0f77a9aa0..000000000 --- a/mdk-stage1/ppp/etc.ppp/options +++ /dev/null @@ -1,5 +0,0 @@ -lock -noauth -noipdefault -usepeerdns - diff --git a/mdk-stage1/ppp/etc.ppp/options.options b/mdk-stage1/ppp/etc.ppp/options.options deleted file mode 100644 index 4b67b6a0d..000000000 --- a/mdk-stage1/ppp/etc.ppp/options.options +++ /dev/null @@ -1 +0,0 @@ -lock diff --git a/mdk-stage1/ppp/etc.ppp/pap-secrets b/mdk-stage1/ppp/etc.ppp/pap-secrets deleted file mode 100644 index f8b7dce3c..000000000 --- a/mdk-stage1/ppp/etc.ppp/pap-secrets +++ /dev/null @@ -1,2 +0,0 @@ -# Secrets for authentication using PAP -# client server secret IP addresses diff --git a/mdk-stage1/ppp/include/linux/if_ppp.h b/mdk-stage1/ppp/include/linux/if_ppp.h deleted file mode 100644 index 1febf0931..000000000 --- a/mdk-stage1/ppp/include/linux/if_ppp.h +++ /dev/null @@ -1,155 +0,0 @@ -/* $Id$ */ - -/* - * if_ppp.h - Point-to-Point Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - * - */ - -/* - * ==FILEVERSION 20000724== - * - * NOTE TO MAINTAINERS: - * If you modify this file at all, please set the above date. - * if_ppp.h is shipped with a PPP distribution as well as with the kernel; - * if everyone increases the FILEVERSION number above, then scripts - * can do the right thing when deciding whether to install a new if_ppp.h - * file. Don't change the format of that line otherwise, so the - * installation script can recognize it. - */ - -#ifndef _IF_PPP_H_ -#define _IF_PPP_H_ - -/* - * Packet sizes - */ - -#define PPP_MTU 1500 /* Default MTU (size of Info field) */ -#define PPP_MAXMRU 65000 /* Largest MRU we allow */ -#define PROTO_IPX 0x002b /* protocol numbers */ -#define PROTO_DNA_RT 0x0027 /* DNA Routing */ - - -/* - * Bit definitions for flags. - */ - -#define SC_COMP_PROT 0x00000001 /* protocol compression (output) */ -#define SC_COMP_AC 0x00000002 /* header compression (output) */ -#define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */ -#define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */ -#define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */ -#define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */ -#define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */ -#define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */ -#define SC_ENABLE_IP 0x00000100 /* IP packets may be exchanged */ -#define SC_LOOP_TRAFFIC 0x00000200 /* send traffic to pppd */ -#define SC_MULTILINK 0x00000400 /* do multilink encapsulation */ -#define SC_MP_SHORTSEQ 0x00000800 /* use short MP sequence numbers */ -#define SC_COMP_RUN 0x00001000 /* compressor has been inited */ -#define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */ -#define SC_MP_XSHORTSEQ 0x00004000 /* transmit short MP seq numbers */ -#define SC_DEBUG 0x00010000 /* enable debug messages */ -#define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */ -#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */ -#define SC_LOG_RAWIN 0x00080000 /* log all chars received */ -#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */ -#define SC_SYNC 0x00200000 /* synchronous serial mode */ -#define SC_MASK 0x0f200fff /* bits that user can change */ - -/* state bits */ -#define SC_XMIT_BUSY 0x10000000 /* (used by isdn_ppp?) */ -#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */ -#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */ -#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */ -#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */ -#define SC_DC_FERROR 0x00800000 /* fatal decomp error detected */ -#define SC_DC_ERROR 0x00400000 /* non-fatal decomp error detected */ - -/* - * Ioctl definitions. - */ - -struct npioctl { - int protocol; /* PPP protocol, e.g. PPP_IP */ - enum NPmode mode; -}; - -/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */ -struct ppp_option_data { - __u8 *ptr; - __u32 length; - int transmit; -}; - -struct ifpppstatsreq { - struct ifreq b; - struct ppp_stats stats; /* statistic information */ -}; - -struct ifpppcstatsreq { - struct ifreq b; - struct ppp_comp_stats stats; -}; - -#define ifr__name b.ifr_ifrn.ifrn_name -#define stats_ptr b.ifr_ifru.ifru_data - -/* - * Ioctl definitions. - */ - -#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */ -#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */ -#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */ -#define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */ -#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */ -#define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */ -#define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */ -#define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */ -#define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */ -#define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */ -#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */ -#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */ -#define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */ -#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data) -#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */ -#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */ -#define PPPIOCSPASS _IOW('t', 71, struct sock_fprog) /* set pass filter */ -#define PPPIOCSACTIVE _IOW('t', 70, struct sock_fprog) /* set active filt */ -#define PPPIOCGDEBUG _IOR('t', 65, int) /* Read debug level */ -#define PPPIOCSDEBUG _IOW('t', 64, int) /* Set debug level */ -#define PPPIOCGIDLE _IOR('t', 63, struct ppp_idle) /* get idle time */ -#define PPPIOCNEWUNIT _IOWR('t', 62, int) /* create new ppp unit */ -#define PPPIOCATTACH _IOW('t', 61, int) /* attach to ppp unit */ -#define PPPIOCDETACH _IOW('t', 60, int) /* detach from ppp unit/chan */ -#define PPPIOCSMRRU _IOW('t', 59, int) /* set multilink MRU */ -#define PPPIOCCONNECT _IOW('t', 58, int) /* connect channel to unit */ -#define PPPIOCDISCONN _IO('t', 57) /* disconnect channel */ -#define PPPIOCATTCHAN _IOW('t', 56, int) /* attach to ppp channel */ -#define PPPIOCGCHAN _IOR('t', 55, int) /* get ppp channel number */ - -#define SIOCGPPPSTATS (SIOCDEVPRIVATE + 0) -#define SIOCGPPPVER (SIOCDEVPRIVATE + 1) /* NEVER change this!! */ -#define SIOCGPPPCSTATS (SIOCDEVPRIVATE + 2) - -#if !defined(ifr_mtu) -#define ifr_mtu ifr_ifru.ifru_metric -#endif - -#endif /* _IF_PPP_H_ */ diff --git a/mdk-stage1/ppp/include/linux/if_pppvar.h b/mdk-stage1/ppp/include/linux/if_pppvar.h deleted file mode 100644 index b2485cd9d..000000000 --- a/mdk-stage1/ppp/include/linux/if_pppvar.h +++ /dev/null @@ -1,138 +0,0 @@ -/* From: if_pppvar.h,v 1.2 1995/06/12 11:36:51 paulus Exp */ -/* - * if_pppvar.h - private structures and declarations for PPP. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -/* - * ==FILEVERSION 990911== - * - * NOTE TO MAINTAINERS: - * If you modify this file at all, please set the above date. - * if_pppvar.h is shipped with a PPP distribution as well as with the kernel; - * if everyone increases the FILEVERSION number above, then scripts - * can do the right thing when deciding whether to install a new if_pppvar.h - * file. Don't change the format of that line otherwise, so the - * installation script can recognize it. - */ - -/* - * Supported network protocols. These values are used for - * indexing sc_npmode. - */ - -#define NP_IP 0 /* Internet Protocol */ -#define NP_IPX 1 /* IPX protocol */ -#define NP_AT 2 /* Appletalk protocol */ -#define NP_IPV6 3 /* Internet Protocol */ -#define NUM_NP 4 /* Number of NPs. */ - -#define OBUFSIZE 256 /* # chars of output buffering */ - -/* - * Structure describing each ppp unit. - */ - -struct ppp { - int magic; /* magic value for structure */ - struct ppp *next; /* unit with next index */ - unsigned long inuse; /* are we allocated? */ - int line; /* network interface unit # */ - __u32 flags; /* miscellaneous control flags */ - int mtu; /* maximum xmit frame size */ - int mru; /* maximum receive frame size */ - struct slcompress *slcomp; /* for TCP header compression */ - struct sk_buff_head xmt_q; /* frames to send from pppd */ - struct sk_buff_head rcv_q; /* frames for pppd to read */ - unsigned long xmit_busy; /* bit 0 set when xmitter busy */ - - /* Information specific to using ppp on async serial lines. */ - struct tty_struct *tty; /* ptr to TTY structure */ - struct tty_struct *backup_tty; /* TTY to use if tty gets closed */ - __u8 escape; /* 0x20 if prev char was PPP_ESC */ - __u8 toss; /* toss this frame */ - volatile __u8 tty_pushing; /* internal state flag */ - volatile __u8 woke_up; /* internal state flag */ - __u32 xmit_async_map[8]; /* 1 bit means that given control - character is quoted on output*/ - __u32 recv_async_map; /* 1 bit means that given control - character is ignored on input*/ - __u32 bytes_sent; /* Bytes sent on frame */ - __u32 bytes_rcvd; /* Bytes recvd on frame */ - - /* Async transmission information */ - struct sk_buff *tpkt; /* frame currently being sent */ - int tpkt_pos; /* how much of it we've done */ - __u16 tfcs; /* FCS so far for it */ - unsigned char *optr; /* where we're up to in sending */ - unsigned char *olim; /* points past last valid char */ - - /* Async reception information */ - struct sk_buff *rpkt; /* frame currently being rcvd */ - __u16 rfcs; /* FCS so far of rpkt */ - - /* Queues for select() functionality */ - struct wait_queue *read_wait; /* queue for reading processes */ - - /* info for detecting idle channels */ - unsigned long last_xmit; /* time of last transmission */ - unsigned long last_recv; /* time last packet received */ - - /* Statistic information */ - struct pppstat stats; /* statistic information */ - - /* PPP compression protocol information */ - struct compressor *sc_xcomp; /* transmit compressor */ - void *sc_xc_state; /* transmit compressor state */ - struct compressor *sc_rcomp; /* receive decompressor */ - void *sc_rc_state; /* receive decompressor state */ - - enum NPmode sc_npmode[NUM_NP]; /* what to do with each NP */ - int sc_xfer; /* PID of reserved PPP table */ - char name[8]; /* space for unit name */ - struct device dev; /* net device structure */ - struct enet_statistics estats; /* more detailed stats */ - - /* tty output buffer */ - unsigned char obuf[OBUFSIZE]; /* buffer for characters to send */ -}; - -#define PPP_MAGIC 0x5002 -#define PPP_VERSION "2.3.11" diff --git a/mdk-stage1/ppp/include/linux/ppp-comp.h b/mdk-stage1/ppp/include/linux/ppp-comp.h deleted file mode 100644 index 3184d0731..000000000 --- a/mdk-stage1/ppp/include/linux/ppp-comp.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * ppp-comp.h - Definitions for doing PPP packet compression. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -/* - * ==FILEVERSION 980319== - * - * NOTE TO MAINTAINERS: - * If you modify this file at all, please set the above date. - * ppp-comp.h is shipped with a PPP distribution as well as with the kernel; - * if everyone increases the FILEVERSION number above, then scripts - * can do the right thing when deciding whether to install a new ppp-comp.h - * file. Don't change the format of that line otherwise, so the - * installation script can recognize it. - */ - -#ifndef _NET_PPP_COMP_H -#define _NET_PPP_COMP_H - -/* - * The following symbols control whether we include code for - * various compression methods. - */ - -#ifndef DO_BSD_COMPRESS -#define DO_BSD_COMPRESS 1 /* by default, include BSD-Compress */ -#endif -#ifndef DO_DEFLATE -#define DO_DEFLATE 1 /* by default, include Deflate */ -#endif -#define DO_PREDICTOR_1 0 -#define DO_PREDICTOR_2 0 - -/* - * Structure giving methods for compression/decompression. - */ - -struct compressor { - int compress_proto; /* CCP compression protocol number */ - - /* Allocate space for a compressor (transmit side) */ - void *(*comp_alloc) (unsigned char *options, int opt_len); - - /* Free space used by a compressor */ - void (*comp_free) (void *state); - - /* Initialize a compressor */ - int (*comp_init) (void *state, unsigned char *options, - int opt_len, int unit, int opthdr, int debug); - - /* Reset a compressor */ - void (*comp_reset) (void *state); - - /* Compress a packet */ - int (*compress) (void *state, unsigned char *rptr, - unsigned char *obuf, int isize, int osize); - - /* Return compression statistics */ - void (*comp_stat) (void *state, struct compstat *stats); - - /* Allocate space for a decompressor (receive side) */ - void *(*decomp_alloc) (unsigned char *options, int opt_len); - - /* Free space used by a decompressor */ - void (*decomp_free) (void *state); - - /* Initialize a decompressor */ - int (*decomp_init) (void *state, unsigned char *options, - int opt_len, int unit, int opthdr, int mru, - int debug); - - /* Reset a decompressor */ - void (*decomp_reset) (void *state); - - /* Decompress a packet. */ - int (*decompress) (void *state, unsigned char *ibuf, int isize, - unsigned char *obuf, int osize); - - /* Update state for an incompressible packet received */ - void (*incomp) (void *state, unsigned char *ibuf, int icnt); - - /* Return decompression statistics */ - void (*decomp_stat) (void *state, struct compstat *stats); -}; - -/* - * The return value from decompress routine is the length of the - * decompressed packet if successful, otherwise DECOMP_ERROR - * or DECOMP_FATALERROR if an error occurred. - * - * We need to make this distinction so that we can disable certain - * useful functionality, namely sending a CCP reset-request as a result - * of an error detected after decompression. This is to avoid infringing - * a patent held by Motorola. - * Don't you just lurve software patents. - */ - -#define DECOMP_ERROR -1 /* error detected before decomp. */ -#define DECOMP_FATALERROR -2 /* error detected after decomp. */ - -/* - * CCP codes. - */ - -#define CCP_CONFREQ 1 -#define CCP_CONFACK 2 -#define CCP_TERMREQ 5 -#define CCP_TERMACK 6 -#define CCP_RESETREQ 14 -#define CCP_RESETACK 15 - -/* - * Max # bytes for a CCP option - */ - -#define CCP_MAX_OPTION_LENGTH 32 - -/* - * Parts of a CCP packet. - */ - -#define CCP_CODE(dp) ((dp)[0]) -#define CCP_ID(dp) ((dp)[1]) -#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) -#define CCP_HDRLEN 4 - -#define CCP_OPT_CODE(dp) ((dp)[0]) -#define CCP_OPT_LENGTH(dp) ((dp)[1]) -#define CCP_OPT_MINLEN 2 - -/* - * Definitions for BSD-Compress. - */ - -#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ -#define CILEN_BSD_COMPRESS 3 /* length of config. option */ - -/* Macros for handling the 3rd byte of the BSD-Compress config option. */ -#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ -#define BSD_VERSION(x) ((x) >> 5) /* version of option format */ -#define BSD_CURRENT_VERSION 1 /* current version number */ -#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) - -#define BSD_MIN_BITS 9 /* smallest code size supported */ -#define BSD_MAX_BITS 15 /* largest code size supported */ - -/* - * Definitions for Deflate. - */ - -#define CI_DEFLATE 26 /* config option for Deflate */ -#define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */ -#define CILEN_DEFLATE 4 /* length of its config option */ - -#define DEFLATE_MIN_SIZE 8 -#define DEFLATE_MAX_SIZE 15 -#define DEFLATE_METHOD_VAL 8 -#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) -#define DEFLATE_METHOD(x) ((x) & 0x0F) -#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ - + DEFLATE_METHOD_VAL) -#define DEFLATE_CHK_SEQUENCE 0 - -/* - * Definitions for other, as yet unsupported, compression methods. - */ - -#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ -#define CILEN_PREDICTOR_1 2 /* length of its config option */ -#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ -#define CILEN_PREDICTOR_2 2 /* length of its config option */ - -#ifdef __KERNEL__ -extern int ppp_register_compressor(struct compressor *); -extern void ppp_unregister_compressor(struct compressor *); -#endif /* __KERNEL__ */ - -#endif /* _NET_PPP_COMP_H */ diff --git a/mdk-stage1/ppp/include/linux/ppp_defs.h b/mdk-stage1/ppp/include/linux/ppp_defs.h deleted file mode 100644 index 46946fbdc..000000000 --- a/mdk-stage1/ppp/include/linux/ppp_defs.h +++ /dev/null @@ -1,185 +0,0 @@ -/* $Id$ */ - -/* - * ppp_defs.h - PPP definitions. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - */ - -/* - * ==FILEVERSION 20000114== - * - * NOTE TO MAINTAINERS: - * If you modify this file at all, please set the above date. - * ppp_defs.h is shipped with a PPP distribution as well as with the kernel; - * if everyone increases the FILEVERSION number above, then scripts - * can do the right thing when deciding whether to install a new ppp_defs.h - * file. Don't change the format of that line otherwise, so the - * installation script can recognize it. - */ - -#ifndef _PPP_DEFS_H_ -#define _PPP_DEFS_H_ - -/* - * The basic PPP frame. - */ -#define PPP_HDRLEN 4 /* octets for standard ppp header */ -#define PPP_FCSLEN 2 /* octets for FCS */ -#define PPP_MRU 1500 /* default MRU = max length of info field */ - -#define PPP_ADDRESS(p) (((__u8 *)(p))[0]) -#define PPP_CONTROL(p) (((__u8 *)(p))[1]) -#define PPP_PROTOCOL(p) ((((__u8 *)(p))[2] << 8) + ((__u8 *)(p))[3]) - -/* - * Significant octet values. - */ -#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ -#define PPP_UI 0x03 /* Unnumbered Information */ -#define PPP_FLAG 0x7e /* Flag Sequence */ -#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ -#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ - -/* - * Protocol field values. - */ -#define PPP_IP 0x21 /* Internet Protocol */ -#define PPP_AT 0x29 /* AppleTalk Protocol */ -#define PPP_IPX 0x2b /* IPX protocol */ -#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ -#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ -#define PPP_MP 0x3d /* Multilink protocol */ -#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ -#define PPP_COMPFRAG 0xfb /* fragment compressed below bundle */ -#define PPP_COMP 0xfd /* compressed packet */ -#define PPP_IPCP 0x8021 /* IP Control Protocol */ -#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ -#define PPP_IPXCP 0x802b /* IPX Control Protocol */ -#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ -#define PPP_CCPFRAG 0x80fb /* CCP at link level (below MP bundle) */ -#define PPP_CCP 0x80fd /* Compression Control Protocol */ -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#define PPP_LQR 0xc025 /* Link Quality Report protocol */ -#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ -#define PPP_CBCP 0xc029 /* Callback Control Protocol */ - -/* - * Values for FCS calculations. - */ - -#define PPP_INITFCS 0xffff /* Initial FCS value */ -#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) - -/* - * Extended asyncmap - allows any character to be escaped. - */ - -typedef __u32 ext_accm[8]; - -/* - * What to do with network protocol (NP) packets. - */ -enum NPmode { - NPMODE_PASS, /* pass the packet through */ - NPMODE_DROP, /* silently drop the packet */ - NPMODE_ERROR, /* return an error */ - NPMODE_QUEUE /* save it up for later. */ -}; - -/* - * Statistics for LQRP and pppstats - */ -struct pppstat { - __u32 ppp_discards; /* # frames discarded */ - - __u32 ppp_ibytes; /* bytes received */ - __u32 ppp_ioctects; /* bytes received not in error */ - __u32 ppp_ipackets; /* packets received */ - __u32 ppp_ierrors; /* receive errors */ - __u32 ppp_ilqrs; /* # LQR frames received */ - - __u32 ppp_obytes; /* raw bytes sent */ - __u32 ppp_ooctects; /* frame bytes sent */ - __u32 ppp_opackets; /* packets sent */ - __u32 ppp_oerrors; /* transmit errors */ - __u32 ppp_olqrs; /* # LQR frames sent */ -}; - -struct vjstat { - __u32 vjs_packets; /* outbound packets */ - __u32 vjs_compressed; /* outbound compressed packets */ - __u32 vjs_searches; /* searches for connection state */ - __u32 vjs_misses; /* times couldn't find conn. state */ - __u32 vjs_uncompressedin; /* inbound uncompressed packets */ - __u32 vjs_compressedin; /* inbound compressed packets */ - __u32 vjs_errorin; /* inbound unknown type packets */ - __u32 vjs_tossed; /* inbound packets tossed because of error */ -}; - -struct compstat { - __u32 unc_bytes; /* total uncompressed bytes */ - __u32 unc_packets; /* total uncompressed packets */ - __u32 comp_bytes; /* compressed bytes */ - __u32 comp_packets; /* compressed packets */ - __u32 inc_bytes; /* incompressible bytes */ - __u32 inc_packets; /* incompressible packets */ - - /* the compression ratio is defined as in_count / bytes_out */ - __u32 in_count; /* Bytes received */ - __u32 bytes_out; /* Bytes transmitted */ - - double ratio; /* not computed in kernel. */ -}; - -struct ppp_stats { - struct pppstat p; /* basic PPP statistics */ - struct vjstat vj; /* VJ header compression statistics */ -}; - -struct ppp_comp_stats { - struct compstat c; /* packet compression statistics */ - struct compstat d; /* packet decompression statistics */ -}; - -/* - * The following structure records the time in seconds since - * the last NP packet was sent or received. - */ -struct ppp_idle { - time_t xmit_idle; /* time since last NP packet sent */ - time_t recv_idle; /* time since last NP packet received */ -}; - -#ifndef __P -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif -#endif - -#endif /* _PPP_DEFS_H_ */ diff --git a/mdk-stage1/ppp/include/net/if_ppp.h b/mdk-stage1/ppp/include/net/if_ppp.h deleted file mode 100644 index 1527ecf3f..000000000 --- a/mdk-stage1/ppp/include/net/if_ppp.h +++ /dev/null @@ -1,133 +0,0 @@ -/* $Id$ */ - -/* - * if_ppp.h - Point-to-Point Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon 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 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 _IF_PPP_H_ -#define _IF_PPP_H_ - -/* - * Bit definitions for flags. - */ -#define SC_COMP_PROT 0x00000001 /* protocol compression (output) */ -#define SC_COMP_AC 0x00000002 /* header compression (output) */ -#define SC_COMP_TCP 0x00000004 /* TCP (VJ) compression (output) */ -#define SC_NO_TCP_CCID 0x00000008 /* disable VJ connection-id comp. */ -#define SC_REJ_COMP_AC 0x00000010 /* reject adrs/ctrl comp. on input */ -#define SC_REJ_COMP_TCP 0x00000020 /* reject TCP (VJ) comp. on input */ -#define SC_CCP_OPEN 0x00000040 /* Look at CCP packets */ -#define SC_CCP_UP 0x00000080 /* May send/recv compressed packets */ -#define SC_DEBUG 0x00010000 /* enable debug messages */ -#define SC_LOG_INPKT 0x00020000 /* log contents of good pkts recvd */ -#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */ -#define SC_LOG_RAWIN 0x00080000 /* log all chars received */ -#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */ -#define SC_RCV_B7_0 0x01000000 /* have rcvd char with bit 7 = 0 */ -#define SC_RCV_B7_1 0x02000000 /* have rcvd char with bit 7 = 1 */ -#define SC_RCV_EVNP 0x04000000 /* have rcvd char with even parity */ -#define SC_RCV_ODDP 0x08000000 /* have rcvd char with odd parity */ -#define SC_SYNC 0x00200000 /* use synchronous HDLC framing */ -#define SC_MASK 0x0fff00ff /* bits that user can change */ - -/* - * State bits in sc_flags, not changeable by user. - */ -#define SC_TIMEOUT 0x00000400 /* timeout is currently pending */ -#define SC_VJ_RESET 0x00000800 /* need to reset VJ decomp */ -#define SC_COMP_RUN 0x00001000 /* compressor has been inited */ -#define SC_DECOMP_RUN 0x00002000 /* decompressor has been inited */ -#define SC_DC_ERROR 0x00004000 /* non-fatal decomp error detected */ -#define SC_DC_FERROR 0x00008000 /* fatal decomp error detected */ -#define SC_TBUSY 0x10000000 /* xmitter doesn't need a packet yet */ -#define SC_PKTLOST 0x20000000 /* have lost or dropped a packet */ -#define SC_FLUSH 0x40000000 /* flush input until next PPP_FLAG */ -#define SC_ESCAPED 0x80000000 /* saw a PPP_ESCAPE */ - -/* - * Ioctl definitions. - */ - -struct npioctl { - int protocol; /* PPP procotol, e.g. PPP_IP */ - enum NPmode mode; -}; - -/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */ -struct ppp_option_data { - u_char *ptr; - u_int length; - int transmit; -}; - -struct ifpppstatsreq { - char ifr_name[IFNAMSIZ]; - struct ppp_stats stats; -}; - -struct ifpppcstatsreq { - char ifr_name[IFNAMSIZ]; - struct ppp_comp_stats stats; -}; - -/* - * Ioctl definitions. - */ - -#define PPPIOCGFLAGS _IOR('t', 90, int) /* get configuration flags */ -#define PPPIOCSFLAGS _IOW('t', 89, int) /* set configuration flags */ -#define PPPIOCGASYNCMAP _IOR('t', 88, int) /* get async map */ -#define PPPIOCSASYNCMAP _IOW('t', 87, int) /* set async map */ -#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */ -#define PPPIOCGRASYNCMAP _IOR('t', 85, int) /* get receive async map */ -#define PPPIOCSRASYNCMAP _IOW('t', 84, int) /* set receive async map */ -#define PPPIOCGMRU _IOR('t', 83, int) /* get max receive unit */ -#define PPPIOCSMRU _IOW('t', 82, int) /* set max receive unit */ -#define PPPIOCSMAXCID _IOW('t', 81, int) /* set VJ max slot ID */ -#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */ -#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */ -#define PPPIOCXFERUNIT _IO('t', 78) /* transfer PPP unit */ -#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data) -#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl) /* get NP mode */ -#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl) /* set NP mode */ -#define PPPIOCGIDLE _IOR('t', 74, struct ppp_idle) /* get idle time */ -#ifdef PPP_FILTER -#define PPPIOCSPASS _IOW('t', 71, struct bpf_program) /* set pass filter */ -#define PPPIOCSACTIVE _IOW('t', 70, struct bpf_program) /* set active filt */ -#endif /* PPP_FILTER */ - -/* PPPIOC[GS]MTU are alternatives to SIOC[GS]IFMTU, used under Ultrix */ -#define PPPIOCGMTU _IOR('t', 73, int) /* get interface MTU */ -#define PPPIOCSMTU _IOW('t', 72, int) /* set interface MTU */ - -/* - * These two are interface ioctls so that pppstats can do them on - * a socket without having to open the serial device. - */ -#define SIOCGPPPSTATS _IOWR('i', 123, struct ifpppstatsreq) -#define SIOCGPPPCSTATS _IOWR('i', 122, struct ifpppcstatsreq) - -#if !defined(ifr_mtu) -#define ifr_mtu ifr_ifru.ifru_metric -#endif - -#if (defined(_KERNEL) || defined(KERNEL)) && !defined(NeXT) -void pppattach __P((void)); -void pppintr __P((void)); -#endif -#endif /* _IF_PPP_H_ */ diff --git a/mdk-stage1/ppp/include/net/ppp-comp.h b/mdk-stage1/ppp/include/net/ppp-comp.h deleted file mode 100644 index 0e6a9c672..000000000 --- a/mdk-stage1/ppp/include/net/ppp-comp.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * ppp-comp.h - Definitions for doing PPP packet compression. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -#ifndef _NET_PPP_COMP_H -#define _NET_PPP_COMP_H - -/* - * The following symbols control whether we include code for - * various compression methods. - */ -#ifndef DO_BSD_COMPRESS -#define DO_BSD_COMPRESS 1 /* by default, include BSD-Compress */ -#endif -#ifndef DO_DEFLATE -#define DO_DEFLATE 1 /* by default, include Deflate */ -#endif -#define DO_PREDICTOR_1 0 -#define DO_PREDICTOR_2 0 - -/* - * Structure giving methods for compression/decompression. - */ -#ifdef PACKETPTR -struct compressor { - int compress_proto; /* CCP compression protocol number */ - - /* Allocate space for a compressor (transmit side) */ - void *(*comp_alloc) __P((u_char *options, int opt_len)); - /* Free space used by a compressor */ - void (*comp_free) __P((void *state)); - /* Initialize a compressor */ - int (*comp_init) __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int debug)); - /* Reset a compressor */ - void (*comp_reset) __P((void *state)); - /* Compress a packet */ - int (*compress) __P((void *state, PACKETPTR *mret, - PACKETPTR mp, int orig_len, int max_len)); - /* Return compression statistics */ - void (*comp_stat) __P((void *state, struct compstat *stats)); - - /* Allocate space for a decompressor (receive side) */ - void *(*decomp_alloc) __P((u_char *options, int opt_len)); - /* Free space used by a decompressor */ - void (*decomp_free) __P((void *state)); - /* Initialize a decompressor */ - int (*decomp_init) __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); - /* Reset a decompressor */ - void (*decomp_reset) __P((void *state)); - /* Decompress a packet. */ - int (*decompress) __P((void *state, PACKETPTR mp, - PACKETPTR *dmpp)); - /* Update state for an incompressible packet received */ - void (*incomp) __P((void *state, PACKETPTR mp)); - /* Return decompression statistics */ - void (*decomp_stat) __P((void *state, struct compstat *stats)); -}; -#endif /* PACKETPTR */ - -/* - * Return values for decompress routine. - * We need to make these distinctions so that we can disable certain - * useful functionality, namely sending a CCP reset-request as a result - * of an error detected after decompression. This is to avoid infringing - * a patent held by Motorola. - * Don't you just lurve software patents. - */ -#define DECOMP_OK 0 /* everything went OK */ -#define DECOMP_ERROR 1 /* error detected before decomp. */ -#define DECOMP_FATALERROR 2 /* error detected after decomp. */ - -/* - * CCP codes. - */ -#define CCP_CONFREQ 1 -#define CCP_CONFACK 2 -#define CCP_TERMREQ 5 -#define CCP_TERMACK 6 -#define CCP_RESETREQ 14 -#define CCP_RESETACK 15 - -/* - * Max # bytes for a CCP option - */ -#define CCP_MAX_OPTION_LENGTH 32 - -/* - * Parts of a CCP packet. - */ -#define CCP_CODE(dp) ((dp)[0]) -#define CCP_ID(dp) ((dp)[1]) -#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) -#define CCP_HDRLEN 4 - -#define CCP_OPT_CODE(dp) ((dp)[0]) -#define CCP_OPT_LENGTH(dp) ((dp)[1]) -#define CCP_OPT_MINLEN 2 - -/* - * Definitions for BSD-Compress. - */ -#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ -#define CILEN_BSD_COMPRESS 3 /* length of config. option */ - -/* Macros for handling the 3rd byte of the BSD-Compress config option. */ -#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ -#define BSD_VERSION(x) ((x) >> 5) /* version of option format */ -#define BSD_CURRENT_VERSION 1 /* current version number */ -#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) - -#define BSD_MIN_BITS 9 /* smallest code size supported */ -#define BSD_MAX_BITS 15 /* largest code size supported */ - -/* - * Definitions for Deflate. - */ -#define CI_DEFLATE 26 /* config option for Deflate */ -#define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */ -#define CILEN_DEFLATE 4 /* length of its config option */ - -#define DEFLATE_MIN_SIZE 8 -#define DEFLATE_MAX_SIZE 15 -#define DEFLATE_METHOD_VAL 8 -#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) -#define DEFLATE_METHOD(x) ((x) & 0x0F) -#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ - + DEFLATE_METHOD_VAL) -#define DEFLATE_CHK_SEQUENCE 0 - -/* - * Definitions for other, as yet unsupported, compression methods. - */ -#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ -#define CILEN_PREDICTOR_1 2 /* length of its config option */ -#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ -#define CILEN_PREDICTOR_2 2 /* length of its config option */ - -#endif /* _NET_PPP_COMP_H */ diff --git a/mdk-stage1/ppp/include/net/ppp_defs.h b/mdk-stage1/ppp/include/net/ppp_defs.h deleted file mode 100644 index c35020eab..000000000 --- a/mdk-stage1/ppp/include/net/ppp_defs.h +++ /dev/null @@ -1,184 +0,0 @@ -/* $Id$ */ - -/* - * ppp_defs.h - PPP definitions. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - */ - -#ifndef _PPP_DEFS_H_ -#define _PPP_DEFS_H_ - -/* - * The basic PPP frame. - */ -#define PPP_HDRLEN 4 /* octets for standard ppp header */ -#define PPP_FCSLEN 2 /* octets for FCS */ - -/* - * Packet sizes - * - * Note - lcp shouldn't be allowed to negotiate stuff outside these - * limits. See lcp.h in the pppd directory. - * (XXX - these constants should simply be shared by lcp.c instead - * of living in lcp.h) - */ -#define PPP_MTU 1500 /* Default MTU (size of Info field) */ -#define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) -#define PPP_MINMTU 64 -#define PPP_MRU 1500 /* default MRU = max length of info field */ -#define PPP_MAXMRU 65000 /* Largest MRU we allow */ -#define PPP_MINMRU 128 - -#define PPP_ADDRESS(p) (((u_char *)(p))[0]) -#define PPP_CONTROL(p) (((u_char *)(p))[1]) -#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) - -/* - * Significant octet values. - */ -#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ -#define PPP_UI 0x03 /* Unnumbered Information */ -#define PPP_FLAG 0x7e /* Flag Sequence */ -#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ -#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ - -/* - * Protocol field values. - */ -#define PPP_IP 0x21 /* Internet Protocol */ -#define PPP_AT 0x29 /* AppleTalk Protocol */ -#define PPP_IPX 0x2b /* IPX protocol */ -#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ -#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ -#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ -#define PPP_COMP 0xfd /* compressed packet */ -#define PPP_IPCP 0x8021 /* IP Control Protocol */ -#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ -#define PPP_IPXCP 0x802b /* IPX Control Protocol */ -#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ -#define PPP_CCP 0x80fd /* Compression Control Protocol */ -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#define PPP_LQR 0xc025 /* Link Quality Report protocol */ -#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ -#define PPP_CBCP 0xc029 /* Callback Control Protocol */ - -/* - * Values for FCS calculations. - */ -#define PPP_INITFCS 0xffff /* Initial FCS value */ -#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) - -/* - * A 32-bit unsigned integral type. - */ - -#if !defined(__BIT_TYPES_DEFINED__) && !defined(_BITYPES) \ - && !defined(__FreeBSD__) && (NS_TARGET < 40) -#ifdef UINT32_T -typedef UINT32_T u_int32_t; -#else -typedef unsigned int u_int32_t; -typedef unsigned short u_int16_t; -#endif -#endif - -/* - * Extended asyncmap - allows any character to be escaped. - */ -typedef u_int32_t ext_accm[8]; - -/* - * What to do with network protocol (NP) packets. - */ -enum NPmode { - NPMODE_PASS, /* pass the packet through */ - NPMODE_DROP, /* silently drop the packet */ - NPMODE_ERROR, /* return an error */ - NPMODE_QUEUE /* save it up for later. */ -}; - -/* - * Statistics. - */ -struct pppstat { - unsigned int ppp_ibytes; /* bytes received */ - unsigned int ppp_ipackets; /* packets received */ - unsigned int ppp_ierrors; /* receive errors */ - unsigned int ppp_obytes; /* bytes sent */ - unsigned int ppp_opackets; /* packets sent */ - unsigned int ppp_oerrors; /* transmit errors */ -}; - -struct vjstat { - unsigned int vjs_packets; /* outbound packets */ - unsigned int vjs_compressed; /* outbound compressed packets */ - unsigned int vjs_searches; /* searches for connection state */ - unsigned int vjs_misses; /* times couldn't find conn. state */ - unsigned int vjs_uncompressedin; /* inbound uncompressed packets */ - unsigned int vjs_compressedin; /* inbound compressed packets */ - unsigned int vjs_errorin; /* inbound unknown type packets */ - unsigned int vjs_tossed; /* inbound packets tossed because of error */ -}; - -struct ppp_stats { - struct pppstat p; /* basic PPP statistics */ - struct vjstat vj; /* VJ header compression statistics */ -}; - -struct compstat { - unsigned int unc_bytes; /* total uncompressed bytes */ - unsigned int unc_packets; /* total uncompressed packets */ - unsigned int comp_bytes; /* compressed bytes */ - unsigned int comp_packets; /* compressed packets */ - unsigned int inc_bytes; /* incompressible bytes */ - unsigned int inc_packets; /* incompressible packets */ - unsigned int ratio; /* recent compression ratio << 8 */ -}; - -struct ppp_comp_stats { - struct compstat c; /* packet compression statistics */ - struct compstat d; /* packet decompression statistics */ -}; - -/* - * The following structure records the time in seconds since - * the last NP packet was sent or received. - */ -struct ppp_idle { - time_t xmit_idle; /* time since last NP packet sent */ - time_t recv_idle; /* time since last NP packet received */ -}; - -#ifndef __P -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif -#endif - -#endif /* _PPP_DEFS_H_ */ diff --git a/mdk-stage1/ppp/include/net/pppio.h b/mdk-stage1/ppp/include/net/pppio.h deleted file mode 100644 index 9db1ca9ab..000000000 --- a/mdk-stage1/ppp/include/net/pppio.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * pppio.h - ioctl and other misc. definitions for STREAMS modules. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -#define _PPPIO(n) (('p' << 8) + (n)) - -#define PPPIO_NEWPPA _PPPIO(130) /* allocate a new PPP unit */ -#define PPPIO_GETSTAT _PPPIO(131) /* get PPP statistics */ -#define PPPIO_GETCSTAT _PPPIO(132) /* get PPP compression stats */ -#define PPPIO_MTU _PPPIO(133) /* set max transmission unit */ -#define PPPIO_MRU _PPPIO(134) /* set max receive unit */ -#define PPPIO_CFLAGS _PPPIO(135) /* set/clear/get compression flags */ -#define PPPIO_XCOMP _PPPIO(136) /* alloc transmit compressor */ -#define PPPIO_RCOMP _PPPIO(137) /* alloc receive decompressor */ -#define PPPIO_XACCM _PPPIO(138) /* set transmit asyncmap */ -#define PPPIO_RACCM _PPPIO(139) /* set receive asyncmap */ -#define PPPIO_VJINIT _PPPIO(140) /* initialize VJ comp/decomp */ -#define PPPIO_ATTACH _PPPIO(141) /* attach to a ppa (without putmsg) */ -#define PPPIO_LASTMOD _PPPIO(142) /* mark last ppp module */ -#define PPPIO_GCLEAN _PPPIO(143) /* get 8-bit-clean flags */ -#define PPPIO_DEBUG _PPPIO(144) /* request debug information */ -#define PPPIO_BIND _PPPIO(145) /* bind to SAP */ -#define PPPIO_NPMODE _PPPIO(146) /* set mode for handling data pkts */ -#define PPPIO_GIDLE _PPPIO(147) /* get time since last data pkt */ -#define PPPIO_PASSFILT _PPPIO(148) /* set filter for packets to pass */ -#define PPPIO_ACTIVEFILT _PPPIO(149) /* set filter for "link active" pkts */ - -/* - * Values for PPPIO_CFLAGS - */ -#define COMP_AC 0x1 /* compress address/control */ -#define DECOMP_AC 0x2 /* decompress address/control */ -#define COMP_PROT 0x4 /* compress PPP protocol */ -#define DECOMP_PROT 0x8 /* decompress PPP protocol */ - -#define COMP_VJC 0x10 /* compress TCP/IP headers */ -#define COMP_VJCCID 0x20 /* compress connection ID as well */ -#define DECOMP_VJC 0x40 /* decompress TCP/IP headers */ -#define DECOMP_VJCCID 0x80 /* accept compressed connection ID */ - -#define CCP_ISOPEN 0x100 /* look at CCP packets */ -#define CCP_ISUP 0x200 /* do packet comp/decomp */ -#define CCP_ERROR 0x400 /* (status) error in packet decomp */ -#define CCP_FATALERROR 0x800 /* (status) fatal error ditto */ -#define CCP_COMP_RUN 0x1000 /* (status) seen CCP ack sent */ -#define CCP_DECOMP_RUN 0x2000 /* (status) seen CCP ack rcvd */ - -/* - * Values for 8-bit-clean flags. - */ -#define RCV_B7_0 1 /* have rcvd char with bit 7 = 0 */ -#define RCV_B7_1 2 /* have rcvd char with bit 7 = 1 */ -#define RCV_EVNP 4 /* have rcvd char with even parity */ -#define RCV_ODDP 8 /* have rcvd char with odd parity */ - -/* - * Values for the first byte of M_CTL messages passed between - * PPP modules. - */ -#define PPPCTL_OERROR 0xe0 /* output error [up] */ -#define PPPCTL_IERROR 0xe1 /* input error (e.g. FCS) [up] */ -#define PPPCTL_MTU 0xe2 /* set MTU [down] */ -#define PPPCTL_MRU 0xe3 /* set MRU [down] */ -#define PPPCTL_UNIT 0xe4 /* note PPP unit number [down] */ - -/* - * Values for the integer argument to PPPIO_DEBUG. - */ -#define PPPDBG_DUMP 0x10000 /* print out debug info now */ -#define PPPDBG_LOG 0x100 /* log various things */ -#define PPPDBG_DRIVER 0 /* identifies ppp driver as target */ -#define PPPDBG_IF 1 /* identifies ppp network i/f target */ -#define PPPDBG_COMP 2 /* identifies ppp compression target */ -#define PPPDBG_AHDLC 3 /* identifies ppp async hdlc target */ diff --git a/mdk-stage1/ppp/include/net/slcompress.h b/mdk-stage1/ppp/include/net/slcompress.h deleted file mode 100644 index 9e19bc0ed..000000000 --- a/mdk-stage1/ppp/include/net/slcompress.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Definitions for tcp compression routines. - * - * $Id$ - * - * Copyright (c) 1989 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. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. - */ - -#ifndef _SLCOMPRESS_H_ -#define _SLCOMPRESS_H_ - -#define MAX_STATES 16 /* must be > 2 and < 256 */ -#define MAX_HDR MLEN /* XXX 4bsd-ism: should really be 128 */ - -/* - * Compressed packet format: - * - * The first octet contains the packet type (top 3 bits), TCP - * 'push' bit, and flags that indicate which of the 4 TCP sequence - * numbers have changed (bottom 5 bits). The next octet is a - * conversation number that associates a saved IP/TCP header with - * the compressed packet. The next two octets are the TCP checksum - * from the original datagram. The next 0 to 15 octets are - * sequence number changes, one change per bit set in the header - * (there may be no changes and there are two special cases where - * the receiver implicitly knows what changed -- see below). - * - * There are 5 numbers which can change (they are always inserted - * in the following order): TCP urgent pointer, window, - * acknowlegement, sequence number and IP ID. (The urgent pointer - * is different from the others in that its value is sent, not the - * change in value.) Since typical use of SLIP links is biased - * toward small packets (see comments on MTU/MSS below), changes - * use a variable length coding with one octet for numbers in the - * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the - * range 256 - 65535 or 0. (If the change in sequence number or - * ack is more than 65535, an uncompressed packet is sent.) - */ - -/* - * Packet types (must not conflict with IP protocol version) - * - * The top nibble of the first octet is the packet type. There are - * three possible types: IP (not proto TCP or tcp with one of the - * control flags set); uncompressed TCP (a normal IP/TCP packet but - * with the 8-bit protocol field replaced by an 8-bit connection id -- - * this type of packet syncs the sender & receiver); and compressed - * TCP (described above). - * - * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and - * is logically part of the 4-bit "changes" field that follows. Top - * three bits are actual packet type. For backward compatibility - * and in the interest of conserving bits, numbers are chosen so the - * IP protocol version number (4) which normally appears in this nibble - * means "IP packet". - */ - -/* packet types */ -#define TYPE_IP 0x40 -#define TYPE_UNCOMPRESSED_TCP 0x70 -#define TYPE_COMPRESSED_TCP 0x80 -#define TYPE_ERROR 0x00 - -/* Bits in first octet of compressed packet */ -#define NEW_C 0x40 /* flag bits for what changed in a packet */ -#define NEW_I 0x20 -#define NEW_S 0x08 -#define NEW_A 0x04 -#define NEW_W 0x02 -#define NEW_U 0x01 - -/* reserved, special-case values of above */ -#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ -#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ -#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) - -#define TCP_PUSH_BIT 0x10 - - -/* - * "state" data for each active tcp conversation on the wire. This is - * basically a copy of the entire IP/TCP header from the last packet - * we saw from the conversation together with a small identifier - * the transmit & receive ends of the line use to locate saved header. - */ -struct cstate { - struct cstate *cs_next; /* next most recently used cstate (xmit only) */ - u_short cs_hlen; /* size of hdr (receive only) */ - u_char cs_id; /* connection # associated with this state */ - u_char cs_filler; - union { - char csu_hdr[MAX_HDR]; - struct ip csu_ip; /* ip/tcp hdr from most recent packet */ - } slcs_u; -}; -#define cs_ip slcs_u.csu_ip -#define cs_hdr slcs_u.csu_hdr - -/* - * all the state data for one serial line (we need one of these - * per line). - */ -struct slcompress { - struct cstate *last_cs; /* most recently used tstate */ - u_char last_recv; /* last rcvd conn. id */ - u_char last_xmit; /* last sent conn. id */ - u_short flags; -#ifndef SL_NO_STATS - int sls_packets; /* outbound packets */ - int sls_compressed; /* outbound compressed packets */ - int sls_searches; /* searches for connection state */ - int sls_misses; /* times couldn't find conn. state */ - int sls_uncompressedin; /* inbound uncompressed packets */ - int sls_compressedin; /* inbound compressed packets */ - int sls_errorin; /* inbound unknown type packets */ - int sls_tossed; /* inbound packets tossed because of error */ -#endif - struct cstate tstate[MAX_STATES]; /* xmit connection states */ - struct cstate rstate[MAX_STATES]; /* receive connection states */ -}; -/* flag values */ -#define SLF_TOSS 1 /* tossing rcvd frames because of input err */ - -void sl_compress_init __P((struct slcompress *)); -void sl_compress_setup __P((struct slcompress *, int)); -u_int sl_compress_tcp __P((struct mbuf *, - struct ip *, struct slcompress *, int)); -int sl_uncompress_tcp __P((u_char **, int, u_int, struct slcompress *)); -int sl_uncompress_tcp_core __P((u_char *, int, int, u_int, - struct slcompress *, u_char **, u_int *)); - -#endif /* _SLCOMPRESS_H_ */ diff --git a/mdk-stage1/ppp/include/net/vjcompress.h b/mdk-stage1/ppp/include/net/vjcompress.h deleted file mode 100644 index c64596926..000000000 --- a/mdk-stage1/ppp/include/net/vjcompress.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Definitions for tcp compression routines. - * - * $Id$ - * - * Copyright (c) 1989 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. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. - */ - -#ifndef _VJCOMPRESS_H_ -#define _VJCOMPRESS_H_ - -#define MAX_STATES 16 /* must be > 2 and < 256 */ -#define MAX_HDR 128 - -/* - * Compressed packet format: - * - * The first octet contains the packet type (top 3 bits), TCP - * 'push' bit, and flags that indicate which of the 4 TCP sequence - * numbers have changed (bottom 5 bits). The next octet is a - * conversation number that associates a saved IP/TCP header with - * the compressed packet. The next two octets are the TCP checksum - * from the original datagram. The next 0 to 15 octets are - * sequence number changes, one change per bit set in the header - * (there may be no changes and there are two special cases where - * the receiver implicitly knows what changed -- see below). - * - * There are 5 numbers which can change (they are always inserted - * in the following order): TCP urgent pointer, window, - * acknowlegement, sequence number and IP ID. (The urgent pointer - * is different from the others in that its value is sent, not the - * change in value.) Since typical use of SLIP links is biased - * toward small packets (see comments on MTU/MSS below), changes - * use a variable length coding with one octet for numbers in the - * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the - * range 256 - 65535 or 0. (If the change in sequence number or - * ack is more than 65535, an uncompressed packet is sent.) - */ - -/* - * Packet types (must not conflict with IP protocol version) - * - * The top nibble of the first octet is the packet type. There are - * three possible types: IP (not proto TCP or tcp with one of the - * control flags set); uncompressed TCP (a normal IP/TCP packet but - * with the 8-bit protocol field replaced by an 8-bit connection id -- - * this type of packet syncs the sender & receiver); and compressed - * TCP (described above). - * - * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and - * is logically part of the 4-bit "changes" field that follows. Top - * three bits are actual packet type. For backward compatibility - * and in the interest of conserving bits, numbers are chosen so the - * IP protocol version number (4) which normally appears in this nibble - * means "IP packet". - */ - -/* packet types */ -#define TYPE_IP 0x40 -#define TYPE_UNCOMPRESSED_TCP 0x70 -#define TYPE_COMPRESSED_TCP 0x80 -#define TYPE_ERROR 0x00 - -/* Bits in first octet of compressed packet */ -#define NEW_C 0x40 /* flag bits for what changed in a packet */ -#define NEW_I 0x20 -#define NEW_S 0x08 -#define NEW_A 0x04 -#define NEW_W 0x02 -#define NEW_U 0x01 - -/* reserved, special-case values of above */ -#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ -#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ -#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) - -#define TCP_PUSH_BIT 0x10 - - -/* - * "state" data for each active tcp conversation on the wire. This is - * basically a copy of the entire IP/TCP header from the last packet - * we saw from the conversation together with a small identifier - * the transmit & receive ends of the line use to locate saved header. - */ -struct cstate { - struct cstate *cs_next; /* next most recently used state (xmit only) */ - u_short cs_hlen; /* size of hdr (receive only) */ - u_char cs_id; /* connection # associated with this state */ - u_char cs_filler; - union { - char csu_hdr[MAX_HDR]; - struct ip csu_ip; /* ip/tcp hdr from most recent packet */ - } vjcs_u; -}; -#define cs_ip vjcs_u.csu_ip -#define cs_hdr vjcs_u.csu_hdr - -/* - * all the state data for one serial line (we need one of these per line). - */ -struct vjcompress { - struct cstate *last_cs; /* most recently used tstate */ - u_char last_recv; /* last rcvd conn. id */ - u_char last_xmit; /* last sent conn. id */ - u_short flags; -#ifndef VJ_NO_STATS - struct vjstat stats; -#endif - struct cstate tstate[MAX_STATES]; /* xmit connection states */ - struct cstate rstate[MAX_STATES]; /* receive connection states */ -}; - -/* flag values */ -#define VJF_TOSS 1 /* tossing rcvd frames because of input err */ - -extern void vj_compress_init __P((struct vjcompress *comp, int max_state)); -extern u_int vj_compress_tcp __P((struct ip *ip, u_int mlen, - struct vjcompress *comp, int compress_cid_flag, - u_char **vjhdrp)); -extern void vj_uncompress_err __P((struct vjcompress *comp)); -extern int vj_uncompress_uncomp __P((u_char *buf, int buflen, - struct vjcompress *comp)); -extern int vj_uncompress_tcp __P((u_char *buf, int buflen, int total_len, - struct vjcompress *comp, u_char **hdrp, - u_int *hlenp)); - -#endif /* _VJCOMPRESS_H_ */ diff --git a/mdk-stage1/ppp/include/pcap-int.h b/mdk-stage1/ppp/include/pcap-int.h deleted file mode 100644 index 323994929..000000000 --- a/mdk-stage1/ppp/include/pcap-int.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 1994, 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#) $Header$ (LBL) - */ - -#ifndef pcap_int_h -#define pcap_int_h - -#include <pcap.h> - -/* - * Savefile - */ -struct pcap_sf { - FILE *rfile; - int swapped; - int version_major; - int version_minor; - u_char *base; -}; - -struct pcap_md { - struct pcap_stat stat; - /*XXX*/ - int use_bpf; - u_long TotPkts; /* can't oflow for 79 hrs on ether */ - u_long TotAccepted; /* count accepted by filter */ - u_long TotDrops; /* count of dropped packets */ - long TotMissed; /* missed by i/f during this run */ - long OrigMissed; /* missed by i/f before this run */ -#ifdef linux - int pad; - int skip; - char *device; -#endif -}; - -struct pcap { - int fd; - int snapshot; - int linktype; - int tzoff; /* timezone offset */ - int offset; /* offset for proper alignment */ - - struct pcap_sf sf; - struct pcap_md md; - - /* - * Read buffer. - */ - int bufsize; - u_char *buffer; - u_char *bp; - int cc; - - /* - * Place holder for pcap_next(). - */ - u_char *pkt; - - - /* - * Placeholder for filter code if bpf not in kernel. - */ - struct bpf_program fcode; - - char errbuf[PCAP_ERRBUF_SIZE]; -}; - -int yylex(void); - -#ifndef min -#define min(a, b) ((a) > (b) ? (b) : (a)) -#endif - -/* XXX should these be in pcap.h? */ -int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *); -int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *); - -/* Ultrix pads to make everything line up on a nice boundary */ -#if defined(ultrix) || defined(__alpha) -#define PCAP_FDDIPAD 3 -#endif - -/* XXX */ -extern int pcap_fddipad; -#endif diff --git a/mdk-stage1/ppp/linux/Makefile.top b/mdk-stage1/ppp/linux/Makefile.top deleted file mode 100644 index fa34ce59f..000000000 --- a/mdk-stage1/ppp/linux/Makefile.top +++ /dev/null @@ -1,55 +0,0 @@ -# PPP top-level Makefile for Linux. - - -BINDIR = $(DESTDIR)/usr/sbin -MANDIR = $(DESTDIR)/usr/man -ETCDIR = $(DESTDIR)/etc/ppp - -# uid 0 = root -INSTALL= install - -all: - cd chat; $(MAKE) $(MFLAGS) all - cd pppd; $(MAKE) $(MFLAGS) all - cd pppstats; $(MAKE) $(MFLAGS) all - cd pppdump; $(MAKE) $(MFLAGS) all - -install: $(BINDIR) $(MANDIR)/man8 install-progs install-etcppp - -install-progs: - cd chat; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install - cd pppd; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install - cd pppstats; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install - cd pppdump; $(MAKE) BINDIR=$(BINDIR) MANDIR=$(MANDIR) $(MFLAGS) install - -install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ - $(ETCDIR)/chap-secrets - -$(ETCDIR)/options: - $(INSTALL) -c -m 644 etc.ppp/options $@ -$(ETCDIR)/pap-secrets: - $(INSTALL) -c -m 600 etc.ppp/pap-secrets $@ -$(ETCDIR)/chap-secrets: - $(INSTALL) -c -m 600 etc.ppp/chap-secrets $@ - -$(BINDIR): - $(INSTALL) -d -m 755 $@ -$(MANDIR)/man8: - $(INSTALL) -d -m 755 $@ -$(ETCDIR): - $(INSTALL) -d -m 755 $@ - -clean: - rm -f `find . -name '*.[oas]' -print` - rm -f `find . -name 'core' -print` - rm -f `find . -name '*~' -print` - cd chat; $(MAKE) clean - cd pppd; $(MAKE) clean - cd pppstats; $(MAKE) clean - cd pppdump; $(MAKE) clean - -dist-clean: clean - rm -f Makefile `find . -name Makefile -print` - -#kernel: -# cd linux; ./kinstall.sh diff --git a/mdk-stage1/ppp/modules/bsd-comp.c b/mdk-stage1/ppp/modules/bsd-comp.c deleted file mode 100644 index b1b9325c7..000000000 --- a/mdk-stage1/ppp/modules/bsd-comp.c +++ /dev/null @@ -1,1116 +0,0 @@ -/* Because this code is derived from the 4.3BSD compress source: - * - * - * Copyright (c) 1985, 1986 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * James A. Woods, derived from original work by Spencer Thomas - * and Joseph Orost. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * This version is for use with STREAMS under SunOS 4.x, - * Digital UNIX, AIX 4.x, and SVR4 systems including Solaris 2. - * - * $Id$ - */ - -#ifdef AIX4 -#include <net/net_globals.h> -#endif -#include <sys/param.h> -#include <sys/types.h> -#include <sys/stream.h> -#include <net/ppp_defs.h> -#include "ppp_mod.h" - -#ifdef SVR4 -#include <sys/byteorder.h> -#ifndef _BIG_ENDIAN -#define BSD_LITTLE_ENDIAN -#endif -#endif - -#ifdef __osf__ -#undef FIRST -#undef LAST -#define BSD_LITTLE_ENDIAN -#endif - -#define PACKETPTR mblk_t * -#include <net/ppp-comp.h> - -#if DO_BSD_COMPRESS - -/* - * PPP "BSD compress" compression - * The differences between this compression and the classic BSD LZW - * source are obvious from the requirement that the classic code worked - * with files while this handles arbitrarily long streams that - * are broken into packets. They are: - * - * When the code size expands, a block of junk is not emitted by - * the compressor and not expected by the decompressor. - * - * New codes are not necessarily assigned every time an old - * code is output by the compressor. This is because a packet - * end forces a code to be emitted, but does not imply that a - * new sequence has been seen. - * - * The compression ratio is checked at the first end of a packet - * after the appropriate gap. Besides simplifying and speeding - * things up, this makes it more likely that the transmitter - * and receiver will agree when the dictionary is cleared when - * compression is not going well. - */ - -/* - * A dictionary for doing BSD compress. - */ -struct bsd_db { - int totlen; /* length of this structure */ - u_int hsize; /* size of the hash table */ - u_char hshift; /* used in hash function */ - u_char n_bits; /* current bits/code */ - u_char maxbits; - u_char debug; - u_char unit; - u_short seqno; /* sequence number of next packet */ - u_int hdrlen; /* header length to preallocate */ - u_int mru; - u_int maxmaxcode; /* largest valid code */ - u_int max_ent; /* largest code in use */ - u_int in_count; /* uncompressed bytes, aged */ - u_int bytes_out; /* compressed bytes, aged */ - u_int ratio; /* recent compression ratio */ - u_int checkpoint; /* when to next check the ratio */ - u_int clear_count; /* times dictionary cleared */ - u_int incomp_count; /* incompressible packets */ - u_int incomp_bytes; /* incompressible bytes */ - u_int uncomp_count; /* uncompressed packets */ - u_int uncomp_bytes; /* uncompressed bytes */ - u_int comp_count; /* compressed packets */ - u_int comp_bytes; /* compressed bytes */ - u_short *lens; /* array of lengths of codes */ - struct bsd_dict { - union { /* hash value */ - u_int32_t fcode; - struct { -#ifdef BSD_LITTLE_ENDIAN - u_short prefix; /* preceding code */ - u_char suffix; /* last character of new code */ - u_char pad; -#else - u_char pad; - u_char suffix; /* last character of new code */ - u_short prefix; /* preceding code */ -#endif - } hs; - } f; - u_short codem1; /* output of hash table -1 */ - u_short cptr; /* map code to hash table entry */ - } dict[1]; -}; - -#define BSD_OVHD 2 /* BSD compress overhead/packet */ -#define BSD_INIT_BITS BSD_MIN_BITS - -static void *bsd_comp_alloc __P((u_char *options, int opt_len)); -static void *bsd_decomp_alloc __P((u_char *options, int opt_len)); -static void bsd_free __P((void *state)); -static int bsd_comp_init __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int debug)); -static int bsd_decomp_init __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); -static int bsd_compress __P((void *state, mblk_t **mret, - mblk_t *mp, int slen, int maxolen)); -static void bsd_incomp __P((void *state, mblk_t *dmsg)); -static int bsd_decompress __P((void *state, mblk_t *cmp, mblk_t **dmpp)); -static void bsd_reset __P((void *state)); -static void bsd_comp_stats __P((void *state, struct compstat *stats)); - -/* - * Procedures exported to ppp_comp.c. - */ -struct compressor ppp_bsd_compress = { - CI_BSD_COMPRESS, /* compress_proto */ - bsd_comp_alloc, /* comp_alloc */ - bsd_free, /* comp_free */ - bsd_comp_init, /* comp_init */ - bsd_reset, /* comp_reset */ - bsd_compress, /* compress */ - bsd_comp_stats, /* comp_stat */ - bsd_decomp_alloc, /* decomp_alloc */ - bsd_free, /* decomp_free */ - bsd_decomp_init, /* decomp_init */ - bsd_reset, /* decomp_reset */ - bsd_decompress, /* decompress */ - bsd_incomp, /* incomp */ - bsd_comp_stats, /* decomp_stat */ -}; - -/* - * the next two codes should not be changed lightly, as they must not - * lie within the contiguous general code space. - */ -#define CLEAR 256 /* table clear output code */ -#define FIRST 257 /* first free entry */ -#define LAST 255 - -#define MAXCODE(b) ((1 << (b)) - 1) -#define BADCODEM1 MAXCODE(BSD_MAX_BITS) - -#define BSD_HASH(prefix,suffix,hshift) ((((u_int32_t)(suffix)) << (hshift)) \ - ^ (u_int32_t)(prefix)) -#define BSD_KEY(prefix,suffix) ((((u_int32_t)(suffix)) << 16) \ - + (u_int32_t)(prefix)) - -#define CHECK_GAP 10000 /* Ratio check interval */ - -#define RATIO_SCALE_LOG 8 -#define RATIO_SCALE (1<<RATIO_SCALE_LOG) -#define RATIO_MAX (0x7fffffff>>RATIO_SCALE_LOG) - -#define DECOMP_CHUNK 256 - -/* - * clear the dictionary - */ -static void -bsd_clear(db) - struct bsd_db *db; -{ - db->clear_count++; - db->max_ent = FIRST-1; - db->n_bits = BSD_INIT_BITS; - db->ratio = 0; - db->bytes_out = 0; - db->in_count = 0; - db->checkpoint = CHECK_GAP; -} - -/* - * If the dictionary is full, then see if it is time to reset it. - * - * Compute the compression ratio using fixed-point arithmetic - * with 8 fractional bits. - * - * Since we have an infinite stream instead of a single file, - * watch only the local compression ratio. - * - * Since both peers must reset the dictionary at the same time even in - * the absence of CLEAR codes (while packets are incompressible), they - * must compute the same ratio. - */ -static int /* 1=output CLEAR */ -bsd_check(db) - struct bsd_db *db; -{ - u_int new_ratio; - - if (db->in_count >= db->checkpoint) { - /* age the ratio by limiting the size of the counts */ - if (db->in_count >= RATIO_MAX - || db->bytes_out >= RATIO_MAX) { - db->in_count -= db->in_count/4; - db->bytes_out -= db->bytes_out/4; - } - - db->checkpoint = db->in_count + CHECK_GAP; - - if (db->max_ent >= db->maxmaxcode) { - /* Reset the dictionary only if the ratio is worse, - * or if it looks as if it has been poisoned - * by incompressible data. - * - * This does not overflow, because - * db->in_count <= RATIO_MAX. - */ - new_ratio = db->in_count << RATIO_SCALE_LOG; - if (db->bytes_out != 0) - new_ratio /= db->bytes_out; - - if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE) { - bsd_clear(db); - return 1; - } - db->ratio = new_ratio; - } - } - return 0; -} - -/* - * Return statistics. - */ -static void -bsd_comp_stats(state, stats) - void *state; - struct compstat *stats; -{ - struct bsd_db *db = (struct bsd_db *) state; - u_int out; - - stats->unc_bytes = db->uncomp_bytes; - stats->unc_packets = db->uncomp_count; - stats->comp_bytes = db->comp_bytes; - stats->comp_packets = db->comp_count; - stats->inc_bytes = db->incomp_bytes; - stats->inc_packets = db->incomp_count; - stats->ratio = db->in_count; - out = db->bytes_out; - if (stats->ratio <= 0x7fffff) - stats->ratio <<= 8; - else - out >>= 8; - if (out != 0) - stats->ratio /= out; -} - -/* - * Reset state, as on a CCP ResetReq. - */ -static void -bsd_reset(state) - void *state; -{ - struct bsd_db *db = (struct bsd_db *) state; - - db->seqno = 0; - bsd_clear(db); - db->clear_count = 0; -} - -/* - * Allocate space for a (de) compressor. - */ -static void * -bsd_alloc(options, opt_len, decomp) - u_char *options; - int opt_len, decomp; -{ - int bits; - u_int newlen, hsize, hshift, maxmaxcode; - struct bsd_db *db; - - if (opt_len != 3 || options[0] != CI_BSD_COMPRESS || options[1] != 3 - || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION) - return NULL; - - bits = BSD_NBITS(options[2]); - switch (bits) { - case 9: /* needs 82152 for both directions */ - case 10: /* needs 84144 */ - case 11: /* needs 88240 */ - case 12: /* needs 96432 */ - hsize = 5003; - hshift = 4; - break; - case 13: /* needs 176784 */ - hsize = 9001; - hshift = 5; - break; - case 14: /* needs 353744 */ - hsize = 18013; - hshift = 6; - break; - case 15: /* needs 691440 */ - hsize = 35023; - hshift = 7; - break; - case 16: /* needs 1366160--far too much, */ - /* hsize = 69001; */ /* and 69001 is too big for cptr */ - /* hshift = 8; */ /* in struct bsd_db */ - /* break; */ - default: - return NULL; - } - - maxmaxcode = MAXCODE(bits); - newlen = sizeof(*db) + (hsize-1) * (sizeof(db->dict[0])); -#ifdef __osf__ - db = (struct bsd_db *) ALLOC_SLEEP(newlen); -#else - db = (struct bsd_db *) ALLOC_NOSLEEP(newlen); -#endif - if (!db) - return NULL; - bzero(db, sizeof(*db) - sizeof(db->dict)); - - if (!decomp) { - db->lens = NULL; - } else { -#ifdef __osf__ - db->lens = (u_short *) ALLOC_SLEEP((maxmaxcode+1) * sizeof(db->lens[0])); -#else - db->lens = (u_short *) ALLOC_NOSLEEP((maxmaxcode+1) * sizeof(db->lens[0])); -#endif - if (!db->lens) { - FREE(db, newlen); - return NULL; - } - } - - db->totlen = newlen; - db->hsize = hsize; - db->hshift = hshift; - db->maxmaxcode = maxmaxcode; - db->maxbits = bits; - - return (void *) db; -} - -static void -bsd_free(state) - void *state; -{ - struct bsd_db *db = (struct bsd_db *) state; - - if (db->lens) - FREE(db->lens, (db->maxmaxcode+1) * sizeof(db->lens[0])); - FREE(db, db->totlen); -} - -static void * -bsd_comp_alloc(options, opt_len) - u_char *options; - int opt_len; -{ - return bsd_alloc(options, opt_len, 0); -} - -static void * -bsd_decomp_alloc(options, opt_len) - u_char *options; - int opt_len; -{ - return bsd_alloc(options, opt_len, 1); -} - -/* - * Initialize the database. - */ -static int -bsd_init(db, options, opt_len, unit, hdrlen, mru, debug, decomp) - struct bsd_db *db; - u_char *options; - int opt_len, unit, hdrlen, mru, debug, decomp; -{ - int i; - - if (opt_len < CILEN_BSD_COMPRESS - || options[0] != CI_BSD_COMPRESS || options[1] != CILEN_BSD_COMPRESS - || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION - || BSD_NBITS(options[2]) != db->maxbits - || decomp && db->lens == NULL) - return 0; - - if (decomp) { - i = LAST+1; - while (i != 0) - db->lens[--i] = 1; - } - i = db->hsize; - while (i != 0) { - db->dict[--i].codem1 = BADCODEM1; - db->dict[i].cptr = 0; - } - - db->unit = unit; - db->hdrlen = hdrlen; - db->mru = mru; - if (debug) - db->debug = 1; - - bsd_reset(db); - - return 1; -} - -static int -bsd_comp_init(state, options, opt_len, unit, hdrlen, debug) - void *state; - u_char *options; - int opt_len, unit, hdrlen, debug; -{ - return bsd_init((struct bsd_db *) state, options, opt_len, - unit, hdrlen, 0, debug, 0); -} - -static int -bsd_decomp_init(state, options, opt_len, unit, hdrlen, mru, debug) - void *state; - u_char *options; - int opt_len, unit, hdrlen, mru, debug; -{ - return bsd_init((struct bsd_db *) state, options, opt_len, - unit, hdrlen, mru, debug, 1); -} - - -/* - * compress a packet - * One change from the BSD compress command is that when the - * code size expands, we do not output a bunch of padding. - * - * N.B. at present, we ignore the hdrlen specified in the comp_init call. - */ -static int /* new slen */ -bsd_compress(state, mretp, mp, slen, maxolen) - void *state; - mblk_t **mretp; /* return compressed mbuf chain here */ - mblk_t *mp; /* from here */ - int slen; /* uncompressed length */ - int maxolen; /* max compressed length */ -{ - struct bsd_db *db = (struct bsd_db *) state; - int hshift = db->hshift; - u_int max_ent = db->max_ent; - u_int n_bits = db->n_bits; - u_int bitno = 32; - u_int32_t accm = 0, fcode; - struct bsd_dict *dictp; - u_char c; - int hval, disp, ent, ilen; - mblk_t *np, *mret; - u_char *rptr, *wptr; - u_char *cp_end; - int olen; - mblk_t *m, **mnp; - -#define PUTBYTE(v) { \ - if (wptr) { \ - *wptr++ = (v); \ - if (wptr >= cp_end) { \ - m->b_wptr = wptr; \ - m = m->b_cont; \ - if (m) { \ - wptr = m->b_wptr; \ - cp_end = m->b_datap->db_lim; \ - } else \ - wptr = NULL; \ - } \ - } \ - ++olen; \ -} - -#define OUTPUT(ent) { \ - bitno -= n_bits; \ - accm |= ((ent) << bitno); \ - do { \ - PUTBYTE(accm >> 24); \ - accm <<= 8; \ - bitno += 8; \ - } while (bitno <= 24); \ -} - - /* - * First get the protocol and check that we're - * interested in this packet. - */ - *mretp = NULL; - rptr = mp->b_rptr; - if (rptr + PPP_HDRLEN > mp->b_wptr) { - if (!pullupmsg(mp, PPP_HDRLEN)) - return 0; - rptr = mp->b_rptr; - } - ent = PPP_PROTOCOL(rptr); /* get the protocol */ - if (ent < 0x21 || ent > 0xf9) - return 0; - - /* Don't generate compressed packets which are larger than - the uncompressed packet. */ - if (maxolen > slen) - maxolen = slen; - - /* Allocate enough message blocks to give maxolen total space. */ - mnp = &mret; - for (olen = maxolen; olen > 0; ) { - m = allocb((olen < 4096? olen: 4096), BPRI_MED); - *mnp = m; - if (m == NULL) { - if (mret != NULL) { - freemsg(mret); - mnp = &mret; - } - break; - } - mnp = &m->b_cont; - olen -= m->b_datap->db_lim - m->b_wptr; - } - *mnp = NULL; - - if ((m = mret) != NULL) { - wptr = m->b_wptr; - cp_end = m->b_datap->db_lim; - } else - wptr = cp_end = NULL; - olen = 0; - - /* - * Copy the PPP header over, changing the protocol, - * and install the 2-byte sequence number. - */ - if (wptr) { - wptr[0] = PPP_ADDRESS(rptr); - wptr[1] = PPP_CONTROL(rptr); - wptr[2] = 0; /* change the protocol */ - wptr[3] = PPP_COMP; - wptr[4] = db->seqno >> 8; - wptr[5] = db->seqno; - wptr += PPP_HDRLEN + BSD_OVHD; - } - ++db->seqno; - rptr += PPP_HDRLEN; - - slen = mp->b_wptr - rptr; - ilen = slen + 1; - np = mp->b_cont; - for (;;) { - if (slen <= 0) { - if (!np) - break; - rptr = np->b_rptr; - slen = np->b_wptr - rptr; - np = np->b_cont; - if (!slen) - continue; /* handle 0-length buffers */ - ilen += slen; - } - - slen--; - c = *rptr++; - fcode = BSD_KEY(ent, c); - hval = BSD_HASH(ent, c, hshift); - dictp = &db->dict[hval]; - - /* Validate and then check the entry. */ - if (dictp->codem1 >= max_ent) - goto nomatch; - if (dictp->f.fcode == fcode) { - ent = dictp->codem1+1; - continue; /* found (prefix,suffix) */ - } - - /* continue probing until a match or invalid entry */ - disp = (hval == 0) ? 1 : hval; - do { - hval += disp; - if (hval >= db->hsize) - hval -= db->hsize; - dictp = &db->dict[hval]; - if (dictp->codem1 >= max_ent) - goto nomatch; - } while (dictp->f.fcode != fcode); - ent = dictp->codem1 + 1; /* finally found (prefix,suffix) */ - continue; - - nomatch: - OUTPUT(ent); /* output the prefix */ - - /* code -> hashtable */ - if (max_ent < db->maxmaxcode) { - struct bsd_dict *dictp2; - /* expand code size if needed */ - if (max_ent >= MAXCODE(n_bits)) - db->n_bits = ++n_bits; - - /* Invalidate old hash table entry using - * this code, and then take it over. - */ - dictp2 = &db->dict[max_ent+1]; - if (db->dict[dictp2->cptr].codem1 == max_ent) - db->dict[dictp2->cptr].codem1 = BADCODEM1; - dictp2->cptr = hval; - dictp->codem1 = max_ent; - dictp->f.fcode = fcode; - - db->max_ent = ++max_ent; - } - ent = c; - } - - OUTPUT(ent); /* output the last code */ - db->bytes_out += olen; - db->in_count += ilen; - if (bitno < 32) - ++db->bytes_out; /* count complete bytes */ - - if (bsd_check(db)) - OUTPUT(CLEAR); /* do not count the CLEAR */ - - /* - * Pad dribble bits of last code with ones. - * Do not emit a completely useless byte of ones. - */ - if (bitno != 32) - PUTBYTE((accm | (0xff << (bitno-8))) >> 24); - - /* - * Increase code size if we would have without the packet - * boundary and as the decompressor will. - */ - if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) - db->n_bits++; - - db->uncomp_bytes += ilen; - ++db->uncomp_count; - if (olen + PPP_HDRLEN + BSD_OVHD > maxolen && mret != NULL) { - /* throw away the compressed stuff if it is longer than uncompressed */ - freemsg(mret); - mret = NULL; - ++db->incomp_count; - db->incomp_bytes += ilen; - } else if (wptr != NULL) { - m->b_wptr = wptr; - if (m->b_cont) { - freemsg(m->b_cont); - m->b_cont = NULL; - } - ++db->comp_count; - db->comp_bytes += olen + BSD_OVHD; - } - - *mretp = mret; - return olen + PPP_HDRLEN + BSD_OVHD; -#undef OUTPUT -#undef PUTBYTE -} - - -/* - * Update the "BSD Compress" dictionary on the receiver for - * incompressible data by pretending to compress the incoming data. - */ -static void -bsd_incomp(state, dmsg) - void *state; - mblk_t *dmsg; -{ - struct bsd_db *db = (struct bsd_db *) state; - u_int hshift = db->hshift; - u_int max_ent = db->max_ent; - u_int n_bits = db->n_bits; - struct bsd_dict *dictp; - u_int32_t fcode; - u_char c; - long hval, disp; - int slen, ilen; - u_int bitno = 7; - u_char *rptr; - u_int ent; - - rptr = dmsg->b_rptr; - if (rptr + PPP_HDRLEN > dmsg->b_wptr) { - if (!pullupmsg(dmsg, PPP_HDRLEN)) - return; - rptr = dmsg->b_rptr; - } - ent = PPP_PROTOCOL(rptr); /* get the protocol */ - if (ent < 0x21 || ent > 0xf9) - return; - - db->seqno++; - ilen = 1; /* count the protocol as 1 byte */ - rptr += PPP_HDRLEN; - for (;;) { - slen = dmsg->b_wptr - rptr; - if (slen <= 0) { - dmsg = dmsg->b_cont; - if (!dmsg) - break; - rptr = dmsg->b_rptr; - continue; /* skip zero-length buffers */ - } - ilen += slen; - - do { - c = *rptr++; - fcode = BSD_KEY(ent, c); - hval = BSD_HASH(ent, c, hshift); - dictp = &db->dict[hval]; - - /* validate and then check the entry */ - if (dictp->codem1 >= max_ent) - goto nomatch; - if (dictp->f.fcode == fcode) { - ent = dictp->codem1+1; - continue; /* found (prefix,suffix) */ - } - - /* continue probing until a match or invalid entry */ - disp = (hval == 0) ? 1 : hval; - do { - hval += disp; - if (hval >= db->hsize) - hval -= db->hsize; - dictp = &db->dict[hval]; - if (dictp->codem1 >= max_ent) - goto nomatch; - } while (dictp->f.fcode != fcode); - ent = dictp->codem1+1; - continue; /* finally found (prefix,suffix) */ - - nomatch: /* output (count) the prefix */ - bitno += n_bits; - - /* code -> hashtable */ - if (max_ent < db->maxmaxcode) { - struct bsd_dict *dictp2; - /* expand code size if needed */ - if (max_ent >= MAXCODE(n_bits)) - db->n_bits = ++n_bits; - - /* Invalidate previous hash table entry - * assigned this code, and then take it over. - */ - dictp2 = &db->dict[max_ent+1]; - if (db->dict[dictp2->cptr].codem1 == max_ent) - db->dict[dictp2->cptr].codem1 = BADCODEM1; - dictp2->cptr = hval; - dictp->codem1 = max_ent; - dictp->f.fcode = fcode; - - db->max_ent = ++max_ent; - db->lens[max_ent] = db->lens[ent]+1; - } - ent = c; - } while (--slen != 0); - } - bitno += n_bits; /* output (count) the last code */ - db->bytes_out += bitno/8; - db->in_count += ilen; - (void)bsd_check(db); - - ++db->incomp_count; - db->incomp_bytes += ilen; - ++db->uncomp_count; - db->uncomp_bytes += ilen; - - /* Increase code size if we would have without the packet - * boundary and as the decompressor will. - */ - if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) - db->n_bits++; -} - - -/* - * Decompress "BSD Compress" - * - * Because of patent problems, we return DECOMP_ERROR for errors - * found by inspecting the input data and for system problems, but - * DECOMP_FATALERROR for any errors which could possibly be said to - * be being detected "after" decompression. For DECOMP_ERROR, - * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be - * infringing a patent of Motorola's if we do, so we take CCP down - * instead. - * - * Given that the frame has the correct sequence number and a good FCS, - * errors such as invalid codes in the input most likely indicate a - * bug, so we return DECOMP_FATALERROR for them in order to turn off - * compression, even though they are detected by inspecting the input. - */ -static int -bsd_decompress(state, cmsg, dmpp) - void *state; - mblk_t *cmsg, **dmpp; -{ - struct bsd_db *db = (struct bsd_db *) state; - u_int max_ent = db->max_ent; - u_int32_t accm = 0; - u_int bitno = 32; /* 1st valid bit in accm */ - u_int n_bits = db->n_bits; - u_int tgtbitno = 32-n_bits; /* bitno when we have a code */ - struct bsd_dict *dictp; - int explen, i, seq, len; - u_int incode, oldcode, finchar; - u_char *p, *rptr, *wptr; - mblk_t *dmsg, *mret; - int adrs, ctrl, ilen; - int dlen, space, codelen, extra; - - /* - * Get at least the BSD Compress header in the first buffer - */ - rptr = cmsg->b_rptr; - if (rptr + PPP_HDRLEN + BSD_OVHD >= cmsg->b_wptr) { - if (!pullupmsg(cmsg, PPP_HDRLEN + BSD_OVHD + 1)) { - if (db->debug) - printf("bsd_decomp%d: failed to pullup\n", db->unit); - return DECOMP_ERROR; - } - rptr = cmsg->b_rptr; - } - - /* - * Save the address/control from the PPP header - * and then get the sequence number. - */ - adrs = PPP_ADDRESS(rptr); - ctrl = PPP_CONTROL(rptr); - rptr += PPP_HDRLEN; - seq = (rptr[0] << 8) + rptr[1]; - rptr += BSD_OVHD; - ilen = len = cmsg->b_wptr - rptr; - - /* - * Check the sequence number and give up if it is not what we expect. - */ - if (seq != db->seqno++) { - if (db->debug) - printf("bsd_decomp%d: bad sequence # %d, expected %d\n", - db->unit, seq, db->seqno - 1); - return DECOMP_ERROR; - } - - /* - * Allocate one message block to start with. - */ - if ((dmsg = allocb(DECOMP_CHUNK + db->hdrlen, BPRI_MED)) == NULL) - return DECOMP_ERROR; - mret = dmsg; - dmsg->b_wptr += db->hdrlen; - dmsg->b_rptr = wptr = dmsg->b_wptr; - - /* Fill in the ppp header, but not the last byte of the protocol - (that comes from the decompressed data). */ - wptr[0] = adrs; - wptr[1] = ctrl; - wptr[2] = 0; - wptr += PPP_HDRLEN - 1; - space = dmsg->b_datap->db_lim - wptr; - - oldcode = CLEAR; - explen = 0; - for (;;) { - if (len == 0) { - cmsg = cmsg->b_cont; - if (!cmsg) /* quit at end of message */ - break; - rptr = cmsg->b_rptr; - len = cmsg->b_wptr - rptr; - ilen += len; - continue; /* handle 0-length buffers */ - } - - /* - * Accumulate bytes until we have a complete code. - * Then get the next code, relying on the 32-bit, - * unsigned accm to mask the result. - */ - bitno -= 8; - accm |= *rptr++ << bitno; - --len; - if (tgtbitno < bitno) - continue; - incode = accm >> tgtbitno; - accm <<= n_bits; - bitno += n_bits; - - if (incode == CLEAR) { - /* - * The dictionary must only be cleared at - * the end of a packet. But there could be an - * empty message block at the end. - */ - if (len > 0 || cmsg->b_cont != 0) { - if (cmsg->b_cont) - len += msgdsize(cmsg->b_cont); - if (len > 0) { - freemsg(dmsg); - if (db->debug) - printf("bsd_decomp%d: bad CLEAR\n", db->unit); - return DECOMP_FATALERROR; - } - } - bsd_clear(db); - explen = ilen = 0; - break; - } - - if (incode > max_ent + 2 || incode > db->maxmaxcode - || incode > max_ent && oldcode == CLEAR) { - freemsg(dmsg); - if (db->debug) { - printf("bsd_decomp%d: bad code 0x%x oldcode=0x%x ", - db->unit, incode, oldcode); - printf("max_ent=0x%x dlen=%d seqno=%d\n", - max_ent, dlen, db->seqno); - } - return DECOMP_FATALERROR; /* probably a bug */ - } - - /* Special case for KwKwK string. */ - if (incode > max_ent) { - finchar = oldcode; - extra = 1; - } else { - finchar = incode; - extra = 0; - } - - codelen = db->lens[finchar]; - explen += codelen + extra; - if (explen > db->mru + 1) { - freemsg(dmsg); - if (db->debug) - printf("bsd_decomp%d: ran out of mru\n", db->unit); - return DECOMP_FATALERROR; - } - - /* - * Decode this code and install it in the decompressed buffer. - */ - space -= codelen + extra; - if (space < 0) { - /* Allocate another message block. */ - dmsg->b_wptr = wptr; - dlen = codelen + extra; - if (dlen < DECOMP_CHUNK) - dlen = DECOMP_CHUNK; - if ((dmsg->b_cont = allocb(dlen, BPRI_MED)) == NULL) { - freemsg(dmsg); - return DECOMP_ERROR; - } - dmsg = dmsg->b_cont; - wptr = dmsg->b_wptr; - space = dmsg->b_datap->db_lim - wptr - codelen - extra; - } - p = (wptr += codelen); - while (finchar > LAST) { - dictp = &db->dict[db->dict[finchar].cptr]; -#ifdef DEBUG - --codelen; - if (codelen <= 0) { - freemsg(dmsg); - printf("bsd_decomp%d: fell off end of chain ", db->unit); - printf("0x%x at 0x%x by 0x%x, max_ent=0x%x\n", - incode, finchar, db->dict[finchar].cptr, max_ent); - return DECOMP_FATALERROR; - } - if (dictp->codem1 != finchar-1) { - freemsg(dmsg); - printf("bsd_decomp%d: bad code chain 0x%x finchar=0x%x ", - db->unit, incode, finchar); - printf("oldcode=0x%x cptr=0x%x codem1=0x%x\n", oldcode, - db->dict[finchar].cptr, dictp->codem1); - return DECOMP_FATALERROR; - } -#endif - *--p = dictp->f.hs.suffix; - finchar = dictp->f.hs.prefix; - } - *--p = finchar; - -#ifdef DEBUG - if (--codelen != 0) - printf("bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%x\n", - db->unit, codelen, incode, max_ent); -#endif - - if (extra) /* the KwKwK case again */ - *wptr++ = finchar; - - /* - * If not first code in a packet, and - * if not out of code space, then allocate a new code. - * - * Keep the hash table correct so it can be used - * with uncompressed packets. - */ - if (oldcode != CLEAR && max_ent < db->maxmaxcode) { - struct bsd_dict *dictp2; - u_int32_t fcode; - int hval, disp; - - fcode = BSD_KEY(oldcode,finchar); - hval = BSD_HASH(oldcode,finchar,db->hshift); - dictp = &db->dict[hval]; - - /* look for a free hash table entry */ - if (dictp->codem1 < max_ent) { - disp = (hval == 0) ? 1 : hval; - do { - hval += disp; - if (hval >= db->hsize) - hval -= db->hsize; - dictp = &db->dict[hval]; - } while (dictp->codem1 < max_ent); - } - - /* - * Invalidate previous hash table entry - * assigned this code, and then take it over - */ - dictp2 = &db->dict[max_ent+1]; - if (db->dict[dictp2->cptr].codem1 == max_ent) { - db->dict[dictp2->cptr].codem1 = BADCODEM1; - } - dictp2->cptr = hval; - dictp->codem1 = max_ent; - dictp->f.fcode = fcode; - - db->max_ent = ++max_ent; - db->lens[max_ent] = db->lens[oldcode]+1; - - /* Expand code size if needed. */ - if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) { - db->n_bits = ++n_bits; - tgtbitno = 32-n_bits; - } - } - oldcode = incode; - } - dmsg->b_wptr = wptr; - - /* - * Keep the checkpoint right so that incompressible packets - * clear the dictionary at the right times. - */ - db->bytes_out += ilen; - db->in_count += explen; - if (bsd_check(db) && db->debug) { - printf("bsd_decomp%d: peer should have cleared dictionary\n", - db->unit); - } - - ++db->comp_count; - db->comp_bytes += ilen + BSD_OVHD; - ++db->uncomp_count; - db->uncomp_bytes += explen; - - *dmpp = mret; - return DECOMP_OK; -} -#endif /* DO_BSD_COMPRESS */ diff --git a/mdk-stage1/ppp/modules/deflate.c b/mdk-stage1/ppp/modules/deflate.c deleted file mode 100644 index 1b9054412..000000000 --- a/mdk-stage1/ppp/modules/deflate.c +++ /dev/null @@ -1,760 +0,0 @@ -/* - * ppp_deflate.c - interface the zlib procedures for Deflate compression - * and decompression (as used by gzip) to the PPP code. - * This version is for use with STREAMS under SunOS 4.x, Solaris 2, - * SVR4, OSF/1 and AIX 4.x. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -#ifdef AIX4 -#include <net/net_globals.h> -#endif -#include <sys/param.h> -#include <sys/types.h> -#include <sys/stream.h> -#include <net/ppp_defs.h> -#include "ppp_mod.h" - -#define PACKETPTR mblk_t * -#include <net/ppp-comp.h> - -#ifdef __osf__ -#include "zlib.h" -#else -#include "../common/zlib.h" -#endif - -#if DO_DEFLATE - -#define DEFLATE_DEBUG 1 - -/* - * State for a Deflate (de)compressor. - */ -struct deflate_state { - int seqno; - int w_size; - int unit; - int hdrlen; - int mru; - int debug; - z_stream strm; - struct compstat stats; -}; - -#define DEFLATE_OVHD 2 /* Deflate overhead/packet */ - -static void *z_alloc __P((void *, u_int items, u_int size)); -static void *z_alloc_init __P((void *, u_int items, u_int size)); -static void z_free __P((void *, void *ptr)); -static void *z_comp_alloc __P((u_char *options, int opt_len)); -static void *z_decomp_alloc __P((u_char *options, int opt_len)); -static void z_comp_free __P((void *state)); -static void z_decomp_free __P((void *state)); -static int z_comp_init __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int debug)); -static int z_decomp_init __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); -static int z_compress __P((void *state, mblk_t **mret, - mblk_t *mp, int slen, int maxolen)); -static void z_incomp __P((void *state, mblk_t *dmsg)); -static int z_decompress __P((void *state, mblk_t *cmp, - mblk_t **dmpp)); -static void z_comp_reset __P((void *state)); -static void z_decomp_reset __P((void *state)); -static void z_comp_stats __P((void *state, struct compstat *stats)); - -/* - * Procedures exported to ppp_comp.c. - */ -struct compressor ppp_deflate = { - CI_DEFLATE, /* compress_proto */ - z_comp_alloc, /* comp_alloc */ - z_comp_free, /* comp_free */ - z_comp_init, /* comp_init */ - z_comp_reset, /* comp_reset */ - z_compress, /* compress */ - z_comp_stats, /* comp_stat */ - z_decomp_alloc, /* decomp_alloc */ - z_decomp_free, /* decomp_free */ - z_decomp_init, /* decomp_init */ - z_decomp_reset, /* decomp_reset */ - z_decompress, /* decompress */ - z_incomp, /* incomp */ - z_comp_stats, /* decomp_stat */ -}; - -struct compressor ppp_deflate_draft = { - CI_DEFLATE_DRAFT, /* compress_proto */ - z_comp_alloc, /* comp_alloc */ - z_comp_free, /* comp_free */ - z_comp_init, /* comp_init */ - z_comp_reset, /* comp_reset */ - z_compress, /* compress */ - z_comp_stats, /* comp_stat */ - z_decomp_alloc, /* decomp_alloc */ - z_decomp_free, /* decomp_free */ - z_decomp_init, /* decomp_init */ - z_decomp_reset, /* decomp_reset */ - z_decompress, /* decompress */ - z_incomp, /* incomp */ - z_comp_stats, /* decomp_stat */ -}; - -#define DECOMP_CHUNK 512 - -/* - * Space allocation and freeing routines for use by zlib routines. - */ -struct zchunk { - u_int size; - u_int guard; -}; - -#define GUARD_MAGIC 0x77a6011a - -static void * -z_alloc_init(notused, items, size) - void *notused; - u_int items, size; -{ - struct zchunk *z; - - size = items * size + sizeof(struct zchunk); -#ifdef __osf__ - z = (struct zchunk *) ALLOC_SLEEP(size); -#else - z = (struct zchunk *) ALLOC_NOSLEEP(size); -#endif - z->size = size; - z->guard = GUARD_MAGIC; - return (void *) (z + 1); -} - -static void * -z_alloc(notused, items, size) - void *notused; - u_int items, size; -{ - struct zchunk *z; - - size = items * size + sizeof(struct zchunk); - z = (struct zchunk *) ALLOC_NOSLEEP(size); - z->size = size; - z->guard = GUARD_MAGIC; - return (void *) (z + 1); -} - -static void -z_free(notused, ptr) - void *notused; - void *ptr; -{ - struct zchunk *z = ((struct zchunk *) ptr) - 1; - - if (z->guard != GUARD_MAGIC) { - printf("ppp: z_free of corrupted chunk at %x (%x, %x)\n", - z, z->size, z->guard); - return; - } - FREE(z, z->size); -} - -/* - * Allocate space for a compressor. - */ -static void * -z_comp_alloc(options, opt_len) - u_char *options; - int opt_len; -{ - struct deflate_state *state; - int w_size; - - if (opt_len != CILEN_DEFLATE - || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) - || options[1] != CILEN_DEFLATE - || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL - || options[3] != DEFLATE_CHK_SEQUENCE) - return NULL; - w_size = DEFLATE_SIZE(options[2]); - /* - * N.B. the 9 below should be DEFLATE_MIN_SIZE (8), but using - * 8 will cause kernel crashes because of a bug in zlib. - */ - if (w_size < 9 || w_size > DEFLATE_MAX_SIZE) - return NULL; - - -#ifdef __osf__ - state = (struct deflate_state *) ALLOC_SLEEP(sizeof(*state)); -#else - state = (struct deflate_state *) ALLOC_NOSLEEP(sizeof(*state)); -#endif - - if (state == NULL) - return NULL; - - state->strm.next_in = NULL; - state->strm.zalloc = (alloc_func) z_alloc_init; - state->strm.zfree = (free_func) z_free; - if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL, - -w_size, 8, Z_DEFAULT_STRATEGY) != Z_OK) { - FREE(state, sizeof(*state)); - return NULL; - } - - state->strm.zalloc = (alloc_func) z_alloc; - state->w_size = w_size; - bzero(&state->stats, sizeof(state->stats)); - return (void *) state; -} - -static void -z_comp_free(arg) - void *arg; -{ - struct deflate_state *state = (struct deflate_state *) arg; - - deflateEnd(&state->strm); - FREE(state, sizeof(*state)); -} - -static int -z_comp_init(arg, options, opt_len, unit, hdrlen, debug) - void *arg; - u_char *options; - int opt_len, unit, hdrlen, debug; -{ - struct deflate_state *state = (struct deflate_state *) arg; - - if (opt_len < CILEN_DEFLATE - || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) - || options[1] != CILEN_DEFLATE - || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL - || DEFLATE_SIZE(options[2]) != state->w_size - || options[3] != DEFLATE_CHK_SEQUENCE) - return 0; - - state->seqno = 0; - state->unit = unit; - state->hdrlen = hdrlen; - state->debug = debug; - - deflateReset(&state->strm); - - return 1; -} - -static void -z_comp_reset(arg) - void *arg; -{ - struct deflate_state *state = (struct deflate_state *) arg; - - state->seqno = 0; - deflateReset(&state->strm); -} - -static int -z_compress(arg, mret, mp, orig_len, maxolen) - void *arg; - mblk_t **mret; /* compressed packet (out) */ - mblk_t *mp; /* uncompressed packet (in) */ - int orig_len, maxolen; -{ - struct deflate_state *state = (struct deflate_state *) arg; - u_char *rptr, *wptr; - int proto, olen, wspace, r, flush; - mblk_t *m; - - /* - * Check that the protocol is in the range we handle. - */ - *mret = NULL; - rptr = mp->b_rptr; - if (rptr + PPP_HDRLEN > mp->b_wptr) { - if (!pullupmsg(mp, PPP_HDRLEN)) - return 0; - rptr = mp->b_rptr; - } - proto = PPP_PROTOCOL(rptr); - if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) - return orig_len; - - /* Allocate one mblk initially. */ - if (maxolen > orig_len) - maxolen = orig_len; - if (maxolen <= PPP_HDRLEN + 2) { - wspace = 0; - m = NULL; - } else { - wspace = maxolen + state->hdrlen; - if (wspace > 4096) - wspace = 4096; - m = allocb(wspace, BPRI_MED); - } - if (m != NULL) { - *mret = m; - if (state->hdrlen + PPP_HDRLEN + 2 < wspace) { - m->b_rptr += state->hdrlen; - m->b_wptr = m->b_rptr; - wspace -= state->hdrlen; - } - wptr = m->b_wptr; - - /* - * Copy over the PPP header and store the 2-byte sequence number. - */ - wptr[0] = PPP_ADDRESS(rptr); - wptr[1] = PPP_CONTROL(rptr); - wptr[2] = PPP_COMP >> 8; - wptr[3] = PPP_COMP; - wptr += PPP_HDRLEN; - wptr[0] = state->seqno >> 8; - wptr[1] = state->seqno; - wptr += 2; - state->strm.next_out = wptr; - state->strm.avail_out = wspace - (PPP_HDRLEN + 2); - } else { - state->strm.next_out = NULL; - state->strm.avail_out = 1000000; - } - ++state->seqno; - - rptr += (proto > 0xff)? 2: 3; /* skip 1st proto byte if 0 */ - state->strm.next_in = rptr; - state->strm.avail_in = mp->b_wptr - rptr; - mp = mp->b_cont; - flush = (mp == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH; - olen = 0; - for (;;) { - r = deflate(&state->strm, flush); - if (r != Z_OK) { - printf("z_compress: deflate returned %d (%s)\n", - r, (state->strm.msg? state->strm.msg: "")); - break; - } - if (flush != Z_NO_FLUSH && state->strm.avail_out != 0) - break; /* all done */ - if (state->strm.avail_in == 0 && mp != NULL) { - state->strm.next_in = mp->b_rptr; - state->strm.avail_in = mp->b_wptr - mp->b_rptr; - mp = mp->b_cont; - if (mp == NULL) - flush = Z_PACKET_FLUSH; - } - if (state->strm.avail_out == 0) { - if (m != NULL) { - m->b_wptr += wspace; - olen += wspace; - wspace = maxolen - olen; - if (wspace <= 0) { - wspace = 0; - m->b_cont = NULL; - } else { - if (wspace < 32) - wspace = 32; - else if (wspace > 4096) - wspace = 4096; - m->b_cont = allocb(wspace, BPRI_MED); - } - m = m->b_cont; - if (m != NULL) { - state->strm.next_out = m->b_wptr; - state->strm.avail_out = wspace; - } - } - if (m == NULL) { - state->strm.next_out = NULL; - state->strm.avail_out = 1000000; - } - } - } - if (m != NULL) { - m->b_wptr += wspace - state->strm.avail_out; - olen += wspace - state->strm.avail_out; - } - - /* - * See if we managed to reduce the size of the packet. - */ - if (olen < orig_len && m != NULL) { - state->stats.comp_bytes += olen; - state->stats.comp_packets++; - } else { - if (*mret != NULL) { - freemsg(*mret); - *mret = NULL; - } - state->stats.inc_bytes += orig_len; - state->stats.inc_packets++; - olen = orig_len; - } - state->stats.unc_bytes += orig_len; - state->stats.unc_packets++; - - return olen; -} - -static void -z_comp_stats(arg, stats) - void *arg; - struct compstat *stats; -{ - struct deflate_state *state = (struct deflate_state *) arg; - u_int out; - - *stats = state->stats; - stats->ratio = stats->unc_bytes; - out = stats->comp_bytes + stats->unc_bytes; - if (stats->ratio <= 0x7ffffff) - stats->ratio <<= 8; - else - out >>= 8; - if (out != 0) - stats->ratio /= out; -} - -/* - * Allocate space for a decompressor. - */ -static void * -z_decomp_alloc(options, opt_len) - u_char *options; - int opt_len; -{ - struct deflate_state *state; - int w_size; - - if (opt_len != CILEN_DEFLATE - || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) - || options[1] != CILEN_DEFLATE - || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL - || options[3] != DEFLATE_CHK_SEQUENCE) - return NULL; - w_size = DEFLATE_SIZE(options[2]); - /* - * N.B. the 9 below should be DEFLATE_MIN_SIZE (8), but using - * 8 will cause kernel crashes because of a bug in zlib. - */ - if (w_size < 9 || w_size > DEFLATE_MAX_SIZE) - return NULL; - -#ifdef __osf__ - state = (struct deflate_state *) ALLOC_SLEEP(sizeof(*state)); -#else - state = (struct deflate_state *) ALLOC_NOSLEEP(sizeof(*state)); -#endif - if (state == NULL) - return NULL; - - state->strm.next_out = NULL; - state->strm.zalloc = (alloc_func) z_alloc_init; - state->strm.zfree = (free_func) z_free; - if (inflateInit2(&state->strm, -w_size) != Z_OK) { - FREE(state, sizeof(*state)); - return NULL; - } - - state->strm.zalloc = (alloc_func) z_alloc; - state->w_size = w_size; - bzero(&state->stats, sizeof(state->stats)); - return (void *) state; -} - -static void -z_decomp_free(arg) - void *arg; -{ - struct deflate_state *state = (struct deflate_state *) arg; - - inflateEnd(&state->strm); - FREE(state, sizeof(*state)); -} - -static int -z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug) - void *arg; - u_char *options; - int opt_len, unit, hdrlen, mru, debug; -{ - struct deflate_state *state = (struct deflate_state *) arg; - - if (opt_len < CILEN_DEFLATE - || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) - || options[1] != CILEN_DEFLATE - || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL - || DEFLATE_SIZE(options[2]) != state->w_size - || options[3] != DEFLATE_CHK_SEQUENCE) - return 0; - - state->seqno = 0; - state->unit = unit; - state->hdrlen = hdrlen; - state->debug = debug; - state->mru = mru; - - inflateReset(&state->strm); - - return 1; -} - -static void -z_decomp_reset(arg) - void *arg; -{ - struct deflate_state *state = (struct deflate_state *) arg; - - state->seqno = 0; - inflateReset(&state->strm); -} - -/* - * Decompress a Deflate-compressed packet. - * - * Because of patent problems, we return DECOMP_ERROR for errors - * found by inspecting the input data and for system problems, but - * DECOMP_FATALERROR for any errors which could possibly be said to - * be being detected "after" decompression. For DECOMP_ERROR, - * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be - * infringing a patent of Motorola's if we do, so we take CCP down - * instead. - * - * Given that the frame has the correct sequence number and a good FCS, - * errors such as invalid codes in the input most likely indicate a - * bug, so we return DECOMP_FATALERROR for them in order to turn off - * compression, even though they are detected by inspecting the input. - */ -static int -z_decompress(arg, mi, mop) - void *arg; - mblk_t *mi, **mop; -{ - struct deflate_state *state = (struct deflate_state *) arg; - mblk_t *mo, *mo_head; - u_char *rptr, *wptr; - int rlen, olen, ospace; - int seq, i, flush, r, decode_proto; - u_char hdr[PPP_HDRLEN + DEFLATE_OVHD]; - - *mop = NULL; - rptr = mi->b_rptr; - for (i = 0; i < PPP_HDRLEN + DEFLATE_OVHD; ++i) { - while (rptr >= mi->b_wptr) { - mi = mi->b_cont; - if (mi == NULL) - return DECOMP_ERROR; - rptr = mi->b_rptr; - } - hdr[i] = *rptr++; - } - - /* Check the sequence number. */ - seq = (hdr[PPP_HDRLEN] << 8) + hdr[PPP_HDRLEN+1]; - if (seq != state->seqno) { -#if !DEFLATE_DEBUG - if (state->debug) -#endif - printf("z_decompress%d: bad seq # %d, expected %d\n", - state->unit, seq, state->seqno); - return DECOMP_ERROR; - } - ++state->seqno; - - /* Allocate an output message block. */ - mo = allocb(DECOMP_CHUNK + state->hdrlen, BPRI_MED); - if (mo == NULL) - return DECOMP_ERROR; - mo_head = mo; - mo->b_cont = NULL; - mo->b_rptr += state->hdrlen; - mo->b_wptr = wptr = mo->b_rptr; - ospace = DECOMP_CHUNK; - olen = 0; - - /* - * Fill in the first part of the PPP header. The protocol field - * comes from the decompressed data. - */ - wptr[0] = PPP_ADDRESS(hdr); - wptr[1] = PPP_CONTROL(hdr); - wptr[2] = 0; - - /* - * Set up to call inflate. We set avail_out to 1 initially so we can - * look at the first byte of the output and decide whether we have - * a 1-byte or 2-byte protocol field. - */ - state->strm.next_in = rptr; - state->strm.avail_in = mi->b_wptr - rptr; - mi = mi->b_cont; - flush = (mi == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH; - rlen = state->strm.avail_in + PPP_HDRLEN + DEFLATE_OVHD; - state->strm.next_out = wptr + 3; - state->strm.avail_out = 1; - decode_proto = 1; - - /* - * Call inflate, supplying more input or output as needed. - */ - for (;;) { - r = inflate(&state->strm, flush); - if (r != Z_OK) { -#if !DEFLATE_DEBUG - if (state->debug) -#endif - printf("z_decompress%d: inflate returned %d (%s)\n", - state->unit, r, (state->strm.msg? state->strm.msg: "")); - freemsg(mo_head); - return DECOMP_FATALERROR; - } - if (flush != Z_NO_FLUSH && state->strm.avail_out != 0) - break; /* all done */ - if (state->strm.avail_in == 0 && mi != NULL) { - state->strm.next_in = mi->b_rptr; - state->strm.avail_in = mi->b_wptr - mi->b_rptr; - rlen += state->strm.avail_in; - mi = mi->b_cont; - if (mi == NULL) - flush = Z_PACKET_FLUSH; - } - if (state->strm.avail_out == 0) { - if (decode_proto) { - state->strm.avail_out = ospace - PPP_HDRLEN; - if ((wptr[3] & 1) == 0) { - /* 2-byte protocol field */ - wptr[2] = wptr[3]; - --state->strm.next_out; - ++state->strm.avail_out; - } - decode_proto = 0; - } else { - mo->b_wptr += ospace; - olen += ospace; - mo->b_cont = allocb(DECOMP_CHUNK, BPRI_MED); - mo = mo->b_cont; - if (mo == NULL) { - freemsg(mo_head); - return DECOMP_ERROR; - } - state->strm.next_out = mo->b_rptr; - state->strm.avail_out = ospace = DECOMP_CHUNK; - } - } - } - if (decode_proto) { - freemsg(mo_head); - return DECOMP_ERROR; - } - mo->b_wptr += ospace - state->strm.avail_out; - olen += ospace - state->strm.avail_out; - -#if DEFLATE_DEBUG - if (olen > state->mru + PPP_HDRLEN) - printf("ppp_deflate%d: exceeded mru (%d > %d)\n", - state->unit, olen, state->mru + PPP_HDRLEN); -#endif - - state->stats.unc_bytes += olen; - state->stats.unc_packets++; - state->stats.comp_bytes += rlen; - state->stats.comp_packets++; - - *mop = mo_head; - return DECOMP_OK; -} - -/* - * Incompressible data has arrived - add it to the history. - */ -static void -z_incomp(arg, mi) - void *arg; - mblk_t *mi; -{ - struct deflate_state *state = (struct deflate_state *) arg; - u_char *rptr; - int rlen, proto, r; - - /* - * Check that the protocol is one we handle. - */ - rptr = mi->b_rptr; - if (rptr + PPP_HDRLEN > mi->b_wptr) { - if (!pullupmsg(mi, PPP_HDRLEN)) - return; - rptr = mi->b_rptr; - } - proto = PPP_PROTOCOL(rptr); - if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) - return; - - ++state->seqno; - - /* - * Iterate through the message blocks, adding the characters in them - * to the decompressor's history. For the first block, we start - * at the either the 1st or 2nd byte of the protocol field, - * depending on whether the protocol value is compressible. - */ - rlen = mi->b_wptr - mi->b_rptr; - state->strm.next_in = rptr + 3; - state->strm.avail_in = rlen - 3; - if (proto > 0xff) { - --state->strm.next_in; - ++state->strm.avail_in; - } - for (;;) { - r = inflateIncomp(&state->strm); - if (r != Z_OK) { - /* gak! */ -#if !DEFLATE_DEBUG - if (state->debug) -#endif - printf("z_incomp%d: inflateIncomp returned %d (%s)\n", - state->unit, r, (state->strm.msg? state->strm.msg: "")); - return; - } - mi = mi->b_cont; - if (mi == NULL) - break; - state->strm.next_in = mi->b_rptr; - state->strm.avail_in = mi->b_wptr - mi->b_rptr; - rlen += state->strm.avail_in; - } - - /* - * Update stats. - */ - state->stats.inc_bytes += rlen; - state->stats.inc_packets++; - state->stats.unc_bytes += rlen; - state->stats.unc_packets++; -} - -#endif /* DO_DEFLATE */ diff --git a/mdk-stage1/ppp/modules/if_ppp.c b/mdk-stage1/ppp/modules/if_ppp.c deleted file mode 100644 index 14e89eb4a..000000000 --- a/mdk-stage1/ppp/modules/if_ppp.c +++ /dev/null @@ -1,865 +0,0 @@ -/* - * if_ppp.c - a network interface connected to a STREAMS module. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -/* - * This file is used under SunOS 4 and Digital UNIX. - * - * This file provides the glue between PPP and IP. - */ - -#define INET 1 - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/errno.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <net/if.h> -#include <net/netisr.h> -#include <net/ppp_defs.h> -#include <net/pppio.h> -#include <netinet/in.h> -#include <netinet/in_var.h> -#ifdef __osf__ -#include <sys/ioctl.h> -#include <net/if_types.h> -#else -#include <sys/sockio.h> -#endif -#include "ppp_mod.h" - -#include <sys/stream.h> - -#ifdef SNIT_SUPPORT -#include <sys/time.h> -#include <net/nit_if.h> -#include <netinet/if_ether.h> -#endif - -#ifdef __osf__ -#define SIOCSIFMTU SIOCSIPMTU -#define SIOCGIFMTU SIOCRIPMTU -#define IFA_ADDR(ifa) (*(ifa)->ifa_addr) -#else -#define IFA_ADDR(ifa) ((ifa)->ifa_addr) -#endif - -#define ifr_mtu ifr_metric - -static int if_ppp_open __P((queue_t *, int, int, int)); -static int if_ppp_close __P((queue_t *, int)); -static int if_ppp_wput __P((queue_t *, mblk_t *)); -static int if_ppp_rput __P((queue_t *, mblk_t *)); - -#define PPP_IF_ID 0x8021 -static struct module_info minfo = { - PPP_IF_ID, "if_ppp", 0, INFPSZ, 4096, 128 -}; - -static struct qinit rinit = { - if_ppp_rput, NULL, if_ppp_open, if_ppp_close, NULL, &minfo, NULL -}; - -static struct qinit winit = { - if_ppp_wput, NULL, NULL, NULL, NULL, &minfo, NULL -}; - -struct streamtab if_pppinfo = { - &rinit, &winit, NULL, NULL -}; - -typedef struct if_ppp_state { - int unit; - queue_t *q; - int flags; -} if_ppp_t; - -/* Values for flags */ -#define DBGLOG 1 - -static int if_ppp_count; /* Number of currently-active streams */ - -static int ppp_nalloc; /* Number of elements of ifs and states */ -static struct ifnet **ifs; /* Array of pointers to interface structs */ -static if_ppp_t **states; /* Array of pointers to state structs */ - -static int if_ppp_output __P((struct ifnet *, struct mbuf *, - struct sockaddr *)); -static int if_ppp_ioctl __P((struct ifnet *, u_int, caddr_t)); -static struct mbuf *make_mbufs __P((mblk_t *, int)); -static mblk_t *make_message __P((struct mbuf *, int)); - -#ifdef SNIT_SUPPORT -/* Fake ether header for SNIT */ -static struct ether_header snit_ehdr = {{0}, {0}, ETHERTYPE_IP}; -#endif - -#ifndef __osf__ -static void ppp_if_detach __P((struct ifnet *)); - -/* - * Detach all the interfaces before unloading. - * Not sure this works. - */ -int -if_ppp_unload() -{ - int i; - - if (if_ppp_count > 0) - return EBUSY; - for (i = 0; i < ppp_nalloc; ++i) - if (ifs[i] != 0) - ppp_if_detach(ifs[i]); - if (ifs) { - FREE(ifs, ppp_nalloc * sizeof (struct ifnet *)); - FREE(states, ppp_nalloc * sizeof (struct if_ppp_t *)); - } - ppp_nalloc = 0; - return 0; -} -#endif /* __osf__ */ - -/* - * STREAMS module entry points. - */ -static int -if_ppp_open(q, dev, flag, sflag) - queue_t *q; - int dev; - int flag, sflag; -{ - if_ppp_t *sp; - - if (q->q_ptr == 0) { - sp = (if_ppp_t *) ALLOC_SLEEP(sizeof (if_ppp_t)); - if (sp == 0) - return OPENFAIL; - bzero(sp, sizeof (if_ppp_t)); - q->q_ptr = (caddr_t) sp; - WR(q)->q_ptr = (caddr_t) sp; - sp->unit = -1; /* no interface unit attached at present */ - sp->q = WR(q); - sp->flags = 0; - ++if_ppp_count; - } - return 0; -} - -static int -if_ppp_close(q, flag) - queue_t *q; - int flag; -{ - if_ppp_t *sp; - struct ifnet *ifp; - - sp = (if_ppp_t *) q->q_ptr; - if (sp != 0) { - if (sp->flags & DBGLOG) - printf("if_ppp closed, q=%x sp=%x\n", q, sp); - if (sp->unit >= 0) { - if (sp->unit < ppp_nalloc) { - states[sp->unit] = 0; - ifp = ifs[sp->unit]; - if (ifp != 0) - ifp->if_flags &= ~(IFF_UP | IFF_RUNNING); -#ifdef DEBUG - } else { - printf("if_ppp: unit %d nonexistent!\n", sp->unit); -#endif - } - } - FREE(sp, sizeof (if_ppp_t)); - --if_ppp_count; - } - return 0; -} - -static int -if_ppp_wput(q, mp) - queue_t *q; - mblk_t *mp; -{ - if_ppp_t *sp; - struct iocblk *iop; - int error, unit; - struct ifnet *ifp; - - sp = (if_ppp_t *) q->q_ptr; - switch (mp->b_datap->db_type) { - case M_DATA: - /* - * Now why would we be getting data coming in here?? - */ - if (sp->flags & DBGLOG) - printf("if_ppp: got M_DATA len=%d\n", msgdsize(mp)); - freemsg(mp); - break; - - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - error = EINVAL; - - if (sp->flags & DBGLOG) - printf("if_ppp: got ioctl cmd=%x count=%d\n", - iop->ioc_cmd, iop->ioc_count); - - switch (iop->ioc_cmd) { - case PPPIO_NEWPPA: /* well almost */ - if (iop->ioc_count != sizeof(int) || sp->unit >= 0) - break; - if ((error = NOTSUSER()) != 0) - break; - unit = *(int *)mp->b_cont->b_rptr; - - /* Check that this unit isn't already in use */ - if (unit < ppp_nalloc && states[unit] != 0) { - error = EADDRINUSE; - break; - } - - /* Extend ifs and states arrays if necessary. */ - error = ENOSR; - if (unit >= ppp_nalloc) { - int newn; - struct ifnet **newifs; - if_ppp_t **newstates; - - newn = unit + 4; - if (sp->flags & DBGLOG) - printf("if_ppp: extending ifs to %d\n", newn); - newifs = (struct ifnet **) - ALLOC_NOSLEEP(newn * sizeof (struct ifnet *)); - if (newifs == 0) - break; - bzero(newifs, newn * sizeof (struct ifnet *)); - newstates = (if_ppp_t **) - ALLOC_NOSLEEP(newn * sizeof (struct if_ppp_t *)); - if (newstates == 0) { - FREE(newifs, newn * sizeof (struct ifnet *)); - break; - } - bzero(newstates, newn * sizeof (struct if_ppp_t *)); - bcopy(ifs, newifs, ppp_nalloc * sizeof(struct ifnet *)); - bcopy(states, newstates, ppp_nalloc * sizeof(if_ppp_t *)); - if (ifs) { - FREE(ifs, ppp_nalloc * sizeof(struct ifnet *)); - FREE(states, ppp_nalloc * sizeof(if_ppp_t *)); - } - ifs = newifs; - states = newstates; - ppp_nalloc = newn; - } - - /* Allocate a new ifnet struct if necessary. */ - ifp = ifs[unit]; - if (ifp == 0) { - ifp = (struct ifnet *) ALLOC_NOSLEEP(sizeof (struct ifnet)); - if (ifp == 0) - break; - bzero(ifp, sizeof (struct ifnet)); - ifs[unit] = ifp; - ifp->if_name = "ppp"; - ifp->if_unit = unit; - ifp->if_mtu = PPP_MTU; - ifp->if_flags = IFF_POINTOPOINT | IFF_RUNNING; -#ifndef __osf__ -#ifdef IFF_MULTICAST - ifp->if_flags |= IFF_MULTICAST; -#endif -#endif /* __osf__ */ - ifp->if_output = if_ppp_output; -#ifdef __osf__ - ifp->if_version = "Point-to-Point Protocol, version 2.3.11"; - ifp->if_mediamtu = PPP_MTU; - ifp->if_type = IFT_PPP; - ifp->if_hdrlen = PPP_HDRLEN; - ifp->if_addrlen = 0; - ifp->if_flags |= IFF_NOARP | IFF_SIMPLEX | IFF_NOTRAILERS; -#ifdef IFF_VAR_MTU - ifp->if_flags |= IFF_VAR_MTU; -#endif -#ifdef NETMASTERCPU - ifp->if_affinity = NETMASTERCPU; -#endif -#endif - ifp->if_ioctl = if_ppp_ioctl; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; - if_attach(ifp); - if (sp->flags & DBGLOG) - printf("if_ppp: created unit %d\n", unit); - } else { - ifp->if_mtu = PPP_MTU; - ifp->if_flags |= IFF_RUNNING; - } - - states[unit] = sp; - sp->unit = unit; - - error = 0; - iop->ioc_count = 0; - if (sp->flags & DBGLOG) - printf("if_ppp: attached unit %d, sp=%x q=%x\n", unit, - sp, sp->q); - break; - - case PPPIO_DEBUG: - error = -1; - if (iop->ioc_count == sizeof(int)) { - if (*(int *)mp->b_cont->b_rptr == PPPDBG_LOG + PPPDBG_IF) { - printf("if_ppp: debug log enabled, q=%x sp=%x\n", q, sp); - sp->flags |= DBGLOG; - error = 0; - iop->ioc_count = 0; - } - } - break; - - default: - error = -1; - break; - } - - if (sp->flags & DBGLOG) - printf("if_ppp: ioctl result %d\n", error); - if (error < 0) - putnext(q, mp); - else if (error == 0) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } else { - mp->b_datap->db_type = M_IOCNAK; - iop->ioc_count = 0; - iop->ioc_error = error; - qreply(q, mp); - } - break; - - default: - putnext(q, mp); - } - return 0; -} - -static int -if_ppp_rput(q, mp) - queue_t *q; - mblk_t *mp; -{ - if_ppp_t *sp; - int proto, s; - struct mbuf *mb; - struct ifqueue *inq; - struct ifnet *ifp; - int len; - - sp = (if_ppp_t *) q->q_ptr; - switch (mp->b_datap->db_type) { - case M_DATA: - /* - * Convert the message into an mbuf chain - * and inject it into the network code. - */ - if (sp->flags & DBGLOG) - printf("if_ppp: rput pkt len %d data %x %x %x %x %x %x %x %x\n", - msgdsize(mp), mp->b_rptr[0], mp->b_rptr[1], mp->b_rptr[2], - mp->b_rptr[3], mp->b_rptr[4], mp->b_rptr[5], mp->b_rptr[6], - mp->b_rptr[7]); - - if (sp->unit < 0) { - freemsg(mp); - break; - } - if (sp->unit >= ppp_nalloc || (ifp = ifs[sp->unit]) == 0) { -#ifdef DEBUG - printf("if_ppp: no unit %d!\n", sp->unit); -#endif - freemsg(mp); - break; - } - - if ((ifp->if_flags & IFF_UP) == 0) { - freemsg(mp); - break; - } - ++ifp->if_ipackets; - - proto = PPP_PROTOCOL(mp->b_rptr); - adjmsg(mp, PPP_HDRLEN); - len = msgdsize(mp); - mb = make_mbufs(mp, sizeof(struct ifnet *)); - freemsg(mp); - if (mb == NULL) { - if (sp->flags & DBGLOG) - printf("if_ppp%d: make_mbufs failed\n", ifp->if_unit); - ++ifp->if_ierrors; - break; - } - -#ifdef SNIT_SUPPORT - if (proto == PPP_IP && (ifp->if_flags & IFF_PROMISC)) { - struct nit_if nif; - - nif.nif_header = (caddr_t) &snit_ehdr; - nif.nif_hdrlen = sizeof(snit_ehdr); - nif.nif_bodylen = len; - nif.nif_promisc = 0; - snit_intr(ifp, mb, &nif); - } -#endif - -/* - * For Digital UNIX, there's space set aside in the header mbuf - * for the interface info. - * - * For Sun it's smuggled around via a pointer at the front of the mbuf. - */ -#ifdef __osf__ - mb->m_pkthdr.rcvif = ifp; - mb->m_pkthdr.len = len; -#else - mb->m_off -= sizeof(struct ifnet *); - mb->m_len += sizeof(struct ifnet *); - *mtod(mb, struct ifnet **) = ifp; -#endif - - inq = 0; - switch (proto) { - case PPP_IP: - inq = &ipintrq; - schednetisr(NETISR_IP); - } - - if (inq != 0) { - s = splhigh(); - if (IF_QFULL(inq)) { - IF_DROP(inq); - ++ifp->if_ierrors; - if (sp->flags & DBGLOG) - printf("if_ppp: inq full, proto=%x\n", proto); - m_freem(mb); - } else { - IF_ENQUEUE(inq, mb); - } - splx(s); - } else { - if (sp->flags & DBGLOG) - printf("if_ppp%d: proto=%x?\n", ifp->if_unit, proto); - ++ifp->if_ierrors; - m_freem(mb); - } - break; - - default: - putnext(q, mp); - } - return 0; -} - -/* - * Network code wants to output a packet. - * Turn it into a STREAMS message and send it down. - */ -static int -if_ppp_output(ifp, m0, dst) - struct ifnet *ifp; - struct mbuf *m0; - struct sockaddr *dst; -{ - mblk_t *mp; - int proto, s; - if_ppp_t *sp; - u_char *p; - - if ((ifp->if_flags & IFF_UP) == 0) { - m_freem(m0); - return ENETDOWN; - } - - if ((unsigned)ifp->if_unit >= ppp_nalloc) { -#ifdef DEBUG - printf("if_ppp_output: unit %d?\n", ifp->if_unit); -#endif - m_freem(m0); - return EINVAL; - } - sp = states[ifp->if_unit]; - if (sp == 0) { -#ifdef DEBUG - printf("if_ppp_output: no queue?\n"); -#endif - m_freem(m0); - return ENETDOWN; - } - - if (sp->flags & DBGLOG) { - p = mtod(m0, u_char *); - printf("if_ppp_output%d: af=%d data=%x %x %x %x %x %x %x %x q=%x\n", - ifp->if_unit, dst->sa_family, p[0], p[1], p[2], p[3], p[4], - p[5], p[6], p[7], sp->q); - } - - switch (dst->sa_family) { - case AF_INET: - proto = PPP_IP; -#ifdef SNIT_SUPPORT - if (ifp->if_flags & IFF_PROMISC) { - struct nit_if nif; - struct mbuf *m; - int len; - - for (len = 0, m = m0; m != NULL; m = m->m_next) - len += m->m_len; - nif.nif_header = (caddr_t) &snit_ehdr; - nif.nif_hdrlen = sizeof(snit_ehdr); - nif.nif_bodylen = len; - nif.nif_promisc = 0; - snit_intr(ifp, m0, &nif); - } -#endif - break; - - default: - m_freem(m0); - return EAFNOSUPPORT; - } - - ++ifp->if_opackets; - mp = make_message(m0, PPP_HDRLEN); - m_freem(m0); - if (mp == 0) { - ++ifp->if_oerrors; - return ENOBUFS; - } - mp->b_rptr -= PPP_HDRLEN; - mp->b_rptr[0] = PPP_ALLSTATIONS; - mp->b_rptr[1] = PPP_UI; - mp->b_rptr[2] = proto >> 8; - mp->b_rptr[3] = proto; - - s = splstr(); - if (sp->flags & DBGLOG) - printf("if_ppp: putnext(%x, %x), r=%x w=%x p=%x\n", - sp->q, mp, mp->b_rptr, mp->b_wptr, proto); - putnext(sp->q, mp); - splx(s); - - return 0; -} - -/* - * Socket ioctl routine for ppp interfaces. - */ -static int -if_ppp_ioctl(ifp, cmd, data) - struct ifnet *ifp; - u_int cmd; - caddr_t data; -{ - int s, error; - struct ifreq *ifr = (struct ifreq *) data; - struct ifaddr *ifa = (struct ifaddr *) data; - u_short mtu; - - error = 0; - s = splimp(); - switch (cmd) { - case SIOCSIFFLAGS: - if ((ifp->if_flags & IFF_RUNNING) == 0) - ifp->if_flags &= ~IFF_UP; - break; - - case SIOCSIFADDR: - if (IFA_ADDR(ifa).sa_family != AF_INET) - error = EAFNOSUPPORT; - break; - - case SIOCSIFDSTADDR: - if (IFA_ADDR(ifa).sa_family != AF_INET) - error = EAFNOSUPPORT; - break; - - case SIOCSIFMTU: - if ((error = NOTSUSER()) != 0) - break; -#ifdef __osf__ - /* this hack is necessary because ifioctl checks ifr_data - * in 4.0 and 5.0, but ifr_data and ifr_metric overlay each - * other in the definition of struct ifreq so pppd can't set both. - */ - bcopy(ifr->ifr_data, &mtu, sizeof (u_short)); - ifr->ifr_mtu = mtu; -#endif - - if (ifr->ifr_mtu < PPP_MINMTU || ifr->ifr_mtu > PPP_MAXMTU) { - error = EINVAL; - break; - } - ifp->if_mtu = ifr->ifr_mtu; - break; - - case SIOCGIFMTU: - ifr->ifr_mtu = ifp->if_mtu; - break; - - case SIOCADDMULTI: - case SIOCDELMULTI: - switch(ifr->ifr_addr.sa_family) { - case AF_INET: - break; - default: - error = EAFNOSUPPORT; - break; - } - break; - - default: - error = EINVAL; - } - splx(s); - return (error); -} - -/* - * Turn a STREAMS message into an mbuf chain. - */ -static struct mbuf * -make_mbufs(mp, off) - mblk_t *mp; - int off; -{ - struct mbuf *head, **prevp, *m; - int len, space, n; - unsigned char *cp, *dp; - - len = msgdsize(mp); - if (len == 0) - return 0; - prevp = &head; - space = 0; - cp = mp->b_rptr; -#ifdef __osf__ - MGETHDR(m, M_DONTWAIT, MT_DATA); - m->m_len = 0; - space = MHLEN; - *prevp = m; - prevp = &m->m_next; - dp = mtod(m, unsigned char *); - len -= space; - off = 0; -#endif - for (;;) { - while (cp >= mp->b_wptr) { - mp = mp->b_cont; - if (mp == 0) { - *prevp = 0; - return head; - } - cp = mp->b_rptr; - } - n = mp->b_wptr - cp; - if (space == 0) { - MGET(m, M_DONTWAIT, MT_DATA); - *prevp = m; - if (m == 0) { - if (head != 0) - m_freem(head); - return 0; - } - if (len + off > 2 * MLEN) { -#ifdef __osf__ - MCLGET(m, M_DONTWAIT); -#else - MCLGET(m); -#endif - } -#ifdef __osf__ - space = ((m->m_flags & M_EXT) ? MCLBYTES : MLEN); -#else - space = (m->m_off > MMAXOFF? MCLBYTES: MLEN) - off; - m->m_off += off; -#endif - m->m_len = 0; - len -= space; - dp = mtod(m, unsigned char *); - off = 0; - prevp = &m->m_next; - } - if (n > space) - n = space; - bcopy(cp, dp, n); - cp += n; - dp += n; - space -= n; - m->m_len += n; - } -} - -/* - * Turn an mbuf chain into a STREAMS message. - */ -#define ALLOCB_MAX 4096 - -static mblk_t * -make_message(m, off) - struct mbuf *m; - int off; -{ - mblk_t *head, **prevp, *mp; - int len, space, n, nb; - unsigned char *cp, *dp; - struct mbuf *nm; - - len = 0; - for (nm = m; nm != 0; nm = nm->m_next) - len += nm->m_len; - prevp = &head; - space = 0; - cp = mtod(m, unsigned char *); - nb = m->m_len; - for (;;) { - while (nb <= 0) { - m = m->m_next; - if (m == 0) { - *prevp = 0; - return head; - } - cp = mtod(m, unsigned char *); - nb = m->m_len; - } - if (space == 0) { - space = len + off; - if (space > ALLOCB_MAX) - space = ALLOCB_MAX; - mp = allocb(space, BPRI_LO); - *prevp = mp; - if (mp == 0) { - if (head != 0) - freemsg(head); - return 0; - } - dp = mp->b_rptr += off; - space -= off; - len -= space; - off = 0; - prevp = &mp->b_cont; - } - n = nb < space? nb: space; - bcopy(cp, dp, n); - cp += n; - dp += n; - nb -= n; - space -= n; - mp->b_wptr = dp; - } -} - -/* - * Digital UNIX doesn't allow for removing ifnet structures - * from the list. But then we're not using this as a loadable - * module anyway, so that's OK. - * - * Under SunOS, this should allow the module to be unloaded. - * Unfortunately, it doesn't seem to detach all the references, - * so your system may well crash after you unload this module :-( - */ -#ifndef __osf__ - -/* - * Remove an interface from the system. - * This routine contains magic. - */ -#include <net/route.h> -#include <netinet/in_pcb.h> -#include <netinet/ip_var.h> -#include <netinet/tcp.h> -#include <netinet/tcp_timer.h> -#include <netinet/tcp_var.h> -#include <netinet/udp.h> -#include <netinet/udp_var.h> - -static void -ppp_if_detach(ifp) - struct ifnet *ifp; -{ - int s; - struct inpcb *pcb; - struct ifaddr *ifa; - struct in_ifaddr **inap; - struct ifnet **ifpp; - - s = splhigh(); - - /* - * Clear the interface from any routes currently cached in - * TCP or UDP protocol control blocks. - */ - for (pcb = tcb.inp_next; pcb != &tcb; pcb = pcb->inp_next) - if (pcb->inp_route.ro_rt && pcb->inp_route.ro_rt->rt_ifp == ifp) - in_losing(pcb); - for (pcb = udb.inp_next; pcb != &udb; pcb = pcb->inp_next) - if (pcb->inp_route.ro_rt && pcb->inp_route.ro_rt->rt_ifp == ifp) - in_losing(pcb); - - /* - * Delete routes through all addresses of the interface. - */ - for (ifa = ifp->if_addrlist; ifa != 0; ifa = ifa->ifa_next) { - rtinit(ifa, ifa, SIOCDELRT, RTF_HOST); - rtinit(ifa, ifa, SIOCDELRT, 0); - } - - /* - * Unlink the interface's address(es) from the in_ifaddr list. - */ - for (inap = &in_ifaddr; *inap != 0; ) { - if ((*inap)->ia_ifa.ifa_ifp == ifp) - *inap = (*inap)->ia_next; - else - inap = &(*inap)->ia_next; - } - - /* - * Delete the interface from the ifnet list. - */ - for (ifpp = &ifnet; (*ifpp) != 0; ) { - if (*ifpp == ifp) - break; - ifpp = &(*ifpp)->if_next; - } - if (*ifpp == 0) - printf("couldn't find interface ppp%d in ifnet list\n", ifp->if_unit); - else - *ifpp = ifp->if_next; - - splx(s); -} - -#endif /* __osf__ */ diff --git a/mdk-stage1/ppp/modules/ppp.c b/mdk-stage1/ppp/modules/ppp.c deleted file mode 100644 index 44bf08dff..000000000 --- a/mdk-stage1/ppp/modules/ppp.c +++ /dev/null @@ -1,2486 +0,0 @@ -/* - * ppp.c - STREAMS multiplexing pseudo-device driver for PPP. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -/* - * This file is used under Solaris 2, SVR4, SunOS 4, and Digital UNIX. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/stream.h> -#include <sys/stropts.h> -#include <sys/errno.h> -#ifdef __osf__ -#include <sys/ioctl.h> -#include <sys/cmn_err.h> -#define queclass(mp) ((mp)->b_band & QPCTL) -#else -#include <sys/ioccom.h> -#endif -#include <sys/time.h> -#ifdef SVR4 -#include <sys/cmn_err.h> -#include <sys/conf.h> -#include <sys/dlpi.h> -#include <sys/ddi.h> -#ifdef SOL2 -#include <sys/ksynch.h> -#include <sys/kstat.h> -#include <sys/sunddi.h> -#include <sys/ethernet.h> -#else -#include <sys/socket.h> -#include <sys/sockio.h> -#include <net/if.h> -#include <netinet/in.h> -#endif /* SOL2 */ -#else /* not SVR4 */ -#include <sys/user.h> -#endif /* SVR4 */ -#include <net/ppp_defs.h> -#include <net/pppio.h> -#include "ppp_mod.h" - -/* - * Modifications marked with #ifdef PRIOQ are for priority queueing of - * interactive traffic, and are due to Marko Zec <zec@japa.tel.fer.hr>. - */ -#ifdef PRIOQ -#endif /* PRIOQ */ - -#include <netinet/in.h> /* leave this outside of PRIOQ for htons */ - -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif - -/* - * The IP module may use this SAP value for IP packets. - */ -#ifndef ETHERTYPE_IP -#define ETHERTYPE_IP 0x800 -#endif - -#if !defined(ETHERTYPE_IPV6) -#define ETHERTYPE_IPV6 0x86dd -#endif /* !defined(ETHERTYPE_IPV6) */ - -#if !defined(ETHERTYPE_ALLSAP) && defined(SOL2) -#define ETHERTYPE_ALLSAP 0 -#endif /* !defined(ETHERTYPE_ALLSAP) && defined(SOL2) */ - -#if !defined(PPP_ALLSAP) && defined(SOL2) -#define PPP_ALLSAP PPP_ALLSTATIONS -#endif /* !defined(PPP_ALLSAP) && defined(SOL2) */ - -extern time_t time; - -#ifdef SOL2 -/* - * We use this reader-writer lock to ensure that the lower streams - * stay connected to the upper streams while the lower-side put and - * service procedures are running. Essentially it is an existence - * lock for the upper stream associated with each lower stream. - */ -krwlock_t ppp_lower_lock; -#define LOCK_LOWER_W rw_enter(&ppp_lower_lock, RW_WRITER) -#define LOCK_LOWER_R rw_enter(&ppp_lower_lock, RW_READER) -#define TRYLOCK_LOWER_R rw_tryenter(&ppp_lower_lock, RW_READER) -#define UNLOCK_LOWER rw_exit(&ppp_lower_lock) - -#define MT_ENTER(x) mutex_enter(x) -#define MT_EXIT(x) mutex_exit(x) - -/* - * Notes on multithreaded implementation for Solaris 2: - * - * We use an inner perimeter around each queue pair and an outer - * perimeter around the whole driver. The inner perimeter is - * entered exclusively for all entry points (open, close, put, - * service). The outer perimeter is entered exclusively for open - * and close and shared for put and service. This is all done for - * us by the streams framework. - * - * I used to think that the perimeters were entered for the lower - * streams' put and service routines as well as for the upper streams'. - * Because of problems experienced by people, and after reading the - * documentation more closely, I now don't think that is true. So we - * now use ppp_lower_lock to give us an existence guarantee on the - * upper stream controlling each lower stream. - * - * Shared entry to the outer perimeter protects the existence of all - * the upper streams and their upperstr_t structures, and guarantees - * that the following fields of any upperstr_t won't change: - * nextmn, next, nextppa. It guarantees that the lowerq field of an - * upperstr_t won't go from non-zero to zero, that the global `ppas' - * won't change and that the no lower stream will get unlinked. - * - * Shared (reader) access to ppa_lower_lock guarantees that no lower - * stream will be unlinked and that the lowerq field of all upperstr_t - * structures won't change. - */ - -#else /* SOL2 */ -#define LOCK_LOWER_W 0 -#define LOCK_LOWER_R 0 -#define TRYLOCK_LOWER_R 1 -#define UNLOCK_LOWER 0 -#define MT_ENTER(x) 0 -#define MT_EXIT(x) 0 - -#endif /* SOL2 */ - -/* - * Private information; one per upper stream. - */ -typedef struct upperstr { - minor_t mn; /* minor device number */ - struct upperstr *nextmn; /* next minor device */ - queue_t *q; /* read q associated with this upper stream */ - int flags; /* flag bits, see below */ - int state; /* current DLPI state */ - int sap; /* service access point */ - int req_sap; /* which SAP the DLPI client requested */ - struct upperstr *ppa; /* control stream for our ppa */ - struct upperstr *next; /* next stream for this ppa */ - uint ioc_id; /* last ioctl ID for this stream */ - enum NPmode npmode; /* what to do with packets on this SAP */ - unsigned char rblocked; /* flow control has blocked upper read strm */ - /* N.B. rblocked is only changed by control stream's put/srv procs */ - /* - * There is exactly one control stream for each PPA. - * The following fields are only used for control streams. - */ - int ppa_id; - queue_t *lowerq; /* write queue attached below this PPA */ - struct upperstr *nextppa; /* next control stream */ - int mru; - int mtu; - struct pppstat stats; /* statistics */ - time_t last_sent; /* time last NP packet sent */ - time_t last_recv; /* time last NP packet rcvd */ -#ifdef SOL2 - kmutex_t stats_lock; /* lock for stats updates */ - kstat_t *kstats; /* stats for netstat */ -#endif /* SOL2 */ -#ifdef LACHTCP - int ifflags; - char ifname[IFNAMSIZ]; - struct ifstats ifstats; -#endif /* LACHTCP */ -} upperstr_t; - -/* Values for flags */ -#define US_PRIV 1 /* stream was opened by superuser */ -#define US_CONTROL 2 /* stream is a control stream */ -#define US_BLOCKED 4 /* flow ctrl has blocked lower write stream */ -#define US_LASTMOD 8 /* no PPP modules below us */ -#define US_DBGLOG 0x10 /* log various occurrences */ -#define US_RBLOCKED 0x20 /* flow ctrl has blocked upper read stream */ - -#if defined(SOL2) -#if DL_CURRENT_VERSION >= 2 -#define US_PROMISC 0x40 /* stream is promiscuous */ -#endif /* DL_CURRENT_VERSION >= 2 */ -#define US_RAWDATA 0x80 /* raw M_DATA, no DLPI header */ -#endif /* defined(SOL2) */ - -#ifdef PRIOQ -static u_char max_band=0; -static u_char def_band=0; - -#define IPPORT_DEFAULT 65535 - -/* - * Port priority table - * Highest priority ports are listed first, lowest are listed last. - * ICMP & packets using unlisted ports will be treated as "default". - * If IPPORT_DEFAULT is not listed here, "default" packets will be - * assigned lowest priority. - * Each line should be terminated with "0". - * Line containing only "0" marks the end of the list. - */ - -static u_short prioq_table[]= { - 113, 53, 0, - 22, 23, 513, 517, 518, 0, - 514, 21, 79, 111, 0, - 25, 109, 110, 0, - IPPORT_DEFAULT, 0, - 20, 70, 80, 8001, 8008, 8080, 0, /* 8001,8008,8080 - common proxy ports */ -0 }; - -#endif /* PRIOQ */ - - -static upperstr_t *minor_devs = NULL; -static upperstr_t *ppas = NULL; - -#ifdef SVR4 -static int pppopen __P((queue_t *, dev_t *, int, int, cred_t *)); -static int pppclose __P((queue_t *, int, cred_t *)); -#else -static int pppopen __P((queue_t *, int, int, int)); -static int pppclose __P((queue_t *, int)); -#endif /* SVR4 */ -static int pppurput __P((queue_t *, mblk_t *)); -static int pppuwput __P((queue_t *, mblk_t *)); -static int pppursrv __P((queue_t *)); -static int pppuwsrv __P((queue_t *)); -static int ppplrput __P((queue_t *, mblk_t *)); -static int ppplwput __P((queue_t *, mblk_t *)); -static int ppplrsrv __P((queue_t *)); -static int ppplwsrv __P((queue_t *)); -#ifndef NO_DLPI -static void dlpi_request __P((queue_t *, mblk_t *, upperstr_t *)); -static void dlpi_error __P((queue_t *, upperstr_t *, int, int, int)); -static void dlpi_ok __P((queue_t *, int)); -#endif -static int send_data __P((mblk_t *, upperstr_t *)); -static void new_ppa __P((queue_t *, mblk_t *)); -static void attach_ppa __P((queue_t *, mblk_t *)); -static void detach_ppa __P((queue_t *, mblk_t *)); -static void detach_lower __P((queue_t *, mblk_t *)); -static void debug_dump __P((queue_t *, mblk_t *)); -static upperstr_t *find_dest __P((upperstr_t *, int)); -#if defined(SOL2) -static upperstr_t *find_promisc __P((upperstr_t *, int)); -static mblk_t *prepend_ether __P((upperstr_t *, mblk_t *, int)); -static mblk_t *prepend_udind __P((upperstr_t *, mblk_t *, int)); -static void promisc_sendup __P((upperstr_t *, mblk_t *, int, int)); -#endif /* defined(SOL2) */ -static int putctl2 __P((queue_t *, int, int, int)); -static int putctl4 __P((queue_t *, int, int, int)); -static int pass_packet __P((upperstr_t *ppa, mblk_t *mp, int outbound)); -#ifdef FILTER_PACKETS -static int ip_hard_filter __P((upperstr_t *ppa, mblk_t *mp, int outbound)); -#endif /* FILTER_PACKETS */ - -#define PPP_ID 0xb1a6 -static struct module_info ppp_info = { -#ifdef PRIOQ - PPP_ID, "ppp", 0, 512, 512, 384 -#else - PPP_ID, "ppp", 0, 512, 512, 128 -#endif /* PRIOQ */ -}; - -static struct qinit pppurint = { - pppurput, pppursrv, pppopen, pppclose, NULL, &ppp_info, NULL -}; - -static struct qinit pppuwint = { - pppuwput, pppuwsrv, NULL, NULL, NULL, &ppp_info, NULL -}; - -static struct qinit ppplrint = { - ppplrput, ppplrsrv, NULL, NULL, NULL, &ppp_info, NULL -}; - -static struct qinit ppplwint = { - ppplwput, ppplwsrv, NULL, NULL, NULL, &ppp_info, NULL -}; - -#ifdef LACHTCP -extern struct ifstats *ifstats; -int pppdevflag = 0; -#endif - -struct streamtab pppinfo = { - &pppurint, &pppuwint, - &ppplrint, &ppplwint -}; - -int ppp_count; - -/* - * How we maintain statistics. - */ -#ifdef SOL2 -#define INCR_IPACKETS(ppa) \ - if (ppa->kstats != 0) { \ - KSTAT_NAMED_PTR(ppa->kstats)[0].value.ul++; \ - } -#define INCR_IERRORS(ppa) \ - if (ppa->kstats != 0) { \ - KSTAT_NAMED_PTR(ppa->kstats)[1].value.ul++; \ - } -#define INCR_OPACKETS(ppa) \ - if (ppa->kstats != 0) { \ - KSTAT_NAMED_PTR(ppa->kstats)[2].value.ul++; \ - } -#define INCR_OERRORS(ppa) \ - if (ppa->kstats != 0) { \ - KSTAT_NAMED_PTR(ppa->kstats)[3].value.ul++; \ - } -#endif - -#ifdef LACHTCP -#define INCR_IPACKETS(ppa) ppa->ifstats.ifs_ipackets++; -#define INCR_IERRORS(ppa) ppa->ifstats.ifs_ierrors++; -#define INCR_OPACKETS(ppa) ppa->ifstats.ifs_opackets++; -#define INCR_OERRORS(ppa) ppa->ifstats.ifs_oerrors++; -#endif - -/* - * STREAMS driver entry points. - */ -static int -#ifdef SVR4 -pppopen(q, devp, oflag, sflag, credp) - queue_t *q; - dev_t *devp; - int oflag, sflag; - cred_t *credp; -#else -pppopen(q, dev, oflag, sflag) - queue_t *q; - int dev; /* really dev_t */ - int oflag, sflag; -#endif -{ - upperstr_t *up; - upperstr_t **prevp; - minor_t mn; -#ifdef PRIOQ - u_short *ptr; - u_char new_band; -#endif /* PRIOQ */ - - if (q->q_ptr) - DRV_OPEN_OK(dev); /* device is already open */ - -#ifdef PRIOQ - /* Calculate max_bband & def_band from definitions in prioq.h - This colud be done at some more approtiate time (less often) - but this way it works well so I'll just leave it here */ - - max_band = 1; - def_band = 0; - ptr = prioq_table; - while (*ptr) { - new_band = 1; - while (*ptr) - if (*ptr++ == IPPORT_DEFAULT) { - new_band = 0; - def_band = max_band; - } - max_band += new_band; - ptr++; - } - if (def_band) - def_band = max_band - def_band; - --max_band; -#endif /* PRIOQ */ - - if (sflag == CLONEOPEN) { - mn = 0; - for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) { - if (up->mn != mn) - break; - ++mn; - } - } else { -#ifdef SVR4 - mn = getminor(*devp); -#else - mn = minor(dev); -#endif - for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) { - if (up->mn >= mn) - break; - } - if (up->mn == mn) { - /* this can't happen */ - q->q_ptr = WR(q)->q_ptr = (caddr_t) up; - DRV_OPEN_OK(dev); - } - } - - /* - * Construct a new minor node. - */ - up = (upperstr_t *) ALLOC_SLEEP(sizeof(upperstr_t)); - bzero((caddr_t) up, sizeof(upperstr_t)); - if (up == 0) { - DPRINT("pppopen: out of kernel memory\n"); - OPEN_ERROR(ENXIO); - } - up->nextmn = *prevp; - *prevp = up; - up->mn = mn; -#ifdef SVR4 - *devp = makedevice(getmajor(*devp), mn); -#endif - up->q = q; - if (NOTSUSER() == 0) - up->flags |= US_PRIV; -#ifndef NO_DLPI - up->state = DL_UNATTACHED; -#endif -#ifdef LACHTCP - up->ifflags = IFF_UP | IFF_POINTOPOINT; -#endif - up->sap = -1; - up->last_sent = up->last_recv = time; - up->npmode = NPMODE_DROP; - q->q_ptr = (caddr_t) up; - WR(q)->q_ptr = (caddr_t) up; - noenable(WR(q)); -#ifdef SOL2 - mutex_init(&up->stats_lock, NULL, MUTEX_DRIVER, NULL); -#endif - ++ppp_count; - - qprocson(q); - DRV_OPEN_OK(makedev(major(dev), mn)); -} - -static int -#ifdef SVR4 -pppclose(q, flag, credp) - queue_t *q; - int flag; - cred_t *credp; -#else -pppclose(q, flag) - queue_t *q; - int flag; -#endif -{ - upperstr_t *up, **upp; - upperstr_t *as, *asnext; - upperstr_t **prevp; - - qprocsoff(q); - - up = (upperstr_t *) q->q_ptr; - if (up == 0) { - DPRINT("pppclose: q_ptr = 0\n"); - return 0; - } - if (up->flags & US_DBGLOG) - DPRINT2("ppp/%d: close, flags=%x\n", up->mn, up->flags); - if (up->flags & US_CONTROL) { -#ifdef LACHTCP - struct ifstats *ifp, *pifp; -#endif - if (up->lowerq != 0) { - /* Gack! the lower stream should have be unlinked earlier! */ - DPRINT1("ppp%d: lower stream still connected on close?\n", - up->mn); - LOCK_LOWER_W; - up->lowerq->q_ptr = 0; - RD(up->lowerq)->q_ptr = 0; - up->lowerq = 0; - UNLOCK_LOWER; - } - - /* - * This stream represents a PPA: - * For all streams attached to the PPA, clear their - * references to this PPA. - * Then remove this PPA from the list of PPAs. - */ - for (as = up->next; as != 0; as = asnext) { - asnext = as->next; - as->next = 0; - as->ppa = 0; - if (as->flags & US_BLOCKED) { - as->flags &= ~US_BLOCKED; - flushq(WR(as->q), FLUSHDATA); - } - } - for (upp = &ppas; *upp != 0; upp = &(*upp)->nextppa) - if (*upp == up) { - *upp = up->nextppa; - break; - } -#ifdef LACHTCP - /* Remove the statistics from the active list. */ - for (ifp = ifstats, pifp = 0; ifp; ifp = ifp->ifs_next) { - if (ifp == &up->ifstats) { - if (pifp) - pifp->ifs_next = ifp->ifs_next; - else - ifstats = ifp->ifs_next; - break; - } - pifp = ifp; - } -#endif - } else { - /* - * If this stream is attached to a PPA, - * remove it from the PPA's list. - */ - if ((as = up->ppa) != 0) { - for (; as->next != 0; as = as->next) - if (as->next == up) { - as->next = up->next; - break; - } - } - } - -#ifdef SOL2 - if (up->kstats) - kstat_delete(up->kstats); - mutex_destroy(&up->stats_lock); -#endif - - q->q_ptr = NULL; - WR(q)->q_ptr = NULL; - - for (prevp = &minor_devs; *prevp != 0; prevp = &(*prevp)->nextmn) { - if (*prevp == up) { - *prevp = up->nextmn; - break; - } - } - FREE(up, sizeof(upperstr_t)); - --ppp_count; - - return 0; -} - -/* - * A message from on high. We do one of three things: - * - qreply() - * - put the message on the lower write stream - * - queue it for our service routine - */ -static int -pppuwput(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us, *ppa, *nps; - struct iocblk *iop; - struct linkblk *lb; -#ifdef LACHTCP - struct ifreq *ifr; - int i; -#endif - queue_t *lq; - int error, n, sap; - mblk_t *mq; - struct ppp_idle *pip; -#ifdef PRIOQ - queue_t *tlq; -#endif /* PRIOQ */ -#ifdef NO_DLPI - upperstr_t *os; -#endif - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("pppuwput: q_ptr = 0!\n"); - return 0; - } - if (mp == 0) { - DPRINT1("pppuwput/%d: mp = 0!\n", us->mn); - return 0; - } - if (mp->b_datap == 0) { - DPRINT1("pppuwput/%d: mp->b_datap = 0!\n", us->mn); - return 0; - } - switch (mp->b_datap->db_type) { -#ifndef NO_DLPI - case M_PCPROTO: - case M_PROTO: - dlpi_request(q, mp, us); - break; -#endif /* NO_DLPI */ - - case M_DATA: - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: uwput M_DATA len=%d flags=%x\n", - us->mn, msgdsize(mp), us->flags); - if (us->ppa == 0 || msgdsize(mp) > us->ppa->mtu + PPP_HDRLEN -#ifndef NO_DLPI - || (us->flags & US_CONTROL) == 0 -#endif /* NO_DLPI */ - ) { - DPRINT1("pppuwput: junk data len=%d\n", msgdsize(mp)); - freemsg(mp); - break; - } -#ifdef NO_DLPI - if ((us->flags & US_CONTROL) == 0 && !pass_packet(us, mp, 1)) - break; -#endif - if (!send_data(mp, us)) - putq(q, mp); - break; - - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - error = EINVAL; - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: ioctl %x count=%d\n", - us->mn, iop->ioc_cmd, iop->ioc_count); - switch (iop->ioc_cmd) { -#if defined(SOL2) - case DLIOCRAW: /* raw M_DATA mode */ - us->flags |= US_RAWDATA; - error = 0; - break; -#endif /* defined(SOL2) */ - case I_LINK: - if ((us->flags & US_CONTROL) == 0 || us->lowerq != 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl I_LINK b_cont = 0!\n", us->mn); - break; - } - lb = (struct linkblk *) mp->b_cont->b_rptr; - lq = lb->l_qbot; - if (lq == 0) { - DPRINT1("pppuwput/%d: ioctl I_LINK l_qbot = 0!\n", us->mn); - break; - } - LOCK_LOWER_W; - us->lowerq = lq; - lq->q_ptr = (caddr_t) q; - RD(lq)->q_ptr = (caddr_t) us->q; - UNLOCK_LOWER; - iop->ioc_count = 0; - error = 0; - us->flags &= ~US_LASTMOD; - /* Unblock upper streams which now feed this lower stream. */ - qenable(q); - /* Send useful information down to the modules which - are now linked below us. */ - putctl2(lq, M_CTL, PPPCTL_UNIT, us->ppa_id); - putctl4(lq, M_CTL, PPPCTL_MRU, us->mru); - putctl4(lq, M_CTL, PPPCTL_MTU, us->mtu); -#ifdef PRIOQ - /* Lower tty driver's queue hiwat/lowat from default 4096/128 - to 256/128 since we don't want queueing of data on - output to physical device */ - - freezestr(lq); - for (tlq = lq; tlq->q_next != NULL; tlq = tlq->q_next) - ; - strqset(tlq, QHIWAT, 0, 256); - strqset(tlq, QLOWAT, 0, 128); - unfreezestr(lq); -#endif /* PRIOQ */ - break; - - case I_UNLINK: - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl I_UNLINK b_cont = 0!\n", us->mn); - break; - } - lb = (struct linkblk *) mp->b_cont->b_rptr; -#if DEBUG - if (us->lowerq != lb->l_qbot) { - DPRINT2("ppp unlink: lowerq=%x qbot=%x\n", - us->lowerq, lb->l_qbot); - break; - } -#endif - iop->ioc_count = 0; - qwriter(q, mp, detach_lower, PERIM_OUTER); - error = -1; - break; - - case PPPIO_NEWPPA: - if (us->flags & US_CONTROL) - break; - if ((us->flags & US_PRIV) == 0) { - error = EPERM; - break; - } - /* Arrange to return an int */ - if ((mq = mp->b_cont) == 0 - || mq->b_datap->db_lim - mq->b_rptr < sizeof(int)) { - mq = allocb(sizeof(int), BPRI_HI); - if (mq == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = mq; - mq->b_cont = 0; - } - iop->ioc_count = sizeof(int); - mq->b_wptr = mq->b_rptr + sizeof(int); - qwriter(q, mp, new_ppa, PERIM_OUTER); - error = -1; - break; - - case PPPIO_ATTACH: - /* like dlpi_attach, for programs which can't write to - the stream (like pppstats) */ - if (iop->ioc_count != sizeof(int) || us->ppa != 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_ATTACH b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - for (ppa = ppas; ppa != 0; ppa = ppa->nextppa) - if (ppa->ppa_id == n) - break; - if (ppa == 0) - break; - us->ppa = ppa; - iop->ioc_count = 0; - qwriter(q, mp, attach_ppa, PERIM_OUTER); - error = -1; - break; - -#ifdef NO_DLPI - case PPPIO_BIND: - /* Attach to a given SAP. */ - if (iop->ioc_count != sizeof(int) || us->ppa == 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_BIND b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - /* n must be a valid PPP network protocol number. */ - if (n < 0x21 || n > 0x3fff || (n & 0x101) != 1) - break; - /* check that no other stream is bound to this sap already. */ - for (os = us->ppa; os != 0; os = os->next) - if (os->sap == n) - break; - if (os != 0) - break; - us->sap = n; - iop->ioc_count = 0; - error = 0; - break; -#endif /* NO_DLPI */ - - case PPPIO_MRU: - if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_MRU b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - if (n <= 0 || n > PPP_MAXMRU) - break; - if (n < PPP_MRU) - n = PPP_MRU; - us->mru = n; - if (us->lowerq) - putctl4(us->lowerq, M_CTL, PPPCTL_MRU, n); - error = 0; - iop->ioc_count = 0; - break; - - case PPPIO_MTU: - if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_MTU b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - if (n <= 0 || n > PPP_MAXMTU) - break; - us->mtu = n; -#ifdef LACHTCP - /* The MTU reported in netstat, not used as IP max packet size! */ - us->ifstats.ifs_mtu = n; -#endif - if (us->lowerq) - putctl4(us->lowerq, M_CTL, PPPCTL_MTU, n); - error = 0; - iop->ioc_count = 0; - break; - - case PPPIO_LASTMOD: - us->flags |= US_LASTMOD; - error = 0; - break; - - case PPPIO_DEBUG: - if (iop->ioc_count != sizeof(int)) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_DEBUG b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - if (n == PPPDBG_DUMP + PPPDBG_DRIVER) { - qwriter(q, NULL, debug_dump, PERIM_OUTER); - iop->ioc_count = 0; - error = -1; - } else if (n == PPPDBG_LOG + PPPDBG_DRIVER) { - DPRINT1("ppp/%d: debug log enabled\n", us->mn); - us->flags |= US_DBGLOG; - iop->ioc_count = 0; - error = 0; - } else { - if (us->ppa == 0 || us->ppa->lowerq == 0) - break; - putnext(us->ppa->lowerq, mp); - error = -1; - } - break; - - case PPPIO_NPMODE: - if (iop->ioc_count != 2 * sizeof(int)) - break; - if ((us->flags & US_CONTROL) == 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_NPMODE b_cont = 0!\n", us->mn); - break; - } - sap = ((int *)mp->b_cont->b_rptr)[0]; - for (nps = us->next; nps != 0; nps = nps->next) { - if (us->flags & US_DBGLOG) - DPRINT2("us = 0x%x, us->next->sap = 0x%x\n", nps, nps->sap); - if (nps->sap == sap) - break; - } - if (nps == 0) { - if (us->flags & US_DBGLOG) - DPRINT2("ppp/%d: no stream for sap %x\n", us->mn, sap); - break; - } - /* XXX possibly should use qwriter here */ - nps->npmode = (enum NPmode) ((int *)mp->b_cont->b_rptr)[1]; - if (nps->npmode != NPMODE_QUEUE && (nps->flags & US_BLOCKED) != 0) - qenable(WR(nps->q)); - iop->ioc_count = 0; - error = 0; - break; - - case PPPIO_GIDLE: - if ((ppa = us->ppa) == 0) - break; - mq = allocb(sizeof(struct ppp_idle), BPRI_HI); - if (mq == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = mq; - mq->b_cont = 0; - pip = (struct ppp_idle *) mq->b_wptr; - pip->xmit_idle = time - ppa->last_sent; - pip->recv_idle = time - ppa->last_recv; - mq->b_wptr += sizeof(struct ppp_idle); - iop->ioc_count = sizeof(struct ppp_idle); - error = 0; - break; - -#ifdef LACHTCP - case SIOCSIFNAME: - /* Sent from IP down to us. Attach the ifstats structure. */ - if (iop->ioc_count != sizeof(struct ifreq) || us->ppa == 0) - break; - ifr = (struct ifreq *)mp->b_cont->b_rptr; - /* Find the unit number in the interface name. */ - for (i = 0; i < IFNAMSIZ; i++) { - if (ifr->ifr_name[i] == 0 || - (ifr->ifr_name[i] >= '0' && - ifr->ifr_name[i] <= '9')) - break; - else - us->ifname[i] = ifr->ifr_name[i]; - } - us->ifname[i] = 0; - - /* Convert the unit number to binary. */ - for (n = 0; i < IFNAMSIZ; i++) { - if (ifr->ifr_name[i] == 0) { - break; - } - else { - n = n * 10 + ifr->ifr_name[i] - '0'; - } - } - - /* Verify the ppa. */ - if (us->ppa->ppa_id != n) - break; - ppa = us->ppa; - - /* Set up the netstat block. */ - strncpy (ppa->ifname, us->ifname, IFNAMSIZ); - - ppa->ifstats.ifs_name = ppa->ifname; - ppa->ifstats.ifs_unit = n; - ppa->ifstats.ifs_active = us->state != DL_UNBOUND; - ppa->ifstats.ifs_mtu = ppa->mtu; - - /* Link in statistics used by netstat. */ - ppa->ifstats.ifs_next = ifstats; - ifstats = &ppa->ifstats; - - iop->ioc_count = 0; - error = 0; - break; - - case SIOCGIFFLAGS: - if (!(us->flags & US_CONTROL)) { - if (us->ppa) - us = us->ppa; - else - break; - } - ((struct iocblk_in *)iop)->ioc_ifflags = us->ifflags; - error = 0; - break; - - case SIOCSIFFLAGS: - if (!(us->flags & US_CONTROL)) { - if (us->ppa) - us = us->ppa; - else - break; - } - us->ifflags = ((struct iocblk_in *)iop)->ioc_ifflags; - error = 0; - break; - - case SIOCSIFADDR: - if (!(us->flags & US_CONTROL)) { - if (us->ppa) - us = us->ppa; - else - break; - } - us->ifflags |= IFF_RUNNING; - ((struct iocblk_in *)iop)->ioc_ifflags |= IFF_RUNNING; - error = 0; - break; - - case SIOCSIFMTU: - /* - * Vanilla SVR4 systems don't handle SIOCSIFMTU, rather - * they take the MTU from the DL_INFO_ACK we sent in response - * to their DL_INFO_REQ. Fortunately, they will update the - * MTU if we send an unsolicited DL_INFO_ACK up. - */ - if ((mq = allocb(sizeof(dl_info_req_t), BPRI_HI)) == 0) - break; /* should do bufcall */ - ((union DL_primitives *)mq->b_rptr)->dl_primitive = DL_INFO_REQ; - mq->b_wptr = mq->b_rptr + sizeof(dl_info_req_t); - dlpi_request(q, mq, us); - error = 0; - break; - - case SIOCGIFNETMASK: - case SIOCSIFNETMASK: - case SIOCGIFADDR: - case SIOCGIFDSTADDR: - case SIOCSIFDSTADDR: - case SIOCGIFMETRIC: - error = 0; - break; -#endif /* LACHTCP */ - - default: - if (us->ppa == 0 || us->ppa->lowerq == 0) - break; - us->ioc_id = iop->ioc_id; - error = -1; - switch (iop->ioc_cmd) { - case PPPIO_GETSTAT: - case PPPIO_GETCSTAT: - if (us->flags & US_LASTMOD) { - error = EINVAL; - break; - } - putnext(us->ppa->lowerq, mp); - break; - default: - if (us->flags & US_PRIV) - putnext(us->ppa->lowerq, mp); - else { - DPRINT1("ppp ioctl %x rejected\n", iop->ioc_cmd); - error = EPERM; - } - break; - } - break; - } - - if (error > 0) { - iop->ioc_error = error; - mp->b_datap->db_type = M_IOCNAK; - qreply(q, mp); - } else if (error == 0) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } - break; - - case M_FLUSH: - if (us->flags & US_DBGLOG) - DPRINT2("ppp/%d: flush %x\n", us->mn, *mp->b_rptr); - if (*mp->b_rptr & FLUSHW) - flushq(q, FLUSHDATA); - if (*mp->b_rptr & FLUSHR) { - *mp->b_rptr &= ~FLUSHW; - qreply(q, mp); - } else - freemsg(mp); - break; - - default: - freemsg(mp); - break; - } - return 0; -} - -#ifndef NO_DLPI -static void -dlpi_request(q, mp, us) - queue_t *q; - mblk_t *mp; - upperstr_t *us; -{ - union DL_primitives *d = (union DL_primitives *) mp->b_rptr; - int size = mp->b_wptr - mp->b_rptr; - mblk_t *reply, *np; - upperstr_t *ppa, *os; - int sap, len; - dl_info_ack_t *info; - dl_bind_ack_t *ackp; -#if DL_CURRENT_VERSION >= 2 - dl_phys_addr_ack_t *paddrack; - static struct ether_addr eaddr = {0}; -#endif - - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: dlpi prim %x len=%d\n", us->mn, - d->dl_primitive, size); - switch (d->dl_primitive) { - case DL_INFO_REQ: - if (size < sizeof(dl_info_req_t)) - goto badprim; - if ((reply = allocb(sizeof(dl_info_ack_t), BPRI_HI)) == 0) - break; /* should do bufcall */ - reply->b_datap->db_type = M_PCPROTO; - info = (dl_info_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_info_ack_t); - bzero((caddr_t) info, sizeof(dl_info_ack_t)); - info->dl_primitive = DL_INFO_ACK; - info->dl_max_sdu = us->ppa? us->ppa->mtu: PPP_MAXMTU; - info->dl_min_sdu = 1; - info->dl_addr_length = sizeof(uint); - info->dl_mac_type = DL_ETHER; /* a bigger lie */ - info->dl_current_state = us->state; - info->dl_service_mode = DL_CLDLS; - info->dl_provider_style = DL_STYLE2; -#if DL_CURRENT_VERSION >= 2 - info->dl_sap_length = sizeof(uint); - info->dl_version = DL_CURRENT_VERSION; -#endif - qreply(q, reply); - break; - - case DL_ATTACH_REQ: - if (size < sizeof(dl_attach_req_t)) - goto badprim; - if (us->state != DL_UNATTACHED || us->ppa != 0) { - dlpi_error(q, us, DL_ATTACH_REQ, DL_OUTSTATE, 0); - break; - } - for (ppa = ppas; ppa != 0; ppa = ppa->nextppa) - if (ppa->ppa_id == d->attach_req.dl_ppa) - break; - if (ppa == 0) { - dlpi_error(q, us, DL_ATTACH_REQ, DL_BADPPA, 0); - break; - } - us->ppa = ppa; - qwriter(q, mp, attach_ppa, PERIM_OUTER); - return; - - case DL_DETACH_REQ: - if (size < sizeof(dl_detach_req_t)) - goto badprim; - if (us->state != DL_UNBOUND || us->ppa == 0) { - dlpi_error(q, us, DL_DETACH_REQ, DL_OUTSTATE, 0); - break; - } - qwriter(q, mp, detach_ppa, PERIM_OUTER); - return; - - case DL_BIND_REQ: - if (size < sizeof(dl_bind_req_t)) - goto badprim; - if (us->state != DL_UNBOUND || us->ppa == 0) { - dlpi_error(q, us, DL_BIND_REQ, DL_OUTSTATE, 0); - break; - } -#if 0 - /* apparently this test fails (unnecessarily?) on some systems */ - if (d->bind_req.dl_service_mode != DL_CLDLS) { - dlpi_error(q, us, DL_BIND_REQ, DL_UNSUPPORTED, 0); - break; - } -#endif - - /* saps must be valid PPP network protocol numbers, - except that we accept ETHERTYPE_IP in place of PPP_IP. */ - sap = d->bind_req.dl_sap; - us->req_sap = sap; - -#if defined(SOL2) - if (us->flags & US_DBGLOG) - DPRINT2("DL_BIND_REQ: ip gives sap = 0x%x, us = 0x%x", sap, us); - - if (sap == ETHERTYPE_IP) /* normal IFF_IPV4 */ - sap = PPP_IP; - else if (sap == ETHERTYPE_IPV6) /* when IFF_IPV6 is set */ - sap = PPP_IPV6; - else if (sap == ETHERTYPE_ALLSAP) /* snoop gives sap of 0 */ - sap = PPP_ALLSAP; - else { - DPRINT2("DL_BIND_REQ: unrecognized sap = 0x%x, us = 0x%x", sap, us); - dlpi_error(q, us, DL_BIND_REQ, DL_BADADDR, 0); - break; - } -#else - if (sap == ETHERTYPE_IP) - sap = PPP_IP; - if (sap < 0x21 || sap > 0x3fff || (sap & 0x101) != 1) { - dlpi_error(q, us, DL_BIND_REQ, DL_BADADDR, 0); - break; - } -#endif /* defined(SOL2) */ - - /* check that no other stream is bound to this sap already. */ - for (os = us->ppa; os != 0; os = os->next) - if (os->sap == sap) - break; - if (os != 0) { - dlpi_error(q, us, DL_BIND_REQ, DL_NOADDR, 0); - break; - } - - us->sap = sap; - us->state = DL_IDLE; - - if ((reply = allocb(sizeof(dl_bind_ack_t) + sizeof(uint), - BPRI_HI)) == 0) - break; /* should do bufcall */ - ackp = (dl_bind_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_bind_ack_t) + sizeof(uint); - reply->b_datap->db_type = M_PCPROTO; - bzero((caddr_t) ackp, sizeof(dl_bind_ack_t)); - ackp->dl_primitive = DL_BIND_ACK; - ackp->dl_sap = sap; - ackp->dl_addr_length = sizeof(uint); - ackp->dl_addr_offset = sizeof(dl_bind_ack_t); - *(uint *)(ackp+1) = sap; - qreply(q, reply); - break; - - case DL_UNBIND_REQ: - if (size < sizeof(dl_unbind_req_t)) - goto badprim; - if (us->state != DL_IDLE) { - dlpi_error(q, us, DL_UNBIND_REQ, DL_OUTSTATE, 0); - break; - } - us->sap = -1; - us->state = DL_UNBOUND; -#ifdef LACHTCP - us->ppa->ifstats.ifs_active = 0; -#endif - dlpi_ok(q, DL_UNBIND_REQ); - break; - - case DL_UNITDATA_REQ: - if (size < sizeof(dl_unitdata_req_t)) - goto badprim; - if (us->state != DL_IDLE) { - dlpi_error(q, us, DL_UNITDATA_REQ, DL_OUTSTATE, 0); - break; - } - if ((ppa = us->ppa) == 0) { - cmn_err(CE_CONT, "ppp: in state dl_idle but ppa == 0?\n"); - break; - } - len = mp->b_cont == 0? 0: msgdsize(mp->b_cont); - if (len > ppa->mtu) { - DPRINT2("dlpi data too large (%d > %d)\n", len, ppa->mtu); - break; - } - -#if defined(SOL2) - /* - * Should there be any promiscuous stream(s), send the data - * up for each promiscuous stream that we recognize. - */ - if (mp->b_cont) - promisc_sendup(ppa, mp->b_cont, us->sap, 0); -#endif /* defined(SOL2) */ - - mp->b_band = 0; -#ifdef PRIOQ - /* Extract s_port & d_port from IP-packet, the code is a bit - dirty here, but so am I, too... */ - if (mp->b_datap->db_type == M_PROTO && us->sap == PPP_IP - && mp->b_cont != 0) { - u_char *bb, *tlh; - int iphlen, len; - u_short *ptr; - u_char band_unset, cur_band, syn; - u_short s_port, d_port; - - bb = mp->b_cont->b_rptr; /* bb points to IP-header*/ - len = mp->b_cont->b_wptr - mp->b_cont->b_rptr; - syn = 0; - s_port = IPPORT_DEFAULT; - d_port = IPPORT_DEFAULT; - if (len >= 20) { /* 20 = minimum length of IP header */ - iphlen = (bb[0] & 0x0f) * 4; - tlh = bb + iphlen; - len -= iphlen; - switch (bb[9]) { - case IPPROTO_TCP: - if (len >= 20) { /* min length of TCP header */ - s_port = (tlh[0] << 8) + tlh[1]; - d_port = (tlh[2] << 8) + tlh[3]; - syn = tlh[13] & 0x02; - } - break; - case IPPROTO_UDP: - if (len >= 8) { /* min length of UDP header */ - s_port = (tlh[0] << 8) + tlh[1]; - d_port = (tlh[2] << 8) + tlh[3]; - } - break; - } - } - - /* - * Now calculate b_band for this packet from the - * port-priority table. - */ - ptr = prioq_table; - cur_band = max_band; - band_unset = 1; - while (*ptr) { - while (*ptr && band_unset) - if (s_port == *ptr || d_port == *ptr++) { - mp->b_band = cur_band; - band_unset = 0; - break; - } - ptr++; - cur_band--; - } - if (band_unset) - mp->b_band = def_band; - /* It may be usable to urge SYN packets a bit */ - if (syn) - mp->b_band++; - } -#endif /* PRIOQ */ - /* this assumes PPP_HDRLEN <= sizeof(dl_unitdata_req_t) */ - if (mp->b_datap->db_ref > 1) { - np = allocb(PPP_HDRLEN, BPRI_HI); - if (np == 0) - break; /* gak! */ - np->b_cont = mp->b_cont; - mp->b_cont = 0; - freeb(mp); - mp = np; - } else - mp->b_datap->db_type = M_DATA; - /* XXX should use dl_dest_addr_offset/length here, - but we would have to translate ETHERTYPE_IP -> PPP_IP */ - mp->b_wptr = mp->b_rptr + PPP_HDRLEN; - mp->b_rptr[0] = PPP_ALLSTATIONS; - mp->b_rptr[1] = PPP_UI; - mp->b_rptr[2] = us->sap >> 8; - mp->b_rptr[3] = us->sap; - if (pass_packet(us, mp, 1)) { - if (!send_data(mp, us)) - putq(q, mp); - } - return; - -#if DL_CURRENT_VERSION >= 2 - case DL_PHYS_ADDR_REQ: - if (size < sizeof(dl_phys_addr_req_t)) - goto badprim; - - /* - * Don't check state because ifconfig sends this one down too - */ - - if ((reply = allocb(sizeof(dl_phys_addr_ack_t)+ETHERADDRL, - BPRI_HI)) == 0) - break; /* should do bufcall */ - reply->b_datap->db_type = M_PCPROTO; - paddrack = (dl_phys_addr_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_phys_addr_ack_t); - bzero((caddr_t) paddrack, sizeof(dl_phys_addr_ack_t)+ETHERADDRL); - paddrack->dl_primitive = DL_PHYS_ADDR_ACK; - paddrack->dl_addr_length = ETHERADDRL; - paddrack->dl_addr_offset = sizeof(dl_phys_addr_ack_t); - bcopy(&eaddr, reply->b_wptr, ETHERADDRL); - reply->b_wptr += ETHERADDRL; - qreply(q, reply); - break; - -#if defined(SOL2) - case DL_PROMISCON_REQ: - if (size < sizeof(dl_promiscon_req_t)) - goto badprim; - us->flags |= US_PROMISC; - dlpi_ok(q, DL_PROMISCON_REQ); - break; - - case DL_PROMISCOFF_REQ: - if (size < sizeof(dl_promiscoff_req_t)) - goto badprim; - us->flags &= ~US_PROMISC; - dlpi_ok(q, DL_PROMISCOFF_REQ); - break; -#else - case DL_PROMISCON_REQ: /* fall thru */ - case DL_PROMISCOFF_REQ: /* fall thru */ -#endif /* defined(SOL2) */ -#endif /* DL_CURRENT_VERSION >= 2 */ - -#if DL_CURRENT_VERSION >= 2 - case DL_SET_PHYS_ADDR_REQ: - case DL_SUBS_BIND_REQ: - case DL_SUBS_UNBIND_REQ: - case DL_ENABMULTI_REQ: - case DL_DISABMULTI_REQ: - case DL_XID_REQ: - case DL_TEST_REQ: - case DL_REPLY_UPDATE_REQ: - case DL_REPLY_REQ: - case DL_DATA_ACK_REQ: -#endif - case DL_CONNECT_REQ: - case DL_TOKEN_REQ: - dlpi_error(q, us, d->dl_primitive, DL_NOTSUPPORTED, 0); - break; - - case DL_CONNECT_RES: - case DL_DISCONNECT_REQ: - case DL_RESET_REQ: - case DL_RESET_RES: - dlpi_error(q, us, d->dl_primitive, DL_OUTSTATE, 0); - break; - - case DL_UDQOS_REQ: - dlpi_error(q, us, d->dl_primitive, DL_BADQOSTYPE, 0); - break; - -#if DL_CURRENT_VERSION >= 2 - case DL_TEST_RES: - case DL_XID_RES: - break; -#endif - - default: - cmn_err(CE_CONT, "ppp: unknown dlpi prim 0x%x\n", d->dl_primitive); - /* fall through */ - badprim: - dlpi_error(q, us, d->dl_primitive, DL_BADPRIM, 0); - break; - } - freemsg(mp); -} - -static void -dlpi_error(q, us, prim, err, uerr) - queue_t *q; - upperstr_t *us; - int prim, err, uerr; -{ - mblk_t *reply; - dl_error_ack_t *errp; - - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: dlpi error, prim=%x, err=%x\n", us->mn, prim, err); - reply = allocb(sizeof(dl_error_ack_t), BPRI_HI); - if (reply == 0) - return; /* XXX should do bufcall */ - reply->b_datap->db_type = M_PCPROTO; - errp = (dl_error_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_error_ack_t); - errp->dl_primitive = DL_ERROR_ACK; - errp->dl_error_primitive = prim; - errp->dl_errno = err; - errp->dl_unix_errno = uerr; - qreply(q, reply); -} - -static void -dlpi_ok(q, prim) - queue_t *q; - int prim; -{ - mblk_t *reply; - dl_ok_ack_t *okp; - - reply = allocb(sizeof(dl_ok_ack_t), BPRI_HI); - if (reply == 0) - return; /* XXX should do bufcall */ - reply->b_datap->db_type = M_PCPROTO; - okp = (dl_ok_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_ok_ack_t); - okp->dl_primitive = DL_OK_ACK; - okp->dl_correct_primitive = prim; - qreply(q, reply); -} -#endif /* NO_DLPI */ - -static int -pass_packet(us, mp, outbound) - upperstr_t *us; - mblk_t *mp; - int outbound; -{ - int pass; - upperstr_t *ppa; - - if ((ppa = us->ppa) == 0) { - freemsg(mp); - return 0; - } - -#ifdef FILTER_PACKETS - pass = ip_hard_filter(us, mp, outbound); -#else - /* - * Here is where we might, in future, decide whether to pass - * or drop the packet, and whether it counts as link activity. - */ - pass = 1; -#endif /* FILTER_PACKETS */ - - if (pass < 0) { - /* pass only if link already up, and don't update time */ - if (ppa->lowerq == 0) { - freemsg(mp); - return 0; - } - pass = 1; - } else if (pass) { - if (outbound) - ppa->last_sent = time; - else - ppa->last_recv = time; - } - - return pass; -} - -/* - * We have some data to send down to the lower stream (or up the - * control stream, if we don't have a lower stream attached). - * Returns 1 if the message was dealt with, 0 if it wasn't able - * to be sent on and should therefore be queued up. - */ -static int -send_data(mp, us) - mblk_t *mp; - upperstr_t *us; -{ - upperstr_t *ppa; - - if ((us->flags & US_BLOCKED) || us->npmode == NPMODE_QUEUE) - return 0; - ppa = us->ppa; - if (ppa == 0 || us->npmode == NPMODE_DROP || us->npmode == NPMODE_ERROR) { - if (us->flags & US_DBGLOG) - DPRINT2("ppp/%d: dropping pkt (npmode=%d)\n", us->mn, us->npmode); - freemsg(mp); - return 1; - } - if (ppa->lowerq == 0) { - /* try to send it up the control stream */ - if (bcanputnext(ppa->q, mp->b_band)) { - /* - * The message seems to get corrupted for some reason if - * we just send the message up as it is, so we send a copy. - */ - mblk_t *np = copymsg(mp); - freemsg(mp); - if (np != 0) - putnext(ppa->q, np); - return 1; - } - } else { - if (bcanputnext(ppa->lowerq, mp->b_band)) { - MT_ENTER(&ppa->stats_lock); - ppa->stats.ppp_opackets++; - ppa->stats.ppp_obytes += msgdsize(mp); -#ifdef INCR_OPACKETS - INCR_OPACKETS(ppa); -#endif - MT_EXIT(&ppa->stats_lock); - /* - * The lower queue is only ever detached while holding an - * exclusive lock on the whole driver. So we can be confident - * that the lower queue is still there. - */ - putnext(ppa->lowerq, mp); - return 1; - } - } - us->flags |= US_BLOCKED; - return 0; -} - -/* - * Allocate a new PPA id and link this stream into the list of PPAs. - * This procedure is called with an exclusive lock on all queues in - * this driver. - */ -static void -new_ppa(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us, *up, **usp; - int ppa_id; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("new_ppa: q_ptr = 0!\n"); - return; - } - - usp = &ppas; - ppa_id = 0; - while ((up = *usp) != 0 && ppa_id == up->ppa_id) { - ++ppa_id; - usp = &up->nextppa; - } - us->ppa_id = ppa_id; - us->ppa = us; - us->next = 0; - us->nextppa = *usp; - *usp = us; - us->flags |= US_CONTROL; - us->npmode = NPMODE_PASS; - - us->mtu = PPP_MTU; - us->mru = PPP_MRU; - -#ifdef SOL2 - /* - * Create a kstats record for our statistics, so netstat -i works. - */ - if (us->kstats == 0) { - char unit[32]; - - sprintf(unit, "ppp%d", us->ppa->ppa_id); - us->kstats = kstat_create("ppp", us->ppa->ppa_id, unit, - "net", KSTAT_TYPE_NAMED, 4, 0); - if (us->kstats != 0) { - kstat_named_t *kn = KSTAT_NAMED_PTR(us->kstats); - - strcpy(kn[0].name, "ipackets"); - kn[0].data_type = KSTAT_DATA_ULONG; - strcpy(kn[1].name, "ierrors"); - kn[1].data_type = KSTAT_DATA_ULONG; - strcpy(kn[2].name, "opackets"); - kn[2].data_type = KSTAT_DATA_ULONG; - strcpy(kn[3].name, "oerrors"); - kn[3].data_type = KSTAT_DATA_ULONG; - kstat_install(us->kstats); - } - } -#endif /* SOL2 */ - - *(int *)mp->b_cont->b_rptr = ppa_id; - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); -} - -static void -attach_ppa(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us, *t; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("attach_ppa: q_ptr = 0!\n"); - return; - } - -#ifndef NO_DLPI - us->state = DL_UNBOUND; -#endif - for (t = us->ppa; t->next != 0; t = t->next) - ; - t->next = us; - us->next = 0; - if (mp->b_datap->db_type == M_IOCTL) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } else { -#ifndef NO_DLPI - dlpi_ok(q, DL_ATTACH_REQ); -#endif - } -} - -static void -detach_ppa(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us, *t; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("detach_ppa: q_ptr = 0!\n"); - return; - } - - for (t = us->ppa; t->next != 0; t = t->next) - if (t->next == us) { - t->next = us->next; - break; - } - us->next = 0; - us->ppa = 0; -#ifndef NO_DLPI - us->state = DL_UNATTACHED; - dlpi_ok(q, DL_DETACH_REQ); -#endif -} - -/* - * We call this with qwriter in order to give the upper queue procedures - * the guarantee that the lower queue is not going to go away while - * they are executing. - */ -static void -detach_lower(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("detach_lower: q_ptr = 0!\n"); - return; - } - - LOCK_LOWER_W; - us->lowerq->q_ptr = 0; - RD(us->lowerq)->q_ptr = 0; - us->lowerq = 0; - UNLOCK_LOWER; - - /* Unblock streams which now feed back up the control stream. */ - qenable(us->q); - - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); -} - -static int -pppuwsrv(q) - queue_t *q; -{ - upperstr_t *us, *as; - mblk_t *mp; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("pppuwsrv: q_ptr = 0!\n"); - return 0; - } - - /* - * If this is a control stream, then this service procedure - * probably got enabled because of flow control in the lower - * stream being enabled (or because of the lower stream going - * away). Therefore we enable the service procedure of all - * attached upper streams. - */ - if (us->flags & US_CONTROL) { - for (as = us->next; as != 0; as = as->next) - qenable(WR(as->q)); - } - - /* Try to send on any data queued here. */ - us->flags &= ~US_BLOCKED; - while ((mp = getq(q)) != 0) { - if (!send_data(mp, us)) { - putbq(q, mp); - break; - } - } - - return 0; -} - -/* should never get called... */ -static int -ppplwput(q, mp) - queue_t *q; - mblk_t *mp; -{ - putnext(q, mp); - return 0; -} - -static int -ppplwsrv(q) - queue_t *q; -{ - queue_t *uq; - - /* - * Flow control has back-enabled this stream: - * enable the upper write service procedure for - * the upper control stream for this lower stream. - */ - LOCK_LOWER_R; - uq = (queue_t *) q->q_ptr; - if (uq != 0) - qenable(uq); - UNLOCK_LOWER; - return 0; -} - -/* - * This should only get called for control streams. - */ -static int -pppurput(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *ppa, *us; - int proto, len; - struct iocblk *iop; - - ppa = (upperstr_t *) q->q_ptr; - if (ppa == 0) { - DPRINT("pppurput: q_ptr = 0!\n"); - return 0; - } - - switch (mp->b_datap->db_type) { - case M_CTL: - MT_ENTER(&ppa->stats_lock); - switch (*mp->b_rptr) { - case PPPCTL_IERROR: -#ifdef INCR_IERRORS - INCR_IERRORS(ppa); -#endif - ppa->stats.ppp_ierrors++; - break; - case PPPCTL_OERROR: -#ifdef INCR_OERRORS - INCR_OERRORS(ppa); -#endif - ppa->stats.ppp_oerrors++; - break; - } - MT_EXIT(&ppa->stats_lock); - freemsg(mp); - break; - - case M_IOCACK: - case M_IOCNAK: - /* - * Attempt to match up the response with the stream - * that the request came from. - */ - iop = (struct iocblk *) mp->b_rptr; - for (us = ppa; us != 0; us = us->next) - if (us->ioc_id == iop->ioc_id) - break; - if (us == 0) - freemsg(mp); - else - putnext(us->q, mp); - break; - - case M_HANGUP: - /* - * The serial device has hung up. We don't want to send - * the M_HANGUP message up to pppd because that will stop - * us from using the control stream any more. Instead we - * send a zero-length message as an end-of-file indication. - */ - freemsg(mp); - mp = allocb(1, BPRI_HI); - if (mp == 0) { - DPRINT1("ppp/%d: couldn't allocate eof message!\n", ppa->mn); - break; - } - putnext(ppa->q, mp); - break; - - default: - if (mp->b_datap->db_type == M_DATA) { - len = msgdsize(mp); - if (mp->b_wptr - mp->b_rptr < PPP_HDRLEN) { - PULLUP(mp, PPP_HDRLEN); - if (mp == 0) { - DPRINT1("ppp_urput: msgpullup failed (len=%d)\n", len); - break; - } - } - MT_ENTER(&ppa->stats_lock); - ppa->stats.ppp_ipackets++; - ppa->stats.ppp_ibytes += len; -#ifdef INCR_IPACKETS - INCR_IPACKETS(ppa); -#endif - MT_EXIT(&ppa->stats_lock); - - proto = PPP_PROTOCOL(mp->b_rptr); - -#if defined(SOL2) - /* - * Should there be any promiscuous stream(s), send the data - * up for each promiscuous stream that we recognize. - */ - promisc_sendup(ppa, mp, proto, 1); -#endif /* defined(SOL2) */ - - if (proto < 0x8000 && (us = find_dest(ppa, proto)) != 0) { - /* - * A data packet for some network protocol. - * Queue it on the upper stream for that protocol. - * XXX could we just putnext it? (would require thought) - * The rblocked flag is there to ensure that we keep - * messages in order for each network protocol. - */ - if (!pass_packet(us, mp, 0)) - break; - if (!us->rblocked && !canput(us->q)) - us->rblocked = 1; - if (!us->rblocked) - putq(us->q, mp); - else - putq(q, mp); - break; - } - } - /* - * A control frame, a frame for an unknown protocol, - * or some other message type. - * Send it up to pppd via the control stream. - */ - if (queclass(mp) == QPCTL || canputnext(ppa->q)) - putnext(ppa->q, mp); - else - putq(q, mp); - break; - } - - return 0; -} - -static int -pppursrv(q) - queue_t *q; -{ - upperstr_t *us, *as; - mblk_t *mp, *hdr; -#ifndef NO_DLPI - dl_unitdata_ind_t *ud; -#endif - int proto; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("pppursrv: q_ptr = 0!\n"); - return 0; - } - - if (us->flags & US_CONTROL) { - /* - * A control stream. - * If there is no lower queue attached, run the write service - * routines of other upper streams attached to this PPA. - */ - if (us->lowerq == 0) { - as = us; - do { - if (as->flags & US_BLOCKED) - qenable(WR(as->q)); - as = as->next; - } while (as != 0); - } - - /* - * Messages get queued on this stream's read queue if they - * can't be queued on the read queue of the attached stream - * that they are destined for. This is for flow control - - * when this queue fills up, the lower read put procedure will - * queue messages there and the flow control will propagate - * down from there. - */ - while ((mp = getq(q)) != 0) { - proto = PPP_PROTOCOL(mp->b_rptr); - if (proto < 0x8000 && (as = find_dest(us, proto)) != 0) { - if (!canput(as->q)) - break; - putq(as->q, mp); - } else { - if (!canputnext(q)) - break; - putnext(q, mp); - } - } - if (mp) { - putbq(q, mp); - } else { - /* can now put stuff directly on network protocol streams again */ - for (as = us->next; as != 0; as = as->next) - as->rblocked = 0; - } - - /* - * If this stream has a lower stream attached, - * enable the read queue's service routine. - * XXX we should really only do this if the queue length - * has dropped below the low-water mark. - */ - if (us->lowerq != 0) - qenable(RD(us->lowerq)); - - } else { - /* - * A network protocol stream. Put a DLPI header on each - * packet and send it on. - * (Actually, it seems that the IP module will happily - * accept M_DATA messages without the DL_UNITDATA_IND header.) - */ - while ((mp = getq(q)) != 0) { - if (!canputnext(q)) { - putbq(q, mp); - break; - } -#ifndef NO_DLPI - proto = PPP_PROTOCOL(mp->b_rptr); - mp->b_rptr += PPP_HDRLEN; - hdr = allocb(sizeof(dl_unitdata_ind_t) + 2 * sizeof(uint), - BPRI_MED); - if (hdr == 0) { - /* XXX should put it back and use bufcall */ - freemsg(mp); - continue; - } - hdr->b_datap->db_type = M_PROTO; - ud = (dl_unitdata_ind_t *) hdr->b_wptr; - hdr->b_wptr += sizeof(dl_unitdata_ind_t) + 2 * sizeof(uint); - hdr->b_cont = mp; - ud->dl_primitive = DL_UNITDATA_IND; - ud->dl_dest_addr_length = sizeof(uint); - ud->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t); - ud->dl_src_addr_length = sizeof(uint); - ud->dl_src_addr_offset = ud->dl_dest_addr_offset + sizeof(uint); -#if DL_CURRENT_VERSION >= 2 - ud->dl_group_address = 0; -#endif - /* Send the DLPI client the data with the SAP they requested, - (e.g. ETHERTYPE_IP) rather than the PPP protocol number - (e.g. PPP_IP) */ - ((uint *)(ud + 1))[0] = us->req_sap; /* dest SAP */ - ((uint *)(ud + 1))[1] = us->req_sap; /* src SAP */ - putnext(q, hdr); -#else /* NO_DLPI */ - putnext(q, mp); -#endif /* NO_DLPI */ - } - /* - * Now that we have consumed some packets from this queue, - * enable the control stream's read service routine so that we - * can process any packets for us that might have got queued - * there for flow control reasons. - */ - if (us->ppa) - qenable(us->ppa->q); - } - - return 0; -} - -static upperstr_t * -find_dest(ppa, proto) - upperstr_t *ppa; - int proto; -{ - upperstr_t *us; - - for (us = ppa->next; us != 0; us = us->next) - if (proto == us->sap) - break; - return us; -} - -#if defined (SOL2) -/* - * Test upstream promiscuous conditions. As of now, only pass IPv4 and - * Ipv6 packets upstream (let PPP packets be decoded elsewhere). - */ -static upperstr_t * -find_promisc(us, proto) - upperstr_t *us; - int proto; -{ - - if ((proto != PPP_IP) && (proto != PPP_IPV6)) - return (upperstr_t *)0; - - for ( ; us; us = us->next) { - if ((us->flags & US_PROMISC) && (us->state == DL_IDLE)) - return us; - } - - return (upperstr_t *)0; -} - -/* - * Prepend an empty Ethernet header to msg for snoop, et al. - */ -static mblk_t * -prepend_ether(us, mp, proto) - upperstr_t *us; - mblk_t *mp; - int proto; -{ - mblk_t *eh; - int type; - - if ((eh = allocb(sizeof(struct ether_header), BPRI_HI)) == 0) { - freemsg(mp); - return (mblk_t *)0; - } - - if (proto == PPP_IP) - type = ETHERTYPE_IP; - else if (proto == PPP_IPV6) - type = ETHERTYPE_IPV6; - else - type = proto; /* What else? Let decoder decide */ - - eh->b_wptr += sizeof(struct ether_header); - bzero((caddr_t)eh->b_rptr, sizeof(struct ether_header)); - ((struct ether_header *)eh->b_rptr)->ether_type = htons((short)type); - eh->b_cont = mp; - return (eh); -} - -/* - * Prepend DL_UNITDATA_IND mblk to msg - */ -static mblk_t * -prepend_udind(us, mp, proto) - upperstr_t *us; - mblk_t *mp; - int proto; -{ - dl_unitdata_ind_t *dlu; - mblk_t *dh; - size_t size; - - size = sizeof(dl_unitdata_ind_t); - if ((dh = allocb(size, BPRI_MED)) == 0) { - freemsg(mp); - return (mblk_t *)0; - } - - dh->b_datap->db_type = M_PROTO; - dh->b_wptr = dh->b_datap->db_lim; - dh->b_rptr = dh->b_wptr - size; - - dlu = (dl_unitdata_ind_t *)dh->b_rptr; - dlu->dl_primitive = DL_UNITDATA_IND; - dlu->dl_dest_addr_length = 0; - dlu->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t); - dlu->dl_src_addr_length = 0; - dlu->dl_src_addr_offset = sizeof(dl_unitdata_ind_t); - dlu->dl_group_address = 0; - - dh->b_cont = mp; - return (dh); -} - -/* - * For any recognized promiscuous streams, send data upstream - */ -static void -promisc_sendup(ppa, mp, proto, skip) - upperstr_t *ppa; - mblk_t *mp; - int proto, skip; -{ - mblk_t *dup_mp, *dup_dup_mp; - upperstr_t *prus, *nprus; - - if ((prus = find_promisc(ppa, proto)) != 0) { - if (dup_mp = dupmsg(mp)) { - - if (skip) - dup_mp->b_rptr += PPP_HDRLEN; - - for ( ; nprus = find_promisc(prus->next, proto); - prus = nprus) { - - if (dup_dup_mp = dupmsg(dup_mp)) { - if (canputnext(prus->q)) { - if (prus->flags & US_RAWDATA) { - dup_dup_mp = prepend_ether(prus, dup_dup_mp, proto); - putnext(prus->q, dup_dup_mp); - } else { - dup_dup_mp = prepend_udind(prus, dup_dup_mp, proto); - putnext(prus->q, dup_dup_mp); - } - } else { - DPRINT("ppp_urput: data to promisc q dropped\n"); - freemsg(dup_dup_mp); - } - } - } - - if (canputnext(prus->q)) { - if (prus->flags & US_RAWDATA) { - dup_mp = prepend_ether(prus, dup_mp, proto); - putnext(prus->q, dup_mp); - } else { - dup_mp = prepend_udind(prus, dup_mp, proto); - putnext(prus->q, dup_mp); - } - } else { - DPRINT("ppp_urput: data to promisc q dropped\n"); - freemsg(dup_mp); - } - } - } -} -#endif /* defined(SOL2) */ - -/* - * We simply put the message on to the associated upper control stream - * (either here or in ppplrsrv). That way we enter the perimeters - * before looking through the list of attached streams to decide which - * stream it should go up. - */ -static int -ppplrput(q, mp) - queue_t *q; - mblk_t *mp; -{ - queue_t *uq; - struct iocblk *iop; - - switch (mp->b_datap->db_type) { - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - iop->ioc_error = EINVAL; - mp->b_datap->db_type = M_IOCNAK; - qreply(q, mp); - return 0; - case M_FLUSH: - if (*mp->b_rptr & FLUSHR) - flushq(q, FLUSHDATA); - if (*mp->b_rptr & FLUSHW) { - *mp->b_rptr &= ~FLUSHR; - qreply(q, mp); - } else - freemsg(mp); - return 0; - } - - /* - * If we can't get the lower lock straight away, queue this one - * rather than blocking, to avoid the possibility of deadlock. - */ - if (!TRYLOCK_LOWER_R) { - putq(q, mp); - return 0; - } - - /* - * Check that we're still connected to the driver. - */ - uq = (queue_t *) q->q_ptr; - if (uq == 0) { - UNLOCK_LOWER; - DPRINT1("ppplrput: q = %x, uq = 0??\n", q); - freemsg(mp); - return 0; - } - - /* - * Try to forward the message to the put routine for the upper - * control stream for this lower stream. - * If there are already messages queued here, queue this one so - * they don't get out of order. - */ - if (queclass(mp) == QPCTL || (qsize(q) == 0 && canput(uq))) - put(uq, mp); - else - putq(q, mp); - - UNLOCK_LOWER; - return 0; -} - -static int -ppplrsrv(q) - queue_t *q; -{ - mblk_t *mp; - queue_t *uq; - - /* - * Packets get queued here for flow control reasons - * or if the lrput routine couldn't get the lower lock - * without blocking. - */ - LOCK_LOWER_R; - uq = (queue_t *) q->q_ptr; - if (uq == 0) { - UNLOCK_LOWER; - flushq(q, FLUSHALL); - DPRINT1("ppplrsrv: q = %x, uq = 0??\n", q); - return 0; - } - while ((mp = getq(q)) != 0) { - if (queclass(mp) == QPCTL || canput(uq)) - put(uq, mp); - else { - putbq(q, mp); - break; - } - } - UNLOCK_LOWER; - return 0; -} - -static int -putctl2(q, type, code, val) - queue_t *q; - int type, code, val; -{ - mblk_t *mp; - - mp = allocb(2, BPRI_HI); - if (mp == 0) - return 0; - mp->b_datap->db_type = type; - mp->b_wptr[0] = code; - mp->b_wptr[1] = val; - mp->b_wptr += 2; - putnext(q, mp); - return 1; -} - -static int -putctl4(q, type, code, val) - queue_t *q; - int type, code, val; -{ - mblk_t *mp; - - mp = allocb(4, BPRI_HI); - if (mp == 0) - return 0; - mp->b_datap->db_type = type; - mp->b_wptr[0] = code; - ((short *)mp->b_wptr)[1] = val; - mp->b_wptr += 4; - putnext(q, mp); - return 1; -} - -static void -debug_dump(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us; - queue_t *uq, *lq; - - DPRINT("ppp upper streams:\n"); - for (us = minor_devs; us != 0; us = us->nextmn) { - uq = us->q; - DPRINT3(" %d: q=%x rlev=%d", - us->mn, uq, (uq? qsize(uq): 0)); - DPRINT3(" wlev=%d flags=0x%b", (uq? qsize(WR(uq)): 0), - us->flags, "\020\1priv\2control\3blocked\4last"); - DPRINT3(" state=%x sap=%x req_sap=%x", us->state, us->sap, - us->req_sap); - if (us->ppa == 0) - DPRINT(" ppa=?\n"); - else - DPRINT1(" ppa=%d\n", us->ppa->ppa_id); - if (us->flags & US_CONTROL) { - lq = us->lowerq; - DPRINT3(" control for %d lq=%x rlev=%d", - us->ppa_id, lq, (lq? qsize(RD(lq)): 0)); - DPRINT3(" wlev=%d mru=%d mtu=%d\n", - (lq? qsize(lq): 0), us->mru, us->mtu); - } - } - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); -} - -#ifdef FILTER_PACKETS -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/udp.h> -#include <netinet/tcp.h> - -#define MAX_IPHDR 128 /* max TCP/IP header size */ - - -/* The following table contains a hard-coded list of protocol/port pairs. - * Any matching packets are either discarded unconditionally, or, - * if ok_if_link_up is non-zero when a connection does not currently exist - * (i.e., they go through if the connection is present, but never initiate - * a dial-out). - * This idea came from a post by dm@garage.uun.org (David Mazieres) - */ -static struct pktfilt_tab { - int proto; - u_short port; - u_short ok_if_link_up; -} pktfilt_tab[] = { - { IPPROTO_UDP, 520, 1 }, /* RIP, ok to pass if link is up */ - { IPPROTO_UDP, 123, 1 }, /* NTP, don't keep up the link for it */ - { -1, 0, 0 } /* terminator entry has port == -1 */ -}; - - -static int -ip_hard_filter(us, mp, outbound) - upperstr_t *us; - mblk_t *mp; - int outbound; -{ - struct ip *ip; - struct pktfilt_tab *pft; - mblk_t *temp_mp; - int proto; - int len, hlen; - - - /* Note, the PPP header has already been pulled up in all cases */ - proto = PPP_PROTOCOL(mp->b_rptr); - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: filter, proto=0x%x, out=%d\n", us->mn, proto, outbound); - - switch (proto) - { - case PPP_IP: - if ((mp->b_wptr - mp->b_rptr) == PPP_HDRLEN && mp->b_cont != 0) { - temp_mp = mp->b_cont; - len = msgdsize(temp_mp); - hlen = (len < MAX_IPHDR) ? len : MAX_IPHDR; - PULLUP(temp_mp, hlen); - if (temp_mp == 0) { - DPRINT2("ppp/%d: filter, pullup next failed, len=%d\n", - us->mn, hlen); - mp->b_cont = 0; /* PULLUP() freed the rest */ - freemsg(mp); - return 0; - } - ip = (struct ip *)mp->b_cont->b_rptr; - } - else { - len = msgdsize(mp); - hlen = (len < (PPP_HDRLEN+MAX_IPHDR)) ? len : (PPP_HDRLEN+MAX_IPHDR); - PULLUP(mp, hlen); - if (mp == 0) { - DPRINT2("ppp/%d: filter, pullup failed, len=%d\n", - us->mn, hlen); - return 0; - } - ip = (struct ip *)(mp->b_rptr + PPP_HDRLEN); - } - - /* For IP traffic, certain packets (e.g., RIP) may be either - * 1. ignored - dropped completely - * 2. will not initiate a connection, but - * will be passed if a connection is currently up. - */ - for (pft=pktfilt_tab; pft->proto != -1; pft++) { - if (ip->ip_p == pft->proto) { - switch(pft->proto) { - case IPPROTO_UDP: - if (((struct udphdr *) &((int *)ip)[ip->ip_hl])->uh_dport - == htons(pft->port)) goto endfor; - break; - case IPPROTO_TCP: - if (((struct tcphdr *) &((int *)ip)[ip->ip_hl])->th_dport - == htons(pft->port)) goto endfor; - break; - } - } - } - endfor: - if (pft->proto != -1) { - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: found IP pkt, proto=0x%x (%d)\n", - us->mn, pft->proto, pft->port); - /* Discard if not connected, or if not pass_with_link_up */ - /* else, if link is up let go by, but don't update time */ - return pft->ok_if_link_up? -1: 0; - } - break; - } /* end switch (proto) */ - - return 1; -} -#endif /* FILTER_PACKETS */ - diff --git a/mdk-stage1/ppp/modules/ppp_ahdlc.c b/mdk-stage1/ppp/modules/ppp_ahdlc.c deleted file mode 100644 index d0b961258..000000000 --- a/mdk-stage1/ppp/modules/ppp_ahdlc.c +++ /dev/null @@ -1,878 +0,0 @@ -/* - * ppp_ahdlc.c - STREAMS module for doing PPP asynchronous HDLC. - * - * Re-written by Adi Masputra <adi.masputra@sun.com>, based on - * the original ppp_ahdlc.c - * - * Copyright (c) 2000 by Sun Microsystems, Inc. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. - * - * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF - * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -/* - * This file is used under Solaris 2, SVR4, SunOS 4, and Digital UNIX. - */ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stream.h> -#include <sys/errno.h> - -#ifdef SVR4 -#include <sys/conf.h> -#include <sys/kmem.h> -#include <sys/cmn_err.h> -#include <sys/ddi.h> -#else -#include <sys/user.h> -#ifdef __osf__ -#include <sys/cmn_err.h> -#endif -#endif /* SVR4 */ - -#include <net/ppp_defs.h> -#include <net/pppio.h> -#include "ppp_mod.h" - -/* - * Right now, mutex is only enabled for Solaris 2.x - */ -#if defined(SOL2) -#define USE_MUTEX -#endif /* SOL2 */ - -/* - * intpointer_t and uintpointer_t are signed and unsigned integer types - * large enough to hold any data pointer; that is, data pointers can be - * assigned into or from these integer types without losing precision. - * On recent Solaris releases, these types are defined in sys/int_types.h, - * but not on SunOS 4.x or the earlier Solaris versions. - */ -#if defined(_LP64) || defined(_I32LPx) -typedef long intpointer_t; -typedef unsigned long uintpointer_t; -#else -typedef int intpointer_t; -typedef unsigned int uintpointer_t; -#endif - -MOD_OPEN_DECL(ahdlc_open); -MOD_CLOSE_DECL(ahdlc_close); -static int ahdlc_wput __P((queue_t *, mblk_t *)); -static int ahdlc_rput __P((queue_t *, mblk_t *)); -static void ahdlc_encode __P((queue_t *, mblk_t *)); -static void ahdlc_decode __P((queue_t *, mblk_t *)); -static int msg_byte __P((mblk_t *, unsigned int)); - -#if defined(SOL2) -/* - * Don't send HDLC start flag is last transmit is within 1.5 seconds - - * FLAG_TIME is defined is microseconds - */ -#define FLAG_TIME 1500 -#define ABS(x) (x >= 0 ? x : (-x)) -#endif /* SOL2 */ - -/* - * Extract byte i of message mp - */ -#define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \ - msg_byte((mp), (i))) - -/* - * Is this LCP packet one we have to transmit using LCP defaults? - */ -#define LCP_USE_DFLT(mp) (1 <= (code = MSG_BYTE((mp), 4)) && code <= 7) - -/* - * Standard STREAMS declarations - */ -static struct module_info minfo = { - 0x7d23, "ppp_ahdl", 0, INFPSZ, 32768, 512 -}; - -static struct qinit rinit = { - ahdlc_rput, NULL, ahdlc_open, ahdlc_close, NULL, &minfo, NULL -}; - -static struct qinit winit = { - ahdlc_wput, NULL, NULL, NULL, NULL, &minfo, NULL -}; - -#if defined(SVR4) && !defined(SOL2) -int phdldevflag = 0; -#define ppp_ahdlcinfo phdlinfo -#endif /* defined(SVR4) && !defined(SOL2) */ - -struct streamtab ppp_ahdlcinfo = { - &rinit, /* ptr to st_rdinit */ - &winit, /* ptr to st_wrinit */ - NULL, /* ptr to st_muxrinit */ - NULL, /* ptr to st_muxwinit */ -#if defined(SUNOS4) - NULL /* ptr to ptr to st_modlist */ -#endif /* SUNOS4 */ -}; - -#if defined(SUNOS4) -int ppp_ahdlc_count = 0; /* open counter */ -#endif /* SUNOS4 */ - -/* - * Per-stream state structure - */ -typedef struct ahdlc_state { -#if defined(USE_MUTEX) - kmutex_t lock; /* lock for this structure */ -#endif /* USE_MUTEX */ - int flags; /* link flags */ - mblk_t *rx_buf; /* ptr to receive buffer */ - int rx_buf_size; /* receive buffer size */ - ushort_t infcs; /* calculated rx HDLC FCS */ - u_int32_t xaccm[8]; /* 256-bit xmit ACCM */ - u_int32_t raccm; /* 32-bit rcv ACCM */ - int mtu; /* interface MTU */ - int mru; /* link MRU */ - int unit; /* current PPP unit number */ - struct pppstat stats; /* statistic structure */ -#if defined(SOL2) - clock_t flag_time; /* time in usec between flags */ - clock_t lbolt; /* last updated lbolt */ -#endif /* SOL2 */ -} ahdlc_state_t; - -/* - * Values for flags - */ -#define ESCAPED 0x100 /* last saw escape char on input */ -#define IFLUSH 0x200 /* flushing input due to error */ - -/* - * RCV_B7_1, etc., defined in net/pppio.h, are stored in flags also. - */ -#define RCV_FLAGS (RCV_B7_1|RCV_B7_0|RCV_ODDP|RCV_EVNP) - -/* - * FCS lookup table as calculated by genfcstab. - */ -static u_short fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -static u_int32_t paritytab[8] = -{ - 0x96696996, 0x69969669, 0x69969669, 0x96696996, - 0x69969669, 0x96696996, 0x96696996, 0x69969669 -}; - -/* - * STREAMS module open (entry) point - */ -MOD_OPEN(ahdlc_open) -{ - ahdlc_state_t *state; - - /* - * Return if it's already opened - */ - if (q->q_ptr) { - return 0; - } - - /* - * This can only be opened as a module - */ - if (sflag != MODOPEN) { - return 0; - } - - state = (ahdlc_state_t *) ALLOC_NOSLEEP(sizeof(ahdlc_state_t)); - if (state == 0) - OPEN_ERROR(ENOSR); - bzero((caddr_t) state, sizeof(ahdlc_state_t)); - - q->q_ptr = (caddr_t) state; - WR(q)->q_ptr = (caddr_t) state; - -#if defined(USE_MUTEX) - mutex_init(&state->lock, NULL, MUTEX_DEFAULT, NULL); - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - - state->xaccm[0] = ~0; /* escape 0x00 through 0x1f */ - state->xaccm[3] = 0x60000000; /* escape 0x7d and 0x7e */ - state->mru = PPP_MRU; /* default of 1500 bytes */ -#if defined(SOL2) - state->flag_time = drv_usectohz(FLAG_TIME); -#endif /* SOL2 */ - -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - -#if defined(SUNOS4) - ppp_ahdlc_count++; -#endif /* SUNOS4 */ - - qprocson(q); - - return 0; -} - -/* - * STREAMS module close (exit) point - */ -MOD_CLOSE(ahdlc_close) -{ - ahdlc_state_t *state; - - qprocsoff(q); - - state = (ahdlc_state_t *) q->q_ptr; - - if (state == 0) { - DPRINT("state == 0 in ahdlc_close\n"); - return 0; - } - -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - - if (state->rx_buf != 0) { - freemsg(state->rx_buf); - state->rx_buf = 0; - } - -#if defined(USE_MUTEX) - mutex_exit(&state->lock); - mutex_destroy(&state->lock); -#endif /* USE_MUTEX */ - - FREE(q->q_ptr, sizeof(ahdlc_state_t)); - q->q_ptr = NULL; - OTHERQ(q)->q_ptr = NULL; - -#if defined(SUNOS4) - if (ppp_ahdlc_count) - ppp_ahdlc_count--; -#endif /* SUNOS4 */ - - return 0; -} - -/* - * Write side put routine - */ -static int -ahdlc_wput(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - struct iocblk *iop; - int error; - mblk_t *np; - struct ppp_stats *psp; - - state = (ahdlc_state_t *) q->q_ptr; - if (state == 0) { - DPRINT("state == 0 in ahdlc_wput\n"); - freemsg(mp); - return 0; - } - - switch (mp->b_datap->db_type) { - case M_DATA: - /* - * A data packet - do character-stuffing and FCS, and - * send it onwards. - */ - ahdlc_encode(q, mp); - freemsg(mp); - break; - - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - error = EINVAL; - switch (iop->ioc_cmd) { - case PPPIO_XACCM: - if ((iop->ioc_count < sizeof(u_int32_t)) || - (iop->ioc_count > sizeof(ext_accm))) { - break; - } - if (mp->b_cont == 0) { - DPRINT1("ahdlc_wput/%d: PPPIO_XACCM b_cont = 0!\n", state->unit); - break; - } -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)state->xaccm, - iop->ioc_count); - state->xaccm[2] &= ~0x40000000; /* don't escape 0x5e */ - state->xaccm[3] |= 0x60000000; /* do escape 0x7d, 0x7e */ -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - iop->ioc_count = 0; - error = 0; - break; - - case PPPIO_RACCM: - if (iop->ioc_count != sizeof(u_int32_t)) - break; - if (mp->b_cont == 0) { - DPRINT1("ahdlc_wput/%d: PPPIO_RACCM b_cont = 0!\n", state->unit); - break; - } -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)&state->raccm, - sizeof(u_int32_t)); -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - iop->ioc_count = 0; - error = 0; - break; - - case PPPIO_GCLEAN: - np = allocb(sizeof(int), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - *(int *)np->b_wptr = state->flags & RCV_FLAGS; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - np->b_wptr += sizeof(int); - iop->ioc_count = sizeof(int); - error = 0; - break; - - case PPPIO_GETSTAT: - np = allocb(sizeof(struct ppp_stats), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - psp = (struct ppp_stats *) np->b_wptr; - np->b_wptr += sizeof(struct ppp_stats); - bzero((caddr_t)psp, sizeof(struct ppp_stats)); - psp->p = state->stats; - iop->ioc_count = sizeof(struct ppp_stats); - error = 0; - break; - - case PPPIO_LASTMOD: - /* we knew this anyway */ - error = 0; - break; - - default: - error = -1; - break; - } - - if (error < 0) - putnext(q, mp); - else if (error == 0) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } else { - mp->b_datap->db_type = M_IOCNAK; - iop->ioc_count = 0; - iop->ioc_error = error; - qreply(q, mp); - } - break; - - case M_CTL: - switch (*mp->b_rptr) { - case PPPCTL_MTU: -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - state->mtu = ((unsigned short *)mp->b_rptr)[1]; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - freemsg(mp); - break; - case PPPCTL_MRU: -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - state->mru = ((unsigned short *)mp->b_rptr)[1]; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - freemsg(mp); - break; - case PPPCTL_UNIT: -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - state->unit = mp->b_rptr[1]; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - break; - default: - putnext(q, mp); - } - break; - - default: - putnext(q, mp); - } - - return 0; -} - -/* - * Read side put routine - */ -static int -ahdlc_rput(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - - state = (ahdlc_state_t *) q->q_ptr; - if (state == 0) { - DPRINT("state == 0 in ahdlc_rput\n"); - freemsg(mp); - return 0; - } - - switch (mp->b_datap->db_type) { - case M_DATA: - ahdlc_decode(q, mp); - freemsg(mp); - break; - - case M_HANGUP: -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - if (state->rx_buf != 0) { - /* XXX would like to send this up for debugging */ - freemsg(state->rx_buf); - state->rx_buf = 0; - } - state->flags = IFLUSH; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - putnext(q, mp); - break; - - default: - putnext(q, mp); - } - return 0; -} - -/* - * Extract bit c from map m, to determine if c needs to be escaped - */ -#define IN_TX_MAP(c, m) ((m)[(c) >> 5] & (1 << ((c) & 0x1f))) - -static void -ahdlc_encode(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - u_int32_t *xaccm, loc_xaccm[8]; - ushort_t fcs; - size_t outmp_len; - mblk_t *outmp, *tmp; - uchar_t *dp, fcs_val; - int is_lcp, code; -#if defined(SOL2) - clock_t lbolt; -#endif /* SOL2 */ - - if (msgdsize(mp) < 4) { - return; - } - - state = (ahdlc_state_t *)q->q_ptr; -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - - /* - * Allocate an output buffer large enough to handle a case where all - * characters need to be escaped - */ - outmp_len = (msgdsize(mp) << 1) + /* input block x 2 */ - (sizeof(fcs) << 2) + /* HDLC FCS x 4 */ - (sizeof(uchar_t) << 1); /* HDLC flags x 2 */ - - outmp = allocb(outmp_len, BPRI_MED); - if (outmp == NULL) { - state->stats.ppp_oerrors++; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); - return; - } - -#if defined(SOL2) - /* - * Check if our last transmit happenned within flag_time, using - * the system's LBOLT value in clock ticks - */ - if (drv_getparm(LBOLT, &lbolt) != -1) { - if (ABS((clock_t)lbolt - state->lbolt) > state->flag_time) { - *outmp->b_wptr++ = PPP_FLAG; - } - state->lbolt = lbolt; - } else { - *outmp->b_wptr++ = PPP_FLAG; - } -#else - /* - * If the driver below still has a message to process, skip the - * HDLC flag, otherwise, put one in the beginning - */ - if (qsize(q->q_next) == 0) { - *outmp->b_wptr++ = PPP_FLAG; - } -#endif - - /* - * All control characters must be escaped for LCP packets with code - * values between 1 (Conf-Req) and 7 (Code-Rej). - */ - is_lcp = ((MSG_BYTE(mp, 0) == PPP_ALLSTATIONS) && - (MSG_BYTE(mp, 1) == PPP_UI) && - (MSG_BYTE(mp, 2) == (PPP_LCP >> 8)) && - (MSG_BYTE(mp, 3) == (PPP_LCP & 0xff)) && - LCP_USE_DFLT(mp)); - - xaccm = state->xaccm; - if (is_lcp) { - bcopy((caddr_t)state->xaccm, (caddr_t)loc_xaccm, sizeof(loc_xaccm)); - loc_xaccm[0] = ~0; /* force escape on 0x00 through 0x1f */ - xaccm = loc_xaccm; - } - - fcs = PPP_INITFCS; /* Initial FCS is 0xffff */ - - /* - * Process this block and the rest (if any) attached to the this one - */ - for (tmp = mp; tmp; tmp = tmp->b_cont) { - if (tmp->b_datap->db_type == M_DATA) { - for (dp = tmp->b_rptr; dp < tmp->b_wptr; dp++) { - fcs = PPP_FCS(fcs, *dp); - if (IN_TX_MAP(*dp, xaccm)) { - *outmp->b_wptr++ = PPP_ESCAPE; - *outmp->b_wptr++ = *dp ^ PPP_TRANS; - } else { - *outmp->b_wptr++ = *dp; - } - } - } else { - continue; /* skip if db_type is something other than M_DATA */ - } - } - - /* - * Append the HDLC FCS, making sure that escaping is done on any - * necessary bytes - */ - fcs_val = (fcs ^ 0xffff) & 0xff; - if (IN_TX_MAP(fcs_val, xaccm)) { - *outmp->b_wptr++ = PPP_ESCAPE; - *outmp->b_wptr++ = fcs_val ^ PPP_TRANS; - } else { - *outmp->b_wptr++ = fcs_val; - } - - fcs_val = ((fcs ^ 0xffff) >> 8) & 0xff; - if (IN_TX_MAP(fcs_val, xaccm)) { - *outmp->b_wptr++ = PPP_ESCAPE; - *outmp->b_wptr++ = fcs_val ^ PPP_TRANS; - } else { - *outmp->b_wptr++ = fcs_val; - } - - /* - * And finally, append the HDLC flag, and send it away - */ - *outmp->b_wptr++ = PPP_FLAG; - - state->stats.ppp_obytes += msgdsize(outmp); - state->stats.ppp_opackets++; - -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - - putnext(q, outmp); - return; -} - -/* - * Checks the 32-bit receive ACCM to see if the byte needs un-escaping - */ -#define IN_RX_MAP(c, m) ((((unsigned int) (uchar_t) (c)) < 0x20) && \ - (m) & (1 << (c))) - - -/* - * Process received characters. - */ -static void -ahdlc_decode(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - mblk_t *om; - uchar_t *dp; - ushort_t fcs; -#if defined(SOL2) - mblk_t *zmp; -#endif /* SOL2 */ - -#if defined(SOL2) - /* - * In case the driver (or something below) doesn't send - * data upstream in one message block, concatenate everything - */ - if (!((mp->b_wptr - mp->b_rptr == msgdsize(mp)) && - ((intpointer_t)mp->b_rptr % sizeof(intpointer_t) == 0))) { - - zmp = msgpullup(mp, -1); - freemsg(mp); - mp = zmp; - if (mp == 0) - return; - } -#endif /* SOL2 */ - - state = (ahdlc_state_t *) q->q_ptr; - -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - - state->stats.ppp_ibytes += msgdsize(mp); - - for (dp = mp->b_rptr; dp < mp->b_wptr; dp++) { - - /* - * This should detect the lack of 8-bit communication channel - * which is necessary for PPP to work. In addition, it also - * checks on the parity. - */ - if (*dp & 0x80) - state->flags |= RCV_B7_1; - else - state->flags |= RCV_B7_0; - - if (paritytab[*dp >> 5] & (1 << (*dp & 0x1f))) - state->flags |= RCV_ODDP; - else - state->flags |= RCV_EVNP; - - /* - * So we have a HDLC flag ... - */ - if (*dp == PPP_FLAG) { - - /* - * If we think that it marks the beginning of the frame, - * then continue to process the next octects - */ - if ((state->flags & IFLUSH) || - (state->rx_buf == 0) || - (msgdsize(state->rx_buf) == 0)) { - - state->flags &= ~IFLUSH; - continue; - } - - /* - * We get here because the above condition isn't true, - * in which case the HDLC flag was there to mark the end - * of the frame (or so we think) - */ - om = state->rx_buf; - - if (state->infcs == PPP_GOODFCS) { - state->stats.ppp_ipackets++; - adjmsg(om, -PPP_FCSLEN); - putnext(q, om); - } else { - DPRINT2("ppp%d: bad fcs (len=%d)\n", - state->unit, msgdsize(state->rx_buf)); - freemsg(state->rx_buf); - state->flags &= ~(IFLUSH | ESCAPED); - state->stats.ppp_ierrors++; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - } - - state->rx_buf = 0; - continue; - } - - if (state->flags & IFLUSH) { - continue; - } - - /* - * Allocate a receive buffer, large enough to store a frame (after - * un-escaping) of at least 1500 octets. If MRU is negotiated to - * be more than the default, then allocate that much. In addition, - * we add an extra 32-bytes for a fudge factor - */ - if (state->rx_buf == 0) { - state->rx_buf_size = (state->mru < PPP_MRU ? PPP_MRU : state->mru); - state->rx_buf_size += (sizeof(u_int32_t) << 3); - state->rx_buf = allocb(state->rx_buf_size, BPRI_MED); - - /* - * If allocation fails, try again on the next frame - */ - if (state->rx_buf == 0) { - state->flags |= IFLUSH; - continue; - } - state->flags &= ~(IFLUSH | ESCAPED); - state->infcs = PPP_INITFCS; - } - - if (*dp == PPP_ESCAPE) { - state->flags |= ESCAPED; - continue; - } - - /* - * Make sure we un-escape the necessary characters, as well as the - * ones in our receive async control character map - */ - if (state->flags & ESCAPED) { - *dp ^= PPP_TRANS; - state->flags &= ~ESCAPED; - } else if (IN_RX_MAP(*dp, state->raccm)) - continue; - - /* - * Unless the peer lied to us about the negotiated MRU, we should - * never get a frame which is too long. If it happens, toss it away - * and grab the next incoming one - */ - if (msgdsize(state->rx_buf) < state->rx_buf_size) { - state->infcs = PPP_FCS(state->infcs, *dp); - *state->rx_buf->b_wptr++ = *dp; - } else { - DPRINT2("ppp%d: frame too long (%d)\n", - state->unit, msgdsize(state->rx_buf)); - freemsg(state->rx_buf); - state->rx_buf = 0; - state->flags |= IFLUSH; - } - } - -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ -} - -static int -msg_byte(mp, i) - mblk_t *mp; - unsigned int i; -{ - while (mp != 0 && i >= mp->b_wptr - mp->b_rptr) - mp = mp->b_cont; - if (mp == 0) - return -1; - return mp->b_rptr[i]; -} diff --git a/mdk-stage1/ppp/modules/ppp_comp.c b/mdk-stage1/ppp/modules/ppp_comp.c deleted file mode 100644 index f6eef5ab1..000000000 --- a/mdk-stage1/ppp/modules/ppp_comp.c +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * ppp_comp.c - STREAMS module for kernel-level compression and CCP support. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -/* - * This file is used under SVR4, Solaris 2, SunOS 4, and Digital UNIX. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/errno.h> -#include <sys/stream.h> - -#ifdef SVR4 -#include <sys/conf.h> -#include <sys/cmn_err.h> -#include <sys/ddi.h> -#else -#include <sys/user.h> -#ifdef __osf__ -#include <sys/cmn_err.h> -#endif -#endif /* SVR4 */ - -#include <net/ppp_defs.h> -#include <net/pppio.h> -#include "ppp_mod.h" - -#ifdef __osf__ -#include <sys/mbuf.h> -#include <sys/protosw.h> -#endif - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <net/vjcompress.h> - -#define PACKETPTR mblk_t * -#include <net/ppp-comp.h> - -MOD_OPEN_DECL(ppp_comp_open); -MOD_CLOSE_DECL(ppp_comp_close); -static int ppp_comp_rput __P((queue_t *, mblk_t *)); -static int ppp_comp_rsrv __P((queue_t *)); -static int ppp_comp_wput __P((queue_t *, mblk_t *)); -static int ppp_comp_wsrv __P((queue_t *)); -static void ppp_comp_ccp __P((queue_t *, mblk_t *, int)); -static int msg_byte __P((mblk_t *, unsigned int)); - -/* Extract byte i of message mp. */ -#define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \ - msg_byte((mp), (i))) - -/* Is this LCP packet one we have to transmit using LCP defaults? */ -#define LCP_USE_DFLT(mp) (1 <= (code = MSG_BYTE((mp), 4)) && code <= 7) - -#define PPP_COMP_ID 0xbadf -static struct module_info minfo = { -#ifdef PRIOQ - PPP_COMP_ID, "ppp_comp", 0, INFPSZ, 16512, 16384, -#else - PPP_COMP_ID, "ppp_comp", 0, INFPSZ, 16384, 4096, -#endif -}; - -static struct qinit r_init = { - ppp_comp_rput, ppp_comp_rsrv, ppp_comp_open, ppp_comp_close, - NULL, &minfo, NULL -}; - -static struct qinit w_init = { - ppp_comp_wput, ppp_comp_wsrv, NULL, NULL, NULL, &minfo, NULL -}; - -#if defined(SVR4) && !defined(SOL2) -int pcmpdevflag = 0; -#define ppp_compinfo pcmpinfo -#endif -struct streamtab ppp_compinfo = { - &r_init, &w_init, NULL, NULL -}; - -int ppp_comp_count; /* number of module instances in use */ - -#ifdef __osf__ - -static void ppp_comp_alloc __P((comp_state_t *)); -typedef struct memreq { - unsigned char comp_opts[20]; - int cmd; - int thread_status; - char *returned_mem; -} memreq_t; - -#endif - -typedef struct comp_state { - int flags; - int mru; - int mtu; - int unit; - struct compressor *xcomp; - void *xstate; - struct compressor *rcomp; - void *rstate; - struct vjcompress vj_comp; - int vj_last_ierrors; - struct pppstat stats; -#ifdef __osf__ - memreq_t memreq; - thread_t thread; -#endif -} comp_state_t; - - -#ifdef __osf__ -extern task_t first_task; -#endif - -/* Bits in flags are as defined in pppio.h. */ -#define CCP_ERR (CCP_ERROR | CCP_FATALERROR) -#define LAST_MOD 0x1000000 /* no ppp modules below us */ -#define DBGLOG 0x2000000 /* log debugging stuff */ - -#define MAX_IPHDR 128 /* max TCP/IP header size */ -#define MAX_VJHDR 20 /* max VJ compressed header size (?) */ - -#undef MIN /* just in case */ -#define MIN(a, b) ((a) < (b)? (a): (b)) - -/* - * List of compressors we know about. - */ - -#if DO_BSD_COMPRESS -extern struct compressor ppp_bsd_compress; -#endif -#if DO_DEFLATE -extern struct compressor ppp_deflate, ppp_deflate_draft; -#endif - -struct compressor *ppp_compressors[] = { -#if DO_BSD_COMPRESS - &ppp_bsd_compress, -#endif -#if DO_DEFLATE - &ppp_deflate, - &ppp_deflate_draft, -#endif - NULL -}; - -/* - * STREAMS module entry points. - */ -MOD_OPEN(ppp_comp_open) -{ - comp_state_t *cp; -#ifdef __osf__ - thread_t thread; -#endif - - if (q->q_ptr == NULL) { - cp = (comp_state_t *) ALLOC_SLEEP(sizeof(comp_state_t)); - if (cp == NULL) - OPEN_ERROR(ENOSR); - bzero((caddr_t)cp, sizeof(comp_state_t)); - WR(q)->q_ptr = q->q_ptr = (caddr_t) cp; - cp->mru = PPP_MRU; - cp->mtu = PPP_MTU; - cp->xstate = NULL; - cp->rstate = NULL; - vj_compress_init(&cp->vj_comp, -1); -#ifdef __osf__ - if (!(thread = kernel_thread_w_arg(first_task, ppp_comp_alloc, (void *)cp))) - OPEN_ERROR(ENOSR); - cp->thread = thread; -#endif - ++ppp_comp_count; - qprocson(q); - } - return 0; -} - -MOD_CLOSE(ppp_comp_close) -{ - comp_state_t *cp; - - qprocsoff(q); - cp = (comp_state_t *) q->q_ptr; - if (cp != NULL) { - if (cp->xstate != NULL) - (*cp->xcomp->comp_free)(cp->xstate); - if (cp->rstate != NULL) - (*cp->rcomp->decomp_free)(cp->rstate); -#ifdef __osf__ - if (!cp->thread) - printf("ppp_comp_close: NULL thread!\n"); - else - thread_terminate(cp->thread); -#endif - FREE(cp, sizeof(comp_state_t)); - q->q_ptr = NULL; - OTHERQ(q)->q_ptr = NULL; - --ppp_comp_count; - } - return 0; -} - -#ifdef __osf__ - -/* thread for calling back to a compressor's memory allocator - * Needed for Digital UNIX since it's VM can't handle requests - * for large amounts of memory without blocking. The thread - * provides a context in which we can call a memory allocator - * that may block. - */ -static void -ppp_comp_alloc(comp_state_t *cp) -{ - int len, cmd; - unsigned char *compressor_options; - thread_t thread; - void *(*comp_allocator)(); - - -#if defined(MAJOR_VERSION) && (MAJOR_VERSION <= 2) - - /* In 2.x and earlier the argument gets passed - * in the thread structure itself. Yuck. - */ - thread = current_thread(); - cp = thread->reply_port; - thread->reply_port = PORT_NULL; - -#endif - - for (;;) { - assert_wait((vm_offset_t)&cp->memreq.thread_status, TRUE); - thread_block(); - - if (thread_should_halt(current_thread())) - thread_halt_self(); - cmd = cp->memreq.cmd; - compressor_options = &cp->memreq.comp_opts[0]; - len = compressor_options[1]; - if (cmd == PPPIO_XCOMP) { - cp->memreq.returned_mem = cp->xcomp->comp_alloc(compressor_options, len); - if (!cp->memreq.returned_mem) { - cp->memreq.thread_status = ENOSR; - } else { - cp->memreq.thread_status = 0; - } - } else { - cp->memreq.returned_mem = cp->rcomp->decomp_alloc(compressor_options, len); - if (!cp->memreq.returned_mem) { - cp->memreq.thread_status = ENOSR; - } else { - cp->memreq.thread_status = 0; - } - } - } -} - -#endif /* __osf__ */ - -/* here's the deal with memory allocation under Digital UNIX. - * Some other may also benefit from this... - * We can't ask for huge chunks of memory in a context where - * the caller can't be put to sleep (like, here.) The alloc - * is likely to fail. Instead we do this: the first time we - * get called, kick off a thread to do the allocation. Return - * immediately to the caller with EAGAIN, as an indication that - * they should send down the ioctl again. By the time the - * second call comes in it's likely that the memory allocation - * thread will have returned with the requested memory. We will - * continue to return EAGAIN however until the thread has completed. - * When it has, we return zero (and the memory) if the allocator - * was successful and ENOSR otherwise. - * - * Callers of the RCOMP and XCOMP ioctls are encouraged (but not - * required) to loop for some number of iterations with a small - * delay in the loop body (for instance a 1/10-th second "sleep" - * via select.) - */ -static int -ppp_comp_wput(q, mp) - queue_t *q; - mblk_t *mp; -{ - struct iocblk *iop; - comp_state_t *cp; - int error, len, n; - int flags, mask; - mblk_t *np; - struct compressor **comp; - struct ppp_stats *psp; - struct ppp_comp_stats *csp; - unsigned char *opt_data; - int nxslots, nrslots; - - cp = (comp_state_t *) q->q_ptr; - if (cp == 0) { - DPRINT("cp == 0 in ppp_comp_wput\n"); - freemsg(mp); - return 0; - } - - switch (mp->b_datap->db_type) { - - case M_DATA: - putq(q, mp); - break; - - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - error = EINVAL; - switch (iop->ioc_cmd) { - - case PPPIO_CFLAGS: - /* set/get CCP state */ - if (iop->ioc_count != 2 * sizeof(int)) - break; - if (mp->b_cont == 0) { - DPRINT1("ppp_comp_wput/%d: PPPIO_CFLAGS b_cont = 0!\n", cp->unit); - break; - } - flags = ((int *) mp->b_cont->b_rptr)[0]; - mask = ((int *) mp->b_cont->b_rptr)[1]; - cp->flags = (cp->flags & ~mask) | (flags & mask); - if ((mask & CCP_ISOPEN) && (flags & CCP_ISOPEN) == 0) { - if (cp->xstate != NULL) { - (*cp->xcomp->comp_free)(cp->xstate); - cp->xstate = NULL; - } - if (cp->rstate != NULL) { - (*cp->rcomp->decomp_free)(cp->rstate); - cp->rstate = NULL; - } - cp->flags &= ~CCP_ISUP; - } - error = 0; - iop->ioc_count = sizeof(int); - ((int *) mp->b_cont->b_rptr)[0] = cp->flags; - mp->b_cont->b_wptr = mp->b_cont->b_rptr + sizeof(int); - break; - - case PPPIO_VJINIT: - /* - * Initialize VJ compressor/decompressor - */ - if (iop->ioc_count != 2) - break; - if (mp->b_cont == 0) { - DPRINT1("ppp_comp_wput/%d: PPPIO_VJINIT b_cont = 0!\n", cp->unit); - break; - } - nxslots = mp->b_cont->b_rptr[0] + 1; - nrslots = mp->b_cont->b_rptr[1] + 1; - if (nxslots > MAX_STATES || nrslots > MAX_STATES) - break; - vj_compress_init(&cp->vj_comp, nxslots); - cp->vj_last_ierrors = cp->stats.ppp_ierrors; - error = 0; - iop->ioc_count = 0; - break; - - case PPPIO_XCOMP: - case PPPIO_RCOMP: - if (iop->ioc_count <= 0) - break; - if (mp->b_cont == 0) { - DPRINT1("ppp_comp_wput/%d: PPPIO_[XR]COMP b_cont = 0!\n", cp->unit); - break; - } - opt_data = mp->b_cont->b_rptr; - len = mp->b_cont->b_wptr - opt_data; - if (len > iop->ioc_count) - len = iop->ioc_count; - if (opt_data[1] < 2 || opt_data[1] > len) - break; - for (comp = ppp_compressors; *comp != NULL; ++comp) - if ((*comp)->compress_proto == opt_data[0]) { - /* here's the handler! */ - error = 0; -#ifndef __osf__ - if (iop->ioc_cmd == PPPIO_XCOMP) { - /* A previous call may have fetched memory for a compressor - * that's now being retired or reset. Free it using it's - * mechanism for freeing stuff. - */ - if (cp->xstate != NULL) { - (*cp->xcomp->comp_free)(cp->xstate); - cp->xstate = NULL; - } - cp->xcomp = *comp; - cp->xstate = (*comp)->comp_alloc(opt_data, len); - if (cp->xstate == NULL) - error = ENOSR; - } else { - if (cp->rstate != NULL) { - (*cp->rcomp->decomp_free)(cp->rstate); - cp->rstate = NULL; - } - cp->rcomp = *comp; - cp->rstate = (*comp)->decomp_alloc(opt_data, len); - if (cp->rstate == NULL) - error = ENOSR; - } -#else - if ((error = cp->memreq.thread_status) != EAGAIN) - if (iop->ioc_cmd == PPPIO_XCOMP) { - if (cp->xstate) { - (*cp->xcomp->comp_free)(cp->xstate); - cp->xstate = 0; - } - /* sanity check for compressor options - */ - if (sizeof (cp->memreq.comp_opts) < len) { - printf("can't handle options for compressor %d (%d)\n", opt_data[0], - opt_data[1]); - cp->memreq.thread_status = ENOSR; - cp->memreq.returned_mem = 0; - } - /* fill in request for the thread and kick it off - */ - if (cp->memreq.thread_status == 0 && !cp->memreq.returned_mem) { - bcopy(opt_data, cp->memreq.comp_opts, len); - cp->memreq.cmd = PPPIO_XCOMP; - cp->xcomp = *comp; - error = cp->memreq.thread_status = EAGAIN; - thread_wakeup((vm_offset_t)&cp->memreq.thread_status); - } else { - cp->xstate = cp->memreq.returned_mem; - cp->memreq.returned_mem = 0; - cp->memreq.thread_status = 0; - } - } else { - if (cp->rstate) { - (*cp->rcomp->decomp_free)(cp->rstate); - cp->rstate = NULL; - } - if (sizeof (cp->memreq.comp_opts) < len) { - printf("can't handle options for compressor %d (%d)\n", opt_data[0], - opt_data[1]); - cp->memreq.thread_status = ENOSR; - cp->memreq.returned_mem = 0; - } - if (cp->memreq.thread_status == 0 && !cp->memreq.returned_mem) { - bcopy(opt_data, cp->memreq.comp_opts, len); - cp->memreq.cmd = PPPIO_RCOMP; - cp->rcomp = *comp; - error = cp->memreq.thread_status = EAGAIN; - thread_wakeup((vm_offset_t)&cp->memreq.thread_status); - } else { - cp->rstate = cp->memreq.returned_mem; - cp->memreq.returned_mem = 0; - cp->memreq.thread_status = 0; - } - } -#endif - break; - } - iop->ioc_count = 0; - break; - - case PPPIO_GETSTAT: - if ((cp->flags & LAST_MOD) == 0) { - error = -1; /* let the ppp_ahdl module handle it */ - break; - } - np = allocb(sizeof(struct ppp_stats), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - psp = (struct ppp_stats *) np->b_wptr; - np->b_wptr += sizeof(struct ppp_stats); - iop->ioc_count = sizeof(struct ppp_stats); - psp->p = cp->stats; - psp->vj = cp->vj_comp.stats; - error = 0; - break; - - case PPPIO_GETCSTAT: - np = allocb(sizeof(struct ppp_comp_stats), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - csp = (struct ppp_comp_stats *) np->b_wptr; - np->b_wptr += sizeof(struct ppp_comp_stats); - iop->ioc_count = sizeof(struct ppp_comp_stats); - bzero((caddr_t)csp, sizeof(struct ppp_comp_stats)); - if (cp->xstate != 0) - (*cp->xcomp->comp_stat)(cp->xstate, &csp->c); - if (cp->rstate != 0) - (*cp->rcomp->decomp_stat)(cp->rstate, &csp->d); - error = 0; - break; - - case PPPIO_DEBUG: - if (iop->ioc_count != sizeof(int)) - break; - if (mp->b_cont == 0) { - DPRINT1("ppp_comp_wput/%d: PPPIO_DEBUG b_cont = 0!\n", cp->unit); - break; - } - n = *(int *)mp->b_cont->b_rptr; - if (n == PPPDBG_LOG + PPPDBG_COMP) { - DPRINT1("ppp_comp%d: debug log enabled\n", cp->unit); - cp->flags |= DBGLOG; - error = 0; - iop->ioc_count = 0; - } else { - error = -1; - } - break; - - case PPPIO_LASTMOD: - cp->flags |= LAST_MOD; - error = 0; - break; - - default: - error = -1; - break; - } - - if (error < 0) - putnext(q, mp); - else if (error == 0) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } else { - mp->b_datap->db_type = M_IOCNAK; - iop->ioc_error = error; - iop->ioc_count = 0; - qreply(q, mp); - } - break; - - case M_CTL: - switch (*mp->b_rptr) { - case PPPCTL_MTU: - cp->mtu = ((unsigned short *)mp->b_rptr)[1]; - break; - case PPPCTL_MRU: - cp->mru = ((unsigned short *)mp->b_rptr)[1]; - break; - case PPPCTL_UNIT: - cp->unit = mp->b_rptr[1]; - break; - } - putnext(q, mp); - break; - - default: - putnext(q, mp); - } - - return 0; -} - -static int -ppp_comp_wsrv(q) - queue_t *q; -{ - mblk_t *mp, *cmp = NULL; - comp_state_t *cp; - int len, proto, type, hlen, code; - struct ip *ip; - unsigned char *vjhdr, *dp; - - cp = (comp_state_t *) q->q_ptr; - if (cp == 0) { - DPRINT("cp == 0 in ppp_comp_wsrv\n"); - return 0; - } - - while ((mp = getq(q)) != 0) { - /* assert(mp->b_datap->db_type == M_DATA) */ -#ifdef PRIOQ - if (!bcanputnext(q,mp->b_band)) -#else - if (!canputnext(q)) -#endif PRIOQ - { - putbq(q, mp); - break; - } - - /* - * First check the packet length and work out what the protocol is. - */ - len = msgdsize(mp); - if (len < PPP_HDRLEN) { - DPRINT1("ppp_comp_wsrv: bogus short packet (%d)\n", len); - freemsg(mp); - cp->stats.ppp_oerrors++; - putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); - continue; - } - proto = (MSG_BYTE(mp, 2) << 8) + MSG_BYTE(mp, 3); - - /* - * Make sure we've got enough data in the first mblk - * and that we are its only user. - */ - if (proto == PPP_CCP) - hlen = len; - else if (proto == PPP_IP) - hlen = PPP_HDRLEN + MAX_IPHDR; - else - hlen = PPP_HDRLEN; - if (hlen > len) - hlen = len; - if (mp->b_wptr < mp->b_rptr + hlen || mp->b_datap->db_ref > 1) { - PULLUP(mp, hlen); - if (mp == 0) { - DPRINT1("ppp_comp_wsrv: pullup failed (%d)\n", hlen); - cp->stats.ppp_oerrors++; - putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); - continue; - } - } - - /* - * Do VJ compression if requested. - */ - if (proto == PPP_IP && (cp->flags & COMP_VJC)) { - ip = (struct ip *) (mp->b_rptr + PPP_HDRLEN); - if (ip->ip_p == IPPROTO_TCP) { - type = vj_compress_tcp(ip, len - PPP_HDRLEN, &cp->vj_comp, - (cp->flags & COMP_VJCCID), &vjhdr); - switch (type) { - case TYPE_UNCOMPRESSED_TCP: - mp->b_rptr[3] = proto = PPP_VJC_UNCOMP; - break; - case TYPE_COMPRESSED_TCP: - dp = vjhdr - PPP_HDRLEN; - dp[1] = mp->b_rptr[1]; /* copy control field */ - dp[0] = mp->b_rptr[0]; /* copy address field */ - dp[2] = 0; /* set protocol field */ - dp[3] = proto = PPP_VJC_COMP; - mp->b_rptr = dp; - break; - } - } - } - - /* - * Do packet compression if enabled. - */ - if (proto == PPP_CCP) - ppp_comp_ccp(q, mp, 0); - else if (proto != PPP_LCP && (cp->flags & CCP_COMP_RUN) - && cp->xstate != NULL) { - len = msgdsize(mp); - (*cp->xcomp->compress)(cp->xstate, &cmp, mp, len, - (cp->flags & CCP_ISUP? cp->mtu + PPP_HDRLEN: 0)); - if (cmp != NULL) { -#ifdef PRIOQ - cmp->b_band=mp->b_band; -#endif PRIOQ - freemsg(mp); - mp = cmp; - } - } - - /* - * Do address/control and protocol compression if enabled. - */ - if ((cp->flags & COMP_AC) - && !(proto == PPP_LCP && LCP_USE_DFLT(mp))) { - mp->b_rptr += 2; /* drop the address & ctrl fields */ - if (proto < 0x100 && (cp->flags & COMP_PROT)) - ++mp->b_rptr; /* drop the high protocol byte */ - } else if (proto < 0x100 && (cp->flags & COMP_PROT)) { - /* shuffle up the address & ctrl fields */ - mp->b_rptr[2] = mp->b_rptr[1]; - mp->b_rptr[1] = mp->b_rptr[0]; - ++mp->b_rptr; - } - - cp->stats.ppp_opackets++; - cp->stats.ppp_obytes += msgdsize(mp); - putnext(q, mp); - } - - return 0; -} - -static int -ppp_comp_rput(q, mp) - queue_t *q; - mblk_t *mp; -{ - comp_state_t *cp; - struct iocblk *iop; - struct ppp_stats *psp; - - cp = (comp_state_t *) q->q_ptr; - if (cp == 0) { - DPRINT("cp == 0 in ppp_comp_rput\n"); - freemsg(mp); - return 0; - } - - switch (mp->b_datap->db_type) { - - case M_DATA: - putq(q, mp); - break; - - case M_IOCACK: - iop = (struct iocblk *) mp->b_rptr; - switch (iop->ioc_cmd) { - case PPPIO_GETSTAT: - /* - * Catch this on the way back from the ppp_ahdl module - * so we can fill in the VJ stats. - */ - if (mp->b_cont == 0 || iop->ioc_count != sizeof(struct ppp_stats)) - break; - psp = (struct ppp_stats *) mp->b_cont->b_rptr; - psp->vj = cp->vj_comp.stats; - break; - } - putnext(q, mp); - break; - - case M_CTL: - switch (mp->b_rptr[0]) { - case PPPCTL_IERROR: - ++cp->stats.ppp_ierrors; - break; - case PPPCTL_OERROR: - ++cp->stats.ppp_oerrors; - break; - } - putnext(q, mp); - break; - - default: - putnext(q, mp); - } - - return 0; -} - -static int -ppp_comp_rsrv(q) - queue_t *q; -{ - int proto, rv, i; - mblk_t *mp, *dmp = NULL, *np; - uchar_t *dp, *iphdr; - comp_state_t *cp; - int len, hlen, vjlen; - u_int iphlen; - - cp = (comp_state_t *) q->q_ptr; - if (cp == 0) { - DPRINT("cp == 0 in ppp_comp_rsrv\n"); - return 0; - } - - while ((mp = getq(q)) != 0) { - /* assert(mp->b_datap->db_type == M_DATA) */ - if (!canputnext(q)) { - putbq(q, mp); - break; - } - - len = msgdsize(mp); - cp->stats.ppp_ibytes += len; - cp->stats.ppp_ipackets++; - - /* - * First work out the protocol and where the PPP header ends. - */ - i = 0; - proto = MSG_BYTE(mp, 0); - if (proto == PPP_ALLSTATIONS) { - i = 2; - proto = MSG_BYTE(mp, 2); - } - if ((proto & 1) == 0) { - ++i; - proto = (proto << 8) + MSG_BYTE(mp, i); - } - hlen = i + 1; - - /* - * Now reconstruct a complete, contiguous PPP header at the - * start of the packet. - */ - if (hlen < ((cp->flags & DECOMP_AC)? 0: 2) - + ((cp->flags & DECOMP_PROT)? 1: 2)) { - /* count these? */ - goto bad; - } - if (mp->b_rptr + hlen > mp->b_wptr) { - adjmsg(mp, hlen); /* XXX check this call */ - hlen = 0; - } - if (hlen != PPP_HDRLEN) { - /* - * We need to put some bytes on the front of the packet - * to make a full-length PPP header. - * If we can put them in *mp, we do, otherwise we - * tack another mblk on the front. - * XXX we really shouldn't need to carry around - * the address and control at this stage. - */ - dp = mp->b_rptr + hlen - PPP_HDRLEN; - if (dp < mp->b_datap->db_base || mp->b_datap->db_ref > 1) { - np = allocb(PPP_HDRLEN, BPRI_MED); - if (np == 0) - goto bad; - np->b_cont = mp; - mp->b_rptr += hlen; - mp = np; - dp = mp->b_wptr; - mp->b_wptr += PPP_HDRLEN; - } else - mp->b_rptr = dp; - - dp[0] = PPP_ALLSTATIONS; - dp[1] = PPP_UI; - dp[2] = proto >> 8; - dp[3] = proto; - } - - /* - * Now see if we have a compressed packet to decompress, - * or a CCP packet to take notice of. - */ - proto = PPP_PROTOCOL(mp->b_rptr); - if (proto == PPP_CCP) { - len = msgdsize(mp); - if (mp->b_wptr < mp->b_rptr + len) { - PULLUP(mp, len); - if (mp == 0) - goto bad; - } - ppp_comp_ccp(q, mp, 1); - } else if (proto == PPP_COMP) { - if ((cp->flags & CCP_ISUP) - && (cp->flags & CCP_DECOMP_RUN) && cp->rstate - && (cp->flags & CCP_ERR) == 0) { - rv = (*cp->rcomp->decompress)(cp->rstate, mp, &dmp); - switch (rv) { - case DECOMP_OK: - freemsg(mp); - mp = dmp; - if (mp == NULL) { - /* no error, but no packet returned either. */ - continue; - } - break; - case DECOMP_ERROR: - cp->flags |= CCP_ERROR; - ++cp->stats.ppp_ierrors; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - break; - case DECOMP_FATALERROR: - cp->flags |= CCP_FATALERROR; - ++cp->stats.ppp_ierrors; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - break; - } - } - } else if (cp->rstate && (cp->flags & CCP_DECOMP_RUN)) { - (*cp->rcomp->incomp)(cp->rstate, mp); - } - - /* - * Now do VJ decompression. - */ - proto = PPP_PROTOCOL(mp->b_rptr); - if (proto == PPP_VJC_COMP || proto == PPP_VJC_UNCOMP) { - len = msgdsize(mp) - PPP_HDRLEN; - if ((cp->flags & DECOMP_VJC) == 0 || len <= 0) - goto bad; - - /* - * Advance past the ppp header. - * Here we assume that the whole PPP header is in the first mblk. - */ - np = mp; - dp = np->b_rptr + PPP_HDRLEN; - if (dp >= mp->b_wptr) { - np = np->b_cont; - dp = np->b_rptr; - } - - /* - * Make sure we have sufficient contiguous data at this point. - */ - hlen = (proto == PPP_VJC_COMP)? MAX_VJHDR: MAX_IPHDR; - if (hlen > len) - hlen = len; - if (np->b_wptr < dp + hlen || np->b_datap->db_ref > 1) { - PULLUP(mp, hlen + PPP_HDRLEN); - if (mp == 0) - goto bad; - np = mp; - dp = np->b_rptr + PPP_HDRLEN; - } - - if (proto == PPP_VJC_COMP) { - /* - * Decompress VJ-compressed packet. - * First reset compressor if an input error has occurred. - */ - if (cp->stats.ppp_ierrors != cp->vj_last_ierrors) { - if (cp->flags & DBGLOG) - DPRINT1("ppp%d: resetting VJ\n", cp->unit); - vj_uncompress_err(&cp->vj_comp); - cp->vj_last_ierrors = cp->stats.ppp_ierrors; - } - - vjlen = vj_uncompress_tcp(dp, np->b_wptr - dp, len, - &cp->vj_comp, &iphdr, &iphlen); - if (vjlen < 0) { - if (cp->flags & DBGLOG) - DPRINT2("ppp%d: vj_uncomp_tcp failed, pkt len %d\n", - cp->unit, len); - ++cp->vj_last_ierrors; /* so we don't reset next time */ - goto bad; - } - - /* drop ppp and vj headers off */ - if (mp != np) { - freeb(mp); - mp = np; - } - mp->b_rptr = dp + vjlen; - - /* allocate a new mblk for the ppp and ip headers */ - if ((np = allocb(iphlen + PPP_HDRLEN + 4, BPRI_MED)) == 0) - goto bad; - dp = np->b_rptr; /* prepend mblk with TCP/IP hdr */ - dp[0] = PPP_ALLSTATIONS; /* reconstruct PPP header */ - dp[1] = PPP_UI; - dp[2] = PPP_IP >> 8; - dp[3] = PPP_IP; - bcopy((caddr_t)iphdr, (caddr_t)dp + PPP_HDRLEN, iphlen); - np->b_wptr = dp + iphlen + PPP_HDRLEN; - np->b_cont = mp; - - /* XXX there seems to be a bug which causes panics in strread - if we make an mbuf with only the IP header in it :-( */ - if (mp->b_wptr - mp->b_rptr > 4) { - bcopy((caddr_t)mp->b_rptr, (caddr_t)np->b_wptr, 4); - mp->b_rptr += 4; - np->b_wptr += 4; - } else { - bcopy((caddr_t)mp->b_rptr, (caddr_t)np->b_wptr, - mp->b_wptr - mp->b_rptr); - np->b_wptr += mp->b_wptr - mp->b_rptr; - np->b_cont = mp->b_cont; - freeb(mp); - } - - mp = np; - - } else { - /* - * "Decompress" a VJ-uncompressed packet. - */ - cp->vj_last_ierrors = cp->stats.ppp_ierrors; - if (!vj_uncompress_uncomp(dp, hlen, &cp->vj_comp)) { - if (cp->flags & DBGLOG) - DPRINT2("ppp%d: vj_uncomp_uncomp failed, pkt len %d\n", - cp->unit, len); - ++cp->vj_last_ierrors; /* don't need to reset next time */ - goto bad; - } - mp->b_rptr[3] = PPP_IP; /* fix up the PPP protocol field */ - } - } - - putnext(q, mp); - continue; - - bad: - if (mp != 0) - freemsg(mp); - cp->stats.ppp_ierrors++; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - } - - return 0; -} - -/* - * Handle a CCP packet being sent or received. - * Here all the data in the packet is in a single mbuf. - */ -static void -ppp_comp_ccp(q, mp, rcvd) - queue_t *q; - mblk_t *mp; - int rcvd; -{ - int len, clen; - comp_state_t *cp; - unsigned char *dp; - - len = msgdsize(mp); - if (len < PPP_HDRLEN + CCP_HDRLEN) - return; - - cp = (comp_state_t *) q->q_ptr; - dp = mp->b_rptr + PPP_HDRLEN; - len -= PPP_HDRLEN; - clen = CCP_LENGTH(dp); - if (clen > len) - return; - - switch (CCP_CODE(dp)) { - case CCP_CONFREQ: - case CCP_TERMREQ: - case CCP_TERMACK: - cp->flags &= ~CCP_ISUP; - break; - - case CCP_CONFACK: - if ((cp->flags & (CCP_ISOPEN | CCP_ISUP)) == CCP_ISOPEN - && clen >= CCP_HDRLEN + CCP_OPT_MINLEN - && clen >= CCP_HDRLEN + CCP_OPT_LENGTH(dp + CCP_HDRLEN)) { - if (!rcvd) { - if (cp->xstate != NULL - && (*cp->xcomp->comp_init) - (cp->xstate, dp + CCP_HDRLEN, clen - CCP_HDRLEN, - cp->unit, 0, ((cp->flags & DBGLOG) != 0))) - cp->flags |= CCP_COMP_RUN; - } else { - if (cp->rstate != NULL - && (*cp->rcomp->decomp_init) - (cp->rstate, dp + CCP_HDRLEN, clen - CCP_HDRLEN, - cp->unit, 0, cp->mru, ((cp->flags & DBGLOG) != 0))) - cp->flags = (cp->flags & ~CCP_ERR) | CCP_DECOMP_RUN; - } - } - break; - - case CCP_RESETACK: - if (cp->flags & CCP_ISUP) { - if (!rcvd) { - if (cp->xstate && (cp->flags & CCP_COMP_RUN)) - (*cp->xcomp->comp_reset)(cp->xstate); - } else { - if (cp->rstate && (cp->flags & CCP_DECOMP_RUN)) { - (*cp->rcomp->decomp_reset)(cp->rstate); - cp->flags &= ~CCP_ERROR; - } - } - } - break; - } -} - -#if 0 -dump_msg(mp) - mblk_t *mp; -{ - dblk_t *db; - - while (mp != 0) { - db = mp->b_datap; - DPRINT2("mp=%x cont=%x ", mp, mp->b_cont); - DPRINT3("rptr=%x wptr=%x datap=%x\n", mp->b_rptr, mp->b_wptr, db); - DPRINT2(" base=%x lim=%x", db->db_base, db->db_lim); - DPRINT2(" ref=%d type=%d\n", db->db_ref, db->db_type); - mp = mp->b_cont; - } -} -#endif - -static int -msg_byte(mp, i) - mblk_t *mp; - unsigned int i; -{ - while (mp != 0 && i >= mp->b_wptr - mp->b_rptr) - mp = mp->b_cont; - if (mp == 0) - return -1; - return mp->b_rptr[i]; -} diff --git a/mdk-stage1/ppp/modules/ppp_mod.h b/mdk-stage1/ppp/modules/ppp_mod.h deleted file mode 100644 index f0af00886..000000000 --- a/mdk-stage1/ppp/modules/ppp_mod.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Miscellaneous definitions for PPP STREAMS modules. - */ - -/* - * Macros for allocating and freeing kernel memory. - */ -#ifdef SVR4 /* SVR4, including Solaris 2 */ -#include <sys/kmem.h> -#define ALLOC_SLEEP(n) kmem_alloc((n), KM_SLEEP) -#define ALLOC_NOSLEEP(n) kmem_alloc((n), KM_NOSLEEP) -#define FREE(p, n) kmem_free((p), (n)) -#endif - -#ifdef SUNOS4 -#include <sys/kmem_alloc.h> /* SunOS 4.x */ -#define ALLOC_SLEEP(n) kmem_alloc((n), KMEM_SLEEP) -#define ALLOC_NOSLEEP(n) kmem_alloc((n), KMEM_NOSLEEP) -#define FREE(p, n) kmem_free((p), (n)) -#define NOTSUSER() (suser()? 0: EPERM) -#define bcanputnext(q, band) canputnext((q)) -#endif /* SunOS 4 */ - -#ifdef __osf__ -#include <sys/malloc.h> - -/* caution: this mirrors macros in sys/malloc.h, and uses interfaces - * which are subject to change. - * The problems are that: - * - the official MALLOC macro wants the lhs of the assignment as an argument, - * and it takes care of the assignment itself (yuck.) - * - PPP insists on using "FREE" which conflicts with a macro of the same name. - * - */ -#ifdef BUCKETINDX /* V2.0 */ -#define ALLOC_SLEEP(n) (void *)malloc((u_long)(n), BUCKETP(n), M_DEVBUF, M_WAITOK) -#define ALLOC_NOSLEEP(n) (void *)malloc((u_long)(n), BUCKETP(n), M_DEVBUF, M_NOWAIT) -#else -#define ALLOC_SLEEP(n) (void *)malloc((u_long)(n), BUCKETINDEX(n), M_DEVBUF, M_WAITOK) -#define ALLOC_NOSLEEP(n) (void *)malloc((u_long)(n), BUCKETINDEX(n), M_DEVBUF, M_NOWAIT) -#endif - -#define bcanputnext(q, band) canputnext((q)) - -#ifdef FREE -#undef FREE -#endif -#define FREE(p, n) free((void *)(p), M_DEVBUF) - -#define NO_DLPI 1 - -#ifndef IFT_PPP -#define IFT_PPP 0x17 -#endif - -#include <sys/proc.h> -#define NOTSUSER() (suser(u.u_procp->p_rcred, &u.u_acflag) ? EPERM : 0) - -/* #include "ppp_osf.h" */ - -#endif /* __osf__ */ - -#ifdef AIX4 -#define ALLOC_SLEEP(n) xmalloc((n), 0, pinned_heap) /* AIX V4.x */ -#define ALLOC_NOSLEEP(n) xmalloc((n), 0, pinned_heap) /* AIX V4.x */ -#define FREE(p, n) xmfree((p), pinned_heap) -#define NOTSUSER() (suser()? 0: EPERM) -#endif /* AIX */ - -/* - * Macros for printing debugging stuff. - */ -#ifdef DEBUG -#if defined(SVR4) || defined(__osf__) -#if defined(SNI) -#include <sys/strlog.h> -#define STRLOG_ID 4712 -#define DPRINT(f) strlog(STRLOG_ID, 0, 0, SL_TRACE, f) -#define DPRINT1(f, a1) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1) -#define DPRINT2(f, a1, a2) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1, a2) -#define DPRINT3(f, a1, a2, a3) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1, a2, a3) -#else -#define DPRINT(f) cmn_err(CE_CONT, f) -#define DPRINT1(f, a1) cmn_err(CE_CONT, f, a1) -#define DPRINT2(f, a1, a2) cmn_err(CE_CONT, f, a1, a2) -#define DPRINT3(f, a1, a2, a3) cmn_err(CE_CONT, f, a1, a2, a3) -#endif /* SNI */ -#else -#define DPRINT(f) printf(f) -#define DPRINT1(f, a1) printf(f, a1) -#define DPRINT2(f, a1, a2) printf(f, a1, a2) -#define DPRINT3(f, a1, a2, a3) printf(f, a1, a2, a3) -#endif /* SVR4 or OSF */ - -#else -#define DPRINT(f) 0 -#define DPRINT1(f, a1) 0 -#define DPRINT2(f, a1, a2) 0 -#define DPRINT3(f, a1, a2, a3) 0 -#endif /* DEBUG */ - -#ifndef SVR4 -typedef unsigned char uchar_t; -typedef unsigned short ushort_t; -#ifndef __osf__ -typedef int minor_t; -#endif -#endif - -/* - * If we don't have multithreading support, define substitutes. - */ -#ifndef D_MP -# define qprocson(q) -# define qprocsoff(q) -# define put(q, mp) ((*(q)->q_qinfo->qi_putp)((q), (mp))) -# define canputnext(q) canput((q)->q_next) -# define qwriter(q, mp, func, scope) (func)((q), (mp)) -#endif - -#ifdef D_MP -/* Use msgpullup if we have other multithreading support. */ -#define PULLUP(mp, len) \ - do { \ - mblk_t *np = msgpullup((mp), (len)); \ - freemsg((mp)); \ - mp = np; \ - } while (0) - -#else -/* Use pullupmsg if we don't have any multithreading support. */ -#define PULLUP(mp, len) \ - do { \ - if (!pullupmsg((mp), (len))) { \ - freemsg((mp)); \ - mp = 0; \ - } \ - } while (0) -#endif - -/* - * How to declare the open and close procedures for a module. - */ -#ifdef SVR4 -#define MOD_OPEN_DECL(name) \ -static int name __P((queue_t *, dev_t *, int, int, cred_t *)) - -#define MOD_CLOSE_DECL(name) \ -static int name __P((queue_t *, int, cred_t *)) - -#define MOD_OPEN(name) \ -static int name(q, devp, flag, sflag, credp) \ - queue_t *q; \ - dev_t *devp; \ - int flag, sflag; \ - cred_t *credp; - -#define MOD_CLOSE(name) \ -static int name(q, flag, credp) \ - queue_t *q; \ - int flag; \ - cred_t *credp; - -#define OPEN_ERROR(x) return (x) -#define DRV_OPEN_OK(dev) return 0 - -#define NOTSUSER() (drv_priv(credp)) - -#else /* not SVR4 */ -#define MOD_OPEN_DECL(name) \ -static int name __P((queue_t *, int, int, int)) - -#define MOD_CLOSE_DECL(name) \ -static int name __P((queue_t *, int)) - -#define MOD_OPEN(name) \ -static int name(q, dev, flag, sflag) \ - queue_t *q; \ - int dev; \ - int flag, sflag; - -#define MOD_CLOSE(name) \ -static int name(q, flag) \ - queue_t *q; \ - int flag; - -#define OPEN_ERROR(x) { u.u_error = (x); return OPENFAIL; } -#define DRV_OPEN_OK(dev) return (dev) - -#endif /* SVR4 */ diff --git a/mdk-stage1/ppp/modules/vjcompress.c b/mdk-stage1/ppp/modules/vjcompress.c deleted file mode 100644 index 809b87231..000000000 --- a/mdk-stage1/ppp/modules/vjcompress.c +++ /dev/null @@ -1,587 +0,0 @@ -/* - * Routines to compress and uncompess tcp packets (for transmission - * over low speed serial lines. - * - * Copyright (c) 1989 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. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. - * - * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au, - * so that the entire packet being decompressed doesn't have - * to be in contiguous memory (just the compressed header). - */ - -/* - * This version is used under SunOS 4.x, Digital UNIX, AIX 4.x, - * and SVR4 systems including Solaris 2. - * - * $Id$ - */ - -#include <sys/types.h> -#include <sys/param.h> - -#ifdef SVR4 -#ifndef __GNUC__ -#include <sys/byteorder.h> /* for ntohl, etc. */ -#else -/* make sure we don't get the gnu "fixed" one! */ -#include "/usr/include/sys/byteorder.h" -#endif -#endif - -#ifdef __osf__ -#include <net/net_globals.h> -#endif -#include <netinet/in.h> - -#ifdef AIX4 -#define _NETINET_IN_SYSTM_H_ -typedef u_long n_long; -#else -#include <netinet/in_systm.h> -#endif - -#include <netinet/ip.h> -#include <netinet/tcp.h> - -#include <net/ppp_defs.h> -#include <net/vjcompress.h> - -#ifndef VJ_NO_STATS -#define INCR(counter) ++comp->stats.counter -#else -#define INCR(counter) -#endif - -#define BCMP(p1, p2, n) bcmp((char *)(p1), (char *)(p2), (int)(n)) -#undef BCOPY -#define BCOPY(p1, p2, n) bcopy((char *)(p1), (char *)(p2), (int)(n)) -#ifndef KERNEL -#define ovbcopy bcopy -#endif - -#ifdef __osf__ -#define getip_hl(base) (((base).ip_vhl)&0xf) -#define getth_off(base) ((((base).th_xoff)&0xf0)>>4) - -#else -#define getip_hl(base) ((base).ip_hl) -#define getth_off(base) ((base).th_off) -#endif - -void -vj_compress_init(comp, max_state) - struct vjcompress *comp; - int max_state; -{ - register u_int i; - register struct cstate *tstate = comp->tstate; - - if (max_state == -1) - max_state = MAX_STATES - 1; - bzero((char *)comp, sizeof(*comp)); - for (i = max_state; i > 0; --i) { - tstate[i].cs_id = i; - tstate[i].cs_next = &tstate[i - 1]; - } - tstate[0].cs_next = &tstate[max_state]; - tstate[0].cs_id = 0; - comp->last_cs = &tstate[0]; - comp->last_recv = 255; - comp->last_xmit = 255; - comp->flags = VJF_TOSS; -} - - -/* ENCODE encodes a number that is known to be non-zero. ENCODEZ - * checks for zero (since zero has to be encoded in the long, 3 byte - * form). - */ -#define ENCODE(n) { \ - if ((u_short)(n) >= 256) { \ - *cp++ = 0; \ - cp[1] = (n); \ - cp[0] = (n) >> 8; \ - cp += 2; \ - } else { \ - *cp++ = (n); \ - } \ -} -#define ENCODEZ(n) { \ - if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \ - *cp++ = 0; \ - cp[1] = (n); \ - cp[0] = (n) >> 8; \ - cp += 2; \ - } else { \ - *cp++ = (n); \ - } \ -} - -#define DECODEL(f) { \ - if (*cp == 0) {\ - u_int32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \ - (f) = htonl(tmp); \ - cp += 3; \ - } else { \ - u_int32_t tmp = ntohl(f) + (u_int32_t)*cp++; \ - (f) = htonl(tmp); \ - } \ -} - -#define DECODES(f) { \ - if (*cp == 0) {\ - u_short tmp = ntohs(f) + ((cp[1] << 8) | cp[2]); \ - (f) = htons(tmp); \ - cp += 3; \ - } else { \ - u_short tmp = ntohs(f) + (u_int32_t)*cp++; \ - (f) = htons(tmp); \ - } \ -} - -#define DECODEU(f) { \ - if (*cp == 0) {\ - (f) = htons((cp[1] << 8) | cp[2]); \ - cp += 3; \ - } else { \ - (f) = htons((u_int32_t)*cp++); \ - } \ -} - -u_int -vj_compress_tcp(ip, mlen, comp, compress_cid, vjhdrp) - register struct ip *ip; - u_int mlen; - struct vjcompress *comp; - int compress_cid; - u_char **vjhdrp; -{ - register struct cstate *cs = comp->last_cs->cs_next; - register u_int hlen = getip_hl(*ip); - register struct tcphdr *oth; - register struct tcphdr *th; - register u_int deltaS, deltaA; - register u_int changes = 0; - u_char new_seq[16]; - register u_char *cp = new_seq; - - /* - * Bail if this is an IP fragment or if the TCP packet isn't - * `compressible' (i.e., ACK isn't set or some other control bit is - * set). (We assume that the caller has already made sure the - * packet is IP proto TCP). - */ - if ((ip->ip_off & htons(0x3fff)) || mlen < 40) - return (TYPE_IP); - - th = (struct tcphdr *)&((int *)ip)[hlen]; - if ((th->th_flags & (TH_SYN|TH_FIN|TH_RST|TH_ACK)) != TH_ACK) - return (TYPE_IP); - /* - * Packet is compressible -- we're going to send either a - * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need - * to locate (or create) the connection state. Special case the - * most recently used connection since it's most likely to be used - * again & we don't have to do any reordering if it's used. - */ - INCR(vjs_packets); - if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr || - ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr || - *(int *)th != ((int *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) { - /* - * Wasn't the first -- search for it. - * - * States are kept in a circularly linked list with - * last_cs pointing to the end of the list. The - * list is kept in lru order by moving a state to the - * head of the list whenever it is referenced. Since - * the list is short and, empirically, the connection - * we want is almost always near the front, we locate - * states via linear search. If we don't find a state - * for the datagram, the oldest state is (re-)used. - */ - register struct cstate *lcs; - register struct cstate *lastcs = comp->last_cs; - - do { - lcs = cs; cs = cs->cs_next; - INCR(vjs_searches); - if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr - && ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr - && *(int *)th == ((int *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) - goto found; - } while (cs != lastcs); - - /* - * Didn't find it -- re-use oldest cstate. Send an - * uncompressed packet that tells the other side what - * connection number we're using for this conversation. - * Note that since the state list is circular, the oldest - * state points to the newest and we only need to set - * last_cs to update the lru linkage. - */ - INCR(vjs_misses); - comp->last_cs = lcs; - hlen += getth_off(*th); - hlen <<= 2; - if (hlen > mlen) - return (TYPE_IP); - goto uncompressed; - - found: - /* - * Found it -- move to the front on the connection list. - */ - if (cs == lastcs) - comp->last_cs = lcs; - else { - lcs->cs_next = cs->cs_next; - cs->cs_next = lastcs->cs_next; - lastcs->cs_next = cs; - } - } - - /* - * Make sure that only what we expect to change changed. The first - * line of the `if' checks the IP protocol version, header length & - * type of service. The 2nd line checks the "Don't fragment" bit. - * The 3rd line checks the time-to-live and protocol (the protocol - * check is unnecessary but costless). The 4th line checks the TCP - * header length. The 5th line checks IP options, if any. The 6th - * line checks TCP options, if any. If any of these things are - * different between the previous & current datagram, we send the - * current datagram `uncompressed'. - */ - oth = (struct tcphdr *)&((int *)&cs->cs_ip)[hlen]; - deltaS = hlen; - hlen += getth_off(*th); - hlen <<= 2; - if (hlen > mlen) - return (TYPE_IP); - - if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] || - ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] || - ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] || - getth_off(*th) != getth_off(*oth) || - (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) || - (getth_off(*th) > 5 && BCMP(th + 1, oth + 1, (getth_off(*th) - 5) << 2))) - goto uncompressed; - - /* - * Figure out which of the changing fields changed. The - * receiver expects changes in the order: urgent, window, - * ack, seq (the order minimizes the number of temporaries - * needed in this section of code). - */ - if (th->th_flags & TH_URG) { - deltaS = ntohs(th->th_urp); - ENCODEZ(deltaS); - changes |= NEW_U; - } else if (th->th_urp != oth->th_urp) - /* argh! URG not set but urp changed -- a sensible - * implementation should never do this but RFC793 - * doesn't prohibit the change so we have to deal - * with it. */ - goto uncompressed; - - if ((deltaS = (u_short)(ntohs(th->th_win) - ntohs(oth->th_win))) > 0) { - ENCODE(deltaS); - changes |= NEW_W; - } - - if ((deltaA = ntohl(th->th_ack) - ntohl(oth->th_ack)) > 0) { - if (deltaA > 0xffff) - goto uncompressed; - ENCODE(deltaA); - changes |= NEW_A; - } - - if ((deltaS = ntohl(th->th_seq) - ntohl(oth->th_seq)) > 0) { - if (deltaS > 0xffff) - goto uncompressed; - ENCODE(deltaS); - changes |= NEW_S; - } - - switch(changes) { - - case 0: - /* - * Nothing changed. If this packet contains data and the - * last one didn't, this is probably a data packet following - * an ack (normal on an interactive connection) and we send - * it compressed. Otherwise it's probably a retransmit, - * retransmitted ack or window probe. Send it uncompressed - * in case the other side missed the compressed version. - */ - if (ip->ip_len != cs->cs_ip.ip_len && - ntohs(cs->cs_ip.ip_len) == hlen) - break; - - /* (fall through) */ - - case SPECIAL_I: - case SPECIAL_D: - /* - * actual changes match one of our special case encodings -- - * send packet uncompressed. - */ - goto uncompressed; - - case NEW_S|NEW_A: - if (deltaS == deltaA && deltaS == ntohs(cs->cs_ip.ip_len) - hlen) { - /* special case for echoed terminal traffic */ - changes = SPECIAL_I; - cp = new_seq; - } - break; - - case NEW_S: - if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) { - /* special case for data xfer */ - changes = SPECIAL_D; - cp = new_seq; - } - break; - } - - deltaS = ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id); - if (deltaS != 1) { - ENCODEZ(deltaS); - changes |= NEW_I; - } - if (th->th_flags & TH_PUSH) - changes |= TCP_PUSH_BIT; - /* - * Grab the cksum before we overwrite it below. Then update our - * state with this packet's header. - */ - deltaA = ntohs(th->th_sum); - BCOPY(ip, &cs->cs_ip, hlen); - - /* - * We want to use the original packet as our compressed packet. - * (cp - new_seq) is the number of bytes we need for compressed - * sequence numbers. In addition we need one byte for the change - * mask, one for the connection id and two for the tcp checksum. - * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how - * many bytes of the original packet to toss so subtract the two to - * get the new packet size. - */ - deltaS = cp - new_seq; - cp = (u_char *)ip; - if (compress_cid == 0 || comp->last_xmit != cs->cs_id) { - comp->last_xmit = cs->cs_id; - hlen -= deltaS + 4; - *vjhdrp = (cp += hlen); - *cp++ = changes | NEW_C; - *cp++ = cs->cs_id; - } else { - hlen -= deltaS + 3; - *vjhdrp = (cp += hlen); - *cp++ = changes; - } - *cp++ = deltaA >> 8; - *cp++ = deltaA; - BCOPY(new_seq, cp, deltaS); - INCR(vjs_compressed); - return (TYPE_COMPRESSED_TCP); - - /* - * Update connection state cs & send uncompressed packet (that is, - * a regular ip/tcp packet but with the 'conversation id' we hope - * to use on future compressed packets in the protocol field). - */ - uncompressed: - BCOPY(ip, &cs->cs_ip, hlen); - ip->ip_p = cs->cs_id; - comp->last_xmit = cs->cs_id; - return (TYPE_UNCOMPRESSED_TCP); -} - -/* - * Called when we may have missed a packet. - */ -void -vj_uncompress_err(comp) - struct vjcompress *comp; -{ - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); -} - -/* - * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP. - */ -int -vj_uncompress_uncomp(buf, buflen, comp) - u_char *buf; - int buflen; - struct vjcompress *comp; -{ - register u_int hlen; - register struct cstate *cs; - register struct ip *ip; - - ip = (struct ip *) buf; - hlen = getip_hl(*ip) << 2; - if (ip->ip_p >= MAX_STATES - || hlen + sizeof(struct tcphdr) > buflen - || (hlen += getth_off(*((struct tcphdr *)&((char *)ip)[hlen])) << 2) - > buflen - || hlen > MAX_HDR) { - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); - return (0); - } - cs = &comp->rstate[comp->last_recv = ip->ip_p]; - comp->flags &=~ VJF_TOSS; - ip->ip_p = IPPROTO_TCP; - BCOPY(ip, &cs->cs_ip, hlen); - cs->cs_hlen = hlen; - INCR(vjs_uncompressedin); - return (1); -} - -/* - * Uncompress a packet of type TYPE_COMPRESSED_TCP. - * The packet starts at buf and is of total length total_len. - * The first buflen bytes are at buf; this must include the entire - * compressed TCP/IP header. This procedure returns the length - * of the VJ header, with a pointer to the uncompressed IP header - * in *hdrp and its length in *hlenp. - */ -int -vj_uncompress_tcp(buf, buflen, total_len, comp, hdrp, hlenp) - u_char *buf; - int buflen, total_len; - struct vjcompress *comp; - u_char **hdrp; - u_int *hlenp; -{ - register u_char *cp; - register u_int hlen, changes; - register struct tcphdr *th; - register struct cstate *cs; - register u_short *bp; - register u_int vjlen; - register u_int32_t tmp; - - INCR(vjs_compressedin); - cp = buf; - changes = *cp++; - if (changes & NEW_C) { - /* Make sure the state index is in range, then grab the state. - * If we have a good state index, clear the 'discard' flag. */ - if (*cp >= MAX_STATES) - goto bad; - - comp->flags &=~ VJF_TOSS; - comp->last_recv = *cp++; - } else { - /* this packet has an implicit state index. If we've - * had a line error since the last time we got an - * explicit state index, we have to toss the packet. */ - if (comp->flags & VJF_TOSS) { - INCR(vjs_tossed); - return (-1); - } - } - cs = &comp->rstate[comp->last_recv]; - hlen = getip_hl(cs->cs_ip) << 2; - th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen]; - th->th_sum = htons((*cp << 8) | cp[1]); - cp += 2; - if (changes & TCP_PUSH_BIT) - th->th_flags |= TH_PUSH; - else - th->th_flags &=~ TH_PUSH; - - switch (changes & SPECIALS_MASK) { - case SPECIAL_I: - { - register u_int32_t i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen; - /* some compilers can't nest inline assembler.. */ - tmp = ntohl(th->th_ack) + i; - th->th_ack = htonl(tmp); - tmp = ntohl(th->th_seq) + i; - th->th_seq = htonl(tmp); - } - break; - - case SPECIAL_D: - /* some compilers can't nest inline assembler.. */ - tmp = ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len) - cs->cs_hlen; - th->th_seq = htonl(tmp); - break; - - default: - if (changes & NEW_U) { - th->th_flags |= TH_URG; - DECODEU(th->th_urp); - } else - th->th_flags &=~ TH_URG; - if (changes & NEW_W) - DECODES(th->th_win); - if (changes & NEW_A) - DECODEL(th->th_ack); - if (changes & NEW_S) - DECODEL(th->th_seq); - break; - } - if (changes & NEW_I) { - DECODES(cs->cs_ip.ip_id); - } else { - cs->cs_ip.ip_id = ntohs(cs->cs_ip.ip_id) + 1; - cs->cs_ip.ip_id = htons(cs->cs_ip.ip_id); - } - - /* - * At this point, cp points to the first byte of data in the - * packet. Fill in the IP total length and update the IP - * header checksum. - */ - vjlen = cp - buf; - buflen -= vjlen; - if (buflen < 0) - /* we must have dropped some characters (crc should detect - * this but the old slip framing won't) */ - goto bad; - - total_len += cs->cs_hlen - vjlen; - cs->cs_ip.ip_len = htons(total_len); - - /* recompute the ip header checksum */ - bp = (u_short *) &cs->cs_ip; - cs->cs_ip.ip_sum = 0; - for (changes = 0; hlen > 0; hlen -= 2) - changes += *bp++; - changes = (changes & 0xffff) + (changes >> 16); - changes = (changes & 0xffff) + (changes >> 16); - cs->cs_ip.ip_sum = ~ changes; - - *hdrp = (u_char *) &cs->cs_ip; - *hlenp = cs->cs_hlen; - return vjlen; - - bad: - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); - return (-1); -} diff --git a/mdk-stage1/ppp/pppd/.cvsignore b/mdk-stage1/ppp/pppd/.cvsignore deleted file mode 100644 index 476ef2253..000000000 --- a/mdk-stage1/ppp/pppd/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -pppd -pppd-DIET diff --git a/mdk-stage1/ppp/pppd/Makefile b/mdk-stage1/ppp/pppd/Makefile deleted file mode 100644 index ad2bdae90..000000000 --- a/mdk-stage1/ppp/pppd/Makefile +++ /dev/null @@ -1,59 +0,0 @@ - #****************************************************************************** - # - # Guillaume Cottenceau (gc@mandrakesoft.com) - # - # Copyright 2000 MandrakeSoft - # - # This software may be freely redistributed under the terms of the GNU - # public license. - # - # You should have received a copy of the GNU General Public License - # along with this program; if not, write to the Free Software - # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - # - #***************************************************************************** - -top_dir = ../.. - -include $(top_dir)/Makefile.common - - -TARGETS = pppd - -ifeq (DIETLIBC, $(L)) -TARGETS += pppd-DIET -endif - -BINTARGET = ../pppd-bin - - -all: $(TARGETS) - -clean: - rm -f *.o *.a $(BINTARGET) pppd pppd-DIET - -FLAGS = -Wall -Werror -Os -fomit-frame-pointer -DDO_BSD_COMPRESS=0 -D_linux_=1 -DHAVE_MMAP -DNO_DRAND48 - -INCS = -I../include -I. - - -OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o auth.o options.o demand.o utils.o sys-linux.o ipxcp.o multilink.o tdb.o tty.o -OBJS-DIET = $(subst .o,-DIET.o,$(OBJS)) - - -pppd: $(OBJS) - gcc -static -o $@ $^ -lcrypt - $(STRIPCMD) $@ - cp -f $@ $(BINTARGET) - -pppd-DIET: $(OBJS-DIET) - gcc $(DIETLIBC_LDFLAGS_STAGE1) -o $@ $^ $(DIETLIBC_LIBC) - $(STRIPCMD) $@ - cp -f $@ $(BINTARGET) - -$(OBJS): %.o: %.c - gcc $(FLAGS) $(INCS) $(GLIBC_INCLUDES) -c $< -o $@ - -$(OBJS-DIET): %-DIET.o: %.c - gcc $(FLAGS) $(INCS) $(DIETLIBC_INCLUDES) -c $< -o $@ - diff --git a/mdk-stage1/ppp/pppd/Makefile.linux b/mdk-stage1/ppp/pppd/Makefile.linux deleted file mode 100644 index 47d6ba01e..000000000 --- a/mdk-stage1/ppp/pppd/Makefile.linux +++ /dev/null @@ -1,129 +0,0 @@ -# -# pppd makefile for Linux -# $Id$ -# - -# Default installation locations -BINDIR = $(DESTDIR)/usr/sbin -MANDIR = $(DESTDIR)/usr/man - -PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ - ipxcp.c auth.c options.c sys-linux.c md4.c chap_ms.c cbcp.c \ - demand.c utils.c multilink.c tdb.c tty.c -HEADERS = callout.h pathnames.h patchlevel.h chap.h md5.h chap_ms.h md4.h \ - ipxcp.h cbcp.h tdb.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 demand.o utils.o sys-linux.o ipxcp.o multilink.o \ - tdb.o tty.o - -all: pppd - -# -# include dependancies if present and backup if as a header file -ifeq (.depend,$(wildcard .depend)) -include .depend -endif - -CC = gcc -# -COPTS = -Wall $(RPM_OPT_FLAGS) -LIBS = -lutil - -ifneq ($(wildcard /usr/lib/libcrypt.*),) -LIBS += -lcrypt -endif - -# Uncomment the next 2 lines to include support for Microsoft's -# MS-CHAP authentication protocol. -CHAPMS=y -USE_CRYPT=y -ifneq ($(wildcard /usr/lib/libcrypt.*),) -HAVE_CRYPT_H=y -endif - -# Uncomment the next line to include support for PPP packet filtering. -# This requires that the libpcap library and headers be installed -# and that the kernel driver support PPP packet filtering, which it -# doesn't yet. -#FILTER=y - -HAS_SHADOW=y -USE_PAM=y -#HAVE_INET6=y - -PLUGIN=y - -INCLUDE_DIRS= -I../include - -COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MULTILINK -DHAVE_MMAP - -CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) - -ifdef CHAPMS -CFLAGS += -DCHAPMS=1 -ifndef USE_CRYPT -LIBS := -ldes $(LIBS) -else -CFLAGS += -DUSE_CRYPT=1 -ifneq ($(wildcard /usr/include/crypt.h),) -CFLAGS += -DHAVE_CRYPT_H=1 -endif -endif -PPPDOBJS += md4.o chap_ms.o -ifdef MSLANMAN -CFLAGS += -DMSLANMAN=1 -endif -endif - -ifdef HAS_SHADOW -CFLAGS += -DHAS_SHADOW -#LIBS := -lshadow $(LIBS) -endif - -# For "Pluggable Authentication Modules", see ftp.redhat.com:/pub/pam/. -ifdef USE_PAM -CFLAGS += -DUSE_PAM -LIBS := -lpam -ldl $(LIBS) -endif - -# Lock library binary for Linux is included in 'linux' subdirectory. -ifdef LOCKLIB -LIBS := -llock $(LIBS) -CFLAGS += -DLOCKLIB=1 -endif - -ifdef PLUGIN -CFLAGS += -DPLUGIN -LDFLAGS += -Wl,-E -LIBS += -ldl -endif - -ifdef FILTER -LIBS += -lpcap -CFLAGS += -DPPP_FILTER -I/usr/include/pcap -endif - -ifdef HAVE_INET6 - PPPDSRCS += ipv6cp.c eui64.c - HEADERS += ipv6cp.h eui64.h - PPPDOBJS += ipv6cp.o eui64.o - CFLAGS += -DINET6=1 -endif - - -INSTALL= install - -install: pppd - mkdir -p $(BINDIR) $(MANDIR) - $(INSTALL) -m 555 pppd $(BINDIR)/pppd - $(INSTALL) -c -m 444 pppd.8 $(MANDIR)/man8 - -pppd: $(PPPDOBJS) - $(CC) $(CFLAGS) $(LDFLAGS) -o pppd $(PPPDOBJS) $(LIBS) - -clean: - rm -f $(PPPDOBJS) pppd *~ #* core - -depend: - $(CPP) -M $(CFLAGS) $(PPPDSRCS) >.depend diff --git a/mdk-stage1/ppp/pppd/Makefile.linux.make b/mdk-stage1/ppp/pppd/Makefile.linux.make deleted file mode 100644 index d98a32562..000000000 --- a/mdk-stage1/ppp/pppd/Makefile.linux.make +++ /dev/null @@ -1,131 +0,0 @@ -# -# pppd makefile for Linux -# $Id$ -# - -# Default installation locations -BINDIR = /usr/sbin -MANDIR = /usr/man - -PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ - ipxcp.c auth.c options.c sys-linux.c md4.c chap_ms.c cbcp.c \ - demand.c utils.c multilink.c tdb.c tty.c -HEADERS = callout.h pathnames.h patchlevel.h chap.h md5.h chap_ms.h md4.h \ - ipxcp.h cbcp.h tdb.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 demand.o utils.o sys-linux.o ipxcp.o multilink.o \ - tdb.o tty.o - -all: pppd - -# -# include dependancies if present and backup if as a header file -ifeq (.depend,$(wildcard .depend)) -include .depend -endif - -# CC = gcc -# -COPTS = -O2 -pipe -Wall -g -LIBS = - -ifneq ($(wildcard /usr/lib/libcrypt.*),) -LIBS += -lcrypt -endif - -# Uncomment the next 2 lines to include support for Microsoft's -# MS-CHAP authentication protocol. -CHAPMS=y -USE_CRYPT=y -ifneq ($(wildcard /usr/lib/libcrypt.*),) -HAVE_CRYPT_H=y -endif - -# Uncomment the next line to include support for PPP packet filtering. -# This requires that the libpcap library and headers be installed -# and that the kernel driver support PPP packet filtering, which it -# doesn't yet. -#FILTER=y - -HAS_SHADOW=y -#USE_PAM=y -#HAVE_INET6=y - -PLUGIN=y - -INCLUDE_DIRS= -I../include - -COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MULTILINK -DHAVE_MMAP - -CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) - -ifdef CHAPMS -CFLAGS += -DCHAPMS=1 -ifndef USE_CRYPT -LIBS := -ldes $(LIBS) -else -CFLAGS += -DUSE_CRYPT=1 -ifneq ($(wildcard /usr/include/crypt.h),) -CFLAGS += -DHAVE_CRYPT_H=1 -endif -endif -PPPDOBJS += md4.o chap_ms.o -ifdef MSLANMAN -CFLAGS += -DMSLANMAN=1 -endif -endif - -ifdef HAS_SHADOW -CFLAGS += -DHAS_SHADOW -#LIBS := -lshadow $(LIBS) -endif - -# For "Pluggable Authentication Modules", see ftp.redhat.com:/pub/pam/. -ifdef USE_PAM -CFLAGS += -DUSE_PAM -LIBS := -lpam -ldl $(LIBS) -endif - -# Lock library binary for Linux is included in 'linux' subdirectory. -ifdef LOCKLIB -LIBS := -llock $(LIBS) -CFLAGS += -DLOCKLIB=1 -endif - -ifdef PLUGIN -CFLAGS += -DPLUGIN -LDFLAGS += -Wl,-E -LIBS += -ldl -endif - -ifdef FILTER -LIBS += -lpcap -CFLAGS += -DPPP_FILTER -I/usr/include/pcap -endif - -ifdef HAVE_INET6 - PPPDSRCS += ipv6cp.c eui64.c - HEADERS += ipv6cp.h eui64.h - PPPDOBJS += ipv6cp.o eui64.o - CFLAGS += -DINET6=1 -endif - - -INSTALL= install -o root - -install: pppd - mkdir -p $(BINDIR) $(MANDIR) - $(INSTALL) -s -c -m 555 pppd $(BINDIR)/pppd - if chgrp pppusers $(BINDIR)/pppd 2>/dev/null; then \ - chmod o-rx,u+s $(BINDIR)/pppd; fi - $(INSTALL) -c -m 444 pppd.8 $(MANDIR)/man8 - -pppd: $(PPPDOBJS) - $(CC) $(CFLAGS) $(LDFLAGS) -o pppd $(PPPDOBJS) $(LIBS) - -clean: - rm -f $(PPPDOBJS) pppd *~ #* core - -depend: - $(CPP) -M $(CFLAGS) $(PPPDSRCS) >.depend diff --git a/mdk-stage1/ppp/pppd/Makefile.linux.makeopt b/mdk-stage1/ppp/pppd/Makefile.linux.makeopt deleted file mode 100644 index 3094c941c..000000000 --- a/mdk-stage1/ppp/pppd/Makefile.linux.makeopt +++ /dev/null @@ -1,129 +0,0 @@ -# -# pppd makefile for Linux -# $Id$ -# - -# Default installation locations -BINDIR = $(DESTDIR)/usr/sbin -MANDIR = $(DESTDIR)/usr/man - -PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \ - ipxcp.c auth.c options.c sys-linux.c md4.c chap_ms.c cbcp.c \ - demand.c utils.c multilink.c tdb.c tty.c -HEADERS = callout.h pathnames.h patchlevel.h chap.h md5.h chap_ms.h md4.h \ - ipxcp.h cbcp.h tdb.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 demand.o utils.o sys-linux.o ipxcp.o multilink.o \ - tdb.o tty.o - -all: pppd - -# -# include dependancies if present and backup if as a header file -ifeq (.depend,$(wildcard .depend)) -include .depend -endif - -CC = gcc -# -COPTS = -O2 -pipe -Wall -g -LIBS = -lutil - -ifneq ($(wildcard /usr/lib/libcrypt.*),) -LIBS += -lcrypt -endif - -# Uncomment the next 2 lines to include support for Microsoft's -# MS-CHAP authentication protocol. -CHAPMS=y -USE_CRYPT=y -ifneq ($(wildcard /usr/lib/libcrypt.*),) -HAVE_CRYPT_H=y -endif - -# Uncomment the next line to include support for PPP packet filtering. -# This requires that the libpcap library and headers be installed -# and that the kernel driver support PPP packet filtering, which it -# doesn't yet. -#FILTER=y - -HAS_SHADOW=y -USE_PAM=y -#HAVE_INET6=y - -PLUGIN=y - -INCLUDE_DIRS= -I../include - -COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MULTILINK -DHAVE_MMAP - -CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) - -ifdef CHAPMS -CFLAGS += -DCHAPMS=1 -ifndef USE_CRYPT -LIBS := -ldes $(LIBS) -else -CFLAGS += -DUSE_CRYPT=1 -ifneq ($(wildcard /usr/include/crypt.h),) -CFLAGS += -DHAVE_CRYPT_H=1 -endif -endif -PPPDOBJS += md4.o chap_ms.o -ifdef MSLANMAN -CFLAGS += -DMSLANMAN=1 -endif -endif - -ifdef HAS_SHADOW -CFLAGS += -DHAS_SHADOW -#LIBS := -lshadow $(LIBS) -endif - -# For "Pluggable Authentication Modules", see ftp.redhat.com:/pub/pam/. -ifdef USE_PAM -CFLAGS += -DUSE_PAM -LIBS := -lpam -ldl $(LIBS) -endif - -# Lock library binary for Linux is included in 'linux' subdirectory. -ifdef LOCKLIB -LIBS := -llock $(LIBS) -CFLAGS += -DLOCKLIB=1 -endif - -ifdef PLUGIN -CFLAGS += -DPLUGIN -LDFLAGS += -Wl,-E -LIBS += -ldl -endif - -ifdef FILTER -LIBS += -lpcap -CFLAGS += -DPPP_FILTER -I/usr/include/pcap -endif - -ifdef HAVE_INET6 - PPPDSRCS += ipv6cp.c eui64.c - HEADERS += ipv6cp.h eui64.h - PPPDOBJS += ipv6cp.o eui64.o - CFLAGS += -DINET6=1 -endif - - -INSTALL= install - -install: pppd - mkdir -p $(BINDIR) $(MANDIR) - $(INSTALL) -m 555 pppd $(BINDIR)/pppd - $(INSTALL) -c -m 444 pppd.8 $(MANDIR)/man8 - -pppd: $(PPPDOBJS) - $(CC) $(CFLAGS) $(LDFLAGS) -o pppd $(PPPDOBJS) $(LIBS) - -clean: - rm -f $(PPPDOBJS) pppd *~ #* core - -depend: - $(CPP) -M $(CFLAGS) $(PPPDSRCS) >.depend diff --git a/mdk-stage1/ppp/pppd/Makefile.sol2 b/mdk-stage1/ppp/pppd/Makefile.sol2 deleted file mode 100644 index dfdcddd97..000000000 --- a/mdk-stage1/ppp/pppd/Makefile.sol2 +++ /dev/null @@ -1,48 +0,0 @@ -# -# Makefile for pppd under Solaris 2. -# $Id$ -# - -include ../solaris/Makedefs - -COPTS += -xO2 -xspace -W0,-Lt -CFLAGS = -I../include -DSVR4 -DSOL2 $(COPTS) -LIBS = -lsocket -lnsl - -OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o tty.o \ - ccp.o auth.o options.o demand.o utils.o sys-solaris.o tdb.o - -# -# uncomment the following to enable plugins -# -CFLAGS += -DPLUGIN -LIBS += -ldl - -# -# Solaris 8 and above accomodates /var/run, so uncomment the -# following to place pppd process IDs on that location -# -#CFLAGS += -D_PATH_VARRUN='"/var/run/"' - -# -# uncomment the following to enable IPv6 -# -# Solaris 8 and on includes support for IPv6 -# -#CFLAGS += -DINET6 -#OBJS += ipv6cp.o eui64.o - -# -# Make targets -# -all: pppd - -pppd: $(OBJS) - $(CC) -o pppd $(OBJS) $(LIBS) - -install: - $(INSTALL) -f $(BINDIR) -m 4755 -u root pppd - $(INSTALL) -f $(MANDIR)/man8 -m 444 pppd.8 - -clean: - rm -f $(OBJS) pppd *~ core y.tab.c y.tab.h diff --git a/mdk-stage1/ppp/pppd/Makefile.sunos4 b/mdk-stage1/ppp/pppd/Makefile.sunos4 deleted file mode 100644 index 694ac341f..000000000 --- a/mdk-stage1/ppp/pppd/Makefile.sunos4 +++ /dev/null @@ -1,26 +0,0 @@ -# -# Makefile for pppd under SunOS 4. -# $Id$ -# - -include ../sunos4/Makedefs - -LIBS = - -CFLAGS = $(COPTS) -I../include -DSUNOS4 -DGIDSET_TYPE=int \ - -DLOCK_DIR=\"/usr/spool/locks\" - -all: pppd - -OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \ - auth.o options.o demand.o utils.o sys-sunos4.o tty.o - -pppd: $(OBJS) - $(CC) -o pppd $(OBJS) $(LIBS) - -install: - $(INSTALL) -c -m 4555 pppd $(BINDIR)/pppd - $(INSTALL) -c -m 444 pppd.8 $(MANDIR)/man8/pppd.8 - -clean: - rm -f $(OBJS) pppd *~ core diff --git a/mdk-stage1/ppp/pppd/auth.c b/mdk-stage1/ppp/pppd/auth.c deleted file mode 100644 index 5f95a2982..000000000 --- a/mdk-stage1/ppp/pppd/auth.c +++ /dev/null @@ -1,1939 +0,0 @@ -/* - * auth.c - PPP authentication and phase control. - * - * Copyright (c) 1993 The Australian National 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 the Australian National 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. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -#define RCSID "$Id$" - -#include <stdio.h> -#include <stddef.h> -#include <stdlib.h> -#include <unistd.h> -#include <pwd.h> -#include <grp.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <utmp.h> -#include <fcntl.h> -#if defined(_PATH_LASTLOG) && defined(_linux_) -#include <lastlog.h> -#endif - -#include <netdb.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#ifdef USE_PAM -#include <security/pam_appl.h> -#endif - -#ifdef HAS_SHADOW -#include <shadow.h> -#ifndef PW_PPP -#define PW_PPP PW_LOGIN -#endif -#endif - -#include "pppd.h" -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" -#include "upap.h" -#include "chap.h" -#ifdef CBCP_SUPPORT -#include "cbcp.h" -#endif -#include "pathnames.h" - -#include <time.h> - -static const char rcsid[] = RCSID; - -/* Bits in scan_authfile return value */ -#define NONWILD_SERVER 1 -#define NONWILD_CLIENT 2 - -#define ISWILD(word) (word[0] == '*' && word[1] == 0) - -/* The name by which the peer authenticated itself to us. */ -char peer_authname[MAXNAMELEN]; - -/* Records which authentication operations haven't completed yet. */ -static int auth_pending[NUM_PPP]; - -/* Set if we have successfully called plogin() */ -static int logged_in; - -/* List of addresses which the peer may use. */ -static struct permitted_ip *addresses[NUM_PPP]; - -/* Wordlist giving addresses which the peer may use - without authenticating itself. */ -static struct wordlist *noauth_addrs; - -/* Extra options to apply, from the secrets file entry for the peer. */ -static struct wordlist *extra_options; - -/* Number of network protocols which we have opened. */ -static int num_np_open; - -/* Number of network protocols which have come up. */ -static int num_np_up; - -/* Set if we got the contents of passwd[] from the pap-secrets file. */ -static int passwd_from_file; - -/* Set if we require authentication only because we have a default route. */ -static bool default_auth; - -/* Hook to enable a plugin to control the idle time limit */ -int (*idle_time_hook) __P((struct ppp_idle *)) = NULL; - -/* Hook for a plugin to say whether we can possibly authenticate any peer */ -int (*pap_check_hook) __P((void)) = NULL; - -/* Hook for a plugin to check the PAP user and password */ -int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, - struct wordlist **paddrs, - struct wordlist **popts)) = NULL; - -/* Hook for a plugin to know about the PAP user logout */ -void (*pap_logout_hook) __P((void)) = NULL; - -/* Hook for a plugin to get the PAP password for authenticating us */ -int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL; - -/* - * This is used to ensure that we don't start an auth-up/down - * script while one is already running. - */ -enum script_state { - s_down, - s_up -}; - -static enum script_state auth_state = s_down; -static enum script_state auth_script_state = s_down; -static pid_t auth_script_pid = 0; - -static int used_login; /* peer authenticated against login database */ - -/* - * Option variables. - */ -bool uselogin = 0; /* Use /etc/passwd for checking PAP */ -bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */ -bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */ -bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */ -bool usehostname = 0; /* Use hostname for our_name */ -bool auth_required = 0; /* Always require authentication from peer */ -bool allow_any_ip = 0; /* Allow peer to use any IP address */ -bool explicit_remote = 0; /* User specified explicit remote name */ -char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ - -static char *uafname; /* name of most recent +ua file */ - -/* Bits in auth_pending[] */ -#define PAP_WITHPEER 1 -#define PAP_PEER 2 -#define CHAP_WITHPEER 4 -#define CHAP_PEER 8 - -extern char *crypt __P((const char *, const char *)); - -/* Prototypes for procedures local to this file. */ - -static void network_phase __P((int)); -static void check_idle __P((void *)); -static void connect_time_expired __P((void *)); -static int plogin __P((char *, char *, char **)); -static void plogout __P((void)); -static int null_login __P((int)); -static int get_pap_passwd __P((char *)); -static int have_pap_secret __P((int *)); -static int have_chap_secret __P((char *, char *, int, int *)); -static int ip_addr_check __P((u_int32_t, struct permitted_ip *)); -static int scan_authfile __P((FILE *, char *, char *, char *, - struct wordlist **, struct wordlist **, - char *)); -static void free_wordlist __P((struct wordlist *)); -static void auth_script __P((char *)); -static void auth_script_done __P((void *)); -static void set_allowed_addrs __P((int, struct wordlist *, struct wordlist *)); -static int some_ip_ok __P((struct wordlist *)); -static int setupapfile __P((char **)); -static int privgroup __P((char **)); -static int set_noauth_addr __P((char **)); -static void check_access __P((FILE *, char *)); -static int wordlist_count __P((struct wordlist *)); - -/* - * Authentication-related options. - */ -option_t auth_options[] = { - { "auth", o_bool, &auth_required, - "Require authentication from peer", OPT_PRIO | 1 }, - { "noauth", o_bool, &auth_required, - "Don't require peer to authenticate", OPT_PRIOSUB | OPT_PRIV, - &allow_any_ip }, - { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap, - "Require PAP authentication from peer", - OPT_PRIOSUB | 1, &auth_required }, - { "+pap", o_bool, &lcp_wantoptions[0].neg_upap, - "Require PAP authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | 1, &auth_required }, - { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap, - "Require CHAP authentication from peer", - OPT_PRIOSUB | 1, &auth_required }, - { "+chap", o_bool, &lcp_wantoptions[0].neg_chap, - "Require CHAP authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | 1, &auth_required }, - - { "refuse-pap", o_bool, &refuse_pap, - "Don't agree to auth to peer with PAP", 1 }, - { "-pap", o_bool, &refuse_pap, - "Don't allow PAP authentication with peer", OPT_ALIAS | 1 }, - - { "refuse-chap", o_bool, &refuse_chap, - "Don't agree to auth to peer with CHAP", 1 }, - { "-chap", o_bool, &refuse_chap, - "Don't allow CHAP authentication with peer", OPT_ALIAS | 1 }, - - { "name", o_string, our_name, - "Set local name for authentication", - OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXNAMELEN }, - - { "+ua", o_special, (void *)setupapfile, - "Get PAP user and password from file", - OPT_PRIO | OPT_A2STRVAL, &uafname }, - - { "user", o_string, user, - "Set name for auth with peer", OPT_PRIO | OPT_STATIC, NULL, MAXNAMELEN }, - - { "password", o_string, passwd, - "Password for authenticating us to the peer", - OPT_PRIO | OPT_STATIC | OPT_HIDE, NULL, MAXSECRETLEN }, - - { "usehostname", o_bool, &usehostname, - "Must use hostname for authentication", 1 }, - - { "remotename", o_string, remote_name, - "Set remote name for authentication", OPT_PRIO | OPT_STATIC, - &explicit_remote, MAXNAMELEN }, - - { "login", o_bool, &uselogin, - "Use system password database for PAP", 1 }, - - { "papcrypt", o_bool, &cryptpap, - "PAP passwords are encrypted", 1 }, - - { "privgroup", o_special, (void *)privgroup, - "Allow group members to use privileged options", OPT_PRIV | OPT_A2LIST }, - - { "allow-ip", o_special, (void *)set_noauth_addr, - "Set IP address(es) which can be used without authentication", - OPT_PRIV | OPT_A2LIST }, - - { NULL } -}; - -/* - * setupapfile - specifies UPAP info for authenticating with peer. - */ -static int -setupapfile(argv) - char **argv; -{ - FILE *ufile; - int l; - char u[MAXNAMELEN], p[MAXSECRETLEN]; - char *fname; - - lcp_allowoptions[0].neg_upap = 1; - - /* open user info file */ - fname = strdup(*argv); - if (fname == NULL) - novm("+ua file name"); - seteuid(getuid()); - ufile = fopen(fname, "r"); - seteuid(0); - if (ufile == NULL) { - option_error("unable to open user login data file %s", fname); - return 0; - } - check_access(ufile, fname); - uafname = fname; - - /* get username */ - if (fgets(u, MAXNAMELEN - 1, ufile) == NULL - || fgets(p, MAXSECRETLEN - 1, ufile) == NULL){ - option_error("unable to read user login data file %s", fname); - return 0; - } - fclose(ufile); - - /* get rid of newlines */ - l = strlen(u); - if (l > 0 && u[l-1] == '\n') - u[l-1] = 0; - l = strlen(p); - if (l > 0 && p[l-1] == '\n') - p[l-1] = 0; - - if (override_value("user", option_priority, fname)) - strlcpy(user, u, sizeof(user)); - if (override_value("passwd", option_priority, fname)) - strlcpy(passwd, p, sizeof(passwd)); - - return (1); -} - - -/* - * privgroup - allow members of the group to have privileged access. - */ -static int -privgroup(argv) - char **argv; -{ - struct group *g; - int i; - - g = getgrnam(*argv); - if (g == 0) { - option_error("group %s is unknown", *argv); - return 0; - } - for (i = 0; i < ngroups; ++i) { - if (groups[i] == g->gr_gid) { - privileged = 1; - break; - } - } - return 1; -} - - -/* - * set_noauth_addr - set address(es) that can be used without authentication. - * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets. - */ -static int -set_noauth_addr(argv) - char **argv; -{ - char *addr = *argv; - int l = strlen(addr) + 1; - struct wordlist *wp; - - wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); - if (wp == NULL) - novm("allow-ip argument"); - wp->word = (char *) (wp + 1); - wp->next = noauth_addrs; - BCOPY(addr, wp->word, l); - noauth_addrs = wp; - return 1; -} - - -/* - * An Open on LCP has requested a change from Dead to Establish phase. - * Do what's necessary to bring the physical layer up. - */ -void -link_required(unit) - int unit; -{ -} - -/* - * LCP has terminated the link; go to the Dead phase and take the - * physical layer down. - */ -void -link_terminated(unit) - int unit; -{ - if (phase == PHASE_DEAD) - return; - if (pap_logout_hook) { - pap_logout_hook(); - } else { - if (logged_in) - plogout(); - } - new_phase(PHASE_DEAD); - notice("Connection terminated."); -} - -/* - * LCP has gone down; it will either die or try to re-establish. - */ -void -link_down(unit) - int unit; -{ - int i; - struct protent *protp; - - auth_state = s_down; - if (auth_script_state == s_up && auth_script_pid == 0) { - update_link_stats(unit); - auth_script_state = s_down; - auth_script(_PATH_AUTHDOWN); - } - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (!protp->enabled_flag) - continue; - if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) - (*protp->lowerdown)(unit); - if (protp->protocol < 0xC000 && protp->close != NULL) - (*protp->close)(unit, "LCP down"); - } - num_np_open = 0; - num_np_up = 0; - if (phase != PHASE_DEAD) - new_phase(PHASE_TERMINATE); -} - -/* - * The link is established. - * Proceed to the Dead, Authenticate or Network phase as appropriate. - */ -void -link_established(unit) - int unit; -{ - int auth; - lcp_options *wo = &lcp_wantoptions[unit]; - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ho = &lcp_hisoptions[unit]; - int i; - struct protent *protp; - - /* - * Tell higher-level protocols that LCP is up. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol != PPP_LCP && protp->enabled_flag - && protp->lowerup != NULL) - (*protp->lowerup)(unit); - - if (auth_required && !(go->neg_chap || go->neg_upap)) { - /* - * We wanted the peer to authenticate itself, and it refused: - * if we have some address(es) it can use without auth, fine, - * otherwise treat it as though it authenticated with PAP using - * a username * of "" and a password of "". If that's not OK, - * boot it out. - */ - if (noauth_addrs != NULL) { - set_allowed_addrs(unit, NULL, NULL); - } else if (!wo->neg_upap || uselogin || !null_login(unit)) { - warn("peer refused to authenticate: terminating link"); - lcp_close(unit, "peer refused to authenticate"); - status = EXIT_PEER_AUTH_FAILED; - return; - } - } - - new_phase(PHASE_AUTHENTICATE); - used_login = 0; - auth = 0; - if (go->neg_chap) { - ChapAuthPeer(unit, our_name, go->chap_mdtype); - auth |= CHAP_PEER; - } else if (go->neg_upap) { - upap_authpeer(unit); - auth |= PAP_PEER; - } - if (ho->neg_chap) { - ChapAuthWithPeer(unit, user, ho->chap_mdtype); - auth |= CHAP_WITHPEER; - } else if (ho->neg_upap) { - if (passwd[0] == 0) { - passwd_from_file = 1; - if (!get_pap_passwd(passwd)) - error("No secret found for PAP login"); - } - upap_authwithpeer(unit, user, passwd); - auth |= PAP_WITHPEER; - } - auth_pending[unit] = auth; - - if (!auth) - network_phase(unit); -} - -/* - * Proceed to the network phase. - */ -static void -network_phase(unit) - int unit; -{ - lcp_options *go = &lcp_gotoptions[unit]; - - /* - * If the peer had to authenticate, run the auth-up script now. - */ - if (go->neg_chap || go->neg_upap) { - auth_state = s_up; - if (auth_script_state == s_down && auth_script_pid == 0) { - auth_script_state = s_up; - auth_script(_PATH_AUTHUP); - } - } - -#ifdef CBCP_SUPPORT - /* - * If we negotiated callback, do it now. - */ - if (go->neg_cbcp) { - new_phase(PHASE_CALLBACK); - (*cbcp_protent.open)(unit); - return; - } -#endif - - /* - * Process extra options from the secrets file - */ - if (extra_options) { - options_from_list(extra_options, 1); - free_wordlist(extra_options); - extra_options = 0; - } - start_networks(); -} - -void -start_networks() -{ - int i; - struct protent *protp; - - new_phase(PHASE_NETWORK); - -#ifdef HAVE_MULTILINK - if (multilink) { - if (mp_join_bundle()) { - if (updetach && !nodetach) - detach(); - return; - } - } -#endif /* HAVE_MULTILINK */ - -#ifdef PPP_FILTER - if (!demand) - set_filters(&pass_filter, &active_filter); -#endif - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol < 0xC000 && protp->enabled_flag - && protp->open != NULL) { - (*protp->open)(0); - if (protp->protocol != PPP_CCP) - ++num_np_open; - } - - if (num_np_open == 0) - /* nothing to do */ - lcp_close(0, "No network protocols running"); -} - -/* - * The peer has failed to authenticate himself using `protocol'. - */ -void -auth_peer_fail(unit, protocol) - int unit, protocol; -{ - /* - * Authentication failure: take the link down - */ - lcp_close(unit, "Authentication failed"); - status = EXIT_PEER_AUTH_FAILED; -} - -/* - * The peer has been successfully authenticated using `protocol'. - */ -void -auth_peer_success(unit, protocol, name, namelen) - int unit, protocol; - char *name; - int namelen; -{ - int bit; - - switch (protocol) { - case PPP_CHAP: - bit = CHAP_PEER; - break; - case PPP_PAP: - bit = PAP_PEER; - break; - default: - warn("auth_peer_success: unknown protocol %x", protocol); - return; - } - - /* - * Save the authenticated name of the peer for later. - */ - if (namelen > sizeof(peer_authname) - 1) - namelen = sizeof(peer_authname) - 1; - BCOPY(name, peer_authname, namelen); - peer_authname[namelen] = 0; - script_setenv("PEERNAME", peer_authname, 0); - - /* - * If there is no more authentication still to be done, - * proceed to the network (or callback) phase. - */ - if ((auth_pending[unit] &= ~bit) == 0) - network_phase(unit); -} - -/* - * We have failed to authenticate ourselves to the peer using `protocol'. - */ -void -auth_withpeer_fail(unit, protocol) - int unit, protocol; -{ - if (passwd_from_file) - BZERO(passwd, MAXSECRETLEN); - /* - * We've failed to authenticate ourselves to our peer. - * Some servers keep sending CHAP challenges, but there - * is no point in persisting without any way to get updated - * authentication secrets. - */ - lcp_close(unit, "Failed to authenticate ourselves to peer"); - status = EXIT_AUTH_TOPEER_FAILED; -} - -/* - * We have successfully authenticated ourselves with the peer using `protocol'. - */ -void -auth_withpeer_success(unit, protocol) - int unit, protocol; -{ - int bit; - - switch (protocol) { - case PPP_CHAP: - bit = CHAP_WITHPEER; - break; - case PPP_PAP: - if (passwd_from_file) - BZERO(passwd, MAXSECRETLEN); - bit = PAP_WITHPEER; - break; - default: - warn("auth_withpeer_success: unknown protocol %x", protocol); - bit = 0; - } - - /* - * If there is no more authentication still being done, - * proceed to the network (or callback) phase. - */ - if ((auth_pending[unit] &= ~bit) == 0) - network_phase(unit); -} - - -/* - * np_up - a network protocol has come up. - */ -void -np_up(unit, proto) - int unit, proto; -{ - int tlim; - - if (num_np_up == 0) { - /* - * At this point we consider that the link has come up successfully. - */ - status = EXIT_OK; - unsuccess = 0; - new_phase(PHASE_RUNNING); - - if (idle_time_hook != 0) - tlim = (*idle_time_hook)(NULL); - else - tlim = idle_time_limit; - if (tlim > 0) - TIMEOUT(check_idle, NULL, tlim); - - /* - * Set a timeout to close the connection once the maximum - * connect time has expired. - */ - if (maxconnect > 0) - TIMEOUT(connect_time_expired, 0, maxconnect); - - /* - * Detach now, if the updetach option was given. - */ - if (updetach && !nodetach) - detach(); - } - ++num_np_up; -} - -/* - * np_down - a network protocol has gone down. - */ -void -np_down(unit, proto) - int unit, proto; -{ - if (--num_np_up == 0) { - UNTIMEOUT(check_idle, NULL); - new_phase(PHASE_NETWORK); - } -} - -/* - * np_finished - a network protocol has finished using the link. - */ -void -np_finished(unit, proto) - int unit, proto; -{ - if (--num_np_open <= 0) { - /* no further use for the link: shut up shop. */ - lcp_close(0, "No network protocols running"); - } -} - -/* - * check_idle - check whether the link has been idle for long - * enough that we can shut it down. - */ -static void -check_idle(arg) - void *arg; -{ - struct ppp_idle idle; - time_t itime; - int tlim; - - if (!get_idle_time(0, &idle)) - return; - if (idle_time_hook != 0) { - tlim = idle_time_hook(&idle); - } else { - itime = MIN(idle.xmit_idle, idle.recv_idle); - tlim = idle_time_limit - itime; - } - if (tlim <= 0) { - /* link is idle: shut it down. */ - notice("Terminating connection due to lack of activity."); - lcp_close(0, "Link inactive"); - need_holdoff = 0; - status = EXIT_IDLE_TIMEOUT; - } else { - TIMEOUT(check_idle, NULL, tlim); - } -} - -/* - * connect_time_expired - log a message and close the connection. - */ -static void -connect_time_expired(arg) - void *arg; -{ - info("Connect time expired"); - lcp_close(0, "Connect time expired"); /* Close connection */ - status = EXIT_CONNECT_TIME; -} - -/* - * auth_check_options - called to check authentication options. - */ -void -auth_check_options() -{ - lcp_options *wo = &lcp_wantoptions[0]; - int can_auth; - int lacks_ip; - - /* Default our_name to hostname, and user to our_name */ - if (our_name[0] == 0 || usehostname) - strlcpy(our_name, hostname, sizeof(our_name)); - if (user[0] == 0) - strlcpy(user, our_name, sizeof(user)); - - /* - * If we have a default route, require the peer to authenticate - * unless the noauth option was given or the real user is root. - */ - if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) { - auth_required = 1; - default_auth = 1; - } - - /* If authentication is required, ask peer for CHAP or PAP. */ - if (auth_required) { - allow_any_ip = 0; - if (!wo->neg_chap && !wo->neg_upap) { - wo->neg_chap = 1; - wo->neg_upap = 1; - } - } else { - wo->neg_chap = 0; - wo->neg_upap = 0; - } - - /* - * Check whether we have appropriate secrets to use - * to authenticate the peer. - */ - lacks_ip = 0; - can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); - if (!can_auth && wo->neg_chap) { - can_auth = have_chap_secret((explicit_remote? remote_name: NULL), - our_name, 1, &lacks_ip); - } - - if (auth_required && !can_auth && noauth_addrs == NULL) { - if (default_auth) { - option_error( -"By default the remote system is required to authenticate itself"); - option_error( -"(because this system has a default route to the internet)"); - } else if (explicit_remote) - option_error( -"The remote system (%s) is required to authenticate itself", - remote_name); - else - option_error( -"The remote system is required to authenticate itself"); - option_error( -"but I couldn't find any suitable secret (password) for it to use to do so."); - if (lacks_ip) - option_error( -"(None of the available passwords would let it use an IP address.)"); - - exit(1); - } -} - -/* - * auth_reset - called when LCP is starting negotiations to recheck - * authentication options, i.e. whether we have appropriate secrets - * to use for authenticating ourselves and/or the peer. - */ -void -auth_reset(unit) - int unit; -{ - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ao = &lcp_allowoptions[0]; - - ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); - ao->neg_chap = !refuse_chap - && (passwd[0] != 0 - || have_chap_secret(user, (explicit_remote? remote_name: NULL), - 0, NULL)); - - if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) - go->neg_upap = 0; - if (go->neg_chap) { - if (!have_chap_secret((explicit_remote? remote_name: NULL), - our_name, 1, NULL)) - go->neg_chap = 0; - } -} - - -/* - * check_passwd - Check the user name and passwd against the PAP secrets - * file. If requested, also check against the system password database, - * and login the user if OK. - * - * returns: - * UPAP_AUTHNAK: Authentication failed. - * UPAP_AUTHACK: Authentication succeeded. - * In either case, msg points to an appropriate message. - */ -int -check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) - int unit; - char *auser; - int userlen; - char *apasswd; - int passwdlen; - char **msg; -{ - int ret; - char *filename; - FILE *f; - struct wordlist *addrs = NULL, *opts = NULL; - char passwd[256], user[256]; - char secret[MAXWORDLEN]; - static int attempts = 0; - - /* - * Make copies of apasswd and auser, then null-terminate them. - * If there are unprintable characters in the password, make - * them visible. - */ - slprintf(passwd, sizeof(passwd), "%.*v", passwdlen, apasswd); - slprintf(user, sizeof(user), "%.*v", userlen, auser); - *msg = ""; - - /* - * Check if a plugin wants to handle this. - */ - if (pap_auth_hook) { - ret = (*pap_auth_hook)(user, passwd, msg, &addrs, &opts); - if (ret >= 0) { - if (ret) - set_allowed_addrs(unit, addrs, opts); - BZERO(passwd, sizeof(passwd)); - if (addrs != 0) - free_wordlist(addrs); - return ret? UPAP_AUTHACK: UPAP_AUTHNAK; - } - } - - /* - * Open the file of pap secrets and scan for a suitable secret - * for authenticating this user. - */ - filename = _PATH_UPAPFILE; - addrs = opts = NULL; - ret = UPAP_AUTHNAK; - f = fopen(filename, "r"); - if (f == NULL) { - error("Can't open PAP password file %s: %m", filename); - - } else { - check_access(f, filename); - if (scan_authfile(f, user, our_name, secret, &addrs, &opts, filename) < 0) { - warn("no PAP secret found for %s", user); - } else { - /* - * If the secret is "@login", it means to check - * the password against the login database. - */ - int login_secret = strcmp(secret, "@login") == 0; - ret = UPAP_AUTHACK; - if (uselogin || login_secret) { - /* login option or secret is @login */ - ret = plogin(user, passwd, msg); - if (ret == UPAP_AUTHNAK) - warn("PAP login failure for %s", user); - else - used_login = 1; - } - if (secret[0] != 0 && !login_secret) { - /* password given in pap-secrets - must match */ - if ((cryptpap || strcmp(passwd, secret) != 0) - && strcmp(crypt(passwd, secret), secret) != 0) { - ret = UPAP_AUTHNAK; - warn("PAP authentication failure for %s", user); - } - } - } - fclose(f); - } - - if (ret == UPAP_AUTHNAK) { - if (**msg == 0) - *msg = "Login incorrect"; - /* - * XXX can we ever get here more than once?? - * Frustrate passwd stealer programs. - * Allow 10 tries, but start backing off after 3 (stolen from login). - * On 10'th, drop the connection. - */ - if (attempts++ >= 10) { - warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user); - lcp_close(unit, "login failed"); - } - if (attempts > 3) - sleep((u_int) (attempts - 3) * 5); - if (opts != NULL) - free_wordlist(opts); - - } else { - attempts = 0; /* Reset count */ - if (**msg == 0) - *msg = "Login ok"; - set_allowed_addrs(unit, addrs, opts); - } - - if (addrs != NULL) - free_wordlist(addrs); - BZERO(passwd, sizeof(passwd)); - BZERO(secret, sizeof(secret)); - - return ret; -} - -/* - * This function is needed for PAM. - */ - -#ifdef USE_PAM -/* Static variables used to communicate between the conversation function - * and the server_login function - */ -static char *PAM_username; -static char *PAM_password; -static int PAM_error = 0; -static pam_handle_t *pamh = NULL; - -/* PAM conversation function - * Here we assume (for now, at least) that echo on means login name, and - * echo off means password. - */ - -static int PAM_conv (int num_msg, const struct pam_message **msg, - struct pam_response **resp, void *appdata_ptr) -{ - int replies = 0; - struct pam_response *reply = NULL; - -#define COPY_STRING(s) (s) ? strdup(s) : NULL - - reply = malloc(sizeof(struct pam_response) * num_msg); - if (!reply) return PAM_CONV_ERR; - - for (replies = 0; replies < num_msg; replies++) { - switch (msg[replies]->msg_style) { - case PAM_PROMPT_ECHO_ON: - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = COPY_STRING(PAM_username); - /* PAM frees resp */ - break; - case PAM_PROMPT_ECHO_OFF: - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = COPY_STRING(PAM_password); - /* PAM frees resp */ - break; - case PAM_TEXT_INFO: - /* fall through */ - case PAM_ERROR_MSG: - /* ignore it, but pam still wants a NULL response... */ - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = NULL; - break; - default: - /* Must be an error of some sort... */ - free (reply); - PAM_error = 1; - return PAM_CONV_ERR; - } - } - *resp = reply; - return PAM_SUCCESS; -} - -static struct pam_conv PAM_conversation = { - &PAM_conv, - NULL -}; -#endif /* USE_PAM */ - -/* - * plogin - Check the user name and password against the system - * password database, and login the user if OK. - * - * returns: - * UPAP_AUTHNAK: Login failed. - * UPAP_AUTHACK: Login succeeded. - * In either case, msg points to an appropriate message. - */ - -static int -plogin(user, passwd, msg) - char *user; - char *passwd; - char **msg; -{ - char *tty; - -#ifdef USE_PAM - int pam_error; - - pam_error = pam_start ("ppp", user, &PAM_conversation, &pamh); - if (pam_error != PAM_SUCCESS) { - *msg = (char *) pam_strerror (pamh, pam_error); - reopen_log(); - return UPAP_AUTHNAK; - } - /* - * Define the fields for the credential validation - */ - - PAM_username = user; - PAM_password = passwd; - PAM_error = 0; - pam_set_item (pamh, PAM_TTY, devnam); /* this might be useful to some modules */ - - /* - * Validate the user - */ - pam_error = pam_authenticate (pamh, PAM_SILENT); - if (pam_error == PAM_SUCCESS && !PAM_error) { - pam_error = pam_acct_mgmt (pamh, PAM_SILENT); - if (pam_error == PAM_SUCCESS) - pam_error = pam_open_session (pamh, PAM_SILENT); - } - - *msg = (char *) pam_strerror (pamh, pam_error); - - /* - * Clean up the mess - */ - reopen_log(); /* apparently the PAM stuff does closelog() */ - PAM_username = NULL; - PAM_password = NULL; - if (pam_error != PAM_SUCCESS) - return UPAP_AUTHNAK; -#else /* #ifdef USE_PAM */ - -/* - * Use the non-PAM methods directly - */ - -#ifdef HAS_SHADOW - struct spwd *spwd; - struct spwd *getspnam(); -#endif - struct passwd *pw = getpwnam(user); - - endpwent(); - if (pw == NULL) - return (UPAP_AUTHNAK); - -#ifdef HAS_SHADOW - spwd = getspnam(user); - endspent(); - if (spwd) { - /* check the age of the password entry */ - long now = time(NULL) / 86400L; - - if ((spwd->sp_expire > 0 && now >= spwd->sp_expire) - || ((spwd->sp_max >= 0 && spwd->sp_max < 10000) - && spwd->sp_lstchg >= 0 - && now >= spwd->sp_lstchg + spwd->sp_max)) { - warn("Password for %s has expired", user); - return (UPAP_AUTHNAK); - } - pw->pw_passwd = spwd->sp_pwdp; - } -#endif - - /* - * If no passwd, don't let them login. - */ - if (pw->pw_passwd == NULL || strlen(pw->pw_passwd) < 2 - || strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd) != 0) - return (UPAP_AUTHNAK); - -#endif /* #ifdef USE_PAM */ - - /* - * Write a wtmp entry for this user. - */ - - tty = devnam; - if (strncmp(tty, "/dev/", 5) == 0) - tty += 5; -// logwtmp(tty, user, remote_name); /* Add wtmp login entry */ - -#if defined(_PATH_LASTLOG) && !defined(USE_PAM) - if (pw != (struct passwd *)NULL) { - struct lastlog ll; - int fd; - - if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) { - (void)lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET); - memset((void *)&ll, 0, sizeof(ll)); - (void)time(&ll.ll_time); - (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); - (void)write(fd, (char *)&ll, sizeof(ll)); - (void)close(fd); - } - } -#endif /* _PATH_LASTLOG and not USE_PAM */ - - info("user %s logged in", user); - logged_in = 1; - - return (UPAP_AUTHACK); -} - -/* - * plogout - Logout the user. - */ -static void -plogout() -{ -#ifdef USE_PAM - int pam_error; - - if (pamh != NULL) { - pam_error = pam_close_session (pamh, PAM_SILENT); - pam_end (pamh, pam_error); - pamh = NULL; - } - /* Apparently the pam stuff does closelog(). */ - reopen_log(); -#else /* ! USE_PAM */ - char *tty; - - tty = devnam; - if (strncmp(tty, "/dev/", 5) == 0) - tty += 5; -// logwtmp(tty, "", ""); /* Wipe out utmp logout entry */ -#endif /* ! USE_PAM */ - logged_in = 0; -} - - -/* - * null_login - Check if a username of "" and a password of "" are - * acceptable, and iff so, set the list of acceptable IP addresses - * and return 1. - */ -static int -null_login(unit) - int unit; -{ - char *filename; - FILE *f; - int i, ret; - struct wordlist *addrs, *opts; - char secret[MAXWORDLEN]; - - /* - * Open the file of pap secrets and scan for a suitable secret. - */ - filename = _PATH_UPAPFILE; - addrs = NULL; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - check_access(f, filename); - - i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename); - ret = i >= 0 && secret[0] == 0; - BZERO(secret, sizeof(secret)); - - if (ret) - set_allowed_addrs(unit, addrs, opts); - else if (opts != 0) - free_wordlist(opts); - if (addrs != 0) - free_wordlist(addrs); - - fclose(f); - return ret; -} - - -/* - * get_pap_passwd - get a password for authenticating ourselves with - * our peer using PAP. Returns 1 on success, 0 if no suitable password - * could be found. - * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null). - */ -static int -get_pap_passwd(passwd) - char *passwd; -{ - char *filename; - FILE *f; - int ret; - char secret[MAXWORDLEN]; - - /* - * Check whether a plugin wants to supply this. - */ - if (pap_passwd_hook) { - ret = (*pap_passwd_hook)(user, passwd); - if (ret >= 0) - return ret; - } - - filename = _PATH_UPAPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - check_access(f, filename); - ret = scan_authfile(f, user, - (remote_name[0]? remote_name: NULL), - secret, NULL, NULL, filename); - fclose(f); - if (ret < 0) - return 0; - if (passwd != NULL) - strlcpy(passwd, secret, MAXSECRETLEN); - BZERO(secret, sizeof(secret)); - return 1; -} - - -/* - * have_pap_secret - check whether we have a PAP file with any - * secrets that we could possibly use for authenticating the peer. - */ -static int -have_pap_secret(lacks_ipp) - int *lacks_ipp; -{ - FILE *f; - int ret; - char *filename; - struct wordlist *addrs; - - /* let the plugin decide, if there is one */ - if (pap_check_hook) { - ret = (*pap_check_hook)(); - if (ret >= 0) - return ret; - } - - filename = _PATH_UPAPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - - ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name, - NULL, &addrs, NULL, filename); - fclose(f); - if (ret >= 0 && !some_ip_ok(addrs)) { - if (lacks_ipp != 0) - *lacks_ipp = 1; - ret = -1; - } - if (addrs != 0) - free_wordlist(addrs); - - return ret >= 0; -} - - -/* - * have_chap_secret - check whether we have a CHAP file with a - * secret that we could possibly use for authenticating `client' - * on `server'. Either can be the null string, meaning we don't - * know the identity yet. - */ -static int -have_chap_secret(client, server, need_ip, lacks_ipp) - char *client; - char *server; - int need_ip; - int *lacks_ipp; -{ - FILE *f; - int ret; - char *filename; - struct wordlist *addrs; - - filename = _PATH_CHAPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - - if (client != NULL && client[0] == 0) - client = NULL; - else if (server != NULL && server[0] == 0) - server = NULL; - - ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename); - fclose(f); - if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { - if (lacks_ipp != 0) - *lacks_ipp = 1; - ret = -1; - } - if (addrs != 0) - free_wordlist(addrs); - - return ret >= 0; -} - - -/* - * get_secret - open the CHAP secret file and return the secret - * for authenticating the given client on the given server. - * (We could be either client or server). - */ -int -get_secret(unit, client, server, secret, secret_len, am_server) - int unit; - char *client; - char *server; - char *secret; - int *secret_len; - int am_server; -{ - FILE *f; - int ret, len; - char *filename; - struct wordlist *addrs, *opts; - char secbuf[MAXWORDLEN]; - - if (!am_server && passwd[0] != 0) { - strlcpy(secbuf, passwd, sizeof(secbuf)); - } else { - filename = _PATH_CHAPFILE; - addrs = NULL; - secbuf[0] = 0; - - f = fopen(filename, "r"); - if (f == NULL) { - error("Can't open chap secret file %s: %m", filename); - return 0; - } - check_access(f, filename); - - ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename); - fclose(f); - if (ret < 0) - return 0; - - if (am_server) - set_allowed_addrs(unit, addrs, opts); - else if (opts != 0) - free_wordlist(opts); - if (addrs != 0) - free_wordlist(addrs); - } - - len = strlen(secbuf); - if (len > MAXSECRETLEN) { - error("Secret for %s on %s is too long", client, server); - len = MAXSECRETLEN; - } - BCOPY(secbuf, secret, len); - BZERO(secbuf, sizeof(secbuf)); - *secret_len = len; - - return 1; -} - -/* - * set_allowed_addrs() - set the list of allowed addresses. - * Also looks for `--' indicating options to apply for this peer - * and leaves the following words in extra_options. - */ -static void -set_allowed_addrs(unit, addrs, opts) - int unit; - struct wordlist *addrs; - struct wordlist *opts; -{ - int n; - struct wordlist *ap, **plink; - struct permitted_ip *ip; - char *ptr_word, *ptr_mask; - struct hostent *hp; - u_int32_t a, mask, offset; - struct ipcp_options *wo = &ipcp_wantoptions[unit]; - u_int32_t suggested_ip = 0; - - if (addresses[unit] != NULL) - free(addresses[unit]); - addresses[unit] = NULL; - if (extra_options != NULL) - free_wordlist(extra_options); - extra_options = opts; - - /* - * Count the number of IP addresses given. - */ - n = wordlist_count(addrs) + wordlist_count(noauth_addrs); - if (n == 0) - return; - ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip)); - if (ip == 0) - return; - - /* temporarily append the noauth_addrs list to addrs */ - for (plink = &addrs; *plink != NULL; plink = &(*plink)->next) - ; - *plink = noauth_addrs; - - n = 0; - for (ap = addrs; ap != NULL; ap = ap->next) { - /* "-" means no addresses authorized, "*" means any address allowed */ - ptr_word = ap->word; - if (strcmp(ptr_word, "-") == 0) - break; - if (strcmp(ptr_word, "*") == 0) { - ip[n].permit = 1; - ip[n].base = ip[n].mask = 0; - ++n; - break; - } - - ip[n].permit = 1; - if (*ptr_word == '!') { - ip[n].permit = 0; - ++ptr_word; - } - - mask = ~ (u_int32_t) 0; - offset = 0; - ptr_mask = strchr (ptr_word, '/'); - if (ptr_mask != NULL) { - int bit_count; - char *endp; - - bit_count = (int) strtol (ptr_mask+1, &endp, 10); - if (bit_count <= 0 || bit_count > 32) { - warn("invalid address length %v in auth. address list", - ptr_mask+1); - continue; - } - bit_count = 32 - bit_count; /* # bits in host part */ - if (*endp == '+') { - offset = ifunit + 1; - ++endp; - } - if (*endp != 0) { - warn("invalid address length syntax: %v", ptr_mask+1); - continue; - } - *ptr_mask = '\0'; - mask <<= bit_count; - } - - hp = gethostbyname(ptr_word); - if (hp != NULL && hp->h_addrtype == AF_INET) { - a = *(u_int32_t *)hp->h_addr; - } else { - printf("*** getnetbyname is unsupported, please report bug! ***\n"); - return; - } - - if (ptr_mask != NULL) - *ptr_mask = '/'; - - if (a == (u_int32_t)-1L) { - warn("unknown host %s in auth. address list", ap->word); - continue; - } - if (offset != 0) { - if (offset >= ~mask) { - warn("interface unit %d too large for subnet %v", - ifunit, ptr_word); - continue; - } - a = htonl((ntohl(a) & mask) + offset); - mask = ~(u_int32_t)0; - } - ip[n].mask = htonl(mask); - ip[n].base = a & ip[n].mask; - ++n; - if (~mask == 0 && suggested_ip == 0) - suggested_ip = a; - } - *plink = NULL; - - ip[n].permit = 0; /* make the last entry forbid all addresses */ - ip[n].base = 0; /* to terminate the list */ - ip[n].mask = 0; - - addresses[unit] = ip; - - /* - * If the address given for the peer isn't authorized, or if - * the user hasn't given one, AND there is an authorized address - * which is a single host, then use that if we find one. - */ - if (suggested_ip != 0 - && (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr))) { - wo->hisaddr = suggested_ip; - /* - * Do we insist on this address? No, if there are other - * addresses authorized than the suggested one. - */ - if (n > 1) - wo->accept_remote = 1; - } -} - -/* - * auth_ip_addr - check whether the peer is authorized to use - * a given IP address. Returns 1 if authorized, 0 otherwise. - */ -int -auth_ip_addr(unit, addr) - int unit; - u_int32_t addr; -{ - int ok; - - /* don't allow loopback or multicast address */ - if (bad_ip_adrs(addr)) - return 0; - - if (addresses[unit] != NULL) { - ok = ip_addr_check(addr, addresses[unit]); - if (ok >= 0) - return ok; - } - if (auth_required) - return 0; /* no addresses authorized */ - return allow_any_ip || privileged || !have_route_to(addr); -} - -static int -ip_addr_check(addr, addrs) - u_int32_t addr; - struct permitted_ip *addrs; -{ - for (; ; ++addrs) - if ((addr & addrs->mask) == addrs->base) - return addrs->permit; -} - -/* - * bad_ip_adrs - return 1 if the IP address is one we don't want - * to use, such as an address in the loopback net or a multicast address. - * addr is in network byte order. - */ -int -bad_ip_adrs(addr) - u_int32_t addr; -{ - addr = ntohl(addr); - return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET - || IN_MULTICAST(addr) || IN_BADCLASS(addr); -} - -/* - * some_ip_ok - check a wordlist to see if it authorizes any - * IP address(es). - */ -static int -some_ip_ok(addrs) - struct wordlist *addrs; -{ - for (; addrs != 0; addrs = addrs->next) { - if (addrs->word[0] == '-') - break; - if (addrs->word[0] != '!') - return 1; /* some IP address is allowed */ - } - return 0; -} - -/* - * check_access - complain if a secret file has too-liberal permissions. - */ -static void -check_access(f, filename) - FILE *f; - char *filename; -{ - struct stat sbuf; - - if (fstat(fileno(f), &sbuf) < 0) { - warn("cannot stat secret file %s: %m", filename); - } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { - warn("Warning - secret file %s has world and/or group access", - filename); - } -} - - -/* - * scan_authfile - Scan an authorization file for a secret suitable - * for authenticating `client' on `server'. The return value is -1 - * if no secret is found, otherwise >= 0. The return value has - * NONWILD_CLIENT set if the secret didn't have "*" for the client, and - * NONWILD_SERVER set if the secret didn't have "*" for the server. - * Any following words on the line up to a "--" (i.e. address authorization - * info) are placed in a wordlist and returned in *addrs. Any - * following words (extra options) are placed in a wordlist and - * returned in *opts. - * We assume secret is NULL or points to MAXWORDLEN bytes of space. - */ -static int -scan_authfile(f, client, server, secret, addrs, opts, filename) - FILE *f; - char *client; - char *server; - char *secret; - struct wordlist **addrs; - struct wordlist **opts; - char *filename; -{ - int newline, xxx; - int got_flag, best_flag; - FILE *sf; - struct wordlist *ap, *addr_list, *alist, **app; - char word[MAXWORDLEN]; - char atfile[MAXWORDLEN]; - char lsecret[MAXWORDLEN]; - - if (addrs != NULL) - *addrs = NULL; - if (opts != NULL) - *opts = NULL; - addr_list = NULL; - if (!getword(f, word, &newline, filename)) - return -1; /* file is empty??? */ - newline = 1; - best_flag = -1; - for (;;) { - /* - * Skip until we find a word at the start of a line. - */ - while (!newline && getword(f, word, &newline, filename)) - ; - if (!newline) - break; /* got to end of file */ - - /* - * Got a client - check if it's a match or a wildcard. - */ - got_flag = 0; - if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { - newline = 0; - continue; - } - if (!ISWILD(word)) - got_flag = NONWILD_CLIENT; - - /* - * Now get a server and check if it matches. - */ - if (!getword(f, word, &newline, filename)) - break; - if (newline) - continue; - if (!ISWILD(word)) { - if (server != NULL && strcmp(word, server) != 0) - continue; - got_flag |= NONWILD_SERVER; - } - - /* - * Got some sort of a match - see if it's better than what - * we have already. - */ - if (got_flag <= best_flag) - continue; - - /* - * Get the secret. - */ - if (!getword(f, word, &newline, filename)) - break; - if (newline) - continue; - - if (secret != NULL) { - /* - * Special syntax: @/pathname means read secret from file. - */ - if (word[0] == '@' && word[1] == '/') { - strlcpy(atfile, word+1, sizeof(atfile)); - if ((sf = fopen(atfile, "r")) == NULL) { - warn("can't open indirect secret file %s", atfile); - continue; - } - check_access(sf, atfile); - if (!getword(sf, word, &xxx, atfile)) { - warn("no secret in indirect secret file %s", atfile); - fclose(sf); - continue; - } - fclose(sf); - } - strlcpy(lsecret, word, sizeof(lsecret)); - } - - /* - * Now read address authorization info and make a wordlist. - */ - app = &alist; - for (;;) { - if (!getword(f, word, &newline, filename) || newline) - break; - ap = (struct wordlist *) - malloc(sizeof(struct wordlist) + strlen(word) + 1); - if (ap == NULL) - novm("authorized addresses"); - ap->word = (char *) (ap + 1); - strcpy(ap->word, word); - *app = ap; - app = &ap->next; - } - *app = NULL; - - /* - * This is the best so far; remember it. - */ - best_flag = got_flag; - if (addr_list) - free_wordlist(addr_list); - addr_list = alist; - if (secret != NULL) - strlcpy(secret, lsecret, MAXWORDLEN); - - if (!newline) - break; - } - - /* scan for a -- word indicating the start of options */ - for (app = &addr_list; (ap = *app) != NULL; app = &ap->next) - if (strcmp(ap->word, "--") == 0) - break; - /* ap = start of options */ - if (ap != NULL) { - ap = ap->next; /* first option */ - free(*app); /* free the "--" word */ - *app = NULL; /* terminate addr list */ - } - if (opts != NULL) - *opts = ap; - else if (ap != NULL) - free_wordlist(ap); - if (addrs != NULL) - *addrs = addr_list; - else if (addr_list != NULL) - free_wordlist(addr_list); - - return best_flag; -} - -/* - * wordlist_count - return the number of items in a wordlist - */ -static int -wordlist_count(wp) - struct wordlist *wp; -{ - int n; - - for (n = 0; wp != NULL; wp = wp->next) - ++n; - return n; -} - -/* - * free_wordlist - release memory allocated for a wordlist. - */ -static void -free_wordlist(wp) - struct wordlist *wp; -{ - struct wordlist *next; - - while (wp != NULL) { - next = wp->next; - free(wp); - wp = next; - } -} - -/* - * auth_script_done - called when the auth-up or auth-down script - * has finished. - */ -static void -auth_script_done(arg) - void *arg; -{ - auth_script_pid = 0; - switch (auth_script_state) { - case s_up: - if (auth_state == s_down) { - auth_script_state = s_down; - auth_script(_PATH_AUTHDOWN); - } - break; - case s_down: - if (auth_state == s_up) { - auth_script_state = s_up; - auth_script(_PATH_AUTHUP); - } - break; - } -} - -/* - * auth_script - execute a script with arguments - * interface-name peer-name real-user tty speed - */ -static void -auth_script(script) - char *script; -{ - char strspeed[32]; - struct passwd *pw; - char struid[32]; - char *user_name; - char *argv[8]; - - if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL) - user_name = pw->pw_name; - else { - slprintf(struid, sizeof(struid), "%d", getuid()); - user_name = struid; - } - slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); - - argv[0] = script; - argv[1] = ifname; - argv[2] = peer_authname; - argv[3] = user_name; - argv[4] = devnam; - argv[5] = strspeed; - argv[6] = NULL; - - auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL); -} diff --git a/mdk-stage1/ppp/pppd/cbcp.c b/mdk-stage1/ppp/pppd/cbcp.c deleted file mode 100644 index 8c57b3cde..000000000 --- a/mdk-stage1/ppp/pppd/cbcp.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * cbcp - Call Back Configuration Protocol. - * - * Copyright (c) 1995 Pedro Roque Marques - * 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 Pedro Roque Marques. The name of the author 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 RCSID "$Id$" - -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <sys/time.h> - -#include "pppd.h" -#include "cbcp.h" -#include "fsm.h" -#include "lcp.h" - -static const char rcsid[] = RCSID; - -/* - * Options. - */ -static int setcbcp __P((char **)); - -static option_t cbcp_option_list[] = { - { "callback", o_special, setcbcp, - "Ask for callback", OPT_PRIO | OPT_A2STRVAL, &cbcp[0].us_number }, - { NULL } -}; - -/* - * Protocol entry points. - */ -static void cbcp_init __P((int unit)); -static void cbcp_open __P((int unit)); -static void cbcp_lowerup __P((int unit)); -static void cbcp_input __P((int unit, u_char *pkt, int len)); -static void cbcp_protrej __P((int unit)); -static int cbcp_printpkt __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); - -struct protent cbcp_protent = { - PPP_CBCP, - cbcp_init, - cbcp_input, - cbcp_protrej, - cbcp_lowerup, - NULL, - cbcp_open, - NULL, - cbcp_printpkt, - NULL, - 0, - "CBCP", - NULL, - cbcp_option_list, - NULL, - NULL, - NULL -}; - -cbcp_state cbcp[NUM_PPP]; - -/* internal prototypes */ - -static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len)); -static void cbcp_resp __P((cbcp_state *us)); -static void cbcp_up __P((cbcp_state *us)); -static void cbcp_recvack __P((cbcp_state *us, char *pckt, int len)); -static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len)); - -/* option processing */ -static int -setcbcp(argv) - char **argv; -{ - lcp_wantoptions[0].neg_cbcp = 1; - cbcp_protent.enabled_flag = 1; - cbcp[0].us_number = strdup(*argv); - if (cbcp[0].us_number == 0) - novm("callback number"); - cbcp[0].us_type |= (1 << CB_CONF_USER); - cbcp[0].us_type |= (1 << CB_CONF_ADMIN); - return (1); -} - -/* init state */ -static void -cbcp_init(iface) - int iface; -{ - cbcp_state *us; - - us = &cbcp[iface]; - memset(us, 0, sizeof(cbcp_state)); - us->us_unit = iface; - us->us_type |= (1 << CB_CONF_NO); -} - -/* lower layer is up */ -static void -cbcp_lowerup(iface) - int iface; -{ - cbcp_state *us = &cbcp[iface]; - - dbglog("cbcp_lowerup"); - dbglog("want: %d", us->us_type); - - if (us->us_type == CB_CONF_USER) - dbglog("phone no: %s", us->us_number); -} - -static void -cbcp_open(unit) - int unit; -{ - dbglog("cbcp_open"); -} - -/* process an incomming packet */ -static void -cbcp_input(unit, inpacket, pktlen) - int unit; - u_char *inpacket; - int pktlen; -{ - u_char *inp; - u_char code, id; - u_short len; - - cbcp_state *us = &cbcp[unit]; - - inp = inpacket; - - if (pktlen < CBCP_MINLEN) { - error("CBCP packet is too small"); - return; - } - - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - -#if 0 - if (len > pktlen) { - error("CBCP packet: invalid length"); - return; - } -#endif - - len -= CBCP_MINLEN; - - switch(code) { - case CBCP_REQ: - us->us_id = id; - cbcp_recvreq(us, inp, len); - break; - - case CBCP_RESP: - dbglog("CBCP_RESP received"); - break; - - case CBCP_ACK: - if (id != us->us_id) - dbglog("id doesn't match: expected %d recv %d", - us->us_id, id); - - cbcp_recvack(us, inp, len); - break; - - default: - break; - } -} - -/* protocol was rejected by foe */ -void cbcp_protrej(int iface) -{ -} - -char *cbcp_codenames[] = { - "Request", "Response", "Ack" -}; - -char *cbcp_optionnames[] = { - "NoCallback", - "UserDefined", - "AdminDefined", - "List" -}; - -/* pretty print a packet */ -static int -cbcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int code, opt, id, len, olen, delay; - u_char *pstart; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(cbcp_codenames) / sizeof(char *)) - printer(arg, " %s", cbcp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - - switch (code) { - case CBCP_REQ: - case CBCP_RESP: - case CBCP_ACK: - while(len >= 2) { - GETCHAR(opt, p); - GETCHAR(olen, p); - - if (olen < 2 || olen > len) { - break; - } - - printer(arg, " <"); - len -= olen; - - if (opt >= 1 && opt <= sizeof(cbcp_optionnames) / sizeof(char *)) - printer(arg, " %s", cbcp_optionnames[opt-1]); - else - printer(arg, " option=0x%x", opt); - - if (olen > 2) { - GETCHAR(delay, p); - printer(arg, " delay = %d", delay); - } - - if (olen > 3) { - int addrt; - char str[256]; - - GETCHAR(addrt, p); - memcpy(str, p, olen - 4); - str[olen - 4] = 0; - printer(arg, " number = %s", str); - } - printer(arg, ">"); - break; - } - - default: - break; - } - - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} - -/* received CBCP request */ -static void -cbcp_recvreq(us, pckt, pcktlen) - cbcp_state *us; - char *pckt; - int pcktlen; -{ - u_char type, opt_len, delay, addr_type; - char address[256]; - int len = pcktlen; - - address[0] = 0; - - while (len) { - dbglog("length: %d", len); - - GETCHAR(type, pckt); - GETCHAR(opt_len, pckt); - - if (opt_len > 2) - GETCHAR(delay, pckt); - - us->us_allowed |= (1 << type); - - switch(type) { - case CB_CONF_NO: - dbglog("no callback allowed"); - break; - - case CB_CONF_USER: - dbglog("user callback allowed"); - if (opt_len > 4) { - GETCHAR(addr_type, pckt); - memcpy(address, pckt, opt_len - 4); - address[opt_len - 4] = 0; - if (address[0]) - dbglog("address: %s", address); - } - break; - - case CB_CONF_ADMIN: - dbglog("user admin defined allowed"); - break; - - case CB_CONF_LIST: - break; - } - len -= opt_len; - } - - cbcp_resp(us); -} - -static void -cbcp_resp(us) - cbcp_state *us; -{ - u_char cb_type; - u_char buf[256]; - u_char *bufp = buf; - int len = 0; - - cb_type = us->us_allowed & us->us_type; - dbglog("cbcp_resp cb_type=%d", cb_type); - -#if 0 - if (!cb_type) - lcp_down(us->us_unit); -#endif - - if (cb_type & ( 1 << CB_CONF_USER ) ) { - dbglog("cbcp_resp CONF_USER"); - PUTCHAR(CB_CONF_USER, bufp); - len = 3 + 1 + strlen(us->us_number) + 1; - PUTCHAR(len , bufp); - PUTCHAR(5, bufp); /* delay */ - PUTCHAR(1, bufp); - BCOPY(us->us_number, bufp, strlen(us->us_number) + 1); - cbcp_send(us, CBCP_RESP, buf, len); - return; - } - - if (cb_type & ( 1 << CB_CONF_ADMIN ) ) { - dbglog("cbcp_resp CONF_ADMIN"); - PUTCHAR(CB_CONF_ADMIN, bufp); - len = 3; - PUTCHAR(len, bufp); - PUTCHAR(5, bufp); /* delay */ - cbcp_send(us, CBCP_RESP, buf, len); - return; - } - - if (cb_type & ( 1 << CB_CONF_NO ) ) { - dbglog("cbcp_resp CONF_NO"); - PUTCHAR(CB_CONF_NO, bufp); - len = 3; - PUTCHAR(len , bufp); - PUTCHAR(0, bufp); - cbcp_send(us, CBCP_RESP, buf, len); - start_networks(); - return; - } -} - -static void -cbcp_send(us, code, buf, len) - cbcp_state *us; - u_char code; - u_char *buf; - int len; -{ - u_char *outp; - int outlen; - - outp = outpacket_buf; - - outlen = 4 + len; - - MAKEHEADER(outp, PPP_CBCP); - - PUTCHAR(code, outp); - PUTCHAR(us->us_id, outp); - PUTSHORT(outlen, outp); - - if (len) - BCOPY(buf, outp, len); - - output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN); -} - -static void -cbcp_recvack(us, pckt, len) - cbcp_state *us; - char *pckt; - int len; -{ - u_char type, delay, addr_type; - int opt_len; - char address[256]; - - if (len) { - GETCHAR(type, pckt); - GETCHAR(opt_len, pckt); - - if (opt_len > 2) - GETCHAR(delay, pckt); - - if (opt_len > 4) { - GETCHAR(addr_type, pckt); - memcpy(address, pckt, opt_len - 4); - address[opt_len - 4] = 0; - if (address[0]) - dbglog("peer will call: %s", address); - } - if (type == CB_CONF_NO) - return; - } - - cbcp_up(us); -} - -/* ok peer will do callback */ -static void -cbcp_up(us) - cbcp_state *us; -{ - persist = 0; - lcp_close(0, "Call me back, please"); - status = EXIT_CALLBACK; -} diff --git a/mdk-stage1/ppp/pppd/cbcp.h b/mdk-stage1/ppp/pppd/cbcp.h deleted file mode 100644 index c2ab3f689..000000000 --- a/mdk-stage1/ppp/pppd/cbcp.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef CBCP_H -#define CBCP_H - -typedef struct cbcp_state { - int us_unit; /* Interface unit number */ - u_char us_id; /* Current id */ - u_char us_allowed; - int us_type; - char *us_number; /* Telefone Number */ -} cbcp_state; - -extern cbcp_state cbcp[]; - -extern struct protent cbcp_protent; - -#define CBCP_MINLEN 4 - -#define CBCP_REQ 1 -#define CBCP_RESP 2 -#define CBCP_ACK 3 - -#define CB_CONF_NO 1 -#define CB_CONF_USER 2 -#define CB_CONF_ADMIN 3 -#define CB_CONF_LIST 4 -#endif diff --git a/mdk-stage1/ppp/pppd/ccp.c b/mdk-stage1/ppp/pppd/ccp.c deleted file mode 100644 index 7e36e384e..000000000 --- a/mdk-stage1/ppp/pppd/ccp.c +++ /dev/null @@ -1,1257 +0,0 @@ -/* - * ccp.c - PPP Compression Control Protocol. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - */ - -#define RCSID "$Id$" - -#include <stdlib.h> -#include <string.h> - -#include "pppd.h" -#include "fsm.h" -#include "ccp.h" -#include <net/ppp-comp.h> - -static const char rcsid[] = RCSID; - -/* - * Unfortunately there is a bug in zlib which means that using a - * size of 8 (window size = 256) for Deflate compression will cause - * buffer overruns and kernel crashes in the deflate module. - * Until this is fixed we only accept sizes in the range 9 .. 15. - * Thanks to James Carlson for pointing this out. - */ -#define DEFLATE_MIN_WORKS 9 - -/* - * Command-line options. - */ -static int setbsdcomp __P((char **)); -static int setdeflate __P((char **)); -static char bsd_value[8]; -static char deflate_value[8]; - -static option_t ccp_option_list[] = { - { "noccp", o_bool, &ccp_protent.enabled_flag, - "Disable CCP negotiation" }, - { "-ccp", o_bool, &ccp_protent.enabled_flag, - "Disable CCP negotiation", OPT_ALIAS }, - - { "bsdcomp", o_special, (void *)setbsdcomp, - "Request BSD-Compress packet compression", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value }, - { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, - "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].bsd_compress }, - { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, - "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].bsd_compress }, - - { "deflate", o_special, (void *)setdeflate, - "request Deflate compression", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value }, - { "nodeflate", o_bool, &ccp_wantoptions[0].deflate, - "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].deflate }, - { "-deflate", o_bool, &ccp_wantoptions[0].deflate, - "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].deflate }, - - { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft, - "don't use draft deflate #", OPT_A2COPY, - &ccp_allowoptions[0].deflate_draft }, - - { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "request Predictor-1", 1, &ccp_allowoptions[0].predictor_1, OPT_PRIO }, - { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].predictor_1 }, - { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].predictor_1 }, - - { NULL } -}; - -/* - * Protocol entry points from main code. - */ -static void ccp_init __P((int unit)); -static void ccp_open __P((int unit)); -static void ccp_close __P((int unit, char *)); -static void ccp_lowerup __P((int unit)); -static void ccp_lowerdown __P((int)); -static void ccp_input __P((int unit, u_char *pkt, int len)); -static void ccp_protrej __P((int unit)); -static int ccp_printpkt __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); -static void ccp_datainput __P((int unit, u_char *pkt, int len)); - -struct protent ccp_protent = { - PPP_CCP, - ccp_init, - ccp_input, - ccp_protrej, - ccp_lowerup, - ccp_lowerdown, - ccp_open, - ccp_close, - ccp_printpkt, - ccp_datainput, - 1, - "CCP", - "Compressed", - ccp_option_list, - NULL, - NULL, - NULL -}; - -fsm ccp_fsm[NUM_PPP]; -ccp_options ccp_wantoptions[NUM_PPP]; /* what to request the peer to use */ -ccp_options ccp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ -ccp_options ccp_allowoptions[NUM_PPP]; /* what we'll agree to do */ -ccp_options ccp_hisoptions[NUM_PPP]; /* what we agreed to do */ - -/* - * Callbacks for fsm code. - */ -static void ccp_resetci __P((fsm *)); -static int ccp_cilen __P((fsm *)); -static void ccp_addci __P((fsm *, u_char *, int *)); -static int ccp_ackci __P((fsm *, u_char *, int)); -static int ccp_nakci __P((fsm *, u_char *, int)); -static int ccp_rejci __P((fsm *, u_char *, int)); -static int ccp_reqci __P((fsm *, u_char *, int *, int)); -static void ccp_up __P((fsm *)); -static void ccp_down __P((fsm *)); -static int ccp_extcode __P((fsm *, int, int, u_char *, int)); -static void ccp_rack_timeout __P((void *)); -static char *method_name __P((ccp_options *, ccp_options *)); - -static fsm_callbacks ccp_callbacks = { - ccp_resetci, - ccp_cilen, - ccp_addci, - ccp_ackci, - ccp_nakci, - ccp_rejci, - ccp_reqci, - ccp_up, - ccp_down, - NULL, - NULL, - NULL, - NULL, - ccp_extcode, - "CCP" -}; - -/* - * Do we want / did we get any compression? - */ -#define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \ - || (opt).predictor_1 || (opt).predictor_2) - -/* - * Local state (mainly for handling reset-reqs and reset-acks). - */ -static int ccp_localstate[NUM_PPP]; -#define RACK_PENDING 1 /* waiting for reset-ack */ -#define RREQ_REPEAT 2 /* send another reset-req if no reset-ack */ - -#define RACKTIMEOUT 1 /* second */ - -static int all_rejected[NUM_PPP]; /* we rejected all peer's options */ - -/* - * Option parsing. - */ -static int -setbsdcomp(argv) - char **argv; -{ - int rbits, abits; - char *str, *endp; - - str = *argv; - abits = rbits = strtol(str, &endp, 0); - if (endp != str && *endp == ',') { - str = endp + 1; - abits = strtol(str, &endp, 0); - } - if (*endp != 0 || endp == str) { - option_error("invalid parameter '%s' for bsdcomp option", *argv); - return 0; - } - if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS)) - || (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) { - option_error("bsdcomp option values must be 0 or %d .. %d", - BSD_MIN_BITS, BSD_MAX_BITS); - return 0; - } - if (rbits > 0) { - ccp_wantoptions[0].bsd_compress = 1; - ccp_wantoptions[0].bsd_bits = rbits; - } else - ccp_wantoptions[0].bsd_compress = 0; - if (abits > 0) { - ccp_allowoptions[0].bsd_compress = 1; - ccp_allowoptions[0].bsd_bits = abits; - } else - ccp_allowoptions[0].bsd_compress = 0; - slprintf(bsd_value, sizeof(bsd_value), - rbits == abits? "%d": "%d,%d", rbits, abits); - - return 1; -} - -static int -setdeflate(argv) - char **argv; -{ - int rbits, abits; - char *str, *endp; - - str = *argv; - abits = rbits = strtol(str, &endp, 0); - if (endp != str && *endp == ',') { - str = endp + 1; - abits = strtol(str, &endp, 0); - } - if (*endp != 0 || endp == str) { - option_error("invalid parameter '%s' for deflate option", *argv); - return 0; - } - if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE)) - || (abits != 0 && (abits < DEFLATE_MIN_SIZE - || abits > DEFLATE_MAX_SIZE))) { - option_error("deflate option values must be 0 or %d .. %d", - DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE); - return 0; - } - if (rbits == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) { - if (rbits == DEFLATE_MIN_SIZE) - rbits = DEFLATE_MIN_WORKS; - if (abits == DEFLATE_MIN_SIZE) - abits = DEFLATE_MIN_WORKS; - warn("deflate option value of %d changed to %d to avoid zlib bug", - DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS); - } - if (rbits > 0) { - ccp_wantoptions[0].deflate = 1; - ccp_wantoptions[0].deflate_size = rbits; - } else - ccp_wantoptions[0].deflate = 0; - if (abits > 0) { - ccp_allowoptions[0].deflate = 1; - ccp_allowoptions[0].deflate_size = abits; - } else - ccp_allowoptions[0].deflate = 0; - slprintf(deflate_value, sizeof(deflate_value), - rbits == abits? "%d": "%d,%d", rbits, abits); - - return 1; -} - -/* - * ccp_init - initialize CCP. - */ -static void -ccp_init(unit) - int unit; -{ - fsm *f = &ccp_fsm[unit]; - - f->unit = unit; - f->protocol = PPP_CCP; - f->callbacks = &ccp_callbacks; - fsm_init(f); - - memset(&ccp_wantoptions[unit], 0, sizeof(ccp_options)); - memset(&ccp_gotoptions[unit], 0, sizeof(ccp_options)); - memset(&ccp_allowoptions[unit], 0, sizeof(ccp_options)); - memset(&ccp_hisoptions[unit], 0, sizeof(ccp_options)); - - ccp_wantoptions[0].deflate = 1; - ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE; - ccp_wantoptions[0].deflate_correct = 1; - ccp_wantoptions[0].deflate_draft = 1; - ccp_allowoptions[0].deflate = 1; - ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE; - ccp_allowoptions[0].deflate_correct = 1; - ccp_allowoptions[0].deflate_draft = 1; - - ccp_wantoptions[0].bsd_compress = 1; - ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS; - ccp_allowoptions[0].bsd_compress = 1; - ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS; - - ccp_allowoptions[0].predictor_1 = 1; -} - -/* - * ccp_open - CCP is allowed to come up. - */ -static void -ccp_open(unit) - int unit; -{ - fsm *f = &ccp_fsm[unit]; - - if (f->state != OPENED) - ccp_flags_set(unit, 1, 0); - - /* - * Find out which compressors the kernel supports before - * deciding whether to open in silent mode. - */ - ccp_resetci(f); - if (!ANY_COMPRESS(ccp_gotoptions[unit])) - f->flags |= OPT_SILENT; - - fsm_open(f); -} - -/* - * ccp_close - Terminate CCP. - */ -static void -ccp_close(unit, reason) - int unit; - char *reason; -{ - ccp_flags_set(unit, 0, 0); - fsm_close(&ccp_fsm[unit], reason); -} - -/* - * ccp_lowerup - we may now transmit CCP packets. - */ -static void -ccp_lowerup(unit) - int unit; -{ - fsm_lowerup(&ccp_fsm[unit]); -} - -/* - * ccp_lowerdown - we may not transmit CCP packets. - */ -static void -ccp_lowerdown(unit) - int unit; -{ - fsm_lowerdown(&ccp_fsm[unit]); -} - -/* - * ccp_input - process a received CCP packet. - */ -static void -ccp_input(unit, p, len) - int unit; - u_char *p; - int len; -{ - fsm *f = &ccp_fsm[unit]; - int oldstate; - - /* - * Check for a terminate-request so we can print a message. - */ - oldstate = f->state; - fsm_input(f, p, len); - if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) - notice("Compression disabled by peer."); - - /* - * If we get a terminate-ack and we're not asking for compression, - * close CCP. - */ - if (oldstate == REQSENT && p[0] == TERMACK - && !ANY_COMPRESS(ccp_gotoptions[unit])) - ccp_close(unit, "No compression negotiated"); -} - -/* - * Handle a CCP-specific code. - */ -static int -ccp_extcode(f, code, id, p, len) - fsm *f; - int code, id; - u_char *p; - int len; -{ - switch (code) { - case CCP_RESETREQ: - if (f->state != OPENED) - break; - /* send a reset-ack, which the transmitter will see and - reset its compression state. */ - fsm_sdata(f, CCP_RESETACK, id, NULL, 0); - break; - - case CCP_RESETACK: - if (ccp_localstate[f->unit] & RACK_PENDING && id == f->reqid) { - ccp_localstate[f->unit] &= ~(RACK_PENDING | RREQ_REPEAT); - UNTIMEOUT(ccp_rack_timeout, f); - } - break; - - default: - return 0; - } - - return 1; -} - -/* - * ccp_protrej - peer doesn't talk CCP. - */ -static void -ccp_protrej(unit) - int unit; -{ - ccp_flags_set(unit, 0, 0); - fsm_lowerdown(&ccp_fsm[unit]); -} - -/* - * ccp_resetci - initialize at start of negotiation. - */ -static void -ccp_resetci(f) - fsm *f; -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - u_char opt_buf[16]; - - *go = ccp_wantoptions[f->unit]; - all_rejected[f->unit] = 0; - - /* - * Check whether the kernel knows about the various - * compression methods we might request. - */ - if (go->bsd_compress) { - opt_buf[0] = CI_BSD_COMPRESS; - opt_buf[1] = CILEN_BSD_COMPRESS; - opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, BSD_MIN_BITS); - if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS, 0) <= 0) - go->bsd_compress = 0; - } - if (go->deflate) { - if (go->deflate_correct) { - opt_buf[0] = CI_DEFLATE; - opt_buf[1] = CILEN_DEFLATE; - opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS); - opt_buf[3] = DEFLATE_CHK_SEQUENCE; - if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) - go->deflate_correct = 0; - } - if (go->deflate_draft) { - opt_buf[0] = CI_DEFLATE_DRAFT; - opt_buf[1] = CILEN_DEFLATE; - opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS); - opt_buf[3] = DEFLATE_CHK_SEQUENCE; - if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) - go->deflate_draft = 0; - } - if (!go->deflate_correct && !go->deflate_draft) - go->deflate = 0; - } - if (go->predictor_1) { - opt_buf[0] = CI_PREDICTOR_1; - opt_buf[1] = CILEN_PREDICTOR_1; - if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_1, 0) <= 0) - go->predictor_1 = 0; - } - if (go->predictor_2) { - opt_buf[0] = CI_PREDICTOR_2; - opt_buf[1] = CILEN_PREDICTOR_2; - if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_2, 0) <= 0) - go->predictor_2 = 0; - } -} - -/* - * ccp_cilen - Return total length of our configuration info. - */ -static int -ccp_cilen(f) - fsm *f; -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - - return (go->bsd_compress? CILEN_BSD_COMPRESS: 0) - + (go->deflate? CILEN_DEFLATE: 0) - + (go->predictor_1? CILEN_PREDICTOR_1: 0) - + (go->predictor_2? CILEN_PREDICTOR_2: 0); -} - -/* - * ccp_addci - put our requests in a packet. - */ -static void -ccp_addci(f, p, lenp) - fsm *f; - u_char *p; - int *lenp; -{ - int res; - ccp_options *go = &ccp_gotoptions[f->unit]; - u_char *p0 = p; - - /* - * Add the compression types that we can receive, in decreasing - * preference order. Get the kernel to allocate the first one - * in case it gets Acked. - */ - if (go->deflate) { - p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT; - p[1] = CILEN_DEFLATE; - p[2] = DEFLATE_MAKE_OPT(go->deflate_size); - p[3] = DEFLATE_CHK_SEQUENCE; - for (;;) { - res = ccp_test(f->unit, p, CILEN_DEFLATE, 0); - if (res > 0) { - p += CILEN_DEFLATE; - break; - } - if (res < 0 || go->deflate_size <= DEFLATE_MIN_WORKS) { - go->deflate = 0; - break; - } - --go->deflate_size; - p[2] = DEFLATE_MAKE_OPT(go->deflate_size); - } - if (p != p0 && go->deflate_correct && go->deflate_draft) { - p[0] = CI_DEFLATE_DRAFT; - p[1] = CILEN_DEFLATE; - p[2] = p[2 - CILEN_DEFLATE]; - p[3] = DEFLATE_CHK_SEQUENCE; - p += CILEN_DEFLATE; - } - } - if (go->bsd_compress) { - p[0] = CI_BSD_COMPRESS; - p[1] = CILEN_BSD_COMPRESS; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); - if (p != p0) { - p += CILEN_BSD_COMPRESS; /* not the first option */ - } else { - for (;;) { - res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0); - if (res > 0) { - p += CILEN_BSD_COMPRESS; - break; - } - if (res < 0 || go->bsd_bits <= BSD_MIN_BITS) { - go->bsd_compress = 0; - break; - } - --go->bsd_bits; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); - } - } - } - /* XXX Should Predictor 2 be preferable to Predictor 1? */ - if (go->predictor_1) { - p[0] = CI_PREDICTOR_1; - p[1] = CILEN_PREDICTOR_1; - if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 0) <= 0) { - go->predictor_1 = 0; - } else { - p += CILEN_PREDICTOR_1; - } - } - if (go->predictor_2) { - p[0] = CI_PREDICTOR_2; - p[1] = CILEN_PREDICTOR_2; - if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 0) <= 0) { - go->predictor_2 = 0; - } else { - p += CILEN_PREDICTOR_2; - } - } - - go->method = (p > p0)? p0[0]: -1; - - *lenp = p - p0; -} - -/* - * ccp_ackci - process a received configure-ack, and return - * 1 iff the packet was OK. - */ -static int -ccp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - u_char *p0 = p; - - if (go->deflate) { - if (len < CILEN_DEFLATE - || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) - || p[1] != CILEN_DEFLATE - || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - /* XXX Cope with first/fast ack */ - if (len == 0) - return 1; - if (go->deflate_correct && go->deflate_draft) { - if (len < CILEN_DEFLATE - || p[0] != CI_DEFLATE_DRAFT - || p[1] != CILEN_DEFLATE - || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - } - if (go->bsd_compress) { - if (len < CILEN_BSD_COMPRESS - || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS - || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) - return 0; - p += CILEN_BSD_COMPRESS; - len -= CILEN_BSD_COMPRESS; - /* XXX Cope with first/fast ack */ - if (p == p0 && len == 0) - return 1; - } - if (go->predictor_1) { - if (len < CILEN_PREDICTOR_1 - || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1) - return 0; - p += CILEN_PREDICTOR_1; - len -= CILEN_PREDICTOR_1; - /* XXX Cope with first/fast ack */ - if (p == p0 && len == 0) - return 1; - } - if (go->predictor_2) { - if (len < CILEN_PREDICTOR_2 - || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2) - return 0; - p += CILEN_PREDICTOR_2; - len -= CILEN_PREDICTOR_2; - /* XXX Cope with first/fast ack */ - if (p == p0 && len == 0) - return 1; - } - - if (len != 0) - return 0; - return 1; -} - -/* - * ccp_nakci - process received configure-nak. - * Returns 1 iff the nak was OK. - */ -static int -ccp_nakci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - ccp_options no; /* options we've seen already */ - ccp_options try; /* options to ask for next time */ - - memset(&no, 0, sizeof(no)); - try = *go; - - if (go->deflate && len >= CILEN_DEFLATE - && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) - && p[1] == CILEN_DEFLATE) { - no.deflate = 1; - /* - * Peer wants us to use a different code size or something. - * Stop asking for Deflate if we don't understand his suggestion. - */ - if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL - || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_WORKS - || p[3] != DEFLATE_CHK_SEQUENCE) - try.deflate = 0; - else if (DEFLATE_SIZE(p[2]) < go->deflate_size) - try.deflate_size = DEFLATE_SIZE(p[2]); - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - if (go->deflate_correct && go->deflate_draft - && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT - && p[1] == CILEN_DEFLATE) { - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - } - - if (go->bsd_compress && len >= CILEN_BSD_COMPRESS - && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { - no.bsd_compress = 1; - /* - * Peer wants us to use a different number of bits - * or a different version. - */ - if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION) - try.bsd_compress = 0; - else if (BSD_NBITS(p[2]) < go->bsd_bits) - try.bsd_bits = BSD_NBITS(p[2]); - p += CILEN_BSD_COMPRESS; - len -= CILEN_BSD_COMPRESS; - } - - /* - * Predictor-1 and 2 have no options, so they can't be Naked. - * - * There may be remaining options but we ignore them. - */ - - if (f->state != OPENED) - *go = try; - return 1; -} - -/* - * ccp_rejci - reject some of our suggested compression methods. - */ -static int -ccp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - ccp_options try; /* options to request next time */ - - try = *go; - - /* - * Cope with empty configure-rejects by ceasing to send - * configure-requests. - */ - if (len == 0 && all_rejected[f->unit]) - return -1; - - if (go->deflate && len >= CILEN_DEFLATE - && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) - && p[1] == CILEN_DEFLATE) { - if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; /* Rej is bad */ - if (go->deflate_correct) - try.deflate_correct = 0; - else - try.deflate_draft = 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - if (go->deflate_correct && go->deflate_draft - && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT - && p[1] == CILEN_DEFLATE) { - if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; /* Rej is bad */ - try.deflate_draft = 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - if (!try.deflate_correct && !try.deflate_draft) - try.deflate = 0; - } - if (go->bsd_compress && len >= CILEN_BSD_COMPRESS - && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { - if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) - return 0; - try.bsd_compress = 0; - p += CILEN_BSD_COMPRESS; - len -= CILEN_BSD_COMPRESS; - } - if (go->predictor_1 && len >= CILEN_PREDICTOR_1 - && p[0] == CI_PREDICTOR_1 && p[1] == CILEN_PREDICTOR_1) { - try.predictor_1 = 0; - p += CILEN_PREDICTOR_1; - len -= CILEN_PREDICTOR_1; - } - if (go->predictor_2 && len >= CILEN_PREDICTOR_2 - && p[0] == CI_PREDICTOR_2 && p[1] == CILEN_PREDICTOR_2) { - try.predictor_2 = 0; - p += CILEN_PREDICTOR_2; - len -= CILEN_PREDICTOR_2; - } - - if (len != 0) - return 0; - - if (f->state != OPENED) - *go = try; - - return 1; -} - -/* - * ccp_reqci - processed a received configure-request. - * Returns CONFACK, CONFNAK or CONFREJ and the packet modified - * appropriately. - */ -static int -ccp_reqci(f, p, lenp, dont_nak) - fsm *f; - u_char *p; - int *lenp; - int dont_nak; -{ - int ret, newret, res; - u_char *p0, *retp; - int len, clen, type, nb; - ccp_options *ho = &ccp_hisoptions[f->unit]; - ccp_options *ao = &ccp_allowoptions[f->unit]; - - ret = CONFACK; - retp = p0 = p; - len = *lenp; - - memset(ho, 0, sizeof(ccp_options)); - ho->method = (len > 0)? p[0]: -1; - - while (len > 0) { - newret = CONFACK; - if (len < 2 || p[1] < 2 || p[1] > len) { - /* length is bad */ - clen = len; - newret = CONFREJ; - - } else { - type = p[0]; - clen = p[1]; - - switch (type) { - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (!ao->deflate || clen != CILEN_DEFLATE - || (!ao->deflate_correct && type == CI_DEFLATE) - || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) { - newret = CONFREJ; - break; - } - - ho->deflate = 1; - ho->deflate_size = nb = DEFLATE_SIZE(p[2]); - if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL - || p[3] != DEFLATE_CHK_SEQUENCE - || nb > ao->deflate_size || nb < DEFLATE_MIN_WORKS) { - newret = CONFNAK; - if (!dont_nak) { - p[2] = DEFLATE_MAKE_OPT(ao->deflate_size); - p[3] = DEFLATE_CHK_SEQUENCE; - /* fall through to test this #bits below */ - } else - break; - } - - /* - * Check whether we can do Deflate with the window - * size they want. If the window is too big, reduce - * it until the kernel can cope and nak with that. - * We only check this for the first option. - */ - if (p == p0) { - for (;;) { - res = ccp_test(f->unit, p, CILEN_DEFLATE, 1); - if (res > 0) - break; /* it's OK now */ - if (res < 0 || nb == DEFLATE_MIN_WORKS || dont_nak) { - newret = CONFREJ; - p[2] = DEFLATE_MAKE_OPT(ho->deflate_size); - break; - } - newret = CONFNAK; - --nb; - p[2] = DEFLATE_MAKE_OPT(nb); - } - } - break; - - case CI_BSD_COMPRESS: - if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) { - newret = CONFREJ; - break; - } - - ho->bsd_compress = 1; - ho->bsd_bits = nb = BSD_NBITS(p[2]); - if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION - || nb > ao->bsd_bits || nb < BSD_MIN_BITS) { - newret = CONFNAK; - if (!dont_nak) { - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits); - /* fall through to test this #bits below */ - } else - break; - } - - /* - * Check whether we can do BSD-Compress with the code - * size they want. If the code size is too big, reduce - * it until the kernel can cope and nak with that. - * We only check this for the first option. - */ - if (p == p0) { - for (;;) { - res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 1); - if (res > 0) - break; - if (res < 0 || nb == BSD_MIN_BITS || dont_nak) { - newret = CONFREJ; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, - ho->bsd_bits); - break; - } - newret = CONFNAK; - --nb; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb); - } - } - break; - - case CI_PREDICTOR_1: - if (!ao->predictor_1 || clen != CILEN_PREDICTOR_1) { - newret = CONFREJ; - break; - } - - ho->predictor_1 = 1; - if (p == p0 - && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 1) <= 0) { - newret = CONFREJ; - } - break; - - case CI_PREDICTOR_2: - if (!ao->predictor_2 || clen != CILEN_PREDICTOR_2) { - newret = CONFREJ; - break; - } - - ho->predictor_2 = 1; - if (p == p0 - && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 1) <= 0) { - newret = CONFREJ; - } - break; - - default: - newret = CONFREJ; - } - } - - if (newret == CONFNAK && dont_nak) - newret = CONFREJ; - if (!(newret == CONFACK || (newret == CONFNAK && ret == CONFREJ))) { - /* we're returning this option */ - if (newret == CONFREJ && ret == CONFNAK) - retp = p0; - ret = newret; - if (p != retp) - BCOPY(p, retp, clen); - retp += clen; - } - - p += clen; - len -= clen; - } - - if (ret != CONFACK) { - if (ret == CONFREJ && *lenp == retp - p0) - all_rejected[f->unit] = 1; - else - *lenp = retp - p0; - } - return ret; -} - -/* - * Make a string name for a compression method (or 2). - */ -static char * -method_name(opt, opt2) - ccp_options *opt, *opt2; -{ - static char result[64]; - - if (!ANY_COMPRESS(*opt)) - return "(none)"; - switch (opt->method) { - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (opt2 != NULL && opt2->deflate_size != opt->deflate_size) - slprintf(result, sizeof(result), "Deflate%s (%d/%d)", - (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), - opt->deflate_size, opt2->deflate_size); - else - slprintf(result, sizeof(result), "Deflate%s (%d)", - (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), - opt->deflate_size); - break; - case CI_BSD_COMPRESS: - if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits) - slprintf(result, sizeof(result), "BSD-Compress (%d/%d)", - opt->bsd_bits, opt2->bsd_bits); - else - slprintf(result, sizeof(result), "BSD-Compress (%d)", - opt->bsd_bits); - break; - case CI_PREDICTOR_1: - return "Predictor 1"; - case CI_PREDICTOR_2: - return "Predictor 2"; - default: - slprintf(result, sizeof(result), "Method %d", opt->method); - } - return result; -} - -/* - * CCP has come up - inform the kernel driver and log a message. - */ -static void -ccp_up(f) - fsm *f; -{ - ccp_options *go = &ccp_gotoptions[f->unit]; - ccp_options *ho = &ccp_hisoptions[f->unit]; - char method1[64]; - - ccp_flags_set(f->unit, 1, 1); - if (ANY_COMPRESS(*go)) { - if (ANY_COMPRESS(*ho)) { - if (go->method == ho->method) { - notice("%s compression enabled", method_name(go, ho)); - } else { - strlcpy(method1, method_name(go, NULL), sizeof(method1)); - notice("%s / %s compression enabled", - method1, method_name(ho, NULL)); - } - } else - notice("%s receive compression enabled", method_name(go, NULL)); - } else if (ANY_COMPRESS(*ho)) - notice("%s transmit compression enabled", method_name(ho, NULL)); -} - -/* - * CCP has gone down - inform the kernel driver. - */ -static void -ccp_down(f) - fsm *f; -{ - if (ccp_localstate[f->unit] & RACK_PENDING) - UNTIMEOUT(ccp_rack_timeout, f); - ccp_localstate[f->unit] = 0; - ccp_flags_set(f->unit, 1, 0); -} - -/* - * Print the contents of a CCP packet. - */ -static char *ccp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej", - NULL, NULL, NULL, NULL, NULL, NULL, - "ResetReq", "ResetAck", -}; - -static int -ccp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - u_char *p0, *optend; - int code, id, len; - int optlen; - - p0 = p; - if (plen < HEADERLEN) - return 0; - code = p[0]; - id = p[1]; - len = (p[2] << 8) + p[3]; - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(ccp_codenames) / sizeof(char *) - && ccp_codenames[code-1] != NULL) - printer(arg, " %s", ccp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - p += HEADERLEN; - - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print list of possible compression methods */ - while (len >= 2) { - code = p[0]; - optlen = p[1]; - if (optlen < 2 || optlen > len) - break; - printer(arg, " <"); - len -= optlen; - optend = p + optlen; - switch (code) { - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (optlen >= CILEN_DEFLATE) { - printer(arg, "deflate%s %d", - (code == CI_DEFLATE_DRAFT? "(old#)": ""), - DEFLATE_SIZE(p[2])); - if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL) - printer(arg, " method %d", DEFLATE_METHOD(p[2])); - if (p[3] != DEFLATE_CHK_SEQUENCE) - printer(arg, " check %d", p[3]); - p += CILEN_DEFLATE; - } - break; - case CI_BSD_COMPRESS: - if (optlen >= CILEN_BSD_COMPRESS) { - printer(arg, "bsd v%d %d", BSD_VERSION(p[2]), - BSD_NBITS(p[2])); - p += CILEN_BSD_COMPRESS; - } - break; - case CI_PREDICTOR_1: - if (optlen >= CILEN_PREDICTOR_1) { - printer(arg, "predictor 1"); - p += CILEN_PREDICTOR_1; - } - break; - case CI_PREDICTOR_2: - if (optlen >= CILEN_PREDICTOR_2) { - printer(arg, "predictor 2"); - p += CILEN_PREDICTOR_2; - } - break; - } - while (p < optend) - printer(arg, " %.2x", *p++); - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - print_string((char *)p, len, printer, arg); - p += len; - len = 0; - } - break; - } - - /* dump out the rest of the packet in hex */ - while (--len >= 0) - printer(arg, " %.2x", *p++); - - return p - p0; -} - -/* - * We have received a packet that the decompressor failed to - * decompress. Here we would expect to issue a reset-request, but - * Motorola has a patent on resetting the compressor as a result of - * detecting an error in the decompressed data after decompression. - * (See US patent 5,130,993; international patent publication number - * WO 91/10289; Australian patent 73296/91.) - * - * So we ask the kernel whether the error was detected after - * decompression; if it was, we take CCP down, thus disabling - * compression :-(, otherwise we issue the reset-request. - */ -static void -ccp_datainput(unit, pkt, len) - int unit; - u_char *pkt; - int len; -{ - fsm *f; - - f = &ccp_fsm[unit]; - if (f->state == OPENED) { - if (ccp_fatal_error(unit)) { - /* - * Disable compression by taking CCP down. - */ - error("Lost compression sync: disabling compression"); - ccp_close(unit, "Lost compression sync"); - } else { - /* - * Send a reset-request to reset the peer's compressor. - * We don't do that if we are still waiting for an - * acknowledgement to a previous reset-request. - */ - if (!(ccp_localstate[f->unit] & RACK_PENDING)) { - fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0); - TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); - ccp_localstate[f->unit] |= RACK_PENDING; - } else - ccp_localstate[f->unit] |= RREQ_REPEAT; - } - } -} - -/* - * Timeout waiting for reset-ack. - */ -static void -ccp_rack_timeout(arg) - void *arg; -{ - fsm *f = arg; - - if (f->state == OPENED && ccp_localstate[f->unit] & RREQ_REPEAT) { - fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0); - TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); - ccp_localstate[f->unit] &= ~RREQ_REPEAT; - } else - ccp_localstate[f->unit] &= ~RACK_PENDING; -} - diff --git a/mdk-stage1/ppp/pppd/ccp.h b/mdk-stage1/ppp/pppd/ccp.h deleted file mode 100644 index 609d858c5..000000000 --- a/mdk-stage1/ppp/pppd/ccp.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ccp.h - Definitions for PPP Compression Control Protocol. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -typedef struct ccp_options { - bool bsd_compress; /* do BSD Compress? */ - bool deflate; /* do Deflate? */ - bool predictor_1; /* do Predictor-1? */ - bool predictor_2; /* do Predictor-2? */ - bool deflate_correct; /* use correct code for deflate? */ - bool deflate_draft; /* use draft RFC code for deflate? */ - u_short bsd_bits; /* # bits/code for BSD Compress */ - u_short deflate_size; /* lg(window size) for Deflate */ - short method; /* code for chosen compression method */ -} ccp_options; - -extern fsm ccp_fsm[]; -extern ccp_options ccp_wantoptions[]; -extern ccp_options ccp_gotoptions[]; -extern ccp_options ccp_allowoptions[]; -extern ccp_options ccp_hisoptions[]; - -extern struct protent ccp_protent; diff --git a/mdk-stage1/ppp/pppd/chap.c b/mdk-stage1/ppp/pppd/chap.c deleted file mode 100644 index 54c0e0095..000000000 --- a/mdk-stage1/ppp/pppd/chap.c +++ /dev/null @@ -1,860 +0,0 @@ -/* - * chap.c - Challenge Handshake Authentication Protocol. - * - * Copyright (c) 1993 The Australian National 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 the Australian National 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. - * - * Copyright (c) 1991 Gregory M. Christy. - * 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 Gregory M. Christy. The name of the author 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 RCSID "$Id$" - -/* - * TODO: - */ - -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <sys/time.h> - -#include "pppd.h" -#include "chap.h" -#include "md5.h" -#ifdef CHAPMS -#include "chap_ms.h" -#endif - -static const char rcsid[] = RCSID; - -/* - * Command-line options. - */ -static option_t chap_option_list[] = { - { "chap-restart", o_int, &chap[0].timeouttime, - "Set timeout for CHAP", OPT_PRIO }, - { "chap-max-challenge", o_int, &chap[0].max_transmits, - "Set max #xmits for challenge", OPT_PRIO }, - { "chap-interval", o_int, &chap[0].chal_interval, - "Set interval for rechallenge", OPT_PRIO }, -#ifdef MSLANMAN - { "ms-lanman", o_bool, &ms_lanman, - "Use LanMan passwd when using MS-CHAP", 1 }, -#endif - { NULL } -}; - -/* - * Protocol entry points. - */ -static void ChapInit __P((int)); -static void ChapLowerUp __P((int)); -static void ChapLowerDown __P((int)); -static void ChapInput __P((int, u_char *, int)); -static void ChapProtocolReject __P((int)); -static int ChapPrintPkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); - -struct protent chap_protent = { - PPP_CHAP, - ChapInit, - ChapInput, - ChapProtocolReject, - ChapLowerUp, - ChapLowerDown, - NULL, - NULL, - ChapPrintPkt, - NULL, - 1, - "CHAP", - NULL, - chap_option_list, - NULL, - NULL, - NULL -}; - -chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */ - -static void ChapChallengeTimeout __P((void *)); -static void ChapResponseTimeout __P((void *)); -static void ChapReceiveChallenge __P((chap_state *, u_char *, int, int)); -static void ChapRechallenge __P((void *)); -static void ChapReceiveResponse __P((chap_state *, u_char *, int, int)); -static void ChapReceiveSuccess __P((chap_state *, u_char *, int, int)); -static void ChapReceiveFailure __P((chap_state *, u_char *, int, int)); -static void ChapSendStatus __P((chap_state *, int)); -static void ChapSendChallenge __P((chap_state *)); -static void ChapSendResponse __P((chap_state *)); -static void ChapGenChallenge __P((chap_state *)); - -extern double drand48 __P((void)); -extern void srand48 __P((long)); - -/* - * ChapInit - Initialize a CHAP unit. - */ -static void -ChapInit(unit) - int unit; -{ - chap_state *cstate = &chap[unit]; - - BZERO(cstate, sizeof(*cstate)); - cstate->unit = unit; - cstate->clientstate = CHAPCS_INITIAL; - cstate->serverstate = CHAPSS_INITIAL; - cstate->timeouttime = CHAP_DEFTIMEOUT; - cstate->max_transmits = CHAP_DEFTRANSMITS; - /* random number generator is initialized in magic_init */ -} - - -/* - * ChapAuthWithPeer - Authenticate us with our peer (start client). - * - */ -void -ChapAuthWithPeer(unit, our_name, digest) - int unit; - char *our_name; - int digest; -{ - chap_state *cstate = &chap[unit]; - - cstate->resp_name = our_name; - cstate->resp_type = digest; - - if (cstate->clientstate == CHAPCS_INITIAL || - cstate->clientstate == CHAPCS_PENDING) { - /* lower layer isn't up - wait until later */ - cstate->clientstate = CHAPCS_PENDING; - return; - } - - /* - * We get here as a result of LCP coming up. - * So even if CHAP was open before, we will - * have to re-authenticate ourselves. - */ - cstate->clientstate = CHAPCS_LISTEN; -} - - -/* - * ChapAuthPeer - Authenticate our peer (start server). - */ -void -ChapAuthPeer(unit, our_name, digest) - int unit; - char *our_name; - int digest; -{ - chap_state *cstate = &chap[unit]; - - cstate->chal_name = our_name; - cstate->chal_type = digest; - - if (cstate->serverstate == CHAPSS_INITIAL || - cstate->serverstate == CHAPSS_PENDING) { - /* lower layer isn't up - wait until later */ - cstate->serverstate = CHAPSS_PENDING; - return; - } - - ChapGenChallenge(cstate); - ChapSendChallenge(cstate); /* crank it up dude! */ - cstate->serverstate = CHAPSS_INITIAL_CHAL; -} - - -/* - * ChapChallengeTimeout - Timeout expired on sending challenge. - */ -static void -ChapChallengeTimeout(arg) - void *arg; -{ - chap_state *cstate = (chap_state *) arg; - - /* if we aren't sending challenges, don't worry. then again we */ - /* probably shouldn't be here either */ - if (cstate->serverstate != CHAPSS_INITIAL_CHAL && - cstate->serverstate != CHAPSS_RECHALLENGE) - return; - - if (cstate->chal_transmits >= cstate->max_transmits) { - /* give up on peer */ - error("Peer failed to respond to CHAP challenge"); - cstate->serverstate = CHAPSS_BADAUTH; - auth_peer_fail(cstate->unit, PPP_CHAP); - return; - } - - ChapSendChallenge(cstate); /* Re-send challenge */ -} - - -/* - * ChapResponseTimeout - Timeout expired on sending response. - */ -static void -ChapResponseTimeout(arg) - void *arg; -{ - chap_state *cstate = (chap_state *) arg; - - /* if we aren't sending a response, don't worry. */ - if (cstate->clientstate != CHAPCS_RESPONSE) - return; - - ChapSendResponse(cstate); /* re-send response */ -} - - -/* - * ChapRechallenge - Time to challenge the peer again. - */ -static void -ChapRechallenge(arg) - void *arg; -{ - chap_state *cstate = (chap_state *) arg; - - /* if we aren't sending a response, don't worry. */ - if (cstate->serverstate != CHAPSS_OPEN) - return; - - ChapGenChallenge(cstate); - ChapSendChallenge(cstate); - cstate->serverstate = CHAPSS_RECHALLENGE; -} - - -/* - * ChapLowerUp - The lower layer is up. - * - * Start up if we have pending requests. - */ -static void -ChapLowerUp(unit) - int unit; -{ - chap_state *cstate = &chap[unit]; - - if (cstate->clientstate == CHAPCS_INITIAL) - cstate->clientstate = CHAPCS_CLOSED; - else if (cstate->clientstate == CHAPCS_PENDING) - cstate->clientstate = CHAPCS_LISTEN; - - if (cstate->serverstate == CHAPSS_INITIAL) - cstate->serverstate = CHAPSS_CLOSED; - else if (cstate->serverstate == CHAPSS_PENDING) { - ChapGenChallenge(cstate); - ChapSendChallenge(cstate); - cstate->serverstate = CHAPSS_INITIAL_CHAL; - } -} - - -/* - * ChapLowerDown - The lower layer is down. - * - * Cancel all timeouts. - */ -static void -ChapLowerDown(unit) - int unit; -{ - chap_state *cstate = &chap[unit]; - - /* Timeout(s) pending? Cancel if so. */ - if (cstate->serverstate == CHAPSS_INITIAL_CHAL || - cstate->serverstate == CHAPSS_RECHALLENGE) - UNTIMEOUT(ChapChallengeTimeout, cstate); - else if (cstate->serverstate == CHAPSS_OPEN - && cstate->chal_interval != 0) - UNTIMEOUT(ChapRechallenge, cstate); - if (cstate->clientstate == CHAPCS_RESPONSE) - UNTIMEOUT(ChapResponseTimeout, cstate); - - cstate->clientstate = CHAPCS_INITIAL; - cstate->serverstate = CHAPSS_INITIAL; -} - - -/* - * ChapProtocolReject - Peer doesn't grok CHAP. - */ -static void -ChapProtocolReject(unit) - int unit; -{ - chap_state *cstate = &chap[unit]; - - if (cstate->serverstate != CHAPSS_INITIAL && - cstate->serverstate != CHAPSS_CLOSED) - auth_peer_fail(unit, PPP_CHAP); - if (cstate->clientstate != CHAPCS_INITIAL && - cstate->clientstate != CHAPCS_CLOSED) - auth_withpeer_fail(unit, PPP_CHAP); - ChapLowerDown(unit); /* shutdown chap */ -} - - -/* - * ChapInput - Input CHAP packet. - */ -static void -ChapInput(unit, inpacket, packet_len) - int unit; - u_char *inpacket; - int packet_len; -{ - chap_state *cstate = &chap[unit]; - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (packet_len < CHAP_HEADERLEN) { - CHAPDEBUG(("ChapInput: rcvd short header.")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < CHAP_HEADERLEN) { - CHAPDEBUG(("ChapInput: rcvd illegal length.")); - return; - } - if (len > packet_len) { - CHAPDEBUG(("ChapInput: rcvd short packet.")); - return; - } - len -= CHAP_HEADERLEN; - - /* - * Action depends on code (as in fact it usually does :-). - */ - switch (code) { - case CHAP_CHALLENGE: - ChapReceiveChallenge(cstate, inp, id, len); - break; - - case CHAP_RESPONSE: - ChapReceiveResponse(cstate, inp, id, len); - break; - - case CHAP_FAILURE: - ChapReceiveFailure(cstate, inp, id, len); - break; - - case CHAP_SUCCESS: - ChapReceiveSuccess(cstate, inp, id, len); - break; - - default: /* Need code reject? */ - warn("Unknown CHAP code (%d) received.", code); - break; - } -} - - -/* - * ChapReceiveChallenge - Receive Challenge and send Response. - */ -static void -ChapReceiveChallenge(cstate, inp, id, len) - chap_state *cstate; - u_char *inp; - int id; - int len; -{ - int rchallenge_len; - u_char *rchallenge; - int secret_len; - char secret[MAXSECRETLEN]; - char rhostname[256]; - MD5_CTX mdContext; - u_char hash[MD5_SIGNATURE_SIZE]; - - if (cstate->clientstate == CHAPCS_CLOSED || - cstate->clientstate == CHAPCS_PENDING) { - CHAPDEBUG(("ChapReceiveChallenge: in state %d", cstate->clientstate)); - return; - } - - if (len < 2) { - CHAPDEBUG(("ChapReceiveChallenge: rcvd short packet.")); - return; - } - - GETCHAR(rchallenge_len, inp); - len -= sizeof (u_char) + rchallenge_len; /* now name field length */ - if (len < 0) { - CHAPDEBUG(("ChapReceiveChallenge: rcvd short packet.")); - return; - } - rchallenge = inp; - INCPTR(rchallenge_len, inp); - - if (len >= sizeof(rhostname)) - len = sizeof(rhostname) - 1; - BCOPY(inp, rhostname, len); - rhostname[len] = '\000'; - - /* Microsoft doesn't send their name back in the PPP packet */ - if (explicit_remote || (remote_name[0] != 0 && rhostname[0] == 0)) { - strlcpy(rhostname, remote_name, sizeof(rhostname)); - CHAPDEBUG(("ChapReceiveChallenge: using '%q' as remote name", - rhostname)); - } - - /* get secret for authenticating ourselves with the specified host */ - if (!get_secret(cstate->unit, cstate->resp_name, rhostname, - secret, &secret_len, 0)) { - secret_len = 0; /* assume null secret if can't find one */ - warn("No CHAP secret found for authenticating us to %q", rhostname); - } - - /* cancel response send timeout if necessary */ - if (cstate->clientstate == CHAPCS_RESPONSE) - UNTIMEOUT(ChapResponseTimeout, cstate); - - cstate->resp_id = id; - cstate->resp_transmits = 0; - - /* generate MD based on negotiated type */ - switch (cstate->resp_type) { - - case CHAP_DIGEST_MD5: - MD5Init(&mdContext); - MD5Update(&mdContext, &cstate->resp_id, 1); - MD5Update(&mdContext, secret, secret_len); - MD5Update(&mdContext, rchallenge, rchallenge_len); - MD5Final(hash, &mdContext); - BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE); - cstate->resp_length = MD5_SIGNATURE_SIZE; - break; - -#ifdef CHAPMS - case CHAP_MICROSOFT: - ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len); - break; -#endif - - default: - CHAPDEBUG(("unknown digest type %d", cstate->resp_type)); - return; - } - - BZERO(secret, sizeof(secret)); - ChapSendResponse(cstate); -} - - -/* - * ChapReceiveResponse - Receive and process response. - */ -static void -ChapReceiveResponse(cstate, inp, id, len) - chap_state *cstate; - u_char *inp; - int id; - int len; -{ - u_char *remmd, remmd_len; - int secret_len, old_state; - int code; - char rhostname[256]; - MD5_CTX mdContext; - char secret[MAXSECRETLEN]; - u_char hash[MD5_SIGNATURE_SIZE]; - - if (cstate->serverstate == CHAPSS_CLOSED || - cstate->serverstate == CHAPSS_PENDING) { - CHAPDEBUG(("ChapReceiveResponse: in state %d", cstate->serverstate)); - return; - } - - if (id != cstate->chal_id) - return; /* doesn't match ID of last challenge */ - - /* - * If we have received a duplicate or bogus Response, - * we have to send the same answer (Success/Failure) - * as we did for the first Response we saw. - */ - if (cstate->serverstate == CHAPSS_OPEN) { - ChapSendStatus(cstate, CHAP_SUCCESS); - return; - } - if (cstate->serverstate == CHAPSS_BADAUTH) { - ChapSendStatus(cstate, CHAP_FAILURE); - return; - } - - if (len < 2) { - CHAPDEBUG(("ChapReceiveResponse: rcvd short packet.")); - return; - } - GETCHAR(remmd_len, inp); /* get length of MD */ - remmd = inp; /* get pointer to MD */ - INCPTR(remmd_len, inp); - - len -= sizeof (u_char) + remmd_len; - if (len < 0) { - CHAPDEBUG(("ChapReceiveResponse: rcvd short packet.")); - return; - } - - UNTIMEOUT(ChapChallengeTimeout, cstate); - - if (len >= sizeof(rhostname)) - len = sizeof(rhostname) - 1; - BCOPY(inp, rhostname, len); - rhostname[len] = '\000'; - - /* - * Get secret for authenticating them with us, - * do the hash ourselves, and compare the result. - */ - code = CHAP_FAILURE; - if (!get_secret(cstate->unit, (explicit_remote? remote_name: rhostname), - cstate->chal_name, secret, &secret_len, 1)) { - warn("No CHAP secret found for authenticating %q", rhostname); - } else { - - /* generate MD based on negotiated type */ - switch (cstate->chal_type) { - - case CHAP_DIGEST_MD5: /* only MD5 is defined for now */ - if (remmd_len != MD5_SIGNATURE_SIZE) - break; /* it's not even the right length */ - MD5Init(&mdContext); - MD5Update(&mdContext, &cstate->chal_id, 1); - MD5Update(&mdContext, secret, secret_len); - MD5Update(&mdContext, cstate->challenge, cstate->chal_len); - MD5Final(hash, &mdContext); - - /* compare local and remote MDs and send the appropriate status */ - if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0) - code = CHAP_SUCCESS; /* they are the same! */ - break; - - default: - CHAPDEBUG(("unknown digest type %d", cstate->chal_type)); - } - } - - BZERO(secret, sizeof(secret)); - ChapSendStatus(cstate, code); - - if (code == CHAP_SUCCESS) { - old_state = cstate->serverstate; - cstate->serverstate = CHAPSS_OPEN; - if (old_state == CHAPSS_INITIAL_CHAL) { - auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len); - } - if (cstate->chal_interval != 0) - TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval); - notice("CHAP peer authentication succeeded for %q", rhostname); - - } else { - error("CHAP peer authentication failed for remote host %q", rhostname); - cstate->serverstate = CHAPSS_BADAUTH; - auth_peer_fail(cstate->unit, PPP_CHAP); - } -} - -/* - * ChapReceiveSuccess - Receive Success - */ -static void -ChapReceiveSuccess(cstate, inp, id, len) - chap_state *cstate; - u_char *inp; - u_char id; - int len; -{ - - if (cstate->clientstate == CHAPCS_OPEN) - /* presumably an answer to a duplicate response */ - return; - - if (cstate->clientstate != CHAPCS_RESPONSE) { - /* don't know what this is */ - CHAPDEBUG(("ChapReceiveSuccess: in state %d\n", cstate->clientstate)); - return; - } - - UNTIMEOUT(ChapResponseTimeout, cstate); - - /* - * Print message. - */ - if (len > 0) - PRINTMSG(inp, len); - - cstate->clientstate = CHAPCS_OPEN; - - auth_withpeer_success(cstate->unit, PPP_CHAP); -} - - -/* - * ChapReceiveFailure - Receive failure. - */ -static void -ChapReceiveFailure(cstate, inp, id, len) - chap_state *cstate; - u_char *inp; - u_char id; - int len; -{ - if (cstate->clientstate != CHAPCS_RESPONSE) { - /* don't know what this is */ - CHAPDEBUG(("ChapReceiveFailure: in state %d\n", cstate->clientstate)); - return; - } - - UNTIMEOUT(ChapResponseTimeout, cstate); - - /* - * Print message. - */ - if (len > 0) - PRINTMSG(inp, len); - - error("CHAP authentication failed"); - auth_withpeer_fail(cstate->unit, PPP_CHAP); -} - - -/* - * ChapSendChallenge - Send an Authenticate challenge. - */ -static void -ChapSendChallenge(cstate) - chap_state *cstate; -{ - u_char *outp; - int chal_len, name_len; - int outlen; - - chal_len = cstate->chal_len; - name_len = strlen(cstate->chal_name); - outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len; - outp = outpacket_buf; - - MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */ - - PUTCHAR(CHAP_CHALLENGE, outp); - PUTCHAR(cstate->chal_id, outp); - PUTSHORT(outlen, outp); - - PUTCHAR(chal_len, outp); /* put length of challenge */ - BCOPY(cstate->challenge, outp, chal_len); - INCPTR(chal_len, outp); - - BCOPY(cstate->chal_name, outp, name_len); /* append hostname */ - - output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN); - - TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime); - ++cstate->chal_transmits; -} - - -/* - * ChapSendStatus - Send a status response (ack or nak). - */ -static void -ChapSendStatus(cstate, code) - chap_state *cstate; - int code; -{ - u_char *outp; - int outlen, msglen; - char msg[256]; - - if (code == CHAP_SUCCESS) - slprintf(msg, sizeof(msg), "Welcome to %s.", hostname); - else - slprintf(msg, sizeof(msg), "I don't like you. Go 'way."); - msglen = strlen(msg); - - outlen = CHAP_HEADERLEN + msglen; - outp = outpacket_buf; - - MAKEHEADER(outp, PPP_CHAP); /* paste in a header */ - - PUTCHAR(code, outp); - PUTCHAR(cstate->chal_id, outp); - PUTSHORT(outlen, outp); - BCOPY(msg, outp, msglen); - output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN); -} - -/* - * ChapGenChallenge is used to generate a pseudo-random challenge string of - * a pseudo-random length between min_len and max_len. The challenge - * string and its length are stored in *cstate, and various other fields of - * *cstate are initialized. - */ - -static void -ChapGenChallenge(cstate) - chap_state *cstate; -{ - int chal_len; - u_char *ptr = cstate->challenge; - int i; - - /* pick a random challenge length between MIN_CHALLENGE_LENGTH and - MAX_CHALLENGE_LENGTH */ - chal_len = (unsigned) ((drand48() * - (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) + - MIN_CHALLENGE_LENGTH); - cstate->chal_len = chal_len; - cstate->chal_id = ++cstate->id; - cstate->chal_transmits = 0; - - /* generate a random string */ - for (i = 0; i < chal_len; i++) - *ptr++ = (char) (drand48() * 0xff); -} - -/* - * ChapSendResponse - send a response packet with values as specified - * in *cstate. - */ -/* ARGSUSED */ -static void -ChapSendResponse(cstate) - chap_state *cstate; -{ - u_char *outp; - int outlen, md_len, name_len; - - md_len = cstate->resp_length; - name_len = strlen(cstate->resp_name); - outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len; - outp = outpacket_buf; - - MAKEHEADER(outp, PPP_CHAP); - - PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */ - PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */ - PUTSHORT(outlen, outp); /* packet length */ - - PUTCHAR(md_len, outp); /* length of MD */ - BCOPY(cstate->response, outp, md_len); /* copy MD to buffer */ - INCPTR(md_len, outp); - - BCOPY(cstate->resp_name, outp, name_len); /* append our name */ - - /* send the packet */ - output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN); - - cstate->clientstate = CHAPCS_RESPONSE; - TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime); - ++cstate->resp_transmits; -} - -/* - * ChapPrintPkt - print the contents of a CHAP packet. - */ -static char *ChapCodenames[] = { - "Challenge", "Response", "Success", "Failure" -}; - -static int -ChapPrintPkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int code, id, len; - int clen, nlen; - u_char x; - - if (plen < CHAP_HEADERLEN) - return 0; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < CHAP_HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *)) - printer(arg, " %s", ChapCodenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= CHAP_HEADERLEN; - switch (code) { - case CHAP_CHALLENGE: - case CHAP_RESPONSE: - if (len < 1) - break; - clen = p[0]; - if (len < clen + 1) - break; - ++p; - nlen = len - clen - 1; - printer(arg, " <"); - for (; clen > 0; --clen) { - GETCHAR(x, p); - printer(arg, "%.2x", x); - } - printer(arg, ">, name = "); - print_string((char *)p, nlen, printer, arg); - break; - case CHAP_FAILURE: - case CHAP_SUCCESS: - printer(arg, " "); - print_string((char *)p, len, printer, arg); - break; - default: - for (clen = len; clen > 0; --clen) { - GETCHAR(x, p); - printer(arg, " %.2x", x); - } - } - - return len + CHAP_HEADERLEN; -} diff --git a/mdk-stage1/ppp/pppd/chap.h b/mdk-stage1/ppp/pppd/chap.h deleted file mode 100644 index 945d051d0..000000000 --- a/mdk-stage1/ppp/pppd/chap.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * chap.h - Challenge Handshake Authentication Protocol definitions. - * - * Copyright (c) 1993 The Australian National 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 the Australian National 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. - * - * Copyright (c) 1991 Gregory M. Christy - * 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 author. - * - * 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. - * - * $Id$ - */ - -#ifndef __CHAP_INCLUDE__ - -/* Code + ID + length */ -#define CHAP_HEADERLEN 4 - -/* - * CHAP codes. - */ - -#define CHAP_DIGEST_MD5 5 /* use MD5 algorithm */ -#define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */ -#define CHAP_MICROSOFT 0x80 /* use Microsoft-compatible alg. */ -#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ - -#define CHAP_CHALLENGE 1 -#define CHAP_RESPONSE 2 -#define CHAP_SUCCESS 3 -#define CHAP_FAILURE 4 - -/* - * Challenge lengths (for challenges we send) and other limits. - */ -#define MIN_CHALLENGE_LENGTH 16 -#define MAX_CHALLENGE_LENGTH 24 -#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 or MS-CHAP */ - -/* - * Each interface is described by a chap structure. - */ - -typedef struct chap_state { - int unit; /* Interface unit number */ - int clientstate; /* Client state */ - int serverstate; /* Server state */ - u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */ - u_char chal_len; /* challenge length */ - u_char chal_id; /* ID of last challenge */ - u_char chal_type; /* hash algorithm for challenges */ - u_char id; /* Current id */ - char *chal_name; /* Our name to use with challenge */ - int chal_interval; /* Time until we challenge peer again */ - int timeouttime; /* Timeout time in seconds */ - int max_transmits; /* Maximum # of challenge transmissions */ - int chal_transmits; /* Number of transmissions of challenge */ - int resp_transmits; /* Number of transmissions of response */ - u_char response[MAX_RESPONSE_LENGTH]; /* Response to send */ - u_char resp_length; /* length of response */ - u_char resp_id; /* ID for response messages */ - u_char resp_type; /* hash algorithm for responses */ - char *resp_name; /* Our name to send with response */ -} chap_state; - - -/* - * Client (peer) states. - */ -#define CHAPCS_INITIAL 0 /* Lower layer down, not opened */ -#define CHAPCS_CLOSED 1 /* Lower layer up, not opened */ -#define CHAPCS_PENDING 2 /* Auth us to peer when lower up */ -#define CHAPCS_LISTEN 3 /* Listening for a challenge */ -#define CHAPCS_RESPONSE 4 /* Sent response, waiting for status */ -#define CHAPCS_OPEN 5 /* We've received Success */ - -/* - * Server (authenticator) states. - */ -#define CHAPSS_INITIAL 0 /* Lower layer down, not opened */ -#define CHAPSS_CLOSED 1 /* Lower layer up, not opened */ -#define CHAPSS_PENDING 2 /* Auth peer when lower up */ -#define CHAPSS_INITIAL_CHAL 3 /* We've sent the first challenge */ -#define CHAPSS_OPEN 4 /* We've sent a Success msg */ -#define CHAPSS_RECHALLENGE 5 /* We've sent another challenge */ -#define CHAPSS_BADAUTH 6 /* We've sent a Failure msg */ - -/* - * Timeouts. - */ -#define CHAP_DEFTIMEOUT 3 /* Timeout time in seconds */ -#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ - -extern chap_state chap[]; - -void ChapAuthWithPeer __P((int, char *, int)); -void ChapAuthPeer __P((int, char *, int)); - -extern struct protent chap_protent; - -#define __CHAP_INCLUDE__ -#endif /* __CHAP_INCLUDE__ */ diff --git a/mdk-stage1/ppp/pppd/chap_ms.c b/mdk-stage1/ppp/pppd/chap_ms.c deleted file mode 100644 index 81a57bb5a..000000000 --- a/mdk-stage1/ppp/pppd/chap_ms.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * chap_ms.c - Microsoft MS-CHAP compatible implementation. - * - * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited. - * http://www.strataware.com/ - * - * 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 Eric Rosenquist. The name of the author 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. - */ - -/* - * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997 - * - * Implemented LANManager type password response to MS-CHAP challenges. - * Now pppd provides both NT style and LANMan style blocks, and the - * prefered is set by option "ms-lanman". Default is to use NT. - * The hash text (StdText) was taken from Win95 RASAPI32.DLL. - * - * You should also use DOMAIN\\USERNAME as described in README.MSCHAP80 - */ - -#define RCSID "$Id$" - -#ifdef CHAPMS - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/time.h> -#include <unistd.h> -#ifdef HAVE_CRYPT_H -#include <crypt.h> -#endif - -#include "pppd.h" -#include "chap.h" -#include "chap_ms.h" -#include "md4.h" - -#ifndef USE_CRYPT -#include <des.h> -#endif - -static const char rcsid[] = RCSID; - -typedef struct { - u_char LANManResp[24]; - u_char NTResp[24]; - u_char UseNT; /* If 1, ignore the LANMan response field */ -} MS_ChapResponse; -/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse), - in case this struct gets padded. */ - - -static void ChallengeResponse __P((u_char *, u_char *, u_char *)); -static void DesEncrypt __P((u_char *, u_char *, u_char *)); -static void MakeKey __P((u_char *, u_char *)); -static u_char Get7Bits __P((u_char *, int)); -static void ChapMS_NT __P((char *, int, char *, int, MS_ChapResponse *)); -#ifdef MSLANMAN -static void ChapMS_LANMan __P((char *, int, char *, int, MS_ChapResponse *)); -#endif - -#ifdef USE_CRYPT -static void Expand __P((u_char *, u_char *)); -static void Collapse __P((u_char *, u_char *)); -#endif - -#ifdef MSLANMAN -bool ms_lanman = 0; /* Use LanMan password instead of NT */ - /* Has meaning only with MS-CHAP challenges */ -#endif - -static void -ChallengeResponse(challenge, pwHash, response) - u_char *challenge; /* IN 8 octets */ - u_char *pwHash; /* IN 16 octets */ - u_char *response; /* OUT 24 octets */ -{ - char ZPasswordHash[21]; - - BZERO(ZPasswordHash, sizeof(ZPasswordHash)); - BCOPY(pwHash, ZPasswordHash, MD4_SIGNATURE_SIZE); - -#if 0 - dbglog("ChallengeResponse - ZPasswordHash %.*B", - sizeof(ZPasswordHash), ZPasswordHash); -#endif - - DesEncrypt(challenge, ZPasswordHash + 0, response + 0); - DesEncrypt(challenge, ZPasswordHash + 7, response + 8); - DesEncrypt(challenge, ZPasswordHash + 14, response + 16); - -#if 0 - dbglog("ChallengeResponse - response %.24B", response); -#endif -} - - -#ifdef USE_CRYPT -static void -DesEncrypt(clear, key, cipher) - u_char *clear; /* IN 8 octets */ - u_char *key; /* IN 7 octets */ - u_char *cipher; /* OUT 8 octets */ -{ - u_char des_key[8]; - u_char crypt_key[66]; - u_char des_input[66]; - - MakeKey(key, des_key); - - Expand(des_key, crypt_key); - setkey(crypt_key); - -#if 0 - CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %.8B", clear)); -#endif - - Expand(clear, des_input); - encrypt(des_input, 0); - Collapse(des_input, cipher); - -#if 0 - CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %.8B", cipher)); -#endif -} - -#else /* USE_CRYPT */ - -static void -DesEncrypt(clear, key, cipher) - u_char *clear; /* IN 8 octets */ - u_char *key; /* IN 7 octets */ - u_char *cipher; /* OUT 8 octets */ -{ - des_cblock des_key; - des_key_schedule key_schedule; - - MakeKey(key, des_key); - - des_set_key(&des_key, key_schedule); - -#if 0 - CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %.8B", clear)); -#endif - - des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1); - -#if 0 - CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %.8B", cipher)); -#endif -} - -#endif /* USE_CRYPT */ - - -static u_char Get7Bits(input, startBit) - u_char *input; - int startBit; -{ - register unsigned int word; - - word = (unsigned)input[startBit / 8] << 8; - word |= (unsigned)input[startBit / 8 + 1]; - - word >>= 15 - (startBit % 8 + 7); - - return word & 0xFE; -} - -#ifdef USE_CRYPT - -/* in == 8-byte string (expanded version of the 56-bit key) - * out == 64-byte string where each byte is either 1 or 0 - * Note that the low-order "bit" is always ignored by by setkey() - */ -static void Expand(in, out) - u_char *in; - u_char *out; -{ - int j, c; - int i; - - for(i = 0; i < 64; in++){ - c = *in; - for(j = 7; j >= 0; j--) - *out++ = (c >> j) & 01; - i += 8; - } -} - -/* The inverse of Expand - */ -static void Collapse(in, out) - u_char *in; - u_char *out; -{ - int j; - int i; - unsigned int c; - - for (i = 0; i < 64; i += 8, out++) { - c = 0; - for (j = 7; j >= 0; j--, in++) - c |= *in << j; - *out = c & 0xff; - } -} -#endif - -static void MakeKey(key, des_key) - u_char *key; /* IN 56 bit DES key missing parity bits */ - u_char *des_key; /* OUT 64 bit DES key with parity bits added */ -{ - des_key[0] = Get7Bits(key, 0); - des_key[1] = Get7Bits(key, 7); - des_key[2] = Get7Bits(key, 14); - des_key[3] = Get7Bits(key, 21); - des_key[4] = Get7Bits(key, 28); - des_key[5] = Get7Bits(key, 35); - des_key[6] = Get7Bits(key, 42); - des_key[7] = Get7Bits(key, 49); - -#ifndef USE_CRYPT - des_set_odd_parity((des_cblock *)des_key); -#endif - -#if 0 - CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %.7B", key)); - CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %.8B", des_key)); -#endif -} - -static void -ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, response) - char *rchallenge; - int rchallenge_len; - char *secret; - int secret_len; - MS_ChapResponse *response; -{ - int i; -#ifdef __NetBSD__ - /* NetBSD uses the libc md4 routines which take bytes instead of bits */ - int mdlen = secret_len * 2; -#else - int mdlen = secret_len * 2 * 8; -#endif - MD4_CTX md4Context; - u_char hash[MD4_SIGNATURE_SIZE]; - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - - /* Initialize the Unicode version of the secret (== password). */ - /* This implicitly supports 8-bit ISO8859/1 characters. */ - BZERO(unicodePassword, sizeof(unicodePassword)); - for (i = 0; i < secret_len; i++) - unicodePassword[i * 2] = (u_char)secret[i]; - - MD4Init(&md4Context); - MD4Update(&md4Context, unicodePassword, mdlen); - - MD4Final(hash, &md4Context); /* Tell MD4 we're done */ - - ChallengeResponse(rchallenge, hash, response->NTResp); -} - -#ifdef MSLANMAN -static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ - -static void -ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, response) - char *rchallenge; - int rchallenge_len; - char *secret; - int secret_len; - MS_ChapResponse *response; -{ - int i; - u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - - /* LANMan password is case insensitive */ - BZERO(UcasePassword, sizeof(UcasePassword)); - for (i = 0; i < secret_len; i++) - UcasePassword[i] = (u_char)toupper(secret[i]); - DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 ); - DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 ); - ChallengeResponse(rchallenge, PasswordHash, response->LANManResp); -} -#endif - -void -ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len) - chap_state *cstate; - char *rchallenge; - int rchallenge_len; - char *secret; - int secret_len; -{ - MS_ChapResponse response; - -#if 0 - CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'", secret_len, secret)); -#endif - BZERO(&response, sizeof(response)); - - /* Calculate both always */ - ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response); - -#ifdef MSLANMAN - ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response); - - /* prefered method is set by option */ - response.UseNT = !ms_lanman; -#else - response.UseNT = 1; -#endif - - BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN); - cstate->resp_length = MS_CHAP_RESPONSE_LEN; -} - -#endif /* CHAPMS */ diff --git a/mdk-stage1/ppp/pppd/chap_ms.h b/mdk-stage1/ppp/pppd/chap_ms.h deleted file mode 100644 index fad2755c8..000000000 --- a/mdk-stage1/ppp/pppd/chap_ms.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * chap.h - Challenge Handshake Authentication Protocol definitions. - * - * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited. - * http://www.strataware.com/ - * - * 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 Eric Rosenquist. The name of the author 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. - * - * $Id$ - */ - -#ifndef __CHAPMS_INCLUDE__ - -#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */ -#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */ - -void ChapMS __P((chap_state *, char *, int, char *, int)); - -#define __CHAPMS_INCLUDE__ -#endif /* __CHAPMS_INCLUDE__ */ diff --git a/mdk-stage1/ppp/pppd/demand.c b/mdk-stage1/ppp/pppd/demand.c deleted file mode 100644 index 9a740be8d..000000000 --- a/mdk-stage1/ppp/pppd/demand.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * demand.c - Support routines for demand-dialling. - * - * Copyright (c) 1993 The Australian National 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 the Australian National 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. - */ - -#define RCSID "$Id$" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <fcntl.h> -#include <netdb.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/socket.h> -#ifdef PPP_FILTER -#include <net/if.h> -#include <net/bpf.h> -#include <pcap.h> -#endif - -#include "pppd.h" -#include "fsm.h" -#include "ipcp.h" -#include "lcp.h" - -static const char rcsid[] = RCSID; - -char *frame; -int framelen; -int framemax; -int escape_flag; -int flush_flag; -int fcs; - -struct packet { - int length; - struct packet *next; - unsigned char data[1]; -}; - -struct packet *pend_q; -struct packet *pend_qtail; - -static int active_packet __P((unsigned char *, int)); - -/* - * demand_conf - configure the interface for doing dial-on-demand. - */ -void -demand_conf() -{ - int i; - struct protent *protp; - -/* framemax = lcp_allowoptions[0].mru; - if (framemax < PPP_MRU) */ - framemax = PPP_MRU; - framemax += PPP_HDRLEN + PPP_FCSLEN; - frame = malloc(framemax); - if (frame == NULL) - novm("demand frame"); - framelen = 0; - pend_q = NULL; - escape_flag = 0; - flush_flag = 0; - fcs = PPP_INITFCS; - - netif_set_mtu(0, MIN(lcp_allowoptions[0].mru, PPP_MRU)); - ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0); - ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0); - -#ifdef PPP_FILTER - set_filters(&pass_filter, &active_filter); -#endif - - /* - * Call the demand_conf procedure for each protocol that's got one. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->enabled_flag && protp->demand_conf != NULL) - if (!((*protp->demand_conf)(0))) - die(1); -} - - -/* - * demand_block - set each network protocol to block further packets. - */ -void -demand_block() -{ - int i; - struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->enabled_flag && protp->demand_conf != NULL) - sifnpmode(0, protp->protocol & ~0x8000, NPMODE_QUEUE); - get_loop_output(); -} - -/* - * demand_discard - set each network protocol to discard packets - * with an error. - */ -void -demand_discard() -{ - struct packet *pkt, *nextpkt; - int i; - struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->enabled_flag && protp->demand_conf != NULL) - sifnpmode(0, protp->protocol & ~0x8000, NPMODE_ERROR); - get_loop_output(); - - /* discard all saved packets */ - for (pkt = pend_q; pkt != NULL; pkt = nextpkt) { - nextpkt = pkt->next; - free(pkt); - } - pend_q = NULL; - framelen = 0; - flush_flag = 0; - escape_flag = 0; - fcs = PPP_INITFCS; -} - -/* - * demand_unblock - set each enabled network protocol to pass packets. - */ -void -demand_unblock() -{ - int i; - struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->enabled_flag && protp->demand_conf != NULL) - sifnpmode(0, protp->protocol & ~0x8000, NPMODE_PASS); -} - -/* - * FCS lookup table as calculated by genfcstab. - */ -static u_short fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -/* - * loop_chars - process characters received from the loopback. - * Calls loop_frame when a complete frame has been accumulated. - * Return value is 1 if we need to bring up the link, 0 otherwise. - */ -int -loop_chars(p, n) - unsigned char *p; - int n; -{ - int c, rv; - - rv = 0; - for (; n > 0; --n) { - c = *p++; - if (c == PPP_FLAG) { - if (!escape_flag && !flush_flag - && framelen > 2 && fcs == PPP_GOODFCS) { - framelen -= 2; - if (loop_frame((unsigned char *)frame, framelen)) - rv = 1; - } - framelen = 0; - flush_flag = 0; - escape_flag = 0; - fcs = PPP_INITFCS; - continue; - } - if (flush_flag) - continue; - if (escape_flag) { - c ^= PPP_TRANS; - escape_flag = 0; - } else if (c == PPP_ESCAPE) { - escape_flag = 1; - continue; - } - if (framelen >= framemax) { - flush_flag = 1; - continue; - } - frame[framelen++] = c; - fcs = PPP_FCS(fcs, c); - } - return rv; -} - -/* - * loop_frame - given a frame obtained from the loopback, - * decide whether to bring up the link or not, and, if we want - * to transmit this frame later, put it on the pending queue. - * Return value is 1 if we need to bring up the link, 0 otherwise. - * We assume that the kernel driver has already applied the - * pass_filter, so we won't get packets it rejected. - * We apply the active_filter to see if we want this packet to - * bring up the link. - */ -int -loop_frame(frame, len) - unsigned char *frame; - int len; -{ - struct packet *pkt; - - /* dbglog("from loop: %P", frame, len); */ - if (len < PPP_HDRLEN) - return 0; - if ((PPP_PROTOCOL(frame) & 0x8000) != 0) - return 0; /* shouldn't get any of these anyway */ - if (!active_packet(frame, len)) - return 0; - - pkt = (struct packet *) malloc(sizeof(struct packet) + len); - if (pkt != NULL) { - pkt->length = len; - pkt->next = NULL; - memcpy(pkt->data, frame, len); - if (pend_q == NULL) - pend_q = pkt; - else - pend_qtail->next = pkt; - pend_qtail = pkt; - } - return 1; -} - -/* - * demand_rexmit - Resend all those frames which we got via the - * loopback, now that the real serial link is up. - */ -void -demand_rexmit(proto) - int proto; -{ - struct packet *pkt, *prev, *nextpkt; - - prev = NULL; - pkt = pend_q; - pend_q = NULL; - for (; pkt != NULL; pkt = nextpkt) { - nextpkt = pkt->next; - if (PPP_PROTOCOL(pkt->data) == proto) { - output(0, pkt->data, pkt->length); - free(pkt); - } else { - if (prev == NULL) - pend_q = pkt; - else - prev->next = pkt; - prev = pkt; - } - } - pend_qtail = prev; - if (prev != NULL) - prev->next = NULL; -} - -/* - * Scan a packet to decide whether it is an "active" packet, - * that is, whether it is worth bringing up the link for. - */ -static int -active_packet(p, len) - unsigned char *p; - int len; -{ - int proto, i; - struct protent *protp; - - if (len < PPP_HDRLEN) - return 0; - proto = PPP_PROTOCOL(p); -#ifdef PPP_FILTER - if (pass_filter.bf_len != 0 - && bpf_filter(pass_filter.bf_insns, p, len, len) == 0) - return 0; - if (active_filter.bf_len != 0 - && bpf_filter(active_filter.bf_insns, p, len, len) == 0) - return 0; -#endif - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) { - if (!protp->enabled_flag) - return 0; - if (protp->active_pkt == NULL) - return 1; - return (*protp->active_pkt)(p, len); - } - } - return 0; /* not a supported protocol !!?? */ -} diff --git a/mdk-stage1/ppp/pppd/eui64.c b/mdk-stage1/ppp/pppd/eui64.c deleted file mode 100644 index 7f3176035..000000000 --- a/mdk-stage1/ppp/pppd/eui64.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - eui64.c - EUI64 routines for IPv6CP. - Copyright (C) 1999 Tommi Komulainen <Tommi.Komulainen@iki.fi> - - 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 Tommi Komulainen. The name of the author 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. - - - $Id$ -*/ - -#define RCSID "$Id$" - -#include "pppd.h" - -static const char rcsid[] = RCSID; - -/* - * eui64_ntoa - Make an ascii representation of an interface identifier - */ -char * -eui64_ntoa(e) - eui64_t e; -{ - static char buf[32]; - - snprintf(buf, 32, "%02x%02x:%02x%02x:%02x%02x:%02x%02x", - e.e8[0], e.e8[1], e.e8[2], e.e8[3], - e.e8[4], e.e8[5], e.e8[6], e.e8[7]); - return buf; -} diff --git a/mdk-stage1/ppp/pppd/eui64.h b/mdk-stage1/ppp/pppd/eui64.h deleted file mode 100644 index ca4445345..000000000 --- a/mdk-stage1/ppp/pppd/eui64.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - eui64.h - EUI64 routines for IPv6CP. - Copyright (C) 1999 Tommi Komulainen <Tommi.Komulainen@iki.fi> - - 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 Tommi Komulainen. The name of the author 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. - - - $Id$ -*/ - -#ifndef __EUI64_H__ -#define __EUI64_H__ - -#if !defined(INET6) -#error "this file should only be included when INET6 is defined" -#endif /* not defined(INET6) */ - -#if defined(SOL2) -#include <netinet/in.h> - -typedef union { - uint8_t e8[8]; /* lower 64-bit IPv6 address */ - uint32_t e32[2]; /* lower 64-bit IPv6 address */ -} eui64_t; - -/* - * Declare the two below, since in.h only defines them when _KERNEL - * is declared - which shouldn't be true when dealing with user-land programs - */ -#define s6_addr8 _S6_un._S6_u8 -#define s6_addr32 _S6_un._S6_u32 - -#else /* else if not defined(SOL2) */ - -/* - * TODO: - * - * Maybe this should be done by processing struct in6_addr directly... - */ -typedef union -{ - u_int8_t e8[8]; - u_int16_t e16[4]; - u_int32_t e32[2]; -} eui64_t; - -#endif /* defined(SOL2) */ - -#define eui64_iszero(e) (((e).e32[0] | (e).e32[1]) == 0) -#define eui64_equals(e, o) (((e).e32[0] == (o).e32[0]) && \ - ((e).e32[1] == (o).e32[1])) -#define eui64_zero(e) (e).e32[0] = (e).e32[1] = 0; - -#define eui64_copy(s, d) memcpy(&(d), &(s), sizeof(eui64_t)) - -#define eui64_magic(e) do { \ - (e).e32[0] = magic(); \ - (e).e32[1] = magic(); \ - (e).e8[0] &= ~2; \ - } while (0) -#define eui64_magic_nz(x) do { \ - eui64_magic(x); \ - } while (eui64_iszero(x)) -#define eui64_magic_ne(x, y) do { \ - eui64_magic(x); \ - } while (eui64_equals(x, y)) - -#define eui64_get(ll, cp) do { \ - eui64_copy((*cp), (ll)); \ - (cp) += sizeof(eui64_t); \ - } while (0) - -#define eui64_put(ll, cp) do { \ - eui64_copy((ll), (*cp)); \ - (cp) += sizeof(eui64_t); \ - } while (0) - -#define eui64_set32(e, l) do { \ - (e).e32[0] = 0; \ - (e).e32[1] = htonl(l); \ - } while (0) -#define eui64_setlo32(e, l) eui64_set32(e, l) - -char *eui64_ntoa __P((eui64_t)); /* Returns ascii representation of id */ - -#endif /* __EUI64_H__ */ - diff --git a/mdk-stage1/ppp/pppd/fsm.c b/mdk-stage1/ppp/pppd/fsm.c deleted file mode 100644 index 07a8c11f1..000000000 --- a/mdk-stage1/ppp/pppd/fsm.c +++ /dev/null @@ -1,762 +0,0 @@ -/* - * fsm.c - {Link, IP} Control Protocol Finite State Machine. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -#define RCSID "$Id$" - -/* - * TODO: - * Randomize fsm id on link/init. - * Deal with variable outgoing MTU. - */ - -#include <stdio.h> -#include <string.h> -#include <sys/types.h> - -#include "pppd.h" -#include "fsm.h" - -static const char rcsid[] = RCSID; - -static void fsm_timeout __P((void *)); -static void fsm_rconfreq __P((fsm *, int, u_char *, int)); -static void fsm_rconfack __P((fsm *, int, u_char *, int)); -static void fsm_rconfnakrej __P((fsm *, int, int, u_char *, int)); -static void fsm_rtermreq __P((fsm *, int, u_char *, int)); -static void fsm_rtermack __P((fsm *)); -static void fsm_rcoderej __P((fsm *, u_char *, int)); -static void fsm_sconfreq __P((fsm *, int)); - -#define PROTO_NAME(f) ((f)->callbacks->proto_name) - -int peer_mru[NUM_PPP]; - - -/* - * fsm_init - Initialize fsm. - * - * Initialize fsm state. - */ -void -fsm_init(f) - fsm *f; -{ - f->state = INITIAL; - f->flags = 0; - f->id = 0; /* XXX Start with random id? */ - f->timeouttime = DEFTIMEOUT; - f->maxconfreqtransmits = DEFMAXCONFREQS; - f->maxtermtransmits = DEFMAXTERMREQS; - f->maxnakloops = DEFMAXNAKLOOPS; - f->term_reason_len = 0; -} - - -/* - * fsm_lowerup - The lower layer is up. - */ -void -fsm_lowerup(f) - fsm *f; -{ - switch( f->state ){ - case INITIAL: - f->state = CLOSED; - break; - - case STARTING: - if( f->flags & OPT_SILENT ) - f->state = STOPPED; - else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = REQSENT; - } - break; - - default: - FSMDEBUG(("%s: Up event in state %d!", PROTO_NAME(f), f->state)); - } -} - - -/* - * fsm_lowerdown - The lower layer is down. - * - * Cancel all timeouts and inform upper layers. - */ -void -fsm_lowerdown(f) - fsm *f; -{ - switch( f->state ){ - case CLOSED: - f->state = INITIAL; - break; - - case STOPPED: - f->state = STARTING; - if( f->callbacks->starting ) - (*f->callbacks->starting)(f); - break; - - case CLOSING: - f->state = INITIAL; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case STOPPING: - case REQSENT: - case ACKRCVD: - case ACKSENT: - f->state = STARTING; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case OPENED: - if( f->callbacks->down ) - (*f->callbacks->down)(f); - f->state = STARTING; - break; - - default: - FSMDEBUG(("%s: Down event in state %d!", PROTO_NAME(f), f->state)); - } -} - - -/* - * fsm_open - Link is allowed to come up. - */ -void -fsm_open(f) - fsm *f; -{ - switch( f->state ){ - case INITIAL: - f->state = STARTING; - if( f->callbacks->starting ) - (*f->callbacks->starting)(f); - break; - - case CLOSED: - if( f->flags & OPT_SILENT ) - f->state = STOPPED; - else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = REQSENT; - } - break; - - case CLOSING: - f->state = STOPPING; - /* fall through */ - case STOPPED: - case OPENED: - if( f->flags & OPT_RESTART ){ - fsm_lowerdown(f); - fsm_lowerup(f); - } - break; - } -} - - -/* - * fsm_close - Start closing connection. - * - * Cancel timeouts and either initiate close or possibly go directly to - * the CLOSED state. - */ -void -fsm_close(f, reason) - fsm *f; - char *reason; -{ - f->term_reason = reason; - f->term_reason_len = (reason == NULL? 0: strlen(reason)); - switch( f->state ){ - case STARTING: - f->state = INITIAL; - break; - case STOPPED: - f->state = CLOSED; - break; - case STOPPING: - f->state = CLOSING; - break; - - case REQSENT: - case ACKRCVD: - case ACKSENT: - case OPENED: - if( f->state != OPENED ) - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - else if( f->callbacks->down ) - (*f->callbacks->down)(f); /* Inform upper layers we're down */ - - /* Init restart counter, send Terminate-Request */ - f->retransmits = f->maxtermtransmits; - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - - f->state = CLOSING; - break; - } -} - - -/* - * fsm_timeout - Timeout expired. - */ -static void -fsm_timeout(arg) - void *arg; -{ - fsm *f = (fsm *) arg; - - switch (f->state) { - case CLOSING: - case STOPPING: - if( f->retransmits <= 0 ){ - /* - * We've waited for an ack long enough. Peer probably heard us. - */ - f->state = (f->state == CLOSING)? CLOSED: STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - } else { - /* Send Terminate-Request */ - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - } - break; - - case REQSENT: - case ACKRCVD: - case ACKSENT: - if (f->retransmits <= 0) { - warn("%s: timeout sending Config-Requests\n", PROTO_NAME(f)); - f->state = STOPPED; - if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) - (*f->callbacks->finished)(f); - - } else { - /* Retransmit the configure-request */ - if (f->callbacks->retransmit) - (*f->callbacks->retransmit)(f); - fsm_sconfreq(f, 1); /* Re-send Configure-Request */ - if( f->state == ACKRCVD ) - f->state = REQSENT; - } - break; - - default: - FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state)); - } -} - - -/* - * fsm_input - Input packet. - */ -void -fsm_input(f, inpacket, l) - fsm *f; - u_char *inpacket; - int l; -{ - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (l < HEADERLEN) { - FSMDEBUG(("fsm_input(%x): Rcvd short header.", f->protocol)); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < HEADERLEN) { - FSMDEBUG(("fsm_input(%x): Rcvd illegal length.", f->protocol)); - return; - } - if (len > l) { - FSMDEBUG(("fsm_input(%x): Rcvd short packet.", f->protocol)); - return; - } - len -= HEADERLEN; /* subtract header length */ - - if( f->state == INITIAL || f->state == STARTING ){ - FSMDEBUG(("fsm_input(%x): Rcvd packet in state %d.", - f->protocol, f->state)); - return; - } - - /* - * Action depends on code. - */ - switch (code) { - case CONFREQ: - fsm_rconfreq(f, id, inp, len); - break; - - case CONFACK: - fsm_rconfack(f, id, inp, len); - break; - - case CONFNAK: - case CONFREJ: - fsm_rconfnakrej(f, code, id, inp, len); - break; - - case TERMREQ: - fsm_rtermreq(f, id, inp, len); - break; - - case TERMACK: - fsm_rtermack(f); - break; - - case CODEREJ: - fsm_rcoderej(f, inp, len); - break; - - default: - if( !f->callbacks->extcode - || !(*f->callbacks->extcode)(f, code, id, inp, len) ) - fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN); - break; - } -} - - -/* - * fsm_rconfreq - Receive Configure-Request. - */ -static void -fsm_rconfreq(f, id, inp, len) - fsm *f; - u_char id; - u_char *inp; - int len; -{ - int code, reject_if_disagree; - - switch( f->state ){ - case CLOSED: - /* Go away, we're closed */ - fsm_sdata(f, TERMACK, id, NULL, 0); - return; - case CLOSING: - case STOPPING: - return; - - case OPENED: - /* Go down and restart negotiation */ - if( f->callbacks->down ) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - break; - - case STOPPED: - /* Negotiation started by our peer */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = REQSENT; - break; - } - - /* - * Pass the requested configuration options - * to protocol-specific code for checking. - */ - if (f->callbacks->reqci){ /* Check CI */ - reject_if_disagree = (f->nakloops >= f->maxnakloops); - code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree); - } else if (len) - code = CONFREJ; /* Reject all CI */ - else - code = CONFACK; - - /* send the Ack, Nak or Rej to the peer */ - fsm_sdata(f, code, id, inp, len); - - if (code == CONFACK) { - if (f->state == ACKRCVD) { - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = OPENED; - if (f->callbacks->up) - (*f->callbacks->up)(f); /* Inform upper layers */ - } else - f->state = ACKSENT; - f->nakloops = 0; - - } else { - /* we sent CONFACK or CONFREJ */ - if (f->state != ACKRCVD) - f->state = REQSENT; - if( code == CONFNAK ) - ++f->nakloops; - } -} - - -/* - * fsm_rconfack - Receive Configure-Ack. - */ -static void -fsm_rconfack(f, id, inp, len) - fsm *f; - int id; - u_char *inp; - int len; -{ - if (id != f->reqid || f->seen_ack) /* Expected id? */ - return; /* Nope, toss... */ - if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): - (len == 0)) ){ - /* Ack is bad - ignore it */ - error("Received bad configure-ack: %P", inp, len); - return; - } - f->seen_ack = 1; - - switch (f->state) { - case CLOSED: - case STOPPED: - fsm_sdata(f, TERMACK, id, NULL, 0); - break; - - case REQSENT: - f->state = ACKRCVD; - f->retransmits = f->maxconfreqtransmits; - break; - - case ACKRCVD: - /* Huh? an extra valid Ack? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = REQSENT; - break; - - case ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = OPENED; - f->retransmits = f->maxconfreqtransmits; - if (f->callbacks->up) - (*f->callbacks->up)(f); /* Inform upper layers */ - break; - - case OPENED: - /* Go down and restart negotiation */ - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = REQSENT; - break; - } -} - - -/* - * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. - */ -static void -fsm_rconfnakrej(f, code, id, inp, len) - fsm *f; - int code, id; - u_char *inp; - int len; -{ - int (*proc) __P((fsm *, u_char *, int)); - int ret; - - if (id != f->reqid || f->seen_ack) /* Expected id? */ - return; /* Nope, toss... */ - proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci; - if (!proc || !(ret = proc(f, inp, len))) { - /* Nak/reject is bad - ignore it */ - error("Received bad configure-nak/rej: %P", inp, len); - return; - } - f->seen_ack = 1; - - switch (f->state) { - case CLOSED: - case STOPPED: - fsm_sdata(f, TERMACK, id, NULL, 0); - break; - - case REQSENT: - case ACKSENT: - /* They didn't agree to what we wanted - try another request */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - if (ret < 0) - f->state = STOPPED; /* kludge for stopping CCP */ - else - fsm_sconfreq(f, 0); /* Send Configure-Request */ - break; - - case ACKRCVD: - /* Got a Nak/reject when we had already had an Ack?? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = REQSENT; - break; - - case OPENED: - /* Go down and restart negotiation */ - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = REQSENT; - break; - } -} - - -/* - * fsm_rtermreq - Receive Terminate-Req. - */ -static void -fsm_rtermreq(f, id, p, len) - fsm *f; - int id; - u_char *p; - int len; -{ - switch (f->state) { - case ACKRCVD: - case ACKSENT: - f->state = REQSENT; /* Start over but keep trying */ - break; - - case OPENED: - if (len > 0) { - info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p); - } else - info("%s terminated by peer", PROTO_NAME(f)); - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - f->retransmits = 0; - f->state = STOPPING; - TIMEOUT(fsm_timeout, f, f->timeouttime); - break; - } - - fsm_sdata(f, TERMACK, id, NULL, 0); -} - - -/* - * fsm_rtermack - Receive Terminate-Ack. - */ -static void -fsm_rtermack(f) - fsm *f; -{ - switch (f->state) { - case CLOSING: - UNTIMEOUT(fsm_timeout, f); - f->state = CLOSED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - case STOPPING: - UNTIMEOUT(fsm_timeout, f); - f->state = STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case ACKRCVD: - f->state = REQSENT; - break; - - case OPENED: - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); - break; - } -} - - -/* - * fsm_rcoderej - Receive an Code-Reject. - */ -static void -fsm_rcoderej(f, inp, len) - fsm *f; - u_char *inp; - int len; -{ - u_char code, id; - - if (len < HEADERLEN) { - FSMDEBUG(("fsm_rcoderej: Rcvd short Code-Reject packet!")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id); - - if( f->state == ACKRCVD ) - f->state = REQSENT; -} - - -/* - * fsm_protreject - Peer doesn't speak this protocol. - * - * Treat this as a catastrophic error (RXJ-). - */ -void -fsm_protreject(f) - fsm *f; -{ - switch( f->state ){ - case CLOSING: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - case CLOSED: - f->state = CLOSED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case STOPPING: - case REQSENT: - case ACKRCVD: - case ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - case STOPPED: - f->state = STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case OPENED: - if( f->callbacks->down ) - (*f->callbacks->down)(f); - - /* Init restart counter, send Terminate-Request */ - f->retransmits = f->maxtermtransmits; - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, f->timeouttime); - --f->retransmits; - - f->state = STOPPING; - break; - - default: - FSMDEBUG(("%s: Protocol-reject event in state %d!", - PROTO_NAME(f), f->state)); - } -} - - -/* - * fsm_sconfreq - Send a Configure-Request. - */ -static void -fsm_sconfreq(f, retransmit) - fsm *f; - int retransmit; -{ - u_char *outp; - int cilen; - - if( f->state != REQSENT && f->state != ACKRCVD && f->state != ACKSENT ){ - /* Not currently negotiating - reset options */ - if( f->callbacks->resetci ) - (*f->callbacks->resetci)(f); - f->nakloops = 0; - } - - if( !retransmit ){ - /* New request - reset retransmission counter, use new ID */ - f->retransmits = f->maxconfreqtransmits; - f->reqid = ++f->id; - } - - f->seen_ack = 0; - - /* - * Make up the request packet - */ - outp = outpacket_buf + PPP_HDRLEN + HEADERLEN; - if( f->callbacks->cilen && f->callbacks->addci ){ - cilen = (*f->callbacks->cilen)(f); - if( cilen > peer_mru[f->unit] - HEADERLEN ) - cilen = peer_mru[f->unit] - HEADERLEN; - if (f->callbacks->addci) - (*f->callbacks->addci)(f, outp, &cilen); - } else - cilen = 0; - - /* send the request to our peer */ - fsm_sdata(f, CONFREQ, f->reqid, outp, cilen); - - /* start the retransmit timer */ - --f->retransmits; - TIMEOUT(fsm_timeout, f, f->timeouttime); -} - - -/* - * fsm_sdata - Send some data. - * - * Used for all packets sent to our peer by this module. - */ -void -fsm_sdata(f, code, id, data, datalen) - fsm *f; - u_char code, id; - u_char *data; - int datalen; -{ - u_char *outp; - int outlen; - - /* Adjust length to be smaller than MTU */ - outp = outpacket_buf; - if (datalen > peer_mru[f->unit] - HEADERLEN) - datalen = peer_mru[f->unit] - HEADERLEN; - if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) - BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen); - outlen = datalen + HEADERLEN; - MAKEHEADER(outp, f->protocol); - PUTCHAR(code, outp); - PUTCHAR(id, outp); - PUTSHORT(outlen, outp); - output(f->unit, outpacket_buf, outlen + PPP_HDRLEN); -} diff --git a/mdk-stage1/ppp/pppd/fsm.h b/mdk-stage1/ppp/pppd/fsm.h deleted file mode 100644 index c94a68e6c..000000000 --- a/mdk-stage1/ppp/pppd/fsm.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - * - * $Id$ - */ - -/* - * Packet header = Code, id, length. - */ -#define HEADERLEN 4 - - -/* - * CP (LCP, IPCP, etc.) codes. - */ -#define CONFREQ 1 /* Configuration Request */ -#define CONFACK 2 /* Configuration Ack */ -#define CONFNAK 3 /* Configuration Nak */ -#define CONFREJ 4 /* Configuration Reject */ -#define TERMREQ 5 /* Termination Request */ -#define TERMACK 6 /* Termination Ack */ -#define CODEREJ 7 /* Code Reject */ - - -/* - * Each FSM is described by an fsm structure and fsm callbacks. - */ -typedef struct fsm { - int unit; /* Interface unit number */ - int protocol; /* Data Link Layer Protocol field value */ - int state; /* State */ - int flags; /* Contains option bits */ - u_char id; /* Current id */ - u_char reqid; /* Current request id */ - u_char seen_ack; /* Have received valid Ack/Nak/Rej to Req */ - int timeouttime; /* Timeout time in milliseconds */ - int maxconfreqtransmits; /* Maximum Configure-Request transmissions */ - int retransmits; /* Number of retransmissions left */ - int maxtermtransmits; /* Maximum Terminate-Request transmissions */ - int nakloops; /* Number of nak loops since last ack */ - int maxnakloops; /* Maximum number of nak loops tolerated */ - struct fsm_callbacks *callbacks; /* Callback routines */ - char *term_reason; /* Reason for closing protocol */ - int term_reason_len; /* Length of term_reason */ -} fsm; - - -typedef struct fsm_callbacks { - void (*resetci) /* Reset our Configuration Information */ - __P((fsm *)); - int (*cilen) /* Length of our Configuration Information */ - __P((fsm *)); - void (*addci) /* Add our Configuration Information */ - __P((fsm *, u_char *, int *)); - int (*ackci) /* ACK our Configuration Information */ - __P((fsm *, u_char *, int)); - int (*nakci) /* NAK our Configuration Information */ - __P((fsm *, u_char *, int)); - int (*rejci) /* Reject our Configuration Information */ - __P((fsm *, u_char *, int)); - int (*reqci) /* Request peer's Configuration Information */ - __P((fsm *, u_char *, int *, int)); - void (*up) /* Called when fsm reaches OPENED state */ - __P((fsm *)); - void (*down) /* Called when fsm leaves OPENED state */ - __P((fsm *)); - void (*starting) /* Called when we want the lower layer */ - __P((fsm *)); - void (*finished) /* Called when we don't want the lower layer */ - __P((fsm *)); - void (*protreject) /* Called when Protocol-Reject received */ - __P((int)); - void (*retransmit) /* Retransmission is necessary */ - __P((fsm *)); - int (*extcode) /* Called when unknown code received */ - __P((fsm *, int, int, u_char *, int)); - char *proto_name; /* String name for protocol (for messages) */ -} fsm_callbacks; - - -/* - * Link states. - */ -#define INITIAL 0 /* Down, hasn't been opened */ -#define STARTING 1 /* Down, been opened */ -#define CLOSED 2 /* Up, hasn't been opened */ -#define STOPPED 3 /* Open, waiting for down event */ -#define CLOSING 4 /* Terminating the connection, not open */ -#define STOPPING 5 /* Terminating, but open */ -#define REQSENT 6 /* We've sent a Config Request */ -#define ACKRCVD 7 /* We've received a Config Ack */ -#define ACKSENT 8 /* We've sent a Config Ack */ -#define OPENED 9 /* Connection available */ - - -/* - * Flags - indicate options controlling FSM operation - */ -#define OPT_PASSIVE 1 /* Don't die if we don't get a response */ -#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */ -#define OPT_SILENT 4 /* Wait for peer to speak first */ - - -/* - * Timeouts. - */ -#define DEFTIMEOUT 3 /* Timeout time in seconds */ -#define DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ -#define DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ -#define DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ - - -/* - * Prototypes - */ -void fsm_init __P((fsm *)); -void fsm_lowerup __P((fsm *)); -void fsm_lowerdown __P((fsm *)); -void fsm_open __P((fsm *)); -void fsm_close __P((fsm *, char *)); -void fsm_input __P((fsm *, u_char *, int)); -void fsm_protreject __P((fsm *)); -void fsm_sdata __P((fsm *, int, int, u_char *, int)); - - -/* - * Variables - */ -extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */ diff --git a/mdk-stage1/ppp/pppd/ipcp.c b/mdk-stage1/ppp/pppd/ipcp.c deleted file mode 100644 index 3f64357ed..000000000 --- a/mdk-stage1/ppp/pppd/ipcp.c +++ /dev/null @@ -1,2054 +0,0 @@ -/* - * ipcp.c - PPP IP Control Protocol. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -#define RCSID "$Id$" - -/* - * TODO: - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <netdb.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include "pppd.h" -#include "fsm.h" -#include "ipcp.h" -#include "pathnames.h" - -static const char rcsid[] = RCSID; - -/* global vars */ -ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ -ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ -ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ -ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ - -u_int32_t netmask = 0; /* IP netmask to set on interface */ - -bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ - -/* Hook for a plugin to know when IP protocol has come up */ -void (*ip_up_hook) __P((void)) = NULL; - -/* Hook for a plugin to know when IP protocol has come down */ -void (*ip_down_hook) __P((void)) = NULL; - -/* Hook for a plugin to choose the remote IP address */ -void (*ip_choose_hook) __P((u_int32_t *)) = NULL; - -/* local vars */ -static int default_route_set[NUM_PPP]; /* Have set up a default route */ -static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */ -static bool usepeerdns; /* Ask peer for DNS addrs */ -static int ipcp_is_up; /* have called np_up() */ -static bool ask_for_local; /* request our address from peer */ -static char vj_value[8]; /* string form of vj option value */ -static char netmask_str[20]; /* string form of netmask value */ - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void ipcp_resetci __P((fsm *)); /* Reset our CI */ -static int ipcp_cilen __P((fsm *)); /* Return length of our CI */ -static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ -static int ipcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int ipcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */ -static int ipcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ -static int ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ -static void ipcp_up __P((fsm *)); /* We're UP */ -static void ipcp_down __P((fsm *)); /* We're DOWN */ -static void ipcp_finished __P((fsm *)); /* Don't need lower layer */ - -fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ - -static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ - ipcp_resetci, /* Reset our Configuration Information */ - ipcp_cilen, /* Length of our Configuration Information */ - ipcp_addci, /* Add our Configuration Information */ - ipcp_ackci, /* ACK our Configuration Information */ - ipcp_nakci, /* NAK our Configuration Information */ - ipcp_rejci, /* Reject our Configuration Information */ - ipcp_reqci, /* Request peer's Configuration Information */ - ipcp_up, /* Called when fsm reaches OPENED state */ - ipcp_down, /* Called when fsm leaves OPENED state */ - NULL, /* Called when we want the lower layer up */ - ipcp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - NULL, /* Called to handle protocol-specific codes */ - "IPCP" /* String name of protocol */ -}; - -/* - * Command-line options. - */ -static int setvjslots __P((char **)); -static int setdnsaddr __P((char **)); -static int setwinsaddr __P((char **)); -static int setnetmask __P((char **)); -static int setipaddr __P((char *, char **, int)); -static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *)); - -static option_t ipcp_option_list[] = { - { "noip", o_bool, &ipcp_protent.enabled_flag, - "Disable IP and IPCP" }, - { "-ip", o_bool, &ipcp_protent.enabled_flag, - "Disable IP and IPCP", OPT_ALIAS }, - - { "novj", o_bool, &ipcp_wantoptions[0].neg_vj, - "Disable VJ compression", OPT_A2CLR, &ipcp_allowoptions[0].neg_vj }, - { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj, - "Disable VJ compression", OPT_ALIAS | OPT_A2CLR, - &ipcp_allowoptions[0].neg_vj }, - - { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag, - "Disable VJ connection-ID compression", OPT_A2CLR, - &ipcp_allowoptions[0].cflag }, - { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag, - "Disable VJ connection-ID compression", OPT_ALIAS | OPT_A2CLR, - &ipcp_allowoptions[0].cflag }, - - { "vj-max-slots", o_special, (void *)setvjslots, - "Set maximum VJ header slots", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, vj_value }, - - { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local, - "Accept peer's address for us", 1 }, - { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote, - "Accept peer's address for it", 1 }, - - { "ipparam", o_string, &ipparam, - "Set ip script parameter", OPT_PRIO }, - - { "noipdefault", o_bool, &disable_defaultip, - "Don't use name for default IP adrs", 1 }, - - { "ms-dns", 1, (void *)setdnsaddr, - "DNS address for the peer's use" }, - { "ms-wins", 1, (void *)setwinsaddr, - "Nameserver for SMB over TCP/IP for peer" }, - - { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime, - "Set timeout for IPCP", OPT_PRIO }, - { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits, - "Set max #xmits for term-reqs", OPT_PRIO }, - { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits, - "Set max #xmits for conf-reqs", OPT_PRIO }, - { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops, - "Set max #conf-naks for IPCP", OPT_PRIO }, - - { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route, - "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route }, - { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route, - "disable defaultroute option", OPT_A2CLR, - &ipcp_wantoptions[0].default_route }, - { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route, - "disable defaultroute option", OPT_ALIAS | OPT_A2CLR, - &ipcp_wantoptions[0].default_route }, - - { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp, - "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp }, - { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, - "disable proxyarp option", OPT_A2CLR, - &ipcp_wantoptions[0].proxy_arp }, - { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, - "disable proxyarp option", OPT_ALIAS | OPT_A2CLR, - &ipcp_wantoptions[0].proxy_arp }, - - { "usepeerdns", o_bool, &usepeerdns, - "Ask peer for DNS address(es)", 1 }, - - { "netmask", o_special, (void *)setnetmask, - "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str }, - - { "IP addresses", o_wild, (void *) &setipaddr, - "set local and remote IP addresses", - OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr }, - - { NULL } -}; - -/* - * Protocol entry points from main code. - */ -static void ipcp_init __P((int)); -static void ipcp_open __P((int)); -static void ipcp_close __P((int, char *)); -static void ipcp_lowerup __P((int)); -static void ipcp_lowerdown __P((int)); -static void ipcp_input __P((int, u_char *, int)); -static void ipcp_protrej __P((int)); -static int ipcp_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); -static void ip_check_options __P((void)); -static int ip_demand_conf __P((int)); -static int ip_active_pkt __P((u_char *, int)); -static void create_resolv __P((u_int32_t, u_int32_t)); - -struct protent ipcp_protent = { - PPP_IPCP, - ipcp_init, - ipcp_input, - ipcp_protrej, - ipcp_lowerup, - ipcp_lowerdown, - ipcp_open, - ipcp_close, - ipcp_printpkt, - NULL, - 1, - "IPCP", - "IP", - ipcp_option_list, - ip_check_options, - ip_demand_conf, - ip_active_pkt -}; - -static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t)); -static void ipcp_script __P((char *)); /* Run an up/down script */ -static void ipcp_script_done __P((void *)); - -/* - * Lengths of configuration options. - */ -#define CILEN_VOID 2 -#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ -#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ -#define CILEN_ADDR 6 /* new-style single address option */ -#define CILEN_ADDRS 10 /* old-style dual address option */ - - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - -/* - * This state variable is used to ensure that we don't - * run an ipcp-up/down script while one is already running. - */ -static enum script_state { - s_down, - s_up, -} ipcp_script_state; -static pid_t ipcp_script_pid; - -/* - * Make a string representation of a network IP address. - */ -char * -ip_ntoa(ipaddr) -u_int32_t ipaddr; -{ - static char b[64]; - - slprintf(b, sizeof(b), "%I", ipaddr); - return b; -} - -/* - * Option parsing. - */ - -/* - * setvjslots - set maximum number of connection slots for VJ compression - */ -static int -setvjslots(argv) - char **argv; -{ - int value; - - if (!int_option(*argv, &value)) - return 0; - if (value < 2 || value > 16) { - option_error("vj-max-slots value must be between 2 and 16"); - return 0; - } - ipcp_wantoptions [0].maxslotindex = - ipcp_allowoptions[0].maxslotindex = value - 1; - slprintf(vj_value, sizeof(vj_value), "%d", value); - return 1; -} - -/* - * setdnsaddr - set the dns address(es) - */ -static int -setdnsaddr(argv) - char **argv; -{ - u_int32_t dns; - struct hostent *hp; - - dns = inet_addr(*argv); - if (dns == (u_int32_t) -1) { - if ((hp = gethostbyname(*argv)) == NULL) { - option_error("invalid address parameter '%s' for ms-dns option", - *argv); - return 0; - } - dns = *(u_int32_t *)hp->h_addr; - } - - /* We take the last 2 values given, the 2nd-last as the primary - and the last as the secondary. If only one is given it - becomes both primary and secondary. */ - if (ipcp_allowoptions[0].dnsaddr[1] == 0) - ipcp_allowoptions[0].dnsaddr[0] = dns; - else - ipcp_allowoptions[0].dnsaddr[0] = ipcp_allowoptions[0].dnsaddr[1]; - - /* always set the secondary address value. */ - ipcp_allowoptions[0].dnsaddr[1] = dns; - - return (1); -} - -/* - * setwinsaddr - set the wins address(es) - * This is primrarly used with the Samba package under UNIX or for pointing - * the caller to the existing WINS server on a Windows NT platform. - */ -static int -setwinsaddr(argv) - char **argv; -{ - u_int32_t wins; - struct hostent *hp; - - wins = inet_addr(*argv); - if (wins == (u_int32_t) -1) { - if ((hp = gethostbyname(*argv)) == NULL) { - option_error("invalid address parameter '%s' for ms-wins option", - *argv); - return 0; - } - wins = *(u_int32_t *)hp->h_addr; - } - - /* We take the last 2 values given, the 2nd-last as the primary - and the last as the secondary. If only one is given it - becomes both primary and secondary. */ - if (ipcp_allowoptions[0].winsaddr[1] == 0) - ipcp_allowoptions[0].winsaddr[0] = wins; - else - ipcp_allowoptions[0].winsaddr[0] = ipcp_allowoptions[0].winsaddr[1]; - - /* always set the secondary address value. */ - ipcp_allowoptions[0].winsaddr[1] = wins; - - return (1); -} - -/* - * setipaddr - Set the IP address - * If doit is 0, the call is to check whether this option is - * potentially an IP address specification. - */ -static int -setipaddr(arg, argv, doit) - char *arg; - char **argv; - int doit; -{ - struct hostent *hp; - char *colon; - u_int32_t local, remote; - ipcp_options *wo = &ipcp_wantoptions[0]; - static int prio_local = 0, prio_remote = 0; - - /* - * IP address pair separated by ":". - */ - if ((colon = strchr(arg, ':')) == NULL) - return 0; - if (!doit) - return 1; - - /* - * If colon first character, then no local addr. - */ - if (colon != arg && option_priority >= prio_local) { - *colon = '\0'; - if ((local = inet_addr(arg)) == (u_int32_t) -1) { - if ((hp = gethostbyname(arg)) == NULL) { - option_error("unknown host: %s", arg); - return 0; - } - local = *(u_int32_t *)hp->h_addr; - } - if (bad_ip_adrs(local)) { - option_error("bad local IP address %s", ip_ntoa(local)); - return 0; - } - if (local != 0) - wo->ouraddr = local; - *colon = ':'; - prio_local = option_priority; - } - - /* - * If colon last character, then no remote addr. - */ - if (*++colon != '\0' && option_priority >= prio_remote) { - if ((remote = inet_addr(colon)) == (u_int32_t) -1) { - if ((hp = gethostbyname(colon)) == NULL) { - option_error("unknown host: %s", colon); - return 0; - } - remote = *(u_int32_t *)hp->h_addr; - if (remote_name[0] == 0) - strlcpy(remote_name, colon, sizeof(remote_name)); - } - if (bad_ip_adrs(remote)) { - option_error("bad remote IP address %s", ip_ntoa(remote)); - return 0; - } - if (remote != 0) - wo->hisaddr = remote; - prio_remote = option_priority; - } - - return 1; -} - -static void -printipaddr(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - ipcp_options *wo = &ipcp_wantoptions[0]; - - if (wo->ouraddr != 0) - printer(arg, "%I", wo->ouraddr); - printer(arg, ":"); - if (wo->hisaddr != 0) - printer(arg, "%I", wo->hisaddr); -} - -/* - * setnetmask - set the netmask to be used on the interface. - */ -static int -setnetmask(argv) - char **argv; -{ - u_int32_t mask; - int n; - char *p; - - /* - * Unfortunately, if we use inet_addr, we can't tell whether - * a result of all 1s is an error or a valid 255.255.255.255. - */ - p = *argv; - n = parse_dotted_ip(p, &mask); - - mask = htonl(mask); - - if (n == 0 || p[n] != 0 || (netmask & ~mask) != 0) { - option_error("invalid netmask value '%s'", *argv); - return 0; - } - - netmask = mask; - slprintf(netmask_str, sizeof(netmask_str), "%I", mask); - - return (1); -} - -int -parse_dotted_ip(p, vp) - char *p; - u_int32_t *vp; -{ - int n; - u_int32_t v, b; - char *endp, *p0 = p; - - v = 0; - for (n = 3;; --n) { - b = strtoul(p, &endp, 0); - if (endp == p) - return 0; - if (b > 255) { - if (n < 3) - return 0; - /* accept e.g. 0xffffff00 */ - *vp = b; - return endp - p0; - } - v |= b << (n * 8); - p = endp; - if (n == 0) - break; - if (*p != '.') - return 0; - ++p; - } - *vp = v; - return p - p0; -} - - -/* - * ipcp_init - Initialize IPCP. - */ -static void -ipcp_init(unit) - int unit; -{ - fsm *f = &ipcp_fsm[unit]; - ipcp_options *wo = &ipcp_wantoptions[unit]; - ipcp_options *ao = &ipcp_allowoptions[unit]; - - f->unit = unit; - f->protocol = PPP_IPCP; - f->callbacks = &ipcp_callbacks; - fsm_init(&ipcp_fsm[unit]); - - memset(wo, 0, sizeof(*wo)); - memset(ao, 0, sizeof(*ao)); - - wo->neg_addr = 1; - wo->neg_vj = 1; - wo->vj_protocol = IPCP_VJ_COMP; - wo->maxslotindex = MAX_STATES - 1; /* really max index */ - wo->cflag = 1; - - - /* max slots and slot-id compression are currently hardwired in */ - /* ppp_if.c to 16 and 1, this needs to be changed (among other */ - /* things) gmc */ - - ao->neg_addr = 1; - ao->neg_vj = 1; - ao->maxslotindex = MAX_STATES - 1; - ao->cflag = 1; - - /* - * XXX These control whether the user may use the proxyarp - * and defaultroute options. - */ - ao->proxy_arp = 1; - ao->default_route = 1; -} - - -/* - * ipcp_open - IPCP is allowed to come up. - */ -static void -ipcp_open(unit) - int unit; -{ - fsm_open(&ipcp_fsm[unit]); -} - - -/* - * ipcp_close - Take IPCP down. - */ -static void -ipcp_close(unit, reason) - int unit; - char *reason; -{ - fsm_close(&ipcp_fsm[unit], reason); -} - - -/* - * ipcp_lowerup - The lower layer is up. - */ -static void -ipcp_lowerup(unit) - int unit; -{ - fsm_lowerup(&ipcp_fsm[unit]); -} - - -/* - * ipcp_lowerdown - The lower layer is down. - */ -static void -ipcp_lowerdown(unit) - int unit; -{ - fsm_lowerdown(&ipcp_fsm[unit]); -} - - -/* - * ipcp_input - Input IPCP packet. - */ -static void -ipcp_input(unit, p, len) - int unit; - u_char *p; - int len; -{ - fsm_input(&ipcp_fsm[unit], p, len); -} - - -/* - * ipcp_protrej - A Protocol-Reject was received for IPCP. - * - * Pretend the lower layer went down, so we shut up. - */ -static void -ipcp_protrej(unit) - int unit; -{ - fsm_lowerdown(&ipcp_fsm[unit]); -} - - -/* - * ipcp_resetci - Reset our CI. - * Called by fsm_sconfreq, Send Configure Request. - */ -static void -ipcp_resetci(f) - fsm *f; -{ - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - ipcp_options *go = &ipcp_gotoptions[f->unit]; - - wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr; - if (wo->ouraddr == 0) - wo->accept_local = 1; - if (wo->hisaddr == 0) - wo->accept_remote = 1; - wo->req_dns1 = usepeerdns; /* Request DNS addresses from the peer */ - wo->req_dns2 = usepeerdns; - *go = *wo; - if (!ask_for_local) - go->ouraddr = 0; - if (ip_choose_hook) - ip_choose_hook(&wo->hisaddr); -} - - -/* - * ipcp_cilen - Return length of our CI. - * Called by fsm_sconfreq, Send Configure Request. - */ -static int -ipcp_cilen(f) - fsm *f; -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; - -#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) -#define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0) -#define LENCIDNS(neg) (neg ? (CILEN_ADDR) : 0) - - /* - * First see if we want to change our options to the old - * forms because we have received old forms from the peer. - */ - if (wo->neg_addr && !go->neg_addr && !go->old_addrs) { - /* use the old style of address negotiation */ - go->neg_addr = 1; - go->old_addrs = 1; - } - if (wo->neg_vj && !go->neg_vj && !go->old_vj) { - /* try an older style of VJ negotiation */ - /* use the old style only if the peer did */ - if (ho->neg_vj && ho->old_vj) { - go->neg_vj = 1; - go->old_vj = 1; - go->vj_protocol = ho->vj_protocol; - } - } - - return (LENCIADDR(go->neg_addr, go->old_addrs) + - LENCIVJ(go->neg_vj, go->old_vj) + - LENCIDNS(go->req_dns1) + - LENCIDNS(go->req_dns2)) ; -} - - -/* - * ipcp_addci - Add our desired CIs to a packet. - * Called by fsm_sconfreq, Send Configure Request. - */ -static void -ipcp_addci(f, ucp, lenp) - fsm *f; - u_char *ucp; - int *lenp; -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - int len = *lenp; - -#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ - if (neg) { \ - int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ - if (len >= vjlen) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(vjlen, ucp); \ - PUTSHORT(val, ucp); \ - if (!old) { \ - PUTCHAR(maxslotindex, ucp); \ - PUTCHAR(cflag, ucp); \ - } \ - len -= vjlen; \ - } else \ - neg = 0; \ - } - -#define ADDCIADDR(opt, neg, old, val1, val2) \ - if (neg) { \ - int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ - if (len >= addrlen) { \ - u_int32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(addrlen, ucp); \ - l = ntohl(val1); \ - PUTLONG(l, ucp); \ - if (old) { \ - l = ntohl(val2); \ - PUTLONG(l, ucp); \ - } \ - len -= addrlen; \ - } else \ - neg = 0; \ - } - -#define ADDCIDNS(opt, neg, addr) \ - if (neg) { \ - if (len >= CILEN_ADDR) { \ - u_int32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_ADDR, ucp); \ - l = ntohl(addr); \ - PUTLONG(l, ucp); \ - len -= CILEN_ADDR; \ - } else \ - neg = 0; \ - } - - ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, - go->old_addrs, go->ouraddr, go->hisaddr); - - ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); - - ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); - - ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); - - *lenp -= len; -} - - -/* - * ipcp_ackci - Ack our CIs. - * Called by fsm_rconfack, Receive Configure ACK. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int -ipcp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_short cilen, citype, cishort; - u_int32_t cilong; - u_char cimaxslotindex, cicflag; - - /* - * CIs must be in exactly the same order that we sent... - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ - -#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ - if (neg) { \ - int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ - if ((len -= vjlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != vjlen || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - if (!old) { \ - GETCHAR(cimaxslotindex, p); \ - if (cimaxslotindex != maxslotindex) \ - goto bad; \ - GETCHAR(cicflag, p); \ - if (cicflag != cflag) \ - goto bad; \ - } \ - } - -#define ACKCIADDR(opt, neg, old, val1, val2) \ - if (neg) { \ - int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ - u_int32_t l; \ - if ((len -= addrlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != addrlen || \ - citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = htonl(l); \ - if (val1 != cilong) \ - goto bad; \ - if (old) { \ - GETLONG(l, p); \ - cilong = htonl(l); \ - if (val2 != cilong) \ - goto bad; \ - } \ - } - -#define ACKCIDNS(opt, neg, addr) \ - if (neg) { \ - u_int32_t l; \ - if ((len -= CILEN_ADDR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_ADDR || citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = htonl(l); \ - if (addr != cilong) \ - goto bad; \ - } - - ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, - go->old_addrs, go->ouraddr, go->hisaddr); - - ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); - - ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); - - ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); - -bad: - IPCPDEBUG(("ipcp_ackci: received bad Ack!")); - return (0); -} - -/* - * ipcp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if IPCP is in the OPENED state. - * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int -ipcp_nakci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_char cimaxslotindex, cicflag; - u_char citype, cilen, *next; - u_short cishort; - u_int32_t ciaddr1, ciaddr2, l, cidnsaddr; - ipcp_options no; /* options we've seen Naks for */ - ipcp_options try; /* options to request next time */ - - BZERO(&no, sizeof(no)); - try = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIADDR(opt, neg, old, code) \ - if (go->neg && \ - len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \ - p[1] == cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - ciaddr1 = htonl(l); \ - if (old) { \ - GETLONG(l, p); \ - ciaddr2 = htonl(l); \ - no.old_addrs = 1; \ - } else \ - ciaddr2 = 0; \ - no.neg = 1; \ - code \ - } - -#define NAKCIVJ(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } - -#define NAKCIDNS(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cidnsaddr = htonl(l); \ - no.neg = 1; \ - code \ - } - - /* - * Accept the peer's idea of {our,his} address, if different - * from our idea, only if the accept_{local,remote} flag is set. - */ - NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs, - if (go->accept_local && ciaddr1) { /* Do we know our address? */ - try.ouraddr = ciaddr1; - } - if (go->accept_remote && ciaddr2) { /* Does he know his? */ - try.hisaddr = ciaddr2; - } - ); - - /* - * Accept the peer's value of maxslotindex provided that it - * is less than what we asked for. Turn off slot-ID compression - * if the peer wants. Send old-style compress-type option if - * the peer wants. - */ - NAKCIVJ(CI_COMPRESSTYPE, neg_vj, - if (cilen == CILEN_VJ) { - GETCHAR(cimaxslotindex, p); - GETCHAR(cicflag, p); - if (cishort == IPCP_VJ_COMP) { - try.old_vj = 0; - if (cimaxslotindex < go->maxslotindex) - try.maxslotindex = cimaxslotindex; - if (!cicflag) - try.cflag = 0; - } else { - try.neg_vj = 0; - } - } else { - if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { - try.old_vj = 1; - try.vj_protocol = cishort; - } else { - try.neg_vj = 0; - } - } - ); - - NAKCIDNS(CI_MS_DNS1, req_dns1, - try.dnsaddr[0] = cidnsaddr; - ); - - NAKCIDNS(CI_MS_DNS2, req_dns2, - try.dnsaddr[1] = cidnsaddr; - ); - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If they want to negotiate about IP addresses, we comply. - * If they want us to ask for compression, we refuse. - */ - while (len > CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if( (len -= cilen) < 0 ) - goto bad; - next = p + cilen - 2; - - switch (citype) { - case CI_COMPRESSTYPE: - if (go->neg_vj || no.neg_vj || - (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) - goto bad; - no.neg_vj = 1; - break; - case CI_ADDRS: - if ((go->neg_addr && go->old_addrs) || no.old_addrs - || cilen != CILEN_ADDRS) - goto bad; - try.neg_addr = 1; - try.old_addrs = 1; - GETLONG(l, p); - ciaddr1 = htonl(l); - if (ciaddr1 && go->accept_local) - try.ouraddr = ciaddr1; - GETLONG(l, p); - ciaddr2 = htonl(l); - if (ciaddr2 && go->accept_remote) - try.hisaddr = ciaddr2; - no.old_addrs = 1; - break; - case CI_ADDR: - if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) - goto bad; - try.old_addrs = 0; - GETLONG(l, p); - ciaddr1 = htonl(l); - if (ciaddr1 && go->accept_local) - try.ouraddr = ciaddr1; - if (try.ouraddr != 0) - try.neg_addr = 1; - no.neg_addr = 1; - break; - } - p = next; - } - - /* - * OK, the Nak is good. Now we can update state. - * If there are any remaining options, we ignore them. - */ - if (f->state != OPENED) - *go = try; - - return 1; - -bad: - IPCPDEBUG(("ipcp_nakci: received bad Nak!")); - return 0; -} - - -/* - * ipcp_rejci - Reject some of our CIs. - * Callback from fsm_rconfnakrej. - */ -static int -ipcp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_char cimaxslotindex, ciflag, cilen; - u_short cishort; - u_int32_t cilong; - ipcp_options try; /* options to request next time */ - - try = *go; - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIADDR(opt, neg, old, val1, val2) \ - if (go->neg && \ - len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \ - p[1] == cilen && \ - p[0] == opt) { \ - u_int32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val1) \ - goto bad; \ - if (old) { \ - GETLONG(l, p); \ - cilong = htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val2) \ - goto bad; \ - } \ - try.neg = 0; \ - } - -#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ - if (go->neg && \ - p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ - len >= p[1] && \ - p[0] == opt) { \ - len -= p[1]; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) \ - goto bad; \ - if (!old) { \ - GETCHAR(cimaxslotindex, p); \ - if (cimaxslotindex != maxslot) \ - goto bad; \ - GETCHAR(ciflag, p); \ - if (ciflag != cflag) \ - goto bad; \ - } \ - try.neg = 0; \ - } - -#define REJCIDNS(opt, neg, dnsaddr) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - u_int32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = htonl(l); \ - /* Check rejected value. */ \ - if (cilong != dnsaddr) \ - goto bad; \ - try.neg = 0; \ - } - - - REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, - go->old_addrs, go->ouraddr, go->hisaddr); - - REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); - - REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); - - REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - /* - * Now we can update state. - */ - if (f->state != OPENED) - *go = try; - return 1; - -bad: - IPCPDEBUG(("ipcp_rejci: received bad Reject!")); - return 0; -} - - -/* - * ipcp_reqci - Check the peer's requested CIs and send appropriate response. - * Callback from fsm_rconfreq, Receive Configure Request - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - */ -static int -ipcp_reqci(f, inp, len, reject_if_disagree) - fsm *f; - u_char *inp; /* Requested CIs */ - int *len; /* Length of requested CIs */ - int reject_if_disagree; -{ - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; - ipcp_options *ao = &ipcp_allowoptions[f->unit]; - ipcp_options *go = &ipcp_gotoptions[f->unit]; - u_char *cip, *next; /* Pointer to current and next CIs */ - u_short cilen, citype; /* Parsed len, type */ - u_short cishort; /* Parsed short value */ - u_int32_t tl, ciaddr1, ciaddr2;/* Parsed address values */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *ucp = inp; /* Pointer to current output char */ - int l = *len; /* Length left */ - u_char maxslotindex, cflag; - int d; - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - IPCPDEBUG(("ipcp_reqci: bad CI length!")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ - case CI_ADDRS: - if (!ao->neg_addr || - cilen != CILEN_ADDRS) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no address, or if we both have his address but - * disagree about it, then NAK it with our idea. - * In particular, if we don't know his address, but he does, - * then accept it. - */ - GETLONG(tl, p); /* Parse source address (his) */ - ciaddr1 = htonl(tl); - if (ciaddr1 != wo->hisaddr - && (ciaddr1 == 0 || !wo->accept_remote)) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u_int32_t), p); - tl = ntohl(wo->hisaddr); - PUTLONG(tl, p); - } - } else if (ciaddr1 == 0 && wo->hisaddr == 0) { - /* - * If neither we nor he knows his address, reject the option. - */ - orc = CONFREJ; - wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ - break; - } - - /* - * If he doesn't know our address, or if we both have our address - * but disagree about it, then NAK it with our idea. - */ - GETLONG(tl, p); /* Parse desination address (ours) */ - ciaddr2 = htonl(tl); - if (ciaddr2 != wo->ouraddr) { - if (ciaddr2 == 0 || !wo->accept_local) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u_int32_t), p); - tl = ntohl(wo->ouraddr); - PUTLONG(tl, p); - } - } else { - go->ouraddr = ciaddr2; /* accept peer's idea */ - } - } - - ho->neg_addr = 1; - ho->old_addrs = 1; - ho->hisaddr = ciaddr1; - ho->ouraddr = ciaddr2; - break; - - case CI_ADDR: - if (!ao->neg_addr || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no address, or if we both have his address but - * disagree about it, then NAK it with our idea. - * In particular, if we don't know his address, but he does, - * then accept it. - */ - GETLONG(tl, p); /* Parse source address (his) */ - ciaddr1 = htonl(tl); - if (ciaddr1 != wo->hisaddr - && (ciaddr1 == 0 || !wo->accept_remote)) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u_int32_t), p); - tl = ntohl(wo->hisaddr); - PUTLONG(tl, p); - } - } else if (ciaddr1 == 0 && wo->hisaddr == 0) { - /* - * Don't ACK an address of 0.0.0.0 - reject it instead. - */ - orc = CONFREJ; - wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ - break; - } - - ho->neg_addr = 1; - ho->hisaddr = ciaddr1; - break; - - case CI_MS_DNS1: - case CI_MS_DNS2: - /* Microsoft primary or secondary DNS request */ - d = citype == CI_MS_DNS2; - - /* If we do not have a DNS address then we cannot send it */ - if (ao->dnsaddr[d] == 0 || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETLONG(tl, p); - if (htonl(tl) != ao->dnsaddr[d]) { - DECPTR(sizeof(u_int32_t), p); - tl = ntohl(ao->dnsaddr[d]); - PUTLONG(tl, p); - orc = CONFNAK; - } - break; - - case CI_MS_WINS1: - case CI_MS_WINS2: - /* Microsoft primary or secondary WINS request */ - d = citype == CI_MS_WINS2; - - /* If we do not have a DNS address then we cannot send it */ - if (ao->winsaddr[d] == 0 || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETLONG(tl, p); - if (htonl(tl) != ao->winsaddr[d]) { - DECPTR(sizeof(u_int32_t), p); - tl = ntohl(ao->winsaddr[d]); - PUTLONG(tl, p); - orc = CONFNAK; - } - break; - - case CI_COMPRESSTYPE: - if (!ao->neg_vj || - (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - - if (!(cishort == IPCP_VJ_COMP || - (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { - orc = CONFREJ; - break; - } - - ho->neg_vj = 1; - ho->vj_protocol = cishort; - if (cilen == CILEN_VJ) { - GETCHAR(maxslotindex, p); - if (maxslotindex > ao->maxslotindex) { - orc = CONFNAK; - if (!reject_if_disagree){ - DECPTR(1, p); - PUTCHAR(ao->maxslotindex, p); - } - } - GETCHAR(cflag, p); - if (cflag && !ao->cflag) { - orc = CONFNAK; - if (!reject_if_disagree){ - DECPTR(1, p); - PUTCHAR(wo->cflag, p); - } - } - ho->maxslotindex = maxslotindex; - ho->cflag = cflag; - } else { - ho->old_vj = 1; - ho->maxslotindex = MAX_STATES - 1; - ho->cflag = 1; - } - break; - - default: - orc = CONFREJ; - break; - } -endswitch: - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) /* but prior CI wasnt? */ - continue; /* Don't send this one */ - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree) /* Getting fed up with sending NAKs? */ - orc = CONFREJ; /* Get tough if so */ - else { - if (rc == CONFREJ) /* Rejecting prior CI? */ - continue; /* Don't send this one */ - if (rc == CONFACK) { /* Ack'd all prior CIs? */ - rc = CONFNAK; /* Not anymore... */ - ucp = inp; /* Backup */ - } - } - } - - if (orc == CONFREJ && /* Reject this CI */ - rc != CONFREJ) { /* but no prior ones? */ - rc = CONFREJ; - ucp = inp; /* Backup */ - } - - /* Need to move CI? */ - if (ucp != cip) - BCOPY(cip, ucp, cilen); /* Move it */ - - /* Update output pointer */ - INCPTR(cilen, ucp); - } - - /* - * If we aren't rejecting this packet, and we want to negotiate - * their address, and they didn't send their address, then we - * send a NAK with a CI_ADDR option appended. We assume the - * input buffer is long enough that we can append the extra - * option safely. - */ - if (rc != CONFREJ && !ho->neg_addr && - wo->req_addr && !reject_if_disagree) { - if (rc == CONFACK) { - rc = CONFNAK; - ucp = inp; /* reset pointer */ - wo->req_addr = 0; /* don't ask again */ - } - PUTCHAR(CI_ADDR, ucp); - PUTCHAR(CILEN_ADDR, ucp); - tl = ntohl(wo->hisaddr); - PUTLONG(tl, ucp); - } - - *len = ucp - inp; /* Compute output length */ - IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc))); - return (rc); /* Return final code */ -} - - -/* - * ip_check_options - check that any IP-related options are OK, - * and assign appropriate defaults. - */ -static void -ip_check_options() -{ - struct hostent *hp; - u_int32_t local; - ipcp_options *wo = &ipcp_wantoptions[0]; - - /* - * Default our local IP address based on our hostname. - * If local IP address already given, don't bother. - */ - if (wo->ouraddr == 0 && !disable_defaultip) { - /* - * Look up our hostname (possibly with domain name appended) - * and take the first IP address as our local IP address. - * If there isn't an IP address for our hostname, too bad. - */ - wo->accept_local = 1; /* don't insist on this default value */ - if ((hp = gethostbyname(hostname)) != NULL) { - local = *(u_int32_t *)hp->h_addr; - if (local != 0 && !bad_ip_adrs(local)) - wo->ouraddr = local; - } - } - ask_for_local = wo->ouraddr != 0 || !disable_defaultip; -} - - -/* - * ip_demand_conf - configure the interface as though - * IPCP were up, for use with dial-on-demand. - */ -static int -ip_demand_conf(u) - int u; -{ - ipcp_options *wo = &ipcp_wantoptions[u]; - - if (wo->hisaddr == 0) { - /* make up an arbitrary address for the peer */ - wo->hisaddr = htonl(0x0a707070 + ifunit); - wo->accept_remote = 1; - } - if (wo->ouraddr == 0) { - /* make up an arbitrary address for us */ - wo->ouraddr = htonl(0x0a404040 + ifunit); - wo->accept_local = 1; - ask_for_local = 0; /* don't tell the peer this address */ - } - if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) - return 0; - if (!sifup(u)) - return 0; - if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) - return 0; - if (wo->default_route) - if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr)) - default_route_set[u] = 1; - if (wo->proxy_arp) - if (sifproxyarp(u, wo->hisaddr)) - proxy_arp_set[u] = 1; - - notice("local IP address %I", wo->ouraddr); - notice("remote IP address %I", wo->hisaddr); - - return 1; -} - - -/* - * ipcp_up - IPCP has come UP. - * - * Configure the IP network interface appropriately and bring it up. - */ -static void -ipcp_up(f) - fsm *f; -{ - u_int32_t mask; - ipcp_options *ho = &ipcp_hisoptions[f->unit]; - ipcp_options *go = &ipcp_gotoptions[f->unit]; - ipcp_options *wo = &ipcp_wantoptions[f->unit]; - - IPCPDEBUG(("ipcp: up")); - - /* - * We must have a non-zero IP address for both ends of the link. - */ - if (!ho->neg_addr) - ho->hisaddr = wo->hisaddr; - - if (go->ouraddr == 0) { - error("Could not determine local IP address"); - ipcp_close(f->unit, "Could not determine local IP address"); - return; - } - if (ho->hisaddr == 0) { - ho->hisaddr = htonl(0x0a404040 + ifunit); - warn("Could not determine remote IP address: defaulting to %I", - ho->hisaddr); - } - script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0); - script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1); - - if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { - script_setenv("USEPEERDNS", "1", 0); - if (go->dnsaddr[0]) - script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0); - if (go->dnsaddr[1]) - script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); - create_resolv(go->dnsaddr[0], go->dnsaddr[1]); - } - - /* - * Check that the peer is allowed to use the IP address it wants. - */ - if (!auth_ip_addr(f->unit, ho->hisaddr)) { - error("Peer is not authorized to use remote address %I", ho->hisaddr); - ipcp_close(f->unit, "Unauthorized remote IP address"); - return; - } - - /* set tcp compression */ - sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); - - /* - * If we are doing dial-on-demand, the interface is already - * configured, so we put out any saved-up packets, then set the - * interface to pass IP packets. - */ - if (demand) { - if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { - ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr); - if (go->ouraddr != wo->ouraddr) { - warn("Local IP address changed to %I", go->ouraddr); - script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); - wo->ouraddr = go->ouraddr; - } else - script_unsetenv("OLDIPLOCAL"); - if (ho->hisaddr != wo->hisaddr) { - warn("Remote IP address changed to %I", ho->hisaddr); - script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0); - wo->hisaddr = ho->hisaddr; - } else - script_unsetenv("OLDIPREMOTE"); - - /* Set the interface to the new addresses */ - mask = GetMask(go->ouraddr); - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { - if (debug) - warn("Interface configuration failed"); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } - - /* assign a default route through the interface if required */ - if (ipcp_wantoptions[f->unit].default_route) - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) - default_route_set[f->unit] = 1; - - /* Make a proxy ARP entry if requested. */ - if (ipcp_wantoptions[f->unit].proxy_arp) - if (sifproxyarp(f->unit, ho->hisaddr)) - proxy_arp_set[f->unit] = 1; - - } - demand_rexmit(PPP_IP); - sifnpmode(f->unit, PPP_IP, NPMODE_PASS); - - } else { - /* - * Set IP addresses and (if specified) netmask. - */ - mask = GetMask(go->ouraddr); - -#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { - if (debug) - warn("Interface configuration failed"); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } -#endif - - /* bring the interface up for IP */ - if (!sifup(f->unit)) { - if (debug) - warn("Interface failed to come up"); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } - -#if (defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { - if (debug) - warn("Interface configuration failed"); - ipcp_close(f->unit, "Interface configuration failed"); - return; - } -#endif - sifnpmode(f->unit, PPP_IP, NPMODE_PASS); - - /* assign a default route through the interface if required */ - if (ipcp_wantoptions[f->unit].default_route) - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) - default_route_set[f->unit] = 1; - - /* Make a proxy ARP entry if requested. */ - if (ipcp_wantoptions[f->unit].proxy_arp) - if (sifproxyarp(f->unit, ho->hisaddr)) - proxy_arp_set[f->unit] = 1; - - ipcp_wantoptions[0].ouraddr = go->ouraddr; - - notice("local IP address %I", go->ouraddr); - notice("remote IP address %I", ho->hisaddr); - if (go->dnsaddr[0]) - notice("primary DNS address %I", go->dnsaddr[0]); - if (go->dnsaddr[1]) - notice("secondary DNS address %I", go->dnsaddr[1]); - } - - np_up(f->unit, PPP_IP); - ipcp_is_up = 1; - - if (ip_up_hook) - ip_up_hook(); - - /* - * Execute the ip-up script, like this: - * /etc/ppp/ip-up interface tty speed local-IP remote-IP - */ - if (ipcp_script_state == s_down && ipcp_script_pid == 0) { - ipcp_script_state = s_up; - ipcp_script(_PATH_IPUP); - } -} - - -/* - * ipcp_down - IPCP has gone DOWN. - * - * Take the IP network interface down, clear its addresses - * and delete routes through it. - */ -static void -ipcp_down(f) - fsm *f; -{ - IPCPDEBUG(("ipcp: down")); - /* XXX a bit IPv4-centric here, we only need to get the stats - * before the interface is marked down. */ - update_link_stats(f->unit); - if (ip_down_hook) - ip_down_hook(); - if (ipcp_is_up) { - ipcp_is_up = 0; - np_down(f->unit, PPP_IP); - } - sifvjcomp(f->unit, 0, 0, 0); - - /* - * If we are doing dial-on-demand, set the interface - * to queue up outgoing packets (for now). - */ - if (demand) { - sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE); - } else { - sifnpmode(f->unit, PPP_IP, NPMODE_DROP); - sifdown(f->unit); - ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr, - ipcp_hisoptions[f->unit].hisaddr); - } - - /* Execute the ip-down script */ - if (ipcp_script_state == s_up && ipcp_script_pid == 0) { - ipcp_script_state = s_down; - ipcp_script(_PATH_IPDOWN); - } -} - - -/* - * ipcp_clear_addrs() - clear the interface addresses, routes, - * proxy arp entries, etc. - */ -static void -ipcp_clear_addrs(unit, ouraddr, hisaddr) - int unit; - u_int32_t ouraddr; /* local address */ - u_int32_t hisaddr; /* remote address */ -{ - if (proxy_arp_set[unit]) { - cifproxyarp(unit, hisaddr); - proxy_arp_set[unit] = 0; - } - if (default_route_set[unit]) { - cifdefaultroute(unit, ouraddr, hisaddr); - default_route_set[unit] = 0; - } - cifaddr(unit, ouraddr, hisaddr); -} - - -/* - * ipcp_finished - possibly shut down the lower layers. - */ -static void -ipcp_finished(f) - fsm *f; -{ - np_finished(f->unit, PPP_IP); -} - - -/* - * ipcp_script_done - called when the ip-up or ip-down script - * has finished. - */ -static void -ipcp_script_done(arg) - void *arg; -{ - ipcp_script_pid = 0; - switch (ipcp_script_state) { - case s_up: - if (ipcp_fsm[0].state != OPENED) { - ipcp_script_state = s_down; - ipcp_script(_PATH_IPDOWN); - } - break; - case s_down: - if (ipcp_fsm[0].state == OPENED) { - ipcp_script_state = s_up; - ipcp_script(_PATH_IPUP); - } - break; - } -} - - -/* - * ipcp_script - Execute a script with arguments - * interface-name tty-name speed local-IP remote-IP. - */ -static void -ipcp_script(script) - char *script; -{ - char strspeed[32], strlocal[32], strremote[32]; - char *argv[8]; - - slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); - slprintf(strlocal, sizeof(strlocal), "%I", ipcp_gotoptions[0].ouraddr); - slprintf(strremote, sizeof(strremote), "%I", ipcp_hisoptions[0].hisaddr); - - argv[0] = script; - argv[1] = ifname; - argv[2] = devnam; - argv[3] = strspeed; - argv[4] = strlocal; - argv[5] = strremote; - argv[6] = ipparam; - argv[7] = NULL; - ipcp_script_pid = run_program(script, argv, 0, ipcp_script_done, NULL); -} - -/* - * create_resolv - create the replacement resolv.conf file - */ -static void -create_resolv(peerdns1, peerdns2) - u_int32_t peerdns1, peerdns2; -{ - FILE *f; - - f = fopen(_PATH_RESOLV, "w"); - if (f == NULL) { - error("Failed to create %s: %m", _PATH_RESOLV); - return; - } - - if (peerdns1) - fprintf(f, "nameserver %s\n", ip_ntoa(peerdns1)); - - if (peerdns2) - fprintf(f, "nameserver %s\n", ip_ntoa(peerdns2)); - - if (ferror(f)) - error("Write failed to %s: %m", _PATH_RESOLV); - - fclose(f); -} - -/* - * ipcp_printpkt - print the contents of an IPCP packet. - */ -static char *ipcp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej" -}; - -static int -ipcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int code, id, len, olen; - u_char *pstart, *optend; - u_short cishort; - u_int32_t cilong; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(ipcp_codenames) / sizeof(char *)) - printer(arg, " %s", ipcp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < 2 || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { - case CI_ADDRS: - if (olen == CILEN_ADDRS) { - p += 2; - GETLONG(cilong, p); - printer(arg, "addrs %I", htonl(cilong)); - GETLONG(cilong, p); - printer(arg, " %I", htonl(cilong)); - } - break; - case CI_COMPRESSTYPE: - if (olen >= CILEN_COMPRESS) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "compress "); - switch (cishort) { - case IPCP_VJ_COMP: - printer(arg, "VJ"); - break; - case IPCP_VJ_COMP_OLD: - printer(arg, "old-VJ"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_ADDR: - if (olen == CILEN_ADDR) { - p += 2; - GETLONG(cilong, p); - printer(arg, "addr %I", htonl(cilong)); - } - break; - case CI_MS_DNS1: - case CI_MS_DNS2: - p += 2; - GETLONG(cilong, p); - printer(arg, "ms-dns%d %I", code - CI_MS_DNS1 + 1, - htonl(cilong)); - break; - case CI_MS_WINS1: - case CI_MS_WINS2: - p += 2; - GETLONG(cilong, p); - printer(arg, "ms-wins %I", htonl(cilong)); - break; - } - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - print_string((char *)p, len, printer, arg); - p += len; - len = 0; - } - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} - -/* - * ip_active_pkt - see if this IP packet is worth bringing the link up for. - * We don't bring the link up for IP fragments or for TCP FIN packets - * with no data. - */ -#define IP_HDRLEN 20 /* bytes */ -#define IP_OFFMASK 0x1fff -// #define IPPROTO_TCP 6 -#define TCP_HDRLEN 20 -#define TH_FIN 0x01 - -/* - * We use these macros because the IP header may be at an odd address, - * and some compilers might use word loads to get th_off or ip_hl. - */ - -#define net_short(x) (((x)[0] << 8) + (x)[1]) -#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) -#define get_ipoff(x) net_short((unsigned char *)(x) + 6) -#define get_ipproto(x) (((unsigned char *)(x))[9]) -#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) -#define get_tcpflags(x) (((unsigned char *)(x))[13]) - -static int -ip_active_pkt(pkt, len) - u_char *pkt; - int len; -{ - u_char *tcp; - int hlen; - - len -= PPP_HDRLEN; - pkt += PPP_HDRLEN; - if (len < IP_HDRLEN) - return 0; - if ((get_ipoff(pkt) & IP_OFFMASK) != 0) - return 0; - if (get_ipproto(pkt) != IPPROTO_TCP) - return 1; - hlen = get_iphl(pkt) * 4; - if (len < hlen + TCP_HDRLEN) - return 0; - tcp = pkt + hlen; - if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) - return 0; - return 1; -} diff --git a/mdk-stage1/ppp/pppd/ipcp.h b/mdk-stage1/ppp/pppd/ipcp.h deleted file mode 100644 index 8c5aca861..000000000 --- a/mdk-stage1/ppp/pppd/ipcp.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * ipcp.h - IP Control Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - * - * $Id$ - */ - -/* - * Options. - */ -#define CI_ADDRS 1 /* IP Addresses */ -#define CI_COMPRESSTYPE 2 /* Compression Type */ -#define CI_ADDR 3 - -#define CI_MS_DNS1 129 /* Primary DNS value */ -#define CI_MS_WINS1 130 /* Primary WINS value */ -#define CI_MS_DNS2 131 /* Secondary DNS value */ -#define CI_MS_WINS2 132 /* Secondary WINS value */ - -#define MAX_STATES 16 /* from slcompress.h */ - -#define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */ -#define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */ -#define IPCP_VJMODE_RFC1332 3 /* "new-rfc"mode (option # = 0x002d, */ - /* maxslot and slot number compression) */ - -#define IPCP_VJ_COMP 0x002d /* current value for VJ compression option*/ -#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */ - /* compression option*/ - -typedef struct ipcp_options { - bool neg_addr; /* Negotiate IP Address? */ - bool old_addrs; /* Use old (IP-Addresses) option? */ - bool req_addr; /* Ask peer to send IP address? */ - bool default_route; /* Assign default route through interface? */ - bool proxy_arp; /* Make proxy ARP entry for peer? */ - bool neg_vj; /* Van Jacobson Compression? */ - bool old_vj; /* use old (short) form of VJ option? */ - bool accept_local; /* accept peer's value for ouraddr */ - bool accept_remote; /* accept peer's value for hisaddr */ - bool req_dns1; /* Ask peer to send primary DNS address? */ - bool req_dns2; /* Ask peer to send secondary DNS address? */ - int vj_protocol; /* protocol value to use in VJ option */ - int maxslotindex; /* values for RFC1332 VJ compression neg. */ - bool cflag; - u_int32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ - u_int32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ - u_int32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ -} ipcp_options; - -extern fsm ipcp_fsm[]; -extern ipcp_options ipcp_wantoptions[]; -extern ipcp_options ipcp_gotoptions[]; -extern ipcp_options ipcp_allowoptions[]; -extern ipcp_options ipcp_hisoptions[]; - -char *ip_ntoa __P((u_int32_t)); - -extern struct protent ipcp_protent; diff --git a/mdk-stage1/ppp/pppd/ipv6cp.c b/mdk-stage1/ppp/pppd/ipv6cp.c deleted file mode 100644 index 54ff7d7d8..000000000 --- a/mdk-stage1/ppp/pppd/ipv6cp.c +++ /dev/null @@ -1,1512 +0,0 @@ -/* - ipv6cp.c - PPP IPV6 Control Protocol. - Copyright (C) 1999 Tommi Komulainen <Tommi.Komulainen@iki.fi> - - 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. The name of the author 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. -*/ - -/* Original version, based on RFC2023 : - - Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt - Économique ayant pour membres BULL S.A. et l'INRIA). - - Ce logiciel informatique est disponible aux conditions - usuelles dans la recherche, c'est-à-dire qu'il peut - être utilisé, copié, modifié, distribué à l'unique - condition que ce texte soit conservé afin que - l'origine de ce logiciel soit reconnue. - - Le nom de l'Institut National de Recherche en Informatique - et en Automatique (INRIA), de l'IMAG, ou d'une personne morale - ou physique ayant participé à l'élaboration de ce logiciel ne peut - être utilisé sans son accord préalable explicite. - - Ce logiciel est fourni tel quel sans aucune garantie, - support ou responsabilité d'aucune sorte. - Ce logiciel est dérivé de sources d'origine - "University of California at Berkeley" et - "Digital Equipment Corporation" couvertes par des copyrights. - - L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) - est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National - Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant - sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). - - This work has been done in the context of GIE DYADE (joint R & D venture - between BULL S.A. and INRIA). - - This software is available with usual "research" terms - with the aim of retain credits of the software. - Permission to use, copy, modify and distribute this software for any - purpose and without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies, - and the name of INRIA, IMAG, or any contributor not be used in advertising - or publicity pertaining to this material without the prior explicit - permission. The software is provided "as is" without any - warranties, support or liabilities of any kind. - This software is derived from source code from - "University of California at Berkeley" and - "Digital Equipment Corporation" protected by copyrights. - - Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) - is a federation of seven research units funded by the CNRS, National - Polytechnic Institute of Grenoble and University Joseph Fourier. - The research unit in Software, Systems, Networks (LSR) is member of IMAG. -*/ - -/* - * Derived from : - * - * - * ipcp.c - PPP IP Control Protocol. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - * - * $Id$ - */ - -#define RCSID "$Id$" - -/* - * TODO: - * - * Proxy Neighbour Discovery. - * - * Better defines for selecting the ordering of - * interface up / set address. (currently checks for __linux__, - * since SVR4 && (SNI || __USLC__) didn't work properly) - */ - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <netdb.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include "pppd.h" -#include "fsm.h" -#include "ipcp.h" -#include "ipv6cp.h" -#include "magic.h" -#include "pathnames.h" - -static const char rcsid[] = RCSID; - -/* global vars */ -ipv6cp_options ipv6cp_wantoptions[NUM_PPP]; /* Options that we want to request */ -ipv6cp_options ipv6cp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ -ipv6cp_options ipv6cp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ -ipv6cp_options ipv6cp_hisoptions[NUM_PPP]; /* Options that we ack'd */ -int no_ifaceid_neg = 0; - -/* local vars */ -static int ipv6cp_is_up; - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void ipv6cp_resetci __P((fsm *)); /* Reset our CI */ -static int ipv6cp_cilen __P((fsm *)); /* Return length of our CI */ -static void ipv6cp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ -static int ipv6cp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int ipv6cp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */ -static int ipv6cp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ -static int ipv6cp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ -static void ipv6cp_up __P((fsm *)); /* We're UP */ -static void ipv6cp_down __P((fsm *)); /* We're DOWN */ -static void ipv6cp_finished __P((fsm *)); /* Don't need lower layer */ - -fsm ipv6cp_fsm[NUM_PPP]; /* IPV6CP fsm structure */ - -static fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ - ipv6cp_resetci, /* Reset our Configuration Information */ - ipv6cp_cilen, /* Length of our Configuration Information */ - ipv6cp_addci, /* Add our Configuration Information */ - ipv6cp_ackci, /* ACK our Configuration Information */ - ipv6cp_nakci, /* NAK our Configuration Information */ - ipv6cp_rejci, /* Reject our Configuration Information */ - ipv6cp_reqci, /* Request peer's Configuration Information */ - ipv6cp_up, /* Called when fsm reaches OPENED state */ - ipv6cp_down, /* Called when fsm leaves OPENED state */ - NULL, /* Called when we want the lower layer up */ - ipv6cp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - NULL, /* Called to handle protocol-specific codes */ - "IPV6CP" /* String name of protocol */ -}; - -/* - * Command-line options. - */ -static int setifaceid __P((char **arg)); -static void printifaceid __P((option_t *, - void (*)(void *, char *, ...), void *)); - -static option_t ipv6cp_option_list[] = { - { "ipv6", o_special, (void *)setifaceid, - "Set interface identifiers for IPV6", - OPT_A2PRINTER, (void *)printifaceid }, - - { "+ipv6", o_bool, &ipv6cp_protent.enabled_flag, - "Enable IPv6 and IPv6CP", OPT_PRIO | 1 }, - { "noipv6", o_bool, &ipv6cp_protent.enabled_flag, - "Disable IPv6 and IPv6CP", OPT_PRIOSUB }, - { "-ipv6", o_bool, &ipv6cp_protent.enabled_flag, - "Disable IPv6 and IPv6CP", OPT_PRIOSUB | OPT_ALIAS }, - - { "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local, - "Accept peer's interface identifier for us", 1 }, - - { "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip, - "Use (default) IPv4 address as interface identifier", 1 }, - -#if defined(SOL2) - { "ipv6cp-use-persistent", o_bool, &ipv6cp_wantoptions[0].use_persistent, - "Use uniquely-available persistent value for link local address", 1 }, -#endif /* defined(SOL2) */ - - { "ipv6cp-restart", o_int, &ipv6cp_fsm[0].timeouttime, - "Set timeout for IPv6CP", OPT_PRIO }, - { "ipv6cp-max-terminate", o_int, &ipv6cp_fsm[0].maxtermtransmits, - "Set max #xmits for term-reqs", OPT_PRIO }, - { "ipv6cp-max-configure", o_int, &ipv6cp_fsm[0].maxconfreqtransmits, - "Set max #xmits for conf-reqs", OPT_PRIO }, - { "ipv6cp-max-failure", o_int, &ipv6cp_fsm[0].maxnakloops, - "Set max #conf-naks for IPv6CP", OPT_PRIO }, - - { NULL } -}; - - -/* - * Protocol entry points from main code. - */ -static void ipv6cp_init __P((int)); -static void ipv6cp_open __P((int)); -static void ipv6cp_close __P((int, char *)); -static void ipv6cp_lowerup __P((int)); -static void ipv6cp_lowerdown __P((int)); -static void ipv6cp_input __P((int, u_char *, int)); -static void ipv6cp_protrej __P((int)); -static int ipv6cp_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); -static void ipv6_check_options __P((void)); -static int ipv6_demand_conf __P((int)); -static int ipv6_active_pkt __P((u_char *, int)); - -struct protent ipv6cp_protent = { - PPP_IPV6CP, - ipv6cp_init, - ipv6cp_input, - ipv6cp_protrej, - ipv6cp_lowerup, - ipv6cp_lowerdown, - ipv6cp_open, - ipv6cp_close, - ipv6cp_printpkt, - NULL, - 0, - "IPV6CP", - "IPV6", - ipv6cp_option_list, - ipv6_check_options, - ipv6_demand_conf, - ipv6_active_pkt -}; - -static void ipv6cp_clear_addrs __P((int, eui64_t, eui64_t)); -static void ipv6cp_script __P((char *)); -static void ipv6cp_script_done __P((void *)); - -/* - * Lengths of configuration options. - */ -#define CILEN_VOID 2 -#define CILEN_COMPRESS 4 /* length for RFC2023 compress opt. */ -#define CILEN_IFACEID 10 /* RFC2472, interface identifier */ - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - -/* - * This state variable is used to ensure that we don't - * run an ipcp-up/down script while one is already running. - */ -static enum script_state { - s_down, - s_up, -} ipv6cp_script_state; -static pid_t ipv6cp_script_pid; - -/* - * setifaceid - set the interface identifiers manually - */ -static int -setifaceid(argv) - char **argv; -{ - char *comma, *arg, c; - ipv6cp_options *wo = &ipv6cp_wantoptions[0]; - struct in6_addr addr; - static int prio_local, prio_remote; - -#define VALIDID(a) ( (((a).s6_addr32[0] == 0) && ((a).s6_addr32[1] == 0)) && \ - (((a).s6_addr32[2] != 0) || ((a).s6_addr32[3] != 0)) ) - - arg = *argv; - if ((comma = strchr(arg, ',')) == NULL) - comma = arg + strlen(arg); - - /* - * If comma first character, then no local identifier - */ - if (comma != arg) { - c = *comma; - *comma = '\0'; - - if (inet_pton(AF_INET6, arg, &addr) == 0 || !VALIDID(addr)) { - option_error("Illegal interface identifier (local): %s", arg); - return 0; - } - - if (option_priority >= prio_local) { - eui64_copy(addr.s6_addr32[2], wo->ourid); - wo->opt_local = 1; - prio_local = option_priority; - } - *comma = c; - } - - /* - * If comma last character, the no remote identifier - */ - if (*comma != 0 && *++comma != '\0') { - if (inet_pton(AF_INET6, comma, &addr) == 0 || !VALIDID(addr)) { - option_error("Illegal interface identifier (remote): %s", comma); - return 0; - } - if (option_priority >= prio_remote) { - eui64_copy(addr.s6_addr32[2], wo->hisid); - wo->opt_remote = 1; - prio_remote = option_priority; - } - } - - if (override_value("+ipv6", option_priority, option_source)) - ipv6cp_protent.enabled_flag = 1; - return 1; -} - -static void -printifaceid(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - ipv6cp_options *wo = &ipv6cp_wantoptions[0]; - - if (wo->opt_local) - printer(arg, "%s", llv6_ntoa(wo->ourid)); - printer(arg, ","); - if (wo->opt_remote) - printer(arg, "%s", llv6_ntoa(wo->hisid)); -} - -/* - * Make a string representation of a network address. - */ -char * -llv6_ntoa(ifaceid) - eui64_t ifaceid; -{ - static char b[64]; - - sprintf(b, "fe80::%s", eui64_ntoa(ifaceid)); - return b; -} - - -/* - * ipv6cp_init - Initialize IPV6CP. - */ -static void -ipv6cp_init(unit) - int unit; -{ - fsm *f = &ipv6cp_fsm[unit]; - ipv6cp_options *wo = &ipv6cp_wantoptions[unit]; - ipv6cp_options *ao = &ipv6cp_allowoptions[unit]; - - f->unit = unit; - f->protocol = PPP_IPV6CP; - f->callbacks = &ipv6cp_callbacks; - fsm_init(&ipv6cp_fsm[unit]); - - memset(wo, 0, sizeof(*wo)); - memset(ao, 0, sizeof(*ao)); - - wo->accept_local = 1; - wo->neg_ifaceid = 1; - ao->neg_ifaceid = 1; - -#ifdef IPV6CP_COMP - wo->neg_vj = 1; - ao->neg_vj = 1; - wo->vj_protocol = IPV6CP_COMP; -#endif - -} - - -/* - * ipv6cp_open - IPV6CP is allowed to come up. - */ -static void -ipv6cp_open(unit) - int unit; -{ - fsm_open(&ipv6cp_fsm[unit]); -} - - -/* - * ipv6cp_close - Take IPV6CP down. - */ -static void -ipv6cp_close(unit, reason) - int unit; - char *reason; -{ - fsm_close(&ipv6cp_fsm[unit], reason); -} - - -/* - * ipv6cp_lowerup - The lower layer is up. - */ -static void -ipv6cp_lowerup(unit) - int unit; -{ - fsm_lowerup(&ipv6cp_fsm[unit]); -} - - -/* - * ipv6cp_lowerdown - The lower layer is down. - */ -static void -ipv6cp_lowerdown(unit) - int unit; -{ - fsm_lowerdown(&ipv6cp_fsm[unit]); -} - - -/* - * ipv6cp_input - Input IPV6CP packet. - */ -static void -ipv6cp_input(unit, p, len) - int unit; - u_char *p; - int len; -{ - fsm_input(&ipv6cp_fsm[unit], p, len); -} - - -/* - * ipv6cp_protrej - A Protocol-Reject was received for IPV6CP. - * - * Pretend the lower layer went down, so we shut up. - */ -static void -ipv6cp_protrej(unit) - int unit; -{ - fsm_lowerdown(&ipv6cp_fsm[unit]); -} - - -/* - * ipv6cp_resetci - Reset our CI. - */ -static void -ipv6cp_resetci(f) - fsm *f; -{ - ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; - - wo->req_ifaceid = wo->neg_ifaceid && ipv6cp_allowoptions[f->unit].neg_ifaceid; - - if (!wo->opt_local) { - eui64_magic_nz(wo->ourid); - } - - *go = *wo; - eui64_zero(go->hisid); /* last proposed interface identifier */ -} - - -/* - * ipv6cp_cilen - Return length of our CI. - */ -static int -ipv6cp_cilen(f) - fsm *f; -{ - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; - -#define LENCIVJ(neg) (neg ? CILEN_COMPRESS : 0) -#define LENCIIFACEID(neg) (neg ? CILEN_IFACEID : 0) - - return (LENCIIFACEID(go->neg_ifaceid) + - LENCIVJ(go->neg_vj)); -} - - -/* - * ipv6cp_addci - Add our desired CIs to a packet. - */ -static void -ipv6cp_addci(f, ucp, lenp) - fsm *f; - u_char *ucp; - int *lenp; -{ - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; - int len = *lenp; - -#define ADDCIVJ(opt, neg, val) \ - if (neg) { \ - int vjlen = CILEN_COMPRESS; \ - if (len >= vjlen) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(vjlen, ucp); \ - PUTSHORT(val, ucp); \ - len -= vjlen; \ - } else \ - neg = 0; \ - } - -#define ADDCIIFACEID(opt, neg, val1) \ - if (neg) { \ - int idlen = CILEN_IFACEID; \ - if (len >= idlen) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(idlen, ucp); \ - eui64_put(val1, ucp); \ - len -= idlen; \ - } else \ - neg = 0; \ - } - - ADDCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); - - ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); - - *lenp -= len; -} - - -/* - * ipv6cp_ackci - Ack our CIs. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int -ipv6cp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; - u_short cilen, citype, cishort; - eui64_t ifaceid; - - /* - * CIs must be in exactly the same order that we sent... - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ - -#define ACKCIVJ(opt, neg, val) \ - if (neg) { \ - int vjlen = CILEN_COMPRESS; \ - if ((len -= vjlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != vjlen || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - } - -#define ACKCIIFACEID(opt, neg, val1) \ - if (neg) { \ - int idlen = CILEN_IFACEID; \ - if ((len -= idlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != idlen || \ - citype != opt) \ - goto bad; \ - eui64_get(ifaceid, p); \ - if (! eui64_equals(val1, ifaceid)) \ - goto bad; \ - } - - ACKCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); - - ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); - -bad: - IPV6CPDEBUG(("ipv6cp_ackci: received bad Ack!")); - return (0); -} - -/* - * ipv6cp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if IPV6CP is in the OPENED state. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int -ipv6cp_nakci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; - u_char citype, cilen, *next; - u_short cishort; - eui64_t ifaceid; - ipv6cp_options no; /* options we've seen Naks for */ - ipv6cp_options try; /* options to request next time */ - - BZERO(&no, sizeof(no)); - try = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIIFACEID(opt, neg, code) \ - if (go->neg && \ - len >= (cilen = CILEN_IFACEID) && \ - p[1] == cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - eui64_get(ifaceid, p); \ - no.neg = 1; \ - code \ - } - -#define NAKCIVJ(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_COMPRESS) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } - - /* - * Accept the peer's idea of {our,his} interface identifier, if different - * from our idea, only if the accept_{local,remote} flag is set. - */ - NAKCIIFACEID(CI_IFACEID, neg_ifaceid, - if (go->accept_local) { - while (eui64_iszero(ifaceid) || - eui64_equals(ifaceid, go->hisid)) /* bad luck */ - eui64_magic(ifaceid); - try.ourid = ifaceid; - IPV6CPDEBUG(("local LL address %s", llv6_ntoa(ifaceid))); - } - ); - -#ifdef IPV6CP_COMP - NAKCIVJ(CI_COMPRESSTYPE, neg_vj, - { - if (cishort == IPV6CP_COMP) { - try.vj_protocol = cishort; - } else { - try.neg_vj = 0; - } - } - ); -#else - NAKCIVJ(CI_COMPRESSTYPE, neg_vj, - { - try.neg_vj = 0; - } - ); -#endif - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If they want to negotiate about interface identifier, we comply. - * If they want us to ask for compression, we refuse. - */ - while (len > CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if( (len -= cilen) < 0 ) - goto bad; - next = p + cilen - 2; - - switch (citype) { - case CI_COMPRESSTYPE: - if (go->neg_vj || no.neg_vj || - (cilen != CILEN_COMPRESS)) - goto bad; - no.neg_vj = 1; - break; - case CI_IFACEID: - if (go->neg_ifaceid || no.neg_ifaceid || cilen != CILEN_IFACEID) - goto bad; - try.neg_ifaceid = 1; - eui64_get(ifaceid, p); - if (go->accept_local) { - while (eui64_iszero(ifaceid) || - eui64_equals(ifaceid, go->hisid)) /* bad luck */ - eui64_magic(ifaceid); - try.ourid = ifaceid; - } - no.neg_ifaceid = 1; - break; - } - p = next; - } - - /* If there is still anything left, this packet is bad. */ - if (len != 0) - goto bad; - - /* - * OK, the Nak is good. Now we can update state. - */ - if (f->state != OPENED) - *go = try; - - return 1; - -bad: - IPV6CPDEBUG(("ipv6cp_nakci: received bad Nak!")); - return 0; -} - - -/* - * ipv6cp_rejci - Reject some of our CIs. - */ -static int -ipv6cp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; - u_char cilen; - u_short cishort; - eui64_t ifaceid; - ipv6cp_options try; /* options to request next time */ - - try = *go; - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIIFACEID(opt, neg, val1) \ - if (go->neg && \ - len >= (cilen = CILEN_IFACEID) && \ - p[1] == cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - eui64_get(ifaceid, p); \ - /* Check rejected value. */ \ - if (! eui64_equals(ifaceid, val1)) \ - goto bad; \ - try.neg = 0; \ - } - -#define REJCIVJ(opt, neg, val) \ - if (go->neg && \ - p[1] == CILEN_COMPRESS && \ - len >= p[1] && \ - p[0] == opt) { \ - len -= p[1]; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) \ - goto bad; \ - try.neg = 0; \ - } - - REJCIIFACEID(CI_IFACEID, neg_ifaceid, go->ourid); - - REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - /* - * Now we can update state. - */ - if (f->state != OPENED) - *go = try; - return 1; - -bad: - IPV6CPDEBUG(("ipv6cp_rejci: received bad Reject!")); - return 0; -} - - -/* - * ipv6cp_reqci - Check the peer's requested CIs and send appropriate response. - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - */ -static int -ipv6cp_reqci(f, inp, len, reject_if_disagree) - fsm *f; - u_char *inp; /* Requested CIs */ - int *len; /* Length of requested CIs */ - int reject_if_disagree; -{ - ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; - ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit]; - ipv6cp_options *ao = &ipv6cp_allowoptions[f->unit]; - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; - u_char *cip, *next; /* Pointer to current and next CIs */ - u_short cilen, citype; /* Parsed len, type */ - u_short cishort; /* Parsed short value */ - eui64_t ifaceid; /* Parsed interface identifier */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *ucp = inp; /* Pointer to current output char */ - int l = *len; /* Length left */ - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - IPV6CPDEBUG(("ipv6cp_reqci: bad CI length!")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ - case CI_IFACEID: - IPV6CPDEBUG(("ipv6cp: received interface identifier ")); - - if (!ao->neg_ifaceid || - cilen != CILEN_IFACEID) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no interface identifier, or if we both have same - * identifier then NAK it with new idea. - * In particular, if we don't know his identifier, but he does, - * then accept it. - */ - eui64_get(ifaceid, p); - IPV6CPDEBUG(("(%s)", llv6_ntoa(ifaceid))); - if (eui64_iszero(ifaceid) && eui64_iszero(go->ourid)) { - orc = CONFREJ; /* Reject CI */ - break; - } - if (!eui64_iszero(wo->hisid) && - !eui64_equals(ifaceid, wo->hisid) && - eui64_iszero(go->hisid)) { - - orc = CONFNAK; - ifaceid = wo->hisid; - go->hisid = ifaceid; - DECPTR(sizeof(ifaceid), p); - eui64_put(ifaceid, p); - } else - if (eui64_iszero(ifaceid) || eui64_equals(ifaceid, go->ourid)) { - orc = CONFNAK; - if (eui64_iszero(go->hisid)) /* first time, try option */ - ifaceid = wo->hisid; - while (eui64_iszero(ifaceid) || - eui64_equals(ifaceid, go->ourid)) /* bad luck */ - eui64_magic(ifaceid); - go->hisid = ifaceid; - DECPTR(sizeof(ifaceid), p); - eui64_put(ifaceid, p); - } - - ho->neg_ifaceid = 1; - ho->hisid = ifaceid; - break; - - case CI_COMPRESSTYPE: - IPV6CPDEBUG(("ipv6cp: received COMPRESSTYPE ")); - if (!ao->neg_vj || - (cilen != CILEN_COMPRESS)) { - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - IPV6CPDEBUG(("(%d)", cishort)); - -#ifdef IPV6CP_COMP - if (!(cishort == IPV6CP_COMP)) { - orc = CONFREJ; - break; - } - - ho->neg_vj = 1; - ho->vj_protocol = cishort; - break; -#else - orc = CONFREJ; - break; -#endif - - default: - orc = CONFREJ; - break; - } - -endswitch: - IPV6CPDEBUG((" (%s)\n", CODENAME(orc))); - - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) /* but prior CI wasnt? */ - continue; /* Don't send this one */ - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree) /* Getting fed up with sending NAKs? */ - orc = CONFREJ; /* Get tough if so */ - else { - if (rc == CONFREJ) /* Rejecting prior CI? */ - continue; /* Don't send this one */ - if (rc == CONFACK) { /* Ack'd all prior CIs? */ - rc = CONFNAK; /* Not anymore... */ - ucp = inp; /* Backup */ - } - } - } - - if (orc == CONFREJ && /* Reject this CI */ - rc != CONFREJ) { /* but no prior ones? */ - rc = CONFREJ; - ucp = inp; /* Backup */ - } - - /* Need to move CI? */ - if (ucp != cip) - BCOPY(cip, ucp, cilen); /* Move it */ - - /* Update output pointer */ - INCPTR(cilen, ucp); - } - - /* - * If we aren't rejecting this packet, and we want to negotiate - * their identifier and they didn't send their identifier, then we - * send a NAK with a CI_IFACEID option appended. We assume the - * input buffer is long enough that we can append the extra - * option safely. - */ - if (rc != CONFREJ && !ho->neg_ifaceid && - wo->req_ifaceid && !reject_if_disagree) { - if (rc == CONFACK) { - rc = CONFNAK; - ucp = inp; /* reset pointer */ - wo->req_ifaceid = 0; /* don't ask again */ - } - PUTCHAR(CI_IFACEID, ucp); - PUTCHAR(CILEN_IFACEID, ucp); - eui64_put(wo->hisid, ucp); - } - - *len = ucp - inp; /* Compute output length */ - IPV6CPDEBUG(("ipv6cp: returning Configure-%s", CODENAME(rc))); - return (rc); /* Return final code */ -} - - -/* - * ipv6_check_options - check that any IP-related options are OK, - * and assign appropriate defaults. - */ -static void -ipv6_check_options() -{ - ipv6cp_options *wo = &ipv6cp_wantoptions[0]; - - if (!ipv6cp_protent.enabled_flag) - return; - -#if defined(SOL2) - /* - * Persistent link-local id is only used when user has not explicitly - * configure/hard-code the id - */ - if ((wo->use_persistent) && (!wo->opt_local) && (!wo->opt_remote)) { - - /* - * On systems where there are no Ethernet interfaces used, there - * may be other ways to obtain a persistent id. Right now, it - * will fall back to using magic [see eui64_magic] below when - * an EUI-48 from MAC address can't be obtained. Other possibilities - * include obtaining EEPROM serial numbers, or some other unique - * yet persistent number. On Sparc platforms, this is possible, - * but too bad there's no standards yet for x86 machines. - */ - if (ether_to_eui64(&wo->ourid)) { - wo->opt_local = 1; - } - } -#endif - - if (!wo->opt_local) { /* init interface identifier */ - if (wo->use_ip && eui64_iszero(wo->ourid)) { - eui64_setlo32(wo->ourid, ntohl(ipcp_wantoptions[0].ouraddr)); - if (!eui64_iszero(wo->ourid)) - wo->opt_local = 1; - } - - while (eui64_iszero(wo->ourid)) - eui64_magic(wo->ourid); - } - - if (!wo->opt_remote) { - if (wo->use_ip && eui64_iszero(wo->hisid)) { - eui64_setlo32(wo->hisid, ntohl(ipcp_wantoptions[0].hisaddr)); - if (!eui64_iszero(wo->hisid)) - wo->opt_remote = 1; - } - } - - if (demand && (eui64_iszero(wo->ourid) || eui64_iszero(wo->hisid))) { - option_error("local/remote LL address required for demand-dialling\n"); - exit(1); - } -} - - -/* - * ipv6_demand_conf - configure the interface as though - * IPV6CP were up, for use with dial-on-demand. - */ -static int -ipv6_demand_conf(u) - int u; -{ - ipv6cp_options *wo = &ipv6cp_wantoptions[u]; - -#if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) -#if defined(SOL2) - if (!sif6up(u)) - return 0; -#else - if (!sifup(u)) - return 0; -#endif /* defined(SOL2) */ -#endif - if (!sif6addr(u, wo->ourid, wo->hisid)) - return 0; -#if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifup(u)) - return 0; -#endif - if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE)) - return 0; - - notice("ipv6_demand_conf"); - notice("local LL address %s", llv6_ntoa(wo->ourid)); - notice("remote LL address %s", llv6_ntoa(wo->hisid)); - - return 1; -} - - -/* - * ipv6cp_up - IPV6CP has come UP. - * - * Configure the IPv6 network interface appropriately and bring it up. - */ -static void -ipv6cp_up(f) - fsm *f; -{ - ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit]; - ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; - ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; - - IPV6CPDEBUG(("ipv6cp: up")); - - /* - * We must have a non-zero LL address for both ends of the link. - */ - if (!ho->neg_ifaceid) - ho->hisid = wo->hisid; - - if(!no_ifaceid_neg) { - if (eui64_iszero(ho->hisid)) { - error("Could not determine remote LL address"); - ipv6cp_close(f->unit, "Could not determine remote LL address"); - return; - } - if (eui64_iszero(go->ourid)) { - error("Could not determine local LL address"); - ipv6cp_close(f->unit, "Could not determine local LL address"); - return; - } - if (eui64_equals(go->ourid, ho->hisid)) { - error("local and remote LL addresses are equal"); - ipv6cp_close(f->unit, "local and remote LL addresses are equal"); - return; - } - } - script_setenv("LLLOCAL", llv6_ntoa(go->ourid), 0); - script_setenv("LLREMOTE", llv6_ntoa(ho->hisid), 0); - -#ifdef IPV6CP_COMP - /* set tcp compression */ - sif6comp(f->unit, ho->neg_vj); -#endif - - /* - * If we are doing dial-on-demand, the interface is already - * configured, so we put out any saved-up packets, then set the - * interface to pass IPv6 packets. - */ - if (demand) { - if (! eui64_equals(go->ourid, wo->ourid) || - ! eui64_equals(ho->hisid, wo->hisid)) { - if (! eui64_equals(go->ourid, wo->ourid)) - warn("Local LL address changed to %s", - llv6_ntoa(go->ourid)); - if (! eui64_equals(ho->hisid, wo->hisid)) - warn("Remote LL address changed to %s", - llv6_ntoa(ho->hisid)); - ipv6cp_clear_addrs(f->unit, go->ourid, ho->hisid); - - /* Set the interface to the new addresses */ - if (!sif6addr(f->unit, go->ourid, ho->hisid)) { - if (debug) - warn("sif6addr failed"); - ipv6cp_close(f->unit, "Interface configuration failed"); - return; - } - - } - demand_rexmit(PPP_IPV6); - sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); - - } else { - /* - * Set LL addresses - */ -#if !defined(__linux__) && !defined(SOL2) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sif6addr(f->unit, go->ourid, ho->hisid)) { - if (debug) - warn("sif6addr failed"); - ipv6cp_close(f->unit, "Interface configuration failed"); - return; - } -#endif - - /* bring the interface up for IPv6 */ -#if defined(SOL2) - if (!sif6up(f->unit)) { - if (debug) - warn("sifup failed (IPV6)"); - ipv6cp_close(f->unit, "Interface configuration failed"); - return; - } -#else - if (!sifup(f->unit)) { - if (debug) - warn("sifup failed (IPV6)"); - ipv6cp_close(f->unit, "Interface configuration failed"); - return; - } -#endif /* defined(SOL2) */ - -#if defined(__linux__) || defined(SOL2) || (defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sif6addr(f->unit, go->ourid, ho->hisid)) { - if (debug) - warn("sif6addr failed"); - ipv6cp_close(f->unit, "Interface configuration failed"); - return; - } -#endif - sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); - - notice("local LL address %s", llv6_ntoa(go->ourid)); - notice("remote LL address %s", llv6_ntoa(ho->hisid)); - } - - np_up(f->unit, PPP_IPV6); - ipv6cp_is_up = 1; - - /* - * Execute the ipv6-up script, like this: - * /etc/ppp/ipv6-up interface tty speed local-LL remote-LL - */ - if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) { - ipv6cp_script_state = s_up; - ipv6cp_script(_PATH_IPV6UP); - } -} - - -/* - * ipv6cp_down - IPV6CP has gone DOWN. - * - * Take the IPv6 network interface down, clear its addresses - * and delete routes through it. - */ -static void -ipv6cp_down(f) - fsm *f; -{ - IPV6CPDEBUG(("ipv6cp: down")); - update_link_stats(f->unit); - if (ipv6cp_is_up) { - ipv6cp_is_up = 0; - np_down(f->unit, PPP_IPV6); - } -#ifdef IPV6CP_COMP - sif6comp(f->unit, 0); -#endif - - /* - * If we are doing dial-on-demand, set the interface - * to queue up outgoing packets (for now). - */ - if (demand) { - sifnpmode(f->unit, PPP_IPV6, NPMODE_QUEUE); - } else { - sifnpmode(f->unit, PPP_IPV6, NPMODE_DROP); -#if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC))) -#if defined(SOL2) - sif6down(f->unit); -#else - sifdown(f->unit); -#endif /* defined(SOL2) */ -#endif - ipv6cp_clear_addrs(f->unit, - ipv6cp_gotoptions[f->unit].ourid, - ipv6cp_hisoptions[f->unit].hisid); -#if defined(__linux__) || (defined(SVR4) && (defined(SNI) || defined(__USLC))) - sifdown(f->unit); -#endif - } - - /* Execute the ipv6-down script */ - if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) { - ipv6cp_script_state = s_down; - ipv6cp_script(_PATH_IPV6DOWN); - } -} - - -/* - * ipv6cp_clear_addrs() - clear the interface addresses, routes, - * proxy neighbour discovery entries, etc. - */ -static void -ipv6cp_clear_addrs(unit, ourid, hisid) - int unit; - eui64_t ourid; - eui64_t hisid; -{ - cif6addr(unit, ourid, hisid); -} - - -/* - * ipv6cp_finished - possibly shut down the lower layers. - */ -static void -ipv6cp_finished(f) - fsm *f; -{ - np_finished(f->unit, PPP_IPV6); -} - - -/* - * ipv6cp_script_done - called when the ipv6-up or ipv6-down script - * has finished. - */ -static void -ipv6cp_script_done(arg) - void *arg; -{ - ipv6cp_script_pid = 0; - switch (ipv6cp_script_state) { - case s_up: - if (ipv6cp_fsm[0].state != OPENED) { - ipv6cp_script_state = s_down; - ipv6cp_script(_PATH_IPV6DOWN); - } - break; - case s_down: - if (ipv6cp_fsm[0].state == OPENED) { - ipv6cp_script_state = s_up; - ipv6cp_script(_PATH_IPV6UP); - } - break; - } -} - - -/* - * ipv6cp_script - Execute a script with arguments - * interface-name tty-name speed local-LL remote-LL. - */ -static void -ipv6cp_script(script) - char *script; -{ - char strspeed[32], strlocal[32], strremote[32]; - char *argv[8]; - - sprintf(strspeed, "%d", baud_rate); - strcpy(strlocal, llv6_ntoa(ipv6cp_gotoptions[0].ourid)); - strcpy(strremote, llv6_ntoa(ipv6cp_hisoptions[0].hisid)); - - argv[0] = script; - argv[1] = ifname; - argv[2] = devnam; - argv[3] = strspeed; - argv[4] = strlocal; - argv[5] = strremote; - argv[6] = ipparam; - argv[7] = NULL; - - ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done, NULL); -} - -/* - * ipv6cp_printpkt - print the contents of an IPV6CP packet. - */ -static char *ipv6cp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej" -}; - -static int -ipv6cp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int code, id, len, olen; - u_char *pstart, *optend; - u_short cishort; - eui64_t ifaceid; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(ipv6cp_codenames) / sizeof(char *)) - printer(arg, " %s", ipv6cp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < 2 || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { - case CI_COMPRESSTYPE: - if (olen >= CILEN_COMPRESS) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "compress "); - printer(arg, "0x%x", cishort); - } - break; - case CI_IFACEID: - if (olen == CILEN_IFACEID) { - p += 2; - eui64_get(ifaceid, p); - printer(arg, "addr %s", llv6_ntoa(ifaceid)); - } - break; - } - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - print_string((char *)p, len, printer, arg); - p += len; - len = 0; - } - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} - -/* - * ipv6_active_pkt - see if this IP packet is worth bringing the link up for. - * We don't bring the link up for IP fragments or for TCP FIN packets - * with no data. - */ -#define IP6_HDRLEN 40 /* bytes */ -#define IP6_NHDR_FRAG 44 /* fragment IPv6 header */ -#define IPPROTO_TCP 6 -#define TCP_HDRLEN 20 -#define TH_FIN 0x01 - -/* - * We use these macros because the IP header may be at an odd address, - * and some compilers might use word loads to get th_off or ip_hl. - */ - -#define get_ip6nh(x) (((unsigned char *)(x))[6]) -#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) -#define get_tcpflags(x) (((unsigned char *)(x))[13]) - -static int -ipv6_active_pkt(pkt, len) - u_char *pkt; - int len; -{ - u_char *tcp; - - len -= PPP_HDRLEN; - pkt += PPP_HDRLEN; - if (len < IP6_HDRLEN) - return 0; - if (get_ip6nh(pkt) == IP6_NHDR_FRAG) - return 0; - if (get_ip6nh(pkt) != IPPROTO_TCP) - return 1; - if (len < IP6_HDRLEN + TCP_HDRLEN) - return 0; - tcp = pkt + IP6_HDRLEN; - if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == IP6_HDRLEN + get_tcpoff(tcp) * 4) - return 0; - return 1; -} diff --git a/mdk-stage1/ppp/pppd/ipv6cp.h b/mdk-stage1/ppp/pppd/ipv6cp.h deleted file mode 100644 index 60d366eb3..000000000 --- a/mdk-stage1/ppp/pppd/ipv6cp.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - ipv6cp.h - PPP IPV6 Control Protocol. - Copyright (C) 1999 Tommi Komulainen <Tommi.Komulainen@iki.fi> - - 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. The name of the author 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. -*/ - -/* Original version, based on RFC2023 : - - Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt - Économique ayant pour membres BULL S.A. et l'INRIA). - - Ce logiciel informatique est disponible aux conditions - usuelles dans la recherche, c'est-à-dire qu'il peut - être utilisé, copié, modifié, distribué à l'unique - condition que ce texte soit conservé afin que - l'origine de ce logiciel soit reconnue. - - Le nom de l'Institut National de Recherche en Informatique - et en Automatique (INRIA), de l'IMAG, ou d'une personne morale - ou physique ayant participé à l'élaboration de ce logiciel ne peut - être utilisé sans son accord préalable explicite. - - Ce logiciel est fourni tel quel sans aucune garantie, - support ou responsabilité d'aucune sorte. - Ce logiciel est dérivé de sources d'origine - "University of California at Berkeley" et - "Digital Equipment Corporation" couvertes par des copyrights. - - L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) - est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National - Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant - sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). - - This work has been done in the context of GIE DYADE (joint R & D venture - between BULL S.A. and INRIA). - - This software is available with usual "research" terms - with the aim of retain credits of the software. - Permission to use, copy, modify and distribute this software for any - purpose and without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies, - and the name of INRIA, IMAG, or any contributor not be used in advertising - or publicity pertaining to this material without the prior explicit - permission. The software is provided "as is" without any - warranties, support or liabilities of any kind. - This software is derived from source code from - "University of California at Berkeley" and - "Digital Equipment Corporation" protected by copyrights. - - Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) - is a federation of seven research units funded by the CNRS, National - Polytechnic Institute of Grenoble and University Joseph Fourier. - The research unit in Software, Systems, Networks (LSR) is member of IMAG. -*/ - -/* - * Derived from : - * - * - * ipcp.h - IP Control Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - * - * $Id$ - */ - -/* - * Options. - */ -#define CI_IFACEID 1 /* Interface Identifier */ -#define CI_COMPRESSTYPE 2 /* Compression Type */ - -/* No compression types yet defined. - *#define IPV6CP_COMP 0x004f - */ -typedef struct ipv6cp_options { - int neg_ifaceid; /* Negotiate interface identifier? */ - int req_ifaceid; /* Ask peer to send interface identifier? */ - int accept_local; /* accept peer's value for iface id? */ - int opt_local; /* ourtoken set by option */ - int opt_remote; /* histoken set by option */ - int use_ip; /* use IP as interface identifier */ -#if defined(SOL2) - int use_persistent; /* use uniquely persistent value for address */ -#endif /* defined(SOL2) */ - int neg_vj; /* Van Jacobson Compression? */ - u_short vj_protocol; /* protocol value to use in VJ option */ - eui64_t ourid, hisid; /* Interface identifiers */ -} ipv6cp_options; - -extern fsm ipv6cp_fsm[]; -extern ipv6cp_options ipv6cp_wantoptions[]; -extern ipv6cp_options ipv6cp_gotoptions[]; -extern ipv6cp_options ipv6cp_allowoptions[]; -extern ipv6cp_options ipv6cp_hisoptions[]; - -extern struct protent ipv6cp_protent; diff --git a/mdk-stage1/ppp/pppd/ipxcp.c b/mdk-stage1/ppp/pppd/ipxcp.c deleted file mode 100644 index f9a12b934..000000000 --- a/mdk-stage1/ppp/pppd/ipxcp.c +++ /dev/null @@ -1,1570 +0,0 @@ -/* - * ipxcp.c - PPP IPX Control Protocol. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -#ifdef IPX_CHANGE - -#define RCSID "$Id$" - -/* - * TODO: - */ - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> - -#include "pppd.h" -#include "fsm.h" -#include "ipxcp.h" -#include "pathnames.h" -#include "magic.h" - -static const char rcsid[] = RCSID; - -/* global vars */ -ipxcp_options ipxcp_wantoptions[NUM_PPP]; /* Options that we want to request */ -ipxcp_options ipxcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ -ipxcp_options ipxcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ -ipxcp_options ipxcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ - -#define wo (&ipxcp_wantoptions[0]) -#define ao (&ipxcp_allowoptions[0]) -#define go (&ipxcp_gotoptions[0]) -#define ho (&ipxcp_hisoptions[0]) - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void ipxcp_resetci __P((fsm *)); /* Reset our CI */ -static int ipxcp_cilen __P((fsm *)); /* Return length of our CI */ -static void ipxcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ -static int ipxcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int ipxcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */ -static int ipxcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ -static int ipxcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ -static void ipxcp_up __P((fsm *)); /* We're UP */ -static void ipxcp_down __P((fsm *)); /* We're DOWN */ -static void ipxcp_finished __P((fsm *)); /* Don't need lower layer */ -static void ipxcp_script __P((fsm *, char *)); /* Run an up/down script */ - -fsm ipxcp_fsm[NUM_PPP]; /* IPXCP fsm structure */ - -static fsm_callbacks ipxcp_callbacks = { /* IPXCP callback routines */ - ipxcp_resetci, /* Reset our Configuration Information */ - ipxcp_cilen, /* Length of our Configuration Information */ - ipxcp_addci, /* Add our Configuration Information */ - ipxcp_ackci, /* ACK our Configuration Information */ - ipxcp_nakci, /* NAK our Configuration Information */ - ipxcp_rejci, /* Reject our Configuration Information */ - ipxcp_reqci, /* Request peer's Configuration Information */ - ipxcp_up, /* Called when fsm reaches OPENED state */ - ipxcp_down, /* Called when fsm leaves OPENED state */ - NULL, /* Called when we want the lower layer up */ - ipxcp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - NULL, /* Called to handle protocol-specific codes */ - "IPXCP" /* String name of protocol */ -}; - -/* - * Command-line options. - */ -static int setipxnode __P((char **)); -static void printipxnode __P((option_t *, - void (*)(void *, char *, ...), void *)); -static int setipxname __P((char **)); - -static option_t ipxcp_option_list[] = { - { "ipx", o_bool, &ipxcp_protent.enabled_flag, - "Enable IPXCP (and IPX)", OPT_PRIO | 1 }, - { "+ipx", o_bool, &ipxcp_protent.enabled_flag, - "Enable IPXCP (and IPX)", OPT_PRIOSUB | OPT_ALIAS | 1 }, - { "noipx", o_bool, &ipxcp_protent.enabled_flag, - "Disable IPXCP (and IPX)", OPT_PRIOSUB }, - { "-ipx", o_bool, &ipxcp_protent.enabled_flag, - "Disable IPXCP (and IPX)", OPT_PRIOSUB | OPT_ALIAS }, - - { "ipx-network", o_uint32, &ipxcp_wantoptions[0].our_network, - "Set our IPX network number", OPT_PRIO, &ipxcp_wantoptions[0].neg_nn }, - - { "ipxcp-accept-network", o_bool, &ipxcp_wantoptions[0].accept_network, - "Accept peer IPX network number", 1, - &ipxcp_allowoptions[0].accept_network }, - - { "ipx-node", o_special, (void *)setipxnode, - "Set IPX node number", OPT_A2PRINTER, (void *)printipxnode }, - - { "ipxcp-accept-local", o_bool, &ipxcp_wantoptions[0].accept_local, - "Accept our IPX address", 1, - &ipxcp_allowoptions[0].accept_local }, - - { "ipxcp-accept-remote", o_bool, &ipxcp_wantoptions[0].accept_remote, - "Accept peer's IPX address", 1, - &ipxcp_allowoptions[0].accept_remote }, - - { "ipx-routing", o_int, &ipxcp_wantoptions[0].router, - "Set IPX routing proto number", OPT_PRIO, - &ipxcp_wantoptions[0].neg_router }, - - { "ipx-router-name", o_special, setipxname, - "Set IPX router name", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, - &ipxcp_wantoptions[0].name }, - - { "ipxcp-restart", o_int, &ipxcp_fsm[0].timeouttime, - "Set timeout for IPXCP", OPT_PRIO }, - { "ipxcp-max-terminate", o_int, &ipxcp_fsm[0].maxtermtransmits, - "Set max #xmits for IPXCP term-reqs", OPT_PRIO }, - { "ipxcp-max-configure", o_int, &ipxcp_fsm[0].maxconfreqtransmits, - "Set max #xmits for IPXCP conf-reqs", OPT_PRIO }, - { "ipxcp-max-failure", o_int, &ipxcp_fsm[0].maxnakloops, - "Set max #conf-naks for IPXCP", OPT_PRIO }, - - { NULL } -}; - -/* - * Protocol entry points. - */ - -static void ipxcp_init __P((int)); -static void ipxcp_open __P((int)); -static void ipxcp_close __P((int, char *)); -static void ipxcp_lowerup __P((int)); -static void ipxcp_lowerdown __P((int)); -static void ipxcp_input __P((int, u_char *, int)); -static void ipxcp_protrej __P((int)); -static int ipxcp_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); - -struct protent ipxcp_protent = { - PPP_IPXCP, - ipxcp_init, - ipxcp_input, - ipxcp_protrej, - ipxcp_lowerup, - ipxcp_lowerdown, - ipxcp_open, - ipxcp_close, - ipxcp_printpkt, - NULL, - 0, - "IPXCP", - "IPX", - ipxcp_option_list, - NULL, - NULL, - NULL -}; - -/* - * Lengths of configuration options. - */ - -#define CILEN_VOID 2 -#define CILEN_COMPLETE 2 /* length of complete option */ -#define CILEN_NETN 6 /* network number length option */ -#define CILEN_NODEN 8 /* node number length option */ -#define CILEN_PROTOCOL 4 /* Minimum length of routing protocol */ -#define CILEN_NAME 3 /* Minimum length of router name */ -#define CILEN_COMPRESS 4 /* Minimum length of compression protocol */ - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - -static int ipxcp_is_up; - -static char *ipx_ntoa __P((u_int32_t)); - -/* Used in printing the node number */ -#define NODE(base) base[0], base[1], base[2], base[3], base[4], base[5] - -/* Used to generate the proper bit mask */ -#define BIT(num) (1 << (num)) - -/* - * Convert from internal to external notation - */ - -static short int -to_external(internal) -short int internal; -{ - short int external; - - if (internal & BIT(IPX_NONE) ) - external = IPX_NONE; - else - external = RIP_SAP; - - return external; -} - -/* - * Make a string representation of a network IP address. - */ - -static char * -ipx_ntoa(ipxaddr) -u_int32_t ipxaddr; -{ - static char b[64]; - slprintf(b, sizeof(b), "%x", ipxaddr); - return b; -} - - -static u_char * -setipxnodevalue(src,dst) -u_char *src, *dst; -{ - int indx; - int item; - - for (;;) { - if (!isxdigit (*src)) - break; - - for (indx = 0; indx < 5; ++indx) { - dst[indx] <<= 4; - dst[indx] |= (dst[indx + 1] >> 4) & 0x0F; - } - - item = toupper (*src) - '0'; - if (item > 9) - item -= 7; - - dst[5] = (dst[5] << 4) | item; - ++src; - } - return src; -} - -static int ipx_prio_our, ipx_prio_his; - -static int -setipxnode(argv) - char **argv; -{ - char *end; - int have_his = 0; - u_char our_node[6]; - u_char his_node[6]; - - memset (our_node, 0, 6); - memset (his_node, 0, 6); - - end = setipxnodevalue (*argv, our_node); - if (*end == ':') { - have_his = 1; - end = setipxnodevalue (++end, his_node); - } - - if (*end == '\0') { - ipxcp_wantoptions[0].neg_node = 1; - if (option_priority >= ipx_prio_our) { - memcpy(&ipxcp_wantoptions[0].our_node[0], our_node, 6); - ipx_prio_our = option_priority; - } - if (have_his && option_priority >= ipx_prio_his) { - memcpy(&ipxcp_wantoptions[0].his_node[0], his_node, 6); - ipx_prio_his = option_priority; - } - return 1; - } - - option_error("invalid parameter '%s' for ipx-node option", *argv); - return 0; -} - -static void -printipxnode(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - unsigned char *p; - - p = ipxcp_wantoptions[0].our_node; - if (ipx_prio_our) - printer(arg, "%.2x%.2x%.2x%.2x%.2x%.2x", - p[0], p[1], p[2], p[3], p[4], p[5]); - printer(arg, ":"); - p = ipxcp_wantoptions[0].his_node; - if (ipx_prio_his) - printer(arg, "%.2x%.2x%.2x%.2x%.2x%.2x", - p[0], p[1], p[2], p[3], p[4], p[5]); -} - -static int -setipxname (argv) - char **argv; -{ - char *dest = ipxcp_wantoptions[0].name; - char *src = *argv; - int count; - char ch; - - ipxcp_wantoptions[0].neg_name = 1; - ipxcp_allowoptions[0].neg_name = 1; - memset (dest, '\0', sizeof (ipxcp_wantoptions[0].name)); - - count = 0; - while (*src) { - ch = *src++; - if (! isalnum (ch) && ch != '_') { - option_error("IPX router name must be alphanumeric or _"); - return 0; - } - - if (count >= sizeof (ipxcp_wantoptions[0].name) - 1) { - option_error("IPX router name is limited to %d characters", - sizeof (ipxcp_wantoptions[0].name) - 1); - return 0; - } - - dest[count++] = toupper (ch); - } - dest[count] = 0; - - return 1; -} - -/* - * ipxcp_init - Initialize IPXCP. - */ -static void -ipxcp_init(unit) - int unit; -{ - fsm *f = &ipxcp_fsm[unit]; - - f->unit = unit; - f->protocol = PPP_IPXCP; - f->callbacks = &ipxcp_callbacks; - fsm_init(&ipxcp_fsm[unit]); - - memset (wo->name, 0, sizeof (wo->name)); - memset (wo->our_node, 0, sizeof (wo->our_node)); - memset (wo->his_node, 0, sizeof (wo->his_node)); - - wo->neg_nn = 1; - wo->neg_complete = 1; - wo->network = 0; - - ao->neg_node = 1; - ao->neg_nn = 1; - ao->neg_name = 1; - ao->neg_complete = 1; - ao->neg_router = 1; - - ao->accept_local = 0; - ao->accept_remote = 0; - ao->accept_network = 0; - - wo->tried_rip = 0; - wo->tried_nlsp = 0; -} - -/* - * Copy the node number - */ - -static void -copy_node (src, dst) -u_char *src, *dst; -{ - memcpy (dst, src, sizeof (ipxcp_wantoptions[0].our_node)); -} - -/* - * Compare node numbers - */ - -static int -compare_node (src, dst) -u_char *src, *dst; -{ - return memcmp (dst, src, sizeof (ipxcp_wantoptions[0].our_node)) == 0; -} - -/* - * Is the node number zero? - */ - -static int -zero_node (node) -u_char *node; -{ - int indx; - for (indx = 0; indx < sizeof (ipxcp_wantoptions[0].our_node); ++indx) - if (node [indx] != 0) - return 0; - return 1; -} - -/* - * Increment the node number - */ - -static void -inc_node (node) -u_char *node; -{ - u_char *outp; - u_int32_t magic_num; - - outp = node; - magic_num = magic(); - *outp++ = '\0'; - *outp++ = '\0'; - PUTLONG (magic_num, outp); -} - -/* - * ipxcp_open - IPXCP is allowed to come up. - */ -static void -ipxcp_open(unit) - int unit; -{ - fsm_open(&ipxcp_fsm[unit]); -} - -/* - * ipxcp_close - Take IPXCP down. - */ -static void -ipxcp_close(unit, reason) - int unit; - char *reason; -{ - fsm_close(&ipxcp_fsm[unit], reason); -} - - -/* - * ipxcp_lowerup - The lower layer is up. - */ -static void -ipxcp_lowerup(unit) - int unit; -{ - fsm_lowerup(&ipxcp_fsm[unit]); -} - - -/* - * ipxcp_lowerdown - The lower layer is down. - */ -static void -ipxcp_lowerdown(unit) - int unit; -{ - fsm_lowerdown(&ipxcp_fsm[unit]); -} - - -/* - * ipxcp_input - Input IPXCP packet. - */ -static void -ipxcp_input(unit, p, len) - int unit; - u_char *p; - int len; -{ - fsm_input(&ipxcp_fsm[unit], p, len); -} - - -/* - * ipxcp_protrej - A Protocol-Reject was received for IPXCP. - * - * Pretend the lower layer went down, so we shut up. - */ -static void -ipxcp_protrej(unit) - int unit; -{ - fsm_lowerdown(&ipxcp_fsm[unit]); -} - - -/* - * ipxcp_resetci - Reset our CI. - */ -static void -ipxcp_resetci(f) - fsm *f; -{ - wo->req_node = wo->neg_node && ao->neg_node; - wo->req_nn = wo->neg_nn && ao->neg_nn; - - if (wo->our_network == 0) { - wo->neg_node = 1; - ao->accept_network = 1; - } -/* - * If our node number is zero then change it. - */ - if (zero_node (wo->our_node)) { - inc_node (wo->our_node); - ao->accept_local = 1; - wo->neg_node = 1; - } -/* - * If his node number is zero then change it. - */ - if (zero_node (wo->his_node)) { - inc_node (wo->his_node); - ao->accept_remote = 1; - } -/* - * If no routing agent was specified then we do RIP/SAP according to the - * RFC documents. If you have specified something then OK. Otherwise, we - * do RIP/SAP. - */ - if (ao->router == 0) { - ao->router |= BIT(RIP_SAP); - wo->router |= BIT(RIP_SAP); - } - - /* Always specify a routing protocol unless it was REJected. */ - wo->neg_router = 1; -/* - * Start with these default values - */ - *go = *wo; -} - -/* - * ipxcp_cilen - Return length of our CI. - */ - -static int -ipxcp_cilen(f) - fsm *f; -{ - int len; - - len = go->neg_nn ? CILEN_NETN : 0; - len += go->neg_node ? CILEN_NODEN : 0; - len += go->neg_name ? CILEN_NAME + strlen (go->name) - 1 : 0; - - /* RFC says that defaults should not be included. */ - if (go->neg_router && to_external(go->router) != RIP_SAP) - len += CILEN_PROTOCOL; - - return (len); -} - - -/* - * ipxcp_addci - Add our desired CIs to a packet. - */ -static void -ipxcp_addci(f, ucp, lenp) - fsm *f; - u_char *ucp; - int *lenp; -{ -/* - * Add the options to the record. - */ - if (go->neg_nn) { - PUTCHAR (IPX_NETWORK_NUMBER, ucp); - PUTCHAR (CILEN_NETN, ucp); - PUTLONG (go->our_network, ucp); - } - - if (go->neg_node) { - int indx; - PUTCHAR (IPX_NODE_NUMBER, ucp); - PUTCHAR (CILEN_NODEN, ucp); - for (indx = 0; indx < sizeof (go->our_node); ++indx) - PUTCHAR (go->our_node[indx], ucp); - } - - if (go->neg_name) { - int cilen = strlen (go->name); - int indx; - PUTCHAR (IPX_ROUTER_NAME, ucp); - PUTCHAR (CILEN_NAME + cilen - 1, ucp); - for (indx = 0; indx < cilen; ++indx) - PUTCHAR (go->name [indx], ucp); - } - - if (go->neg_router) { - short external = to_external (go->router); - if (external != RIP_SAP) { - PUTCHAR (IPX_ROUTER_PROTOCOL, ucp); - PUTCHAR (CILEN_PROTOCOL, ucp); - PUTSHORT (external, ucp); - } - } -} - -/* - * ipxcp_ackci - Ack our CIs. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int -ipxcp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - u_short cilen, citype, cishort; - u_char cichar; - u_int32_t cilong; - -#define ACKCIVOID(opt, neg) \ - if (neg) { \ - if ((len -= CILEN_VOID) < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_VOID || \ - citype != opt) \ - break; \ - } - -#define ACKCICOMPLETE(opt,neg) ACKCIVOID(opt, neg) - -#define ACKCICHARS(opt, neg, val, cnt) \ - if (neg) { \ - int indx, count = cnt; \ - len -= (count + 2); \ - if (len < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != (count + 2) || \ - citype != opt) \ - break; \ - for (indx = 0; indx < count; ++indx) {\ - GETCHAR(cichar, p); \ - if (cichar != ((u_char *) &val)[indx]) \ - break; \ - }\ - if (indx != count) \ - break; \ - } - -#define ACKCINODE(opt,neg,val) ACKCICHARS(opt,neg,val,sizeof(val)) -#define ACKCINAME(opt,neg,val) ACKCICHARS(opt,neg,val,strlen(val)) - -#define ACKCINETWORK(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_NETN) < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_NETN || \ - citype != opt) \ - break; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - break; \ - } - -#define ACKCIPROTO(opt, neg, val) \ - if (neg) { \ - if (len < 2) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_PROTOCOL || citype != opt) \ - break; \ - len -= cilen; \ - if (len < 0) \ - break; \ - GETSHORT(cishort, p); \ - if (cishort != to_external (val) || cishort == RIP_SAP) \ - break; \ - } -/* - * Process the ACK frame in the order in which the frame was assembled - */ - do { - ACKCINETWORK (IPX_NETWORK_NUMBER, go->neg_nn, go->our_network); - ACKCINODE (IPX_NODE_NUMBER, go->neg_node, go->our_node); - ACKCINAME (IPX_ROUTER_NAME, go->neg_name, go->name); - if (len > 0) - ACKCIPROTO (IPX_ROUTER_PROTOCOL, go->neg_router, go->router); -/* - * This is the end of the record. - */ - if (len == 0) - return (1); - } while (0); -/* - * The frame is invalid - */ - IPXCPDEBUG(("ipxcp_ackci: received bad Ack!")); - return (0); -} - -/* - * ipxcp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if IPXCP is in the OPENED state. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ - -static int -ipxcp_nakci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - u_char citype, cilen, *next; - u_short s; - u_int32_t l; - ipxcp_options no; /* options we've seen Naks for */ - ipxcp_options try; /* options to request next time */ - - BZERO(&no, sizeof(no)); - try = *go; - - while (len > CILEN_VOID) { - GETCHAR (citype, p); - GETCHAR (cilen, p); - len -= cilen; - if (len < 0) - goto bad; - next = &p [cilen - CILEN_VOID]; - - switch (citype) { - case IPX_NETWORK_NUMBER: - if (!go->neg_nn || no.neg_nn || (cilen != CILEN_NETN)) - goto bad; - no.neg_nn = 1; - - GETLONG(l, p); - if (l && ao->accept_network) - try.our_network = l; - break; - - case IPX_NODE_NUMBER: - if (!go->neg_node || no.neg_node || (cilen != CILEN_NODEN)) - goto bad; - no.neg_node = 1; - - if (!zero_node (p) && ao->accept_local && - ! compare_node (p, ho->his_node)) - copy_node (p, try.our_node); - break; - - /* This has never been sent. Ignore the NAK frame */ - case IPX_COMPRESSION_PROTOCOL: - goto bad; - - case IPX_ROUTER_PROTOCOL: - if (!go->neg_router || (cilen < CILEN_PROTOCOL)) - goto bad; - - GETSHORT (s, p); - if (s > 15) /* This is just bad, but ignore for now. */ - break; - - s = BIT(s); - if (no.router & s) /* duplicate NAKs are always bad */ - goto bad; - - if (no.router == 0) /* Reset on first NAK only */ - try.router = 0; - - no.router |= s; - try.router |= s; - try.neg_router = 1; - break; - - /* These, according to the RFC, must never be NAKed. */ - case IPX_ROUTER_NAME: - case IPX_COMPLETE: - goto bad; - - /* These are for options which we have not seen. */ - default: - break; - } - p = next; - } - - /* - * Do not permit the peer to force a router protocol which we do not - * support. However, default to the condition that will accept "NONE". - */ - try.router &= (ao->router | BIT(IPX_NONE)); - if (try.router == 0 && ao->router != 0) - try.router = BIT(IPX_NONE); - - if (try.router != 0) - try.neg_router = 1; - - /* - * OK, the Nak is good. Now we can update state. - * If there are any options left, we ignore them. - */ - if (f->state != OPENED) - *go = try; - - return 1; - -bad: - IPXCPDEBUG(("ipxcp_nakci: received bad Nak!")); - return 0; -} - -/* - * ipxcp_rejci - Reject some of our CIs. - */ -static int -ipxcp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - u_short cilen, citype, cishort; - u_char cichar; - u_int32_t cilong; - ipxcp_options try; /* options to request next time */ - -#define REJCINETWORK(opt, neg, val) \ - if (neg && p[0] == opt) { \ - if ((len -= CILEN_NETN) < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_NETN || \ - citype != opt) \ - break; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - break; \ - neg = 0; \ - } - -#define REJCICHARS(opt, neg, val, cnt) \ - if (neg && p[0] == opt) { \ - int indx, count = cnt; \ - len -= (count + 2); \ - if (len < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != (count + 2) || \ - citype != opt) \ - break; \ - for (indx = 0; indx < count; ++indx) {\ - GETCHAR(cichar, p); \ - if (cichar != ((u_char *) &val)[indx]) \ - break; \ - }\ - if (indx != count) \ - break; \ - neg = 0; \ - } - -#define REJCINODE(opt,neg,val) REJCICHARS(opt,neg,val,sizeof(val)) -#define REJCINAME(opt,neg,val) REJCICHARS(opt,neg,val,strlen(val)) - -#define REJCIVOID(opt, neg) \ - if (neg && p[0] == opt) { \ - if ((len -= CILEN_VOID) < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_VOID || citype != opt) \ - break; \ - neg = 0; \ - } - -/* a reject for RIP/SAP is invalid since we don't send it and you can't - reject something which is not sent. (You can NAK, but you can't REJ.) */ -#define REJCIPROTO(opt, neg, val, bit) \ - if (neg && p[0] == opt) { \ - if ((len -= CILEN_PROTOCOL) < 0) \ - break; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_PROTOCOL) \ - break; \ - GETSHORT(cishort, p); \ - if (cishort != to_external (val) || cishort == RIP_SAP) \ - break; \ - neg = 0; \ - } -/* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ - try = *go; - - do { - REJCINETWORK (IPX_NETWORK_NUMBER, try.neg_nn, try.our_network); - REJCINODE (IPX_NODE_NUMBER, try.neg_node, try.our_node); - REJCINAME (IPX_ROUTER_NAME, try.neg_name, try.name); - REJCIPROTO (IPX_ROUTER_PROTOCOL, try.neg_router, try.router, 0); -/* - * This is the end of the record. - */ - if (len == 0) { - if (f->state != OPENED) - *go = try; - return (1); - } - } while (0); -/* - * The frame is invalid at this point. - */ - IPXCPDEBUG(("ipxcp_rejci: received bad Reject!")); - return 0; -} - -/* - * ipxcp_reqci - Check the peer's requested CIs and send appropriate response. - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - */ -static int -ipxcp_reqci(f, inp, len, reject_if_disagree) - fsm *f; - u_char *inp; /* Requested CIs */ - int *len; /* Length of requested CIs */ - int reject_if_disagree; -{ - u_char *cip, *next; /* Pointer to current and next CIs */ - u_short cilen, citype; /* Parsed len, type */ - u_short cishort; /* Parsed short value */ - u_int32_t cinetwork; /* Parsed address values */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *ucp = inp; /* Pointer to current output char */ - int l = *len; /* Length left */ - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - IPXCPDEBUG(("ipxcp_reqci: bad CI length!")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ -/* - * The network number must match. Choose the larger of the two. - */ - case IPX_NETWORK_NUMBER: - /* if we wont negotiate the network number or the length is wrong - then reject the option */ - if ( !ao->neg_nn || cilen != CILEN_NETN ) { - orc = CONFREJ; - break; - } - GETLONG(cinetwork, p); - - /* If the network numbers match then acknowledge them. */ - if (cinetwork != 0) { - ho->his_network = cinetwork; - ho->neg_nn = 1; - if (wo->our_network == cinetwork) - break; -/* - * If the network number is not given or we don't accept their change or - * the network number is too small then NAK it. - */ - if (! ao->accept_network || cinetwork < wo->our_network) { - DECPTR (sizeof (u_int32_t), p); - PUTLONG (wo->our_network, p); - orc = CONFNAK; - } - break; - } -/* - * The peer sent '0' for the network. Give it ours if we have one. - */ - if (go->our_network != 0) { - DECPTR (sizeof (u_int32_t), p); - PUTLONG (wo->our_network, p); - orc = CONFNAK; -/* - * We don't have one. Reject the value. - */ - } else - orc = CONFREJ; - - break; -/* - * The node number is required - */ - case IPX_NODE_NUMBER: - /* if we wont negotiate the node number or the length is wrong - then reject the option */ - if ( cilen != CILEN_NODEN ) { - orc = CONFREJ; - break; - } - - copy_node (p, ho->his_node); - ho->neg_node = 1; -/* - * If the remote does not have a number and we do then NAK it with the value - * which we have for it. (We never have a default value of zero.) - */ - if (zero_node (ho->his_node)) { - orc = CONFNAK; - copy_node (wo->his_node, p); - INCPTR (sizeof (wo->his_node), p); - break; - } -/* - * If you have given me the expected network node number then I'll accept - * it now. - */ - if (compare_node (wo->his_node, ho->his_node)) { - orc = CONFACK; - ho->neg_node = 1; - INCPTR (sizeof (wo->his_node), p); - break; - } -/* - * If his node number is the same as ours then ask him to try the next - * value. - */ - if (compare_node (ho->his_node, go->our_node)) { - inc_node (ho->his_node); - orc = CONFNAK; - copy_node (ho->his_node, p); - INCPTR (sizeof (wo->his_node), p); - break; - } -/* - * If we don't accept a new value then NAK it. - */ - if (! ao->accept_remote) { - copy_node (wo->his_node, p); - INCPTR (sizeof (wo->his_node), p); - orc = CONFNAK; - break; - } - orc = CONFACK; - ho->neg_node = 1; - INCPTR (sizeof (wo->his_node), p); - break; -/* - * Compression is not desired at this time. It is always rejected. - */ - case IPX_COMPRESSION_PROTOCOL: - orc = CONFREJ; - break; -/* - * The routing protocol is a bitmask of various types. Any combination - * of the values RIP_SAP and NLSP are permissible. 'IPX_NONE' for no - * routing protocol must be specified only once. - */ - case IPX_ROUTER_PROTOCOL: - if ( !ao->neg_router || cilen < CILEN_PROTOCOL ) { - orc = CONFREJ; - break; - } - - GETSHORT (cishort, p); - - if (wo->neg_router == 0) { - wo->neg_router = 1; - wo->router = BIT(IPX_NONE); - } - - if ((cishort == IPX_NONE && ho->router != 0) || - (ho->router & BIT(IPX_NONE))) { - orc = CONFREJ; - break; - } - - cishort = BIT(cishort); - if (ho->router & cishort) { - orc = CONFREJ; - break; - } - - ho->router |= cishort; - ho->neg_router = 1; - - /* Finally do not allow a router protocol which we do not - support. */ - - if ((cishort & (ao->router | BIT(IPX_NONE))) == 0) { - int protocol; - - if (cishort == BIT(NLSP) && - (ao->router & BIT(RIP_SAP)) && - !wo->tried_rip) { - protocol = RIP_SAP; - wo->tried_rip = 1; - } else - protocol = IPX_NONE; - - DECPTR (sizeof (u_int16_t), p); - PUTSHORT (protocol, p); - orc = CONFNAK; - } - break; -/* - * The router name is advisorary. Just accept it if it is not too large. - */ - case IPX_ROUTER_NAME: - if (cilen >= CILEN_NAME) { - int name_size = cilen - CILEN_NAME; - if (name_size > sizeof (ho->name)) - name_size = sizeof (ho->name) - 1; - memset (ho->name, 0, sizeof (ho->name)); - memcpy (ho->name, p, name_size); - ho->name [name_size] = '\0'; - ho->neg_name = 1; - orc = CONFACK; - break; - } - orc = CONFREJ; - break; -/* - * This is advisorary. - */ - case IPX_COMPLETE: - if (cilen != CILEN_COMPLETE) - orc = CONFREJ; - else { - ho->neg_complete = 1; - orc = CONFACK; - } - break; -/* - * All other entries are not known at this time. - */ - default: - orc = CONFREJ; - break; - } -endswitch: - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) /* but prior CI wasnt? */ - continue; /* Don't send this one */ - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree) /* Getting fed up with sending NAKs? */ - orc = CONFREJ; /* Get tough if so */ - if (rc == CONFREJ) /* Rejecting prior CI? */ - continue; /* Don't send this one */ - if (rc == CONFACK) { /* Ack'd all prior CIs? */ - rc = CONFNAK; /* Not anymore... */ - ucp = inp; /* Backup */ - } - } - - if (orc == CONFREJ && /* Reject this CI */ - rc != CONFREJ) { /* but no prior ones? */ - rc = CONFREJ; - ucp = inp; /* Backup */ - } - - /* Need to move CI? */ - if (ucp != cip) - BCOPY(cip, ucp, cilen); /* Move it */ - - /* Update output pointer */ - INCPTR(cilen, ucp); - } - - /* - * If we aren't rejecting this packet, and we want to negotiate - * their address, and they didn't send their address, then we - * send a NAK with a IPX_NODE_NUMBER option appended. We assume the - * input buffer is long enough that we can append the extra - * option safely. - */ - - if (rc != CONFREJ && !ho->neg_node && - wo->req_nn && !reject_if_disagree) { - if (rc == CONFACK) { - rc = CONFNAK; - wo->req_nn = 0; /* don't ask again */ - ucp = inp; /* reset pointer */ - } - - if (zero_node (wo->his_node)) - inc_node (wo->his_node); - - PUTCHAR (IPX_NODE_NUMBER, ucp); - PUTCHAR (CILEN_NODEN, ucp); - copy_node (wo->his_node, ucp); - INCPTR (sizeof (wo->his_node), ucp); - } - - *len = ucp - inp; /* Compute output length */ - IPXCPDEBUG(("ipxcp: returning Configure-%s", CODENAME(rc))); - return (rc); /* Return final code */ -} - -/* - * ipxcp_up - IPXCP has come UP. - * - * Configure the IP network interface appropriately and bring it up. - */ - -static void -ipxcp_up(f) - fsm *f; -{ - int unit = f->unit; - - IPXCPDEBUG(("ipxcp: up")); - - /* The default router protocol is RIP/SAP. */ - if (ho->router == 0) - ho->router = BIT(RIP_SAP); - - if (go->router == 0) - go->router = BIT(RIP_SAP); - - /* Fetch the network number */ - if (!ho->neg_nn) - ho->his_network = wo->his_network; - - if (!ho->neg_node) - copy_node (wo->his_node, ho->his_node); - - if (!wo->neg_node && !go->neg_node) - copy_node (wo->our_node, go->our_node); - - if (zero_node (go->our_node)) { - static char errmsg[] = "Could not determine local IPX node address"; - if (debug) - error(errmsg); - ipxcp_close(f->unit, errmsg); - return; - } - - go->network = go->our_network; - if (ho->his_network != 0 && ho->his_network > go->network) - go->network = ho->his_network; - - if (go->network == 0) { - static char errmsg[] = "Can not determine network number"; - if (debug) - error(errmsg); - ipxcp_close (unit, errmsg); - return; - } - - /* bring the interface up */ - if (!sifup(unit)) { - if (debug) - warn("sifup failed (IPX)"); - ipxcp_close(unit, "Interface configuration failed"); - return; - } - ipxcp_is_up = 1; - - /* set the network number for IPX */ - if (!sipxfaddr(unit, go->network, go->our_node)) { - if (debug) - warn("sipxfaddr failed"); - ipxcp_close(unit, "Interface configuration failed"); - return; - } - - np_up(f->unit, PPP_IPX); - - /* - * Execute the ipx-up script, like this: - * /etc/ppp/ipx-up interface tty speed local-IPX remote-IPX - */ - - ipxcp_script (f, _PATH_IPXUP); -} - -/* - * ipxcp_down - IPXCP has gone DOWN. - * - * Take the IP network interface down, clear its addresses - * and delete routes through it. - */ - -static void -ipxcp_down(f) - fsm *f; -{ - IPXCPDEBUG(("ipxcp: down")); - - if (!ipxcp_is_up) - return; - ipxcp_is_up = 0; - np_down(f->unit, PPP_IPX); - cipxfaddr(f->unit); - sifnpmode(f->unit, PPP_IPX, NPMODE_DROP); - sifdown(f->unit); - ipxcp_script (f, _PATH_IPXDOWN); -} - - -/* - * ipxcp_finished - possibly shut down the lower layers. - */ -static void -ipxcp_finished(f) - fsm *f; -{ - np_finished(f->unit, PPP_IPX); -} - - -/* - * ipxcp_script - Execute a script with arguments - * interface-name tty-name speed local-IPX remote-IPX networks. - */ -static void -ipxcp_script(f, script) - fsm *f; - char *script; -{ - char strspeed[32], strlocal[32], strremote[32]; - char strnetwork[32], strpid[32]; - char *argv[14], strproto_lcl[32], strproto_rmt[32]; - - slprintf(strpid, sizeof(strpid), "%d", getpid()); - slprintf(strspeed, sizeof(strspeed),"%d", baud_rate); - - strproto_lcl[0] = '\0'; - if (go->neg_router && ((go->router & BIT(IPX_NONE)) == 0)) { - if (go->router & BIT(RIP_SAP)) - strlcpy (strproto_lcl, "RIP ", sizeof(strproto_lcl)); - if (go->router & BIT(NLSP)) - strlcat (strproto_lcl, "NLSP ", sizeof(strproto_lcl)); - } - - if (strproto_lcl[0] == '\0') - strlcpy (strproto_lcl, "NONE ", sizeof(strproto_lcl)); - - strproto_lcl[strlen (strproto_lcl)-1] = '\0'; - - strproto_rmt[0] = '\0'; - if (ho->neg_router && ((ho->router & BIT(IPX_NONE)) == 0)) { - if (ho->router & BIT(RIP_SAP)) - strlcpy (strproto_rmt, "RIP ", sizeof(strproto_rmt)); - if (ho->router & BIT(NLSP)) - strlcat (strproto_rmt, "NLSP ", sizeof(strproto_rmt)); - } - - if (strproto_rmt[0] == '\0') - strlcpy (strproto_rmt, "NONE ", sizeof(strproto_rmt)); - - strproto_rmt[strlen (strproto_rmt)-1] = '\0'; - - strlcpy (strnetwork, ipx_ntoa (go->network), sizeof(strnetwork)); - - slprintf (strlocal, sizeof(strlocal), "%0.6B", go->our_node); - - slprintf (strremote, sizeof(strremote), "%0.6B", ho->his_node); - - argv[0] = script; - argv[1] = ifname; - argv[2] = devnam; - argv[3] = strspeed; - argv[4] = strnetwork; - argv[5] = strlocal; - argv[6] = strremote; - argv[7] = strproto_lcl; - argv[8] = strproto_rmt; - argv[9] = go->name; - argv[10] = ho->name; - argv[11] = ipparam; - argv[12] = strpid; - argv[13] = NULL; - run_program(script, argv, 0, NULL, NULL); -} - -/* - * ipxcp_printpkt - print the contents of an IPXCP packet. - */ -static char *ipxcp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej" -}; - -static int -ipxcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int code, id, len, olen; - u_char *pstart, *optend; - u_short cishort; - u_int32_t cilong; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(ipxcp_codenames) / sizeof(char *)) - printer(arg, " %s", ipxcp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < CILEN_VOID || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { - case IPX_NETWORK_NUMBER: - if (olen == CILEN_NETN) { - p += 2; - GETLONG(cilong, p); - printer (arg, "network %s", ipx_ntoa (cilong)); - } - break; - case IPX_NODE_NUMBER: - if (olen == CILEN_NODEN) { - p += 2; - printer (arg, "node "); - while (p < optend) { - GETCHAR(code, p); - printer(arg, "%.2x", (int) (unsigned int) (unsigned char) code); - } - } - break; - case IPX_COMPRESSION_PROTOCOL: - if (olen == CILEN_COMPRESS) { - p += 2; - GETSHORT (cishort, p); - printer (arg, "compression %d", (int) cishort); - } - break; - case IPX_ROUTER_PROTOCOL: - if (olen == CILEN_PROTOCOL) { - p += 2; - GETSHORT (cishort, p); - printer (arg, "router proto %d", (int) cishort); - } - break; - case IPX_ROUTER_NAME: - if (olen >= CILEN_NAME) { - p += 2; - printer (arg, "router name \""); - while (p < optend) { - GETCHAR(code, p); - if (code >= 0x20 && code <= 0x7E) - printer (arg, "%c", (int) (unsigned int) (unsigned char) code); - else - printer (arg, " \\%.2x", (int) (unsigned int) (unsigned char) code); - } - printer (arg, "\""); - } - break; - case IPX_COMPLETE: - if (olen == CILEN_COMPLETE) { - p += 2; - printer (arg, "complete"); - } - break; - default: - break; - } - - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", (int) (unsigned int) (unsigned char) code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", (int) (unsigned int) (unsigned char) code); - } - - return p - pstart; -} -#endif /* ifdef IPX_CHANGE */ diff --git a/mdk-stage1/ppp/pppd/ipxcp.h b/mdk-stage1/ppp/pppd/ipxcp.h deleted file mode 100644 index 47f680d70..000000000 --- a/mdk-stage1/ppp/pppd/ipxcp.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * ipxcp.h - IPX Control Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - * - * $Id$ - */ - -/* - * Options. - */ -#define IPX_NETWORK_NUMBER 1 /* IPX Network Number */ -#define IPX_NODE_NUMBER 2 -#define IPX_COMPRESSION_PROTOCOL 3 -#define IPX_ROUTER_PROTOCOL 4 -#define IPX_ROUTER_NAME 5 -#define IPX_COMPLETE 6 - -/* Values for the router protocol */ -#define IPX_NONE 0 -#define RIP_SAP 2 -#define NLSP 4 - -typedef struct ipxcp_options { - bool neg_node; /* Negotiate IPX node number? */ - bool req_node; /* Ask peer to send IPX node number? */ - - bool neg_nn; /* Negotiate IPX network number? */ - bool req_nn; /* Ask peer to send IPX network number */ - - bool neg_name; /* Negotiate IPX router name */ - bool neg_complete; /* Negotiate completion */ - bool neg_router; /* Negotiate IPX router number */ - - bool accept_local; /* accept peer's value for ournode */ - bool accept_remote; /* accept peer's value for hisnode */ - bool accept_network; /* accept network number */ - - bool tried_nlsp; /* I have suggested NLSP already */ - bool tried_rip; /* I have suggested RIP/SAP already */ - - u_int32_t his_network; /* base network number */ - u_int32_t our_network; /* our value for network number */ - u_int32_t network; /* the final network number */ - - u_char his_node[6]; /* peer's node number */ - u_char our_node[6]; /* our node number */ - u_char name [48]; /* name of the router */ - int router; /* routing protocol */ -} ipxcp_options; - -extern fsm ipxcp_fsm[]; -extern ipxcp_options ipxcp_wantoptions[]; -extern ipxcp_options ipxcp_gotoptions[]; -extern ipxcp_options ipxcp_allowoptions[]; -extern ipxcp_options ipxcp_hisoptions[]; - -extern struct protent ipxcp_protent; diff --git a/mdk-stage1/ppp/pppd/lcp.c b/mdk-stage1/ppp/pppd/lcp.c deleted file mode 100644 index 41c58cad5..000000000 --- a/mdk-stage1/ppp/pppd/lcp.c +++ /dev/null @@ -1,2224 +0,0 @@ -/* - * lcp.c - PPP Link Control Protocol. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -#define RCSID "$Id$" - -/* - * TODO: - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#include "pppd.h" -#include "fsm.h" -#include "lcp.h" -#include "chap.h" -#include "magic.h" - -static const char rcsid[] = RCSID; - -/* - * When the link comes up we want to be able to wait for a short while, - * or until seeing some input from the peer, before starting to send - * configure-requests. We do this by delaying the fsm_lowerup call. - */ -/* steal a bit in fsm flags word */ -#define DELAYED_UP 0x100 - -static void lcp_delayed_up __P((void *)); - -/* - * LCP-related command-line options. - */ -int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ -int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ -bool lax_recv = 0; /* accept control chars in asyncmap */ -bool noendpoint = 0; /* don't send/accept endpoint discriminator */ - -static int noopt __P((char **)); - -#ifdef HAVE_MULTILINK -static int setendpoint __P((char **)); -static void printendpoint __P((option_t *, void (*)(void *, char *, ...), - void *)); -#endif /* HAVE_MULTILINK */ - -static option_t lcp_option_list[] = { - /* LCP options */ - { "-all", o_special_noarg, (void *)noopt, - "Don't request/allow any LCP options" }, - - { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression, - "Disable address/control compression", - OPT_A2CLR, &lcp_allowoptions[0].neg_accompression }, - { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression, - "Disable address/control compression", - OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression }, - - { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, - "Set asyncmap (for received packets)", - OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, - { "-as", o_uint32, &lcp_wantoptions[0].asyncmap, - "Set asyncmap (for received packets)", - OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, - { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, - "Disable asyncmap negotiation", - OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR, - &lcp_allowoptions[0].neg_asyncmap }, - { "-am", o_uint32, &lcp_wantoptions[0].asyncmap, - "Disable asyncmap negotiation", - OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR, - &lcp_allowoptions[0].neg_asyncmap }, - - { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber, - "Disable magic number negotiation (looped-back line detection)", - OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber }, - { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber, - "Disable magic number negotiation (looped-back line detection)", - OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber }, - - { "mru", o_int, &lcp_wantoptions[0].mru, - "Set MRU (maximum received packet size) for negotiation", - OPT_PRIO, &lcp_wantoptions[0].neg_mru }, - { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru, - "Disable MRU negotiation (use default 1500)", - OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru }, - { "-mru", o_bool, &lcp_wantoptions[0].neg_mru, - "Disable MRU negotiation (use default 1500)", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru }, - - { "mtu", o_int, &lcp_allowoptions[0].mru, - "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU }, - - { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression, - "Disable protocol field compression", - OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression }, - { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression, - "Disable protocol field compression", - OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression }, - - { "passive", o_bool, &lcp_wantoptions[0].passive, - "Set passive mode", 1 }, - { "-p", o_bool, &lcp_wantoptions[0].passive, - "Set passive mode", OPT_ALIAS | 1 }, - - { "silent", o_bool, &lcp_wantoptions[0].silent, - "Set silent mode", 1 }, - - { "lcp-echo-failure", o_int, &lcp_echo_fails, - "Set number of consecutive echo failures to indicate link failure", - OPT_PRIO }, - { "lcp-echo-interval", o_int, &lcp_echo_interval, - "Set time in seconds between LCP echo requests", OPT_PRIO }, - { "lcp-restart", o_int, &lcp_fsm[0].timeouttime, - "Set time in seconds between LCP retransmissions", OPT_PRIO }, - { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits, - "Set maximum number of LCP terminate-request transmissions", OPT_PRIO }, - { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits, - "Set maximum number of LCP configure-request transmissions", OPT_PRIO }, - { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops, - "Set limit on number of LCP configure-naks", OPT_PRIO }, - - { "receive-all", o_bool, &lax_recv, - "Accept all received control characters", 1 }, - -#ifdef HAVE_MULTILINK - { "mrru", o_int, &lcp_wantoptions[0].mrru, - "Maximum received packet size for multilink bundle", - OPT_PRIO, &lcp_wantoptions[0].neg_mrru }, - - { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, - "Use short sequence numbers in multilink headers", - OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf }, - { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, - "Don't use short sequence numbers in multilink headers", - OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf }, - - { "endpoint", o_special, (void *) setendpoint, - "Endpoint discriminator for multilink", - OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint }, -#endif /* HAVE_MULTILINK */ - - { "noendpoint", o_bool, &noendpoint, - "Don't send or accept multilink endpoint discriminator", 1 }, - - {NULL} -}; - -/* global vars */ -fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/ -lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */ -lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ -lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ -lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ - -static int lcp_echos_pending = 0; /* Number of outstanding echo msgs */ -static int lcp_echo_number = 0; /* ID number of next echo frame */ -static int lcp_echo_timer_running = 0; /* set if a timer is running */ - -static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void lcp_resetci __P((fsm *)); /* Reset our CI */ -static int lcp_cilen __P((fsm *)); /* Return length of our CI */ -static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */ -static int lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int lcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */ -static int lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ -static int lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */ -static void lcp_up __P((fsm *)); /* We're UP */ -static void lcp_down __P((fsm *)); /* We're DOWN */ -static void lcp_starting __P((fsm *)); /* We need lower layer up */ -static void lcp_finished __P((fsm *)); /* We need lower layer down */ -static int lcp_extcode __P((fsm *, int, int, u_char *, int)); -static void lcp_rprotrej __P((fsm *, u_char *, int)); - -/* - * routines to send LCP echos to peer - */ - -static void lcp_echo_lowerup __P((int)); -static void lcp_echo_lowerdown __P((int)); -static void LcpEchoTimeout __P((void *)); -static void lcp_received_echo_reply __P((fsm *, int, u_char *, int)); -static void LcpSendEchoRequest __P((fsm *)); -static void LcpLinkFailure __P((fsm *)); -static void LcpEchoCheck __P((fsm *)); - -static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ - lcp_resetci, /* Reset our Configuration Information */ - lcp_cilen, /* Length of our Configuration Information */ - lcp_addci, /* Add our Configuration Information */ - lcp_ackci, /* ACK our Configuration Information */ - lcp_nakci, /* NAK our Configuration Information */ - lcp_rejci, /* Reject our Configuration Information */ - lcp_reqci, /* Request peer's Configuration Information */ - lcp_up, /* Called when fsm reaches OPENED state */ - lcp_down, /* Called when fsm leaves OPENED state */ - lcp_starting, /* Called when we want the lower layer up */ - lcp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - lcp_extcode, /* Called to handle LCP-specific codes */ - "LCP" /* String name of protocol */ -}; - -/* - * Protocol entry points. - * Some of these are called directly. - */ - -static void lcp_init __P((int)); -static void lcp_input __P((int, u_char *, int)); -static void lcp_protrej __P((int)); -static int lcp_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); - -struct protent lcp_protent = { - PPP_LCP, - lcp_init, - lcp_input, - lcp_protrej, - lcp_lowerup, - lcp_lowerdown, - lcp_open, - lcp_close, - lcp_printpkt, - NULL, - 1, - "LCP", - NULL, - lcp_option_list, - NULL, - NULL, - NULL -}; - -int lcp_loopbackfail = DEFLOOPBACKFAIL; - -/* - * Length of each type of configuration option (in octets) - */ -#define CILEN_VOID 2 -#define CILEN_CHAR 3 -#define CILEN_SHORT 4 /* CILEN_VOID + 2 */ -#define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */ -#define CILEN_LONG 6 /* CILEN_VOID + 4 */ -#define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */ -#define CILEN_CBCP 3 - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - -/* - * noopt - Disable all options (why?). - */ -static int -noopt(argv) - char **argv; -{ - BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options)); - BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options)); - - return (1); -} - -#ifdef HAVE_MULTILINK -static int -setendpoint(argv) - char **argv; -{ - if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) { - lcp_wantoptions[0].neg_endpoint = 1; - return 1; - } - option_error("Can't parse '%s' as an endpoint discriminator", *argv); - return 0; -} - -static void -printendpoint(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint)); -} -#endif /* HAVE_MULTILINK */ - -/* - * lcp_init - Initialize LCP. - */ -static void -lcp_init(unit) - int unit; -{ - fsm *f = &lcp_fsm[unit]; - lcp_options *wo = &lcp_wantoptions[unit]; - lcp_options *ao = &lcp_allowoptions[unit]; - - f->unit = unit; - f->protocol = PPP_LCP; - f->callbacks = &lcp_callbacks; - - fsm_init(f); - - BZERO(wo, sizeof(*wo)); - wo->neg_mru = 1; - wo->mru = DEFMRU; - wo->neg_asyncmap = 1; - wo->chap_mdtype = CHAP_DIGEST_MD5; - wo->neg_magicnumber = 1; - wo->neg_pcompression = 1; - wo->neg_accompression = 1; - - BZERO(ao, sizeof(*ao)); - ao->neg_mru = 1; - ao->mru = MAXMRU; - ao->neg_asyncmap = 1; - ao->neg_chap = 1; - ao->chap_mdtype = CHAP_DIGEST_MD5; - ao->neg_upap = 1; - ao->neg_magicnumber = 1; - ao->neg_pcompression = 1; - ao->neg_accompression = 1; -#ifdef CBCP_SUPPORT - ao->neg_cbcp = 1; -#endif - ao->neg_endpoint = 1; -} - - -/* - * lcp_open - LCP is allowed to come up. - */ -void -lcp_open(unit) - int unit; -{ - fsm *f = &lcp_fsm[unit]; - lcp_options *wo = &lcp_wantoptions[unit]; - - f->flags &= ~(OPT_PASSIVE | OPT_SILENT); - if (wo->passive) - f->flags |= OPT_PASSIVE; - if (wo->silent) - f->flags |= OPT_SILENT; - fsm_open(f); -} - - -/* - * lcp_close - Take LCP down. - */ -void -lcp_close(unit, reason) - int unit; - char *reason; -{ - fsm *f = &lcp_fsm[unit]; - - if (phase != PHASE_DEAD) - new_phase(PHASE_TERMINATE); - if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) { - /* - * This action is not strictly according to the FSM in RFC1548, - * but it does mean that the program terminates if you do a - * lcp_close() in passive/silent mode when a connection hasn't - * been established. - */ - f->state = CLOSED; - lcp_finished(f); - - } else - fsm_close(&lcp_fsm[unit], reason); -} - - -/* - * lcp_lowerup - The lower layer is up. - */ -void -lcp_lowerup(unit) - int unit; -{ - lcp_options *wo = &lcp_wantoptions[unit]; - fsm *f = &lcp_fsm[unit]; - - /* - * Don't use A/C or protocol compression on transmission, - * but accept A/C and protocol compressed packets - * if we are going to ask for A/C and protocol compression. - */ - ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0); - ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff), - wo->neg_pcompression, wo->neg_accompression); - peer_mru[unit] = PPP_MRU; - - if (listen_time != 0) { - f->flags |= DELAYED_UP; - timeout(lcp_delayed_up, f, 0, listen_time * 1000); - } else - fsm_lowerup(f); -} - - -/* - * lcp_lowerdown - The lower layer is down. - */ -void -lcp_lowerdown(unit) - int unit; -{ - fsm *f = &lcp_fsm[unit]; - - if (f->flags & DELAYED_UP) - f->flags &= ~DELAYED_UP; - else - fsm_lowerdown(&lcp_fsm[unit]); -} - - -/* - * lcp_delayed_up - Bring the lower layer up now. - */ -static void -lcp_delayed_up(arg) - void *arg; -{ - fsm *f = arg; - - if (f->flags & DELAYED_UP) { - f->flags &= ~DELAYED_UP; - fsm_lowerup(f); - } -} - - -/* - * lcp_input - Input LCP packet. - */ -static void -lcp_input(unit, p, len) - int unit; - u_char *p; - int len; -{ - fsm *f = &lcp_fsm[unit]; - - if (f->flags & DELAYED_UP) { - f->flags &= ~DELAYED_UP; - fsm_lowerup(f); - } - fsm_input(f, p, len); -} - - -/* - * lcp_extcode - Handle a LCP-specific code. - */ -static int -lcp_extcode(f, code, id, inp, len) - fsm *f; - int code, id; - u_char *inp; - int len; -{ - u_char *magp; - - switch( code ){ - case PROTREJ: - lcp_rprotrej(f, inp, len); - break; - - case ECHOREQ: - if (f->state != OPENED) - break; - magp = inp; - PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp); - fsm_sdata(f, ECHOREP, id, inp, len); - break; - - case ECHOREP: - lcp_received_echo_reply(f, id, inp, len); - break; - - case DISCREQ: - break; - - default: - return 0; - } - return 1; -} - - -/* - * lcp_rprotrej - Receive an Protocol-Reject. - * - * Figure out which protocol is rejected and inform it. - */ -static void -lcp_rprotrej(f, inp, len) - fsm *f; - u_char *inp; - int len; -{ - int i; - struct protent *protp; - u_short prot; - - if (len < 2) { - LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!")); - return; - } - - GETSHORT(prot, inp); - - /* - * Protocol-Reject packets received in any state other than the LCP - * OPENED state SHOULD be silently discarded. - */ - if( f->state != OPENED ){ - LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state)); - return; - } - - /* - * Upcall the proper Protocol-Reject routine. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol == prot && protp->enabled_flag) { - (*protp->protrej)(f->unit); - return; - } - - warn("Protocol-Reject for unsupported protocol 0x%x", prot); -} - - -/* - * lcp_protrej - A Protocol-Reject was received. - */ -/*ARGSUSED*/ -static void -lcp_protrej(unit) - int unit; -{ - /* - * Can't reject LCP! - */ - error("Received Protocol-Reject for LCP!"); - fsm_protreject(&lcp_fsm[unit]); -} - - -/* - * lcp_sprotrej - Send a Protocol-Reject for some protocol. - */ -void -lcp_sprotrej(unit, p, len) - int unit; - u_char *p; - int len; -{ - /* - * Send back the protocol and the information field of the - * rejected packet. We only get here if LCP is in the OPENED state. - */ - p += 2; - len -= 2; - - fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, - p, len); -} - - -/* - * lcp_resetci - Reset our CI. - */ -static void -lcp_resetci(f) - fsm *f; -{ - lcp_options *wo = &lcp_wantoptions[f->unit]; - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *ao = &lcp_allowoptions[f->unit]; - - wo->magicnumber = magic(); - wo->numloops = 0; - *go = *wo; - if (!multilink) { - go->neg_mrru = 0; - go->neg_ssnhf = 0; - go->neg_endpoint = 0; - } - if (noendpoint) - ao->neg_endpoint = 0; - peer_mru[f->unit] = PPP_MRU; - auth_reset(f->unit); -} - - -/* - * lcp_cilen - Return length of our CI. - */ -static int -lcp_cilen(f) - fsm *f; -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - -#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) -#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0) -#define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) -#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) -#define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) -#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) - /* - * NB: we only ask for one of CHAP and UPAP, even if we will - * accept either. - */ - return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) + - LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) + - LENCICHAP(go->neg_chap) + - LENCISHORT(!go->neg_chap && go->neg_upap) + - LENCILQR(go->neg_lqr) + - LENCICBCP(go->neg_cbcp) + - LENCILONG(go->neg_magicnumber) + - LENCIVOID(go->neg_pcompression) + - LENCIVOID(go->neg_accompression) + - LENCISHORT(go->neg_mrru) + - LENCIVOID(go->neg_ssnhf) + - (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0)); -} - - -/* - * lcp_addci - Add our desired CIs to a packet. - */ -static void -lcp_addci(f, ucp, lenp) - fsm *f; - u_char *ucp; - int *lenp; -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - u_char *start_ucp = ucp; - -#define ADDCIVOID(opt, neg) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_VOID, ucp); \ - } -#define ADDCISHORT(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_SHORT, ucp); \ - PUTSHORT(val, ucp); \ - } -#define ADDCICHAP(opt, neg, val, digest) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAP, ucp); \ - PUTSHORT(val, ucp); \ - PUTCHAR(digest, ucp); \ - } -#define ADDCILONG(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_LONG, ucp); \ - PUTLONG(val, ucp); \ - } -#define ADDCILQR(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_LQR, ucp); \ - PUTSHORT(PPP_LQR, ucp); \ - PUTLONG(val, ucp); \ - } -#define ADDCICHAR(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAR, ucp); \ - PUTCHAR(val, ucp); \ - } -#define ADDCIENDP(opt, neg, class, val, len) \ - if (neg) { \ - int i; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAR + len, ucp); \ - PUTCHAR(class, ucp); \ - for (i = 0; i < len; ++i) \ - PUTCHAR(val[i], ucp); \ - } - - ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); - ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, - go->asyncmap); - ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); - ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); - ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); - ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); - ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); - ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); - ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); - ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru); - ADDCIVOID(CI_SSNHF, go->neg_ssnhf); - ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, - go->endpoint.value, go->endpoint.length); - - if (ucp - start_ucp != *lenp) { - /* this should never happen, because peer_mtu should be 1500 */ - error("Bug in lcp_addci: wrong length"); - } -} - - -/* - * lcp_ackci - Ack our CIs. - * This should not modify any state if the Ack is bad. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int -lcp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - u_char cilen, citype, cichar; - u_short cishort; - u_int32_t cilong; - - /* - * CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define ACKCIVOID(opt, neg) \ - if (neg) { \ - if ((len -= CILEN_VOID) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_VOID || \ - citype != opt) \ - goto bad; \ - } -#define ACKCISHORT(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_SHORT) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_SHORT || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - } -#define ACKCICHAR(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_CHAR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAR || \ - citype != opt) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != val) \ - goto bad; \ - } -#define ACKCICHAP(opt, neg, val, digest) \ - if (neg) { \ - if ((len -= CILEN_CHAP) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAP || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != digest) \ - goto bad; \ - } -#define ACKCILONG(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_LONG) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_LONG || \ - citype != opt) \ - goto bad; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - goto bad; \ - } -#define ACKCILQR(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_LQR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_LQR || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != PPP_LQR) \ - goto bad; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - goto bad; \ - } -#define ACKCIENDP(opt, neg, class, val, vlen) \ - if (neg) { \ - int i; \ - if ((len -= CILEN_CHAR + vlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAR + vlen || \ - citype != opt) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != class) \ - goto bad; \ - for (i = 0; i < vlen; ++i) { \ - GETCHAR(cichar, p); \ - if (cichar != val[i]) \ - goto bad; \ - } \ - } - - ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); - ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, - go->asyncmap); - ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); - ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); - ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); - ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); - ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); - ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); - ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); - ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru); - ACKCIVOID(CI_SSNHF, go->neg_ssnhf); - ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, - go->endpoint.value, go->endpoint.length); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); -bad: - LCPDEBUG(("lcp_acki: received bad Ack!")); - return (0); -} - - -/* - * lcp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if LCP is in the OPENED state. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int -lcp_nakci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *wo = &lcp_wantoptions[f->unit]; - u_char citype, cichar, *next; - u_short cishort; - u_int32_t cilong; - lcp_options no; /* options we've seen Naks for */ - lcp_options try; /* options to request next time */ - int looped_back = 0; - int cilen; - - BZERO(&no, sizeof(no)); - try = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIVOID(opt, neg) \ - if (go->neg && \ - len >= CILEN_VOID && \ - p[1] == CILEN_VOID && \ - p[0] == opt) { \ - len -= CILEN_VOID; \ - INCPTR(CILEN_VOID, p); \ - no.neg = 1; \ - try.neg = 0; \ - } -#define NAKCICHAP(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - no.neg = 1; \ - code \ - } -#define NAKCICHAR(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_CHAR && \ - p[1] == CILEN_CHAR && \ - p[0] == opt) { \ - len -= CILEN_CHAR; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - no.neg = 1; \ - code \ - } -#define NAKCISHORT(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_SHORT && \ - p[1] == CILEN_SHORT && \ - p[0] == opt) { \ - len -= CILEN_SHORT; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } -#define NAKCILONG(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_LONG && \ - p[1] == CILEN_LONG && \ - p[0] == opt) { \ - len -= CILEN_LONG; \ - INCPTR(2, p); \ - GETLONG(cilong, p); \ - no.neg = 1; \ - code \ - } -#define NAKCILQR(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_LQR && \ - p[1] == CILEN_LQR && \ - p[0] == opt) { \ - len -= CILEN_LQR; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETLONG(cilong, p); \ - no.neg = 1; \ - code \ - } -#define NAKCIENDP(opt, neg) \ - if (go->neg && \ - len >= CILEN_CHAR && \ - p[0] == opt && \ - p[1] >= CILEN_CHAR && \ - p[1] <= len) { \ - len -= p[1]; \ - INCPTR(p[1], p); \ - no.neg = 1; \ - try.neg = 0; \ - } - - /* - * We don't care if they want to send us smaller packets than - * we want. Therefore, accept any MRU less than what we asked for, - * but then ignore the new value when setting the MRU in the kernel. - * If they send us a bigger MRU than what we asked, accept it, up to - * the limit of the default MRU we'd get if we didn't negotiate. - */ - if (go->neg_mru && go->mru != DEFMRU) { - NAKCISHORT(CI_MRU, neg_mru, - if (cishort <= wo->mru || cishort <= DEFMRU) - try.mru = cishort; - ); - } - - /* - * Add any characters they want to our (receive-side) asyncmap. - */ - if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) { - NAKCILONG(CI_ASYNCMAP, neg_asyncmap, - try.asyncmap = go->asyncmap | cilong; - ); - } - - /* - * If they've nak'd our authentication-protocol, check whether - * they are proposing a different protocol, or a different - * hash algorithm for CHAP. - */ - if ((go->neg_chap || go->neg_upap) - && len >= CILEN_SHORT - && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) { - cilen = p[1]; - len -= cilen; - no.neg_chap = go->neg_chap; - no.neg_upap = go->neg_upap; - INCPTR(2, p); - GETSHORT(cishort, p); - if (cishort == PPP_PAP && cilen == CILEN_SHORT) { - /* - * If we were asking for CHAP, they obviously don't want to do it. - * If we weren't asking for CHAP, then we were asking for PAP, - * in which case this Nak is bad. - */ - if (!go->neg_chap) - goto bad; - try.neg_chap = 0; - - } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { - GETCHAR(cichar, p); - if (go->neg_chap) { - /* - * We were asking for CHAP/MD5; they must want a different - * algorithm. If they can't do MD5, we can ask for M$-CHAP - * if we support it, otherwise we'll have to stop - * asking for CHAP. - */ - if (cichar != go->chap_mdtype) { -#ifdef CHAPMS - if (cichar == CHAP_MICROSOFT) - go->chap_mdtype = CHAP_MICROSOFT; - else -#endif /* CHAPMS */ - try.neg_chap = 0; - } - } else { - /* - * Stop asking for PAP if we were asking for it. - */ - try.neg_upap = 0; - } - - } else { - /* - * We don't recognize what they're suggesting. - * Stop asking for what we were asking for. - */ - if (go->neg_chap) - try.neg_chap = 0; - else - try.neg_upap = 0; - p += cilen - CILEN_SHORT; - } - } - - /* - * If they can't cope with our link quality protocol, we'll have - * to stop asking for LQR. We haven't got any other protocol. - * If they Nak the reporting period, take their value XXX ? - */ - NAKCILQR(CI_QUALITY, neg_lqr, - if (cishort != PPP_LQR) - try.neg_lqr = 0; - else - try.lqr_period = cilong; - ); - - /* - * Only implementing CBCP...not the rest of the callback options - */ - NAKCICHAR(CI_CALLBACK, neg_cbcp, - try.neg_cbcp = 0; - ); - - /* - * Check for a looped-back line. - */ - NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, - try.magicnumber = magic(); - looped_back = 1; - ); - - /* - * Peer shouldn't send Nak for protocol compression or - * address/control compression requests; they should send - * a Reject instead. If they send a Nak, treat it as a Reject. - */ - NAKCIVOID(CI_PCOMPRESSION, neg_pcompression); - NAKCIVOID(CI_ACCOMPRESSION, neg_accompression); - - /* - * Nak for MRRU option - accept their value if it is smaller - * than the one we want. - */ - if (go->neg_mrru) { - NAKCISHORT(CI_MRRU, neg_mrru, - if (cishort <= wo->mrru) - try.mrru = cishort; - ); - } - - /* - * Nak for short sequence numbers shouldn't be sent, treat it - * like a reject. - */ - NAKCIVOID(CI_SSNHF, neg_ssnhf); - - /* - * Nak of the endpoint discriminator option is not permitted, - * treat it like a reject. - */ - NAKCIENDP(CI_EPDISC, neg_endpoint); - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If we see an option that we requested, or one we've already seen - * in this packet, then this packet is bad. - * If we wanted to respond by starting to negotiate on the requested - * option(s), we could, but we don't, because except for the - * authentication type and quality protocol, if we are not negotiating - * an option, it is because we were told not to. - * For the authentication type, the Nak from the peer means - * `let me authenticate myself with you' which is a bit pointless. - * For the quality protocol, the Nak means `ask me to send you quality - * reports', but if we didn't ask for them, we don't want them. - * An option we don't recognize represents the peer asking to - * negotiate some option we don't support, so ignore it. - */ - while (len > CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if (cilen < CILEN_VOID || (len -= cilen) < 0) - goto bad; - next = p + cilen - 2; - - switch (citype) { - case CI_MRU: - if ((go->neg_mru && go->mru != DEFMRU) - || no.neg_mru || cilen != CILEN_SHORT) - goto bad; - GETSHORT(cishort, p); - if (cishort < DEFMRU) { - try.neg_mru = 1; - try.mru = cishort; - } - break; - case CI_ASYNCMAP: - if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) - || no.neg_asyncmap || cilen != CILEN_LONG) - goto bad; - break; - case CI_AUTHTYPE: - if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap) - goto bad; - break; - case CI_MAGICNUMBER: - if (go->neg_magicnumber || no.neg_magicnumber || - cilen != CILEN_LONG) - goto bad; - break; - case CI_PCOMPRESSION: - if (go->neg_pcompression || no.neg_pcompression - || cilen != CILEN_VOID) - goto bad; - break; - case CI_ACCOMPRESSION: - if (go->neg_accompression || no.neg_accompression - || cilen != CILEN_VOID) - goto bad; - break; - case CI_QUALITY: - if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) - goto bad; - break; - case CI_MRRU: - if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT) - goto bad; - break; - case CI_SSNHF: - if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID) - goto bad; - try.neg_ssnhf = 1; - break; - case CI_EPDISC: - if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR) - goto bad; - break; - } - p = next; - } - - /* - * OK, the Nak is good. Now we can update state. - * If there are any options left we ignore them. - */ - if (f->state != OPENED) { - if (looped_back) { - if (++try.numloops >= lcp_loopbackfail) { - notice("Serial line is looped back."); - lcp_close(f->unit, "Loopback detected"); - status = EXIT_LOOPBACK; - } - } else - try.numloops = 0; - *go = try; - } - - return 1; - -bad: - LCPDEBUG(("lcp_nakci: received bad Nak!")); - return 0; -} - - -/* - * lcp_rejci - Peer has Rejected some of our CIs. - * This should not modify any state if the Reject is bad - * or if LCP is in the OPENED state. - * - * Returns: - * 0 - Reject was bad. - * 1 - Reject was good. - */ -static int -lcp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - u_char cichar; - u_short cishort; - u_int32_t cilong; - lcp_options try; /* options to request next time */ - - try = *go; - - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIVOID(opt, neg) \ - if (go->neg && \ - len >= CILEN_VOID && \ - p[1] == CILEN_VOID && \ - p[0] == opt) { \ - len -= CILEN_VOID; \ - INCPTR(CILEN_VOID, p); \ - try.neg = 0; \ - } -#define REJCISHORT(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_SHORT && \ - p[1] == CILEN_SHORT && \ - p[0] == opt) { \ - len -= CILEN_SHORT; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) \ - goto bad; \ - try.neg = 0; \ - } -#define REJCICHAP(opt, neg, val, digest) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if (cishort != val || cichar != digest) \ - goto bad; \ - try.neg = 0; \ - try.neg_upap = 0; \ - } -#define REJCILONG(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_LONG && \ - p[1] == CILEN_LONG && \ - p[0] == opt) { \ - len -= CILEN_LONG; \ - INCPTR(2, p); \ - GETLONG(cilong, p); \ - /* Check rejected value. */ \ - if (cilong != val) \ - goto bad; \ - try.neg = 0; \ - } -#define REJCILQR(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_LQR && \ - p[1] == CILEN_LQR && \ - p[0] == opt) { \ - len -= CILEN_LQR; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETLONG(cilong, p); \ - /* Check rejected value. */ \ - if (cishort != PPP_LQR || cilong != val) \ - goto bad; \ - try.neg = 0; \ - } -#define REJCICBCP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CBCP && \ - p[1] == CILEN_CBCP && \ - p[0] == opt) { \ - len -= CILEN_CBCP; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if (cichar != val) \ - goto bad; \ - try.neg = 0; \ - } -#define REJCIENDP(opt, neg, class, val, vlen) \ - if (go->neg && \ - len >= CILEN_CHAR + vlen && \ - p[0] == opt && \ - p[1] == CILEN_CHAR + vlen) { \ - int i; \ - len -= CILEN_CHAR + vlen; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - if (cichar != class) \ - goto bad; \ - for (i = 0; i < vlen; ++i) { \ - GETCHAR(cichar, p); \ - if (cichar != val[i]) \ - goto bad; \ - } \ - try.neg = 0; \ - } - - REJCISHORT(CI_MRU, neg_mru, go->mru); - REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); - REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype); - if (!go->neg_chap) { - REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); - } - REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); - REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); - REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); - REJCIVOID(CI_PCOMPRESSION, neg_pcompression); - REJCIVOID(CI_ACCOMPRESSION, neg_accompression); - REJCISHORT(CI_MRRU, neg_mrru, go->mrru); - REJCIVOID(CI_SSNHF, neg_ssnhf); - REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class, - go->endpoint.value, go->endpoint.length); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - /* - * Now we can update state. - */ - if (f->state != OPENED) - *go = try; - return 1; - -bad: - LCPDEBUG(("lcp_rejci: received bad Reject!")); - return 0; -} - - -/* - * lcp_reqci - Check the peer's requested CIs and send appropriate response. - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - */ -static int -lcp_reqci(f, inp, lenp, reject_if_disagree) - fsm *f; - u_char *inp; /* Requested CIs */ - int *lenp; /* Length of requested CIs */ - int reject_if_disagree; -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *ho = &lcp_hisoptions[f->unit]; - lcp_options *ao = &lcp_allowoptions[f->unit]; - u_char *cip, *next; /* Pointer to current and next CIs */ - int cilen, citype, cichar; /* Parsed len, type, char value */ - u_short cishort; /* Parsed short value */ - u_int32_t cilong; /* Parse long value */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *rejp; /* Pointer to next char in reject frame */ - u_char *nakp; /* Pointer to next char in Nak frame */ - int l = *lenp; /* Length left */ - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - nakp = nak_buffer; - rejp = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - LCPDEBUG(("lcp_reqci: bad CI length!")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - citype = 0; - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ - case CI_MRU: - if (!ao->neg_mru || /* Allow option? */ - cilen != CILEN_SHORT) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETSHORT(cishort, p); /* Parse MRU */ - - /* - * He must be able to receive at least our minimum. - * No need to check a maximum. If he sends a large number, - * we'll just ignore it. - */ - if (cishort < MINMRU) { - orc = CONFNAK; /* Nak CI */ - PUTCHAR(CI_MRU, nakp); - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(MINMRU, nakp); /* Give him a hint */ - break; - } - ho->neg_mru = 1; /* Remember he sent MRU */ - ho->mru = cishort; /* And remember value */ - break; - - case CI_ASYNCMAP: - if (!ao->neg_asyncmap || - cilen != CILEN_LONG) { - orc = CONFREJ; - break; - } - GETLONG(cilong, p); - - /* - * Asyncmap must have set at least the bits - * which are set in lcp_allowoptions[unit].asyncmap. - */ - if ((ao->asyncmap & ~cilong) != 0) { - orc = CONFNAK; - PUTCHAR(CI_ASYNCMAP, nakp); - PUTCHAR(CILEN_LONG, nakp); - PUTLONG(ao->asyncmap | cilong, nakp); - break; - } - ho->neg_asyncmap = 1; - ho->asyncmap = cilong; - break; - - case CI_AUTHTYPE: - if (cilen < CILEN_SHORT || - !(ao->neg_upap || ao->neg_chap)) { - /* - * Reject the option if we're not willing to authenticate. - */ - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - - /* - * Authtype must be PAP or CHAP. - * - * Note: if both ao->neg_upap and ao->neg_chap are set, - * and the peer sends a Configure-Request with two - * authenticate-protocol requests, one for CHAP and one - * for UPAP, then we will reject the second request. - * Whether we end up doing CHAP or UPAP depends then on - * the ordering of the CIs in the peer's Configure-Request. - */ - - if (cishort == PPP_PAP) { - if (ho->neg_chap || /* we've already accepted CHAP */ - cilen != CILEN_SHORT) { - LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting...")); - orc = CONFREJ; - break; - } - if (!ao->neg_upap) { /* we don't want to do PAP */ - orc = CONFNAK; /* NAK it and suggest CHAP */ - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - /* XXX if we can do CHAP_MICROSOFT as well, we should - probably put in another option saying so */ - break; - } - ho->neg_upap = 1; - break; - } - if (cishort == PPP_CHAP) { - if (ho->neg_upap || /* we've already accepted PAP */ - cilen != CILEN_CHAP) { - LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting...")); - orc = CONFREJ; - break; - } - if (!ao->neg_chap) { /* we don't want to do CHAP */ - orc = CONFNAK; /* NAK it and suggest PAP */ - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_PAP, nakp); - break; - } - GETCHAR(cichar, p); /* get digest type*/ - if (cichar != CHAP_DIGEST_MD5 -#ifdef CHAPMS - && cichar != CHAP_MICROSOFT -#endif - ) { - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakp); - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - break; - } - ho->chap_mdtype = cichar; /* save md type */ - ho->neg_chap = 1; - break; - } - - /* - * We don't recognize the protocol they're asking for. - * Nak it with something we're willing to do. - * (At this point we know ao->neg_upap || ao->neg_chap.) - */ - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakp); - if (ao->neg_chap) { - PUTCHAR(CILEN_CHAP, nakp); - PUTSHORT(PPP_CHAP, nakp); - PUTCHAR(ao->chap_mdtype, nakp); - } else { - PUTCHAR(CILEN_SHORT, nakp); - PUTSHORT(PPP_PAP, nakp); - } - break; - - case CI_QUALITY: - if (!ao->neg_lqr || - cilen != CILEN_LQR) { - orc = CONFREJ; - break; - } - - GETSHORT(cishort, p); - GETLONG(cilong, p); - - /* - * Check the protocol and the reporting period. - * XXX When should we Nak this, and what with? - */ - if (cishort != PPP_LQR) { - orc = CONFNAK; - PUTCHAR(CI_QUALITY, nakp); - PUTCHAR(CILEN_LQR, nakp); - PUTSHORT(PPP_LQR, nakp); - PUTLONG(ao->lqr_period, nakp); - break; - } - break; - - case CI_MAGICNUMBER: - if (!(ao->neg_magicnumber || go->neg_magicnumber) || - cilen != CILEN_LONG) { - orc = CONFREJ; - break; - } - GETLONG(cilong, p); - - /* - * He must have a different magic number. - */ - if (go->neg_magicnumber && - cilong == go->magicnumber) { - cilong = magic(); /* Don't put magic() inside macro! */ - orc = CONFNAK; - PUTCHAR(CI_MAGICNUMBER, nakp); - PUTCHAR(CILEN_LONG, nakp); - PUTLONG(cilong, nakp); - break; - } - ho->neg_magicnumber = 1; - ho->magicnumber = cilong; - break; - - - case CI_PCOMPRESSION: - if (!ao->neg_pcompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_pcompression = 1; - break; - - case CI_ACCOMPRESSION: - if (!ao->neg_accompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_accompression = 1; - break; - - case CI_MRRU: - if (!ao->neg_mrru || !multilink || - cilen != CILEN_SHORT) { - orc = CONFREJ; - break; - } - - GETSHORT(cishort, p); - /* possibly should insist on a minimum/maximum MRRU here */ - ho->neg_mrru = 1; - ho->mrru = cishort; - break; - - case CI_SSNHF: - if (!ao->neg_ssnhf || !multilink || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_ssnhf = 1; - break; - - case CI_EPDISC: - if (!ao->neg_endpoint || - cilen < CILEN_CHAR || - cilen > CILEN_CHAR + MAX_ENDP_LEN) { - orc = CONFREJ; - break; - } - GETCHAR(cichar, p); - cilen -= CILEN_CHAR; - ho->neg_endpoint = 1; - ho->endpoint.class = cichar; - ho->endpoint.length = cilen; - BCOPY(p, ho->endpoint.value, cilen); - INCPTR(cilen, p); - break; - - default: - LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype)); - orc = CONFREJ; - break; - } - -endswitch: - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) /* but prior CI wasnt? */ - continue; /* Don't send this one */ - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree /* Getting fed up with sending NAKs? */ - && citype != CI_MAGICNUMBER) { - orc = CONFREJ; /* Get tough if so */ - } else { - if (rc == CONFREJ) /* Rejecting prior CI? */ - continue; /* Don't send this one */ - rc = CONFNAK; - } - } - if (orc == CONFREJ) { /* Reject this CI */ - rc = CONFREJ; - if (cip != rejp) /* Need to move rejected CI? */ - BCOPY(cip, rejp, cilen); /* Move it */ - INCPTR(cilen, rejp); /* Update output pointer */ - } - } - - /* - * If we wanted to send additional NAKs (for unsent CIs), the - * code would go here. The extra NAKs would go at *nakp. - * At present there are no cases where we want to ask the - * peer to negotiate an option. - */ - - switch (rc) { - case CONFACK: - *lenp = next - inp; - break; - case CONFNAK: - /* - * Copy the Nak'd options from the nak_buffer to the caller's buffer. - */ - *lenp = nakp - nak_buffer; - BCOPY(nak_buffer, inp, *lenp); - break; - case CONFREJ: - *lenp = rejp - inp; - break; - } - - LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc))); - return (rc); /* Return final code */ -} - - -/* - * lcp_up - LCP has come UP. - */ -static void -lcp_up(f) - fsm *f; -{ - lcp_options *wo = &lcp_wantoptions[f->unit]; - lcp_options *ho = &lcp_hisoptions[f->unit]; - lcp_options *go = &lcp_gotoptions[f->unit]; - lcp_options *ao = &lcp_allowoptions[f->unit]; - int mtu; - - if (!go->neg_magicnumber) - go->magicnumber = 0; - if (!ho->neg_magicnumber) - ho->magicnumber = 0; - - /* - * Set our MTU to the smaller of the MTU we wanted and - * the MRU our peer wanted. If we negotiated an MRU, - * set our MRU to the larger of value we wanted and - * the value we got in the negotiation. - * Note on the MTU: the link MTU can be the MRU the peer wanted, - * the interface MTU is set to the lower of that and the - * MTU we want to use. - */ - mtu = ho->neg_mru? ho->mru: PPP_MRU; -#ifdef HAVE_MULTILINK - if (!(multilink && go->neg_mrru && ho->neg_mrru)) -#endif /* HAVE_MULTILINK */ - netif_set_mtu(f->unit, MIN(mtu, ao->mru)); - ppp_send_config(f->unit, mtu, - (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), - ho->neg_pcompression, ho->neg_accompression); - ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU), - (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), - go->neg_pcompression, go->neg_accompression); - - if (ho->neg_mru) - peer_mru[f->unit] = ho->mru; - - lcp_echo_lowerup(f->unit); /* Enable echo messages */ - - link_established(f->unit); -} - - -/* - * lcp_down - LCP has gone DOWN. - * - * Alert other protocols. - */ -static void -lcp_down(f) - fsm *f; -{ - lcp_options *go = &lcp_gotoptions[f->unit]; - - lcp_echo_lowerdown(f->unit); - - link_down(f->unit); - - ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0); - ppp_recv_config(f->unit, PPP_MRU, - (go->neg_asyncmap? go->asyncmap: 0xffffffff), - go->neg_pcompression, go->neg_accompression); - peer_mru[f->unit] = PPP_MRU; -} - - -/* - * lcp_starting - LCP needs the lower layer up. - */ -static void -lcp_starting(f) - fsm *f; -{ - link_required(f->unit); -} - - -/* - * lcp_finished - LCP has finished with the lower layer. - */ -static void -lcp_finished(f) - fsm *f; -{ - link_terminated(f->unit); -} - - -/* - * lcp_printpkt - print the contents of an LCP packet. - */ -static char *lcp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej", "ProtRej", - "EchoReq", "EchoRep", "DiscReq" -}; - -static int -lcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int code, id, len, olen, i; - u_char *pstart, *optend; - u_short cishort; - u_int32_t cilong; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *)) - printer(arg, " %s", lcp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < 2 || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { - case CI_MRU: - if (olen == CILEN_SHORT) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "mru %d", cishort); - } - break; - case CI_ASYNCMAP: - if (olen == CILEN_LONG) { - p += 2; - GETLONG(cilong, p); - printer(arg, "asyncmap 0x%x", cilong); - } - break; - case CI_AUTHTYPE: - if (olen >= CILEN_SHORT) { - p += 2; - printer(arg, "auth "); - GETSHORT(cishort, p); - switch (cishort) { - case PPP_PAP: - printer(arg, "pap"); - break; - case PPP_CHAP: - printer(arg, "chap"); - if (p < optend) { - switch (*p) { - case CHAP_DIGEST_MD5: - printer(arg, " MD5"); - ++p; - break; -#ifdef CHAPMS - case CHAP_MICROSOFT: - printer(arg, " m$oft"); - ++p; - break; -#endif - } - } - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_QUALITY: - if (olen >= CILEN_SHORT) { - p += 2; - printer(arg, "quality "); - GETSHORT(cishort, p); - switch (cishort) { - case PPP_LQR: - printer(arg, "lqr"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_CALLBACK: - if (olen >= CILEN_CHAR) { - p += 2; - printer(arg, "callback "); - GETCHAR(cishort, p); - switch (cishort) { - case CBCP_OPT: - printer(arg, "CBCP"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_MAGICNUMBER: - if (olen == CILEN_LONG) { - p += 2; - GETLONG(cilong, p); - printer(arg, "magic 0x%x", cilong); - } - break; - case CI_PCOMPRESSION: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "pcomp"); - } - break; - case CI_ACCOMPRESSION: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "accomp"); - } - break; - case CI_MRRU: - if (olen == CILEN_SHORT) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "mrru %d", cishort); - } - break; - case CI_SSNHF: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "ssnhf"); - } - break; - case CI_EPDISC: -#ifdef HAVE_MULTILINK - if (olen >= CILEN_CHAR) { - struct epdisc epd; - p += 2; - GETCHAR(epd.class, p); - epd.length = olen - CILEN_CHAR; - if (epd.length > MAX_ENDP_LEN) - epd.length = MAX_ENDP_LEN; - if (epd.length > 0) { - BCOPY(p, epd.value, epd.length); - p += epd.length; - } - printer(arg, "endpoint [%s]", epdisc_to_str(&epd)); - } -#else - printer(arg, "endpoint"); -#endif - break; - } - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - print_string((char *)p, len, printer, arg); - p += len; - len = 0; - } - break; - - case ECHOREQ: - case ECHOREP: - case DISCREQ: - if (len >= 4) { - GETLONG(cilong, p); - printer(arg, " magic=0x%x", cilong); - p += 4; - len -= 4; - } - break; - } - - /* print the rest of the bytes in the packet */ - for (i = 0; i < len && i < 32; ++i) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - if (i < len) { - printer(arg, " ..."); - p += len - i; - } - - return p - pstart; -} - -/* - * Time to shut down the link because there is nothing out there. - */ - -static -void LcpLinkFailure (f) - fsm *f; -{ - if (f->state == OPENED) { - info("No response to %d echo-requests", lcp_echos_pending); - notice("Serial link appears to be disconnected."); - lcp_close(f->unit, "Peer not responding"); - status = EXIT_PEER_DEAD; - } -} - -/* - * Timer expired for the LCP echo requests from this process. - */ - -static void -LcpEchoCheck (f) - fsm *f; -{ - LcpSendEchoRequest (f); - if (f->state != OPENED) - return; - - /* - * Start the timer for the next interval. - */ - if (lcp_echo_timer_running) - warn("assertion lcp_echo_timer_running==0 failed"); - TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); - lcp_echo_timer_running = 1; -} - -/* - * LcpEchoTimeout - Timer expired on the LCP echo - */ - -static void -LcpEchoTimeout (arg) - void *arg; -{ - if (lcp_echo_timer_running != 0) { - lcp_echo_timer_running = 0; - LcpEchoCheck ((fsm *) arg); - } -} - -/* - * LcpEchoReply - LCP has received a reply to the echo - */ - -static void -lcp_received_echo_reply (f, id, inp, len) - fsm *f; - int id; - u_char *inp; - int len; -{ - u_int32_t magic; - - /* Check the magic number - don't count replies from ourselves. */ - if (len < 4) { - dbglog("lcp: received short Echo-Reply, length %d", len); - return; - } - GETLONG(magic, inp); - if (lcp_gotoptions[f->unit].neg_magicnumber - && magic == lcp_gotoptions[f->unit].magicnumber) { - warn("appear to have received our own echo-reply!"); - return; - } - - /* Reset the number of outstanding echo frames */ - lcp_echos_pending = 0; -} - -/* - * LcpSendEchoRequest - Send an echo request frame to the peer - */ - -static void -LcpSendEchoRequest (f) - fsm *f; -{ - u_int32_t lcp_magic; - u_char pkt[4], *pktp; - - /* - * Detect the failure of the peer at this point. - */ - if (lcp_echo_fails != 0) { - if (lcp_echos_pending >= lcp_echo_fails) { - LcpLinkFailure(f); - lcp_echos_pending = 0; - } - } - - /* - * Make and send the echo request frame. - */ - if (f->state == OPENED) { - lcp_magic = lcp_gotoptions[f->unit].magicnumber; - pktp = pkt; - PUTLONG(lcp_magic, pktp); - fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt); - ++lcp_echos_pending; - } -} - -/* - * lcp_echo_lowerup - Start the timer for the LCP frame - */ - -static void -lcp_echo_lowerup (unit) - int unit; -{ - fsm *f = &lcp_fsm[unit]; - - /* Clear the parameters for generating echo frames */ - lcp_echos_pending = 0; - lcp_echo_number = 0; - lcp_echo_timer_running = 0; - - /* If a timeout interval is specified then start the timer */ - if (lcp_echo_interval != 0) - LcpEchoCheck (f); -} - -/* - * lcp_echo_lowerdown - Stop the timer for the LCP frame - */ - -static void -lcp_echo_lowerdown (unit) - int unit; -{ - fsm *f = &lcp_fsm[unit]; - - if (lcp_echo_timer_running != 0) { - UNTIMEOUT (LcpEchoTimeout, f); - lcp_echo_timer_running = 0; - } -} diff --git a/mdk-stage1/ppp/pppd/lcp.h b/mdk-stage1/ppp/pppd/lcp.h deleted file mode 100644 index b87a9295e..000000000 --- a/mdk-stage1/ppp/pppd/lcp.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * lcp.h - Link Control Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - * - * $Id$ - */ - -/* - * Options. - */ -#define CI_MRU 1 /* Maximum Receive Unit */ -#define CI_ASYNCMAP 2 /* Async Control Character Map */ -#define CI_AUTHTYPE 3 /* Authentication Type */ -#define CI_QUALITY 4 /* Quality Protocol */ -#define CI_MAGICNUMBER 5 /* Magic Number */ -#define CI_PCOMPRESSION 7 /* Protocol Field Compression */ -#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */ -#define CI_CALLBACK 13 /* callback */ -#define CI_MRRU 17 /* max reconstructed receive unit; multilink */ -#define CI_SSNHF 18 /* short sequence numbers for multilink */ -#define CI_EPDISC 19 /* endpoint discriminator */ - -/* - * LCP-specific packet types. - */ -#define PROTREJ 8 /* Protocol Reject */ -#define ECHOREQ 9 /* Echo Request */ -#define ECHOREP 10 /* Echo Reply */ -#define DISCREQ 11 /* Discard Request */ -#define CBCP_OPT 6 /* Use callback control protocol */ - -/* - * The state of options is described by an lcp_options structure. - */ -typedef struct lcp_options { - bool passive; /* Don't die if we don't get a response */ - bool silent; /* Wait for the other end to start first */ - bool restart; /* Restart vs. exit after close */ - bool neg_mru; /* Negotiate the MRU? */ - bool neg_asyncmap; /* Negotiate the async map? */ - bool neg_upap; /* Ask for UPAP authentication? */ - bool neg_chap; /* Ask for CHAP authentication? */ - bool neg_magicnumber; /* Ask for magic number? */ - bool neg_pcompression; /* HDLC Protocol Field Compression? */ - bool neg_accompression; /* HDLC Address/Control Field Compression? */ - bool neg_lqr; /* Negotiate use of Link Quality Reports */ - bool neg_cbcp; /* Negotiate use of CBCP */ - bool neg_mrru; /* negotiate multilink MRRU */ - bool neg_ssnhf; /* negotiate short sequence numbers */ - bool neg_endpoint; /* negotiate endpoint discriminator */ - int mru; /* Value of MRU */ - int mrru; /* Value of MRRU, and multilink enable */ - u_char chap_mdtype; /* which MD type (hashing algorithm) */ - u_int32_t asyncmap; /* Value of async map */ - u_int32_t magicnumber; - int numloops; /* Number of loops during magic number neg. */ - u_int32_t lqr_period; /* Reporting period for LQR 1/100ths second */ - struct epdisc endpoint; /* endpoint discriminator */ -} lcp_options; - -extern fsm lcp_fsm[]; -extern lcp_options lcp_wantoptions[]; -extern lcp_options lcp_gotoptions[]; -extern lcp_options lcp_allowoptions[]; -extern lcp_options lcp_hisoptions[]; - -#define DEFMRU 1500 /* Try for this */ -#define MINMRU 128 /* No MRUs below this */ -#define MAXMRU 16384 /* Normally limit MRU to this */ - -void lcp_open __P((int)); -void lcp_close __P((int, char *)); -void lcp_lowerup __P((int)); -void lcp_lowerdown __P((int)); -void lcp_sprotrej __P((int, u_char *, int)); /* send protocol reject */ - -extern struct protent lcp_protent; - -/* Default number of times we receive our magic number from the peer - before deciding the link is looped-back. */ -#define DEFLOOPBACKFAIL 10 diff --git a/mdk-stage1/ppp/pppd/magic.c b/mdk-stage1/ppp/pppd/magic.c deleted file mode 100644 index 1682dee03..000000000 --- a/mdk-stage1/ppp/pppd/magic.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * magic.c - PPP Magic Number routines. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -#define RCSID "$Id$" - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/time.h> - -#include "pppd.h" -#include "magic.h" - -static const char rcsid[] = RCSID; - -extern long mrand48 __P((void)); -extern void srand48 __P((long)); - -/* - * magic_init - Initialize the magic number generator. - * - * Attempts to compute a random number seed which will not repeat. - * The current method uses the current hostid, current process ID - * and current time, currently. - */ -void -magic_init() -{ - long seed; - struct timeval t; - - gettimeofday(&t, NULL); - seed = get_host_seed() ^ t.tv_sec ^ t.tv_usec ^ getpid(); - srand48(seed); -} - -/* - * magic - Returns the next magic number. - */ -u_int32_t -magic() -{ - return (u_int32_t) mrand48(); -} - -#ifdef NO_DRAND48 -/* - * Substitute procedures for those systems which don't have - * drand48 et al. - */ - -double -drand48() -{ - return (double)random() / (double)0x7fffffffL; /* 2**31-1 */ -} - -long -mrand48() -{ - return random(); -} - -void -srand48(seedval) -long seedval; -{ - srandom((int)seedval); -} - -#endif diff --git a/mdk-stage1/ppp/pppd/magic.h b/mdk-stage1/ppp/pppd/magic.h deleted file mode 100644 index 1344626a3..000000000 --- a/mdk-stage1/ppp/pppd/magic.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * magic.h - PPP Magic Number definitions. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - * - * $Id$ - */ - -void magic_init __P((void)); /* Initialize the magic number generator */ -u_int32_t magic __P((void)); /* Returns the next magic number */ diff --git a/mdk-stage1/ppp/pppd/main.c b/mdk-stage1/ppp/pppd/main.c deleted file mode 100644 index c074938cd..000000000 --- a/mdk-stage1/ppp/pppd/main.c +++ /dev/null @@ -1,1846 +0,0 @@ -/* - * main.c - Point-to-Point Protocol main module - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -#define RCSID "$Id$" - -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> -#include <errno.h> -#include <fcntl.h> -#include <syslog.h> -#include <netdb.h> -#include <utmp.h> -#include <pwd.h> -#include <setjmp.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include "pppd.h" -#include "magic.h" -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" -#ifdef INET6 -#include "ipv6cp.h" -#endif -#include "upap.h" -#include "chap.h" -#include "ccp.h" -#include "pathnames.h" -#include "tdb.h" - -#ifdef CBCP_SUPPORT -#include "cbcp.h" -#endif - -#ifdef IPX_CHANGE -#include "ipxcp.h" -#endif /* IPX_CHANGE */ -#ifdef AT_CHANGE -#include "atcp.h" -#endif - -static const char rcsid[] = RCSID; - -/* interface vars */ -char ifname[32]; /* Interface name */ -int ifunit; /* Interface unit number */ - -struct channel *the_channel; - -char *progname; /* Name of this program */ -char hostname[MAXNAMELEN]; /* Our hostname */ -static char pidfilename[MAXPATHLEN]; /* name of pid file */ -static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */ -char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */ -uid_t uid; /* Our real user-id */ -struct notifier *pidchange = NULL; -struct notifier *phasechange = NULL; -struct notifier *exitnotify = NULL; -struct notifier *sigreceived = NULL; - -int hungup; /* terminal has been hung up */ -int privileged; /* we're running as real uid root */ -int need_holdoff; /* need holdoff period before restarting */ -int detached; /* have detached from terminal */ -volatile int status; /* exit status for pppd */ -int unsuccess; /* # unsuccessful connection attempts */ -int do_callback; /* != 0 if we should do callback next */ -int doing_callback; /* != 0 if we are doing callback */ -TDB_CONTEXT *pppdb; /* database for storing status etc. */ -char db_key[32]; - -int (*holdoff_hook) __P((void)) = NULL; -int (*new_phase_hook) __P((int)) = NULL; - -static int conn_running; /* we have a [dis]connector running */ -static int devfd; /* fd of underlying device */ -static int fd_ppp = -1; /* fd for talking PPP */ -static int fd_loop; /* fd for getting demand-dial packets */ - -int phase; /* where the link is at */ -int kill_link; -int open_ccp_flag; -int listen_time; -int got_sigusr2; -int got_sigterm; -int got_sighup; - -static int waiting; -static sigjmp_buf sigjmp; - -char **script_env; /* Env. variable values for scripts */ -int s_env_nalloc; /* # words avail at script_env */ - -u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */ -u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */ - -static int n_children; /* # child processes still running */ -static int got_sigchld; /* set if we have received a SIGCHLD */ - -int privopen; /* don't lock, open device as root */ - -char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; - -GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */ -int ngroups; /* How many groups valid in groups */ - -static struct timeval start_time; /* Time when link was started. */ - -struct pppd_stats link_stats; -int link_connect_time; -int link_stats_valid; - -/* - * We maintain a list of child process pids and - * functions to call when they exit. - */ -struct subprocess { - pid_t pid; - char *prog; - void (*done) __P((void *)); - void *arg; - struct subprocess *next; -}; - -static struct subprocess *children; - -/* Prototypes for procedures local to this file. */ - -static void setup_signals __P((void)); -static void create_pidfile __P((void)); -static void create_linkpidfile __P((void)); -static void cleanup __P((void)); -static void get_input __P((void)); -static void calltimeout __P((void)); -static struct timeval *timeleft __P((struct timeval *)); -static void kill_my_pg __P((int)); -static void hup __P((int)); -static void term __P((int)); -static void chld __P((int)); -static void toggle_debug __P((int)); -static void open_ccp __P((int)); -static void bad_signal __P((int)); -static void holdoff_end __P((void *)); -static int reap_kids __P((int waitfor)); -static void update_db_entry __P((void)); -static void add_db_key __P((const char *)); -static void delete_db_key __P((const char *)); -static void cleanup_db __P((void)); -static void handle_events __P((void)); - -extern char *ttyname __P((int)); -extern char *getlogin __P((void)); -int main __P((int, char *[])); - -#ifdef ultrix -#undef O_NONBLOCK -#define O_NONBLOCK O_NDELAY -#endif - -#ifdef ULTRIX -#define setlogmask(x) -#endif - -/* - * PPP Data Link Layer "protocol" table. - * One entry per supported protocol. - * The last entry must be NULL. - */ -struct protent *protocols[] = { - &lcp_protent, - &pap_protent, - &chap_protent, -#ifdef CBCP_SUPPORT - &cbcp_protent, -#endif - &ipcp_protent, -#ifdef INET6 - &ipv6cp_protent, -#endif - &ccp_protent, -#ifdef IPX_CHANGE - &ipxcp_protent, -#endif -#ifdef AT_CHANGE - &atcp_protent, -#endif - NULL -}; - -/* - * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name. - */ -#if !defined(PPP_DRV_NAME) -#define PPP_DRV_NAME "ppp" -#endif /* !defined(PPP_DRV_NAME) */ - -int -main(argc, argv) - int argc; - char *argv[]; -{ - int i, t; - char *p; - struct passwd *pw; - struct protent *protp; - char numbuf[16]; - - new_phase(PHASE_INITIALIZE); - - /* - * Ensure that fds 0, 1, 2 are open, to /dev/null if nowhere else. - * This way we can close 0, 1, 2 in detach() without clobbering - * a fd that we are using. - */ - if ((i = open("/dev/null", O_RDWR)) >= 0) { - while (0 <= i && i <= 2) - i = dup(i); - if (i >= 0) - close(i); - } - - script_env = NULL; - - /* Initialize syslog facilities */ - reopen_log(); - - if (gethostname(hostname, MAXNAMELEN) < 0 ) { - option_error("Couldn't get hostname: %m"); - exit(1); - } - hostname[MAXNAMELEN-1] = 0; - - /* make sure we don't create world or group writable files. */ - umask(umask(0777) | 022); - - uid = getuid(); - privileged = uid == 0; - slprintf(numbuf, sizeof(numbuf), "%d", uid); - script_setenv("ORIG_UID", numbuf, 0); - - ngroups = getgroups(NGROUPS_MAX, groups); - - /* - * Initialize magic number generator now so that protocols may - * use magic numbers in initialization. - */ - magic_init(); - - /* - * Initialize each protocol. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - (*protp->init)(0); - - /* - * Initialize the default channel. - */ - tty_init(); - - progname = *argv; - - /* - * Parse, in order, the system options file, the user's options file, - * and the command line arguments. - */ - if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1) - || !options_from_user() - || !parse_args(argc-1, argv+1)) - exit(EXIT_OPTION_ERROR); - devnam_fixed = 1; /* can no longer change device name */ - - /* - * Work out the device name, if it hasn't already been specified, - * and parse the tty's options file. - */ - if (the_channel->process_extra_options) - (*the_channel->process_extra_options)(); - - if (debug) - setlogmask(LOG_UPTO(LOG_DEBUG)); - - /* - * Check that we are running as root. - */ - if (geteuid() != 0) { - option_error("must be root to run %s, since it is not setuid-root", - argv[0]); - exit(EXIT_NOT_ROOT); - } - - if (!ppp_available()) { - option_error("%s", no_ppp_msg); - exit(EXIT_NO_KERNEL_SUPPORT); - } - - /* - * Check that the options given are valid and consistent. - */ - check_options(); - if (!sys_check_options()) - exit(EXIT_OPTION_ERROR); - auth_check_options(); -#ifdef HAVE_MULTILINK - mp_check_options(); -#endif - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->check_options != NULL) - (*protp->check_options)(); - if (the_channel->check_options) - (*the_channel->check_options)(); - - - if (dump_options || dryrun) { - init_pr_log(NULL, LOG_INFO); - print_options(pr_log, NULL); - end_pr_log(); - if (dryrun) - die(0); - } - - /* - * Initialize system-dependent stuff. - */ - sys_init(); - - pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644); - if (pppdb != NULL) { - slprintf(db_key, sizeof(db_key), "pppd%d", getpid()); - update_db_entry(); - } else { - warn("Warning: couldn't open ppp database %s", _PATH_PPPDB); - if (multilink) { - warn("Warning: disabling multilink"); - multilink = 0; - } - } - - /* - * Detach ourselves from the terminal, if required, - * and identify who is running us. - */ - if (!nodetach && !updetach) - detach(); - p = getlogin(); - if (p == NULL) { - pw = getpwuid(uid); - if (pw != NULL && pw->pw_name != NULL) - p = pw->pw_name; - else - p = "(unknown)"; - } - syslog(LOG_NOTICE, "pppd %s started by %s, uid %d", VERSION, p, uid); - script_setenv("PPPLOGNAME", p, 0); - - if (devnam[0]) - script_setenv("DEVICE", devnam, 1); - slprintf(numbuf, sizeof(numbuf), "%d", getpid()); - script_setenv("PPPD_PID", numbuf, 1); - - setup_signals(); - - waiting = 0; - - create_linkpidfile(); - - /* - * If we're doing dial-on-demand, set up the interface now. - */ - if (demand) { - /* - * Open the loopback channel and set it up to be the ppp interface. - */ - tdb_writelock(pppdb); - fd_loop = open_ppp_loopback(); - set_ifunit(1); - tdb_writeunlock(pppdb); - - /* - * Configure the interface and mark it up, etc. - */ - demand_conf(); - } - - do_callback = 0; - for (;;) { - - listen_time = 0; - need_holdoff = 1; - devfd = -1; - status = EXIT_OK; - ++unsuccess; - doing_callback = do_callback; - do_callback = 0; - - if (demand && !doing_callback) { - /* - * Don't do anything until we see some activity. - */ - new_phase(PHASE_DORMANT); - demand_unblock(); - add_fd(fd_loop); - for (;;) { - handle_events(); - if (kill_link && !persist) - break; - if (get_loop_output()) - break; - } - remove_fd(fd_loop); - if (kill_link && !persist) - break; - - /* - * Now we want to bring up the link. - */ - demand_block(); - info("Starting link"); - } - - new_phase(PHASE_SERIALCONN); - - devfd = the_channel->connect(); - if (devfd < 0) - goto fail; - - /* set up the serial device as a ppp interface */ - tdb_writelock(pppdb); - fd_ppp = the_channel->establish_ppp(devfd); - if (fd_ppp < 0) { - tdb_writeunlock(pppdb); - status = EXIT_FATAL_ERROR; - goto disconnect; - } - - if (!demand && ifunit >= 0) - set_ifunit(1); - tdb_writeunlock(pppdb); - - /* - * Start opening the connection and wait for - * incoming events (reply, timeout, etc.). - */ - notice("Connect: %s <--> %s", ifname, ppp_devnam); - gettimeofday(&start_time, NULL); - link_stats_valid = 0; - script_unsetenv("CONNECT_TIME"); - script_unsetenv("BYTES_SENT"); - script_unsetenv("BYTES_RCVD"); - lcp_lowerup(0); - - add_fd(fd_ppp); - lcp_open(0); /* Start protocol */ - status = EXIT_NEGOTIATION_FAILED; - new_phase(PHASE_ESTABLISH); - while (phase != PHASE_DEAD) { - handle_events(); - get_input(); - if (kill_link) - lcp_close(0, "User request"); - if (open_ccp_flag) { - if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) { - ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ - (*ccp_protent.open)(0); - } - } - } - - /* - * Print connect time and statistics. - */ - if (link_stats_valid) { - int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ - info("Connect time %d.%d minutes.", t/10, t%10); - info("Sent %u bytes, received %u bytes.", - link_stats.bytes_out, link_stats.bytes_in); - } - - /* - * Delete pid file before disestablishing ppp. Otherwise it - * can happen that another pppd gets the same unit and then - * we delete its pid file. - */ - if (!demand) { - if (pidfilename[0] != 0 - && unlink(pidfilename) < 0 && errno != ENOENT) - warn("unable to delete pid file %s: %m", pidfilename); - pidfilename[0] = 0; - } - - /* - * If we may want to bring the link up again, transfer - * the ppp unit back to the loopback. Set the - * real serial device back to its normal mode of operation. - */ - remove_fd(fd_ppp); - clean_check(); - the_channel->disestablish_ppp(devfd); - fd_ppp = -1; - if (!hungup) - lcp_lowerdown(0); - if (!demand) - script_unsetenv("IFNAME"); - - /* - * Run disconnector script, if requested. - * XXX we may not be able to do this if the line has hung up! - */ - disconnect: - new_phase(PHASE_DISCONNECT); - the_channel->disconnect(); - - fail: - if (the_channel->cleanup) - (*the_channel->cleanup)(); - - if (!demand) { - if (pidfilename[0] != 0 - && unlink(pidfilename) < 0 && errno != ENOENT) - warn("unable to delete pid file %s: %m", pidfilename); - pidfilename[0] = 0; - } - - if (!persist || (maxfail > 0 && unsuccess >= maxfail)) - break; - - if (demand) - demand_discard(); - t = need_holdoff? holdoff: 0; - if (holdoff_hook) - t = (*holdoff_hook)(); - if (t > 0) { - new_phase(PHASE_HOLDOFF); - TIMEOUT(holdoff_end, NULL, t); - do { - handle_events(); - if (kill_link) - new_phase(PHASE_DORMANT); /* allow signal to end holdoff */ - } while (phase == PHASE_HOLDOFF); - if (!persist) - break; - } - } - - /* Wait for scripts to finish */ - /* XXX should have a timeout here */ - while (n_children > 0) { - if (debug) { - struct subprocess *chp; - dbglog("Waiting for %d child processes...", n_children); - for (chp = children; chp != NULL; chp = chp->next) - dbglog(" script %s, pid %d", chp->prog, chp->pid); - } - if (reap_kids(1) < 0) - break; - } - - die(status); - return 0; -} - -/* - * handle_events - wait for something to happen and respond to it. - */ -static void -handle_events() -{ - struct timeval timo; - sigset_t mask; - - kill_link = open_ccp_flag = 0; - if (sigsetjmp(sigjmp, 1) == 0) { - sigprocmask(SIG_BLOCK, &mask, NULL); - if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) { - sigprocmask(SIG_UNBLOCK, &mask, NULL); - } else { - waiting = 1; - sigprocmask(SIG_UNBLOCK, &mask, NULL); - wait_input(timeleft(&timo)); - } - } - waiting = 0; - calltimeout(); - if (got_sighup) { - kill_link = 1; - got_sighup = 0; - if (status != EXIT_HANGUP) - status = EXIT_USER_REQUEST; - } - if (got_sigterm) { - kill_link = 1; - persist = 0; - status = EXIT_USER_REQUEST; - got_sigterm = 0; - } - if (got_sigchld) { - reap_kids(0); /* Don't leave dead kids lying around */ - got_sigchld = 0; - } - if (got_sigusr2) { - open_ccp_flag = 1; - got_sigusr2 = 0; - } -} - -/* - * setup_signals - initialize signal handling. - */ -static void -setup_signals() -{ - struct sigaction sa; - sigset_t mask; - - /* - * Compute mask of all interesting signals and install signal handlers - * for each. Only one signal handler may be active at a time. Therefore, - * all other signals should be masked when any handler is executing. - */ - sigemptyset(&mask); - sigaddset(&mask, SIGHUP); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGTERM); - sigaddset(&mask, SIGCHLD); - sigaddset(&mask, SIGUSR2); - -#define SIGNAL(s, handler) do { \ - sa.sa_handler = handler; \ - if (sigaction(s, &sa, NULL) < 0) \ - fatal("Couldn't establish signal handler (%d): %m", s); \ - } while (0) - - sa.sa_mask = mask; - sa.sa_flags = 0; - SIGNAL(SIGHUP, hup); /* Hangup */ - SIGNAL(SIGINT, term); /* Interrupt */ - SIGNAL(SIGTERM, term); /* Terminate */ - SIGNAL(SIGCHLD, chld); - - SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ - SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ - - /* - * Install a handler for other signals which would otherwise - * cause pppd to exit without cleaning up. - */ - SIGNAL(SIGABRT, bad_signal); - SIGNAL(SIGALRM, bad_signal); - SIGNAL(SIGFPE, bad_signal); - SIGNAL(SIGILL, bad_signal); - SIGNAL(SIGPIPE, bad_signal); - SIGNAL(SIGQUIT, bad_signal); - SIGNAL(SIGSEGV, bad_signal); -#ifdef SIGBUS - SIGNAL(SIGBUS, bad_signal); -#endif -#ifdef SIGEMT - SIGNAL(SIGEMT, bad_signal); -#endif -#ifdef SIGPOLL - SIGNAL(SIGPOLL, bad_signal); -#endif -#ifdef SIGPROF - SIGNAL(SIGPROF, bad_signal); -#endif -#ifdef SIGSYS - SIGNAL(SIGSYS, bad_signal); -#endif -#ifdef SIGTRAP - SIGNAL(SIGTRAP, bad_signal); -#endif -#ifdef SIGVTALRM - SIGNAL(SIGVTALRM, bad_signal); -#endif -#ifdef SIGXCPU - SIGNAL(SIGXCPU, bad_signal); -#endif -#ifdef SIGXFSZ - SIGNAL(SIGXFSZ, bad_signal); -#endif - - /* - * Apparently we can get a SIGPIPE when we call syslog, if - * syslogd has died and been restarted. Ignoring it seems - * be sufficient. - */ - signal(SIGPIPE, SIG_IGN); -} - -/* - * set_ifunit - do things we need to do once we know which ppp - * unit we are using. - */ -void -set_ifunit(iskey) - int iskey; -{ - info("Using interface %s%d", PPP_DRV_NAME, ifunit); - slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); - script_setenv("IFNAME", ifname, iskey); - if (iskey) { - create_pidfile(); /* write pid to file */ - create_linkpidfile(); - } -} - -/* - * detach - detach us from the controlling terminal. - */ -void -detach() -{ - int pid; - char numbuf[16]; - - if (detached) - return; - if ((pid = fork()) < 0) { - error("Couldn't detach (fork failed: %m)"); - die(1); /* or just return? */ - } - if (pid != 0) { - /* parent */ - notify(pidchange, pid); - exit(0); /* parent dies */ - } - setsid(); - chdir("/"); - close(0); - close(1); - close(2); - detached = 1; - if (log_default) - log_to_fd = -1; - /* update pid files if they have been written already */ - if (pidfilename[0]) - create_pidfile(); - if (linkpidfile[0]) - create_linkpidfile(); - slprintf(numbuf, sizeof(numbuf), "%d", getpid()); - script_setenv("PPPD_PID", numbuf, 1); -} - -/* - * reopen_log - (re)open our connection to syslog. - */ -void -reopen_log() -{ -#ifdef ULTRIX - openlog("pppd", LOG_PID); -#else - openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); - setlogmask(LOG_UPTO(LOG_INFO)); -#endif -} - -/* - * Create a file containing our process ID. - */ -static void -create_pidfile() -{ - FILE *pidfile; - - slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid", - _PATH_VARRUN, ifname); - if ((pidfile = fopen(pidfilename, "w")) != NULL) { - fprintf(pidfile, "%d\n", getpid()); - (void) fclose(pidfile); - } else { - error("Failed to create pid file %s: %m", pidfilename); - pidfilename[0] = 0; - } -} - -static void -create_linkpidfile() -{ - FILE *pidfile; - - if (linkname[0] == 0) - return; - script_setenv("LINKNAME", linkname, 1); - slprintf(linkpidfile, sizeof(linkpidfile), "%sppp-%s.pid", - _PATH_VARRUN, linkname); - if ((pidfile = fopen(linkpidfile, "w")) != NULL) { - fprintf(pidfile, "%d\n", getpid()); - if (ifname[0]) - fprintf(pidfile, "%s\n", ifname); - (void) fclose(pidfile); - } else { - error("Failed to create pid file %s: %m", linkpidfile); - linkpidfile[0] = 0; - } -} - -/* - * holdoff_end - called via a timeout when the holdoff period ends. - */ -static void -holdoff_end(arg) - void *arg; -{ - new_phase(PHASE_DORMANT); -} - -/* List of protocol names, to make our messages a little more informative. */ -struct protocol_list { - u_short proto; - const char *name; -} protocol_list[] = { - { 0x21, "IP" }, - { 0x23, "OSI Network Layer" }, - { 0x25, "Xerox NS IDP" }, - { 0x27, "DECnet Phase IV" }, - { 0x29, "Appletalk" }, - { 0x2b, "Novell IPX" }, - { 0x2d, "VJ compressed TCP/IP" }, - { 0x2f, "VJ uncompressed TCP/IP" }, - { 0x31, "Bridging PDU" }, - { 0x33, "Stream Protocol ST-II" }, - { 0x35, "Banyan Vines" }, - { 0x39, "AppleTalk EDDP" }, - { 0x3b, "AppleTalk SmartBuffered" }, - { 0x3d, "Multi-Link" }, - { 0x3f, "NETBIOS Framing" }, - { 0x41, "Cisco Systems" }, - { 0x43, "Ascom Timeplex" }, - { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" }, - { 0x47, "DCA Remote Lan" }, - { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" }, - { 0x4b, "SNA over 802.2" }, - { 0x4d, "SNA" }, - { 0x4f, "IP6 Header Compression" }, - { 0x6f, "Stampede Bridging" }, - { 0xfb, "single-link compression" }, - { 0xfd, "1st choice compression" }, - { 0x0201, "802.1d Hello Packets" }, - { 0x0203, "IBM Source Routing BPDU" }, - { 0x0205, "DEC LANBridge100 Spanning Tree" }, - { 0x0231, "Luxcom" }, - { 0x0233, "Sigma Network Systems" }, - { 0x8021, "Internet Protocol Control Protocol" }, - { 0x8023, "OSI Network Layer Control Protocol" }, - { 0x8025, "Xerox NS IDP Control Protocol" }, - { 0x8027, "DECnet Phase IV Control Protocol" }, - { 0x8029, "Appletalk Control Protocol" }, - { 0x802b, "Novell IPX Control Protocol" }, - { 0x8031, "Bridging NCP" }, - { 0x8033, "Stream Protocol Control Protocol" }, - { 0x8035, "Banyan Vines Control Protocol" }, - { 0x803d, "Multi-Link Control Protocol" }, - { 0x803f, "NETBIOS Framing Control Protocol" }, - { 0x8041, "Cisco Systems Control Protocol" }, - { 0x8043, "Ascom Timeplex" }, - { 0x8045, "Fujitsu LBLB Control Protocol" }, - { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" }, - { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" }, - { 0x804b, "SNA over 802.2 Control Protocol" }, - { 0x804d, "SNA Control Protocol" }, - { 0x804f, "IP6 Header Compression Control Protocol" }, - { 0x006f, "Stampede Bridging Control Protocol" }, - { 0x80fb, "Single Link Compression Control Protocol" }, - { 0x80fd, "Compression Control Protocol" }, - { 0xc021, "Link Control Protocol" }, - { 0xc023, "Password Authentication Protocol" }, - { 0xc025, "Link Quality Report" }, - { 0xc027, "Shiva Password Authentication Protocol" }, - { 0xc029, "CallBack Control Protocol (CBCP)" }, - { 0xc081, "Container Control Protocol" }, - { 0xc223, "Challenge Handshake Authentication Protocol" }, - { 0xc281, "Proprietary Authentication Protocol" }, - { 0, NULL }, -}; - -/* - * protocol_name - find a name for a PPP protocol. - */ -const char * -protocol_name(proto) - int proto; -{ - struct protocol_list *lp; - - for (lp = protocol_list; lp->proto != 0; ++lp) - if (proto == lp->proto) - return lp->name; - return NULL; -} - -/* - * get_input - called when incoming data is available. - */ -static void -get_input() -{ - int len, i; - u_char *p; - u_short protocol; - struct protent *protp; - - p = inpacket_buf; /* point to beginning of packet buffer */ - - len = read_packet(inpacket_buf); - if (len < 0) - return; - - if (len == 0) { - notice("Modem hangup"); - hungup = 1; - status = EXIT_HANGUP; - lcp_lowerdown(0); /* serial link is no longer available */ - link_terminated(0); - return; - } - - if (debug /*&& (debugflags & DBG_INPACKET)*/) - dbglog("rcvd %P", p, len); - - if (len < PPP_HDRLEN) { - MAINDEBUG(("io(): Received short packet.")); - return; - } - - p += 2; /* Skip address and control */ - GETSHORT(protocol, p); - len -= PPP_HDRLEN; - - /* - * Toss all non-LCP packets unless LCP is OPEN. - */ - if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { - MAINDEBUG(("get_input: Received non-LCP packet when LCP not open.")); - return; - } - - /* - * Until we get past the authentication phase, toss all packets - * except LCP, LQR and authentication packets. - */ - if (phase <= PHASE_AUTHENTICATE - && !(protocol == PPP_LCP || protocol == PPP_LQR - || protocol == PPP_PAP || protocol == PPP_CHAP)) { - MAINDEBUG(("get_input: discarding proto 0x%x in phase %d", - protocol, phase)); - return; - } - - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (protp->protocol == protocol && protp->enabled_flag) { - (*protp->input)(0, p, len); - return; - } - if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag - && protp->datainput != NULL) { - (*protp->datainput)(0, p, len); - return; - } - } - - if (debug) { - const char *pname = protocol_name(protocol); - if (pname != NULL) - warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); - else - warn("Unsupported protocol 0x%x received", protocol); - } - lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); -} - -/* - * new_phase - signal the start of a new phase of pppd's operation. - */ -void -new_phase(p) - int p; -{ - phase = p; - if (new_phase_hook) - (*new_phase_hook)(p); - notify(phasechange, p); -} - -/* - * die - clean up state and exit with the specified status. - */ -void -die(status) - int status; -{ - cleanup(); - notify(exitnotify, status); - syslog(LOG_INFO, "Exit."); - exit(status); -} - -/* - * cleanup - restore anything which needs to be restored before we exit - */ -/* ARGSUSED */ -static void -cleanup() -{ - sys_cleanup(); - - if (fd_ppp >= 0) - the_channel->disestablish_ppp(devfd); - if (the_channel->cleanup) - (*the_channel->cleanup)(); - - if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) - warn("unable to delete pid file %s: %m", pidfilename); - pidfilename[0] = 0; - if (linkpidfile[0] != 0 && unlink(linkpidfile) < 0 && errno != ENOENT) - warn("unable to delete pid file %s: %m", linkpidfile); - linkpidfile[0] = 0; - - if (pppdb != NULL) - cleanup_db(); -} - -/* - * update_link_stats - get stats at link termination. - */ -void -update_link_stats(u) - int u; -{ - struct timeval now; - char numbuf[32]; - - if (!get_ppp_stats(u, &link_stats) - || gettimeofday(&now, NULL) < 0) - return; - link_connect_time = now.tv_sec - start_time.tv_sec; - link_stats_valid = 1; - - slprintf(numbuf, sizeof(numbuf), "%d", link_connect_time); - script_setenv("CONNECT_TIME", numbuf, 0); - slprintf(numbuf, sizeof(numbuf), "%d", link_stats.bytes_out); - script_setenv("BYTES_SENT", numbuf, 0); - slprintf(numbuf, sizeof(numbuf), "%d", link_stats.bytes_in); - script_setenv("BYTES_RCVD", numbuf, 0); -} - - -struct callout { - struct timeval c_time; /* time at which to call routine */ - void *c_arg; /* argument to routine */ - void (*c_func) __P((void *)); /* routine */ - struct callout *c_next; -}; - -static struct callout *callout = NULL; /* Callout list */ -static struct timeval timenow; /* Current time */ - -/* - * timeout - Schedule a timeout. - * - * Note that this timeout takes the number of milliseconds, NOT hz (as in - * the kernel). - */ -void -timeout(func, arg, secs, usecs) - void (*func) __P((void *)); - void *arg; - int secs, usecs; -{ - struct callout *newp, *p, **pp; - - MAINDEBUG(("Timeout %p:%p in %d.%03d seconds.", func, arg, - time / 1000, time % 1000)); - - /* - * Allocate timeout. - */ - if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) - fatal("Out of memory in timeout()!"); - newp->c_arg = arg; - newp->c_func = func; - gettimeofday(&timenow, NULL); - newp->c_time.tv_sec = timenow.tv_sec + secs; - newp->c_time.tv_usec = timenow.tv_usec + usecs; - if (newp->c_time.tv_usec >= 1000000) { - newp->c_time.tv_sec += newp->c_time.tv_usec / 1000000; - newp->c_time.tv_usec %= 1000000; - } - - /* - * Find correct place and link it in. - */ - for (pp = &callout; (p = *pp); pp = &p->c_next) - if (newp->c_time.tv_sec < p->c_time.tv_sec - || (newp->c_time.tv_sec == p->c_time.tv_sec - && newp->c_time.tv_usec < p->c_time.tv_usec)) - break; - newp->c_next = p; - *pp = newp; -} - - -/* - * untimeout - Unschedule a timeout. - */ -void -untimeout(func, arg) - void (*func) __P((void *)); - void *arg; -{ - struct callout **copp, *freep; - - MAINDEBUG(("Untimeout %p:%p.", func, arg)); - - /* - * Find first matching timeout and remove it from the list. - */ - for (copp = &callout; (freep = *copp); copp = &freep->c_next) - if (freep->c_func == func && freep->c_arg == arg) { - *copp = freep->c_next; - free((char *) freep); - break; - } -} - - -/* - * calltimeout - Call any timeout routines which are now due. - */ -static void -calltimeout() -{ - struct callout *p; - - while (callout != NULL) { - p = callout; - - if (gettimeofday(&timenow, NULL) < 0) - fatal("Failed to get time of day: %m"); - if (!(p->c_time.tv_sec < timenow.tv_sec - || (p->c_time.tv_sec == timenow.tv_sec - && p->c_time.tv_usec <= timenow.tv_usec))) - break; /* no, it's not time yet */ - - callout = p->c_next; - (*p->c_func)(p->c_arg); - - free((char *) p); - } -} - - -/* - * timeleft - return the length of time until the next timeout is due. - */ -static struct timeval * -timeleft(tvp) - struct timeval *tvp; -{ - if (callout == NULL) - return NULL; - - gettimeofday(&timenow, NULL); - tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; - tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; - if (tvp->tv_usec < 0) { - tvp->tv_usec += 1000000; - tvp->tv_sec -= 1; - } - if (tvp->tv_sec < 0) - tvp->tv_sec = tvp->tv_usec = 0; - - return tvp; -} - - -/* - * kill_my_pg - send a signal to our process group, and ignore it ourselves. - */ -static void -kill_my_pg(sig) - int sig; -{ - struct sigaction act, oldact; - - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - kill(0, sig); - sigaction(sig, &act, &oldact); - sigaction(sig, &oldact, NULL); -} - - -/* - * hup - Catch SIGHUP signal. - * - * Indicates that the physical layer has been disconnected. - * We don't rely on this indication; if the user has sent this - * signal, we just take the link down. - */ -static void -hup(sig) - int sig; -{ - info("Hangup (SIGHUP)"); - got_sighup = 1; - if (conn_running) - /* Send the signal to the [dis]connector process(es) also */ - kill_my_pg(sig); - notify(sigreceived, sig); - if (waiting) - siglongjmp(sigjmp, 1); -} - - -/* - * term - Catch SIGTERM signal and SIGINT signal (^C/del). - * - * Indicates that we should initiate a graceful disconnect and exit. - */ -/*ARGSUSED*/ -static void -term(sig) - int sig; -{ - info("Terminating on signal %d.", sig); - got_sigterm = 1; - if (conn_running) - /* Send the signal to the [dis]connector process(es) also */ - kill_my_pg(sig); - notify(sigreceived, sig); - if (waiting) - siglongjmp(sigjmp, 1); -} - - -/* - * chld - Catch SIGCHLD signal. - * Sets a flag so we will call reap_kids in the mainline. - */ -static void -chld(sig) - int sig; -{ - got_sigchld = 1; - if (waiting) - siglongjmp(sigjmp, 1); -} - - -/* - * toggle_debug - Catch SIGUSR1 signal. - * - * Toggle debug flag. - */ -/*ARGSUSED*/ -static void -toggle_debug(sig) - int sig; -{ - debug = !debug; - if (debug) { - setlogmask(LOG_UPTO(LOG_DEBUG)); - } else { - setlogmask(LOG_UPTO(LOG_WARNING)); - } -} - - -/* - * open_ccp - Catch SIGUSR2 signal. - * - * Try to (re)negotiate compression. - */ -/*ARGSUSED*/ -static void -open_ccp(sig) - int sig; -{ - got_sigusr2 = 1; - if (waiting) - siglongjmp(sigjmp, 1); -} - - -/* - * bad_signal - We've caught a fatal signal. Clean up state and exit. - */ -static void -bad_signal(sig) - int sig; -{ - static int crashed = 0; - - if (crashed) - _exit(127); - crashed = 1; - error("Fatal signal %d", sig); - if (conn_running) - kill_my_pg(SIGTERM); - notify(sigreceived, sig); - die(127); -} - - -/* - * device_script - run a program to talk to the specified fds - * (e.g. to run the connector or disconnector script). - * stderr gets connected to the log fd or to the _PATH_CONNERRS file. - */ -int -device_script(program, in, out, dont_wait) - char *program; - int in, out; - int dont_wait; -{ - int pid, fd; - int status = -1; - int errfd; - - ++conn_running; - pid = fork(); - - if (pid < 0) { - --conn_running; - error("Failed to create child process: %m"); - return -1; - } - - if (pid != 0) { - if (dont_wait) { - record_child(pid, program, NULL, NULL); - status = 0; - } else { - while (waitpid(pid, &status, 0) < 0) { - if (errno == EINTR) - continue; - fatal("error waiting for (dis)connection process: %m"); - } - --conn_running; - } - return (status == 0 ? 0 : -1); - } - - /* here we are executing in the child */ - /* make sure fds 0, 1, 2 are occupied */ - while ((fd = dup(in)) >= 0) { - if (fd > 2) { - close(fd); - break; - } - } - - /* dup in and out to fds > 2 */ - in = dup(in); - out = dup(out); - if (log_to_fd >= 0) { - errfd = dup(log_to_fd); - } else { - errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); - } - - /* close fds 0 - 2 and any others we can think of */ - close(0); - close(1); - close(2); - sys_close(); - if (the_channel->close) - (*the_channel->close)(); - closelog(); - - /* dup the in, out, err fds to 0, 1, 2 */ - dup2(in, 0); - close(in); - dup2(out, 1); - close(out); - if (errfd >= 0) { - dup2(errfd, 2); - close(errfd); - } - - setuid(uid); - if (getuid() != uid) { - error("setuid failed"); - exit(1); - } - setgid(getgid()); - { - int argc = 0; - char * argv[500]; - char * ptr = program; - while (ptr != NULL) { - argv[argc] = ptr; - argc++; - ptr = strchr(ptr, ' '); - if (ptr) { - ptr[0] = '\0'; - ptr++; - } - } - argv[argc] = NULL; - execv(argv[0], argv); - error("could not exec %s: %m", program); - exit(99); - } - /* NOTREACHED */ -} - - -/* - * run-program - execute a program with given arguments, - * but don't wait for it. - * If the program can't be executed, logs an error unless - * must_exist is 0 and the program file doesn't exist. - * Returns -1 if it couldn't fork, 0 if the file doesn't exist - * or isn't an executable plain file, or the process ID of the child. - * If done != NULL, (*done)(arg) will be called later (within - * reap_kids) iff the return value is > 0. - */ -pid_t -run_program(prog, args, must_exist, done, arg) - char *prog; - char **args; - int must_exist; - void (*done) __P((void *)); - void *arg; -{ - int pid; - struct stat sbuf; - - /* - * First check if the file exists and is executable. - * We don't use access() because that would use the - * real user-id, which might not be root, and the script - * might be accessible only to root. - */ - errno = EINVAL; - if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode) - || (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) { - if (must_exist || errno != ENOENT) - warn("Can't execute %s: %m", prog); - return 0; - } - - pid = fork(); - if (pid == -1) { - error("Failed to create child process for %s: %m", prog); - return -1; - } - if (pid == 0) { - int new_fd; - - /* Leave the current location */ - (void) setsid(); /* No controlling tty. */ - (void) umask (S_IRWXG|S_IRWXO); - (void) chdir ("/"); /* no current directory. */ - setuid(0); /* set real UID = root */ - setgid(getegid()); - - /* Ensure that nothing of our device environment is inherited. */ - sys_close(); - closelog(); - close (0); - close (1); - close (2); - if (the_channel->close) - (*the_channel->close)(); - - /* Don't pass handles to the PPP device, even by accident. */ - new_fd = open (_PATH_DEVNULL, O_RDWR); - if (new_fd >= 0) { - if (new_fd != 0) { - dup2 (new_fd, 0); /* stdin <- /dev/null */ - close (new_fd); - } - dup2 (0, 1); /* stdout -> /dev/null */ - dup2 (0, 2); /* stderr -> /dev/null */ - } - -#ifdef BSD - /* Force the priority back to zero if pppd is running higher. */ - if (setpriority (PRIO_PROCESS, 0, 0) < 0) - warn("can't reset priority to 0: %m"); -#endif - - /* SysV recommends a second fork at this point. */ - - /* run the program */ - execve(prog, args, script_env); - if (must_exist || errno != ENOENT) { - /* have to reopen the log, there's nowhere else - for the message to go. */ - reopen_log(); - syslog(LOG_ERR, "Can't execute %s: %m", prog); - closelog(); - } - _exit(-1); - } - - if (debug) - dbglog("Script %s started (pid %d)", prog, pid); - record_child(pid, prog, done, arg); - - return pid; -} - - -/* - * record_child - add a child process to the list for reap_kids - * to use. - */ -void -record_child(pid, prog, done, arg) - int pid; - char *prog; - void (*done) __P((void *)); - void *arg; -{ - struct subprocess *chp; - - ++n_children; - - chp = (struct subprocess *) malloc(sizeof(struct subprocess)); - if (chp == NULL) { - warn("losing track of %s process", prog); - } else { - chp->pid = pid; - chp->prog = prog; - chp->done = done; - chp->arg = arg; - chp->next = children; - children = chp; - } -} - - -/* - * reap_kids - get status from any dead child processes, - * and log a message for abnormal terminations. - */ -static int -reap_kids(waitfor) - int waitfor; -{ - int pid, status; - struct subprocess *chp, **prevp; - - if (n_children == 0) - return 0; - while ((pid = waitpid(-1, &status, (waitfor? 0: WNOHANG))) != -1 - && pid != 0) { - for (prevp = &children; (chp = *prevp) != NULL; prevp = &chp->next) { - if (chp->pid == pid) { - --n_children; - *prevp = chp->next; - break; - } - } - if (WIFSIGNALED(status)) { - warn("Child process %s (pid %d) terminated with signal %d", - (chp? chp->prog: "??"), pid, WTERMSIG(status)); - } else if (debug) - dbglog("Script %s finished (pid %d), status = 0x%x", - (chp? chp->prog: "??"), pid, status); - if (chp && chp->done) - (*chp->done)(chp->arg); - if (chp) - free(chp); - } - if (pid == -1) { - if (errno == ECHILD) - return -1; - if (errno != EINTR) - error("Error waiting for child process: %m"); - } - return 0; -} - -/* - * add_notifier - add a new function to be called when something happens. - */ -void -add_notifier(notif, func, arg) - struct notifier **notif; - notify_func func; - void *arg; -{ - struct notifier *np; - - np = malloc(sizeof(struct notifier)); - if (np == 0) - novm("notifier struct"); - np->next = *notif; - np->func = func; - np->arg = arg; - *notif = np; -} - -/* - * remove_notifier - remove a function from the list of things to - * be called when something happens. - */ -void -remove_notifier(notif, func, arg) - struct notifier **notif; - notify_func func; - void *arg; -{ - struct notifier *np; - - for (; (np = *notif) != 0; notif = &np->next) { - if (np->func == func && np->arg == arg) { - *notif = np->next; - free(np); - break; - } - } -} - -/* - * notify - call a set of functions registered with add_notify. - */ -void -notify(notif, val) - struct notifier *notif; - int val; -{ - struct notifier *np; - - while ((np = notif) != 0) { - notif = np->next; - (*np->func)(np->arg, val); - } -} - -/* - * novm - log an error message saying we ran out of memory, and die. - */ -void -novm(msg) - char *msg; -{ - fatal("Virtual memory exhausted allocating %s\n", msg); -} - -/* - * script_setenv - set an environment variable value to be used - * for scripts that we run (e.g. ip-up, auth-up, etc.) - */ -void -script_setenv(var, value, iskey) - char *var, *value; - int iskey; -{ - size_t varl = strlen(var); - size_t vl = varl + strlen(value) + 2; - int i; - char *p, *newstring; - - newstring = (char *) malloc(vl+1); - if (newstring == 0) - return; - *newstring++ = iskey; - slprintf(newstring, vl, "%s=%s", var, value); - - /* check if this variable is already set */ - if (script_env != 0) { - for (i = 0; (p = script_env[i]) != 0; ++i) { - if (strncmp(p, var, varl) == 0 && p[varl] == '=') { - if (p[-1] && pppdb != NULL) - delete_db_key(p); - free(p-1); - script_env[i] = newstring; - if (iskey && pppdb != NULL) - add_db_key(newstring); - update_db_entry(); - return; - } - } - } else { - /* no space allocated for script env. ptrs. yet */ - i = 0; - script_env = (char **) malloc(16 * sizeof(char *)); - if (script_env == 0) - return; - s_env_nalloc = 16; - } - - /* reallocate script_env with more space if needed */ - if (i + 1 >= s_env_nalloc) { - int new_n = i + 17; - char **newenv = (char **) realloc((void *)script_env, - new_n * sizeof(char *)); - if (newenv == 0) - return; - script_env = newenv; - s_env_nalloc = new_n; - } - - script_env[i] = newstring; - script_env[i+1] = 0; - - if (pppdb != NULL) { - if (iskey) - add_db_key(newstring); - update_db_entry(); - } -} - -/* - * script_unsetenv - remove a variable from the environment - * for scripts. - */ -void -script_unsetenv(var) - char *var; -{ - int vl = strlen(var); - int i; - char *p; - - if (script_env == 0) - return; - for (i = 0; (p = script_env[i]) != 0; ++i) { - if (strncmp(p, var, vl) == 0 && p[vl] == '=') { - if (p[-1] && pppdb != NULL) - delete_db_key(p); - free(p-1); - while ((script_env[i] = script_env[i+1]) != 0) - ++i; - break; - } - } - if (pppdb != NULL) - update_db_entry(); -} - -/* - * update_db_entry - update our entry in the database. - */ -static void -update_db_entry() -{ - TDB_DATA key, dbuf; - int vlen, i; - char *p, *q, *vbuf; - - if (script_env == NULL) - return; - vlen = 0; - for (i = 0; (p = script_env[i]) != 0; ++i) - vlen += strlen(p) + 1; - vbuf = malloc(vlen); - if (vbuf == 0) - novm("database entry"); - q = vbuf; - for (i = 0; (p = script_env[i]) != 0; ++i) - q += slprintf(q, vbuf + vlen - q, "%s;", p); - - key.dptr = db_key; - key.dsize = strlen(db_key); - dbuf.dptr = vbuf; - dbuf.dsize = vlen; - if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) - error("tdb_store failed: %s", tdb_error(pppdb)); - -} - -/* - * add_db_key - add a key that we can use to look up our database entry. - */ -static void -add_db_key(str) - const char *str; -{ - TDB_DATA key, dbuf; - - key.dptr = (char *) str; - key.dsize = strlen(str); - dbuf.dptr = db_key; - dbuf.dsize = strlen(db_key); - if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) - error("tdb_store key failed: %s", tdb_error(pppdb)); -} - -/* - * delete_db_key - delete a key for looking up our database entry. - */ -static void -delete_db_key(str) - const char *str; -{ - TDB_DATA key; - - key.dptr = (char *) str; - key.dsize = strlen(str); - tdb_delete(pppdb, key); -} - -/* - * cleanup_db - delete all the entries we put in the database. - */ -static void -cleanup_db() -{ - TDB_DATA key; - int i; - char *p; - - key.dptr = db_key; - key.dsize = strlen(db_key); - tdb_delete(pppdb, key); - for (i = 0; (p = script_env[i]) != 0; ++i) - if (p[-1]) - delete_db_key(p); -} diff --git a/mdk-stage1/ppp/pppd/md4.c b/mdk-stage1/ppp/pppd/md4.c deleted file mode 100644 index cda9f943d..000000000 --- a/mdk-stage1/ppp/pppd/md4.c +++ /dev/null @@ -1,298 +0,0 @@ -/* -** ******************************************************************** -** md4.c -- Implementation of MD4 Message Digest Algorithm ** -** Updated: 2/16/90 by Ronald L. Rivest ** -** (C) 1990 RSA Data Security, Inc. ** -** ******************************************************************** -*/ - -/* -** To use MD4: -** -- Include md4.h in your program -** -- Declare an MDstruct MD to hold the state of the digest -** computation. -** -- Initialize MD using MDbegin(&MD) -** -- For each full block (64 bytes) X you wish to process, call -** MD4Update(&MD,X,512) -** (512 is the number of bits in a full block.) -** -- For the last block (less than 64 bytes) you wish to process, -** MD4Update(&MD,X,n) -** where n is the number of bits in the partial block. A partial -** block terminates the computation, so every MD computation -** should terminate by processing a partial block, even if it -** has n = 0. -** -- The message digest is available in MD.buffer[0] ... -** MD.buffer[3]. (Least-significant byte of each word -** should be output first.) -** -- You can print out the digest using MDprint(&MD) -*/ - -/* Implementation notes: -** This implementation assumes that ints are 32-bit quantities. -*/ - -#define TRUE 1 -#define FALSE 0 - -/* Compile-time includes -*/ -#include <stdio.h> -#include "md4.h" -#include "pppd.h" - -/* Compile-time declarations of MD4 "magic constants". -*/ -#define I0 0x67452301 /* Initial values for MD buffer */ -#define I1 0xefcdab89 -#define I2 0x98badcfe -#define I3 0x10325476 -#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */ -#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */ -/* C2 and C3 are from Knuth, The Art of Programming, Volume 2 -** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley. -** Table 2, page 660. -*/ - -#define fs1 3 /* round 1 shift amounts */ -#define fs2 7 -#define fs3 11 -#define fs4 19 -#define gs1 3 /* round 2 shift amounts */ -#define gs2 5 -#define gs3 9 -#define gs4 13 -#define hs1 3 /* round 3 shift amounts */ -#define hs2 9 -#define hs3 11 -#define hs4 15 - -/* Compile-time macro declarations for MD4. -** Note: The "rot" operator uses the variable "tmp". -** It assumes tmp is declared as unsigned int, so that the >> -** operator will shift in zeros rather than extending the sign bit. -*/ -#define f(X,Y,Z) ((X&Y) | ((~X)&Z)) -#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z)) -#define h(X,Y,Z) (X^Y^Z) -#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S))) -#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s) -#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s) -#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s) - -/* MD4print(MDp) -** Print message digest buffer MDp as 32 hexadecimal digits. -** Order is from low-order byte of buffer[0] to high-order byte of -** buffer[3]. -** Each byte is printed with high-order hexadecimal digit first. -** This is a user-callable routine. -*/ -void -MD4Print(MDp) -MD4_CTX *MDp; -{ - int i,j; - for (i=0;i<4;i++) - for (j=0;j<32;j=j+8) - printf("%02x",(MDp->buffer[i]>>j) & 0xFF); -} - -/* MD4Init(MDp) -** Initialize message digest buffer MDp. -** This is a user-callable routine. -*/ -void -MD4Init(MDp) -MD4_CTX *MDp; -{ - int i; - MDp->buffer[0] = I0; - MDp->buffer[1] = I1; - MDp->buffer[2] = I2; - MDp->buffer[3] = I3; - for (i=0;i<8;i++) MDp->count[i] = 0; - MDp->done = 0; -} - -/* MDblock(MDp,X) -** Update message digest buffer MDp->buffer using 16-word data block X. -** Assumes all 16 words of X are full of data. -** Does not update MDp->count. -** This routine is not user-callable. -*/ -static void -MDblock(MDp,Xb) -MD4_CTX *MDp; -unsigned char *Xb; -{ - register unsigned int tmp, A, B, C, D; - unsigned int X[16]; - int i; - - for (i = 0; i < 16; ++i) { - X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24); - Xb += 4; - } - - A = MDp->buffer[0]; - B = MDp->buffer[1]; - C = MDp->buffer[2]; - D = MDp->buffer[3]; - /* Update the message digest buffer */ - ff(A , B , C , D , 0 , fs1); /* Round 1 */ - ff(D , A , B , C , 1 , fs2); - ff(C , D , A , B , 2 , fs3); - ff(B , C , D , A , 3 , fs4); - ff(A , B , C , D , 4 , fs1); - ff(D , A , B , C , 5 , fs2); - ff(C , D , A , B , 6 , fs3); - ff(B , C , D , A , 7 , fs4); - ff(A , B , C , D , 8 , fs1); - ff(D , A , B , C , 9 , fs2); - ff(C , D , A , B , 10 , fs3); - ff(B , C , D , A , 11 , fs4); - ff(A , B , C , D , 12 , fs1); - ff(D , A , B , C , 13 , fs2); - ff(C , D , A , B , 14 , fs3); - ff(B , C , D , A , 15 , fs4); - gg(A , B , C , D , 0 , gs1); /* Round 2 */ - gg(D , A , B , C , 4 , gs2); - gg(C , D , A , B , 8 , gs3); - gg(B , C , D , A , 12 , gs4); - gg(A , B , C , D , 1 , gs1); - gg(D , A , B , C , 5 , gs2); - gg(C , D , A , B , 9 , gs3); - gg(B , C , D , A , 13 , gs4); - gg(A , B , C , D , 2 , gs1); - gg(D , A , B , C , 6 , gs2); - gg(C , D , A , B , 10 , gs3); - gg(B , C , D , A , 14 , gs4); - gg(A , B , C , D , 3 , gs1); - gg(D , A , B , C , 7 , gs2); - gg(C , D , A , B , 11 , gs3); - gg(B , C , D , A , 15 , gs4); - hh(A , B , C , D , 0 , hs1); /* Round 3 */ - hh(D , A , B , C , 8 , hs2); - hh(C , D , A , B , 4 , hs3); - hh(B , C , D , A , 12 , hs4); - hh(A , B , C , D , 2 , hs1); - hh(D , A , B , C , 10 , hs2); - hh(C , D , A , B , 6 , hs3); - hh(B , C , D , A , 14 , hs4); - hh(A , B , C , D , 1 , hs1); - hh(D , A , B , C , 9 , hs2); - hh(C , D , A , B , 5 , hs3); - hh(B , C , D , A , 13 , hs4); - hh(A , B , C , D , 3 , hs1); - hh(D , A , B , C , 11 , hs2); - hh(C , D , A , B , 7 , hs3); - hh(B , C , D , A , 15 , hs4); - MDp->buffer[0] += A; - MDp->buffer[1] += B; - MDp->buffer[2] += C; - MDp->buffer[3] += D; -} - -/* MD4Update(MDp,X,count) -** Input: X -- a pointer to an array of unsigned characters. -** count -- the number of bits of X to use. -** (if not a multiple of 8, uses high bits of last byte.) -** Update MDp using the number of bits of X given by count. -** This is the basic input routine for an MD4 user. -** The routine completes the MD computation when count < 512, so -** every MD computation should end with one call to MD4Update with a -** count less than 512. A call with count 0 will be ignored if the -** MD has already been terminated (done != 0), so an extra call with -** count 0 can be given as a "courtesy close" to force termination -** if desired. -*/ -void -MD4Update(MDp,X,count) -MD4_CTX *MDp; -unsigned char *X; -unsigned int count; -{ - unsigned int i, tmp, bit, byte, mask; - unsigned char XX[64]; - unsigned char *p; - - /* return with no error if this is a courtesy close with count - ** zero and MDp->done is true. - */ - if (count == 0 && MDp->done) return; - /* check to see if MD is already done and report error */ - if (MDp->done) - { printf("\nError: MD4Update MD already done."); return; } - - /* Add count to MDp->count */ - tmp = count; - p = MDp->count; - while (tmp) - { tmp += *p; - *p++ = tmp; - tmp = tmp >> 8; - } - - /* Process data */ - if (count == 512) - { /* Full block of data to handle */ - MDblock(MDp,X); - } - else if (count > 512) /* Check for count too large */ - { - printf("\nError: MD4Update called with illegal count value %d.", - count); - return; - } - else /* partial block -- must be last block so finish up */ - { - /* Find out how many bytes and residual bits there are */ - byte = count >> 3; - bit = count & 7; - /* Copy X into XX since we need to modify it */ - for (i=0;i<=byte;i++) XX[i] = X[i]; - for (i=byte+1;i<64;i++) XX[i] = 0; - /* Add padding '1' bit and low-order zeros in last byte */ - mask = 1 << (7 - bit); - XX[byte] = (XX[byte] | mask) & ~( mask - 1); - /* If room for bit count, finish up with this block */ - if (byte <= 55) - { - for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; - MDblock(MDp,XX); - } - else /* need to do two blocks to finish up */ - { - MDblock(MDp,XX); - for (i=0;i<56;i++) XX[i] = 0; - for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; - MDblock(MDp,XX); - } - /* Set flag saying we're done with MD computation */ - MDp->done = 1; - } -} - -/* -** Finish up MD4 computation and return message digest. -*/ -void -MD4Final(buf, MD) -unsigned char *buf; -MD4_CTX *MD; -{ - int i, j; - unsigned int w; - - MD4Update(MD, NULL, 0); - for (i = 0; i < 4; ++i) { - w = MD->buffer[i]; - for (j = 0; j < 4; ++j) { - *buf++ = w; - w >>= 8; - } - } -} - -/* -** End of md4.c -****************************(cut)***********************************/ diff --git a/mdk-stage1/ppp/pppd/md4.h b/mdk-stage1/ppp/pppd/md4.h deleted file mode 100644 index 80e8f9a2a..000000000 --- a/mdk-stage1/ppp/pppd/md4.h +++ /dev/null @@ -1,64 +0,0 @@ - -/* -** ******************************************************************** -** md4.h -- Header file for implementation of ** -** MD4 Message Digest Algorithm ** -** Updated: 2/13/90 by Ronald L. Rivest ** -** (C) 1990 RSA Data Security, Inc. ** -** ******************************************************************** -*/ - -#ifndef __P -# if defined(__STDC__) || defined(__GNUC__) -# define __P(x) x -# else -# define __P(x) () -# endif -#endif - - -/* MDstruct is the data structure for a message digest computation. -*/ -typedef struct { - unsigned int buffer[4]; /* Holds 4-word result of MD computation */ - unsigned char count[8]; /* Number of bits processed so far */ - unsigned int done; /* Nonzero means MD computation finished */ -} MD4_CTX; - -/* MD4Init(MD4_CTX *) -** Initialize the MD4_CTX prepatory to doing a message digest -** computation. -*/ -extern void MD4Init __P((MD4_CTX *MD)); - -/* MD4Update(MD,X,count) -** Input: X -- a pointer to an array of unsigned characters. -** count -- the number of bits of X to use (an unsigned int). -** Updates MD using the first "count" bits of X. -** The array pointed to by X is not modified. -** If count is not a multiple of 8, MD4Update uses high bits of -** last byte. -** This is the basic input routine for a user. -** The routine terminates the MD computation when count < 512, so -** every MD computation should end with one call to MD4Update with a -** count less than 512. Zero is OK for a count. -*/ -extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count)); - -/* MD4Print(MD) -** Prints message digest buffer MD as 32 hexadecimal digits. -** Order is from low-order byte of buffer[0] to high-order byte -** of buffer[3]. -** Each byte is printed with high-order hexadecimal digit first. -*/ -extern void MD4Print __P((MD4_CTX *)); - -/* MD4Final(buf, MD) -** Returns message digest from MD and terminates the message -** digest computation. -*/ -extern void MD4Final __P((unsigned char *, MD4_CTX *)); - -/* -** End of md4.h -****************************(cut)***********************************/ diff --git a/mdk-stage1/ppp/pppd/md5.c b/mdk-stage1/ppp/pppd/md5.c deleted file mode 100644 index 0b8de3aae..000000000 --- a/mdk-stage1/ppp/pppd/md5.c +++ /dev/null @@ -1,309 +0,0 @@ - - -/* - *********************************************************************** - ** md5.c -- the source code for MD5 routines ** - ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** - *********************************************************************** - */ - -/* - *********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - *********************************************************************** - */ - -#include <stdlib.h> -#include <string.h> - -#include "md5.h" - -/* - *********************************************************************** - ** Message-digest routines: ** - ** To form the message digest for a message M ** - ** (1) Initialize a context buffer mdContext using MD5Init ** - ** (2) Call MD5Update on mdContext and M ** - ** (3) Call MD5Final on mdContext ** - ** The message digest is now in mdContext->digest[0...15] ** - *********************************************************************** - */ - -/* forward declaration */ -static void Transform (); - -static unsigned char PADDING[64] = { - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* F, G, H and I are basic MD5 functions */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ -/* Rotation is separate from addition to prevent recomputation */ -#define FF(a, b, c, d, x, s, ac) \ - {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) \ - {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) \ - {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) \ - {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -#ifdef __STDC__ -#define UL(x) x##U -#else -#define UL(x) x -#endif - -/* The routine MD5Init initializes the message-digest context - mdContext. All fields are set to zero. - */ -void MD5Init (mdContext) -MD5_CTX *mdContext; -{ - mdContext->i[0] = mdContext->i[1] = (UINT4)0; - - /* Load magic initialization constants. - */ - mdContext->buf[0] = (UINT4)0x67452301; - mdContext->buf[1] = (UINT4)0xefcdab89; - mdContext->buf[2] = (UINT4)0x98badcfe; - mdContext->buf[3] = (UINT4)0x10325476; -} - -/* The routine MD5Update updates the message-digest context to - account for the presence of each of the characters inBuf[0..inLen-1] - in the message whose digest is being computed. - */ -void MD5Update (mdContext, inBuf, inLen) -MD5_CTX *mdContext; -unsigned char *inBuf; -unsigned int inLen; -{ - UINT4 in[16]; - int mdi; - unsigned int i, ii; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext->i[0] >> 3) & 0x3F); - - /* update number of bits */ - if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) - mdContext->i[1]++; - mdContext->i[0] += ((UINT4)inLen << 3); - mdContext->i[1] += ((UINT4)inLen >> 29); - - while (inLen--) { - /* add new character to buffer, increment mdi */ - mdContext->in[mdi++] = *inBuf++; - - /* transform if necessary */ - if (mdi == 0x40) { - for (i = 0, ii = 0; i < 16; i++, ii += 4) - in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | - (((UINT4)mdContext->in[ii+2]) << 16) | - (((UINT4)mdContext->in[ii+1]) << 8) | - ((UINT4)mdContext->in[ii]); - Transform (mdContext->buf, in); - mdi = 0; - } - } -} - -/* The routine MD5Final terminates the message-digest computation and - ends with the desired message digest in mdContext->digest[0...15]. - */ -void MD5Final (hash, mdContext) -unsigned char hash[]; -MD5_CTX *mdContext; -{ - UINT4 in[16]; - int mdi; - unsigned int i, ii; - unsigned int padLen; - - /* save number of bits */ - in[14] = mdContext->i[0]; - in[15] = mdContext->i[1]; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext->i[0] >> 3) & 0x3F); - - /* pad out to 56 mod 64 */ - padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); - MD5Update (mdContext, PADDING, padLen); - - /* append length in bits and transform */ - for (i = 0, ii = 0; i < 14; i++, ii += 4) - in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | - (((UINT4)mdContext->in[ii+2]) << 16) | - (((UINT4)mdContext->in[ii+1]) << 8) | - ((UINT4)mdContext->in[ii]); - Transform (mdContext->buf, in); - - /* store buffer in digest */ - for (i = 0, ii = 0; i < 4; i++, ii += 4) { - mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); - mdContext->digest[ii+1] = - (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); - mdContext->digest[ii+2] = - (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); - mdContext->digest[ii+3] = - (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); - } - memcpy(hash, mdContext->digest, 16); -} - -/* Basic MD5 step. Transforms buf based on in. - */ -static void Transform (buf, in) -UINT4 *buf; -UINT4 *in; -{ - UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; - - /* Round 1 */ -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 - FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ - FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ - FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ - FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ - FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ - FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ - FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ - FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ - FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ - FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ - FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ - FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ - FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ - FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ - FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ - FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ - - /* Round 2 */ -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 - GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ - GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ - GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ - GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ - GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ - GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ - GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ - GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ - GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ - GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ - GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ - GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ - GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ - GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ - GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ - GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ - - /* Round 3 */ -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 - HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ - HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ - HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ - HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ - HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ - HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ - HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ - HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ - HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ - HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ - HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ - HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ - HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ - HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ - HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ - HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ - - /* Round 4 */ -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ - II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ - II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ - II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ - II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ - II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ - II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ - II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ - II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ - II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ - II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ - II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ - II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ - II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ - II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ - II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -/* - *********************************************************************** - ** End of md5.c ** - ******************************** (cut) ******************************** - */ diff --git a/mdk-stage1/ppp/pppd/md5.h b/mdk-stage1/ppp/pppd/md5.h deleted file mode 100644 index 7492b2228..000000000 --- a/mdk-stage1/ppp/pppd/md5.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - *********************************************************************** - ** md5.h -- header file for implementation of MD5 ** - ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** - ** Revised (for MD5): RLR 4/27/91 ** - ** -- G modified to have y&~z instead of y&z ** - ** -- FF, GG, HH modified to add in last register done ** - ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** - ** -- distinct additive constant for each step ** - ** -- round 4 added, working mod 7 ** - *********************************************************************** - */ - -/* - *********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - *********************************************************************** - */ - -#ifndef __MD5_INCLUDE__ - -/* typedef a 32-bit type */ -typedef unsigned int UINT4; - -/* Data structure for MD5 (Message-Digest) computation */ -typedef struct { - UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ - UINT4 buf[4]; /* scratch buffer */ - unsigned char in[64]; /* input buffer */ - unsigned char digest[16]; /* actual digest after MD5Final call */ -} MD5_CTX; - -void MD5Init (); -void MD5Update (); -void MD5Final (); - -#define __MD5_INCLUDE__ -#endif /* __MD5_INCLUDE__ */ diff --git a/mdk-stage1/ppp/pppd/multilink.c b/mdk-stage1/ppp/pppd/multilink.c deleted file mode 100644 index c30b07e0a..000000000 --- a/mdk-stage1/ppp/pppd/multilink.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - * multilink.c - support routines for multilink. - * - * Copyright (c) 2000 Paul Mackerras. - * 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. The name of the author 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. - */ -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> -#include <netdb.h> -#include <errno.h> -#include <signal.h> -#include <netinet/in.h> - -#include "pppd.h" -#include "fsm.h" -#include "lcp.h" -#include "tdb.h" - -bool endpoint_specified; /* user gave explicit endpoint discriminator */ -char *bundle_id; /* identifier for our bundle */ - -extern TDB_CONTEXT *pppdb; -extern char db_key[]; - -static int get_default_epdisc __P((struct epdisc *)); -static int parse_num __P((char *str, const char *key, int *valp)); -static int owns_unit __P((TDB_DATA pid, int unit)); - -#define set_ip_epdisc(ep, addr) do { \ - ep->length = 4; \ - ep->value[0] = addr >> 24; \ - ep->value[1] = addr >> 16; \ - ep->value[2] = addr >> 8; \ - ep->value[3] = addr; \ -} while (0) - -#define LOCAL_IP_ADDR(addr) \ - (((addr) & 0xff000000) == 0x0a000000 /* 10.x.x.x */ \ - || ((addr) & 0xfff00000) == 0xac100000 /* 172.16.x.x */ \ - || ((addr) & 0xffff0000) == 0xc0a80000) /* 192.168.x.x */ - -#define process_exists(n) (kill((n), 0) == 0 || errno != ESRCH) - -void -mp_check_options() -{ - lcp_options *wo = &lcp_wantoptions[0]; - lcp_options *ao = &lcp_allowoptions[0]; - - if (!multilink) - return; - /* if we're doing multilink, we have to negotiate MRRU */ - if (!wo->neg_mrru) { - /* mrru not specified, default to mru */ - wo->mrru = wo->mru; - wo->neg_mrru = 1; - } - ao->mrru = ao->mru; - ao->neg_mrru = 1; - - if (!wo->neg_endpoint && !noendpoint) { - /* get a default endpoint value */ - wo->neg_endpoint = get_default_epdisc(&wo->endpoint); - } -} - -/* - * Make a new bundle or join us to an existing bundle - * if we are doing multilink. - */ -int -mp_join_bundle() -{ - lcp_options *go = &lcp_gotoptions[0]; - lcp_options *ho = &lcp_hisoptions[0]; - lcp_options *ao = &lcp_allowoptions[0]; - int unit, pppd_pid; - int l, mtu; - char *p; - TDB_DATA key, pid, rec; - - if (!go->neg_mrru || !ho->neg_mrru) { - /* not doing multilink */ - if (go->neg_mrru) - notice("oops, multilink negotiated only for receive"); - mtu = ho->neg_mru? ho->mru: PPP_MRU; - if (mtu > ao->mru) - mtu = ao->mru; - if (demand) { - /* already have a bundle */ - cfg_bundle(0, 0, 0, 0); - netif_set_mtu(0, mtu); - return 0; - } - make_new_bundle(0, 0, 0, 0); - set_ifunit(1); - netif_set_mtu(0, mtu); - return 0; - } - - /* - * Find the appropriate bundle or join a new one. - * First we make up a name for the bundle. - * The length estimate is worst-case assuming every - * character has to be quoted. - */ - l = 4 * strlen(peer_authname) + 10; - if (ho->neg_endpoint) - l += 3 * ho->endpoint.length + 8; - if (bundle_name) - l += 3 * strlen(bundle_name) + 2; - bundle_id = malloc(l); - if (bundle_id == 0) - novm("bundle identifier"); - - p = bundle_id; - p += slprintf(p, l-1, "BUNDLE=\"%q\"", peer_authname); - if (ho->neg_endpoint || bundle_name) - *p++ = '/'; - if (ho->neg_endpoint) - p += slprintf(p, bundle_id+l-p, "%s", - epdisc_to_str(&ho->endpoint)); - if (bundle_name) - p += slprintf(p, bundle_id+l-p, "/%v", bundle_name); - - /* - * For demand mode, we only need to configure the bundle - * and attach the link. - */ - mtu = MIN(ho->mrru, ao->mru); - if (demand) { - cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); - netif_set_mtu(0, mtu); - script_setenv("BUNDLE", bundle_id + 7, 1); - return 0; - } - - /* - * Check if the bundle ID is already in the database. - */ - unit = -1; - tdb_writelock(pppdb); - key.dptr = bundle_id; - key.dsize = p - bundle_id; - pid = tdb_fetch(pppdb, key); - if (pid.dptr != NULL) { - /* bundle ID exists, see if the pppd record exists */ - rec = tdb_fetch(pppdb, pid); - if (rec.dptr != NULL) { - /* it is, parse the interface number */ - parse_num(rec.dptr, "IFNAME=ppp", &unit); - /* check the pid value */ - if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid) - || !process_exists(pppd_pid) - || !owns_unit(pid, unit)) - unit = -1; - free(rec.dptr); - } - free(pid.dptr); - } - - if (unit >= 0) { - /* attach to existing unit */ - if (bundle_attach(unit)) { - set_ifunit(0); - script_setenv("BUNDLE", bundle_id + 7, 0); - tdb_writeunlock(pppdb); - info("Link attached to %s", ifname); - return 1; - } - /* attach failed because bundle doesn't exist */ - } - - /* we have to make a new bundle */ - make_new_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); - set_ifunit(1); - netif_set_mtu(0, mtu); - script_setenv("BUNDLE", bundle_id + 7, 1); - tdb_writeunlock(pppdb); - info("New bundle %s created", ifname); - return 0; -} - -static int -parse_num(str, key, valp) - char *str; - const char *key; - int *valp; -{ - char *p, *endp; - int i; - - p = strstr(str, key); - if (p != 0) { - p += strlen(key); - i = strtol(p, &endp, 10); - if (endp != p && (*endp == 0 || *endp == ';')) { - *valp = i; - return 1; - } - } - return 0; -} - -/* - * Check whether the pppd identified by `key' still owns ppp unit `unit'. - */ -static int -owns_unit(key, unit) - TDB_DATA key; - int unit; -{ - char ifkey[32]; - TDB_DATA kd, vd; - int ret = 0; - - slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit); - kd.dptr = ifkey; - kd.dsize = strlen(ifkey); - vd = tdb_fetch(pppdb, kd); - if (vd.dptr != NULL) { - ret = vd.dsize == key.dsize - && memcmp(vd.dptr, key.dptr, vd.dsize) == 0; - free(vd.dptr); - } - return ret; -} - -static int -get_default_epdisc(ep) - struct epdisc *ep; -{ - char *p; - struct hostent *hp; - u_int32_t addr; - - /* First try for an ethernet MAC address */ - p = get_first_ethernet(); - if (p != 0 && get_if_hwaddr(ep->value, p) >= 0) { - ep->class = EPD_MAC; - ep->length = 6; - return 1; - } - - /* see if our hostname corresponds to a reasonable IP address */ - hp = gethostbyname(hostname); - if (hp != NULL) { - addr = *(u_int32_t *)hp->h_addr; - if (!bad_ip_adrs(addr)) { - addr = ntohl(addr); - if (!LOCAL_IP_ADDR(addr)) { - ep->class = EPD_IP; - set_ip_epdisc(ep, addr); - return 1; - } - } - } - - return 0; -} - -/* - * epdisc_to_str - make a printable string from an endpoint discriminator. - */ - -static char *endp_class_names[] = { - "null", "local", "IP", "MAC", "magic", "phone" -}; - -char * -epdisc_to_str(ep) - struct epdisc *ep; -{ - static char str[MAX_ENDP_LEN*3+8]; - u_char *p = ep->value; - int i, mask = 0; - char *q, c, c2; - - if (ep->class == EPD_NULL && ep->length == 0) - return "null"; - if (ep->class == EPD_IP && ep->length == 4) { - u_int32_t addr; - - GETLONG(addr, p); - slprintf(str, sizeof(str), "IP:%I", htonl(addr)); - return str; - } - - c = ':'; - c2 = '.'; - if (ep->class == EPD_MAC && ep->length == 6) - c2 = ':'; - else if (ep->class == EPD_MAGIC && (ep->length % 4) == 0) - mask = 3; - q = str; - if (ep->class <= EPD_PHONENUM) - q += slprintf(q, sizeof(str)-1, "%s", - endp_class_names[ep->class]); - else - q += slprintf(q, sizeof(str)-1, "%d", ep->class); - c = ':'; - for (i = 0; i < ep->length && i < MAX_ENDP_LEN; ++i) { - if ((i & mask) == 0) { - *q++ = c; - c = c2; - } - q += slprintf(q, str + sizeof(str) - q, "%.2x", ep->value[i]); - } - return str; -} - -static int hexc_val(int c) -{ - if (c >= 'a') - return c - 'a' + 10; - if (c >= 'A') - return c - 'A' + 10; - return c - '0'; -} - -int -str_to_epdisc(ep, str) - struct epdisc *ep; - char *str; -{ - int i, l; - char *p, *endp; - - for (i = EPD_NULL; i <= EPD_PHONENUM; ++i) { - int sl = strlen(endp_class_names[i]); - if (strncasecmp(str, endp_class_names[i], sl) == 0) { - str += sl; - break; - } - } - if (i > EPD_PHONENUM) { - /* not a class name, try a decimal class number */ - i = strtol(str, &endp, 10); - if (endp == str) - return 0; /* can't parse class number */ - str = endp; - } - ep->class = i; - if (*str == 0) { - ep->length = 0; - return 1; - } - if (*str != ':' && *str != '.') - return 0; - ++str; - - if (i == EPD_IP) { - u_int32_t addr; - i = parse_dotted_ip(str, &addr); - if (i == 0 || str[i] != 0) - return 0; - set_ip_epdisc(ep, addr); - return 1; - } - if (i == EPD_MAC && get_if_hwaddr(ep->value, str) >= 0) { - ep->length = 6; - return 1; - } - - p = str; - for (l = 0; l < MAX_ENDP_LEN; ++l) { - if (*str == 0) - break; - if (p <= str) - for (p = str; isxdigit(*p); ++p) - ; - i = p - str; - if (i == 0) - return 0; - ep->value[l] = hexc_val(*str++); - if ((i & 1) == 0) - ep->value[l] = (ep->value[l] << 4) + hexc_val(*str++); - if (*str == ':' || *str == '.') - ++str; - } - if (*str != 0 || (ep->class == EPD_MAC && l != 6)) - return 0; - ep->length = l; - return 1; -} - diff --git a/mdk-stage1/ppp/pppd/options.c b/mdk-stage1/ppp/pppd/options.c deleted file mode 100644 index 1921d9ec5..000000000 --- a/mdk-stage1/ppp/pppd/options.c +++ /dev/null @@ -1,1513 +0,0 @@ -/* - * options.c - handles option processing for PPP. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -#define RCSID "$Id$" - -#include <ctype.h> -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdlib.h> -#include <syslog.h> -#include <string.h> -#include <pwd.h> -#ifdef PLUGIN -#include <dlfcn.h> -#endif -#ifdef PPP_FILTER -#include <pcap.h> -#include <pcap-int.h> /* XXX: To get struct pcap */ -#endif - -#include "pppd.h" -#include "pathnames.h" - -#if defined(ultrix) || defined(NeXT) -char *strdup __P((char *)); -#endif - -static const char rcsid[] = RCSID; - -struct option_value { - struct option_value *next; - const char *source; - char value[1]; -}; - -/* - * Option variables and default values. - */ -#ifdef PPP_FILTER -int dflag = 0; /* Tell libpcap we want debugging */ -#endif -int debug = 0; /* Debug flag */ -int kdebugflag = 0; /* Tell kernel to print debug messages */ -int default_device = 1; /* Using /dev/tty or equivalent */ -char devnam[MAXPATHLEN]; /* Device name */ -bool nodetach = 0; /* Don't detach from controlling tty */ -bool updetach = 0; /* Detach once link is up */ -int maxconnect = 0; /* Maximum connect time */ -char user[MAXNAMELEN]; /* Username for PAP */ -char passwd[MAXSECRETLEN]; /* Password for PAP */ -bool persist = 0; /* Reopen link after it goes down */ -char our_name[MAXNAMELEN]; /* Our name for authentication purposes */ -bool demand = 0; /* do dial-on-demand */ -char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ -int idle_time_limit = 0; /* Disconnect if idle for this many seconds */ -int holdoff = 30; /* # seconds to pause before reconnecting */ -bool holdoff_specified; /* true if a holdoff value has been given */ -int log_to_fd = 1; /* send log messages to this fd too */ -bool log_default = 1; /* log_to_fd is default (stdout) */ -int maxfail = 10; /* max # of unsuccessful connection attempts */ -char linkname[MAXPATHLEN]; /* logical name for link */ -bool tune_kernel; /* may alter kernel settings */ -int connect_delay = 1000; /* wait this many ms after connect script */ -int req_unit = -1; /* requested interface unit */ -bool multilink = 0; /* Enable multilink operation */ -char *bundle_name = NULL; /* bundle name for multilink */ -bool dump_options; /* print out option values */ -bool dryrun; /* print out option values and exit */ -char *domain; /* domain name set by domain option */ - -extern option_t auth_options[]; -extern struct stat devstat; - -#ifdef PPP_FILTER -struct bpf_program pass_filter;/* Filter program for packets to pass */ -struct bpf_program active_filter; /* Filter program for link-active pkts */ -pcap_t pc; /* Fake struct pcap so we can compile expr */ -#endif - -char *current_option; /* the name of the option being parsed */ -int privileged_option; /* set iff the current option came from root */ -char *option_source; /* string saying where the option came from */ -int option_priority = OPRIO_CFGFILE; /* priority of the current options */ -bool devnam_fixed; /* can no longer change device name */ - -static int logfile_fd = -1; /* fd opened for log file */ -static char logfile_name[MAXPATHLEN]; /* name of log file */ - -/* - * Prototypes - */ -static int setdomain __P((char **)); -static int readfile __P((char **)); -static int callfile __P((char **)); -static int showversion __P((char **)); -static int showhelp __P((char **)); -static void usage __P((void)); -static int setlogfile __P((char **)); -#ifdef PLUGIN -static int loadplugin __P((char **)); -#endif - -#ifdef PPP_FILTER -static int setpassfilter __P((char **)); -static int setactivefilter __P((char **)); -#endif - -static option_t *find_option __P((const char *name)); -static int process_option __P((option_t *, char *, char **)); -static int n_arguments __P((option_t *)); -static int number_option __P((char *, u_int32_t *, int)); - -/* - * Structure to store extra lists of options. - */ -struct option_list { - option_t *options; - struct option_list *next; -}; - -static struct option_list *extra_options = NULL; - -/* - * Valid arguments. - */ -option_t general_options[] = { - { "debug", o_int, &debug, - "Increase debugging level", OPT_INC | OPT_NOARG | 1 }, - { "-d", o_int, &debug, - "Increase debugging level", - OPT_ALIAS | OPT_INC | OPT_NOARG | 1 }, - - { "kdebug", o_int, &kdebugflag, - "Set kernel driver debug level", OPT_PRIO }, - - { "nodetach", o_bool, &nodetach, - "Don't detach from controlling tty", OPT_PRIO | 1 }, - { "-detach", o_bool, &nodetach, - "Don't detach from controlling tty", OPT_ALIAS | OPT_PRIOSUB | 1 }, - { "updetach", o_bool, &updetach, - "Detach from controlling tty once link is up", - OPT_PRIOSUB | OPT_A2CLR | 1, &nodetach }, - - { "holdoff", o_int, &holdoff, - "Set time in seconds before retrying connection", OPT_PRIO }, - - { "idle", o_int, &idle_time_limit, - "Set time in seconds before disconnecting idle link", OPT_PRIO }, - - { "maxconnect", o_int, &maxconnect, - "Set connection time limit", - OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF }, - - { "domain", o_special, (void *)setdomain, - "Add given domain name to hostname", - OPT_PRIO | OPT_PRIV | OPT_A2STRVAL, &domain }, - - { "file", o_special, (void *)readfile, - "Take options from a file", OPT_NOPRINT }, - { "call", o_special, (void *)callfile, - "Take options from a privileged file", OPT_NOPRINT }, - - { "persist", o_bool, &persist, - "Keep on reopening connection after close", OPT_PRIO | 1 }, - { "nopersist", o_bool, &persist, - "Turn off persist option", OPT_PRIOSUB }, - - { "demand", o_bool, &demand, - "Dial on demand", OPT_INITONLY | 1, &persist }, - - { "--version", o_special_noarg, (void *)showversion, - "Show version number" }, - { "--help", o_special_noarg, (void *)showhelp, - "Show brief listing of options" }, - { "-h", o_special_noarg, (void *)showhelp, - "Show brief listing of options", OPT_ALIAS }, - - { "logfile", o_special, (void *)setlogfile, - "Append log messages to this file", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, &logfile_name }, - { "logfd", o_int, &log_to_fd, - "Send log messages to this file descriptor", - OPT_PRIOSUB | OPT_A2CLR, &log_default }, - { "nolog", o_int, &log_to_fd, - "Don't send log messages to any file", - OPT_PRIOSUB | OPT_NOARG | OPT_VAL(-1) }, - { "nologfd", o_int, &log_to_fd, - "Don't send log messages to any file descriptor", - OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, - - { "linkname", o_string, linkname, - "Set logical name for link", - OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXPATHLEN }, - - { "maxfail", o_int, &maxfail, - "Maximum number of unsuccessful connection attempts to allow", - OPT_PRIO }, - - { "ktune", o_bool, &tune_kernel, - "Alter kernel settings as necessary", OPT_PRIO | 1 }, - { "noktune", o_bool, &tune_kernel, - "Don't alter kernel settings", OPT_PRIOSUB }, - - { "connect-delay", o_int, &connect_delay, - "Maximum time (in ms) to wait after connect script finishes", - OPT_PRIO }, - - { "unit", o_int, &req_unit, - "PPP interface unit number to use if possible", - OPT_PRIO | OPT_LLIMIT, 0, 0 }, - - { "dump", o_bool, &dump_options, - "Print out option values after parsing all options", 1 }, - { "dryrun", o_bool, &dryrun, - "Stop after parsing, printing, and checking options", 1 }, - -#ifdef HAVE_MULTILINK - { "multilink", o_bool, &multilink, - "Enable multilink operation", OPT_PRIO | 1 }, - { "mp", o_bool, &multilink, - "Enable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 1 }, - { "nomultilink", o_bool, &multilink, - "Disable multilink operation", OPT_PRIOSUB | 0 }, - { "nomp", o_bool, &multilink, - "Disable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 0 }, - - { "bundle", o_string, &bundle_name, - "Bundle name for multilink", OPT_PRIO }, -#endif /* HAVE_MULTILINK */ - -#ifdef PLUGIN - { "plugin", o_special, (void *)loadplugin, - "Load a plug-in module into pppd", OPT_PRIV | OPT_A2LIST }, -#endif - -#ifdef PPP_FILTER - { "pdebug", o_int, &dflag, - "libpcap debugging", OPT_PRIO }, - - { "pass-filter", 1, setpassfilter, - "set filter for packets to pass", OPT_PRIO }, - - { "active-filter", 1, setactivefilter, - "set filter for active pkts", OPT_PRIO }, -#endif - - { NULL } -}; - -#ifndef IMPLEMENTATION -#define IMPLEMENTATION "" -#endif - -static char *usage_string = "\ -pppd version %s\n\ -Usage: %s [ options ], where options are:\n\ - <device> Communicate over the named device\n\ - <speed> Set the baud rate to <speed>\n\ - <loc>:<rem> Set the local and/or remote interface IP\n\ - addresses. Either one may be omitted.\n\ - asyncmap <n> Set the desired async map to hex <n>\n\ - auth Require authentication from peer\n\ - connect <p> Invoke shell command <p> to set up the serial line\n\ - crtscts Use hardware RTS/CTS flow control\n\ - defaultroute Add default route through interface\n\ - file <f> Take options from file <f>\n\ - modem Use modem control lines\n\ - mru <n> Set MRU value to <n> for negotiation\n\ -See pppd(8) for more options.\n\ -"; - -/* - * parse_args - parse a string of arguments from the command line. - */ -int -parse_args(argc, argv) - int argc; - char **argv; -{ - char *arg; - option_t *opt; - int n; - - privileged_option = privileged; - option_source = "command line"; - option_priority = OPRIO_CMDLINE; - while (argc > 0) { - arg = *argv++; - --argc; - opt = find_option(arg); - if (opt == NULL) { - option_error("unrecognized option '%s'", arg); - usage(); - return 0; - } - n = n_arguments(opt); - if (argc < n) { - option_error("too few parameters for option %s", arg); - return 0; - } - if (!process_option(opt, arg, argv)) - return 0; - argc -= n; - argv += n; - } - return 1; -} - -/* - * options_from_file - Read a string of options from a file, - * and interpret them. - */ -int -options_from_file(filename, must_exist, check_prot, priv) - char *filename; - int must_exist; - int check_prot; - int priv; -{ - FILE *f; - int i, newline, ret, err; - option_t *opt; - int oldpriv, n; - char *oldsource; - char *argv[MAXARGS]; - char args[MAXARGS][MAXWORDLEN]; - char cmd[MAXWORDLEN]; - - if (check_prot) - seteuid(getuid()); - f = fopen(filename, "r"); - err = errno; - if (check_prot) - seteuid(0); - if (f == NULL) { - errno = err; - if (!must_exist) { - if (err != ENOENT && err != ENOTDIR) - warn("Warning: can't open options file %s: %m", filename); - return 1; - } - option_error("Can't open options file %s: %m", filename); - return 0; - } - - oldpriv = privileged_option; - privileged_option = priv; - oldsource = option_source; - option_source = strdup(filename); - if (option_source == NULL) - option_source = "file"; - ret = 0; - while (getword(f, cmd, &newline, filename)) { - opt = find_option(cmd); - if (opt == NULL) { - option_error("In file %s: unrecognized option '%s'", - filename, cmd); - goto err; - } - n = n_arguments(opt); - for (i = 0; i < n; ++i) { - if (!getword(f, args[i], &newline, filename)) { - option_error( - "In file %s: too few parameters for option '%s'", - filename, cmd); - goto err; - } - argv[i] = args[i]; - } - if (!process_option(opt, cmd, argv)) - goto err; - } - ret = 1; - -err: - fclose(f); - privileged_option = oldpriv; - option_source = oldsource; - return ret; -} - -/* - * options_from_user - See if the use has a ~/.ppprc file, - * and if so, interpret options from it. - */ -int -options_from_user() -{ - char *user, *path, *file; - int ret; - struct passwd *pw; - size_t pl; - - pw = getpwuid(getuid()); - if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) - return 1; - file = _PATH_USEROPT; - pl = strlen(user) + strlen(file) + 2; - path = malloc(pl); - if (path == NULL) - novm("init file name"); - slprintf(path, pl, "%s/%s", user, file); - option_priority = OPRIO_CFGFILE; - ret = options_from_file(path, 0, 1, privileged); - free(path); - return ret; -} - -/* - * options_for_tty - See if an options file exists for the serial - * device, and if so, interpret options from it. - * We only allow the per-tty options file to override anything from - * the command line if it is something that the user can't override - * once it has been set by root; this is done by giving configuration - * files a lower priority than the command line. - */ -int -options_for_tty() -{ - char *dev, *path, *p; - int ret; - size_t pl; - - dev = devnam; - if (strncmp(dev, "/dev/", 5) == 0) - dev += 5; - if (dev[0] == 0 || strcmp(dev, "tty") == 0) - return 1; /* don't look for /etc/ppp/options.tty */ - pl = strlen(_PATH_TTYOPT) + strlen(dev) + 1; - path = malloc(pl); - if (path == NULL) - novm("tty init file name"); - slprintf(path, pl, "%s%s", _PATH_TTYOPT, dev); - /* Turn slashes into dots, for Solaris case (e.g. /dev/term/a) */ - for (p = path + strlen(_PATH_TTYOPT); *p != 0; ++p) - if (*p == '/') - *p = '.'; - option_priority = OPRIO_CFGFILE; - ret = options_from_file(path, 0, 0, 1); - free(path); - return ret; -} - -/* - * options_from_list - process a string of options in a wordlist. - */ -int -options_from_list(w, priv) - struct wordlist *w; - int priv; -{ - char *argv[MAXARGS]; - option_t *opt; - int i, n, ret = 0; - struct wordlist *w0; - - privileged_option = priv; - option_source = "secrets file"; - option_priority = OPRIO_SECFILE; - - while (w != NULL) { - opt = find_option(w->word); - if (opt == NULL) { - option_error("In secrets file: unrecognized option '%s'", - w->word); - goto err; - } - n = n_arguments(opt); - w0 = w; - for (i = 0; i < n; ++i) { - w = w->next; - if (w == NULL) { - option_error( - "In secrets file: too few parameters for option '%s'", - w0->word); - goto err; - } - argv[i] = w->word; - } - if (!process_option(opt, w0->word, argv)) - goto err; - w = w->next; - } - ret = 1; - -err: - return ret; -} - -/* - * match_option - see if this option matches an option_t structure. - */ -static int -match_option(name, opt, dowild) - char *name; - option_t *opt; - int dowild; -{ - int (*match) __P((char *, char **, int)); - - if (dowild != (opt->type == o_wild)) - return 0; - if (!dowild) - return strcmp(name, opt->name) == 0; - match = (int (*) __P((char *, char **, int))) opt->addr; - return (*match)(name, NULL, 0); -} - -/* - * find_option - scan the option lists for the various protocols - * looking for an entry with the given name. - * This could be optimized by using a hash table. - */ -static option_t * -find_option(name) - const char *name; -{ - option_t *opt; - struct option_list *list; - int i, dowild; - - for (dowild = 0; dowild <= 1; ++dowild) { - for (opt = general_options; opt->name != NULL; ++opt) - if (match_option(name, opt, dowild)) - return opt; - for (opt = auth_options; opt->name != NULL; ++opt) - if (match_option(name, opt, dowild)) - return opt; - for (list = extra_options; list != NULL; list = list->next) - for (opt = list->options; opt->name != NULL; ++opt) - if (match_option(name, opt, dowild)) - return opt; - for (opt = the_channel->options; opt->name != NULL; ++opt) - if (match_option(name, opt, dowild)) - return opt; - for (i = 0; protocols[i] != NULL; ++i) - if ((opt = protocols[i]->options) != NULL) - for (; opt->name != NULL; ++opt) - if (match_option(name, opt, dowild)) - return opt; - } - return NULL; -} - -/* - * process_option - process one new-style option. - */ -static int -process_option(opt, cmd, argv) - option_t *opt; - char *cmd; - char **argv; -{ - u_int32_t v; - int iv, a; - char *sv; - int (*parser) __P((char **)); - int (*wildp) __P((char *, char **, int)); - char *optopt = (opt->type == o_wild)? "": " option"; - int prio = option_priority; - option_t *mainopt = opt; - - if ((opt->flags & OPT_PRIVFIX) && privileged_option) - prio += OPRIO_ROOT; - while (mainopt->flags & OPT_PRIOSUB) - --mainopt; - if (mainopt->flags & OPT_PRIO) { - if (prio < mainopt->priority) { - /* new value doesn't override old */ - if (prio == OPRIO_CMDLINE && mainopt->priority > OPRIO_ROOT) { - option_error("%s%s set in %s cannot be overridden\n", - opt->name, optopt, mainopt->source); - return 0; - } - return 1; - } - if (prio > OPRIO_ROOT && mainopt->priority == OPRIO_CMDLINE) - warn("%s%s from %s overrides command line", - opt->name, optopt, option_source); - } - - if ((opt->flags & OPT_INITONLY) && phase != PHASE_INITIALIZE) { - option_error("%s%s cannot be changed after initialization", - opt->name, optopt); - return 0; - } - if ((opt->flags & OPT_PRIV) && !privileged_option) { - option_error("using the %s%s requires root privilege", - opt->name, optopt); - return 0; - } - if ((opt->flags & OPT_ENABLE) && *(bool *)(opt->addr2) == 0) { - option_error("%s%s is disabled", opt->name, optopt); - return 0; - } - if ((opt->flags & OPT_DEVEQUIV) && devnam_fixed) { - option_error("the %s%s may not be changed in %s", - opt->name, optopt, option_source); - return 0; - } - - switch (opt->type) { - case o_bool: - v = opt->flags & OPT_VALUE; - *(bool *)(opt->addr) = v; - if (opt->addr2 && (opt->flags & OPT_A2COPY)) - *(bool *)(opt->addr2) = v; - break; - - case o_int: - iv = 0; - if ((opt->flags & OPT_NOARG) == 0) { - if (!int_option(*argv, &iv)) - return 0; - if ((((opt->flags & OPT_LLIMIT) && iv < opt->lower_limit) - || ((opt->flags & OPT_ULIMIT) && iv > opt->upper_limit)) - && !((opt->flags & OPT_ZEROOK && iv == 0))) { - char *zok = (opt->flags & OPT_ZEROOK)? " zero or": ""; - switch (opt->flags & OPT_LIMITS) { - case OPT_LLIMIT: - option_error("%s value must be%s >= %d", - opt->name, zok, opt->lower_limit); - break; - case OPT_ULIMIT: - option_error("%s value must be%s <= %d", - opt->name, zok, opt->upper_limit); - break; - case OPT_LIMITS: - option_error("%s value must be%s between %d and %d", - opt->name, opt->lower_limit, opt->upper_limit); - break; - } - return 0; - } - } - a = opt->flags & OPT_VALUE; - if (a >= 128) - a -= 256; /* sign extend */ - iv += a; - if (opt->flags & OPT_INC) - iv += *(int *)(opt->addr); - if ((opt->flags & OPT_NOINCR) && !privileged_option) { - int oldv = *(int *)(opt->addr); - if ((opt->flags & OPT_ZEROINF) ? - (oldv != 0 && (iv == 0 || iv > oldv)) : (iv > oldv)) { - option_error("%s value cannot be increased", opt->name); - return 0; - } - } - *(int *)(opt->addr) = iv; - if (opt->addr2 && (opt->flags & OPT_A2COPY)) - *(int *)(opt->addr2) = iv; - break; - - case o_uint32: - if (opt->flags & OPT_NOARG) { - v = opt->flags & OPT_VALUE; - if (v & 0x80) - v |= 0xffffff00U; - } else if (!number_option(*argv, &v, 16)) - return 0; - if (opt->flags & OPT_OR) - v |= *(u_int32_t *)(opt->addr); - *(u_int32_t *)(opt->addr) = v; - if (opt->addr2 && (opt->flags & OPT_A2COPY)) - *(u_int32_t *)(opt->addr2) = v; - break; - - case o_string: - if (opt->flags & OPT_STATIC) { - strlcpy((char *)(opt->addr), *argv, opt->upper_limit); - } else { - sv = strdup(*argv); - if (sv == NULL) - novm("option argument"); - *(char **)(opt->addr) = sv; - } - break; - - case o_special_noarg: - case o_special: - parser = (int (*) __P((char **))) opt->addr; - if (!(*parser)(argv)) - return 0; - if (opt->flags & OPT_A2LIST) { - struct option_value *ovp, **pp; - - ovp = malloc(sizeof(*ovp) + strlen(*argv)); - if (ovp != 0) { - strcpy(ovp->value, *argv); - ovp->source = option_source; - ovp->next = NULL; - pp = (struct option_value **) &opt->addr2; - while (*pp != 0) - pp = &(*pp)->next; - *pp = ovp; - } - } - break; - - case o_wild: - wildp = (int (*) __P((char *, char **, int))) opt->addr; - if (!(*wildp)(cmd, argv, 1)) - return 0; - break; - } - - if (opt->addr2 && (opt->flags & (OPT_A2COPY|OPT_ENABLE - |OPT_A2PRINTER|OPT_A2STRVAL|OPT_A2LIST)) == 0) - *(bool *)(opt->addr2) = !(opt->flags & OPT_A2CLR); - - mainopt->source = option_source; - mainopt->priority = prio; - mainopt->winner = opt - mainopt; - - return 1; -} - -/* - * override_value - if the option priorities would permit us to - * override the value of option, return 1 and update the priority - * and source of the option value. Otherwise returns 0. - */ -int -override_value(option, priority, source) - const char *option; - int priority; - const char *source; -{ - option_t *opt; - - opt = find_option(option); - if (opt == NULL) - return 0; - while (opt->flags & OPT_PRIOSUB) - --opt; - if ((opt->flags & OPT_PRIO) && priority < opt->priority) - return 0; - opt->priority = priority; - opt->source = source; - opt->winner = -1; - return 1; -} - -/* - * n_arguments - tell how many arguments an option takes - */ -static int -n_arguments(opt) - option_t *opt; -{ - return (opt->type == o_bool || opt->type == o_special_noarg - || (opt->flags & OPT_NOARG))? 0: 1; -} - -/* - * add_options - add a list of options to the set we grok. - */ -void -add_options(opt) - option_t *opt; -{ - struct option_list *list; - - list = malloc(sizeof(*list)); - if (list == 0) - novm("option list entry"); - list->options = opt; - list->next = extra_options; - extra_options = list; -} - -/* - * check_options - check that options are valid and consistent. - */ -void -check_options() -{ - if (logfile_fd >= 0 && logfile_fd != log_to_fd) - close(logfile_fd); -} - -/* - * print_option - print out an option and its value - */ -static void -print_option(opt, mainopt, printer, arg) - option_t *opt, *mainopt; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int i, v; - char *p; - - if (opt->flags & OPT_NOPRINT) - return; - switch (opt->type) { - case o_bool: - v = opt->flags & OPT_VALUE; - if (*(bool *)opt->addr != v) - /* this can happen legitimately, e.g. lock - option turned off for default device */ - break; - printer(arg, "%s", opt->name); - break; - case o_int: - v = opt->flags & OPT_VALUE; - if (v >= 128) - v -= 256; - i = *(int *)opt->addr; - if (opt->flags & OPT_NOARG) { - printer(arg, "%s", opt->name); - if (i != v) { - if (opt->flags & OPT_INC) { - for (; i > v; i -= v) - printer(arg, " %s", opt->name); - } else - printer(arg, " # oops: %d not %d\n", - i, v); - } - } else { - printer(arg, "%s %d", opt->name, i); - } - break; - case o_uint32: - printer(arg, "%s", opt->name); - if ((opt->flags & OPT_NOARG) == 0) - printer(arg, " %x", *(u_int32_t *)opt->addr); - break; - - case o_string: - if (opt->flags & OPT_HIDE) { - p = "??????"; - } else { - p = (char *) opt->addr; - if ((opt->flags & OPT_STATIC) == 0) - p = *(char **)p; - } - printer(arg, "%s %q", opt->name, p); - break; - - case o_special: - case o_special_noarg: - case o_wild: - if (opt->type != o_wild) { - printer(arg, "%s", opt->name); - if (n_arguments(opt) == 0) - break; - printer(arg, " "); - } - if (opt->flags & OPT_A2PRINTER) { - void (*oprt) __P((option_t *, - void ((*)__P((void *, char *, ...))), - void *)); - oprt = opt->addr2; - (*oprt)(opt, printer, arg); - } else if (opt->flags & OPT_A2STRVAL) { - p = (char *) opt->addr2; - if ((opt->flags & OPT_STATIC) == 0) - p = *(char **)p; - printer("%q", p); - } else if (opt->flags & OPT_A2LIST) { - struct option_value *ovp; - - ovp = (struct option_value *) opt->addr2; - for (;;) { - printer(arg, "%q", ovp->value); - if ((ovp = ovp->next) == NULL) - break; - printer(arg, "\t\t# (from %s)\n%s ", - ovp->source, opt->name); - } - } else { - printer(arg, "xxx # [don't know how to print value]"); - } - break; - - default: - printer(arg, "# %s value (type %d)", opt->name, opt->type); - break; - } - printer(arg, "\t\t# (from %s)\n", mainopt->source); -} - -/* - * print_option_list - print out options in effect from an - * array of options. - */ -static void -print_option_list(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - while (opt->name != NULL) { - if (opt->priority != OPRIO_DEFAULT - && opt->winner != (short int) -1) - print_option(opt + opt->winner, opt, printer, arg); - do { - ++opt; - } while (opt->flags & OPT_PRIOSUB); - } -} - -/* - * print_options - print out what options are in effect. - */ -void -print_options(printer, arg) - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - struct option_list *list; - int i; - - printer(arg, "pppd options in effect:\n"); - print_option_list(general_options, printer, arg); - print_option_list(auth_options, printer, arg); - for (list = extra_options; list != NULL; list = list->next) - print_option_list(list->options, printer, arg); - print_option_list(the_channel->options, printer, arg); - for (i = 0; protocols[i] != NULL; ++i) - print_option_list(protocols[i]->options, printer, arg); -} - -/* - * usage - print out a message telling how to use the program. - */ -static void -usage() -{ - if (phase == PHASE_INITIALIZE) - fprintf(stderr, usage_string, VERSION, progname); -} - -/* - * showhelp - print out usage message and exit. - */ -static int -showhelp(argv) - char **argv; -{ - if (phase == PHASE_INITIALIZE) { - usage(); - exit(0); - } - return 0; -} - -/* - * showversion - print out the version number and exit. - */ -static int -showversion(argv) - char **argv; -{ - if (phase == PHASE_INITIALIZE) { - fprintf(stderr, "pppd version %s\n", VERSION); - exit(0); - } - return 0; -} - -/* - * option_error - print a message about an error in an option. - * The message is logged, and also sent to - * stderr if phase == PHASE_INITIALIZE. - */ -void -option_error __V((char *fmt, ...)) -{ - va_list args; - char buf[1024]; - -#if defined(__STDC__) - va_start(args, fmt); -#else - char *fmt; - va_start(args); - fmt = va_arg(args, char *); -#endif - vslprintf(buf, sizeof(buf), fmt, args); - va_end(args); - if (phase == PHASE_INITIALIZE) - fprintf(stderr, "%s: %s\n", progname, buf); - syslog(LOG_ERR, "%s", buf); -} - -#if 0 -/* - * readable - check if a file is readable by the real user. - */ -int -readable(fd) - int fd; -{ - uid_t uid; - int i; - struct stat sbuf; - - uid = getuid(); - if (uid == 0) - return 1; - if (fstat(fd, &sbuf) != 0) - return 0; - if (sbuf.st_uid == uid) - return sbuf.st_mode & S_IRUSR; - if (sbuf.st_gid == getgid()) - return sbuf.st_mode & S_IRGRP; - for (i = 0; i < ngroups; ++i) - if (sbuf.st_gid == groups[i]) - return sbuf.st_mode & S_IRGRP; - return sbuf.st_mode & S_IROTH; -} -#endif - -/* - * Read a word from a file. - * Words are delimited by white-space or by quotes (" or '). - * Quotes, white-space and \ may be escaped with \. - * \<newline> is ignored. - */ -int -getword(f, word, newlinep, filename) - FILE *f; - char *word; - int *newlinep; - char *filename; -{ - int c, len, escape; - int quoted, comment; - int value, digit, got, n; - -#define isoctal(c) ((c) >= '0' && (c) < '8') - - *newlinep = 0; - len = 0; - escape = 0; - comment = 0; - - /* - * First skip white-space and comments. - */ - for (;;) { - c = getc(f); - if (c == EOF) - break; - - /* - * A newline means the end of a comment; backslash-newline - * is ignored. Note that we cannot have escape && comment. - */ - if (c == '\n') { - if (!escape) { - *newlinep = 1; - comment = 0; - } else - escape = 0; - continue; - } - - /* - * Ignore characters other than newline in a comment. - */ - if (comment) - continue; - - /* - * If this character is escaped, we have a word start. - */ - if (escape) - break; - - /* - * If this is the escape character, look at the next character. - */ - if (c == '\\') { - escape = 1; - continue; - } - - /* - * If this is the start of a comment, ignore the rest of the line. - */ - if (c == '#') { - comment = 1; - continue; - } - - /* - * A non-whitespace character is the start of a word. - */ - if (!isspace(c)) - break; - } - - /* - * Save the delimiter for quoted strings. - */ - if (!escape && (c == '"' || c == '\'')) { - quoted = c; - c = getc(f); - } else - quoted = 0; - - /* - * Process characters until the end of the word. - */ - while (c != EOF) { - if (escape) { - /* - * This character is escaped: backslash-newline is ignored, - * various other characters indicate particular values - * as for C backslash-escapes. - */ - escape = 0; - if (c == '\n') { - c = getc(f); - continue; - } - - got = 0; - switch (c) { - case 'a': - value = '\a'; - break; - case 'b': - value = '\b'; - break; - case 'f': - value = '\f'; - break; - case 'n': - value = '\n'; - break; - case 'r': - value = '\r'; - break; - case 's': - value = ' '; - break; - case 't': - value = '\t'; - break; - - default: - if (isoctal(c)) { - /* - * \ddd octal sequence - */ - value = 0; - for (n = 0; n < 3 && isoctal(c); ++n) { - value = (value << 3) + (c & 07); - c = getc(f); - } - got = 1; - break; - } - - if (c == 'x') { - /* - * \x<hex_string> sequence - */ - value = 0; - c = getc(f); - for (n = 0; n < 2 && isxdigit(c); ++n) { - digit = toupper(c) - '0'; - if (digit > 10) - digit += '0' + 10 - 'A'; - value = (value << 4) + digit; - c = getc (f); - } - got = 1; - break; - } - - /* - * Otherwise the character stands for itself. - */ - value = c; - break; - } - - /* - * Store the resulting character for the escape sequence. - */ - if (len < MAXWORDLEN-1) - word[len] = value; - ++len; - - if (!got) - c = getc(f); - continue; - - } - - /* - * Not escaped: see if we've reached the end of the word. - */ - if (quoted) { - if (c == quoted) - break; - } else { - if (isspace(c) || c == '#') { - ungetc (c, f); - break; - } - } - - /* - * Backslash starts an escape sequence. - */ - if (c == '\\') { - escape = 1; - c = getc(f); - continue; - } - - /* - * An ordinary character: store it in the word and get another. - */ - if (len < MAXWORDLEN-1) - word[len] = c; - ++len; - - c = getc(f); - } - - /* - * End of the word: check for errors. - */ - if (c == EOF) { - if (ferror(f)) { - if (errno == 0) - errno = EIO; - option_error("Error reading %s: %m", filename); - die(1); - } - /* - * If len is zero, then we didn't find a word before the - * end of the file. - */ - if (len == 0) - return 0; - } - - /* - * Warn if the word was too long, and append a terminating null. - */ - if (len >= MAXWORDLEN) { - option_error("warning: word in file %s too long (%.20s...)", - filename, word); - len = MAXWORDLEN - 1; - } - word[len] = 0; - - return 1; - -#undef isoctal - -} - -/* - * number_option - parse an unsigned numeric parameter for an option. - */ -static int -number_option(str, valp, base) - char *str; - u_int32_t *valp; - int base; -{ - char *ptr; - - *valp = strtoul(str, &ptr, base); - if (ptr == str) { - option_error("invalid numeric parameter '%s' for %s option", - str, current_option); - return 0; - } - return 1; -} - - -/* - * int_option - like number_option, but valp is int *, - * the base is assumed to be 0, and *valp is not changed - * if there is an error. - */ -int -int_option(str, valp) - char *str; - int *valp; -{ - u_int32_t v; - - if (!number_option(str, &v, 0)) - return 0; - *valp = (int) v; - return 1; -} - - -/* - * The following procedures parse options. - */ - -/* - * readfile - take commands from a file. - */ -static int -readfile(argv) - char **argv; -{ - return options_from_file(*argv, 1, 1, privileged_option); -} - -/* - * callfile - take commands from /etc/ppp/peers/<name>. - * Name may not contain /../, start with / or ../, or end in /.. - */ -static int -callfile(argv) - char **argv; -{ - char *fname, *arg, *p; - int l, ok; - - arg = *argv; - ok = 1; - if (arg[0] == '/' || arg[0] == 0) - ok = 0; - else { - for (p = arg; *p != 0; ) { - if (p[0] == '.' && p[1] == '.' && (p[2] == '/' || p[2] == 0)) { - ok = 0; - break; - } - while (*p != '/' && *p != 0) - ++p; - if (*p == '/') - ++p; - } - } - if (!ok) { - option_error("call option value may not contain .. or start with /"); - return 0; - } - - l = strlen(arg) + strlen(_PATH_PEERFILES) + 1; - if ((fname = (char *) malloc(l)) == NULL) - novm("call file name"); - slprintf(fname, l, "%s%s", _PATH_PEERFILES, arg); - - ok = options_from_file(fname, 1, 1, 1); - - free(fname); - return ok; -} - -#ifdef PPP_FILTER -/* - * setpassfilter - Set the pass filter for packets - */ -static int -setpassfilter(argv) - char **argv; -{ - pc.linktype = DLT_PPP; - pc.snapshot = PPP_HDRLEN; - - if (pcap_compile(&pc, &pass_filter, *argv, 1, netmask) == 0) - return 1; - option_error("error in pass-filter expression: %s\n", pcap_geterr(&pc)); - return 0; -} - -/* - * setactivefilter - Set the active filter for packets - */ -static int -setactivefilter(argv) - char **argv; -{ - pc.linktype = DLT_PPP; - pc.snapshot = PPP_HDRLEN; - - if (pcap_compile(&pc, &active_filter, *argv, 1, netmask) == 0) - return 1; - option_error("error in active-filter expression: %s\n", pcap_geterr(&pc)); - return 0; -} -#endif - -/* - * setdomain - Set domain name to append to hostname - */ -static int -setdomain(argv) - char **argv; -{ - gethostname(hostname, MAXNAMELEN); - if (**argv != 0) { - if (**argv != '.') - strncat(hostname, ".", MAXNAMELEN - strlen(hostname)); - domain = hostname + strlen(hostname); - strncat(hostname, *argv, MAXNAMELEN - strlen(hostname)); - } - hostname[MAXNAMELEN-1] = 0; - return (1); -} - - -static int -setlogfile(argv) - char **argv; -{ - int fd, err; - - if (!privileged_option) - seteuid(getuid()); - fd = open(*argv, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0644); - if (fd < 0 && errno == EEXIST) - fd = open(*argv, O_WRONLY | O_APPEND); - err = errno; - if (!privileged_option) - seteuid(0); - if (fd < 0) { - errno = err; - option_error("Can't open log file %s: %m", *argv); - return 0; - } - strlcpy(logfile_name, *argv, sizeof(logfile_name)); - if (logfile_fd >= 0) - close(logfile_fd); - logfile_fd = fd; - log_to_fd = fd; - log_default = 0; - return 1; -} - -#ifdef PLUGIN -static int -loadplugin(argv) - char **argv; -{ - char *arg = *argv; - void *handle; - const char *err; - void (*init) __P((void)); - char *path = arg; - const char *vers; - - if (strchr(arg, '/') == 0) { - const char *base = _PATH_PLUGIN; - int l = strlen(base) + strlen(arg) + 2; - path = malloc(l); - if (path == 0) - novm("plugin file path"); - strlcpy(path, base, l); - strlcat(path, "/", l); - strlcat(path, arg, l); - } - handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW); - if (handle == 0) { - err = dlerror(); - if (err != 0) - option_error("%s", err); - option_error("Couldn't load plugin %s", arg); - goto err; - } - init = (void (*)(void))dlsym(handle, "plugin_init"); - if (init == 0) { - option_error("%s has no initialization entry point", arg); - goto errclose; - } - vers = (const char *) dlsym(handle, "pppd_version"); - if (vers == 0) { - warn("Warning: plugin %s has no version information", arg); - } else if (strcmp(vers, VERSION) != 0) { - option_error("Plugin %s is for pppd version %s, this is %s", - vers, VERSION); - goto errclose; - } - info("Plugin %s loaded.", arg); - (*init)(); - return 1; - - errclose: - dlclose(handle); - err: - if (path != arg) - free(path); - return 0; -} -#endif /* PLUGIN */ diff --git a/mdk-stage1/ppp/pppd/patchlevel.h b/mdk-stage1/ppp/pppd/patchlevel.h deleted file mode 100644 index 2a2d816f1..000000000 --- a/mdk-stage1/ppp/pppd/patchlevel.h +++ /dev/null @@ -1,4 +0,0 @@ -/* $Id$ */ - -#define VERSION "2.4.1" -#define DATE "25 March 2001" diff --git a/mdk-stage1/ppp/pppd/pathnames.h b/mdk-stage1/ppp/pppd/pathnames.h deleted file mode 100644 index e80784567..000000000 --- a/mdk-stage1/ppp/pppd/pathnames.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * define path names - * - * $Id$ - */ - -#define _PATH_VARRUN "/var/run/" -#define _PATH_DEVNULL "/dev/null" -#define _ROOT_PATH - -#define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets" -#define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets" -#define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options" -#define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up" -#define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down" -#define _PATH_AUTHUP _ROOT_PATH "/etc/ppp/auth-up" -#define _PATH_AUTHDOWN _ROOT_PATH "/etc/ppp/auth-down" -#define _PATH_TTYOPT _ROOT_PATH "/etc/ppp/options." -#define _PATH_CONNERRS _ROOT_PATH "/etc/ppp/connect-errors" -#define _PATH_PEERFILES _ROOT_PATH "/etc/ppp/peers/" -#define _PATH_RESOLV _ROOT_PATH "/etc/resolv.conf" - -#define _PATH_USEROPT ".ppprc" - -#define _PATH_PPPDB _ROOT_PATH _PATH_VARRUN "pppd.tdb" diff --git a/mdk-stage1/ppp/pppd/plugins/Makefile.linux b/mdk-stage1/ppp/pppd/plugins/Makefile.linux deleted file mode 100644 index a64256461..000000000 --- a/mdk-stage1/ppp/pppd/plugins/Makefile.linux +++ /dev/null @@ -1,19 +0,0 @@ -CC = gcc -CFLAGS = -g -O2 -I.. -I../../include -fPIC -LDFLAGS = -shared -INSTALL = install - -all: minconn.so passprompt.so - -minconn.so: minconn.c - $(CC) -o $@ $(LDFLAGS) $(CFLAGS) minconn.c - -passprompt.so: passprompt.c - $(CC) -o $@ $(LDFLAGS) $(CFLAGS) passprompt.c - -LIBDIR = /usr/lib/pppd - -install: minconn.so passprompt.so - version=`awk -F '"' '/VERSION/ { print $$2; }' ../patchlevel.h`; \ - $(INSTALL) -d $(LIBDIR)/$$version; \ - $(INSTALL) $? $(LIBDIR)/$$version
\ No newline at end of file diff --git a/mdk-stage1/ppp/pppd/plugins/Makefile.sol2 b/mdk-stage1/ppp/pppd/plugins/Makefile.sol2 deleted file mode 100644 index 8f4398258..000000000 --- a/mdk-stage1/ppp/pppd/plugins/Makefile.sol2 +++ /dev/null @@ -1,27 +0,0 @@ -# -# Makefile for plugins on Solaris 2 -# -# $Id$ -# - -include ../../svr4/Makedefs - -CFLAGS = -c -O -I.. -I../../include $(COPTS) -LDFLAGS = -G - -all: minconn.so - -minconn.so: minconn.o - ld -o $@ $(LDFLAGS) -h $@ minconn.o - -minconn.o: minconn.c - $(CC) $(CFLAGS) -c $? - -passprompt.so: passprompt.o - ld -o $@ $(LDFLAGS) -h $@ passprompt.o - -passprompt.o: passprompt.c - $(CC) $(CFLAGS) -c $? - -clean: - rm -f *.o *.so diff --git a/mdk-stage1/ppp/pppd/plugins/minconn.c b/mdk-stage1/ppp/pppd/plugins/minconn.c deleted file mode 100644 index 02ea34bf6..000000000 --- a/mdk-stage1/ppp/pppd/plugins/minconn.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * minconn.c - pppd plugin to implement a `minconnect' option. - * - * Copyright 1999 Paul Mackerras. - * - * 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. The name of the author - * 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. - */ -#include <stddef.h> -#include <time.h> -#include "pppd.h" - -char pppd_version[] = VERSION; - -static int minconnect = 0; - -static option_t my_options[] = { - { "minconnect", o_int, &minconnect, - "Set minimum connect time before idle timeout applies" }, - { NULL } -}; - -static int my_get_idle(struct ppp_idle *idle) -{ - time_t t; - - if (idle == NULL) - return minconnect? minconnect: idle_time_limit; - t = idle->xmit_idle; - if (idle->recv_idle < t) - t = idle->recv_idle; - return idle_time_limit - t; -} - -void plugin_init(void) -{ - info("plugin_init"); - add_options(my_options); - idle_time_hook = my_get_idle; -} diff --git a/mdk-stage1/ppp/pppd/plugins/passprompt.c b/mdk-stage1/ppp/pppd/plugins/passprompt.c deleted file mode 100644 index 5e6a7f90b..000000000 --- a/mdk-stage1/ppp/pppd/plugins/passprompt.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * passprompt.c - pppd plugin to invoke an external PAP password prompter - * - * Copyright 1999 Paul Mackerras, Alan Curry. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include <errno.h> -#include <unistd.h> -#include <sys/wait.h> -#include <syslog.h> -#include "pppd.h" - -char pppd_version[] = VERSION; - -static char promptprog[PATH_MAX+1]; - -static option_t options[] = { - { "promptprog", o_string, promptprog, - "External PAP password prompting program", - OPT_STATIC, NULL, PATH_MAX }, - { NULL } -}; - -static int promptpass(char *user, char *passwd) -{ - int p[2]; - pid_t kid; - int readgood, wstat; - size_t red; - - if (promptprog[0] == 0 || access(promptprog, X_OK) < 0) - return -1; /* sorry, can't help */ - - if (!passwd) - return 1; - - if (pipe(p)) { - warn("Can't make a pipe for %s", promptprog); - return 0; - } - if ((kid = fork()) == (pid_t) -1) { - warn("Can't fork to run %s", promptprog); - close(p[0]); - close(p[1]); - return 0; - } - if (!kid) { - /* we are the child, exec the program */ - char *argv[4], fdstr[32]; - sys_close(); - closelog(); - close(p[0]); - seteuid(getuid()); - setegid(getgid()); - argv[0] = promptprog; - argv[1] = user; - argv[2] = remote_name; - sprintf(fdstr, "%d", p[1]); - argv[3] = fdstr; - argv[4] = 0; - execv(*argv, argv); - _exit(127); - } - - /* we are the parent, read the password from the pipe */ - close(p[1]); - readgood = 0; - do { - red = read(p[0], passwd + readgood, MAXSECRETLEN-1 - readgood); - if (red == 0) - break; - if (red < 0) { - error("Can't read secret from %s: %m", promptprog); - readgood = -1; - break; - } - readgood += red; - } while (readgood < MAXSECRETLEN - 1); - passwd[readgood] = 0; - close(p[0]); - - /* now wait for child to exit */ - while (waitpid(kid, &wstat, 0) < 0) { - if (errno != EINTR) { - warn("error waiting for %s: %m", promptprog); - break; - } - } - - if (readgood < 0) - return 0; - if (!WIFEXITED(wstat)) - warn("%s terminated abnormally", promptprog); - if (WEXITSTATUS(wstat)) - warn("%s exited with code %d", promptprog, WEXITSTATUS(status)); - - return 1; -} - -void plugin_init(void) -{ - add_options(options); - pap_passwd_hook = promptpass; -} diff --git a/mdk-stage1/ppp/pppd/ppp.pam b/mdk-stage1/ppp/pppd/ppp.pam deleted file mode 100644 index 475a4bc88..000000000 --- a/mdk-stage1/ppp/pppd/ppp.pam +++ /dev/null @@ -1,6 +0,0 @@ -#%PAM-1.0 -# Information for the PPPD process with the 'login' option. -auth required pam_nologin.so -auth required pam_unix.so -account required pam_unix.so -session required pam_unix.so
\ No newline at end of file diff --git a/mdk-stage1/ppp/pppd/pppd.8 b/mdk-stage1/ppp/pppd/pppd.8 deleted file mode 100644 index ab091cd83..000000000 --- a/mdk-stage1/ppp/pppd/pppd.8 +++ /dev/null @@ -1,1591 +0,0 @@ -.\" manual page [] for pppd 2.4 -.\" $Id$ -.\" SH section heading -.\" SS subsection heading -.\" LP paragraph -.\" IP indented paragraph -.\" TP hanging label -.TH PPPD 8 -.SH NAME -pppd \- Point to Point Protocol daemon -.SH SYNOPSIS -.B pppd -[ -.I tty_name -] [ -.I speed -] [ -.I options -] -.SH DESCRIPTION -.LP -The Point-to-Point Protocol (PPP) provides a method for transmitting -datagrams over serial point-to-point links. PPP -is composed of three parts: a method for encapsulating datagrams over -serial links, an extensible Link Control Protocol (LCP), and -a family of Network Control Protocols (NCP) for establishing -and configuring different network-layer protocols. -.LP -The encapsulation scheme is provided by driver code in the kernel. -Pppd provides the basic LCP, authentication support, and an NCP for -establishing and configuring the Internet Protocol (IP) (called the IP -Control Protocol, IPCP). -.SH FREQUENTLY USED OPTIONS -.TP -.I <tty_name> -Communicate over the named device. The string "/dev/" is prepended if -necessary. If no device name is given, or if the name of the terminal -connected to the standard input is given, pppd will use that terminal, -and will not fork to put itself in the background. A value for this -option from a privileged source cannot be overridden by a -non-privileged user. -.TP -.I <speed> -Set the baud rate to <speed> (a decimal number). On systems such as -4.4BSD and NetBSD, any speed can be specified. Other systems -(e.g. SunOS) allow only a limited set of speeds. -.TP -.B asyncmap \fI<map> -Set the async character map to <map>. This map describes which -control characters cannot be successfully received over the serial -line. Pppd will ask the peer to send these characters as a 2-byte -escape sequence. The argument is a 32 bit hex number with each bit -representing a character to escape. Bit 0 (00000001) represents the -character 0x00; bit 31 (80000000) represents the character 0x1f or ^_. -If multiple \fIasyncmap\fR options are given, the values are ORed -together. If no \fIasyncmap\fR option is given, no async character -map will be negotiated for the receive direction; the peer should then -escape \fIall\fR control characters. To escape transmitted -characters, use the \fIescape\fR option. -.TP -.B auth -Require the peer to authenticate itself before allowing network -packets to be sent or received. This option is the default if the -system has a default route. If neither this option nor the -\fInoauth\fR option is specified, pppd will only allow the peer to use -IP addresses to which the system does not already have a route. -.TP -.B call \fIname -Read options from the file /etc/ppp/peers/\fIname\fR. This file may -contain privileged options, such as \fInoauth\fR, even if pppd -is not being run by root. The \fIname\fR string may not begin with / -or include .. as a pathname component. The format of the options file -is described below. -.TP -.B connect \fIscript -Use the executable or shell command specified by \fIscript\fR to set -up the serial line. This script would typically use the chat(8) -program to dial the modem and start the remote ppp session. A value -for this option from a privileged source cannot be overridden by a -non-privileged user. -.TP -.B crtscts -Use hardware flow control (i.e. RTS/CTS) to control the flow of -data on the serial port. If neither the \fIcrtscts\fR, the -\fInocrtscts\fR, the \fIcdtrcts\fR nor the \fInocdtrcts\fR option -is given, the hardware flow control setting for the serial port is -left unchanged. -Some serial ports (such as Macintosh serial ports) lack a true -RTS output. Such serial ports use this mode to implement -unidirectional flow control. The serial port will -suspend transmission when requested by the modem (via CTS) -but will be unable to request the modem stop sending to the -computer. This mode retains the ability to use DTR as -a modem control line. -.TP -.B defaultroute -Add a default route to the system routing tables, using the peer as -the gateway, when IPCP negotiation is successfully completed. -This entry is removed when the PPP connection is broken. This option -is privileged if the \fInodefaultroute\fR option has been specified. -.TP -.B disconnect \fIscript -Run the executable or shell command specified by \fIscript\fR after -pppd has terminated the link. This script could, for example, issue -commands to the modem to cause it to hang up if hardware modem control -signals were not available. The disconnect script is not run if the -modem has already hung up. A value for this option from a privileged -source cannot be overridden by a non-privileged user. -.TP -.B escape \fIxx,yy,... -Specifies that certain characters should be escaped on transmission -(regardless of whether the peer requests them to be escaped with its -async control character map). The characters to be escaped are -specified as a list of hex numbers separated by commas. Note that -almost any character can be specified for the \fIescape\fR option, -unlike the \fIasyncmap\fR option which only allows control characters -to be specified. The characters which may not be escaped are those -with hex values 0x20 - 0x3f or 0x5e. -.TP -.B file \fIname -Read options from file \fIname\fR (the format is described below). -The file must be readable by the user who has invoked pppd. -.TP -.B init \fIscript -Run the executable or shell command specified by \fIscript\fR to -initialize the serial line. This script would typically use the -chat(8) program to configure the modem to enable auto answer. A value -for this option from a privileged source cannot be overridden by a -non-privileged user. -.TP -.B lock -Specifies that pppd should create a UUCP-style lock file for the -serial device to ensure exclusive access to the device. -.TP -.B mru \fIn -Set the MRU [Maximum Receive Unit] value to \fIn\fR. Pppd -will ask the peer to send packets of no more than \fIn\fR bytes. The -minimum MRU value is 128. The default MRU value is 1500. A value of -296 is recommended for slow links (40 bytes for TCP/IP header + 256 -bytes of data). (Note that for IPv6 MRU must be at least 1280) -.TP -.B mtu \fIn -Set the MTU [Maximum Transmit Unit] value to \fIn\fR. Unless the -peer requests a smaller value via MRU negotiation, pppd will -request that the kernel networking code send data packets of no more -than \fIn\fR bytes through the PPP network interface. (Note that for -IPv6 MTU must be at least 1280) -.TP -.B passive -Enables the "passive" option in the LCP. With this option, pppd will -attempt to initiate a connection; if no reply is received from the -peer, pppd will then just wait passively for a valid LCP packet from -the peer, instead of exiting, as it would without this option. -.SH OPTIONS -.TP -.I <local_IP_address>\fB:\fI<remote_IP_address> -Set the local and/or remote interface IP addresses. Either one may be -omitted. The IP addresses can be specified with a host name or in -decimal dot notation (e.g. 150.234.56.78). The default local -address is the (first) IP address of the system (unless the -\fInoipdefault\fR -option is given). The remote address will be obtained from the peer -if not specified in any option. Thus, in simple cases, this option is -not required. If a local and/or remote IP address is specified with -this option, pppd -will not accept a different value from the peer in the IPCP -negotiation, unless the \fIipcp-accept-local\fR and/or -\fIipcp-accept-remote\fR options are given, respectively. -.TP -.B ipv6 \fI<local_interface_identifier>\fR,\fI<remote_interface_identifier> -Set the local and/or remote 64-bit interface identifier. Either one may be -omitted. The identifier must be specified in standard ascii notation of -IPv6 addresses (e.g. ::dead:beef). If the -\fIipv6cp-use-ipaddr\fR -option is given, the local identifier is the local IPv4 address (see above). -On systems which supports a unique persistent id, such as EUI-48 derived -from the Ethernet MAC address, \fIipv6cp-use-persistent\fR option can be -used to replace the \fIipv6 <local>,<remote>\fR option. Otherwise the -identifier is randomized. -.TP -.B active-filter \fIfilter-expression -Specifies a packet filter to be applied to data packets to determine -which packets are to be regarded as link activity, and therefore reset -the idle timer, or cause the link to be brought up in demand-dialling -mode. This option is useful in conjunction with the -\fBidle\fR option if there are packets being sent or received -regularly over the link (for example, routing information packets) -which would otherwise prevent the link from ever appearing to be idle. -The \fIfilter-expression\fR syntax is as described for tcpdump(1), -except that qualifiers which are inappropriate for a PPP link, such as -\fBether\fR and \fBarp\fR, are not permitted. Generally the filter -expression should be enclosed in single-quotes to prevent whitespace -in the expression from being interpreted by the shell. This option -is currently only available under NetBSD, and then only -if both the kernel and pppd were compiled with PPP_FILTER defined. -.TP -.B allow-ip \fIaddress(es) -Allow peers to use the given IP address or subnet without -authenticating themselves. The parameter is parsed as for each -element of the list of allowed IP addresses in the secrets files (see -the AUTHENTICATION section below). -.TP -.B bsdcomp \fInr,nt -Request that the peer compress packets that it sends, using the -BSD-Compress scheme, with a maximum code size of \fInr\fR bits, and -agree to compress packets sent to the peer with a maximum code size of -\fInt\fR bits. If \fInt\fR is not specified, it defaults to the value -given for \fInr\fR. Values in the range 9 to 15 may be used for -\fInr\fR and \fInt\fR; larger values give better compression but -consume more kernel memory for compression dictionaries. -Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables -compression in the corresponding direction. Use \fInobsdcomp\fR or -\fIbsdcomp 0\fR to disable BSD-Compress compression entirely. -.TP -.B cdtrcts -Use a non-standard hardware flow control (i.e. DTR/CTS) to control -the flow of data on the serial port. If neither the \fIcrtscts\fR, -the \fInocrtscts\fR, the \fIcdtrcts\fR nor the \fInocdtrcts\fR -option is given, the hardware flow control setting for the serial -port is left unchanged. -Some serial ports (such as Macintosh serial ports) lack a true -RTS output. Such serial ports use this mode to implement true -bi-directional flow control. The sacrifice is that this flow -control mode does not permit using DTR as a modem control line. -.TP -.B chap-interval \fIn -If this option is given, pppd will rechallenge the peer every \fIn\fR -seconds. -.TP -.B chap-max-challenge \fIn -Set the maximum number of CHAP challenge transmissions to \fIn\fR -(default 10). -.TP -.B chap-restart \fIn -Set the CHAP restart interval (retransmission timeout for challenges) -to \fIn\fR seconds (default 3). -.TP -.B connect-delay \fIn -Wait for up \fIn\fR milliseconds after the connect script finishes for -a valid PPP packet from the peer. At the end of this time, or when a -valid PPP packet is received from the peer, pppd will commence -negotiation by sending its first LCP packet. The default value is -1000 (1 second). This wait period only applies if the \fBconnect\fR -or \fBpty\fR option is used. -.TP -.B debug -Enables connection debugging facilities. -If this option is given, pppd will log the contents of all -control packets sent or received in a readable form. The packets are -logged through syslog with facility \fIdaemon\fR and level -\fIdebug\fR. This information can be directed to a file by setting up -/etc/syslog.conf appropriately (see syslog.conf(5)). -.TP -.B default-asyncmap -Disable asyncmap negotiation, forcing all control characters to be -escaped for both the transmit and the receive direction. -.TP -.B default-mru -Disable MRU [Maximum Receive Unit] negotiation. With this option, -pppd will use the default MRU value of 1500 bytes for both the -transmit and receive direction. -.TP -.B deflate \fInr,nt -Request that the peer compress packets that it sends, using the -Deflate scheme, with a maximum window size of \fI2**nr\fR bytes, and -agree to compress packets sent to the peer with a maximum window size -of \fI2**nt\fR bytes. If \fInt\fR is not specified, it defaults to -the value given for \fInr\fR. Values in the range 9 to 15 may be used -for \fInr\fR and \fInt\fR; larger values give better compression but -consume more kernel memory for compression dictionaries. -Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables -compression in the corresponding direction. Use \fInodeflate\fR or -\fIdeflate 0\fR to disable Deflate compression entirely. (Note: pppd -requests Deflate compression in preference to BSD-Compress if the peer -can do either.) -.TP -.B demand -Initiate the link only on demand, i.e. when data traffic is present. -With this option, the remote IP address must be specified by the user -on the command line or in an options file. Pppd will initially -configure the interface and enable it for IP traffic without -connecting to the peer. When traffic is available, pppd will -connect to the peer and perform negotiation, authentication, etc. -When this is completed, pppd will commence passing data packets -(i.e., IP packets) across the link. - -The \fIdemand\fR option implies the \fIpersist\fR option. If this -behaviour is not desired, use the \fInopersist\fR option after the -\fIdemand\fR option. The \fIidle\fR and \fIholdoff\fR -options are also useful in conjuction with the \fIdemand\fR option. -.TP -.B domain \fId -Append the domain name \fId\fR to the local host name for authentication -purposes. For example, if gethostname() returns the name porsche, but -the fully qualified domain name is porsche.Quotron.COM, you could -specify \fIdomain Quotron.COM\fR. Pppd would then use the name -\fIporsche.Quotron.COM\fR for looking up secrets in the secrets file, -and as the default name to send to the peer when authenticating itself -to the peer. This option is privileged. -.TP -.B dryrun -With the \fBdryrun\fR option, pppd will print out all the option -values which have been set and then exit, after parsing the command -line and options files and checking the option values, but before -initiating the link. The option values are logged at level info, and -also printed to standard output unless the device on standard output -is the device that pppd would be using to communicate with the peer. -.TP -.B dump -With the \fBdump\fR option, pppd will print out all the option values -which have been set. This option is like the \fBdryrun\fR option -except that pppd proceeds as normal rather than exiting. -.TP -.B endpoint \fI<epdisc> -Sets the endpoint discriminator sent by the local machine to the peer -during multilink negotiation to \fI<epdisc>\fR. The default is to use -the MAC address of the first ethernet interface on the system, if any, -otherwise the IPv4 address corresponding to the hostname, if any, -provided it is not in the multicast or locally-assigned IP address -ranges, or the localhost address. The endpoint discriminator can be -the string \fBnull\fR or of the form \fItype\fR:\fIvalue\fR, where -type is a decimal number or one of the strings \fBlocal\fR, \fBIP\fR, -\fBMAC\fR, \fBmagic\fR, or \fBphone\fR. The value is an IP address in -dotted-decimal notation for the \fBIP\fR type, or a string of bytes in -hexadecimal, separated by periods or colons for the other types. For -the MAC type, the value may also be the name of an ethernet or similar -network interface. This option is currently only available under -Linux. -.TP -.B hide-password -When logging the contents of PAP packets, this option causes pppd to -exclude the password string from the log. This is the default. -.TP -.B holdoff \fIn -Specifies how many seconds to wait before re-initiating the link after -it terminates. This option only has any effect if the \fIpersist\fR -or \fIdemand\fR option is used. The holdoff period is not applied if -the link was terminated because it was idle. -.TP -.B idle \fIn -Specifies that pppd should disconnect if the link is idle for \fIn\fR -seconds. The link is idle when no data packets (i.e. IP packets) are -being sent or received. Note: it is not advisable to use this option -with the \fIpersist\fR option without the \fIdemand\fR option. -If the \fBactive-filter\fR -option is given, data packets which are rejected by the specified -activity filter also count as the link being idle. -.TP -.B ipcp-accept-local -With this option, pppd will accept the peer's idea of our local IP -address, even if the local IP address was specified in an option. -.TP -.B ipcp-accept-remote -With this option, pppd will accept the peer's idea of its (remote) IP -address, even if the remote IP address was specified in an option. -.TP -.B ipcp-max-configure \fIn -Set the maximum number of IPCP configure-request transmissions to -\fIn\fR (default 10). -.TP -.B ipcp-max-failure \fIn -Set the maximum number of IPCP configure-NAKs returned before starting -to send configure-Rejects instead to \fIn\fR (default 10). -.TP -.B ipcp-max-terminate \fIn -Set the maximum number of IPCP terminate-request transmissions to -\fIn\fR (default 3). -.TP -.B ipcp-restart \fIn -Set the IPCP restart interval (retransmission timeout) to \fIn\fR -seconds (default 3). -.TP -.B ipparam \fIstring -Provides an extra parameter to the ip-up and ip-down scripts. If this -option is given, the \fIstring\fR supplied is given as the 6th -parameter to those scripts. -.TP -.B ipv6cp-max-configure \fIn -Set the maximum number of IPv6CP configure-request transmissions to -\fIn\fR (default 10). -.TP -.B ipv6cp-max-failure \fIn -Set the maximum number of IPv6CP configure-NAKs returned before starting -to send configure-Rejects instead to \fIn\fR (default 10). -.TP -.B ipv6cp-max-terminate \fIn -Set the maximum number of IPv6CP terminate-request transmissions to -\fIn\fR (default 3). -.TP -.B ipv6cp-restart \fIn -Set the IPv6CP restart interval (retransmission timeout) to \fIn\fR -seconds (default 3). -.TP -.B ipx -Enable the IPXCP and IPX protocols. This option is presently only -supported under Linux, and only if your kernel has been configured to -include IPX support. -.TP -.B ipx-network \fIn -Set the IPX network number in the IPXCP configure request frame to -\fIn\fR, a hexadecimal number (without a leading 0x). There is no -valid default. If this option is not specified, the network number is -obtained from the peer. If the peer does not have the network number, -the IPX protocol will not be started. -.TP -.B ipx-node \fIn\fB:\fIm -Set the IPX node numbers. The two node numbers are separated from each -other with a colon character. The first number \fIn\fR is the local -node number. The second number \fIm\fR is the peer's node number. Each -node number is a hexadecimal number, at most 10 digits long. The node -numbers on the ipx-network must be unique. There is no valid -default. If this option is not specified then the node numbers are -obtained from the peer. -.TP -.B ipx-router-name \fI<string> -Set the name of the router. This is a string and is sent to the peer -as information data. -.TP -.B ipx-routing \fIn -Set the routing protocol to be received by this option. More than one -instance of \fIipx-routing\fR may be specified. The '\fInone\fR' -option (0) may be specified as the only instance of ipx-routing. The -values may be \fI0\fR for \fINONE\fR, \fI2\fR for \fIRIP/SAP\fR, and -\fI4\fR for \fINLSP\fR. -.TP -.B ipxcp-accept-local -Accept the peer's NAK for the node number specified in the ipx-node -option. If a node number was specified, and non-zero, the default is -to insist that the value be used. If you include this option then you -will permit the peer to override the entry of the node number. -.TP -.B ipxcp-accept-network -Accept the peer's NAK for the network number specified in the -ipx-network option. If a network number was specified, and non-zero, the -default is to insist that the value be used. If you include this -option then you will permit the peer to override the entry of the node -number. -.TP -.B ipxcp-accept-remote -Use the peer's network number specified in the configure request -frame. If a node number was specified for the peer and this option was -not specified, the peer will be forced to use the value which you have -specified. -.TP -.B ipxcp-max-configure \fIn -Set the maximum number of IPXCP configure request frames which the -system will send to \fIn\fR. The default is 10. -.TP -.B ipxcp-max-failure \fIn -Set the maximum number of IPXCP NAK frames which the local system will -send before it rejects the options. The default value is 3. -.TP -.B ipxcp-max-terminate \fIn -Set the maximum nuber of IPXCP terminate request frames before the -local system considers that the peer is not listening to them. The -default value is 3. -.TP -.B kdebug \fIn -Enable debugging code in the kernel-level PPP driver. The argument -values depend on the specific kernel driver, but in general a value of -1 will enable general kernel debug messages. (Note that these -messages are usually only useful for debugging the kernel driver -itself.) For the Linux 2.2.x kernel driver, the value is a sum of -bits: 1 to -enable general debug messages, 2 to request that the contents of -received packets be printed, and 4 to request that the contents of -transmitted packets be printed. On most systems, messages printed by -the kernel are logged by syslog(1) to a file as directed in the -/etc/syslog.conf configuration file. -.TP -.B ktune -Enables pppd to alter kernel settings as appropriate. Under Linux, -pppd will enable IP forwarding (i.e. set /proc/sys/net/ipv4/ip_forward -to 1) if the \fIproxyarp\fR option is used, and will enable the -dynamic IP address option (i.e. set /proc/sys/net/ipv4/ip_dynaddr to -1) in demand mode if the local address changes. -.TP -.B lcp-echo-failure \fIn -If this option is given, pppd will presume the peer to be dead -if \fIn\fR LCP echo-requests are sent without receiving a valid LCP -echo-reply. If this happens, pppd will terminate the -connection. Use of this option requires a non-zero value for the -\fIlcp-echo-interval\fR parameter. This option can be used to enable -pppd to terminate after the physical connection has been broken -(e.g., the modem has hung up) in situations where no hardware modem -control lines are available. -.TP -.B lcp-echo-interval \fIn -If this option is given, pppd will send an LCP echo-request frame to -the peer every \fIn\fR seconds. Normally the peer should respond to -the echo-request by sending an echo-reply. This option can be used -with the \fIlcp-echo-failure\fR option to detect that the peer is no -longer connected. -.TP -.B lcp-max-configure \fIn -Set the maximum number of LCP configure-request transmissions to -\fIn\fR (default 10). -.TP -.B lcp-max-failure \fIn -Set the maximum number of LCP configure-NAKs returned before starting -to send configure-Rejects instead to \fIn\fR (default 10). -.TP -.B lcp-max-terminate \fIn -Set the maximum number of LCP terminate-request transmissions to -\fIn\fR (default 3). -.TP -.B lcp-restart \fIn -Set the LCP restart interval (retransmission timeout) to \fIn\fR -seconds (default 3). -.TP -.B linkname \fIname\fR -Sets the logical name of the link to \fIname\fR. Pppd will create a -file named \fBppp-\fIname\fB.pid\fR in /var/run (or /etc/ppp on some -systems) containing its process ID. This can be useful in determining -which instance of pppd is responsible for the link to a given peer -system. This is a privileged option. -.TP -.B local -Don't use the modem control lines. With this option, pppd will ignore -the state of the CD (Carrier Detect) signal from the modem and will -not change the state of the DTR (Data Terminal Ready) signal. -.TP -.B logfd \fIn -Send log messages to file descriptor \fIn\fR. Pppd will send log -messages to at most one file or file descriptor (as well as sending -the log messages to syslog), so this option and the \fBlogfile\fR -option are mutually exclusive. The default is for pppd to send log -messages to stdout (file descriptor 1), unless the serial port is -already open on stdout. -.TP -.B logfile \fIfilename -Append log messages to the file \fIfilename\fR (as well as sending the -log messages to syslog). The file is opened with the privileges of -the user who invoked pppd, in append mode. -.TP -.B login -Use the system password database for authenticating the peer using -PAP, and record the user in the system wtmp file. Note that the peer -must have an entry in the /etc/ppp/pap-secrets file as well as the -system password database to be allowed access. -.TP -.B maxconnect \fIn -Terminate the connection when it has been available for network -traffic for \fIn\fR seconds (i.e. \fIn\fR seconds after the first -network control protocol comes up). -.TP -.B maxfail \fIn -Terminate after \fIn\fR consecutive failed connection attempts. A -value of 0 means no limit. The default value is 10. -.TP -.B modem -Use the modem control lines. This option is the default. With this -option, pppd will wait for the CD (Carrier Detect) signal from the -modem to be asserted when opening the serial device (unless a connect -script is specified), and it will drop the DTR (Data Terminal Ready) -signal briefly when the connection is terminated and before executing -the connect script. On Ultrix, this option implies hardware flow -control, as for the \fIcrtscts\fR option. -.TP -.B mp -Enables the use of PPP multilink; this is an alias for the `multilink' -option. This option is currently only available under Linux. -.TP -.B mpshortseq -Enables the use of short (12-bit) sequence numbers in multilink -headers, as opposed to 24-bit sequence numbers. This option is only -available under Linux, and only has any effect if multilink is -enabled (see the multilink option). -.TP -.B mrru \fIn -Sets the Maximum Reconstructed Receive Unit to \fIn\fR. The MRRU is -the maximum size for a received packet on a multilink bundle, and is -analogous to the MRU for the individual links. This option is -currently only available under Linux, and only has any effect if -multilink is enabled (see the multilink option). -.TP -.B ms-dns \fI<addr> -If pppd is acting as a server for Microsoft Windows clients, this -option allows pppd to supply one or two DNS (Domain Name Server) -addresses to the clients. The first instance of this option specifies -the primary DNS address; the second instance (if given) specifies the -secondary DNS address. (This option was present in some older -versions of pppd under the name \fBdns-addr\fR.) -.TP -.B ms-wins \fI<addr> -If pppd is acting as a server for Microsoft Windows or "Samba" -clients, this option allows pppd to supply one or two WINS (Windows -Internet Name Services) server addresses to the clients. The first -instance of this option specifies the primary WINS address; the second -instance (if given) specifies the secondary WINS address. -.TP -.B multilink -Enables the use of the PPP multilink protocol. If the peer also -supports multilink, then this link can become part of a bundle between -the local system and the peer. If there is an existing bundle to the -peer, pppd will join this link to that bundle, otherwise pppd will -create a new bundle. See the MULTILINK section below. This option is -currently only available under Linux. -.TP -.B name \fIname -Set the name of the local system for authentication purposes to -\fIname\fR. This is a privileged option. With this option, pppd will -use lines in the secrets files which have \fIname\fR as the second -field when looking for a secret to use in authenticating the peer. In -addition, unless overridden with the \fIuser\fR option, \fIname\fR -will be used as the name to send to the peer when authenticating the -local system to the peer. (Note that pppd does not append the domain -name to \fIname\fR.) -.TP -.B netmask \fIn -Set the interface netmask to \fIn\fR, a 32 bit netmask in "decimal dot" -notation (e.g. 255.255.255.0). If this option is given, the value -specified is ORed with the default netmask. The default netmask is -chosen based on the negotiated remote IP address; it is the -appropriate network mask for the class of the remote IP address, ORed -with the netmasks for any non point-to-point network interfaces in the -system which are on the same network. (Note: on some platforms, pppd -will always use 255.255.255.255 for the netmask, if that is the only -appropriate value for a point-to-point interface.) -.TP -.B noaccomp -Disable Address/Control compression in both directions (send and -receive). -.TP -.B noauth -Do not require the peer to authenticate itself. This option is -privileged. -.TP -.B nobsdcomp -Disables BSD-Compress compression; \fBpppd\fR will not request or -agree to compress packets using the BSD-Compress scheme. -.TP -.B noccp -Disable CCP (Compression Control Protocol) negotiation. This option -should only be required if the peer is buggy and gets confused by -requests from pppd for CCP negotiation. -.TP -.B nocrtscts -Disable hardware flow control (i.e. RTS/CTS) on the serial port. -If neither the \fIcrtscts\fR nor the \fInocrtscts\fR nor the -\fIcdtrcts\fR nor the \fInocdtrcts\fR option is given, the hardware -flow control setting for the serial port is left unchanged. -.TP -.B nocdtrcts -This option is a synonym for \fInocrtscts\fR. Either of these options will -disable both forms of hardware flow control. -.TP -.B nodefaultroute -Disable the \fIdefaultroute\fR option. The system administrator who -wishes to prevent users from creating default routes with pppd -can do so by placing this option in the /etc/ppp/options file. -.TP -.B nodeflate -Disables Deflate compression; pppd will not request or agree to -compress packets using the Deflate scheme. -.TP -.B nodetach -Don't detach from the controlling terminal. Without this option, if a -serial device other than the terminal on the standard input is -specified, pppd will fork to become a background process. -.TP -.B noendpoint -Disables pppd from sending an endpoint discriminator to the peer or -accepting one from the peer (see the MULTILINK section below). This -option should only be required if the peer is buggy. -.TP -.B noip -Disable IPCP negotiation and IP communication. This option should -only be required if the peer is buggy and gets confused by requests -from pppd for IPCP negotiation. -.TP -.B noipv6 -Disable IPv6CP negotiation and IPv6 communication. This option should -only be required if the peer is buggy and gets confused by requests -from pppd for IPv6CP negotiation. -.TP -.B noipdefault -Disables the default behaviour when no local IP address is specified, -which is to determine (if possible) the local IP address from the -hostname. With this option, the peer will have to supply the local IP -address during IPCP negotiation (unless it specified explicitly on the -command line or in an options file). -.TP -.B noipx -Disable the IPXCP and IPX protocols. This option should only be -required if the peer is buggy and gets confused by requests from pppd -for IPXCP negotiation. -.TP -.B noktune -Opposite of the \fIktune\fR option; disables pppd from changing system -settings. -.TP -.B nolog -Do not send log messages to a file or file descriptor. This option -cancels the \fBlogfd\fR and \fBlogfile\fR options. -.TP -.B nomagic -Disable magic number negotiation. With this option, pppd cannot -detect a looped-back line. This option should only be needed if the -peer is buggy. -.TP -.B nomp -Disables the use of PPP multilink. This option is currently only -available under Linux. -.TP -.B nompshortseq -Disables the use of short (12-bit) sequence numbers in the PPP -multilink protocol, forcing the use of 24-bit sequence numbers. This -option is currently only available under Linux, and only has any -effect if multilink is enabled. -.TP -.B nomultilink -Disables the use of PPP multilink. This option is currently only -available under Linux. -.TP -.B nopcomp -Disable protocol field compression negotiation in both the receive and -the transmit direction. -.TP -.B nopersist -Exit once a connection has been made and terminated. This is the -default unless the \fIpersist\fR or \fIdemand\fR option has been -specified. -.TP -.B nopredictor1 -Do not accept or agree to Predictor-1 compression. -.TP -.B noproxyarp -Disable the \fIproxyarp\fR option. The system administrator who -wishes to prevent users from creating proxy ARP entries with pppd can -do so by placing this option in the /etc/ppp/options file. -.TP -.B notty -Normally, pppd requires a terminal device. With this option, pppd -will allocate itself a pseudo-tty master/slave pair and use the slave -as its terminal device. Pppd will create a child process to act as a -`character shunt' to transfer characters between the pseudo-tty master -and its standard input and output. Thus pppd will transmit characters -on its standard output and receive characters on its standard input -even if they are not terminal devices. This option increases the -latency and CPU overhead of transferring data over the ppp interface -as all of the characters sent and received must flow through the -character shunt process. An explicit device name may not be given if -this option is used. -.TP -.B novj -Disable Van Jacobson style TCP/IP header compression in both the -transmit and the receive direction. -.TP -.B novjccomp -Disable the connection-ID compression option in Van Jacobson style -TCP/IP header compression. With this option, pppd will not omit the -connection-ID byte from Van Jacobson compressed TCP/IP headers, nor -ask the peer to do so. -.TP -.B papcrypt -Indicates that all secrets in the /etc/ppp/pap-secrets file which are -used for checking the identity of the peer are encrypted, and thus -pppd should not accept a password which, before encryption, is -identical to the secret from the /etc/ppp/pap-secrets file. -.TP -.B pap-max-authreq \fIn -Set the maximum number of PAP authenticate-request transmissions to -\fIn\fR (default 10). -.TP -.B pap-restart \fIn -Set the PAP restart interval (retransmission timeout) to \fIn\fR -seconds (default 3). -.TP -.B pap-timeout \fIn -Set the maximum time that pppd will wait for the peer to authenticate -itself with PAP to \fIn\fR seconds (0 means no limit). -.TP -.B pass-filter \fIfilter-expression -Specifies a packet filter to applied to data packets being sent or -received to determine which packets should be allowed to pass. -Packets which are rejected by the filter are silently discarded. This -option can be used to prevent specific network daemons (such as -routed) using up link bandwidth, or to provide a basic firewall -capability. -The \fIfilter-expression\fR syntax is as described for tcpdump(1), -except that qualifiers which are inappropriate for a PPP link, such as -\fBether\fR and \fBarp\fR, are not permitted. Generally the filter -expression should be enclosed in single-quotes to prevent whitespace -in the expression from being interpreted by the shell. Note that it -is possible to apply different constraints to incoming and outgoing -packets using the \fBinbound\fR and \fBoutbound\fR qualifiers. This -option is currently only available under NetBSD, and then only if both -the kernel and pppd were compiled with PPP_FILTER defined. -.TP -.B persist -Do not exit after a connection is terminated; instead try to reopen -the connection. -.TP -.B plugin \fIfilename -Load the shared library object file \fIfilename\fR as a plugin. This -is a privileged option. -.TP -.B predictor1 -Request that the peer compress frames that it sends using Predictor-1 -compression, and agree to compress transmitted frames with Predictor-1 -if requested. This option has no effect unless the kernel driver -supports Predictor-1 compression. -.TP -.B privgroup \fIgroup-name -Allows members of group \fIgroup-name\fR to use privileged options. -This is a privileged option. Use of this option requires care as -there is no guarantee that members of \fIgroup-name\fR cannot use pppd -to become root themselves. Consider it equivalent to putting the -members of \fIgroup-name\fR in the kmem or disk group. -.TP -.B proxyarp -Add an entry to this system's ARP [Address Resolution Protocol] table -with the IP address of the peer and the Ethernet address of this -system. This will have the effect of making the peer appear to other -systems to be on the local ethernet. -.TP -.B pty \fIscript -Specifies that the command \fIscript\fR is to be used to communicate -rather than a specific terminal device. Pppd will allocate itself a -pseudo-tty master/slave pair and use the slave as its terminal -device. The \fIscript\fR will be run in a child process with the -pseudo-tty master as its standard input and output. An explicit -device name may not be given if this option is used. (Note: if the -\fIrecord\fR option is used in conjuction with the \fIpty\fR option, -the child process will have pipes on its standard input and output.) -.TP -.B receive-all -With this option, pppd will accept all control characters from the -peer, including those marked in the receive asyncmap. Without this -option, pppd will discard those characters as specified in RFC1662. -This option should only be needed if the peer is buggy. -.TP -.B record \fIfilename -Specifies that pppd should record all characters sent and received to -a file named \fIfilename\fR. This file is opened in append mode, -using the user's user-ID and permissions. This option is implemented -using a pseudo-tty and a process to transfer characters between the -pseudo-tty and the real serial device, so it will increase the latency -and CPU overhead of transferring data over the ppp interface. The -characters are stored in a tagged format with timestamps, which can be -displayed in readable form using the pppdump(8) program. -.TP -.B remotename \fIname -Set the assumed name of the remote system for authentication purposes -to \fIname\fR. -.TP -.B refuse-chap -With this option, pppd will not agree to authenticate itself to the -peer using CHAP. -.TP -.B refuse-pap -With this option, pppd will not agree to authenticate itself to the -peer using PAP. -.TP -.B require-chap -Require the peer to authenticate itself using CHAP [Challenge -Handshake Authentication Protocol] authentication. -.TP -.B require-pap -Require the peer to authenticate itself using PAP [Password -Authentication Protocol] authentication. -.TP -.B show-password -When logging the contents of PAP packets, this option causes pppd to -show the password string in the log message. -.TP -.B silent -With this option, pppd will not transmit LCP packets to initiate a -connection until a valid LCP packet is received from the peer (as for -the `passive' option with ancient versions of pppd). -.TP -.B sync -Use synchronous HDLC serial encoding instead of asynchronous. -The device used by pppd with this option must have sync support. -Currently supports Microgate SyncLink adapters -under Linux and FreeBSD 2.2.8 and later. -.TP -.B updetach -With this option, pppd will detach from its controlling terminal once -it has successfully established the ppp connection (to the point where -the first network control protocol, usually the IP control protocol, -has come up). -.TP -.B usehostname -Enforce the use of the hostname (with domain name appended, if given) -as the name of the local system for authentication purposes (overrides -the \fIname\fR option). This option is not normally needed since the -\fIname\fR option is privileged. -.TP -.B usepeerdns -Ask the peer for up to 2 DNS server addresses. The addresses supplied -by the peer (if any) are passed to the /etc/ppp/ip-up script in the -environment variables DNS1 and DNS2. In addition, pppd will create an -/etc/ppp/resolv.conf file containing one or two nameserver lines with -the address(es) supplied by the peer. -.TP -.B user \fIname -Sets the name used for authenticating the local system to the peer to -\fIname\fR. -.TP -.B vj-max-slots \fIn -Sets the number of connection slots to be used by the Van Jacobson -TCP/IP header compression and decompression code to \fIn\fR, which -must be between 2 and 16 (inclusive). -.TP -.B welcome \fIscript -Run the executable or shell command specified by \fIscript\fR before -initiating PPP negotiation, after the connect script (if any) has -completed. A value for this option from a privileged source cannot be -overridden by a non-privileged user. -.TP -.B xonxoff -Use software flow control (i.e. XON/XOFF) to control the flow of data on -the serial port. -.SH OPTIONS FILES -Options can be taken from files as well as the command line. Pppd -reads options from the files /etc/ppp/options, ~/.ppprc and -/etc/ppp/options.\fIttyname\fR (in that order) before processing the -options on the command line. (In fact, the command-line options are -scanned to find the terminal name before the options.\fIttyname\fR -file is read.) In forming the name of the options.\fIttyname\fR file, -the initial /dev/ is removed from the terminal name, and any remaining -/ characters are replaced with dots. -.PP -An options file is parsed into a series of words, delimited by -whitespace. Whitespace can be included in a word by enclosing the -word in double-quotes ("). A backslash (\\) quotes the following character. -A hash (#) starts a comment, which continues until the end of the -line. There is no restriction on using the \fIfile\fR or \fIcall\fR -options within an options file. -.SH SECURITY -.I pppd -provides system administrators with sufficient access control that PPP -access to a server machine can be provided to legitimate users without -fear of compromising the security of the server or the network it's -on. This control is provided through restrictions on which IP -addresses the peer may use, based on its authenticated identity (if -any), and through restrictions on which options a non-privileged user -may use. Several of pppd's options are privileged, in particular -those which permit potentially insecure configurations; these options -are only accepted in files which are under the control of the system -administrator, or if pppd is being run by root. -.PP -The default behaviour of pppd is to allow an unauthenticated peer to -use a given IP address only if the system does not already have a -route to that IP address. For example, a system with a -permanent connection to the wider internet will normally have a -default route, and thus all peers will have to authenticate themselves -in order to set up a connection. On such a system, the \fIauth\fR -option is the default. On the other hand, a system where the -PPP link is the only connection to the internet will not normally have -a default route, so the peer will be able to use almost any IP address -without authenticating itself. -.PP -As indicated above, some security-sensitive options are privileged, -which means that they may not be used by an ordinary non-privileged -user running a setuid-root pppd, either on the command line, in the -user's ~/.ppprc file, or in an options file read using the \fIfile\fR -option. Privileged options may be used in /etc/ppp/options file or in -an options file read using the \fIcall\fR option. If pppd is being -run by the root user, privileged options can be used without -restriction. -.PP -When opening the device, pppd uses either the invoking user's user ID -or the root UID (that is, 0), depending on whether the device name was -specified by the user or the system administrator. If the device name -comes from a privileged source, that is, /etc/ppp/options or an -options file read using the \fIcall\fR option, pppd uses full root -privileges when opening the device. Thus, by creating an appropriate -file under /etc/ppp/peers, the system administrator can allow users to -establish a ppp connection via a device which they would not normally -have permission to access. Otherwise pppd uses the invoking user's -real UID when opening the device. -.SH AUTHENTICATION -Authentication is the process whereby one peer convinces the other of -its identity. This involves the first peer sending its name to the -other, together with some kind of secret information which could only -come from the genuine authorized user of that name. In such an -exchange, we will call the first peer the "client" and the other the -"server". The client has a name by which it identifies itself to the -server, and the server also has a name by which it identifies itself -to the client. Generally the genuine client shares some secret (or -password) with the server, and authenticates itself by proving that it -knows that secret. Very often, the names used for authentication -correspond to the internet hostnames of the peers, but this is not -essential. -.LP -At present, pppd supports two authentication protocols: the Password -Authentication Protocol (PAP) and the Challenge Handshake -Authentication Protocol (CHAP). PAP involves the client sending its -name and a cleartext password to the server to authenticate itself. -In contrast, the server initiates the CHAP authentication exchange by -sending a challenge to the client (the challenge packet includes the -server's name). The client must respond with a response which -includes its name plus a hash value derived from the shared secret and -the challenge, in order to prove that it knows the secret. -.LP -The PPP protocol, being symmetrical, allows both peers to require the -other to authenticate itself. In that case, two separate and -independent authentication exchanges will occur. The two exchanges -could use different authentication protocols, and in principle, -different names could be used in the two exchanges. -.LP -The default behaviour of pppd is to agree to authenticate if -requested, and to not require authentication from the peer. However, -pppd will not agree to authenticate itself with a particular protocol -if it has no secrets which could be used to do so. -.LP -Pppd stores secrets for use in authentication in secrets -files (/etc/ppp/pap-secrets for PAP, /etc/ppp/chap-secrets for CHAP). -Both secrets files have the same format. The secrets files can -contain secrets for pppd to use in authenticating itself to other -systems, as well as secrets for pppd to use when authenticating other -systems to itself. -.LP -Each line in a secrets file contains one secret. A given secret is -specific to a particular combination of client and server - it can -only be used by that client to authenticate itself to that server. -Thus each line in a secrets file has at least 3 fields: the name of -the client, the name of the server, and the secret. These fields may -be followed by a list of the IP addresses that the specified client -may use when connecting to the specified server. -.LP -A secrets file is parsed into words as for a options file, so the -client name, server name and secrets fields must each be one word, -with any embedded spaces or other special characters quoted or -escaped. Note that case is significant in the client and server names -and in the secret. -.LP -If the secret starts with an `@', what follows is assumed to be the -name of a file from which to read the secret. A "*" as the client or -server name matches any name. When selecting a secret, pppd takes the -best match, i.e. the match with the fewest wildcards. -.LP -Any following words on the same line are taken to be a list of -acceptable IP addresses for that client. If there are only 3 words on -the line, or if the first word is "-", then all IP addresses are -disallowed. To allow any address, use "*". A word starting with "!" -indicates that the specified address is \fInot\fR acceptable. An -address may be followed by "/" and a number \fIn\fR, to indicate a -whole subnet, i.e. all addresses which have the same value in the most -significant \fIn\fR bits. In this form, the address may be followed -by a plus sign ("+") to indicate that one address from the subnet is -authorized, based on the ppp network interface unit number in use. -In this case, the host part of the address will be set to the unit -number plus one. -.LP -Thus a secrets file contains both secrets for use in authenticating -other hosts, plus secrets which we use for authenticating ourselves to -others. When pppd is authenticating the peer (checking the peer's -identity), it chooses a secret with the peer's name in the first -field and the name of the local system in the second field. The -name of the local system defaults to the hostname, with the domain -name appended if the \fIdomain\fR option is used. This default can be -overridden with the \fIname\fR option, except when the -\fIusehostname\fR option is used. -.LP -When pppd is choosing a secret to use in authenticating itself to the -peer, it first determines what name it is going to use to identify -itself to the peer. This name can be specified by the user with the -\fIuser\fR option. If this option is not used, the name defaults to -the name of the local system, determined as described in the previous -paragraph. Then pppd looks for a secret with this name in the first -field and the peer's name in the second field. Pppd will know the -name of the peer if CHAP authentication is being used, because the -peer will have sent it in the challenge packet. However, if PAP is being -used, pppd will have to determine the peer's name from the options -specified by the user. The user can specify the peer's name directly -with the \fIremotename\fR option. Otherwise, if the remote IP address -was specified by a name (rather than in numeric form), that name will -be used as the peer's name. Failing that, pppd will use the null -string as the peer's name. -.LP -When authenticating the peer with PAP, the supplied password is first -compared with the secret from the secrets file. If the password -doesn't match the secret, the password is encrypted using crypt() and -checked against the secret again. Thus secrets for authenticating the -peer can be stored in encrypted form if desired. If the -\fIpapcrypt\fR option is given, the first (unencrypted) comparison is -omitted, for better security. -.LP -Furthermore, if the \fIlogin\fR option was specified, the username and -password are also checked against the system password database. Thus, -the system administrator can set up the pap-secrets file to allow PPP -access only to certain users, and to restrict the set of IP addresses -that each user can use. Typically, when using the \fIlogin\fR option, -the secret in /etc/ppp/pap-secrets would be "", which will match any -password supplied by the peer. This avoids the need to have the same -secret in two places. -.LP -Authentication must be satisfactorily completed before IPCP (or any -other Network Control Protocol) can be started. If the peer is -required to authenticate itself, and fails to do so, pppd will -terminated the link (by closing LCP). If IPCP negotiates an -unacceptable IP address for the remote host, IPCP will be closed. IP -packets can only be sent or received when IPCP is open. -.LP -In some cases it is desirable to allow some hosts which can't -authenticate themselves to connect and use one of a restricted set of -IP addresses, even when the local host generally requires -authentication. If the peer refuses to authenticate itself when -requested, pppd takes that as equivalent to authenticating with PAP -using the empty string for the username and password. Thus, by adding -a line to the pap-secrets file which specifies the empty string for -the client and password, it is possible to allow restricted access to -hosts which refuse to authenticate themselves. -.SH ROUTING -.LP -When IPCP negotiation is completed successfully, pppd will inform the -kernel of the local and remote IP addresses for the ppp interface. -This is sufficient to create a host route to the remote end of the -link, which will enable the peers to exchange IP packets. -Communication with other machines generally requires further -modification to routing tables and/or ARP (Address Resolution -Protocol) tables. In most cases the \fIdefaultroute\fR and/or -\fIproxyarp\fR options are sufficient for this, but in some cases -further intervention is required. The /etc/ppp/ip-up script can be -used for this. -.LP -Sometimes it is desirable to add a default route through the remote -host, as in the case of a machine whose only connection to the -Internet is through the ppp interface. The \fIdefaultroute\fR option -causes pppd to create such a default route when IPCP comes up, and -delete it when the link is terminated. -.LP -In some cases it is desirable to use proxy ARP, for example on a -server machine connected to a LAN, in order to allow other hosts to -communicate with the remote host. The \fIproxyarp\fR option causes -pppd to look for a network interface on the same subnet as the remote -host (an interface supporting broadcast and ARP, which is up and not a -point-to-point or loopback interface). If found, pppd creates a -permanent, published ARP entry with the IP address of the remote host -and the hardware address of the network interface found. -.LP -When the \fIdemand\fR option is used, the interface IP addresses have -already been set at the point when IPCP comes up. If pppd has not -been able to negotiate the same addresses that it used to configure -the interface (for example when the peer is an ISP that uses dynamic -IP address assignment), pppd has to change the interface IP addresses -to the negotiated addresses. This may disrupt existing connections, -and the use of demand dialling with peers that do dynamic IP address -assignment is not recommended. -.SH MULTILINK -Multilink PPP provides the capability to combine two or more PPP links -between a pair of machines into a single `bundle', which appears as a -single virtual PPP link which has the combined bandwidth of the -individual links. Currently, multilink PPP is only supported under -Linux. -.LP -Pppd detects that the link it is controlling is connected to the same -peer as another link using the peer's endpoint discriminator and the -authenticated identity of the peer (if it authenticates itself). The -endpoint discriminator is a block of data which is hopefully unique -for each peer. Several types of data can be used, including -locally-assigned strings of bytes, IP addresses, MAC addresses, -randomly strings of bytes, or E-164 phone numbers. The endpoint -discriminator sent to the peer by pppd can be set using the endpoint -option. -.LP -In circumstances the peer may send no endpoint discriminator or a -non-unique value. The optional bundle option adds an extra string -which is added to the peer's endpoint discriminator and authenticated -identity when matching up links to be joined together in a bundle. -The bundle option can also be used to allow the establishment of -multiple bundles between the local system and the peer. Pppd uses a -TDB database in /var/run/pppd.tdb to match up links. -.LP -Assuming that multilink is enabled and the peer is willing to -negotiate multilink, then when pppd is invoked to bring up the first -link to the peer, it will detect that no other link is connected to -the peer and create a new bundle, that is, another ppp network -interface unit. When another pppd is invoked to bring up another link -to the peer, it will detect the existing bundle and join its link to -it. Currently, if the first pppd terminates (for example, because of -a hangup or a received signal) the bundle is destroyed. -.SH EXAMPLES -.LP -The following examples assume that the /etc/ppp/options file contains -the \fIauth\fR option (as in the default /etc/ppp/options file in the -ppp distribution). -.LP -Probably the most common use of pppd is to dial out to an ISP. This -can be done with a command such as -.IP -pppd call isp -.LP -where the /etc/ppp/peers/isp file is set up by the system -administrator to contain something like this: -.IP -ttyS0 19200 crtscts -.br -connect '/usr/sbin/chat -v -f /etc/ppp/chat-isp' -.br -noauth -.LP -In this example, we are using chat to dial the ISP's modem and go -through any logon sequence required. The /etc/ppp/chat-isp file -contains the script used by chat; it could for example contain -something like this: -.IP -ABORT "NO CARRIER" -.br -ABORT "NO DIALTONE" -.br -ABORT "ERROR" -.br -ABORT "NO ANSWER" -.br -ABORT "BUSY" -.br -ABORT "Username/Password Incorrect" -.br -"" "at" -.br -OK "at&d0&c1" -.br -OK "atdt2468135" -.br -"name:" "^Umyuserid" -.br -"word:" "\\qmypassword" -.br -"ispts" "\\q^Uppp" -.br -"~-^Uppp-~" -.LP -See the chat(8) man page for details of chat scripts. -.LP -Pppd can also be used to provide a dial-in ppp service for users. If -the users already have login accounts, the simplest way to set up the -ppp service is to let the users log in to their accounts and run pppd -(installed setuid-root) with a command such as -.IP -pppd proxyarp -.LP -To allow a user to use the PPP facilities, you need to allocate an IP -address for that user's machine and create an entry in -/etc/ppp/pap-secrets or /etc/ppp/chap-secrets (depending on which -authentication method the PPP implementation on the user's machine -supports), so that the user's -machine can authenticate itself. For example, if Joe has a machine -called "joespc" which is to be allowed to dial in to the machine -called "server" and use the IP address joespc.my.net, you would add an -entry like this to /etc/ppp/pap-secrets or /etc/ppp/chap-secrets: -.IP -joespc server "joe's secret" joespc.my.net -.LP -Alternatively, you can create a username called (for example) "ppp", -whose login shell is pppd and whose home directory is /etc/ppp. -Options to be used when pppd is run this way can be put in -/etc/ppp/.ppprc. -.LP -If your serial connection is any more complicated than a piece of -wire, you may need to arrange for some control characters to be -escaped. In particular, it is often useful to escape XON (^Q) and -XOFF (^S), using \fIasyncmap a0000\fR. If the path includes a telnet, -you probably should escape ^] as well (\fIasyncmap 200a0000\fR). If -the path includes an rlogin, you will need to use the \fIescape ff\fR -option on the end which is running the rlogin client, since many -rlogin implementations are not transparent; they will remove the -sequence [0xff, 0xff, 0x73, 0x73, followed by any 8 bytes] from the -stream. -.SH DIAGNOSTICS -.LP -Messages are sent to the syslog daemon using facility LOG_DAEMON. -(This can be overriden by recompiling pppd with the macro -LOG_PPP defined as the desired facility.) In order to see the error -and debug messages, you will need to edit your /etc/syslog.conf file -to direct the messages to the desired output device or file. -.LP -The \fIdebug\fR option causes the contents of all control packets sent -or received to be logged, that is, all LCP, PAP, CHAP or IPCP packets. -This can be useful if the PPP negotiation does not succeed or if -authentication fails. -If debugging is enabled at compile time, the \fIdebug\fR option also -causes other debugging messages to be logged. -.LP -Debugging can also be enabled or disabled by sending a SIGUSR1 signal -to the pppd process. This signal acts as a toggle. -.SH EXIT STATUS -The exit status of pppd is set to indicate whether any error was -detected, or the reason for the link being terminated. The values -used are: -.TP -.B 0 -Pppd has detached, or otherwise the connection was successfully -established and terminated at the peer's request. -.TP -.B 1 -An immediately fatal error of some kind occurred, such as an essential -system call failing, or running out of virtual memory. -.TP -.B 2 -An error was detected in processing the options given, such as two -mutually exclusive options being used. -.TP -.B 3 -Pppd is not setuid-root and the invoking user is not root. -.TP -.B 4 -The kernel does not support PPP, for example, the PPP kernel driver is -not included or cannot be loaded. -.TP -.B 5 -Pppd terminated because it was sent a SIGINT, SIGTERM or SIGHUP -signal. -.TP -.B 6 -The serial port could not be locked. -.TP -.B 7 -The serial port could not be opened. -.TP -.B 8 -The connect script failed (returned a non-zero exit status). -.TP -.B 9 -The command specified as the argument to the \fIpty\fR option could -not be run. -.TP -.B 10 -The PPP negotiation failed, that is, it didn't reach the point where -at least one network protocol (e.g. IP) was running. -.TP -.B 11 -The peer system failed (or refused) to authenticate itself. -.TP -.B 12 -The link was established successfully and terminated because it was -idle. -.TP -.B 13 -The link was established successfully and terminated because the -connect time limit was reached. -.TP -.B 14 -Callback was negotiated and an incoming call should arrive shortly. -.TP -.B 15 -The link was terminated because the peer is not responding to echo -requests. -.TP -.B 16 -The link was terminated by the modem hanging up. -.TP -.B 17 -The PPP negotiation failed because serial loopback was detected. -.TP -.B 18 -The init script failed (returned a non-zero exit status). -.TP -.B 19 -We failed to authenticate ourselves to the peer. -.SH SCRIPTS -Pppd invokes scripts at various stages in its processing which can be -used to perform site-specific ancillary processing. These scripts are -usually shell scripts, but could be executable code files instead. -Pppd does not wait for the scripts to finish. The scripts are -executed as root (with the real and effective user-id set to 0), so -that they can do things such as update routing tables or run -privileged daemons. Be careful that the contents of these scripts do -not compromise your system's security. Pppd runs the scripts with -standard input, output and error redirected to /dev/null, and with an -environment that is empty except for some environment variables that -give information about the link. The environment variables that pppd -sets are: -.TP -.B DEVICE -The name of the serial tty device being used. -.TP -.B IFNAME -The name of the network interface being used. -.TP -.B IPLOCAL -The IP address for the local end of the link. This is only set when -IPCP has come up. -.TP -.B IPREMOTE -The IP address for the remote end of the link. This is only set when -IPCP has come up. -.TP -.B PEERNAME -The authenticated name of the peer. This is only set if the peer -authenticates itself. -.TP -.B SPEED -The baud rate of the tty device. -.TP -.B ORIG_UID -The real user-id of the user who invoked pppd. -.TP -.B PPPLOGNAME -The username of the real user-id that invoked pppd. This is always set. -.P -For the ip-down and auth-down scripts, pppd also sets the following -variables giving statistics for the connection: -.TP -.B CONNECT_TIME -The number of seconds from when the PPP negotiation started until the -connection was terminated. -.TP -.B BYTES_SENT -The number of bytes sent (at the level of the serial port) during the -connection. -.TP -.B BYTES_RCVD -The number of bytes received (at the level of the serial port) during -the connection. -.TP -.B LINKNAME -The logical name of the link, set with the \fIlinkname\fR option. -.P -Pppd invokes the following scripts, if they exist. It is not an error -if they don't exist. -.TP -.B /etc/ppp/auth-up -A program or script which is executed after the remote system -successfully authenticates itself. It is executed with the parameters -.IP -\fIinterface-name peer-name user-name tty-device speed\fR -.IP -Note that this script is not executed if the peer doesn't authenticate -itself, for example when the \fInoauth\fR option is used. -.TP -.B /etc/ppp/auth-down -A program or script which is executed when the link goes down, if -/etc/ppp/auth-up was previously executed. It is executed in the same -manner with the same parameters as /etc/ppp/auth-up. -.TP -.B /etc/ppp/ip-up -A program or script which is executed when the link is available for -sending and receiving IP packets (that is, IPCP has come up). It is -executed with the parameters -.IP -\fIinterface-name tty-device speed local-IP-address -remote-IP-address ipparam\fR -.TP -.B /etc/ppp/ip-down -A program or script which is executed when the link is no longer -available for sending and receiving IP packets. This script can be -used for undoing the effects of the /etc/ppp/ip-up script. It is -invoked in the same manner and with the same parameters as the ip-up -script. -.TP -.B /etc/ppp/ipv6-up -Like /etc/ppp/ip-up, except that it is executed when the link is available -for sending and receiving IPv6 packets. It is executed with the parameters -.IP -\fIinterface-name tty-device speed local-link-local-address -remote-link-local-address ipparam\fR -.TP -.B /etc/ppp/ipv6-down -Similar to /etc/ppp/ip-down, but it is executed when IPv6 packets can no -longer be transmitted on the link. It is executed with the same parameters -as the ipv6-up script. -.TP -.B /etc/ppp/ipx-up -A program or script which is executed when the link is available for -sending and receiving IPX packets (that is, IPXCP has come up). It is -executed with the parameters -.IP -\fIinterface-name tty-device speed network-number local-IPX-node-address -remote-IPX-node-address local-IPX-routing-protocol remote-IPX-routing-protocol -local-IPX-router-name remote-IPX-router-name ipparam pppd-pid\fR -.IP -The local-IPX-routing-protocol and remote-IPX-routing-protocol field -may be one of the following: -.IP -NONE to indicate that there is no routing protocol -.br -RIP to indicate that RIP/SAP should be used -.br -NLSP to indicate that Novell NLSP should be used -.br -RIP NLSP to indicate that both RIP/SAP and NLSP should be used -.TP -.B /etc/ppp/ipx-down -A program or script which is executed when the link is no longer -available for sending and receiving IPX packets. This script can be -used for undoing the effects of the /etc/ppp/ipx-up script. It is -invoked in the same manner and with the same parameters as the ipx-up -script. -.SH FILES -.TP -.B /var/run/ppp\fIn\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp\fIn\fB.pid \fR(others) -Process-ID for pppd process on ppp interface unit \fIn\fR. -.TP -.B /var/run/ppp-\fIname\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp-\fIname\fB.pid \fR(others) -Process-ID for pppd process for logical link \fIname\fR (see the -\fIlinkname\fR option). -.TP -.B /etc/ppp/pap-secrets -Usernames, passwords and IP addresses for PAP authentication. This -file should be owned by root and not readable or writable by any other -user. Pppd will log a warning if this is not the case. -.TP -.B /etc/ppp/chap-secrets -Names, secrets and IP addresses for CHAP authentication. As for -/etc/ppp/pap-secrets, this file should be owned by root and not -readable or writable by any other user. Pppd will log a warning if -this is not the case. -.TP -.B /etc/ppp/options -System default options for pppd, read before user default options or -command-line options. -.TP -.B ~/.ppprc -User default options, read before /etc/ppp/options.\fIttyname\fR. -.TP -.B /etc/ppp/options.\fIttyname -System default options for the serial port being used, read after -~/.ppprc. In forming the \fIttyname\fR part of this -filename, an initial /dev/ is stripped from the port name (if -present), and any slashes in the remaining part are converted to -dots. -.TP -.B /etc/ppp/peers -A directory containing options files which may contain privileged -options, even if pppd was invoked by a user other than root. The -system administrator can create options files in this directory to -permit non-privileged users to dial out without requiring the peer to -authenticate, but only to certain trusted peers. -.SH SEE ALSO -.TP -.B RFC1144 -Jacobson, V. -\fICompressing TCP/IP headers for low-speed serial links.\fR -February 1990. -.TP -.B RFC1321 -Rivest, R. -.I The MD5 Message-Digest Algorithm. -April 1992. -.TP -.B RFC1332 -McGregor, G. -.I PPP Internet Protocol Control Protocol (IPCP). -May 1992. -.TP -.B RFC1334 -Lloyd, B.; Simpson, W.A. -.I PPP authentication protocols. -October 1992. -.TP -.B RFC1661 -Simpson, W.A. -.I The Point\-to\-Point Protocol (PPP). -July 1994. -.TP -.B RFC1662 -Simpson, W.A. -.I PPP in HDLC-like Framing. -July 1994. -.TP -.B RFC2472 -Haskin, D. -.I IP Version 6 over PPP -December 1998. -.SH NOTES -The following signals have the specified effect when sent to pppd. -.TP -.B SIGINT, SIGTERM -These signals cause pppd to terminate the link (by closing LCP), -restore the serial device settings, and exit. -.TP -.B SIGHUP -This signal causes pppd to terminate the link, restore the serial -device settings, and close the serial device. If the \fIpersist\fR or -\fIdemand\fR option has been specified, pppd will try to reopen the -serial device and start another connection (after the holdoff period). -Otherwise pppd will exit. If this signal is received during the -holdoff period, it causes pppd to end the holdoff period immediately. -.TP -.B SIGUSR1 -This signal toggles the state of the \fIdebug\fR option. -.TP -.B SIGUSR2 -This signal causes pppd to renegotiate compression. This can be -useful to re-enable compression after it has been disabled as a result -of a fatal decompression error. (Fatal decompression errors generally -indicate a bug in one or other implementation.) - -.SH AUTHORS -Paul Mackerras (Paul.Mackerras@cs.anu.edu.au), based on earlier work by -Drew Perkins, -Brad Clements, -Karl Fox, -Greg Christy, -and -Brad Parker. diff --git a/mdk-stage1/ppp/pppd/pppd.h b/mdk-stage1/ppp/pppd/pppd.h deleted file mode 100644 index 02f6dfcef..000000000 --- a/mdk-stage1/ppp/pppd/pppd.h +++ /dev/null @@ -1,787 +0,0 @@ -/* - * pppd.h - PPP daemon global declarations. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - * - * $Id$ - */ - -/* - * TODO: - */ - -#ifndef __PPPD_H__ -#define __PPPD_H__ - -#include <stdio.h> /* for FILE */ -#include <limits.h> /* for NGROUPS_MAX */ -#include <sys/param.h> /* for MAXPATHLEN and BSD4_4, if defined */ -#include <sys/types.h> /* for u_int32_t, if defined */ -#include <sys/time.h> /* for struct timeval */ -#include <net/ppp_defs.h> -#include "patchlevel.h" - -#if defined(__STDC__) -#include <stdarg.h> -#define __V(x) x -#else -#include <varargs.h> -#define __V(x) (va_alist) va_dcl -#define const -#define volatile -#endif - -#ifdef INET6 -#include "eui64.h" -#endif - -/* - * Limits. - */ - -#define NUM_PPP 1 /* One PPP interface supported (per process) */ -#define MAXWORDLEN 1024 /* max length of word in file (incl null) */ -#define MAXARGS 1 /* max # args to a command */ -#define MAXNAMELEN 256 /* max length of hostname or name for auth */ -#define MAXSECRETLEN 256 /* max length of password or secret */ - -/* - * Option descriptor structure. - */ - -typedef unsigned char bool; - -enum opt_type { - o_special_noarg = 0, - o_special = 1, - o_bool, - o_int, - o_uint32, - o_string, - o_wild, -}; - -typedef struct { - char *name; /* name of the option */ - enum opt_type type; - void *addr; - char *description; - int flags; - void *addr2; - int upper_limit; - int lower_limit; - const char *source; - short int priority; - short int winner; -} option_t; - -/* Values for flags */ -#define OPT_VALUE 0xff /* mask for presupplied value */ -#define OPT_HEX 0x100 /* int option is in hex */ -#define OPT_NOARG 0x200 /* option doesn't take argument */ -#define OPT_OR 0x400 /* OR in argument to value */ -#define OPT_INC 0x800 /* increment value */ -#define OPT_PRIV 0x1000 /* privileged option */ -#define OPT_STATIC 0x2000 /* string option goes into static array */ -#define OPT_LLIMIT 0x4000 /* check value against lower limit */ -#define OPT_ULIMIT 0x8000 /* check value against upper limit */ -#define OPT_LIMITS (OPT_LLIMIT|OPT_ULIMIT) -#define OPT_ZEROOK 0x10000 /* 0 value is OK even if not within limits */ -#define OPT_HIDE 0x10000 /* for o_string, print value as ?????? */ -#define OPT_A2LIST 0x10000 /* for o_special, keep list of values */ -#define OPT_NOINCR 0x20000 /* value mustn't be increased */ -#define OPT_ZEROINF 0x40000 /* with OPT_NOINCR, 0 == infinity */ -#define OPT_PRIO 0x80000 /* process option priorities for this option */ -#define OPT_PRIOSUB 0x100000 /* subsidiary member of priority group */ -#define OPT_ALIAS 0x200000 /* option is alias for previous option */ -#define OPT_A2COPY 0x400000 /* addr2 -> second location to rcv value */ -#define OPT_ENABLE 0x800000 /* use *addr2 as enable for option */ -#define OPT_A2CLR 0x1000000 /* clear *(bool *)addr2 */ -#define OPT_PRIVFIX 0x2000000 /* user can't override if set by root */ -#define OPT_INITONLY 0x4000000 /* option can only be set in init phase */ -#define OPT_DEVEQUIV 0x8000000 /* equiv to device name */ -#define OPT_DEVNAM (OPT_INITONLY | OPT_DEVEQUIV) -#define OPT_A2PRINTER 0x10000000 /* *addr2 is a fn for printing option */ -#define OPT_A2STRVAL 0x20000000 /* *addr2 points to current string value */ -#define OPT_NOPRINT 0x40000000 /* don't print this option at all */ - -#define OPT_VAL(x) ((x) & OPT_VALUE) - -/* Values for priority */ -#define OPRIO_DEFAULT 0 /* a default value */ -#define OPRIO_CFGFILE 1 /* value from a configuration file */ -#define OPRIO_CMDLINE 2 /* value from the command line */ -#define OPRIO_SECFILE 3 /* value from options in a secrets file */ -#define OPRIO_ROOT 100 /* added to priority if OPT_PRIVFIX && root */ - -#ifndef GIDSET_TYPE -#define GIDSET_TYPE gid_t -#endif - -/* Structure representing a list of permitted IP addresses. */ -struct permitted_ip { - int permit; /* 1 = permit, 0 = forbid */ - u_int32_t base; /* match if (addr & mask) == base */ - u_int32_t mask; /* base and mask are in network byte order */ -}; - -/* - * Unfortunately, the linux kernel driver uses a different structure - * for statistics from the rest of the ports. - * This structure serves as a common representation for the bits - * pppd needs. - */ -struct pppd_stats { - unsigned int bytes_in; - unsigned int bytes_out; -}; - -/* Used for storing a sequence of words. Usually malloced. */ -struct wordlist { - struct wordlist *next; - char *word; -}; - -/* An endpoint discriminator, used with multilink. */ -#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ -struct epdisc { - unsigned char class; - unsigned char length; - unsigned char value[MAX_ENDP_LEN]; -}; - -/* values for epdisc.class */ -#define EPD_NULL 0 /* null discriminator, no data */ -#define EPD_LOCAL 1 -#define EPD_IP 2 -#define EPD_MAC 3 -#define EPD_MAGIC 4 -#define EPD_PHONENUM 5 - -typedef void (*notify_func) __P((void *, int)); - -struct notifier { - struct notifier *next; - notify_func func; - void *arg; -}; - -/* - * Global variables. - */ - -extern int hungup; /* Physical layer has disconnected */ -extern int ifunit; /* Interface unit number */ -extern char ifname[]; /* Interface name */ -extern char hostname[]; /* Our hostname */ -extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ -extern int phase; /* Current state of link - see values below */ -extern int baud_rate; /* Current link speed in bits/sec */ -extern char *progname; /* Name of this program */ -extern int redirect_stderr;/* Connector's stderr should go to file */ -extern char peer_authname[];/* Authenticated name of peer */ -extern int privileged; /* We were run by real-uid root */ -extern int need_holdoff; /* Need holdoff period after link terminates */ -extern char **script_env; /* Environment variables for scripts */ -extern int detached; /* Have detached from controlling tty */ -extern GIDSET_TYPE groups[NGROUPS_MAX]; /* groups the user is in */ -extern int ngroups; /* How many groups valid in groups */ -extern struct pppd_stats link_stats; /* byte/packet counts etc. for link */ -extern int link_stats_valid; /* set if link_stats is valid */ -extern int link_connect_time; /* time the link was up for */ -extern int using_pty; /* using pty as device (notty or pty opt.) */ -extern int log_to_fd; /* logging to this fd as well as syslog */ -extern bool log_default; /* log_to_fd is default (stdout) */ -extern char *no_ppp_msg; /* message to print if ppp not in kernel */ -extern volatile int status; /* exit status for pppd */ -extern bool devnam_fixed; /* can no longer change devnam */ -extern int unsuccess; /* # unsuccessful connection attempts */ -extern int do_callback; /* set if we want to do callback next */ -extern int doing_callback; /* set if this is a callback */ -extern char ppp_devnam[MAXPATHLEN]; -extern struct notifier *pidchange; /* for notifications of pid changing */ -extern struct notifier *phasechange; /* for notifications of phase changes */ -extern struct notifier *exitnotify; /* for notification that we're exiting */ -extern struct notifier *sigreceived; /* notification of received signal */ -extern int listen_time; /* time to listen first (ms) */ - -/* Values for do_callback and doing_callback */ -#define CALLBACK_DIALIN 1 /* we are expecting the call back */ -#define CALLBACK_DIALOUT 2 /* we are dialling out to call back */ - -/* - * Variables set by command-line options. - */ - -extern int debug; /* Debug flag */ -extern int kdebugflag; /* Tell kernel to print debug messages */ -extern int default_device; /* Using /dev/tty or equivalent */ -extern char devnam[MAXPATHLEN]; /* Device name */ -extern int crtscts; /* Use hardware flow control */ -extern bool modem; /* Use modem control lines */ -extern int inspeed; /* Input/Output speed requested */ -extern u_int32_t netmask; /* IP netmask to set on interface */ -extern bool lockflag; /* Create lock file to lock the serial dev */ -extern bool nodetach; /* Don't detach from controlling tty */ -extern bool updetach; /* Detach from controlling tty when link up */ -extern char *initializer; /* Script to initialize physical link */ -extern char *connect_script; /* Script to establish physical link */ -extern char *disconnect_script; /* Script to disestablish physical link */ -extern char *welcomer; /* Script to welcome client after connection */ -extern char *ptycommand; /* Command to run on other side of pty */ -extern int maxconnect; /* Maximum connect time (seconds) */ -extern char user[MAXNAMELEN];/* Our name for authenticating ourselves */ -extern char passwd[MAXSECRETLEN]; /* Password for PAP or CHAP */ -extern bool auth_required; /* Peer is required to authenticate */ -extern bool persist; /* Reopen link after it goes down */ -extern bool uselogin; /* Use /etc/passwd for checking PAP */ -extern char our_name[MAXNAMELEN];/* Our name for authentication purposes */ -extern char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ -extern bool explicit_remote;/* remote_name specified with remotename opt */ -extern bool demand; /* Do dial-on-demand */ -extern char *ipparam; /* Extra parameter for ip up/down scripts */ -extern bool cryptpap; /* Others' PAP passwords are encrypted */ -extern int idle_time_limit;/* Shut down link if idle for this long */ -extern int holdoff; /* Dead time before restarting */ -extern bool holdoff_specified; /* true if user gave a holdoff value */ -extern bool notty; /* Stdin/out is not a tty */ -extern char *pty_socket; /* Socket to connect to pty */ -extern char *record_file; /* File to record chars sent/received */ -extern bool sync_serial; /* Device is synchronous serial device */ -extern int maxfail; /* Max # of unsuccessful connection attempts */ -extern char linkname[MAXPATHLEN]; /* logical name for link */ -extern bool tune_kernel; /* May alter kernel settings as necessary */ -extern int connect_delay; /* Time to delay after connect script */ -extern int max_data_rate; /* max bytes/sec through charshunt */ -extern int req_unit; /* interface unit number to use */ -extern bool multilink; /* enable multilink operation */ -extern bool noendpoint; /* don't send or accept endpt. discrim. */ -extern char *bundle_name; /* bundle name for multilink */ -extern bool dump_options; /* print out option values */ -extern bool dryrun; /* check everything, print options, exit */ - -#ifdef PPP_FILTER -extern struct bpf_program pass_filter; /* Filter for pkts to pass */ -extern struct bpf_program active_filter; /* Filter for link-active pkts */ -#endif - -#ifdef MSLANMAN -extern bool ms_lanman; /* Use LanMan password instead of NT */ - /* Has meaning only with MS-CHAP challenges */ -#endif - -extern char *current_option; /* the name of the option being parsed */ -extern int privileged_option; /* set iff the current option came from root */ -extern char *option_source; /* string saying where the option came from */ -extern int option_priority; /* priority of current options */ - -/* - * Values for phase. - */ -#define PHASE_DEAD 0 -#define PHASE_INITIALIZE 1 -#define PHASE_SERIALCONN 2 -#define PHASE_DORMANT 3 -#define PHASE_ESTABLISH 4 -#define PHASE_AUTHENTICATE 5 -#define PHASE_CALLBACK 6 -#define PHASE_NETWORK 7 -#define PHASE_RUNNING 8 -#define PHASE_TERMINATE 9 -#define PHASE_DISCONNECT 10 -#define PHASE_HOLDOFF 11 - -/* - * The following struct gives the addresses of procedures to call - * for a particular protocol. - */ -struct protent { - u_short protocol; /* PPP protocol number */ - /* Initialization procedure */ - void (*init) __P((int unit)); - /* Process a received packet */ - void (*input) __P((int unit, u_char *pkt, int len)); - /* Process a received protocol-reject */ - void (*protrej) __P((int unit)); - /* Lower layer has come up */ - void (*lowerup) __P((int unit)); - /* Lower layer has gone down */ - void (*lowerdown) __P((int unit)); - /* Open the protocol */ - void (*open) __P((int unit)); - /* Close the protocol */ - void (*close) __P((int unit, char *reason)); - /* Print a packet in readable form */ - int (*printpkt) __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); - /* Process a received data packet */ - void (*datainput) __P((int unit, u_char *pkt, int len)); - bool enabled_flag; /* 0 iff protocol is disabled */ - char *name; /* Text name of protocol */ - char *data_name; /* Text name of corresponding data protocol */ - option_t *options; /* List of command-line options */ - /* Check requested options, assign defaults */ - void (*check_options) __P((void)); - /* Configure interface for demand-dial */ - int (*demand_conf) __P((int unit)); - /* Say whether to bring up link for this pkt */ - int (*active_pkt) __P((u_char *pkt, int len)); -}; - -/* Table of pointers to supported protocols */ -extern struct protent *protocols[]; - -/* - * This struct contains pointers to a set of procedures for - * doing operations on a "channel". A channel provides a way - * to send and receive PPP packets - the canonical example is - * a serial port device in PPP line discipline (or equivalently - * with PPP STREAMS modules pushed onto it). - */ -struct channel { - /* set of options for this channel */ - option_t *options; - /* find and process a per-channel options file */ - void (*process_extra_options) __P((void)); - /* check all the options that have been given */ - void (*check_options) __P((void)); - /* get the channel ready to do PPP, return a file descriptor */ - int (*connect) __P((void)); - /* we're finished with the channel */ - void (*disconnect) __P((void)); - /* put the channel into PPP `mode' */ - int (*establish_ppp) __P((int)); - /* take the channel out of PPP `mode', restore loopback if demand */ - void (*disestablish_ppp) __P((int)); - /* set the transmit-side PPP parameters of the channel */ - void (*send_config) __P((int, u_int32_t, int, int)); - /* set the receive-side PPP parameters of the channel */ - void (*recv_config) __P((int, u_int32_t, int, int)); - /* cleanup on error or normal exit */ - void (*cleanup) __P((void)); - /* close the device, called in children after fork */ - void (*close) __P((void)); -}; - -extern struct channel *the_channel; - -#define ppp_send_config(unit, mtu, accm, pc, acc) \ -do { \ - if (the_channel->send_config) \ - (*the_channel->send_config)((mtu), (accm), (pc), (acc)); \ -} while (0) - -#define ppp_recv_config(unit, mtu, accm, pc, acc) \ -do { \ - if (the_channel->send_config) \ - (*the_channel->recv_config)((mtu), (accm), (pc), (acc)); \ -} while (0) - -/* - * Prototypes. - */ - -/* Procedures exported from main.c. */ -void set_ifunit __P((int)); /* set stuff that depends on ifunit */ -void detach __P((void)); /* Detach from controlling tty */ -void die __P((int)); /* Cleanup and exit */ -void quit __P((void)); /* like die(1) */ -void novm __P((char *)); /* Say we ran out of memory, and die */ -void timeout __P((void (*func)(void *), void *arg, int s, int us)); - /* Call func(arg) after s.us seconds */ -void untimeout __P((void (*func)(void *), void *arg)); - /* Cancel call to func(arg) */ -void record_child __P((int, char *, void (*) (void *), void *)); -int device_script __P((char *cmd, int in, int out, int dont_wait)); - /* Run `cmd' with given stdin and stdout */ -pid_t run_program __P((char *prog, char **args, int must_exist, - void (*done)(void *), void *arg)); - /* Run program prog with args in child */ -void reopen_log __P((void)); /* (re)open the connection to syslog */ -void update_link_stats __P((int)); /* Get stats at link termination */ -void script_setenv __P((char *, char *, int)); /* set script env var */ -void script_unsetenv __P((char *)); /* unset script env var */ -void new_phase __P((int)); /* signal start of new phase */ -void add_notifier __P((struct notifier **, notify_func, void *)); -void remove_notifier __P((struct notifier **, notify_func, void *)); -void notify __P((struct notifier *, int)); - -/* Procedures exported from tty.c. */ -void tty_init __P((void)); - -/* Procedures exported from utils.c. */ -void log_packet __P((u_char *, int, char *, int)); - /* Format a packet and log it with syslog */ -void print_string __P((char *, int, void (*) (void *, char *, ...), - void *)); /* Format a string for output */ -int slprintf __P((char *, int, char *, ...)); /* sprintf++ */ -int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */ -size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */ -size_t strlcat __P((char *, const char *, size_t)); /* safe strncpy */ -void dbglog __P((char *, ...)); /* log a debug message */ -void info __P((char *, ...)); /* log an informational message */ -void notice __P((char *, ...)); /* log a notice-level message */ -void warn __P((char *, ...)); /* log a warning message */ -void error __P((char *, ...)); /* log an error message */ -void fatal __P((char *, ...)); /* log an error message and die(1) */ -void init_pr_log __P((char *, int)); /* initialize for using pr_log */ -void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */ -void end_pr_log __P((void)); /* finish up after using pr_log */ - -/* Procedures exported from auth.c */ -void link_required __P((int)); /* we are starting to use the link */ -void link_terminated __P((int)); /* we are finished with the link */ -void link_down __P((int)); /* the LCP layer has left the Opened state */ -void link_established __P((int)); /* the link is up; authenticate now */ -void start_networks __P((void)); /* start all the network control protos */ -void np_up __P((int, int)); /* a network protocol has come up */ -void np_down __P((int, int)); /* a network protocol has gone down */ -void np_finished __P((int, int)); /* a network protocol no longer needs link */ -void auth_peer_fail __P((int, int)); - /* peer failed to authenticate itself */ -void auth_peer_success __P((int, int, char *, int)); - /* peer successfully authenticated itself */ -void auth_withpeer_fail __P((int, int)); - /* we failed to authenticate ourselves */ -void auth_withpeer_success __P((int, int)); - /* we successfully authenticated ourselves */ -void auth_check_options __P((void)); - /* check authentication options supplied */ -void auth_reset __P((int)); /* check what secrets we have */ -int check_passwd __P((int, char *, int, char *, int, char **)); - /* Check peer-supplied username/password */ -int get_secret __P((int, char *, char *, char *, int *, int)); - /* get "secret" for chap */ -int auth_ip_addr __P((int, u_int32_t)); - /* check if IP address is authorized */ -int bad_ip_adrs __P((u_int32_t)); - /* check if IP address is unreasonable */ - -/* Procedures exported from demand.c */ -void demand_conf __P((void)); /* config interface(s) for demand-dial */ -void demand_block __P((void)); /* set all NPs to queue up packets */ -void demand_unblock __P((void)); /* set all NPs to pass packets */ -void demand_discard __P((void)); /* set all NPs to discard packets */ -void demand_rexmit __P((int)); /* retransmit saved frames for an NP */ -int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ -int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ - -/* Procedures exported from multilink.c */ -void mp_check_options __P((void)); /* Check multilink-related options */ -int mp_join_bundle __P((void)); /* join our link to an appropriate bundle */ -char *epdisc_to_str __P((struct epdisc *)); /* string from endpoint discrim. */ -int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */ - -/* Procedures exported from sys-*.c */ -void sys_init __P((void)); /* Do system-dependent initialization */ -void sys_cleanup __P((void)); /* Restore system state before exiting */ -int sys_check_options __P((void)); /* Check options specified */ -void sys_close __P((void)); /* Clean up in a child before execing */ -int ppp_available __P((void)); /* Test whether ppp kernel support exists */ -int get_pty __P((int *, int *, char *, int)); /* Get pty master/slave */ -int open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */ -int tty_establish_ppp __P((int)); /* Turn serial port into a ppp interface */ -void tty_disestablish_ppp __P((int)); /* Restore port to normal operation */ -void make_new_bundle __P((int, int, int, int)); /* Create new bundle */ -int bundle_attach __P((int)); /* Attach link to existing bundle */ -void cfg_bundle __P((int, int, int, int)); /* Configure existing bundle */ -void clean_check __P((void)); /* Check if line was 8-bit clean */ -void set_up_tty __P((int, int)); /* Set up port's speed, parameters, etc. */ -void restore_tty __P((int)); /* Restore port's original parameters */ -void setdtr __P((int, int)); /* Raise or lower port's DTR line */ -void output __P((int, u_char *, int)); /* Output a PPP packet */ -void wait_input __P((struct timeval *)); - /* Wait for input, with timeout */ -void add_fd __P((int)); /* Add fd to set to wait for */ -void remove_fd __P((int)); /* Remove fd from set to wait for */ -int read_packet __P((u_char *)); /* Read PPP packet */ -int get_loop_output __P((void)); /* Read pkts from loopback */ -void tty_send_config __P((int, u_int32_t, int, int)); - /* Configure i/f transmit parameters */ -void tty_set_xaccm __P((ext_accm)); - /* Set extended transmit ACCM */ -void tty_recv_config __P((int, u_int32_t, int, int)); - /* Configure i/f receive parameters */ -int ccp_test __P((int, u_char *, int, int)); - /* Test support for compression scheme */ -void ccp_flags_set __P((int, int, int)); - /* Set kernel CCP state */ -int ccp_fatal_error __P((int)); /* Test for fatal decomp error in kernel */ -int get_idle_time __P((int, struct ppp_idle *)); - /* Find out how long link has been idle */ -int get_ppp_stats __P((int, struct pppd_stats *)); - /* Return link statistics */ -void netif_set_mtu __P((int, int)); /* Set PPP interface MTU */ -int sifvjcomp __P((int, int, int, int)); - /* Configure VJ TCP header compression */ -int sifup __P((int)); /* Configure i/f up for one protocol */ -int sifnpmode __P((int u, int proto, enum NPmode mode)); - /* Set mode for handling packets for proto */ -int sifdown __P((int)); /* Configure i/f down for one protocol */ -int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t)); - /* Configure IPv4 addresses for i/f */ -int cifaddr __P((int, u_int32_t, u_int32_t)); - /* Reset i/f IP addresses */ -#ifdef INET6 -int sif6addr __P((int, eui64_t, eui64_t)); - /* Configure IPv6 addresses for i/f */ -int cif6addr __P((int, eui64_t, eui64_t)); - /* Remove an IPv6 address from i/f */ -#endif -int sifdefaultroute __P((int, u_int32_t, u_int32_t)); - /* Create default route through i/f */ -int cifdefaultroute __P((int, u_int32_t, u_int32_t)); - /* Delete default route through i/f */ -int sifproxyarp __P((int, u_int32_t)); - /* Add proxy ARP entry for peer */ -int cifproxyarp __P((int, u_int32_t)); - /* Delete proxy ARP entry for peer */ -u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */ -int lock __P((char *)); /* Create lock file for device */ -int relock __P((int)); /* Rewrite lock file with new pid */ -void unlock __P((void)); /* Delete previously-created lock file */ -int get_host_seed __P((void)); /* Get host-dependent random number seed */ -int have_route_to __P((u_int32_t)); /* Check if route to addr exists */ -#ifdef PPP_FILTER -int set_filters __P((struct bpf_program *pass, struct bpf_program *active)); - /* Set filter programs in kernel */ -#endif -#ifdef IPX_CHANGE -int sipxfaddr __P((int, unsigned long, unsigned char *)); -int cipxfaddr __P((int)); -#endif -int get_if_hwaddr __P((u_char *addr, char *name)); -char *get_first_ethernet __P((void)); - -/* Procedures exported from options.c */ -int parse_args __P((int argc, char **argv)); - /* Parse options from arguments given */ -int options_from_file __P((char *filename, int must_exist, int check_prot, - int privileged)); - /* Parse options from an options file */ -int options_from_user __P((void)); /* Parse options from user's .ppprc */ -int options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */ -int options_from_list __P((struct wordlist *, int privileged)); - /* Parse options from a wordlist */ -int getword __P((FILE *f, char *word, int *newlinep, char *filename)); - /* Read a word from a file */ -void option_error __P((char *fmt, ...)); - /* Print an error message about an option */ -int int_option __P((char *, int *)); - /* Simplified number_option for decimal ints */ -void add_options __P((option_t *)); /* Add extra options */ -void check_options __P((void)); /* check values after all options parsed */ -int override_value __P((const char *, int, const char *)); - /* override value if permitted by priority */ -void print_options __P((void (*) __P((void *, char *, ...)), void *)); - /* print out values of all options */ - -int parse_dotted_ip __P((char *, u_int32_t *)); - -/* - * Hooks to enable plugins to change various things. - */ -extern int (*new_phase_hook) __P((int)); -extern int (*idle_time_hook) __P((struct ppp_idle *)); -extern int (*holdoff_hook) __P((void)); -extern int (*pap_check_hook) __P((void)); -extern int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, - struct wordlist **paddrs, - struct wordlist **popts)); -extern void (*pap_logout_hook) __P((void)); -extern int (*pap_passwd_hook) __P((char *user, char *passwd)); -extern void (*ip_up_hook) __P((void)); -extern void (*ip_down_hook) __P((void)); -extern void (*ip_choose_hook) __P((u_int32_t *)); - -/* - * Inline versions of get/put char/short/long. - * Pointer is advanced; we assume that both arguments - * are lvalues and will already be in registers. - * cp MUST be u_char *. - */ -#define GETCHAR(c, cp) { \ - (c) = *(cp)++; \ -} -#define PUTCHAR(c, cp) { \ - *(cp)++ = (u_char) (c); \ -} - - -#define GETSHORT(s, cp) { \ - (s) = *(cp)++ << 8; \ - (s) |= *(cp)++; \ -} -#define PUTSHORT(s, cp) { \ - *(cp)++ = (u_char) ((s) >> 8); \ - *(cp)++ = (u_char) (s); \ -} - -#define GETLONG(l, cp) { \ - (l) = *(cp)++ << 8; \ - (l) |= *(cp)++; (l) <<= 8; \ - (l) |= *(cp)++; (l) <<= 8; \ - (l) |= *(cp)++; \ -} -#define PUTLONG(l, cp) { \ - *(cp)++ = (u_char) ((l) >> 24); \ - *(cp)++ = (u_char) ((l) >> 16); \ - *(cp)++ = (u_char) ((l) >> 8); \ - *(cp)++ = (u_char) (l); \ -} - -#define INCPTR(n, cp) ((cp) += (n)) -#define DECPTR(n, cp) ((cp) -= (n)) - -/* - * System dependent definitions for user-level 4.3BSD UNIX implementation. - */ - -#define TIMEOUT(r, f, t) timeout((r), (f), (t), 0) -#define UNTIMEOUT(r, f) untimeout((r), (f)) - -#define BCOPY(s, d, l) memcpy(d, s, l) -#define BZERO(s, n) memset(s, 0, n) - -#define PRINTMSG(m, l) { info("Remote message: %0.*v", l, m); } - -/* - * MAKEHEADER - Add Header fields to a packet. - */ -#define MAKEHEADER(p, t) { \ - PUTCHAR(PPP_ALLSTATIONS, p); \ - PUTCHAR(PPP_UI, p); \ - PUTSHORT(t, p); } - -/* - * Exit status values. - */ -#define EXIT_OK 0 -#define EXIT_FATAL_ERROR 1 -#define EXIT_OPTION_ERROR 2 -#define EXIT_NOT_ROOT 3 -#define EXIT_NO_KERNEL_SUPPORT 4 -#define EXIT_USER_REQUEST 5 -#define EXIT_LOCK_FAILED 6 -#define EXIT_OPEN_FAILED 7 -#define EXIT_CONNECT_FAILED 8 -#define EXIT_PTYCMD_FAILED 9 -#define EXIT_NEGOTIATION_FAILED 10 -#define EXIT_PEER_AUTH_FAILED 11 -#define EXIT_IDLE_TIMEOUT 12 -#define EXIT_CONNECT_TIME 13 -#define EXIT_CALLBACK 14 -#define EXIT_PEER_DEAD 15 -#define EXIT_HANGUP 16 -#define EXIT_LOOPBACK 17 -#define EXIT_INIT_FAILED 18 -#define EXIT_AUTH_TOPEER_FAILED 19 - -/* - * Debug macros. Slightly useful for finding bugs in pppd, not particularly - * useful for finding out why your connection isn't being established. - */ -#ifdef DEBUGALL -#define DEBUGMAIN 1 -#define DEBUGFSM 1 -#define DEBUGLCP 1 -#define DEBUGIPCP 1 -#define DEBUGIPV6CP 1 -#define DEBUGUPAP 1 -#define DEBUGCHAP 1 -#endif - -#ifndef LOG_PPP /* we use LOG_LOCAL2 for syslog by default */ -#if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUGSYS) \ - || defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \ - || defined(DEBUGCHAP) || defined(DEBUG) || defined(DEBUGIPV6CP) -#define LOG_PPP LOG_LOCAL2 -#else -#define LOG_PPP LOG_DAEMON -#endif -#endif /* LOG_PPP */ - -#ifdef DEBUGMAIN -#define MAINDEBUG(x) if (debug) dbglog x -#else -#define MAINDEBUG(x) -#endif - -#ifdef DEBUGSYS -#define SYSDEBUG(x) if (debug) dbglog x -#else -#define SYSDEBUG(x) -#endif - -#ifdef DEBUGFSM -#define FSMDEBUG(x) if (debug) dbglog x -#else -#define FSMDEBUG(x) -#endif - -#ifdef DEBUGLCP -#define LCPDEBUG(x) if (debug) dbglog x -#else -#define LCPDEBUG(x) -#endif - -#ifdef DEBUGIPCP -#define IPCPDEBUG(x) if (debug) dbglog x -#else -#define IPCPDEBUG(x) -#endif - -#ifdef DEBUGIPV6CP -#define IPV6CPDEBUG(x) if (debug) dbglog x -#else -#define IPV6CPDEBUG(x) -#endif - -#ifdef DEBUGUPAP -#define UPAPDEBUG(x) if (debug) dbglog x -#else -#define UPAPDEBUG(x) -#endif - -#ifdef DEBUGCHAP -#define CHAPDEBUG(x) if (debug) dbglog x -#else -#define CHAPDEBUG(x) -#endif - -#ifdef DEBUGIPXCP -#define IPXCPDEBUG(x) if (debug) dbglog x -#else -#define IPXCPDEBUG(x) -#endif - -#ifndef SIGTYPE -#if defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) -#define SIGTYPE void -#else -#define SIGTYPE int -#endif /* defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) */ -#endif /* SIGTYPE */ - -#ifndef MIN -#define MIN(a, b) ((a) < (b)? (a): (b)) -#endif -#ifndef MAX -#define MAX(a, b) ((a) > (b)? (a): (b)) -#endif - -#endif /* __PPP_H__ */ diff --git a/mdk-stage1/ppp/pppd/pppd.h.wtmp b/mdk-stage1/ppp/pppd/pppd.h.wtmp deleted file mode 100644 index 4d440be06..000000000 --- a/mdk-stage1/ppp/pppd/pppd.h.wtmp +++ /dev/null @@ -1,789 +0,0 @@ -/* - * pppd.h - PPP daemon global declarations. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - * - * $Id$ - */ - -/* - * TODO: - */ - -#ifndef __PPPD_H__ -#define __PPPD_H__ - -#include <stdio.h> /* for FILE */ -#include <limits.h> /* for NGROUPS_MAX */ -#include <sys/param.h> /* for MAXPATHLEN and BSD4_4, if defined */ -#include <sys/types.h> /* for u_int32_t, if defined */ -#include <sys/time.h> /* for struct timeval */ -#include <net/ppp_defs.h> -#include "patchlevel.h" - -#if defined(__STDC__) -#include <stdarg.h> -#define __V(x) x -#else -#include <varargs.h> -#define __V(x) (va_alist) va_dcl -#define const -#define volatile -#endif - -#ifdef INET6 -#include "eui64.h" -#endif - -/* - * Limits. - */ - -#define NUM_PPP 1 /* One PPP interface supported (per process) */ -#define MAXWORDLEN 1024 /* max length of word in file (incl null) */ -#define MAXARGS 1 /* max # args to a command */ -#define MAXNAMELEN 256 /* max length of hostname or name for auth */ -#define MAXSECRETLEN 256 /* max length of password or secret */ - -/* - * Option descriptor structure. - */ - -typedef unsigned char bool; - -enum opt_type { - o_special_noarg = 0, - o_special = 1, - o_bool, - o_int, - o_uint32, - o_string, - o_wild, -}; - -typedef struct { - char *name; /* name of the option */ - enum opt_type type; - void *addr; - char *description; - int flags; - void *addr2; - int upper_limit; - int lower_limit; - const char *source; - short int priority; - short int winner; -} option_t; - -/* Values for flags */ -#define OPT_VALUE 0xff /* mask for presupplied value */ -#define OPT_HEX 0x100 /* int option is in hex */ -#define OPT_NOARG 0x200 /* option doesn't take argument */ -#define OPT_OR 0x400 /* OR in argument to value */ -#define OPT_INC 0x800 /* increment value */ -#define OPT_PRIV 0x1000 /* privileged option */ -#define OPT_STATIC 0x2000 /* string option goes into static array */ -#define OPT_LLIMIT 0x4000 /* check value against lower limit */ -#define OPT_ULIMIT 0x8000 /* check value against upper limit */ -#define OPT_LIMITS (OPT_LLIMIT|OPT_ULIMIT) -#define OPT_ZEROOK 0x10000 /* 0 value is OK even if not within limits */ -#define OPT_HIDE 0x10000 /* for o_string, print value as ?????? */ -#define OPT_A2LIST 0x10000 /* for o_special, keep list of values */ -#define OPT_NOINCR 0x20000 /* value mustn't be increased */ -#define OPT_ZEROINF 0x40000 /* with OPT_NOINCR, 0 == infinity */ -#define OPT_PRIO 0x80000 /* process option priorities for this option */ -#define OPT_PRIOSUB 0x100000 /* subsidiary member of priority group */ -#define OPT_ALIAS 0x200000 /* option is alias for previous option */ -#define OPT_A2COPY 0x400000 /* addr2 -> second location to rcv value */ -#define OPT_ENABLE 0x800000 /* use *addr2 as enable for option */ -#define OPT_A2CLR 0x1000000 /* clear *(bool *)addr2 */ -#define OPT_PRIVFIX 0x2000000 /* user can't override if set by root */ -#define OPT_INITONLY 0x4000000 /* option can only be set in init phase */ -#define OPT_DEVEQUIV 0x8000000 /* equiv to device name */ -#define OPT_DEVNAM (OPT_INITONLY | OPT_DEVEQUIV) -#define OPT_A2PRINTER 0x10000000 /* *addr2 is a fn for printing option */ -#define OPT_A2STRVAL 0x20000000 /* *addr2 points to current string value */ -#define OPT_NOPRINT 0x40000000 /* don't print this option at all */ - -#define OPT_VAL(x) ((x) & OPT_VALUE) - -/* Values for priority */ -#define OPRIO_DEFAULT 0 /* a default value */ -#define OPRIO_CFGFILE 1 /* value from a configuration file */ -#define OPRIO_CMDLINE 2 /* value from the command line */ -#define OPRIO_SECFILE 3 /* value from options in a secrets file */ -#define OPRIO_ROOT 100 /* added to priority if OPT_PRIVFIX && root */ - -#ifndef GIDSET_TYPE -#define GIDSET_TYPE gid_t -#endif - -/* Structure representing a list of permitted IP addresses. */ -struct permitted_ip { - int permit; /* 1 = permit, 0 = forbid */ - u_int32_t base; /* match if (addr & mask) == base */ - u_int32_t mask; /* base and mask are in network byte order */ -}; - -/* - * Unfortunately, the linux kernel driver uses a different structure - * for statistics from the rest of the ports. - * This structure serves as a common representation for the bits - * pppd needs. - */ -struct pppd_stats { - unsigned int bytes_in; - unsigned int bytes_out; -}; - -/* Used for storing a sequence of words. Usually malloced. */ -struct wordlist { - struct wordlist *next; - char *word; -}; - -/* An endpoint discriminator, used with multilink. */ -#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ -struct epdisc { - unsigned char class; - unsigned char length; - unsigned char value[MAX_ENDP_LEN]; -}; - -/* values for epdisc.class */ -#define EPD_NULL 0 /* null discriminator, no data */ -#define EPD_LOCAL 1 -#define EPD_IP 2 -#define EPD_MAC 3 -#define EPD_MAGIC 4 -#define EPD_PHONENUM 5 - -typedef void (*notify_func) __P((void *, int)); - -struct notifier { - struct notifier *next; - notify_func func; - void *arg; -}; - -/* - * Global variables. - */ - -extern int hungup; /* Physical layer has disconnected */ -extern int ifunit; /* Interface unit number */ -extern char ifname[]; /* Interface name */ -extern char hostname[]; /* Our hostname */ -extern u_char outpacket_buf[]; /* Buffer for outgoing packets */ -extern int phase; /* Current state of link - see values below */ -extern int baud_rate; /* Current link speed in bits/sec */ -extern char *progname; /* Name of this program */ -extern int redirect_stderr;/* Connector's stderr should go to file */ -extern char peer_authname[];/* Authenticated name of peer */ -extern int privileged; /* We were run by real-uid root */ -extern int need_holdoff; /* Need holdoff period after link terminates */ -extern char **script_env; /* Environment variables for scripts */ -extern int detached; /* Have detached from controlling tty */ -extern GIDSET_TYPE groups[NGROUPS_MAX]; /* groups the user is in */ -extern int ngroups; /* How many groups valid in groups */ -extern struct pppd_stats link_stats; /* byte/packet counts etc. for link */ -extern int link_stats_valid; /* set if link_stats is valid */ -extern int link_connect_time; /* time the link was up for */ -extern int using_pty; /* using pty as device (notty or pty opt.) */ -extern int log_to_fd; /* logging to this fd as well as syslog */ -extern bool log_default; /* log_to_fd is default (stdout) */ -extern char *no_ppp_msg; /* message to print if ppp not in kernel */ -extern volatile int status; /* exit status for pppd */ -extern bool devnam_fixed; /* can no longer change devnam */ -extern int unsuccess; /* # unsuccessful connection attempts */ -extern int do_callback; /* set if we want to do callback next */ -extern int doing_callback; /* set if this is a callback */ -extern char ppp_devnam[MAXPATHLEN]; -extern struct notifier *pidchange; /* for notifications of pid changing */ -extern struct notifier *phasechange; /* for notifications of phase changes */ -extern struct notifier *exitnotify; /* for notification that we're exiting */ -extern struct notifier *sigreceived; /* notification of received signal */ -extern int listen_time; /* time to listen first (ms) */ - -/* Values for do_callback and doing_callback */ -#define CALLBACK_DIALIN 1 /* we are expecting the call back */ -#define CALLBACK_DIALOUT 2 /* we are dialling out to call back */ - -/* - * Variables set by command-line options. - */ - -extern int debug; /* Debug flag */ -extern int kdebugflag; /* Tell kernel to print debug messages */ -extern int default_device; /* Using /dev/tty or equivalent */ -extern char devnam[MAXPATHLEN]; /* Device name */ -extern int crtscts; /* Use hardware flow control */ -extern bool modem; /* Use modem control lines */ -extern int inspeed; /* Input/Output speed requested */ -extern u_int32_t netmask; /* IP netmask to set on interface */ -extern bool lockflag; /* Create lock file to lock the serial dev */ -extern bool nodetach; /* Don't detach from controlling tty */ -extern bool updetach; /* Detach from controlling tty when link up */ -extern char *initializer; /* Script to initialize physical link */ -extern char *connect_script; /* Script to establish physical link */ -extern char *disconnect_script; /* Script to disestablish physical link */ -extern char *welcomer; /* Script to welcome client after connection */ -extern char *ptycommand; /* Command to run on other side of pty */ -extern int maxconnect; /* Maximum connect time (seconds) */ -extern char user[MAXNAMELEN];/* Our name for authenticating ourselves */ -extern char passwd[MAXSECRETLEN]; /* Password for PAP or CHAP */ -extern bool auth_required; /* Peer is required to authenticate */ -extern bool persist; /* Reopen link after it goes down */ -extern bool uselogin; /* Use /etc/passwd for checking PAP */ -extern char our_name[MAXNAMELEN];/* Our name for authentication purposes */ -extern char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ -extern bool explicit_remote;/* remote_name specified with remotename opt */ -extern bool demand; /* Do dial-on-demand */ -extern char *ipparam; /* Extra parameter for ip up/down scripts */ -extern bool cryptpap; /* Others' PAP passwords are encrypted */ -extern int idle_time_limit;/* Shut down link if idle for this long */ -extern int holdoff; /* Dead time before restarting */ -extern bool holdoff_specified; /* true if user gave a holdoff value */ -extern bool notty; /* Stdin/out is not a tty */ -extern char *pty_socket; /* Socket to connect to pty */ -extern char *record_file; /* File to record chars sent/received */ -extern bool sync_serial; /* Device is synchronous serial device */ -extern int maxfail; /* Max # of unsuccessful connection attempts */ -extern char linkname[MAXPATHLEN]; /* logical name for link */ -extern bool tune_kernel; /* May alter kernel settings as necessary */ -extern int connect_delay; /* Time to delay after connect script */ -extern int max_data_rate; /* max bytes/sec through charshunt */ -extern int req_unit; /* interface unit number to use */ -extern bool multilink; /* enable multilink operation */ -extern bool noendpoint; /* don't send or accept endpt. discrim. */ -extern char *bundle_name; /* bundle name for multilink */ -extern bool dump_options; /* print out option values */ -extern bool dryrun; /* check everything, print options, exit */ - -#ifdef PPP_FILTER -extern struct bpf_program pass_filter; /* Filter for pkts to pass */ -extern struct bpf_program active_filter; /* Filter for link-active pkts */ -#endif - -#ifdef MSLANMAN -extern bool ms_lanman; /* Use LanMan password instead of NT */ - /* Has meaning only with MS-CHAP challenges */ -#endif - -extern char *current_option; /* the name of the option being parsed */ -extern int privileged_option; /* set iff the current option came from root */ -extern char *option_source; /* string saying where the option came from */ -extern int option_priority; /* priority of current options */ - -/* - * Values for phase. - */ -#define PHASE_DEAD 0 -#define PHASE_INITIALIZE 1 -#define PHASE_SERIALCONN 2 -#define PHASE_DORMANT 3 -#define PHASE_ESTABLISH 4 -#define PHASE_AUTHENTICATE 5 -#define PHASE_CALLBACK 6 -#define PHASE_NETWORK 7 -#define PHASE_RUNNING 8 -#define PHASE_TERMINATE 9 -#define PHASE_DISCONNECT 10 -#define PHASE_HOLDOFF 11 - -/* - * The following struct gives the addresses of procedures to call - * for a particular protocol. - */ -struct protent { - u_short protocol; /* PPP protocol number */ - /* Initialization procedure */ - void (*init) __P((int unit)); - /* Process a received packet */ - void (*input) __P((int unit, u_char *pkt, int len)); - /* Process a received protocol-reject */ - void (*protrej) __P((int unit)); - /* Lower layer has come up */ - void (*lowerup) __P((int unit)); - /* Lower layer has gone down */ - void (*lowerdown) __P((int unit)); - /* Open the protocol */ - void (*open) __P((int unit)); - /* Close the protocol */ - void (*close) __P((int unit, char *reason)); - /* Print a packet in readable form */ - int (*printpkt) __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); - /* Process a received data packet */ - void (*datainput) __P((int unit, u_char *pkt, int len)); - bool enabled_flag; /* 0 iff protocol is disabled */ - char *name; /* Text name of protocol */ - char *data_name; /* Text name of corresponding data protocol */ - option_t *options; /* List of command-line options */ - /* Check requested options, assign defaults */ - void (*check_options) __P((void)); - /* Configure interface for demand-dial */ - int (*demand_conf) __P((int unit)); - /* Say whether to bring up link for this pkt */ - int (*active_pkt) __P((u_char *pkt, int len)); -}; - -/* Table of pointers to supported protocols */ -extern struct protent *protocols[]; - -/* - * This struct contains pointers to a set of procedures for - * doing operations on a "channel". A channel provides a way - * to send and receive PPP packets - the canonical example is - * a serial port device in PPP line discipline (or equivalently - * with PPP STREAMS modules pushed onto it). - */ -struct channel { - /* set of options for this channel */ - option_t *options; - /* find and process a per-channel options file */ - void (*process_extra_options) __P((void)); - /* check all the options that have been given */ - void (*check_options) __P((void)); - /* get the channel ready to do PPP, return a file descriptor */ - int (*connect) __P((void)); - /* we're finished with the channel */ - void (*disconnect) __P((void)); - /* put the channel into PPP `mode' */ - int (*establish_ppp) __P((int)); - /* take the channel out of PPP `mode', restore loopback if demand */ - void (*disestablish_ppp) __P((int)); - /* set the transmit-side PPP parameters of the channel */ - void (*send_config) __P((int, u_int32_t, int, int)); - /* set the receive-side PPP parameters of the channel */ - void (*recv_config) __P((int, u_int32_t, int, int)); - /* cleanup on error or normal exit */ - void (*cleanup) __P((void)); - /* close the device, called in children after fork */ - void (*close) __P((void)); -}; - -extern struct channel *the_channel; - -#define ppp_send_config(unit, mtu, accm, pc, acc) \ -do { \ - if (the_channel->send_config) \ - (*the_channel->send_config)((mtu), (accm), (pc), (acc)); \ -} while (0) - -#define ppp_recv_config(unit, mtu, accm, pc, acc) \ -do { \ - if (the_channel->send_config) \ - (*the_channel->recv_config)((mtu), (accm), (pc), (acc)); \ -} while (0) - -/* - * Prototypes. - */ - -/* Procedures exported from main.c. */ -void set_ifunit __P((int)); /* set stuff that depends on ifunit */ -void detach __P((void)); /* Detach from controlling tty */ -void die __P((int)); /* Cleanup and exit */ -void quit __P((void)); /* like die(1) */ -void novm __P((char *)); /* Say we ran out of memory, and die */ -void timeout __P((void (*func)(void *), void *arg, int s, int us)); - /* Call func(arg) after s.us seconds */ -void untimeout __P((void (*func)(void *), void *arg)); - /* Cancel call to func(arg) */ -void record_child __P((int, char *, void (*) (void *), void *)); -int device_script __P((char *cmd, int in, int out, int dont_wait)); - /* Run `cmd' with given stdin and stdout */ -pid_t run_program __P((char *prog, char **args, int must_exist, - void (*done)(void *), void *arg)); - /* Run program prog with args in child */ -void reopen_log __P((void)); /* (re)open the connection to syslog */ -void update_link_stats __P((int)); /* Get stats at link termination */ -void script_setenv __P((char *, char *, int)); /* set script env var */ -void script_unsetenv __P((char *)); /* unset script env var */ -void new_phase __P((int)); /* signal start of new phase */ -void add_notifier __P((struct notifier **, notify_func, void *)); -void remove_notifier __P((struct notifier **, notify_func, void *)); -void notify __P((struct notifier *, int)); - -/* Procedures exported from tty.c. */ -void tty_init __P((void)); - -/* Procedures exported from utils.c. */ -void log_packet __P((u_char *, int, char *, int)); - /* Format a packet and log it with syslog */ -void print_string __P((char *, int, void (*) (void *, char *, ...), - void *)); /* Format a string for output */ -int slprintf __P((char *, int, char *, ...)); /* sprintf++ */ -int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */ -size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */ -size_t strlcat __P((char *, const char *, size_t)); /* safe strncpy */ -void dbglog __P((char *, ...)); /* log a debug message */ -void info __P((char *, ...)); /* log an informational message */ -void notice __P((char *, ...)); /* log a notice-level message */ -void warn __P((char *, ...)); /* log a warning message */ -void error __P((char *, ...)); /* log an error message */ -void fatal __P((char *, ...)); /* log an error message and die(1) */ -void init_pr_log __P((char *, int)); /* initialize for using pr_log */ -void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */ -void end_pr_log __P((void)); /* finish up after using pr_log */ - -/* Procedures exported from auth.c */ -void link_required __P((int)); /* we are starting to use the link */ -void link_terminated __P((int)); /* we are finished with the link */ -void link_down __P((int)); /* the LCP layer has left the Opened state */ -void link_established __P((int)); /* the link is up; authenticate now */ -void start_networks __P((void)); /* start all the network control protos */ -void np_up __P((int, int)); /* a network protocol has come up */ -void np_down __P((int, int)); /* a network protocol has gone down */ -void np_finished __P((int, int)); /* a network protocol no longer needs link */ -void auth_peer_fail __P((int, int)); - /* peer failed to authenticate itself */ -void auth_peer_success __P((int, int, char *, int)); - /* peer successfully authenticated itself */ -void auth_withpeer_fail __P((int, int)); - /* we failed to authenticate ourselves */ -void auth_withpeer_success __P((int, int)); - /* we successfully authenticated ourselves */ -void auth_check_options __P((void)); - /* check authentication options supplied */ -void auth_reset __P((int)); /* check what secrets we have */ -int check_passwd __P((int, char *, int, char *, int, char **)); - /* Check peer-supplied username/password */ -int get_secret __P((int, char *, char *, char *, int *, int)); - /* get "secret" for chap */ -int auth_ip_addr __P((int, u_int32_t)); - /* check if IP address is authorized */ -int bad_ip_adrs __P((u_int32_t)); - /* check if IP address is unreasonable */ - -/* Procedures exported from demand.c */ -void demand_conf __P((void)); /* config interface(s) for demand-dial */ -void demand_block __P((void)); /* set all NPs to queue up packets */ -void demand_unblock __P((void)); /* set all NPs to pass packets */ -void demand_discard __P((void)); /* set all NPs to discard packets */ -void demand_rexmit __P((int)); /* retransmit saved frames for an NP */ -int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ -int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ - -/* Procedures exported from multilink.c */ -void mp_check_options __P((void)); /* Check multilink-related options */ -int mp_join_bundle __P((void)); /* join our link to an appropriate bundle */ -char *epdisc_to_str __P((struct epdisc *)); /* string from endpoint discrim. */ -int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */ - -/* Procedures exported from sys-*.c */ -void sys_init __P((void)); /* Do system-dependent initialization */ -void sys_cleanup __P((void)); /* Restore system state before exiting */ -int sys_check_options __P((void)); /* Check options specified */ -void sys_close __P((void)); /* Clean up in a child before execing */ -int ppp_available __P((void)); /* Test whether ppp kernel support exists */ -int get_pty __P((int *, int *, char *, int)); /* Get pty master/slave */ -int open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */ -int tty_establish_ppp __P((int)); /* Turn serial port into a ppp interface */ -void tty_disestablish_ppp __P((int)); /* Restore port to normal operation */ -void make_new_bundle __P((int, int, int, int)); /* Create new bundle */ -int bundle_attach __P((int)); /* Attach link to existing bundle */ -void cfg_bundle __P((int, int, int, int)); /* Configure existing bundle */ -void clean_check __P((void)); /* Check if line was 8-bit clean */ -void set_up_tty __P((int, int)); /* Set up port's speed, parameters, etc. */ -void restore_tty __P((int)); /* Restore port's original parameters */ -void setdtr __P((int, int)); /* Raise or lower port's DTR line */ -void output __P((int, u_char *, int)); /* Output a PPP packet */ -void wait_input __P((struct timeval *)); - /* Wait for input, with timeout */ -void add_fd __P((int)); /* Add fd to set to wait for */ -void remove_fd __P((int)); /* Remove fd from set to wait for */ -int read_packet __P((u_char *)); /* Read PPP packet */ -int get_loop_output __P((void)); /* Read pkts from loopback */ -void tty_send_config __P((int, u_int32_t, int, int)); - /* Configure i/f transmit parameters */ -void tty_set_xaccm __P((ext_accm)); - /* Set extended transmit ACCM */ -void tty_recv_config __P((int, u_int32_t, int, int)); - /* Configure i/f receive parameters */ -int ccp_test __P((int, u_char *, int, int)); - /* Test support for compression scheme */ -void ccp_flags_set __P((int, int, int)); - /* Set kernel CCP state */ -int ccp_fatal_error __P((int)); /* Test for fatal decomp error in kernel */ -int get_idle_time __P((int, struct ppp_idle *)); - /* Find out how long link has been idle */ -int get_ppp_stats __P((int, struct pppd_stats *)); - /* Return link statistics */ -void netif_set_mtu __P((int, int)); /* Set PPP interface MTU */ -int sifvjcomp __P((int, int, int, int)); - /* Configure VJ TCP header compression */ -int sifup __P((int)); /* Configure i/f up for one protocol */ -int sifnpmode __P((int u, int proto, enum NPmode mode)); - /* Set mode for handling packets for proto */ -int sifdown __P((int)); /* Configure i/f down for one protocol */ -int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t)); - /* Configure IPv4 addresses for i/f */ -int cifaddr __P((int, u_int32_t, u_int32_t)); - /* Reset i/f IP addresses */ -#ifdef INET6 -int sif6addr __P((int, eui64_t, eui64_t)); - /* Configure IPv6 addresses for i/f */ -int cif6addr __P((int, eui64_t, eui64_t)); - /* Remove an IPv6 address from i/f */ -#endif -int sifdefaultroute __P((int, u_int32_t, u_int32_t)); - /* Create default route through i/f */ -int cifdefaultroute __P((int, u_int32_t, u_int32_t)); - /* Delete default route through i/f */ -int sifproxyarp __P((int, u_int32_t)); - /* Add proxy ARP entry for peer */ -int cifproxyarp __P((int, u_int32_t)); - /* Delete proxy ARP entry for peer */ -u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */ -int lock __P((char *)); /* Create lock file for device */ -int relock __P((int)); /* Rewrite lock file with new pid */ -void unlock __P((void)); /* Delete previously-created lock file */ -void logwtmp __P((const char *, const char *, const char *)); - /* Write entry to wtmp file */ -int get_host_seed __P((void)); /* Get host-dependent random number seed */ -int have_route_to __P((u_int32_t)); /* Check if route to addr exists */ -#ifdef PPP_FILTER -int set_filters __P((struct bpf_program *pass, struct bpf_program *active)); - /* Set filter programs in kernel */ -#endif -#ifdef IPX_CHANGE -int sipxfaddr __P((int, unsigned long, unsigned char *)); -int cipxfaddr __P((int)); -#endif -int get_if_hwaddr __P((u_char *addr, char *name)); -char *get_first_ethernet __P((void)); - -/* Procedures exported from options.c */ -int parse_args __P((int argc, char **argv)); - /* Parse options from arguments given */ -int options_from_file __P((char *filename, int must_exist, int check_prot, - int privileged)); - /* Parse options from an options file */ -int options_from_user __P((void)); /* Parse options from user's .ppprc */ -int options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */ -int options_from_list __P((struct wordlist *, int privileged)); - /* Parse options from a wordlist */ -int getword __P((FILE *f, char *word, int *newlinep, char *filename)); - /* Read a word from a file */ -void option_error __P((char *fmt, ...)); - /* Print an error message about an option */ -int int_option __P((char *, int *)); - /* Simplified number_option for decimal ints */ -void add_options __P((option_t *)); /* Add extra options */ -void check_options __P((void)); /* check values after all options parsed */ -int override_value __P((const char *, int, const char *)); - /* override value if permitted by priority */ -void print_options __P((void (*) __P((void *, char *, ...)), void *)); - /* print out values of all options */ - -int parse_dotted_ip __P((char *, u_int32_t *)); - -/* - * Hooks to enable plugins to change various things. - */ -extern int (*new_phase_hook) __P((int)); -extern int (*idle_time_hook) __P((struct ppp_idle *)); -extern int (*holdoff_hook) __P((void)); -extern int (*pap_check_hook) __P((void)); -extern int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, - struct wordlist **paddrs, - struct wordlist **popts)); -extern void (*pap_logout_hook) __P((void)); -extern int (*pap_passwd_hook) __P((char *user, char *passwd)); -extern void (*ip_up_hook) __P((void)); -extern void (*ip_down_hook) __P((void)); -extern void (*ip_choose_hook) __P((u_int32_t *)); - -/* - * Inline versions of get/put char/short/long. - * Pointer is advanced; we assume that both arguments - * are lvalues and will already be in registers. - * cp MUST be u_char *. - */ -#define GETCHAR(c, cp) { \ - (c) = *(cp)++; \ -} -#define PUTCHAR(c, cp) { \ - *(cp)++ = (u_char) (c); \ -} - - -#define GETSHORT(s, cp) { \ - (s) = *(cp)++ << 8; \ - (s) |= *(cp)++; \ -} -#define PUTSHORT(s, cp) { \ - *(cp)++ = (u_char) ((s) >> 8); \ - *(cp)++ = (u_char) (s); \ -} - -#define GETLONG(l, cp) { \ - (l) = *(cp)++ << 8; \ - (l) |= *(cp)++; (l) <<= 8; \ - (l) |= *(cp)++; (l) <<= 8; \ - (l) |= *(cp)++; \ -} -#define PUTLONG(l, cp) { \ - *(cp)++ = (u_char) ((l) >> 24); \ - *(cp)++ = (u_char) ((l) >> 16); \ - *(cp)++ = (u_char) ((l) >> 8); \ - *(cp)++ = (u_char) (l); \ -} - -#define INCPTR(n, cp) ((cp) += (n)) -#define DECPTR(n, cp) ((cp) -= (n)) - -/* - * System dependent definitions for user-level 4.3BSD UNIX implementation. - */ - -#define TIMEOUT(r, f, t) timeout((r), (f), (t), 0) -#define UNTIMEOUT(r, f) untimeout((r), (f)) - -#define BCOPY(s, d, l) memcpy(d, s, l) -#define BZERO(s, n) memset(s, 0, n) - -#define PRINTMSG(m, l) { info("Remote message: %0.*v", l, m); } - -/* - * MAKEHEADER - Add Header fields to a packet. - */ -#define MAKEHEADER(p, t) { \ - PUTCHAR(PPP_ALLSTATIONS, p); \ - PUTCHAR(PPP_UI, p); \ - PUTSHORT(t, p); } - -/* - * Exit status values. - */ -#define EXIT_OK 0 -#define EXIT_FATAL_ERROR 1 -#define EXIT_OPTION_ERROR 2 -#define EXIT_NOT_ROOT 3 -#define EXIT_NO_KERNEL_SUPPORT 4 -#define EXIT_USER_REQUEST 5 -#define EXIT_LOCK_FAILED 6 -#define EXIT_OPEN_FAILED 7 -#define EXIT_CONNECT_FAILED 8 -#define EXIT_PTYCMD_FAILED 9 -#define EXIT_NEGOTIATION_FAILED 10 -#define EXIT_PEER_AUTH_FAILED 11 -#define EXIT_IDLE_TIMEOUT 12 -#define EXIT_CONNECT_TIME 13 -#define EXIT_CALLBACK 14 -#define EXIT_PEER_DEAD 15 -#define EXIT_HANGUP 16 -#define EXIT_LOOPBACK 17 -#define EXIT_INIT_FAILED 18 -#define EXIT_AUTH_TOPEER_FAILED 19 - -/* - * Debug macros. Slightly useful for finding bugs in pppd, not particularly - * useful for finding out why your connection isn't being established. - */ -#ifdef DEBUGALL -#define DEBUGMAIN 1 -#define DEBUGFSM 1 -#define DEBUGLCP 1 -#define DEBUGIPCP 1 -#define DEBUGIPV6CP 1 -#define DEBUGUPAP 1 -#define DEBUGCHAP 1 -#endif - -#ifndef LOG_PPP /* we use LOG_LOCAL2 for syslog by default */ -#if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUGSYS) \ - || defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \ - || defined(DEBUGCHAP) || defined(DEBUG) || defined(DEBUGIPV6CP) -#define LOG_PPP LOG_LOCAL2 -#else -#define LOG_PPP LOG_DAEMON -#endif -#endif /* LOG_PPP */ - -#ifdef DEBUGMAIN -#define MAINDEBUG(x) if (debug) dbglog x -#else -#define MAINDEBUG(x) -#endif - -#ifdef DEBUGSYS -#define SYSDEBUG(x) if (debug) dbglog x -#else -#define SYSDEBUG(x) -#endif - -#ifdef DEBUGFSM -#define FSMDEBUG(x) if (debug) dbglog x -#else -#define FSMDEBUG(x) -#endif - -#ifdef DEBUGLCP -#define LCPDEBUG(x) if (debug) dbglog x -#else -#define LCPDEBUG(x) -#endif - -#ifdef DEBUGIPCP -#define IPCPDEBUG(x) if (debug) dbglog x -#else -#define IPCPDEBUG(x) -#endif - -#ifdef DEBUGIPV6CP -#define IPV6CPDEBUG(x) if (debug) dbglog x -#else -#define IPV6CPDEBUG(x) -#endif - -#ifdef DEBUGUPAP -#define UPAPDEBUG(x) if (debug) dbglog x -#else -#define UPAPDEBUG(x) -#endif - -#ifdef DEBUGCHAP -#define CHAPDEBUG(x) if (debug) dbglog x -#else -#define CHAPDEBUG(x) -#endif - -#ifdef DEBUGIPXCP -#define IPXCPDEBUG(x) if (debug) dbglog x -#else -#define IPXCPDEBUG(x) -#endif - -#ifndef SIGTYPE -#if defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) -#define SIGTYPE void -#else -#define SIGTYPE int -#endif /* defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) */ -#endif /* SIGTYPE */ - -#ifndef MIN -#define MIN(a, b) ((a) < (b)? (a): (b)) -#endif -#ifndef MAX -#define MAX(a, b) ((a) > (b)? (a): (b)) -#endif - -#endif /* __PPP_H__ */ diff --git a/mdk-stage1/ppp/pppd/sys-linux.c b/mdk-stage1/ppp/pppd/sys-linux.c deleted file mode 100644 index d341bb3de..000000000 --- a/mdk-stage1/ppp/pppd/sys-linux.c +++ /dev/null @@ -1,2672 +0,0 @@ -/* - * sys-linux.c - System-dependent procedures for setting up - * PPP interfaces on Linux systems - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <sys/errno.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/utsname.h> -#include <sys/sysmacros.h> - -#include <stdio.h> -#include <stdlib.h> -#include <syslog.h> -#include <string.h> -#include <time.h> -#include <memory.h> -#include <utmp.h> -#include <mntent.h> -#include <signal.h> -#include <fcntl.h> -#include <ctype.h> -#include <termios.h> -#include <unistd.h> - -/* This is in netdevice.h. However, this compile will fail miserably if - you attempt to include netdevice.h because it has so many references - to __memcpy functions which it should not attempt to do. So, since I - really don't use it, but it must be defined, define it now. */ - -#ifndef MAX_ADDR_LEN -#define MAX_ADDR_LEN 7 -#endif - -#if __GLIBC__ >= 2 -#include <asm/types.h> /* glibc 2 conflicts with linux/types.h */ -#include <net/if.h> -#include <net/if_arp.h> -#include <net/route.h> -#include <netinet/if_ether.h> -#else -#include <linux/types.h> -#include <linux/if.h> -#include <linux/if_arp.h> -#include <linux/route.h> -#include <linux/if_ether.h> -#endif -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <linux/ppp_defs.h> -#include <linux/if_ppp.h> - -#include "pppd.h" -#include "fsm.h" -#include "ipcp.h" - -#ifdef IPX_CHANGE -#include "ipxcp.h" -#if __GLIBC__ >= 2 && \ - !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0) -#include <netipx/ipx.h> -#else -#include <linux/ipx.h> -#endif -#endif /* IPX_CHANGE */ - -#ifdef PPP_FILTER -#include <net/bpf.h> -#include <linux/filter.h> -#endif /* PPP_FILTER */ - -#ifdef LOCKLIB -#include <sys/locks.h> -#endif - -#ifdef INET6 -#ifndef _LINUX_IN6_H -/* - * This is in linux/include/net/ipv6.h. - */ - -struct in6_ifreq { - struct in6_addr ifr6_addr; - __u32 ifr6_prefixlen; - unsigned int ifr6_ifindex; -}; -#endif - -#define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \ - memset(&sin6.s6_addr, 0, sizeof(struct in6_addr)); \ - sin6.s6_addr16[0] = htons(0xfe80); \ - eui64_copy(eui64, sin6.s6_addr32[2]); \ - } while (0) - -#endif /* INET6 */ - -/* We can get an EIO error on an ioctl if the modem has hung up */ -#define ok_error(num) ((num)==EIO) - -static int tty_disc = N_TTY; /* The TTY discipline */ -static int ppp_disc = N_PPP; /* The PPP discpline */ -static int initfdflags = -1; /* Initial file descriptor flags for fd */ -static int ppp_fd = -1; /* fd which is set to PPP discipline */ -static int sock_fd = -1; /* socket for doing interface ioctls */ -static int slave_fd = -1; -static int master_fd = -1; -#ifdef INET6 -static int sock6_fd = -1; -#endif /* INET6 */ -static int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */ -static int chindex; /* channel index (new style driver) */ - -static fd_set in_fds; /* set of fds that wait_input waits for */ -static int max_in_fd; /* highest fd set in in_fds */ - -static int has_proxy_arp = 0; -static int driver_version = 0; -static int driver_modification = 0; -static int driver_patch = 0; -static int driver_is_old = 0; -static int restore_term = 0; /* 1 => we've munged the terminal */ -static struct termios inittermios; /* Initial TTY termios */ - -static int new_style_driver = 0; - -static char loop_name[20]; -static unsigned char inbuf[512]; /* buffer for chars read from loopback */ - -static int if_is_up; /* Interface has been marked up */ -static u_int32_t default_route_gateway; /* Gateway for default route added */ -static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ -static char proxy_arp_dev[16]; /* Device for proxy arp entry */ -static u_int32_t our_old_addr; /* for detecting address changes */ -static int dynaddr_set; /* 1 if ip_dynaddr set */ -static int looped; /* 1 if using loop */ -static int link_mtu; /* mtu for the link (not bundle) */ - -static struct utsname utsname; /* for the kernel version */ -static int kernel_version; -#define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p)) - -#define MAX_IFS 100 - -#define FLAGS_GOOD (IFF_UP | IFF_BROADCAST) -#define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \ - IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP) - -#define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr) - -/* Prototypes for procedures local to this file. */ -static int get_flags (int fd); -static void set_flags (int fd, int flags); -static int translate_speed (int bps); -static int baud_rate_of (int speed); -static void close_route_table (void); -static int open_route_table (void); -static int read_route_table (struct rtentry *rt); -static int defaultroute_exists (struct rtentry *rt); -static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr, - char *name, int namelen); -static void decode_version (char *buf, int *version, int *mod, int *patch); -static int set_kdebugflag(int level); -static int ppp_registered(void); -static int make_ppp_unit(void); -static void restore_loop(void); /* Transfer ppp unit back to loopback */ - -extern u_char inpacket_buf[]; /* borrowed from main.c */ - -/* - * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, - * if it exists. - */ - -#define SET_SA_FAMILY(addr, family) \ - memset ((char *) &(addr), '\0', sizeof(addr)); \ - addr.sa_family = (family); - -/* - * Determine if the PPP connection should still be present. - */ - -extern int hungup; - -/* new_fd is the fd of a tty */ -static void set_ppp_fd (int new_fd) -{ - SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", new_fd)); - ppp_fd = new_fd; - if (!new_style_driver) - ppp_dev_fd = new_fd; -} - -static int still_ppp(void) -{ - if (new_style_driver) - return !hungup && ppp_fd >= 0; - if (!hungup || ppp_fd == slave_fd) - return 1; - if (slave_fd >= 0) { - set_ppp_fd(slave_fd); - return 1; - } - return 0; -} - -/******************************************************************** - * - * Functions to read and set the flags value in the device driver - */ - -static int get_flags (int fd) -{ - int flags; - - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &flags) < 0) { - if ( ok_error (errno) ) - flags = 0; - else - fatal("ioctl(PPPIOCGFLAGS): %m"); - } - - SYSDEBUG ((LOG_DEBUG, "get flags = %x\n", flags)); - return flags; -} - -/********************************************************************/ - -static void set_flags (int fd, int flags) -{ - SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags)); - - if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) { - if (! ok_error (errno) ) - fatal("ioctl(PPPIOCSFLAGS, %x): %m", flags, errno); - } -} - -/******************************************************************** - * - * sys_init - System-dependent initialization. - */ - -void sys_init(void) -{ - int flags; - - if (new_style_driver) { - ppp_dev_fd = open("/dev/ppp", O_RDWR); - if (ppp_dev_fd < 0) - fatal("Couldn't open /dev/ppp: %m"); - flags = fcntl(ppp_dev_fd, F_GETFL); - if (flags == -1 - || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("Couldn't set /dev/ppp to nonblock: %m"); - } - - /* Get an internet socket for doing socket ioctls. */ - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd < 0) - fatal("Couldn't create IP socket: %m(%d)", errno); - -#ifdef INET6 - sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0); - if (sock6_fd < 0) - sock6_fd = -errno; /* save errno for later */ -#endif - - FD_ZERO(&in_fds); - max_in_fd = 0; -} - -/******************************************************************** - * - * sys_cleanup - restore any system state we modified before exiting: - * mark the interface down, delete default route and/or proxy arp entry. - * This shouldn't call die() because it's called from die(). - */ - -void sys_cleanup(void) -{ -/* - * Take down the device - */ - if (if_is_up) { - if_is_up = 0; - sifdown(0); - } -/* - * Delete any routes through the device. - */ - if (default_route_gateway != 0) - cifdefaultroute(0, 0, default_route_gateway); - - if (has_proxy_arp) - cifproxyarp(0, proxy_arp_addr); -} - -/******************************************************************** - * - * sys_close - Clean up in a child process before execing. - */ -void -sys_close(void) -{ - if (new_style_driver) - close(ppp_dev_fd); - if (sock_fd >= 0) - close(sock_fd); - if (slave_fd >= 0) - close(slave_fd); - if (master_fd >= 0) - close(master_fd); - closelog(); -} - -/******************************************************************** - * - * set_kdebugflag - Define the debugging level for the kernel - */ - -static int set_kdebugflag (int requested_level) -{ - if (new_style_driver && ifunit < 0) - return 1; - if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) { - if ( ! ok_error (errno) ) - error("ioctl(PPPIOCSDEBUG): %m"); - return (0); - } - SYSDEBUG ((LOG_INFO, "set kernel debugging level to %d", - requested_level)); - return (1); -} - -/******************************************************************** - * - * tty_establish_ppp - Turn the serial port into a ppp interface. - */ - -int tty_establish_ppp (int tty_fd) -{ - int x; - int fd = -1; - -/* - * Ensure that the tty device is in exclusive mode. - */ - if (ioctl(tty_fd, TIOCEXCL, 0) < 0) { - if ( ! ok_error ( errno )) - warn("Couldn't make tty exclusive: %m"); - } -/* - * Demand mode - prime the old ppp device to relinquish the unit. - */ - if (!new_style_driver && looped - && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) { - error("ioctl(transfer ppp unit): %m"); - return -1; - } -/* - * Set the current tty to the PPP discpline - */ - -#ifndef N_SYNC_PPP -#define N_SYNC_PPP 14 -#endif - ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP; - if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) { - if ( ! ok_error (errno) ) { - error("Couldn't set tty to PPP discipline: %m"); - return -1; - } - } - - if (new_style_driver) { - /* Open another instance of /dev/ppp and connect the channel to it */ - int flags; - - if (ioctl(tty_fd, PPPIOCGCHAN, &chindex) == -1) { - error("Couldn't get channel number: %m"); - goto err; - } - dbglog("using channel %d", chindex); - fd = open("/dev/ppp", O_RDWR); - if (fd < 0) { - error("Couldn't reopen /dev/ppp: %m"); - goto err; - } - if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) { - error("Couldn't attach to channel %d: %m", chindex); - goto err_close; - } - flags = fcntl(fd, F_GETFL); - if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("Couldn't set /dev/ppp (channel) to nonblock: %m"); - set_ppp_fd(fd); - - if (!looped) - ifunit = -1; - if (!looped && !multilink) { - /* - * Create a new PPP unit. - */ - if (make_ppp_unit() < 0) - goto err_close; - } - - if (looped) - set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) & ~SC_LOOP_TRAFFIC); - - if (!multilink) { - add_fd(ppp_dev_fd); - if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) { - error("Couldn't attach to PPP unit %d: %m", ifunit); - goto err_close; - } - } - - } else { - /* - * Old-style driver: find out which interface we were given. - */ - set_ppp_fd (tty_fd); - if (ioctl(tty_fd, PPPIOCGUNIT, &x) < 0) { - if (ok_error (errno)) - goto err; - fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno); - } - /* Check that we got the same unit again. */ - if (looped && x != ifunit) - fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x); - ifunit = x; - - /* - * Fetch the initial file flags and reset blocking mode on the file. - */ - initfdflags = fcntl(tty_fd, F_GETFL); - if (initfdflags == -1 || - fcntl(tty_fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { - if ( ! ok_error (errno)) - warn("Couldn't set device to non-blocking mode: %m"); - } - } - - looped = 0; - - /* - * Enable debug in the driver if requested. - */ - if (!looped) - set_kdebugflag (kdebugflag); - -#define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP) -#define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \ - | SC_LOG_FLUSH) - - set_flags(ppp_fd, ((get_flags(ppp_fd) & ~(SC_RCVB | SC_LOGB)) - | ((kdebugflag * SC_DEBUG) & SC_LOGB))); - - SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver", - driver_version, driver_modification, driver_patch)); - - return ppp_fd; - - err_close: - close(fd); - err: - if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno)) - warn("Couldn't reset tty to normal line discipline: %m"); - return -1; -} - -/******************************************************************** - * - * tty_disestablish_ppp - Restore the serial port to normal operation, - * and reconnect the ppp unit to the loopback if in demand mode. - * This shouldn't call die() because it's called from die(). - */ - -void tty_disestablish_ppp(int tty_fd) -{ - if (demand) - restore_loop(); - if (!hungup) { -/* - * Flush the tty output buffer so that the TIOCSETD doesn't hang. - */ - if (tcflush(tty_fd, TCIOFLUSH) < 0) - warn("tcflush failed: %m"); -/* - * Restore the previous line discipline - */ - if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) { - if ( ! ok_error (errno)) - error("ioctl(TIOCSETD, N_TTY): %m"); - } - - if (ioctl(tty_fd, TIOCNXCL, 0) < 0) { - if ( ! ok_error (errno)) - warn("ioctl(TIOCNXCL): %m(%d)", errno); - } - - /* Reset non-blocking mode on fd. */ - if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) { - if ( ! ok_error (errno)) - warn("Couldn't restore device fd flags: %m"); - } - } - initfdflags = -1; - - if (new_style_driver) { - close(ppp_fd); - ppp_fd = -1; - if (!looped && ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0) - error("Couldn't release PPP unit: %m"); - if (!multilink) - remove_fd(ppp_dev_fd); - } -} - -/* - * make_ppp_unit - make a new ppp unit for ppp_dev_fd. - * Assumes new_style_driver. - */ -static int make_ppp_unit() -{ - int x; - - ifunit = req_unit; - x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); - if (x < 0 && req_unit >= 0 && errno == EEXIST) { - warn("Couldn't allocate PPP unit %d as it is already in use"); - ifunit = -1; - x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); - } - if (x < 0) - error("Couldn't create new ppp unit: %m"); - return x; -} - -/* - * cfg_bundle - configure the existing bundle. - * Used in demand mode. - */ -void cfg_bundle(int mrru, int mtru, int rssn, int tssn) -{ - int flags; - - if (!new_style_driver) - return; - - /* set the mrru, mtu and flags */ - if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0) - error("Couldn't set MRRU: %m"); - flags = get_flags(ppp_dev_fd); - flags &= ~(SC_MP_SHORTSEQ | SC_MP_XSHORTSEQ); - flags |= (rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0) - | (mrru? SC_MULTILINK: 0); - - set_flags(ppp_dev_fd, flags); - - /* connect up the channel */ - if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0) - fatal("Couldn't attach to PPP unit %d: %m", ifunit); - add_fd(ppp_dev_fd); -} - -/* - * make_new_bundle - create a new PPP unit (i.e. a bundle) - * and connect our channel to it. This should only get called - * if `multilink' was set at the time establish_ppp was called. - * In demand mode this uses our existing bundle instead of making - * a new one. - */ -void make_new_bundle(int mrru, int mtru, int rssn, int tssn) -{ - if (!new_style_driver) - return; - - /* make us a ppp unit */ - if (make_ppp_unit() < 0) - die(1); - - /* set the mrru and flags */ - cfg_bundle(mrru, mtru, rssn, tssn); -} - -/* - * bundle_attach - attach our link to a given PPP unit. - * We assume the unit is controlled by another pppd. - */ -int bundle_attach(int ifnum) -{ - if (!new_style_driver) - return -1; - - if (ioctl(ppp_dev_fd, PPPIOCATTACH, &ifnum) < 0) { - if (errno == ENXIO) - return 0; /* doesn't still exist */ - fatal("Couldn't attach to interface unit %d: %m\n", ifnum); - } - if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0) - fatal("Couldn't connect to interface unit %d: %m", ifnum); - set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_MULTILINK); - - ifunit = ifnum; - return 1; -} - -/******************************************************************** - * - * clean_check - Fetch the flags for the device and generate - * appropriate error messages. - */ -void clean_check(void) -{ - int x; - char *s; - - if (still_ppp()) { - if (ioctl(ppp_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 = "all had bit 7 set to 1"; - break; - - case SC_RCV_B7_1: - s = "all had bit 7 set to 0"; - break; - - case SC_RCV_EVNP: - s = "all had odd parity"; - break; - - case SC_RCV_ODDP: - s = "all had even parity"; - break; - } - - if (s != NULL) { - warn("Receive serial link is not 8-bit clean:"); - warn("Problem: %s", s); - } - } - } -} - - -/* - * 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 B57600 - { 57600, B57600 }, -#endif -#ifdef B76800 - { 76800, B76800 }, -#endif -#ifdef B115200 - { 115200, B115200 }, -#endif -#ifdef EXTA - { 19200, EXTA }, -#endif -#ifdef EXTB - { 38400, EXTB }, -#endif -#ifdef B230400 - { 230400, B230400 }, -#endif -#ifdef B460800 - { 460800, B460800 }, -#endif -#ifdef B921600 - { 921600, B921600 }, -#endif - { 0, 0 } -}; - -/******************************************************************** - * - * Translate from bits/second to a speed_t. - */ - -static int translate_speed (int bps) -{ - struct speed *speedp; - - if (bps != 0) { - for (speedp = speeds; speedp->speed_int; speedp++) { - if (bps == speedp->speed_int) - return speedp->speed_val; - } - warn("speed %d not supported", bps); - } - return 0; -} - -/******************************************************************** - * - * Translate from a speed_t to bits/second. - */ - -static int baud_rate_of (int speed) -{ - struct speed *speedp; - - if (speed != 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. - */ - -void set_up_tty(int tty_fd, int local) -{ - int speed; - struct termios tios; - - setdtr(tty_fd, 1); - if (tcgetattr(tty_fd, &tios) < 0) { - if (!ok_error(errno)) - fatal("tcgetattr: %m(%d)", errno); - return; - } - - if (!restore_term) - inittermios = tios; - - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); - tios.c_cflag |= CS8 | CREAD | HUPCL; - - tios.c_iflag = IGNBRK | IGNPAR; - tios.c_oflag = 0; - tios.c_lflag = 0; - tios.c_cc[VMIN] = 1; - tios.c_cc[VTIME] = 0; - - if (local || !modem) - tios.c_cflag ^= (CLOCAL | HUPCL); - - switch (crtscts) { - case 1: - tios.c_cflag |= CRTSCTS; - break; - - case -2: - tios.c_iflag |= IXON | IXOFF; - tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ - tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ - break; - - case -1: - tios.c_cflag &= ~CRTSCTS; - break; - - default: - break; - } - - speed = translate_speed(inspeed); - if (speed) { - cfsetospeed (&tios, speed); - cfsetispeed (&tios, speed); - } -/* - * We can't proceed if the serial port speed is B0, - * since that implies that the serial port is disabled. - */ - else { - speed = cfgetospeed(&tios); - if (speed == B0) - fatal("Baud rate for %s is 0; need explicit baud rate", devnam); - } - - if (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0) - if (!ok_error(errno)) - fatal("tcsetattr: %m"); - - baud_rate = baud_rate_of(speed); - restore_term = 1; -} - -/******************************************************************** - * - * setdtr - control the DTR line on the serial port. - * This is called from die(), so it shouldn't call die(). - */ - -void setdtr (int tty_fd, int on) -{ - int modembits = TIOCM_DTR; - - ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits); -} - -/******************************************************************** - * - * restore_tty - restore the terminal to the saved settings. - */ - -void restore_tty (int tty_fd) -{ - if (restore_term) { - restore_term = 0; -/* - * Turn off echoing, because otherwise we can get into - * a loop with the tty and the modem echoing to each other. - * We presume we are the sole user of this tty device, so - * when we close it, it will revert to its defaults anyway. - */ - if (!default_device) - inittermios.c_lflag &= ~(ECHO | ECHONL); - - if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) { - if (! ok_error (errno)) - warn("tcsetattr: %m"); - } - } -} - -/******************************************************************** - * - * output - Output PPP packet. - */ - -void output (int unit, unsigned char *p, int len) -{ - int fd = ppp_fd; - int proto; - - if (debug) - dbglog("sent %P", p, len); - - if (len < PPP_HDRLEN) - return; - if (new_style_driver) { - p += 2; - len -= 2; - proto = (p[0] << 8) + p[1]; - if (ifunit >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG)) - fd = ppp_dev_fd; - } - if (write(fd, p, len) < 0) { - if (errno == EWOULDBLOCK || errno == ENOBUFS - || errno == ENXIO || errno == EIO || errno == EINTR) - warn("write: warning: %m (%d)", errno); - else - error("write: %m (%d)", errno); - } -} - -/******************************************************************** - * - * wait_input - wait until there is data available, - * for the length of time specified by *timo (indefinite - * if timo is NULL). - */ - -void wait_input(struct timeval *timo) -{ - fd_set ready, exc; - int n; - - ready = in_fds; - exc = in_fds; - n = select(max_in_fd + 1, &ready, NULL, &exc, timo); - if (n < 0 && errno != EINTR) - fatal("select: %m(%d)", errno); -} - -/* - * add_fd - add an fd to the set that wait_input waits for. - */ -void add_fd(int fd) -{ - FD_SET(fd, &in_fds); - if (fd > max_in_fd) - max_in_fd = fd; -} - -/* - * remove_fd - remove an fd from the set that wait_input waits for. - */ -void remove_fd(int fd) -{ - FD_CLR(fd, &in_fds); -} - - -/******************************************************************** - * - * read_packet - get a PPP packet from the serial device. - */ - -int read_packet (unsigned char *buf) -{ - int len, nr; - - len = PPP_MRU + PPP_HDRLEN; - if (new_style_driver) { - *buf++ = PPP_ALLSTATIONS; - *buf++ = PPP_UI; - len -= 2; - } - nr = -1; - if (ppp_fd >= 0) { - nr = read(ppp_fd, buf, len); - if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR) - error("read: %m"); - if (nr < 0 && errno == ENXIO) - return 0; - } - if (nr < 0 && new_style_driver && ifunit >= 0) { - /* N.B. we read ppp_fd first since LCP packets come in there. */ - nr = read(ppp_dev_fd, buf, len); - if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR) - error("read /dev/ppp: %m"); - if (nr < 0 && errno == ENXIO) - return 0; - } - return (new_style_driver && nr > 0)? nr+2: nr; -} - -/******************************************************************** - * - * get_loop_output - get outgoing packets from the ppp device, - * and detect when we want to bring the real link up. - * Return value is 1 if we need to bring up the link, 0 otherwise. - */ -int -get_loop_output(void) -{ - int rv = 0; - int n; - - if (new_style_driver) { - while ((n = read_packet(inpacket_buf)) > 0) - if (loop_frame(inpacket_buf, n)) - rv = 1; - return rv; - } - - while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0) - if (loop_chars(inbuf, n)) - rv = 1; - - if (n == 0) - fatal("eof on loopback"); - - if (errno != EWOULDBLOCK) - fatal("read from loopback: %m(%d)", errno); - - return rv; -} - -/* - * netif_set_mtu - set the MTU on the PPP network interface. - */ -void -netif_set_mtu(int unit, int mtu) -{ - struct ifreq ifr; - - SYSDEBUG ((LOG_DEBUG, "netif_set_mtu: mtu = %d\n", mtu)); - - memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - ifr.ifr_mtu = mtu; - - if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0) - fatal("ioctl(SIOCSIFMTU): %m"); -} - -/******************************************************************** - * - * tty_send_config - configure the transmit characteristics of - * the ppp interface. - */ - -void tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp) -{ - u_int x; - -/* - * Set the asyncmap and other parameters for the ppp device - */ - if (!still_ppp()) - return; - link_mtu = mtu; - SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap)); - if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) { - if (!ok_error(errno)) - fatal("ioctl(PPPIOCSASYNCMAP): %m(%d)", errno); - return; - } - - x = get_flags(ppp_fd); - x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT; - x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC; - x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC; - set_flags(ppp_fd, x); -} - -/******************************************************************** - * - * tty_set_xaccm - set the extended transmit ACCM for the interface. - */ - -void tty_set_xaccm (ext_accm accm) -{ - SYSDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n", - accm[0], accm[1], accm[2], accm[3])); - - if (!still_ppp()) - return; - if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) { - if ( ! ok_error (errno)) - warn("ioctl(set extended ACCM): %m(%d)", errno); - } -} - -/******************************************************************** - * - * tty_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ - -void tty_recv_config (int mru,u_int32_t asyncmap,int pcomp,int accomp) -{ - SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru)); -/* - * If we were called because the link has gone down then there is nothing - * which may be done. Just return without incident. - */ - if (!still_ppp()) - return; -/* - * Set the receiver parameters - */ - if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { - if ( ! ok_error (errno)) - error("ioctl(PPPIOCSMRU): %m(%d)", errno); - } - if (new_style_driver && ifunit >= 0 - && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) - error("Couldn't set MRU in generic PPP layer: %m"); - - SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap)); - if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) { - if (!ok_error(errno)) - error("ioctl(PPPIOCSRASYNCMAP): %m(%d)", errno); - } -} - -/******************************************************************** - * - * ccp_test - ask kernel whether a given compression method - * is acceptable for use. - */ - -int ccp_test (int unit, u_char *opt_ptr, int opt_len, int for_transmit) -{ - struct ppp_option_data data; - - memset (&data, '\0', sizeof (data)); - data.ptr = opt_ptr; - data.length = opt_len; - data.transmit = for_transmit; - - if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0) - return 1; - - return (errno == ENOBUFS)? 0: -1; -} - -/******************************************************************** - * - * ccp_flags_set - inform kernel about the current state of CCP. - */ - -void ccp_flags_set (int unit, int isopen, int isup) -{ - if (still_ppp()) { - int x = get_flags(ppp_dev_fd); - x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN; - x = isup? x | SC_CCP_UP : x &~ SC_CCP_UP; - set_flags (ppp_dev_fd, x); - } -} - -#ifdef PPP_FILTER -/* - * set_filters - set the active and pass filters in the kernel driver. - */ -int set_filters(struct bpf_program *pass, struct bpf_program *active) -{ - struct sock_fprog fp; - - fp.len = pass->bf_len; - fp.filter = (struct sock_filter *) pass->bf_insns; - if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) { - if (errno == ENOTTY) - warn("kernel does not support PPP filtering"); - else - error("Couldn't set pass-filter in kernel: %m"); - return 0; - } - fp.len = active->bf_len; - fp.filter = (struct sock_filter *) active->bf_insns; - if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) { - error("Couldn't set active-filter in kernel: %m"); - return 0; - } - return 1; -} -#endif /* PPP_FILTER */ - -/******************************************************************** - * - * get_idle_time - return how long the link has been idle. - */ -int -get_idle_time(u, ip) - int u; - struct ppp_idle *ip; -{ - return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0; -} - -/******************************************************************** - * - * get_ppp_stats - return statistics for the link. - */ -int -get_ppp_stats(u, stats) - int u; - struct pppd_stats *stats; -{ - struct ifpppstatsreq req; - - memset (&req, 0, sizeof (req)); - - req.stats_ptr = (caddr_t) &req.stats; - strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name)); - if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) { - error("Couldn't get PPP statistics: %m"); - return 0; - } - stats->bytes_in = req.stats.p.ppp_ibytes; - stats->bytes_out = req.stats.p.ppp_obytes; - return 1; -} - -/******************************************************************** - * - * 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 (int unit) -{ - int x = get_flags(ppp_dev_fd); - - return x & SC_DC_FERROR; -} - -/******************************************************************** - * - * path_to_procfs - find the path to the proc file system mount point - */ -static char proc_path[MAXPATHLEN]; -static int proc_path_len; - -static char *path_to_procfs(const char *tail) -{ - struct mntent *mntent; - FILE *fp; - - if (proc_path_len == 0) { - /* Default the mount location of /proc */ - strlcpy (proc_path, "/proc", sizeof(proc_path)); - proc_path_len = 5; - fp = fopen(MOUNTED, "r"); - if (fp != NULL) { - while ((mntent = getmntent(fp)) != NULL) { - if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0) - continue; - if (strcmp(mntent->mnt_type, "proc") == 0) { - strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path)); - proc_path_len = strlen(proc_path); - break; - } - } - fclose (fp); - } - } - - strlcpy(proc_path + proc_path_len, tail, - sizeof(proc_path) - proc_path_len); - return proc_path; -} - -/* - * /proc/net/route parsing stuff. - */ -#define ROUTE_MAX_COLS 12 -FILE *route_fd = (FILE *) 0; -static char route_buffer[512]; -static int route_dev_col, route_dest_col, route_gw_col; -static int route_flags_col, route_mask_col; -static int route_num_cols; - -static int open_route_table (void); -static void close_route_table (void); -static int read_route_table (struct rtentry *rt); - -/******************************************************************** - * - * close_route_table - close the interface to the route table - */ - -static void close_route_table (void) -{ - if (route_fd != (FILE *) 0) { - fclose (route_fd); - route_fd = (FILE *) 0; - } -} - -/******************************************************************** - * - * open_route_table - open the interface to the route table - */ -static char route_delims[] = " \t\n"; - -static int open_route_table (void) -{ - char *path; - - close_route_table(); - - path = path_to_procfs("/net/route"); - route_fd = fopen (path, "r"); - if (route_fd == NULL) { - error("can't open routing table %s: %m", path); - return 0; - } - - route_dev_col = 0; /* default to usual columns */ - route_dest_col = 1; - route_gw_col = 2; - route_flags_col = 3; - route_mask_col = 7; - route_num_cols = 8; - - /* parse header line */ - if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) { - char *p = route_buffer, *q; - int col; - for (col = 0; col < ROUTE_MAX_COLS; ++col) { - int used = 1; - if ((q = strtok(p, route_delims)) == 0) - break; - if (strcasecmp(q, "iface") == 0) - route_dev_col = col; - else if (strcasecmp(q, "destination") == 0) - route_dest_col = col; - else if (strcasecmp(q, "gateway") == 0) - route_gw_col = col; - else if (strcasecmp(q, "flags") == 0) - route_flags_col = col; - else if (strcasecmp(q, "mask") == 0) - route_mask_col = col; - else - used = 0; - if (used && col >= route_num_cols) - route_num_cols = col + 1; - p = NULL; - } - } - - return 1; -} - -/******************************************************************** - * - * read_route_table - read the next entry from the route table - */ - -static int read_route_table(struct rtentry *rt) -{ - char *cols[ROUTE_MAX_COLS], *p; - int col; - - memset (rt, '\0', sizeof (struct rtentry)); - - if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0) - return 0; - - p = route_buffer; - for (col = 0; col < route_num_cols; ++col) { - cols[col] = strtok(p, route_delims); - if (cols[col] == NULL) - return 0; /* didn't get enough columns */ - p = NULL; - } - - SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16); - SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16); - SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16); - - rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16); - rt->rt_dev = cols[route_dev_col]; - - return 1; -} - -/******************************************************************** - * - * defaultroute_exists - determine if there is a default route - */ - -static int defaultroute_exists (struct rtentry *rt) -{ - int result = 0; - - if (!open_route_table()) - return 0; - - while (read_route_table(rt) != 0) { - if ((rt->rt_flags & RTF_UP) == 0) - continue; - - if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0) - continue; - if (SIN_ADDR(rt->rt_dst) == 0L) { - result = 1; - break; - } - } - - close_route_table(); - return result; -} - -/* - * have_route_to - determine if the system has any route to - * a given IP address. `addr' is in network byte order. - * Return value is 1 if yes, 0 if no, -1 if don't know. - * For demand mode to work properly, we have to ignore routes - * through our own interface. - */ -int have_route_to(u_int32_t addr) -{ - struct rtentry rt; - int result = 0; - - if (!open_route_table()) - return -1; /* don't know */ - - while (read_route_table(&rt)) { - if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0) - continue; - if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) { - result = 1; - break; - } - } - - close_route_table(); - return result; -} - -/******************************************************************** - * - * sifdefaultroute - assign a default route through the address given. - */ - -int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) -{ - struct rtentry rt; - - if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) { - u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway); - - if (old_gateway != gateway) - error("not replacing existing default route to %s [%I]", - rt.rt_dev, old_gateway); - return 0; - } - - memset (&rt, '\0', sizeof (rt)); - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = 0L; - } - - SIN_ADDR(rt.rt_gateway) = gateway; - - rt.rt_flags = RTF_UP | RTF_GATEWAY; - if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { - if ( ! ok_error ( errno )) - error("default route ioctl(SIOCADDRT): %m(%d)", errno); - return 0; - } - - default_route_gateway = gateway; - return 1; -} - -/******************************************************************** - * - * cifdefaultroute - delete a default route through the address given. - */ - -int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) -{ - struct rtentry rt; - - default_route_gateway = 0; - - memset (&rt, '\0', sizeof (rt)); - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = 0L; - } - - SIN_ADDR(rt.rt_gateway) = gateway; - - rt.rt_flags = RTF_UP | RTF_GATEWAY; - if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { - if (still_ppp()) { - if ( ! ok_error ( errno )) - error("default route ioctl(SIOCDELRT): %m (%d)", errno); - return 0; - } - } - - return 1; -} - -/******************************************************************** - * - * sifproxyarp - Make a proxy ARP entry for the peer. - */ - -int sifproxyarp (int unit, u_int32_t his_adr) -{ - struct arpreq arpreq; - char *forw_path; - - if (has_proxy_arp == 0) { - memset (&arpreq, '\0', sizeof(arpreq)); - - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - SIN_ADDR(arpreq.arp_pa) = his_adr; - arpreq.arp_flags = ATF_PERM | ATF_PUBL; -/* - * Get the hardware address of an interface on the same subnet - * as our local address. - */ - if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev, - sizeof(proxy_arp_dev))) { - error("Cannot determine ethernet address for proxy ARP"); - return 0; - } - strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); - - if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) { - if ( ! ok_error ( errno )) - error("ioctl(SIOCSARP): %m(%d)", errno); - return 0; - } - proxy_arp_addr = his_adr; - has_proxy_arp = 1; - - if (tune_kernel) { - forw_path = path_to_procfs("/sys/net/ipv4/ip_forward"); - if (forw_path != 0) { - int fd = open(forw_path, O_WRONLY); - if (fd >= 0) { - if (write(fd, "1", 1) != 1) - error("Couldn't enable IP forwarding: %m"); - close(fd); - } - } - } - } - - return 1; -} - -/******************************************************************** - * - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ - -int cifproxyarp (int unit, u_int32_t his_adr) -{ - struct arpreq arpreq; - - if (has_proxy_arp) { - has_proxy_arp = 0; - memset (&arpreq, '\0', sizeof(arpreq)); - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - SIN_ADDR(arpreq.arp_pa) = his_adr; - arpreq.arp_flags = ATF_PERM | ATF_PUBL; - strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); - - if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) { - if ( ! ok_error ( errno )) - warn("ioctl(SIOCDARP): %m(%d)", errno); - return 0; - } - } - return 1; -} - -/******************************************************************** - * - * get_ether_addr - get the hardware address of an interface on the - * the same subnet as ipaddr. - */ - -static int get_ether_addr (u_int32_t ipaddr, - struct sockaddr *hwaddr, - char *name, int namelen) -{ - struct ifreq *ifr, *ifend; - u_int32_t ina, mask; - char *aliasp; - struct ifreq ifreq; - struct ifconf ifc; - struct ifreq ifs[MAX_IFS]; - - ifc.ifc_len = sizeof(ifs); - ifc.ifc_req = ifs; - if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) { - if ( ! ok_error ( errno )) - error("ioctl(SIOCGIFCONF): %m(%d)", errno); - return 0; - } - - SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s", - ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr))); -/* - * Scan through looking for an interface with an Internet - * address on the same subnet as `ipaddr'. - */ - ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq)); - for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { - if (ifr->ifr_addr.sa_family == AF_INET) { - ina = SIN_ADDR(ifr->ifr_addr); - strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s", - ifreq.ifr_name)); -/* - * Check that the interface is up, and not point-to-point - * nor loopback. - */ - if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) - continue; - - if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0) - continue; -/* - * Get its netmask and check that it's on the right subnet. - */ - if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0) - continue; - - mask = SIN_ADDR(ifreq.ifr_addr); - SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx", - ip_ntoa(ina), ntohl(mask))); - - if (((ipaddr ^ ina) & mask) != 0) - continue; - break; - } - } - - if (ifr >= ifend) - return 0; - - strlcpy(name, ifreq.ifr_name, namelen); - - /* trim off the :1 in eth0:1 */ - aliasp = strchr(name, ':'); - if (aliasp != 0) - *aliasp = 0; - - info("found interface %s for proxy arp", name); -/* - * Now get the hardware address. - */ - memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr)); - if (ioctl (sock_fd, SIOCGIFHWADDR, &ifreq) < 0) { - error("SIOCGIFHWADDR(%s): %m(%d)", ifreq.ifr_name, errno); - return 0; - } - - memcpy (hwaddr, - &ifreq.ifr_hwaddr, - sizeof (struct sockaddr)); - - SYSDEBUG ((LOG_DEBUG, - "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - (int) ((unsigned char *) &hwaddr->sa_data)[0], - (int) ((unsigned char *) &hwaddr->sa_data)[1], - (int) ((unsigned char *) &hwaddr->sa_data)[2], - (int) ((unsigned char *) &hwaddr->sa_data)[3], - (int) ((unsigned char *) &hwaddr->sa_data)[4], - (int) ((unsigned char *) &hwaddr->sa_data)[5], - (int) ((unsigned char *) &hwaddr->sa_data)[6], - (int) ((unsigned char *) &hwaddr->sa_data)[7])); - return 1; -} - -/* - * get_if_hwaddr - get the hardware address for the specified - * network interface device. - */ -int -get_if_hwaddr(u_char *addr, char *name) -{ - struct ifreq ifreq; - int ret, sock_fd; - - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd < 0) - return 0; - memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr)); - strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name)); - ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq); - close(sock_fd); - if (ret >= 0) - memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6); - return ret; -} - -/* - * get_first_ethernet - return the name of the first ethernet-style - * interface on this system. - */ -char * -get_first_ethernet() -{ - return "eth0"; -} - -/******************************************************************** - * - * 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 (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(sock_fd, SIOCGIFCONF, &ifc) < 0) { - if ( ! ok_error ( errno )) - warn("ioctl(SIOCGIFCONF): %m(%d)", errno); - return mask; - } - - ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { -/* - * Check the interface's internet address. - */ - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - ina = SIN_ADDR(ifr->ifr_addr); - if (((ntohl(ina) ^ addr) & nmask) != 0) - continue; -/* - * Check that the interface is up, and not point-to-point nor loopback. - */ - strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) - continue; - - if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0) - continue; -/* - * Get its netmask and OR it into our mask. - */ - if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0) - continue; - mask |= SIN_ADDR(ifreq.ifr_addr); - break; - } - return mask; -} - -/******************************************************************** - * - * Internal routine to decode the version.modification.patch level - */ - -static void decode_version (char *buf, int *version, - int *modification, int *patch) -{ - char *endp; - - *version = (int) strtoul (buf, &endp, 10); - *modification = 0; - *patch = 0; - - if (endp != buf && *endp == '.') { - buf = endp + 1; - *modification = (int) strtoul (buf, &endp, 10); - if (endp != buf && *endp == '.') { - buf = endp + 1; - *patch = (int) strtoul (buf, &buf, 10); - } - } -} - -/******************************************************************** - * - * Procedure to determine if the PPP line discipline is registered. - */ - -static int -ppp_registered(void) -{ - int local_fd; - int mfd = -1; - int ret = 0; - char slave[16]; - - /* - * We used to open the serial device and set it to the ppp line - * discipline here, in order to create a ppp unit. But that is - * not a good idea - the user might have specified a device that - * they can't open (permission, or maybe it doesn't really exist). - * So we grab a pty master/slave pair and use that. - */ - if (!get_pty(&mfd, &local_fd, slave, 0)) { - no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)"; - return 0; - } - - /* - * Try to put the device into the PPP discipline. - */ - if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) { - error("ioctl(TIOCSETD(PPP)): %m(%d)", errno); - } else - ret = 1; - - close(local_fd); - close(mfd); - return ret; -} - -/******************************************************************** - * - * 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(void) -{ - int s, ok, fd; - struct ifreq ifr; - int size; - int my_version, my_modification, my_patch; - int osmaj, osmin, ospatch; - - no_ppp_msg = - "This system lacks kernel support for PPP. This could be because\n" - "the PPP kernel module could not be loaded, or because PPP was not\n" - "included in the kernel configuration. If PPP was included as a\n" - "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n" - "ppp.o exists in /lib/modules/`uname -r`/net.\n" - "See README.linux file in the ppp distribution for more details.\n"; - - /* get the kernel version now, since we are called before sys_init */ - uname(&utsname); - osmaj = osmin = ospatch = 0; - sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch); - kernel_version = KVERSION(osmaj, osmin, ospatch); - - fd = open("/dev/ppp", O_RDWR); -#if 0 - if (fd < 0 && errno == ENOENT) { - /* try making it and see if that helps. */ - if (mknod("/dev/ppp", S_IFCHR | S_IRUSR | S_IWUSR, - makedev(108, 0)) >= 0) { - fd = open("/dev/ppp", O_RDWR); - if (fd >= 0) - info("Created /dev/ppp device node"); - else - unlink("/dev/ppp"); /* didn't work, undo the mknod */ - } else if (errno == EEXIST) { - fd = open("/dev/ppp", O_RDWR); - } - } -#endif /* 0 */ - if (fd >= 0) { - new_style_driver = 1; - - /* XXX should get from driver */ - driver_version = 2; - driver_modification = 4; - driver_patch = 0; - close(fd); - return 1; - } - if (kernel_version >= KVERSION(2,3,13)) { - if (errno == ENOENT) - no_ppp_msg = - "pppd is unable to open the /dev/ppp device.\n" - "You need to create the /dev/ppp device node by\n" - "executing the following command as root:\n" - " mknod /dev/ppp c 108 0\n"; - return 0; - } - -/* - * Open a socket for doing the ioctl operations. - */ - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) - return 0; - - strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); - ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; -/* - * If the device did not exist then attempt to create one by putting the - * current tty into the PPP discipline. If this works then obtain the - * flags for the device again. - */ - if (!ok) { - if (ppp_registered()) { - strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); - ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; - } - } -/* - * Ensure that the hardware address is for PPP and not something else - */ - if (ok) - ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0; - - if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP)) - ok = 0; - -/* - * This is the PPP device. Validate the version of the driver at this - * point to ensure that this program will work with the driver. - */ - if (ok) { - char abBuffer [1024]; - - ifr.ifr_data = abBuffer; - size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr); - if (size < 0) { - error("Couldn't read driver version: %m"); - ok = 0; - no_ppp_msg = "Sorry, couldn't verify kernel driver version\n"; - - } else { - decode_version(abBuffer, - &driver_version, - &driver_modification, - &driver_patch); -/* - * Validate the version of the driver against the version that we used. - */ - decode_version(VERSION, - &my_version, - &my_modification, - &my_patch); - - /* The version numbers must match */ - if (driver_version != my_version) - ok = 0; - - /* The modification levels must be legal */ - if (driver_modification < 3) { - if (driver_modification >= 2) { - /* we can cope with 2.2.0 and above */ - driver_is_old = 1; - } else { - ok = 0; - } - } - - close (s); - if (!ok) { - slprintf(route_buffer, sizeof(route_buffer), - "Sorry - PPP driver version %d.%d.%d is out of date\n", - driver_version, driver_modification, driver_patch); - - no_ppp_msg = route_buffer; - } - } - } - return ok; -} - -/******************************************************************** - * - * sifvjcomp - config tcp header compression - */ - -int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) -{ - u_int x = get_flags(ppp_dev_fd); - - if (vjcomp) { - if (ioctl (ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { - if (! ok_error (errno)) - error("ioctl(PPPIOCSMAXCID): %m(%d)", errno); - vjcomp = 0; - } - } - - x = vjcomp ? x | SC_COMP_TCP : x &~ SC_COMP_TCP; - x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID; - set_flags (ppp_dev_fd, x); - - return 1; -} - -/******************************************************************** - * - * sifup - Config the interface up and enable IP packets to pass. - */ - -int sifup(int u) -{ - struct ifreq ifr; - - memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl (SIOCGIFFLAGS): %m(%d)", errno); - return 0; - } - - ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT); - if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFFLAGS): %m(%d)", errno); - return 0; - } - if_is_up++; - - return 1; -} - -/******************************************************************** - * - * sifdown - Disable the indicated protocol and config the interface - * down if there are no remaining protocols. - */ - -int sifdown (int u) -{ - struct ifreq ifr; - - if (if_is_up && --if_is_up > 0) - return 1; - - memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl (SIOCGIFFLAGS): %m(%d)", errno); - return 0; - } - - ifr.ifr_flags &= ~IFF_UP; - ifr.ifr_flags |= IFF_POINTOPOINT; - if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFFLAGS): %m(%d)", errno); - return 0; - } - return 1; -} - -/******************************************************************** - * - * sifaddr - Config the interface IP addresses and netmask. - */ - -int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, - u_int32_t net_mask) -{ - struct ifreq ifr; - struct rtentry rt; - - memset (&ifr, '\0', sizeof (ifr)); - memset (&rt, '\0', sizeof (rt)); - - SET_SA_FAMILY (ifr.ifr_addr, AF_INET); - SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); - SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); - - strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); -/* - * Set our IP address - */ - SIN_ADDR(ifr.ifr_addr) = our_adr; - if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - if (errno != EEXIST) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFADDR): %m(%d)", errno); - } - else { - warn("ioctl(SIOCSIFADDR): Address already exists"); - } - return (0); - } -/* - * Set the gateway address - */ - SIN_ADDR(ifr.ifr_dstaddr) = his_adr; - if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFDSTADDR): %m(%d)", errno); - return (0); - } -/* - * Set the netmask. - * For recent kernels, force the netmask to 255.255.255.255. - */ - if (kernel_version >= KVERSION(2,1,16)) - net_mask = ~0L; - if (net_mask != 0) { - SIN_ADDR(ifr.ifr_netmask) = net_mask; - if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFNETMASK): %m(%d)", errno); - return (0); - } - } -/* - * Add the device route - */ - if (kernel_version < KVERSION(2,1,16)) { - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - rt.rt_dev = ifname; - - SIN_ADDR(rt.rt_gateway) = 0L; - SIN_ADDR(rt.rt_dst) = his_adr; - rt.rt_flags = RTF_UP | RTF_HOST; - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = -1L; - } - - if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCADDRT) device route: %m(%d)", errno); - return (0); - } - } - - /* set ip_dynaddr in demand mode if address changes */ - if (demand && tune_kernel && !dynaddr_set - && our_old_addr && our_old_addr != our_adr) { - /* set ip_dynaddr if possible */ - char *path; - int fd; - - path = path_to_procfs("/sys/net/ipv4/ip_dynaddr"); - if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) { - if (write(fd, "1", 1) != 1) - error("Couldn't enable dynamic IP addressing: %m"); - close(fd); - } - dynaddr_set = 1; /* only 1 attempt */ - } - our_old_addr = 0; - - return 1; -} - -/******************************************************************** - * - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - */ - -int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) -{ - struct ifreq ifr; - - if (kernel_version < KVERSION(2,1,16)) { -/* - * Delete the route through the device - */ - struct rtentry rt; - memset (&rt, '\0', sizeof (rt)); - - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - rt.rt_dev = ifname; - - SIN_ADDR(rt.rt_gateway) = 0; - SIN_ADDR(rt.rt_dst) = his_adr; - rt.rt_flags = RTF_UP | RTF_HOST; - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = -1L; - } - - if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { - if (still_ppp() && ! ok_error (errno)) - error("ioctl(SIOCDELRT) device route: %m(%d)", errno); - return (0); - } - } - - /* This way it is possible to have an IPX-only or IPv6-only interface */ - memset(&ifr, 0, sizeof(ifr)); - SET_SA_FAMILY(ifr.ifr_addr, AF_INET); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) { - error("ioctl(SIOCSIFADDR): %m(%d)", errno); - return 0; - } - } - - our_old_addr = our_adr; - - return 1; -} - -#ifdef INET6 -/******************************************************************** - * - * sif6addr - Config the interface with an IPv6 link-local address - */ -int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) -{ - struct in6_ifreq ifr6; - struct ifreq ifr; - struct in6_rtmsg rt6; - - if (sock6_fd < 0) { - errno = -sock6_fd; - error("IPv6 socket creation failed: %m"); - return 0; - } - memset(&ifr, 0, sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { - error("sif6addr: ioctl(SIOCGIFINDEX): %m (%d)", errno); - return 0; - } - - /* Local interface */ - memset(&ifr6, 0, sizeof(ifr6)); - IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); - ifr6.ifr6_ifindex = ifr.ifr_ifindex; - ifr6.ifr6_prefixlen = 10; - - if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) { - error("sif6addr: ioctl(SIOCSIFADDR): %m (%d)", errno); - return 0; - } - - /* Route to remote host */ - memset(&rt6, 0, sizeof(rt6)); - IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64); - rt6.rtmsg_flags = RTF_UP; - rt6.rtmsg_dst_len = 10; - rt6.rtmsg_ifindex = ifr.ifr_ifindex; - rt6.rtmsg_metric = 1; - - if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) { - error("sif6addr: ioctl(SIOCADDRT): %m (%d)", errno); - return 0; - } - - return 1; -} - - -/******************************************************************** - * - * cif6addr - Remove IPv6 address from interface - */ -int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) -{ - struct ifreq ifr; - struct in6_ifreq ifr6; - - if (sock6_fd < 0) { - errno = -sock6_fd; - error("IPv6 socket creation failed: %m"); - return 0; - } - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { - error("cif6addr: ioctl(SIOCGIFINDEX): %m (%d)", errno); - return 0; - } - - memset(&ifr6, 0, sizeof(ifr6)); - IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); - ifr6.ifr6_ifindex = ifr.ifr_ifindex; - ifr6.ifr6_prefixlen = 10; - - if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) { - if (errno != EADDRNOTAVAIL) { - if (! ok_error (errno)) - error("cif6addr: ioctl(SIOCDIFADDR): %m (%d)", errno); - } - else { - warn("cif6addr: ioctl(SIOCDIFADDR): No such address"); - } - return (0); - } - return 1; -} -#endif /* INET6 */ - -/* - * get_pty - get a pty master/slave pair and chown the slave side - * to the uid given. Assumes slave_name points to >= 16 bytes of space. - */ -int -get_pty(master_fdp, slave_fdp, slave_name, uid) - int *master_fdp; - int *slave_fdp; - char *slave_name; - int uid; -{ - int i, mfd, sfd = -1; - char pty_name[16]; - struct termios tios; - -#ifdef TIOCGPTN - /* - * Try the unix98 way first. - */ - mfd = open("/dev/ptmx", O_RDWR); - if (mfd >= 0) { - int ptn; - if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) { - slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn); - chmod(pty_name, S_IRUSR | S_IWUSR); -#ifdef TIOCSPTLCK - ptn = 0; - if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0) - warn("Couldn't unlock pty slave %s: %m", pty_name); -#endif - if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0) - warn("Couldn't open pty slave %s: %m", pty_name); - } - } -#endif /* TIOCGPTN */ - - if (sfd < 0) { - /* the old way - scan through the pty name space */ - for (i = 0; i < 64; ++i) { - slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x", - 'p' + i / 16, i % 16); - mfd = open(pty_name, O_RDWR, 0); - if (mfd >= 0) { - pty_name[5] = 't'; - sfd = open(pty_name, O_RDWR | O_NOCTTY, 0); - if (sfd >= 0) { - fchown(sfd, uid, -1); - fchmod(sfd, S_IRUSR | S_IWUSR); - break; - } - close(mfd); - } - } - } - - if (sfd < 0) - return 0; - - strlcpy(slave_name, pty_name, 16); - *master_fdp = mfd; - *slave_fdp = sfd; - if (tcgetattr(sfd, &tios) == 0) { - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); - tios.c_cflag |= CS8 | CREAD | CLOCAL; - tios.c_iflag = IGNPAR; - tios.c_oflag = 0; - tios.c_lflag = 0; - if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0) - warn("couldn't set attributes on pty: %m"); - } else - warn("couldn't get attributes on pty: %m"); - - return 1; -} - -/******************************************************************** - * - * open_loopback - open the device we use for getting packets - * in demand mode. Under Linux, we use a pty master/slave pair. - */ -int -open_ppp_loopback(void) -{ - int flags; - - looped = 1; - if (new_style_driver) { - /* allocate ourselves a ppp unit */ - if (make_ppp_unit() < 0) - die(1); - set_flags(ppp_dev_fd, SC_LOOP_TRAFFIC); - set_kdebugflag(kdebugflag); - ppp_fd = -1; - return ppp_dev_fd; - } - - if (!get_pty(&master_fd, &slave_fd, loop_name, 0)) - fatal("No free pty for loopback"); - SYSDEBUG(("using %s for loopback", loop_name)); - - set_ppp_fd(slave_fd); - - flags = fcntl(master_fd, F_GETFL); - if (flags == -1 || - fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("couldn't set master loopback to nonblock: %m(%d)", errno); - - flags = fcntl(ppp_fd, F_GETFL); - if (flags == -1 || - fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("couldn't set slave loopback to nonblock: %m(%d)", errno); - - if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0) - fatal("ioctl(TIOCSETD): %m(%d)", errno); -/* - * Find out which interface we were given. - */ - if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0) - fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno); -/* - * Enable debug in the driver if requested. - */ - set_kdebugflag (kdebugflag); - - return master_fd; -} - -/******************************************************************** - * - * restore_loop - reattach the ppp unit to the loopback. - * - * The kernel ppp driver automatically reattaches the ppp unit to - * the loopback if the serial port is set to a line discipline other - * than ppp, or if it detects a modem hangup. The former will happen - * in disestablish_ppp if the latter hasn't already happened, so we - * shouldn't need to do anything. - * - * Just to be sure, set the real serial port to the normal discipline. - */ - -static void -restore_loop(void) -{ - looped = 1; - if (new_style_driver) { - set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC); - return; - } - if (ppp_fd != slave_fd) { - (void) ioctl(ppp_fd, TIOCSETD, &tty_disc); - set_ppp_fd(slave_fd); - } -} - -/******************************************************************** - * - * sifnpmode - Set the mode for handling packets for a given NP. - */ - -int -sifnpmode(u, proto, mode) - int u; - int proto; - enum NPmode mode; -{ - struct npioctl npi; - - npi.protocol = proto; - npi.mode = mode; - if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) { - if (! ok_error (errno)) - error("ioctl(PPPIOCSNPMODE, %d, %d): %m (%d)", - proto, mode, errno); - return 0; - } - return 1; -} - - -/******************************************************************** - * - * sipxfaddr - Config the interface IPX networknumber - */ - -int sipxfaddr (int unit, unsigned long int network, unsigned char * node ) -{ - int result = 1; - -#ifdef IPX_CHANGE - int skfd; - struct ifreq ifr; - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; - - skfd = socket (AF_IPX, SOCK_DGRAM, 0); - if (skfd < 0) { - if (! ok_error (errno)) - dbglog("socket(AF_IPX): %m (%d)", errno); - result = 0; - } - else { - memset (&ifr, '\0', sizeof (ifr)); - strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - memcpy (sipx->sipx_node, node, IPX_NODE_LEN); - sipx->sipx_family = AF_IPX; - sipx->sipx_port = 0; - sipx->sipx_network = htonl (network); - sipx->sipx_type = IPX_FRAME_ETHERII; - sipx->sipx_action = IPX_CRTITF; -/* - * Set the IPX device - */ - if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - result = 0; - if (errno != EEXIST) { - if (! ok_error (errno)) - dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (%d)", errno); - } - else { - warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists"); - } - } - close (skfd); - } -#endif - return result; -} - -/******************************************************************** - * - * cipxfaddr - Clear the information for the IPX network. The IPX routes - * are removed and the device is no longer able to pass IPX - * frames. - */ - -int cipxfaddr (int unit) -{ - int result = 1; - -#ifdef IPX_CHANGE - int skfd; - struct ifreq ifr; - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; - - skfd = socket (AF_IPX, SOCK_DGRAM, 0); - if (skfd < 0) { - if (! ok_error (errno)) - dbglog("socket(AF_IPX): %m (%d)", errno); - result = 0; - } - else { - memset (&ifr, '\0', sizeof (ifr)); - strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - sipx->sipx_type = IPX_FRAME_ETHERII; - sipx->sipx_action = IPX_DLTITF; - sipx->sipx_family = AF_IPX; -/* - * Set the IPX device - */ - if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (%d)", errno); - result = 0; - } - close (skfd); - } -#endif - return result; -} - -/* - * Use the hostname as part of the random number seed. - */ -int -get_host_seed() -{ - int h; - char *p = hostname; - - h = 407; - for (p = hostname; *p != 0; ++p) - h = h * 37 + *p; - return h; -} - -/******************************************************************** - * - * sys_check_options - check the options that the user specified - */ - -int -sys_check_options(void) -{ -#ifdef IPX_CHANGE -/* - * Disable the IPX protocol if the support is not present in the kernel. - */ - char *path; - - if (ipxcp_protent.enabled_flag) { - struct stat stat_buf; - if ((path = path_to_procfs("/net/ipx_interface")) == 0 - || lstat(path, &stat_buf) < 0) { - error("IPX support is not present in the kernel\n"); - ipxcp_protent.enabled_flag = 0; - } - } -#endif - if (demand && driver_is_old) { - option_error("demand dialling is not supported by kernel driver " - "version %d.%d.%d", driver_version, driver_modification, - driver_patch); - return 0; - } - if (multilink && !new_style_driver) { - warn("Warning: multilink is not supported by the kernel driver"); - multilink = 0; - } - return 1; -} diff --git a/mdk-stage1/ppp/pppd/sys-linux.c.wtmp b/mdk-stage1/ppp/pppd/sys-linux.c.wtmp deleted file mode 100644 index f1b48423e..000000000 --- a/mdk-stage1/ppp/pppd/sys-linux.c.wtmp +++ /dev/null @@ -1,2750 +0,0 @@ -/* - * sys-linux.c - System-dependent procedures for setting up - * PPP interfaces on Linux systems - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <sys/errno.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <sys/utsname.h> -#include <sys/sysmacros.h> - -#include <stdio.h> -#include <stdlib.h> -#include <syslog.h> -#include <string.h> -#include <time.h> -#include <memory.h> -#include <utmp.h> -#include <mntent.h> -#include <signal.h> -#include <fcntl.h> -#include <ctype.h> -#include <termios.h> -#include <unistd.h> - -/* This is in netdevice.h. However, this compile will fail miserably if - you attempt to include netdevice.h because it has so many references - to __memcpy functions which it should not attempt to do. So, since I - really don't use it, but it must be defined, define it now. */ - -#ifndef MAX_ADDR_LEN -#define MAX_ADDR_LEN 7 -#endif - -#if __GLIBC__ >= 2 -#include <asm/types.h> /* glibc 2 conflicts with linux/types.h */ -#include <net/if.h> -#include <net/if_arp.h> -#include <net/route.h> -#include <netinet/if_ether.h> -#else -#include <linux/types.h> -#include <linux/if.h> -#include <linux/if_arp.h> -#include <linux/route.h> -#include <linux/if_ether.h> -#endif -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <linux/ppp_defs.h> -#include <linux/if_ppp.h> - -#include "pppd.h" -#include "fsm.h" -#include "ipcp.h" - -#ifdef IPX_CHANGE -#include "ipxcp.h" -#if __GLIBC__ >= 2 && \ - !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0) -#include <netipx/ipx.h> -#else -#include <linux/ipx.h> -#endif -#endif /* IPX_CHANGE */ - -#ifdef PPP_FILTER -#include <net/bpf.h> -#include <linux/filter.h> -#endif /* PPP_FILTER */ - -#ifdef LOCKLIB -#include <sys/locks.h> -#endif - -#ifdef INET6 -#ifndef _LINUX_IN6_H -/* - * This is in linux/include/net/ipv6.h. - */ - -struct in6_ifreq { - struct in6_addr ifr6_addr; - __u32 ifr6_prefixlen; - unsigned int ifr6_ifindex; -}; -#endif - -#define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \ - memset(&sin6.s6_addr, 0, sizeof(struct in6_addr)); \ - sin6.s6_addr16[0] = htons(0xfe80); \ - eui64_copy(eui64, sin6.s6_addr32[2]); \ - } while (0) - -#endif /* INET6 */ - -/* We can get an EIO error on an ioctl if the modem has hung up */ -#define ok_error(num) ((num)==EIO) - -static int tty_disc = N_TTY; /* The TTY discipline */ -static int ppp_disc = N_PPP; /* The PPP discpline */ -static int initfdflags = -1; /* Initial file descriptor flags for fd */ -static int ppp_fd = -1; /* fd which is set to PPP discipline */ -static int sock_fd = -1; /* socket for doing interface ioctls */ -static int slave_fd = -1; -static int master_fd = -1; -#ifdef INET6 -static int sock6_fd = -1; -#endif /* INET6 */ -static int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */ -static int chindex; /* channel index (new style driver) */ - -static fd_set in_fds; /* set of fds that wait_input waits for */ -static int max_in_fd; /* highest fd set in in_fds */ - -static int has_proxy_arp = 0; -static int driver_version = 0; -static int driver_modification = 0; -static int driver_patch = 0; -static int driver_is_old = 0; -static int restore_term = 0; /* 1 => we've munged the terminal */ -static struct termios inittermios; /* Initial TTY termios */ - -static int new_style_driver = 0; - -static char loop_name[20]; -static unsigned char inbuf[512]; /* buffer for chars read from loopback */ - -static int if_is_up; /* Interface has been marked up */ -static u_int32_t default_route_gateway; /* Gateway for default route added */ -static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ -static char proxy_arp_dev[16]; /* Device for proxy arp entry */ -static u_int32_t our_old_addr; /* for detecting address changes */ -static int dynaddr_set; /* 1 if ip_dynaddr set */ -static int looped; /* 1 if using loop */ -static int link_mtu; /* mtu for the link (not bundle) */ - -static struct utsname utsname; /* for the kernel version */ -static int kernel_version; -#define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p)) - -#define MAX_IFS 100 - -#define FLAGS_GOOD (IFF_UP | IFF_BROADCAST) -#define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \ - IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP) - -#define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr) - -/* Prototypes for procedures local to this file. */ -static int get_flags (int fd); -static void set_flags (int fd, int flags); -static int translate_speed (int bps); -static int baud_rate_of (int speed); -static void close_route_table (void); -static int open_route_table (void); -static int read_route_table (struct rtentry *rt); -static int defaultroute_exists (struct rtentry *rt); -static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr, - char *name, int namelen); -static void decode_version (char *buf, int *version, int *mod, int *patch); -static int set_kdebugflag(int level); -static int ppp_registered(void); -static int make_ppp_unit(void); -static void restore_loop(void); /* Transfer ppp unit back to loopback */ - -extern u_char inpacket_buf[]; /* borrowed from main.c */ - -/* - * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, - * if it exists. - */ - -#define SET_SA_FAMILY(addr, family) \ - memset ((char *) &(addr), '\0', sizeof(addr)); \ - addr.sa_family = (family); - -/* - * Determine if the PPP connection should still be present. - */ - -extern int hungup; - -/* new_fd is the fd of a tty */ -static void set_ppp_fd (int new_fd) -{ - SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", new_fd)); - ppp_fd = new_fd; - if (!new_style_driver) - ppp_dev_fd = new_fd; -} - -static int still_ppp(void) -{ - if (new_style_driver) - return !hungup && ppp_fd >= 0; - if (!hungup || ppp_fd == slave_fd) - return 1; - if (slave_fd >= 0) { - set_ppp_fd(slave_fd); - return 1; - } - return 0; -} - -/******************************************************************** - * - * Functions to read and set the flags value in the device driver - */ - -static int get_flags (int fd) -{ - int flags; - - if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &flags) < 0) { - if ( ok_error (errno) ) - flags = 0; - else - fatal("ioctl(PPPIOCGFLAGS): %m"); - } - - SYSDEBUG ((LOG_DEBUG, "get flags = %x\n", flags)); - return flags; -} - -/********************************************************************/ - -static void set_flags (int fd, int flags) -{ - SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags)); - - if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) { - if (! ok_error (errno) ) - fatal("ioctl(PPPIOCSFLAGS, %x): %m", flags, errno); - } -} - -/******************************************************************** - * - * sys_init - System-dependent initialization. - */ - -void sys_init(void) -{ - int flags; - - if (new_style_driver) { - ppp_dev_fd = open("/dev/ppp", O_RDWR); - if (ppp_dev_fd < 0) - fatal("Couldn't open /dev/ppp: %m"); - flags = fcntl(ppp_dev_fd, F_GETFL); - if (flags == -1 - || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("Couldn't set /dev/ppp to nonblock: %m"); - } - - /* Get an internet socket for doing socket ioctls. */ - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd < 0) - fatal("Couldn't create IP socket: %m(%d)", errno); - -#ifdef INET6 - sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0); - if (sock6_fd < 0) - sock6_fd = -errno; /* save errno for later */ -#endif - - FD_ZERO(&in_fds); - max_in_fd = 0; -} - -/******************************************************************** - * - * sys_cleanup - restore any system state we modified before exiting: - * mark the interface down, delete default route and/or proxy arp entry. - * This shouldn't call die() because it's called from die(). - */ - -void sys_cleanup(void) -{ -/* - * Take down the device - */ - if (if_is_up) { - if_is_up = 0; - sifdown(0); - } -/* - * Delete any routes through the device. - */ - if (default_route_gateway != 0) - cifdefaultroute(0, 0, default_route_gateway); - - if (has_proxy_arp) - cifproxyarp(0, proxy_arp_addr); -} - -/******************************************************************** - * - * sys_close - Clean up in a child process before execing. - */ -void -sys_close(void) -{ - if (new_style_driver) - close(ppp_dev_fd); - if (sock_fd >= 0) - close(sock_fd); - if (slave_fd >= 0) - close(slave_fd); - if (master_fd >= 0) - close(master_fd); - closelog(); -} - -/******************************************************************** - * - * set_kdebugflag - Define the debugging level for the kernel - */ - -static int set_kdebugflag (int requested_level) -{ - if (new_style_driver && ifunit < 0) - return 1; - if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) { - if ( ! ok_error (errno) ) - error("ioctl(PPPIOCSDEBUG): %m"); - return (0); - } - SYSDEBUG ((LOG_INFO, "set kernel debugging level to %d", - requested_level)); - return (1); -} - -/******************************************************************** - * - * tty_establish_ppp - Turn the serial port into a ppp interface. - */ - -int tty_establish_ppp (int tty_fd) -{ - int x; - int fd = -1; - -/* - * Ensure that the tty device is in exclusive mode. - */ - if (ioctl(tty_fd, TIOCEXCL, 0) < 0) { - if ( ! ok_error ( errno )) - warn("Couldn't make tty exclusive: %m"); - } -/* - * Demand mode - prime the old ppp device to relinquish the unit. - */ - if (!new_style_driver && looped - && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) { - error("ioctl(transfer ppp unit): %m"); - return -1; - } -/* - * Set the current tty to the PPP discpline - */ - -#ifndef N_SYNC_PPP -#define N_SYNC_PPP 14 -#endif - ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP; - if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) { - if ( ! ok_error (errno) ) { - error("Couldn't set tty to PPP discipline: %m"); - return -1; - } - } - - if (new_style_driver) { - /* Open another instance of /dev/ppp and connect the channel to it */ - int flags; - - if (ioctl(tty_fd, PPPIOCGCHAN, &chindex) == -1) { - error("Couldn't get channel number: %m"); - goto err; - } - dbglog("using channel %d", chindex); - fd = open("/dev/ppp", O_RDWR); - if (fd < 0) { - error("Couldn't reopen /dev/ppp: %m"); - goto err; - } - if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) { - error("Couldn't attach to channel %d: %m", chindex); - goto err_close; - } - flags = fcntl(fd, F_GETFL); - if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("Couldn't set /dev/ppp (channel) to nonblock: %m"); - set_ppp_fd(fd); - - if (!looped) - ifunit = -1; - if (!looped && !multilink) { - /* - * Create a new PPP unit. - */ - if (make_ppp_unit() < 0) - goto err_close; - } - - if (looped) - set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) & ~SC_LOOP_TRAFFIC); - - if (!multilink) { - add_fd(ppp_dev_fd); - if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) { - error("Couldn't attach to PPP unit %d: %m", ifunit); - goto err_close; - } - } - - } else { - /* - * Old-style driver: find out which interface we were given. - */ - set_ppp_fd (tty_fd); - if (ioctl(tty_fd, PPPIOCGUNIT, &x) < 0) { - if (ok_error (errno)) - goto err; - fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno); - } - /* Check that we got the same unit again. */ - if (looped && x != ifunit) - fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x); - ifunit = x; - - /* - * Fetch the initial file flags and reset blocking mode on the file. - */ - initfdflags = fcntl(tty_fd, F_GETFL); - if (initfdflags == -1 || - fcntl(tty_fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { - if ( ! ok_error (errno)) - warn("Couldn't set device to non-blocking mode: %m"); - } - } - - looped = 0; - - /* - * Enable debug in the driver if requested. - */ - if (!looped) - set_kdebugflag (kdebugflag); - -#define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP) -#define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \ - | SC_LOG_FLUSH) - - set_flags(ppp_fd, ((get_flags(ppp_fd) & ~(SC_RCVB | SC_LOGB)) - | ((kdebugflag * SC_DEBUG) & SC_LOGB))); - - SYSDEBUG ((LOG_NOTICE, "Using version %d.%d.%d of PPP driver", - driver_version, driver_modification, driver_patch)); - - return ppp_fd; - - err_close: - close(fd); - err: - if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno)) - warn("Couldn't reset tty to normal line discipline: %m"); - return -1; -} - -/******************************************************************** - * - * tty_disestablish_ppp - Restore the serial port to normal operation, - * and reconnect the ppp unit to the loopback if in demand mode. - * This shouldn't call die() because it's called from die(). - */ - -void tty_disestablish_ppp(int tty_fd) -{ - if (demand) - restore_loop(); - if (!hungup) { -/* - * Flush the tty output buffer so that the TIOCSETD doesn't hang. - */ - if (tcflush(tty_fd, TCIOFLUSH) < 0) - warn("tcflush failed: %m"); -/* - * Restore the previous line discipline - */ - if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) { - if ( ! ok_error (errno)) - error("ioctl(TIOCSETD, N_TTY): %m"); - } - - if (ioctl(tty_fd, TIOCNXCL, 0) < 0) { - if ( ! ok_error (errno)) - warn("ioctl(TIOCNXCL): %m(%d)", errno); - } - - /* Reset non-blocking mode on fd. */ - if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) { - if ( ! ok_error (errno)) - warn("Couldn't restore device fd flags: %m"); - } - } - initfdflags = -1; - - if (new_style_driver) { - close(ppp_fd); - ppp_fd = -1; - if (!looped && ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0) - error("Couldn't release PPP unit: %m"); - if (!multilink) - remove_fd(ppp_dev_fd); - } -} - -/* - * make_ppp_unit - make a new ppp unit for ppp_dev_fd. - * Assumes new_style_driver. - */ -static int make_ppp_unit() -{ - int x; - - ifunit = req_unit; - x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); - if (x < 0 && req_unit >= 0 && errno == EEXIST) { - warn("Couldn't allocate PPP unit %d as it is already in use"); - ifunit = -1; - x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); - } - if (x < 0) - error("Couldn't create new ppp unit: %m"); - return x; -} - -/* - * cfg_bundle - configure the existing bundle. - * Used in demand mode. - */ -void cfg_bundle(int mrru, int mtru, int rssn, int tssn) -{ - int flags; - - if (!new_style_driver) - return; - - /* set the mrru, mtu and flags */ - if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0) - error("Couldn't set MRRU: %m"); - flags = get_flags(ppp_dev_fd); - flags &= ~(SC_MP_SHORTSEQ | SC_MP_XSHORTSEQ); - flags |= (rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0) - | (mrru? SC_MULTILINK: 0); - - set_flags(ppp_dev_fd, flags); - - /* connect up the channel */ - if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0) - fatal("Couldn't attach to PPP unit %d: %m", ifunit); - add_fd(ppp_dev_fd); -} - -/* - * make_new_bundle - create a new PPP unit (i.e. a bundle) - * and connect our channel to it. This should only get called - * if `multilink' was set at the time establish_ppp was called. - * In demand mode this uses our existing bundle instead of making - * a new one. - */ -void make_new_bundle(int mrru, int mtru, int rssn, int tssn) -{ - if (!new_style_driver) - return; - - /* make us a ppp unit */ - if (make_ppp_unit() < 0) - die(1); - - /* set the mrru and flags */ - cfg_bundle(mrru, mtru, rssn, tssn); -} - -/* - * bundle_attach - attach our link to a given PPP unit. - * We assume the unit is controlled by another pppd. - */ -int bundle_attach(int ifnum) -{ - if (!new_style_driver) - return -1; - - if (ioctl(ppp_dev_fd, PPPIOCATTACH, &ifnum) < 0) { - if (errno == ENXIO) - return 0; /* doesn't still exist */ - fatal("Couldn't attach to interface unit %d: %m\n", ifnum); - } - if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0) - fatal("Couldn't connect to interface unit %d: %m", ifnum); - set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_MULTILINK); - - ifunit = ifnum; - return 1; -} - -/******************************************************************** - * - * clean_check - Fetch the flags for the device and generate - * appropriate error messages. - */ -void clean_check(void) -{ - int x; - char *s; - - if (still_ppp()) { - if (ioctl(ppp_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 = "all had bit 7 set to 1"; - break; - - case SC_RCV_B7_1: - s = "all had bit 7 set to 0"; - break; - - case SC_RCV_EVNP: - s = "all had odd parity"; - break; - - case SC_RCV_ODDP: - s = "all had even parity"; - break; - } - - if (s != NULL) { - warn("Receive serial link is not 8-bit clean:"); - warn("Problem: %s", s); - } - } - } -} - - -/* - * 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 B57600 - { 57600, B57600 }, -#endif -#ifdef B76800 - { 76800, B76800 }, -#endif -#ifdef B115200 - { 115200, B115200 }, -#endif -#ifdef EXTA - { 19200, EXTA }, -#endif -#ifdef EXTB - { 38400, EXTB }, -#endif -#ifdef B230400 - { 230400, B230400 }, -#endif -#ifdef B460800 - { 460800, B460800 }, -#endif -#ifdef B921600 - { 921600, B921600 }, -#endif - { 0, 0 } -}; - -/******************************************************************** - * - * Translate from bits/second to a speed_t. - */ - -static int translate_speed (int bps) -{ - struct speed *speedp; - - if (bps != 0) { - for (speedp = speeds; speedp->speed_int; speedp++) { - if (bps == speedp->speed_int) - return speedp->speed_val; - } - warn("speed %d not supported", bps); - } - return 0; -} - -/******************************************************************** - * - * Translate from a speed_t to bits/second. - */ - -static int baud_rate_of (int speed) -{ - struct speed *speedp; - - if (speed != 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. - */ - -void set_up_tty(int tty_fd, int local) -{ - int speed; - struct termios tios; - - setdtr(tty_fd, 1); - if (tcgetattr(tty_fd, &tios) < 0) { - if (!ok_error(errno)) - fatal("tcgetattr: %m(%d)", errno); - return; - } - - if (!restore_term) - inittermios = tios; - - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); - tios.c_cflag |= CS8 | CREAD | HUPCL; - - tios.c_iflag = IGNBRK | IGNPAR; - tios.c_oflag = 0; - tios.c_lflag = 0; - tios.c_cc[VMIN] = 1; - tios.c_cc[VTIME] = 0; - - if (local || !modem) - tios.c_cflag ^= (CLOCAL | HUPCL); - - switch (crtscts) { - case 1: - tios.c_cflag |= CRTSCTS; - break; - - case -2: - tios.c_iflag |= IXON | IXOFF; - tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ - tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ - break; - - case -1: - tios.c_cflag &= ~CRTSCTS; - break; - - default: - break; - } - - speed = translate_speed(inspeed); - if (speed) { - cfsetospeed (&tios, speed); - cfsetispeed (&tios, speed); - } -/* - * We can't proceed if the serial port speed is B0, - * since that implies that the serial port is disabled. - */ - else { - speed = cfgetospeed(&tios); - if (speed == B0) - fatal("Baud rate for %s is 0; need explicit baud rate", devnam); - } - - if (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0) - if (!ok_error(errno)) - fatal("tcsetattr: %m"); - - baud_rate = baud_rate_of(speed); - restore_term = 1; -} - -/******************************************************************** - * - * setdtr - control the DTR line on the serial port. - * This is called from die(), so it shouldn't call die(). - */ - -void setdtr (int tty_fd, int on) -{ - int modembits = TIOCM_DTR; - - ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits); -} - -/******************************************************************** - * - * restore_tty - restore the terminal to the saved settings. - */ - -void restore_tty (int tty_fd) -{ - if (restore_term) { - restore_term = 0; -/* - * Turn off echoing, because otherwise we can get into - * a loop with the tty and the modem echoing to each other. - * We presume we are the sole user of this tty device, so - * when we close it, it will revert to its defaults anyway. - */ - if (!default_device) - inittermios.c_lflag &= ~(ECHO | ECHONL); - - if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) { - if (! ok_error (errno)) - warn("tcsetattr: %m"); - } - } -} - -/******************************************************************** - * - * output - Output PPP packet. - */ - -void output (int unit, unsigned char *p, int len) -{ - int fd = ppp_fd; - int proto; - - if (debug) - dbglog("sent %P", p, len); - - if (len < PPP_HDRLEN) - return; - if (new_style_driver) { - p += 2; - len -= 2; - proto = (p[0] << 8) + p[1]; - if (ifunit >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG)) - fd = ppp_dev_fd; - } - if (write(fd, p, len) < 0) { - if (errno == EWOULDBLOCK || errno == ENOBUFS - || errno == ENXIO || errno == EIO || errno == EINTR) - warn("write: warning: %m (%d)", errno); - else - error("write: %m (%d)", errno); - } -} - -/******************************************************************** - * - * wait_input - wait until there is data available, - * for the length of time specified by *timo (indefinite - * if timo is NULL). - */ - -void wait_input(struct timeval *timo) -{ - fd_set ready, exc; - int n; - - ready = in_fds; - exc = in_fds; - n = select(max_in_fd + 1, &ready, NULL, &exc, timo); - if (n < 0 && errno != EINTR) - fatal("select: %m(%d)", errno); -} - -/* - * add_fd - add an fd to the set that wait_input waits for. - */ -void add_fd(int fd) -{ - FD_SET(fd, &in_fds); - if (fd > max_in_fd) - max_in_fd = fd; -} - -/* - * remove_fd - remove an fd from the set that wait_input waits for. - */ -void remove_fd(int fd) -{ - FD_CLR(fd, &in_fds); -} - - -/******************************************************************** - * - * read_packet - get a PPP packet from the serial device. - */ - -int read_packet (unsigned char *buf) -{ - int len, nr; - - len = PPP_MRU + PPP_HDRLEN; - if (new_style_driver) { - *buf++ = PPP_ALLSTATIONS; - *buf++ = PPP_UI; - len -= 2; - } - nr = -1; - if (ppp_fd >= 0) { - nr = read(ppp_fd, buf, len); - if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR) - error("read: %m"); - if (nr < 0 && errno == ENXIO) - return 0; - } - if (nr < 0 && new_style_driver && ifunit >= 0) { - /* N.B. we read ppp_fd first since LCP packets come in there. */ - nr = read(ppp_dev_fd, buf, len); - if (nr < 0 && errno != EWOULDBLOCK && errno != EIO && errno != EINTR) - error("read /dev/ppp: %m"); - if (nr < 0 && errno == ENXIO) - return 0; - } - return (new_style_driver && nr > 0)? nr+2: nr; -} - -/******************************************************************** - * - * get_loop_output - get outgoing packets from the ppp device, - * and detect when we want to bring the real link up. - * Return value is 1 if we need to bring up the link, 0 otherwise. - */ -int -get_loop_output(void) -{ - int rv = 0; - int n; - - if (new_style_driver) { - while ((n = read_packet(inpacket_buf)) > 0) - if (loop_frame(inpacket_buf, n)) - rv = 1; - return rv; - } - - while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0) - if (loop_chars(inbuf, n)) - rv = 1; - - if (n == 0) - fatal("eof on loopback"); - - if (errno != EWOULDBLOCK) - fatal("read from loopback: %m(%d)", errno); - - return rv; -} - -/* - * netif_set_mtu - set the MTU on the PPP network interface. - */ -void -netif_set_mtu(int unit, int mtu) -{ - struct ifreq ifr; - - SYSDEBUG ((LOG_DEBUG, "netif_set_mtu: mtu = %d\n", mtu)); - - memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - ifr.ifr_mtu = mtu; - - if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0) - fatal("ioctl(SIOCSIFMTU): %m"); -} - -/******************************************************************** - * - * tty_send_config - configure the transmit characteristics of - * the ppp interface. - */ - -void tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp) -{ - u_int x; - -/* - * Set the asyncmap and other parameters for the ppp device - */ - if (!still_ppp()) - return; - link_mtu = mtu; - SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap)); - if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) { - if (!ok_error(errno)) - fatal("ioctl(PPPIOCSASYNCMAP): %m(%d)", errno); - return; - } - - x = get_flags(ppp_fd); - x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT; - x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC; - x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC; - set_flags(ppp_fd, x); -} - -/******************************************************************** - * - * tty_set_xaccm - set the extended transmit ACCM for the interface. - */ - -void tty_set_xaccm (ext_accm accm) -{ - SYSDEBUG ((LOG_DEBUG, "set_xaccm: %08lx %08lx %08lx %08lx\n", - accm[0], accm[1], accm[2], accm[3])); - - if (!still_ppp()) - return; - if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) { - if ( ! ok_error (errno)) - warn("ioctl(set extended ACCM): %m(%d)", errno); - } -} - -/******************************************************************** - * - * tty_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ - -void tty_recv_config (int mru,u_int32_t asyncmap,int pcomp,int accomp) -{ - SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru)); -/* - * If we were called because the link has gone down then there is nothing - * which may be done. Just return without incident. - */ - if (!still_ppp()) - return; -/* - * Set the receiver parameters - */ - if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { - if ( ! ok_error (errno)) - error("ioctl(PPPIOCSMRU): %m(%d)", errno); - } - if (new_style_driver && ifunit >= 0 - && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) - error("Couldn't set MRU in generic PPP layer: %m"); - - SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap)); - if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) { - if (!ok_error(errno)) - error("ioctl(PPPIOCSRASYNCMAP): %m(%d)", errno); - } -} - -/******************************************************************** - * - * ccp_test - ask kernel whether a given compression method - * is acceptable for use. - */ - -int ccp_test (int unit, u_char *opt_ptr, int opt_len, int for_transmit) -{ - struct ppp_option_data data; - - memset (&data, '\0', sizeof (data)); - data.ptr = opt_ptr; - data.length = opt_len; - data.transmit = for_transmit; - - if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0) - return 1; - - return (errno == ENOBUFS)? 0: -1; -} - -/******************************************************************** - * - * ccp_flags_set - inform kernel about the current state of CCP. - */ - -void ccp_flags_set (int unit, int isopen, int isup) -{ - if (still_ppp()) { - int x = get_flags(ppp_dev_fd); - x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN; - x = isup? x | SC_CCP_UP : x &~ SC_CCP_UP; - set_flags (ppp_dev_fd, x); - } -} - -#ifdef PPP_FILTER -/* - * set_filters - set the active and pass filters in the kernel driver. - */ -int set_filters(struct bpf_program *pass, struct bpf_program *active) -{ - struct sock_fprog fp; - - fp.len = pass->bf_len; - fp.filter = (struct sock_filter *) pass->bf_insns; - if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) { - if (errno == ENOTTY) - warn("kernel does not support PPP filtering"); - else - error("Couldn't set pass-filter in kernel: %m"); - return 0; - } - fp.len = active->bf_len; - fp.filter = (struct sock_filter *) active->bf_insns; - if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) { - error("Couldn't set active-filter in kernel: %m"); - return 0; - } - return 1; -} -#endif /* PPP_FILTER */ - -/******************************************************************** - * - * get_idle_time - return how long the link has been idle. - */ -int -get_idle_time(u, ip) - int u; - struct ppp_idle *ip; -{ - return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0; -} - -/******************************************************************** - * - * get_ppp_stats - return statistics for the link. - */ -int -get_ppp_stats(u, stats) - int u; - struct pppd_stats *stats; -{ - struct ifpppstatsreq req; - - memset (&req, 0, sizeof (req)); - - req.stats_ptr = (caddr_t) &req.stats; - strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name)); - if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) { - error("Couldn't get PPP statistics: %m"); - return 0; - } - stats->bytes_in = req.stats.p.ppp_ibytes; - stats->bytes_out = req.stats.p.ppp_obytes; - return 1; -} - -/******************************************************************** - * - * 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 (int unit) -{ - int x = get_flags(ppp_dev_fd); - - return x & SC_DC_FERROR; -} - -/******************************************************************** - * - * path_to_procfs - find the path to the proc file system mount point - */ -static char proc_path[MAXPATHLEN]; -static int proc_path_len; - -static char *path_to_procfs(const char *tail) -{ - struct mntent *mntent; - FILE *fp; - - if (proc_path_len == 0) { - /* Default the mount location of /proc */ - strlcpy (proc_path, "/proc", sizeof(proc_path)); - proc_path_len = 5; - fp = fopen(MOUNTED, "r"); - if (fp != NULL) { - while ((mntent = getmntent(fp)) != NULL) { - if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0) - continue; - if (strcmp(mntent->mnt_type, "proc") == 0) { - strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path)); - proc_path_len = strlen(proc_path); - break; - } - } - fclose (fp); - } - } - - strlcpy(proc_path + proc_path_len, tail, - sizeof(proc_path) - proc_path_len); - return proc_path; -} - -/* - * /proc/net/route parsing stuff. - */ -#define ROUTE_MAX_COLS 12 -FILE *route_fd = (FILE *) 0; -static char route_buffer[512]; -static int route_dev_col, route_dest_col, route_gw_col; -static int route_flags_col, route_mask_col; -static int route_num_cols; - -static int open_route_table (void); -static void close_route_table (void); -static int read_route_table (struct rtentry *rt); - -/******************************************************************** - * - * close_route_table - close the interface to the route table - */ - -static void close_route_table (void) -{ - if (route_fd != (FILE *) 0) { - fclose (route_fd); - route_fd = (FILE *) 0; - } -} - -/******************************************************************** - * - * open_route_table - open the interface to the route table - */ -static char route_delims[] = " \t\n"; - -static int open_route_table (void) -{ - char *path; - - close_route_table(); - - path = path_to_procfs("/net/route"); - route_fd = fopen (path, "r"); - if (route_fd == NULL) { - error("can't open routing table %s: %m", path); - return 0; - } - - route_dev_col = 0; /* default to usual columns */ - route_dest_col = 1; - route_gw_col = 2; - route_flags_col = 3; - route_mask_col = 7; - route_num_cols = 8; - - /* parse header line */ - if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) { - char *p = route_buffer, *q; - int col; - for (col = 0; col < ROUTE_MAX_COLS; ++col) { - int used = 1; - if ((q = strtok(p, route_delims)) == 0) - break; - if (strcasecmp(q, "iface") == 0) - route_dev_col = col; - else if (strcasecmp(q, "destination") == 0) - route_dest_col = col; - else if (strcasecmp(q, "gateway") == 0) - route_gw_col = col; - else if (strcasecmp(q, "flags") == 0) - route_flags_col = col; - else if (strcasecmp(q, "mask") == 0) - route_mask_col = col; - else - used = 0; - if (used && col >= route_num_cols) - route_num_cols = col + 1; - p = NULL; - } - } - - return 1; -} - -/******************************************************************** - * - * read_route_table - read the next entry from the route table - */ - -static int read_route_table(struct rtentry *rt) -{ - char *cols[ROUTE_MAX_COLS], *p; - int col; - - memset (rt, '\0', sizeof (struct rtentry)); - - if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0) - return 0; - - p = route_buffer; - for (col = 0; col < route_num_cols; ++col) { - cols[col] = strtok(p, route_delims); - if (cols[col] == NULL) - return 0; /* didn't get enough columns */ - p = NULL; - } - - SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16); - SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16); - SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16); - - rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16); - rt->rt_dev = cols[route_dev_col]; - - return 1; -} - -/******************************************************************** - * - * defaultroute_exists - determine if there is a default route - */ - -static int defaultroute_exists (struct rtentry *rt) -{ - int result = 0; - - if (!open_route_table()) - return 0; - - while (read_route_table(rt) != 0) { - if ((rt->rt_flags & RTF_UP) == 0) - continue; - - if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0) - continue; - if (SIN_ADDR(rt->rt_dst) == 0L) { - result = 1; - break; - } - } - - close_route_table(); - return result; -} - -/* - * have_route_to - determine if the system has any route to - * a given IP address. `addr' is in network byte order. - * Return value is 1 if yes, 0 if no, -1 if don't know. - * For demand mode to work properly, we have to ignore routes - * through our own interface. - */ -int have_route_to(u_int32_t addr) -{ - struct rtentry rt; - int result = 0; - - if (!open_route_table()) - return -1; /* don't know */ - - while (read_route_table(&rt)) { - if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0) - continue; - if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) { - result = 1; - break; - } - } - - close_route_table(); - return result; -} - -/******************************************************************** - * - * sifdefaultroute - assign a default route through the address given. - */ - -int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) -{ - struct rtentry rt; - - if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) { - u_int32_t old_gateway = SIN_ADDR(rt.rt_gateway); - - if (old_gateway != gateway) - error("not replacing existing default route to %s [%I]", - rt.rt_dev, old_gateway); - return 0; - } - - memset (&rt, '\0', sizeof (rt)); - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = 0L; - } - - SIN_ADDR(rt.rt_gateway) = gateway; - - rt.rt_flags = RTF_UP | RTF_GATEWAY; - if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { - if ( ! ok_error ( errno )) - error("default route ioctl(SIOCADDRT): %m(%d)", errno); - return 0; - } - - default_route_gateway = gateway; - return 1; -} - -/******************************************************************** - * - * cifdefaultroute - delete a default route through the address given. - */ - -int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) -{ - struct rtentry rt; - - default_route_gateway = 0; - - memset (&rt, '\0', sizeof (rt)); - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = 0L; - } - - SIN_ADDR(rt.rt_gateway) = gateway; - - rt.rt_flags = RTF_UP | RTF_GATEWAY; - if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { - if (still_ppp()) { - if ( ! ok_error ( errno )) - error("default route ioctl(SIOCDELRT): %m (%d)", errno); - return 0; - } - } - - return 1; -} - -/******************************************************************** - * - * sifproxyarp - Make a proxy ARP entry for the peer. - */ - -int sifproxyarp (int unit, u_int32_t his_adr) -{ - struct arpreq arpreq; - char *forw_path; - - if (has_proxy_arp == 0) { - memset (&arpreq, '\0', sizeof(arpreq)); - - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - SIN_ADDR(arpreq.arp_pa) = his_adr; - arpreq.arp_flags = ATF_PERM | ATF_PUBL; -/* - * Get the hardware address of an interface on the same subnet - * as our local address. - */ - if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev, - sizeof(proxy_arp_dev))) { - error("Cannot determine ethernet address for proxy ARP"); - return 0; - } - strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); - - if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) { - if ( ! ok_error ( errno )) - error("ioctl(SIOCSARP): %m(%d)", errno); - return 0; - } - proxy_arp_addr = his_adr; - has_proxy_arp = 1; - - if (tune_kernel) { - forw_path = path_to_procfs("/sys/net/ipv4/ip_forward"); - if (forw_path != 0) { - int fd = open(forw_path, O_WRONLY); - if (fd >= 0) { - if (write(fd, "1", 1) != 1) - error("Couldn't enable IP forwarding: %m"); - close(fd); - } - } - } - } - - return 1; -} - -/******************************************************************** - * - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ - -int cifproxyarp (int unit, u_int32_t his_adr) -{ - struct arpreq arpreq; - - if (has_proxy_arp) { - has_proxy_arp = 0; - memset (&arpreq, '\0', sizeof(arpreq)); - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - SIN_ADDR(arpreq.arp_pa) = his_adr; - arpreq.arp_flags = ATF_PERM | ATF_PUBL; - strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev)); - - if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) { - if ( ! ok_error ( errno )) - warn("ioctl(SIOCDARP): %m(%d)", errno); - return 0; - } - } - return 1; -} - -/******************************************************************** - * - * get_ether_addr - get the hardware address of an interface on the - * the same subnet as ipaddr. - */ - -static int get_ether_addr (u_int32_t ipaddr, - struct sockaddr *hwaddr, - char *name, int namelen) -{ - struct ifreq *ifr, *ifend; - u_int32_t ina, mask; - char *aliasp; - struct ifreq ifreq; - struct ifconf ifc; - struct ifreq ifs[MAX_IFS]; - - ifc.ifc_len = sizeof(ifs); - ifc.ifc_req = ifs; - if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) { - if ( ! ok_error ( errno )) - error("ioctl(SIOCGIFCONF): %m(%d)", errno); - return 0; - } - - SYSDEBUG ((LOG_DEBUG, "proxy arp: scanning %d interfaces for IP %s", - ifc.ifc_len / sizeof(struct ifreq), ip_ntoa(ipaddr))); -/* - * Scan through looking for an interface with an Internet - * address on the same subnet as `ipaddr'. - */ - ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq)); - for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { - if (ifr->ifr_addr.sa_family == AF_INET) { - ina = SIN_ADDR(ifr->ifr_addr); - strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s", - ifreq.ifr_name)); -/* - * Check that the interface is up, and not point-to-point - * nor loopback. - */ - if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) - continue; - - if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0) - continue; -/* - * Get its netmask and check that it's on the right subnet. - */ - if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0) - continue; - - mask = SIN_ADDR(ifreq.ifr_addr); - SYSDEBUG ((LOG_DEBUG, "proxy arp: interface addr %s mask %lx", - ip_ntoa(ina), ntohl(mask))); - - if (((ipaddr ^ ina) & mask) != 0) - continue; - break; - } - } - - if (ifr >= ifend) - return 0; - - strlcpy(name, ifreq.ifr_name, namelen); - - /* trim off the :1 in eth0:1 */ - aliasp = strchr(name, ':'); - if (aliasp != 0) - *aliasp = 0; - - info("found interface %s for proxy arp", name); -/* - * Now get the hardware address. - */ - memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr)); - if (ioctl (sock_fd, SIOCGIFHWADDR, &ifreq) < 0) { - error("SIOCGIFHWADDR(%s): %m(%d)", ifreq.ifr_name, errno); - return 0; - } - - memcpy (hwaddr, - &ifreq.ifr_hwaddr, - sizeof (struct sockaddr)); - - SYSDEBUG ((LOG_DEBUG, - "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - (int) ((unsigned char *) &hwaddr->sa_data)[0], - (int) ((unsigned char *) &hwaddr->sa_data)[1], - (int) ((unsigned char *) &hwaddr->sa_data)[2], - (int) ((unsigned char *) &hwaddr->sa_data)[3], - (int) ((unsigned char *) &hwaddr->sa_data)[4], - (int) ((unsigned char *) &hwaddr->sa_data)[5], - (int) ((unsigned char *) &hwaddr->sa_data)[6], - (int) ((unsigned char *) &hwaddr->sa_data)[7])); - return 1; -} - -/* - * get_if_hwaddr - get the hardware address for the specified - * network interface device. - */ -int -get_if_hwaddr(u_char *addr, char *name) -{ - struct ifreq ifreq; - int ret, sock_fd; - - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd < 0) - return 0; - memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr)); - strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name)); - ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq); - close(sock_fd); - if (ret >= 0) - memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6); - return ret; -} - -/* - * get_first_ethernet - return the name of the first ethernet-style - * interface on this system. - */ -char * -get_first_ethernet() -{ - return "eth0"; -} - -/******************************************************************** - * - * 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 (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(sock_fd, SIOCGIFCONF, &ifc) < 0) { - if ( ! ok_error ( errno )) - warn("ioctl(SIOCGIFCONF): %m(%d)", errno); - return mask; - } - - ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - for (ifr = ifc.ifc_req; ifr < ifend; ifr++) { -/* - * Check the interface's internet address. - */ - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - ina = SIN_ADDR(ifr->ifr_addr); - if (((ntohl(ina) ^ addr) & nmask) != 0) - continue; -/* - * Check that the interface is up, and not point-to-point nor loopback. - */ - strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) - continue; - - if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0) - continue; -/* - * Get its netmask and OR it into our mask. - */ - if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0) - continue; - mask |= SIN_ADDR(ifreq.ifr_addr); - break; - } - return mask; -} - -/******************************************************************** - * - * Internal routine to decode the version.modification.patch level - */ - -static void decode_version (char *buf, int *version, - int *modification, int *patch) -{ - char *endp; - - *version = (int) strtoul (buf, &endp, 10); - *modification = 0; - *patch = 0; - - if (endp != buf && *endp == '.') { - buf = endp + 1; - *modification = (int) strtoul (buf, &endp, 10); - if (endp != buf && *endp == '.') { - buf = endp + 1; - *patch = (int) strtoul (buf, &buf, 10); - } - } -} - -/******************************************************************** - * - * Procedure to determine if the PPP line discipline is registered. - */ - -static int -ppp_registered(void) -{ - int local_fd; - int mfd = -1; - int ret = 0; - char slave[16]; - - /* - * We used to open the serial device and set it to the ppp line - * discipline here, in order to create a ppp unit. But that is - * not a good idea - the user might have specified a device that - * they can't open (permission, or maybe it doesn't really exist). - * So we grab a pty master/slave pair and use that. - */ - if (!get_pty(&mfd, &local_fd, slave, 0)) { - no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)"; - return 0; - } - - /* - * Try to put the device into the PPP discipline. - */ - if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) { - error("ioctl(TIOCSETD(PPP)): %m(%d)", errno); - } else - ret = 1; - - close(local_fd); - close(mfd); - return ret; -} - -/******************************************************************** - * - * 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(void) -{ - int s, ok, fd; - struct ifreq ifr; - int size; - int my_version, my_modification, my_patch; - int osmaj, osmin, ospatch; - - no_ppp_msg = - "This system lacks kernel support for PPP. This could be because\n" - "the PPP kernel module could not be loaded, or because PPP was not\n" - "included in the kernel configuration. If PPP was included as a\n" - "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n" - "ppp.o exists in /lib/modules/`uname -r`/net.\n" - "See README.linux file in the ppp distribution for more details.\n"; - - /* get the kernel version now, since we are called before sys_init */ - uname(&utsname); - osmaj = osmin = ospatch = 0; - sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch); - kernel_version = KVERSION(osmaj, osmin, ospatch); - - fd = open("/dev/ppp", O_RDWR); -#if 0 - if (fd < 0 && errno == ENOENT) { - /* try making it and see if that helps. */ - if (mknod("/dev/ppp", S_IFCHR | S_IRUSR | S_IWUSR, - makedev(108, 0)) >= 0) { - fd = open("/dev/ppp", O_RDWR); - if (fd >= 0) - info("Created /dev/ppp device node"); - else - unlink("/dev/ppp"); /* didn't work, undo the mknod */ - } else if (errno == EEXIST) { - fd = open("/dev/ppp", O_RDWR); - } - } -#endif /* 0 */ - if (fd >= 0) { - new_style_driver = 1; - - /* XXX should get from driver */ - driver_version = 2; - driver_modification = 4; - driver_patch = 0; - close(fd); - return 1; - } - if (kernel_version >= KVERSION(2,3,13)) { - if (errno == ENOENT) - no_ppp_msg = - "pppd is unable to open the /dev/ppp device.\n" - "You need to create the /dev/ppp device node by\n" - "executing the following command as root:\n" - " mknod /dev/ppp c 108 0\n"; - return 0; - } - -/* - * Open a socket for doing the ioctl operations. - */ - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) - return 0; - - strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); - ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; -/* - * If the device did not exist then attempt to create one by putting the - * current tty into the PPP discipline. If this works then obtain the - * flags for the device again. - */ - if (!ok) { - if (ppp_registered()) { - strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); - ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; - } - } -/* - * Ensure that the hardware address is for PPP and not something else - */ - if (ok) - ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0; - - if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP)) - ok = 0; - -/* - * This is the PPP device. Validate the version of the driver at this - * point to ensure that this program will work with the driver. - */ - if (ok) { - char abBuffer [1024]; - - ifr.ifr_data = abBuffer; - size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr); - if (size < 0) { - error("Couldn't read driver version: %m"); - ok = 0; - no_ppp_msg = "Sorry, couldn't verify kernel driver version\n"; - - } else { - decode_version(abBuffer, - &driver_version, - &driver_modification, - &driver_patch); -/* - * Validate the version of the driver against the version that we used. - */ - decode_version(VERSION, - &my_version, - &my_modification, - &my_patch); - - /* The version numbers must match */ - if (driver_version != my_version) - ok = 0; - - /* The modification levels must be legal */ - if (driver_modification < 3) { - if (driver_modification >= 2) { - /* we can cope with 2.2.0 and above */ - driver_is_old = 1; - } else { - ok = 0; - } - } - - close (s); - if (!ok) { - slprintf(route_buffer, sizeof(route_buffer), - "Sorry - PPP driver version %d.%d.%d is out of date\n", - driver_version, driver_modification, driver_patch); - - no_ppp_msg = route_buffer; - } - } - } - return ok; -} - -/******************************************************************** - * - * Update the wtmp file with the appropriate user name and tty device. - */ - -void logwtmp (const char *line, const char *name, const char *host) -{ - struct utmp ut, *utp; - pid_t mypid = getpid(); -#if __GLIBC__ < 2 - int wtmp; -#endif - -/* - * Update the signon database for users. - * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996 - */ - utmpname(_PATH_UTMP); - setutent(); - while ((utp = getutent()) && (utp->ut_pid != mypid)) - /* nothing */; - - /* Is this call really necessary? There is another one after the 'put' */ - endutent(); - - if (utp) - memcpy(&ut, utp, sizeof(ut)); - else - /* some gettys/telnetds don't initialize utmp... */ - memset(&ut, 0, sizeof(ut)); - - if (ut.ut_id[0] == 0) - strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id)); - - strncpy(ut.ut_user, name, sizeof(ut.ut_user)); - strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - - time(&ut.ut_time); - - ut.ut_type = USER_PROCESS; - ut.ut_pid = mypid; - - /* Insert the host name if one is supplied */ - if (*host) - strncpy (ut.ut_host, host, sizeof(ut.ut_host)); - - /* Insert the IP address of the remote system if IP is enabled */ - if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr) - memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr, - sizeof(ut.ut_addr)); - - /* CL: Makes sure that the logout works */ - if (*host == 0 && *name==0) - ut.ut_host[0]=0; - - pututline(&ut); - endutent(); -/* - * Update the wtmp file. - */ -#if __GLIBC__ >= 2 - updwtmp(_PATH_WTMP, &ut); -#else - wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY); - if (wtmp >= 0) { - flock(wtmp, LOCK_EX); - - if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut)) - warn("error writing %s: %m", _PATH_WTMP); - - flock(wtmp, LOCK_UN); - - close (wtmp); - } -#endif -} - - -/******************************************************************** - * - * sifvjcomp - config tcp header compression - */ - -int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid) -{ - u_int x = get_flags(ppp_dev_fd); - - if (vjcomp) { - if (ioctl (ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { - if (! ok_error (errno)) - error("ioctl(PPPIOCSMAXCID): %m(%d)", errno); - vjcomp = 0; - } - } - - x = vjcomp ? x | SC_COMP_TCP : x &~ SC_COMP_TCP; - x = cidcomp ? x & ~SC_NO_TCP_CCID : x | SC_NO_TCP_CCID; - set_flags (ppp_dev_fd, x); - - return 1; -} - -/******************************************************************** - * - * sifup - Config the interface up and enable IP packets to pass. - */ - -int sifup(int u) -{ - struct ifreq ifr; - - memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl (SIOCGIFFLAGS): %m(%d)", errno); - return 0; - } - - ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT); - if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFFLAGS): %m(%d)", errno); - return 0; - } - if_is_up++; - - return 1; -} - -/******************************************************************** - * - * sifdown - Disable the indicated protocol and config the interface - * down if there are no remaining protocols. - */ - -int sifdown (int u) -{ - struct ifreq ifr; - - if (if_is_up && --if_is_up > 0) - return 1; - - memset (&ifr, '\0', sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); - if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl (SIOCGIFFLAGS): %m(%d)", errno); - return 0; - } - - ifr.ifr_flags &= ~IFF_UP; - ifr.ifr_flags |= IFF_POINTOPOINT; - if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFFLAGS): %m(%d)", errno); - return 0; - } - return 1; -} - -/******************************************************************** - * - * sifaddr - Config the interface IP addresses and netmask. - */ - -int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, - u_int32_t net_mask) -{ - struct ifreq ifr; - struct rtentry rt; - - memset (&ifr, '\0', sizeof (ifr)); - memset (&rt, '\0', sizeof (rt)); - - SET_SA_FAMILY (ifr.ifr_addr, AF_INET); - SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); - SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); - - strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); -/* - * Set our IP address - */ - SIN_ADDR(ifr.ifr_addr) = our_adr; - if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - if (errno != EEXIST) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFADDR): %m(%d)", errno); - } - else { - warn("ioctl(SIOCSIFADDR): Address already exists"); - } - return (0); - } -/* - * Set the gateway address - */ - SIN_ADDR(ifr.ifr_dstaddr) = his_adr; - if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFDSTADDR): %m(%d)", errno); - return (0); - } -/* - * Set the netmask. - * For recent kernels, force the netmask to 255.255.255.255. - */ - if (kernel_version >= KVERSION(2,1,16)) - net_mask = ~0L; - if (net_mask != 0) { - SIN_ADDR(ifr.ifr_netmask) = net_mask; - if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCSIFNETMASK): %m(%d)", errno); - return (0); - } - } -/* - * Add the device route - */ - if (kernel_version < KVERSION(2,1,16)) { - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - rt.rt_dev = ifname; - - SIN_ADDR(rt.rt_gateway) = 0L; - SIN_ADDR(rt.rt_dst) = his_adr; - rt.rt_flags = RTF_UP | RTF_HOST; - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = -1L; - } - - if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { - if (! ok_error (errno)) - error("ioctl(SIOCADDRT) device route: %m(%d)", errno); - return (0); - } - } - - /* set ip_dynaddr in demand mode if address changes */ - if (demand && tune_kernel && !dynaddr_set - && our_old_addr && our_old_addr != our_adr) { - /* set ip_dynaddr if possible */ - char *path; - int fd; - - path = path_to_procfs("/sys/net/ipv4/ip_dynaddr"); - if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) { - if (write(fd, "1", 1) != 1) - error("Couldn't enable dynamic IP addressing: %m"); - close(fd); - } - dynaddr_set = 1; /* only 1 attempt */ - } - our_old_addr = 0; - - return 1; -} - -/******************************************************************** - * - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - */ - -int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) -{ - struct ifreq ifr; - - if (kernel_version < KVERSION(2,1,16)) { -/* - * Delete the route through the device - */ - struct rtentry rt; - memset (&rt, '\0', sizeof (rt)); - - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - rt.rt_dev = ifname; - - SIN_ADDR(rt.rt_gateway) = 0; - SIN_ADDR(rt.rt_dst) = his_adr; - rt.rt_flags = RTF_UP | RTF_HOST; - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = -1L; - } - - if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { - if (still_ppp() && ! ok_error (errno)) - error("ioctl(SIOCDELRT) device route: %m(%d)", errno); - return (0); - } - } - - /* This way it is possible to have an IPX-only or IPv6-only interface */ - memset(&ifr, 0, sizeof(ifr)); - SET_SA_FAMILY(ifr.ifr_addr, AF_INET); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) { - error("ioctl(SIOCSIFADDR): %m(%d)", errno); - return 0; - } - } - - our_old_addr = our_adr; - - return 1; -} - -#ifdef INET6 -/******************************************************************** - * - * sif6addr - Config the interface with an IPv6 link-local address - */ -int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) -{ - struct in6_ifreq ifr6; - struct ifreq ifr; - struct in6_rtmsg rt6; - - if (sock6_fd < 0) { - errno = -sock6_fd; - error("IPv6 socket creation failed: %m"); - return 0; - } - memset(&ifr, 0, sizeof (ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { - error("sif6addr: ioctl(SIOCGIFINDEX): %m (%d)", errno); - return 0; - } - - /* Local interface */ - memset(&ifr6, 0, sizeof(ifr6)); - IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); - ifr6.ifr6_ifindex = ifr.ifr_ifindex; - ifr6.ifr6_prefixlen = 10; - - if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) { - error("sif6addr: ioctl(SIOCSIFADDR): %m (%d)", errno); - return 0; - } - - /* Route to remote host */ - memset(&rt6, 0, sizeof(rt6)); - IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64); - rt6.rtmsg_flags = RTF_UP; - rt6.rtmsg_dst_len = 10; - rt6.rtmsg_ifindex = ifr.ifr_ifindex; - rt6.rtmsg_metric = 1; - - if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) { - error("sif6addr: ioctl(SIOCADDRT): %m (%d)", errno); - return 0; - } - - return 1; -} - - -/******************************************************************** - * - * cif6addr - Remove IPv6 address from interface - */ -int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64) -{ - struct ifreq ifr; - struct in6_ifreq ifr6; - - if (sock6_fd < 0) { - errno = -sock6_fd; - error("IPv6 socket creation failed: %m"); - return 0; - } - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { - error("cif6addr: ioctl(SIOCGIFINDEX): %m (%d)", errno); - return 0; - } - - memset(&ifr6, 0, sizeof(ifr6)); - IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); - ifr6.ifr6_ifindex = ifr.ifr_ifindex; - ifr6.ifr6_prefixlen = 10; - - if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) { - if (errno != EADDRNOTAVAIL) { - if (! ok_error (errno)) - error("cif6addr: ioctl(SIOCDIFADDR): %m (%d)", errno); - } - else { - warn("cif6addr: ioctl(SIOCDIFADDR): No such address"); - } - return (0); - } - return 1; -} -#endif /* INET6 */ - -/* - * get_pty - get a pty master/slave pair and chown the slave side - * to the uid given. Assumes slave_name points to >= 16 bytes of space. - */ -int -get_pty(master_fdp, slave_fdp, slave_name, uid) - int *master_fdp; - int *slave_fdp; - char *slave_name; - int uid; -{ - int i, mfd, sfd = -1; - char pty_name[16]; - struct termios tios; - -#ifdef TIOCGPTN - /* - * Try the unix98 way first. - */ - mfd = open("/dev/ptmx", O_RDWR); - if (mfd >= 0) { - int ptn; - if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) { - slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn); - chmod(pty_name, S_IRUSR | S_IWUSR); -#ifdef TIOCSPTLCK - ptn = 0; - if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0) - warn("Couldn't unlock pty slave %s: %m", pty_name); -#endif - if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0) - warn("Couldn't open pty slave %s: %m", pty_name); - } - } -#endif /* TIOCGPTN */ - - if (sfd < 0) { - /* the old way - scan through the pty name space */ - for (i = 0; i < 64; ++i) { - slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x", - 'p' + i / 16, i % 16); - mfd = open(pty_name, O_RDWR, 0); - if (mfd >= 0) { - pty_name[5] = 't'; - sfd = open(pty_name, O_RDWR | O_NOCTTY, 0); - if (sfd >= 0) { - fchown(sfd, uid, -1); - fchmod(sfd, S_IRUSR | S_IWUSR); - break; - } - close(mfd); - } - } - } - - if (sfd < 0) - return 0; - - strlcpy(slave_name, pty_name, 16); - *master_fdp = mfd; - *slave_fdp = sfd; - if (tcgetattr(sfd, &tios) == 0) { - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); - tios.c_cflag |= CS8 | CREAD | CLOCAL; - tios.c_iflag = IGNPAR; - tios.c_oflag = 0; - tios.c_lflag = 0; - if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0) - warn("couldn't set attributes on pty: %m"); - } else - warn("couldn't get attributes on pty: %m"); - - return 1; -} - -/******************************************************************** - * - * open_loopback - open the device we use for getting packets - * in demand mode. Under Linux, we use a pty master/slave pair. - */ -int -open_ppp_loopback(void) -{ - int flags; - - looped = 1; - if (new_style_driver) { - /* allocate ourselves a ppp unit */ - if (make_ppp_unit() < 0) - die(1); - set_flags(ppp_dev_fd, SC_LOOP_TRAFFIC); - set_kdebugflag(kdebugflag); - ppp_fd = -1; - return ppp_dev_fd; - } - - if (!get_pty(&master_fd, &slave_fd, loop_name, 0)) - fatal("No free pty for loopback"); - SYSDEBUG(("using %s for loopback", loop_name)); - - set_ppp_fd(slave_fd); - - flags = fcntl(master_fd, F_GETFL); - if (flags == -1 || - fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("couldn't set master loopback to nonblock: %m(%d)", errno); - - flags = fcntl(ppp_fd, F_GETFL); - if (flags == -1 || - fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("couldn't set slave loopback to nonblock: %m(%d)", errno); - - if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0) - fatal("ioctl(TIOCSETD): %m(%d)", errno); -/* - * Find out which interface we were given. - */ - if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0) - fatal("ioctl(PPPIOCGUNIT): %m(%d)", errno); -/* - * Enable debug in the driver if requested. - */ - set_kdebugflag (kdebugflag); - - return master_fd; -} - -/******************************************************************** - * - * restore_loop - reattach the ppp unit to the loopback. - * - * The kernel ppp driver automatically reattaches the ppp unit to - * the loopback if the serial port is set to a line discipline other - * than ppp, or if it detects a modem hangup. The former will happen - * in disestablish_ppp if the latter hasn't already happened, so we - * shouldn't need to do anything. - * - * Just to be sure, set the real serial port to the normal discipline. - */ - -static void -restore_loop(void) -{ - looped = 1; - if (new_style_driver) { - set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC); - return; - } - if (ppp_fd != slave_fd) { - (void) ioctl(ppp_fd, TIOCSETD, &tty_disc); - set_ppp_fd(slave_fd); - } -} - -/******************************************************************** - * - * sifnpmode - Set the mode for handling packets for a given NP. - */ - -int -sifnpmode(u, proto, mode) - int u; - int proto; - enum NPmode mode; -{ - struct npioctl npi; - - npi.protocol = proto; - npi.mode = mode; - if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) { - if (! ok_error (errno)) - error("ioctl(PPPIOCSNPMODE, %d, %d): %m (%d)", - proto, mode, errno); - return 0; - } - return 1; -} - - -/******************************************************************** - * - * sipxfaddr - Config the interface IPX networknumber - */ - -int sipxfaddr (int unit, unsigned long int network, unsigned char * node ) -{ - int result = 1; - -#ifdef IPX_CHANGE - int skfd; - struct ifreq ifr; - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; - - skfd = socket (AF_IPX, SOCK_DGRAM, 0); - if (skfd < 0) { - if (! ok_error (errno)) - dbglog("socket(AF_IPX): %m (%d)", errno); - result = 0; - } - else { - memset (&ifr, '\0', sizeof (ifr)); - strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - memcpy (sipx->sipx_node, node, IPX_NODE_LEN); - sipx->sipx_family = AF_IPX; - sipx->sipx_port = 0; - sipx->sipx_network = htonl (network); - sipx->sipx_type = IPX_FRAME_ETHERII; - sipx->sipx_action = IPX_CRTITF; -/* - * Set the IPX device - */ - if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - result = 0; - if (errno != EEXIST) { - if (! ok_error (errno)) - dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (%d)", errno); - } - else { - warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists"); - } - } - close (skfd); - } -#endif - return result; -} - -/******************************************************************** - * - * cipxfaddr - Clear the information for the IPX network. The IPX routes - * are removed and the device is no longer able to pass IPX - * frames. - */ - -int cipxfaddr (int unit) -{ - int result = 1; - -#ifdef IPX_CHANGE - int skfd; - struct ifreq ifr; - struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; - - skfd = socket (AF_IPX, SOCK_DGRAM, 0); - if (skfd < 0) { - if (! ok_error (errno)) - dbglog("socket(AF_IPX): %m (%d)", errno); - result = 0; - } - else { - memset (&ifr, '\0', sizeof (ifr)); - strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - sipx->sipx_type = IPX_FRAME_ETHERII; - sipx->sipx_action = IPX_DLTITF; - sipx->sipx_family = AF_IPX; -/* - * Set the IPX device - */ - if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { - if (! ok_error (errno)) - info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (%d)", errno); - result = 0; - } - close (skfd); - } -#endif - return result; -} - -/* - * Use the hostname as part of the random number seed. - */ -int -get_host_seed() -{ - int h; - char *p = hostname; - - h = 407; - for (p = hostname; *p != 0; ++p) - h = h * 37 + *p; - return h; -} - -/******************************************************************** - * - * sys_check_options - check the options that the user specified - */ - -int -sys_check_options(void) -{ -#ifdef IPX_CHANGE -/* - * Disable the IPX protocol if the support is not present in the kernel. - */ - char *path; - - if (ipxcp_protent.enabled_flag) { - struct stat stat_buf; - if ((path = path_to_procfs("/net/ipx_interface")) == 0 - || lstat(path, &stat_buf) < 0) { - error("IPX support is not present in the kernel\n"); - ipxcp_protent.enabled_flag = 0; - } - } -#endif - if (demand && driver_is_old) { - option_error("demand dialling is not supported by kernel driver " - "version %d.%d.%d", driver_version, driver_modification, - driver_patch); - return 0; - } - if (multilink && !new_style_driver) { - warn("Warning: multilink is not supported by the kernel driver"); - multilink = 0; - } - return 1; -} diff --git a/mdk-stage1/ppp/pppd/sys-solaris.c b/mdk-stage1/ppp/pppd/sys-solaris.c deleted file mode 100644 index da5f9c45a..000000000 --- a/mdk-stage1/ppp/pppd/sys-solaris.c +++ /dev/null @@ -1,2737 +0,0 @@ -/* - * System-dependent procedures for pppd under Solaris 2. - * - * Parts re-written by Adi Masputra <adi.masputra@sun.com>, based on - * the original sys-svr4.c - * - * Copyright (c) 2000 by Sun Microsystems, Inc. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. - * - * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF - * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - */ - -#define RCSID "$Id$" - -#include <limits.h> -#include <stdio.h> -#include <stddef.h> -#include <stdlib.h> -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <termios.h> -#ifndef CRTSCTS -#include <sys/termiox.h> -#endif -#include <signal.h> -#include <utmpx.h> -#include <sys/types.h> -#include <sys/ioccom.h> -#include <sys/stream.h> -#include <sys/stropts.h> -#include <sys/socket.h> -#include <sys/sockio.h> -#include <sys/sysmacros.h> -#include <sys/systeminfo.h> -#include <sys/dlpi.h> -#include <sys/stat.h> -#include <sys/mkdev.h> -#include <net/if.h> -#include <net/if_arp.h> -#include <net/route.h> -#include <net/ppp_defs.h> -#include <net/pppio.h> -#include <netinet/in.h> -#ifdef SOL2 -#include <sys/tihdr.h> -#include <sys/tiuser.h> -#include <inet/common.h> -#include <inet/mib2.h> -#include <sys/ethernet.h> -#endif - -#include "pppd.h" -#include "fsm.h" -#include "lcp.h" -#include "ipcp.h" -#include "ccp.h" - -#if !defined(PPP_DRV_NAME) -#define PPP_DRV_NAME "ppp" -#endif /* !defined(PPP_DRV_NAME) */ - -#if !defined(PPP_DEV_NAME) -#define PPP_DEV_NAME "/dev/" PPP_DRV_NAME -#endif /* !defined(PPP_DEV_NAME) */ - -#if !defined(AHDLC_MOD_NAME) -#define AHDLC_MOD_NAME "ppp_ahdl" -#endif /* !defined(AHDLC_MOD_NAME) */ - -#if !defined(COMP_MOD_NAME) -#define COMP_MOD_NAME "ppp_comp" -#endif /* !defined(COMP_MOD_NAME) */ - -#if !defined(IP_DEV_NAME) -#define IP_DEV_NAME "/dev/ip" -#endif /* !defined(IP_DEV_NAME) */ - -#if !defined(IP_MOD_NAME) -#define IP_MOD_NAME "ip" -#endif /* !defined(IP_MOD_NAME) */ - -#if !defined(UDP_DEV_NAME) && defined(SOL2) -#define UDP_DEV_NAME "/dev/udp" -#endif /* !defined(UDP_DEV_NAME) && defined(SOL2) */ - -#if !defined(UDP6_DEV_NAME) && defined(SOL2) -#define UDP6_DEV_NAME "/dev/udp6" -#endif /* !defined(UDP6_DEV_NAME) && defined(SOL2) */ - -static const char rcsid[] = RCSID; - -#if defined(SOL2) -/* - * "/dev/udp" is used as a multiplexor to PLINK the interface stream - * under. It is used in place of "/dev/ip" since STREAMS will not let - * a driver be PLINK'ed under itself, and "/dev/ip" is typically the - * driver at the bottom of the tunneling interfaces stream. - */ -static char *mux_dev_name = UDP_DEV_NAME; -#else -static char *mux_dev_name = IP_DEV_NAME; -#endif -static int pppfd; -static int fdmuxid = -1; -static int ipfd; -static int ipmuxid = -1; - -#if defined(INET6) && defined(SOL2) -static int ip6fd; /* IP file descriptor */ -static int ip6muxid = -1; /* Multiplexer file descriptor */ -static int if6_is_up = 0; /* IPv6 interface has been marked up */ - -#define _IN6_LLX_FROM_EUI64(l, s, eui64, as) do { \ - s->sin6_addr.s6_addr32[0] = htonl(as); \ - eui64_copy(eui64, s->sin6_addr.s6_addr32[2]); \ - s->sin6_family = AF_INET6; \ - l.lifr_addr.ss_family = AF_INET6; \ - l.lifr_addrlen = 10; \ - l.lifr_addr = laddr; \ - } while (0) - -#define IN6_LLADDR_FROM_EUI64(l, s, eui64) \ - _IN6_LLX_FROM_EUI64(l, s, eui64, 0xfe800000) - -#define IN6_LLTOKEN_FROM_EUI64(l, s, eui64) \ - _IN6_LLX_FROM_EUI64(l, s, eui64, 0) - -#endif /* defined(INET6) && defined(SOL2) */ - -#if defined(INET6) && defined(SOL2) -static char first_ether_name[LIFNAMSIZ]; /* Solaris 8 and above */ -#else -static char first_ether_name[IFNAMSIZ]; /* Before Solaris 8 */ -#define MAXIFS 256 /* Max # of interfaces */ -#endif /* defined(INET6) && defined(SOL2) */ - -static int restore_term; -static struct termios inittermios; -#ifndef CRTSCTS -static struct termiox inittermiox; -static int termiox_ok; -#endif -static struct winsize wsinfo; /* Initial window size info */ -static pid_t tty_sid; /* original session ID for terminal */ - -extern u_char inpacket_buf[]; /* borrowed from main.c */ - -#define MAX_POLLFDS 32 -static struct pollfd pollfds[MAX_POLLFDS]; -static int n_pollfds; - -static int link_mtu, link_mru; - -#define NMODULES 32 -static int tty_nmodules; -static char tty_modules[NMODULES][FMNAMESZ+1]; -static int tty_npushed; - -static int if_is_up; /* Interface has been marked up */ -static u_int32_t remote_addr; /* IP address of peer */ -static u_int32_t default_route_gateway; /* Gateway for default route added */ -static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ - -/* Prototypes for procedures local to this file. */ -static int translate_speed __P((int)); -static int baud_rate_of __P((int)); -static int get_ether_addr __P((u_int32_t, struct sockaddr *)); -static int get_hw_addr __P((char *, u_int32_t, struct sockaddr *)); -static int get_hw_addr_dlpi __P((char *, struct sockaddr *)); -static int dlpi_attach __P((int, int)); -static int dlpi_info_req __P((int)); -static int dlpi_get_reply __P((int, union DL_primitives *, int, int)); -static int strioctl __P((int, int, void *, int, int)); - -#ifdef SOL2 -/* - * sifppa - Sets interface ppa - * - * without setting the ppa, ip module will return EINVAL upon setting the - * interface UP (SIOCSxIFFLAGS). This is because ip module in 2.8 expects - * two DLPI_INFO_REQ to be sent down to the driver (below ip) before - * IFF_UP can be set. Plumbing the device causes one DLPI_INFO_REQ to - * be sent down, and the second DLPI_INFO_REQ is sent upon receiving - * IF_UNITSEL (old) or SIOCSLIFNAME (new) ioctls. Such setting of the ppa - * is required because the ppp DLPI provider advertises itself as - * a DLPI style 2 type, which requires a point of attachment to be - * specified. The only way the user can specify a point of attachment - * is via SIOCSLIFNAME or IF_UNITSEL. - * - * Such changes in the behavior of ip module was made to meet new or - * evolving standards requirements. - * - */ -static int -sifppa(fd, ppa) - int fd; - int ppa; -{ - return (int)ioctl(fd, IF_UNITSEL, (char *)&ppa); -} -#endif /* SOL2 */ - -#if defined(SOL2) && defined(INET6) -/* - * get_first_ethernet - returns the first Ethernet interface name found in - * the system, or NULL if none is found - * - * NOTE: This is the lifreq version (Solaris 8 and above) - */ -char * -get_first_ethernet() -{ - struct lifnum lifn; - struct lifconf lifc; - struct lifreq *plifreq; - struct lifreq lifr; - int fd, num_ifs, i, found; - uint_t fl, req_size; - char *req; - - fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - return 0; - } - - /* - * Find out how many interfaces are running - */ - lifn.lifn_family = AF_UNSPEC; - lifn.lifn_flags = LIFC_NOXMIT; - if (ioctl(fd, SIOCGLIFNUM, &lifn) < 0) { - close(fd); - error("could not determine number of interfaces: %m"); - return 0; - } - - num_ifs = lifn.lifn_count; - req_size = num_ifs * sizeof(struct lifreq); - req = malloc(req_size); - if (req == NULL) { - close(fd); - error("out of memory"); - return 0; - } - - /* - * Get interface configuration info for all interfaces - */ - lifc.lifc_family = AF_UNSPEC; - lifc.lifc_flags = LIFC_NOXMIT; - lifc.lifc_len = req_size; - lifc.lifc_buf = req; - if (ioctl(fd, SIOCGLIFCONF, &lifc) < 0) { - close(fd); - free(req); - error("SIOCGLIFCONF: %m"); - return 0; - } - - /* - * And traverse each interface to look specifically for the first - * occurence of an Ethernet interface which has been marked up - */ - plifreq = lifc.lifc_req; - found = 0; - for (i = lifc.lifc_len / sizeof(struct lifreq); i > 0; i--, plifreq++) { - - if (strchr(plifreq->lifr_name, ':') != NULL) - continue; - - memset(&lifr, 0, sizeof(lifr)); - strncpy(lifr.lifr_name, plifreq->lifr_name, sizeof(lifr.lifr_name)); - if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) { - close(fd); - free(req); - error("SIOCGLIFFLAGS: %m"); - return 0; - } - fl = lifr.lifr_flags; - - if ((fl & (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) - != (IFF_UP | IFF_BROADCAST)) - continue; - - found = 1; - break; - } - free(req); - close(fd); - - if (found) { - strncpy(first_ether_name, lifr.lifr_name, sizeof(first_ether_name)); - return (char *)first_ether_name; - } else - return NULL; -} -#else -/* - * get_first_ethernet - returns the first Ethernet interface name found in - * the system, or NULL if none is found - * - * NOTE: This is the ifreq version (before Solaris 8). - */ -char * -get_first_ethernet() -{ - struct ifconf ifc; - struct ifreq *pifreq; - struct ifreq ifr; - int fd, num_ifs, i, found; - uint_t fl, req_size; - char *req; - - fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - return 0; - } - - /* - * Find out how many interfaces are running - */ - if (ioctl(fd, SIOCGIFNUM, (char *)&num_ifs) < 0) { - num_ifs = MAXIFS; - } - - req_size = num_ifs * sizeof(struct ifreq); - req = malloc(req_size); - if (req == NULL) { - close(fd); - error("out of memory"); - return 0; - } - - /* - * Get interface configuration info for all interfaces - */ - ifc.ifc_len = req_size; - ifc.ifc_buf = req; - if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) { - close(fd); - free(req); - error("SIOCGIFCONF: %m"); - return 0; - } - - /* - * And traverse each interface to look specifically for the first - * occurence of an Ethernet interface which has been marked up - */ - pifreq = ifc.ifc_req; - found = 0; - for (i = ifc.ifc_len / sizeof(struct ifreq); i > 0; i--, pifreq++) { - - if (strchr(pifreq->ifr_name, ':') != NULL) - continue; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, pifreq->ifr_name, sizeof(ifr.ifr_name)); - if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { - close(fd); - free(req); - error("SIOCGIFFLAGS: %m"); - return 0; - } - fl = ifr.ifr_flags; - - if ((fl & (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) - != (IFF_UP | IFF_BROADCAST)) - continue; - - found = 1; - break; - } - free(req); - close(fd); - - if (found) { - strncpy(first_ether_name, ifr.ifr_name, sizeof(first_ether_name)); - return (char *)first_ether_name; - } else - return NULL; -} -#endif /* defined(SOL2) && defined(INET6) */ - -#if defined(SOL2) -/* - * get_if_hwaddr - get the hardware address for the specified - * network interface device. - */ -int -get_if_hwaddr(u_char *addr, char *if_name) -{ - struct sockaddr s_eth_addr; - struct ether_addr *eth_addr = (struct ether_addr *)&s_eth_addr.sa_data; - - if (if_name == NULL) - return -1; - - /* - * Send DL_INFO_REQ to the driver to solicit its MAC address - */ - if (!get_hw_addr_dlpi(if_name, &s_eth_addr)) { - error("could not obtain hardware address for %s", if_name); - return -1; - } - - memcpy(addr, eth_addr->ether_addr_octet, 6); - return 1; -} -#endif /* SOL2 */ - -#if defined(SOL2) && defined(INET6) -/* - * slifname - Sets interface ppa and flags - * - * in addition to the comments stated in sifppa(), IFF_IPV6 bit must - * be set in order to declare this as an IPv6 interface - */ -static int -slifname(fd, ppa) - int fd; - int ppa; -{ - struct lifreq lifr; - int ret; - - memset(&lifr, 0, sizeof(lifr)); - ret = ioctl(fd, SIOCGLIFFLAGS, &lifr); - if (ret < 0) - goto slifname_done; - - lifr.lifr_flags |= IFF_IPV6; - lifr.lifr_flags &= ~(IFF_BROADCAST | IFF_IPV4); - lifr.lifr_ppa = ppa; - strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); - - ret = ioctl(fd, SIOCSLIFNAME, &lifr); - -slifname_done: - return ret; - - -} - - -/* - * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI - * - * walks the list of valid ethernet interfaces, and convert the first - * found 48-bit MAC address into EUI 64. caller also assumes that - * the system has a properly configured Ethernet interface for this - * function to return non-zero. - */ -int -ether_to_eui64(eui64_t *p_eui64) -{ - struct sockaddr s_eth_addr; - struct ether_addr *eth_addr = (struct ether_addr *)&s_eth_addr.sa_data; - char *if_name; - - if ((if_name = get_first_ethernet()) == NULL) { - error("no persistent id can be found"); - return 0; - } - - /* - * Send DL_INFO_REQ to the driver to solicit its MAC address - */ - if (!get_hw_addr_dlpi(if_name, &s_eth_addr)) { - error("could not obtain hardware address for %s", if_name); - return 0; - } - - /* - * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1] - */ - p_eui64->e8[0] = (eth_addr->ether_addr_octet[0] & 0xFF) | 0x02; - p_eui64->e8[1] = (eth_addr->ether_addr_octet[1] & 0xFF); - p_eui64->e8[2] = (eth_addr->ether_addr_octet[2] & 0xFF); - p_eui64->e8[3] = 0xFF; - p_eui64->e8[4] = 0xFE; - p_eui64->e8[5] = (eth_addr->ether_addr_octet[3] & 0xFF); - p_eui64->e8[6] = (eth_addr->ether_addr_octet[4] & 0xFF); - p_eui64->e8[7] = (eth_addr->ether_addr_octet[5] & 0xFF); - - return 1; -} -#endif /* defined(SOL2) && defined(INET6) */ - -/* - * sys_init - System-dependent initialization. - */ -void -sys_init() -{ - int ifd, x; - struct ifreq ifr; -#if defined(INET6) && defined(SOL2) - int i6fd; - struct lifreq lifr; -#endif /* defined(INET6) && defined(SOL2) */ -#if !defined(SOL2) - struct { - union DL_primitives prim; - char space[64]; - } reply; -#endif /* !defined(SOL2) */ - - ipfd = open(mux_dev_name, O_RDWR, 0); - if (ipfd < 0) - fatal("Couldn't open IP device: %m"); - -#if defined(INET6) && defined(SOL2) - ip6fd = open(UDP6_DEV_NAME, O_RDWR, 0); - if (ip6fd < 0) - fatal("Couldn't open IP device (2): %m"); -#endif /* defined(INET6) && defined(SOL2) */ - - if (default_device && !notty) - tty_sid = getsid((pid_t)0); - - pppfd = open(PPP_DEV_NAME, O_RDWR | O_NONBLOCK, 0); - if (pppfd < 0) - fatal("Can't open %s: %m", PPP_DEV_NAME); - if (kdebugflag & 1) { - x = PPPDBG_LOG + PPPDBG_DRIVER; - strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0); - } - - /* Assign a new PPA and get its unit number. */ - if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0) - fatal("Can't create new PPP interface: %m"); - -#if defined(SOL2) - /* - * Since sys_init() is called prior to ifname being set in main(), - * we need to get the ifname now, otherwise slifname(), and others, - * will fail, or maybe, I should move them to a later point ? - * <adi.masputra@sun.com> - */ - sprintf(ifname, PPP_DRV_NAME "%d", ifunit); -#endif /* defined(SOL2) */ - /* - * Open the ppp device again and link it under the ip multiplexor. - * IP will assign a unit number which hopefully is the same as ifunit. - * I don't know any way to be certain they will be the same. :-( - */ - ifd = open(PPP_DEV_NAME, O_RDWR, 0); - if (ifd < 0) - fatal("Can't open %s (2): %m", PPP_DEV_NAME); - if (kdebugflag & 1) { - x = PPPDBG_LOG + PPPDBG_DRIVER; - strioctl(ifd, PPPIO_DEBUG, &x, sizeof(int), 0); - } - -#if defined(INET6) && defined(SOL2) - i6fd = open(PPP_DEV_NAME, O_RDWR, 0); - if (i6fd < 0) { - close(ifd); - fatal("Can't open %s (3): %m", PPP_DEV_NAME); - } - if (kdebugflag & 1) { - x = PPPDBG_LOG + PPPDBG_DRIVER; - strioctl(i6fd, PPPIO_DEBUG, &x, sizeof(int), 0); - } -#endif /* defined(INET6) && defined(SOL2) */ - -#if defined(SOL2) - if (ioctl(ifd, I_PUSH, IP_MOD_NAME) < 0) { - close(ifd); -#if defined(INET6) - close(i6fd); -#endif /* defined(INET6) */ - fatal("Can't push IP module: %m"); - } - - /* - * Assign ppa according to the unit number returned by ppp device - * after plumbing is completed above. - */ - if (sifppa(ifd, ifunit) < 0) { - close (ifd); -#if defined(INET6) - close(i6fd); -#endif /* defined(INET6) */ - fatal("Can't set ppa for unit %d: %m", ifunit); - } - -#if defined(INET6) - /* - * An IPv6 interface is created anyway, even when the user does not - * explicitly enable it. Note that the interface will be marked - * IPv6 during slifname(). - */ - if (ioctl(i6fd, I_PUSH, IP_MOD_NAME) < 0) { - close(ifd); - close(i6fd); - fatal("Can't push IP module (2): %m"); - } - - /* - * Assign ppa according to the unit number returned by ppp device - * after plumbing is completed above. In addition, mark the interface - * as an IPv6 interface. - */ - if (slifname(i6fd, ifunit) < 0) { - close(ifd); - close(i6fd); - fatal("Can't set ifname for unit %d: %m", ifunit); - } -#endif /* defined(INET6) */ - - ipmuxid = ioctl(ipfd, I_PLINK, ifd); - close(ifd); - if (ipmuxid < 0) { -#if defined(INET6) - close(i6fd); -#endif /* defined(INET6) */ - fatal("Can't I_PLINK PPP device to IP: %m"); - } - - memset(&ifr, 0, sizeof(ifr)); - sprintf(ifr.ifr_name, "%s", ifname); - ifr.ifr_ip_muxid = ipmuxid; - - /* - * In Sol 8 and later, STREAMS dynamic module plumbing feature exists. - * This is so that an arbitrary module can be inserted, or deleted, - * between ip module and the device driver without tearing down the - * existing stream. Such feature requires the mux ids, which is set - * by SIOCSIFMUXID (or SIOCLSIFMUXID). - */ - if (ioctl(ipfd, SIOCSIFMUXID, &ifr) < 0) { - ioctl(ipfd, I_PUNLINK, ipmuxid); -#if defined(INET6) - close(i6fd); -#endif /* defined(INET6) */ - fatal("SIOCSIFMUXID: %m"); - } - -#else /* else if !defined(SOL2) */ - - if (dlpi_attach(ifd, ifunit) < 0 || - dlpi_get_reply(ifd, &reply.prim, DL_OK_ACK, sizeof(reply)) < 0) { - close(ifd); - fatal("Can't attach to ppp%d: %m", ifunit); - } - - ipmuxid = ioctl(ipfd, I_LINK, ifd); - close(ifd); - if (ipmuxid < 0) - fatal("Can't link PPP device to IP: %m"); -#endif /* defined(SOL2) */ - -#if defined(INET6) && defined(SOL2) - ip6muxid = ioctl(ip6fd, I_PLINK, i6fd); - close(i6fd); - if (ip6muxid < 0) { - ioctl(ipfd, I_PUNLINK, ipmuxid); - fatal("Can't I_PLINK PPP device to IP (2): %m"); - } - - memset(&lifr, 0, sizeof(lifr)); - sprintf(lifr.lifr_name, "%s", ifname); - lifr.lifr_ip_muxid = ip6muxid; - - /* - * Let IP know of the mux id [see comment for SIOCSIFMUXID above] - */ - if (ioctl(ip6fd, SIOCSLIFMUXID, &lifr) < 0) { - ioctl(ipfd, I_PUNLINK, ipmuxid); - ioctl(ip6fd, I_PUNLINK, ip6muxid); - fatal("Can't link PPP device to IP (2): %m"); - } -#endif /* defined(INET6) && defined(SOL2) */ - -#if !defined(SOL2) - /* Set the interface name for the link. */ - slprintf(ifr.ifr_name, sizeof(ifr.ifr_name), PPP_DRV_NAME "%d", ifunit); - ifr.ifr_metric = ipmuxid; - if (strioctl(ipfd, SIOCSIFNAME, (char *)&ifr, sizeof ifr, 0) < 0) - fatal("Can't set interface name %s: %m", ifr.ifr_name); -#endif /* !defined(SOL2) */ - - n_pollfds = 0; -} - -/* - * sys_cleanup - restore any system state we modified before exiting: - * mark the interface down, delete default route and/or proxy arp entry. - * This should call die() because it's called from die(). - */ -void -sys_cleanup() -{ -#if defined(SOL2) - struct ifreq ifr; -#if defined(INET6) - struct lifreq lifr; -#endif /* defined(INET6) */ -#endif /* defined(SOL2) */ - -#if defined(SOL2) && defined(INET6) - if (if6_is_up) - sif6down(0); -#endif /* defined(SOL2) && defined(INET6) */ - if (if_is_up) - sifdown(0); - if (default_route_gateway) - cifdefaultroute(0, default_route_gateway, default_route_gateway); - if (proxy_arp_addr) - cifproxyarp(0, proxy_arp_addr); -#if defined(SOL2) - /* - * Make sure we ask ip what the muxid, because 'ifconfig modlist' will - * unlink and re-link the modules, causing the muxid to change. - */ - memset(&ifr, 0, sizeof(ifr)); - sprintf(ifr.ifr_name, "%s", ifname); - if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) { - error("SIOCGIFFLAGS: %m"); - return; - } - - if (ioctl(ipfd, SIOCGIFMUXID, &ifr) < 0) { - error("SIOCGIFMUXID: %m"); - return; - } - - ipmuxid = ifr.ifr_ip_muxid; - - if (ioctl(ipfd, I_PUNLINK, ipmuxid) < 0) { - error("Can't I_PUNLINK PPP from IP: %m"); - return; - } -#if defined(INET6) - /* - * Make sure we ask ip what the muxid, because 'ifconfig modlist' will - * unlink and re-link the modules, causing the muxid to change. - */ - memset(&lifr, 0, sizeof(lifr)); - sprintf(lifr.lifr_name, "%s", ifname); - if (ioctl(ip6fd, SIOCGLIFFLAGS, &lifr) < 0) { - error("SIOCGLIFFLAGS: %m"); - return; - } - - if (ioctl(ip6fd, SIOCGLIFMUXID, &lifr) < 0) { - error("SIOCGLIFMUXID: %m"); - return; - } - - ip6muxid = lifr.lifr_ip_muxid; - - if (ioctl(ip6fd, I_PUNLINK, ip6muxid) < 0) { - error("Can't I_PUNLINK PPP from IP (2): %m"); - } -#endif /* defined(INET6) */ -#endif /* defined(SOL2) */ -} - -/* - * sys_close - Clean up in a child process before execing. - */ -void -sys_close() -{ - close(ipfd); -#if defined(INET6) && defined(SOL2) - close(ip6fd); -#endif /* defined(INET6) && defined(SOL2) */ - if (pppfd >= 0) - close(pppfd); -} - -/* - * sys_check_options - check the options that the user specified - */ -int -sys_check_options() -{ - return 1; -} - -#if 0 -/* - * daemon - Detach us from controlling terminal session. - */ -int -daemon(nochdir, noclose) - int nochdir, noclose; -{ - int pid; - - if ((pid = fork()) < 0) - return -1; - if (pid != 0) - exit(0); /* parent dies */ - setsid(); - if (!nochdir) - chdir("/"); - if (!noclose) { - fclose(stdin); /* don't need stdin, stdout, stderr */ - fclose(stdout); - fclose(stderr); - } - return 0; -} -#endif - -/* - * ppp_available - check whether the system has any ppp interfaces - */ -int -ppp_available() -{ - struct stat buf; - - return stat(PPP_DEV_NAME, &buf) >= 0; -} - -/* - * any_compressions - see if compression is enabled or not - * - * In the STREAMS implementation of kernel-portion pppd, - * the comp STREAMS module performs the ACFC, PFC, as well - * CCP and VJ compressions. However, if the user has explicitly - * declare to not enable them from the command line, there is - * no point of having the comp module be pushed on the stream. - */ -static int -any_compressions() -{ - if ((!lcp_wantoptions[0].neg_accompression) && - (!lcp_wantoptions[0].neg_pcompression) && - (!ccp_protent.enabled_flag) && - (!ipcp_wantoptions[0].neg_vj)) { - return 0; - } - return 1; -} - -/* - * tty_establish_ppp - Turn the serial port into a ppp interface. - */ -int -tty_establish_ppp(fd) - int fd; -{ - int i; - - /* Pop any existing modules off the tty stream. */ - for (i = 0;; ++i) - if (ioctl(fd, I_LOOK, tty_modules[i]) < 0 - || strcmp(tty_modules[i], "ptem") == 0 - || ioctl(fd, I_POP, 0) < 0) - break; - tty_nmodules = i; - - /* Push the async hdlc module and the compressor module. */ - tty_npushed = 0; - - if(!sync_serial) { - if (ioctl(fd, I_PUSH, AHDLC_MOD_NAME) < 0) { - error("Couldn't push PPP Async HDLC module: %m"); - return -1; - } - ++tty_npushed; - } - if (kdebugflag & 4) { - i = PPPDBG_LOG + PPPDBG_AHDLC; - strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0); - } - /* - * There's no need to push comp module if we don't intend - * to compress anything - */ - if (any_compressions()) { - if (ioctl(fd, I_PUSH, COMP_MOD_NAME) < 0) - error("Couldn't push PPP compression module: %m"); - else - ++tty_npushed; - } - - if (kdebugflag & 2) { - i = PPPDBG_LOG; - if (any_compressions()) - i += PPPDBG_COMP; - strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0); - } - - /* Link the serial port under the PPP multiplexor. */ - if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0) { - error("Can't link tty to PPP mux: %m"); - return -1; - } - - return pppfd; -} - -/* - * tty_disestablish_ppp - Restore the serial port to normal operation. - * It attempts to reconstruct the stream with the previously popped - * modules. This shouldn't call die() because it's called from die(). - */ -void -tty_disestablish_ppp(fd) - int fd; -{ - int i; - - if (fdmuxid >= 0) { - if (ioctl(pppfd, I_UNLINK, fdmuxid) < 0) { - if (!hungup) - error("Can't unlink tty from PPP mux: %m"); - } - fdmuxid = -1; - - if (!hungup) { - while (tty_npushed > 0 && ioctl(fd, I_POP, 0) >= 0) - --tty_npushed; - for (i = tty_nmodules - 1; i >= 0; --i) - if (ioctl(fd, I_PUSH, tty_modules[i]) < 0) - error("Couldn't restore tty module %s: %m", - tty_modules[i]); - } - if (hungup && default_device && tty_sid > 0) { - /* - * If we have received a hangup, we need to send a SIGHUP - * to the terminal's controlling process. The reason is - * that the original stream head for the terminal hasn't - * seen the M_HANGUP message (it went up through the ppp - * driver to the stream head for our fd to /dev/ppp). - */ - kill(tty_sid, SIGHUP); - } - } -} - -/* - * Check whether the link seems not to be 8-bit clean. - */ -void -clean_check() -{ - int x; - char *s; - - if (strioctl(pppfd, PPPIO_GCLEAN, &x, 0, sizeof(x)) < 0) - return; - s = NULL; - switch (~x) { - case RCV_B7_0: - s = "bit 7 set to 1"; - break; - case RCV_B7_1: - s = "bit 7 set to 0"; - break; - case RCV_EVNP: - s = "odd parity"; - break; - case RCV_ODDP: - s = "even parity"; - break; - } - if (s != NULL) { - warn("Serial link is not 8-bit clean:"); - warn("All received characters had %s", s); - } -} - -/* - * 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 B57600 - { 57600, B57600 }, -#endif -#ifdef B76800 - { 76800, B76800 }, -#endif -#ifdef B115200 - { 115200, B115200 }, -#endif -#ifdef B153600 - { 153600, B153600 }, -#endif -#ifdef B230400 - { 230400, B230400 }, -#endif -#ifdef B307200 - { 307200, B307200 }, -#endif -#ifdef B460800 - { 460800, B460800 }, -#endif - { 0, 0 } -}; - -/* - * Translate from bits/second to a speed_t. - */ -static 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; - warn("speed %d not supported", bps); - return 0; -} - -/* - * Translate from a speed_t to bits/second. - */ -static 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. - */ -void -set_up_tty(fd, local) - int fd, local; -{ - int speed; - struct termios tios; -#if !defined (CRTSCTS) - struct termiox tiox; -#endif - - if (!sync_serial && tcgetattr(fd, &tios) < 0) - fatal("tcgetattr: %m"); - -#ifndef CRTSCTS - termiox_ok = 1; - if (!sync_serial && ioctl (fd, TCGETX, &tiox) < 0) { - termiox_ok = 0; - if (errno != ENOTTY) - error("TCGETX: %m"); - } -#endif - - if (!restore_term) { - inittermios = tios; -#ifndef CRTSCTS - inittermiox = tiox; -#endif - if (!sync_serial) - ioctl(fd, TIOCGWINSZ, &wsinfo); - } - - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); -#ifdef CRTSCTS - if (crtscts > 0) - tios.c_cflag |= CRTSCTS; - else if (crtscts < 0) - tios.c_cflag &= ~CRTSCTS; -#else - if (crtscts != 0 && !termiox_ok) { - error("Can't set RTS/CTS flow control"); - } else if (crtscts > 0) { - tiox.x_hflag |= RTSXOFF|CTSXON; - } else if (crtscts < 0) { - tiox.x_hflag &= ~(RTSXOFF|CTSXON); - } -#endif - - 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 |= IXON | 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); - /* - * We can't proceed if the serial port speed is 0, - * since that implies that the serial port is disabled. - */ - if ((speed == B0) && !sync_serial) - fatal("Baud rate for %s is 0; need explicit baud rate", devnam); - } - - if (!sync_serial && tcsetattr(fd, TCSAFLUSH, &tios) < 0) - fatal("tcsetattr: %m"); - -#ifndef CRTSCTS - if (!sync_serial && termiox_ok && ioctl (fd, TCSETXF, &tiox) < 0){ - error("TCSETXF: %m"); - } -#endif - - baud_rate = inspeed = baud_rate_of(speed); - if (!sync_serial) - restore_term = 1; -} - -/* - * restore_tty - restore the terminal to the saved settings. - */ -void -restore_tty(fd) - int fd; -{ - if (restore_term) { - if (!default_device) { - /* - * Turn off echoing, because otherwise we can get into - * a loop with the tty and the modem echoing to each other. - * We presume we are the sole user of this tty device, so - * when we close it, it will revert to its defaults anyway. - */ - inittermios.c_lflag &= ~(ECHO | ECHONL); - } - if (!sync_serial && tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) - if (!hungup && errno != ENXIO) - warn("tcsetattr: %m"); -#ifndef CRTSCTS - if (!sync_serial && ioctl (fd, TCSETXF, &inittermiox) < 0){ - if (!hungup && errno != ENXIO) - error("TCSETXF: %m"); - } -#endif - if (!sync_serial) - ioctl(fd, TIOCSWINSZ, &wsinfo); - restore_term = 0; - } -} - -/* - * setdtr - control the DTR line on the serial port. - * This is called from die(), so it shouldn't call die(). - */ -void -setdtr(fd, on) -int fd, on; -{ - int modembits = TIOCM_DTR; - - ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits); -} - -/* - * open_loopback - open the device we use for getting packets - * in demand mode. Under Solaris 2, we use our existing fd - * to the ppp driver. - */ -int -open_ppp_loopback() -{ - return pppfd; -} - -/* - * output - Output PPP packet. - */ -void -output(unit, p, len) - int unit; - u_char *p; - int len; -{ - struct strbuf data; - int retries; - struct pollfd pfd; - - if (debug) - dbglog("sent %P", p, len); - - data.len = len; - data.buf = (caddr_t) p; - retries = 4; - while (putmsg(pppfd, NULL, &data, 0) < 0) { - if (--retries < 0 || (errno != EWOULDBLOCK && errno != EAGAIN)) { - if (errno != ENXIO) - error("Couldn't send packet: %m"); - break; - } - pfd.fd = pppfd; - pfd.events = POLLOUT; - poll(&pfd, 1, 250); /* wait for up to 0.25 seconds */ - } -} - - -/* - * wait_input - wait until there is data available, - * for the length of time specified by *timo (indefinite - * if timo is NULL). - */ -void -wait_input(timo) - struct timeval *timo; -{ - int t; - - t = timo == NULL? -1: timo->tv_sec * 1000 + timo->tv_usec / 1000; - if (poll(pollfds, n_pollfds, t) < 0 && errno != EINTR) - fatal("poll: %m"); -} - -/* - * add_fd - add an fd to the set that wait_input waits for. - */ -void add_fd(fd) - int fd; -{ - int n; - - for (n = 0; n < n_pollfds; ++n) - if (pollfds[n].fd == fd) - return; - if (n_pollfds < MAX_POLLFDS) { - pollfds[n_pollfds].fd = fd; - pollfds[n_pollfds].events = POLLIN | POLLPRI | POLLHUP; - ++n_pollfds; - } else - error("Too many inputs!"); -} - -/* - * remove_fd - remove an fd from the set that wait_input waits for. - */ -void remove_fd(fd) - int fd; -{ - int n; - - for (n = 0; n < n_pollfds; ++n) { - if (pollfds[n].fd == fd) { - while (++n < n_pollfds) - pollfds[n-1] = pollfds[n]; - --n_pollfds; - break; - } - } -} - -#if 0 -/* - * wait_loop_output - wait until there is data available on the - * loopback, for the length of time specified by *timo (indefinite - * if timo is NULL). - */ -void -wait_loop_output(timo) - struct timeval *timo; -{ - wait_input(timo); -} - -/* - * wait_time - wait for a given length of time or until a - * signal is received. - */ -void -wait_time(timo) - struct timeval *timo; -{ - int n; - - n = select(0, NULL, NULL, NULL, timo); - if (n < 0 && errno != EINTR) - fatal("select: %m"); -} -#endif - - -/* - * read_packet - get a PPP packet from the serial device. - */ -int -read_packet(buf) - u_char *buf; -{ - struct strbuf ctrl, data; - int flags, len; - unsigned char ctrlbuf[sizeof(union DL_primitives) + 64]; - - for (;;) { - data.maxlen = PPP_MRU + PPP_HDRLEN; - data.buf = (caddr_t) buf; - ctrl.maxlen = sizeof(ctrlbuf); - ctrl.buf = (caddr_t) ctrlbuf; - flags = 0; - len = getmsg(pppfd, &ctrl, &data, &flags); - if (len < 0) { - if (errno == EAGAIN || errno == EINTR) - return -1; - fatal("Error reading packet: %m"); - } - - if (ctrl.len <= 0) - return data.len; - - /* - * Got a M_PROTO or M_PCPROTO message. Interpret it - * as a DLPI primitive?? - */ - if (debug) - dbglog("got dlpi prim 0x%x, len=%d", - ((union DL_primitives *)ctrlbuf)->dl_primitive, ctrl.len); - - } -} - -/* - * get_loop_output - get outgoing packets from the ppp device, - * and detect when we want to bring the real link up. - * Return value is 1 if we need to bring up the link, 0 otherwise. - */ -int -get_loop_output() -{ - int len; - int rv = 0; - - while ((len = read_packet(inpacket_buf)) > 0) { - if (loop_frame(inpacket_buf, len)) - rv = 1; - } - return rv; -} - -/* - * netif_set_mtu - set the MTU on the PPP network interface. - */ -void -netif_set_mtu(unit, mtu) - int unit, mtu; -{ - struct ifreq ifr; -#if defined(INET6) && defined(SOL2) - struct lifreq lifr; - int fd; -#endif /* defined(INET6) && defined(SOL2) */ - - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - ifr.ifr_metric = link_mtu; - if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) { - error("Couldn't set IP MTU (%s): %m", ifr.ifr_name); - } - -#if defined(INET6) && defined(SOL2) - fd = socket(AF_INET6, SOCK_DGRAM, 0); - if (fd < 0) - error("Couldn't open IPv6 socket: %m"); - - memset(&lifr, 0, sizeof(lifr)); - strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); - lifr.lifr_mtu = link_mtu; - if (ioctl(fd, SIOCSLIFMTU, &lifr) < 0) { - close(fd); - error("Couldn't set IPv6 MTU (%s): %m", ifr.ifr_name); - } - close(fd); -#endif /* defined(INET6) && defined(SOL2) */ -} - -/* - * tty_send_config - configure the transmit characteristics of - * the ppp interface. - */ -void -tty_send_config(mtu, asyncmap, pcomp, accomp) - int mtu; - u_int32_t asyncmap; - int pcomp, accomp; -{ - int cf[2]; - - link_mtu = mtu; - if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) { - if (hungup && errno == ENXIO) - return; - error("Couldn't set MTU: %m"); - } - if (fdmuxid >= 0) { - if (!sync_serial) { - if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { - error("Couldn't set transmit ACCM: %m"); - } - } - cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0); - cf[1] = COMP_PROT | COMP_AC; - if (any_compressions() && - strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - error("Couldn't set prot/AC compression: %m"); - } - } -} - -/* - * ppp_set_xaccm - set the extended transmit ACCM for the interface. - */ -void -tty_set_xaccm(accm) - ext_accm accm; -{ - if (sync_serial) - return; - - if (fdmuxid >= 0 - && strioctl(pppfd, PPPIO_XACCM, accm, sizeof(ext_accm), 0) < 0) { - if (!hungup || errno != ENXIO) - warn("Couldn't set extended ACCM: %m"); - } -} - -/* - * ppp_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ -void -tty_recv_config(mru, asyncmap, pcomp, accomp) - int mru; - u_int32_t asyncmap; - int pcomp, accomp; -{ - int cf[2]; - - link_mru = mru; - if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) { - if (hungup && errno == ENXIO) - return; - error("Couldn't set MRU: %m"); - } - if (fdmuxid >= 0) { - if (!sync_serial) { - if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { - error("Couldn't set receive ACCM: %m"); - } - } - cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0); - cf[1] = DECOMP_PROT | DECOMP_AC; - if (any_compressions() && - strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - error("Couldn't set prot/AC decompression: %m"); - } - } -} - -/* - * ccp_test - ask kernel whether a given compression method - * is acceptable for use. - */ -int -ccp_test(unit, opt_ptr, opt_len, for_transmit) - int unit, opt_len, for_transmit; - u_char *opt_ptr; -{ - if (strioctl(pppfd, (for_transmit? PPPIO_XCOMP: PPPIO_RCOMP), - opt_ptr, opt_len, 0) >= 0) - return 1; - return (errno == ENOSR)? 0: -1; -} - -/* - * ccp_flags_set - inform kernel about the current state of CCP. - */ -void -ccp_flags_set(unit, isopen, isup) - int unit, isopen, isup; -{ - int cf[2]; - - cf[0] = (isopen? CCP_ISOPEN: 0) + (isup? CCP_ISUP: 0); - cf[1] = CCP_ISOPEN | CCP_ISUP | CCP_ERROR | CCP_FATALERROR; - if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - if (!hungup || errno != ENXIO) - error("Couldn't set kernel CCP state: %m"); - } -} - -/* - * get_idle_time - return how long the link has been idle. - */ -int -get_idle_time(u, ip) - int u; - struct ppp_idle *ip; -{ - return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0; -} - -/* - * get_ppp_stats - return statistics for the link. - */ -int -get_ppp_stats(u, stats) - int u; - struct pppd_stats *stats; -{ - struct ppp_stats s; - - if (!sync_serial && - strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) { - error("Couldn't get link statistics: %m"); - return 0; - } - stats->bytes_in = s.p.ppp_ibytes; - stats->bytes_out = s.p.ppp_obytes; - return 1; -} - -#if 0 -/* - * set_filters - transfer the pass and active filters to the kernel. - */ -int -set_filters(pass, active) - struct bpf_program *pass, *active; -{ - int ret = 1; - - if (pass->bf_len > 0) { - if (strioctl(pppfd, PPPIO_PASSFILT, pass, - sizeof(struct bpf_program), 0) < 0) { - error("Couldn't set pass-filter in kernel: %m"); - ret = 0; - } - } - if (active->bf_len > 0) { - if (strioctl(pppfd, PPPIO_ACTIVEFILT, active, - sizeof(struct bpf_program), 0) < 0) { - error("Couldn't set active-filter in kernel: %m"); - ret = 0; - } - } - return ret; -} -#endif - -/* - * 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 cf[2]; - - cf[0] = cf[1] = 0; - if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - if (errno != ENXIO && errno != EINVAL) - error("Couldn't get compression flags: %m"); - return 0; - } - return cf[0] & CCP_FATALERROR; -} - -/* - * sifvjcomp - config tcp header compression - */ -int -sifvjcomp(u, vjcomp, xcidcomp, xmaxcid) - int u, vjcomp, xcidcomp, xmaxcid; -{ - int cf[2]; - char maxcid[2]; - - if (vjcomp) { - maxcid[0] = xcidcomp; - maxcid[1] = 15; /* XXX should be rmaxcid */ - if (strioctl(pppfd, PPPIO_VJINIT, maxcid, sizeof(maxcid), 0) < 0) { - error("Couldn't initialize VJ compression: %m"); - } - } - - cf[0] = (vjcomp? COMP_VJC + DECOMP_VJC: 0) /* XXX this is wrong */ - + (xcidcomp? COMP_VJCCID + DECOMP_VJCCID: 0); - cf[1] = COMP_VJC + DECOMP_VJC + COMP_VJCCID + DECOMP_VJCCID; - if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - if (vjcomp) - error("Couldn't enable VJ compression: %m"); - } - - return 1; -} - -/* - * sifup - Config the interface up and enable IP packets to pass. - */ -int -sifup(u) - int u; -{ - struct ifreq ifr; - - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) { - error("Couldn't mark interface up (get): %m"); - return 0; - } - ifr.ifr_flags |= IFF_UP; - if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) { - error("Couldn't mark interface up (set): %m"); - return 0; - } - if_is_up = 1; - return 1; -} - -/* - * sifdown - Config the interface down and disable IP. - */ -int -sifdown(u) - int u; -{ - struct ifreq ifr; - - if (ipmuxid < 0) - return 1; - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) { - error("Couldn't mark interface down (get): %m"); - return 0; - } - ifr.ifr_flags &= ~IFF_UP; - if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) { - error("Couldn't mark interface down (set): %m"); - return 0; - } - if_is_up = 0; - return 1; -} - -/* - * sifnpmode - Set the mode for handling packets for a given NP. - */ -int -sifnpmode(u, proto, mode) - int u; - int proto; - enum NPmode mode; -{ - int npi[2]; - - npi[0] = proto; - npi[1] = (int) mode; - if (strioctl(pppfd, PPPIO_NPMODE, &npi, 2 * sizeof(int), 0) < 0) { - error("ioctl(set NP %d mode to %d): %m", proto, mode); - return 0; - } - return 1; -} - -#if defined(SOL2) && defined(INET6) -/* - * sif6up - Config the IPv6 interface up and enable IPv6 packets to pass. - */ -int -sif6up(u) - int u; -{ - struct lifreq lifr; - int fd; - - fd = socket(AF_INET6, SOCK_DGRAM, 0); - if (fd < 0) { - return 0; - } - - memset(&lifr, 0, sizeof(lifr)); - strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); - if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) { - close(fd); - return 0; - } - - lifr.lifr_flags |= IFF_UP; - strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); - if (ioctl(fd, SIOCSLIFFLAGS, &lifr) < 0) { - close(fd); - return 0; - } - - if6_is_up = 1; - close(fd); - return 1; -} - -/* - * sifdown - Config the IPv6 interface down and disable IPv6. - */ -int -sif6down(u) - int u; -{ - struct lifreq lifr; - int fd; - - fd = socket(AF_INET6, SOCK_DGRAM, 0); - if (fd < 0) - return 0; - - memset(&lifr, 0, sizeof(lifr)); - strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); - if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) { - close(fd); - return 0; - } - - lifr.lifr_flags &= ~IFF_UP; - strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); - if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) { - close(fd); - return 0; - } - - if6_is_up = 0; - close(fd); - return 1; -} - -/* - * sif6addr - Config the interface with an IPv6 link-local address - */ -int -sif6addr(u, o, h) - int u; - eui64_t o, h; -{ - struct lifreq lifr; - struct sockaddr_storage laddr; - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&laddr; - int fd; - - fd = socket(AF_INET6, SOCK_DGRAM, 0); - if (fd < 0) - return 0; - - memset(&lifr, 0, sizeof(lifr)); - strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); - - /* - * Do this because /dev/ppp responds to DL_PHYS_ADDR_REQ with - * zero values, hence the interface token came to be zero too, - * and without this, in.ndpd will complain - */ - IN6_LLTOKEN_FROM_EUI64(lifr, sin6, o); - if (ioctl(fd, SIOCSLIFTOKEN, &lifr) < 0) { - close(fd); - return 0; - } - - /* - * Set the interface address and destination address - */ - IN6_LLADDR_FROM_EUI64(lifr, sin6, o); - if (ioctl(fd, SIOCSLIFADDR, &lifr) < 0) { - close(fd); - return 0; - } - - memset(&lifr, 0, sizeof(lifr)); - strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); - IN6_LLADDR_FROM_EUI64(lifr, sin6, h); - if (ioctl(fd, SIOCSLIFDSTADDR, &lifr) < 0) { - close(fd); - return 0; - } - - return 1; -} - -/* - * cif6addr - Remove the IPv6 address from interface - */ -int -cif6addr(u, o, h) - int u; - eui64_t o, h; -{ - return 1; -} - -#endif /* defined(SOL2) && defined(INET6) */ - - -#define INET_ADDR(x) (((struct sockaddr_in *) &(x))->sin_addr.s_addr) - -/* - * sifaddr - Config the interface IP addresses and netmask. - */ -int -sifaddr(u, o, h, m) - int u; - u_int32_t o, h, m; -{ - struct ifreq ifr; - int ret = 1; - - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - ifr.ifr_addr.sa_family = AF_INET; - INET_ADDR(ifr.ifr_addr) = m; - if (ioctl(ipfd, SIOCSIFNETMASK, &ifr) < 0) { - error("Couldn't set IP netmask: %m"); - ret = 0; - } - ifr.ifr_addr.sa_family = AF_INET; - INET_ADDR(ifr.ifr_addr) = o; - if (ioctl(ipfd, SIOCSIFADDR, &ifr) < 0) { - error("Couldn't set local IP address: %m"); - ret = 0; - } - - /* - * On some systems, we have to explicitly set the point-to-point - * flag bit before we can set a destination address. - */ - if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) >= 0 - && (ifr.ifr_flags & IFF_POINTOPOINT) == 0) { - ifr.ifr_flags |= IFF_POINTOPOINT; - if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) { - error("Couldn't mark interface pt-to-pt: %m"); - ret = 0; - } - } - ifr.ifr_dstaddr.sa_family = AF_INET; - INET_ADDR(ifr.ifr_dstaddr) = h; - if (ioctl(ipfd, SIOCSIFDSTADDR, &ifr) < 0) { - error("Couldn't set remote IP address: %m"); - ret = 0; - } -#if 0 /* now done in ppp_send_config */ - ifr.ifr_metric = link_mtu; - if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) { - error("Couldn't set IP MTU: %m"); - } -#endif - - remote_addr = h; - return ret; -} - -/* - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - */ -int -cifaddr(u, o, h) - int u; - u_int32_t o, h; -{ -#if defined(__USLC__) /* was: #if 0 */ - cifroute(unit, ouraddr, hisaddr); - if (ipmuxid >= 0) { - notice("Removing ppp interface unit"); - if (ioctl(ipfd, I_UNLINK, ipmuxid) < 0) { - error("Can't remove ppp interface unit: %m"); - return 0; - } - ipmuxid = -1; - } -#endif - remote_addr = 0; - return 1; -} - -/* - * sifdefaultroute - assign a default route through the address given. - */ -int -sifdefaultroute(u, l, g) - int u; - u_int32_t l, g; -{ - struct rtentry rt; - -#if defined(__USLC__) - g = l; /* use the local address as gateway */ -#endif - memset(&rt, 0, sizeof(rt)); - rt.rt_dst.sa_family = AF_INET; - INET_ADDR(rt.rt_dst) = 0; - rt.rt_gateway.sa_family = AF_INET; - INET_ADDR(rt.rt_gateway) = g; - rt.rt_flags = RTF_GATEWAY; - - if (ioctl(ipfd, SIOCADDRT, &rt) < 0) { - error("Can't add default route: %m"); - return 0; - } - - default_route_gateway = g; - return 1; -} - -/* - * cifdefaultroute - delete a default route through the address given. - */ -int -cifdefaultroute(u, l, g) - int u; - u_int32_t l, g; -{ - struct rtentry rt; - -#if defined(__USLC__) - g = l; /* use the local address as gateway */ -#endif - memset(&rt, 0, sizeof(rt)); - rt.rt_dst.sa_family = AF_INET; - INET_ADDR(rt.rt_dst) = 0; - rt.rt_gateway.sa_family = AF_INET; - INET_ADDR(rt.rt_gateway) = g; - rt.rt_flags = RTF_GATEWAY; - - if (ioctl(ipfd, SIOCDELRT, &rt) < 0) { - error("Can't delete default route: %m"); - return 0; - } - - default_route_gateway = 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; - - memset(&arpreq, 0, sizeof(arpreq)); - if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) - return 0; - - arpreq.arp_pa.sa_family = AF_INET; - INET_ADDR(arpreq.arp_pa) = hisaddr; - arpreq.arp_flags = ATF_PERM | ATF_PUBL; - if (ioctl(ipfd, SIOCSARP, (caddr_t) &arpreq) < 0) { - error("Couldn't set proxy ARP entry: %m"); - return 0; - } - - proxy_arp_addr = hisaddr; - return 1; -} - -/* - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ -int -cifproxyarp(unit, hisaddr) - int unit; - u_int32_t hisaddr; -{ - struct arpreq arpreq; - - memset(&arpreq, 0, sizeof(arpreq)); - arpreq.arp_pa.sa_family = AF_INET; - INET_ADDR(arpreq.arp_pa) = hisaddr; - if (ioctl(ipfd, SIOCDARP, (caddr_t)&arpreq) < 0) { - error("Couldn't delete proxy ARP entry: %m"); - return 0; - } - - proxy_arp_addr = 0; - return 1; -} - -/* - * get_ether_addr - get the hardware address of an interface on the - * the same subnet as ipaddr. - */ -#define MAX_IFS 32 - -static int -get_ether_addr(ipaddr, hwaddr) - u_int32_t ipaddr; - struct sockaddr *hwaddr; -{ - struct ifreq *ifr, *ifend, ifreq; - int nif; - struct ifconf ifc; - u_int32_t ina, mask; - - /* - * Scan through the system's network interfaces. - */ -#ifdef SIOCGIFNUM - if (ioctl(ipfd, SIOCGIFNUM, &nif) < 0) -#endif - nif = MAX_IFS; - ifc.ifc_len = nif * sizeof(struct ifreq); - ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len); - if (ifc.ifc_buf == 0) - return 0; - if (ioctl(ipfd, SIOCGIFCONF, &ifc) < 0) { - warn("Couldn't get system interface list: %m"); - free(ifc.ifc_buf); - return 0; - } - ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - for (ifr = ifc.ifc_req; ifr < ifend; ++ifr) { - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - /* - * Check that the interface is up, and not point-to-point or loopback. - */ - strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - if (ioctl(ipfd, 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(ipfd, SIOCGIFNETMASK, &ifreq) < 0) - continue; - ina = INET_ADDR(ifr->ifr_addr); - mask = INET_ADDR(ifreq.ifr_addr); - if ((ipaddr & mask) == (ina & mask)) - break; - } - - if (ifr >= ifend) { - warn("No suitable interface found for proxy ARP"); - free(ifc.ifc_buf); - return 0; - } - - info("found interface %s for proxy ARP", ifr->ifr_name); - if (!get_hw_addr(ifr->ifr_name, ina, hwaddr)) { - error("Couldn't get hardware address for %s", ifr->ifr_name); - free(ifc.ifc_buf); - return 0; - } - - free(ifc.ifc_buf); - return 1; -} - -/* - * get_hw_addr_dlpi - obtain the hardware address using DLPI - */ -static int -get_hw_addr_dlpi(name, hwaddr) - char *name; - struct sockaddr *hwaddr; -{ - char *p, *q; - int unit, iffd, adrlen; - unsigned char *adrp; - char ifdev[24]; - struct { - union DL_primitives prim; - char space[64]; - } reply; - - /* - * We have to open the device and ask it for its hardware address. - * First split apart the device name and unit. - */ - slprintf(ifdev, sizeof(ifdev), "/dev/%s", name); - for (q = ifdev + strlen(ifdev); --q >= ifdev; ) - if (!isdigit(*q)) - break; - unit = atoi(q+1); - q[1] = 0; - - /* - * Open the device and do a DLPI attach and phys_addr_req. - */ - iffd = open(ifdev, O_RDWR); - if (iffd < 0) { - error("Can't open %s: %m", ifdev); - return 0; - } - if (dlpi_attach(iffd, unit) < 0 - || dlpi_get_reply(iffd, &reply.prim, DL_OK_ACK, sizeof(reply)) < 0 - || dlpi_info_req(iffd) < 0 - || dlpi_get_reply(iffd, &reply.prim, DL_INFO_ACK, sizeof(reply)) < 0) { - close(iffd); - return 0; - } - - adrlen = reply.prim.info_ack.dl_addr_length; - adrp = (unsigned char *)&reply + reply.prim.info_ack.dl_addr_offset; - -#if DL_CURRENT_VERSION >= 2 - if (reply.prim.info_ack.dl_sap_length < 0) - adrlen += reply.prim.info_ack.dl_sap_length; - else - adrp += reply.prim.info_ack.dl_sap_length; -#endif - - hwaddr->sa_family = AF_UNSPEC; - memcpy(hwaddr->sa_data, adrp, adrlen); - - return 1; -} -/* - * get_hw_addr - obtain the hardware address for a named interface. - */ -static int -get_hw_addr(name, ina, hwaddr) - char *name; - u_int32_t ina; - struct sockaddr *hwaddr; -{ - /* New way - get the address by doing an arp request. */ - int s; - struct arpreq req; - - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) - return 0; - memset(&req, 0, sizeof(req)); - req.arp_pa.sa_family = AF_INET; - INET_ADDR(req.arp_pa) = ina; - if (ioctl(s, SIOCGARP, &req) < 0) { - error("Couldn't get ARP entry for %s: %m", ip_ntoa(ina)); - return 0; - } - *hwaddr = req.arp_ha; - hwaddr->sa_family = AF_UNSPEC; - - return 1; -} - -static int -dlpi_attach(fd, ppa) - int fd, ppa; -{ - dl_attach_req_t req; - struct strbuf buf; - - req.dl_primitive = DL_ATTACH_REQ; - req.dl_ppa = ppa; - buf.len = sizeof(req); - buf.buf = (void *) &req; - return putmsg(fd, &buf, NULL, RS_HIPRI); -} - -static int -dlpi_info_req(fd) - int fd; -{ - dl_info_req_t req; - struct strbuf buf; - - req.dl_primitive = DL_INFO_REQ; - buf.len = sizeof(req); - buf.buf = (void *) &req; - return putmsg(fd, &buf, NULL, RS_HIPRI); -} - -static int -dlpi_get_reply(fd, reply, expected_prim, maxlen) - union DL_primitives *reply; - int fd, expected_prim, maxlen; -{ - struct strbuf buf; - int flags, n; - struct pollfd pfd; - - /* - * Use poll to wait for a message with a timeout. - */ - pfd.fd = fd; - pfd.events = POLLIN | POLLPRI; - do { - n = poll(&pfd, 1, 1000); - } while (n == -1 && errno == EINTR); - if (n <= 0) - return -1; - - /* - * Get the reply. - */ - buf.maxlen = maxlen; - buf.buf = (void *) reply; - flags = 0; - if (getmsg(fd, &buf, NULL, &flags) < 0) - return -1; - - if (buf.len < sizeof(ulong)) { - if (debug) - dbglog("dlpi response short (len=%d)\n", buf.len); - return -1; - } - - if (reply->dl_primitive == expected_prim) - return 0; - - if (debug) { - if (reply->dl_primitive == DL_ERROR_ACK) { - dbglog("dlpi error %d (unix errno %d) for prim %x\n", - reply->error_ack.dl_errno, reply->error_ack.dl_unix_errno, - reply->error_ack.dl_error_primitive); - } else { - dbglog("dlpi unexpected response prim %x\n", - reply->dl_primitive); - } - } - - return -1; -} - -/* - * 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; - int nif; - struct ifconf ifc; - - 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. - */ -#ifdef SIOCGIFNUM - if (ioctl(ipfd, SIOCGIFNUM, &nif) < 0) -#endif - nif = MAX_IFS; - ifc.ifc_len = nif * sizeof(struct ifreq); - ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len); - if (ifc.ifc_buf == 0) - return mask; - if (ioctl(ipfd, SIOCGIFCONF, &ifc) < 0) { - warn("Couldn't get system interface list: %m"); - free(ifc.ifc_buf); - return mask; - } - ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - for (ifr = ifc.ifc_req; ifr < ifend; ++ifr) { - /* - * Check the interface's internet address. - */ - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - ina = INET_ADDR(ifr->ifr_addr); - if ((ntohl(ina) & nmask) != (addr & nmask)) - continue; - /* - * Check that the interface is up, and not point-to-point or loopback. - */ - strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - if (ioctl(ipfd, 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(ipfd, SIOCGIFNETMASK, &ifreq) < 0) - continue; - mask |= INET_ADDR(ifreq.ifr_addr); - } - - free(ifc.ifc_buf); - return mask; -} - -/* - * logwtmp - write an accounting record to the /var/adm/wtmp file. - */ -void -logwtmp(line, name, host) - const char *line, *name, *host; -{ - static struct utmpx utmpx; - - if (name[0] != 0) { - /* logging in */ - strncpy(utmpx.ut_user, name, sizeof(utmpx.ut_user)); - strncpy(utmpx.ut_id, ifname, sizeof(utmpx.ut_id)); - strncpy(utmpx.ut_line, line, sizeof(utmpx.ut_line)); - utmpx.ut_pid = getpid(); - utmpx.ut_type = USER_PROCESS; - } else { - utmpx.ut_type = DEAD_PROCESS; - } - gettimeofday(&utmpx.ut_tv, NULL); - updwtmpx("/var/adm/wtmpx", &utmpx); -} - -/* - * get_host_seed - return the serial number of this machine. - */ -int -get_host_seed() -{ - char buf[32]; - - if (sysinfo(SI_HW_SERIAL, buf, sizeof(buf)) < 0) { - error("sysinfo: %m"); - return 0; - } - return (int) strtoul(buf, NULL, 16); -} - -static int -strioctl(fd, cmd, ptr, ilen, olen) - int fd, cmd, ilen, olen; - void *ptr; -{ - struct strioctl str; - - str.ic_cmd = cmd; - str.ic_timout = 0; - str.ic_len = ilen; - str.ic_dp = ptr; - if (ioctl(fd, I_STR, &str) == -1) - return -1; - if (str.ic_len != olen) - dbglog("strioctl: expected %d bytes, got %d for cmd %x\n", - olen, str.ic_len, cmd); - return 0; -} - -#if 0 -/* - * lock - create a lock file for the named lock device - */ - -#define LOCK_PREFIX "/var/spool/locks/LK." -static char lock_file[40]; /* name of lock file created */ - -int -lock(dev) - char *dev; -{ - int n, fd, pid; - struct stat sbuf; - char ascii_pid[12]; - - if (stat(dev, &sbuf) < 0) { - error("Can't get device number for %s: %m", dev); - return -1; - } - if ((sbuf.st_mode & S_IFMT) != S_IFCHR) { - error("Can't lock %s: not a character device", dev); - return -1; - } - slprintf(lock_file, sizeof(lock_file), "%s%03d.%03d.%03d", - LOCK_PREFIX, major(sbuf.st_dev), - major(sbuf.st_rdev), minor(sbuf.st_rdev)); - - 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, ascii_pid, 11); - if (n <= 0) { - error("Can't read pid from lock file %s", lock_file); - close(fd); - } else { - ascii_pid[n] = 0; - pid = atoi(ascii_pid); - if (pid > 0 && kill(pid, 0) == -1 && errno == ESRCH) { - /* pid no longer exists - remove the lock file */ - if (unlink(lock_file) == 0) { - close(fd); - notice("Removed stale lock on %s (pid %d)", - dev, pid); - continue; - } else - warn("Couldn't remove stale lock on %s", - dev); - } else - notice("Device %s is locked by pid %d", - dev, pid); - } - close(fd); - } else - error("Can't create lock file %s: %m", lock_file); - lock_file[0] = 0; - return -1; - } - - slprintf(ascii_pid, sizeof(ascii_pid), "%10d\n", getpid()); - write(fd, ascii_pid, 11); - - close(fd); - return 1; -} - -/* - * unlock - remove our lockfile - */ -void -unlock() -{ - if (lock_file[0]) { - unlink(lock_file); - lock_file[0] = 0; - } -} -#endif - -/* - * cifroute - delete a route through the addresses given. - */ -int -cifroute(u, our, his) - int u; - u_int32_t our, his; -{ - struct rtentry rt; - - memset(&rt, 0, sizeof(rt)); - rt.rt_dst.sa_family = AF_INET; - INET_ADDR(rt.rt_dst) = his; - rt.rt_gateway.sa_family = AF_INET; - INET_ADDR(rt.rt_gateway) = our; - rt.rt_flags = RTF_HOST; - - if (ioctl(ipfd, SIOCDELRT, &rt) < 0) { - error("Can't delete route: %m"); - return 0; - } - - return 1; -} - -/* - * have_route_to - determine if the system has a route to the specified - * IP address. Returns 0 if not, 1 if so, -1 if we can't tell. - * `addr' is in network byte order. - * For demand mode to work properly, we have to ignore routes - * through our own interface. - */ -#ifndef T_CURRENT /* needed for Solaris 2.5 */ -#define T_CURRENT MI_T_CURRENT -#endif - -int -have_route_to(addr) - u_int32_t addr; -{ -#ifdef SOL2 - int fd, r, flags, i; - struct { - struct T_optmgmt_req req; - struct opthdr hdr; - } req; - union { - struct T_optmgmt_ack ack; - unsigned char space[64]; - } ack; - struct opthdr *rh; - struct strbuf cbuf, dbuf; - int nroutes; - mib2_ipRouteEntry_t routes[8]; - mib2_ipRouteEntry_t *rp; - - fd = open(mux_dev_name, O_RDWR); - if (fd < 0) { - warn("have_route_to: couldn't open %s: %m", mux_dev_name); - return -1; - } - - req.req.PRIM_type = T_OPTMGMT_REQ; - req.req.OPT_offset = (char *) &req.hdr - (char *) &req; - req.req.OPT_length = sizeof(req.hdr); - req.req.MGMT_flags = T_CURRENT; - - req.hdr.level = MIB2_IP; - req.hdr.name = 0; - req.hdr.len = 0; - - cbuf.buf = (char *) &req; - cbuf.len = sizeof(req); - - if (putmsg(fd, &cbuf, NULL, 0) == -1) { - warn("have_route_to: putmsg: %m"); - close(fd); - return -1; - } - - for (;;) { - cbuf.buf = (char *) &ack; - cbuf.maxlen = sizeof(ack); - dbuf.buf = (char *) routes; - dbuf.maxlen = sizeof(routes); - flags = 0; - r = getmsg(fd, &cbuf, &dbuf, &flags); - if (r == -1) { - warn("have_route_to: getmsg: %m"); - close(fd); - return -1; - } - - if (cbuf.len < sizeof(struct T_optmgmt_ack) - || ack.ack.PRIM_type != T_OPTMGMT_ACK - || ack.ack.MGMT_flags != T_SUCCESS - || ack.ack.OPT_length < sizeof(struct opthdr)) { - dbglog("have_route_to: bad message len=%d prim=%d", - cbuf.len, ack.ack.PRIM_type); - close(fd); - return -1; - } - - rh = (struct opthdr *) ((char *)&ack + ack.ack.OPT_offset); - if (rh->level == 0 && rh->name == 0) - break; - if (rh->level != MIB2_IP || rh->name != MIB2_IP_21) { - while (r == MOREDATA) - r = getmsg(fd, NULL, &dbuf, &flags); - continue; - } - - for (;;) { - nroutes = dbuf.len / sizeof(mib2_ipRouteEntry_t); - for (rp = routes, i = 0; i < nroutes; ++i, ++rp) { - if (rp->ipRouteMask != ~0) { - dbglog("have_route_to: dest=%x gw=%x mask=%x\n", - rp->ipRouteDest, rp->ipRouteNextHop, - rp->ipRouteMask); - if (((addr ^ rp->ipRouteDest) & rp->ipRouteMask) == 0 - && rp->ipRouteNextHop != remote_addr) - return 1; - } - } - if (r == 0) - break; - r = getmsg(fd, NULL, &dbuf, &flags); - } - } - close(fd); - return 0; -#else - return -1; -#endif /* SOL2 */ -} - -/* - * get_pty - get a pty master/slave pair and chown the slave side to - * the uid given. Assumes slave_name points to MAXPATHLEN bytes of space. - */ -int -get_pty(master_fdp, slave_fdp, slave_name, uid) - int *master_fdp; - int *slave_fdp; - char *slave_name; - int uid; -{ - int mfd, sfd; - char *pty_name; - struct termios tios; - - mfd = open("/dev/ptmx", O_RDWR); - if (mfd < 0) { - error("Couldn't open pty master: %m"); - return 0; - } - - pty_name = ptsname(mfd); - if (pty_name == NULL) { - error("Couldn't get name of pty slave"); - close(mfd); - return 0; - } - if (chown(pty_name, uid, -1) < 0) - warn("Couldn't change owner of pty slave: %m"); - if (chmod(pty_name, S_IRUSR | S_IWUSR) < 0) - warn("Couldn't change permissions on pty slave: %m"); - if (unlockpt(mfd) < 0) - warn("Couldn't unlock pty slave: %m"); - - sfd = open(pty_name, O_RDWR); - if (sfd < 0) { - error("Couldn't open pty slave %s: %m", pty_name); - close(mfd); - return 0; - } - if (ioctl(sfd, I_PUSH, "ptem") < 0) - warn("Couldn't push ptem module on pty slave: %m"); - - dbglog("Using %s", pty_name); - strlcpy(slave_name, pty_name, MAXPATHLEN); - *master_fdp = mfd; - *slave_fdp = sfd; - - return 1; -} diff --git a/mdk-stage1/ppp/pppd/sys-sunos4.c b/mdk-stage1/ppp/pppd/sys-sunos4.c deleted file mode 100644 index 3344948e9..000000000 --- a/mdk-stage1/ppp/pppd/sys-sunos4.c +++ /dev/null @@ -1,1559 +0,0 @@ -/* - * System-dependent procedures for pppd under SunOS 4. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - */ - -#define RCSID "$Id$" - -#include <stdio.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <termios.h> -#include <signal.h> -#include <malloc.h> -#include <utmp.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/sockio.h> -#include <sys/stream.h> -#include <sys/stropts.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/poll.h> -#include <net/if.h> -#include <net/if_arp.h> -#include <net/nit_if.h> -#include <net/route.h> -#include <net/ppp_defs.h> -#include <net/pppio.h> -#include <netinet/in.h> - -#include "pppd.h" - -#if defined(sun) && defined(sparc) -#include <alloca.h> -#ifndef __GNUC__ -extern void *alloca(); -#endif -#endif /*sparc*/ - -static const char rcsid[] = RCSID; - -static int pppfd; -static int fdmuxid = -1; -static int iffd; -static int sockfd; - -static int restore_term; -static struct termios inittermios; -static struct winsize wsinfo; /* Initial window size info */ -static pid_t parent_pid; /* PID of our parent */ - -extern u_char inpacket_buf[]; /* borrowed from main.c */ - -#define MAX_POLLFDS 32 -static struct pollfd pollfds[MAX_POLLFDS]; -static int n_pollfds; - -static int link_mtu, link_mru; - -#define NMODULES 32 -static int tty_nmodules; -static char tty_modules[NMODULES][FMNAMESZ+1]; - -static int if_is_up; /* Interface has been marked up */ -static u_int32_t ifaddrs[2]; /* local and remote addresses */ -static u_int32_t default_route_gateway; /* Gateway for default route added */ -static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ - -/* Prototypes for procedures local to this file. */ -static int translate_speed __P((int)); -static int baud_rate_of __P((int)); -static int get_ether_addr __P((u_int32_t, struct sockaddr *)); -static int strioctl __P((int, int, void *, int, int)); - - -/* - * sys_init - System-dependent initialization. - */ -void -sys_init() -{ - int x; - - /* Get an internet socket for doing socket ioctl's on. */ - if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - fatal("Couldn't create IP socket: %m"); - - /* - * We may want to send a SIGHUP to the session leader associated - * with our controlling terminal later. Because SunOS doesn't - * have getsid(), we make do with sending the signal to our - * parent process. - */ - parent_pid = getppid(); - - /* - * Open the ppp device. - */ - pppfd = open("/dev/ppp", O_RDWR | O_NONBLOCK, 0); - if (pppfd < 0) - fatal("Can't open /dev/ppp: %m"); - if (kdebugflag) { - x = PPPDBG_LOG + PPPDBG_DRIVER; - strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0); - } - - /* Assign a new PPA and get its unit number. */ - if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0) - fatal("Can't create new PPP interface: %m"); - - /* - * Open the ppp device again and push the if_ppp module on it. - */ - iffd = open("/dev/ppp", O_RDWR, 0); - if (iffd < 0) - fatal("Can't open /dev/ppp (2): %m"); - if (kdebugflag) { - x = PPPDBG_LOG + PPPDBG_DRIVER; - strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0); - } - if (strioctl(iffd, PPPIO_ATTACH, &ifunit, sizeof(int), 0) < 0) - fatal("Couldn't attach ppp interface to device: %m"); - if (ioctl(iffd, I_PUSH, "if_ppp") < 0) - fatal("Can't push ppp interface module: %m"); - if (kdebugflag) { - x = PPPDBG_LOG + PPPDBG_IF; - strioctl(iffd, PPPIO_DEBUG, &x, sizeof(int), 0); - } - if (strioctl(iffd, PPPIO_NEWPPA, &ifunit, sizeof(int), 0) < 0) - fatal("Couldn't create ppp interface unit: %m"); - x = PPP_IP; - if (strioctl(iffd, PPPIO_BIND, &x, sizeof(int), 0) < 0) - fatal("Couldn't bind ppp interface to IP SAP: %m"); - - n_pollfds = 0; -} - -/* - * sys_cleanup - restore any system state we modified before exiting: - * mark the interface down, delete default route and/or proxy arp entry. - * This shouldn't call die() because it's called from die(). - */ -void -sys_cleanup() -{ - if (if_is_up) - sifdown(0); - if (ifaddrs[0]) - cifaddr(0, ifaddrs[0], ifaddrs[1]); - if (default_route_gateway) - cifdefaultroute(0, 0, default_route_gateway); - if (proxy_arp_addr) - cifproxyarp(0, proxy_arp_addr); -} - -/* - * sys_close - Clean up in a child process before execing. - */ -void -sys_close() -{ - close(iffd); - close(pppfd); - close(sockfd); -} - -/* - * sys_check_options - check the options that the user specified - */ -int -sys_check_options() -{ - return 1; -} - -#if 0 -/* - * daemon - Detach us from controlling terminal session. - */ -int -daemon(nochdir, noclose) - int nochdir, noclose; -{ - int pid; - - if ((pid = fork()) < 0) - return -1; - if (pid != 0) - exit(0); /* parent dies */ - setsid(); - if (!nochdir) - chdir("/"); - if (!noclose) { - fclose(stdin); /* don't need stdin, stdout, stderr */ - fclose(stdout); - fclose(stderr); - } - return 0; -} -#endif - -/* - * ppp_available - check whether the system has any ppp interfaces - */ -int -ppp_available() -{ - struct stat buf; - - return stat("/dev/ppp", &buf) >= 0; -} - -/* - * tty_establish_ppp - Turn the serial port into a ppp interface. - */ -int -tty_establish_ppp(fd) - int fd; -{ - int i; - - /* Pop any existing modules off the tty stream. */ - for (i = 0;; ++i) - if (ioctl(fd, I_LOOK, tty_modules[i]) < 0 - || ioctl(fd, I_POP, 0) < 0) - break; - tty_nmodules = i; - - /* Push the async hdlc module and the compressor module. */ - if (ioctl(fd, I_PUSH, "ppp_ahdl") < 0) - fatal("Couldn't push PPP Async HDLC module: %m"); - if (ioctl(fd, I_PUSH, "ppp_comp") < 0) - error("Couldn't push PPP compression module: %m"); - - /* Link the serial port under the PPP multiplexor. */ - if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0) - fatal("Can't link tty to PPP mux: %m"); - - return pppfd; -} - -/* - * disestablish_ppp - Restore the serial port to normal operation. - * It attempts to reconstruct the stream with the previously popped - * modules. This shouldn't call die() because it's called from die(). - */ -void -tty_disestablish_ppp(fd) - int fd; -{ - int i; - - if (fdmuxid >= 0) { - if (ioctl(pppfd, I_UNLINK, fdmuxid) < 0) { - if (!hungup) - error("Can't unlink tty from PPP mux: %m"); - } - fdmuxid = -1; - - if (!hungup) { - while (ioctl(fd, I_POP, 0) >= 0) - ; - for (i = tty_nmodules - 1; i >= 0; --i) - if (ioctl(fd, I_PUSH, tty_modules[i]) < 0) - error("Couldn't restore tty module %s: %m", - tty_modules[i]); - } - if (hungup && default_device && parent_pid > 0) { - /* - * If we have received a hangup, we need to send a SIGHUP - * to the terminal's controlling process. The reason is - * that the original stream head for the terminal hasn't - * seen the M_HANGUP message (it went up through the ppp - * driver to the stream head for our fd to /dev/ppp). - * Actually we send the signal to the process that invoked - * pppd, since SunOS doesn't have getsid(). - */ - kill(parent_pid, SIGHUP); - } - } -} - -/* - * Check whether the link seems not to be 8-bit clean. - */ -void -clean_check() -{ - int x; - char *s; - - if (strioctl(pppfd, PPPIO_GCLEAN, &x, 0, sizeof(x)) < 0) - return; - s = NULL; - switch (~x) { - case RCV_B7_0: - s = "bit 7 set to 1"; - break; - case RCV_B7_1: - s = "bit 7 set to 0"; - break; - case RCV_EVNP: - s = "odd parity"; - break; - case RCV_ODDP: - s = "even parity"; - break; - } - if (s != NULL) { - warn("Serial link is not 8-bit clean:"); - warn("All received characters had %s", s); - } -} - -/* - * 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 B57600 - { 57600, B57600 }, -#endif -#ifdef B115200 - { 115200, B115200 }, -#endif - { 0, 0 } -}; - -/* - * Translate from bits/second to a speed_t. - */ -static 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; - warn("speed %d not supported", bps); - return 0; -} - -/* - * Translate from a speed_t to bits/second. - */ -static 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. - */ -void -set_up_tty(fd, local) - int fd, local; -{ - int speed; - struct termios tios; - - if (tcgetattr(fd, &tios) < 0) - fatal("tcgetattr: %m"); - - if (!restore_term) { - inittermios = tios; - ioctl(fd, TIOCGWINSZ, &wsinfo); - } - - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); - if (crtscts > 0) - tios.c_cflag |= CRTSCTS; - else if (crtscts < 0) - tios.c_cflag &= ~CRTSCTS; - - 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 |= IXON | 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); - /* - * We can't proceed if the serial port speed is 0, - * since that implies that the serial port is disabled. - */ - if (speed == B0) - fatal("Baud rate for %s is 0; need explicit baud rate", devnam); - } - - if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) - fatal("tcsetattr: %m"); - - baud_rate = inspeed = baud_rate_of(speed); - restore_term = 1; -} - -/* - * restore_tty - restore the terminal to the saved settings. - */ -void -restore_tty(fd) - int fd; -{ - if (restore_term) { - if (!default_device) { - /* - * Turn off echoing, because otherwise we can get into - * a loop with the tty and the modem echoing to each other. - * We presume we are the sole user of this tty device, so - * when we close it, it will revert to its defaults anyway. - */ - inittermios.c_lflag &= ~(ECHO | ECHONL); - } - if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) - if (!hungup && errno != ENXIO) - warn("tcsetattr: %m"); - ioctl(fd, TIOCSWINSZ, &wsinfo); - restore_term = 0; - } -} - -/* - * setdtr - control the DTR line on the serial port. - * This is called from die(), so it shouldn't call die(). - */ -void -setdtr(fd, on) -int fd, on; -{ - int modembits = TIOCM_DTR; - - ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits); -} - -/* - * open_loopback - open the device we use for getting packets - * in demand mode. Under SunOS, we use our existing fd - * to the ppp driver. - */ -int -open_ppp_loopback() -{ - return pppfd; -} - -/* - * output - Output PPP packet. - */ -void -output(unit, p, len) - int unit; - u_char *p; - int len; -{ - struct strbuf data; - int retries; - struct pollfd pfd; - - if (debug) - dbglog("sent %P", p, len); - - data.len = len; - data.buf = (caddr_t) p; - retries = 4; - while (putmsg(pppfd, NULL, &data, 0) < 0) { - if (--retries < 0 || (errno != EWOULDBLOCK && errno != EAGAIN)) { - if (errno != ENXIO) - error("Couldn't send packet: %m"); - break; - } - pfd.fd = pppfd; - pfd.events = POLLOUT; - poll(&pfd, 1, 250); /* wait for up to 0.25 seconds */ - } -} - - -/* - * wait_input - wait until there is data available, - * for the length of time specified by *timo (indefinite - * if timo is NULL). - */ -void -wait_input(timo) - struct timeval *timo; -{ - int t; - - t = timo == NULL? -1: timo->tv_sec * 1000 + timo->tv_usec / 1000; - if (poll(pollfds, n_pollfds, t) < 0 && errno != EINTR) { - if (errno != EAGAIN) - fatal("poll: %m"); - /* we can get EAGAIN on a heavily loaded system, - * just wait a short time and try again. */ - usleep(50000); - } -} - -/* - * add_fd - add an fd to the set that wait_input waits for. - */ -void add_fd(fd) - int fd; -{ - int n; - - for (n = 0; n < n_pollfds; ++n) - if (pollfds[n].fd == fd) - return; - if (n_pollfds < MAX_POLLFDS) { - pollfds[n_pollfds].fd = fd; - pollfds[n_pollfds].events = POLLIN | POLLPRI | POLLHUP; - ++n_pollfds; - } else - error("Too many inputs!"); -} - -/* - * remove_fd - remove an fd from the set that wait_input waits for. - */ -void remove_fd(fd) - int fd; -{ - int n; - - for (n = 0; n < n_pollfds; ++n) { - if (pollfds[n].fd == fd) { - while (++n < n_pollfds) - pollfds[n-1] = pollfds[n]; - --n_pollfds; - break; - } - } -} - -#if 0 -/* - * wait_loop_output - wait until there is data available on the - * loopback, for the length of time specified by *timo (indefinite - * if timo is NULL). - */ -void -wait_loop_output(timo) - struct timeval *timo; -{ - wait_input(timo); -} - -/* - * wait_time - wait for a given length of time or until a - * signal is received. - */ -void -wait_time(timo) - struct timeval *timo; -{ - int n; - - n = select(0, NULL, NULL, NULL, timo); - if (n < 0 && errno != EINTR) - fatal("select: %m"); -} -#endif - -/* - * read_packet - get a PPP packet from the serial device. - */ -int -read_packet(buf) - u_char *buf; -{ - struct strbuf ctrl, data; - int flags, len; - unsigned char ctrlbuf[64]; - - for (;;) { - data.maxlen = PPP_MRU + PPP_HDRLEN; - data.buf = (caddr_t) buf; - ctrl.maxlen = sizeof(ctrlbuf); - ctrl.buf = (caddr_t) ctrlbuf; - flags = 0; - len = getmsg(pppfd, &ctrl, &data, &flags); - if (len < 0) { - if (errno == EAGAIN || errno == EINTR) - return -1; - fatal("Error reading packet: %m"); - } - - if (ctrl.len <= 0) - return data.len; - - /* - * Got a M_PROTO or M_PCPROTO message. Huh? - */ - if (debug) - dbglog("got ctrl msg len=%d", ctrl.len); - - } -} - -/* - * get_loop_output - get outgoing packets from the ppp device, - * and detect when we want to bring the real link up. - * Return value is 1 if we need to bring up the link, 0 otherwise. - */ -int -get_loop_output() -{ - int len; - int rv = 0; - - while ((len = read_packet(inpacket_buf)) > 0) { - if (loop_frame(inpacket_buf, len)) - rv = 1; - } - return rv; -} - -/* - * 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; -{ - int cf[2]; - struct ifreq ifr; - - link_mtu = mtu; - if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) { - if (hungup && errno == ENXIO) - return; - error("Couldn't set MTU: %m"); - } - if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { - error("Couldn't set transmit ACCM: %m"); - } - cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0); - cf[1] = COMP_PROT | COMP_AC; - if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - error("Couldn't set prot/AC compression: %m"); - } - - /* set mtu for ip as well */ - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - ifr.ifr_metric = link_mtu; - if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) { - error("Couldn't set IP MTU: %m"); - } -} - -/* - * ppp_set_xaccm - set the extended transmit ACCM for the interface. - */ -void -ppp_set_xaccm(unit, accm) - int unit; - ext_accm accm; -{ - if (strioctl(pppfd, PPPIO_XACCM, accm, sizeof(ext_accm), 0) < 0) { - if (!hungup || errno != ENXIO) - warn("Couldn't set extended ACCM: %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 cf[2]; - - link_mru = mru; - if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) { - if (hungup && errno == ENXIO) - return; - error("Couldn't set MRU: %m"); - } - if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { - error("Couldn't set receive ACCM: %m"); - } - cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0); - cf[1] = DECOMP_PROT | DECOMP_AC; - if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - error("Couldn't set prot/AC decompression: %m"); - } -} - -/* - * ccp_test - ask kernel whether a given compression method - * is acceptable for use. - */ -int -ccp_test(unit, opt_ptr, opt_len, for_transmit) - int unit, opt_len, for_transmit; - u_char *opt_ptr; -{ - if (strioctl(pppfd, (for_transmit? PPPIO_XCOMP: PPPIO_RCOMP), - opt_ptr, opt_len, 0) >= 0) - return 1; - return (errno == ENOSR)? 0: -1; -} - -/* - * ccp_flags_set - inform kernel about the current state of CCP. - */ -void -ccp_flags_set(unit, isopen, isup) - int unit, isopen, isup; -{ - int cf[2]; - - cf[0] = (isopen? CCP_ISOPEN: 0) + (isup? CCP_ISUP: 0); - cf[1] = CCP_ISOPEN | CCP_ISUP | CCP_ERROR | CCP_FATALERROR; - if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - if (!hungup || errno != ENXIO) - error("Couldn't set kernel CCP state: %m"); - } -} - -/* - * get_idle_time - return how long the link has been idle. - */ -int -get_idle_time(u, ip) - int u; - struct ppp_idle *ip; -{ - return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0; -} - -/* - * get_ppp_stats - return statistics for the link. - */ -int -get_ppp_stats(u, stats) - int u; - struct pppd_stats *stats; -{ - struct ppp_stats s; - - if (strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) { - error("Couldn't get link statistics: %m"); - return 0; - } - stats->bytes_in = s.p.ppp_ibytes; - stats->bytes_out = s.p.ppp_obytes; - return 1; -} - - -/* - * 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 cf[2]; - - cf[0] = cf[1] = 0; - if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - if (errno != ENXIO && errno != EINVAL) - error("Couldn't get compression flags: %m"); - return 0; - } - return cf[0] & CCP_FATALERROR; -} - -/* - * sifvjcomp - config tcp header compression - */ -int -sifvjcomp(u, vjcomp, xcidcomp, xmaxcid) - int u, vjcomp, xcidcomp, xmaxcid; -{ - int cf[2]; - char maxcid[2]; - - if (vjcomp) { - maxcid[0] = xcidcomp; - maxcid[1] = 15; /* XXX should be rmaxcid */ - if (strioctl(pppfd, PPPIO_VJINIT, maxcid, sizeof(maxcid), 0) < 0) { - error("Couldn't initialize VJ compression: %m"); - } - } - - cf[0] = (vjcomp? COMP_VJC + DECOMP_VJC: 0) /* XXX this is wrong */ - + (xcidcomp? COMP_VJCCID + DECOMP_VJCCID: 0); - cf[1] = COMP_VJC + DECOMP_VJC + COMP_VJCCID + DECOMP_VJCCID; - if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { - if (vjcomp) - error("Couldn't enable VJ compression: %m"); - } - - return 1; -} - -/* - * sifup - Config the interface up and enable IP packets to pass. - */ -int -sifup(u) - int u; -{ - struct ifreq ifr; - - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { - error("Couldn't mark interface up (get): %m"); - return 0; - } - ifr.ifr_flags |= IFF_UP; - if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { - error("Couldn't mark interface up (set): %m"); - return 0; - } - if_is_up = 1; - return 1; -} - -/* - * sifdown - Config the interface down and disable IP. - */ -int -sifdown(u) - int u; -{ - struct ifreq ifr; - - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { - error("Couldn't mark interface down (get): %m"); - return 0; - } - if ((ifr.ifr_flags & IFF_UP) != 0) { - ifr.ifr_flags &= ~IFF_UP; - if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { - error("Couldn't mark interface down (set): %m"); - return 0; - } - } - if_is_up = 0; - return 1; -} - -/* - * sifnpmode - Set the mode for handling packets for a given NP. - */ -int -sifnpmode(u, proto, mode) - int u; - int proto; - enum NPmode mode; -{ - int npi[2]; - - npi[0] = proto; - npi[1] = (int) mode; - if (strioctl(pppfd, PPPIO_NPMODE, npi, 2 * sizeof(int), 0) < 0) { - error("ioctl(set NP %d mode to %d): %m", proto, mode); - return 0; - } - return 1; -} - -#define INET_ADDR(x) (((struct sockaddr_in *) &(x))->sin_addr.s_addr) - -/* - * sifaddr - Config the interface IP addresses and netmask. - */ -int -sifaddr(u, o, h, m) - int u; - u_int32_t o, h, m; -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - ifr.ifr_addr.sa_family = AF_INET; - INET_ADDR(ifr.ifr_addr) = m; - if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) { - error("Couldn't set IP netmask: %m"); - } - ifr.ifr_addr.sa_family = AF_INET; - INET_ADDR(ifr.ifr_addr) = o; - if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) { - error("Couldn't set local IP address: %m"); - } - ifr.ifr_dstaddr.sa_family = AF_INET; - INET_ADDR(ifr.ifr_dstaddr) = h; - if (ioctl(sockfd, SIOCSIFDSTADDR, &ifr) < 0) { - error("Couldn't set remote IP address: %m"); - } -#if 0 /* now done in ppp_send_config */ - ifr.ifr_metric = link_mtu; - if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) { - error("Couldn't set IP MTU: %m"); - } -#endif - ifaddrs[0] = o; - ifaddrs[1] = h; - - return 1; -} - -/* - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - */ -int -cifaddr(u, o, h) - int u; - u_int32_t o, h; -{ - struct rtentry rt; - - bzero(&rt, sizeof(rt)); - rt.rt_dst.sa_family = AF_INET; - INET_ADDR(rt.rt_dst) = h; - rt.rt_gateway.sa_family = AF_INET; - INET_ADDR(rt.rt_gateway) = o; - rt.rt_flags = RTF_HOST; - if (ioctl(sockfd, SIOCDELRT, &rt) < 0) - error("Couldn't delete route through interface: %m"); - ifaddrs[0] = 0; - return 1; -} - -/* - * sifdefaultroute - assign a default route through the address given. - */ -int -sifdefaultroute(u, l, g) - int u; - u_int32_t l, g; -{ - struct rtentry rt; - - bzero(&rt, sizeof(rt)); - rt.rt_dst.sa_family = AF_INET; - INET_ADDR(rt.rt_dst) = 0; - rt.rt_gateway.sa_family = AF_INET; - INET_ADDR(rt.rt_gateway) = g; - rt.rt_flags = RTF_GATEWAY; - - if (ioctl(sockfd, SIOCADDRT, &rt) < 0) { - error("Can't add default route: %m"); - return 0; - } - - default_route_gateway = g; - return 1; -} - -/* - * cifdefaultroute - delete a default route through the address given. - */ -int -cifdefaultroute(u, l, g) - int u; - u_int32_t l, g; -{ - struct rtentry rt; - - bzero(&rt, sizeof(rt)); - rt.rt_dst.sa_family = AF_INET; - INET_ADDR(rt.rt_dst) = 0; - rt.rt_gateway.sa_family = AF_INET; - INET_ADDR(rt.rt_gateway) = g; - rt.rt_flags = RTF_GATEWAY; - - if (ioctl(sockfd, SIOCDELRT, &rt) < 0) { - error("Can't delete default route: %m"); - return 0; - } - - default_route_gateway = 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)); - if (!get_ether_addr(hisaddr, &arpreq.arp_ha)) - return 0; - - arpreq.arp_pa.sa_family = AF_INET; - INET_ADDR(arpreq.arp_pa) = hisaddr; - arpreq.arp_flags = ATF_PERM | ATF_PUBL; - if (ioctl(sockfd, SIOCSARP, (caddr_t) &arpreq) < 0) { - error("Couldn't set proxy ARP entry: %m"); - return 0; - } - - proxy_arp_addr = hisaddr; - 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)); - arpreq.arp_pa.sa_family = AF_INET; - INET_ADDR(arpreq.arp_pa) = hisaddr; - if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) { - error("Couldn't delete proxy ARP entry: %m"); - return 0; - } - - proxy_arp_addr = 0; - return 1; -} - -/* - * get_ether_addr - get the hardware address of an interface on the - * the same subnet as ipaddr. - */ -#define MAX_IFS 32 - -static int -get_ether_addr(ipaddr, hwaddr) - u_int32_t ipaddr; - struct sockaddr *hwaddr; -{ - struct ifreq *ifr, *ifend; - u_int32_t ina, mask; - struct ifreq ifreq; - struct ifconf ifc; - struct ifreq ifs[MAX_IFS]; - int nit_fd; - - ifc.ifc_len = sizeof(ifs); - ifc.ifc_req = ifs; - if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { - error("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) { - - /* - * Check that the interface is up, and not point-to-point - * or loopback. - */ - strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - 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; - ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; - mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr; - if ((ipaddr & mask) != (ina & mask)) - continue; - - break; - } - } - - if (ifr >= ifend) - return 0; - info("found interface %s for proxy arp", ifr->ifr_name); - - /* - * Grab the physical address for this interface. - */ - if ((nit_fd = open("/dev/nit", O_RDONLY)) < 0) { - error("Couldn't open /dev/nit: %m"); - return 0; - } - strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); - if (ioctl(nit_fd, NIOCBIND, &ifreq) < 0 - || ioctl(nit_fd, SIOCGIFADDR, &ifreq) < 0) { - error("Couldn't get hardware address for %s: %m", - ifreq.ifr_name); - close(nit_fd); - return 0; - } - - hwaddr->sa_family = AF_UNSPEC; - memcpy(hwaddr->sa_data, ifreq.ifr_addr.sa_data, 6); - close(nit_fd); - return 1; -} - -/* - * have_route_to - determine if the system has any route to - * a given IP address. - * For demand mode to work properly, we have to ignore routes - * through our own interface. - */ -int have_route_to(addr) - u_int32_t addr; -{ - return -1; -} - -#define WTMPFILE "/usr/adm/wtmp" - -void -logwtmp(line, name, host) - const 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)) { - strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - 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); -} - -/* - * 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; - - 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 = MAX_IFS * sizeof(struct ifreq); - ifc.ifc_req = alloca(ifc.ifc_len); - if (ifc.ifc_req == 0) - return mask; - if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { - warn("Couldn't get system interface list: %m"); - return mask; - } - ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); - for (ifr = ifc.ifc_req; ifr < ifend; ++ifr) { - /* - * Check the interface's internet address. - */ - if (ifr->ifr_addr.sa_family != AF_INET) - continue; - ina = INET_ADDR(ifr->ifr_addr); - if ((ntohl(ina) & nmask) != (addr & nmask)) - continue; - /* - * Check that the interface is up, and not point-to-point or loopback. - */ - strlcpy(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 |= INET_ADDR(ifreq.ifr_addr); - } - - return mask; -} - -static int -strioctl(fd, cmd, ptr, ilen, olen) - int fd, cmd, ilen, olen; - void *ptr; -{ - struct strioctl str; - - str.ic_cmd = cmd; - str.ic_timout = 0; - str.ic_len = ilen; - str.ic_dp = ptr; - if (ioctl(fd, I_STR, &str) == -1) - return -1; - if (str.ic_len != olen) - dbglog("strioctl: expected %d bytes, got %d for cmd %x\n", - olen, str.ic_len, cmd); - return 0; -} - -/* - * Use the hostid as part of the random number seed. - */ -int -get_host_seed() -{ - return gethostid(); -} - -#if 0 -/* - * Code for locking/unlocking the serial device. - * This code is derived from chat.c. - */ - -#if !defined(HDB) && !defined(SUNOS3) -#define HDB 1 /* ascii lock files are the default */ -#endif - -#ifndef LOCK_DIR -# if HDB -# define PIDSTRING -# define LOCK_PREFIX "/usr/spool/locks/LCK.." -# else /* HDB */ -# define LOCK_PREFIX "/usr/spool/uucp/LCK.." -# endif /* HDB */ -#endif /* LOCK_DIR */ - -static char *lock_file; /* name of lock file created */ - -/* - * lock - create a lock file for the named device. - */ -int -lock(dev) - char *dev; -{ - char hdb_lock_buffer[12]; - int fd, pid, n; - char *p; - size_t l; - - if ((p = strrchr(dev, '/')) != NULL) - dev = p + 1; - l = strlen(LOCK_PREFIX) + strlen(dev) + 1; - lock_file = malloc(l); - if (lock_file == NULL) - novm("lock file name"); - slprintf(lock_file, l, "%s%s", 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 */ -#ifdef PIDSTRING - n = read(fd, hdb_lock_buffer, 11); - if (n > 0) { - hdb_lock_buffer[n] = 0; - pid = atoi(hdb_lock_buffer); - } -#else - n = read(fd, &pid, sizeof(pid)); -#endif - if (n <= 0) { - error("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); - notice("Removed stale lock on %s (pid %d)", - dev, pid); - continue; - } else - warn("Couldn't remove stale lock on %s", - dev); - } else - notice("Device %s is locked by pid %d", - dev, pid); - } - close(fd); - } else - error("Can't create lock file %s: %m", lock_file); - free(lock_file); - lock_file = NULL; - return -1; - } - -#ifdef PIDSTRING - slprintf(hdb_lock_buffer, sizeof(hdb_lock_buffer), "%10d\n", getpid()); - write(fd, hdb_lock_buffer, 11); -#else - pid = getpid(); - write(fd, &pid, sizeof pid); -#endif - - close(fd); - return 0; -} - -/* - * unlock - remove our lockfile - */ -void -unlock() -{ - if (lock_file) { - unlink(lock_file); - free(lock_file); - lock_file = NULL; - } -} -#endif /* lock stuff removed */ - -/* - * get_pty - get a pty master/slave pair and chown the slave side - * to the uid given. Assumes slave_name points to >= 12 bytes of space. - */ -int -get_pty(master_fdp, slave_fdp, slave_name, uid) - int *master_fdp; - int *slave_fdp; - char *slave_name; - int uid; -{ - int i, mfd, sfd; - char pty_name[12]; - struct termios tios; - - sfd = -1; - for (i = 0; i < 64; ++i) { - slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x", - 'p' + i / 16, i % 16); - mfd = open(pty_name, O_RDWR, 0); - if (mfd >= 0) { - pty_name[5] = 't'; - sfd = open(pty_name, O_RDWR | O_NOCTTY, 0); - if (sfd >= 0) - break; - close(mfd); - } - } - if (sfd < 0) - return 0; - - strlcpy(slave_name, pty_name, 12); - *master_fdp = mfd; - *slave_fdp = sfd; - fchown(sfd, uid, -1); - fchmod(sfd, S_IRUSR | S_IWUSR); - if (tcgetattr(sfd, &tios) == 0) { - tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); - tios.c_cflag |= CS8 | CREAD; - tios.c_iflag = IGNPAR | CLOCAL; - tios.c_oflag = 0; - tios.c_lflag = 0; - if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0) - warn("couldn't set attributes on pty: %m"); - } else - warn("couldn't get attributes on pty: %m"); - - return 1; -} - -/* - * SunOS doesn't have strtoul :-( - */ -unsigned long -strtoul(str, ptr, base) - char *str, **ptr; - int base; -{ - return (unsigned long) strtol(str, ptr, base); -} - -/* - * Or strerror :-( - */ -extern char *sys_errlist[]; -extern int sys_nerr; - -char * -strerror(n) - int n; -{ - static char unknown[32]; - - if (n > 0 && n < sys_nerr) - return sys_errlist[n]; - slprintf(unknown, sizeof(unknown), "Error %d", n); - return unknown; -} diff --git a/mdk-stage1/ppp/pppd/tdb.c b/mdk-stage1/ppp/pppd/tdb.c deleted file mode 100644 index 7fd58291e..000000000 --- a/mdk-stage1/ppp/pppd/tdb.c +++ /dev/null @@ -1,1282 +0,0 @@ -/* - * Database functions - * Copyright (C) Andrew Tridgell 1999 - * - * 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 provided that this software or - * any derived work is only used as part of the PPP daemon (pppd) - * and related utilities. - * The name of the author 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 software is also available under the Gnu Public License - * version 2 or later. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include "tdb.h" - -#define TDB_VERSION (0x26011967 + 1) -#define TDB_MAGIC (0x26011999U) -#define TDB_FREE_MAGIC (~TDB_MAGIC) -#define TDB_ALIGN 4 -#define MIN_REC_SIZE (2*sizeof(struct list_struct) + TDB_ALIGN) -#define DEFAULT_HASH_SIZE 128 -#define TDB_PAGE_SIZE 0x2000 -#define TDB_LEN_MULTIPLIER 10 -#define FREELIST_TOP (sizeof(struct tdb_header)) - -#define LOCK_SET 1 -#define LOCK_CLEAR 0 - -/* lock offsets */ -#define GLOBAL_LOCK 0 -#define ACTIVE_LOCK 4 -#define LIST_LOCK_BASE 1024 - -#define BUCKET(hash) ((hash) % tdb->header.hash_size) - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -/* the body of the database is made of one list_struct for the free space - plus a separate data list for each hash value */ -struct list_struct { - tdb_len rec_len; /* total byte length of record */ - tdb_off next; /* offset of the next record in the list */ - tdb_len key_len; /* byte length of key */ - tdb_len data_len; /* byte length of data */ - unsigned full_hash; /* the full 32 bit hash of the key */ - unsigned magic; /* try to catch errors */ - /* - the following union is implied - union { - char record[rec_len]; - struct { - char key[key_len]; - char data[data_len]; - } - } - */ -}; - -/* a null data record - useful for error returns */ -static TDB_DATA null_data; - -/* a byte range locking function - return 0 on success - this functions locks/unlocks 1 byte at the specified offset */ -static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, - int set, int rw_type, int lck_type) -{ -#if NOLOCK - return 0; -#else - struct flock fl; - - if (tdb->fd == -1) return 0; /* for in memory tdb */ - - if (tdb->read_only) return -1; - - fl.l_type = set==LOCK_SET?rw_type:F_UNLCK; - fl.l_whence = SEEK_SET; - fl.l_start = offset; - fl.l_len = 1; - fl.l_pid = 0; - - if (fcntl(tdb->fd, lck_type, &fl) != 0) { -#if TDB_DEBUG - if (lck_type == F_SETLKW) { - printf("lock %d failed at %d (%s)\n", - set, offset, strerror(errno)); - } -#endif - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - return 0; -#endif -} - -/* lock a list in the database. list -1 is the alloc list */ -static int tdb_lock(TDB_CONTEXT *tdb, int list) -{ - if (list < -1 || list >= (int)tdb->header.hash_size) { -#if TDB_DEBUG - printf("bad list %d\n", list); -#endif - return -1; - } - if (tdb->locked[list+1] == 0) { - if (tdb_brlock(tdb, LIST_LOCK_BASE + 4*list, LOCK_SET, - F_WRLCK, F_SETLKW) != 0) { - return -1; - } - } - tdb->locked[list+1]++; - return 0; -} - -/* unlock the database. */ -static int tdb_unlock(TDB_CONTEXT *tdb, int list) -{ - if (list < -1 || list >= (int)tdb->header.hash_size) { -#if TDB_DEBUG - printf("bad unlock list %d\n", list); -#endif - return -1; - } - - if (tdb->locked[list+1] == 0) { -#if TDB_DEBUG - printf("not locked %d\n", list); -#endif - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - if (tdb->locked[list+1] == 1) { - if (tdb_brlock(tdb, LIST_LOCK_BASE + 4*list, LOCK_CLEAR, - F_WRLCK, F_SETLKW) != 0) { - return -1; - } - } - tdb->locked[list+1]--; - return 0; -} - -/* the hash algorithm - turn a key into an integer - This is based on the hash agorithm from gdbm */ -static unsigned tdb_hash(TDB_DATA *key) -{ - unsigned value; /* Used to compute the hash value. */ - unsigned i; /* Used to cycle through random values. */ - - /* Set the initial value from the key size. */ - value = 0x238F13AF * key->dsize; - for (i=0; i < key->dsize; i++) { - value = (value + (key->dptr[i] << (i*5 % 24))); - } - - value = (1103515243 * value + 12345); - - return value; -} - -/* find the top of the hash chain for an open database */ -static tdb_off tdb_hash_top(TDB_CONTEXT *tdb, unsigned hash) -{ - tdb_off ret; - hash = BUCKET(hash); - ret = FREELIST_TOP + (hash+1)*sizeof(tdb_off); - return ret; -} - - -/* check for an out of bounds access - if it is out of bounds then - see if the database has been expanded by someone else and expand - if necessary */ -static int tdb_oob(TDB_CONTEXT *tdb, tdb_off offset) -{ - struct stat st; - if ((offset <= tdb->map_size) || (tdb->fd == -1)) return 0; - - fstat(tdb->fd, &st); - if (st.st_size <= (ssize_t)offset) { - tdb->ecode = TDB_ERR_IO; - return -1; - } - -#if HAVE_MMAP - if (tdb->map_ptr) { - munmap(tdb->map_ptr, tdb->map_size); - tdb->map_ptr = NULL; - } -#endif - - tdb->map_size = st.st_size; -#if HAVE_MMAP - tdb->map_ptr = (void *)mmap(NULL, tdb->map_size, - tdb->read_only?PROT_READ:PROT_READ|PROT_WRITE, - MAP_SHARED | MAP_FILE, tdb->fd, 0); -#endif - return 0; -} - - -/* write a lump of data at a specified offset */ -static int tdb_write(TDB_CONTEXT *tdb, tdb_off offset, const char *buf, tdb_len len) -{ - if (tdb_oob(tdb, offset + len) != 0) { - /* oops - trying to write beyond the end of the database! */ - return -1; - } - - if (tdb->map_ptr) { - memcpy(offset + (char *)tdb->map_ptr, buf, len); - } else { - if (lseek(tdb->fd, offset, SEEK_SET) != offset || - write(tdb->fd, buf, len) != (ssize_t)len) { - tdb->ecode = TDB_ERR_IO; - return -1; - } - } - return 0; -} - -/* read a lump of data at a specified offset */ -static int tdb_read(TDB_CONTEXT *tdb, tdb_off offset, char *buf, tdb_len len) -{ - if (tdb_oob(tdb, offset + len) != 0) { - /* oops - trying to read beyond the end of the database! */ - return -1; - } - - if (tdb->map_ptr) { - memcpy(buf, offset + (char *)tdb->map_ptr, len); - } else { - if (lseek(tdb->fd, offset, SEEK_SET) != offset || - read(tdb->fd, buf, len) != (ssize_t)len) { - tdb->ecode = TDB_ERR_IO; - return -1; - } - } - return 0; -} - - -/* read a lump of data, allocating the space for it */ -static char *tdb_alloc_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_len len) -{ - char *buf; - - buf = (char *)malloc(len); - - if (!buf) { - tdb->ecode = TDB_ERR_OOM; - return NULL; - } - - if (tdb_read(tdb, offset, buf, len) == -1) { - free(buf); - return NULL; - } - - return buf; -} - -/* convenience routine for writing a record */ -static int rec_write(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) -{ - return tdb_write(tdb, offset, (char *)rec, sizeof(*rec)); -} - -/* convenience routine for writing a tdb_off */ -static int ofs_write(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) -{ - return tdb_write(tdb, offset, (char *)d, sizeof(*d)); -} - -/* read a tdb_off from the store */ -static int ofs_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) -{ - return tdb_read(tdb, offset, (char *)d, sizeof(*d)); -} - -/* read a record and check for simple errors */ -static int rec_read(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) -{ - if (tdb_read(tdb, offset, (char *)rec, sizeof(*rec)) == -1) return -1; - if (rec->magic != TDB_MAGIC) { -#if TDB_DEBUG - printf("bad magic 0x%08x at offset %d\n", - rec->magic, offset); -#endif - tdb->ecode = TDB_ERR_CORRUPT; - return -1; - } - if (tdb_oob(tdb, rec->next) != 0) { - return -1; - } - return 0; -} - -/* expand the database at least length bytes by expanding the - underlying file and doing the mmap again if necessary */ -static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length) -{ - struct list_struct rec; - tdb_off offset, ptr; - char b = 0; - - tdb_lock(tdb,-1); - - /* make sure we know about any previous expansions by another - process */ - tdb_oob(tdb,tdb->map_size + 1); - - /* always make room for at least 10 more records */ - length *= TDB_LEN_MULTIPLIER; - - /* and round the database up to a multiple of TDB_PAGE_SIZE */ - length = ((tdb->map_size + length + TDB_PAGE_SIZE) & ~(TDB_PAGE_SIZE - 1)) - tdb->map_size; - - /* expand the file itself */ - if (tdb->fd != -1) { - lseek(tdb->fd, tdb->map_size + length - 1, SEEK_SET); - if (write(tdb->fd, &b, 1) != 1) goto fail; - } - - /* form a new freelist record */ - offset = FREELIST_TOP; - rec.rec_len = length - sizeof(rec); - rec.magic = TDB_FREE_MAGIC; - if (ofs_read(tdb, offset, &rec.next) == -1) { - goto fail; - } - -#if HAVE_MMAP - if (tdb->fd != -1 && tdb->map_ptr) { - munmap(tdb->map_ptr, tdb->map_size); - tdb->map_ptr = NULL; - } -#endif - - tdb->map_size += length; - - if (tdb->fd == -1) { - tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size); - } - - /* write it out */ - if (rec_write(tdb, tdb->map_size - length, &rec) == -1) { - goto fail; - } - - /* link it into the free list */ - ptr = tdb->map_size - length; - if (ofs_write(tdb, offset, &ptr) == -1) goto fail; - -#if HAVE_MMAP - if (tdb->fd != -1) { - tdb->map_ptr = (void *)mmap(NULL, tdb->map_size, - PROT_READ|PROT_WRITE, - MAP_SHARED | MAP_FILE, tdb->fd, 0); - } -#endif - - tdb_unlock(tdb, -1); - return 0; - - fail: - tdb_unlock(tdb,-1); - return -1; -} - -/* allocate some space from the free list. The offset returned points - to a unconnected list_struct within the database with room for at - least length bytes of total data - - 0 is returned if the space could not be allocated - */ -static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length) -{ - tdb_off offset, rec_ptr, last_ptr; - struct list_struct rec, lastrec, newrec; - - tdb_lock(tdb, -1); - - again: - last_ptr = 0; - offset = FREELIST_TOP; - - /* read in the freelist top */ - if (ofs_read(tdb, offset, &rec_ptr) == -1) { - goto fail; - } - - /* keep looking until we find a freelist record that is big - enough */ - while (rec_ptr) { - if (tdb_read(tdb, rec_ptr, (char *)&rec, sizeof(rec)) == -1) { - goto fail; - } - - if (rec.magic != TDB_FREE_MAGIC) { -#if TDB_DEBUG - printf("bad magic 0x%08x in free list\n", rec.magic); -#endif - goto fail; - } - - if (rec.rec_len >= length) { - /* found it - now possibly split it up */ - if (rec.rec_len > length + MIN_REC_SIZE) { - length = (length + TDB_ALIGN) & ~(TDB_ALIGN-1); - - newrec.rec_len = rec.rec_len - (sizeof(rec) + length); - newrec.next = rec.next; - newrec.magic = TDB_FREE_MAGIC; - - rec.rec_len = length; - rec.next = rec_ptr + sizeof(rec) + rec.rec_len; - - if (rec_write(tdb, rec.next, &newrec) == -1) { - goto fail; - } - - if (rec_write(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - } - - /* remove it from the list */ - if (last_ptr == 0) { - offset = FREELIST_TOP; - - if (ofs_write(tdb, offset, &rec.next) == -1) { - goto fail; - } - } else { - lastrec.next = rec.next; - if (rec_write(tdb, last_ptr, &lastrec) == -1) { - goto fail; - } - } - - /* all done - return the new record offset */ - tdb_unlock(tdb, -1); - return rec_ptr; - } - - /* move to the next record */ - lastrec = rec; - last_ptr = rec_ptr; - rec_ptr = rec.next; - } - - /* we didn't find enough space. See if we can expand the - database and if we can then try again */ - if (tdb_expand(tdb, length + sizeof(rec)) == 0) goto again; - - fail: -#if TDB_DEBUG - printf("tdb_allocate failed for size %u\n", length); -#endif - tdb_unlock(tdb, -1); - return 0; -} - -/* initialise a new database with a specified hash size */ -static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size) -{ - struct tdb_header header; - tdb_off offset; - int i, size = 0; - tdb_off buf[16]; - - /* create the header */ - memset(&header, 0, sizeof(header)); - memcpy(header.magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); - header.version = TDB_VERSION; - header.hash_size = hash_size; - lseek(tdb->fd, 0, SEEK_SET); - ftruncate(tdb->fd, 0); - - if (tdb->fd != -1 && write(tdb->fd, &header, sizeof(header)) != - sizeof(header)) { - tdb->ecode = TDB_ERR_IO; - return -1; - } else size += sizeof(header); - - /* the freelist and hash pointers */ - offset = 0; - memset(buf, 0, sizeof(buf)); - - for (i=0;(hash_size+1)-i >= 16; i += 16) { - if (tdb->fd != -1 && write(tdb->fd, buf, sizeof(buf)) != - sizeof(buf)) { - tdb->ecode = TDB_ERR_IO; - return -1; - } else size += sizeof(buf); - } - - for (;i<hash_size+1; i++) { - if (tdb->fd != -1 && write(tdb->fd, buf, sizeof(tdb_off)) != - sizeof(tdb_off)) { - tdb->ecode = TDB_ERR_IO; - return -1; - } else size += sizeof(tdb_off); - } - - if (tdb->fd == -1) { - tdb->map_ptr = calloc(size, 1); - tdb->map_size = size; - if (tdb->map_ptr == NULL) { - tdb->ecode = TDB_ERR_IO; - return -1; - } - memcpy(&tdb->header, &header, sizeof(header)); - } - -#if TDB_DEBUG - printf("initialised database of hash_size %u\n", - hash_size); -#endif - return 0; -} - -/* Returns 0 on fail. On success, return offset of record, and fills - in rec */ -static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, unsigned int hash, - struct list_struct *rec) -{ - tdb_off offset, rec_ptr; - - /* find the top of the hash chain */ - offset = tdb_hash_top(tdb, hash); - - /* read in the hash top */ - if (ofs_read(tdb, offset, &rec_ptr) == -1) - return 0; - - /* keep looking until we find the right record */ - while (rec_ptr) { - if (rec_read(tdb, rec_ptr, rec) == -1) - return 0; - - if (hash == rec->full_hash && key.dsize == rec->key_len) { - char *k; - /* a very likely hit - read the key */ - k = tdb_alloc_read(tdb, rec_ptr + sizeof(*rec), - rec->key_len); - - if (!k) - return 0; - - if (memcmp(key.dptr, k, key.dsize) == 0) { - free(k); - return rec_ptr; - } - free(k); - } - - /* move to the next record */ - rec_ptr = rec->next; - } - return 0; -} - -/* - return an error string for the last tdb error -*/ -char *tdb_error(TDB_CONTEXT *tdb) -{ - int i; - static struct { - enum TDB_ERROR ecode; - char *estring; - } emap[] = { - {TDB_SUCCESS, "Success"}, - {TDB_ERR_CORRUPT, "Corrupt database"}, - {TDB_ERR_IO, "IO Error"}, - {TDB_ERR_LOCK, "Locking error"}, - {TDB_ERR_OOM, "Out of memory"}, - {TDB_ERR_EXISTS, "Record exists"}, - {-1, NULL}}; - if (tdb != NULL) { - for (i=0;emap[i].estring;i++) { - if (tdb->ecode == emap[i].ecode) return emap[i].estring; - } - } else { - return "Invalid tdb context"; - } - return "Invalid error code"; -} - - -/* update an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1 -*/ -int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf) -{ - unsigned hash; - struct list_struct rec; - tdb_off rec_ptr; - int ret = -1; - - if (tdb == NULL) { -#ifdef TDB_DEBUG - printf("tdb_update() called with null context\n"); -#endif - return -1; - } - - /* find which hash bucket it is in */ - hash = tdb_hash(&key); - - tdb_lock(tdb, BUCKET(hash)); - rec_ptr = tdb_find(tdb, key, hash, &rec); - - if (!rec_ptr) - goto out; - - /* must be long enough */ - if (rec.rec_len < key.dsize + dbuf.dsize) - goto out; - - if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, - dbuf.dptr, dbuf.dsize) == -1) - goto out; - - if (dbuf.dsize != rec.data_len) { - /* update size */ - rec.data_len = dbuf.dsize; - ret = rec_write(tdb, rec_ptr, &rec); - } else - ret = 0; - - out: - tdb_unlock(tdb, BUCKET(hash)); - return ret; -} - -/* find an entry in the database given a key */ -TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key) -{ - unsigned hash; - tdb_off rec_ptr; - struct list_struct rec; - TDB_DATA ret = null_data; - - if (tdb == NULL) { -#ifdef TDB_DEBUG - printf("tdb_fetch() called with null context\n"); -#endif - return null_data; - } - - /* find which hash bucket it is in */ - hash = tdb_hash(&key); - - tdb_lock(tdb, BUCKET(hash)); - rec_ptr = tdb_find(tdb, key, hash, &rec); - - if (rec_ptr) { - ret.dptr = tdb_alloc_read(tdb, - rec_ptr + sizeof(rec) + rec.key_len, - rec.data_len); - ret.dsize = rec.data_len; - } - - tdb_unlock(tdb, BUCKET(hash)); - return ret; -} - -/* check if an entry in the database exists - - note that 1 is returned if the key is found and 0 is returned if not found - this doesn't match the conventions in the rest of this module, but is - compatible with gdbm -*/ -int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key) -{ - unsigned hash; - tdb_off rec_ptr; - struct list_struct rec; - - if (tdb == NULL) { -#ifdef TDB_DEBUG - printf("tdb_exists() called with null context\n"); -#endif - return 0; - } - - /* find which hash bucket it is in */ - hash = tdb_hash(&key); - - tdb_lock(tdb, BUCKET(hash)); - rec_ptr = tdb_find(tdb, key, hash, &rec); - tdb_unlock(tdb, BUCKET(hash)); - - return rec_ptr != 0; -} - -/* traverse the entire database - calling fn(tdb, key, data) on each element. - return -1 on error or the record count traversed - if fn is NULL then it is not called - a non-zero return value from fn() indicates that the traversal should stop - */ -int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void* state), void* state) -{ - int count = 0; - unsigned h; - tdb_off offset, rec_ptr; - struct list_struct rec; - char *data; - TDB_DATA key, dbuf; - - if (tdb == NULL) { -#ifdef TDB_DEBUG - printf("tdb_traverse() called with null context\n"); -#endif - return -1; - } - - /* loop over all hash chains */ - for (h = 0; h < tdb->header.hash_size; h++) { - tdb_lock(tdb, BUCKET(h)); - - /* read in the hash top */ - offset = tdb_hash_top(tdb, h); - if (ofs_read(tdb, offset, &rec_ptr) == -1) { - goto fail; - } - - /* traverse all records for this hash */ - while (rec_ptr) { - if (rec_read(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - - /* now read the full record */ - data = tdb_alloc_read(tdb, rec_ptr + sizeof(rec), - rec.key_len + rec.data_len); - if (!data) { - goto fail; - } - - key.dptr = data; - key.dsize = rec.key_len; - dbuf.dptr = data + rec.key_len; - dbuf.dsize = rec.data_len; - count++; - - if (fn && fn(tdb, key, dbuf, state) != 0) { - /* they want us to stop traversing */ - free(data); - tdb_unlock(tdb, BUCKET(h)); - return count; - } - - /* a miss - drat */ - free(data); - - /* move to the next record */ - rec_ptr = rec.next; - } - tdb_unlock(tdb, BUCKET(h)); - } - - /* return the number traversed */ - return count; - - fail: - tdb_unlock(tdb, BUCKET(h)); - return -1; -} - - -/* find the first entry in the database and return its key */ -TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb) -{ - tdb_off offset, rec_ptr; - struct list_struct rec; - unsigned hash; - TDB_DATA ret; - - if (tdb == NULL) { -#ifdef TDB_DEBUG - printf("tdb_firstkey() called with null context\n"); -#endif - return null_data; - } - - /* look for a non-empty hash chain */ - for (hash = 0, rec_ptr = 0; - hash < tdb->header.hash_size; - hash++) { - /* find the top of the hash chain */ - offset = tdb_hash_top(tdb, hash); - - tdb_lock(tdb, BUCKET(hash)); - - /* read in the hash top */ - if (ofs_read(tdb, offset, &rec_ptr) == -1) { - goto fail; - } - - if (rec_ptr) break; - - tdb_unlock(tdb, BUCKET(hash)); - } - - if (rec_ptr == 0) return null_data; - - /* we've found a non-empty chain, now read the record */ - if (rec_read(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - - /* allocate and read the key space */ - ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec), rec.key_len); - ret.dsize = rec.key_len; - tdb_unlock(tdb, BUCKET(hash)); - return ret; - - fail: - tdb_unlock(tdb, BUCKET(hash)); - return null_data; -} - -/* find the next entry in the database, returning its key */ -TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key) -{ - unsigned hash, hbucket; - tdb_off rec_ptr, offset; - struct list_struct rec; - TDB_DATA ret; - - if (tdb == NULL) { -#ifdef TDB_DEBUG - printf("tdb_nextkey() called with null context\n"); -#endif - return null_data; - } - - /* find which hash bucket it is in */ - hash = tdb_hash(&key); - hbucket = BUCKET(hash); - - tdb_lock(tdb, hbucket); - rec_ptr = tdb_find(tdb, key, hash, &rec); - if (rec_ptr) { - /* we want the next record after this one */ - rec_ptr = rec.next; - } - - /* not found or last in hash: look for next non-empty hash chain */ - while (rec_ptr == 0) { - tdb_unlock(tdb, hbucket); - - if (++hbucket >= tdb->header.hash_size - 1) - return null_data; - - offset = tdb_hash_top(tdb, hbucket); - tdb_lock(tdb, hbucket); - /* read in the hash top */ - if (ofs_read(tdb, offset, &rec_ptr) == -1) { - tdb_unlock(tdb, hbucket); - return null_data; - } - } - - /* Read the record. */ - if (rec_read(tdb, rec_ptr, &rec) == -1) { - tdb_unlock(tdb, hbucket); - return null_data; - } - /* allocate and read the key */ - ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec), rec.key_len); - ret.dsize = rec.key_len; - tdb_unlock(tdb, hbucket); - - return ret; -} - -/* delete an entry in the database given a key */ -int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key) -{ - unsigned hash; - tdb_off offset, rec_ptr, last_ptr; - struct list_struct rec, lastrec; - char *data = NULL; - - if (tdb == NULL) { -#ifdef TDB_DEBUG - printf("tdb_delete() called with null context\n"); -#endif - return -1; - } - - /* find which hash bucket it is in */ - hash = tdb_hash(&key); - - tdb_lock(tdb, BUCKET(hash)); - - /* find the top of the hash chain */ - offset = tdb_hash_top(tdb, hash); - - /* read in the hash top */ - if (ofs_read(tdb, offset, &rec_ptr) == -1) { - goto fail; - } - - last_ptr = 0; - - /* keep looking until we find the right record */ - while (rec_ptr) { - if (rec_read(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - - if (hash == rec.full_hash && key.dsize == rec.key_len) { - /* a very likely hit - read the record and full key */ - data = tdb_alloc_read(tdb, rec_ptr + sizeof(rec), - rec.key_len); - if (!data) { - goto fail; - } - - if (memcmp(key.dptr, data, key.dsize) == 0) { - /* a definite match - delete it */ - if (last_ptr == 0) { - offset = tdb_hash_top(tdb, hash); - if (ofs_write(tdb, offset, &rec.next) == -1) { - goto fail; - } - } else { - lastrec.next = rec.next; - if (rec_write(tdb, last_ptr, &lastrec) == -1) { - goto fail; - } - } - tdb_unlock(tdb, BUCKET(hash)); - tdb_lock(tdb, -1); - /* and recover the space */ - offset = FREELIST_TOP; - if (ofs_read(tdb, offset, &rec.next) == -1) { - goto fail2; - } - rec.magic = TDB_FREE_MAGIC; - if (rec_write(tdb, rec_ptr, &rec) == -1) { - goto fail2; - } - if (ofs_write(tdb, offset, &rec_ptr) == -1) { - goto fail2; - } - - /* yipee - all done */ - free(data); - tdb_unlock(tdb, -1); - return 0; - } - - /* a miss - drat */ - free(data); - data = NULL; - } - - /* move to the next record */ - last_ptr = rec_ptr; - lastrec = rec; - rec_ptr = rec.next; - } - - fail: - if (data) free(data); - tdb_unlock(tdb, BUCKET(hash)); - return -1; - - fail2: - if (data) free(data); - tdb_unlock(tdb, -1); - return -1; -} - - -/* store an element in the database, replacing any existing element - with the same key - - return 0 on success, -1 on failure -*/ -int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) -{ - struct list_struct rec; - unsigned hash; - tdb_off rec_ptr, offset; - char *p = NULL; - - if (tdb == NULL) { -#ifdef TDB_DEBUG - printf("tdb_store() called with null context\n"); -#endif - return -1; - } - - /* find which hash bucket it is in */ - hash = tdb_hash(&key); - - /* check for it existing */ - if (flag == TDB_INSERT && tdb_exists(tdb, key)) { - tdb->ecode = TDB_ERR_EXISTS; - return -1; - } - - /* first try in-place update */ - if (flag != TDB_INSERT && tdb_update(tdb, key, dbuf) == 0) { - return 0; - } - - rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize); - if (rec_ptr == 0) { - return -1; - } - - tdb_lock(tdb, BUCKET(hash)); - - /* delete any existing record - if it doesn't exist we don't care */ - if (flag != TDB_INSERT) { - tdb_delete(tdb, key); - } - - /* read the newly created record */ - if (tdb_read(tdb, rec_ptr, (char *)&rec, sizeof(rec)) == -1) { - goto fail; - } - - if (rec.magic != TDB_FREE_MAGIC) goto fail; - - /* find the top of the hash chain */ - offset = tdb_hash_top(tdb, hash); - - /* read in the hash top diretcly into our next pointer */ - if (ofs_read(tdb, offset, &rec.next) == -1) { - goto fail; - } - - rec.key_len = key.dsize; - rec.data_len = dbuf.dsize; - rec.full_hash = hash; - rec.magic = TDB_MAGIC; - - p = (char *)malloc(sizeof(rec) + key.dsize + dbuf.dsize); - if (!p) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - - memcpy(p, &rec, sizeof(rec)); - memcpy(p+sizeof(rec), key.dptr, key.dsize); - memcpy(p+sizeof(rec)+key.dsize, dbuf.dptr, dbuf.dsize); - - if (tdb_write(tdb, rec_ptr, p, sizeof(rec)+key.dsize+dbuf.dsize) == -1) - goto fail; - - free(p); - p = NULL; - - /* and point the top of the hash chain at it */ - if (ofs_write(tdb, offset, &rec_ptr) == -1) goto fail; - - tdb_unlock(tdb, BUCKET(hash)); - return 0; - - fail: -#if TDB_DEBUG - printf("store failed for hash 0x%08x in bucket %u\n", hash, BUCKET(hash)); -#endif - if (p) free(p); - tdb_unlock(tdb, BUCKET(hash)); - return -1; -} - - -/* open the database, creating it if necessary - - The open_flags and mode are passed straight to the open call on the database - file. A flags value of O_WRONLY is invalid - - The hash size is advisory, use zero for a default value. - - return is NULL on error -*/ -TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - TDB_CONTEXT tdb, *ret; - struct stat st; - - memset(&tdb, 0, sizeof(tdb)); - - tdb.fd = -1; - tdb.name = NULL; - tdb.map_ptr = NULL; - - if ((open_flags & O_ACCMODE) == O_WRONLY) { - goto fail; - } - - if (hash_size == 0) hash_size = DEFAULT_HASH_SIZE; - - tdb.read_only = ((open_flags & O_ACCMODE) == O_RDONLY); - - if (name != NULL) { - tdb.fd = open(name, open_flags, mode); - if (tdb.fd == -1) { - goto fail; - } - } - - /* ensure there is only one process initialising at once */ - tdb_brlock(&tdb, GLOBAL_LOCK, LOCK_SET, F_WRLCK, F_SETLKW); - - if (tdb_flags & TDB_CLEAR_IF_FIRST) { - /* we need to zero the database if we are the only - one with it open */ - if (tdb_brlock(&tdb, ACTIVE_LOCK, LOCK_SET, F_WRLCK, F_SETLK) == 0) { - ftruncate(tdb.fd, 0); - tdb_brlock(&tdb, ACTIVE_LOCK, LOCK_CLEAR, F_WRLCK, F_SETLK); - } - } - - /* leave this lock in place */ - tdb_brlock(&tdb, ACTIVE_LOCK, LOCK_SET, F_RDLCK, F_SETLKW); - - if (read(tdb.fd, &tdb.header, sizeof(tdb.header)) != sizeof(tdb.header) || - strcmp(tdb.header.magic_food, TDB_MAGIC_FOOD) != 0 || - tdb.header.version != TDB_VERSION) { - /* its not a valid database - possibly initialise it */ - if (!(open_flags & O_CREAT)) { - goto fail; - } - if (tdb_new_database(&tdb, hash_size) == -1) goto fail; - - lseek(tdb.fd, 0, SEEK_SET); - if (tdb.fd != -1 && read(tdb.fd, &tdb.header, - sizeof(tdb.header)) != - sizeof(tdb.header)) - goto fail; - } - - if (tdb.fd != -1) { - fstat(tdb.fd, &st); - - /* map the database and fill in the return structure */ - tdb.name = (char *)strdup(name); - tdb.map_size = st.st_size; - } - - tdb.locked = (int *)calloc(tdb.header.hash_size+1, - sizeof(tdb.locked[0])); - if (!tdb.locked) { - goto fail; - } - -#if HAVE_MMAP - if (tdb.fd != -1) { - tdb.map_ptr = (void *)mmap(NULL, st.st_size, - tdb.read_only? PROT_READ : PROT_READ|PROT_WRITE, - MAP_SHARED | MAP_FILE, tdb.fd, 0); - } -#endif - - ret = (TDB_CONTEXT *)malloc(sizeof(tdb)); - if (!ret) goto fail; - - *ret = tdb; - -#if TDB_DEBUG - printf("mapped database of hash_size %u map_size=%u\n", - hash_size, tdb.map_size); -#endif - - tdb_brlock(&tdb, GLOBAL_LOCK, LOCK_CLEAR, F_WRLCK, F_SETLKW); - return ret; - - fail: - if (tdb.name) free(tdb.name); - if (tdb.fd != -1) close(tdb.fd); - if (tdb.map_ptr) munmap(tdb.map_ptr, tdb.map_size); - - return NULL; -} - -/* close a database */ -int tdb_close(TDB_CONTEXT *tdb) -{ - if (!tdb) return -1; - - if (tdb->name) free(tdb->name); - if (tdb->fd != -1) close(tdb->fd); - if (tdb->locked) free(tdb->locked); - - if (tdb->map_ptr) { - if (tdb->fd != -1) { - munmap(tdb->map_ptr, tdb->map_size); - } else { - free(tdb->map_ptr); - } - } - - memset(tdb, 0, sizeof(*tdb)); - free(tdb); - - return 0; -} - -/* lock the database. If we already have it locked then don't do anything */ -int tdb_writelock(TDB_CONTEXT *tdb) -{ - if (tdb == NULL) { -#ifdef TDB_DEBUG - printf("tdb_writelock() called with null context\n"); -#endif - return -1; - } - - return tdb_lock(tdb, -1); -} - -/* unlock the database. */ -int tdb_writeunlock(TDB_CONTEXT *tdb) -{ - if (tdb == NULL) { -#ifdef TDB_DEBUG - printf("tdb_writeunlock() called with null context\n"); -#endif - return -1; - } - - return tdb_unlock(tdb, -1); -} - -/* lock one hash chain. This is meant to be used to reduce locking - contention - it cannot guarantee how many records will be locked */ -int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key) -{ - if (tdb == NULL) { -#ifdef TDB_DEBUG - printf("tdb_lockchain() called with null context\n"); -#endif - return -1; - } - - return tdb_lock(tdb, BUCKET(tdb_hash(&key))); -} - - -/* unlock one hash chain */ -int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key) -{ - if (tdb == NULL) { -#ifdef TDB_DEBUG - printf("tdb_unlockchain() called with null context\n"); -#endif - return -1; - } - - return tdb_unlock(tdb, BUCKET(tdb_hash(&key))); -} diff --git a/mdk-stage1/ppp/pppd/tdb.h b/mdk-stage1/ppp/pppd/tdb.h deleted file mode 100644 index 56ae0ac2a..000000000 --- a/mdk-stage1/ppp/pppd/tdb.h +++ /dev/null @@ -1,77 +0,0 @@ -#define STANDALONE 1 -/* - * Database functions - * Copyright (C) Andrew Tridgell 1999 - * - * 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 provided that this software or - * any derived work is only used as part of the PPP daemon (pppd) - * and related utilities. - * The name of the author 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 software is also available under the Gnu Public License - * version 2 or later. - */ - -typedef unsigned tdb_len; -typedef unsigned tdb_off; - -#define TDB_MAGIC_FOOD "TDB file\n" - -/* this is stored at the front of every database */ -struct tdb_header { - char magic_food[32]; /* for /etc/magic */ - unsigned version; /* version of the code */ - unsigned hash_size; /* number of hash entries */ -}; - -typedef struct { - char *dptr; - size_t dsize; -} TDB_DATA; - -/* this is the context structure that is returned from a db open */ -typedef struct { - char *name; /* the name of the database */ - void *map_ptr; /* where it is currently mapped */ - int fd; /* open file descriptor for the database */ - tdb_len map_size; /* how much space has been mapped */ - int read_only; /* opened read-only */ - int *locked; /* set if we have a chain locked */ - int ecode; /* error code for last tdb error */ - struct tdb_header header; /* a cached copy of the header */ -} TDB_CONTEXT; - -/* flags to tdb_store() */ -#define TDB_REPLACE 1 -#define TDB_INSERT 2 - -/* flags for tdb_open() */ -#define TDB_CLEAR_IF_FIRST 1 - -/* error codes */ -enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, - TDB_ERR_OOM, TDB_ERR_EXISTS}; - -#if STANDALONE -TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode); -char *tdb_error(TDB_CONTEXT *tdb); -int tdb_writelock(TDB_CONTEXT *tdb); -int tdb_writeunlock(TDB_CONTEXT *tdb); -TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); -int tdb_close(TDB_CONTEXT *tdb); -TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); -TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_traverse(TDB_CONTEXT *tdb, - int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state), - void *state); -int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); -#endif diff --git a/mdk-stage1/ppp/pppd/tty.c b/mdk-stage1/ppp/pppd/tty.c deleted file mode 100644 index 4db707968..000000000 --- a/mdk-stage1/ppp/pppd/tty.c +++ /dev/null @@ -1,1164 +0,0 @@ -/* - * tty.c - code for handling serial ports in pppd. - * - * Copyright (C) 2000 Paul Mackerras. - * All rights reserved. - * - * Portions Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -#define RCSID "$Id$" - -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> -#include <errno.h> -#include <fcntl.h> -#include <syslog.h> -#include <netdb.h> -#include <utmp.h> -#include <pwd.h> -#include <setjmp.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include "pppd.h" -#include "fsm.h" -#include "lcp.h" - -void tty_process_extra_options __P((void)); -void tty_check_options __P((void)); -int connect_tty __P((void)); -void disconnect_tty __P((void)); -void tty_close_fds __P((void)); -void cleanup_tty __P((void)); -void tty_do_send_config __P((int, u_int32_t, int, int)); - -static int setdevname __P((char *, char **, int)); -static int setspeed __P((char *, char **, int)); -static int setxonxoff __P((char **)); -static int setescape __P((char **)); -static void printescape __P((option_t *, void (*)(void *, char *,...),void *)); -static void finish_tty __P((void)); -static int start_charshunt __P((int, int)); -static void stop_charshunt __P((void *, int)); -static void charshunt_done __P((void *)); -static void charshunt __P((int, int, char *)); -static int record_write __P((FILE *, int code, u_char *buf, int nb, - struct timeval *)); -static int open_socket __P((char *)); -static void maybe_relock __P((void *, int)); - -static int pty_master; /* fd for master side of pty */ -static int pty_slave; /* fd for slave side of pty */ -static int real_ttyfd; /* fd for actual serial port (not pty) */ -static int ttyfd; /* Serial port file descriptor */ -static char speed_str[16]; /* Serial port speed as string */ - -mode_t tty_mode = (mode_t)-1; /* Original access permissions to tty */ -int baud_rate; /* Actual bits/second for serial device */ -char *callback_script; /* script for doing callback */ -int charshunt_pid; /* Process ID for charshunt */ -int locked; /* lock() has succeeded */ -struct stat devstat; /* result of stat() on devnam */ - -/* option variables */ -int crtscts = 0; /* Use hardware flow control */ -bool modem = 1; /* Use modem control lines */ -int inspeed = 0; /* Input/Output speed requested */ -bool lockflag = 0; /* Create lock file to lock the serial dev */ -char *initializer = NULL; /* Script to initialize physical link */ -char *connect_script = NULL; /* Script to establish physical link */ -char *disconnect_script = NULL; /* Script to disestablish physical link */ -char *welcomer = NULL; /* Script to run after phys link estab. */ -char *ptycommand = NULL; /* Command to run on other side of pty */ -bool notty = 0; /* Stdin/out is not a tty */ -char *record_file = NULL; /* File to record chars sent/received */ -int max_data_rate; /* max bytes/sec through charshunt */ -bool sync_serial = 0; /* Device is synchronous serial device */ -char *pty_socket = NULL; /* Socket to connect to pty */ -int using_pty = 0; /* we're allocating a pty as the device */ - -extern uid_t uid; -extern int kill_link; - -/* XXX */ -extern int privopen; /* don't lock, open device as root */ - -u_int32_t xmit_accm[8]; /* extended transmit ACCM */ - -/* option descriptors */ -option_t tty_options[] = { - /* device name must be first, or change connect_tty() below! */ - { "device name", o_wild, (void *) &setdevname, - "Serial port device name", - OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, - devnam}, - - { "tty speed", o_wild, (void *) &setspeed, - "Baud rate for serial port", - OPT_PRIO | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, speed_str }, - - { "lock", o_bool, &lockflag, - "Lock serial device with UUCP-style lock file", OPT_PRIO | 1 }, - { "nolock", o_bool, &lockflag, - "Don't lock serial device", OPT_PRIOSUB | OPT_PRIV }, - - { "init", o_string, &initializer, - "A program to initialize the device", OPT_PRIO | OPT_PRIVFIX }, - - { "connect", o_string, &connect_script, - "A program to set up a connection", OPT_PRIO | OPT_PRIVFIX }, - - { "disconnect", o_string, &disconnect_script, - "Program to disconnect serial device", OPT_PRIO | OPT_PRIVFIX }, - - { "welcome", o_string, &welcomer, - "Script to welcome client", OPT_PRIO | OPT_PRIVFIX }, - - { "pty", o_string, &ptycommand, - "Script to run on pseudo-tty master side", - OPT_PRIO | OPT_PRIVFIX | OPT_DEVNAM }, - - { "notty", o_bool, ¬ty, - "Input/output is not a tty", OPT_DEVNAM | 1 }, - - { "socket", o_string, &pty_socket, - "Send and receive over socket, arg is host:port", - OPT_PRIO | OPT_DEVNAM }, - - { "record", o_string, &record_file, - "Record characters sent/received to file", OPT_PRIO }, - - { "crtscts", o_int, &crtscts, - "Set hardware (RTS/CTS) flow control", - OPT_PRIO | OPT_NOARG | OPT_VAL(1) }, - { "cdtrcts", o_int, &crtscts, - "Set alternate hardware (DTR/CTS) flow control", - OPT_PRIOSUB | OPT_NOARG | OPT_VAL(2) }, - { "nocrtscts", o_int, &crtscts, - "Disable hardware flow control", - OPT_PRIOSUB | OPT_NOARG | OPT_VAL(-1) }, - { "-crtscts", o_int, &crtscts, - "Disable hardware flow control", - OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, - { "nocdtrcts", o_int, &crtscts, - "Disable hardware flow control", - OPT_PRIOSUB | OPT_ALIAS | OPT_NOARG | OPT_VAL(-1) }, - { "xonxoff", o_special_noarg, (void *)setxonxoff, - "Set software (XON/XOFF) flow control", OPT_PRIOSUB }, - - { "modem", o_bool, &modem, - "Use modem control lines", OPT_PRIO | 1 }, - { "local", o_bool, &modem, - "Don't use modem control lines", OPT_PRIOSUB | 0 }, - - { "sync", o_bool, &sync_serial, - "Use synchronous HDLC serial encoding", 1 }, - - { "datarate", o_int, &max_data_rate, - "Maximum data rate in bytes/sec (with pty, notty or record option)", - OPT_PRIO }, - - { "escape", o_special, (void *)setescape, - "List of character codes to escape on transmission", - OPT_A2PRINTER, (void *)printescape }, - - { NULL } -}; - - -struct channel tty_channel = { - tty_options, - &tty_process_extra_options, - &tty_check_options, - &connect_tty, - &disconnect_tty, - &tty_establish_ppp, - &tty_disestablish_ppp, - &tty_do_send_config, - &tty_recv_config, - &cleanup_tty, - &tty_close_fds -}; - -/* - * setspeed - Set the serial port baud rate. - * If doit is 0, the call is to check whether this option is - * potentially a speed value. - */ -static int -setspeed(arg, argv, doit) - char *arg; - char **argv; - int doit; -{ - char *ptr; - int spd; - - spd = strtol(arg, &ptr, 0); - if (ptr == arg || *ptr != 0 || spd == 0) - return 0; - if (doit) { - inspeed = spd; - slprintf(speed_str, sizeof(speed_str), "%d", spd); - } - return 1; -} - - -/* - * setdevname - Set the device name. - * If doit is 0, the call is to check whether this option is - * potentially a device name. - */ -static int -setdevname(cp, argv, doit) - char *cp; - char **argv; - int doit; -{ - struct stat statbuf; - char dev[MAXPATHLEN]; - - if (*cp == 0) - return 0; - - if (strncmp("/dev/", cp, 5) != 0) { - strlcpy(dev, "/dev/", sizeof(dev)); - strlcat(dev, cp, sizeof(dev)); - cp = dev; - } - - /* - * Check if there is a character device by this name. - */ - if (stat(cp, &statbuf) < 0) { - if (!doit) - return errno != ENOENT; - option_error("Couldn't stat %s: %m", cp); - return 0; - } - if (!S_ISCHR(statbuf.st_mode)) { - if (doit) - option_error("%s is not a character device", cp); - return 0; - } - - if (doit) { - strlcpy(devnam, cp, sizeof(devnam)); - devstat = statbuf; - default_device = 0; - } - - return 1; -} - -static int -setxonxoff(argv) - char **argv; -{ - lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */ - lcp_wantoptions[0].neg_asyncmap = 1; - - crtscts = -2; - return 1; -} - -/* - * setescape - add chars to the set we escape on transmission. - */ -static int -setescape(argv) - char **argv; -{ - int n, ret; - char *p, *endp; - - p = *argv; - ret = 1; - while (*p) { - n = strtol(p, &endp, 16); - if (p == endp) { - option_error("escape parameter contains invalid hex number '%s'", - p); - return 0; - } - p = endp; - if (n < 0 || n == 0x5E || n > 0xFF) { - option_error("can't escape character 0x%x", n); - ret = 0; - } else - xmit_accm[n >> 5] |= 1 << (n & 0x1F); - while (*p == ',' || *p == ' ') - ++p; - } - lcp_allowoptions[0].asyncmap = xmit_accm[0]; - return ret; -} - -static void -printescape(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int n; - int first = 1; - - for (n = 0; n < 256; ++n) { - if (n == 0x7d) - n += 2; /* skip 7d, 7e */ - if (xmit_accm[n >> 5] & (1 << (n & 0x1f))) { - if (!first) - printer(arg, ","); - else - first = 0; - printer(arg, "%x", n); - } - } - if (first) - printer(arg, "oops # nothing escaped"); -} - -/* - * tty_init - do various tty-related initializations. - */ -void tty_init() -{ - add_notifier(&pidchange, maybe_relock, 0); - the_channel = &tty_channel; - xmit_accm[3] = 0x60000000; -} - -/* - * tty_process_extra_options - work out which tty device we are using - * and read its options file. - */ -void tty_process_extra_options() -{ - using_pty = notty || ptycommand != NULL || pty_socket != NULL; - if (using_pty) - return; - if (default_device) { - char *p; - if (!isatty(0) || (p = ttyname(0)) == NULL) { - option_error("no device specified and stdin is not a tty"); - exit(EXIT_OPTION_ERROR); - } - strlcpy(devnam, p, sizeof(devnam)); - if (stat(devnam, &devstat) < 0) - fatal("Couldn't stat default device %s: %m", devnam); - } - - - /* - * Parse the tty options file. - * The per-tty options file should not change - * ptycommand, pty_socket, notty or devnam. - * options_for_tty doesn't override options set on the command line, - * except for some privileged options. - */ - if (!options_for_tty()) - exit(EXIT_OPTION_ERROR); -} - -/* - * tty_check_options - do consistency checks on the options we were given. - */ -void -tty_check_options() -{ - struct stat statbuf; - int fdflags; - - if (demand && connect_script == 0) { - option_error("connect script is required for demand-dialling\n"); - exit(EXIT_OPTION_ERROR); - } - /* default holdoff to 0 if no connect script has been given */ - if (connect_script == 0 && !holdoff_specified) - holdoff = 0; - - if (using_pty) { - if (!default_device) { - option_error("%s option precludes specifying device name", - notty? "notty": "pty"); - exit(EXIT_OPTION_ERROR); - } - if (ptycommand != NULL && notty) { - option_error("pty option is incompatible with notty option"); - exit(EXIT_OPTION_ERROR); - } - if (pty_socket != NULL && (ptycommand != NULL || notty)) { - option_error("socket option is incompatible with pty and notty"); - exit(EXIT_OPTION_ERROR); - } - default_device = notty; - lockflag = 0; - modem = 0; - if (notty && log_to_fd <= 1) - log_to_fd = -1; - } else { - /* - * If the user has specified a device which is the same as - * the one on stdin, pretend they didn't specify any. - * If the device is already open read/write on stdin, - * we assume we don't need to lock it, and we can open it - * as root. - */ - if (fstat(0, &statbuf) >= 0 && S_ISCHR(statbuf.st_mode) - && statbuf.st_rdev == devstat.st_rdev) { - default_device = 1; - fdflags = fcntl(0, F_GETFL); - if (fdflags != -1 && (fdflags & O_ACCMODE) == O_RDWR) - privopen = 1; - } - } - if (default_device) - nodetach = 1; - - /* - * Don't send log messages to the serial port, it tends to - * confuse the peer. :-) - */ - if (log_to_fd >= 0 && fstat(log_to_fd, &statbuf) >= 0 - && S_ISCHR(statbuf.st_mode) && statbuf.st_rdev == devstat.st_rdev) - log_to_fd = -1; -} - -/* - * connect_tty - get the serial port ready to start doing PPP. - * That is, open the serial port, set its speed and mode, and run - * the connector and/or welcomer. - */ -int connect_tty() -{ - char *connector; - int fdflags; - struct stat statbuf; - char numbuf[16]; - - /* - * Get a pty master/slave pair if the pty, notty, socket, - * or record options were specified. - */ - strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); - pty_master = -1; - pty_slave = -1; - real_ttyfd = -1; - if (using_pty || record_file != NULL) { - if (!get_pty(&pty_master, &pty_slave, ppp_devnam, uid)) { - error("Couldn't allocate pseudo-tty"); - status = EXIT_FATAL_ERROR; - return -1; - } - set_up_tty(pty_slave, 1); - } - - /* - * Lock the device if we've been asked to. - */ - status = EXIT_LOCK_FAILED; - if (lockflag && !privopen) { - if (lock(devnam) < 0) - return -1; - locked = 1; - } - - /* - * Open the serial device and set it up to be the ppp interface. - * First we open it in non-blocking mode so we can set the - * various termios flags appropriately. If we aren't dialling - * out and we want to use the modem lines, we reopen it later - * in order to wait for the carrier detect signal from the modem. - */ - hungup = 0; - kill_link = 0; - connector = doing_callback? callback_script: connect_script; - if (devnam[0] != 0) { - for (;;) { - /* If the user specified the device name, become the - user before opening it. */ - int err, prio; - - prio = privopen? OPRIO_ROOT: tty_options[0].priority; - if (prio < OPRIO_ROOT) - seteuid(uid); - ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0); - err = errno; - if (prio < OPRIO_ROOT) - seteuid(0); - if (ttyfd >= 0) - break; - errno = err; - if (err != EINTR) { - error("Failed to open %s: %m", devnam); - status = EXIT_OPEN_FAILED; - } - if (!persist || err != EINTR) - return -1; - } - real_ttyfd = ttyfd; - if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 - || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) - warn("Couldn't reset non-blocking mode on device: %m"); - - /* - * Do the equivalent of `mesg n' to stop broadcast messages. - */ - if (fstat(ttyfd, &statbuf) < 0 - || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) { - warn("Couldn't restrict write permissions to %s: %m", devnam); - } else - tty_mode = statbuf.st_mode; - - /* - * Set line speed, flow control, etc. - * If we have a non-null connection or initializer script, - * on most systems we set CLOCAL for now so that we can talk - * to the modem before carrier comes up. But this has the - * side effect that we might miss it if CD drops before we - * get to clear CLOCAL below. On systems where we can talk - * successfully to the modem with CLOCAL clear and CD down, - * we could clear CLOCAL at this point. - */ - set_up_tty(ttyfd, ((connector != NULL && connector[0] != 0) - || initializer != NULL)); - } - - /* - * If the pty, socket, notty and/or record option was specified, - * start up the character shunt now. - */ - status = EXIT_PTYCMD_FAILED; - if (ptycommand != NULL) { - if (record_file != NULL) { - int ipipe[2], opipe[2], ok; - - if (pipe(ipipe) < 0 || pipe(opipe) < 0) - fatal("Couldn't create pipes for record option: %m"); - ok = device_script(ptycommand, opipe[0], ipipe[1], 1) == 0 - && start_charshunt(ipipe[0], opipe[1]); - close(ipipe[0]); - close(ipipe[1]); - close(opipe[0]); - close(opipe[1]); - if (!ok) - return -1; - } else { - if (device_script(ptycommand, pty_master, pty_master, 1) < 0) - return -1; - ttyfd = pty_slave; - close(pty_master); - pty_master = -1; - } - } else if (pty_socket != NULL) { - int fd = open_socket(pty_socket); - if (fd < 0) - return -1; - if (!start_charshunt(fd, fd)) - return -1; - } else if (notty) { - if (!start_charshunt(0, 1)) - return -1; - } else if (record_file != NULL) { - if (!start_charshunt(ttyfd, ttyfd)) - return -1; - } - - /* run connection script */ - if ((connector && connector[0]) || initializer) { - if (real_ttyfd != -1) { - /* XXX do this if doing_callback == CALLBACK_DIALIN? */ - if (!default_device && modem) { - setdtr(real_ttyfd, 0); /* in case modem is off hook */ - sleep(1); - setdtr(real_ttyfd, 1); - } - } - - if (initializer && initializer[0]) { - if (device_script(initializer, ttyfd, ttyfd, 0) < 0) { - error("Initializer script failed"); - status = EXIT_INIT_FAILED; - return -1; - } - if (kill_link) { - disconnect_tty(); - return -1; - } - info("Serial port initialized."); - } - - if (connector && connector[0]) { - if (device_script(connector, ttyfd, ttyfd, 0) < 0) { - error("Connect script failed"); - status = EXIT_CONNECT_FAILED; - return -1; - } - if (kill_link) { - disconnect_tty(); - return -1; - } - info("Serial connection established."); - } - - /* set line speed, flow control, etc.; - clear CLOCAL if modem option */ - if (real_ttyfd != -1) - set_up_tty(real_ttyfd, 0); - - if (doing_callback == CALLBACK_DIALIN) - connector = NULL; - } - - /* reopen tty if necessary to wait for carrier */ - if (connector == NULL && modem && devnam[0] != 0) { - int i; - for (;;) { - if ((i = open(devnam, O_RDWR)) >= 0) - break; - if (errno != EINTR) { - error("Failed to reopen %s: %m", devnam); - status = EXIT_OPEN_FAILED; - } - if (!persist || errno != EINTR || hungup || kill_link) - return -1; - } - close(i); - } - - slprintf(numbuf, sizeof(numbuf), "%d", baud_rate); - script_setenv("SPEED", numbuf, 0); - - /* run welcome script, if any */ - if (welcomer && welcomer[0]) { - if (device_script(welcomer, ttyfd, ttyfd, 0) < 0) - warn("Welcome script failed"); - } - - /* - * If we are initiating this connection, wait for a short - * time for something from the peer. This can avoid bouncing - * our packets off his tty before he has it set up. - */ - if (connector != NULL || ptycommand != NULL) - listen_time = connect_delay; - - return ttyfd; -} - - -void disconnect_tty() -{ - if (disconnect_script == NULL || hungup) - return; - if (real_ttyfd >= 0) - set_up_tty(real_ttyfd, 1); - if (device_script(disconnect_script, ttyfd, ttyfd, 0) < 0) { - warn("disconnect script failed"); - } else { - info("Serial link disconnected."); - } -} - -void tty_close_fds() -{ - if (pty_master >= 0) - close(pty_master); - if (pty_slave >= 0) - close(pty_slave); - if (real_ttyfd >= 0) { - close(real_ttyfd); - real_ttyfd = -1; - } - /* N.B. ttyfd will == either pty_slave or real_ttyfd */ -} - -void cleanup_tty() -{ - if (real_ttyfd >= 0) - finish_tty(); - tty_close_fds(); - if (locked) { - unlock(); - locked = 0; - } -} - -/* - * tty_do_send_config - set transmit-side PPP configuration. - * We set the extended transmit ACCM here as well. - */ -void -tty_do_send_config(mtu, accm, pcomp, accomp) - int mtu; - u_int32_t accm; - int pcomp, accomp; -{ - tty_set_xaccm(xmit_accm); - tty_send_config(mtu, accm, pcomp, accomp); -} - -/* - * finish_tty - restore the terminal device to its original settings - */ -static void -finish_tty() -{ - /* drop dtr to hang up */ - if (!default_device && modem) { - setdtr(real_ttyfd, 0); - /* - * This sleep is in case the serial port has CLOCAL set by default, - * and consequently will reassert DTR when we close the device. - */ - sleep(1); - } - - restore_tty(real_ttyfd); - - if (tty_mode != (mode_t) -1) { - if (fchmod(real_ttyfd, tty_mode) != 0) { - /* XXX if devnam is a symlink, this will change the link */ - chmod(devnam, tty_mode); - } - } - - close(real_ttyfd); - real_ttyfd = -1; -} - -/* - * maybe_relock - our PID has changed, maybe update the lock file. - */ -static void -maybe_relock(arg, pid) - void *arg; - int pid; -{ - if (locked) - relock(pid); -} - -/* - * open_socket - establish a stream socket connection to the nominated - * host and port. - */ -static int -open_socket(dest) - char *dest; -{ - char *sep, *endp = NULL; - int sock, port = -1; - u_int32_t host; - struct hostent *hent; - struct sockaddr_in sad; - - /* parse host:port and resolve host to an IP address */ - sep = strchr(dest, ':'); - if (sep != NULL) - port = strtol(sep+1, &endp, 10); - if (port < 0 || endp == sep+1 || sep == dest) { - error("Can't parse host:port for socket destination"); - return -1; - } - *sep = 0; - host = inet_addr(dest); - if (host == (u_int32_t) -1) { - hent = gethostbyname(dest); - if (hent == NULL) { - error("%s: unknown host in socket option", dest); - *sep = ':'; - return -1; - } - host = *(u_int32_t *)(hent->h_addr_list[0]); - } - *sep = ':'; - - /* get a socket and connect it to the other end */ - sock = socket(PF_INET, SOCK_STREAM, 0); - if (sock < 0) { - error("Can't create socket: %m"); - return -1; - } - memset(&sad, 0, sizeof(sad)); - sad.sin_family = AF_INET; - sad.sin_port = htons(port); - sad.sin_addr.s_addr = host; - if (connect(sock, (struct sockaddr *)&sad, sizeof(sad)) < 0) { - error("Can't connect to %s: %m", dest); - close(sock); - return -1; - } - - return sock; -} - - -/* - * start_charshunt - create a child process to run the character shunt. - */ -static int -start_charshunt(ifd, ofd) - int ifd, ofd; -{ - int cpid; - - cpid = fork(); - if (cpid == -1) { - error("Can't fork process for character shunt: %m"); - return 0; - } - if (cpid == 0) { - /* child */ - close(pty_slave); - setuid(uid); - if (getuid() != uid) - fatal("setuid failed"); - setgid(getgid()); - if (!nodetach) - log_to_fd = -1; - charshunt(ifd, ofd, record_file); - exit(0); - } - charshunt_pid = cpid; - add_notifier(&sigreceived, stop_charshunt, 0); - close(pty_master); - pty_master = -1; - ttyfd = pty_slave; - record_child(cpid, "pppd (charshunt)", charshunt_done, NULL); - return 1; -} - -static void -charshunt_done(arg) - void *arg; -{ - charshunt_pid = 0; -} - -static void -stop_charshunt(arg, sig) - void *arg; - int sig; -{ - if (charshunt_pid) - kill(charshunt_pid, (sig == SIGINT? sig: SIGTERM)); -} - -/* - * charshunt - the character shunt, which passes characters between - * the pty master side and the serial port (or stdin/stdout). - * This runs as the user (not as root). - * (We assume ofd >= ifd which is true the way this gets called. :-). - */ -static void -charshunt(ifd, ofd, record_file) - int ifd, ofd; - char *record_file; -{ - int n, nfds; - fd_set ready, writey; - u_char *ibufp, *obufp; - int nibuf, nobuf; - int flags; - int pty_readable, stdin_readable; - struct timeval lasttime; - FILE *recordf = NULL; - int ilevel, olevel, max_level; - struct timeval levelt, tout, *top; - extern u_char inpacket_buf[]; - - /* - * Reset signal handlers. - */ - signal(SIGHUP, SIG_IGN); /* Hangup */ - signal(SIGINT, SIG_DFL); /* Interrupt */ - signal(SIGTERM, SIG_DFL); /* Terminate */ - signal(SIGCHLD, SIG_DFL); - signal(SIGUSR1, SIG_DFL); - signal(SIGUSR2, SIG_DFL); - signal(SIGABRT, SIG_DFL); - signal(SIGALRM, SIG_DFL); - signal(SIGFPE, SIG_DFL); - signal(SIGILL, SIG_DFL); - signal(SIGPIPE, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGSEGV, SIG_DFL); -#ifdef SIGBUS - signal(SIGBUS, SIG_DFL); -#endif -#ifdef SIGEMT - signal(SIGEMT, SIG_DFL); -#endif -#ifdef SIGPOLL - signal(SIGPOLL, SIG_DFL); -#endif -#ifdef SIGPROF - signal(SIGPROF, SIG_DFL); -#endif -#ifdef SIGSYS - signal(SIGSYS, SIG_DFL); -#endif -#ifdef SIGTRAP - signal(SIGTRAP, SIG_DFL); -#endif -#ifdef SIGVTALRM - signal(SIGVTALRM, SIG_DFL); -#endif -#ifdef SIGXCPU - signal(SIGXCPU, SIG_DFL); -#endif -#ifdef SIGXFSZ - signal(SIGXFSZ, SIG_DFL); -#endif - - /* - * Open the record file if required. - */ - if (record_file != NULL) { - recordf = fopen(record_file, "a"); - if (recordf == NULL) - error("Couldn't create record file %s: %m", record_file); - } - - /* set all the fds to non-blocking mode */ - flags = fcntl(pty_master, F_GETFL); - if (flags == -1 - || fcntl(pty_master, F_SETFL, flags | O_NONBLOCK) == -1) - warn("couldn't set pty master to nonblock: %m"); - flags = fcntl(ifd, F_GETFL); - if (flags == -1 - || fcntl(ifd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("couldn't set %s to nonblock: %m", (ifd==0? "stdin": "tty")); - if (ofd != ifd) { - flags = fcntl(ofd, F_GETFL); - if (flags == -1 - || fcntl(ofd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("couldn't set stdout to nonblock: %m"); - } - - nibuf = nobuf = 0; - ibufp = obufp = NULL; - pty_readable = stdin_readable = 1; - - ilevel = olevel = 0; - gettimeofday(&levelt, NULL); - if (max_data_rate) { - max_level = max_data_rate / 10; - if (max_level < 100) - max_level = 100; - } else - max_level = PPP_MRU + PPP_HDRLEN + 1; - - nfds = (ofd > pty_master? ofd: pty_master) + 1; - if (recordf != NULL) { - gettimeofday(&lasttime, NULL); - putc(7, recordf); /* put start marker */ - putc(lasttime.tv_sec >> 24, recordf); - putc(lasttime.tv_sec >> 16, recordf); - putc(lasttime.tv_sec >> 8, recordf); - putc(lasttime.tv_sec, recordf); - lasttime.tv_usec = 0; - } - - while (nibuf != 0 || nobuf != 0 || pty_readable || stdin_readable) { - top = 0; - tout.tv_sec = 0; - tout.tv_usec = 10000; - FD_ZERO(&ready); - FD_ZERO(&writey); - if (nibuf != 0) { - if (ilevel >= max_level) - top = &tout; - else - FD_SET(pty_master, &writey); - } else if (stdin_readable) - FD_SET(ifd, &ready); - if (nobuf != 0) { - if (olevel >= max_level) - top = &tout; - else - FD_SET(ofd, &writey); - } else if (pty_readable) - FD_SET(pty_master, &ready); - if (select(nfds, &ready, &writey, NULL, top) < 0) { - if (errno != EINTR) - fatal("select"); - continue; - } - if (max_data_rate) { - double dt; - int nbt; - struct timeval now; - - gettimeofday(&now, NULL); - dt = (now.tv_sec - levelt.tv_sec - + (now.tv_usec - levelt.tv_usec) / 1e6); - nbt = (int)(dt * max_data_rate); - ilevel = (nbt < 0 || nbt > ilevel)? 0: ilevel - nbt; - olevel = (nbt < 0 || nbt > olevel)? 0: olevel - nbt; - levelt = now; - } else - ilevel = olevel = 0; - if (FD_ISSET(ifd, &ready)) { - ibufp = inpacket_buf; - nibuf = read(ifd, ibufp, PPP_MRU + PPP_HDRLEN); - if (nibuf < 0 && errno == EIO) - nibuf = 0; - if (nibuf < 0) { - if (!(errno == EINTR || errno == EAGAIN)) { - error("Error reading standard input: %m"); - break; - } - nibuf = 0; - } else if (nibuf == 0) { - /* end of file from stdin */ - stdin_readable = 0; - /* do a 0-length write, hopefully this will generate - an EOF (hangup) on the slave side. */ - write(pty_master, inpacket_buf, 0); - if (recordf) - if (!record_write(recordf, 4, NULL, 0, &lasttime)) - recordf = NULL; - } else { - FD_SET(pty_master, &writey); - if (recordf) - if (!record_write(recordf, 2, ibufp, nibuf, &lasttime)) - recordf = NULL; - } - } - if (FD_ISSET(pty_master, &ready)) { - obufp = outpacket_buf; - nobuf = read(pty_master, obufp, PPP_MRU + PPP_HDRLEN); - if (nobuf < 0 && errno == EIO) - nobuf = 0; - if (nobuf < 0) { - if (!(errno == EINTR || errno == EAGAIN)) { - error("Error reading pseudo-tty master: %m"); - break; - } - nobuf = 0; - } else if (nobuf == 0) { - /* end of file from the pty - slave side has closed */ - pty_readable = 0; - stdin_readable = 0; /* pty is not writable now */ - nibuf = 0; - close(ofd); - if (recordf) - if (!record_write(recordf, 3, NULL, 0, &lasttime)) - recordf = NULL; - } else { - FD_SET(ofd, &writey); - if (recordf) - if (!record_write(recordf, 1, obufp, nobuf, &lasttime)) - recordf = NULL; - } - } - if (FD_ISSET(ofd, &writey)) { - n = nobuf; - if (olevel + n > max_level) - n = max_level - olevel; - n = write(ofd, obufp, n); - if (n < 0) { - if (errno == EIO) { - pty_readable = 0; - nobuf = 0; - } else if (errno != EAGAIN && errno != EINTR) { - error("Error writing standard output: %m"); - break; - } - } else { - obufp += n; - nobuf -= n; - olevel += n; - } - } - if (FD_ISSET(pty_master, &writey)) { - n = nibuf; - if (ilevel + n > max_level) - n = max_level - ilevel; - n = write(pty_master, ibufp, n); - if (n < 0) { - if (errno == EIO) { - stdin_readable = 0; - nibuf = 0; - } else if (errno != EAGAIN && errno != EINTR) { - error("Error writing pseudo-tty master: %m"); - break; - } - } else { - ibufp += n; - nibuf -= n; - ilevel += n; - } - } - } - exit(0); -} - -static int -record_write(f, code, buf, nb, tp) - FILE *f; - int code; - u_char *buf; - int nb; - struct timeval *tp; -{ - struct timeval now; - int diff; - - gettimeofday(&now, NULL); - now.tv_usec /= 100000; /* actually 1/10 s, not usec now */ - diff = (now.tv_sec - tp->tv_sec) * 10 + (now.tv_usec - tp->tv_usec); - if (diff > 0) { - if (diff > 255) { - putc(5, f); - putc(diff >> 24, f); - putc(diff >> 16, f); - putc(diff >> 8, f); - putc(diff, f); - } else { - putc(6, f); - putc(diff, f); - } - *tp = now; - } - putc(code, f); - if (buf != NULL) { - putc(nb >> 8, f); - putc(nb, f); - fwrite(buf, nb, 1, f); - } - fflush(f); - if (ferror(f)) { - error("Error writing record file: %m"); - return 0; - } - return 1; -} diff --git a/mdk-stage1/ppp/pppd/upap.c b/mdk-stage1/ppp/pppd/upap.c deleted file mode 100644 index bd569fb74..000000000 --- a/mdk-stage1/ppp/pppd/upap.c +++ /dev/null @@ -1,640 +0,0 @@ -/* - * upap.c - User/Password Authentication Protocol. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - */ - -#define RCSID "$Id$" - -/* - * TODO: - */ - -#include <stdio.h> -#include <string.h> - -#include "pppd.h" -#include "upap.h" - -static const char rcsid[] = RCSID; - -static bool hide_password = 1; - -/* - * Command-line options. - */ -static option_t pap_option_list[] = { - { "hide-password", o_bool, &hide_password, - "Don't output passwords to log", OPT_PRIO | 1 }, - { "show-password", o_bool, &hide_password, - "Show password string in debug log messages", OPT_PRIOSUB | 0 }, - - { "pap-restart", o_int, &upap[0].us_timeouttime, - "Set retransmit timeout for PAP", OPT_PRIO }, - { "pap-max-authreq", o_int, &upap[0].us_maxtransmits, - "Set max number of transmissions for auth-reqs", OPT_PRIO }, - { "pap-timeout", o_int, &upap[0].us_reqtimeout, - "Set time limit for peer PAP authentication", OPT_PRIO }, - - { NULL } -}; - -/* - * Protocol entry points. - */ -static void upap_init __P((int)); -static void upap_lowerup __P((int)); -static void upap_lowerdown __P((int)); -static void upap_input __P((int, u_char *, int)); -static void upap_protrej __P((int)); -static int upap_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); - -struct protent pap_protent = { - PPP_PAP, - upap_init, - upap_input, - upap_protrej, - upap_lowerup, - upap_lowerdown, - NULL, - NULL, - upap_printpkt, - NULL, - 1, - "PAP", - NULL, - pap_option_list, - NULL, - NULL, - NULL -}; - -upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */ - -static void upap_timeout __P((void *)); -static void upap_reqtimeout __P((void *)); -static void upap_rauthreq __P((upap_state *, u_char *, int, int)); -static void upap_rauthack __P((upap_state *, u_char *, int, int)); -static void upap_rauthnak __P((upap_state *, u_char *, int, int)); -static void upap_sauthreq __P((upap_state *)); -static void upap_sresp __P((upap_state *, int, int, char *, int)); - - -/* - * upap_init - Initialize a UPAP unit. - */ -static void -upap_init(unit) - int unit; -{ - upap_state *u = &upap[unit]; - - u->us_unit = unit; - u->us_user = NULL; - u->us_userlen = 0; - u->us_passwd = NULL; - u->us_passwdlen = 0; - u->us_clientstate = UPAPCS_INITIAL; - u->us_serverstate = UPAPSS_INITIAL; - u->us_id = 0; - u->us_timeouttime = UPAP_DEFTIMEOUT; - u->us_maxtransmits = 10; - u->us_reqtimeout = UPAP_DEFREQTIME; -} - - -/* - * upap_authwithpeer - Authenticate us with our peer (start client). - * - * Set new state and send authenticate's. - */ -void -upap_authwithpeer(unit, user, password) - int unit; - char *user, *password; -{ - upap_state *u = &upap[unit]; - - /* Save the username and password we're given */ - u->us_user = user; - u->us_userlen = strlen(user); - u->us_passwd = password; - u->us_passwdlen = strlen(password); - u->us_transmits = 0; - - /* Lower layer up yet? */ - if (u->us_clientstate == UPAPCS_INITIAL || - u->us_clientstate == UPAPCS_PENDING) { - u->us_clientstate = UPAPCS_PENDING; - return; - } - - upap_sauthreq(u); /* Start protocol */ -} - - -/* - * upap_authpeer - Authenticate our peer (start server). - * - * Set new state. - */ -void -upap_authpeer(unit) - int unit; -{ - upap_state *u = &upap[unit]; - - /* Lower layer up yet? */ - if (u->us_serverstate == UPAPSS_INITIAL || - u->us_serverstate == UPAPSS_PENDING) { - u->us_serverstate = UPAPSS_PENDING; - return; - } - - u->us_serverstate = UPAPSS_LISTEN; - if (u->us_reqtimeout > 0) - TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); -} - - -/* - * upap_timeout - Retransmission timer for sending auth-reqs expired. - */ -static void -upap_timeout(arg) - void *arg; -{ - upap_state *u = (upap_state *) arg; - - if (u->us_clientstate != UPAPCS_AUTHREQ) - return; - - if (u->us_transmits >= u->us_maxtransmits) { - /* give up in disgust */ - error("No response to PAP authenticate-requests"); - u->us_clientstate = UPAPCS_BADAUTH; - auth_withpeer_fail(u->us_unit, PPP_PAP); - return; - } - - upap_sauthreq(u); /* Send Authenticate-Request */ -} - - -/* - * upap_reqtimeout - Give up waiting for the peer to send an auth-req. - */ -static void -upap_reqtimeout(arg) - void *arg; -{ - upap_state *u = (upap_state *) arg; - - if (u->us_serverstate != UPAPSS_LISTEN) - return; /* huh?? */ - - auth_peer_fail(u->us_unit, PPP_PAP); - u->us_serverstate = UPAPSS_BADAUTH; -} - - -/* - * upap_lowerup - The lower layer is up. - * - * Start authenticating if pending. - */ -static void -upap_lowerup(unit) - int unit; -{ - upap_state *u = &upap[unit]; - - if (u->us_clientstate == UPAPCS_INITIAL) - u->us_clientstate = UPAPCS_CLOSED; - else if (u->us_clientstate == UPAPCS_PENDING) { - upap_sauthreq(u); /* send an auth-request */ - } - - if (u->us_serverstate == UPAPSS_INITIAL) - u->us_serverstate = UPAPSS_CLOSED; - else if (u->us_serverstate == UPAPSS_PENDING) { - u->us_serverstate = UPAPSS_LISTEN; - if (u->us_reqtimeout > 0) - TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); - } -} - - -/* - * upap_lowerdown - The lower layer is down. - * - * Cancel all timeouts. - */ -static void -upap_lowerdown(unit) - int unit; -{ - upap_state *u = &upap[unit]; - - if (u->us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */ - UNTIMEOUT(upap_timeout, u); /* Cancel timeout */ - if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) - UNTIMEOUT(upap_reqtimeout, u); - - u->us_clientstate = UPAPCS_INITIAL; - u->us_serverstate = UPAPSS_INITIAL; -} - - -/* - * upap_protrej - Peer doesn't speak this protocol. - * - * This shouldn't happen. In any case, pretend lower layer went down. - */ -static void -upap_protrej(unit) - int unit; -{ - upap_state *u = &upap[unit]; - - if (u->us_clientstate == UPAPCS_AUTHREQ) { - error("PAP authentication failed due to protocol-reject"); - auth_withpeer_fail(unit, PPP_PAP); - } - if (u->us_serverstate == UPAPSS_LISTEN) { - error("PAP authentication of peer failed (protocol-reject)"); - auth_peer_fail(unit, PPP_PAP); - } - upap_lowerdown(unit); -} - - -/* - * upap_input - Input UPAP packet. - */ -static void -upap_input(unit, inpacket, l) - int unit; - u_char *inpacket; - int l; -{ - upap_state *u = &upap[unit]; - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (l < UPAP_HEADERLEN) { - UPAPDEBUG(("pap_input: rcvd short header.")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < UPAP_HEADERLEN) { - UPAPDEBUG(("pap_input: rcvd illegal length.")); - return; - } - if (len > l) { - UPAPDEBUG(("pap_input: rcvd short packet.")); - return; - } - len -= UPAP_HEADERLEN; - - /* - * Action depends on code. - */ - switch (code) { - case UPAP_AUTHREQ: - upap_rauthreq(u, inp, id, len); - break; - - case UPAP_AUTHACK: - upap_rauthack(u, inp, id, len); - break; - - case UPAP_AUTHNAK: - upap_rauthnak(u, inp, id, len); - break; - - default: /* XXX Need code reject */ - break; - } -} - - -/* - * upap_rauth - Receive Authenticate. - */ -static void -upap_rauthreq(u, inp, id, len) - upap_state *u; - u_char *inp; - int id; - int len; -{ - u_char ruserlen, rpasswdlen; - char *ruser, *rpasswd; - int retcode; - char *msg; - int msglen; - - if (u->us_serverstate < UPAPSS_LISTEN) - return; - - /* - * If we receive a duplicate authenticate-request, we are - * supposed to return the same status as for the first request. - */ - if (u->us_serverstate == UPAPSS_OPEN) { - upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ - return; - } - if (u->us_serverstate == UPAPSS_BADAUTH) { - upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ - return; - } - - /* - * Parse user/passwd. - */ - if (len < 1) { - UPAPDEBUG(("pap_rauth: rcvd short packet.")); - return; - } - GETCHAR(ruserlen, inp); - len -= sizeof (u_char) + ruserlen + sizeof (u_char); - if (len < 0) { - UPAPDEBUG(("pap_rauth: rcvd short packet.")); - return; - } - ruser = (char *) inp; - INCPTR(ruserlen, inp); - GETCHAR(rpasswdlen, inp); - if (len < rpasswdlen) { - UPAPDEBUG(("pap_rauth: rcvd short packet.")); - return; - } - rpasswd = (char *) inp; - - /* - * Check the username and password given. - */ - retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, - rpasswdlen, &msg); - BZERO(rpasswd, rpasswdlen); - msglen = strlen(msg); - if (msglen > 255) - msglen = 255; - - upap_sresp(u, retcode, id, msg, msglen); - - if (retcode == UPAP_AUTHACK) { - u->us_serverstate = UPAPSS_OPEN; - auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen); - } else { - u->us_serverstate = UPAPSS_BADAUTH; - auth_peer_fail(u->us_unit, PPP_PAP); - } - - if (u->us_reqtimeout > 0) - UNTIMEOUT(upap_reqtimeout, u); -} - - -/* - * upap_rauthack - Receive Authenticate-Ack. - */ -static void -upap_rauthack(u, inp, id, len) - upap_state *u; - u_char *inp; - int id; - int len; -{ - u_char msglen; - char *msg; - - if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */ - return; - - /* - * Parse message. - */ - if (len < 1) { - UPAPDEBUG(("pap_rauthack: ignoring missing msg-length.")); - } else { - GETCHAR(msglen, inp); - if (msglen > 0) { - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG(("pap_rauthack: rcvd short packet.")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - } - } - - u->us_clientstate = UPAPCS_OPEN; - - auth_withpeer_success(u->us_unit, PPP_PAP); -} - - -/* - * upap_rauthnak - Receive Authenticate-Nakk. - */ -static void -upap_rauthnak(u, inp, id, len) - upap_state *u; - u_char *inp; - int id; - int len; -{ - u_char msglen; - char *msg; - - if (u->us_clientstate != UPAPCS_AUTHREQ) /* XXX */ - return; - - /* - * Parse message. - */ - if (len < 1) { - UPAPDEBUG(("pap_rauthnak: ignoring missing msg-length.")); - } else { - GETCHAR(msglen, inp); - if (msglen > 0) { - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG(("pap_rauthnak: rcvd short packet.")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - } - } - - u->us_clientstate = UPAPCS_BADAUTH; - - error("PAP authentication failed"); - auth_withpeer_fail(u->us_unit, PPP_PAP); -} - - -/* - * upap_sauthreq - Send an Authenticate-Request. - */ -static void -upap_sauthreq(u) - upap_state *u; -{ - u_char *outp; - int outlen; - - outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + - u->us_userlen + u->us_passwdlen; - outp = outpacket_buf; - - MAKEHEADER(outp, PPP_PAP); - - PUTCHAR(UPAP_AUTHREQ, outp); - PUTCHAR(++u->us_id, outp); - PUTSHORT(outlen, outp); - PUTCHAR(u->us_userlen, outp); - BCOPY(u->us_user, outp, u->us_userlen); - INCPTR(u->us_userlen, outp); - PUTCHAR(u->us_passwdlen, outp); - BCOPY(u->us_passwd, outp, u->us_passwdlen); - - output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); - - TIMEOUT(upap_timeout, u, u->us_timeouttime); - ++u->us_transmits; - u->us_clientstate = UPAPCS_AUTHREQ; -} - - -/* - * upap_sresp - Send a response (ack or nak). - */ -static void -upap_sresp(u, code, id, msg, msglen) - upap_state *u; - u_char code, id; - char *msg; - int msglen; -{ - u_char *outp; - int outlen; - - outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; - outp = outpacket_buf; - MAKEHEADER(outp, PPP_PAP); - - PUTCHAR(code, outp); - PUTCHAR(id, outp); - PUTSHORT(outlen, outp); - PUTCHAR(msglen, outp); - BCOPY(msg, outp, msglen); - output(u->us_unit, outpacket_buf, outlen + PPP_HDRLEN); -} - -/* - * upap_printpkt - print the contents of a PAP packet. - */ -static char *upap_codenames[] = { - "AuthReq", "AuthAck", "AuthNak" -}; - -static int -upap_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int code, id, len; - int mlen, ulen, wlen; - char *user, *pwd, *msg; - u_char *pstart; - - if (plen < UPAP_HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < UPAP_HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= sizeof(upap_codenames) / sizeof(char *)) - printer(arg, " %s", upap_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= UPAP_HEADERLEN; - switch (code) { - case UPAP_AUTHREQ: - if (len < 1) - break; - ulen = p[0]; - if (len < ulen + 2) - break; - wlen = p[ulen + 1]; - if (len < ulen + wlen + 2) - break; - user = (char *) (p + 1); - pwd = (char *) (p + ulen + 2); - p += ulen + wlen + 2; - len -= ulen + wlen + 2; - printer(arg, " user="); - print_string(user, ulen, printer, arg); - printer(arg, " password="); - if (!hide_password) - print_string(pwd, wlen, printer, arg); - else - printer(arg, "<hidden>"); - break; - case UPAP_AUTHACK: - case UPAP_AUTHNAK: - if (len < 1) - break; - mlen = p[0]; - if (len < mlen + 1) - break; - msg = (char *) (p + 1); - p += mlen + 1; - len -= mlen + 1; - printer(arg, " "); - print_string(msg, mlen, printer, arg); - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} diff --git a/mdk-stage1/ppp/pppd/upap.h b/mdk-stage1/ppp/pppd/upap.h deleted file mode 100644 index 42d6f4f0f..000000000 --- a/mdk-stage1/ppp/pppd/upap.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * upap.h - User/Password Authentication Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon 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 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. - * - * $Id$ - */ - -/* - * Packet header = Code, id, length. - */ -#define UPAP_HEADERLEN 4 - - -/* - * UPAP codes. - */ -#define UPAP_AUTHREQ 1 /* Authenticate-Request */ -#define UPAP_AUTHACK 2 /* Authenticate-Ack */ -#define UPAP_AUTHNAK 3 /* Authenticate-Nak */ - - -/* - * Each interface is described by upap structure. - */ -typedef struct upap_state { - int us_unit; /* Interface unit number */ - char *us_user; /* User */ - int us_userlen; /* User length */ - char *us_passwd; /* Password */ - int us_passwdlen; /* Password length */ - int us_clientstate; /* Client state */ - int us_serverstate; /* Server state */ - u_char us_id; /* Current id */ - int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */ - int us_transmits; /* Number of auth-reqs sent */ - int us_maxtransmits; /* Maximum number of auth-reqs to send */ - int us_reqtimeout; /* Time to wait for auth-req from peer */ -} upap_state; - - -/* - * Client states. - */ -#define UPAPCS_INITIAL 0 /* Connection down */ -#define UPAPCS_CLOSED 1 /* Connection up, haven't requested auth */ -#define UPAPCS_PENDING 2 /* Connection down, have requested auth */ -#define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */ -#define UPAPCS_OPEN 4 /* We've received an Ack */ -#define UPAPCS_BADAUTH 5 /* We've received a Nak */ - -/* - * Server states. - */ -#define UPAPSS_INITIAL 0 /* Connection down */ -#define UPAPSS_CLOSED 1 /* Connection up, haven't requested auth */ -#define UPAPSS_PENDING 2 /* Connection down, have requested auth */ -#define UPAPSS_LISTEN 3 /* Listening for an Authenticate */ -#define UPAPSS_OPEN 4 /* We've sent an Ack */ -#define UPAPSS_BADAUTH 5 /* We've sent a Nak */ - - -/* - * Timeouts. - */ -#define UPAP_DEFTIMEOUT 3 /* Timeout (seconds) for retransmitting req */ -#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ - -extern upap_state upap[]; - -void upap_authwithpeer __P((int, char *, char *)); -void upap_authpeer __P((int)); - -extern struct protent pap_protent; diff --git a/mdk-stage1/ppp/pppd/utils.c b/mdk-stage1/ppp/pppd/utils.c deleted file mode 100644 index 9c987cfcd..000000000 --- a/mdk-stage1/ppp/pppd/utils.c +++ /dev/null @@ -1,949 +0,0 @@ -/* - * utils.c - various utility functions used in pppd. - * - * Copyright (c) 1999 The Australian National 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 the Australian National 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. - */ - -#define RCSID "$Id$" - -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> -#include <errno.h> -#include <fcntl.h> -#include <syslog.h> -#include <netdb.h> -#include <utmp.h> -#include <pwd.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <netinet/in.h> -#ifdef SVR4 -#include <sys/mkdev.h> -#endif - -#include "pppd.h" -#include <time.h> - -static const char rcsid[] = RCSID; - -#if defined(SUNOS4) -extern char *strerror(); -#endif - -static void logit __P((int, char *, va_list)); -static void log_write __P((int, char *)); -static void vslp_printer __P((void *, char *, ...)); -static void format_packet __P((u_char *, int, void (*) (void *, char *, ...), - void *)); - -struct buffer_info { - char *ptr; - int len; -}; - -/* - * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, - * always leaves destination null-terminated (for len > 0). - */ -size_t -strlcpy(dest, src, len) - char *dest; - const char *src; - size_t len; -{ - size_t ret = strlen(src); - - if (len != 0) { - if (ret < len) - strcpy(dest, src); - else { - strncpy(dest, src, len - 1); - dest[len-1] = 0; - } - } - return ret; -} - -/* - * strlcat - like strcat/strncat, doesn't overflow destination buffer, - * always leaves destination null-terminated (for len > 0). - */ -size_t -strlcat(dest, src, len) - char *dest; - const char *src; - size_t len; -{ - size_t dlen = strlen(dest); - - return dlen + strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0)); -} - - -/* - * slprintf - format a message into a buffer. Like sprintf except we - * also specify the length of the output buffer, and we handle - * %r (recursive format), %m (error message), %v (visible string), - * %q (quoted string), %t (current time) and %I (IP address) formats. - * Doesn't do floating-point formats. - * Returns the number of chars put into buf. - */ -int -slprintf __V((char *buf, int buflen, char *fmt, ...)) -{ - va_list args; - int n; - -#if defined(__STDC__) - va_start(args, fmt); -#else - char *buf; - int buflen; - char *fmt; - va_start(args); - buf = va_arg(args, char *); - buflen = va_arg(args, int); - fmt = va_arg(args, char *); -#endif - n = vslprintf(buf, buflen, fmt, args); - va_end(args); - return n; -} - -/* - * vslprintf - like slprintf, takes a va_list instead of a list of args. - */ -#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) - -int -vslprintf(buf, buflen, fmt, args) - char *buf; - int buflen; - char *fmt; - va_list args; -{ - int c, i, n; - int width, prec, fillch; - int base, len, neg, quoted; - unsigned long val = 0; - char *str, *f, *buf0; - unsigned char *p; - char num[32]; - time_t t; - u_int32_t ip; - static char hexchars[] = "0123456789abcdef"; - struct buffer_info bufinfo; - - buf0 = buf; - --buflen; - while (buflen > 0) { - for (f = fmt; *f != '%' && *f != 0; ++f) - ; - if (f > fmt) { - len = f - fmt; - if (len > buflen) - len = buflen; - memcpy(buf, fmt, len); - buf += len; - buflen -= len; - fmt = f; - } - if (*fmt == 0) - break; - c = *++fmt; - width = 0; - prec = -1; - fillch = ' '; - if (c == '0') { - fillch = '0'; - c = *++fmt; - } - if (c == '*') { - width = va_arg(args, int); - c = *++fmt; - } else { - while (isdigit(c)) { - width = width * 10 + c - '0'; - c = *++fmt; - } - } - if (c == '.') { - c = *++fmt; - if (c == '*') { - prec = va_arg(args, int); - c = *++fmt; - } else { - prec = 0; - while (isdigit(c)) { - prec = prec * 10 + c - '0'; - c = *++fmt; - } - } - } - str = 0; - base = 0; - neg = 0; - ++fmt; - switch (c) { - case 'd': - i = va_arg(args, int); - if (i < 0) { - neg = 1; - val = -i; - } else - val = i; - base = 10; - break; - case 'u': - val = va_arg(args, unsigned int); - base = 10; - break; - case 'o': - val = va_arg(args, unsigned int); - base = 8; - break; - case 'x': - case 'X': - val = va_arg(args, unsigned int); - base = 16; - break; - case 'p': - val = (unsigned long) va_arg(args, void *); - base = 16; - neg = 2; - break; - case 's': - str = va_arg(args, char *); - break; - case 'c': - num[0] = va_arg(args, int); - num[1] = 0; - str = num; - break; - case 'm': - str = strerror(errno); - break; - case 'I': - ip = va_arg(args, u_int32_t); - ip = ntohl(ip); - slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff, - (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); - str = num; - break; - case 'r': - f = va_arg(args, char *); -#ifndef __powerpc__ - n = vslprintf(buf, buflen + 1, f, va_arg(args, va_list)); -#else - /* On the powerpc, a va_list is an array of 1 structure */ - n = vslprintf(buf, buflen + 1, f, va_arg(args, void *)); -#endif - buf += n; - buflen -= n; - continue; - case 't': - time(&t); - str = ctime(&t); - str += 4; /* chop off the day name */ - str[15] = 0; /* chop off year and newline */ - break; - case 'v': /* "visible" string */ - case 'q': /* quoted string */ - quoted = c == 'q'; - p = va_arg(args, unsigned char *); - if (fillch == '0' && prec >= 0) { - n = prec; - } else { - n = strlen((char *)p); - if (prec >= 0 && n > prec) - n = prec; - } - while (n > 0 && buflen > 0) { - c = *p++; - --n; - if (!quoted && c >= 0x80) { - OUTCHAR('M'); - OUTCHAR('-'); - c -= 0x80; - } - if (quoted && (c == '"' || c == '\\')) - OUTCHAR('\\'); - if (c < 0x20 || (0x7f <= c && c < 0xa0)) { - if (quoted) { - OUTCHAR('\\'); - switch (c) { - case '\t': OUTCHAR('t'); break; - case '\n': OUTCHAR('n'); break; - case '\b': OUTCHAR('b'); break; - case '\f': OUTCHAR('f'); break; - default: - OUTCHAR('x'); - OUTCHAR(hexchars[c >> 4]); - OUTCHAR(hexchars[c & 0xf]); - } - } else { - if (c == '\t') - OUTCHAR(c); - else { - OUTCHAR('^'); - OUTCHAR(c ^ 0x40); - } - } - } else - OUTCHAR(c); - } - continue; - case 'P': /* print PPP packet */ - bufinfo.ptr = buf; - bufinfo.len = buflen + 1; - p = va_arg(args, unsigned char *); - n = va_arg(args, int); - format_packet(p, n, vslp_printer, &bufinfo); - buf = bufinfo.ptr; - buflen = bufinfo.len - 1; - continue; - case 'B': - p = va_arg(args, unsigned char *); - for (n = prec; n > 0; --n) { - c = *p++; - if (fillch == ' ') - OUTCHAR(' '); - OUTCHAR(hexchars[(c >> 4) & 0xf]); - OUTCHAR(hexchars[c & 0xf]); - } - continue; - default: - *buf++ = '%'; - if (c != '%') - --fmt; /* so %z outputs %z etc. */ - --buflen; - continue; - } - if (base != 0) { - str = num + sizeof(num); - *--str = 0; - while (str > num + neg) { - *--str = hexchars[val % base]; - val = val / base; - if (--prec <= 0 && val == 0) - break; - } - switch (neg) { - case 1: - *--str = '-'; - break; - case 2: - *--str = 'x'; - *--str = '0'; - break; - } - len = num + sizeof(num) - 1 - str; - } else { - len = strlen(str); - if (prec >= 0 && len > prec) - len = prec; - } - if (width > 0) { - if (width > buflen) - width = buflen; - if ((n = width - len) > 0) { - buflen -= n; - for (; n > 0; --n) - *buf++ = fillch; - } - } - if (len > buflen) - len = buflen; - memcpy(buf, str, len); - buf += len; - buflen -= len; - } - *buf = 0; - return buf - buf0; -} - -/* - * vslp_printer - used in processing a %P format - */ -static void -vslp_printer __V((void *arg, char *fmt, ...)) -{ - int n; - va_list pvar; - struct buffer_info *bi; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - void *arg; - char *fmt; - va_start(pvar); - arg = va_arg(pvar, void *); - fmt = va_arg(pvar, char *); -#endif - - bi = (struct buffer_info *) arg; - n = vslprintf(bi->ptr, bi->len, fmt, pvar); - va_end(pvar); - - bi->ptr += n; - bi->len -= n; -} - -#ifdef unused -/* - * log_packet - format a packet and log it. - */ - -void -log_packet(p, len, prefix, level) - u_char *p; - int len; - char *prefix; - int level; -{ - init_pr_log(prefix, level); - format_packet(p, len, pr_log, &level); - end_pr_log(); -} -#endif /* unused */ - -/* - * format_packet - make a readable representation of a packet, - * calling `printer(arg, format, ...)' to output it. - */ -static void -format_packet(p, len, printer, arg) - u_char *p; - int len; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int i, n; - u_short proto; - struct protent *protp; - - if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { - p += 2; - GETSHORT(proto, p); - len -= PPP_HDRLEN; - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (proto == protp->protocol) - break; - if (protp != NULL) { - printer(arg, "[%s", protp->name); - n = (*protp->printpkt)(p, len, printer, arg); - printer(arg, "]"); - p += n; - len -= n; - } else { - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (proto == (protp->protocol & ~0x8000)) - break; - if (protp != 0 && protp->data_name != 0) { - printer(arg, "[%s data]", protp->data_name); - if (len > 8) - printer(arg, "%.8B ...", p); - else - printer(arg, "%.*B", len, p); - len = 0; - } else - printer(arg, "[proto=0x%x]", proto); - } - } - - if (len > 32) - printer(arg, "%.32B ...", p); - else - printer(arg, "%.*B", len, p); -} - -/* - * init_pr_log, end_pr_log - initialize and finish use of pr_log. - */ - -static char line[256]; /* line to be logged accumulated here */ -static char *linep; /* current pointer within line */ -static int llevel; /* level for logging */ - -void -init_pr_log(prefix, level) - char *prefix; - int level; -{ - linep = line; - if (prefix != NULL) { - strlcpy(line, prefix, sizeof(line)); - linep = line + strlen(line); - } - llevel = level; -} - -void -end_pr_log() -{ - if (linep != line) { - *linep = 0; - log_write(llevel, line); - } -} - -/* - * pr_log - printer routine for outputting to syslog - */ -void -pr_log __V((void *arg, char *fmt, ...)) -{ - int l, n; - va_list pvar; - char *p, *eol; - char buf[256]; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - void *arg; - char *fmt; - va_start(pvar); - arg = va_arg(pvar, void *); - fmt = va_arg(pvar, char *); -#endif - - n = vslprintf(buf, sizeof(buf), fmt, pvar); - va_end(pvar); - - p = buf; - eol = strchr(buf, '\n'); - if (linep != line) { - l = (eol == NULL)? n: eol - buf; - if (linep + l < line + sizeof(line)) { - if (l > 0) { - memcpy(linep, buf, l); - linep += l; - } - if (eol == NULL) - return; - p = eol + 1; - eol = strchr(p, '\n'); - } - *linep = 0; - log_write(llevel, line); - linep = line; - } - - while (eol != NULL) { - *eol = 0; - log_write(llevel, p); - p = eol + 1; - eol = strchr(p, '\n'); - } - - /* assumes sizeof(buf) <= sizeof(line) */ - l = buf + n - p; - if (l > 0) { - memcpy(line, p, n); - linep = line + l; - } -} - -/* - * print_string - print a readable representation of a string using - * printer. - */ -void -print_string(p, len, printer, arg) - char *p; - int len; - void (*printer) __P((void *, char *, ...)); - void *arg; -{ - int c; - - printer(arg, "\""); - for (; len > 0; --len) { - c = *p++; - if (' ' <= c && c <= '~') { - if (c == '\\' || c == '"') - printer(arg, "\\"); - printer(arg, "%c", c); - } else { - switch (c) { - case '\n': - printer(arg, "\\n"); - break; - case '\r': - printer(arg, "\\r"); - break; - case '\t': - printer(arg, "\\t"); - break; - default: - printer(arg, "\\%.3o", c); - } - } - } - printer(arg, "\""); -} - -/* - * logit - does the hard work for fatal et al. - */ -static void -logit(level, fmt, args) - int level; - char *fmt; - va_list args; -{ - int n; - char buf[1024]; - - n = vslprintf(buf, sizeof(buf), fmt, args); - log_write(level, buf); -} - -static void -log_write(level, buf) - int level; - char *buf; -{ - syslog(level, "%s", buf); - if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { - int n = strlen(buf); - - if (n > 0 && buf[n-1] == '\n') - --n; - if (write(log_to_fd, buf, n) != n - || write(log_to_fd, "\n", 1) != 1) - log_to_fd = -1; - } -} - -/* - * fatal - log an error message and die horribly. - */ -void -fatal __V((char *fmt, ...)) -{ - va_list pvar; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif - - logit(LOG_ERR, fmt, pvar); - va_end(pvar); - - die(1); /* as promised */ -} - -/* - * error - log an error message. - */ -void -error __V((char *fmt, ...)) -{ - va_list pvar; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif - - logit(LOG_ERR, fmt, pvar); - va_end(pvar); -} - -/* - * warn - log a warning message. - */ -void -warn __V((char *fmt, ...)) -{ - va_list pvar; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif - - logit(LOG_WARNING, fmt, pvar); - va_end(pvar); -} - -/* - * notice - log a notice-level message. - */ -void -notice __V((char *fmt, ...)) -{ - va_list pvar; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif - - logit(LOG_NOTICE, fmt, pvar); - va_end(pvar); -} - -/* - * info - log an informational message. - */ -void -info __V((char *fmt, ...)) -{ - va_list pvar; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif - - logit(LOG_INFO, fmt, pvar); - va_end(pvar); -} - -/* - * dbglog - log a debug message. - */ -void -dbglog __V((char *fmt, ...)) -{ - va_list pvar; - -#if defined(__STDC__) - va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif - - logit(LOG_DEBUG, fmt, pvar); - va_end(pvar); -} - -/* Procedures for locking the serial device using a lock file. */ -#ifndef LOCK_DIR -#ifdef _linux_ -#define LOCK_DIR "/var/lock" -#else -#ifdef SVR4 -#define LOCK_DIR "/var/spool/locks" -#else -#define LOCK_DIR "/var/spool/lock" -#endif -#endif -#endif /* LOCK_DIR */ - -static char lock_file[MAXPATHLEN]; - -/* - * lock - create a lock file for the named device - */ -int -lock(dev) - char *dev; -{ -#ifdef LOCKLIB - int result; - - result = mklock (dev, (void *) 0); - if (result == 0) { - strlcpy(lock_file, sizeof(lock_file), dev); - return 0; - } - - if (result > 0) - notice("Device %s is locked by pid %d", dev, result); - else - error("Can't create lock file %s", lock_file); - return -1; - -#else /* LOCKLIB */ - - char lock_buffer[12]; - int fd, pid, n; - -#ifdef SVR4 - struct stat sbuf; - - if (stat(dev, &sbuf) < 0) { - error("Can't get device number for %s: %m", dev); - return -1; - } - if ((sbuf.st_mode & S_IFMT) != S_IFCHR) { - error("Can't lock %s: not a character device", dev); - return -1; - } - slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d", - LOCK_DIR, major(sbuf.st_dev), - major(sbuf.st_rdev), minor(sbuf.st_rdev)); -#else - char *p; - - if ((p = strrchr(dev, '/')) != NULL) - dev = p + 1; - slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev); -#endif - - while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { - if (errno != EEXIST) { - error("Can't create lock file %s: %m", lock_file); - break; - } - - /* Read the lock file to find out who has the device locked. */ - fd = open(lock_file, O_RDONLY, 0); - if (fd < 0) { - if (errno == ENOENT) /* This is just a timing problem. */ - continue; - error("Can't open existing lock file %s: %m", lock_file); - break; - } -#ifndef LOCK_BINARY - n = read(fd, lock_buffer, 11); -#else - n = read(fd, &pid, sizeof(pid)); -#endif /* LOCK_BINARY */ - close(fd); - fd = -1; - if (n <= 0) { - error("Can't read pid from lock file %s", lock_file); - break; - } - - /* See if the process still exists. */ -#ifndef LOCK_BINARY - lock_buffer[n] = 0; - pid = atoi(lock_buffer); -#endif /* LOCK_BINARY */ - if (pid == getpid()) - return 1; /* somebody else locked it for us */ - if (pid == 0 - || (kill(pid, 0) == -1 && errno == ESRCH)) { - if (unlink (lock_file) == 0) { - notice("Removed stale lock on %s (pid %d)", dev, pid); - continue; - } - warn("Couldn't remove stale lock on %s", dev); - } else - notice("Device %s is locked by pid %d", dev, pid); - break; - } - - if (fd < 0) { - lock_file[0] = 0; - return -1; - } - - pid = getpid(); -#ifndef LOCK_BINARY - slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); - write (fd, lock_buffer, 11); -#else - write(fd, &pid, sizeof (pid)); -#endif - close(fd); - return 0; - -#endif -} - -/* - * relock - called to update our lockfile when we are about to detach, - * thus changing our pid (we fork, the child carries on, and the parent dies). - * Note that this is called by the parent, with pid equal to the pid - * of the child. This avoids a potential race which would exist if - * we had the child rewrite the lockfile (the parent might die first, - * and another process could think the lock was stale if it checked - * between when the parent died and the child rewrote the lockfile). - */ -int -relock(pid) - int pid; -{ -#ifdef LOCKLIB - /* XXX is there a way to do this? */ - return -1; -#else /* LOCKLIB */ - - int fd; - char lock_buffer[12]; - - if (lock_file[0] == 0) - return -1; - fd = open(lock_file, O_WRONLY, 0); - if (fd < 0) { - error("Couldn't reopen lock file %s: %m", lock_file); - lock_file[0] = 0; - return -1; - } - -#ifndef LOCK_BINARY - slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); - write (fd, lock_buffer, 11); -#else - write(fd, &pid, sizeof(pid)); -#endif /* LOCK_BINARY */ - close(fd); - return 0; - -#endif /* LOCKLIB */ -} - -/* - * unlock - remove our lockfile - */ -void -unlock() -{ - if (lock_file[0]) { -#ifdef LOCKLIB - (void) rmlock(lock_file, (void *) 0); -#else - unlink(lock_file); -#endif - lock_file[0] = 0; - } -} - diff --git a/mdk-stage1/ppp/pppdump/Makefile.linux b/mdk-stage1/ppp/pppdump/Makefile.linux deleted file mode 100644 index 1d8d78ff7..000000000 --- a/mdk-stage1/ppp/pppdump/Makefile.linux +++ /dev/null @@ -1,17 +0,0 @@ -CFLAGS= -I../include/net $(RPM_OPT_FLAGS) -OBJS = pppdump.o bsd-comp.o deflate.o zlib.o - -INSTALL= install - -all: pppdump - -pppdump: $(OBJS) - $(CC) $(RPM_OPT_FLAGS) -o pppdump $(OBJS) - -clean: - rm -f pppdump $(OBJS) *~ - -install: - mkdir -p $(BINDIR) $(MANDIR)/man8 - $(INSTALL) -s -c pppdump $(BINDIR) - $(INSTALL) -c pppdump.8 $(MANDIR)/man8 diff --git a/mdk-stage1/ppp/pppdump/Makefile.linux.makeopt b/mdk-stage1/ppp/pppdump/Makefile.linux.makeopt deleted file mode 100644 index d02fecde8..000000000 --- a/mdk-stage1/ppp/pppdump/Makefile.linux.makeopt +++ /dev/null @@ -1,17 +0,0 @@ -CFLAGS= -O -I../include/net -OBJS = pppdump.o bsd-comp.o deflate.o zlib.o - -INSTALL= install - -all: pppdump - -pppdump: $(OBJS) - $(CC) -o pppdump $(OBJS) - -clean: - rm -f pppdump $(OBJS) *~ - -install: - mkdir -p $(BINDIR) $(MANDIR)/man8 - $(INSTALL) -s -c pppdump $(BINDIR) - $(INSTALL) -c -m 444 pppdump.8 $(MANDIR)/man8 diff --git a/mdk-stage1/ppp/pppdump/Makefile.linux.pppdump-Makefile b/mdk-stage1/ppp/pppdump/Makefile.linux.pppdump-Makefile deleted file mode 100644 index 4c98b6c6d..000000000 --- a/mdk-stage1/ppp/pppdump/Makefile.linux.pppdump-Makefile +++ /dev/null @@ -1,17 +0,0 @@ -CFLAGS= -O -I../include/net -OBJS = pppdump.o bsd-comp.o deflate.o zlib.o - -INSTALL= install - -all: pppdump - -pppdump: $(OBJS) - $(CC) $(RPM_OPT_FLAGS) -o pppdump $(OBJS) - -clean: - rm -f pppdump $(OBJS) *~ - -install: - mkdir -p $(BINDIR) $(MANDIR)/man8 - $(INSTALL) -s -c pppdump $(BINDIR) - $(INSTALL) -c -m 444 pppdump.8 $(MANDIR)/man8 diff --git a/mdk-stage1/ppp/pppdump/Makefile.sol2 b/mdk-stage1/ppp/pppdump/Makefile.sol2 deleted file mode 100644 index d7e6b413e..000000000 --- a/mdk-stage1/ppp/pppdump/Makefile.sol2 +++ /dev/null @@ -1,21 +0,0 @@ -# -# pppdump Makefile for SVR4 systems -# $Id$ -# - -include ../solaris/Makedefs - -CFLAGS= $(COPTS) -I../include/net -OBJS = pppdump.o bsd-comp.o deflate.o zlib.o - -all: pppdump - -pppdump: $(OBJS) - $(CC) -o pppdump $(OBJS) - -clean: - rm -f $(OBJS) pppdump *~ - -install: - $(INSTALL) -f $(BINDIR) pppdump - $(INSTALL) -m 444 -f $(MANDIR)/man8 pppdump.8 diff --git a/mdk-stage1/ppp/pppdump/Makefile.sunos4 b/mdk-stage1/ppp/pppdump/Makefile.sunos4 deleted file mode 100644 index 915c8267d..000000000 --- a/mdk-stage1/ppp/pppdump/Makefile.sunos4 +++ /dev/null @@ -1,21 +0,0 @@ -# -# pppstats makefile -# $Id$ -# - -include ../sunos4/Makedefs - -OBJS = pppdump.o bsd-comp.o deflate.o zlib.o -CFLAGS = $(COPTS) -I../include/net - -all: pppdump - -pppdump: $(OBJS) - $(CC) -o pppdump $(OBJS) - -clean: - rm -f pppdump $(OBJS) *~ - -install: pppdump - $(INSTALL) -c pppdump $(BINDIR)/pppdump - $(INSTALL) -c -m 444 pppdump.8 $(MANDIR)/man8/pppdump.8 diff --git a/mdk-stage1/ppp/pppdump/bsd-comp.c b/mdk-stage1/ppp/pppdump/bsd-comp.c deleted file mode 100644 index 1e14e98bb..000000000 --- a/mdk-stage1/ppp/pppdump/bsd-comp.c +++ /dev/null @@ -1,750 +0,0 @@ -/* Because this code is derived from the 4.3BSD compress source: - * - * - * Copyright (c) 1985, 1986 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * James A. Woods, derived from original work by Spencer Thomas - * and Joseph Orost. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * $Id$ - */ - -#include <sys/types.h> -#include <stddef.h> -#include <stdlib.h> -#include "ppp_defs.h" -#include "ppp-comp.h" - -#if DO_BSD_COMPRESS - -/* - * PPP "BSD compress" compression - * The differences between this compression and the classic BSD LZW - * source are obvious from the requirement that the classic code worked - * with files while this handles arbitrarily long streams that - * are broken into packets. They are: - * - * When the code size expands, a block of junk is not emitted by - * the compressor and not expected by the decompressor. - * - * New codes are not necessarily assigned every time an old - * code is output by the compressor. This is because a packet - * end forces a code to be emitted, but does not imply that a - * new sequence has been seen. - * - * The compression ratio is checked at the first end of a packet - * after the appropriate gap. Besides simplifying and speeding - * things up, this makes it more likely that the transmitter - * and receiver will agree when the dictionary is cleared when - * compression is not going well. - */ - -/* - * A dictionary for doing BSD compress. - */ -struct bsd_db { - int totlen; /* length of this structure */ - u_int hsize; /* size of the hash table */ - u_char hshift; /* used in hash function */ - u_char n_bits; /* current bits/code */ - u_char maxbits; - u_char debug; - u_char unit; - u_short seqno; /* sequence number of next packet */ - u_int hdrlen; /* header length to preallocate */ - u_int mru; - u_int maxmaxcode; /* largest valid code */ - u_int max_ent; /* largest code in use */ - u_int in_count; /* uncompressed bytes, aged */ - u_int bytes_out; /* compressed bytes, aged */ - u_int ratio; /* recent compression ratio */ - u_int checkpoint; /* when to next check the ratio */ - u_int clear_count; /* times dictionary cleared */ - u_int incomp_count; /* incompressible packets */ - u_int incomp_bytes; /* incompressible bytes */ - u_int uncomp_count; /* uncompressed packets */ - u_int uncomp_bytes; /* uncompressed bytes */ - u_int comp_count; /* compressed packets */ - u_int comp_bytes; /* compressed bytes */ - u_short *lens; /* array of lengths of codes */ - struct bsd_dict { - union { /* hash value */ - u_int32_t fcode; - struct { -#ifdef BSD_LITTLE_ENDIAN - u_short prefix; /* preceding code */ - u_char suffix; /* last character of new code */ - u_char pad; -#else - u_char pad; - u_char suffix; /* last character of new code */ - u_short prefix; /* preceding code */ -#endif - } hs; - } f; - u_short codem1; /* output of hash table -1 */ - u_short cptr; /* map code to hash table entry */ - } dict[1]; -}; - -#define BSD_OVHD 2 /* BSD compress overhead/packet */ -#define BSD_INIT_BITS BSD_MIN_BITS - -static void *bsd_decomp_alloc __P((u_char *options, int opt_len)); -static void bsd_free __P((void *state)); -static int bsd_decomp_init __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); -static void bsd_incomp __P((void *state, u_char *dmsg, int len)); -static int bsd_decompress __P((void *state, u_char *cmp, int inlen, - u_char *dmp, int *outlen)); -static void bsd_reset __P((void *state)); -static void bsd_comp_stats __P((void *state, struct compstat *stats)); - -/* - * Exported procedures. - */ -struct compressor ppp_bsd_compress = { - CI_BSD_COMPRESS, /* compress_proto */ - bsd_decomp_alloc, /* decomp_alloc */ - bsd_free, /* decomp_free */ - bsd_decomp_init, /* decomp_init */ - bsd_reset, /* decomp_reset */ - bsd_decompress, /* decompress */ - bsd_incomp, /* incomp */ - bsd_comp_stats, /* decomp_stat */ -}; - -/* - * the next two codes should not be changed lightly, as they must not - * lie within the contiguous general code space. - */ -#define CLEAR 256 /* table clear output code */ -#define FIRST 257 /* first free entry */ -#define LAST 255 - -#define MAXCODE(b) ((1 << (b)) - 1) -#define BADCODEM1 MAXCODE(BSD_MAX_BITS) - -#define BSD_HASH(prefix,suffix,hshift) ((((u_int32_t)(suffix)) << (hshift)) \ - ^ (u_int32_t)(prefix)) -#define BSD_KEY(prefix,suffix) ((((u_int32_t)(suffix)) << 16) \ - + (u_int32_t)(prefix)) - -#define CHECK_GAP 10000 /* Ratio check interval */ - -#define RATIO_SCALE_LOG 8 -#define RATIO_SCALE (1<<RATIO_SCALE_LOG) -#define RATIO_MAX (0x7fffffff>>RATIO_SCALE_LOG) - -/* - * clear the dictionary - */ -static void -bsd_clear(db) - struct bsd_db *db; -{ - db->clear_count++; - db->max_ent = FIRST-1; - db->n_bits = BSD_INIT_BITS; - db->ratio = 0; - db->bytes_out = 0; - db->in_count = 0; - db->checkpoint = CHECK_GAP; -} - -/* - * If the dictionary is full, then see if it is time to reset it. - * - * Compute the compression ratio using fixed-point arithmetic - * with 8 fractional bits. - * - * Since we have an infinite stream instead of a single file, - * watch only the local compression ratio. - * - * Since both peers must reset the dictionary at the same time even in - * the absence of CLEAR codes (while packets are incompressible), they - * must compute the same ratio. - */ -static int /* 1=output CLEAR */ -bsd_check(db) - struct bsd_db *db; -{ - u_int new_ratio; - - if (db->in_count >= db->checkpoint) { - /* age the ratio by limiting the size of the counts */ - if (db->in_count >= RATIO_MAX - || db->bytes_out >= RATIO_MAX) { - db->in_count -= db->in_count/4; - db->bytes_out -= db->bytes_out/4; - } - - db->checkpoint = db->in_count + CHECK_GAP; - - if (db->max_ent >= db->maxmaxcode) { - /* Reset the dictionary only if the ratio is worse, - * or if it looks as if it has been poisoned - * by incompressible data. - * - * This does not overflow, because - * db->in_count <= RATIO_MAX. - */ - new_ratio = db->in_count << RATIO_SCALE_LOG; - if (db->bytes_out != 0) - new_ratio /= db->bytes_out; - - if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE) { - bsd_clear(db); - return 1; - } - db->ratio = new_ratio; - } - } - return 0; -} - -/* - * Return statistics. - */ -static void -bsd_comp_stats(state, stats) - void *state; - struct compstat *stats; -{ - struct bsd_db *db = (struct bsd_db *) state; - u_int out; - - stats->unc_bytes = db->uncomp_bytes; - stats->unc_packets = db->uncomp_count; - stats->comp_bytes = db->comp_bytes; - stats->comp_packets = db->comp_count; - stats->inc_bytes = db->incomp_bytes; - stats->inc_packets = db->incomp_count; - stats->ratio = db->in_count; - out = db->bytes_out; - if (stats->ratio <= 0x7fffff) - stats->ratio <<= 8; - else - out >>= 8; - if (out != 0) - stats->ratio /= out; -} - -/* - * Reset state, as on a CCP ResetReq. - */ -static void -bsd_reset(state) - void *state; -{ - struct bsd_db *db = (struct bsd_db *) state; - - db->seqno = 0; - bsd_clear(db); - db->clear_count = 0; -} - -/* - * Allocate space for a (de) compressor. - */ -static void * -bsd_alloc(options, opt_len, decomp) - u_char *options; - int opt_len, decomp; -{ - int bits; - u_int newlen, hsize, hshift, maxmaxcode; - struct bsd_db *db; - - if (opt_len != 3 || options[0] != CI_BSD_COMPRESS || options[1] != 3 - || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION) - return NULL; - - bits = BSD_NBITS(options[2]); - switch (bits) { - case 9: /* needs 82152 for both directions */ - case 10: /* needs 84144 */ - case 11: /* needs 88240 */ - case 12: /* needs 96432 */ - hsize = 5003; - hshift = 4; - break; - case 13: /* needs 176784 */ - hsize = 9001; - hshift = 5; - break; - case 14: /* needs 353744 */ - hsize = 18013; - hshift = 6; - break; - case 15: /* needs 691440 */ - hsize = 35023; - hshift = 7; - break; - case 16: /* needs 1366160--far too much, */ - /* hsize = 69001; */ /* and 69001 is too big for cptr */ - /* hshift = 8; */ /* in struct bsd_db */ - /* break; */ - default: - return NULL; - } - - maxmaxcode = MAXCODE(bits); - newlen = sizeof(*db) + (hsize-1) * (sizeof(db->dict[0])); - db = (struct bsd_db *) malloc(newlen); - if (!db) - return NULL; - memset(db, 0, sizeof(*db) - sizeof(db->dict)); - - if (!decomp) { - db->lens = NULL; - } else { - db->lens = (u_short *) malloc((maxmaxcode+1) * sizeof(db->lens[0])); - if (!db->lens) { - free(db); - return NULL; - } - } - - db->totlen = newlen; - db->hsize = hsize; - db->hshift = hshift; - db->maxmaxcode = maxmaxcode; - db->maxbits = bits; - - return (void *) db; -} - -static void -bsd_free(state) - void *state; -{ - struct bsd_db *db = (struct bsd_db *) state; - - if (db->lens) - free(db->lens); - free(db); -} - -static void * -bsd_decomp_alloc(options, opt_len) - u_char *options; - int opt_len; -{ - return bsd_alloc(options, opt_len, 1); -} - -/* - * Initialize the database. - */ -static int -bsd_init(db, options, opt_len, unit, hdrlen, mru, debug, decomp) - struct bsd_db *db; - u_char *options; - int opt_len, unit, hdrlen, mru, debug, decomp; -{ - int i; - - if (opt_len < CILEN_BSD_COMPRESS - || options[0] != CI_BSD_COMPRESS || options[1] != CILEN_BSD_COMPRESS - || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION - || BSD_NBITS(options[2]) != db->maxbits - || decomp && db->lens == NULL) - return 0; - - if (decomp) { - i = LAST+1; - while (i != 0) - db->lens[--i] = 1; - } - i = db->hsize; - while (i != 0) { - db->dict[--i].codem1 = BADCODEM1; - db->dict[i].cptr = 0; - } - - db->unit = unit; - db->hdrlen = hdrlen; - db->mru = mru; - if (debug) - db->debug = 1; - - bsd_reset(db); - - return 1; -} - -static int -bsd_decomp_init(state, options, opt_len, unit, hdrlen, mru, debug) - void *state; - u_char *options; - int opt_len, unit, hdrlen, mru, debug; -{ - return bsd_init((struct bsd_db *) state, options, opt_len, - unit, hdrlen, mru, debug, 1); -} - - -/* - * Update the "BSD Compress" dictionary on the receiver for - * incompressible data by pretending to compress the incoming data. - */ -static void -bsd_incomp(state, dmsg, mlen) - void *state; - u_char *dmsg; - int mlen; -{ - struct bsd_db *db = (struct bsd_db *) state; - u_int hshift = db->hshift; - u_int max_ent = db->max_ent; - u_int n_bits = db->n_bits; - struct bsd_dict *dictp; - u_int32_t fcode; - u_char c; - long hval, disp; - int slen, ilen; - u_int bitno = 7; - u_char *rptr; - u_int ent; - - rptr = dmsg; - ent = rptr[0]; /* get the protocol */ - if (ent == 0) { - ++rptr; - --mlen; - ent = rptr[0]; - } - if ((ent & 1) == 0 || ent < 0x21 || ent > 0xf9) - return; - - db->seqno++; - ilen = 1; /* count the protocol as 1 byte */ - ++rptr; - slen = dmsg + mlen - rptr; - ilen += slen; - for (; slen > 0; --slen) { - c = *rptr++; - fcode = BSD_KEY(ent, c); - hval = BSD_HASH(ent, c, hshift); - dictp = &db->dict[hval]; - - /* validate and then check the entry */ - if (dictp->codem1 >= max_ent) - goto nomatch; - if (dictp->f.fcode == fcode) { - ent = dictp->codem1+1; - continue; /* found (prefix,suffix) */ - } - - /* continue probing until a match or invalid entry */ - disp = (hval == 0) ? 1 : hval; - do { - hval += disp; - if (hval >= db->hsize) - hval -= db->hsize; - dictp = &db->dict[hval]; - if (dictp->codem1 >= max_ent) - goto nomatch; - } while (dictp->f.fcode != fcode); - ent = dictp->codem1+1; - continue; /* finally found (prefix,suffix) */ - - nomatch: /* output (count) the prefix */ - bitno += n_bits; - - /* code -> hashtable */ - if (max_ent < db->maxmaxcode) { - struct bsd_dict *dictp2; - /* expand code size if needed */ - if (max_ent >= MAXCODE(n_bits)) - db->n_bits = ++n_bits; - - /* Invalidate previous hash table entry - * assigned this code, and then take it over. - */ - dictp2 = &db->dict[max_ent+1]; - if (db->dict[dictp2->cptr].codem1 == max_ent) - db->dict[dictp2->cptr].codem1 = BADCODEM1; - dictp2->cptr = hval; - dictp->codem1 = max_ent; - dictp->f.fcode = fcode; - - db->max_ent = ++max_ent; - db->lens[max_ent] = db->lens[ent]+1; - } - ent = c; - } - bitno += n_bits; /* output (count) the last code */ - db->bytes_out += bitno/8; - db->in_count += ilen; - (void)bsd_check(db); - - ++db->incomp_count; - db->incomp_bytes += ilen; - ++db->uncomp_count; - db->uncomp_bytes += ilen; - - /* Increase code size if we would have without the packet - * boundary and as the decompressor will. - */ - if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) - db->n_bits++; -} - - -/* - * Decompress "BSD Compress" - * - * Because of patent problems, we return DECOMP_ERROR for errors - * found by inspecting the input data and for system problems, but - * DECOMP_FATALERROR for any errors which could possibly be said to - * be being detected "after" decompression. For DECOMP_ERROR, - * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be - * infringing a patent of Motorola's if we do, so we take CCP down - * instead. - * - * Given that the frame has the correct sequence number and a good FCS, - * errors such as invalid codes in the input most likely indicate a - * bug, so we return DECOMP_FATALERROR for them in order to turn off - * compression, even though they are detected by inspecting the input. - */ -static int -bsd_decompress(state, cmsg, inlen, dmp, outlenp) - void *state; - u_char *cmsg, *dmp; - int inlen, *outlenp; -{ - struct bsd_db *db = (struct bsd_db *) state; - u_int max_ent = db->max_ent; - u_int32_t accm = 0; - u_int bitno = 32; /* 1st valid bit in accm */ - u_int n_bits = db->n_bits; - u_int tgtbitno = 32-n_bits; /* bitno when we have a code */ - struct bsd_dict *dictp; - int explen, i, seq, len; - u_int incode, oldcode, finchar; - u_char *p, *rptr, *wptr; - int ilen; - int dlen, space, codelen, extra; - - rptr = cmsg; - if (*rptr == 0) - ++rptr; - ++rptr; /* skip protocol (assumed 0xfd) */ - seq = (rptr[0] << 8) + rptr[1]; - rptr += BSD_OVHD; - ilen = len = cmsg + inlen - rptr; - - /* - * Check the sequence number and give up if it is not what we expect. - */ - if (seq != db->seqno++) { - if (db->debug) - printf("bsd_decomp%d: bad sequence # %d, expected %d\n", - db->unit, seq, db->seqno - 1); - return DECOMP_ERROR; - } - - wptr = dmp + db->hdrlen; - - oldcode = CLEAR; - explen = 0; - while (len > 0) { - /* - * Accumulate bytes until we have a complete code. - * Then get the next code, relying on the 32-bit, - * unsigned accm to mask the result. - */ - bitno -= 8; - accm |= *rptr++ << bitno; - --len; - if (tgtbitno < bitno) - continue; - incode = accm >> tgtbitno; - accm <<= n_bits; - bitno += n_bits; - - if (incode == CLEAR) { - /* - * The dictionary must only be cleared at - * the end of a packet. But there could be an - * empty message block at the end. - */ - if (len > 0) { - if (db->debug) - printf("bsd_decomp%d: bad CLEAR\n", db->unit); - return DECOMP_FATALERROR; - } - bsd_clear(db); - explen = ilen = 0; - break; - } - - if (incode > max_ent + 2 || incode > db->maxmaxcode - || incode > max_ent && oldcode == CLEAR) { - if (db->debug) { - printf("bsd_decomp%d: bad code 0x%x oldcode=0x%x ", - db->unit, incode, oldcode); - printf("max_ent=0x%x dlen=%d seqno=%d\n", - max_ent, dlen, db->seqno); - } - return DECOMP_FATALERROR; /* probably a bug */ - } - - /* Special case for KwKwK string. */ - if (incode > max_ent) { - finchar = oldcode; - extra = 1; - } else { - finchar = incode; - extra = 0; - } - - codelen = db->lens[finchar]; - explen += codelen + extra; - if (explen > db->mru + 1) { - if (db->debug) - printf("bsd_decomp%d: ran out of mru\n", db->unit); - return DECOMP_FATALERROR; - } - - /* - * Decode this code and install it in the decompressed buffer. - */ - p = (wptr += codelen); - while (finchar > LAST) { - dictp = &db->dict[db->dict[finchar].cptr]; -#ifdef DEBUG - --codelen; - if (codelen <= 0) { - printf("bsd_decomp%d: fell off end of chain ", db->unit); - printf("0x%x at 0x%x by 0x%x, max_ent=0x%x\n", - incode, finchar, db->dict[finchar].cptr, max_ent); - return DECOMP_FATALERROR; - } - if (dictp->codem1 != finchar-1) { - printf("bsd_decomp%d: bad code chain 0x%x finchar=0x%x ", - db->unit, incode, finchar); - printf("oldcode=0x%x cptr=0x%x codem1=0x%x\n", oldcode, - db->dict[finchar].cptr, dictp->codem1); - return DECOMP_FATALERROR; - } -#endif - *--p = dictp->f.hs.suffix; - finchar = dictp->f.hs.prefix; - } - *--p = finchar; - -#ifdef DEBUG - if (--codelen != 0) - printf("bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%x\n", - db->unit, codelen, incode, max_ent); -#endif - - if (extra) /* the KwKwK case again */ - *wptr++ = finchar; - - /* - * If not first code in a packet, and - * if not out of code space, then allocate a new code. - * - * Keep the hash table correct so it can be used - * with uncompressed packets. - */ - if (oldcode != CLEAR && max_ent < db->maxmaxcode) { - struct bsd_dict *dictp2; - u_int32_t fcode; - int hval, disp; - - fcode = BSD_KEY(oldcode,finchar); - hval = BSD_HASH(oldcode,finchar,db->hshift); - dictp = &db->dict[hval]; - - /* look for a free hash table entry */ - if (dictp->codem1 < max_ent) { - disp = (hval == 0) ? 1 : hval; - do { - hval += disp; - if (hval >= db->hsize) - hval -= db->hsize; - dictp = &db->dict[hval]; - } while (dictp->codem1 < max_ent); - } - - /* - * Invalidate previous hash table entry - * assigned this code, and then take it over - */ - dictp2 = &db->dict[max_ent+1]; - if (db->dict[dictp2->cptr].codem1 == max_ent) { - db->dict[dictp2->cptr].codem1 = BADCODEM1; - } - dictp2->cptr = hval; - dictp->codem1 = max_ent; - dictp->f.fcode = fcode; - - db->max_ent = ++max_ent; - db->lens[max_ent] = db->lens[oldcode]+1; - - /* Expand code size if needed. */ - if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) { - db->n_bits = ++n_bits; - tgtbitno = 32-n_bits; - } - } - oldcode = incode; - } - *outlenp = wptr - (dmp + db->hdrlen); - - /* - * Keep the checkpoint right so that incompressible packets - * clear the dictionary at the right times. - */ - db->bytes_out += ilen; - db->in_count += explen; - if (bsd_check(db) && db->debug) { - printf("bsd_decomp%d: peer should have cleared dictionary\n", - db->unit); - } - - ++db->comp_count; - db->comp_bytes += ilen + BSD_OVHD; - ++db->uncomp_count; - db->uncomp_bytes += explen; - - return DECOMP_OK; -} -#endif /* DO_BSD_COMPRESS */ diff --git a/mdk-stage1/ppp/pppdump/deflate.c b/mdk-stage1/ppp/pppdump/deflate.c deleted file mode 100644 index 08e8abc0d..000000000 --- a/mdk-stage1/ppp/pppdump/deflate.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * ppp_deflate.c - interface the zlib procedures for Deflate compression - * and decompression (as used by gzip) to the PPP code. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -#include <sys/types.h> -#include <stddef.h> -#include <stdlib.h> -#include "ppp_defs.h" -#include "ppp-comp.h" -#include "zlib.h" - -#if DO_DEFLATE - -#define DEFLATE_DEBUG 1 - -/* - * State for a Deflate (de)compressor. - */ -struct deflate_state { - int seqno; - int w_size; - int unit; - int hdrlen; - int mru; - int debug; - z_stream strm; - struct compstat stats; -}; - -#define DEFLATE_OVHD 2 /* Deflate overhead/packet */ - -static void *z_alloc __P((void *, u_int items, u_int size)); -static void z_free __P((void *, void *ptr, u_int nb)); -static void *z_decomp_alloc __P((u_char *options, int opt_len)); -static void z_decomp_free __P((void *state)); -static int z_decomp_init __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); -static void z_incomp __P((void *state, u_char *dmsg, int len)); -static int z_decompress __P((void *state, u_char *cmp, int inlen, - u_char *dmp, int *outlenp)); -static void z_decomp_reset __P((void *state)); -static void z_comp_stats __P((void *state, struct compstat *stats)); - -/* - * Procedures exported to if_ppp.c. - */ -struct compressor ppp_deflate = { - CI_DEFLATE, /* compress_proto */ - z_decomp_alloc, /* decomp_alloc */ - z_decomp_free, /* decomp_free */ - z_decomp_init, /* decomp_init */ - z_decomp_reset, /* decomp_reset */ - z_decompress, /* decompress */ - z_incomp, /* incomp */ - z_comp_stats, /* decomp_stat */ -}; - -/* - * Space allocation and freeing routines for use by zlib routines. - */ -static void * -z_alloc(notused, items, size) - void *notused; - u_int items, size; -{ - return malloc(items * size); -} - -static void -z_free(notused, ptr, nbytes) - void *notused; - void *ptr; - u_int nbytes; -{ - free(ptr); -} - -static void -z_comp_stats(arg, stats) - void *arg; - struct compstat *stats; -{ - struct deflate_state *state = (struct deflate_state *) arg; - u_int out; - - *stats = state->stats; - stats->ratio = stats->unc_bytes; - out = stats->comp_bytes + stats->unc_bytes; - if (stats->ratio <= 0x7ffffff) - stats->ratio <<= 8; - else - out >>= 8; - if (out != 0) - stats->ratio /= out; -} - -/* - * Allocate space for a decompressor. - */ -static void * -z_decomp_alloc(options, opt_len) - u_char *options; - int opt_len; -{ - struct deflate_state *state; - int w_size; - - if (opt_len != CILEN_DEFLATE || options[0] != CI_DEFLATE - || options[1] != CILEN_DEFLATE - || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL - || options[3] != DEFLATE_CHK_SEQUENCE) - return NULL; - w_size = DEFLATE_SIZE(options[2]); - if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) - return NULL; - - state = (struct deflate_state *) malloc(sizeof(*state)); - if (state == NULL) - return NULL; - - state->strm.next_out = NULL; - state->strm.zalloc = (alloc_func) z_alloc; - state->strm.zfree = (free_func) z_free; - if (inflateInit2(&state->strm, -w_size) != Z_OK) { - free(state); - return NULL; - } - - state->w_size = w_size; - memset(&state->stats, 0, sizeof(state->stats)); - return (void *) state; -} - -static void -z_decomp_free(arg) - void *arg; -{ - struct deflate_state *state = (struct deflate_state *) arg; - - inflateEnd(&state->strm); - free(state); -} - -static int -z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug) - void *arg; - u_char *options; - int opt_len, unit, hdrlen, mru, debug; -{ - struct deflate_state *state = (struct deflate_state *) arg; - - if (opt_len < CILEN_DEFLATE || options[0] != CI_DEFLATE - || options[1] != CILEN_DEFLATE - || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL - || DEFLATE_SIZE(options[2]) != state->w_size - || options[3] != DEFLATE_CHK_SEQUENCE) - return 0; - - state->seqno = 0; - state->unit = unit; - state->hdrlen = hdrlen; - state->debug = debug; - state->mru = mru; - - inflateReset(&state->strm); - - return 1; -} - -static void -z_decomp_reset(arg) - void *arg; -{ - struct deflate_state *state = (struct deflate_state *) arg; - - state->seqno = 0; - inflateReset(&state->strm); -} - -/* - * Decompress a Deflate-compressed packet. - * - * Because of patent problems, we return DECOMP_ERROR for errors - * found by inspecting the input data and for system problems, but - * DECOMP_FATALERROR for any errors which could possibly be said to - * be being detected "after" decompression. For DECOMP_ERROR, - * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be - * infringing a patent of Motorola's if we do, so we take CCP down - * instead. - * - * Given that the frame has the correct sequence number and a good FCS, - * errors such as invalid codes in the input most likely indicate a - * bug, so we return DECOMP_FATALERROR for them in order to turn off - * compression, even though they are detected by inspecting the input. - */ -static int -z_decompress(arg, mi, inlen, mo, outlenp) - void *arg; - u_char *mi, *mo; - int inlen, *outlenp; -{ - struct deflate_state *state = (struct deflate_state *) arg; - u_char *rptr, *wptr; - int rlen, olen, ospace; - int seq, i, flush, r, decode_proto; - - rptr = mi; - if (*rptr == 0) - ++rptr; - ++rptr; - - /* Check the sequence number. */ - seq = (rptr[0] << 8) + rptr[1]; - rptr += 2; - if (seq != state->seqno) { -#if !DEFLATE_DEBUG - if (state->debug) -#endif - printf("z_decompress%d: bad seq # %d, expected %d\n", - state->unit, seq, state->seqno); - return DECOMP_ERROR; - } - ++state->seqno; - - /* - * Set up to call inflate. - */ - wptr = mo; - state->strm.next_in = rptr; - state->strm.avail_in = mi + inlen - rptr; - rlen = state->strm.avail_in + PPP_HDRLEN + DEFLATE_OVHD; - state->strm.next_out = wptr; - state->strm.avail_out = state->mru + 2; - - r = inflate(&state->strm, Z_PACKET_FLUSH); - if (r != Z_OK) { -#if !DEFLATE_DEBUG - if (state->debug) -#endif - printf("z_decompress%d: inflate returned %d (%s)\n", - state->unit, r, (state->strm.msg? state->strm.msg: "")); - return DECOMP_FATALERROR; - } - olen = state->mru + 2 - state->strm.avail_out; - *outlenp = olen; - - if ((wptr[0] & 1) != 0) - ++olen; /* for suppressed protocol high byte */ - olen += 2; /* for address, control */ - -#if DEFLATE_DEBUG - if (olen > state->mru + PPP_HDRLEN) - printf("ppp_deflate%d: exceeded mru (%d > %d)\n", - state->unit, olen, state->mru + PPP_HDRLEN); -#endif - - state->stats.unc_bytes += olen; - state->stats.unc_packets++; - state->stats.comp_bytes += rlen; - state->stats.comp_packets++; - - return DECOMP_OK; -} - -/* - * Incompressible data has arrived - add it to the history. - */ -static void -z_incomp(arg, mi, mlen) - void *arg; - u_char *mi; - int mlen; -{ - struct deflate_state *state = (struct deflate_state *) arg; - u_char *rptr; - int rlen, proto, r; - - /* - * Check that the protocol is one we handle. - */ - rptr = mi; - proto = rptr[0]; - if ((proto & 1) == 0) - proto = (proto << 8) + rptr[1]; - if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) - return; - - ++state->seqno; - - if (rptr[0] == 0) - ++rptr; - rlen = mi + mlen - rptr; - state->strm.next_in = rptr; - state->strm.avail_in = rlen; - r = inflateIncomp(&state->strm); - if (r != Z_OK) { - /* gak! */ -#if !DEFLATE_DEBUG - if (state->debug) -#endif - printf("z_incomp%d: inflateIncomp returned %d (%s)\n", - state->unit, r, (state->strm.msg? state->strm.msg: "")); - return; - } - - /* - * Update stats. - */ - if (proto <= 0xff) - ++rlen; - rlen += 2; - state->stats.inc_bytes += rlen; - state->stats.inc_packets++; - state->stats.unc_bytes += rlen; - state->stats.unc_packets++; -} - -#endif /* DO_DEFLATE */ diff --git a/mdk-stage1/ppp/pppdump/ppp-comp.h b/mdk-stage1/ppp/pppdump/ppp-comp.h deleted file mode 100644 index 9221c0db4..000000000 --- a/mdk-stage1/ppp/pppdump/ppp-comp.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * ppp-comp.h - Definitions for doing PPP packet compression. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -#ifndef _NET_PPP_COMP_H -#define _NET_PPP_COMP_H - -/* - * The following symbols control whether we include code for - * various compression methods. - */ -#ifndef DO_BSD_COMPRESS -#define DO_BSD_COMPRESS 1 /* by default, include BSD-Compress */ -#endif -#ifndef DO_DEFLATE -#define DO_DEFLATE 1 /* by default, include Deflate */ -#endif -#define DO_PREDICTOR_1 0 -#define DO_PREDICTOR_2 0 - -/* - * Structure giving methods for compression/decompression. - */ -struct compressor { - int compress_proto; /* CCP compression protocol number */ - - /* Allocate space for a decompressor (receive side) */ - void *(*decomp_alloc) __P((u_char *options, int opt_len)); - /* Free space used by a decompressor */ - void (*decomp_free) __P((void *state)); - /* Initialize a decompressor */ - int (*decomp_init) __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); - /* Reset a decompressor */ - void (*decomp_reset) __P((void *state)); - /* Decompress a packet. */ - int (*decompress) __P((void *state, u_char *mp, int inlen, - u_char *dmp, int *outlen)); - /* Update state for an incompressible packet received */ - void (*incomp) __P((void *state, u_char *mp, int len)); - /* Return decompression statistics */ - void (*decomp_stat) __P((void *state, struct compstat *stats)); -}; - -/* - * Return values for decompress routine. - * We need to make these distinctions so that we can disable certain - * useful functionality, namely sending a CCP reset-request as a result - * of an error detected after decompression. This is to avoid infringing - * a patent held by Motorola. - * Don't you just lurve software patents. - */ -#define DECOMP_OK 0 /* everything went OK */ -#define DECOMP_ERROR 1 /* error detected before decomp. */ -#define DECOMP_FATALERROR 2 /* error detected after decomp. */ - -/* - * CCP codes. - */ -#define CCP_CONFREQ 1 -#define CCP_CONFACK 2 -#define CCP_CONFNAK 3 -#define CCP_CONFREJ 4 -#define CCP_TERMREQ 5 -#define CCP_TERMACK 6 -#define CCP_RESETREQ 14 -#define CCP_RESETACK 15 - -/* - * Max # bytes for a CCP option - */ -#define CCP_MAX_OPTION_LENGTH 32 - -/* - * Parts of a CCP packet. - */ -#define CCP_CODE(dp) ((dp)[0]) -#define CCP_ID(dp) ((dp)[1]) -#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) -#define CCP_HDRLEN 4 - -#define CCP_OPT_CODE(dp) ((dp)[0]) -#define CCP_OPT_LENGTH(dp) ((dp)[1]) -#define CCP_OPT_MINLEN 2 - -/* - * Definitions for BSD-Compress. - */ -#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ -#define CILEN_BSD_COMPRESS 3 /* length of config. option */ - -/* Macros for handling the 3rd byte of the BSD-Compress config option. */ -#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ -#define BSD_VERSION(x) ((x) >> 5) /* version of option format */ -#define BSD_CURRENT_VERSION 1 /* current version number */ -#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) - -#define BSD_MIN_BITS 9 /* smallest code size supported */ -#define BSD_MAX_BITS 15 /* largest code size supported */ - -/* - * Definitions for Deflate. - */ -#define CI_DEFLATE 26 /* config option for Deflate */ -#define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */ -#define CILEN_DEFLATE 4 /* length of its config option */ - -#define DEFLATE_MIN_SIZE 8 -#define DEFLATE_MAX_SIZE 15 -#define DEFLATE_METHOD_VAL 8 -#define DEFLATE_SIZE(x) (((x) >> 4) + DEFLATE_MIN_SIZE) -#define DEFLATE_METHOD(x) ((x) & 0x0F) -#define DEFLATE_MAKE_OPT(w) ((((w) - DEFLATE_MIN_SIZE) << 4) \ - + DEFLATE_METHOD_VAL) -#define DEFLATE_CHK_SEQUENCE 0 - -/* - * Definitions for other, as yet unsupported, compression methods. - */ -#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ -#define CILEN_PREDICTOR_1 2 /* length of its config option */ -#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ -#define CILEN_PREDICTOR_2 2 /* length of its config option */ - -#endif /* _NET_PPP_COMP_H */ diff --git a/mdk-stage1/ppp/pppdump/pppdump.8 b/mdk-stage1/ppp/pppdump/pppdump.8 deleted file mode 100644 index c0172f519..000000000 --- a/mdk-stage1/ppp/pppdump/pppdump.8 +++ /dev/null @@ -1,62 +0,0 @@ -.\" @(#) $Id$ -.TH PPPDUMP 8 "1 April 1999" -.SH NAME -pppdump \- convert PPP record file to readable format -.SH SYNOPSIS -.B pppdump -[ -.B -h -| -.B -p -[ -.B -d -]] [ -.B -r -] [ -.B -m \fImru -] [ -.I file \fR... -] -.ti 12 -.SH DESCRIPTION -The -.B pppdump -utility converts the files written using the \fIrecord\fR option of -.B pppd -into a human-readable format. If one or more filenames are specified, -.B pppdump -will read each in turn; otherwise it will read its standard input. In -each case the result is written to standard output. -.PP -The options are as follows: -.TP -.B -h -Prints the bytes sent and received in hexadecimal. If neither this -option nor the \fB-p\fR option is specified, the bytes are printed as -the characters themselves, with non-printing and non-ASCII characters -printed as escape sequences. -.TP -.B -p -Collects the bytes sent and received into PPP packets, interpreting -the async HDLC framing and escape characters and checking the FCS -(frame check sequence) of each packet. The packets are printed as hex -values and as characters (non-printable characters are printed as -`.'). -.TP -.B -d -With the \fB-p\fR option, this option causes -.B pppdump -to decompress packets which have been compressed with the BSD-Compress -or Deflate methods. -.TP -.B -r -Reverses the direction indicators, so that `sent' is printed for -bytes or packets received, and `rcvd' is printed for bytes or packets -sent. -.TP -.B -m \fImru -Use \fImru\fR as the MRU (maximum receive unit) for both directions of -the link when checking for over-length PPP packets (with the \fB-p\fR -option). -.SH SEE ALSO -pppd(8) diff --git a/mdk-stage1/ppp/pppdump/pppdump.c b/mdk-stage1/ppp/pppdump/pppdump.c deleted file mode 100644 index a8e69d4bf..000000000 --- a/mdk-stage1/ppp/pppdump/pppdump.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * pppdump - print out the contents of a record file generated by - * pppd in readable form. - * - * Copyright (C) 1999 Paul Mackerras. 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. The name of the author - * 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. - */ -#include <stdio.h> -#include <unistd.h> -#include <time.h> -#include <sys/types.h> -#include "ppp_defs.h" -#include "ppp-comp.h" - -int hexmode; -int pppmode; -int reverse; -int decompress; -int mru = 1500; -int abs_times; -time_t start_time; -int start_time_tenths; -int tot_sent, tot_rcvd; - -extern int optind; -extern char *optarg; - -main(ac, av) - int ac; - char **av; -{ - int i; - char *p; - FILE *f; - - while ((i = getopt(ac, av, "hprdm:a")) != -1) { - switch (i) { - case 'h': - hexmode = 1; - break; - case 'p': - pppmode = 1; - break; - case 'r': - reverse = 1; - break; - case 'd': - decompress = 1; - break; - case 'm': - mru = atoi(optarg); - break; - case 'a': - abs_times = 1; - break; - default: - fprintf(stderr, "Usage: %s [-h | -p[d]] [-r] [-m mru] [-a] [file ...]\n", av[0]); - exit(1); - } - } - if (optind >= ac) - dumplog(stdin); - else { - for (i = optind; i < ac; ++i) { - p = av[i]; - if ((f = fopen(p, "r")) == NULL) { - perror(p); - exit(1); - } - if (pppmode) - dumpppp(f); - else - dumplog(f); - fclose(f); - } - } - exit(0); -} - -dumplog(f) - FILE *f; -{ - int c, n, k, col; - int nb, c2; - unsigned char buf[16]; - - while ((c = getc(f)) != EOF) { - switch (c) { - case 1: - case 2: - if (reverse) - c = 3 - c; - printf("%s %c", c==1? "sent": "rcvd", hexmode? ' ': '"'); - col = 6; - n = getc(f); - n = (n << 8) + getc(f); - *(c==1? &tot_sent: &tot_rcvd) += n; - nb = 0; - for (; n > 0; --n) { - c = getc(f); - if (c == EOF) { - printf("\nEOF\n"); - exit(0); - } - if (hexmode) { - if (nb >= 16) { - printf(" "); - for (k = 0; k < nb; ++k) { - c2 = buf[k]; - putchar((' ' <= c2 && c2 <= '~')? c2: '.'); - } - printf("\n "); - nb = 0; - } - buf[nb++] = c; - printf(" %.2x", c); - } else { - k = (' ' <= c && c <= '~')? (c != '\\' && c != '"')? 1: 2: 3; - if ((col += k) >= 78) { - printf("\n "); - col = 6 + k; - } - switch (k) { - case 1: - putchar(c); - break; - case 2: - printf("\\%c", c); - break; - case 3: - printf("\\%.2x", c); - break; - } - } - } - if (hexmode) { - for (k = nb; k < 16; ++k) - printf(" "); - printf(" "); - for (k = 0; k < nb; ++k) { - c2 = buf[k]; - putchar((' ' <= c2 && c2 <= '~')? c2: '.'); - } - } else - putchar('"'); - printf("\n"); - break; - case 3: - case 4: - printf("end %s\n", c==3? "send": "recv"); - break; - case 5: - case 6: - case 7: - show_time(f, c); - break; - default: - printf("?%.2x\n"); - } - } -} - -/* - * FCS lookup table as calculated by genfcstab. - */ -static u_short fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -struct pkt { - int cnt; - int esc; - int flags; - struct compressor *comp; - void *state; - unsigned char buf[8192]; -} spkt, rpkt; - -/* Values for flags */ -#define CCP_ISUP 1 -#define CCP_ERROR 2 -#define CCP_FATALERROR 4 -#define CCP_ERR (CCP_ERROR | CCP_FATALERROR) -#define CCP_DECOMP_RUN 8 - -unsigned char dbuf[8192]; - -dumpppp(f) - FILE *f; -{ - int c, n, k; - int nb, nl, dn, proto, rv; - char *dir, *q; - unsigned char *p, *r, *endp; - unsigned char *d; - unsigned short fcs; - struct pkt *pkt; - - spkt.cnt = rpkt.cnt = 0; - spkt.esc = rpkt.esc = 0; - while ((c = getc(f)) != EOF) { - switch (c) { - case 1: - case 2: - if (reverse) - c = 3 - c; - dir = c==1? "sent": "rcvd"; - pkt = c==1? &spkt: &rpkt; - n = getc(f); - n = (n << 8) + getc(f); - *(c==1? &tot_sent: &tot_rcvd) += n; - for (; n > 0; --n) { - c = getc(f); - switch (c) { - case EOF: - printf("\nEOF\n"); - if (spkt.cnt > 0) - printf("[%d bytes in incomplete send packet]\n", - spkt.cnt); - if (rpkt.cnt > 0) - printf("[%d bytes in incomplete recv packet]\n", - rpkt.cnt); - exit(0); - case '~': - if (pkt->cnt > 0) { - q = dir; - if (pkt->esc) { - printf("%s aborted packet:\n ", dir); - q = " "; - } - nb = pkt->cnt; - p = pkt->buf; - pkt->cnt = 0; - pkt->esc = 0; - if (nb <= 2) { - printf("%s short packet [%d bytes]:", q, nb); - for (k = 0; k < nb; ++k) - printf(" %.2x", p[k]); - printf("\n"); - break; - } - fcs = PPP_INITFCS; - for (k = 0; k < nb; ++k) - fcs = PPP_FCS(fcs, p[k]); - fcs &= 0xFFFF; - nb -= 2; - endp = p + nb; - r = p; - if (r[0] == 0xff && r[1] == 3) - r += 2; - if ((r[0] & 1) == 0) - ++r; - ++r; - if (endp - r > mru) - printf(" ERROR: length (%d) > MRU (%d)\n", - endp - r, mru); - if (decompress && fcs == PPP_GOODFCS) { - /* See if this is a CCP or compressed packet */ - d = dbuf; - r = p; - if (r[0] == 0xff && r[1] == 3) { - *d++ = *r++; - *d++ = *r++; - } - proto = r[0]; - if ((proto & 1) == 0) - proto = (proto << 8) + r[1]; - if (proto == PPP_CCP) { - handle_ccp(pkt, r + 2, endp - r - 2); - } else if (proto == PPP_COMP) { - if ((pkt->flags & CCP_ISUP) - && (pkt->flags & CCP_DECOMP_RUN) - && pkt->state - && (pkt->flags & CCP_ERR) == 0) { - rv = pkt->comp->decompress(pkt->state, r, - endp - r, d, &dn); - switch (rv) { - case DECOMP_OK: - p = dbuf; - nb = d + dn - p; - if ((d[0] & 1) == 0) - --dn; - --dn; - if (dn > mru) - printf(" ERROR: decompressed length (%d) > MRU (%d)\n", dn, mru); - break; - case DECOMP_ERROR: - printf(" DECOMPRESSION ERROR\n"); - pkt->flags |= CCP_ERROR; - break; - case DECOMP_FATALERROR: - printf(" FATAL DECOMPRESSION ERROR\n"); - pkt->flags |= CCP_FATALERROR; - break; - } - } - } else if (pkt->state - && (pkt->flags & CCP_DECOMP_RUN)) { - pkt->comp->incomp(pkt->state, r, endp - r); - } - } - do { - nl = nb < 16? nb: 16; - printf("%s ", q); - for (k = 0; k < nl; ++k) - printf(" %.2x", p[k]); - for (; k < 16; ++k) - printf(" "); - printf(" "); - for (k = 0; k < nl; ++k) { - c = p[k]; - putchar((' ' <= c && c <= '~')? c: '.'); - } - printf("\n"); - q = " "; - p += nl; - nb -= nl; - } while (nb > 0); - if (fcs != PPP_GOODFCS) - printf(" BAD FCS: (residue = %x)\n", fcs); - } - break; - case '}': - if (!pkt->esc) { - pkt->esc = 1; - break; - } - /* else fall through */ - default: - if (pkt->esc) { - c ^= 0x20; - pkt->esc = 0; - } - pkt->buf[pkt->cnt++] = c; - break; - } - } - break; - case 3: - case 4: - if (reverse) - c = 7 - c; - dir = c==3? "send": "recv"; - pkt = c==3? &spkt: &rpkt; - printf("end %s", dir); - if (pkt->cnt > 0) - printf(" [%d bytes in incomplete packet]", pkt->cnt); - printf("\n"); - break; - case 5: - case 6: - case 7: - show_time(f, c); - break; - default: - printf("?%.2x\n"); - } - } -} - -extern struct compressor ppp_bsd_compress, ppp_deflate; - -struct compressor *compressors[] = { -#if DO_BSD_COMPRESS - &ppp_bsd_compress, -#endif -#if DO_DEFLATE - &ppp_deflate, -#endif - NULL -}; - -handle_ccp(cp, dp, len) - struct pkt *cp; - u_char *dp; - int len; -{ - int clen; - struct compressor **comp; - - if (len < CCP_HDRLEN) - return; - clen = CCP_LENGTH(dp); - if (clen > len) - return; - - switch (CCP_CODE(dp)) { - case CCP_CONFACK: - cp->flags &= ~(CCP_DECOMP_RUN | CCP_ISUP); - if (clen < CCP_HDRLEN + CCP_OPT_MINLEN - || clen < CCP_HDRLEN + CCP_OPT_LENGTH(dp + CCP_HDRLEN)) - break; - dp += CCP_HDRLEN; - clen -= CCP_HDRLEN; - for (comp = compressors; *comp != NULL; ++comp) { - if ((*comp)->compress_proto == dp[0]) { - if (cp->state != NULL) { - (*cp->comp->decomp_free)(cp->state); - cp->state = NULL; - } - cp->comp = *comp; - cp->state = (*comp)->decomp_alloc(dp, CCP_OPT_LENGTH(dp)); - cp->flags |= CCP_ISUP; - if (cp->state != NULL - && (*cp->comp->decomp_init) - (cp->state, dp, clen, 0, 0, 8192, 1)) - cp->flags = (cp->flags & ~CCP_ERR) | CCP_DECOMP_RUN; - break; - } - } - break; - - case CCP_CONFNAK: - case CCP_CONFREJ: - cp->flags &= ~(CCP_DECOMP_RUN | CCP_ISUP); - break; - - case CCP_RESETACK: - if (cp->flags & CCP_ISUP) { - if (cp->state && (cp->flags & CCP_DECOMP_RUN)) { - (*cp->comp->decomp_reset)(cp->state); - cp->flags &= ~CCP_ERROR; - } - } - break; - } -} - -show_time(f, c) - FILE *f; - int c; -{ - time_t t; - int n; - struct tm *tm; - - if (c == 7) { - t = getc(f); - t = (t << 8) + getc(f); - t = (t << 8) + getc(f); - t = (t << 8) + getc(f); - printf("start %s", ctime(&t)); - start_time = t; - start_time_tenths = 0; - tot_sent = tot_rcvd = 0; - } else { - n = getc(f); - if (c == 5) { - for (c = 3; c > 0; --c) - n = (n << 8) + getc(f); - } - if (abs_times) { - n += start_time_tenths; - start_time += n / 10; - start_time_tenths = n % 10; - tm = localtime(&start_time); - printf("time %.2d:%.2d:%.2d.%d", tm->tm_hour, tm->tm_min, - tm->tm_sec, start_time_tenths); - printf(" (sent %d, rcvd %d)\n", tot_sent, tot_rcvd); - } else - printf("time %.1fs\n", (double) n / 10); - } -} diff --git a/mdk-stage1/ppp/pppdump/zlib.c b/mdk-stage1/ppp/pppdump/zlib.c deleted file mode 100644 index 5b8372719..000000000 --- a/mdk-stage1/ppp/pppdump/zlib.c +++ /dev/null @@ -1,4614 +0,0 @@ -/* - * This file is derived from various .h and .c files from the zlib-0.95 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. See zlib.h for conditions of - * distribution and use. - * - * Changes that have been made include: - * - changed functions not used outside this file to "local" - * - added minCompression parameter to deflateInit2 - * - added Z_PACKET_FLUSH (see zlib.h for details) - * - added inflateIncomp - * - * $Id$ - */ - - -/*+++++*/ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */ - -#define _Z_UTIL_H - -#include "zlib.h" - -#ifdef STDC -# include <string.h> -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -#define FAR - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern char *z_errmsg[]; /* indexed by 1-zlib_error */ - -#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) -/* To be used only when the state is known to be valid */ - -#ifndef NULL -#define NULL ((void *) 0) -#endif - - /* common constants */ - -#define DEFLATED 8 - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - - /* functions */ - -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# define zmemcpy memcpy -# define zmemzero(dest, len) memset(dest, 0, len) -#else -# define zmemcpy(d, s, n) bcopy((s), (d), (n)) -# define zmemzero bzero -#endif - -/* Diagnostic functions */ -#ifdef DEBUG_ZLIB -# include <stdio.h> -# ifndef verbose -# define verbose 0 -# endif -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); - -/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ -/* void zcfree OF((voidpf opaque, voidpf ptr)); */ - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr, size) \ - (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) -#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} - -/* deflate.h -- internal compression state - * Copyright (C) 1995 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - - -/*+++++*/ -/* From: deflate.h,v 1.5 1995/05/03 17:27:09 jloup Exp */ - -/* =========================================================================== - * Internal compression state. - */ - -/* Data type */ -#define BINARY 0 -#define ASCII 1 -#define UNKNOWN 2 - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define INIT_STATE 42 -#define BUSY_STATE 113 -#define FLUSH_STATE 124 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct deflate_state { - z_stream *strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - Bytef *pending_out; /* next pending byte to output to the stream */ - int pending; /* nb of bytes in the pending buffer */ - uLong adler; /* adler32 of uncompressed data */ - int noheader; /* suppress zlib header and adler32 */ - Byte data_type; /* UNKNOWN, BINARY or ASCII */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int minCompr; /* min size decrease for Z_FLUSH_NOSTORE */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to supress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - ulg compressed_len; /* total bit length of compressed file */ - uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ - -#ifdef DEBUG_ZLIB - ulg bits_sent; /* bit length of the compressed data */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - uInt blocks_in_packet; - /* Number of blocks produced since the last time Z_PACKET_FLUSH - * was used. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - - /* in trees.c */ -local void ct_init OF((deflate_state *s)); -local int ct_tally OF((deflate_state *s, int dist, int lc)); -local ulg ct_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int flush)); -local void ct_align OF((deflate_state *s)); -local void ct_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -local void ct_stored_type_only OF((deflate_state *s)); - - -/*+++++*/ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* From: deflate.c,v 1.8 1995/05/03 17:27:08 jloup Exp */ - -local char zlib_copyright[] = " deflate Copyright 1995 Jean-loup Gailly "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ - -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; -} config; - -local config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0}, /* store only */ -/* 1 */ {4, 4, 8, 4}, /* maximum speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8}, -/* 3 */ {4, 6, 32, 32}, - -/* 4 */ {4, 4, 16, 16}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32}, -/* 6 */ {8, 16, 128, 128}, -/* 7 */ {8, 32, 128, 256}, -/* 8 */ {32, 128, 258, 1024}, -/* 9 */ {32, 258, 258, 4096}}; /* maximum compression */ - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -/* =========================================================================== - * Prototypes for local functions. - */ - -local void fill_window OF((deflate_state *s)); -local int deflate_fast OF((deflate_state *s, int flush)); -local int deflate_slow OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local int longest_match OF((deflate_state *s, IPos cur_match)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_stream *strm)); -local int read_buf OF((z_stream *strm, charf *buf, unsigned size)); -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ -#endif - -#ifdef DEBUG_ZLIB -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (str)) - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int deflateInit (strm, level) - z_stream *strm; - int level; -{ - return deflateInit2 (strm, level, DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - 0, 0); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int deflateInit2 (strm, level, method, windowBits, memLevel, - strategy, minCompression) - z_stream *strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - int minCompression; -{ - deflate_state *s; - int noheader = 0; - - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; -/* if (strm->zalloc == Z_NULL) strm->zalloc = zcalloc; */ -/* if (strm->zfree == Z_NULL) strm->zfree = zcfree; */ - - if (level == Z_DEFAULT_COMPRESSION) level = 6; - - if (windowBits < 0) { /* undocumented feature: suppress zlib header */ - noheader = 1; - windowBits = -windowBits; - } - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != DEFLATED || - windowBits < 8 || windowBits > 15 || level < 1 || level > 9) { - return Z_STREAM_ERROR; - } - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->noheader = noheader; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 2*sizeof(ush)); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - strm->msg = z_errmsg[1-Z_MEM_ERROR]; - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = (ushf *) &(s->pending_buf[s->lit_bufsize]); - s->l_buf = (uchf *) &(s->pending_buf[3*s->lit_bufsize]); - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 32 bits (worst case - * is 15+15+13=33). - */ - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - s->minCompr = minCompression; - s->blocks_in_packet = 0; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int deflateReset (strm) - z_stream *strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->noheader < 0) { - s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ - } - s->status = s->noheader ? BUSY_STATE : INIT_STATE; - s->adler = 1; - - ct_init(s); - lm_init(s); - - return Z_OK; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. - */ -local void flush_pending(strm) - z_stream *strm; -{ - deflate_state *state = (deflate_state *) strm->state; - unsigned len = state->pending; - - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - if (strm->next_out != NULL) { - zmemcpy(strm->next_out, state->pending_out, len); - strm->next_out += len; - } - state->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - state->pending -= len; - if (state->pending == 0) { - state->pending_out = state->pending_buf; - } -} - -/* ========================================================================= */ -int deflate (strm, flush) - z_stream *strm; - int flush; -{ - deflate_state *state = (deflate_state *) strm->state; - - if (strm == Z_NULL || state == Z_NULL) return Z_STREAM_ERROR; - - if (strm->next_in == Z_NULL && strm->avail_in != 0) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - state->strm = strm; /* just in case */ - - /* Write the zlib header */ - if (state->status == INIT_STATE) { - - uInt header = (DEFLATED + ((state->w_bits-8)<<4)) << 8; - uInt level_flags = (state->level-1) >> 1; - - if (level_flags > 3) level_flags = 3; - header |= (level_flags << 6); - header += 31 - (header % 31); - - state->status = BUSY_STATE; - putShortMSB(state, header); - } - - /* Flush as much pending output as possible */ - if (state->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) return Z_OK; - } - - /* If we came back in here to get the last output from - * a previous flush, we're done for now. - */ - if (state->status == FLUSH_STATE) { - state->status = BUSY_STATE; - if (flush != Z_NO_FLUSH && flush != Z_FINISH) - return Z_OK; - } - - /* User must not provide more input after the first FINISH: */ - if (state->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || state->lookahead != 0 || - (flush == Z_FINISH && state->status != FINISH_STATE)) { - int quit; - - if (flush == Z_FINISH) { - state->status = FINISH_STATE; - } - if (state->level <= 3) { - quit = deflate_fast(state, flush); - } else { - quit = deflate_slow(state, flush); - } - if (quit || strm->avail_out == 0) - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - - /* If a flush was requested, we have a little more to output now. */ - if (flush != Z_NO_FLUSH && flush != Z_FINISH - && state->status != FINISH_STATE) { - switch (flush) { - case Z_PARTIAL_FLUSH: - ct_align(state); - break; - case Z_PACKET_FLUSH: - /* Output just the 3-bit `stored' block type value, - but not a zero length. */ - ct_stored_type_only(state); - break; - default: - ct_stored_block(state, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(state); /* forget history */ - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - /* We'll have to come back to get the rest of the output; - * this ensures we don't output a second zero-length stored - * block (or whatever). - */ - state->status = FLUSH_STATE; - return Z_OK; - } - } - - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (state->noheader) return Z_STREAM_END; - - /* Write the zlib trailer (adler32) */ - putShortMSB(state, (uInt)(state->adler >> 16)); - putShortMSB(state, (uInt)(state->adler & 0xffff)); - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - state->noheader = -1; /* write the trailer only once! */ - return state->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int deflateEnd (strm) - z_stream *strm; -{ - deflate_state *state = (deflate_state *) strm->state; - - if (strm == Z_NULL || state == Z_NULL) return Z_STREAM_ERROR; - - TRY_FREE(strm, state->window, state->w_size * 2 * sizeof(Byte)); - TRY_FREE(strm, state->prev, state->w_size * sizeof(Pos)); - TRY_FREE(strm, state->head, state->hash_size * sizeof(Pos)); - TRY_FREE(strm, state->pending_buf, state->lit_bufsize * 2 * sizeof(ush)); - - ZFREE(strm, state, sizeof(deflate_state)); - strm->state = Z_NULL; - - return Z_OK; -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. - */ -local int read_buf(strm, buf, size) - z_stream *strm; - charf *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - deflate_state *state = (deflate_state *) strm->state; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - if (!state->noheader) { - state->adler = adler32(state->adler, strm->next_in, len); - } - zmemcpy(buf, strm->next_in, len); - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->match_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -} - -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local int longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2: - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= s->nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - return best_len; -} -#endif /* ASMV */ - -#ifdef DEBUG_ZLIB -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (memcmp((charf *)s->window + match, - (charf *)s->window + start, length) != EQUAL) { - fprintf(stderr, - " start %u, match %u, length %d\n", - start, match, length); - do { fprintf(stderr, "%c%c", s->window[match++], - s->window[start++]); } while (--length != 0); - z_error("invalid match"); - } - if (verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if strstart == 0 - * and lookahead == 1 (input done one byte at time) - */ - more--; - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - } else if (s->strstart >= wsize+MAX_DIST(s)) { - - /* By the IN assertion, the window is not empty so we can't confuse - * more == 0 with more == 64K on a 16 bit machine. - */ - zmemcpy((charf *)s->window, (charf *)s->window+wsize, - (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage): - */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); - - more += wsize; - } - if (s->strm->avail_in == 0) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, (charf *)s->window + s->strstart + s->lookahead, - more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, flush) { \ - ct_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), (long)s->strstart - s->block_start, (flush)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, flush) { \ - FLUSH_BLOCK_ONLY(s, flush); \ - if (s->strm->avail_out == 0) return 1; \ -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return true if - * processing was terminated prematurely (no more input or output space). - * This function does not perform lazy evaluationof matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local int deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - s->prev_length = MIN_MATCH-1; - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1; - - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy != Z_HUFFMAN_ONLY) { - s->match_length = longest_match (s, hash_head); - } - /* longest_match() sets match_start */ - - if (s->match_length > s->lookahead) s->match_length = s->lookahead; - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - bflush = ct_tally(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in hash table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - bflush = ct_tally (s, 0, s->window[s->strstart]); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, Z_NO_FLUSH); - } - FLUSH_BLOCK(s, flush); - return 0; /* normal exit */ -} - -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local int deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1; - - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy != Z_HUFFMAN_ONLY) { - s->match_length = longest_match (s, hash_head); - } - /* longest_match() sets match_start */ - if (s->match_length > s->lookahead) s->match_length = s->lookahead; - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED || - (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR))) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - bflush = ct_tally(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, Z_NO_FLUSH); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - if (ct_tally (s, 0, s->window[s->strstart-1])) { - FLUSH_BLOCK_ONLY(s, Z_NO_FLUSH); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return 1; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - ct_tally (s, 0, s->window[s->strstart-1]); - s->match_available = 0; - } - FLUSH_BLOCK(s, flush); - return 0; -} - - -/*+++++*/ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* From: trees.c,v 1.5 1995/05/03 17:27:12 jloup Exp */ - -#ifdef DEBUG_ZLIB -# include <ctype.h> -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - -/* =========================================================================== - * Local data. These are initialized only once. - * To do: initialize at compile time to be completely reentrant. ??? - */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see ct_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -local uch dist_code[512]; -/* distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -local uch length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -struct static_tree_desc_s { - ct_data *static_tree; /* static tree or NULL */ - intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void ct_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local void set_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifndef DEBUG_ZLIB -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG_ZLIB */ -# define send_code(s, c, tree) \ - { if (verbose>1) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -#define d_code(dist) \ - ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. dist_code[256] and dist_code[257] are never - * used. - */ - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG_ZLIB -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracev((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (value << s->bi_valid); - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG_ZLIB */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (val << s->bi_valid);\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG_ZLIB */ - - -#define MAX(a,b) (a >= b ? a : b) -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - * To do: do this at compile time. - */ -local void ct_static_init() -{ - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1<<extra_lbits[code]); n++) { - length_code[length++] = (uch)code; - } - } - Assert (length == 256, "ct_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - length_code[length-1] = (uch)code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<<extra_dbits[code]); n++) { - dist_code[dist++] = (uch)code; - } - } - Assert (dist == 256, "ct_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "ct_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse(n, 5); - } -} - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -local void ct_init(s) - deflate_state *s; -{ - if (static_dtree[0].Len == 0) { - ct_static_init(); /* To do: at compile time */ - } - - s->compressed_len = 0L; - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ -#ifdef DEBUG_ZLIB - s->bits_sent = 0L; -#endif - s->blocks_in_packet = 0; - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - ct_data *stree = desc->stat_desc->static_tree; - intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if (tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, - "inconsistent bit counts"); - Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].Code = bi_reverse(next_code[len]++, len); - - Tracec(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); - } -} - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -local void build_tree(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -local void ct_stored_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ - s->compressed_len = (s->compressed_len + 3 + 7) & ~7L; - s->compressed_len += (stored_len + 4) << 3; - - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* Send just the `stored block' type code without any length bytes or data. - */ -local void ct_stored_type_only(s) - deflate_state *s; -{ - send_bits(s, (STORED_BLOCK << 1), 3); - bi_windup(s); - s->compressed_len = (s->compressed_len + 3) & ~7L; -} - - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the EOB - * code for the previous block was coded on 5 bits or less, inflate - * may have only 5+3 bits of lookahead to decode this EOB. - * (There are no problems if the previous block is stored or fixed.) - */ -local void ct_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ - bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the EOB of the previous - * block was thus its length plus what we have just sent. - */ - if (s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); - s->compressed_len += 10L; - bi_flush(s); - } - s->last_eob_len = 7; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. This function - * returns the total compressed length for the file so far. - */ -local ulg ct_flush_block(s, buf, stored_len, flush) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int flush; /* Z_FINISH if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex; /* index of last bit length code of non zero freq */ - int eof = flush == Z_FINISH; - - ++s->blocks_in_packet; - - /* Check if the file is ascii or binary */ - if (s->data_type == UNKNOWN) set_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute first the block length in bytes */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - /* If compression failed and this is the first and last block, - * and if the .zip file can be seeked (to rewrite the local header), - * the whole file is transformed into a stored file: - */ -#ifdef STORED_FILE_OK -# ifdef FORCE_STORED_FILE - if (eof && compressed_len == 0L) /* force stored file */ -# else - if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) -# endif - { - /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ - if (buf == (charf*)0) error ("block vanished"); - - copy_block(buf, (unsigned)stored_len, 0); /* without header */ - s->compressed_len = stored_len << 3; - s->method = STORED; - } else -#endif /* STORED_FILE_OK */ - - /* For Z_PACKET_FLUSH, if we don't achieve the required minimum - * compression, and this block contains all the data since the last - * time we used Z_PACKET_FLUSH, then just omit this block completely - * from the output. - */ - if (flush == Z_PACKET_FLUSH && s->blocks_in_packet == 1 - && opt_lenb > stored_len - s->minCompr) { - s->blocks_in_packet = 0; - /* output nothing */ - } else - -#ifdef FORCE_STORED - if (buf != (char*)0) /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) - /* 4: two words for the lengths */ -#endif - { - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - ct_stored_block(s, buf, stored_len, eof); - } else - -#ifdef FORCE_STATIC - if (static_lenb >= 0) /* force static trees */ -#else - if (static_lenb == opt_lenb) -#endif - { - send_bits(s, (STATIC_TREES<<1)+eof, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); - s->compressed_len += 3 + s->static_len; - } else { - send_bits(s, (DYN_TREES<<1)+eof, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); - s->compressed_len += 3 + s->opt_len; - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - init_block(s); - - if (eof) { - bi_windup(s); - s->compressed_len += 7; /* align on byte boundary */ - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*eof)); - - return s->compressed_len >> 3; -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -local int ct_tally (s, dist, lc) - deflate_state *s; - int dist; /* distance of matched string */ - int lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "ct_tally: bad match"); - - s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - - /* Try to guess if it is profitable to stop the current block here */ - if (s->level > 2 && (s->last_lit & 0xfff) == 0) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)s->strstart - s->block_start; - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; -} - -/* =========================================================================== - * Set the data type to ASCII or BINARY, using a crude approximation: - * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. - * IN assertion: the fields freq of dyn_ltree are set and the total of all - * frequencies does not exceed 64K (to fit in an int on 16 bit machines). - */ -local void set_data_type(s) - deflate_state *s; -{ - int n = 0; - unsigned ascii_freq = 0; - unsigned bin_freq = 0; - while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; - while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; - while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; - s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? BINARY : ASCII); -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG_ZLIB - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG_ZLIB - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG_ZLIB - s->bits_sent += (ulg)len<<3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} - - -/*+++++*/ -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_blocks_state; -typedef struct inflate_blocks_state FAR inflate_blocks_statef; - -local inflate_blocks_statef * inflate_blocks_new OF(( - z_stream *z, - check_func c, /* check function */ - uInt w)); /* window size */ - -local int inflate_blocks OF(( - inflate_blocks_statef *, - z_stream *, - int)); /* initial return code */ - -local void inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_stream *, - uLongf *)); /* check value on output */ - -local int inflate_blocks_free OF(( - inflate_blocks_statef *, - z_stream *, - uLongf *)); /* check value on output */ - -local int inflate_addhistory OF(( - inflate_blocks_statef *, - z_stream *)); - -local int inflate_packet_flush OF(( - inflate_blocks_statef *)); - -/*+++++*/ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). */ - -typedef struct inflate_huft_s FAR inflate_huft; - -struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - uInt Nalloc; /* number of these allocated here */ - Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit machines) */ - union { - uInt Base; /* literal, length base, or distance base */ - inflate_huft *Next; /* pointer to next level of table */ - } more; -}; - -#ifdef DEBUG_ZLIB - local uInt inflate_hufts; -#endif - -local int inflate_trees_bits OF(( - uIntf *, /* 19 code lengths */ - uIntf *, /* bits tree desired/actual depth */ - inflate_huft * FAR *, /* bits tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_dynamic OF(( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uIntf *, /* that many (total) code lengths */ - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_fixed OF(( - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *)); /* distance tree result */ - -local int inflate_trees_free OF(( - inflate_huft *, /* tables to free */ - z_stream *)); /* for zfree function */ - - -/*+++++*/ -/* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_codes_state; -typedef struct inflate_codes_state FAR inflate_codes_statef; - -local inflate_codes_statef *inflate_codes_new OF(( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_stream *)); - -local int inflate_codes OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -local void inflate_codes_free OF(( - inflate_codes_statef *, - z_stream *)); - - -/*+++++*/ -/* inflate.c -- zlib interface to inflate modules - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* inflate private state */ -struct internal_state { - - /* mode */ - enum { - METHOD, /* waiting for method byte */ - FLAG, /* waiting for flag byte */ - BLOCKS, /* decompressing blocks */ - CHECK4, /* four check bytes to go */ - CHECK3, /* three check bytes to go */ - CHECK2, /* two check bytes to go */ - CHECK1, /* one check byte to go */ - DONE, /* finished check, done */ - BAD} /* got an error--stay here */ - mode; /* current inflate mode */ - - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ - - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ - -}; - - -int inflateReset(z) -z_stream *z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? BLOCKS : METHOD; - inflate_blocks_reset(z->state->blocks, z, &c); - Trace((stderr, "inflate: reset\n")); - return Z_OK; -} - - -int inflateEnd(z) -z_stream *z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->blocks != Z_NULL) - inflate_blocks_free(z->state->blocks, z, &c); - ZFREE(z, z->state, sizeof(struct internal_state)); - z->state = Z_NULL; - Trace((stderr, "inflate: end\n")); - return Z_OK; -} - - -int inflateInit2(z, w) -z_stream *z; -int w; -{ - /* initialize state */ - if (z == Z_NULL) - return Z_STREAM_ERROR; -/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ -/* if (z->zfree == Z_NULL) z->zfree = zcfree; */ - if ((z->state = (struct internal_state FAR *) - ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) - return Z_MEM_ERROR; - z->state->blocks = Z_NULL; - - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if (w < 0) - { - w = - w; - z->state->nowrap = 1; - } - - /* set window size */ - if (w < 8 || w > 15) - { - inflateEnd(z); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; - - /* create inflate_blocks state */ - if ((z->state->blocks = - inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) - == Z_NULL) - { - inflateEnd(z); - return Z_MEM_ERROR; - } - Trace((stderr, "inflate: allocated\n")); - - /* reset state */ - inflateReset(z); - return Z_OK; -} - - -int inflateInit(z) -z_stream *z; -{ - return inflateInit2(z, DEF_WBITS); -} - - -#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} -#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) - -int inflate(z, f) -z_stream *z; -int f; -{ - int r; - uInt b; - - if (z == Z_NULL || z->next_in == Z_NULL) - return Z_STREAM_ERROR; - r = Z_BUF_ERROR; - while (1) switch (z->state->mode) - { - case METHOD: - NEEDBYTE - if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) - { - z->state->mode = BAD; - z->msg = "unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ((z->state->sub.method >> 4) + 8 > z->state->wbits) - { - z->state->mode = BAD; - z->msg = "invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = FLAG; - case FLAG: - NEEDBYTE - if ((b = NEXTBYTE) & 0x20) - { - z->state->mode = BAD; - z->msg = "invalid reserved bit"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if (((z->state->sub.method << 8) + b) % 31) - { - z->state->mode = BAD; - z->msg = "incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib header ok\n")); - z->state->mode = BLOCKS; - case BLOCKS: - r = inflate_blocks(z->state->blocks, z, r); - if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) - r = inflate_packet_flush(z->state->blocks); - if (r == Z_DATA_ERROR) - { - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if (r != Z_STREAM_END) - return r; - r = Z_OK; - inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); - if (z->state->nowrap) - { - z->state->mode = DONE; - break; - } - z->state->mode = CHECK4; - case CHECK4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = CHECK3; - case CHECK3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = CHECK2; - case CHECK2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = CHECK1; - case CHECK1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - - if (z->state->sub.check.was != z->state->sub.check.need) - { - z->state->mode = BAD; - z->msg = "incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib check ok\n")); - z->state->mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } - - empty: - if (f != Z_PACKET_FLUSH) - return r; - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_DATA_ERROR; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ - -int inflateIncomp(z) -z_stream *z; -{ - if (z->state->mode != BLOCKS) - return Z_DATA_ERROR; - return inflate_addhistory(z->state->blocks, z); -} - - -int inflateSync(z) -z_stream *z; -{ - uInt n; /* number of bytes to look at */ - Bytef *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ - - /* set up */ - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->mode != BAD) - { - z->state->mode = BAD; - z->state->sub.marker = 0; - } - if ((n = z->avail_in) == 0) - return Z_BUF_ERROR; - p = z->next_in; - m = z->state->sub.marker; - - /* search */ - while (n && m < 4) - { - if (*p == (Byte)(m < 2 ? 0 : 0xff)) - m++; - else if (*p) - m = 0; - else - m = 4 - m; - p++, n--; - } - - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; - - /* return no joy or set up to restart on a new block */ - if (m != 4) - return Z_DATA_ERROR; - r = z->total_in; w = z->total_out; - inflateReset(z); - z->total_in = r; z->total_out = w; - z->state->mode = BLOCKS; - return Z_OK; -} - -#undef NEEDBYTE -#undef NEXTBYTE - -/*+++++*/ -/* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* inflate blocks semi-private state */ -struct inflate_blocks_state { - - /* mode */ - enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONEB, /* finished last block, done */ - BADB} /* got a data error--stuck here */ - mode; /* current inflate_block mode */ - - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uIntf *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - int nblens; /* # elements allocated at blens */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_huft *tl, *td; /* trees to free */ - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ - - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - Bytef *window; /* sliding window */ - Bytef *end; /* one byte after sliding window */ - Bytef *read; /* window read pointer */ - Bytef *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ - -}; - - -/* defines for inflate input/output */ -/* update pointers and return */ -#define UPDBITS {s->bitb=b;s->bitk=k;} -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -#define UPDOUT {s->write=q;} -#define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush(s,z,r);} -/* get bytes and bits */ -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -#define NEXTBYTE (n--,*p++) -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} -#define DUMPBITS(j) {b>>=(j);k-=(j);} -/* output bytes */ -#define WAVAIL (q<s->read?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=WAVAIL;} -#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} -#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} -#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -/* load local pointers */ -#define LOAD {LOADIN LOADOUT} - -/* And'ing with mask[n] masks the lower n bits */ -local uInt inflate_mask[] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - -/* copy as much as possible from the sliding window to the output area */ -local int inflate_flush OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -/*+++++*/ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -local int inflate_fast OF(( - uInt, - uInt, - inflate_huft *, - inflate_huft *, - inflate_blocks_statef *, - z_stream *)); - - -/*+++++*/ -/* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* Table for deflate from PKZIP's appnote.txt. */ -local uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - - -local void inflate_blocks_reset(s, z, c) -inflate_blocks_statef *s; -z_stream *z; -uLongf *c; -{ - if (s->checkfn != Z_NULL) - *c = s->check; - if (s->mode == BTREE || s->mode == DTREE) - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); - if (s->mode == CODES) - { - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - } - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(0L, Z_NULL, 0); - Trace((stderr, "inflate: blocks reset\n")); -} - - -local inflate_blocks_statef *inflate_blocks_new(z, c, w) -z_stream *z; -check_func c; -uInt w; -{ - inflate_blocks_statef *s; - - if ((s = (inflate_blocks_statef *)ZALLOC - (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) - return s; - if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) - { - ZFREE(z, s, sizeof(struct inflate_blocks_state)); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Trace((stderr, "inflate: blocks allocated\n")); - inflate_blocks_reset(s, z, &s->check); - return s; -} - - -local int inflate_blocks(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input based on current state */ - while (1) switch (s->mode) - { - case TYPE: - NEEDBITS(3) - t = (uInt)b & 7; - s->last = t & 1; - switch (t >> 1) - { - case 0: /* stored */ - Trace((stderr, "inflate: stored block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - t = k & 7; /* go to byte boundary */ - DUMPBITS(t) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Trace((stderr, "inflate: fixed codes block%s\n", - s->last ? " (last)" : "")); - { - uInt bl, bd; - inflate_huft *tl, *td; - - inflate_trees_fixed(&bl, &bd, &tl, &td); - s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.decode.codes == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.tl = Z_NULL; /* don't try to free these */ - s->sub.decode.td = Z_NULL; - } - DUMPBITS(3) - s->mode = CODES; - break; - case 2: /* dynamic */ - Trace((stderr, "inflate: dynamic codes block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS(3) - s->mode = BADB; - z->msg = "invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS(32) - if (((~b) >> 16) != (b & 0xffff)) - { - s->mode = BADB; - z->msg = "invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); - s->mode = s->sub.left ? STORED : TYPE; - break; - case STORED: - if (n == 0) - LEAVE - NEEDOUT - t = s->sub.left; - if (t > n) t = n; - if (t > m) t = m; - zmemcpy(q, p, t); - p += t; n -= t; - q += t; m -= t; - if ((s->sub.left -= t) != 0) - break; - Tracev((stderr, "inflate: stored end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS(14) - s->sub.trees.table = t = (uInt)b & 0x3fff; -#ifndef PKZIP_BUG_WORKAROUND - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - s->mode = BADB; - z->msg = "too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } -#endif - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if (t < 19) - t = 19; - if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.trees.nblens = t; - DUMPBITS(14) - s->sub.trees.index = 0; - Tracev((stderr, "inflate: table sizes ok\n")); - s->mode = BTREE; - case BTREE: - while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) - { - NEEDBITS(3) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS(3) - } - while (s->sub.trees.index < 19) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, z); - if (t != Z_OK) - { - r = t; - if (r == Z_DATA_ERROR) - s->mode = BADB; - LEAVE - } - s->sub.trees.index = 0; - Tracev((stderr, "inflate: bits tree ok\n")); - s->mode = DTREE; - case DTREE: - while (t = s->sub.trees.table, - s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) - { - inflate_huft *h; - uInt i, j, c; - - t = s->sub.trees.bb; - NEEDBITS(t) - h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); - t = h->word.what.Bits; - c = h->more.Base; - if (c < 16) - { - DUMPBITS(t) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS(t + i) - DUMPBITS(t) - j += (uInt)b & inflate_mask[i]; - DUMPBITS(i) - i = s->sub.trees.index; - t = s->sub.trees.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)) - { - s->mode = BADB; - z->msg = "invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while (--j); - s->sub.trees.index = i; - } - } - inflate_trees_free(s->sub.trees.tb, z); - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; - - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; - t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), - s->sub.trees.blens, &bl, &bd, &tl, &td, z); - if (t != Z_OK) - { - if (t == (uInt)Z_DATA_ERROR) - s->mode = BADB; - r = t; - LEAVE - } - Tracev((stderr, "inflate: trees ok\n")); - if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) - { - inflate_trees_free(td, z); - inflate_trees_free(tl, z); - r = Z_MEM_ERROR; - LEAVE - } - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); - s->sub.decode.codes = c; - s->sub.decode.tl = tl; - s->sub.decode.td = td; - } - s->mode = CODES; - case CODES: - UPDATE - if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) - return inflate_flush(s, z, r); - r = Z_OK; - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - LOAD - Tracev((stderr, "inflate: codes end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - if (!s->last) - { - s->mode = TYPE; - break; - } - if (k > 7) /* return unused byte, if any */ - { - Assert(k < 16, "inflate_codes grabbed too many bytes") - k -= 8; - n++; - p--; /* can always return one */ - } - s->mode = DRY; - case DRY: - FLUSH - if (s->read != s->write) - LEAVE - s->mode = DONEB; - case DONEB: - r = Z_STREAM_END; - LEAVE - case BADB: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -local int inflate_blocks_free(s, z, c) -inflate_blocks_statef *s; -z_stream *z; -uLongf *c; -{ - inflate_blocks_reset(s, z, c); - ZFREE(z, s->window, s->end - s->window); - ZFREE(z, s, sizeof(struct inflate_blocks_state)); - Trace((stderr, "inflate: blocks freed\n")); - return Z_OK; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ -local int inflate_addhistory(s, z) -inflate_blocks_statef *s; -z_stream *z; -{ - uLong b; /* bit buffer */ /* NOT USED HERE */ - uInt k; /* bits in bit buffer */ /* NOT USED HERE */ - uInt t; /* temporary storage */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - if (s->read != s->write) - return Z_STREAM_ERROR; - if (s->mode != TYPE) - return Z_DATA_ERROR; - - /* we're ready to rock */ - LOAD - /* while there is input ready, copy to output buffer, moving - * pointers as needed. - */ - while (n) { - t = n; /* how many to do */ - /* is there room until end of buffer? */ - if (t > m) t = m; - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, t); - zmemcpy(q, p, t); - q += t; - p += t; - n -= t; - z->total_out += t; - s->read = q; /* drag read pointer forward */ -/* WRAP */ /* expand WRAP macro by hand to handle s->read */ - if (q == s->end) { - s->read = q = s->window; - m = WAVAIL; - } - } - UPDATE - return Z_OK; -} - - -/* - * At the end of a Deflate-compressed PPP packet, we expect to have seen - * a `stored' block type value but not the (zero) length bytes. - */ -local int inflate_packet_flush(s) - inflate_blocks_statef *s; -{ - if (s->mode != LENS) - return Z_DATA_ERROR; - s->mode = TYPE; - return Z_OK; -} - - -/*+++++*/ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - - -local int huft_build OF(( - uIntf *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - uIntf *, /* list of base values for non-simple codes */ - uIntf *, /* list of extra bits for non-simple codes */ - inflate_huft * FAR*,/* result: starting table */ - uIntf *, /* maximum lookup bits (returns actual) */ - z_stream *)); /* for zalloc function */ - -local voidpf falloc OF(( - voidpf, /* opaque pointer (not used) */ - uInt, /* number of items */ - uInt)); /* size of item */ - -local void ffree OF(( - voidpf q, /* opaque pointer (not used) */ - voidpf p, /* what to free (not used) */ - uInt n)); /* number of bytes (not used) */ - -/* Tables for deflate from PKZIP's appnote.txt. */ -local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* actually lengths - 2; also see note #13 above about 258 */ -local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ -local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577}; -local uInt cpdext[] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - is not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ -#define BMAX 15 /* maximum bit length of any code */ -#define N_MAX 288 /* maximum number of codes in any set */ - -#ifdef DEBUG_ZLIB - uInt inflate_hufts; -#endif - -local int huft_build(b, n, s, d, e, t, m, zs) -uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ -uInt n; /* number of codes (assumed <= N_MAX) */ -uInt s; /* number of simple-valued codes (0..s-1) */ -uIntf *d; /* list of base values for non-simple codes */ -uIntf *e; /* list of extra bits for non-simple codes */ -inflate_huft * FAR *t; /* result: starting table */ -uIntf *m; /* maximum lookup bits, returns actual */ -z_stream *zs; /* for zalloc function */ -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - if the given code set is incomplete (the tables are still built in this - case), Z_DATA_ERROR if the input is invalid (all zero length codes or an - over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ -{ - - uInt a; /* counter for codes of length k */ - uInt c[BMAX+1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - register uIntf *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - uInt v[N_MAX]; /* values in order of bit length */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX+1]; /* bit offsets, then code stack */ - uIntf *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - p = c; -#define C0 *p++ = 0; -#define C2 C0 C0 C0 C0 -#define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_OK; - } - - - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((uInt)l < j) - l = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((uInt)l > i) - l = i; - *m = l; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return Z_DATA_ERROR; - if ((y -= c[i]) < 0) - return Z_DATA_ERROR; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l) - { - h++; - w += l; /* previous table always l bits */ - - /* compute minimum size table less than or equal to l bits */ - z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if (j < z) - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - z = 1 << j; /* table entries for j-bit table */ - - /* allocate and link in new table */ - if ((q = (inflate_huft *)ZALLOC - (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) - { - if (h) - inflate_trees_free(u[0], zs); - return Z_MEM_ERROR; /* not enough memory */ - } - q->word.Nalloc = z + 1; -#ifdef DEBUG_ZLIB - inflate_hufts += z + 1; -#endif - *t = q + 1; /* link to list for huft_free() */ - *(t = &(q->next)) = Z_NULL; - u[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - r.next = q; /* pointer to this table */ - j = i >> (w - l); /* (get around Turbo C bug) */ - u[h-1][j] = r; /* connect to last table */ - } - } - - /* set up table entry in r */ - r.bits = (Byte)(k - w); - if (p >= v + n) - r.exop = 128 + 64; /* out of values--invalid code */ - else if (*p < s) - { - r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != x[h]) - { - h--; /* don't need to update q */ - w -= l; - } - } - } - - - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -} - - -local int inflate_trees_bits(c, bb, tb, z) -uIntf *c; /* 19 code lengths */ -uIntf *bb; /* bits tree desired/actual depth */ -inflate_huft * FAR *tb; /* bits tree result */ -z_stream *z; /* for zfree function */ -{ - int r; - - r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed dynamic bit lengths tree"; - else if (r == Z_BUF_ERROR) - { - inflate_trees_free(*tb, z); - z->msg = "incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - return r; -} - - -local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) -uInt nl; /* number of literal/length codes */ -uInt nd; /* number of distance codes */ -uIntf *c; /* that many (total) code lengths */ -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -z_stream *z; /* for zfree function */ -{ - int r; - - /* build literal/length tree */ - if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) - { - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) - { - inflate_trees_free(*tl, z); - z->msg = "incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - return r; - } - - /* build distance tree */ - if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) - { - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) { -#ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } -#else - inflate_trees_free(*td, z); - z->msg = "incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - inflate_trees_free(*tl, z); - return r; -#endif - } - - /* done */ - return Z_OK; -} - - -/* build fixed tables only once--keep them here */ -local int fixed_lock = 0; -local int fixed_built = 0; -#define FIXEDH 530 /* number of hufts used by fixed tables */ -local uInt fixed_left = FIXEDH; -local inflate_huft fixed_mem[FIXEDH]; -local uInt fixed_bl; -local uInt fixed_bd; -local inflate_huft *fixed_tl; -local inflate_huft *fixed_td; - - -local voidpf falloc(q, n, s) -voidpf q; /* opaque pointer (not used) */ -uInt n; /* number of items */ -uInt s; /* size of item */ -{ - Assert(s == sizeof(inflate_huft) && n <= fixed_left, - "inflate_trees falloc overflow"); - if (q) s++; /* to make some compilers happy */ - fixed_left -= n; - return (voidpf)(fixed_mem + fixed_left); -} - - -local void ffree(q, p, n) -voidpf q; -voidpf p; -uInt n; -{ - Assert(0, "inflate_trees ffree called!"); - if (q) q = p; /* to make some compilers happy */ -} - - -local int inflate_trees_fixed(bl, bd, tl, td) -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -{ - /* build fixed tables if not built already--lock out other instances */ - while (++fixed_lock > 1) - fixed_lock--; - if (!fixed_built) - { - int k; /* temporary variable */ - unsigned c[288]; /* length list for huft_build */ - z_stream z; /* for falloc function */ - - /* set up fake z_stream for memory routines */ - z.zalloc = falloc; - z.zfree = ffree; - z.opaque = Z_NULL; - - /* literal table */ - for (k = 0; k < 144; k++) - c[k] = 8; - for (; k < 256; k++) - c[k] = 9; - for (; k < 280; k++) - c[k] = 7; - for (; k < 288; k++) - c[k] = 8; - fixed_bl = 7; - huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); - - /* distance table */ - for (k = 0; k < 30; k++) - c[k] = 5; - fixed_bd = 5; - huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); - - /* done */ - fixed_built = 1; - } - fixed_lock--; - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; -} - - -local int inflate_trees_free(t, z) -inflate_huft *t; /* table to free */ -z_stream *z; /* for zfree function */ -/* Free the malloc'ed tables built by huft_build(), which makes a linked - list of the tables it made, with the links in a dummy first entry of - each table. */ -{ - register inflate_huft *p, *q; - - /* Go through linked list, freeing from the malloced (t[-1]) address. */ - p = t; - while (p != Z_NULL) - { - q = (--p)->next; - ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); - p = q; - } - return Z_OK; -} - -/*+++++*/ -/* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* inflate codes private state */ -struct inflate_codes_state { - - /* mode */ - enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE} /* x: got error */ - mode; /* current inflate_codes mode */ - - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ - - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ - -}; - - -local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) -uInt bl, bd; -inflate_huft *tl, *td; -z_stream *z; -{ - inflate_codes_statef *c; - - if ((c = (inflate_codes_statef *) - ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) - { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - Tracev((stderr, "inflate: codes new\n")); - } - return c; -} - - -local int inflate_codes(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Bytef *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input and output based on current state */ - while (1) switch (c->mode) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ -#ifndef SLOW - if (m >= 258 && n >= 10) - { - UPDATE - r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); - LOAD - if (r != Z_OK) - { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } -#endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e == 0) /* literal */ - { - c->sub.lit = t->base; - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", t->base)); - c->mode = LIT; - break; - } - if (e & 16) /* length */ - { - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - if (e & 32) /* end of block */ - { - Tracevv((stderr, "inflate: end of block\n")); - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = "invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS(j) - c->len += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - Tracevv((stderr, "inflate: length %u\n", c->len)); - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e & 16) /* distance */ - { - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = "invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS(j) - c->sub.copy.dist += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ -#ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)(q - s->window) < c->sub.copy.dist ? - s->end - (c->sub.copy.dist - (q - s->window)) : - q - c->sub.copy.dist; -#else - f = q - c->sub.copy.dist; - if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (q - s->window)); -#endif - while (c->len) - { - NEEDOUT - OUTBYTE(*f++) - if (f == s->end) - f = s->window; - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE(c->sub.lit) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - FLUSH - if (s->read != s->write) - LEAVE - c->mode = END; - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -local void inflate_codes_free(c, z) -inflate_codes_statef *c; -z_stream *z; -{ - ZFREE(z, c, sizeof(struct inflate_codes_state)); - Tracev((stderr, "inflate: codes free\n")); -} - -/*+++++*/ -/* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* copy as much as possible from the sliding window to the output area */ -local int inflate_flush(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt n; - Bytef *p, *q; - - /* local copies of source and destination pointers */ - p = z->next_out; - q = s->read; - - /* compute number of bytes to copy as far as end of window */ - n = (uInt)((q <= s->write ? s->write : s->end) - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); - - /* copy as far as end of window */ - if (p != NULL) { - zmemcpy(p, q, n); - p += n; - } - q += n; - - /* see if more to copy at beginning of window */ - if (q == s->end) - { - /* wrap pointers */ - q = s->window; - if (s->write == s->end) - s->write = s->window; - - /* compute bytes to copy */ - n = (uInt)(s->write - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); - - /* copy */ - if (p != NULL) { - zmemcpy(p, q, n); - p += n; - } - q += n; - } - - /* update pointers */ - z->next_out = p; - s->read = q; - - /* done */ - return r; -} - - -/*+++++*/ -/* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} -#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;} - -/* Called with number of bytes left to write in window at least 258 - (the maximum string length) and number of input bytes available - at least ten. The ten bytes are six bytes for the longest length/ - distance pair plus four bytes for overloading the bit buffer. */ - -local int inflate_fast(bl, bd, tl, td, s, z) -uInt bl, bd; -inflate_huft *tl, *td; -inflate_blocks_statef *s; -z_stream *z; -{ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Bytef *r; /* copy source pointer */ - - /* load input, output, bit values */ - LOAD - - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; - - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits for length */ - e &= 15; - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * length %u\n", c)); - - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - e = (t = td + ((uInt)b & md))->exop; - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS(e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* offset before dest */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > e) /* if source crosses, */ - { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); - break; - } - else if ((e & 64) == 0) - e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; - else - { - z->msg = "invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - break; - } - if ((e & 64) == 0) - { - if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - break; - } - } - else if (e & 32) - { - Tracevv((stderr, "inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = "invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - } while (m >= 258 && n >= 10); - - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; -} - - -/*+++++*/ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ - -char *zlib_version = ZLIB_VERSION; - -char *z_errmsg[] = { -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -""}; - - -/*+++++*/ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf) {s1 += *buf++; s2 += s1;} -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); -#define DO16(buf) DO8(buf); DO8(buf); - -/* ========================================================================= */ -uLong adler32(adler, buf, len) - uLong adler; - Bytef *buf; - uInt len; -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == Z_NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - k -= 16; - } - if (k != 0) do { - DO1(buf); - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} diff --git a/mdk-stage1/ppp/pppdump/zlib.h b/mdk-stage1/ppp/pppdump/zlib.h deleted file mode 100644 index 9c7ac734d..000000000 --- a/mdk-stage1/ppp/pppdump/zlib.h +++ /dev/null @@ -1,631 +0,0 @@ -/* $Id$ */ - -/* - * This file is derived from zlib.h and zconf.h from the zlib-0.95 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. - */ - -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 0.95, Aug 16th, 1995. - - Copyright (C) 1995 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - gzip@prep.ai.mit.edu madler@alumni.caltech.edu - */ - -#ifndef _ZLIB_H -#define _ZLIB_H - -/* #include "zconf.h" */ /* included directly here */ - -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ - -/* - The library does not install any signal handler. It is recommended to - add at least a handler for SIGSEGV when decompressing; the library checks - the consistency of the input data whenever possible but may go nuts - for some forms of corrupted input. - */ - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints - * at addresses which are not a multiple of their size. - * Under DOS, -DFAR=far or -DFAR=__far may be needed. - */ - -#ifndef STDC -# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) -# define STDC -# endif -#endif - -#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ -# include <unix.h> -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -#ifndef FAR -# define FAR -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - 1 << (windowBits+2) + 1 << (memLevel+9) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -typedef Byte FAR Bytef; -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -/* end of original zconf.h */ - -#define ZLIB_VERSION "0.95P" - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms may be added later and will have the same - stream interface. - - For compression the application must provide the output buffer and - may optionally provide the input buffer for optimization. For decompression, - the application must provide the input buffer and may optionally provide - the output buffer for optimization. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidp opaque; /* private data object passed to zalloc and zfree */ - - Byte data_type; /* best guess about the data type: ascii or binary */ - -} z_stream; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_FULL_FLUSH 2 -#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ -#define Z_FINISH 4 -#define Z_PACKET_FLUSH 5 -/* See deflate() below for the usage of these constants */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -/* error codes for the compression/decompression functions */ - -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_DEFAULT_STRATEGY 0 - -#define Z_BINARY 0 -#define Z_ASCII 1 -#define Z_UNKNOWN 2 -/* Used to set the data_type field */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -extern char *zlib_version; -/* The application can compare zlib_version and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - */ - - /* basic functions */ - -extern int deflateInit OF((z_stream *strm, int level)); -/* - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 1 and 9: - 1 gives best speed, 9 gives best compression. Z_DEFAULT_COMPRESSION requests - a default compromise between speed and compression (currently equivalent - to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level. - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -extern int deflate OF((z_stream *strm, int flush)); -/* - Performs one or both of the following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). - - If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression - block is terminated and flushed to the output buffer so that the - decompressor can get all input data available so far. For method 9, a future - variant on method 8, the current block will be flushed but not terminated. - If flush is set to Z_FULL_FLUSH, the compression block is terminated, a - special marker is output and the compression dictionary is discarded; this - is useful to allow the decompressor to synchronize if one compressed block - has been damaged (see inflateSync below). Flushing degrades compression and - so should be used only when necessary. Using Z_FULL_FLUSH too often can - seriously degrade the compression. If deflate returns with avail_out == 0, - this function must be called again with the same value of the flush - parameter and more output space (updated avail_out), until the flush is - complete (deflate returns with non-zero avail_out). - - If the parameter flush is set to Z_PACKET_FLUSH, the compression - block is terminated, and a zero-length stored block is output, - omitting the length bytes (the effect of this is that the 3-bit type - code 000 for a stored block is output, and the output is then - byte-aligned). This is designed for use at the end of a PPP packet. - In addition, if the current compression block contains all the data - since the last Z_PACKET_FLUSH, it is never output as a stored block. - If the current compression block output as a static or dynamic block - would not be at least `minCompression' bytes smaller than the - original data, then nothing is output for that block. (The type - code for the zero-length stored block is still output, resulting in - a single zero byte being output for the whole packet.) - `MinCompression' is a parameter to deflateInit2, or 0 if deflateInit - is used. - - If the parameter flush is set to Z_FINISH, all pending input is processed, - all pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - 0.1% larger than avail_in plus 12 bytes. If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() may update data_type if it can make a good guess about - the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible. -*/ - - -extern int deflateEnd OF((z_stream *strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent. In the error case, msg may be set - but then points to a static string (which must not be deallocated). -*/ - - -extern int inflateInit OF((z_stream *strm)); -/* - Initializes the internal stream state for decompression. The fields - zalloc and zfree must be initialized before by the caller. If zalloc and - zfree are set to Z_NULL, inflateInit updates them to use default allocation - functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory. msg is set to null if there is no error message. - inflateInit does not perform any decompression: this will be done by - inflate(). -*/ - - -extern int inflate OF((z_stream *strm, int flush)); -/* - Performs one or both of the following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() always provides as much output as possible - (until there is no more input data or no more space in the output buffer). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). - - If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, - inflate flushes as much output as possible to the output buffer. The - flushing behavior of inflate is not specified for values of the flush - parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the - current implementation actually flushes as much output as possible - anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data - has been consumed, it is expecting to see the length field of a stored - block; if not, it returns Z_DATA_ERROR. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. - - inflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if the end of the - compressed data has been reached and all uncompressed output has been - produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if - the stream structure was inconsistent (for example if next_in or next_out - was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no - progress is possible or if there was not enough room in the output buffer - when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then - call inflateSync to look for a good compression block. */ - - -extern int inflateEnd OF((z_stream *strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -extern int deflateInit2 OF((z_stream *strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy, - int minCompression)); -/* - This is another version of deflateInit with more compression options. The - fields next_in, zalloc and zfree must be initialized before by the caller. - - The method parameter is the compression method. It must be 8 in this - version of the library. (Method 9 will allow a 64K history buffer and - partial block flushes.) - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library (the value 16 will be allowed for method 9). Larger - values of this parameter result in better compression at the expense of - memory usage. The default value is 15 if deflateInit is used instead. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use - the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data - produced by a filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman - encoding only (no string match). Filtered data consists mostly of small - values with a somewhat random distribution. In this case, the - compression algorithm is tuned to compress them better. The strategy - parameter only affects the compression ratio but not the correctness of - the compressed output even if it is not set appropriately. - - The minCompression parameter specifies the minimum reduction in size - required for a compressed block to be output when Z_PACKET_FLUSH is - used (see the description of deflate above). - - If next_in is not null, the library will use this buffer to hold also - some history information; the buffer must either hold the entire input - data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in - is null, the library will allocate its own history buffer (and leave next_in - null). next_out need not be provided here but must be provided by the - application for the next call of deflate(). - - If the history buffer is provided by the application, next_in must - must never be changed by the application since the compressor maintains - information inside this buffer from call to call; the application - must provide more input only by increasing avail_in. next_in is always - reset by the library in this case. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was - not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as - an invalid method). msg is set to null if there is no error message. - deflateInit2 does not perform any compression: this will be done by - deflate(). -*/ - -extern int deflateCopy OF((z_stream *dest, - z_stream *source)); -/* - Sets the destination stream as a complete copy of the source stream. If - the source stream is using an application-supplied history buffer, a new - buffer is allocated for the destination stream. The compressed output - buffer is always application-supplied. It's the responsibility of the - application to provide the correct values of next_out and avail_out for the - next call of deflate. - - This function is useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -extern int deflateReset OF((z_stream *strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -extern int inflateInit2 OF((z_stream *strm, - int windowBits)); -/* - This is another version of inflateInit with more compression options. The - fields next_out, zalloc and zfree must be initialized before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library (the value 16 will be allowed soon). The - default value is 15 if inflateInit is used instead. If a compressed stream - with a larger window size is given as input, inflate() will return with - the error code Z_DATA_ERROR instead of trying to allocate a larger window. - - If next_out is not null, the library will use this buffer for the history - buffer; the buffer must either be large enough to hold the entire output - data, or have at least 1<<windowBits bytes. If next_out is null, the - library will allocate its own buffer (and leave next_out null). next_in - need not be provided here but must be provided by the application for the - next call of inflate(). - - If the history buffer is provided by the application, next_out must - never be changed by the application since the decompressor maintains - history information inside this buffer from call to call; the application - can only reset next_out to the beginning of the history buffer when - avail_out is zero and all output has been consumed. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was - not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as - windowBits < 8). msg is set to null if there is no error message. - inflateInit2 does not perform any decompression: this will be done by - inflate(). -*/ - -extern int inflateSync OF((z_stream *strm)); -/* - Skips invalid compressed data until the special marker (see deflate() - above) can be found, or until all available input is skipped. No output - is provided. - - inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no marker has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -extern int inflateReset OF((z_stream *strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -extern int inflateIncomp OF((z_stream *strm)); -/* - This function adds the data at next_in (avail_in bytes) to the output - history without performing any output. There must be no pending output, - and the decompressor must be expecting to see the start of a block. - Calling this function is equivalent to decompressing a stored block - containing the data at next_in (except that the data is not output). -*/ - - /* checksum functions */ - -/* - This function is not related to compression but is exported - anyway because it might be useful in applications using the - compression library. -*/ - -extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len)); - -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -#ifndef _Z_UTIL_H - struct internal_state {int dummy;}; /* hack for buggy compilers */ -#endif - -#endif /* _ZLIB_H */ diff --git a/mdk-stage1/ppp/pppstats/Makefile.linux b/mdk-stage1/ppp/pppstats/Makefile.linux deleted file mode 100644 index ef0764c5d..000000000 --- a/mdk-stage1/ppp/pppstats/Makefile.linux +++ /dev/null @@ -1,32 +0,0 @@ -# -# pppstats makefile -# $Id$ -# - -PPPSTATSRCS = pppstats.c -PPPSTATOBJS = pppstats.o - -#CC = gcc -COPTS = -O -COMPILE_FLAGS = -D_linux_ -I../include -LIBS = - -INSTALL= install -o root -g daemon - -CFLAGS = $(COPTS) $(COMPILE_FLAGS) - -all: pppstats - -install: pppstats - $(INSTALL) -s -c pppstats $(BINDIR)/pppstats - $(INSTALL) -c -m 444 pppstats.8 $(MANDIR)/man8/pppstats.8 - -pppstats: $(PPPSTATSRCS) - $(CC) $(CFLAGS) -o pppstats pppstats.c $(LIBS) - -clean: - rm -f pppstats *~ #* core - -depend: - cpp -M $(CFLAGS) $(PPPSTATSRCS) >.depend -# makedepend $(CFLAGS) $(PPPSTATSRCS) diff --git a/mdk-stage1/ppp/pppstats/Makefile.sol2 b/mdk-stage1/ppp/pppstats/Makefile.sol2 deleted file mode 100644 index a6544e61b..000000000 --- a/mdk-stage1/ppp/pppstats/Makefile.sol2 +++ /dev/null @@ -1,20 +0,0 @@ -# -# pppstats Makefile for SVR4 systems -# $Id$ -# - -include ../solaris/Makedefs - -CFLAGS = -DSTREAMS -I../include $(COPTS) - -all: pppstats - -pppstats: pppstats.c - $(CC) $(CFLAGS) -o pppstats pppstats.c - -install: pppstats - $(INSTALL) -f $(BINDIR) pppstats - $(INSTALL) -m 444 -f $(MANDIR)/man8 pppstats.8 - -clean: - rm -f pppstats *~ core diff --git a/mdk-stage1/ppp/pppstats/Makefile.sunos4 b/mdk-stage1/ppp/pppstats/Makefile.sunos4 deleted file mode 100644 index 2a036f28f..000000000 --- a/mdk-stage1/ppp/pppstats/Makefile.sunos4 +++ /dev/null @@ -1,30 +0,0 @@ -# -# pppstats makefile -# $Id$ -# - -include ../sunos4/Makedefs - -PPPSTATSRCS = pppstats.c -PPPSTATOBJS = pppstats.o - -COMPILE_FLAGS = -DSTREAMS -DSUNOS4 -LIBS = - -CFLAGS = -I../include $(COPTS) $(COMPILE_FLAGS) - -all: pppstats - -install: pppstats - $(INSTALL) -c pppstats $(BINDIR)/pppstats - $(INSTALL) -c -m 444 pppstats.8 $(MANDIR)/man8/pppstats.8 - -pppstats: $(PPPSTATSRCS) - $(CC) $(CFLAGS) -o pppstats pppstats.c $(LIBS) - -clean: - rm -f pppstats *~ #* core - -depend: - cpp -M $(CFLAGS) $(PPPSTATSRCS) >.depend -# makedepend $(CFLAGS) $(PPPSTATSRCS) diff --git a/mdk-stage1/ppp/pppstats/pppstats.8 b/mdk-stage1/ppp/pppstats/pppstats.8 deleted file mode 100644 index 1ba8d5779..000000000 --- a/mdk-stage1/ppp/pppstats/pppstats.8 +++ /dev/null @@ -1,217 +0,0 @@ -.\" @(#) $Id$ -.TH PPPSTATS 8 "26 June 1995" -.SH NAME -pppstats \- print PPP statistics -.SH SYNOPSIS -.B pppstats -[ -.B -a -] [ -.B -v -] [ -.B -r -] [ -.B -z -] [ -.B -c -.I <count> -] [ -.B -w -.I <secs> -] [ -.I interface -] -.ti 12 -.SH DESCRIPTION -The -.B pppstats -utility reports PPP-related statistics at regular intervals for the -specified PPP interface. If the interface is unspecified, it will -default to ppp0. -The display is split horizontally -into input and output sections containing columns of statistics -describing the properties and volume of packets received and -transmitted by the interface. -.PP -The options are as follows: -.TP -.B -a -Display absolute values rather than deltas. With this option, all -reports show statistics for the time since the link was initiated. -Without this option, the second and subsequent reports show statistics -for the time since the last report. -.TP -.B -c \fIcount -Repeat the display -.I count -times. If this option is not specified, the default repeat count is 1 -if the -.B -w -option is not specified, otherwise infinity. -.TP -.B -r -Display additional statistics summarizing the compression ratio -achieved by the packet compression algorithm in use. -.TP -.B -v -Display additional statistics relating to the performance of the Van -Jacobson TCP header compression algorithm. -.TP -.B -w \fIwait -Pause -.I wait -seconds between each display. If this option is not specified, the -default interval is 5 seconds. -.TP -.B -z -Instead of the standard display, show statistics indicating the -performance of the packet compression algorithm in use. -.PP -The following fields are printed on the input side when the -.B -z -option is not used: -.TP -.B IN -The total number of bytes received by this interface. -.TP -.B PACK -The total number of packets received by this interface. -.TP -.B VJCOMP -The number of header-compressed TCP packets received by this interface. -.TP -.B VJUNC -The number of header-uncompressed TCP packets received by this -interface. Not reported when the -.B -r -option is specified. -.TP -.B VJERR -The number of corrupted or bogus header-compressed TCP packets -received by this interface. Not reported when the -.B -r -option is specified. -.TP -.B VJTOSS -The number of VJ header-compressed TCP packets dropped on reception by -this interface because of preceding errors. Only reported when the -.B -v -option is specified. -.TP -.B NON-VJ -The total number of non-TCP packets received by this interface. Only -reported when the -.B -v -option is specified. -.TP -.B RATIO -The compression ratio achieved for received packets by the -packet compression scheme in use, defined as the uncompressed size -divided by the compressed size. -Only reported when the -.B -r -option is specified. -.TP -.B UBYTE -The total number of bytes received, after decompression of compressed -packets. Only reported when the -.B -r -option is specified. -.PP -The following fields are printed on the output side: -.TP -.B OUT -The total number of bytes transmitted from this interface. -.TP -.B PACK -The total number of packets transmitted from this interface. -.TP -.B VJCOMP -The number of TCP packets transmitted from this interface with -VJ-compressed TCP headers. -.TP -.B VJUNC -The number of TCP packets transmitted from this interface with -VJ-uncompressed TCP headers. -Not reported when the -.B -r -option is specified. -.TP -.B NON-VJ -The total number of non-TCP packets transmitted from this interface. -Not reported when the -.B -r -option is specified. -.TP -.B VJSRCH -The number of searches for the cached header entry for a VJ header -compressed TCP packet. Only reported when the -.B -v -option is specified. -.TP -.B VJMISS -The number of failed searches for the cached header entry for a -VJ header compressed TCP packet. Only reported when the -.B -v -option is specified. -.TP -.B RATIO -The compression ratio achieved for transmitted packets by the -packet compression scheme in use, defined as the size -before compression divided by the compressed size. -Only reported when the -.B -r -option is specified. -.TP -.B UBYTE -The total number of bytes to be transmitted, before packet compression -is applied. Only reported when the -.B -r -option is specified. -.PP -When the -.B -z -option is specified, -.Nm pppstats -instead displays the following fields, relating to the packet -compression algorithm currently in use. If packet compression is not -in use, these fields will all display zeroes. The fields displayed on -the input side are: -.TP -.B COMPRESSED BYTE -The number of bytes of compressed packets received. -.TP -.B COMPRESSED PACK -The number of compressed packets received. -.TP -.B INCOMPRESSIBLE BYTE -The number of bytes of incompressible packets (that is, those which -were transmitted in uncompressed form) received. -.TP -.B INCOMPRESSIBLE PACK -The number of incompressible packets received. -.TP -.B COMP RATIO -The recent compression ratio for incoming packets, defined as the -uncompressed size divided by the compressed size (including both -compressible and incompressible packets). -.PP -The fields displayed on the output side are: -.TP -.B COMPRESSED BYTE -The number of bytes of compressed packets transmitted. -.TP -.B COMPRESSED PACK -The number of compressed packets transmitted. -.TP -.B INCOMPRESSIBLE BYTE -The number of bytes of incompressible packets transmitted (that is, -those which were transmitted in uncompressed form). -.TP -.B INCOMPRESSIBLE PACK -The number of incompressible packets transmitted. -.TP -.B COMP RATIO -The recent compression ratio for outgoing packets. -.SH SEE ALSO -pppd(8) diff --git a/mdk-stage1/ppp/pppstats/pppstats.c b/mdk-stage1/ppp/pppstats/pppstats.c deleted file mode 100644 index 77b803723..000000000 --- a/mdk-stage1/ppp/pppstats/pppstats.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * print PPP statistics: - * pppstats [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface] - * - * -a Show absolute values rather than deltas - * -d Show data rate (kB/s) rather than bytes - * -v Show more stats for VJ TCP header compression - * -r Show compression ratio - * -z Show compression statistics instead of default display - * - * History: - * perkins@cps.msu.edu: Added compression statistics and alternate - * display. 11/94 - * Brad Parker (brad@cayman.com) 6/92 - * - * from the original "slstats" by Van Jacobson - * - * Copyright (c) 1989 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. - */ - -#ifndef __STDC__ -#define const -#endif - -#ifndef lint -static const char rcsid[] = "$Id$"; -#endif - -#include <stdio.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <signal.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/ioctl.h> - -#ifndef STREAMS -#if defined(_linux_) && defined(__powerpc__) \ - && (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0) -/* kludge alert! */ -#undef __GLIBC__ -#endif -#include <sys/socket.h> /* *BSD, Linux, NeXT, Ultrix etc. */ -#ifndef _linux_ -#include <net/if.h> -#include <net/ppp_defs.h> -#include <net/if_ppp.h> -#else -/* Linux */ -#if __GLIBC__ >= 2 -#include <asm/types.h> /* glibc 2 conflicts with linux/types.h */ -#include <net/if.h> -#else -#include <linux/types.h> -#include <linux/if.h> -#endif -#include <linux/ppp_defs.h> -#include <linux/if_ppp.h> -#endif /* _linux_ */ - -#else /* STREAMS */ -#include <sys/stropts.h> /* SVR4, Solaris 2, SunOS 4, OSF/1, etc. */ -#include <net/ppp_defs.h> -#include <net/pppio.h> - -#endif /* STREAMS */ - -int vflag, rflag, zflag; /* select type of display */ -int aflag; /* print absolute values, not deltas */ -int dflag; /* print data rates, not bytes */ -int interval, count; -int infinite; -int unit; -int s; /* socket or /dev/ppp file descriptor */ -int signalled; /* set if alarm goes off "early" */ -char *progname; -char *interface; - -#if defined(SUNOS4) || defined(ULTRIX) || defined(NeXT) -extern int optind; -extern char *optarg; -#endif - -/* - * If PPP_DRV_NAME is not defined, use the legacy "ppp" as the - * device name. - */ -#if !defined(PPP_DRV_NAME) -#define PPP_DRV_NAME "ppp" -#endif /* !defined(PPP_DRV_NAME) */ - -static void usage __P((void)); -static void catchalarm __P((int)); -static void get_ppp_stats __P((struct ppp_stats *)); -static void get_ppp_cstats __P((struct ppp_comp_stats *)); -static void intpr __P((void)); - -int main __P((int, char *argv[])); - -static void -usage() -{ - fprintf(stderr, "Usage: %s [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface]\n", - progname); - exit(1); -} - -/* - * Called if an interval expires before intpr has completed a loop. - * Sets a flag to not wait for the alarm. - */ -static void -catchalarm(arg) - int arg; -{ - signalled = 1; -} - - -#ifndef STREAMS -static void -get_ppp_stats(curp) - struct ppp_stats *curp; -{ - struct ifpppstatsreq req; - - memset (&req, 0, sizeof (req)); - -#ifdef _linux_ - req.stats_ptr = (caddr_t) &req.stats; -#undef ifr_name -#define ifr_name ifr__name -#endif - - strncpy(req.ifr_name, interface, sizeof(req.ifr_name)); - if (ioctl(s, SIOCGPPPSTATS, &req) < 0) { - fprintf(stderr, "%s: ", progname); - if (errno == ENOTTY) - fprintf(stderr, "kernel support missing\n"); - else - perror("couldn't get PPP statistics"); - exit(1); - } - *curp = req.stats; -} - -static void -get_ppp_cstats(csp) - struct ppp_comp_stats *csp; -{ - struct ifpppcstatsreq creq; - - memset (&creq, 0, sizeof (creq)); - -#ifdef _linux_ - creq.stats_ptr = (caddr_t) &creq.stats; -#undef ifr_name -#define ifr_name ifr__name -#endif - - strncpy(creq.ifr_name, interface, sizeof(creq.ifr_name)); - if (ioctl(s, SIOCGPPPCSTATS, &creq) < 0) { - fprintf(stderr, "%s: ", progname); - if (errno == ENOTTY) { - fprintf(stderr, "no kernel compression support\n"); - if (zflag) - exit(1); - rflag = 0; - } else { - perror("couldn't get PPP compression stats"); - exit(1); - } - } - -#ifdef _linux_ - if (creq.stats.c.bytes_out == 0) { - creq.stats.c.bytes_out = creq.stats.c.comp_bytes + creq.stats.c.inc_bytes; - creq.stats.c.in_count = creq.stats.c.unc_bytes; - } - if (creq.stats.c.bytes_out == 0) - creq.stats.c.ratio = 0.0; - else - creq.stats.c.ratio = 256.0 * creq.stats.c.in_count / - creq.stats.c.bytes_out; - - if (creq.stats.d.bytes_out == 0) { - creq.stats.d.bytes_out = creq.stats.d.comp_bytes + creq.stats.d.inc_bytes; - creq.stats.d.in_count = creq.stats.d.unc_bytes; - } - if (creq.stats.d.bytes_out == 0) - creq.stats.d.ratio = 0.0; - else - creq.stats.d.ratio = 256.0 * creq.stats.d.in_count / - creq.stats.d.bytes_out; -#endif - - *csp = creq.stats; -} - -#else /* STREAMS */ - -int -strioctl(fd, cmd, ptr, ilen, olen) - int fd, cmd, ilen, olen; - char *ptr; -{ - struct strioctl str; - - str.ic_cmd = cmd; - str.ic_timout = 0; - str.ic_len = ilen; - str.ic_dp = ptr; - if (ioctl(fd, I_STR, &str) == -1) - return -1; - if (str.ic_len != olen) - fprintf(stderr, "strioctl: expected %d bytes, got %d for cmd %x\n", - olen, str.ic_len, cmd); - return 0; -} - -static void -get_ppp_stats(curp) - struct ppp_stats *curp; -{ - if (strioctl(s, PPPIO_GETSTAT, curp, 0, sizeof(*curp)) < 0) { - fprintf(stderr, "%s: ", progname); - if (errno == EINVAL) - fprintf(stderr, "kernel support missing\n"); - else - perror("couldn't get PPP statistics"); - exit(1); - } -} - -static void -get_ppp_cstats(csp) - struct ppp_comp_stats *csp; -{ - if (strioctl(s, PPPIO_GETCSTAT, csp, 0, sizeof(*csp)) < 0) { - fprintf(stderr, "%s: ", progname); - if (errno == ENOTTY) { - fprintf(stderr, "no kernel compression support\n"); - if (zflag) - exit(1); - rflag = 0; - } else { - perror("couldn't get PPP compression statistics"); - exit(1); - } - } -} - -#endif /* STREAMS */ - -#define MAX0(a) ((int)(a) > 0? (a): 0) -#define V(offset) MAX0(cur.offset - old.offset) -#define W(offset) MAX0(ccs.offset - ocs.offset) - -#define RATIO(c, i, u) ((c) == 0? 1.0: (u) / ((double)(c) + (i))) -#define CRATE(x) RATIO(W(x.comp_bytes), W(x.inc_bytes), W(x.unc_bytes)) - -#define KBPS(n) ((n) / (interval * 1000.0)) - -/* - * Print a running summary of interface statistics. - * Repeat display every interval seconds, showing statistics - * collected over that interval. Assumes that interval is non-zero. - * First line printed is cumulative. - */ -static void -intpr() -{ - register int line = 0; - sigset_t oldmask, mask; - char *bunit; - int ratef = 0; - struct ppp_stats cur, old; - struct ppp_comp_stats ccs, ocs; - - memset(&old, 0, sizeof(old)); - memset(&ocs, 0, sizeof(ocs)); - - while (1) { - get_ppp_stats(&cur); - if (zflag || rflag) - get_ppp_cstats(&ccs); - - (void)signal(SIGALRM, catchalarm); - signalled = 0; - (void)alarm(interval); - - if ((line % 20) == 0) { - if (zflag) { - printf("IN: COMPRESSED INCOMPRESSIBLE COMP | "); - printf("OUT: COMPRESSED INCOMPRESSIBLE COMP\n"); - bunit = dflag? "KB/S": "BYTE"; - printf(" %s PACK %s PACK RATIO | ", bunit, bunit); - printf(" %s PACK %s PACK RATIO", bunit, bunit); - } else { - printf("%8.8s %6.6s %6.6s", - "IN", "PACK", "VJCOMP"); - - if (!rflag) - printf(" %6.6s %6.6s", "VJUNC", "VJERR"); - if (vflag) - printf(" %6.6s %6.6s", "VJTOSS", "NON-VJ"); - if (rflag) - printf(" %6.6s %6.6s", "RATIO", "UBYTE"); - printf(" | %8.8s %6.6s %6.6s", - "OUT", "PACK", "VJCOMP"); - - if (!rflag) - printf(" %6.6s %6.6s", "VJUNC", "NON-VJ"); - if (vflag) - printf(" %6.6s %6.6s", "VJSRCH", "VJMISS"); - if (rflag) - printf(" %6.6s %6.6s", "RATIO", "UBYTE"); - } - putchar('\n'); - } - - if (zflag) { - if (ratef) { - printf("%8.3f %6u %8.3f %6u %6.2f", - KBPS(W(d.comp_bytes)), - W(d.comp_packets), - KBPS(W(d.inc_bytes)), - W(d.inc_packets), - ccs.d.ratio / 256.0); - printf(" | %8.3f %6u %8.3f %6u %6.2f", - KBPS(W(c.comp_bytes)), - W(c.comp_packets), - KBPS(W(c.inc_bytes)), - W(c.inc_packets), - ccs.c.ratio / 256.0); - } else { - printf("%8u %6u %8u %6u %6.2f", - W(d.comp_bytes), - W(d.comp_packets), - W(d.inc_bytes), - W(d.inc_packets), - ccs.d.ratio / 256.0); - printf(" | %8u %6u %8u %6u %6.2f", - W(c.comp_bytes), - W(c.comp_packets), - W(c.inc_bytes), - W(c.inc_packets), - ccs.c.ratio / 256.0); - } - - } else { - if (ratef) - printf("%8.3f", KBPS(V(p.ppp_ibytes))); - else - printf("%8u", V(p.ppp_ibytes)); - printf(" %6u %6u", - V(p.ppp_ipackets), - V(vj.vjs_compressedin)); - if (!rflag) - printf(" %6u %6u", - V(vj.vjs_uncompressedin), - V(vj.vjs_errorin)); - if (vflag) - printf(" %6u %6u", - V(vj.vjs_tossed), - V(p.ppp_ipackets) - V(vj.vjs_compressedin) - - V(vj.vjs_uncompressedin) - V(vj.vjs_errorin)); - if (rflag) { - printf(" %6.2f ", CRATE(d)); - if (ratef) - printf("%6.2f", KBPS(W(d.unc_bytes))); - else - printf("%6u", W(d.unc_bytes)); - } - if (ratef) - printf(" | %8.3f", KBPS(V(p.ppp_obytes))); - else - printf(" | %8u", V(p.ppp_obytes)); - printf(" %6u %6u", - V(p.ppp_opackets), - V(vj.vjs_compressed)); - if (!rflag) - printf(" %6u %6u", - V(vj.vjs_packets) - V(vj.vjs_compressed), - V(p.ppp_opackets) - V(vj.vjs_packets)); - if (vflag) - printf(" %6u %6u", - V(vj.vjs_searches), - V(vj.vjs_misses)); - if (rflag) { - printf(" %6.2f ", CRATE(c)); - if (ratef) - printf("%6.2f", KBPS(W(c.unc_bytes))); - else - printf("%6u", W(c.unc_bytes)); - } - - } - - putchar('\n'); - fflush(stdout); - line++; - - count--; - if (!infinite && !count) - break; - - sigemptyset(&mask); - sigaddset(&mask, SIGALRM); - sigprocmask(SIG_BLOCK, &mask, &oldmask); - if (!signalled) { - sigemptyset(&mask); - sigsuspend(&mask); - } - sigprocmask(SIG_SETMASK, &oldmask, NULL); - signalled = 0; - (void)alarm(interval); - - if (!aflag) { - old = cur; - ocs = ccs; - ratef = dflag; - } - } -} - -int -main(argc, argv) - int argc; - char *argv[]; -{ - int c; -#ifdef STREAMS - char *dev; -#endif - - interface = PPP_DRV_NAME "0"; - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - ++progname; - - while ((c = getopt(argc, argv, "advrzc:w:")) != -1) { - switch (c) { - case 'a': - ++aflag; - break; - case 'd': - ++dflag; - break; - case 'v': - ++vflag; - break; - case 'r': - ++rflag; - break; - case 'z': - ++zflag; - break; - case 'c': - count = atoi(optarg); - if (count <= 0) - usage(); - break; - case 'w': - interval = atoi(optarg); - if (interval <= 0) - usage(); - break; - default: - usage(); - } - } - argc -= optind; - argv += optind; - - if (!interval && count) - interval = 5; - if (interval && !count) - infinite = 1; - if (!interval && !count) - count = 1; - if (aflag) - dflag = 0; - - if (argc > 1) - usage(); - if (argc > 0) - interface = argv[0]; - - if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) { - fprintf(stderr, "%s: invalid interface '%s' specified\n", - progname, interface); - } - -#ifndef STREAMS - { - struct ifreq ifr; - - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) { - fprintf(stderr, "%s: ", progname); - perror("couldn't create IP socket"); - exit(1); - } - -#ifdef _linux_ -#undef ifr_name -#define ifr_name ifr_ifrn.ifrn_name -#endif - strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)); - if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { - fprintf(stderr, "%s: nonexistent interface '%s' specified\n", - progname, interface); - exit(1); - } - } - -#else /* STREAMS */ -#ifdef __osf__ - dev = "/dev/streams/ppp"; -#else - dev = "/dev/" PPP_DRV_NAME; -#endif - if ((s = open(dev, O_RDONLY)) < 0) { - fprintf(stderr, "%s: couldn't open ", progname); - perror(dev); - exit(1); - } - if (strioctl(s, PPPIO_ATTACH, &unit, sizeof(int), 0) < 0) { - fprintf(stderr, "%s: ppp%d is not available\n", progname, unit); - exit(1); - } - -#endif /* STREAMS */ - - intpr(); - exit(0); -} diff --git a/mdk-stage1/ppp/sample/auth-down b/mdk-stage1/ppp/sample/auth-down deleted file mode 100644 index edde65db1..000000000 --- a/mdk-stage1/ppp/sample/auth-down +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# -# A program or script which is executed after the remote system -# successfully authenticates itself. It is executed with the parameters -# <interface-name> <peer-name> <user-name> <tty-device> <speed> -# - -# -# The environment is cleared before executing this script -# so the path must be reset -# -PATH=/usr/sbin:/sbin:/usr/bin:/bin -export PATH - -echo auth-down `date +'%y/%m/%d %T'` $* >> /var/log/pppstats - -# last line diff --git a/mdk-stage1/ppp/sample/auth-up b/mdk-stage1/ppp/sample/auth-up deleted file mode 100644 index 54722a3c0..000000000 --- a/mdk-stage1/ppp/sample/auth-up +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# -# A program or script which is executed after the remote system -# successfully authenticates itself. It is executed with the parameters -# <interface-name> <peer-name> <user-name> <tty-device> <speed> -# - -# -# The environment is cleared before executing this script -# so the path must be reset -# -PATH=/usr/sbin:/sbin:/usr/bin:/bin -export PATH - -echo auth-up `date +'%y/%m/%d %T'` $* >> /var/log/pppstats - -# last line diff --git a/mdk-stage1/ppp/sample/ip-down b/mdk-stage1/ppp/sample/ip-down deleted file mode 100644 index b771fb644..000000000 --- a/mdk-stage1/ppp/sample/ip-down +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# -# This script is run by the pppd _after_ the link is brought down. -# It should be used to delete routes, unset IP addresses etc. -# -# This script is called with the following arguments: -# Arg Name Example -# $1 Interface name ppp0 -# $2 The tty ttyS1 -# $3 The link speed 38400 -# $4 Local IP number 12.34.56.78 -# $5 Peer IP number 12.34.56.99 -# - -# -# The environment is cleared before executing this script -# so the path must be reset -# -PATH=/usr/sbin:/sbin:/usr/bin:/bin -export PATH - -# last line diff --git a/mdk-stage1/ppp/sample/ip-up b/mdk-stage1/ppp/sample/ip-up deleted file mode 100644 index 02bb71c44..000000000 --- a/mdk-stage1/ppp/sample/ip-up +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -# -# This script is run by the pppd after the link is established. -# It should be used to add routes, set IP address, run the mailq -# etc. -# -# This script is called with the following arguments: -# Arg Name Example -# $1 Interface name ppp0 -# $2 The tty ttyS1 -# $3 The link speed 38400 -# $4 Local IP number 12.34.56.78 -# $5 Peer IP number 12.34.56.99 -# - -# -# The environment is cleared before executing this script -# so the path must be reset -# -PATH=/usr/sbin:/sbin:/usr/bin:/bin -export PATH - -# last line diff --git a/mdk-stage1/ppp/sample/options b/mdk-stage1/ppp/sample/options deleted file mode 100644 index 8d0a3f963..000000000 --- a/mdk-stage1/ppp/sample/options +++ /dev/null @@ -1,153 +0,0 @@ -# /etc/ppp/options - -# The name of this server. Often, the FQDN is used here. -#name <host> - -# Enforce the use of the hostname as the name of the local system for -# authentication purposes (overrides the name option). -usehostname - -# If no local IP address is given, pppd will use the first IP address -# that belongs to the local hostname. If "noipdefault" is given, this -# is disabled and the peer will have to supply an IP address. -noipdefault - -# With this option, pppd will accept the peer's idea of our local IP -# address, even if the local IP address was specified in an option. -#ipcp-accept-local - -# With this option, pppd will accept the peer's idea of its (remote) IP -# address, even if the remote IP address was specified in an option. -#ipcp-accept-remote - -# Specify which DNS Servers the incoming Win95 or WinNT Connection should use -# Two Servers can be remotely configured -#ms-dns 192.168.1.1 -#ms-dns 192.168.1.2 - -# Specify which WINS Servers the incoming connection Win95 or WinNT should use -#wins-addr 192.168.1.50 -#wins-addr 192.168.1.51 - -# enable this on a server that already has a permanent default route -#nodefaultroute - -# Run the executable or shell command specified after pppd has terminated -# the link. This script could, for example, issue commands to the modem -# to cause it to hang up if hardware modem control signals were not -# available. -# If mgetty is running, it will reset the modem anyway. So there is no need -# to do it here. -#disconnect "chat -- \d+++\d\c OK ath0 OK" - -# Increase debugging level (same as -d). The debug output is written -# to syslog LOG_LOCAL2. -debug - -# Enable debugging code in the kernel-level PPP driver. The argument n -# is a number which is the sum of the following values: 1 to enable -# general debug messages, 2 to request that the contents of received -# packets be printed, and 4 to request that the contents of transmitted -# packets be printed. -#kdebug n - -# Require the peer to authenticate itself before allowing network -# packets to be sent or received. -# Please do not disable this setting. It is expected to be standard in -# future releases of pppd. Use the call option (see manpage) to disable -# authentication for specific peers. -#auth - -# authentication can either be pap or chap. As most people only want to -# use pap, you can also disable chap: -#require-pap -#refuse-chap - -# Use hardware flow control (i.e. RTS/CTS) to control the flow of data -# on the serial port. -crtscts - -# Specifies that pppd should use a UUCP-style lock on the serial device -# to ensure exclusive access to the device. -lock - -# Use the modem control lines. -modem - -# async character map -- 32-bit hex; each bit is a character -# that needs to be escaped for pppd to receive it. 0x00000001 -# represents '\x01', and 0x80000000 represents '\x1f'. -# To allow pppd to work over a rlogin/telnet connection, ou should escape -# XON (^Q), XOFF (^S) and ^]: (The peer should use "escape ff".) -#asyncmap 200a0000 -asyncmap 0 - -# Specifies that certain characters should be escaped on transmission -# (regardless of whether the peer requests them to be escaped with its -# async control character map). The characters to be escaped are -# specified as a list of hex numbers separated by commas. Note that -# almost any character can be specified for the escape option, unlike -# the asyncmap option which only allows control characters to be -# specified. The characters which may not be escaped are those with hex -# values 0x20 - 0x3f or 0x5e. -#escape 11,13,ff - -# Set the MRU [Maximum Receive Unit] value to <n> for negotiation. pppd -# will ask the peer to send packets of no more than <n> bytes. The -# minimum MRU value is 128. The default MRU value is 1500. A value of -# 296 is recommended for slow links (40 bytes for TCP/IP header + 256 -# bytes of data). -#mru 542 - -# Set the MTU [Maximum Transmit Unit] value to <n>. Unless the peer -# requests a smaller value via MRU negotiation, pppd will request that -# the kernel networking code send data packets of no more than n bytes -# through the PPP network interface. -#mtu <n> - -# Set the interface netmask to <n>, a 32 bit netmask in "decimal dot" -# notation (e.g. 255.255.255.0). -#netmask 255.255.255.0 - -# Don't fork to become a background process (otherwise pppd will do so -# if a serial device is specified). -nodetach - -# Set the assumed name of the remote system for authentication purposes -# to <n>. -#remotename <n> - -# Add an entry to this system's ARP [Address Resolution Protocol] -# table with the IP address of the peer and the Ethernet address of this -# system. {proxyarp,noproxyarp} -proxyarp - -# Use the system password database for authenticating the peer using -# PAP. Note: mgetty already provides this option. If this is specified -# then dialin from users using a script under Linux to fire up ppp wont work. -#login - -# If this option is given, pppd will send an LCP echo-request frame to -# the peer every n seconds. Under Linux, the echo-request is sent when -# no packets have been received from the peer for n seconds. Normally -# the peer should respond to the echo-request by sending an echo-reply. -# This option can be used with the lcp-echo-failure option to detect -# that the peer is no longer connected. -lcp-echo-interval 30 - -# If this option is given, pppd will presume the peer to be dead if n -# LCP echo-requests are sent without receiving a valid LCP echo-reply. -# If this happens, pppd will terminate the connection. Use of this -# option requires a non-zero value for the lcp-echo-interval parameter. -# This option can be used to enable pppd to terminate after the physical -# connection has been broken (e.g., the modem has hung up) in -# situations where no hardware modem control lines are available. -lcp-echo-failure 4 - -# Specifies that pppd should disconnect if the link is idle for n seconds. -idle 600 - -# Disable the IPXCP and IPX protocols. -noipx - -# ---<End of File>--- diff --git a/mdk-stage1/ppp/sample/options.ttyXX b/mdk-stage1/ppp/sample/options.ttyXX deleted file mode 100644 index d4202f534..000000000 --- a/mdk-stage1/ppp/sample/options.ttyXX +++ /dev/null @@ -1,14 +0,0 @@ -# If you need to set up multiple serial lines then copy this file to -# options.<ttyname> for each tty with a modem on it. -# -# The options.tty file will assign an IP address to each PPP connection -# as it comes up. They must all be distinct! -# -# Example: -# options.ttyS1 for com2 under DOS. -# -# Edit the following line so that the first IP address -# mentioned is the ip address of the serial port while the second -# is the IP address of your host -# -hostname-s1:hostname diff --git a/mdk-stage1/ppp/sample/pap-secrets b/mdk-stage1/ppp/sample/pap-secrets deleted file mode 100644 index 098971b9f..000000000 --- a/mdk-stage1/ppp/sample/pap-secrets +++ /dev/null @@ -1,28 +0,0 @@ -# Secrets for authentication using PAP -# client server secret IP addresses - -# OUTBOUND CONNECTIONS -# Here you should add your userid password to connect to your providers via -# pap. The * means that the password is to be used for ANY host you connect -# to. Thus you do not have to worry about the foreign machine name. Just -# replace password with your password. -# If you have different providers with different passwords then you better -# remove the following line. -#hostname * password - -# INBOUND CONNECTIONS -#client hostname <password> 192.168.1.1 - -# If you add "auth login -chap +pap" to /etc/mgetty+sendfax/login.config, -# all users in /etc/passwd can use their password for pap-authentication. -# -# Every regular user can use PPP and has to use passwords from /etc/passwd -#* hostname "" -# UserIDs that cannot use PPP at all. Check your /etc/passwd and add any -# other accounts that should not be able to use pppd! Replace hostname -# with your local hostname. -#guest hostname "*" - -#master hostname "*" - -#root hostname "*" - -#support hostname "*" - -#stats hostname "*" - diff --git a/mdk-stage1/ppp/scripts/README b/mdk-stage1/ppp/scripts/README deleted file mode 100644 index 00e032ca6..000000000 --- a/mdk-stage1/ppp/scripts/README +++ /dev/null @@ -1,143 +0,0 @@ -This directory contains a set of scripts which have been used on Linux -as well as Solaris 2.x systems to initiate or maintain a connection -with PPP. The files in this directory were contributed by Al Longyear -(longyear@netcom.com) and Adi Masputra (adi.masputra@sun.com) - ------------------------------------------------------------------------- - -1. README - -This file. You are reading it. It is just documentation. - ------------------------------------------------------------------------- - -2. ppp-on - -This script will initiate a connection to the PPP system. It will run -the chat program with the connection script as a parameter. This is a -possible security hole. However, it is simple. It is meant to replace -the previous version of ppp-on which was not very functional. - -The ppp-on script has entries for the account name, password, IP -addresses, and telephone numbers. The parameters are passed to the -pppd process and, then in turn, to the second part of the connect -script, as a set of environment variables. - -Please make sure that you put the full path name to the ppp-on-dialer -script in the reference to it in ppp-on. - ------------------------------------------------------------------------- - -3. ppp-on-dialer - -This is the second part to the simple calling script, ppp-on. It -executes the chat program to connect the user with a standard UNIX -style getty/login connection sequence. - ------------------------------------------------------------------------- - -4. callback - -This script may be used in lieu of the ppp-on-dialer to permit the -common modem callback sequence. You may need to make changes to the -expected prompt string for the modem. - -The script works by disabling the system's detection of the DCD -condition and working on the modem status message "NO CARRIER" which -is generated when the modem disconnects. - -It is crude. It does work for my modem connection. Use as you see fit. - ------------------------------------------------------------------------- - -5. redialer - -The redialer script is a replacement for the ppp-on-dialer script. It -will do 'attack dialing' or 'demon dialing' of one or more telephone -numbers. The first number which responds will be used for a -connection. - -There is a limit of ten attempts and a 15 second delay between dialing -attempts. Both values are set in the script. - ------------------------------------------------------------------------- - -6. ppp-off - -This is a script which will terminate the active ppp connection. Use -as either "ppp-off" to terminate ppp0, or "ppp-off <device>" to -terminate the connection on <device>. For example, "ppp-off ppp2" will -terminate the ppp2 connection. - ------------------------------------------------------------------------- - -7. secure-card - -This script was written by Jim Isaacson <jcisaac@crl.com>. It is a script -for the 'expect' programming language used with Tcl. You need to have -expect and Tcl installed before this script may be used. - -This script will operate with a device marketed under the name "SecureCARD". -This little device is mated with its controller. On the credit card size -device, there is a sequence number which changes on a random basis. In order -for you to connect you need to enter a fixed portion of your account name -and the number which is displayed on this card device. The number must match -the value at the controller in order for the account name to be used. - -The problem is that chat uses fixed response strings. In addition, the -timing for running the script may prevent the use of a script that reads the -value before it starts the dial sequence. What was needed was a script which -asked the user at the user's console at the time that it is needed. - -This led to the use of expect. - ------------------------------------------------------------------------- - -8. ppp-on-rsh - -This script will initiate a PPP connection to a remote machine using rsh. -This is implemented by creating a master/slave pseudo-tty with the slave -pointing to rsh, specifically with the 'pty' and 'notty' options of pppd. -It is assumed that the remote machine contains some sort of trust -mechanisms (such as ~/.rhosts, et al) to allow the local machine to -connect via rsh as root. - ------------------------------------------------------------------------- - -9. ppp-on-ssh - -This script will initiate a PPP connection to a remote machine using the -secure shell, or ssh. I've only tested this on ssh 1.x, so those of you -who are running ssh 2.x mahy need to modify the ssh options slightly. -This is implemented by creating a master/slave pseudo-ttyt with the slave -pointing to ssh, specifically with the 'pty' and 'notty' options of pppd. -It is assumed that the remote machine can accept the ssh connection from -the local host, in the sense that all ssh authentication mechanisms have -been properly configured, so that a remote root user can open a ssh -connection. - ------------------------------------------------------------------------- - -10. options-rsh-loc & options-rsh-rem - -These options files accompany the ppp-on-rsh script mentioned above. In -theory, you'd want to copy the options-rsh-rem to the remote machine where -in.rshd is running. The only extra option required on the remote machine -options file is the 'notty' option. In addition, all ASCII control characters -[0x00 to 0x1f], plus 0xff, are escaped. This may need to be modified -depending on the rsh (or pseudo-tty) implementation which may differ across -platforms, for further optimizations. - ------------------------------------------------------------------------- - -11. options-ssh-loc & options-ssh-rem - -These options files accompany the ppp-on-ssh script mentioned above. I've -only tested this on ssh 1.x, so those of you who are running ssh 2.x need -to modify the ssh options slightly. In theory, you'd want to copy the -options-ssh-rem to the remote machine where sshd daemon is running. The only -extra options required on the remote machine options file is the 'notty' -option. In addition, all ASCII control characters [0x00 to 0x1f], plus 0xff, -are escaped. This may need to be modified depending on the ssh (or -pseudo-tty) implementation which may differ across platforms, for further -optimizations. diff --git a/mdk-stage1/ppp/scripts/callback b/mdk-stage1/ppp/scripts/callback deleted file mode 100755 index 3e74e10b2..000000000 --- a/mdk-stage1/ppp/scripts/callback +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/sh -################################################################### -# -# Script to dial the remote system, negotiate the connection, and send -# it the id. Then wait for the modem to disconnect. Reset the modem -# to answer mode and wait for the system to call back. -# -# The telephone number and modempass are used when establishing the -# connection to the modem. -# -PHONE=555-1212 -MODEMPASS=modem_identifier -# -# Once the modem calls back, the account name and password are used for -# a UNIX style login operation. -# -ACCOUNT=my_account_name -PASSWORD=my_password - -################################################################### -# -# Step 1. Dial the modem and negotiate the initial dialog. -# note: the modem is configured to ignore loss of DCD at this point. -# it is important that this be performed because the loss of DCD -# will normally prevent system from working since 'modem' is used -# for pppd. -# -# The script is terminated normally when the carrier is lost. -# -chat -v \ - TIMEOUT 3 \ - ABORT '\nBUSY\r' \ - ABORT '\nNO ANSWER\r' \ - ABORT '\nRINGING\r\n\r\nRINGING\r' \ - '' AT \ - 'OK-+++\c-OK' 'AT&C0&D2S0=0H0 \ - TIMEOUT 30 \ - OK ATDT$TELEPHONE \ - CONNECT '' \ - assword: $MODEMPASS \ - "\nNO CARRIER\r" - -if [ "$?" = "0" ]; then - -################################################################### -# -# Step 2. Wait for the call back from the remote. This will wait for at most -# 30 seconds for the call back should the first attempt fail or -# something happen with the callback logic at the remote. -# -# note: when the callback occurs, the DCD setting is re-enabled. -# -# If some voice call should happen during this period, the system will -# answer the telephone and then hang up on them. I realize that this is -# rude, but there is little that this script can do. -# - chat -v \ - TIMEOUT 30 \ - ABORT '\nVOICE\r' \ - '\nRING\r' 'AT&C1A' \ - CONNECT '' \ - TIMEOUT 10 \ - ogin:--ogin: $ACCOUNT \ - TIMEOUT 45 \ - assword: $PASSWORD - - if [ "$?" = "0" ]; then - exit 0 - fi -fi - -################################################################### -# -# The script has failed. Terminate the connection mode. -# -chat -v TIMEOUT 3 "" AT 'OK-+++\c-OK' 'AT&C1&D2S0=0H0' OK -exit 1 diff --git a/mdk-stage1/ppp/scripts/chat-callback b/mdk-stage1/ppp/scripts/chat-callback deleted file mode 100644 index d014d6af3..000000000 --- a/mdk-stage1/ppp/scripts/chat-callback +++ /dev/null @@ -1,98 +0,0 @@ -# ===================================================================================== -# Chat script to dial our Company PPP account. -# They uses a call-back system to identify us and to reverse -# charge the call cost. -# ===================================================================================== -# -ECHO OFF -# All the usual abort strings -ABORT "NO CARRIER" -ABORT "VOICE" -ABORT "BUSY" -ABORT "NO DIALTONE" -ABORT "NO ANSWER" -# -# If calling outside allowed time we get this: -# -ABORT "Access denied" -# -# Modem initialisation stuff -# -TIMEOUT 5 -SAY "Initialising modem ...\n" -'' ATE1 -'OK\r\n' ATS0=1S11=60X4&K4S42.1=1 -# -# Now dial our ISP and wait for connection -# -SAY "Dialling our ISP ...\n" -'OK\r\n' ATDT09834657 -TIMEOUT 60 -CONNECT \c -SAY "Connected ...\n" -# -# This is the first stage login, we identify ourself so that the remote -# system will agree to call us back. -# -TIMEOUT 30 -SAY "Sending Callback login ID ...\n" -name:-BREAK-name: callme -# -# From now on, we must assume no carrier is normal as well -# as receiving a HANGUP signal because it will be the -# case if our ISP clears the call to call us back. -# -CLR_ABORT "NO CARRIER" -HANGUP OFF -# -ABORT "Invalid" -# -# Now send password and wait to see what happens -# -SAY "Sending Callback password ...\n" -word:--word: xvsgsgs -"You will be" \c -# -# What can happen now is: -# either: we get "You will be called back..." which is the successful case -# or: we get "Invalid login" and we abort (bad login ID or password) -# or: we get "NO CARRIER" because of an error, this will not abort -# and we will time out after 30 seconds -# or: we get nothing and we will time out after 30 seconds -# -# -# We reach here if we got "You will be called back..." -# -CLR_ABORT "Invalid" -SAY "Now waiting for Call back ...\n" -# -# The remote system will now hangup and we will get both "NO CARRIER" -# and a hangup signal which are ignored. We now wait for a connection -# for up to 120 seconds. What happens here if somebody else calls before -# the remote system is a bit dangerous: -# -# If a malicious user connects and says 'name:', he will see 'PPPuser' -# If he then says 'word:' he will see the passowrd 'blipblop'. I may not -# know to which systems these belong to, though. It is up to you to consider -# that case and decide wether the risk is too big or not .... -# -TIMEOUT 120 -"CONNECT" \c -# -# We have been called, re-arm ABORT on NO CARRIER and normal hangup signal -# behaviour -# -HANGUP ON -ABORT "NO CARRIER" -# -# Second stage login in order to start PPP -# -SAY "Remote system called back, logging in ...\n" -SAY "Sending login ID ...\n" -name:-BREAK-name: PPPuser -SAY "Sending password ...\n" -word:--word: blipblop -SAY "Asking to start PPP ...\n" -'CnetSrv' "ppp default" -"Entering PPP mode" \c -SAY "ISP PPP started ...\n" diff --git a/mdk-stage1/ppp/scripts/chatchat/README b/mdk-stage1/ppp/scripts/chatchat/README deleted file mode 100644 index 88a4c6939..000000000 --- a/mdk-stage1/ppp/scripts/chatchat/README +++ /dev/null @@ -1,134 +0,0 @@ -v 0.1 gpk@onramp.net 3/27/99 - -I Intro - - This document covers the use of the modified "chat" program and its -adjunct "chatchat" to login using the Security Dynamics SecurID card -on a linux system. - - This set of files comprises a modified version of the chat program -(the one distributed with ppp-2.3.5) and a new program called chatchat -that allows you to supply data from the keyboard to the chat program. - - The SecurID card generates passwords that have a lifetime of one -minute and are used as a first layer in dial up security. The only -software I know of for this card is for windows, so I wrote my own. -This software allows you to type in the time-sensitive password right -when your chat script is asked to supply the passcode by the remote -system. - - -II How It Works - - This version of chat his an additional command that can be put into -its options that says "Don't reply with this string. Open this pipe, -read the contents, and reply with that instead." Chatchat creates a -pipe and lets you type your passcode into it, then chat picks that up -and sends it out just as though the passcode was hardcoded into the -options. - - -III Installation - - I've provided intel binaries and source code the the modified chat -program and the chatchat program. I'll recommend that you copy the -chat.c program into your ppp-2.3.5/chat directory (save your original -chat.c program first!) and re-make it using the Makefile that comes -with chat. Copy the new chat somewhere into your path. (On my system -chat lives in /usr/sbin/chat, so I've copied the modified one into -/usr/sbin/chat.new and changed my dial in script to call chat.new -instead of chat. - - Second, compile chatchat.c and install it somewhere in your path: - - gcc -g -o chatchat chatchat.c - cp chatchat /usr/sbin - - Third, modify your chat script to use the chatchat program. Mine -looks something like this: - - - -------------------- - -#!/bin/sh -# -# This is part 2 of the ppp-on script. It will perform the connection -# protocol for the desired connection. -# use atm0 to turn down the speaker volume on my sportster x2 voice modem -# gpk 11/2/97 - -exec /usr/sbin/chat.new -V -v \ - ABORT "BUSY" \ - ABORT "NO DIAL TONE" \ - ABORT "NO ANSWER" \ - TIMEOUT 50 \ - "" "atm0" \ - OK ATDT$TELEPHONE \ - CONNECT '' \ - name: \\da0xxxxxx \ - word: @/var/tmp/p \ - compress. '' - - - ----------------------- - - This is a standard chat script: - -* abort if the modem is busy, you don't get a dial tone, no one - answers, or 50 seconds elapses. - -* use atm0 to mute the modem - -* dial the modem, when it connects, wait to be asked for account name - -* when we see "name:" prompt, delay briefly then respond with your - account name (fill in your account name) - -Now we get to the new stuff: - -* when we see "word:" in the password prompt, instead of responding - with "@/var/tmp/p", the modified chat program will open the pipe - /var/tmp/p, read the passcode out of there, and send it - -* when we see "compress." (the last word before ppp starts), reply - with nothing. The script ends and we start ppp. - -Note: - -* Make sure there is some whitespace between the filename and the \. - - -IV Usage - - To use this install the modified chat and chatchat programs, and -modify your chat script similar to the above. Before you dial in, -start that chatchat program giving it the same pipe as in your config -file. In the above case: - -chatchat /var/tmp/p - - Wait until you have one or two tick marks left on your card's -current number, then start your dial up process that eventually calls -chat. When chat goes to open and read the pipe, chatchat will prompt: - - -type PIN into SecurID card and - enter resulting passcode: - - At that point, type your PIN number into your Securid card, press -the diamond, and type the resulting numbers in as your passcode. If -you've left the -V -v options on your chat command you'll see -everything so out, otherwise it works silently. - - If you type the number wrong or run out of time, the server will -respond with an authentication failure. In that case you will have to -hang up and start again. I don't know how to build a conditional script -that says either expect "compress" next, but if you see "name:" again, -do this instead. - - -V Additional Information - - You can obtain additional information about chat and ppp from the -man pages for chat and pppd, as well as the PPP-HOWTO. - diff --git a/mdk-stage1/ppp/scripts/chatchat/chatchat.c b/mdk-stage1/ppp/scripts/chatchat/chatchat.c deleted file mode 100644 index 4534fb9e3..000000000 --- a/mdk-stage1/ppp/scripts/chatchat/chatchat.c +++ /dev/null @@ -1,409 +0,0 @@ -/* ************************************************************************* -* NAME: chatchat.c -* -* DESCRIPTION: -* -* This program creates a pipe for the chat process to read. The user -* can supply information (like a password) that will be picked up -* by chat and sent just like the regular contents of a chat script. -* -* Usage is: -* -* chatchat <filename> -* -* where <filename> matches the option given in the chat script. -* -* for instance the chat script fragment: -* -* ... -* name: \\dmyname \ -* word: @/var/tmp/p \ -* ... -* ^ -* (note: leave some whitespace after the filename) -* -* expect "name:", reply with a delay followed by "myname" -* expect "word:", reply with the data read from the pipe /var/tmp/p -* -* the matching usage of chatchat would be: -* -* chatchat /var/tmp/p -* -* eg: -* -* $chatchat /var/tmp/p -* ... -* some other process eventually starts: -* chat ... -* chat parses the "@/var/tmp/p" option and opens -* /var/tmp/p -* (chatchat prompts:) -* -* type PIN into SecurID card -* enter resulting passcode: [user inputs something] -* -* chat reads /var/tmp/p & gets what the -* user typed at chatchat's "enter string" prompt -* chat removes the pipe file -* chat sends the user's input as a response in -* place of "@/var/tmp/p" -* -* PROCESS: -* -* gcc -g -o chatchat chatchat.c -* -* -* GLOBALS: none -* -* REFERENCES: -* -* see the man pages and documentation that come with the 'chat' program -* (part of the ppp package). you will need to use the modified chat -* program that accepts the '@' operator. -* -* LIMITATIONS: -* -* REVISION HISTORY: -* -* STR Description Author -* -* 23-Mar-99 initial coding gpk -* 12-May-99 unlink the pipe after closing paulus -* -* TARGET: ANSI C -* This program is in the public domain. -* -* -* ************************************************************************* */ - - - - -#include <sys/time.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> - -/* MAXINPUT - the data typed into chatchat must be fewer */ -/* characters than this. */ - -#define MAXINPUT 80 - - - - - - -/* ************************************************************************* - - - NAME: main - - - USAGE: - - int argc; - char * argv[]; - - main(argc, argv[]); - - returns: int - - DESCRIPTION: - if the pipe file name is given on the command line, - create the pipe, prompt the user and put whatever - is typed into the pipe. - - returns -1 on error - else # characters entered - REFERENCES: - - LIMITATIONS: - - GLOBAL VARIABLES: - - accessed: none - - modified: none - - FUNCTIONS CALLED: - - REVISION HISTORY: - - STR Description of Revision Author - - 25-Mar-99 initial coding gpk - - ************************************************************************* */ - -int main(int argc, char * argv[]) -{ - int retval; - - int create_and_write_pipe(char * pipename); - - if (argc != 2) - { - fprintf(stderr, "usage: %s pipename\n", argv[0]); - retval = -1; - } - else - { - retval = create_and_write_pipe(argv[1]); - } - return (retval); -} - - - - -/* ************************************************************************* - - - NAME: create_and_write_pipe - - - USAGE: - - int some_int; - char * pipename; - - some_int = create_and_write_pipe(pipename); - - returns: int - - DESCRIPTION: - given the pipename, create the pipe, open it, - prompt the user for a string to put into the - pipe, write the string, and close the pipe - - on error, print out an error message and return -1 - - returns -1 on error - else #bytes written into the pipe - REFERENCES: - - LIMITATIONS: - - GLOBAL VARIABLES: - - accessed: none - - modified: none - - FUNCTIONS CALLED: - - REVISION HISTORY: - - STR Description of Revision Author - - 25-Mar-99 initial coding gpk - 12-May-99 remove pipe after closing paulus - - ************************************************************************* */ - -int create_and_write_pipe(char * pipename) -{ - int retval, created, pipefd, nread, nwritten; - char input[MAXINPUT]; - char errstring[180]; - - int create_pipe(char * pipename); - int write_to_pipe(int pipefd, char * input, int nchar); - - created = create_pipe(pipename); - - if (-1 == created) - { - sprintf(errstring, "unable to create pipe '%s'", pipename); - perror(errstring); - retval = -1; - } - else - { - - /* note: this open won't succeed until chat has the pipe */ - /* open and ready to read. this makes for nice timing. */ - - pipefd = open(pipename, O_WRONLY); - - if (-1 == pipefd) - { - sprintf(errstring, "unable to open pipe '%s'", pipename); - perror(errstring); - retval = -1; - } - else - { - fprintf(stderr, "%s \n %s", - "type PIN into SecurID card and", - "enter resulting passcode:"); - nread = read(STDIN_FILENO, (void *)input, MAXINPUT); - - - if (0 >= nread) - { - perror("unable to read from stdin"); - retval = -1; - } - else - { - /* munch off the newline character, chat supplies */ - /* a return when it sends the string out. */ - input[nread -1] = 0; - nread--; - nwritten = write_to_pipe(pipefd, input, nread); - /* printf("wrote [%d]: '%s'\n", nwritten, input); */ - retval = nwritten; - } - close(pipefd); - - /* Now make the pipe go away. It won't actually go away - completely until chat closes it. */ - if (unlink(pipename) < 0) - perror("Warning: couldn't remove pipe"); - } - } - return(retval); -} - - - - - - - -/* ************************************************************************* - - - NAME: create_pipe - - - USAGE: - - int some_int; - char * pipename; - - some_int = create_pipe(pipename); - - returns: int - - DESCRIPTION: - create a pipe of the given name - - if there is an error (like the pipe already exists) - print an error message and return - - return -1 on failure else success - - REFERENCES: - - LIMITATIONS: - - GLOBAL VARIABLES: - - accessed: none - - modified: none - - FUNCTIONS CALLED: - - REVISION HISTORY: - - STR Description of Revision Author - - 25-Mar-99 initial coding gpk - - ************************************************************************* */ - -int create_pipe(char * pipename) -{ - mode_t old_umask; - int created; - - /* hijack the umask temporarily to get the mode I want */ - /* on the pipe. */ - - old_umask = umask(000); - - created = mknod(pipename, S_IFIFO | S_IRWXU | S_IWGRP | S_IWOTH, - (dev_t)NULL); - - /* now restore umask. */ - - (void)umask(old_umask); - - if (-1 == created) - { - perror("unable to create pipe"); - } - - return(created); -} - - - - - - -/* ************************************************************************* - - - NAME: write_to_pipe - - - USAGE: - - int some_int; - int pipefd; - char * input; - int nchar; - - some_int = write_to_pipe(pipefd, input, nchar); - - returns: int - - DESCRIPTION: - write nchars of data from input to pipefd - - on error print a message to stderr - - return -1 on error, else # bytes written - REFERENCES: - - LIMITATIONS: - - GLOBAL VARIABLES: - - accessed: none - - modified: none - - FUNCTIONS CALLED: - - REVISION HISTORY: - - STR Description of Revision Author - - 25-Mar-99 initial coding gpk - 12-May-99 don't write count word first paulus - - ************************************************************************* */ - -int write_to_pipe(int pipefd, char * input, int nchar) -{ - int nwritten; - - /* nwritten = write(pipefd, (void *)&nchar, sizeof(nchar)); */ - nwritten = write(pipefd, (void *)input, nchar); - - if (-1 == nwritten) - { - perror("unable to write to pipe"); - } - - return(nwritten); -} diff --git a/mdk-stage1/ppp/scripts/ip-down.local.add b/mdk-stage1/ppp/scripts/ip-down.local.add deleted file mode 100644 index b93590e49..000000000 --- a/mdk-stage1/ppp/scripts/ip-down.local.add +++ /dev/null @@ -1,20 +0,0 @@ - -# -# This sample code shows you one way to modify your setup to allow automatic -# configuration of your resolv.conf for peer supplied DNS addresses when using -# the `usepeerdns' option. -# -# In my case I just added this to my /etc/ppp/ip-down.local script. You may need to -# create an executable script if one does not exist. -# -# Nick Walker (nickwalker@email.com) -# - -if [ -n "$USEPEERDNS" -a -f /etc/ppp/resolv.conf ]; then - if [ -f /etc/ppp/resolv.prev ]; then - cp -f /etc/ppp/resolv.prev /etc/resolv.conf - else - rm -f /etc/resolv.conf - fi -fi - diff --git a/mdk-stage1/ppp/scripts/ip-up.local.add b/mdk-stage1/ppp/scripts/ip-up.local.add deleted file mode 100644 index 80172093a..000000000 --- a/mdk-stage1/ppp/scripts/ip-up.local.add +++ /dev/null @@ -1,24 +0,0 @@ - -# -# This sample code shows you one way to modify your setup to allow automatic -# configuration of your resolv.conf for peer supplied DNS addresses when using -# the `usepeerdns' option. -# -# In my case I just added this to my /etc/ppp/ip-up.local script. You may need to -# create an executable script if one does not exist. -# -# Nick Walker (nickwalker@email.com) -# - -if [ -n "$USEPEERDNS" -a -f /etc/ppp/resolv.conf ]; then - rm -f /etc/ppp/resolv.prev - if [ -f /etc/resolv.conf ]; then - cp /etc/resolv.conf /etc/ppp/resolv.prev - grep domain /etc/ppp/resolv.prev > /etc/resolv.conf - grep search /etc/ppp/resolv.prev >> /etc/resolv.conf - cat /etc/ppp/resolv.conf >> /etc/resolv.conf - else - cp /etc/ppp/resolv.conf /etc - fi -fi - diff --git a/mdk-stage1/ppp/scripts/options-rsh-loc b/mdk-stage1/ppp/scripts/options-rsh-loc deleted file mode 100644 index b015b87fe..000000000 --- a/mdk-stage1/ppp/scripts/options-rsh-loc +++ /dev/null @@ -1 +0,0 @@ -debug asyncmap FFFFFFFF escape FF kdebug 0 noipdefault nodefaultroute noauth mtu 1460 diff --git a/mdk-stage1/ppp/scripts/options-rsh-rem b/mdk-stage1/ppp/scripts/options-rsh-rem deleted file mode 100644 index 4b10bb9e9..000000000 --- a/mdk-stage1/ppp/scripts/options-rsh-rem +++ /dev/null @@ -1 +0,0 @@ -notty debug asyncmap FFFFFFFF escape FF kdebug 0 noipdefault nodefaultroute noauth mtu 1460 diff --git a/mdk-stage1/ppp/scripts/options-ssh-loc b/mdk-stage1/ppp/scripts/options-ssh-loc deleted file mode 100644 index add03d659..000000000 --- a/mdk-stage1/ppp/scripts/options-ssh-loc +++ /dev/null @@ -1 +0,0 @@ -debug asyncmap FFFFFFFF escape FF kdebug 0 noipdefault nodefaultroute noauth mtu 1400 diff --git a/mdk-stage1/ppp/scripts/options-ssh-rem b/mdk-stage1/ppp/scripts/options-ssh-rem deleted file mode 100644 index d690722c6..000000000 --- a/mdk-stage1/ppp/scripts/options-ssh-rem +++ /dev/null @@ -1 +0,0 @@ -notty debug asyncmap FFFFFFFF escape FF kdebug 0 noipdefault nodefaultroute noauth mtu 1400 diff --git a/mdk-stage1/ppp/scripts/ppp-off b/mdk-stage1/ppp/scripts/ppp-off deleted file mode 100755 index a22b5ea3d..000000000 --- a/mdk-stage1/ppp/scripts/ppp-off +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh -###################################################################### -# -# Determine the device to be terminated. -# -if [ "$1" = "" ]; then - DEVICE=ppp0 -else - DEVICE=$1 -fi - -###################################################################### -# -# If the ppp0 pid file is present then the program is running. Stop it. -if [ -r /var/run/$DEVICE.pid ]; then - kill -INT `cat /var/run/$DEVICE.pid` -# -# If the kill did not work then there is no process running for this -# pid. It may also mean that the lock file will be left. You may wish -# to delete the lock file at the same time. - if [ ! "$?" = "0" ]; then - rm -f /var/run/$DEVICE.pid - echo "ERROR: Removed stale pid file" - exit 1 - fi -# -# Success. Let pppd clean up its own junk. - echo "PPP link to $DEVICE terminated." - exit 0 -fi -# -# The ppp process is not running for ppp0 -echo "ERROR: PPP link is not active on $DEVICE" -exit 1 diff --git a/mdk-stage1/ppp/scripts/ppp-on b/mdk-stage1/ppp/scripts/ppp-on deleted file mode 100755 index ab79db471..000000000 --- a/mdk-stage1/ppp/scripts/ppp-on +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# -# Script to initiate a ppp connection. This is the first part of the -# pair of scripts. This is not a secure pair of scripts as the codes -# are visible with the 'ps' command. However, it is simple. -# -# These are the parameters. Change as needed. -TELEPHONE=555-1212 # The telephone number for the connection -ACCOUNT=george # The account name for logon (as in 'George Burns') -PASSWORD=gracie # The password for this account (and 'Gracie Allen') -LOCAL_IP=0.0.0.0 # Local IP address if known. Dynamic = 0.0.0.0 -REMOTE_IP=0.0.0.0 # Remote IP address if desired. Normally 0.0.0.0 -NETMASK=255.255.255.0 # The proper netmask if needed -# -# Export them so that they will be available at 'ppp-on-dialer' time. -export TELEPHONE ACCOUNT PASSWORD -# -# This is the location of the script which dials the phone and logs -# in. Please use the absolute file name as the $PATH variable is not -# used on the connect option. (To do so on a 'root' account would be -# a security hole so don't ask.) -# -DIALER_SCRIPT=/etc/ppp/ppp-on-dialer -# -# Initiate the connection -# -# I put most of the common options on this command. Please, don't -# forget the 'lock' option or some programs such as mgetty will not -# work. The asyncmap and escape will permit the PPP link to work with -# a telnet or rlogin connection. You are welcome to make any changes -# as desired. Don't use the 'defaultroute' option if you currently -# have a default route to an ethernet gateway. -# -exec /usr/sbin/pppd debug lock modem crtscts /dev/ttyS0 38400 \ - asyncmap 20A0000 escape FF kdebug 0 $LOCAL_IP:$REMOTE_IP \ - noipdefault netmask $NETMASK defaultroute connect $DIALER_SCRIPT diff --git a/mdk-stage1/ppp/scripts/ppp-on-dialer b/mdk-stage1/ppp/scripts/ppp-on-dialer deleted file mode 100755 index 7d66765f1..000000000 --- a/mdk-stage1/ppp/scripts/ppp-on-dialer +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# -# This is part 2 of the ppp-on script. It will perform the connection -# protocol for the desired connection. -# -exec chat -v \ - TIMEOUT 3 \ - ABORT '\nBUSY\r' \ - ABORT '\nNO ANSWER\r' \ - ABORT '\nRINGING\r\n\r\nRINGING\r' \ - '' \rAT \ - 'OK-+++\c-OK' ATH0 \ - TIMEOUT 30 \ - OK ATDT$TELEPHONE \ - CONNECT '' \ - ogin:--ogin: $ACCOUNT \ - assword: $PASSWORD diff --git a/mdk-stage1/ppp/scripts/ppp-on-rsh b/mdk-stage1/ppp/scripts/ppp-on-rsh deleted file mode 100755 index 30a50dba6..000000000 --- a/mdk-stage1/ppp/scripts/ppp-on-rsh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh -# -# A sample script to establish PPP session(s) via rsh -# -# Adi Masputra <adi.masputra@sun.com> -# Jan 24, 2000 -# - -# -# You'd definitely want to change the following addresses to suit -# your network configuration -# -LOC_IP=10.0.0.1 -REM_IP=10.0.0.2 -NETMASK=255.255.0.0 - -export LOC_IP REM_IP - -# -# This is the remote peer where in.rshd is running, either -# its hostname or IP address -# -PPPD_RHOST=myremotehost - -# -# For this example, we assume that pppd on both local and remote -# machines reside in the same place, /usr/local/bin/pppd -# -PPPD_LOC=/usr/local/bin/pppd - -# -# The location of local options file (where rsh client is running). -# Note that the sample options file included in the distribution -# may need further customizations, depending on your needs. The 'noauth' -# option specified in the file is there to simplify the example. In -# reality, you'd probably want to remove such option. -# -PPPD_LOC_OPT=/etc/ppp/options-rsh-loc - -# -# The location of remote options file (where in.rshd daemon is running). -# Note that the sample options file included in the distribution -# may need further customizations, depending on your needs. The 'noauth' -# option specified in the file is there to simplify the example. In -# reality, you'd probably want to remove such option. Also note that -# the remote options file need to include the 'notty' option for this -# to work -# -PPPD_REM_OPT=/etc/ppp/options-rsh-rem - -# -# The location of rsh client on the local machine -# -RSH_LOC=/bin/rsh - -export PPPD_LOC PPPD_LOC_OPT PPPD_REM_OPT PPPD_RHOST RSH_LOC - -# -# Uncomment the following to enable IPv6, note that the IPv6 support -# needs to be enabled during compilation -# -# PPPD_IPV6='+ipv6 ipv6cp-use-ipaddr' -export PPPD_IPV6 - -# -# And execute pppd with the pty option, specifying rsh client as the -# slave side of the pseduo-tty master/slave pair. -# -exec $PPPD_LOC \ - pty '$RSH_LOC $PPPD_RHOST $PPPD_LOC $REM_IP:$LOC_IP $PPPD_IPV6 file $PPPD_REM_OPT' \ - $LOC_IP:$REM_IP netmask $NETMASK $PPPD_IPV6 file $PPPD_LOC_OPT - diff --git a/mdk-stage1/ppp/scripts/ppp-on-ssh b/mdk-stage1/ppp/scripts/ppp-on-ssh deleted file mode 100755 index 0e41acac6..000000000 --- a/mdk-stage1/ppp/scripts/ppp-on-ssh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/sh -# -# A sample script to establish PPP session(s) via SSH 1.x -# -# Adi Masputra <adi.masputra@sun.com> -# Jan 24, 2000 -# - -# -# You'd definitely want to change the following addresses to suit -# your network configuration -# -LOC_IP=10.0.0.1 -REM_IP=10.0.0.2 -NETMASK=255.255.0.0 - -export LOC_IP REM_IP - -# -# This is the remote peer where sshd is running, either -# its hostname or IP address -# -PPPD_RHOST=myremotehost - -# -# For this example, we assume that pppd on both local and remote -# machines reside in the same place, /usr/local/bin/pppd -# -PPPD_LOC=/usr/local/bin/pppd - -# -# The location of local options file (where ssh client is running). -# Note that the sample options file included in the distribution -# may need further customizations, depending on your needs. The 'noauth' -# option specified in the file is there to simplify the example, although -# some may choose to have it there and rely on ssh authentication -# instead. -# -PPPD_LOC_OPT=/etc/ppp/options-ssh-loc - -# -# The location of remote options file (where sshd daemon is running) -# Note that the sample options file included in the distribution -# may need further customizations, depending on your needs. The 'noauth' -# option specified in the file is there to simplify the example, although -# some may choose to have it there and rely on ssh authentication -# instead. Also note that the remote options file need to include the 'notty' -# options for this to work. -# -PPPD_REM_OPT=/etc/ppp/options-ssh-rem - -# -# The location of ssh client on the local machine -# -SSH_LOC=/usr/local/bin/ssh - -export PPPD_LOC PPPD_LOC_OPT PPPD_REM_OPT PPPD_RHOST SSH_LOC - -# -# Uncomment the following to enable IPv6, note that the IPv6 support -# needs to be enabled during compilation -# -# PPPD_IPV6='+ipv6 ipv6cp-use-ipaddr' -export PPPD_IPV6 - -# -# And execute pppd with the pty option, specifying ssh client as the -# slave side of the pseudo-tty master/slave pair. Note that on this example, -# ssh has been compiled to allow NULL encryption (thus the '-c none' option), -# but in reality, you'd probably want to specify the encryption algorithm. -# See the man page of ssh(1) for details. -# -exec $PPPD_LOC \ - pty '$SSH_LOC -c none $PPPD_RHOST $PPPD_LOC $REM_IP:$LOC_IP $PPPD_IPV6 file $PPPD_REM_OPT' \ - $LOC_IP:$REM_IP netmask $NETMASK $PPPD_IPV6 file $PPPD_LOC_OPT - diff --git a/mdk-stage1/ppp/scripts/redialer b/mdk-stage1/ppp/scripts/redialer deleted file mode 100755 index 5bbde4e9d..000000000 --- a/mdk-stage1/ppp/scripts/redialer +++ /dev/null @@ -1,96 +0,0 @@ -#!/bin/sh -################################################################### -# -# These parameters control the attack dialing sequence. -# -# Maximum number of attempts to reach the telephone number(s) -MAX_ATTEMPTS=10 - -# Delay between each of the attempts. This is a parameter to sleep -# so use "15s" for 15 seconds, "1m" for 1 minute, etc. -SLEEP_DELAY=15s - -################################################################### -# -# This is a list of telephone numbers. Add new numbers if you wish -# and see the function 'callall' below for the dial process. -PHONE1=555-1212 -PHONE2=411 - -################################################################### -# -# If you use the ppp-on script, then these are passed to this routine -# automatically. There is no need to define them here. If not, then -# you will need to set the values. -# -ACCOUNT=my_account_name -PASSWORD=my_password - -################################################################### -# -# Function to initialize the modem and ensure that it is in command -# state. This may not be needed, but it doesn't hurt. -# -function initialize -{ - chat -v TIMEOUT 3 '' AT 'OK-+++\c-OK' - return -} - -################################################################### -# -# Script to dial a telephone -# -function callnumber -{ -chat -v \ - ABORT '\nBUSY\r' \ - ABORT '\nNO ANSWER\r' \ - ABORT '\nRINGING\r\n\r\nRINGING\r' \ - '' ATDT$1 \ - CONNECT '' \ - ogin:--ogin: $ACCOUNT \ - assword: $PASSWORD -# -# If the connection was successful then end the whole script with a -# success. -# - if [ "$?" = "0" ]; then - exit 0 - fi - - return -} - -################################################################### -# -# Script to dial any telephone number -# -function callall -{ -# echo "dialing attempt number: $1" >/dev/console - callnumber $PHONE1 -# callnumber $PHONE2 -} - -################################################################### -# -# Initialize the modem to ensure that it is in the command state -# -initialize -if [ ! "$?" = "0" ]; then - exit 1 -fi - -# -# Dial telephone numbers until one answers -# -attempt=0 -while : ; do - attempt=`expr $attempt + 1` - callall $attempt - if [ "$attempt" = "$MAX_ATTEMPTS" ]; then - exit 1 - fi - sleep "$SLEEP_DELAY" -done diff --git a/mdk-stage1/ppp/scripts/secure-card b/mdk-stage1/ppp/scripts/secure-card deleted file mode 100644 index a32138b7d..000000000 --- a/mdk-stage1/ppp/scripts/secure-card +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/local/bin/expect -f -# -# This script was written by Jim Isaacson <jcisaac@crl.com>. It is -# designed to work as a script to use the SecureCARD(tm) device. This -# little device is mated with a central controller. The number displayed -# on this card changes every so often and you need to enter the number -# along with your user account name in order to gain access. Since chat -# is based upon fixed strings this procedure will not work with chat. -# -# It is included by permission. An excellent reference for the expect -# program used by this script is in the book: -# -# "Exploring Expect" -# by Don Libes -# Published by O'Rielly and Associates -# - -send_user "hello, starting ppp\n" - -system "stty 19200 -echoe -echo raw < /dev/cua3 > /dev/cua3" - -# -# These are the parameters for the program. -# -set user Pxxxxxx -set password xxxxxxx -set modem /dev/cua3 -set dialup <put phone number here> -set timeout 60 - -spawn -noecho -open [open $modem "r+"] - -send "AT&F\r" -expect "OK" - -send "ATe0v1x4&c1q0&d2&c1s2=128s0=0DT $dialup\r" -set timeout 15 -set counter 0 - -set still_connecting 1 - -expect { - -re ".*CONNECT.*\n" { - set timeout 5 - set still_connecting 0 - continue -expect - } - -re ".*CONNECT.*\r" { - set timeout 5 - set still_connecting 0 - continue -expect - } - -re ".*NO.*CARRIER" { - send_user "Failed to Connect, exiting...\n" - exit - } - -re ".*NO.*DIAL.*TONE" { - send_user "Failed to Connect, exiting...\n" - exit - } - -re ".*VOICE" { - send_user "Failed to Connect, exiting...\n" - exit - } - -re ".*sscode:.*\n" { - continue -expect - } - -re ".*sscode:" { - set timeout -1 - expect_user -re "(.*)\n" - send "$expect_out(1,string)\r" - set timeout 30 - continue -expect - } - -re ".*Next.*:" { - set timeout -1 - expect_user -re "(.*)\n" - send "$expect_out(1,string)\r" - set timeout 30 - continue -expect - } - -re "Your.*" { - send "\r" - continue -expect - } - -re ".*in:" { - send "$user\r" - continue -expect - } - -re ".*word:" { - send "$password\r" - } - - timeout { - if { $still_connecting > 0 } { - continue -expect - } - set timeout 15 - send "\r" - incr counter - if { $counter > 8 } { - send_user "Cannot Connect\n" - exit - } else { - continue -expect - } - } -} - -overlay -0 $spawn_id -1 $spawn_id pppd /dev/cua3 19200 192.111.187.215: \ - crtscts modem defaultroute debug diff --git a/mdk-stage1/ppp/solaris/Makedefs b/mdk-stage1/ppp/solaris/Makedefs deleted file mode 100644 index 81db8ab2e..000000000 --- a/mdk-stage1/ppp/solaris/Makedefs +++ /dev/null @@ -1,16 +0,0 @@ -# -# defines common to several Makefiles -# - -INSTALL= /usr/sbin/install - -BINDIR = /usr/local/bin -MANDIR = /usr/local/man -ETCDIR = /etc/ppp - -COPTS = -O -Xa - -# For compiling with gcc, comment out the COPTS definition above and -# uncomment the next 2 definitions. -#CC = gcc -#COPTS = -O2 diff --git a/mdk-stage1/ppp/solaris/Makedefs.sol2 b/mdk-stage1/ppp/solaris/Makedefs.sol2 deleted file mode 100644 index 1282c6e74..000000000 --- a/mdk-stage1/ppp/solaris/Makedefs.sol2 +++ /dev/null @@ -1,59 +0,0 @@ -# -# Generic make definitions for Solaris 2 -# -# $Id$ -# - -include ../solaris/Makedefs - -CPPFLAGS = -D_KERNEL -DSVR4 -DSOL2 -DPRIOQ -DDEBUG -I../include -CFLAGS = $(CPPFLAGS) $(COPTS) - -# lint-specific variables -LINT = lint -LINT_OPT_32 = -LINT_OPT_64 = -Xarch=v9 -errchk=longptr64 - -LINT_32 = -LINT_32 += -erroff=E_BAD_PTR_CAST_ALIGN -LINT_32 += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED -LINT_32 += -erroff=E_SUSPICIOUS_COMPARISON -LINT_32 += -erroff=E_CAST_UINT_TO_SIGNED_INT -LINT_32 += -erroff=E_PASS_UINT_TO_SIGNED_INT -LINT_32 += -erroff=E_INVALID_ANNOTATION_NAME -LINT_32 += -erroff=E_FUNC_ARG_UNUSED -# This might be needed, but zlib.c and vjcompress.c will squawk -# when not ignored -LINT_32 += -erroff=E_CASE_FALLTHRU -LINT_32 += -erroff=E_RET_INT_IMPLICITLY -LINT_32 += -erroff=E_FUNC_NO_RET_VAL -# Some STREAMS macros will be noisy too when this isn't ignored -LINT_32 += -erroff=E_CONSTANT_CONDITION -LINT_32 += -erroff=E_CONST_EXPR - -# Extra noise suppressant for 64-bit -EXTRA_OFF = -EXTRA_OFF += -erroff=E_CAST_INT_TO_SMALL_INT -EXTRA_OFF += -erroff=E_CAST_INT_CONST_TO_SMALL_INT -EXTRA_OFF += -erroff=E_CAST_TO_PTR_FROM_INT -EXTRA_OFF += -erroff=E_ASSIGN_INT_TO_SMALL_INT -EXTRA_OFF += -erroff=E_ASSIGN_INT_FROM_BIG_CONST -EXTRA_OFF += -erroff=E_CONST_PROMOTED_UNSIGNED_LL -EXTRA_OFF += -erroff=E_CONST_PROMOTED_LONG_LONG -EXTRA_OFF += -erroff=E_CONST_TRUNCATED_BY_ASSIGN -EXTRA_OFF += -erroff=E_PASS_INT_FROM_BIG_CONST -EXTRA_OFF += -erroff=E_COMP_INT_WITH_LARGE_INT -EXTRA_OFF += -erroff=E_ASSIGN_UINT_TO_SIGNED_INT -EXTRA_OFF += -erroff=E_ASSIGN_NARROW_CONV -EXTRA_OFF += -erroff=E_PASS_INT_TO_SMALL_INT -EXTRA_OFF += -erroff=E_PTR_CONV_LOSES_BITS - -LINT_64 = $(LINT_32) -LINT_64 += $(EXTRA_OFF) - -LINTFLAGS64 = -Xa -nsxmuF -errtags=yes $(LINT_OPT_64) $(LINT_64) -LINT64 = $(LINT) -c $(LINTFLAGS64) $(CPPFLAGS) - -LINTFLAGS32 = -Xa -nsxmuF -errtags=yes $(LINT_OPT_32) $(LINT_32) -LINT32 = $(LINT) -c $(LINTFLAGS32) $(CPPFLAGS) - diff --git a/mdk-stage1/ppp/solaris/Makefile.sol2 b/mdk-stage1/ppp/solaris/Makefile.sol2 deleted file mode 100644 index 78628847b..000000000 --- a/mdk-stage1/ppp/solaris/Makefile.sol2 +++ /dev/null @@ -1,66 +0,0 @@ -# -# Makefile for STREAMS modules for Solaris 2. -# -# $Id$ -# - -include Makedefs.sol2 - -COPTS += -xO2 -xspace -W0,-Lt - -COMP_OBJS = ppp_comp.o bsd-comp.o deflate.o zlib.o vjcompress.o \ - ppp_comp_mod.o - -all: ppp ppp_ahdl ppp_comp - -ppp: ppp.o ppp_mod.o - ld -r -o $@ ppp.o ppp_mod.o - chmod +x $@ - -ppp_ahdl: ppp_ahdlc.o ppp_ahdlc_mod.o - ld -r -o $@ ppp_ahdlc.o ppp_ahdlc_mod.o - chmod +x $@ - -ppp_comp: $(COMP_OBJS) - ld -r -o $@ $(COMP_OBJS) - chmod +x $@ - -bsd-comp.o: ../modules/bsd-comp.c - $(CC) $(CFLAGS) -c $? -deflate.o: ../modules/deflate.c - $(CC) $(CFLAGS) -c $? -ppp.o: ppp.c - $(CC) $(CFLAGS) -c $? -ppp_mod.o: ppp_mod.c - $(CC) $(CFLAGS) -c $? -ppp_ahdlc_mod.o: ppp_ahdlc_mod.c - $(CC) $(CFLAGS) -c $? -ppp_ahdlc.o: ppp_ahdlc.c - $(CC) $(CFLAGS) -c $? -ppp_comp.o: ppp_comp.c - $(CC) $(CFLAGS) -c $? -ppp_comp_mod.o: ppp_comp_mod.c - $(CC) $(CFLAGS) -c $? -vjcompress.o: ../modules/vjcompress.c - $(CC) $(CFLAGS) -c $? -zlib.o: ../common/zlib.c - $(CC) $(CFLAGS) -c $? - -install: - cp ppp ppp.conf /kernel/drv - cp ppp_comp ppp_ahdl /kernel/strmod - if grep clone:ppp /etc/minor_perm; then :; else \ - echo clone:ppp 0644 root sys >>/etc/minor_perm; fi - /usr/sbin/rem_drv ppp 2>/dev/null || true - /usr/sbin/add_drv ppp - -SRCS = ppp.c ppp_mod.c ppp_ahdlc.c ppp_ahdlc_mod.c \ - ppp_comp.c ../modules/bsd-comp.c ../modules/deflate.c \ - ../common/zlib.c ../modules/vjcompress.c ppp_comp_mod.c - -lint: - $(LINT32) $(SRCS) - -clean: - rm -f ppp ppp_comp ppp_ahdl *.o *~ core - rm -f *.ln diff --git a/mdk-stage1/ppp/solaris/Makefile.sol2-64 b/mdk-stage1/ppp/solaris/Makefile.sol2-64 deleted file mode 100644 index 63e75fc54..000000000 --- a/mdk-stage1/ppp/solaris/Makefile.sol2-64 +++ /dev/null @@ -1,85 +0,0 @@ -# -# Makefile for 64-bit STREAMS modules for Solaris 2. -# -# $Id$ -# - -include Makedefs.sol2 - -# Sun's cc flag for LP64 compilation / linkage -COPTS += -xchip=ultra -xarch=v9 -Wc,-xcode=abs32 -Wc,-Qiselect-regsym=0 -xO3 -xspace -W0,-Lt - -# subdirectory where 64-bit objects / binaries will be placed -LP64DIR = sparcv9 - -# Name of legacy Makefile (for 32-bit binaries) -STD_MAKE = Makefile.sol2 - -COMP_OBJS = $(LP64DIR)/ppp_comp.o $(LP64DIR)/bsd-comp.o \ - $(LP64DIR)/deflate.o $(LP64DIR)/zlib.o $(LP64DIR)/vjcompress.o \ - $(LP64DIR)/ppp_comp_mod.o - -all: std_objs $(LP64DIR) ppp ppp_ahdl ppp_comp - -std_objs: - $(MAKE) -f $(STD_MAKE) all - -ppp: $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o - ld -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o - chmod +x $(LP64DIR)/$@ - -ppp_ahdl: $(LP64DIR)/ppp_ahdlc.o $(LP64DIR)/ppp_ahdlc_mod.o - ld -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp_ahdlc.o $(LP64DIR)/ppp_ahdlc_mod.o - chmod +x $(LP64DIR)/$@ - -ppp_comp: $(COMP_OBJS) - ld -r -o $(LP64DIR)/$@ $(COMP_OBJS) - chmod +x $(LP64DIR)/$@ - -$(LP64DIR)/bsd-comp.o: ../modules/bsd-comp.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/deflate.o: ../modules/deflate.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp.o: ppp.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_mod.o: ppp_mod.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_ahdlc_mod.o: ppp_ahdlc_mod.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_ahdlc.o: ppp_ahdlc.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_comp.o: ppp_comp.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_comp_mod.o: ppp_comp_mod.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/vjcompress.o: ../modules/vjcompress.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/zlib.o: ../common/zlib.c - $(CC) $(CFLAGS) -c $? -o $@ - -$(LP64DIR): - mkdir -m 755 -p $@ - -install: - cp ppp ppp.conf /kernel/drv - cp ppp_comp ppp_ahdl /kernel/strmod - cp $(LP64DIR)/ppp /kernel/drv/$(LP64DIR) - cp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl /kernel/strmod/$(LP64DIR) - if grep clone:ppp /etc/minor_perm; then :; else \ - echo clone:ppp 0644 root sys >>/etc/minor_perm; fi - /usr/sbin/rem_drv ppp 2>/dev/null || true - /usr/sbin/add_drv ppp - -SRCS = ppp.c ppp_mod.c ppp_ahdlc.c ppp_ahdlc_mod.c \ - ppp_comp.c ../modules/bsd-comp.c ../modules/deflate.c \ - ../common/zlib.c ../modules/vjcompress.c ppp_comp_mod.c - -lint: - $(LINT64) $(SRCS) - -lint-32: - $(LINT32) $(SRCS) - -clean: - $(MAKE) -f $(STD_MAKE) clean - rm -f $(LP64DIR)/ppp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl $(LP64DIR)/*.o $(LP64DIR)/*~ $(LP64DIR)/core diff --git a/mdk-stage1/ppp/solaris/Makefile.top b/mdk-stage1/ppp/solaris/Makefile.top deleted file mode 100644 index f1200b852..000000000 --- a/mdk-stage1/ppp/solaris/Makefile.top +++ /dev/null @@ -1,50 +0,0 @@ -# -# ppp top level makefile for SVR4 and Solaris 2 -# -# $Id$ -# - -include solaris/Makedefs - -all: - cd chat; $(MAKE) all - cd pppd; $(MAKE) all - cd pppstats; $(MAKE) all - cd pppdump; $(MAKE) all - cd solaris; $(MAKE) all - -install: $(BINDIR) $(MANDIR)/man8 install-progs install-etcppp - -install-progs: - cd chat; $(MAKE) install - cd pppd; $(MAKE) install - cd pppstats; $(MAKE) install - cd pppdump; $(MAKE) install - cd solaris; $(MAKE) install - -install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ - $(ETCDIR)/chap-secrets - -$(ETCDIR)/options: - cp etc.ppp/options $@ - chmod go-w $@ -$(ETCDIR)/pap-secrets: - $(INSTALL) -f $(ETCDIR) -m 600 etc.ppp/pap-secrets -$(ETCDIR)/chap-secrets: - $(INSTALL) -f $(ETCDIR) -m 600 etc.ppp/chap-secrets - -$(BINDIR): - mkdir -m 755 -p $@ -$(MANDIR)/man8: - mkdir -m 755 -p $@ -$(ETCDIR): - mkdir -m 755 -p $@ - -clean: - rm -f *~ - cd chat; $(MAKE) clean - cd pppd; $(MAKE) clean - cd pppstats; $(MAKE) clean - cd pppdump; $(MAKE) clean - cd solaris; $(MAKE) clean - diff --git a/mdk-stage1/ppp/solaris/ppp.c b/mdk-stage1/ppp/solaris/ppp.c deleted file mode 100644 index 44bf08dff..000000000 --- a/mdk-stage1/ppp/solaris/ppp.c +++ /dev/null @@ -1,2486 +0,0 @@ -/* - * ppp.c - STREAMS multiplexing pseudo-device driver for PPP. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -/* - * This file is used under Solaris 2, SVR4, SunOS 4, and Digital UNIX. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/stream.h> -#include <sys/stropts.h> -#include <sys/errno.h> -#ifdef __osf__ -#include <sys/ioctl.h> -#include <sys/cmn_err.h> -#define queclass(mp) ((mp)->b_band & QPCTL) -#else -#include <sys/ioccom.h> -#endif -#include <sys/time.h> -#ifdef SVR4 -#include <sys/cmn_err.h> -#include <sys/conf.h> -#include <sys/dlpi.h> -#include <sys/ddi.h> -#ifdef SOL2 -#include <sys/ksynch.h> -#include <sys/kstat.h> -#include <sys/sunddi.h> -#include <sys/ethernet.h> -#else -#include <sys/socket.h> -#include <sys/sockio.h> -#include <net/if.h> -#include <netinet/in.h> -#endif /* SOL2 */ -#else /* not SVR4 */ -#include <sys/user.h> -#endif /* SVR4 */ -#include <net/ppp_defs.h> -#include <net/pppio.h> -#include "ppp_mod.h" - -/* - * Modifications marked with #ifdef PRIOQ are for priority queueing of - * interactive traffic, and are due to Marko Zec <zec@japa.tel.fer.hr>. - */ -#ifdef PRIOQ -#endif /* PRIOQ */ - -#include <netinet/in.h> /* leave this outside of PRIOQ for htons */ - -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif - -/* - * The IP module may use this SAP value for IP packets. - */ -#ifndef ETHERTYPE_IP -#define ETHERTYPE_IP 0x800 -#endif - -#if !defined(ETHERTYPE_IPV6) -#define ETHERTYPE_IPV6 0x86dd -#endif /* !defined(ETHERTYPE_IPV6) */ - -#if !defined(ETHERTYPE_ALLSAP) && defined(SOL2) -#define ETHERTYPE_ALLSAP 0 -#endif /* !defined(ETHERTYPE_ALLSAP) && defined(SOL2) */ - -#if !defined(PPP_ALLSAP) && defined(SOL2) -#define PPP_ALLSAP PPP_ALLSTATIONS -#endif /* !defined(PPP_ALLSAP) && defined(SOL2) */ - -extern time_t time; - -#ifdef SOL2 -/* - * We use this reader-writer lock to ensure that the lower streams - * stay connected to the upper streams while the lower-side put and - * service procedures are running. Essentially it is an existence - * lock for the upper stream associated with each lower stream. - */ -krwlock_t ppp_lower_lock; -#define LOCK_LOWER_W rw_enter(&ppp_lower_lock, RW_WRITER) -#define LOCK_LOWER_R rw_enter(&ppp_lower_lock, RW_READER) -#define TRYLOCK_LOWER_R rw_tryenter(&ppp_lower_lock, RW_READER) -#define UNLOCK_LOWER rw_exit(&ppp_lower_lock) - -#define MT_ENTER(x) mutex_enter(x) -#define MT_EXIT(x) mutex_exit(x) - -/* - * Notes on multithreaded implementation for Solaris 2: - * - * We use an inner perimeter around each queue pair and an outer - * perimeter around the whole driver. The inner perimeter is - * entered exclusively for all entry points (open, close, put, - * service). The outer perimeter is entered exclusively for open - * and close and shared for put and service. This is all done for - * us by the streams framework. - * - * I used to think that the perimeters were entered for the lower - * streams' put and service routines as well as for the upper streams'. - * Because of problems experienced by people, and after reading the - * documentation more closely, I now don't think that is true. So we - * now use ppp_lower_lock to give us an existence guarantee on the - * upper stream controlling each lower stream. - * - * Shared entry to the outer perimeter protects the existence of all - * the upper streams and their upperstr_t structures, and guarantees - * that the following fields of any upperstr_t won't change: - * nextmn, next, nextppa. It guarantees that the lowerq field of an - * upperstr_t won't go from non-zero to zero, that the global `ppas' - * won't change and that the no lower stream will get unlinked. - * - * Shared (reader) access to ppa_lower_lock guarantees that no lower - * stream will be unlinked and that the lowerq field of all upperstr_t - * structures won't change. - */ - -#else /* SOL2 */ -#define LOCK_LOWER_W 0 -#define LOCK_LOWER_R 0 -#define TRYLOCK_LOWER_R 1 -#define UNLOCK_LOWER 0 -#define MT_ENTER(x) 0 -#define MT_EXIT(x) 0 - -#endif /* SOL2 */ - -/* - * Private information; one per upper stream. - */ -typedef struct upperstr { - minor_t mn; /* minor device number */ - struct upperstr *nextmn; /* next minor device */ - queue_t *q; /* read q associated with this upper stream */ - int flags; /* flag bits, see below */ - int state; /* current DLPI state */ - int sap; /* service access point */ - int req_sap; /* which SAP the DLPI client requested */ - struct upperstr *ppa; /* control stream for our ppa */ - struct upperstr *next; /* next stream for this ppa */ - uint ioc_id; /* last ioctl ID for this stream */ - enum NPmode npmode; /* what to do with packets on this SAP */ - unsigned char rblocked; /* flow control has blocked upper read strm */ - /* N.B. rblocked is only changed by control stream's put/srv procs */ - /* - * There is exactly one control stream for each PPA. - * The following fields are only used for control streams. - */ - int ppa_id; - queue_t *lowerq; /* write queue attached below this PPA */ - struct upperstr *nextppa; /* next control stream */ - int mru; - int mtu; - struct pppstat stats; /* statistics */ - time_t last_sent; /* time last NP packet sent */ - time_t last_recv; /* time last NP packet rcvd */ -#ifdef SOL2 - kmutex_t stats_lock; /* lock for stats updates */ - kstat_t *kstats; /* stats for netstat */ -#endif /* SOL2 */ -#ifdef LACHTCP - int ifflags; - char ifname[IFNAMSIZ]; - struct ifstats ifstats; -#endif /* LACHTCP */ -} upperstr_t; - -/* Values for flags */ -#define US_PRIV 1 /* stream was opened by superuser */ -#define US_CONTROL 2 /* stream is a control stream */ -#define US_BLOCKED 4 /* flow ctrl has blocked lower write stream */ -#define US_LASTMOD 8 /* no PPP modules below us */ -#define US_DBGLOG 0x10 /* log various occurrences */ -#define US_RBLOCKED 0x20 /* flow ctrl has blocked upper read stream */ - -#if defined(SOL2) -#if DL_CURRENT_VERSION >= 2 -#define US_PROMISC 0x40 /* stream is promiscuous */ -#endif /* DL_CURRENT_VERSION >= 2 */ -#define US_RAWDATA 0x80 /* raw M_DATA, no DLPI header */ -#endif /* defined(SOL2) */ - -#ifdef PRIOQ -static u_char max_band=0; -static u_char def_band=0; - -#define IPPORT_DEFAULT 65535 - -/* - * Port priority table - * Highest priority ports are listed first, lowest are listed last. - * ICMP & packets using unlisted ports will be treated as "default". - * If IPPORT_DEFAULT is not listed here, "default" packets will be - * assigned lowest priority. - * Each line should be terminated with "0". - * Line containing only "0" marks the end of the list. - */ - -static u_short prioq_table[]= { - 113, 53, 0, - 22, 23, 513, 517, 518, 0, - 514, 21, 79, 111, 0, - 25, 109, 110, 0, - IPPORT_DEFAULT, 0, - 20, 70, 80, 8001, 8008, 8080, 0, /* 8001,8008,8080 - common proxy ports */ -0 }; - -#endif /* PRIOQ */ - - -static upperstr_t *minor_devs = NULL; -static upperstr_t *ppas = NULL; - -#ifdef SVR4 -static int pppopen __P((queue_t *, dev_t *, int, int, cred_t *)); -static int pppclose __P((queue_t *, int, cred_t *)); -#else -static int pppopen __P((queue_t *, int, int, int)); -static int pppclose __P((queue_t *, int)); -#endif /* SVR4 */ -static int pppurput __P((queue_t *, mblk_t *)); -static int pppuwput __P((queue_t *, mblk_t *)); -static int pppursrv __P((queue_t *)); -static int pppuwsrv __P((queue_t *)); -static int ppplrput __P((queue_t *, mblk_t *)); -static int ppplwput __P((queue_t *, mblk_t *)); -static int ppplrsrv __P((queue_t *)); -static int ppplwsrv __P((queue_t *)); -#ifndef NO_DLPI -static void dlpi_request __P((queue_t *, mblk_t *, upperstr_t *)); -static void dlpi_error __P((queue_t *, upperstr_t *, int, int, int)); -static void dlpi_ok __P((queue_t *, int)); -#endif -static int send_data __P((mblk_t *, upperstr_t *)); -static void new_ppa __P((queue_t *, mblk_t *)); -static void attach_ppa __P((queue_t *, mblk_t *)); -static void detach_ppa __P((queue_t *, mblk_t *)); -static void detach_lower __P((queue_t *, mblk_t *)); -static void debug_dump __P((queue_t *, mblk_t *)); -static upperstr_t *find_dest __P((upperstr_t *, int)); -#if defined(SOL2) -static upperstr_t *find_promisc __P((upperstr_t *, int)); -static mblk_t *prepend_ether __P((upperstr_t *, mblk_t *, int)); -static mblk_t *prepend_udind __P((upperstr_t *, mblk_t *, int)); -static void promisc_sendup __P((upperstr_t *, mblk_t *, int, int)); -#endif /* defined(SOL2) */ -static int putctl2 __P((queue_t *, int, int, int)); -static int putctl4 __P((queue_t *, int, int, int)); -static int pass_packet __P((upperstr_t *ppa, mblk_t *mp, int outbound)); -#ifdef FILTER_PACKETS -static int ip_hard_filter __P((upperstr_t *ppa, mblk_t *mp, int outbound)); -#endif /* FILTER_PACKETS */ - -#define PPP_ID 0xb1a6 -static struct module_info ppp_info = { -#ifdef PRIOQ - PPP_ID, "ppp", 0, 512, 512, 384 -#else - PPP_ID, "ppp", 0, 512, 512, 128 -#endif /* PRIOQ */ -}; - -static struct qinit pppurint = { - pppurput, pppursrv, pppopen, pppclose, NULL, &ppp_info, NULL -}; - -static struct qinit pppuwint = { - pppuwput, pppuwsrv, NULL, NULL, NULL, &ppp_info, NULL -}; - -static struct qinit ppplrint = { - ppplrput, ppplrsrv, NULL, NULL, NULL, &ppp_info, NULL -}; - -static struct qinit ppplwint = { - ppplwput, ppplwsrv, NULL, NULL, NULL, &ppp_info, NULL -}; - -#ifdef LACHTCP -extern struct ifstats *ifstats; -int pppdevflag = 0; -#endif - -struct streamtab pppinfo = { - &pppurint, &pppuwint, - &ppplrint, &ppplwint -}; - -int ppp_count; - -/* - * How we maintain statistics. - */ -#ifdef SOL2 -#define INCR_IPACKETS(ppa) \ - if (ppa->kstats != 0) { \ - KSTAT_NAMED_PTR(ppa->kstats)[0].value.ul++; \ - } -#define INCR_IERRORS(ppa) \ - if (ppa->kstats != 0) { \ - KSTAT_NAMED_PTR(ppa->kstats)[1].value.ul++; \ - } -#define INCR_OPACKETS(ppa) \ - if (ppa->kstats != 0) { \ - KSTAT_NAMED_PTR(ppa->kstats)[2].value.ul++; \ - } -#define INCR_OERRORS(ppa) \ - if (ppa->kstats != 0) { \ - KSTAT_NAMED_PTR(ppa->kstats)[3].value.ul++; \ - } -#endif - -#ifdef LACHTCP -#define INCR_IPACKETS(ppa) ppa->ifstats.ifs_ipackets++; -#define INCR_IERRORS(ppa) ppa->ifstats.ifs_ierrors++; -#define INCR_OPACKETS(ppa) ppa->ifstats.ifs_opackets++; -#define INCR_OERRORS(ppa) ppa->ifstats.ifs_oerrors++; -#endif - -/* - * STREAMS driver entry points. - */ -static int -#ifdef SVR4 -pppopen(q, devp, oflag, sflag, credp) - queue_t *q; - dev_t *devp; - int oflag, sflag; - cred_t *credp; -#else -pppopen(q, dev, oflag, sflag) - queue_t *q; - int dev; /* really dev_t */ - int oflag, sflag; -#endif -{ - upperstr_t *up; - upperstr_t **prevp; - minor_t mn; -#ifdef PRIOQ - u_short *ptr; - u_char new_band; -#endif /* PRIOQ */ - - if (q->q_ptr) - DRV_OPEN_OK(dev); /* device is already open */ - -#ifdef PRIOQ - /* Calculate max_bband & def_band from definitions in prioq.h - This colud be done at some more approtiate time (less often) - but this way it works well so I'll just leave it here */ - - max_band = 1; - def_band = 0; - ptr = prioq_table; - while (*ptr) { - new_band = 1; - while (*ptr) - if (*ptr++ == IPPORT_DEFAULT) { - new_band = 0; - def_band = max_band; - } - max_band += new_band; - ptr++; - } - if (def_band) - def_band = max_band - def_band; - --max_band; -#endif /* PRIOQ */ - - if (sflag == CLONEOPEN) { - mn = 0; - for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) { - if (up->mn != mn) - break; - ++mn; - } - } else { -#ifdef SVR4 - mn = getminor(*devp); -#else - mn = minor(dev); -#endif - for (prevp = &minor_devs; (up = *prevp) != 0; prevp = &up->nextmn) { - if (up->mn >= mn) - break; - } - if (up->mn == mn) { - /* this can't happen */ - q->q_ptr = WR(q)->q_ptr = (caddr_t) up; - DRV_OPEN_OK(dev); - } - } - - /* - * Construct a new minor node. - */ - up = (upperstr_t *) ALLOC_SLEEP(sizeof(upperstr_t)); - bzero((caddr_t) up, sizeof(upperstr_t)); - if (up == 0) { - DPRINT("pppopen: out of kernel memory\n"); - OPEN_ERROR(ENXIO); - } - up->nextmn = *prevp; - *prevp = up; - up->mn = mn; -#ifdef SVR4 - *devp = makedevice(getmajor(*devp), mn); -#endif - up->q = q; - if (NOTSUSER() == 0) - up->flags |= US_PRIV; -#ifndef NO_DLPI - up->state = DL_UNATTACHED; -#endif -#ifdef LACHTCP - up->ifflags = IFF_UP | IFF_POINTOPOINT; -#endif - up->sap = -1; - up->last_sent = up->last_recv = time; - up->npmode = NPMODE_DROP; - q->q_ptr = (caddr_t) up; - WR(q)->q_ptr = (caddr_t) up; - noenable(WR(q)); -#ifdef SOL2 - mutex_init(&up->stats_lock, NULL, MUTEX_DRIVER, NULL); -#endif - ++ppp_count; - - qprocson(q); - DRV_OPEN_OK(makedev(major(dev), mn)); -} - -static int -#ifdef SVR4 -pppclose(q, flag, credp) - queue_t *q; - int flag; - cred_t *credp; -#else -pppclose(q, flag) - queue_t *q; - int flag; -#endif -{ - upperstr_t *up, **upp; - upperstr_t *as, *asnext; - upperstr_t **prevp; - - qprocsoff(q); - - up = (upperstr_t *) q->q_ptr; - if (up == 0) { - DPRINT("pppclose: q_ptr = 0\n"); - return 0; - } - if (up->flags & US_DBGLOG) - DPRINT2("ppp/%d: close, flags=%x\n", up->mn, up->flags); - if (up->flags & US_CONTROL) { -#ifdef LACHTCP - struct ifstats *ifp, *pifp; -#endif - if (up->lowerq != 0) { - /* Gack! the lower stream should have be unlinked earlier! */ - DPRINT1("ppp%d: lower stream still connected on close?\n", - up->mn); - LOCK_LOWER_W; - up->lowerq->q_ptr = 0; - RD(up->lowerq)->q_ptr = 0; - up->lowerq = 0; - UNLOCK_LOWER; - } - - /* - * This stream represents a PPA: - * For all streams attached to the PPA, clear their - * references to this PPA. - * Then remove this PPA from the list of PPAs. - */ - for (as = up->next; as != 0; as = asnext) { - asnext = as->next; - as->next = 0; - as->ppa = 0; - if (as->flags & US_BLOCKED) { - as->flags &= ~US_BLOCKED; - flushq(WR(as->q), FLUSHDATA); - } - } - for (upp = &ppas; *upp != 0; upp = &(*upp)->nextppa) - if (*upp == up) { - *upp = up->nextppa; - break; - } -#ifdef LACHTCP - /* Remove the statistics from the active list. */ - for (ifp = ifstats, pifp = 0; ifp; ifp = ifp->ifs_next) { - if (ifp == &up->ifstats) { - if (pifp) - pifp->ifs_next = ifp->ifs_next; - else - ifstats = ifp->ifs_next; - break; - } - pifp = ifp; - } -#endif - } else { - /* - * If this stream is attached to a PPA, - * remove it from the PPA's list. - */ - if ((as = up->ppa) != 0) { - for (; as->next != 0; as = as->next) - if (as->next == up) { - as->next = up->next; - break; - } - } - } - -#ifdef SOL2 - if (up->kstats) - kstat_delete(up->kstats); - mutex_destroy(&up->stats_lock); -#endif - - q->q_ptr = NULL; - WR(q)->q_ptr = NULL; - - for (prevp = &minor_devs; *prevp != 0; prevp = &(*prevp)->nextmn) { - if (*prevp == up) { - *prevp = up->nextmn; - break; - } - } - FREE(up, sizeof(upperstr_t)); - --ppp_count; - - return 0; -} - -/* - * A message from on high. We do one of three things: - * - qreply() - * - put the message on the lower write stream - * - queue it for our service routine - */ -static int -pppuwput(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us, *ppa, *nps; - struct iocblk *iop; - struct linkblk *lb; -#ifdef LACHTCP - struct ifreq *ifr; - int i; -#endif - queue_t *lq; - int error, n, sap; - mblk_t *mq; - struct ppp_idle *pip; -#ifdef PRIOQ - queue_t *tlq; -#endif /* PRIOQ */ -#ifdef NO_DLPI - upperstr_t *os; -#endif - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("pppuwput: q_ptr = 0!\n"); - return 0; - } - if (mp == 0) { - DPRINT1("pppuwput/%d: mp = 0!\n", us->mn); - return 0; - } - if (mp->b_datap == 0) { - DPRINT1("pppuwput/%d: mp->b_datap = 0!\n", us->mn); - return 0; - } - switch (mp->b_datap->db_type) { -#ifndef NO_DLPI - case M_PCPROTO: - case M_PROTO: - dlpi_request(q, mp, us); - break; -#endif /* NO_DLPI */ - - case M_DATA: - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: uwput M_DATA len=%d flags=%x\n", - us->mn, msgdsize(mp), us->flags); - if (us->ppa == 0 || msgdsize(mp) > us->ppa->mtu + PPP_HDRLEN -#ifndef NO_DLPI - || (us->flags & US_CONTROL) == 0 -#endif /* NO_DLPI */ - ) { - DPRINT1("pppuwput: junk data len=%d\n", msgdsize(mp)); - freemsg(mp); - break; - } -#ifdef NO_DLPI - if ((us->flags & US_CONTROL) == 0 && !pass_packet(us, mp, 1)) - break; -#endif - if (!send_data(mp, us)) - putq(q, mp); - break; - - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - error = EINVAL; - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: ioctl %x count=%d\n", - us->mn, iop->ioc_cmd, iop->ioc_count); - switch (iop->ioc_cmd) { -#if defined(SOL2) - case DLIOCRAW: /* raw M_DATA mode */ - us->flags |= US_RAWDATA; - error = 0; - break; -#endif /* defined(SOL2) */ - case I_LINK: - if ((us->flags & US_CONTROL) == 0 || us->lowerq != 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl I_LINK b_cont = 0!\n", us->mn); - break; - } - lb = (struct linkblk *) mp->b_cont->b_rptr; - lq = lb->l_qbot; - if (lq == 0) { - DPRINT1("pppuwput/%d: ioctl I_LINK l_qbot = 0!\n", us->mn); - break; - } - LOCK_LOWER_W; - us->lowerq = lq; - lq->q_ptr = (caddr_t) q; - RD(lq)->q_ptr = (caddr_t) us->q; - UNLOCK_LOWER; - iop->ioc_count = 0; - error = 0; - us->flags &= ~US_LASTMOD; - /* Unblock upper streams which now feed this lower stream. */ - qenable(q); - /* Send useful information down to the modules which - are now linked below us. */ - putctl2(lq, M_CTL, PPPCTL_UNIT, us->ppa_id); - putctl4(lq, M_CTL, PPPCTL_MRU, us->mru); - putctl4(lq, M_CTL, PPPCTL_MTU, us->mtu); -#ifdef PRIOQ - /* Lower tty driver's queue hiwat/lowat from default 4096/128 - to 256/128 since we don't want queueing of data on - output to physical device */ - - freezestr(lq); - for (tlq = lq; tlq->q_next != NULL; tlq = tlq->q_next) - ; - strqset(tlq, QHIWAT, 0, 256); - strqset(tlq, QLOWAT, 0, 128); - unfreezestr(lq); -#endif /* PRIOQ */ - break; - - case I_UNLINK: - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl I_UNLINK b_cont = 0!\n", us->mn); - break; - } - lb = (struct linkblk *) mp->b_cont->b_rptr; -#if DEBUG - if (us->lowerq != lb->l_qbot) { - DPRINT2("ppp unlink: lowerq=%x qbot=%x\n", - us->lowerq, lb->l_qbot); - break; - } -#endif - iop->ioc_count = 0; - qwriter(q, mp, detach_lower, PERIM_OUTER); - error = -1; - break; - - case PPPIO_NEWPPA: - if (us->flags & US_CONTROL) - break; - if ((us->flags & US_PRIV) == 0) { - error = EPERM; - break; - } - /* Arrange to return an int */ - if ((mq = mp->b_cont) == 0 - || mq->b_datap->db_lim - mq->b_rptr < sizeof(int)) { - mq = allocb(sizeof(int), BPRI_HI); - if (mq == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = mq; - mq->b_cont = 0; - } - iop->ioc_count = sizeof(int); - mq->b_wptr = mq->b_rptr + sizeof(int); - qwriter(q, mp, new_ppa, PERIM_OUTER); - error = -1; - break; - - case PPPIO_ATTACH: - /* like dlpi_attach, for programs which can't write to - the stream (like pppstats) */ - if (iop->ioc_count != sizeof(int) || us->ppa != 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_ATTACH b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - for (ppa = ppas; ppa != 0; ppa = ppa->nextppa) - if (ppa->ppa_id == n) - break; - if (ppa == 0) - break; - us->ppa = ppa; - iop->ioc_count = 0; - qwriter(q, mp, attach_ppa, PERIM_OUTER); - error = -1; - break; - -#ifdef NO_DLPI - case PPPIO_BIND: - /* Attach to a given SAP. */ - if (iop->ioc_count != sizeof(int) || us->ppa == 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_BIND b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - /* n must be a valid PPP network protocol number. */ - if (n < 0x21 || n > 0x3fff || (n & 0x101) != 1) - break; - /* check that no other stream is bound to this sap already. */ - for (os = us->ppa; os != 0; os = os->next) - if (os->sap == n) - break; - if (os != 0) - break; - us->sap = n; - iop->ioc_count = 0; - error = 0; - break; -#endif /* NO_DLPI */ - - case PPPIO_MRU: - if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_MRU b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - if (n <= 0 || n > PPP_MAXMRU) - break; - if (n < PPP_MRU) - n = PPP_MRU; - us->mru = n; - if (us->lowerq) - putctl4(us->lowerq, M_CTL, PPPCTL_MRU, n); - error = 0; - iop->ioc_count = 0; - break; - - case PPPIO_MTU: - if (iop->ioc_count != sizeof(int) || (us->flags & US_CONTROL) == 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_MTU b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - if (n <= 0 || n > PPP_MAXMTU) - break; - us->mtu = n; -#ifdef LACHTCP - /* The MTU reported in netstat, not used as IP max packet size! */ - us->ifstats.ifs_mtu = n; -#endif - if (us->lowerq) - putctl4(us->lowerq, M_CTL, PPPCTL_MTU, n); - error = 0; - iop->ioc_count = 0; - break; - - case PPPIO_LASTMOD: - us->flags |= US_LASTMOD; - error = 0; - break; - - case PPPIO_DEBUG: - if (iop->ioc_count != sizeof(int)) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_DEBUG b_cont = 0!\n", us->mn); - break; - } - n = *(int *)mp->b_cont->b_rptr; - if (n == PPPDBG_DUMP + PPPDBG_DRIVER) { - qwriter(q, NULL, debug_dump, PERIM_OUTER); - iop->ioc_count = 0; - error = -1; - } else if (n == PPPDBG_LOG + PPPDBG_DRIVER) { - DPRINT1("ppp/%d: debug log enabled\n", us->mn); - us->flags |= US_DBGLOG; - iop->ioc_count = 0; - error = 0; - } else { - if (us->ppa == 0 || us->ppa->lowerq == 0) - break; - putnext(us->ppa->lowerq, mp); - error = -1; - } - break; - - case PPPIO_NPMODE: - if (iop->ioc_count != 2 * sizeof(int)) - break; - if ((us->flags & US_CONTROL) == 0) - break; - if (mp->b_cont == 0) { - DPRINT1("pppuwput/%d: ioctl PPPIO_NPMODE b_cont = 0!\n", us->mn); - break; - } - sap = ((int *)mp->b_cont->b_rptr)[0]; - for (nps = us->next; nps != 0; nps = nps->next) { - if (us->flags & US_DBGLOG) - DPRINT2("us = 0x%x, us->next->sap = 0x%x\n", nps, nps->sap); - if (nps->sap == sap) - break; - } - if (nps == 0) { - if (us->flags & US_DBGLOG) - DPRINT2("ppp/%d: no stream for sap %x\n", us->mn, sap); - break; - } - /* XXX possibly should use qwriter here */ - nps->npmode = (enum NPmode) ((int *)mp->b_cont->b_rptr)[1]; - if (nps->npmode != NPMODE_QUEUE && (nps->flags & US_BLOCKED) != 0) - qenable(WR(nps->q)); - iop->ioc_count = 0; - error = 0; - break; - - case PPPIO_GIDLE: - if ((ppa = us->ppa) == 0) - break; - mq = allocb(sizeof(struct ppp_idle), BPRI_HI); - if (mq == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = mq; - mq->b_cont = 0; - pip = (struct ppp_idle *) mq->b_wptr; - pip->xmit_idle = time - ppa->last_sent; - pip->recv_idle = time - ppa->last_recv; - mq->b_wptr += sizeof(struct ppp_idle); - iop->ioc_count = sizeof(struct ppp_idle); - error = 0; - break; - -#ifdef LACHTCP - case SIOCSIFNAME: - /* Sent from IP down to us. Attach the ifstats structure. */ - if (iop->ioc_count != sizeof(struct ifreq) || us->ppa == 0) - break; - ifr = (struct ifreq *)mp->b_cont->b_rptr; - /* Find the unit number in the interface name. */ - for (i = 0; i < IFNAMSIZ; i++) { - if (ifr->ifr_name[i] == 0 || - (ifr->ifr_name[i] >= '0' && - ifr->ifr_name[i] <= '9')) - break; - else - us->ifname[i] = ifr->ifr_name[i]; - } - us->ifname[i] = 0; - - /* Convert the unit number to binary. */ - for (n = 0; i < IFNAMSIZ; i++) { - if (ifr->ifr_name[i] == 0) { - break; - } - else { - n = n * 10 + ifr->ifr_name[i] - '0'; - } - } - - /* Verify the ppa. */ - if (us->ppa->ppa_id != n) - break; - ppa = us->ppa; - - /* Set up the netstat block. */ - strncpy (ppa->ifname, us->ifname, IFNAMSIZ); - - ppa->ifstats.ifs_name = ppa->ifname; - ppa->ifstats.ifs_unit = n; - ppa->ifstats.ifs_active = us->state != DL_UNBOUND; - ppa->ifstats.ifs_mtu = ppa->mtu; - - /* Link in statistics used by netstat. */ - ppa->ifstats.ifs_next = ifstats; - ifstats = &ppa->ifstats; - - iop->ioc_count = 0; - error = 0; - break; - - case SIOCGIFFLAGS: - if (!(us->flags & US_CONTROL)) { - if (us->ppa) - us = us->ppa; - else - break; - } - ((struct iocblk_in *)iop)->ioc_ifflags = us->ifflags; - error = 0; - break; - - case SIOCSIFFLAGS: - if (!(us->flags & US_CONTROL)) { - if (us->ppa) - us = us->ppa; - else - break; - } - us->ifflags = ((struct iocblk_in *)iop)->ioc_ifflags; - error = 0; - break; - - case SIOCSIFADDR: - if (!(us->flags & US_CONTROL)) { - if (us->ppa) - us = us->ppa; - else - break; - } - us->ifflags |= IFF_RUNNING; - ((struct iocblk_in *)iop)->ioc_ifflags |= IFF_RUNNING; - error = 0; - break; - - case SIOCSIFMTU: - /* - * Vanilla SVR4 systems don't handle SIOCSIFMTU, rather - * they take the MTU from the DL_INFO_ACK we sent in response - * to their DL_INFO_REQ. Fortunately, they will update the - * MTU if we send an unsolicited DL_INFO_ACK up. - */ - if ((mq = allocb(sizeof(dl_info_req_t), BPRI_HI)) == 0) - break; /* should do bufcall */ - ((union DL_primitives *)mq->b_rptr)->dl_primitive = DL_INFO_REQ; - mq->b_wptr = mq->b_rptr + sizeof(dl_info_req_t); - dlpi_request(q, mq, us); - error = 0; - break; - - case SIOCGIFNETMASK: - case SIOCSIFNETMASK: - case SIOCGIFADDR: - case SIOCGIFDSTADDR: - case SIOCSIFDSTADDR: - case SIOCGIFMETRIC: - error = 0; - break; -#endif /* LACHTCP */ - - default: - if (us->ppa == 0 || us->ppa->lowerq == 0) - break; - us->ioc_id = iop->ioc_id; - error = -1; - switch (iop->ioc_cmd) { - case PPPIO_GETSTAT: - case PPPIO_GETCSTAT: - if (us->flags & US_LASTMOD) { - error = EINVAL; - break; - } - putnext(us->ppa->lowerq, mp); - break; - default: - if (us->flags & US_PRIV) - putnext(us->ppa->lowerq, mp); - else { - DPRINT1("ppp ioctl %x rejected\n", iop->ioc_cmd); - error = EPERM; - } - break; - } - break; - } - - if (error > 0) { - iop->ioc_error = error; - mp->b_datap->db_type = M_IOCNAK; - qreply(q, mp); - } else if (error == 0) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } - break; - - case M_FLUSH: - if (us->flags & US_DBGLOG) - DPRINT2("ppp/%d: flush %x\n", us->mn, *mp->b_rptr); - if (*mp->b_rptr & FLUSHW) - flushq(q, FLUSHDATA); - if (*mp->b_rptr & FLUSHR) { - *mp->b_rptr &= ~FLUSHW; - qreply(q, mp); - } else - freemsg(mp); - break; - - default: - freemsg(mp); - break; - } - return 0; -} - -#ifndef NO_DLPI -static void -dlpi_request(q, mp, us) - queue_t *q; - mblk_t *mp; - upperstr_t *us; -{ - union DL_primitives *d = (union DL_primitives *) mp->b_rptr; - int size = mp->b_wptr - mp->b_rptr; - mblk_t *reply, *np; - upperstr_t *ppa, *os; - int sap, len; - dl_info_ack_t *info; - dl_bind_ack_t *ackp; -#if DL_CURRENT_VERSION >= 2 - dl_phys_addr_ack_t *paddrack; - static struct ether_addr eaddr = {0}; -#endif - - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: dlpi prim %x len=%d\n", us->mn, - d->dl_primitive, size); - switch (d->dl_primitive) { - case DL_INFO_REQ: - if (size < sizeof(dl_info_req_t)) - goto badprim; - if ((reply = allocb(sizeof(dl_info_ack_t), BPRI_HI)) == 0) - break; /* should do bufcall */ - reply->b_datap->db_type = M_PCPROTO; - info = (dl_info_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_info_ack_t); - bzero((caddr_t) info, sizeof(dl_info_ack_t)); - info->dl_primitive = DL_INFO_ACK; - info->dl_max_sdu = us->ppa? us->ppa->mtu: PPP_MAXMTU; - info->dl_min_sdu = 1; - info->dl_addr_length = sizeof(uint); - info->dl_mac_type = DL_ETHER; /* a bigger lie */ - info->dl_current_state = us->state; - info->dl_service_mode = DL_CLDLS; - info->dl_provider_style = DL_STYLE2; -#if DL_CURRENT_VERSION >= 2 - info->dl_sap_length = sizeof(uint); - info->dl_version = DL_CURRENT_VERSION; -#endif - qreply(q, reply); - break; - - case DL_ATTACH_REQ: - if (size < sizeof(dl_attach_req_t)) - goto badprim; - if (us->state != DL_UNATTACHED || us->ppa != 0) { - dlpi_error(q, us, DL_ATTACH_REQ, DL_OUTSTATE, 0); - break; - } - for (ppa = ppas; ppa != 0; ppa = ppa->nextppa) - if (ppa->ppa_id == d->attach_req.dl_ppa) - break; - if (ppa == 0) { - dlpi_error(q, us, DL_ATTACH_REQ, DL_BADPPA, 0); - break; - } - us->ppa = ppa; - qwriter(q, mp, attach_ppa, PERIM_OUTER); - return; - - case DL_DETACH_REQ: - if (size < sizeof(dl_detach_req_t)) - goto badprim; - if (us->state != DL_UNBOUND || us->ppa == 0) { - dlpi_error(q, us, DL_DETACH_REQ, DL_OUTSTATE, 0); - break; - } - qwriter(q, mp, detach_ppa, PERIM_OUTER); - return; - - case DL_BIND_REQ: - if (size < sizeof(dl_bind_req_t)) - goto badprim; - if (us->state != DL_UNBOUND || us->ppa == 0) { - dlpi_error(q, us, DL_BIND_REQ, DL_OUTSTATE, 0); - break; - } -#if 0 - /* apparently this test fails (unnecessarily?) on some systems */ - if (d->bind_req.dl_service_mode != DL_CLDLS) { - dlpi_error(q, us, DL_BIND_REQ, DL_UNSUPPORTED, 0); - break; - } -#endif - - /* saps must be valid PPP network protocol numbers, - except that we accept ETHERTYPE_IP in place of PPP_IP. */ - sap = d->bind_req.dl_sap; - us->req_sap = sap; - -#if defined(SOL2) - if (us->flags & US_DBGLOG) - DPRINT2("DL_BIND_REQ: ip gives sap = 0x%x, us = 0x%x", sap, us); - - if (sap == ETHERTYPE_IP) /* normal IFF_IPV4 */ - sap = PPP_IP; - else if (sap == ETHERTYPE_IPV6) /* when IFF_IPV6 is set */ - sap = PPP_IPV6; - else if (sap == ETHERTYPE_ALLSAP) /* snoop gives sap of 0 */ - sap = PPP_ALLSAP; - else { - DPRINT2("DL_BIND_REQ: unrecognized sap = 0x%x, us = 0x%x", sap, us); - dlpi_error(q, us, DL_BIND_REQ, DL_BADADDR, 0); - break; - } -#else - if (sap == ETHERTYPE_IP) - sap = PPP_IP; - if (sap < 0x21 || sap > 0x3fff || (sap & 0x101) != 1) { - dlpi_error(q, us, DL_BIND_REQ, DL_BADADDR, 0); - break; - } -#endif /* defined(SOL2) */ - - /* check that no other stream is bound to this sap already. */ - for (os = us->ppa; os != 0; os = os->next) - if (os->sap == sap) - break; - if (os != 0) { - dlpi_error(q, us, DL_BIND_REQ, DL_NOADDR, 0); - break; - } - - us->sap = sap; - us->state = DL_IDLE; - - if ((reply = allocb(sizeof(dl_bind_ack_t) + sizeof(uint), - BPRI_HI)) == 0) - break; /* should do bufcall */ - ackp = (dl_bind_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_bind_ack_t) + sizeof(uint); - reply->b_datap->db_type = M_PCPROTO; - bzero((caddr_t) ackp, sizeof(dl_bind_ack_t)); - ackp->dl_primitive = DL_BIND_ACK; - ackp->dl_sap = sap; - ackp->dl_addr_length = sizeof(uint); - ackp->dl_addr_offset = sizeof(dl_bind_ack_t); - *(uint *)(ackp+1) = sap; - qreply(q, reply); - break; - - case DL_UNBIND_REQ: - if (size < sizeof(dl_unbind_req_t)) - goto badprim; - if (us->state != DL_IDLE) { - dlpi_error(q, us, DL_UNBIND_REQ, DL_OUTSTATE, 0); - break; - } - us->sap = -1; - us->state = DL_UNBOUND; -#ifdef LACHTCP - us->ppa->ifstats.ifs_active = 0; -#endif - dlpi_ok(q, DL_UNBIND_REQ); - break; - - case DL_UNITDATA_REQ: - if (size < sizeof(dl_unitdata_req_t)) - goto badprim; - if (us->state != DL_IDLE) { - dlpi_error(q, us, DL_UNITDATA_REQ, DL_OUTSTATE, 0); - break; - } - if ((ppa = us->ppa) == 0) { - cmn_err(CE_CONT, "ppp: in state dl_idle but ppa == 0?\n"); - break; - } - len = mp->b_cont == 0? 0: msgdsize(mp->b_cont); - if (len > ppa->mtu) { - DPRINT2("dlpi data too large (%d > %d)\n", len, ppa->mtu); - break; - } - -#if defined(SOL2) - /* - * Should there be any promiscuous stream(s), send the data - * up for each promiscuous stream that we recognize. - */ - if (mp->b_cont) - promisc_sendup(ppa, mp->b_cont, us->sap, 0); -#endif /* defined(SOL2) */ - - mp->b_band = 0; -#ifdef PRIOQ - /* Extract s_port & d_port from IP-packet, the code is a bit - dirty here, but so am I, too... */ - if (mp->b_datap->db_type == M_PROTO && us->sap == PPP_IP - && mp->b_cont != 0) { - u_char *bb, *tlh; - int iphlen, len; - u_short *ptr; - u_char band_unset, cur_band, syn; - u_short s_port, d_port; - - bb = mp->b_cont->b_rptr; /* bb points to IP-header*/ - len = mp->b_cont->b_wptr - mp->b_cont->b_rptr; - syn = 0; - s_port = IPPORT_DEFAULT; - d_port = IPPORT_DEFAULT; - if (len >= 20) { /* 20 = minimum length of IP header */ - iphlen = (bb[0] & 0x0f) * 4; - tlh = bb + iphlen; - len -= iphlen; - switch (bb[9]) { - case IPPROTO_TCP: - if (len >= 20) { /* min length of TCP header */ - s_port = (tlh[0] << 8) + tlh[1]; - d_port = (tlh[2] << 8) + tlh[3]; - syn = tlh[13] & 0x02; - } - break; - case IPPROTO_UDP: - if (len >= 8) { /* min length of UDP header */ - s_port = (tlh[0] << 8) + tlh[1]; - d_port = (tlh[2] << 8) + tlh[3]; - } - break; - } - } - - /* - * Now calculate b_band for this packet from the - * port-priority table. - */ - ptr = prioq_table; - cur_band = max_band; - band_unset = 1; - while (*ptr) { - while (*ptr && band_unset) - if (s_port == *ptr || d_port == *ptr++) { - mp->b_band = cur_band; - band_unset = 0; - break; - } - ptr++; - cur_band--; - } - if (band_unset) - mp->b_band = def_band; - /* It may be usable to urge SYN packets a bit */ - if (syn) - mp->b_band++; - } -#endif /* PRIOQ */ - /* this assumes PPP_HDRLEN <= sizeof(dl_unitdata_req_t) */ - if (mp->b_datap->db_ref > 1) { - np = allocb(PPP_HDRLEN, BPRI_HI); - if (np == 0) - break; /* gak! */ - np->b_cont = mp->b_cont; - mp->b_cont = 0; - freeb(mp); - mp = np; - } else - mp->b_datap->db_type = M_DATA; - /* XXX should use dl_dest_addr_offset/length here, - but we would have to translate ETHERTYPE_IP -> PPP_IP */ - mp->b_wptr = mp->b_rptr + PPP_HDRLEN; - mp->b_rptr[0] = PPP_ALLSTATIONS; - mp->b_rptr[1] = PPP_UI; - mp->b_rptr[2] = us->sap >> 8; - mp->b_rptr[3] = us->sap; - if (pass_packet(us, mp, 1)) { - if (!send_data(mp, us)) - putq(q, mp); - } - return; - -#if DL_CURRENT_VERSION >= 2 - case DL_PHYS_ADDR_REQ: - if (size < sizeof(dl_phys_addr_req_t)) - goto badprim; - - /* - * Don't check state because ifconfig sends this one down too - */ - - if ((reply = allocb(sizeof(dl_phys_addr_ack_t)+ETHERADDRL, - BPRI_HI)) == 0) - break; /* should do bufcall */ - reply->b_datap->db_type = M_PCPROTO; - paddrack = (dl_phys_addr_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_phys_addr_ack_t); - bzero((caddr_t) paddrack, sizeof(dl_phys_addr_ack_t)+ETHERADDRL); - paddrack->dl_primitive = DL_PHYS_ADDR_ACK; - paddrack->dl_addr_length = ETHERADDRL; - paddrack->dl_addr_offset = sizeof(dl_phys_addr_ack_t); - bcopy(&eaddr, reply->b_wptr, ETHERADDRL); - reply->b_wptr += ETHERADDRL; - qreply(q, reply); - break; - -#if defined(SOL2) - case DL_PROMISCON_REQ: - if (size < sizeof(dl_promiscon_req_t)) - goto badprim; - us->flags |= US_PROMISC; - dlpi_ok(q, DL_PROMISCON_REQ); - break; - - case DL_PROMISCOFF_REQ: - if (size < sizeof(dl_promiscoff_req_t)) - goto badprim; - us->flags &= ~US_PROMISC; - dlpi_ok(q, DL_PROMISCOFF_REQ); - break; -#else - case DL_PROMISCON_REQ: /* fall thru */ - case DL_PROMISCOFF_REQ: /* fall thru */ -#endif /* defined(SOL2) */ -#endif /* DL_CURRENT_VERSION >= 2 */ - -#if DL_CURRENT_VERSION >= 2 - case DL_SET_PHYS_ADDR_REQ: - case DL_SUBS_BIND_REQ: - case DL_SUBS_UNBIND_REQ: - case DL_ENABMULTI_REQ: - case DL_DISABMULTI_REQ: - case DL_XID_REQ: - case DL_TEST_REQ: - case DL_REPLY_UPDATE_REQ: - case DL_REPLY_REQ: - case DL_DATA_ACK_REQ: -#endif - case DL_CONNECT_REQ: - case DL_TOKEN_REQ: - dlpi_error(q, us, d->dl_primitive, DL_NOTSUPPORTED, 0); - break; - - case DL_CONNECT_RES: - case DL_DISCONNECT_REQ: - case DL_RESET_REQ: - case DL_RESET_RES: - dlpi_error(q, us, d->dl_primitive, DL_OUTSTATE, 0); - break; - - case DL_UDQOS_REQ: - dlpi_error(q, us, d->dl_primitive, DL_BADQOSTYPE, 0); - break; - -#if DL_CURRENT_VERSION >= 2 - case DL_TEST_RES: - case DL_XID_RES: - break; -#endif - - default: - cmn_err(CE_CONT, "ppp: unknown dlpi prim 0x%x\n", d->dl_primitive); - /* fall through */ - badprim: - dlpi_error(q, us, d->dl_primitive, DL_BADPRIM, 0); - break; - } - freemsg(mp); -} - -static void -dlpi_error(q, us, prim, err, uerr) - queue_t *q; - upperstr_t *us; - int prim, err, uerr; -{ - mblk_t *reply; - dl_error_ack_t *errp; - - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: dlpi error, prim=%x, err=%x\n", us->mn, prim, err); - reply = allocb(sizeof(dl_error_ack_t), BPRI_HI); - if (reply == 0) - return; /* XXX should do bufcall */ - reply->b_datap->db_type = M_PCPROTO; - errp = (dl_error_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_error_ack_t); - errp->dl_primitive = DL_ERROR_ACK; - errp->dl_error_primitive = prim; - errp->dl_errno = err; - errp->dl_unix_errno = uerr; - qreply(q, reply); -} - -static void -dlpi_ok(q, prim) - queue_t *q; - int prim; -{ - mblk_t *reply; - dl_ok_ack_t *okp; - - reply = allocb(sizeof(dl_ok_ack_t), BPRI_HI); - if (reply == 0) - return; /* XXX should do bufcall */ - reply->b_datap->db_type = M_PCPROTO; - okp = (dl_ok_ack_t *) reply->b_wptr; - reply->b_wptr += sizeof(dl_ok_ack_t); - okp->dl_primitive = DL_OK_ACK; - okp->dl_correct_primitive = prim; - qreply(q, reply); -} -#endif /* NO_DLPI */ - -static int -pass_packet(us, mp, outbound) - upperstr_t *us; - mblk_t *mp; - int outbound; -{ - int pass; - upperstr_t *ppa; - - if ((ppa = us->ppa) == 0) { - freemsg(mp); - return 0; - } - -#ifdef FILTER_PACKETS - pass = ip_hard_filter(us, mp, outbound); -#else - /* - * Here is where we might, in future, decide whether to pass - * or drop the packet, and whether it counts as link activity. - */ - pass = 1; -#endif /* FILTER_PACKETS */ - - if (pass < 0) { - /* pass only if link already up, and don't update time */ - if (ppa->lowerq == 0) { - freemsg(mp); - return 0; - } - pass = 1; - } else if (pass) { - if (outbound) - ppa->last_sent = time; - else - ppa->last_recv = time; - } - - return pass; -} - -/* - * We have some data to send down to the lower stream (or up the - * control stream, if we don't have a lower stream attached). - * Returns 1 if the message was dealt with, 0 if it wasn't able - * to be sent on and should therefore be queued up. - */ -static int -send_data(mp, us) - mblk_t *mp; - upperstr_t *us; -{ - upperstr_t *ppa; - - if ((us->flags & US_BLOCKED) || us->npmode == NPMODE_QUEUE) - return 0; - ppa = us->ppa; - if (ppa == 0 || us->npmode == NPMODE_DROP || us->npmode == NPMODE_ERROR) { - if (us->flags & US_DBGLOG) - DPRINT2("ppp/%d: dropping pkt (npmode=%d)\n", us->mn, us->npmode); - freemsg(mp); - return 1; - } - if (ppa->lowerq == 0) { - /* try to send it up the control stream */ - if (bcanputnext(ppa->q, mp->b_band)) { - /* - * The message seems to get corrupted for some reason if - * we just send the message up as it is, so we send a copy. - */ - mblk_t *np = copymsg(mp); - freemsg(mp); - if (np != 0) - putnext(ppa->q, np); - return 1; - } - } else { - if (bcanputnext(ppa->lowerq, mp->b_band)) { - MT_ENTER(&ppa->stats_lock); - ppa->stats.ppp_opackets++; - ppa->stats.ppp_obytes += msgdsize(mp); -#ifdef INCR_OPACKETS - INCR_OPACKETS(ppa); -#endif - MT_EXIT(&ppa->stats_lock); - /* - * The lower queue is only ever detached while holding an - * exclusive lock on the whole driver. So we can be confident - * that the lower queue is still there. - */ - putnext(ppa->lowerq, mp); - return 1; - } - } - us->flags |= US_BLOCKED; - return 0; -} - -/* - * Allocate a new PPA id and link this stream into the list of PPAs. - * This procedure is called with an exclusive lock on all queues in - * this driver. - */ -static void -new_ppa(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us, *up, **usp; - int ppa_id; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("new_ppa: q_ptr = 0!\n"); - return; - } - - usp = &ppas; - ppa_id = 0; - while ((up = *usp) != 0 && ppa_id == up->ppa_id) { - ++ppa_id; - usp = &up->nextppa; - } - us->ppa_id = ppa_id; - us->ppa = us; - us->next = 0; - us->nextppa = *usp; - *usp = us; - us->flags |= US_CONTROL; - us->npmode = NPMODE_PASS; - - us->mtu = PPP_MTU; - us->mru = PPP_MRU; - -#ifdef SOL2 - /* - * Create a kstats record for our statistics, so netstat -i works. - */ - if (us->kstats == 0) { - char unit[32]; - - sprintf(unit, "ppp%d", us->ppa->ppa_id); - us->kstats = kstat_create("ppp", us->ppa->ppa_id, unit, - "net", KSTAT_TYPE_NAMED, 4, 0); - if (us->kstats != 0) { - kstat_named_t *kn = KSTAT_NAMED_PTR(us->kstats); - - strcpy(kn[0].name, "ipackets"); - kn[0].data_type = KSTAT_DATA_ULONG; - strcpy(kn[1].name, "ierrors"); - kn[1].data_type = KSTAT_DATA_ULONG; - strcpy(kn[2].name, "opackets"); - kn[2].data_type = KSTAT_DATA_ULONG; - strcpy(kn[3].name, "oerrors"); - kn[3].data_type = KSTAT_DATA_ULONG; - kstat_install(us->kstats); - } - } -#endif /* SOL2 */ - - *(int *)mp->b_cont->b_rptr = ppa_id; - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); -} - -static void -attach_ppa(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us, *t; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("attach_ppa: q_ptr = 0!\n"); - return; - } - -#ifndef NO_DLPI - us->state = DL_UNBOUND; -#endif - for (t = us->ppa; t->next != 0; t = t->next) - ; - t->next = us; - us->next = 0; - if (mp->b_datap->db_type == M_IOCTL) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } else { -#ifndef NO_DLPI - dlpi_ok(q, DL_ATTACH_REQ); -#endif - } -} - -static void -detach_ppa(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us, *t; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("detach_ppa: q_ptr = 0!\n"); - return; - } - - for (t = us->ppa; t->next != 0; t = t->next) - if (t->next == us) { - t->next = us->next; - break; - } - us->next = 0; - us->ppa = 0; -#ifndef NO_DLPI - us->state = DL_UNATTACHED; - dlpi_ok(q, DL_DETACH_REQ); -#endif -} - -/* - * We call this with qwriter in order to give the upper queue procedures - * the guarantee that the lower queue is not going to go away while - * they are executing. - */ -static void -detach_lower(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("detach_lower: q_ptr = 0!\n"); - return; - } - - LOCK_LOWER_W; - us->lowerq->q_ptr = 0; - RD(us->lowerq)->q_ptr = 0; - us->lowerq = 0; - UNLOCK_LOWER; - - /* Unblock streams which now feed back up the control stream. */ - qenable(us->q); - - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); -} - -static int -pppuwsrv(q) - queue_t *q; -{ - upperstr_t *us, *as; - mblk_t *mp; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("pppuwsrv: q_ptr = 0!\n"); - return 0; - } - - /* - * If this is a control stream, then this service procedure - * probably got enabled because of flow control in the lower - * stream being enabled (or because of the lower stream going - * away). Therefore we enable the service procedure of all - * attached upper streams. - */ - if (us->flags & US_CONTROL) { - for (as = us->next; as != 0; as = as->next) - qenable(WR(as->q)); - } - - /* Try to send on any data queued here. */ - us->flags &= ~US_BLOCKED; - while ((mp = getq(q)) != 0) { - if (!send_data(mp, us)) { - putbq(q, mp); - break; - } - } - - return 0; -} - -/* should never get called... */ -static int -ppplwput(q, mp) - queue_t *q; - mblk_t *mp; -{ - putnext(q, mp); - return 0; -} - -static int -ppplwsrv(q) - queue_t *q; -{ - queue_t *uq; - - /* - * Flow control has back-enabled this stream: - * enable the upper write service procedure for - * the upper control stream for this lower stream. - */ - LOCK_LOWER_R; - uq = (queue_t *) q->q_ptr; - if (uq != 0) - qenable(uq); - UNLOCK_LOWER; - return 0; -} - -/* - * This should only get called for control streams. - */ -static int -pppurput(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *ppa, *us; - int proto, len; - struct iocblk *iop; - - ppa = (upperstr_t *) q->q_ptr; - if (ppa == 0) { - DPRINT("pppurput: q_ptr = 0!\n"); - return 0; - } - - switch (mp->b_datap->db_type) { - case M_CTL: - MT_ENTER(&ppa->stats_lock); - switch (*mp->b_rptr) { - case PPPCTL_IERROR: -#ifdef INCR_IERRORS - INCR_IERRORS(ppa); -#endif - ppa->stats.ppp_ierrors++; - break; - case PPPCTL_OERROR: -#ifdef INCR_OERRORS - INCR_OERRORS(ppa); -#endif - ppa->stats.ppp_oerrors++; - break; - } - MT_EXIT(&ppa->stats_lock); - freemsg(mp); - break; - - case M_IOCACK: - case M_IOCNAK: - /* - * Attempt to match up the response with the stream - * that the request came from. - */ - iop = (struct iocblk *) mp->b_rptr; - for (us = ppa; us != 0; us = us->next) - if (us->ioc_id == iop->ioc_id) - break; - if (us == 0) - freemsg(mp); - else - putnext(us->q, mp); - break; - - case M_HANGUP: - /* - * The serial device has hung up. We don't want to send - * the M_HANGUP message up to pppd because that will stop - * us from using the control stream any more. Instead we - * send a zero-length message as an end-of-file indication. - */ - freemsg(mp); - mp = allocb(1, BPRI_HI); - if (mp == 0) { - DPRINT1("ppp/%d: couldn't allocate eof message!\n", ppa->mn); - break; - } - putnext(ppa->q, mp); - break; - - default: - if (mp->b_datap->db_type == M_DATA) { - len = msgdsize(mp); - if (mp->b_wptr - mp->b_rptr < PPP_HDRLEN) { - PULLUP(mp, PPP_HDRLEN); - if (mp == 0) { - DPRINT1("ppp_urput: msgpullup failed (len=%d)\n", len); - break; - } - } - MT_ENTER(&ppa->stats_lock); - ppa->stats.ppp_ipackets++; - ppa->stats.ppp_ibytes += len; -#ifdef INCR_IPACKETS - INCR_IPACKETS(ppa); -#endif - MT_EXIT(&ppa->stats_lock); - - proto = PPP_PROTOCOL(mp->b_rptr); - -#if defined(SOL2) - /* - * Should there be any promiscuous stream(s), send the data - * up for each promiscuous stream that we recognize. - */ - promisc_sendup(ppa, mp, proto, 1); -#endif /* defined(SOL2) */ - - if (proto < 0x8000 && (us = find_dest(ppa, proto)) != 0) { - /* - * A data packet for some network protocol. - * Queue it on the upper stream for that protocol. - * XXX could we just putnext it? (would require thought) - * The rblocked flag is there to ensure that we keep - * messages in order for each network protocol. - */ - if (!pass_packet(us, mp, 0)) - break; - if (!us->rblocked && !canput(us->q)) - us->rblocked = 1; - if (!us->rblocked) - putq(us->q, mp); - else - putq(q, mp); - break; - } - } - /* - * A control frame, a frame for an unknown protocol, - * or some other message type. - * Send it up to pppd via the control stream. - */ - if (queclass(mp) == QPCTL || canputnext(ppa->q)) - putnext(ppa->q, mp); - else - putq(q, mp); - break; - } - - return 0; -} - -static int -pppursrv(q) - queue_t *q; -{ - upperstr_t *us, *as; - mblk_t *mp, *hdr; -#ifndef NO_DLPI - dl_unitdata_ind_t *ud; -#endif - int proto; - - us = (upperstr_t *) q->q_ptr; - if (us == 0) { - DPRINT("pppursrv: q_ptr = 0!\n"); - return 0; - } - - if (us->flags & US_CONTROL) { - /* - * A control stream. - * If there is no lower queue attached, run the write service - * routines of other upper streams attached to this PPA. - */ - if (us->lowerq == 0) { - as = us; - do { - if (as->flags & US_BLOCKED) - qenable(WR(as->q)); - as = as->next; - } while (as != 0); - } - - /* - * Messages get queued on this stream's read queue if they - * can't be queued on the read queue of the attached stream - * that they are destined for. This is for flow control - - * when this queue fills up, the lower read put procedure will - * queue messages there and the flow control will propagate - * down from there. - */ - while ((mp = getq(q)) != 0) { - proto = PPP_PROTOCOL(mp->b_rptr); - if (proto < 0x8000 && (as = find_dest(us, proto)) != 0) { - if (!canput(as->q)) - break; - putq(as->q, mp); - } else { - if (!canputnext(q)) - break; - putnext(q, mp); - } - } - if (mp) { - putbq(q, mp); - } else { - /* can now put stuff directly on network protocol streams again */ - for (as = us->next; as != 0; as = as->next) - as->rblocked = 0; - } - - /* - * If this stream has a lower stream attached, - * enable the read queue's service routine. - * XXX we should really only do this if the queue length - * has dropped below the low-water mark. - */ - if (us->lowerq != 0) - qenable(RD(us->lowerq)); - - } else { - /* - * A network protocol stream. Put a DLPI header on each - * packet and send it on. - * (Actually, it seems that the IP module will happily - * accept M_DATA messages without the DL_UNITDATA_IND header.) - */ - while ((mp = getq(q)) != 0) { - if (!canputnext(q)) { - putbq(q, mp); - break; - } -#ifndef NO_DLPI - proto = PPP_PROTOCOL(mp->b_rptr); - mp->b_rptr += PPP_HDRLEN; - hdr = allocb(sizeof(dl_unitdata_ind_t) + 2 * sizeof(uint), - BPRI_MED); - if (hdr == 0) { - /* XXX should put it back and use bufcall */ - freemsg(mp); - continue; - } - hdr->b_datap->db_type = M_PROTO; - ud = (dl_unitdata_ind_t *) hdr->b_wptr; - hdr->b_wptr += sizeof(dl_unitdata_ind_t) + 2 * sizeof(uint); - hdr->b_cont = mp; - ud->dl_primitive = DL_UNITDATA_IND; - ud->dl_dest_addr_length = sizeof(uint); - ud->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t); - ud->dl_src_addr_length = sizeof(uint); - ud->dl_src_addr_offset = ud->dl_dest_addr_offset + sizeof(uint); -#if DL_CURRENT_VERSION >= 2 - ud->dl_group_address = 0; -#endif - /* Send the DLPI client the data with the SAP they requested, - (e.g. ETHERTYPE_IP) rather than the PPP protocol number - (e.g. PPP_IP) */ - ((uint *)(ud + 1))[0] = us->req_sap; /* dest SAP */ - ((uint *)(ud + 1))[1] = us->req_sap; /* src SAP */ - putnext(q, hdr); -#else /* NO_DLPI */ - putnext(q, mp); -#endif /* NO_DLPI */ - } - /* - * Now that we have consumed some packets from this queue, - * enable the control stream's read service routine so that we - * can process any packets for us that might have got queued - * there for flow control reasons. - */ - if (us->ppa) - qenable(us->ppa->q); - } - - return 0; -} - -static upperstr_t * -find_dest(ppa, proto) - upperstr_t *ppa; - int proto; -{ - upperstr_t *us; - - for (us = ppa->next; us != 0; us = us->next) - if (proto == us->sap) - break; - return us; -} - -#if defined (SOL2) -/* - * Test upstream promiscuous conditions. As of now, only pass IPv4 and - * Ipv6 packets upstream (let PPP packets be decoded elsewhere). - */ -static upperstr_t * -find_promisc(us, proto) - upperstr_t *us; - int proto; -{ - - if ((proto != PPP_IP) && (proto != PPP_IPV6)) - return (upperstr_t *)0; - - for ( ; us; us = us->next) { - if ((us->flags & US_PROMISC) && (us->state == DL_IDLE)) - return us; - } - - return (upperstr_t *)0; -} - -/* - * Prepend an empty Ethernet header to msg for snoop, et al. - */ -static mblk_t * -prepend_ether(us, mp, proto) - upperstr_t *us; - mblk_t *mp; - int proto; -{ - mblk_t *eh; - int type; - - if ((eh = allocb(sizeof(struct ether_header), BPRI_HI)) == 0) { - freemsg(mp); - return (mblk_t *)0; - } - - if (proto == PPP_IP) - type = ETHERTYPE_IP; - else if (proto == PPP_IPV6) - type = ETHERTYPE_IPV6; - else - type = proto; /* What else? Let decoder decide */ - - eh->b_wptr += sizeof(struct ether_header); - bzero((caddr_t)eh->b_rptr, sizeof(struct ether_header)); - ((struct ether_header *)eh->b_rptr)->ether_type = htons((short)type); - eh->b_cont = mp; - return (eh); -} - -/* - * Prepend DL_UNITDATA_IND mblk to msg - */ -static mblk_t * -prepend_udind(us, mp, proto) - upperstr_t *us; - mblk_t *mp; - int proto; -{ - dl_unitdata_ind_t *dlu; - mblk_t *dh; - size_t size; - - size = sizeof(dl_unitdata_ind_t); - if ((dh = allocb(size, BPRI_MED)) == 0) { - freemsg(mp); - return (mblk_t *)0; - } - - dh->b_datap->db_type = M_PROTO; - dh->b_wptr = dh->b_datap->db_lim; - dh->b_rptr = dh->b_wptr - size; - - dlu = (dl_unitdata_ind_t *)dh->b_rptr; - dlu->dl_primitive = DL_UNITDATA_IND; - dlu->dl_dest_addr_length = 0; - dlu->dl_dest_addr_offset = sizeof(dl_unitdata_ind_t); - dlu->dl_src_addr_length = 0; - dlu->dl_src_addr_offset = sizeof(dl_unitdata_ind_t); - dlu->dl_group_address = 0; - - dh->b_cont = mp; - return (dh); -} - -/* - * For any recognized promiscuous streams, send data upstream - */ -static void -promisc_sendup(ppa, mp, proto, skip) - upperstr_t *ppa; - mblk_t *mp; - int proto, skip; -{ - mblk_t *dup_mp, *dup_dup_mp; - upperstr_t *prus, *nprus; - - if ((prus = find_promisc(ppa, proto)) != 0) { - if (dup_mp = dupmsg(mp)) { - - if (skip) - dup_mp->b_rptr += PPP_HDRLEN; - - for ( ; nprus = find_promisc(prus->next, proto); - prus = nprus) { - - if (dup_dup_mp = dupmsg(dup_mp)) { - if (canputnext(prus->q)) { - if (prus->flags & US_RAWDATA) { - dup_dup_mp = prepend_ether(prus, dup_dup_mp, proto); - putnext(prus->q, dup_dup_mp); - } else { - dup_dup_mp = prepend_udind(prus, dup_dup_mp, proto); - putnext(prus->q, dup_dup_mp); - } - } else { - DPRINT("ppp_urput: data to promisc q dropped\n"); - freemsg(dup_dup_mp); - } - } - } - - if (canputnext(prus->q)) { - if (prus->flags & US_RAWDATA) { - dup_mp = prepend_ether(prus, dup_mp, proto); - putnext(prus->q, dup_mp); - } else { - dup_mp = prepend_udind(prus, dup_mp, proto); - putnext(prus->q, dup_mp); - } - } else { - DPRINT("ppp_urput: data to promisc q dropped\n"); - freemsg(dup_mp); - } - } - } -} -#endif /* defined(SOL2) */ - -/* - * We simply put the message on to the associated upper control stream - * (either here or in ppplrsrv). That way we enter the perimeters - * before looking through the list of attached streams to decide which - * stream it should go up. - */ -static int -ppplrput(q, mp) - queue_t *q; - mblk_t *mp; -{ - queue_t *uq; - struct iocblk *iop; - - switch (mp->b_datap->db_type) { - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - iop->ioc_error = EINVAL; - mp->b_datap->db_type = M_IOCNAK; - qreply(q, mp); - return 0; - case M_FLUSH: - if (*mp->b_rptr & FLUSHR) - flushq(q, FLUSHDATA); - if (*mp->b_rptr & FLUSHW) { - *mp->b_rptr &= ~FLUSHR; - qreply(q, mp); - } else - freemsg(mp); - return 0; - } - - /* - * If we can't get the lower lock straight away, queue this one - * rather than blocking, to avoid the possibility of deadlock. - */ - if (!TRYLOCK_LOWER_R) { - putq(q, mp); - return 0; - } - - /* - * Check that we're still connected to the driver. - */ - uq = (queue_t *) q->q_ptr; - if (uq == 0) { - UNLOCK_LOWER; - DPRINT1("ppplrput: q = %x, uq = 0??\n", q); - freemsg(mp); - return 0; - } - - /* - * Try to forward the message to the put routine for the upper - * control stream for this lower stream. - * If there are already messages queued here, queue this one so - * they don't get out of order. - */ - if (queclass(mp) == QPCTL || (qsize(q) == 0 && canput(uq))) - put(uq, mp); - else - putq(q, mp); - - UNLOCK_LOWER; - return 0; -} - -static int -ppplrsrv(q) - queue_t *q; -{ - mblk_t *mp; - queue_t *uq; - - /* - * Packets get queued here for flow control reasons - * or if the lrput routine couldn't get the lower lock - * without blocking. - */ - LOCK_LOWER_R; - uq = (queue_t *) q->q_ptr; - if (uq == 0) { - UNLOCK_LOWER; - flushq(q, FLUSHALL); - DPRINT1("ppplrsrv: q = %x, uq = 0??\n", q); - return 0; - } - while ((mp = getq(q)) != 0) { - if (queclass(mp) == QPCTL || canput(uq)) - put(uq, mp); - else { - putbq(q, mp); - break; - } - } - UNLOCK_LOWER; - return 0; -} - -static int -putctl2(q, type, code, val) - queue_t *q; - int type, code, val; -{ - mblk_t *mp; - - mp = allocb(2, BPRI_HI); - if (mp == 0) - return 0; - mp->b_datap->db_type = type; - mp->b_wptr[0] = code; - mp->b_wptr[1] = val; - mp->b_wptr += 2; - putnext(q, mp); - return 1; -} - -static int -putctl4(q, type, code, val) - queue_t *q; - int type, code, val; -{ - mblk_t *mp; - - mp = allocb(4, BPRI_HI); - if (mp == 0) - return 0; - mp->b_datap->db_type = type; - mp->b_wptr[0] = code; - ((short *)mp->b_wptr)[1] = val; - mp->b_wptr += 4; - putnext(q, mp); - return 1; -} - -static void -debug_dump(q, mp) - queue_t *q; - mblk_t *mp; -{ - upperstr_t *us; - queue_t *uq, *lq; - - DPRINT("ppp upper streams:\n"); - for (us = minor_devs; us != 0; us = us->nextmn) { - uq = us->q; - DPRINT3(" %d: q=%x rlev=%d", - us->mn, uq, (uq? qsize(uq): 0)); - DPRINT3(" wlev=%d flags=0x%b", (uq? qsize(WR(uq)): 0), - us->flags, "\020\1priv\2control\3blocked\4last"); - DPRINT3(" state=%x sap=%x req_sap=%x", us->state, us->sap, - us->req_sap); - if (us->ppa == 0) - DPRINT(" ppa=?\n"); - else - DPRINT1(" ppa=%d\n", us->ppa->ppa_id); - if (us->flags & US_CONTROL) { - lq = us->lowerq; - DPRINT3(" control for %d lq=%x rlev=%d", - us->ppa_id, lq, (lq? qsize(RD(lq)): 0)); - DPRINT3(" wlev=%d mru=%d mtu=%d\n", - (lq? qsize(lq): 0), us->mru, us->mtu); - } - } - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); -} - -#ifdef FILTER_PACKETS -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/udp.h> -#include <netinet/tcp.h> - -#define MAX_IPHDR 128 /* max TCP/IP header size */ - - -/* The following table contains a hard-coded list of protocol/port pairs. - * Any matching packets are either discarded unconditionally, or, - * if ok_if_link_up is non-zero when a connection does not currently exist - * (i.e., they go through if the connection is present, but never initiate - * a dial-out). - * This idea came from a post by dm@garage.uun.org (David Mazieres) - */ -static struct pktfilt_tab { - int proto; - u_short port; - u_short ok_if_link_up; -} pktfilt_tab[] = { - { IPPROTO_UDP, 520, 1 }, /* RIP, ok to pass if link is up */ - { IPPROTO_UDP, 123, 1 }, /* NTP, don't keep up the link for it */ - { -1, 0, 0 } /* terminator entry has port == -1 */ -}; - - -static int -ip_hard_filter(us, mp, outbound) - upperstr_t *us; - mblk_t *mp; - int outbound; -{ - struct ip *ip; - struct pktfilt_tab *pft; - mblk_t *temp_mp; - int proto; - int len, hlen; - - - /* Note, the PPP header has already been pulled up in all cases */ - proto = PPP_PROTOCOL(mp->b_rptr); - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: filter, proto=0x%x, out=%d\n", us->mn, proto, outbound); - - switch (proto) - { - case PPP_IP: - if ((mp->b_wptr - mp->b_rptr) == PPP_HDRLEN && mp->b_cont != 0) { - temp_mp = mp->b_cont; - len = msgdsize(temp_mp); - hlen = (len < MAX_IPHDR) ? len : MAX_IPHDR; - PULLUP(temp_mp, hlen); - if (temp_mp == 0) { - DPRINT2("ppp/%d: filter, pullup next failed, len=%d\n", - us->mn, hlen); - mp->b_cont = 0; /* PULLUP() freed the rest */ - freemsg(mp); - return 0; - } - ip = (struct ip *)mp->b_cont->b_rptr; - } - else { - len = msgdsize(mp); - hlen = (len < (PPP_HDRLEN+MAX_IPHDR)) ? len : (PPP_HDRLEN+MAX_IPHDR); - PULLUP(mp, hlen); - if (mp == 0) { - DPRINT2("ppp/%d: filter, pullup failed, len=%d\n", - us->mn, hlen); - return 0; - } - ip = (struct ip *)(mp->b_rptr + PPP_HDRLEN); - } - - /* For IP traffic, certain packets (e.g., RIP) may be either - * 1. ignored - dropped completely - * 2. will not initiate a connection, but - * will be passed if a connection is currently up. - */ - for (pft=pktfilt_tab; pft->proto != -1; pft++) { - if (ip->ip_p == pft->proto) { - switch(pft->proto) { - case IPPROTO_UDP: - if (((struct udphdr *) &((int *)ip)[ip->ip_hl])->uh_dport - == htons(pft->port)) goto endfor; - break; - case IPPROTO_TCP: - if (((struct tcphdr *) &((int *)ip)[ip->ip_hl])->th_dport - == htons(pft->port)) goto endfor; - break; - } - } - } - endfor: - if (pft->proto != -1) { - if (us->flags & US_DBGLOG) - DPRINT3("ppp/%d: found IP pkt, proto=0x%x (%d)\n", - us->mn, pft->proto, pft->port); - /* Discard if not connected, or if not pass_with_link_up */ - /* else, if link is up let go by, but don't update time */ - return pft->ok_if_link_up? -1: 0; - } - break; - } /* end switch (proto) */ - - return 1; -} -#endif /* FILTER_PACKETS */ - diff --git a/mdk-stage1/ppp/solaris/ppp.conf b/mdk-stage1/ppp/solaris/ppp.conf deleted file mode 100644 index e443a7aac..000000000 --- a/mdk-stage1/ppp/solaris/ppp.conf +++ /dev/null @@ -1 +0,0 @@ -name="ppp" parent="pseudo" instance=0; diff --git a/mdk-stage1/ppp/solaris/ppp_ahdlc.c b/mdk-stage1/ppp/solaris/ppp_ahdlc.c deleted file mode 100644 index d0b961258..000000000 --- a/mdk-stage1/ppp/solaris/ppp_ahdlc.c +++ /dev/null @@ -1,878 +0,0 @@ -/* - * ppp_ahdlc.c - STREAMS module for doing PPP asynchronous HDLC. - * - * Re-written by Adi Masputra <adi.masputra@sun.com>, based on - * the original ppp_ahdlc.c - * - * Copyright (c) 2000 by Sun Microsystems, Inc. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. - * - * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF - * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -/* - * This file is used under Solaris 2, SVR4, SunOS 4, and Digital UNIX. - */ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stream.h> -#include <sys/errno.h> - -#ifdef SVR4 -#include <sys/conf.h> -#include <sys/kmem.h> -#include <sys/cmn_err.h> -#include <sys/ddi.h> -#else -#include <sys/user.h> -#ifdef __osf__ -#include <sys/cmn_err.h> -#endif -#endif /* SVR4 */ - -#include <net/ppp_defs.h> -#include <net/pppio.h> -#include "ppp_mod.h" - -/* - * Right now, mutex is only enabled for Solaris 2.x - */ -#if defined(SOL2) -#define USE_MUTEX -#endif /* SOL2 */ - -/* - * intpointer_t and uintpointer_t are signed and unsigned integer types - * large enough to hold any data pointer; that is, data pointers can be - * assigned into or from these integer types without losing precision. - * On recent Solaris releases, these types are defined in sys/int_types.h, - * but not on SunOS 4.x or the earlier Solaris versions. - */ -#if defined(_LP64) || defined(_I32LPx) -typedef long intpointer_t; -typedef unsigned long uintpointer_t; -#else -typedef int intpointer_t; -typedef unsigned int uintpointer_t; -#endif - -MOD_OPEN_DECL(ahdlc_open); -MOD_CLOSE_DECL(ahdlc_close); -static int ahdlc_wput __P((queue_t *, mblk_t *)); -static int ahdlc_rput __P((queue_t *, mblk_t *)); -static void ahdlc_encode __P((queue_t *, mblk_t *)); -static void ahdlc_decode __P((queue_t *, mblk_t *)); -static int msg_byte __P((mblk_t *, unsigned int)); - -#if defined(SOL2) -/* - * Don't send HDLC start flag is last transmit is within 1.5 seconds - - * FLAG_TIME is defined is microseconds - */ -#define FLAG_TIME 1500 -#define ABS(x) (x >= 0 ? x : (-x)) -#endif /* SOL2 */ - -/* - * Extract byte i of message mp - */ -#define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \ - msg_byte((mp), (i))) - -/* - * Is this LCP packet one we have to transmit using LCP defaults? - */ -#define LCP_USE_DFLT(mp) (1 <= (code = MSG_BYTE((mp), 4)) && code <= 7) - -/* - * Standard STREAMS declarations - */ -static struct module_info minfo = { - 0x7d23, "ppp_ahdl", 0, INFPSZ, 32768, 512 -}; - -static struct qinit rinit = { - ahdlc_rput, NULL, ahdlc_open, ahdlc_close, NULL, &minfo, NULL -}; - -static struct qinit winit = { - ahdlc_wput, NULL, NULL, NULL, NULL, &minfo, NULL -}; - -#if defined(SVR4) && !defined(SOL2) -int phdldevflag = 0; -#define ppp_ahdlcinfo phdlinfo -#endif /* defined(SVR4) && !defined(SOL2) */ - -struct streamtab ppp_ahdlcinfo = { - &rinit, /* ptr to st_rdinit */ - &winit, /* ptr to st_wrinit */ - NULL, /* ptr to st_muxrinit */ - NULL, /* ptr to st_muxwinit */ -#if defined(SUNOS4) - NULL /* ptr to ptr to st_modlist */ -#endif /* SUNOS4 */ -}; - -#if defined(SUNOS4) -int ppp_ahdlc_count = 0; /* open counter */ -#endif /* SUNOS4 */ - -/* - * Per-stream state structure - */ -typedef struct ahdlc_state { -#if defined(USE_MUTEX) - kmutex_t lock; /* lock for this structure */ -#endif /* USE_MUTEX */ - int flags; /* link flags */ - mblk_t *rx_buf; /* ptr to receive buffer */ - int rx_buf_size; /* receive buffer size */ - ushort_t infcs; /* calculated rx HDLC FCS */ - u_int32_t xaccm[8]; /* 256-bit xmit ACCM */ - u_int32_t raccm; /* 32-bit rcv ACCM */ - int mtu; /* interface MTU */ - int mru; /* link MRU */ - int unit; /* current PPP unit number */ - struct pppstat stats; /* statistic structure */ -#if defined(SOL2) - clock_t flag_time; /* time in usec between flags */ - clock_t lbolt; /* last updated lbolt */ -#endif /* SOL2 */ -} ahdlc_state_t; - -/* - * Values for flags - */ -#define ESCAPED 0x100 /* last saw escape char on input */ -#define IFLUSH 0x200 /* flushing input due to error */ - -/* - * RCV_B7_1, etc., defined in net/pppio.h, are stored in flags also. - */ -#define RCV_FLAGS (RCV_B7_1|RCV_B7_0|RCV_ODDP|RCV_EVNP) - -/* - * FCS lookup table as calculated by genfcstab. - */ -static u_short fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -static u_int32_t paritytab[8] = -{ - 0x96696996, 0x69969669, 0x69969669, 0x96696996, - 0x69969669, 0x96696996, 0x96696996, 0x69969669 -}; - -/* - * STREAMS module open (entry) point - */ -MOD_OPEN(ahdlc_open) -{ - ahdlc_state_t *state; - - /* - * Return if it's already opened - */ - if (q->q_ptr) { - return 0; - } - - /* - * This can only be opened as a module - */ - if (sflag != MODOPEN) { - return 0; - } - - state = (ahdlc_state_t *) ALLOC_NOSLEEP(sizeof(ahdlc_state_t)); - if (state == 0) - OPEN_ERROR(ENOSR); - bzero((caddr_t) state, sizeof(ahdlc_state_t)); - - q->q_ptr = (caddr_t) state; - WR(q)->q_ptr = (caddr_t) state; - -#if defined(USE_MUTEX) - mutex_init(&state->lock, NULL, MUTEX_DEFAULT, NULL); - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - - state->xaccm[0] = ~0; /* escape 0x00 through 0x1f */ - state->xaccm[3] = 0x60000000; /* escape 0x7d and 0x7e */ - state->mru = PPP_MRU; /* default of 1500 bytes */ -#if defined(SOL2) - state->flag_time = drv_usectohz(FLAG_TIME); -#endif /* SOL2 */ - -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - -#if defined(SUNOS4) - ppp_ahdlc_count++; -#endif /* SUNOS4 */ - - qprocson(q); - - return 0; -} - -/* - * STREAMS module close (exit) point - */ -MOD_CLOSE(ahdlc_close) -{ - ahdlc_state_t *state; - - qprocsoff(q); - - state = (ahdlc_state_t *) q->q_ptr; - - if (state == 0) { - DPRINT("state == 0 in ahdlc_close\n"); - return 0; - } - -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - - if (state->rx_buf != 0) { - freemsg(state->rx_buf); - state->rx_buf = 0; - } - -#if defined(USE_MUTEX) - mutex_exit(&state->lock); - mutex_destroy(&state->lock); -#endif /* USE_MUTEX */ - - FREE(q->q_ptr, sizeof(ahdlc_state_t)); - q->q_ptr = NULL; - OTHERQ(q)->q_ptr = NULL; - -#if defined(SUNOS4) - if (ppp_ahdlc_count) - ppp_ahdlc_count--; -#endif /* SUNOS4 */ - - return 0; -} - -/* - * Write side put routine - */ -static int -ahdlc_wput(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - struct iocblk *iop; - int error; - mblk_t *np; - struct ppp_stats *psp; - - state = (ahdlc_state_t *) q->q_ptr; - if (state == 0) { - DPRINT("state == 0 in ahdlc_wput\n"); - freemsg(mp); - return 0; - } - - switch (mp->b_datap->db_type) { - case M_DATA: - /* - * A data packet - do character-stuffing and FCS, and - * send it onwards. - */ - ahdlc_encode(q, mp); - freemsg(mp); - break; - - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - error = EINVAL; - switch (iop->ioc_cmd) { - case PPPIO_XACCM: - if ((iop->ioc_count < sizeof(u_int32_t)) || - (iop->ioc_count > sizeof(ext_accm))) { - break; - } - if (mp->b_cont == 0) { - DPRINT1("ahdlc_wput/%d: PPPIO_XACCM b_cont = 0!\n", state->unit); - break; - } -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)state->xaccm, - iop->ioc_count); - state->xaccm[2] &= ~0x40000000; /* don't escape 0x5e */ - state->xaccm[3] |= 0x60000000; /* do escape 0x7d, 0x7e */ -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - iop->ioc_count = 0; - error = 0; - break; - - case PPPIO_RACCM: - if (iop->ioc_count != sizeof(u_int32_t)) - break; - if (mp->b_cont == 0) { - DPRINT1("ahdlc_wput/%d: PPPIO_RACCM b_cont = 0!\n", state->unit); - break; - } -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - bcopy((caddr_t)mp->b_cont->b_rptr, (caddr_t)&state->raccm, - sizeof(u_int32_t)); -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - iop->ioc_count = 0; - error = 0; - break; - - case PPPIO_GCLEAN: - np = allocb(sizeof(int), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - *(int *)np->b_wptr = state->flags & RCV_FLAGS; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - np->b_wptr += sizeof(int); - iop->ioc_count = sizeof(int); - error = 0; - break; - - case PPPIO_GETSTAT: - np = allocb(sizeof(struct ppp_stats), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - psp = (struct ppp_stats *) np->b_wptr; - np->b_wptr += sizeof(struct ppp_stats); - bzero((caddr_t)psp, sizeof(struct ppp_stats)); - psp->p = state->stats; - iop->ioc_count = sizeof(struct ppp_stats); - error = 0; - break; - - case PPPIO_LASTMOD: - /* we knew this anyway */ - error = 0; - break; - - default: - error = -1; - break; - } - - if (error < 0) - putnext(q, mp); - else if (error == 0) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } else { - mp->b_datap->db_type = M_IOCNAK; - iop->ioc_count = 0; - iop->ioc_error = error; - qreply(q, mp); - } - break; - - case M_CTL: - switch (*mp->b_rptr) { - case PPPCTL_MTU: -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - state->mtu = ((unsigned short *)mp->b_rptr)[1]; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - freemsg(mp); - break; - case PPPCTL_MRU: -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - state->mru = ((unsigned short *)mp->b_rptr)[1]; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - freemsg(mp); - break; - case PPPCTL_UNIT: -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - state->unit = mp->b_rptr[1]; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - break; - default: - putnext(q, mp); - } - break; - - default: - putnext(q, mp); - } - - return 0; -} - -/* - * Read side put routine - */ -static int -ahdlc_rput(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - - state = (ahdlc_state_t *) q->q_ptr; - if (state == 0) { - DPRINT("state == 0 in ahdlc_rput\n"); - freemsg(mp); - return 0; - } - - switch (mp->b_datap->db_type) { - case M_DATA: - ahdlc_decode(q, mp); - freemsg(mp); - break; - - case M_HANGUP: -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - if (state->rx_buf != 0) { - /* XXX would like to send this up for debugging */ - freemsg(state->rx_buf); - state->rx_buf = 0; - } - state->flags = IFLUSH; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - putnext(q, mp); - break; - - default: - putnext(q, mp); - } - return 0; -} - -/* - * Extract bit c from map m, to determine if c needs to be escaped - */ -#define IN_TX_MAP(c, m) ((m)[(c) >> 5] & (1 << ((c) & 0x1f))) - -static void -ahdlc_encode(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - u_int32_t *xaccm, loc_xaccm[8]; - ushort_t fcs; - size_t outmp_len; - mblk_t *outmp, *tmp; - uchar_t *dp, fcs_val; - int is_lcp, code; -#if defined(SOL2) - clock_t lbolt; -#endif /* SOL2 */ - - if (msgdsize(mp) < 4) { - return; - } - - state = (ahdlc_state_t *)q->q_ptr; -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - - /* - * Allocate an output buffer large enough to handle a case where all - * characters need to be escaped - */ - outmp_len = (msgdsize(mp) << 1) + /* input block x 2 */ - (sizeof(fcs) << 2) + /* HDLC FCS x 4 */ - (sizeof(uchar_t) << 1); /* HDLC flags x 2 */ - - outmp = allocb(outmp_len, BPRI_MED); - if (outmp == NULL) { - state->stats.ppp_oerrors++; -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); - return; - } - -#if defined(SOL2) - /* - * Check if our last transmit happenned within flag_time, using - * the system's LBOLT value in clock ticks - */ - if (drv_getparm(LBOLT, &lbolt) != -1) { - if (ABS((clock_t)lbolt - state->lbolt) > state->flag_time) { - *outmp->b_wptr++ = PPP_FLAG; - } - state->lbolt = lbolt; - } else { - *outmp->b_wptr++ = PPP_FLAG; - } -#else - /* - * If the driver below still has a message to process, skip the - * HDLC flag, otherwise, put one in the beginning - */ - if (qsize(q->q_next) == 0) { - *outmp->b_wptr++ = PPP_FLAG; - } -#endif - - /* - * All control characters must be escaped for LCP packets with code - * values between 1 (Conf-Req) and 7 (Code-Rej). - */ - is_lcp = ((MSG_BYTE(mp, 0) == PPP_ALLSTATIONS) && - (MSG_BYTE(mp, 1) == PPP_UI) && - (MSG_BYTE(mp, 2) == (PPP_LCP >> 8)) && - (MSG_BYTE(mp, 3) == (PPP_LCP & 0xff)) && - LCP_USE_DFLT(mp)); - - xaccm = state->xaccm; - if (is_lcp) { - bcopy((caddr_t)state->xaccm, (caddr_t)loc_xaccm, sizeof(loc_xaccm)); - loc_xaccm[0] = ~0; /* force escape on 0x00 through 0x1f */ - xaccm = loc_xaccm; - } - - fcs = PPP_INITFCS; /* Initial FCS is 0xffff */ - - /* - * Process this block and the rest (if any) attached to the this one - */ - for (tmp = mp; tmp; tmp = tmp->b_cont) { - if (tmp->b_datap->db_type == M_DATA) { - for (dp = tmp->b_rptr; dp < tmp->b_wptr; dp++) { - fcs = PPP_FCS(fcs, *dp); - if (IN_TX_MAP(*dp, xaccm)) { - *outmp->b_wptr++ = PPP_ESCAPE; - *outmp->b_wptr++ = *dp ^ PPP_TRANS; - } else { - *outmp->b_wptr++ = *dp; - } - } - } else { - continue; /* skip if db_type is something other than M_DATA */ - } - } - - /* - * Append the HDLC FCS, making sure that escaping is done on any - * necessary bytes - */ - fcs_val = (fcs ^ 0xffff) & 0xff; - if (IN_TX_MAP(fcs_val, xaccm)) { - *outmp->b_wptr++ = PPP_ESCAPE; - *outmp->b_wptr++ = fcs_val ^ PPP_TRANS; - } else { - *outmp->b_wptr++ = fcs_val; - } - - fcs_val = ((fcs ^ 0xffff) >> 8) & 0xff; - if (IN_TX_MAP(fcs_val, xaccm)) { - *outmp->b_wptr++ = PPP_ESCAPE; - *outmp->b_wptr++ = fcs_val ^ PPP_TRANS; - } else { - *outmp->b_wptr++ = fcs_val; - } - - /* - * And finally, append the HDLC flag, and send it away - */ - *outmp->b_wptr++ = PPP_FLAG; - - state->stats.ppp_obytes += msgdsize(outmp); - state->stats.ppp_opackets++; - -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ - - putnext(q, outmp); - return; -} - -/* - * Checks the 32-bit receive ACCM to see if the byte needs un-escaping - */ -#define IN_RX_MAP(c, m) ((((unsigned int) (uchar_t) (c)) < 0x20) && \ - (m) & (1 << (c))) - - -/* - * Process received characters. - */ -static void -ahdlc_decode(q, mp) - queue_t *q; - mblk_t *mp; -{ - ahdlc_state_t *state; - mblk_t *om; - uchar_t *dp; - ushort_t fcs; -#if defined(SOL2) - mblk_t *zmp; -#endif /* SOL2 */ - -#if defined(SOL2) - /* - * In case the driver (or something below) doesn't send - * data upstream in one message block, concatenate everything - */ - if (!((mp->b_wptr - mp->b_rptr == msgdsize(mp)) && - ((intpointer_t)mp->b_rptr % sizeof(intpointer_t) == 0))) { - - zmp = msgpullup(mp, -1); - freemsg(mp); - mp = zmp; - if (mp == 0) - return; - } -#endif /* SOL2 */ - - state = (ahdlc_state_t *) q->q_ptr; - -#if defined(USE_MUTEX) - mutex_enter(&state->lock); -#endif /* USE_MUTEX */ - - state->stats.ppp_ibytes += msgdsize(mp); - - for (dp = mp->b_rptr; dp < mp->b_wptr; dp++) { - - /* - * This should detect the lack of 8-bit communication channel - * which is necessary for PPP to work. In addition, it also - * checks on the parity. - */ - if (*dp & 0x80) - state->flags |= RCV_B7_1; - else - state->flags |= RCV_B7_0; - - if (paritytab[*dp >> 5] & (1 << (*dp & 0x1f))) - state->flags |= RCV_ODDP; - else - state->flags |= RCV_EVNP; - - /* - * So we have a HDLC flag ... - */ - if (*dp == PPP_FLAG) { - - /* - * If we think that it marks the beginning of the frame, - * then continue to process the next octects - */ - if ((state->flags & IFLUSH) || - (state->rx_buf == 0) || - (msgdsize(state->rx_buf) == 0)) { - - state->flags &= ~IFLUSH; - continue; - } - - /* - * We get here because the above condition isn't true, - * in which case the HDLC flag was there to mark the end - * of the frame (or so we think) - */ - om = state->rx_buf; - - if (state->infcs == PPP_GOODFCS) { - state->stats.ppp_ipackets++; - adjmsg(om, -PPP_FCSLEN); - putnext(q, om); - } else { - DPRINT2("ppp%d: bad fcs (len=%d)\n", - state->unit, msgdsize(state->rx_buf)); - freemsg(state->rx_buf); - state->flags &= ~(IFLUSH | ESCAPED); - state->stats.ppp_ierrors++; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - } - - state->rx_buf = 0; - continue; - } - - if (state->flags & IFLUSH) { - continue; - } - - /* - * Allocate a receive buffer, large enough to store a frame (after - * un-escaping) of at least 1500 octets. If MRU is negotiated to - * be more than the default, then allocate that much. In addition, - * we add an extra 32-bytes for a fudge factor - */ - if (state->rx_buf == 0) { - state->rx_buf_size = (state->mru < PPP_MRU ? PPP_MRU : state->mru); - state->rx_buf_size += (sizeof(u_int32_t) << 3); - state->rx_buf = allocb(state->rx_buf_size, BPRI_MED); - - /* - * If allocation fails, try again on the next frame - */ - if (state->rx_buf == 0) { - state->flags |= IFLUSH; - continue; - } - state->flags &= ~(IFLUSH | ESCAPED); - state->infcs = PPP_INITFCS; - } - - if (*dp == PPP_ESCAPE) { - state->flags |= ESCAPED; - continue; - } - - /* - * Make sure we un-escape the necessary characters, as well as the - * ones in our receive async control character map - */ - if (state->flags & ESCAPED) { - *dp ^= PPP_TRANS; - state->flags &= ~ESCAPED; - } else if (IN_RX_MAP(*dp, state->raccm)) - continue; - - /* - * Unless the peer lied to us about the negotiated MRU, we should - * never get a frame which is too long. If it happens, toss it away - * and grab the next incoming one - */ - if (msgdsize(state->rx_buf) < state->rx_buf_size) { - state->infcs = PPP_FCS(state->infcs, *dp); - *state->rx_buf->b_wptr++ = *dp; - } else { - DPRINT2("ppp%d: frame too long (%d)\n", - state->unit, msgdsize(state->rx_buf)); - freemsg(state->rx_buf); - state->rx_buf = 0; - state->flags |= IFLUSH; - } - } - -#if defined(USE_MUTEX) - mutex_exit(&state->lock); -#endif /* USE_MUTEX */ -} - -static int -msg_byte(mp, i) - mblk_t *mp; - unsigned int i; -{ - while (mp != 0 && i >= mp->b_wptr - mp->b_rptr) - mp = mp->b_cont; - if (mp == 0) - return -1; - return mp->b_rptr[i]; -} diff --git a/mdk-stage1/ppp/solaris/ppp_ahdlc_mod.c b/mdk-stage1/ppp/solaris/ppp_ahdlc_mod.c deleted file mode 100644 index f81be8abb..000000000 --- a/mdk-stage1/ppp/solaris/ppp_ahdlc_mod.c +++ /dev/null @@ -1,49 +0,0 @@ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/conf.h> -#include <sys/modctl.h> -#include <sys/sunddi.h> - -extern struct streamtab ppp_ahdlcinfo; - -static struct fmodsw fsw = { - "ppp_ahdl", - &ppp_ahdlcinfo, - D_NEW | D_MP | D_MTQPAIR -}; - -extern struct mod_ops mod_strmodops; - -static struct modlstrmod modlstrmod = { - &mod_strmodops, - "PPP async HDLC module", - &fsw -}; - -static struct modlinkage modlinkage = { - MODREV_1, - (void *) &modlstrmod, - NULL -}; - -/* - * Entry points for modloading. - */ -int -_init(void) -{ - return mod_install(&modlinkage); -} - -int -_fini(void) -{ - return mod_remove(&modlinkage); -} - -int -_info(mip) - struct modinfo *mip; -{ - return mod_info(&modlinkage, mip); -} diff --git a/mdk-stage1/ppp/solaris/ppp_comp.c b/mdk-stage1/ppp/solaris/ppp_comp.c deleted file mode 100644 index f6eef5ab1..000000000 --- a/mdk-stage1/ppp/solaris/ppp_comp.c +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * ppp_comp.c - STREAMS module for kernel-level compression and CCP support. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -/* - * This file is used under SVR4, Solaris 2, SunOS 4, and Digital UNIX. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/errno.h> -#include <sys/stream.h> - -#ifdef SVR4 -#include <sys/conf.h> -#include <sys/cmn_err.h> -#include <sys/ddi.h> -#else -#include <sys/user.h> -#ifdef __osf__ -#include <sys/cmn_err.h> -#endif -#endif /* SVR4 */ - -#include <net/ppp_defs.h> -#include <net/pppio.h> -#include "ppp_mod.h" - -#ifdef __osf__ -#include <sys/mbuf.h> -#include <sys/protosw.h> -#endif - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <net/vjcompress.h> - -#define PACKETPTR mblk_t * -#include <net/ppp-comp.h> - -MOD_OPEN_DECL(ppp_comp_open); -MOD_CLOSE_DECL(ppp_comp_close); -static int ppp_comp_rput __P((queue_t *, mblk_t *)); -static int ppp_comp_rsrv __P((queue_t *)); -static int ppp_comp_wput __P((queue_t *, mblk_t *)); -static int ppp_comp_wsrv __P((queue_t *)); -static void ppp_comp_ccp __P((queue_t *, mblk_t *, int)); -static int msg_byte __P((mblk_t *, unsigned int)); - -/* Extract byte i of message mp. */ -#define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \ - msg_byte((mp), (i))) - -/* Is this LCP packet one we have to transmit using LCP defaults? */ -#define LCP_USE_DFLT(mp) (1 <= (code = MSG_BYTE((mp), 4)) && code <= 7) - -#define PPP_COMP_ID 0xbadf -static struct module_info minfo = { -#ifdef PRIOQ - PPP_COMP_ID, "ppp_comp", 0, INFPSZ, 16512, 16384, -#else - PPP_COMP_ID, "ppp_comp", 0, INFPSZ, 16384, 4096, -#endif -}; - -static struct qinit r_init = { - ppp_comp_rput, ppp_comp_rsrv, ppp_comp_open, ppp_comp_close, - NULL, &minfo, NULL -}; - -static struct qinit w_init = { - ppp_comp_wput, ppp_comp_wsrv, NULL, NULL, NULL, &minfo, NULL -}; - -#if defined(SVR4) && !defined(SOL2) -int pcmpdevflag = 0; -#define ppp_compinfo pcmpinfo -#endif -struct streamtab ppp_compinfo = { - &r_init, &w_init, NULL, NULL -}; - -int ppp_comp_count; /* number of module instances in use */ - -#ifdef __osf__ - -static void ppp_comp_alloc __P((comp_state_t *)); -typedef struct memreq { - unsigned char comp_opts[20]; - int cmd; - int thread_status; - char *returned_mem; -} memreq_t; - -#endif - -typedef struct comp_state { - int flags; - int mru; - int mtu; - int unit; - struct compressor *xcomp; - void *xstate; - struct compressor *rcomp; - void *rstate; - struct vjcompress vj_comp; - int vj_last_ierrors; - struct pppstat stats; -#ifdef __osf__ - memreq_t memreq; - thread_t thread; -#endif -} comp_state_t; - - -#ifdef __osf__ -extern task_t first_task; -#endif - -/* Bits in flags are as defined in pppio.h. */ -#define CCP_ERR (CCP_ERROR | CCP_FATALERROR) -#define LAST_MOD 0x1000000 /* no ppp modules below us */ -#define DBGLOG 0x2000000 /* log debugging stuff */ - -#define MAX_IPHDR 128 /* max TCP/IP header size */ -#define MAX_VJHDR 20 /* max VJ compressed header size (?) */ - -#undef MIN /* just in case */ -#define MIN(a, b) ((a) < (b)? (a): (b)) - -/* - * List of compressors we know about. - */ - -#if DO_BSD_COMPRESS -extern struct compressor ppp_bsd_compress; -#endif -#if DO_DEFLATE -extern struct compressor ppp_deflate, ppp_deflate_draft; -#endif - -struct compressor *ppp_compressors[] = { -#if DO_BSD_COMPRESS - &ppp_bsd_compress, -#endif -#if DO_DEFLATE - &ppp_deflate, - &ppp_deflate_draft, -#endif - NULL -}; - -/* - * STREAMS module entry points. - */ -MOD_OPEN(ppp_comp_open) -{ - comp_state_t *cp; -#ifdef __osf__ - thread_t thread; -#endif - - if (q->q_ptr == NULL) { - cp = (comp_state_t *) ALLOC_SLEEP(sizeof(comp_state_t)); - if (cp == NULL) - OPEN_ERROR(ENOSR); - bzero((caddr_t)cp, sizeof(comp_state_t)); - WR(q)->q_ptr = q->q_ptr = (caddr_t) cp; - cp->mru = PPP_MRU; - cp->mtu = PPP_MTU; - cp->xstate = NULL; - cp->rstate = NULL; - vj_compress_init(&cp->vj_comp, -1); -#ifdef __osf__ - if (!(thread = kernel_thread_w_arg(first_task, ppp_comp_alloc, (void *)cp))) - OPEN_ERROR(ENOSR); - cp->thread = thread; -#endif - ++ppp_comp_count; - qprocson(q); - } - return 0; -} - -MOD_CLOSE(ppp_comp_close) -{ - comp_state_t *cp; - - qprocsoff(q); - cp = (comp_state_t *) q->q_ptr; - if (cp != NULL) { - if (cp->xstate != NULL) - (*cp->xcomp->comp_free)(cp->xstate); - if (cp->rstate != NULL) - (*cp->rcomp->decomp_free)(cp->rstate); -#ifdef __osf__ - if (!cp->thread) - printf("ppp_comp_close: NULL thread!\n"); - else - thread_terminate(cp->thread); -#endif - FREE(cp, sizeof(comp_state_t)); - q->q_ptr = NULL; - OTHERQ(q)->q_ptr = NULL; - --ppp_comp_count; - } - return 0; -} - -#ifdef __osf__ - -/* thread for calling back to a compressor's memory allocator - * Needed for Digital UNIX since it's VM can't handle requests - * for large amounts of memory without blocking. The thread - * provides a context in which we can call a memory allocator - * that may block. - */ -static void -ppp_comp_alloc(comp_state_t *cp) -{ - int len, cmd; - unsigned char *compressor_options; - thread_t thread; - void *(*comp_allocator)(); - - -#if defined(MAJOR_VERSION) && (MAJOR_VERSION <= 2) - - /* In 2.x and earlier the argument gets passed - * in the thread structure itself. Yuck. - */ - thread = current_thread(); - cp = thread->reply_port; - thread->reply_port = PORT_NULL; - -#endif - - for (;;) { - assert_wait((vm_offset_t)&cp->memreq.thread_status, TRUE); - thread_block(); - - if (thread_should_halt(current_thread())) - thread_halt_self(); - cmd = cp->memreq.cmd; - compressor_options = &cp->memreq.comp_opts[0]; - len = compressor_options[1]; - if (cmd == PPPIO_XCOMP) { - cp->memreq.returned_mem = cp->xcomp->comp_alloc(compressor_options, len); - if (!cp->memreq.returned_mem) { - cp->memreq.thread_status = ENOSR; - } else { - cp->memreq.thread_status = 0; - } - } else { - cp->memreq.returned_mem = cp->rcomp->decomp_alloc(compressor_options, len); - if (!cp->memreq.returned_mem) { - cp->memreq.thread_status = ENOSR; - } else { - cp->memreq.thread_status = 0; - } - } - } -} - -#endif /* __osf__ */ - -/* here's the deal with memory allocation under Digital UNIX. - * Some other may also benefit from this... - * We can't ask for huge chunks of memory in a context where - * the caller can't be put to sleep (like, here.) The alloc - * is likely to fail. Instead we do this: the first time we - * get called, kick off a thread to do the allocation. Return - * immediately to the caller with EAGAIN, as an indication that - * they should send down the ioctl again. By the time the - * second call comes in it's likely that the memory allocation - * thread will have returned with the requested memory. We will - * continue to return EAGAIN however until the thread has completed. - * When it has, we return zero (and the memory) if the allocator - * was successful and ENOSR otherwise. - * - * Callers of the RCOMP and XCOMP ioctls are encouraged (but not - * required) to loop for some number of iterations with a small - * delay in the loop body (for instance a 1/10-th second "sleep" - * via select.) - */ -static int -ppp_comp_wput(q, mp) - queue_t *q; - mblk_t *mp; -{ - struct iocblk *iop; - comp_state_t *cp; - int error, len, n; - int flags, mask; - mblk_t *np; - struct compressor **comp; - struct ppp_stats *psp; - struct ppp_comp_stats *csp; - unsigned char *opt_data; - int nxslots, nrslots; - - cp = (comp_state_t *) q->q_ptr; - if (cp == 0) { - DPRINT("cp == 0 in ppp_comp_wput\n"); - freemsg(mp); - return 0; - } - - switch (mp->b_datap->db_type) { - - case M_DATA: - putq(q, mp); - break; - - case M_IOCTL: - iop = (struct iocblk *) mp->b_rptr; - error = EINVAL; - switch (iop->ioc_cmd) { - - case PPPIO_CFLAGS: - /* set/get CCP state */ - if (iop->ioc_count != 2 * sizeof(int)) - break; - if (mp->b_cont == 0) { - DPRINT1("ppp_comp_wput/%d: PPPIO_CFLAGS b_cont = 0!\n", cp->unit); - break; - } - flags = ((int *) mp->b_cont->b_rptr)[0]; - mask = ((int *) mp->b_cont->b_rptr)[1]; - cp->flags = (cp->flags & ~mask) | (flags & mask); - if ((mask & CCP_ISOPEN) && (flags & CCP_ISOPEN) == 0) { - if (cp->xstate != NULL) { - (*cp->xcomp->comp_free)(cp->xstate); - cp->xstate = NULL; - } - if (cp->rstate != NULL) { - (*cp->rcomp->decomp_free)(cp->rstate); - cp->rstate = NULL; - } - cp->flags &= ~CCP_ISUP; - } - error = 0; - iop->ioc_count = sizeof(int); - ((int *) mp->b_cont->b_rptr)[0] = cp->flags; - mp->b_cont->b_wptr = mp->b_cont->b_rptr + sizeof(int); - break; - - case PPPIO_VJINIT: - /* - * Initialize VJ compressor/decompressor - */ - if (iop->ioc_count != 2) - break; - if (mp->b_cont == 0) { - DPRINT1("ppp_comp_wput/%d: PPPIO_VJINIT b_cont = 0!\n", cp->unit); - break; - } - nxslots = mp->b_cont->b_rptr[0] + 1; - nrslots = mp->b_cont->b_rptr[1] + 1; - if (nxslots > MAX_STATES || nrslots > MAX_STATES) - break; - vj_compress_init(&cp->vj_comp, nxslots); - cp->vj_last_ierrors = cp->stats.ppp_ierrors; - error = 0; - iop->ioc_count = 0; - break; - - case PPPIO_XCOMP: - case PPPIO_RCOMP: - if (iop->ioc_count <= 0) - break; - if (mp->b_cont == 0) { - DPRINT1("ppp_comp_wput/%d: PPPIO_[XR]COMP b_cont = 0!\n", cp->unit); - break; - } - opt_data = mp->b_cont->b_rptr; - len = mp->b_cont->b_wptr - opt_data; - if (len > iop->ioc_count) - len = iop->ioc_count; - if (opt_data[1] < 2 || opt_data[1] > len) - break; - for (comp = ppp_compressors; *comp != NULL; ++comp) - if ((*comp)->compress_proto == opt_data[0]) { - /* here's the handler! */ - error = 0; -#ifndef __osf__ - if (iop->ioc_cmd == PPPIO_XCOMP) { - /* A previous call may have fetched memory for a compressor - * that's now being retired or reset. Free it using it's - * mechanism for freeing stuff. - */ - if (cp->xstate != NULL) { - (*cp->xcomp->comp_free)(cp->xstate); - cp->xstate = NULL; - } - cp->xcomp = *comp; - cp->xstate = (*comp)->comp_alloc(opt_data, len); - if (cp->xstate == NULL) - error = ENOSR; - } else { - if (cp->rstate != NULL) { - (*cp->rcomp->decomp_free)(cp->rstate); - cp->rstate = NULL; - } - cp->rcomp = *comp; - cp->rstate = (*comp)->decomp_alloc(opt_data, len); - if (cp->rstate == NULL) - error = ENOSR; - } -#else - if ((error = cp->memreq.thread_status) != EAGAIN) - if (iop->ioc_cmd == PPPIO_XCOMP) { - if (cp->xstate) { - (*cp->xcomp->comp_free)(cp->xstate); - cp->xstate = 0; - } - /* sanity check for compressor options - */ - if (sizeof (cp->memreq.comp_opts) < len) { - printf("can't handle options for compressor %d (%d)\n", opt_data[0], - opt_data[1]); - cp->memreq.thread_status = ENOSR; - cp->memreq.returned_mem = 0; - } - /* fill in request for the thread and kick it off - */ - if (cp->memreq.thread_status == 0 && !cp->memreq.returned_mem) { - bcopy(opt_data, cp->memreq.comp_opts, len); - cp->memreq.cmd = PPPIO_XCOMP; - cp->xcomp = *comp; - error = cp->memreq.thread_status = EAGAIN; - thread_wakeup((vm_offset_t)&cp->memreq.thread_status); - } else { - cp->xstate = cp->memreq.returned_mem; - cp->memreq.returned_mem = 0; - cp->memreq.thread_status = 0; - } - } else { - if (cp->rstate) { - (*cp->rcomp->decomp_free)(cp->rstate); - cp->rstate = NULL; - } - if (sizeof (cp->memreq.comp_opts) < len) { - printf("can't handle options for compressor %d (%d)\n", opt_data[0], - opt_data[1]); - cp->memreq.thread_status = ENOSR; - cp->memreq.returned_mem = 0; - } - if (cp->memreq.thread_status == 0 && !cp->memreq.returned_mem) { - bcopy(opt_data, cp->memreq.comp_opts, len); - cp->memreq.cmd = PPPIO_RCOMP; - cp->rcomp = *comp; - error = cp->memreq.thread_status = EAGAIN; - thread_wakeup((vm_offset_t)&cp->memreq.thread_status); - } else { - cp->rstate = cp->memreq.returned_mem; - cp->memreq.returned_mem = 0; - cp->memreq.thread_status = 0; - } - } -#endif - break; - } - iop->ioc_count = 0; - break; - - case PPPIO_GETSTAT: - if ((cp->flags & LAST_MOD) == 0) { - error = -1; /* let the ppp_ahdl module handle it */ - break; - } - np = allocb(sizeof(struct ppp_stats), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - psp = (struct ppp_stats *) np->b_wptr; - np->b_wptr += sizeof(struct ppp_stats); - iop->ioc_count = sizeof(struct ppp_stats); - psp->p = cp->stats; - psp->vj = cp->vj_comp.stats; - error = 0; - break; - - case PPPIO_GETCSTAT: - np = allocb(sizeof(struct ppp_comp_stats), BPRI_HI); - if (np == 0) { - error = ENOSR; - break; - } - if (mp->b_cont != 0) - freemsg(mp->b_cont); - mp->b_cont = np; - csp = (struct ppp_comp_stats *) np->b_wptr; - np->b_wptr += sizeof(struct ppp_comp_stats); - iop->ioc_count = sizeof(struct ppp_comp_stats); - bzero((caddr_t)csp, sizeof(struct ppp_comp_stats)); - if (cp->xstate != 0) - (*cp->xcomp->comp_stat)(cp->xstate, &csp->c); - if (cp->rstate != 0) - (*cp->rcomp->decomp_stat)(cp->rstate, &csp->d); - error = 0; - break; - - case PPPIO_DEBUG: - if (iop->ioc_count != sizeof(int)) - break; - if (mp->b_cont == 0) { - DPRINT1("ppp_comp_wput/%d: PPPIO_DEBUG b_cont = 0!\n", cp->unit); - break; - } - n = *(int *)mp->b_cont->b_rptr; - if (n == PPPDBG_LOG + PPPDBG_COMP) { - DPRINT1("ppp_comp%d: debug log enabled\n", cp->unit); - cp->flags |= DBGLOG; - error = 0; - iop->ioc_count = 0; - } else { - error = -1; - } - break; - - case PPPIO_LASTMOD: - cp->flags |= LAST_MOD; - error = 0; - break; - - default: - error = -1; - break; - } - - if (error < 0) - putnext(q, mp); - else if (error == 0) { - mp->b_datap->db_type = M_IOCACK; - qreply(q, mp); - } else { - mp->b_datap->db_type = M_IOCNAK; - iop->ioc_error = error; - iop->ioc_count = 0; - qreply(q, mp); - } - break; - - case M_CTL: - switch (*mp->b_rptr) { - case PPPCTL_MTU: - cp->mtu = ((unsigned short *)mp->b_rptr)[1]; - break; - case PPPCTL_MRU: - cp->mru = ((unsigned short *)mp->b_rptr)[1]; - break; - case PPPCTL_UNIT: - cp->unit = mp->b_rptr[1]; - break; - } - putnext(q, mp); - break; - - default: - putnext(q, mp); - } - - return 0; -} - -static int -ppp_comp_wsrv(q) - queue_t *q; -{ - mblk_t *mp, *cmp = NULL; - comp_state_t *cp; - int len, proto, type, hlen, code; - struct ip *ip; - unsigned char *vjhdr, *dp; - - cp = (comp_state_t *) q->q_ptr; - if (cp == 0) { - DPRINT("cp == 0 in ppp_comp_wsrv\n"); - return 0; - } - - while ((mp = getq(q)) != 0) { - /* assert(mp->b_datap->db_type == M_DATA) */ -#ifdef PRIOQ - if (!bcanputnext(q,mp->b_band)) -#else - if (!canputnext(q)) -#endif PRIOQ - { - putbq(q, mp); - break; - } - - /* - * First check the packet length and work out what the protocol is. - */ - len = msgdsize(mp); - if (len < PPP_HDRLEN) { - DPRINT1("ppp_comp_wsrv: bogus short packet (%d)\n", len); - freemsg(mp); - cp->stats.ppp_oerrors++; - putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); - continue; - } - proto = (MSG_BYTE(mp, 2) << 8) + MSG_BYTE(mp, 3); - - /* - * Make sure we've got enough data in the first mblk - * and that we are its only user. - */ - if (proto == PPP_CCP) - hlen = len; - else if (proto == PPP_IP) - hlen = PPP_HDRLEN + MAX_IPHDR; - else - hlen = PPP_HDRLEN; - if (hlen > len) - hlen = len; - if (mp->b_wptr < mp->b_rptr + hlen || mp->b_datap->db_ref > 1) { - PULLUP(mp, hlen); - if (mp == 0) { - DPRINT1("ppp_comp_wsrv: pullup failed (%d)\n", hlen); - cp->stats.ppp_oerrors++; - putctl1(RD(q)->q_next, M_CTL, PPPCTL_OERROR); - continue; - } - } - - /* - * Do VJ compression if requested. - */ - if (proto == PPP_IP && (cp->flags & COMP_VJC)) { - ip = (struct ip *) (mp->b_rptr + PPP_HDRLEN); - if (ip->ip_p == IPPROTO_TCP) { - type = vj_compress_tcp(ip, len - PPP_HDRLEN, &cp->vj_comp, - (cp->flags & COMP_VJCCID), &vjhdr); - switch (type) { - case TYPE_UNCOMPRESSED_TCP: - mp->b_rptr[3] = proto = PPP_VJC_UNCOMP; - break; - case TYPE_COMPRESSED_TCP: - dp = vjhdr - PPP_HDRLEN; - dp[1] = mp->b_rptr[1]; /* copy control field */ - dp[0] = mp->b_rptr[0]; /* copy address field */ - dp[2] = 0; /* set protocol field */ - dp[3] = proto = PPP_VJC_COMP; - mp->b_rptr = dp; - break; - } - } - } - - /* - * Do packet compression if enabled. - */ - if (proto == PPP_CCP) - ppp_comp_ccp(q, mp, 0); - else if (proto != PPP_LCP && (cp->flags & CCP_COMP_RUN) - && cp->xstate != NULL) { - len = msgdsize(mp); - (*cp->xcomp->compress)(cp->xstate, &cmp, mp, len, - (cp->flags & CCP_ISUP? cp->mtu + PPP_HDRLEN: 0)); - if (cmp != NULL) { -#ifdef PRIOQ - cmp->b_band=mp->b_band; -#endif PRIOQ - freemsg(mp); - mp = cmp; - } - } - - /* - * Do address/control and protocol compression if enabled. - */ - if ((cp->flags & COMP_AC) - && !(proto == PPP_LCP && LCP_USE_DFLT(mp))) { - mp->b_rptr += 2; /* drop the address & ctrl fields */ - if (proto < 0x100 && (cp->flags & COMP_PROT)) - ++mp->b_rptr; /* drop the high protocol byte */ - } else if (proto < 0x100 && (cp->flags & COMP_PROT)) { - /* shuffle up the address & ctrl fields */ - mp->b_rptr[2] = mp->b_rptr[1]; - mp->b_rptr[1] = mp->b_rptr[0]; - ++mp->b_rptr; - } - - cp->stats.ppp_opackets++; - cp->stats.ppp_obytes += msgdsize(mp); - putnext(q, mp); - } - - return 0; -} - -static int -ppp_comp_rput(q, mp) - queue_t *q; - mblk_t *mp; -{ - comp_state_t *cp; - struct iocblk *iop; - struct ppp_stats *psp; - - cp = (comp_state_t *) q->q_ptr; - if (cp == 0) { - DPRINT("cp == 0 in ppp_comp_rput\n"); - freemsg(mp); - return 0; - } - - switch (mp->b_datap->db_type) { - - case M_DATA: - putq(q, mp); - break; - - case M_IOCACK: - iop = (struct iocblk *) mp->b_rptr; - switch (iop->ioc_cmd) { - case PPPIO_GETSTAT: - /* - * Catch this on the way back from the ppp_ahdl module - * so we can fill in the VJ stats. - */ - if (mp->b_cont == 0 || iop->ioc_count != sizeof(struct ppp_stats)) - break; - psp = (struct ppp_stats *) mp->b_cont->b_rptr; - psp->vj = cp->vj_comp.stats; - break; - } - putnext(q, mp); - break; - - case M_CTL: - switch (mp->b_rptr[0]) { - case PPPCTL_IERROR: - ++cp->stats.ppp_ierrors; - break; - case PPPCTL_OERROR: - ++cp->stats.ppp_oerrors; - break; - } - putnext(q, mp); - break; - - default: - putnext(q, mp); - } - - return 0; -} - -static int -ppp_comp_rsrv(q) - queue_t *q; -{ - int proto, rv, i; - mblk_t *mp, *dmp = NULL, *np; - uchar_t *dp, *iphdr; - comp_state_t *cp; - int len, hlen, vjlen; - u_int iphlen; - - cp = (comp_state_t *) q->q_ptr; - if (cp == 0) { - DPRINT("cp == 0 in ppp_comp_rsrv\n"); - return 0; - } - - while ((mp = getq(q)) != 0) { - /* assert(mp->b_datap->db_type == M_DATA) */ - if (!canputnext(q)) { - putbq(q, mp); - break; - } - - len = msgdsize(mp); - cp->stats.ppp_ibytes += len; - cp->stats.ppp_ipackets++; - - /* - * First work out the protocol and where the PPP header ends. - */ - i = 0; - proto = MSG_BYTE(mp, 0); - if (proto == PPP_ALLSTATIONS) { - i = 2; - proto = MSG_BYTE(mp, 2); - } - if ((proto & 1) == 0) { - ++i; - proto = (proto << 8) + MSG_BYTE(mp, i); - } - hlen = i + 1; - - /* - * Now reconstruct a complete, contiguous PPP header at the - * start of the packet. - */ - if (hlen < ((cp->flags & DECOMP_AC)? 0: 2) - + ((cp->flags & DECOMP_PROT)? 1: 2)) { - /* count these? */ - goto bad; - } - if (mp->b_rptr + hlen > mp->b_wptr) { - adjmsg(mp, hlen); /* XXX check this call */ - hlen = 0; - } - if (hlen != PPP_HDRLEN) { - /* - * We need to put some bytes on the front of the packet - * to make a full-length PPP header. - * If we can put them in *mp, we do, otherwise we - * tack another mblk on the front. - * XXX we really shouldn't need to carry around - * the address and control at this stage. - */ - dp = mp->b_rptr + hlen - PPP_HDRLEN; - if (dp < mp->b_datap->db_base || mp->b_datap->db_ref > 1) { - np = allocb(PPP_HDRLEN, BPRI_MED); - if (np == 0) - goto bad; - np->b_cont = mp; - mp->b_rptr += hlen; - mp = np; - dp = mp->b_wptr; - mp->b_wptr += PPP_HDRLEN; - } else - mp->b_rptr = dp; - - dp[0] = PPP_ALLSTATIONS; - dp[1] = PPP_UI; - dp[2] = proto >> 8; - dp[3] = proto; - } - - /* - * Now see if we have a compressed packet to decompress, - * or a CCP packet to take notice of. - */ - proto = PPP_PROTOCOL(mp->b_rptr); - if (proto == PPP_CCP) { - len = msgdsize(mp); - if (mp->b_wptr < mp->b_rptr + len) { - PULLUP(mp, len); - if (mp == 0) - goto bad; - } - ppp_comp_ccp(q, mp, 1); - } else if (proto == PPP_COMP) { - if ((cp->flags & CCP_ISUP) - && (cp->flags & CCP_DECOMP_RUN) && cp->rstate - && (cp->flags & CCP_ERR) == 0) { - rv = (*cp->rcomp->decompress)(cp->rstate, mp, &dmp); - switch (rv) { - case DECOMP_OK: - freemsg(mp); - mp = dmp; - if (mp == NULL) { - /* no error, but no packet returned either. */ - continue; - } - break; - case DECOMP_ERROR: - cp->flags |= CCP_ERROR; - ++cp->stats.ppp_ierrors; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - break; - case DECOMP_FATALERROR: - cp->flags |= CCP_FATALERROR; - ++cp->stats.ppp_ierrors; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - break; - } - } - } else if (cp->rstate && (cp->flags & CCP_DECOMP_RUN)) { - (*cp->rcomp->incomp)(cp->rstate, mp); - } - - /* - * Now do VJ decompression. - */ - proto = PPP_PROTOCOL(mp->b_rptr); - if (proto == PPP_VJC_COMP || proto == PPP_VJC_UNCOMP) { - len = msgdsize(mp) - PPP_HDRLEN; - if ((cp->flags & DECOMP_VJC) == 0 || len <= 0) - goto bad; - - /* - * Advance past the ppp header. - * Here we assume that the whole PPP header is in the first mblk. - */ - np = mp; - dp = np->b_rptr + PPP_HDRLEN; - if (dp >= mp->b_wptr) { - np = np->b_cont; - dp = np->b_rptr; - } - - /* - * Make sure we have sufficient contiguous data at this point. - */ - hlen = (proto == PPP_VJC_COMP)? MAX_VJHDR: MAX_IPHDR; - if (hlen > len) - hlen = len; - if (np->b_wptr < dp + hlen || np->b_datap->db_ref > 1) { - PULLUP(mp, hlen + PPP_HDRLEN); - if (mp == 0) - goto bad; - np = mp; - dp = np->b_rptr + PPP_HDRLEN; - } - - if (proto == PPP_VJC_COMP) { - /* - * Decompress VJ-compressed packet. - * First reset compressor if an input error has occurred. - */ - if (cp->stats.ppp_ierrors != cp->vj_last_ierrors) { - if (cp->flags & DBGLOG) - DPRINT1("ppp%d: resetting VJ\n", cp->unit); - vj_uncompress_err(&cp->vj_comp); - cp->vj_last_ierrors = cp->stats.ppp_ierrors; - } - - vjlen = vj_uncompress_tcp(dp, np->b_wptr - dp, len, - &cp->vj_comp, &iphdr, &iphlen); - if (vjlen < 0) { - if (cp->flags & DBGLOG) - DPRINT2("ppp%d: vj_uncomp_tcp failed, pkt len %d\n", - cp->unit, len); - ++cp->vj_last_ierrors; /* so we don't reset next time */ - goto bad; - } - - /* drop ppp and vj headers off */ - if (mp != np) { - freeb(mp); - mp = np; - } - mp->b_rptr = dp + vjlen; - - /* allocate a new mblk for the ppp and ip headers */ - if ((np = allocb(iphlen + PPP_HDRLEN + 4, BPRI_MED)) == 0) - goto bad; - dp = np->b_rptr; /* prepend mblk with TCP/IP hdr */ - dp[0] = PPP_ALLSTATIONS; /* reconstruct PPP header */ - dp[1] = PPP_UI; - dp[2] = PPP_IP >> 8; - dp[3] = PPP_IP; - bcopy((caddr_t)iphdr, (caddr_t)dp + PPP_HDRLEN, iphlen); - np->b_wptr = dp + iphlen + PPP_HDRLEN; - np->b_cont = mp; - - /* XXX there seems to be a bug which causes panics in strread - if we make an mbuf with only the IP header in it :-( */ - if (mp->b_wptr - mp->b_rptr > 4) { - bcopy((caddr_t)mp->b_rptr, (caddr_t)np->b_wptr, 4); - mp->b_rptr += 4; - np->b_wptr += 4; - } else { - bcopy((caddr_t)mp->b_rptr, (caddr_t)np->b_wptr, - mp->b_wptr - mp->b_rptr); - np->b_wptr += mp->b_wptr - mp->b_rptr; - np->b_cont = mp->b_cont; - freeb(mp); - } - - mp = np; - - } else { - /* - * "Decompress" a VJ-uncompressed packet. - */ - cp->vj_last_ierrors = cp->stats.ppp_ierrors; - if (!vj_uncompress_uncomp(dp, hlen, &cp->vj_comp)) { - if (cp->flags & DBGLOG) - DPRINT2("ppp%d: vj_uncomp_uncomp failed, pkt len %d\n", - cp->unit, len); - ++cp->vj_last_ierrors; /* don't need to reset next time */ - goto bad; - } - mp->b_rptr[3] = PPP_IP; /* fix up the PPP protocol field */ - } - } - - putnext(q, mp); - continue; - - bad: - if (mp != 0) - freemsg(mp); - cp->stats.ppp_ierrors++; - putctl1(q->q_next, M_CTL, PPPCTL_IERROR); - } - - return 0; -} - -/* - * Handle a CCP packet being sent or received. - * Here all the data in the packet is in a single mbuf. - */ -static void -ppp_comp_ccp(q, mp, rcvd) - queue_t *q; - mblk_t *mp; - int rcvd; -{ - int len, clen; - comp_state_t *cp; - unsigned char *dp; - - len = msgdsize(mp); - if (len < PPP_HDRLEN + CCP_HDRLEN) - return; - - cp = (comp_state_t *) q->q_ptr; - dp = mp->b_rptr + PPP_HDRLEN; - len -= PPP_HDRLEN; - clen = CCP_LENGTH(dp); - if (clen > len) - return; - - switch (CCP_CODE(dp)) { - case CCP_CONFREQ: - case CCP_TERMREQ: - case CCP_TERMACK: - cp->flags &= ~CCP_ISUP; - break; - - case CCP_CONFACK: - if ((cp->flags & (CCP_ISOPEN | CCP_ISUP)) == CCP_ISOPEN - && clen >= CCP_HDRLEN + CCP_OPT_MINLEN - && clen >= CCP_HDRLEN + CCP_OPT_LENGTH(dp + CCP_HDRLEN)) { - if (!rcvd) { - if (cp->xstate != NULL - && (*cp->xcomp->comp_init) - (cp->xstate, dp + CCP_HDRLEN, clen - CCP_HDRLEN, - cp->unit, 0, ((cp->flags & DBGLOG) != 0))) - cp->flags |= CCP_COMP_RUN; - } else { - if (cp->rstate != NULL - && (*cp->rcomp->decomp_init) - (cp->rstate, dp + CCP_HDRLEN, clen - CCP_HDRLEN, - cp->unit, 0, cp->mru, ((cp->flags & DBGLOG) != 0))) - cp->flags = (cp->flags & ~CCP_ERR) | CCP_DECOMP_RUN; - } - } - break; - - case CCP_RESETACK: - if (cp->flags & CCP_ISUP) { - if (!rcvd) { - if (cp->xstate && (cp->flags & CCP_COMP_RUN)) - (*cp->xcomp->comp_reset)(cp->xstate); - } else { - if (cp->rstate && (cp->flags & CCP_DECOMP_RUN)) { - (*cp->rcomp->decomp_reset)(cp->rstate); - cp->flags &= ~CCP_ERROR; - } - } - } - break; - } -} - -#if 0 -dump_msg(mp) - mblk_t *mp; -{ - dblk_t *db; - - while (mp != 0) { - db = mp->b_datap; - DPRINT2("mp=%x cont=%x ", mp, mp->b_cont); - DPRINT3("rptr=%x wptr=%x datap=%x\n", mp->b_rptr, mp->b_wptr, db); - DPRINT2(" base=%x lim=%x", db->db_base, db->db_lim); - DPRINT2(" ref=%d type=%d\n", db->db_ref, db->db_type); - mp = mp->b_cont; - } -} -#endif - -static int -msg_byte(mp, i) - mblk_t *mp; - unsigned int i; -{ - while (mp != 0 && i >= mp->b_wptr - mp->b_rptr) - mp = mp->b_cont; - if (mp == 0) - return -1; - return mp->b_rptr[i]; -} diff --git a/mdk-stage1/ppp/solaris/ppp_comp_mod.c b/mdk-stage1/ppp/solaris/ppp_comp_mod.c deleted file mode 100644 index 83ff8e252..000000000 --- a/mdk-stage1/ppp/solaris/ppp_comp_mod.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * ppp_comp_mod.c - modload support for PPP compression STREAMS module. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -/* - * This file is used under Solaris 2. - */ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/conf.h> -#include <sys/modctl.h> -#include <sys/sunddi.h> - -extern struct streamtab ppp_compinfo; - -static struct fmodsw fsw = { - "ppp_comp", - &ppp_compinfo, - D_NEW | D_MP | D_MTQPAIR -}; - -extern struct mod_ops mod_strmodops; - -static struct modlstrmod modlstrmod = { - &mod_strmodops, - "PPP compression module", - &fsw -}; - -static struct modlinkage modlinkage = { - MODREV_1, - (void *) &modlstrmod, - NULL -}; - -/* - * Entry points for modloading. - */ -int -_init(void) -{ - return mod_install(&modlinkage); -} - -int -_fini(void) -{ - return mod_remove(&modlinkage); -} - -int -_info(mip) - struct modinfo *mip; -{ - return mod_info(&modlinkage, mip); -} diff --git a/mdk-stage1/ppp/solaris/ppp_mod.c b/mdk-stage1/ppp/solaris/ppp_mod.c deleted file mode 100644 index a4b1538a5..000000000 --- a/mdk-stage1/ppp/solaris/ppp_mod.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * ppp_mod.c - modload support for PPP pseudo-device driver. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -/* - * This file is used under Solaris 2. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/conf.h> -#include <sys/modctl.h> -#include <sys/sunddi.h> -#include <sys/ksynch.h> - -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif - -static int ppp_identify __P((dev_info_t *)); -static int ppp_attach __P((dev_info_t *, ddi_attach_cmd_t)); -static int ppp_detach __P((dev_info_t *, ddi_detach_cmd_t)); -static int ppp_devinfo __P((dev_info_t *, ddi_info_cmd_t, void *, void **)); - -extern struct streamtab pppinfo; -extern krwlock_t ppp_lower_lock; - -static dev_info_t *ppp_dip; - -static struct cb_ops cb_ppp_ops = { - nulldev, nulldev, nodev, nodev, /* cb_open, ... */ - nodev, nodev, nodev, nodev, /* cb_dump, ... */ - nodev, nodev, nodev, nochpoll, /* cb_devmap, ... */ - ddi_prop_op, /* cb_prop_op */ - &pppinfo, /* cb_stream */ - D_NEW|D_MP|D_MTQPAIR|D_MTOUTPERIM|D_MTOCEXCL /* cb_flag */ -}; - -static struct dev_ops ppp_ops = { - DEVO_REV, /* devo_rev */ - 0, /* devo_refcnt */ - ppp_devinfo, /* devo_getinfo */ - ppp_identify, /* devo_identify */ - nulldev, /* devo_probe */ - ppp_attach, /* devo_attach */ - ppp_detach, /* devo_detach */ - nodev, /* devo_reset */ - &cb_ppp_ops, /* devo_cb_ops */ - NULL /* devo_bus_ops */ -}; - -/* - * Module linkage information - */ - -static struct modldrv modldrv = { - &mod_driverops, /* says this is a pseudo driver */ - "PPP-2.3 multiplexing driver", - &ppp_ops /* driver ops */ -}; - -static struct modlinkage modlinkage = { - MODREV_1, - (void *) &modldrv, - NULL -}; - -int -_init(void) -{ - return mod_install(&modlinkage); -} - -int -_fini(void) -{ - return mod_remove(&modlinkage); -} - -int -_info(mip) - struct modinfo *mip; -{ - return mod_info(&modlinkage, mip); -} - -static int -ppp_identify(dip) - dev_info_t *dip; -{ - return strcmp(ddi_get_name(dip), "ppp") == 0? DDI_IDENTIFIED: - DDI_NOT_IDENTIFIED; -} - -static int -ppp_attach(dip, cmd) - dev_info_t *dip; - ddi_attach_cmd_t cmd; -{ - - if (cmd != DDI_ATTACH) - return DDI_FAILURE; - if (ddi_create_minor_node(dip, "ppp", S_IFCHR, 0, DDI_PSEUDO, CLONE_DEV) - == DDI_FAILURE) { - ddi_remove_minor_node(dip, NULL); - return DDI_FAILURE; - } - rw_init(&ppp_lower_lock, NULL, RW_DRIVER, NULL); - return DDI_SUCCESS; -} - -static int -ppp_detach(dip, cmd) - dev_info_t *dip; - ddi_detach_cmd_t cmd; -{ - rw_destroy(&ppp_lower_lock); - ddi_remove_minor_node(dip, NULL); - return DDI_SUCCESS; -} - -static int -ppp_devinfo(dip, cmd, arg, result) - dev_info_t *dip; - ddi_info_cmd_t cmd; - void *arg; - void **result; -{ - int error; - - error = DDI_SUCCESS; - switch (cmd) { - case DDI_INFO_DEVT2DEVINFO: - if (ppp_dip == NULL) - error = DDI_FAILURE; - else - *result = (void *) ppp_dip; - break; - case DDI_INFO_DEVT2INSTANCE: - *result = NULL; - break; - default: - error = DDI_FAILURE; - } - return error; -} diff --git a/mdk-stage1/ppp/solaris/ppp_mod.h b/mdk-stage1/ppp/solaris/ppp_mod.h deleted file mode 100644 index f0af00886..000000000 --- a/mdk-stage1/ppp/solaris/ppp_mod.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Miscellaneous definitions for PPP STREAMS modules. - */ - -/* - * Macros for allocating and freeing kernel memory. - */ -#ifdef SVR4 /* SVR4, including Solaris 2 */ -#include <sys/kmem.h> -#define ALLOC_SLEEP(n) kmem_alloc((n), KM_SLEEP) -#define ALLOC_NOSLEEP(n) kmem_alloc((n), KM_NOSLEEP) -#define FREE(p, n) kmem_free((p), (n)) -#endif - -#ifdef SUNOS4 -#include <sys/kmem_alloc.h> /* SunOS 4.x */ -#define ALLOC_SLEEP(n) kmem_alloc((n), KMEM_SLEEP) -#define ALLOC_NOSLEEP(n) kmem_alloc((n), KMEM_NOSLEEP) -#define FREE(p, n) kmem_free((p), (n)) -#define NOTSUSER() (suser()? 0: EPERM) -#define bcanputnext(q, band) canputnext((q)) -#endif /* SunOS 4 */ - -#ifdef __osf__ -#include <sys/malloc.h> - -/* caution: this mirrors macros in sys/malloc.h, and uses interfaces - * which are subject to change. - * The problems are that: - * - the official MALLOC macro wants the lhs of the assignment as an argument, - * and it takes care of the assignment itself (yuck.) - * - PPP insists on using "FREE" which conflicts with a macro of the same name. - * - */ -#ifdef BUCKETINDX /* V2.0 */ -#define ALLOC_SLEEP(n) (void *)malloc((u_long)(n), BUCKETP(n), M_DEVBUF, M_WAITOK) -#define ALLOC_NOSLEEP(n) (void *)malloc((u_long)(n), BUCKETP(n), M_DEVBUF, M_NOWAIT) -#else -#define ALLOC_SLEEP(n) (void *)malloc((u_long)(n), BUCKETINDEX(n), M_DEVBUF, M_WAITOK) -#define ALLOC_NOSLEEP(n) (void *)malloc((u_long)(n), BUCKETINDEX(n), M_DEVBUF, M_NOWAIT) -#endif - -#define bcanputnext(q, band) canputnext((q)) - -#ifdef FREE -#undef FREE -#endif -#define FREE(p, n) free((void *)(p), M_DEVBUF) - -#define NO_DLPI 1 - -#ifndef IFT_PPP -#define IFT_PPP 0x17 -#endif - -#include <sys/proc.h> -#define NOTSUSER() (suser(u.u_procp->p_rcred, &u.u_acflag) ? EPERM : 0) - -/* #include "ppp_osf.h" */ - -#endif /* __osf__ */ - -#ifdef AIX4 -#define ALLOC_SLEEP(n) xmalloc((n), 0, pinned_heap) /* AIX V4.x */ -#define ALLOC_NOSLEEP(n) xmalloc((n), 0, pinned_heap) /* AIX V4.x */ -#define FREE(p, n) xmfree((p), pinned_heap) -#define NOTSUSER() (suser()? 0: EPERM) -#endif /* AIX */ - -/* - * Macros for printing debugging stuff. - */ -#ifdef DEBUG -#if defined(SVR4) || defined(__osf__) -#if defined(SNI) -#include <sys/strlog.h> -#define STRLOG_ID 4712 -#define DPRINT(f) strlog(STRLOG_ID, 0, 0, SL_TRACE, f) -#define DPRINT1(f, a1) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1) -#define DPRINT2(f, a1, a2) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1, a2) -#define DPRINT3(f, a1, a2, a3) strlog(STRLOG_ID, 0, 0, SL_TRACE, f, a1, a2, a3) -#else -#define DPRINT(f) cmn_err(CE_CONT, f) -#define DPRINT1(f, a1) cmn_err(CE_CONT, f, a1) -#define DPRINT2(f, a1, a2) cmn_err(CE_CONT, f, a1, a2) -#define DPRINT3(f, a1, a2, a3) cmn_err(CE_CONT, f, a1, a2, a3) -#endif /* SNI */ -#else -#define DPRINT(f) printf(f) -#define DPRINT1(f, a1) printf(f, a1) -#define DPRINT2(f, a1, a2) printf(f, a1, a2) -#define DPRINT3(f, a1, a2, a3) printf(f, a1, a2, a3) -#endif /* SVR4 or OSF */ - -#else -#define DPRINT(f) 0 -#define DPRINT1(f, a1) 0 -#define DPRINT2(f, a1, a2) 0 -#define DPRINT3(f, a1, a2, a3) 0 -#endif /* DEBUG */ - -#ifndef SVR4 -typedef unsigned char uchar_t; -typedef unsigned short ushort_t; -#ifndef __osf__ -typedef int minor_t; -#endif -#endif - -/* - * If we don't have multithreading support, define substitutes. - */ -#ifndef D_MP -# define qprocson(q) -# define qprocsoff(q) -# define put(q, mp) ((*(q)->q_qinfo->qi_putp)((q), (mp))) -# define canputnext(q) canput((q)->q_next) -# define qwriter(q, mp, func, scope) (func)((q), (mp)) -#endif - -#ifdef D_MP -/* Use msgpullup if we have other multithreading support. */ -#define PULLUP(mp, len) \ - do { \ - mblk_t *np = msgpullup((mp), (len)); \ - freemsg((mp)); \ - mp = np; \ - } while (0) - -#else -/* Use pullupmsg if we don't have any multithreading support. */ -#define PULLUP(mp, len) \ - do { \ - if (!pullupmsg((mp), (len))) { \ - freemsg((mp)); \ - mp = 0; \ - } \ - } while (0) -#endif - -/* - * How to declare the open and close procedures for a module. - */ -#ifdef SVR4 -#define MOD_OPEN_DECL(name) \ -static int name __P((queue_t *, dev_t *, int, int, cred_t *)) - -#define MOD_CLOSE_DECL(name) \ -static int name __P((queue_t *, int, cred_t *)) - -#define MOD_OPEN(name) \ -static int name(q, devp, flag, sflag, credp) \ - queue_t *q; \ - dev_t *devp; \ - int flag, sflag; \ - cred_t *credp; - -#define MOD_CLOSE(name) \ -static int name(q, flag, credp) \ - queue_t *q; \ - int flag; \ - cred_t *credp; - -#define OPEN_ERROR(x) return (x) -#define DRV_OPEN_OK(dev) return 0 - -#define NOTSUSER() (drv_priv(credp)) - -#else /* not SVR4 */ -#define MOD_OPEN_DECL(name) \ -static int name __P((queue_t *, int, int, int)) - -#define MOD_CLOSE_DECL(name) \ -static int name __P((queue_t *, int)) - -#define MOD_OPEN(name) \ -static int name(q, dev, flag, sflag) \ - queue_t *q; \ - int dev; \ - int flag, sflag; - -#define MOD_CLOSE(name) \ -static int name(q, flag) \ - queue_t *q; \ - int flag; - -#define OPEN_ERROR(x) { u.u_error = (x); return OPENFAIL; } -#define DRV_OPEN_OK(dev) return (dev) - -#endif /* SVR4 */ diff --git a/mdk-stage1/ppp/sunos4/Makedefs b/mdk-stage1/ppp/sunos4/Makedefs deleted file mode 100644 index 8b56a2b67..000000000 --- a/mdk-stage1/ppp/sunos4/Makedefs +++ /dev/null @@ -1,13 +0,0 @@ -# -# defines common to several Makefiles -# - -INSTALL= install -o root -g daemon - -BINDIR = /usr/local/etc -MANDIR = /usr/local/man -ETCDIR = /etc/ppp - -# To use gcc, uncomment the next line. -#CC = gcc -COPTS = -O diff --git a/mdk-stage1/ppp/sunos4/Makefile b/mdk-stage1/ppp/sunos4/Makefile deleted file mode 100644 index 701e24e14..000000000 --- a/mdk-stage1/ppp/sunos4/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# -# Makefile for STREAMS modules for SunOS 4. -# -# $Id$ -# - -include Makedefs - -LD = /usr/bin/ld # make sure we don't get gnu ld - -# Defining __$(ARCH)__ is for gcc's broken version of sun/vddrv.h. -ARCH = `/bin/arch -k` -DEFINES= -DKERNEL -D_KERNEL -DSUNOS4 -D$(ARCH) -D__$(ARCH)__ \ - -DDEBUG -DNO_DLPI -DSNIT_SUPPORT -CFLAGS= $(DEFINES) -I../include $(COPTS) - -MODULES= ppp_mod.o ppp_ahdl_mod.o ppp_comp_mod.o if_ppp_mod.o - -all: $(MODULES) - -ppp_mod.o: ppp.o ppp_vdcmd.o - $(LD) -r -o ppp_mod.o ppp.o ppp_vdcmd.o - -ppp_ahdl_mod.o: ppp_ahdlc.o ppp_ahdlc_vdcmd.o - $(LD) -r -o ppp_ahdl_mod.o ppp_ahdlc.o ppp_ahdlc_vdcmd.o - -COMP_OBJS = ppp_comp.o bsd-comp.o deflate.o zlib.o vjcompress.o \ - ppp_comp_vdcmd.o -ppp_comp_mod.o: $(COMP_OBJS) - $(LD) -r -o $@ $(COMP_OBJS) - -if_ppp.o: ../modules/if_ppp.c - $(CC) $(CFLAGS) -c $? -bsd-comp.o: ../modules/bsd-comp.c - $(CC) $(CFLAGS) -c $? -deflate.o: ../modules/deflate.c - $(CC) $(CFLAGS) -c $? -ppp.o: ../modules/ppp.c - $(CC) $(CFLAGS) -c $? -ppp_ahdlc.o: ../modules/ppp_ahdlc.c - $(CC) $(CFLAGS) -c $? -ppp_comp.o: ../modules/ppp_comp.c - $(CC) $(CFLAGS) -c $? -vjcompress.o: ../modules/vjcompress.c - $(CC) $(CFLAGS) -c $? -zlib.o: ../common/zlib.c - $(CC) $(CFLAGS) -c $? - -if_ppp_mod.o: if_ppp.o if_ppp_vdcmd.o - $(LD) -r -o if_ppp_mod.o if_ppp.o if_ppp_vdcmd.o - -install: all - $(INSTALL) $(MODULES) $(BINDIR) - ./ppp.INSTALL - -clean: - rm -f ppp ppp_comp ppp_ahdl *.o *~ core diff --git a/mdk-stage1/ppp/sunos4/Makefile.top b/mdk-stage1/ppp/sunos4/Makefile.top deleted file mode 100644 index c86e0884d..000000000 --- a/mdk-stage1/ppp/sunos4/Makefile.top +++ /dev/null @@ -1,46 +0,0 @@ -# -# ppp top level makefile -# - -include sunos4/Makedefs - -all: - cd chat; $(MAKE) all - cd pppd; $(MAKE) all - cd pppstats; $(MAKE) all - cd sunos4; $(MAKE) all - cd pppdump; $(MAKE) all - -install: $(BINDIR) $(MANDIR)/man8 install-progs install-etcppp - -install-progs: - cd chat; $(MAKE) install - cd pppd; $(MAKE) install - cd pppstats; $(MAKE) install - cd pppdump; $(MAKE) install - cd sunos4; $(MAKE) install - -install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ - $(ETCDIR)/chap-secrets - -$(ETCDIR)/options: - $(INSTALL) -c -m 644 etc.ppp/options $@ -$(ETCDIR)/pap-secrets: - $(INSTALL) -c -m 600 etc.ppp/pap-secrets $@ -$(ETCDIR)/chap-secrets: - $(INSTALL) -c -m 600 etc.ppp/chap-secrets $@ - -$(BINDIR): - $(INSTALL) -d -m 755 $@ -$(MANDIR)/man8: - $(INSTALL) -d -m 755 $@ -$(ETCDIR): - $(INSTALL) -d -m 755 $@ - -clean: - rm -f *~ - cd chat; $(MAKE) clean - cd pppd; $(MAKE) clean - cd pppstats; $(MAKE) clean - cd sunos4; $(MAKE) clean - diff --git a/mdk-stage1/ppp/sunos4/if_ppp_vdcmd.c b/mdk-stage1/ppp/sunos4/if_ppp_vdcmd.c deleted file mode 100644 index 2bf9710f4..000000000 --- a/mdk-stage1/ppp/sunos4/if_ppp_vdcmd.c +++ /dev/null @@ -1,57 +0,0 @@ -#include <sys/types.h> -#include <sys/errno.h> -#include <sys/conf.h> -#include <sun/vddrv.h> - -extern struct streamtab if_pppinfo; - -static struct vdldrv vd = { - VDMAGIC_USER, - "if_ppp" -}; - -static int fmodsw_index = -1; - -int -if_ppp_vdcmd(fun, vdp, vdi, vds) - unsigned int fun; - struct vddrv *vdp; - addr_t vdi; - struct vdstat *vds; -{ - int n, error; - - switch (fun) { - case VDLOAD: - vdp->vdd_vdtab = (struct vdlinkage *) &vd; - if (fmodsw_index >= 0) - return EBUSY; - for (n = 0; n < fmodcnt; ++n) - if (fmodsw[n].f_str == 0) - break; - if (n >= fmodcnt) - return ENODEV; - strncpy(fmodsw[n].f_name, vd.Drv_name, FMNAMESZ+1); - fmodsw[n].f_str = &if_pppinfo; - fmodsw_index = n; - break; - - case VDUNLOAD: - if (fmodsw_index <= 0) - return EINVAL; - error = if_ppp_unload(); - if (error != 0) - return error; - fmodsw[fmodsw_index].f_name[0] = 0; - fmodsw[fmodsw_index].f_str = 0; - fmodsw_index = -1; - break; - - case VDSTAT: - break; - - default: - return EIO; - } - return 0; -} diff --git a/mdk-stage1/ppp/sunos4/ppp.INSTALL b/mdk-stage1/ppp/sunos4/ppp.INSTALL deleted file mode 100755 index 0018bf8d0..000000000 --- a/mdk-stage1/ppp/sunos4/ppp.INSTALL +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/sh - -# Script for loading, unloading, etc. ppp modules. - -moddir=/usr/local/etc -etcppp=/etc/ppp - -PATH=/usr/etc:/usr/bin - -# Check that we're superuser -touch /tmp/su$$ -if chown root /tmp/su$$ >/dev/null; then : -else - echo "$0: must be root." - rm -f /tmp/su$$ - exit 1 -fi -rm -f /tmp/su$$ - -case "$0" in -*ppp.INSTALL) - if [ ! -f ppp.INSTALL ]; then - echo "ppp.INSTALL: not found" - exit 1 - fi - for n in INSTALL LOAD UNLOAD MKDEV RMDEV; do - if [ -h /dev/ppp.$n -o -f /dev/ppp.$n ]; then - rm /dev/ppp.$n - fi - done - cp ppp.INSTALL /dev - for n in LOAD UNLOAD MKDEV RMDEV; do - ln -s ppp.INSTALL /dev/ppp.$n - done - ;; - -*ppp.LOAD) - if modstat | grep -w ppp >/dev/null; then - echo "ppp driver is already loaded." - exit 1 - fi - if modstat | grep -w if_ppp >/dev/null; then - echo "if_ppp module already loaded: not reloading." - else - echo -n "if_ppp: " - modload $moddir/if_ppp_mod.o -sym -entry _if_ppp_vdcmd \ - -o $etcppp/if_ppp_mod - fi - echo -n "ppp: " - modload $moddir/ppp_mod.o -sym -entry _ppp_vdcmd -exec /dev/ppp.MKDEV \ - -o $etcppp/ppp_mod - echo -n "ppp_comp: " - modload $moddir/ppp_comp_mod.o -sym -entry _ppp_comp_vdcmd \ - -o $etcppp/ppp_comp - echo -n "ppp_ahdl: " - modload $moddir/ppp_ahdl_mod.o -sym -entry _ppp_ahdlc_vdcmd \ - -o $etcppp/ppp_ahdl - exit 0 - ;; - -*ppp.MKDEV) - # args: module number, type, b-major, c-major - if [ $# -ne 4 ]; then - echo "Usage: $0 module-id module-type b-major c-major" - exit 1 - fi - if [ "$2" -ne "12345607" -a "$2" -ne "12345600" ]; then - echo "$0: $2: bad module type" - exit 1 - fi - rm -f /dev/ppp - # we "just know" that 37 is the major number of the clone driver - mknod /dev/ppp c 37 $4 - chmod 644 /dev/ppp - exit 0 - ;; - -*ppp.UNLOAD) - stat=0 - if modstat | grep -w if_ppp >/dev/null; then - echo "$0: not unloading if_ppp module." - fi - for mod in ppp ppp_comp ppp_ahdl; do - id=`modstat | grep -w $mod | awk '{print $1}'` - if [ x$id = x ]; then - echo "$mod is not loaded." - stat=1 - else - modunload -id $id - fi - done - exit $stat - ;; - -*ppp.RMDEV) - rm -f /dev/ppp - exit 0 - ;; - -*) - echo "Invocation names: ppp.INSTALL ppp.LOAD ppp.UNLOAD ppp.MKDEV ppp.RMDEV" - exit 1 - ;; -esac diff --git a/mdk-stage1/ppp/sunos4/ppp_ahdlc_vdcmd.c b/mdk-stage1/ppp/sunos4/ppp_ahdlc_vdcmd.c deleted file mode 100644 index 2dbe8262b..000000000 --- a/mdk-stage1/ppp/sunos4/ppp_ahdlc_vdcmd.c +++ /dev/null @@ -1,57 +0,0 @@ -#include <sys/types.h> -#include <sys/errno.h> -#include <sys/conf.h> -#include <sun/vddrv.h> - -extern struct streamtab ppp_ahdlcinfo; -extern int ppp_ahdlc_count; - -static struct vdldrv vd = { - VDMAGIC_USER, - "ppp_ahdl" -}; - -static int fmodsw_index = -1; - -int -ppp_ahdlc_vdcmd(fun, vdp, vdi, vds) - unsigned int fun; - struct vddrv *vdp; - addr_t vdi; - struct vdstat *vds; -{ - int n; - - switch (fun) { - case VDLOAD: - vdp->vdd_vdtab = (struct vdlinkage *) &vd; - if (fmodsw_index >= 0) - return EBUSY; - for (n = 0; n < fmodcnt; ++n) - if (fmodsw[n].f_str == 0) - break; - if (n >= fmodcnt) - return ENODEV; - strncpy(fmodsw[n].f_name, vd.Drv_name, FMNAMESZ+1); - fmodsw[n].f_str = &ppp_ahdlcinfo; - fmodsw_index = n; - break; - - case VDUNLOAD: - if (ppp_ahdlc_count > 0) - return EBUSY; - if (fmodsw_index <= 0) - return EINVAL; - fmodsw[fmodsw_index].f_name[0] = 0; - fmodsw[fmodsw_index].f_str = 0; - fmodsw_index = -1; - break; - - case VDSTAT: - break; - - default: - return EIO; - } - return 0; -} diff --git a/mdk-stage1/ppp/sunos4/ppp_comp_vdcmd.c b/mdk-stage1/ppp/sunos4/ppp_comp_vdcmd.c deleted file mode 100644 index b81bc47e8..000000000 --- a/mdk-stage1/ppp/sunos4/ppp_comp_vdcmd.c +++ /dev/null @@ -1,57 +0,0 @@ -#include <sys/types.h> -#include <sys/errno.h> -#include <sys/conf.h> -#include <sun/vddrv.h> - -extern struct streamtab ppp_compinfo; -extern int ppp_comp_count; - -static struct vdldrv vd = { - VDMAGIC_USER, - "ppp_comp" -}; - -static int fmodsw_index = -1; - -int -ppp_comp_vdcmd(fun, vdp, vdi, vds) - unsigned int fun; - struct vddrv *vdp; - addr_t vdi; - struct vdstat *vds; -{ - int n; - - switch (fun) { - case VDLOAD: - vdp->vdd_vdtab = (struct vdlinkage *) &vd; - if (fmodsw_index >= 0) - return EBUSY; - for (n = 0; n < fmodcnt; ++n) - if (fmodsw[n].f_str == 0) - break; - if (n >= fmodcnt) - return ENODEV; - strncpy(fmodsw[n].f_name, vd.Drv_name, FMNAMESZ+1); - fmodsw[n].f_str = &ppp_compinfo; - fmodsw_index = n; - break; - - case VDUNLOAD: - if (ppp_comp_count > 0) - return EBUSY; - if (fmodsw_index <= 0) - return EINVAL; - fmodsw[fmodsw_index].f_name[0] = 0; - fmodsw[fmodsw_index].f_str = 0; - fmodsw_index = -1; - break; - - case VDSTAT: - break; - - default: - return EIO; - } - return 0; -} diff --git a/mdk-stage1/ppp/sunos4/ppp_vdcmd.c b/mdk-stage1/ppp/sunos4/ppp_vdcmd.c deleted file mode 100644 index 68095c92e..000000000 --- a/mdk-stage1/ppp/sunos4/ppp_vdcmd.c +++ /dev/null @@ -1,81 +0,0 @@ -#include <sys/types.h> -#include <sys/errno.h> -#include <sys/conf.h> -#include <sun/vddrv.h> - -extern struct streamtab pppinfo; -extern int ppp_count; -extern int nchrdev; - -static struct vdldrv vd = { - VDMAGIC_PSEUDO, - "ppp" -}; - -extern int nodev(); - -static struct cdevsw ppp_cdevsw = { - nodev, nodev, nodev, nodev, nodev, nodev, nodev, 0, - &pppinfo -}; - -static struct cdevsw old_entry; - -int -ppp_vdcmd(fun, vdp, vdi, vds) - unsigned int fun; - struct vddrv *vdp; - addr_t vdi; - struct vdstat *vds; -{ - static int majnum = -1; - int n, maj; - - switch (fun) { - case VDLOAD: - /* - * It seems like modload doesn't install the cdevsw entry - * for us. Oh well... - */ - for (maj = 1; maj < nchrdev; ++maj) - if (cdevsw[maj].d_open == vd_unuseddev) - break; - if (maj >= nchrdev) - return ENODEV; - vd.Drv_charmajor = maj; - old_entry = cdevsw[maj]; - cdevsw[maj] = ppp_cdevsw; - vd.Drv_cdevsw = &ppp_cdevsw; - vdp->vdd_vdtab = (struct vdlinkage *) &vd; - majnum = maj; - break; - - case VDUNLOAD: - if (ppp_count > 0) - return EBUSY; - if (vd.Drv_charmajor > 0) - cdevsw[vd.Drv_charmajor] = old_entry; - break; - - case VDSTAT: - /* - * We have to fool the modstat command into thinking - * that this module is actually a driver! This is - * so that installation commands that use the -exec - * option of modload to run a shell script find out - * the block and/or char major numbers of the driver - * loaded (so that the shell script can go off to - * /dev and *MAKE* the bloody device nodes- remember - * they might change from one load to another if - * you don't hardwire the number!). - */ - vds->vds_magic = VDMAGIC_DRV; - vds->vds_modinfo[0] = (char) 0; - vds->vds_modinfo[1] = (char) majnum; - break; - - default: - return EIO; - } - return 0; -} diff --git a/mdk-stage1/ppp/svr4/Makedefs b/mdk-stage1/ppp/svr4/Makedefs deleted file mode 100644 index 81db8ab2e..000000000 --- a/mdk-stage1/ppp/svr4/Makedefs +++ /dev/null @@ -1,16 +0,0 @@ -# -# defines common to several Makefiles -# - -INSTALL= /usr/sbin/install - -BINDIR = /usr/local/bin -MANDIR = /usr/local/man -ETCDIR = /etc/ppp - -COPTS = -O -Xa - -# For compiling with gcc, comment out the COPTS definition above and -# uncomment the next 2 definitions. -#CC = gcc -#COPTS = -O2 diff --git a/mdk-stage1/ppp/svr4/Makedefs.sol2 b/mdk-stage1/ppp/svr4/Makedefs.sol2 deleted file mode 100644 index e8b8d282e..000000000 --- a/mdk-stage1/ppp/svr4/Makedefs.sol2 +++ /dev/null @@ -1,59 +0,0 @@ -# -# Generic make definitions for Solaris 2 -# -# $Id$ -# - -include ../svr4/Makedefs - -CPPFLAGS = -D_KERNEL -DSVR4 -DSOL2 -DPRIOQ -DDEBUG -I../include -CFLAGS = $(CPPFLAGS) $(COPTS) - -# lint-specific variables -LINT = lint -LINT_OPT_32 = -LINT_OPT_64 = -Xarch=v9 -errchk=longptr64 - -LINT_32 = -LINT_32 += -erroff=E_BAD_PTR_CAST_ALIGN -LINT_32 += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED -LINT_32 += -erroff=E_SUSPICIOUS_COMPARISON -LINT_32 += -erroff=E_CAST_UINT_TO_SIGNED_INT -LINT_32 += -erroff=E_PASS_UINT_TO_SIGNED_INT -LINT_32 += -erroff=E_INVALID_ANNOTATION_NAME -LINT_32 += -erroff=E_FUNC_ARG_UNUSED -# This might be needed, but zlib.c and vjcompress.c will squawk -# when not ignored -LINT_32 += -erroff=E_CASE_FALLTHRU -LINT_32 += -erroff=E_RET_INT_IMPLICITLY -LINT_32 += -erroff=E_FUNC_NO_RET_VAL -# Some STREAMS macros will be noisy too when this isn't ignored -LINT_32 += -erroff=E_CONSTANT_CONDITION -LINT_32 += -erroff=E_CONST_EXPR - -# Extra noise suppressant for 64-bit -EXTRA_OFF = -EXTRA_OFF += -erroff=E_CAST_INT_TO_SMALL_INT -EXTRA_OFF += -erroff=E_CAST_INT_CONST_TO_SMALL_INT -EXTRA_OFF += -erroff=E_CAST_TO_PTR_FROM_INT -EXTRA_OFF += -erroff=E_ASSIGN_INT_TO_SMALL_INT -EXTRA_OFF += -erroff=E_ASSIGN_INT_FROM_BIG_CONST -EXTRA_OFF += -erroff=E_CONST_PROMOTED_UNSIGNED_LL -EXTRA_OFF += -erroff=E_CONST_PROMOTED_LONG_LONG -EXTRA_OFF += -erroff=E_CONST_TRUNCATED_BY_ASSIGN -EXTRA_OFF += -erroff=E_PASS_INT_FROM_BIG_CONST -EXTRA_OFF += -erroff=E_COMP_INT_WITH_LARGE_INT -EXTRA_OFF += -erroff=E_ASSIGN_UINT_TO_SIGNED_INT -EXTRA_OFF += -erroff=E_ASSIGN_NARROW_CONV -EXTRA_OFF += -erroff=E_PASS_INT_TO_SMALL_INT -EXTRA_OFF += -erroff=E_PTR_CONV_LOSES_BITS - -LINT_64 = $(LINT_32) -LINT_64 += $(EXTRA_OFF) - -LINTFLAGS64 = -Xa -nsxmuF -errtags=yes $(LINT_OPT_64) $(LINT_64) -LINT64 = $(LINT) -c $(LINTFLAGS64) $(CPPFLAGS) - -LINTFLAGS32 = -Xa -nsxmuF -errtags=yes $(LINT_OPT_32) $(LINT_32) -LINT32 = $(LINT) -c $(LINTFLAGS32) $(CPPFLAGS) - diff --git a/mdk-stage1/ppp/svr4/Makefile.sol2 b/mdk-stage1/ppp/svr4/Makefile.sol2 deleted file mode 100644 index 5b2ca8635..000000000 --- a/mdk-stage1/ppp/svr4/Makefile.sol2 +++ /dev/null @@ -1,66 +0,0 @@ -# -# Makefile for STREAMS modules for Solaris 2. -# -# $Id$ -# - -include Makedefs.sol2 - -COPTS += -xO2 -xspace -W0,-Lt - -COMP_OBJS = ppp_comp.o bsd-comp.o deflate.o zlib.o vjcompress.o \ - ppp_comp_mod.o - -all: ppp ppp_ahdl ppp_comp - -ppp: ppp.o ppp_mod.o - ld -r -o $@ ppp.o ppp_mod.o - chmod +x $@ - -ppp_ahdl: ppp_ahdlc.o ppp_ahdlc_mod.o - ld -r -o $@ ppp_ahdlc.o ppp_ahdlc_mod.o - chmod +x $@ - -ppp_comp: $(COMP_OBJS) - ld -r -o $@ $(COMP_OBJS) - chmod +x $@ - -bsd-comp.o: ../modules/bsd-comp.c - $(CC) $(CFLAGS) -c $? -deflate.o: ../modules/deflate.c - $(CC) $(CFLAGS) -c $? -ppp.o: ../modules/ppp.c - $(CC) $(CFLAGS) -c $? -ppp_mod.o: ppp_mod.c - $(CC) $(CFLAGS) -c $? -ppp_ahdlc_mod.o: ppp_ahdlc_mod.c - $(CC) $(CFLAGS) -c $? -ppp_ahdlc.o: ../modules/ppp_ahdlc.c - $(CC) $(CFLAGS) -c $? -ppp_comp.o: ../modules/ppp_comp.c - $(CC) $(CFLAGS) -c $? -ppp_comp_mod.o: ppp_comp_mod.c - $(CC) $(CFLAGS) -c $? -vjcompress.o: ../modules/vjcompress.c - $(CC) $(CFLAGS) -c $? -zlib.o: ../common/zlib.c - $(CC) $(CFLAGS) -c $? - -install: - cp ppp ppp.conf /kernel/drv - cp ppp_comp ppp_ahdl /kernel/strmod - if grep clone:ppp /etc/minor_perm; then :; else \ - echo clone:ppp 0644 root sys >>/etc/minor_perm; fi - /usr/sbin/rem_drv ppp 2>/dev/null || true - /usr/sbin/add_drv ppp - -SRCS = ../modules/ppp.c ppp_mod.c ../modules/ppp_ahdlc.c ppp_ahdlc_mod.c \ - ../modules/ppp_comp.c ../modules/bsd-comp.c ../modules/deflate.c \ - ../common/zlib.c ../modules/vjcompress.c ppp_comp_mod.c - -lint: - $(LINT32) $(SRCS) - -clean: - rm -f ppp ppp_comp ppp_ahdl *.o *~ core - rm -f *.ln diff --git a/mdk-stage1/ppp/svr4/Makefile.sol2-64 b/mdk-stage1/ppp/svr4/Makefile.sol2-64 deleted file mode 100644 index 80c6b185e..000000000 --- a/mdk-stage1/ppp/svr4/Makefile.sol2-64 +++ /dev/null @@ -1,85 +0,0 @@ -# -# Makefile for 64-bit STREAMS modules for Solaris 2. -# -# $Id$ -# - -include Makedefs.sol2 - -# Sun's cc flag for LP64 compilation / linkage -COPTS += -xchip=ultra -xarch=v9 -Wc,-xcode=abs32 -Wc,-Qiselect-regsym=0 -xO3 -xspace -W0,-Lt - -# subdirectory where 64-bit objects / binaries will be placed -LP64DIR = sparcv9 - -# Name of legacy Makefile (for 32-bit binaries) -STD_MAKE = Makefile.sol2 - -COMP_OBJS = $(LP64DIR)/ppp_comp.o $(LP64DIR)/bsd-comp.o \ - $(LP64DIR)/deflate.o $(LP64DIR)/zlib.o $(LP64DIR)/vjcompress.o \ - $(LP64DIR)/ppp_comp_mod.o - -all: std_objs $(LP64DIR) ppp ppp_ahdl ppp_comp - -std_objs: - $(MAKE) -f $(STD_MAKE) all - -ppp: $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o - ld -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp.o $(LP64DIR)/ppp_mod.o - chmod +x $(LP64DIR)/$@ - -ppp_ahdl: $(LP64DIR)/ppp_ahdlc.o $(LP64DIR)/ppp_ahdlc_mod.o - ld -r -o $(LP64DIR)/$@ $(LP64DIR)/ppp_ahdlc.o $(LP64DIR)/ppp_ahdlc_mod.o - chmod +x $(LP64DIR)/$@ - -ppp_comp: $(COMP_OBJS) - ld -r -o $(LP64DIR)/$@ $(COMP_OBJS) - chmod +x $(LP64DIR)/$@ - -$(LP64DIR)/bsd-comp.o: ../modules/bsd-comp.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/deflate.o: ../modules/deflate.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp.o: ../modules/ppp.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_mod.o: ppp_mod.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_ahdlc_mod.o: ppp_ahdlc_mod.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_ahdlc.o: ../modules/ppp_ahdlc.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_comp.o: ../modules/ppp_comp.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/ppp_comp_mod.o: ppp_comp_mod.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/vjcompress.o: ../modules/vjcompress.c - $(CC) $(CFLAGS) -c $? -o $@ -$(LP64DIR)/zlib.o: ../common/zlib.c - $(CC) $(CFLAGS) -c $? -o $@ - -$(LP64DIR): - mkdir -m 755 -p $@ - -install: - cp ppp ppp.conf /kernel/drv - cp ppp_comp ppp_ahdl /kernel/strmod - cp $(LP64DIR)/ppp /kernel/drv/$(LP64DIR) - cp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl /kernel/strmod/$(LP64DIR) - if grep clone:ppp /etc/minor_perm; then :; else \ - echo clone:ppp 0644 root sys >>/etc/minor_perm; fi - /usr/sbin/rem_drv ppp 2>/dev/null || true - /usr/sbin/add_drv ppp - -SRCS = ../modules/ppp.c ppp_mod.c ../modules/ppp_ahdlc.c ppp_ahdlc_mod.c \ - ../modules/ppp_comp.c ../modules/bsd-comp.c ../modules/deflate.c \ - ../common/zlib.c ../modules/vjcompress.c ppp_comp_mod.c - -lint: - $(LINT64) $(SRCS) - -lint-32: - $(LINT32) $(SRCS) - -clean: - $(MAKE) -f $(STD_MAKE) clean - rm -f $(LP64DIR)/ppp $(LP64DIR)/ppp_comp $(LP64DIR)/ppp_ahdl $(LP64DIR)/*.o $(LP64DIR)/*~ $(LP64DIR)/core diff --git a/mdk-stage1/ppp/svr4/Makefile.svr4 b/mdk-stage1/ppp/svr4/Makefile.svr4 deleted file mode 100644 index 252c52428..000000000 --- a/mdk-stage1/ppp/svr4/Makefile.svr4 +++ /dev/null @@ -1,60 +0,0 @@ -# -# Makefile for STREAMS modules for SVR4. -# -# $Id$ -# - -COPTS = -O - -CFLAGS= -D_KERNEL -DSVR4 -DLACHTCP -I../include $(COPTS) - -all: ppp ppp_ahdl ppp_comp - -ppp: ppp.o - ld -r -o $@ ppp.o - -ppp_ahdl: ppp_ahdlc.o - ld -r -o $@ ppp_ahdlc.o - -ppp_comp: ppp_comp.o bsd-comp.o vjcompress.o deflate.o zlib.o - ld -r -o $@ ppp_comp.o bsd-comp.o vjcompress.o deflate.o zlib.o - -bsd-comp.o: ../modules/bsd-comp.c - $(CC) $(CFLAGS) -c $? -deflate.o: ../modules/deflate.c - $(CC) $(CFLAGS) -c $? -ppp.o: ../modules/ppp.c - $(CC) $(CFLAGS) -c $? -ppp_ahdlc.o: ../modules/ppp_ahdlc.c - $(CC) $(CFLAGS) -c $? -ppp_comp.o: ../modules/ppp_comp.c - $(CC) $(CFLAGS) -c $? -vjcompress.o: ../modules/vjcompress.c - $(CC) $(CFLAGS) -c $? -zlib.o: ../common/zlib.c - $(CC) $(CFLAGS) -c $? - -install: all - cp ppp Driver.o - cp ppp.Master Master - cp ppp.System System - cp ppp.Node Node - /etc/conf/bin/idinstall -d ppp - /etc/conf/bin/idinstall -a ppp - cp ppp_comp Driver.o - cp ppp_comp.Master Master - cp ppp_comp.System System - /etc/conf/bin/idinstall -d ppp_comp - /etc/conf/bin/idinstall -a ppp_comp - cp ppp_ahdl Driver.o - cp ppp_ahdl.Master Master - cp ppp_ahdl.System System - /etc/conf/bin/idinstall -d ppp_ahdl - /etc/conf/bin/idinstall -a ppp_ahdl - @echo - @echo 'NOTE: You must rebuild your kernel to incorporate the driver.' - @echo '(use /etc/conf/bin/idbuild)' - @echo - -clean: - rm -f ppp ppp_comp ppp_ahdl *.o *~ core diff --git a/mdk-stage1/ppp/svr4/Makefile.top b/mdk-stage1/ppp/svr4/Makefile.top deleted file mode 100644 index 253e48acb..000000000 --- a/mdk-stage1/ppp/svr4/Makefile.top +++ /dev/null @@ -1,50 +0,0 @@ -# -# ppp top level makefile for SVR4 and Solaris 2 -# -# $Id$ -# - -include svr4/Makedefs - -all: - cd chat; $(MAKE) all - cd pppd; $(MAKE) all - cd pppstats; $(MAKE) all - cd pppdump; $(MAKE) all - cd svr4; $(MAKE) all - -install: $(BINDIR) $(MANDIR)/man8 install-progs install-etcppp - -install-progs: - cd chat; $(MAKE) install - cd pppd; $(MAKE) install - cd pppstats; $(MAKE) install - cd pppdump; $(MAKE) install - cd svr4; $(MAKE) install - -install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ - $(ETCDIR)/chap-secrets - -$(ETCDIR)/options: - cp etc.ppp/options $@ - chmod go-w $@ -$(ETCDIR)/pap-secrets: - $(INSTALL) -f $(ETCDIR) -m 600 etc.ppp/pap-secrets -$(ETCDIR)/chap-secrets: - $(INSTALL) -f $(ETCDIR) -m 600 etc.ppp/chap-secrets - -$(BINDIR): - mkdir -m 755 -p $@ -$(MANDIR)/man8: - mkdir -m 755 -p $@ -$(ETCDIR): - mkdir -m 755 -p $@ - -clean: - rm -f *~ - cd chat; $(MAKE) clean - cd pppd; $(MAKE) clean - cd pppstats; $(MAKE) clean - cd pppdump; $(MAKE) clean - cd svr4; $(MAKE) clean - diff --git a/mdk-stage1/ppp/svr4/ppp.Master b/mdk-stage1/ppp/svr4/ppp.Master deleted file mode 100644 index 346db035b..000000000 --- a/mdk-stage1/ppp/svr4/ppp.Master +++ /dev/null @@ -1 +0,0 @@ -ppp - Sciof ppp 0 0 1 128 -1 diff --git a/mdk-stage1/ppp/svr4/ppp.Node b/mdk-stage1/ppp/svr4/ppp.Node deleted file mode 100644 index 7767ade71..000000000 --- a/mdk-stage1/ppp/svr4/ppp.Node +++ /dev/null @@ -1 +0,0 @@ -clone ppp c ppp diff --git a/mdk-stage1/ppp/svr4/ppp.System b/mdk-stage1/ppp/svr4/ppp.System deleted file mode 100644 index e60c0eec3..000000000 --- a/mdk-stage1/ppp/svr4/ppp.System +++ /dev/null @@ -1 +0,0 @@ -ppp Y 1 0 0 0 0 0 0 0 diff --git a/mdk-stage1/ppp/svr4/ppp.conf b/mdk-stage1/ppp/svr4/ppp.conf deleted file mode 100644 index e443a7aac..000000000 --- a/mdk-stage1/ppp/svr4/ppp.conf +++ /dev/null @@ -1 +0,0 @@ -name="ppp" parent="pseudo" instance=0; diff --git a/mdk-stage1/ppp/svr4/ppp_ahdl.Master b/mdk-stage1/ppp/svr4/ppp_ahdl.Master deleted file mode 100644 index 4fde52596..000000000 --- a/mdk-stage1/ppp/svr4/ppp_ahdl.Master +++ /dev/null @@ -1 +0,0 @@ -ppp_ahdl - iSf phdl 0 0 1 1 -1 diff --git a/mdk-stage1/ppp/svr4/ppp_ahdl.System b/mdk-stage1/ppp/svr4/ppp_ahdl.System deleted file mode 100644 index f41a500f4..000000000 --- a/mdk-stage1/ppp/svr4/ppp_ahdl.System +++ /dev/null @@ -1 +0,0 @@ -ppp_ahdl Y 1 0 0 0 0 0 0 0 diff --git a/mdk-stage1/ppp/svr4/ppp_ahdlc_mod.c b/mdk-stage1/ppp/svr4/ppp_ahdlc_mod.c deleted file mode 100644 index f81be8abb..000000000 --- a/mdk-stage1/ppp/svr4/ppp_ahdlc_mod.c +++ /dev/null @@ -1,49 +0,0 @@ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/conf.h> -#include <sys/modctl.h> -#include <sys/sunddi.h> - -extern struct streamtab ppp_ahdlcinfo; - -static struct fmodsw fsw = { - "ppp_ahdl", - &ppp_ahdlcinfo, - D_NEW | D_MP | D_MTQPAIR -}; - -extern struct mod_ops mod_strmodops; - -static struct modlstrmod modlstrmod = { - &mod_strmodops, - "PPP async HDLC module", - &fsw -}; - -static struct modlinkage modlinkage = { - MODREV_1, - (void *) &modlstrmod, - NULL -}; - -/* - * Entry points for modloading. - */ -int -_init(void) -{ - return mod_install(&modlinkage); -} - -int -_fini(void) -{ - return mod_remove(&modlinkage); -} - -int -_info(mip) - struct modinfo *mip; -{ - return mod_info(&modlinkage, mip); -} diff --git a/mdk-stage1/ppp/svr4/ppp_comp.Master b/mdk-stage1/ppp/svr4/ppp_comp.Master deleted file mode 100644 index 78019064e..000000000 --- a/mdk-stage1/ppp/svr4/ppp_comp.Master +++ /dev/null @@ -1 +0,0 @@ -ppp_comp - iSf pcmp 0 0 1 1 -1 diff --git a/mdk-stage1/ppp/svr4/ppp_comp.System b/mdk-stage1/ppp/svr4/ppp_comp.System deleted file mode 100644 index e69d4a1a3..000000000 --- a/mdk-stage1/ppp/svr4/ppp_comp.System +++ /dev/null @@ -1 +0,0 @@ -ppp_comp Y 1 0 0 0 0 0 0 0 diff --git a/mdk-stage1/ppp/svr4/ppp_comp_mod.c b/mdk-stage1/ppp/svr4/ppp_comp_mod.c deleted file mode 100644 index 83ff8e252..000000000 --- a/mdk-stage1/ppp/svr4/ppp_comp_mod.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * ppp_comp_mod.c - modload support for PPP compression STREAMS module. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -/* - * This file is used under Solaris 2. - */ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/conf.h> -#include <sys/modctl.h> -#include <sys/sunddi.h> - -extern struct streamtab ppp_compinfo; - -static struct fmodsw fsw = { - "ppp_comp", - &ppp_compinfo, - D_NEW | D_MP | D_MTQPAIR -}; - -extern struct mod_ops mod_strmodops; - -static struct modlstrmod modlstrmod = { - &mod_strmodops, - "PPP compression module", - &fsw -}; - -static struct modlinkage modlinkage = { - MODREV_1, - (void *) &modlstrmod, - NULL -}; - -/* - * Entry points for modloading. - */ -int -_init(void) -{ - return mod_install(&modlinkage); -} - -int -_fini(void) -{ - return mod_remove(&modlinkage); -} - -int -_info(mip) - struct modinfo *mip; -{ - return mod_info(&modlinkage, mip); -} diff --git a/mdk-stage1/ppp/svr4/ppp_mod.c b/mdk-stage1/ppp/svr4/ppp_mod.c deleted file mode 100644 index a4b1538a5..000000000 --- a/mdk-stage1/ppp/svr4/ppp_mod.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * ppp_mod.c - modload support for PPP pseudo-device driver. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - * - * $Id$ - */ - -/* - * This file is used under Solaris 2. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/conf.h> -#include <sys/modctl.h> -#include <sys/sunddi.h> -#include <sys/ksynch.h> - -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif - -static int ppp_identify __P((dev_info_t *)); -static int ppp_attach __P((dev_info_t *, ddi_attach_cmd_t)); -static int ppp_detach __P((dev_info_t *, ddi_detach_cmd_t)); -static int ppp_devinfo __P((dev_info_t *, ddi_info_cmd_t, void *, void **)); - -extern struct streamtab pppinfo; -extern krwlock_t ppp_lower_lock; - -static dev_info_t *ppp_dip; - -static struct cb_ops cb_ppp_ops = { - nulldev, nulldev, nodev, nodev, /* cb_open, ... */ - nodev, nodev, nodev, nodev, /* cb_dump, ... */ - nodev, nodev, nodev, nochpoll, /* cb_devmap, ... */ - ddi_prop_op, /* cb_prop_op */ - &pppinfo, /* cb_stream */ - D_NEW|D_MP|D_MTQPAIR|D_MTOUTPERIM|D_MTOCEXCL /* cb_flag */ -}; - -static struct dev_ops ppp_ops = { - DEVO_REV, /* devo_rev */ - 0, /* devo_refcnt */ - ppp_devinfo, /* devo_getinfo */ - ppp_identify, /* devo_identify */ - nulldev, /* devo_probe */ - ppp_attach, /* devo_attach */ - ppp_detach, /* devo_detach */ - nodev, /* devo_reset */ - &cb_ppp_ops, /* devo_cb_ops */ - NULL /* devo_bus_ops */ -}; - -/* - * Module linkage information - */ - -static struct modldrv modldrv = { - &mod_driverops, /* says this is a pseudo driver */ - "PPP-2.3 multiplexing driver", - &ppp_ops /* driver ops */ -}; - -static struct modlinkage modlinkage = { - MODREV_1, - (void *) &modldrv, - NULL -}; - -int -_init(void) -{ - return mod_install(&modlinkage); -} - -int -_fini(void) -{ - return mod_remove(&modlinkage); -} - -int -_info(mip) - struct modinfo *mip; -{ - return mod_info(&modlinkage, mip); -} - -static int -ppp_identify(dip) - dev_info_t *dip; -{ - return strcmp(ddi_get_name(dip), "ppp") == 0? DDI_IDENTIFIED: - DDI_NOT_IDENTIFIED; -} - -static int -ppp_attach(dip, cmd) - dev_info_t *dip; - ddi_attach_cmd_t cmd; -{ - - if (cmd != DDI_ATTACH) - return DDI_FAILURE; - if (ddi_create_minor_node(dip, "ppp", S_IFCHR, 0, DDI_PSEUDO, CLONE_DEV) - == DDI_FAILURE) { - ddi_remove_minor_node(dip, NULL); - return DDI_FAILURE; - } - rw_init(&ppp_lower_lock, NULL, RW_DRIVER, NULL); - return DDI_SUCCESS; -} - -static int -ppp_detach(dip, cmd) - dev_info_t *dip; - ddi_detach_cmd_t cmd; -{ - rw_destroy(&ppp_lower_lock); - ddi_remove_minor_node(dip, NULL); - return DDI_SUCCESS; -} - -static int -ppp_devinfo(dip, cmd, arg, result) - dev_info_t *dip; - ddi_info_cmd_t cmd; - void *arg; - void **result; -{ - int error; - - error = DDI_SUCCESS; - switch (cmd) { - case DDI_INFO_DEVT2DEVINFO: - if (ppp_dip == NULL) - error = DDI_FAILURE; - else - *result = (void *) ppp_dip; - break; - case DDI_INFO_DEVT2INSTANCE: - *result = NULL; - break; - default: - error = DDI_FAILURE; - } - return error; -} |