authenticating itself to you, of course.)
-What's new in ppp-2.4.7.
+What's new in ppp-2.4.8.
************************
+* New pppd options have been added:
+ - ifname, to set the name for the PPP interface device
+ - defaultroute-metric, to set the metric for the default route
+ - defaultroute6, to add an IPv6 default route (with nodefaultroute6
+ to prevent adding an IPv6 default route)
+ - up_sdnotify, to have pppd notify systemd when the link is up.
+
+* The rp-pppoe plugin has new options:
+ - host-uniq, to set the Host-Uniq value to send
+ - pppoe-padi-timeout, to set the timeout for discovery packets
+ - pppoe-padi-attempts, to set the number of discovery attempts.
+
+* Added the CLASS attribute in radius packets.
+
+* Sundry bug fixes.
+
+* Fixed warnings and issues found by static analysis.
+
+* Added Submitting-patches.md.
+
+
+What was new in ppp-2.4.7.
+**************************
+
* Fixed a potential security issue in parsing option files (CVE-2014-3158).
* There is a new "stop-bits" option, which takes an argument of 1 or 2,
--- /dev/null
+EAP-TLS authentication support for PPP
+======================================
+
+1. Intro
+
+ The Extensible Authentication Protocol (EAP; RFC 3748) is a
+ security protocol that can be used with PPP. It provides a means
+ to plug in multiple optional authentication methods.
+
+ Transport Level Security (TLS; RFC 5216) provides for mutual
+ authentication, integrity-protected ciphersuite negotiation and
+ key exchange between two endpoints. It also provides for optional
+ MPPE encryption.
+
+ EAP-TLS (RFC 2716) incapsulates the TLS messages in EAP packets,
+ allowing TLS mutual authentication to be used as a generic EAP
+ mechanism. It also provides optional encryption using the MPPE
+ protocol.
+
+ This patch provide EAP-TLS support to pppd.
+ This authentication method can be used in both client or server
+ mode.
+
+2. Building
+
+ To build pppd with EAP-TLS support, OpenSSL (http://www.openssl.org)
+ is required. Any version from 0.9.7 should work.
+
+ Configure, compile, and install as usual.
+
+3. Configuration
+
+ On the client side there are two ways to configure EAP-TLS:
+
+ 1. supply the appropriate 'ca', 'cert' and 'key' command-line parameters
+
+ 2. edit the /etc/ppp/eaptls-client file.
+ Insert a line for each system with which you use EAP-TLS.
+ The line is composed of this fields separated by tab:
+
+ - Client name
+ The name used by the client for authentication, can be *
+ - Server name
+ The name of the server, can be *
+ - Client certificate file
+ The file containing the certificate chain for the
+ client in PEM format
+ - Server certificate file
+ If you want to specify the certificate that the
+ server is allowed to use, put the certificate file name.
+ Else put a dash '-'.
+ - CA certificate file
+ The file containing the trusted CA certificates in PEM
+ format.
+ - Client private key file
+ The file containing the client private key in PEM format.
+
+
+ On the server side edit the /etc/ppp/eaptls-server file.
+ Insert a line for each system with which you use EAP-TLS.
+ The line is composed of this fields separated by tab:
+
+ - Client name
+ The name used by the client for authentication, can be *
+ - Server name
+ The name of the server, can be *
+ - Client certificate file
+ If you want to specify the certificate that the
+ client is allowed to use, put the certificate file name.
+ Else put a dash '-'.
+ - Server certificate file
+ The file containing the certificate chain for the
+ server in PEM format
+ - CA certificate file
+ The file containing the trusted CA certificates in PEM format.
+ - Client private key file
+ The file containing the server private key in PEM format.
+ - addresses
+ A list of IP addresses the client is allowed to use.
+
+
+ OpenSSL engine support is included starting with v0.95 of this patch.
+ Currently the only engine tested is the 'pkcs11' engine (hardware token
+ support). To use the 'pksc11' engine:
+ - Use a special private key fileiname in the /etc/ppp/eaptls-client file:
+ <engine>:<identifier>
+ e.g.
+ pkcs11:123456
+
+ - The certificate can also be loaded from the 'pkcs11' engine using
+ a special client certificate filename in the /etc/ppp/eaptls-client file:
+ <engine>:<identifier>
+ e.g.
+ pkcs11:123456
+
+ - Create an /etc/ppp/openssl.cnf file to load the right OpenSSL engine prior
+ to starting 'pppd'. A sample openssl.cnf file is
+
+ openssl_conf = openssl_def
+
+ [ openssl_def ]
+ engines = engine_section
+
+ [ engine_section ]
+ pkcs11 = pkcs11_section
+
+ [ pkcs11_section ]
+ engine_id = pkcs11
+ dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so
+ MODULE_PATH = /usr/lib64/libeTPkcs11.so
+ init = 0
+
+ - There are two ways to specify a password/PIN for the PKCS11 engine:
+ - inside the openssl.cnf file using
+ PIN = your-secret-pin
+ Note The keyword 'PIN' is case sensitive!
+ - Using the 'password' in the ppp options file.
+ From v0.97 of the eap-tls patch the password can also be supplied
+ using the appropriate 'eaptls_passwd_hook' (see plugins/passprompt.c
+ for an example).
+
+
+4. Options
+
+ These pppd options are available:
+
+ ca <ca-file>
+ Use the CA public certificate found in <ca-file> in PEM format
+ ca-path <directory>
+ Use the directory <directory> as the CA public certificate directory
+ cert <cert-file>
+ Use the client public certificate found in <cert-file> in PEM format
+ or in engine:engine_id format
+ key <key-file>
+ Use the client private key found in <key-file> in PEM format
+ or in engine:engine_id format
+ crl <crl-file>
+ Use the Certificate Revocation List (CRL) file <crl-file> in PEM format.
+ crl-dir <dir>
+ Use CRL files from directory <dir>. It contains CRL files in PEM
+ format and each file contains a CRL. The files are looked up
+ by the issuer name hash value. Use the c_rehash utility
+ to create necessary links.
+ need-peer-eap
+ If the peer doesn't ask us to authenticate or doesn't use eap
+ to authenticate us, disconnect.
+ max-tls-version <1.0|1.1|1.2 (default)|1.3>
+ Specify the maximum TLS protocol version to negotiate with peers. Defaults
+ to TLSv1.2 as the TLSv1.3 code is experimental.
+
+ Note:
+ password-encrypted certificates can be used as of v0.94 of this
+ patch. The password for the eap-tls.key file is specified using
+ the regular
+ password ....
+ statement in the ppp options file, or by using the appropriate
+ plugin which supplies a 'eaptls_passwd_hook' routine.
+
+5. Connecting
+
+ If you're setting up a pppd server, edit the EAP-TLS configuration file
+ as written above and then run pppd with the 'auth' option to authenticate
+ the client. The EAP-TLS method will be used if the other eap methods can't
+ be used (no secrets).
+
+ If you're setting up a client, edit the configuration file and then run
+ pppd with 'remotename' option to specify the server name. Add the
+ 'need-peer-eap' option if you want to be sure the peer ask you to
+ authenticate (and to use eap) and to disconnect if it doesn't.
+
+6. Example
+
+ The following example can be used to connect a Linux client with the 'pptp'
+ package to a Linux server running the 'pptpd' (PoPToP) package. The server
+ was configured with a certificate with name (CN) 'pptp-server', the client
+ was configured with a certificate with name (CN) 'pptp-client', both
+ signed by the same Certificate Authority (CA).
+
+ Server side:
+ - /etc/pptpd.conf file:
+ option /etc/ppp/options-pptpd-eaptls
+ localip 172.16.1.1
+ remoteip 172.16.1.10-20
+ - /etc/ppp/options-pptpd-eaptls file:
+ name pptp-server
+ lock
+ mtu 1500
+ mru 1450
+ auth
+ lcp-echo-failure 3
+ lcp-echo-interval 5
+ nodeflate
+ nobsdcomp
+ nopredictor1
+ nopcomp
+ noaccomp
+
+ require-eap
+ require-mppe-128
+
+ crl /home/janjust/ppp/keys/crl.pem
+
+ debug
+ logfile /tmp/pppd.log
+
+ - /etc/ppp/eaptls-server file:
+ * pptp-server - /etc/ppp/pptp-server.crt /etc/ppp/ca.crt /etc/ppp/pptp-server.key *
+
+ - On the server, run
+ pptdp --conf /etc/pptpd.conf
+
+ Client side:
+ - Run
+ pppd noauth require-eap require-mppe-128 \
+ ipcp-accept-local ipcp-accept-remote noipdefault \
+ cert /etc/ppp/keys/pptp-client.crt \
+ key /etc/ppp/keys/pptp-client.key \
+ ca /etc/ppp/keys/ca.crt \
+ name pptp-client remotename pptp-server \
+ debug logfile /tmp/pppd.log
+ pty "pptp pptp-server.example.com --nolaunchpppd"
+
+ Check /var/log/messages and the files /tmp/pppd.log on both sides for debugging info.
+
+7. Notes
+
+ This is experimental code.
+ Send suggestions and comments to Jan Just Keijser <janjust@nikhef.nl>
+
--- /dev/null
+How to contribute patches to the PPP project.
+=============================================
+
+The PPP project source code is maintained in a Git repository, which
+is publicly available at
+
+git://git.ozlabs.org/~paulus/ppp.git
+
+and
+
+https://github.com/paulusmack/ppp.git
+
+The linux-ppp@vger.kernel.org mailing list is a suitable place to
+discuss issues relating to the PPP code and to post patches.
+
+Although there is a copy of the repository on github.com, the PPP
+project is not a "github project", in the sense that the development
+of the code does not depend on github infrastructure. In particular,
+patch descriptions should be understandable without reference to any
+github.com web page. Thus, patches or commits whose description
+consists only of something like "Closes #123" will be rejected. See
+below for the minimum standards for patch descriptions.
+
+There are two ways in which patches can be submitted for review:
+
+1. Post the patch on the linux-ppp@vger.kernel.org mailing list. This
+ is my preferred way to receive patches, because it provides more
+ opportunity for other interested people to review the patches.
+
+2. Create a pull request on github.com. However, please don't make
+ the mistake of creating a commit with a minimal commit message and
+ then explaining the rationale for the change in the pull request.
+ Put the rationale in the commit message.
+
+Requirements for patch/commit description
+-----------------------------------------
+
+The description on a patch, which becomes the commit message in the
+resulting commit, should describe the reason why the change is being
+made. If it fixes a bug, it should describe the bug in enough detail
+for the reader to understand why and how the change being made fixes
+the bug. If it adds a feature, it should describe the feature and how
+it might be used and why it would be desirable to have the feature.
+
+Normally the patch description should be a few paragraphs in length --
+it can be longer for a really subtle bug or complex feature, or
+shorter for obvious or trivial changes such as fixing spelling
+mistakes.
+
+The first line of the commit message is the "headline", corresponding
+to the subject line of an emailed patch. If the patch is concerned
+with one particular area of the package, it is helpful to put that at
+the beginning, followed by a colon (':'), for example, "pppd: Fix bug
+in vslprintf". The remainder of the headline should be a sentence and
+should start with a capital letter.
+
+Note that as maintainer I will edit the headline or the commit message
+if necessary to make it clearer or to fix spelling or grammatical
+errors. For a github pull request I may cherry-pick the commits and
+modify their commit messages.
+
+References to information on web sites are permitted provided that the
+full URL is given, and that reference to the web site is not essential
+for understanding the change being made. For example, you can refer
+to a github issue provided that you also put the essential details of
+the issue in the commit message, and put the full URL for the issue,
+not just the issue number.
+
+Signoff
+-------
+
+In order to forestall possible (though unlikely) future legal
+problems, this project requires a "Signed-off-by" line on all
+non-trivial patches, with a real name (not just initials, and no
+pseudonyms). Signing off indicates that you certify that your patch
+meets the 'Developer's Certificate of Origin' below (taken from the
+DCO 1.1 in the Linux kernel source tree).
+
+Developer's Certificate of Origin
+---------------------------------
+
+By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+
*
*/
-#ifndef __STDC__
-#define const
-#endif
-
-#ifndef lint
-static const char rcsid[] = "$Id: chat.c,v 1.30 2004/01/17 05:47:55 carlsonj Exp $";
-#endif
-
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
+#include <stdarg.h>
#ifndef TERMIO
#undef TERMIOS
#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
int say_next = 0, hup_next = 0;
-void *dup_mem __P((void *b, size_t c));
-void *copy_of __P((char *s));
-char *grow __P((char *s, char **p, size_t len));
-void usage __P((void));
-void msgf __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 *dup_mem (void *b, size_t c);
+void *copy_of (char *s);
+char *grow (char *s, char **p, size_t len);
+void usage (void);
+void msgf (const char *fmt, ...);
+void fatal (int code, const char *fmt, ...);
+SIGTYPE sigalrm (int signo);
+SIGTYPE sigint (int signo);
+SIGTYPE sigterm (int signo);
+SIGTYPE sighup (int signo);
+void unalarm (void);
+void init (void);
+void set_tty_parameters (void);
+void echo_stderr (int);
+void break_sequence (void);
+void terminate (int status);
+void do_file (char *chat_file);
+int get_string (register char *string);
+int put_string (register char *s);
+int write_char (int c);
+int put_char (int c);
+int get_char (void);
+void chat_send (register char *s);
+char *character (int c);
+void chat_expect (register char *s);
+char *clean (register char *s, int sending);
+void break_sequence (void);
+void terminate (int status);
+void pack_array (char **array, int end);
+char *expect_strtok (char *, char *);
+int vfmtmsg (char *, int, const char *, va_list); /* vsprintf++ */
+
+int main (int, char *[]);
+
+void *dup_mem(void *b, size_t c)
{
void *ans = malloc (c);
if (!ans)
return ans;
}
-void *copy_of (s)
-char *s;
+void *copy_of (char *s)
{
return dup_mem (s, strlen (s) + 1);
}
/* grow a char buffer and keep a pointer offset */
-char *grow(s, p, len)
-char *s;
-char **p;
-size_t len;
+char *grow(char *s, char **p, size_t len)
{
size_t l = *p - s; /* save p as distance into s */
* Perform a UUCP-dialer-like chat script on stdin and stdout.
*/
int
-main(argc, argv)
- int argc;
- char **argv;
+main(int argc, char **argv)
{
int option;
char *arg;
* Process a chat script when read from a file.
*/
-void do_file (chat_file)
-char *chat_file;
+void do_file (char *chat_file)
{
int linect, sendflg;
char *sp, *arg, quote;
/*
* We got an error parsing the command line.
*/
-void usage()
+void usage(void)
{
fprintf(stderr, "\
Usage: %s [-e] [-E] [-v] [-V] [-t timeout] [-r report-file]\n\
/*
* Send a message to syslog and/or stderr.
*/
-void msgf __V((const char *fmt, ...))
+void msgf(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);
+ va_end(args);
}
/*
* Print an error message and terminate.
*/
-void fatal __V((int code, const char *fmt, ...))
+void fatal(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);
+ va_end(args);
terminate(code);
}
int alarmed = 0;
-SIGTYPE sigalrm(signo)
-int signo;
+SIGTYPE sigalrm(int signo)
{
int flags;
msgf("alarm");
}
-void unalarm()
+void unalarm(void)
{
int flags;
fatal(2, "Can't set file mode flags on stdin: %m");
}
-SIGTYPE sigint(signo)
-int signo;
+SIGTYPE sigint(int signo)
{
fatal(2, "SIGINT");
}
-SIGTYPE sigterm(signo)
-int signo;
+SIGTYPE sigterm(int signo)
{
fatal(2, "SIGTERM");
}
-SIGTYPE sighup(signo)
-int signo;
+SIGTYPE sighup(int signo)
{
fatal(2, "SIGHUP");
}
-void init()
+void init(void)
{
signal(SIGINT, sigint);
signal(SIGTERM, sigterm);
alarmed = 0;
}
-void set_tty_parameters()
+void set_tty_parameters(void)
{
#if defined(get_term_param)
term_parms t;
#endif
}
-void break_sequence()
+void break_sequence(void)
{
#ifdef TERMIOS
tcsendbreak (0, 0);
#endif
}
-void terminate(status)
-int status;
+void terminate(int status)
{
static int terminating = 0;
/*
* 'Clean up' this string.
*/
-char *clean(s, sending)
-register char *s;
-int sending; /* set to 1 when sending (putting) this string. */
+char *clean(register char *s,
+ int sending) /* set to 1 when sending (putting) this string. */
{
char cur_chr;
char *s1, *p, *phchar;
* A modified version of 'strtok'. This version skips \ sequences.
*/
-char *expect_strtok (s, term)
- char *s, *term;
+char *expect_strtok (char *s, char *term)
{
static char *str = "";
int escape_flag = 0;
* Process the expect string
*/
-void chat_expect (s)
-char *s;
+void chat_expect (char *s)
{
char *expect;
char *reply;
* the data.
*/
-char *character(c)
-int c;
+char *character(int c)
{
static char string[10];
char *meta;
/*
* process the reply string
*/
-void chat_send (s)
-register char *s;
+void chat_send (register char *s)
{
char file_data[STR_LEN];
fatal(1, "Failed");
}
-int get_char()
+int get_char(void)
{
int status;
char c;
}
}
-int put_char(c)
-int c;
+int put_char(int c)
{
int status;
char ch = c;
}
}
-int write_char (c)
-int c;
+int write_char(int c)
{
if (alarmed || put_char(c) < 0) {
alarm(0);
return (1);
}
-int put_string (s)
-register char *s;
+int put_string(register char *s)
{
quiet = 0;
s = clean(s, 1);
* 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;
+void echo_stderr(int n)
{
static int need_lf;
char *s;
/*
* 'Wait for' this string to appear on this file descriptor.
*/
-int get_string(string)
-register char *string;
+int get_string(register char *string)
{
char temp[STR_LEN];
int c, printed = 0, len, minlen;
extern int select();
-int
-usleep( usec ) /* returns 0 if ok, else -1 */
- long usec; /* delay in microseconds */
+/* returns 0 if ok, else -1 */
+int usleep(long usec) /* delay in microseconds */
{
static struct { /* `timeval' */
long tv_sec; /* seconds */
}
#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_ */
+void pack_array (
+ char **array, /* The address of the array of string pointers */
+ int end) /* The index of the next free entry before CLR_ */
{
int i, j;
#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;
+vfmtmsg(char *buf, int buflen, const char *fmt, va_list args)
{
int c, i, n;
int width, prec, fillch;
--- /dev/null
+# Parameters for authentication using EAP-TLS (client)
+
+# client name (can be *)
+# server name (can be *)
+# client certificate file (required)
+# server certificate file (optional, if unused put '-')
+# CA certificate file (required)
+# client private key file (required)
+
+#client server /root/cert/client.crt - /root/cert/ca.crt /root/cert/client.key
--- /dev/null
+# Parameters for authentication using EAP-TLS (server)
+
+# client name (can be *)
+# server name (can be *)
+# client certificate file (optional, if unused put '-')
+# server certificate file (required)
+# CA certificate file (required)
+# server private key file (required)
+# allowed addresses (required, can be *)
+
+#client server - /root/cert/server.crt /root/cert/ca.crt /root/cert/server.key 192.168.1.0/24
--- /dev/null
+openssl_conf = openssl_def
+
+[ openssl_def ]
+engines = engine_section
+
+[ engine_section ]
+pkcs11 = pkcs11_section
+
+[ pkcs11_section ]
+engine_id = pkcs11
+dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so
+MODULE_PATH = /usr/lib64/libeTPkcs11.so
+init = 0
+
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_ */
#endif
#if (defined(_KERNEL) || defined(KERNEL)) && !defined(NeXT)
-void pppattach __P((void));
-void pppintr __P((void));
+void pppattach(void);
+void pppintr(void);
#endif
#endif /* _IF_PPP_H_ */
int compress_proto; /* CCP compression protocol number */
/* Allocate space for a compressor (transmit side) */
- void *(*comp_alloc) __P((u_char *options, int opt_len));
+ void *(*comp_alloc)(u_char *options, int opt_len);
/* Free space used by a compressor */
- void (*comp_free) __P((void *state));
+ void (*comp_free)(void *state);
/* Initialize a compressor */
- int (*comp_init) __P((void *state, u_char *options, int opt_len,
- int unit, int hdrlen, int debug));
+ int (*comp_init)(void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int debug);
/* Reset a compressor */
- void (*comp_reset) __P((void *state));
+ void (*comp_reset)(void *state);
/* Compress a packet */
- int (*compress) __P((void *state, PACKETPTR *mret,
- PACKETPTR mp, int orig_len, int max_len));
+ int (*compress)(void *state, PACKETPTR *mret,
+ PACKETPTR mp, int orig_len, int max_len);
/* Return compression statistics */
- void (*comp_stat) __P((void *state, struct compstat *stats));
+ void (*comp_stat)(void *state, struct compstat *stats);
/* Allocate space for a decompressor (receive side) */
- void *(*decomp_alloc) __P((u_char *options, int opt_len));
+ void *(*decomp_alloc)(u_char *options, int opt_len);
/* Free space used by a decompressor */
- void (*decomp_free) __P((void *state));
+ void (*decomp_free)(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));
+ int (*decomp_init)(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));
+ void (*decomp_reset)(void *state);
/* Decompress a packet. */
- int (*decompress) __P((void *state, PACKETPTR mp,
- PACKETPTR *dmpp));
+ int (*decompress)(void *state, PACKETPTR mp,
+ PACKETPTR *dmpp);
/* Update state for an incompressible packet received */
- void (*incomp) __P((void *state, PACKETPTR mp));
+ void (*incomp)(void *state, PACKETPTR mp);
/* Return decompression statistics */
- void (*decomp_stat) __P((void *state, struct compstat *stats));
+ void (*decomp_stat)(void *state, struct compstat *stats);
};
#endif /* PACKETPTR */
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_ */
/* 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 *));
+void sl_compress_init(struct slcompress *);
+void sl_compress_setup(struct slcompress *, int);
+u_int sl_compress_tcp(struct mbuf *,
+ struct ip *, struct slcompress *, int);
+int sl_uncompress_tcp(u_char **, int, u_int, struct slcompress *);
+int sl_uncompress_tcp_core(u_char *, int, int, u_int,
+ struct slcompress *, u_char **, u_int *);
#endif /* _SLCOMPRESS_H_ */
/* 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,
+extern void vj_compress_init(struct vjcompress *comp, int max_state);
+extern u_int vj_compress_tcp(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,
+ u_char **vjhdrp);
+extern void vj_uncompress_err(struct vjcompress *comp);
+extern int vj_uncompress_uncomp(u_char *buf, int buflen,
+ struct vjcompress *comp);
+extern int vj_uncompress_tcp(u_char *buf, int buflen, int total_len,
struct vjcompress *comp, u_char **hdrp,
- u_int *hlenp));
+ u_int *hlenp);
#endif /* _VJCOMPRESS_H_ */
cd pppdump; $(MAKE) $(MFLAGS) install
install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \
- $(ETCDIR)/chap-secrets
+ $(ETCDIR)/chap-secrets $(ETCDIR)/eaptls-server $(ETCDIR)/eaptls-client
install-devel:
cd pppd; $(MAKE) $(MFLAGS) install-devel
$(INSTALL) -c -m 600 etc.ppp/pap-secrets $@
$(ETCDIR)/chap-secrets:
$(INSTALL) -c -m 600 etc.ppp/chap-secrets $@
+$(ETCDIR)/eaptls-server:
+ $(INSTALL) -c -m 600 etc.ppp/eaptls-server $@
+$(ETCDIR)/eaptls-client:
+ $(INSTALL) -c -m 600 etc.ppp/eaptls-client $@
$(BINDIR):
$(INSTALL) -d -m 755 $@
#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));
+static void *bsd_comp_alloc(u_char *options, int opt_len);
+static void *bsd_decomp_alloc(u_char *options, int opt_len);
+static void bsd_free(void *state);
+static int bsd_comp_init(void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int debug);
+static int bsd_decomp_init(void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int mru, int debug);
+static int bsd_compress(void *state, mblk_t **mret,
+ mblk_t *mp, int slen, int maxolen);
+static void bsd_incomp(void *state, mblk_t *dmsg);
+static int bsd_decompress(void *state, mblk_t *cmp, mblk_t **dmpp);
+static void bsd_reset(void *state);
+static void bsd_comp_stats(void *state, struct compstat *stats);
/*
* Procedures exported to ppp_comp.c.
#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));
+static void *z_alloc(void *, u_int items, u_int size);
+static void *z_alloc_init(void *, u_int items, u_int size);
+static void z_free(void *, void *ptr);
+static void *z_comp_alloc(u_char *options, int opt_len);
+static void *z_decomp_alloc(u_char *options, int opt_len);
+static void z_comp_free(void *state);
+static void z_decomp_free(void *state);
+static int z_comp_init(void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int debug);
+static int z_decomp_init(void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int mru, int debug);
+static int z_compress(void *state, mblk_t **mret,
+ mblk_t *mp, int slen, int maxolen);
+static void z_incomp(void *state, mblk_t *dmsg);
+static int z_decompress(void *state, mblk_t *cmp,
+ mblk_t **dmpp);
+static void z_comp_reset(void *state);
+static void z_decomp_reset(void *state);
+static void z_comp_stats(void *state, struct compstat *stats);
/*
* Procedures exported to ppp_comp.c.
#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 *));
+static int if_ppp_open(queue_t *, int, int, int);
+static int if_ppp_close(queue_t *, int);
+static int if_ppp_wput(queue_t *, mblk_t *);
+static int if_ppp_rput(queue_t *, mblk_t *);
#define PPP_IF_ID 0x8021
static struct module_info minfo = {
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));
+static int if_ppp_output(struct ifnet *, struct mbuf *,
+ struct sockaddr *);
+static int if_ppp_ioctl(struct ifnet *, u_int, caddr_t);
+static struct mbuf *make_mbufs(mblk_t *, int);
+static mblk_t *make_message(struct mbuf *, int);
#ifdef SNIT_SUPPORT
/* Fake ether header for SNIT */
#endif
#ifndef __osf__
-static void ppp_if_detach __P((struct ifnet *));
+static void ppp_if_detach(struct ifnet *);
/*
* Detach all the interfaces before unloading.
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $Id: ppp.c,v 1.26 2002/12/06 09:49:15 paulus Exp $
*/
/*
#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.
*/
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 *));
+static int pppopen(queue_t *, dev_t *, int, int, cred_t *);
+static int pppclose(queue_t *, int, cred_t *);
#else
-static int pppopen __P((queue_t *, int, int, int));
-static int pppclose __P((queue_t *, int));
+static int pppopen(queue_t *, int, int, int);
+static int pppclose(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 *));
+static int pppurput(queue_t *, mblk_t *);
+static int pppuwput(queue_t *, mblk_t *);
+static int pppursrv(queue_t *);
+static int pppuwsrv(queue_t *);
+static int ppplrput(queue_t *, mblk_t *);
+static int ppplwput(queue_t *, mblk_t *);
+static int ppplrsrv(queue_t *);
+static int ppplwsrv(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));
+static void dlpi_request(queue_t *, mblk_t *, upperstr_t *);
+static void dlpi_error(queue_t *, upperstr_t *, int, int, int);
+static void dlpi_ok(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));
+static int send_data(mblk_t *, upperstr_t *);
+static void new_ppa(queue_t *, mblk_t *);
+static void attach_ppa(queue_t *, mblk_t *);
+static void detach_ppa(queue_t *, mblk_t *);
+static void detach_lower(queue_t *, mblk_t *);
+static void debug_dump(queue_t *, mblk_t *);
+static upperstr_t *find_dest(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));
+static upperstr_t *find_promisc(upperstr_t *, int);
+static mblk_t *prepend_ether(upperstr_t *, mblk_t *, int);
+static mblk_t *prepend_udind(upperstr_t *, mblk_t *, int);
+static void promisc_sendup(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));
+static int putctl2(queue_t *, int, int, int);
+static int putctl4(queue_t *, int, int, int);
+static int pass_packet(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));
+static int ip_hard_filter(upperstr_t *ppa, mblk_t *mp, int outbound);
#endif /* FILTER_PACKETS */
#define PPP_ID 0xb1a6
* ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
* OR MODIFICATIONS.
- *
- * $Id: ppp_ahdlc.c,v 1.18 2002/12/06 09:49:15 paulus Exp $
*/
/*
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));
+static int ahdlc_wput(queue_t *, mblk_t *);
+static int ahdlc_rput(queue_t *, mblk_t *);
+static void ahdlc_encode(queue_t *, mblk_t *);
+static void ahdlc_decode(queue_t *, mblk_t *);
+static int msg_byte(mblk_t *, unsigned int);
#if defined(SOL2)
/*
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $Id: ppp_comp.c,v 1.14 2002/12/06 09:49:15 paulus Exp $
*/
/*
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));
+static int ppp_comp_rput(queue_t *, mblk_t *);
+static int ppp_comp_rsrv(queue_t *);
+static int ppp_comp_wput(queue_t *, mblk_t *);
+static int ppp_comp_wsrv(queue_t *);
+static void ppp_comp_ccp(queue_t *, mblk_t *, int);
+static int msg_byte(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]: \
#ifdef __osf__
-static void ppp_comp_alloc __P((comp_state_t *));
+static void ppp_comp_alloc(comp_state_t *);
typedef struct memreq {
unsigned char comp_opts[20];
int cmd;
*/
#ifdef SVR4
#define MOD_OPEN_DECL(name) \
-static int name __P((queue_t *, dev_t *, int, int, cred_t *))
+static int name(queue_t *, dev_t *, int, int, cred_t *)
#define MOD_CLOSE_DECL(name) \
-static int name __P((queue_t *, int, cred_t *))
+static int name(queue_t *, int, cred_t *)
#define MOD_OPEN(name) \
static int name(q, devp, flag, sflag, credp) \
#else /* not SVR4 */
#define MOD_OPEN_DECL(name) \
-static int name __P((queue_t *, int, int, int))
+static int name(queue_t *, int, int, int)
#define MOD_CLOSE_DECL(name) \
-static int name __P((queue_t *, int))
+static int name(queue_t *, int)
#define MOD_OPEN(name) \
static int name(q, dev, flag, sflag) \
# CC = gcc
#
COPTS = -O2 -pipe -Wall -g
-LIBS =
+LIBS = -lrt
# Uncomment the next line to include support for Microsoft's
# MS-CHAP authentication protocol. Also, edit plugins/radius/Makefile.linux.
# Use libutil
USE_LIBUTIL=y
+# Enable EAP-TLS authentication (requires MPPE support, libssl and libcrypto)
+USE_EAPTLS=y
+
MAXOCTETS=y
INCLUDE_DIRS= -I../include
endif
ifdef MPPE
CFLAGS += -DMPPE=1
+HEADERS += mppe.h
endif
endif
# EAP SRP-SHA1
ifdef USE_SRP
CFLAGS += -DUSE_SRP -DOPENSSL -I/usr/local/ssl/include
-LIBS += -lsrp -L/usr/local/ssl/lib -lcrypto
+LIBS += -lsrp -L/usr/local/ssl/lib
+NEEDCRYPTOLIB = y
TARGETS += srp-entry
EXTRAINSTALL = $(INSTALL) -s -c -m 555 srp-entry $(BINDIR)/srp-entry
MANPAGES += srp-entry.8
PPPDOBJS += sha1.o
endif
+# EAP-TLS
+ifdef USE_EAPTLS
+CFLAGS += -DUSE_EAPTLS=1
+LIBS += -lssl
+NEEDCRYPTOLIB = y
+PPPDSRC += eap-tls.c
+HEADERS += eap-tls.h
+PPPDOBJS += eap-tls.o
+endif
+
ifdef HAS_SHADOW
CFLAGS += -DHAS_SHADOW
#LIBS += -lshadow $(LIBS)
endif
-ifneq ($(wildcard /usr/include/crypt.h),)
+ifneq ($(wildcard $(shell $(CC) --print-sysroot)/usr/include/crypt.h),)
CFLAGS += -DHAVE_CRYPT_H=1
LIBS += -lcrypt
endif
ifdef NEEDDES
ifndef USE_CRYPT
-CFLAGS += -I/usr/include/openssl
-LIBS += -lcrypto
+CFLAGS += -I$(shell $(CC) --print-sysroot)/usr/include/openssl
+NEEDCRYPTOLIB = y
else
CFLAGS += -DUSE_CRYPT=1
endif
HEADERS += pppcrypt.h
endif
+ifdef NEEDCRYPTOLIB
+LIBS += -lcrypto
+endif
+
# For "Pluggable Authentication Modules", see ftp.redhat.com:/pub/pam/.
ifdef USE_PAM
CFLAGS += -DUSE_PAM
CFLAGS += -DUSE_CRYPT -DCHAPMS -DMSLANMAN -DHAVE_CRYPT_H
OBJS += chap_ms.o pppcrypt.o md4.o sha1.o
+# Uncomment to enable MPPE (in both CHAP and EAP-TLS)
+CFLAGS += -DMPPE
+
+# Uncomment to enable EAP-TLS
+CFLAGS += -DUSE_EAPTLS
+LIBS += -lcrypto -lssl
+OBJS += eap-tls.o
+
# Uncomment for CBCP
#CFLAGS += -DCBCP_SUPPORT
#OBJS += cbcp.o
#include <pwd.h>
#include <grp.h>
#include <string.h>
+#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include "upap.h"
#include "chap-new.h"
#include "eap.h"
+#ifdef USE_EAPTLS
+#include "eap-tls.h"
+#endif
#ifdef CBCP_SUPPORT
#include "cbcp.h"
#endif
#include "pathnames.h"
#include "session.h"
-static const char rcsid[] = RCSID;
/* Bits in scan_authfile return value */
#define NONWILD_SERVER 1
static bool default_auth;
/* Hook to enable a plugin to control the idle time limit */
-int (*idle_time_hook) __P((struct ppp_idle *)) = NULL;
+int (*idle_time_hook)(struct ppp_idle *) = NULL;
/* Hook for a plugin to say whether we can possibly authenticate any peer */
-int (*pap_check_hook) __P((void)) = NULL;
+int (*pap_check_hook)(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;
+int (*pap_auth_hook)(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;
+void (*pap_logout_hook)(void) = NULL;
/* Hook for a plugin to get the PAP password for authenticating us */
-int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL;
+int (*pap_passwd_hook)(char *user, char *passwd) = NULL;
/* Hook for a plugin to say if we can possibly authenticate a peer using CHAP */
-int (*chap_check_hook) __P((void)) = NULL;
+int (*chap_check_hook)(void) = NULL;
/* Hook for a plugin to get the CHAP password for authenticating us */
-int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL;
+int (*chap_passwd_hook)(char *user, char *passwd) = NULL;
+
+#ifdef USE_EAPTLS
+/* Hook for a plugin to get the EAP-TLS password for authenticating us */
+int (*eaptls_passwd_hook)(char *user, char *passwd) = NULL;
+#endif
/* Hook for a plugin to say whether it is OK if the peer
refuses to authenticate. */
-int (*null_auth_hook) __P((struct wordlist **paddrs,
- struct wordlist **popts)) = NULL;
+int (*null_auth_hook)(struct wordlist **paddrs,
+ struct wordlist **popts) = NULL;
-int (*allowed_address_hook) __P((u_int32_t addr)) = NULL;
+int (*allowed_address_hook)(u_int32_t addr) = NULL;
#ifdef HAVE_MULTILINK
/* Hook for plugin to hear when an interface joins a multilink bundle */
-void (*multilink_join_hook) __P((void)) = NULL;
+void (*multilink_join_hook)(void) = NULL;
#endif
/* A notifier for when the peer has authenticated itself,
bool explicit_user = 0; /* Set if "user" option supplied */
bool explicit_passwd = 0; /* Set if "password" option supplied */
char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
+#ifdef USE_EAPTLS
+char *cacert_file = NULL; /* CA certificate file (pem format) */
+char *ca_path = NULL; /* directory with CA certificates */
+char *cert_file = NULL; /* client certificate file (pem format) */
+char *privkey_file = NULL; /* client private key file (pem format) */
+char *crl_dir = NULL; /* directory containing CRL files */
+char *crl_file = NULL; /* Certificate Revocation List (CRL) file (pem format) */
+char *max_tls_version = NULL; /* Maximum TLS protocol version (default=1.2) */
+bool need_peer_eap = 0; /* Require peer to authenticate us */
+#endif
static char *uafname; /* name of most recent +ua file */
-extern char *crypt __P((const char *, const char *));
+extern char *crypt (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 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 have_srp_secret __P((char *client, char *server, int need_ip,
- int *lacks_ipp));
-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 *, int));
-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 int set_permitted_number __P((char **));
-static void check_access __P((FILE *, char *));
-static int wordlist_count __P((struct wordlist *));
+static void network_phase (int);
+static void check_idle (void *);
+static void connect_time_expired (void *);
+static int null_login (int);
+static int get_pap_passwd (char *);
+static int have_pap_secret (int *);
+static int have_chap_secret (char *, char *, int, int *);
+static int have_srp_secret(char *client, char *server, int need_ip,
+ int *lacks_ipp);
+
+#ifdef USE_EAPTLS
+static int have_eaptls_secret_server
+(char *client, char *server, int need_ip, int *lacks_ipp);
+static int have_eaptls_secret_client (char *client, char *server);
+static int scan_authfile_eaptls(FILE * f, char *client, char *server,
+ char *cli_cert, char *serv_cert,
+ char *ca_cert, char *pk,
+ struct wordlist ** addrs,
+ struct wordlist ** opts,
+ char *filename, int flags);
+#endif
+
+static int ip_addr_check (u_int32_t, struct permitted_ip *);
+static int scan_authfile(FILE *, char *, char *, char *,
+ struct wordlist **, struct wordlist **,
+ char *, int);
+static void free_wordlist (struct wordlist *);
+static void auth_script (char *);
+static void auth_script_done (void *);
+static void set_allowed_addrs (int, struct wordlist *, struct wordlist *);
+static int some_ip_ok (struct wordlist *);
+static int setupapfile (char **);
+static int privgroup (char **);
+static int set_noauth_addr (char **);
+static int set_permitted_number (char **);
+static void check_access (FILE *, char *);
+static int wordlist_count (struct wordlist *);
#ifdef MAXOCTETS
-static void check_maxoctets __P((void *));
+static void check_maxoctets (void *);
#endif
/*
"Set telephone number(s) which are allowed to connect",
OPT_PRIV | OPT_A2LIST },
+#ifdef USE_EAPTLS
+ { "ca", o_string, &cacert_file, "EAP-TLS CA certificate in PEM format" },
+ { "capath", o_string, &ca_path, "EAP-TLS CA certificate directory" },
+ { "cert", o_string, &cert_file, "EAP-TLS client certificate in PEM format" },
+ { "key", o_string, &privkey_file, "EAP-TLS client private key in PEM format" },
+ { "crl-dir", o_string, &crl_dir, "Use CRLs in directory" },
+ { "crl", o_string, &crl_file, "Use specific CRL file" },
+ { "max-tls-version", o_string, &max_tls_version,
+ "Maximum TLS version (1.0/1.1/1.2 (default)/1.3)" },
+ { "need-peer-eap", o_bool, &need_peer_eap,
+ "Require the peer to authenticate us", 1 },
+#endif /* USE_EAPTLS */
{ NULL }
};
* setupapfile - specifies UPAP info for authenticating with peer.
*/
static int
-setupapfile(argv)
- char **argv;
+setupapfile(char **argv)
{
FILE *ufile;
int l;
euid = geteuid();
if (seteuid(getuid()) == -1) {
option_error("unable to reset uid before opening %s: %m", fname);
+ free(fname);
return 0;
}
ufile = fopen(fname, "r");
fatal("unable to regain privileges: %m");
if (ufile == NULL) {
option_error("unable to open user login data file %s", fname);
+ free(fname);
return 0;
}
check_access(ufile, fname);
|| fgets(p, MAXSECRETLEN - 1, ufile) == NULL) {
fclose(ufile);
option_error("unable to read user login data file %s", fname);
+ free(fname);
return 0;
}
fclose(ufile);
explicit_passwd = 1;
}
+ free(fname);
return (1);
}
* privgroup - allow members of the group to have privileged access.
*/
static int
-privgroup(argv)
- char **argv;
+privgroup(char **argv)
{
struct group *g;
int i;
* Equivalent to specifying an entry like `"" * "" addr' in pap-secrets.
*/
static int
-set_noauth_addr(argv)
- char **argv;
+set_noauth_addr(char **argv)
{
char *addr = *argv;
int l = strlen(addr) + 1;
* set_permitted_number - set remote telephone number(s) that may connect.
*/
static int
-set_permitted_number(argv)
- char **argv;
+set_permitted_number(char **argv)
{
char *number = *argv;
int l = strlen(number) + 1;
* An Open on LCP has requested a change from Dead to Establish phase.
*/
void
-link_required(unit)
- int unit;
+link_required(int unit)
{
}
/*
* Bring the link up to the point of being able to do ppp.
*/
-void start_link(unit)
- int unit;
+void start_link(int unit)
{
status = EXIT_CONNECT_FAILED;
new_phase(PHASE_SERIALCONN);
* physical layer down.
*/
void
-link_terminated(unit)
- int unit;
+link_terminated(int unit)
{
if (phase == PHASE_DEAD || phase == PHASE_MASTER)
return;
* LCP has gone down; it will either die or try to re-establish.
*/
void
-link_down(unit)
- int unit;
+link_down(int unit)
{
if (auth_state != s_down) {
notify(link_down_notifier, 0);
* Proceed to the Dead, Authenticate or Network phase as appropriate.
*/
void
-link_established(unit)
- int unit;
+link_established(int unit)
{
int auth;
lcp_options *wo = &lcp_wantoptions[unit];
lcp_options *go = &lcp_gotoptions[unit];
lcp_options *ho = &lcp_hisoptions[unit];
+#ifdef USE_EAPTLS
+ lcp_options *ao = &lcp_allowoptions[unit];
+#endif
int i;
struct protent *protp;
}
}
+#ifdef USE_EAPTLS
+ if (need_peer_eap && !ao->neg_eap) {
+ warn("eap required to authenticate us but no suitable secrets");
+ lcp_close(unit, "couldn't negotiate eap");
+ status = EXIT_AUTH_TOPEER_FAILED;
+ return;
+ }
+
+ if (need_peer_eap && !ho->neg_eap) {
+ warn("peer doesn't want to authenticate us with eap");
+ lcp_close(unit, "couldn't negotiate eap");
+ status = EXIT_PEER_AUTH_FAILED;
+ return;
+ }
+#endif
+
new_phase(PHASE_AUTHENTICATE);
auth = 0;
if (go->neg_eap) {
* Proceed to the network phase.
*/
static void
-network_phase(unit)
- int unit;
+network_phase(int unit)
{
lcp_options *go = &lcp_gotoptions[unit];
}
void
-start_networks(unit)
- int unit;
+start_networks(int unit)
{
int i;
struct protent *protp;
}
void
-continue_networks(unit)
- int unit;
+continue_networks(int unit)
{
int i;
struct protent *protp;
* The peer has failed to authenticate himself using `protocol'.
*/
void
-auth_peer_fail(unit, protocol)
- int unit, protocol;
+auth_peer_fail(int unit, int protocol)
{
/*
* Authentication failure: take the link down
* The peer has been successfully authenticated using `protocol'.
*/
void
-auth_peer_success(unit, protocol, prot_flavor, name, namelen)
- int unit, protocol, prot_flavor;
- char *name;
- int namelen;
+auth_peer_success(int unit, int protocol, int prot_flavor,
+ char *name, int namelen)
{
int bit;
* We have failed to authenticate ourselves to the peer using `protocol'.
*/
void
-auth_withpeer_fail(unit, protocol)
- int unit, protocol;
+auth_withpeer_fail(int unit, int protocol)
{
if (passwd_from_file)
BZERO(passwd, MAXSECRETLEN);
* We have successfully authenticated ourselves with the peer using `protocol'.
*/
void
-auth_withpeer_success(unit, protocol, prot_flavor)
- int unit, protocol, prot_flavor;
+auth_withpeer_success(int unit, int protocol, int prot_flavor)
{
int bit;
const char *prot = "";
* np_up - a network protocol has come up.
*/
void
-np_up(unit, proto)
- int unit, proto;
+np_up(int unit, int proto)
{
int tlim;
* np_down - a network protocol has gone down.
*/
void
-np_down(unit, proto)
- int unit, proto;
+np_down(int unit, int proto)
{
if (--num_np_up == 0) {
UNTIMEOUT(check_idle, NULL);
* np_finished - a network protocol has finished using the link.
*/
void
-np_finished(unit, proto)
- int unit, proto;
+np_finished(int unit, int proto)
{
if (--num_np_open <= 0) {
/* no further use for the link: shut up shop. */
#ifdef MAXOCTETS
static void
-check_maxoctets(arg)
- void *arg;
+check_maxoctets(void *arg)
{
unsigned int used;
* enough that we can shut it down.
*/
static void
-check_idle(arg)
- void *arg;
+check_idle(void *arg)
{
struct ppp_idle idle;
time_t itime;
* connect_time_expired - log a message and close the connection.
*/
static void
-connect_time_expired(arg)
- void *arg;
+connect_time_expired(void *arg)
{
info("Connect time expired");
status = EXIT_CONNECT_TIME;
* auth_check_options - called to check authentication options.
*/
void
-auth_check_options()
+auth_check_options(void)
{
lcp_options *wo = &lcp_wantoptions[0];
int can_auth;
our_name, 1, &lacks_ip);
}
+#ifdef USE_EAPTLS
+ if (!can_auth && wo->neg_eap) {
+ can_auth =
+ have_eaptls_secret_server((explicit_remote ? remote_name :
+ NULL), our_name, 1, &lacks_ip);
+
+ }
+#endif
+
if (auth_required && !can_auth && noauth_addrs == NULL) {
if (default_auth) {
option_error(
* to use for authenticating ourselves and/or the peer.
*/
void
-auth_reset(unit)
- int unit;
+auth_reset(int unit)
{
lcp_options *go = &lcp_gotoptions[unit];
lcp_options *ao = &lcp_allowoptions[unit];
hadchap = -1;
ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL));
ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2)
- && (passwd[0] != 0 ||
+ && ((passwd[0] != 0 || explicit_passwd) ||
(hadchap = have_chap_secret(user, (explicit_remote? remote_name:
NULL), 0, NULL)));
ao->neg_eap = !refuse_eap && (
passwd[0] != 0 ||
(hadchap == 1 || (hadchap == -1 && have_chap_secret(user,
(explicit_remote? remote_name: NULL), 0, NULL))) ||
- have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL));
+ have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)
+#ifdef USE_EAPTLS
+ || have_eaptls_secret_client(user, (explicit_remote? remote_name: NULL))
+#endif
+ );
hadchap = -1;
if (go->neg_upap && !uselogin && !have_pap_secret(NULL))
!have_chap_secret((explicit_remote? remote_name: NULL), our_name,
1, NULL))) &&
!have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1,
- NULL))
+ NULL)
+#ifdef USE_EAPTLS
+ && !have_eaptls_secret_server((explicit_remote? remote_name: NULL),
+ our_name, 1, NULL)
+#endif
+ )
go->neg_eap = 0;
}
* 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;
+check_passwd(int unit,
+ char *auser, int userlen,
+ char *apasswd, int passwdlen, char **msg)
{
int ret;
char *filename;
* and return 1.
*/
static int
-null_login(unit)
- int unit;
+null_login(int unit)
{
char *filename;
FILE *f;
* Assumes passwd points to MAXSECRETLEN bytes of space (if non-null).
*/
static int
-get_pap_passwd(passwd)
- char *passwd;
+get_pap_passwd(char *passwd)
{
char *filename;
FILE *f;
* secrets that we could possibly use for authenticating the peer.
*/
static int
-have_pap_secret(lacks_ipp)
- int *lacks_ipp;
+have_pap_secret(int *lacks_ipp)
{
FILE *f;
int ret;
* 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;
+have_chap_secret(char *client, char *server,
+ int need_ip, int *lacks_ipp)
{
FILE *f;
int ret;
* know the identity yet.
*/
static int
-have_srp_secret(client, server, need_ip, lacks_ipp)
- char *client;
- char *server;
- int need_ip;
- int *lacks_ipp;
+have_srp_secret(char *client, char *server, int need_ip, int *lacks_ipp)
{
FILE *f;
int ret;
* (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;
+get_secret(int unit, char *client, char *server,
+ char *secret, int *secret_len, int am_server)
{
FILE *f;
int ret, len;
* (We could be either client or server).
*/
int
-get_srp_secret(unit, client, server, secret, am_server)
- int unit;
- char *client;
- char *server;
- char *secret;
- int am_server;
+get_srp_secret(int unit, char *client, char *server,
+ char *secret, int am_server)
{
FILE *fp;
int ret;
* and leaves the following words in extra_options.
*/
static void
-set_allowed_addrs(unit, addrs, opts)
- int unit;
- struct wordlist *addrs;
- struct wordlist *opts;
+set_allowed_addrs(int unit, struct wordlist *addrs,
+ struct wordlist *opts)
{
int n;
struct wordlist *ap, **plink;
* a given IP address. Returns 1 if authorized, 0 otherwise.
*/
int
-auth_ip_addr(unit, addr)
- int unit;
- u_int32_t addr;
+auth_ip_addr(int unit, u_int32_t addr)
{
int ok;
}
static int
-ip_addr_check(addr, addrs)
- u_int32_t addr;
- struct permitted_ip *addrs;
+ip_addr_check(u_int32_t addr, struct permitted_ip *addrs)
{
for (; ; ++addrs)
if ((addr & addrs->mask) == addrs->base)
* addr is in network byte order.
*/
int
-bad_ip_adrs(addr)
- u_int32_t addr;
+bad_ip_adrs(u_int32_t addr)
{
addr = ntohl(addr);
return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET
* IP address(es).
*/
static int
-some_ip_ok(addrs)
- struct wordlist *addrs;
+some_ip_ok(struct wordlist *addrs)
{
for (; addrs != 0; addrs = addrs->next) {
if (addrs->word[0] == '-')
* Returns 1 if authorized, 0 otherwise.
*/
int
-auth_number()
+auth_number(void)
{
struct wordlist *wp = permitted_numbers;
int l;
* check_access - complain if a secret file has too-liberal permissions.
*/
static void
-check_access(f, filename)
- FILE *f;
- char *filename;
+check_access(FILE *f, char *filename)
{
struct stat sbuf;
* match.
*/
static int
-scan_authfile(f, client, server, secret, addrs, opts, filename, flags)
- FILE *f;
- char *client;
- char *server;
- char *secret;
- struct wordlist **addrs;
- struct wordlist **opts;
- char *filename;
- int flags;
+scan_authfile(FILE *f, char *client, char *server,
+ char *secret, struct wordlist **addrs,
+ struct wordlist **opts, char *filename,
+ int flags)
{
int newline, xxx;
int got_flag, best_flag;
* wordlist_count - return the number of items in a wordlist
*/
static int
-wordlist_count(wp)
- struct wordlist *wp;
+wordlist_count(struct wordlist *wp)
{
int n;
* free_wordlist - release memory allocated for a wordlist.
*/
static void
-free_wordlist(wp)
- struct wordlist *wp;
+free_wordlist(struct wordlist *wp)
{
struct wordlist *next;
* has finished.
*/
static void
-auth_script_done(arg)
- void *arg;
+auth_script_done(void *arg)
{
auth_script_pid = 0;
switch (auth_script_state) {
* interface-name peer-name real-user tty speed
*/
static void
-auth_script(script)
- char *script;
+auth_script(char *script)
{
char strspeed[32];
struct passwd *pw;
auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL, 0);
}
+
+
+#ifdef USE_EAPTLS
+static int
+have_eaptls_secret_server(char *client, char *server,
+ int need_ip, int *lacks_ipp)
+{
+ FILE *f;
+ int ret;
+ char *filename;
+ struct wordlist *addrs;
+ char servcertfile[MAXWORDLEN];
+ char clicertfile[MAXWORDLEN];
+ char cacertfile[MAXWORDLEN];
+ char pkfile[MAXWORDLEN];
+
+ filename = _PATH_EAPTLSSERVFILE;
+ 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_eaptls(f, client, server, clicertfile, servcertfile,
+ cacertfile, pkfile, &addrs, NULL, filename,
+ 0);
+
+ fclose(f);
+
+/*
+ if (ret >= 0 && !eaptls_init_ssl(1, cacertfile, servcertfile,
+ clicertfile, pkfile))
+ ret = -1;
+*/
+
+ 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;
+}
+
+
+static int
+have_eaptls_secret_client(char *client, char *server)
+{
+ FILE *f;
+ int ret;
+ char *filename;
+ struct wordlist *addrs = NULL;
+ char servcertfile[MAXWORDLEN];
+ char clicertfile[MAXWORDLEN];
+ char cacertfile[MAXWORDLEN];
+ char pkfile[MAXWORDLEN];
+
+ if (client != NULL && client[0] == 0)
+ client = NULL;
+ else if (server != NULL && server[0] == 0)
+ server = NULL;
+
+ if ((cacert_file || ca_path) && cert_file && privkey_file)
+ return 1;
+
+ filename = _PATH_EAPTLSCLIFILE;
+ f = fopen(filename, "r");
+ if (f == NULL)
+ return 0;
+
+ ret =
+ scan_authfile_eaptls(f, client, server, clicertfile, servcertfile,
+ cacertfile, pkfile, &addrs, NULL, filename,
+ 0);
+ fclose(f);
+
+/*
+ if (ret >= 0 && !eaptls_init_ssl(0, cacertfile, clicertfile,
+ servcertfile, pkfile))
+ ret = -1;
+*/
+
+ if (addrs != 0)
+ free_wordlist(addrs);
+
+ return ret >= 0;
+}
+
+
+static int
+scan_authfile_eaptls(FILE *f, char *client, char *server,
+ char *cli_cert, char *serv_cert, char *ca_cert,
+ char *pk, struct wordlist **addrs,
+ struct wordlist **opts,
+ char *filename, int flags)
+{
+ int newline;
+ int got_flag, best_flag;
+ struct wordlist *ap, *addr_list, *alist, **app;
+ char word[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 cli_cert
+ */
+ if (!getword(f, word, &newline, filename))
+ break;
+ if (newline)
+ continue;
+ if (strcmp(word, "-") != 0) {
+ strlcpy(cli_cert, word, MAXWORDLEN);
+ } else
+ cli_cert[0] = 0;
+
+ /*
+ * Get serv_cert
+ */
+ if (!getword(f, word, &newline, filename))
+ break;
+ if (newline)
+ continue;
+ if (strcmp(word, "-") != 0) {
+ strlcpy(serv_cert, word, MAXWORDLEN);
+ } else
+ serv_cert[0] = 0;
+
+ /*
+ * Get ca_cert
+ */
+ if (!getword(f, word, &newline, filename))
+ break;
+ if (newline)
+ continue;
+ strlcpy(ca_cert, word, MAXWORDLEN);
+
+ /*
+ * Get pk
+ */
+ if (!getword(f, word, &newline, filename))
+ break;
+ if (newline)
+ continue;
+ strlcpy(pk, word, MAXWORDLEN);
+
+
+ /*
+ * 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 (!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;
+}
+
+
+int
+get_eaptls_secret(int unit, char *client, char *server,
+ char *clicertfile, char *servcertfile, char *cacertfile,
+ char *capath, char *pkfile, int am_server)
+{
+ FILE *fp;
+ int ret;
+ char *filename = NULL;
+ struct wordlist *addrs = NULL;
+ struct wordlist *opts = NULL;
+
+ /* maybe overkill, but it eases debugging */
+ bzero(clicertfile, MAXWORDLEN);
+ bzero(servcertfile, MAXWORDLEN);
+ bzero(cacertfile, MAXWORDLEN);
+ bzero(capath, MAXWORDLEN);
+ bzero(pkfile, MAXWORDLEN);
+
+ /* the ca+cert+privkey can also be specified as options */
+ if (!am_server && (cacert_file || ca_path) && cert_file && privkey_file )
+ {
+ strlcpy( clicertfile, cert_file, MAXWORDLEN );
+ if (cacert_file)
+ strlcpy( cacertfile, cacert_file, MAXWORDLEN );
+ if (ca_path)
+ strlcpy( capath, ca_path, MAXWORDLEN );
+ strlcpy( pkfile, privkey_file, MAXWORDLEN );
+ }
+ else
+ {
+ filename = (am_server ? _PATH_EAPTLSSERVFILE : _PATH_EAPTLSCLIFILE);
+ addrs = NULL;
+
+ fp = fopen(filename, "r");
+ if (fp == NULL)
+ {
+ error("Can't open eap-tls secret file %s: %m", filename);
+ return 0;
+ }
+
+ check_access(fp, filename);
+
+ ret = scan_authfile_eaptls(fp, client, server, clicertfile, servcertfile,
+ cacertfile, pkfile, &addrs, &opts, filename, 0);
+
+ fclose(fp);
+
+ if (ret < 0) return 0;
+ }
+
+ if (eaptls_passwd_hook)
+ {
+ dbglog( "Calling eaptls password hook" );
+ if ( (*eaptls_passwd_hook)(pkfile, passwd) < 0)
+ {
+ error("Unable to obtain EAP-TLS password for %s (%s) from plugin",
+ client, pkfile);
+ return 0;
+ }
+ }
+ if (am_server)
+ set_allowed_addrs(unit, addrs, opts);
+ else if (opts != NULL)
+ free_wordlist(opts);
+ if (addrs != NULL)
+ free_wordlist(addrs);
+
+ return 1;
+}
+#endif
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: cbcp.c,v 1.17 2006/05/22 00:04:07 paulus Exp $"
-
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "fsm.h"
#include "lcp.h"
-static const char rcsid[] = RCSID;
/*
* Options.
*/
-static int setcbcp __P((char **));
+static int setcbcp (char **);
static option_t cbcp_option_list[] = {
{ "callback", o_special, (void *)setcbcp,
/*
* 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));
+static void cbcp_init (int unit);
+static void cbcp_open (int unit);
+static void cbcp_lowerup (int unit);
+static void cbcp_input (int unit, u_char *pkt, int len);
+static void cbcp_protrej (int unit);
+static int cbcp_printpkt (u_char *pkt, int len,
+ void (*printer)(void *, char *, ...),
+ void *arg);
struct protent cbcp_protent = {
PPP_CBCP,
/* internal prototypes */
-static void cbcp_recvreq __P((cbcp_state *us, u_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, u_char *pckt, int len));
-static void cbcp_send __P((cbcp_state *us, int code, u_char *buf, int len));
+static void cbcp_recvreq (cbcp_state *us, u_char *pckt, int len);
+static void cbcp_resp (cbcp_state *us);
+static void cbcp_up (cbcp_state *us);
+static void cbcp_recvack (cbcp_state *us, u_char *pckt, int len);
+static void cbcp_send (cbcp_state *us, int code, u_char *buf, int len);
/* option processing */
static int
-setcbcp(argv)
- char **argv;
+setcbcp(char **argv)
{
lcp_wantoptions[0].neg_cbcp = 1;
cbcp_protent.enabled_flag = 1;
/* init state */
static void
-cbcp_init(iface)
- int iface;
+cbcp_init(int iface)
{
cbcp_state *us;
/* lower layer is up */
static void
-cbcp_lowerup(iface)
- int iface;
+cbcp_lowerup(int iface)
{
cbcp_state *us = &cbcp[iface];
}
static void
-cbcp_open(unit)
- int unit;
+cbcp_open(int unit)
{
dbglog("cbcp_open");
}
/* process an incomming packet */
static void
-cbcp_input(unit, inpacket, pktlen)
- int unit;
- u_char *inpacket;
- int pktlen;
+cbcp_input(int unit, u_char *inpacket, int pktlen)
{
u_char *inp;
u_char code, id;
/* pretty print a packet */
static int
-cbcp_printpkt(p, plen, printer, arg)
- u_char *p;
- int plen;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+cbcp_printpkt(u_char *p, int plen,
+ void (*printer) (void *, char *, ...), void *arg)
{
int code, opt, id, len, olen, delay;
u_char *pstart;
/* received CBCP request */
static void
-cbcp_recvreq(us, pckt, pcktlen)
- cbcp_state *us;
- u_char *pckt;
- int pcktlen;
+cbcp_recvreq(cbcp_state *us, u_char *pckt, int pcktlen)
{
u_char type, opt_len, delay, addr_type;
char address[256];
}
static void
-cbcp_resp(us)
- cbcp_state *us;
+cbcp_resp(cbcp_state *us)
{
u_char cb_type;
u_char buf[256];
}
static void
-cbcp_send(us, code, buf, len)
- cbcp_state *us;
- int code;
- u_char *buf;
- int len;
+cbcp_send(cbcp_state *us, int code, u_char *buf, int len)
{
u_char *outp;
int outlen;
}
static void
-cbcp_recvack(us, pckt, len)
- cbcp_state *us;
- u_char *pckt;
- int len;
+cbcp_recvack(cbcp_state *us, u_char *pckt, int len)
{
u_char type, delay, addr_type;
int opt_len;
/* ok peer will do callback */
static void
-cbcp_up(us)
- cbcp_state *us;
+cbcp_up(cbcp_state *us)
{
persist = 0;
status = EXIT_CALLBACK;
#include "lcp.h" /* lcp_close(), lcp_fsm */
#endif
-static const char rcsid[] = RCSID;
/*
* Unfortunately there is a bug in zlib which means that using a
/*
* Command-line options.
*/
-static int setbsdcomp __P((char **));
-static int setdeflate __P((char **));
+static int setbsdcomp (char **);
+static int setdeflate (char **);
static char bsd_value[8];
static char deflate_value[8];
/*
* 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));
+static void ccp_init (int unit);
+static void ccp_open (int unit);
+static void ccp_close (int unit, char *);
+static void ccp_lowerup (int unit);
+static void ccp_lowerdown (int);
+static void ccp_input (int unit, u_char *pkt, int len);
+static void ccp_protrej (int unit);
+static int ccp_printpkt (u_char *pkt, int len,
+ void (*printer)(void *, char *, ...),
+ void *arg);
+static void ccp_datainput (int unit, u_char *pkt, int len);
struct protent ccp_protent = {
PPP_CCP,
/*
* 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, 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 void ccp_resetci (fsm *);
+static int ccp_cilen (fsm *);
+static void ccp_addci (fsm *, u_char *, int *);
+static int ccp_ackci (fsm *, u_char *, int);
+static int ccp_nakci (fsm *, u_char *, int, int);
+static int ccp_rejci (fsm *, u_char *, int);
+static int ccp_reqci (fsm *, u_char *, int *, int);
+static void ccp_up (fsm *);
+static void ccp_down (fsm *);
+static int ccp_extcode (fsm *, int, int, u_char *, int);
+static void ccp_rack_timeout (void *);
+static char *method_name (ccp_options *, ccp_options *);
static fsm_callbacks ccp_callbacks = {
ccp_resetci,
* Option parsing.
*/
static int
-setbsdcomp(argv)
- char **argv;
+setbsdcomp(char **argv)
{
int rbits, abits;
char *str, *endp;
}
static int
-setdeflate(argv)
- char **argv;
+setdeflate(char **argv)
{
int rbits, abits;
char *str, *endp;
* ccp_init - initialize CCP.
*/
static void
-ccp_init(unit)
- int unit;
+ccp_init(int unit)
{
fsm *f = &ccp_fsm[unit];
* ccp_open - CCP is allowed to come up.
*/
static void
-ccp_open(unit)
- int unit;
+ccp_open(int unit)
{
fsm *f = &ccp_fsm[unit];
* ccp_close - Terminate CCP.
*/
static void
-ccp_close(unit, reason)
- int unit;
- char *reason;
+ccp_close(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;
+ccp_lowerup(int unit)
{
fsm_lowerup(&ccp_fsm[unit]);
}
* ccp_lowerdown - we may not transmit CCP packets.
*/
static void
-ccp_lowerdown(unit)
- int unit;
+ccp_lowerdown(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;
+ccp_input(int unit, u_char *p, int len)
{
fsm *f = &ccp_fsm[unit];
int oldstate;
* Handle a CCP-specific code.
*/
static int
-ccp_extcode(f, code, id, p, len)
- fsm *f;
- int code, id;
- u_char *p;
- int len;
+ccp_extcode(fsm *f, int code, int id, u_char *p, int len)
{
switch (code) {
case CCP_RESETREQ:
* ccp_protrej - peer doesn't talk CCP.
*/
static void
-ccp_protrej(unit)
- int unit;
+ccp_protrej(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_resetci(fsm *f)
{
ccp_options *go = &ccp_gotoptions[f->unit];
u_char opt_buf[CCP_MAX_OPTION_LENGTH];
if (go->mppe) {
ccp_options *ao = &ccp_allowoptions[f->unit];
int auth_mschap_bits = auth_done[f->unit];
+#ifdef USE_EAPTLS
+ int auth_eap_bits = auth_done[f->unit];
+#endif
int numbits;
/*
lcp_close(f->unit, "MPPE required but not available");
return;
}
+
+#ifdef USE_EAPTLS
+ /*
+ * MPPE is also possible in combination with EAP-TLS.
+ * It is not possible to detect if we're doing EAP or EAP-TLS
+ * at this stage, hence we accept all forms of EAP. If TLS is
+ * not used then the MPPE keys will not be derived anyway.
+ */
+ /* Leave only the eap auth bits set */
+ auth_eap_bits &= (EAP_WITHPEER | EAP_PEER );
+
+ if ((numbits == 0) && (auth_eap_bits == 0)) {
+ error("MPPE required, but MS-CHAP[v2] nor EAP-TLS auth are performed.");
+#else
if (!numbits) {
error("MPPE required, but MS-CHAP[v2] auth not performed.");
+#endif
lcp_close(f->unit, "MPPE required but not available");
return;
}
* ccp_cilen - Return total length of our configuration info.
*/
static int
-ccp_cilen(f)
- fsm *f;
+ ccp_cilen(fsm *f)
{
ccp_options *go = &ccp_gotoptions[f->unit];
* ccp_addci - put our requests in a packet.
*/
static void
-ccp_addci(f, p, lenp)
- fsm *f;
- u_char *p;
- int *lenp;
+ ccp_addci(fsm *f, u_char *p, int *lenp)
{
int res;
ccp_options *go = &ccp_gotoptions[f->unit];
* 1 iff the packet was OK.
*/
static int
-ccp_ackci(f, p, len)
- fsm *f;
- u_char *p;
- int len;
+ ccp_ackci(fsm *f, u_char *p, int len)
{
ccp_options *go = &ccp_gotoptions[f->unit];
u_char *p0 = p;
* Returns 1 iff the nak was OK.
*/
static int
-ccp_nakci(f, p, len, treat_as_reject)
- fsm *f;
- u_char *p;
- int len;
- int treat_as_reject;
+ ccp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
{
ccp_options *go = &ccp_gotoptions[f->unit];
ccp_options no; /* options we've seen already */
* ccp_rejci - reject some of our suggested compression methods.
*/
static int
-ccp_rejci(f, p, len)
- fsm *f;
- u_char *p;
- int len;
+ccp_rejci(fsm *f, u_char *p, int len)
{
ccp_options *go = &ccp_gotoptions[f->unit];
ccp_options try; /* options to request next time */
* appropriately.
*/
static int
-ccp_reqci(f, p, lenp, dont_nak)
- fsm *f;
- u_char *p;
- int *lenp;
- int dont_nak;
+ccp_reqci(fsm *f, u_char *p, int *lenp, int dont_nak)
{
int ret, newret, res;
u_char *p0, *retp;
* Make a string name for a compression method (or 2).
*/
static char *
-method_name(opt, opt2)
- ccp_options *opt, *opt2;
+method_name(ccp_options *opt, ccp_options *opt2)
{
static char result[64];
* CCP has come up - inform the kernel driver and log a message.
*/
static void
-ccp_up(f)
- fsm *f;
+ccp_up(fsm *f)
{
ccp_options *go = &ccp_gotoptions[f->unit];
ccp_options *ho = &ccp_hisoptions[f->unit];
* CCP has gone down - inform the kernel driver.
*/
static void
-ccp_down(f)
- fsm *f;
+ccp_down(fsm *f)
{
if (ccp_localstate[f->unit] & RACK_PENDING)
UNTIMEOUT(ccp_rack_timeout, f);
};
static int
-ccp_printpkt(p, plen, printer, arg)
- u_char *p;
- int plen;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+ccp_printpkt(u_char *p, int plen,
+ void (*printer) (void *, char *, ...), void *arg)
{
u_char *p0, *optend;
int code, id, len;
* compression :-(, otherwise we issue the reset-request.
*/
static void
-ccp_datainput(unit, pkt, len)
- int unit;
- u_char *pkt;
- int len;
+ccp_datainput(int unit, u_char *pkt, int len)
{
fsm *f;
* Timeout waiting for reset-ack.
*/
static void
-ccp_rack_timeout(arg)
- void *arg;
+ccp_rack_timeout(void *arg)
{
fsm *f = arg;
/*
* Option variables.
*/
-int chap_timeout_time = 3;
+int chap_server_timeout_time = 3;
int chap_max_transmits = 10;
int chap_rechallenge_time = 0;
+int chap_client_timeout_time = 60;
/*
* Command-line options.
*/
static option_t chap_option_list[] = {
- { "chap-restart", o_int, &chap_timeout_time,
- "Set timeout for CHAP", OPT_PRIO },
+ { "chap-restart", o_int, &chap_server_timeout_time,
+ "Set timeout for CHAP (as server)", OPT_PRIO },
{ "chap-max-challenge", o_int, &chap_max_transmits,
"Set max #xmits for challenge", OPT_PRIO },
{ "chap-interval", o_int, &chap_rechallenge_time,
"Set interval for rechallenge", OPT_PRIO },
+ { "chap-timeout", o_int, &chap_client_timeout_time,
+ "Set timeout for CHAP (as client)", OPT_PRIO },
{ NULL }
};
static void chap_init(int unit);
static void chap_lowerup(int unit);
static void chap_lowerdown(int unit);
-static void chap_timeout(void *arg);
+static void chap_server_timeout(void *arg);
+static void chap_client_timeout(void *arg);
static void chap_generate_challenge(struct chap_server_state *ss);
static void chap_handle_response(struct chap_server_state *ss, int code,
unsigned char *pkt, int len);
static void chap_protrej(int unit);
static void chap_input(int unit, unsigned char *pkt, int pktlen);
static int chap_print_pkt(unsigned char *p, int plen,
- void (*printer) __P((void *, char *, ...)), void *arg);
+ void (*printer)(void *, char *, ...), void *arg);
/* List of digest types that we know about */
static struct chap_digest_type *chap_digests;
cs->flags |= LOWERUP;
ss->flags |= LOWERUP;
if (ss->flags & AUTH_STARTED)
- chap_timeout(ss);
+ chap_server_timeout(ss);
}
static void
struct chap_client_state *cs = &client;
struct chap_server_state *ss = &server;
+ if (cs->flags & TIMEOUT_PENDING)
+ UNTIMEOUT(chap_client_timeout, cs);
cs->flags = 0;
if (ss->flags & TIMEOUT_PENDING)
- UNTIMEOUT(chap_timeout, ss);
+ UNTIMEOUT(chap_server_timeout, ss);
ss->flags = 0;
}
ss->id = (unsigned char)(drand48() * 256);
ss->flags |= AUTH_STARTED;
if (ss->flags & LOWERUP)
- chap_timeout(ss);
+ chap_server_timeout(ss);
}
/*
cs->digest = dp;
cs->name = our_name;
- cs->flags |= AUTH_STARTED;
+ cs->flags |= AUTH_STARTED | TIMEOUT_PENDING;
+ TIMEOUT(chap_client_timeout, cs, chap_client_timeout_time);
}
/*
- * chap_timeout - It's time to send another challenge to the peer.
+ * chap_server_timeout - It's time to send another challenge to the peer.
* This could be either a retransmission of a previous challenge,
* or a new challenge to start re-authentication.
*/
static void
-chap_timeout(void *arg)
+chap_server_timeout(void *arg)
{
struct chap_server_state *ss = arg;
output(0, ss->challenge, ss->challenge_pktlen);
++ss->challenge_xmits;
ss->flags |= TIMEOUT_PENDING;
- TIMEOUT(chap_timeout, arg, chap_timeout_time);
+ TIMEOUT(chap_server_timeout, arg, chap_server_timeout_time);
+}
+
+/* chap_client_timeout - Authentication with peer timed out. */
+static void
+chap_client_timeout(void *arg)
+{
+ struct chap_client_state *cs = arg;
+
+ cs->flags &= ~TIMEOUT_PENDING;
+ cs->flags |= AUTH_DONE | AUTH_FAILED;
+ error("CHAP authentication timed out");
+ auth_withpeer_fail(0, PPP_CHAP);
}
/*
if (ss->flags & TIMEOUT_PENDING) {
ss->flags &= ~TIMEOUT_PENDING;
- UNTIMEOUT(chap_timeout, ss);
+ UNTIMEOUT(chap_server_timeout, ss);
}
if (explicit_remote) {
name, strlen(name));
if (chap_rechallenge_time) {
ss->flags |= TIMEOUT_PENDING;
- TIMEOUT(chap_timeout, ss,
+ TIMEOUT(chap_server_timeout, ss,
chap_rechallenge_time);
}
}
return;
cs->flags |= AUTH_DONE;
+ UNTIMEOUT(chap_client_timeout, cs);
+ cs->flags &= ~TIMEOUT_PENDING;
+
if (code == CHAP_SUCCESS) {
/* used for MS-CHAP v2 mutual auth, yuck */
if (cs->digest->check_success != NULL) {
if (ss->flags & TIMEOUT_PENDING) {
ss->flags &= ~TIMEOUT_PENDING;
- UNTIMEOUT(chap_timeout, ss);
+ UNTIMEOUT(chap_server_timeout, ss);
}
if (ss->flags & AUTH_STARTED) {
ss->flags = 0;
static int
chap_print_pkt(unsigned char *p, int plen,
- void (*printer) __P((void *, char *, ...)), void *arg)
+ void (*printer)(void *, char *, ...), void *arg)
{
int code, id, len;
int clen, nlen;
#include "pppcrypt.h"
#include "magic.h"
-static const char rcsid[] = RCSID;
-static void ascii2unicode __P((char[], int, u_char[]));
-static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE]));
-static void ChallengeResponse __P((u_char *, u_char *, u_char[24]));
-static void ChapMS_NT __P((u_char *, char *, int, u_char[24]));
-static void ChapMS2_NT __P((u_char *, u_char[16], char *, char *, int,
- u_char[24]));
+static void ascii2unicode (char[], int, u_char[]);
+static void NTPasswordHash (u_char *, int, u_char[MD4_SIGNATURE_SIZE]);
+static void ChallengeResponse (u_char *, u_char *, u_char[24]);
+static void ChapMS_NT (u_char *, char *, int, u_char[24]);
+static void ChapMS2_NT (u_char *, u_char[16], char *, char *, int,
+ u_char[24]);
static void GenerateAuthenticatorResponsePlain
- __P((char*, int, u_char[24], u_char[16], u_char *,
- char *, u_char[41]));
+ (char*, int, u_char[24], u_char[16], u_char *,
+ char *, u_char[41]);
#ifdef MSLANMAN
-static void ChapMS_LANMan __P((u_char *, char *, int, u_char *));
+static void ChapMS_LANMan (u_char *, char *, int, u_char *);
#endif
#ifdef MPPE
-static void Set_Start_Key __P((u_char *, char *, int));
-static void SetMasterKeys __P((char *, int, u_char[24], int));
+static void Set_Start_Key (u_char *, char *, int);
+static void SetMasterKeys (char *, int, u_char[24], int);
#endif
#ifdef MSLANMAN
len -= MS_AUTH_RESPONSE_LENGTH;
if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) {
msg += 3; /* Eat the delimiter */
+ } else if ((len >= 2) && !strncmp((char *)msg, "M=", 2)) {
+ msg += 2; /* Eat the delimiter */
} else if (len) {
/* Packet has extra text which does not begin " M=" */
error("MS-CHAPv2 Success packet is badly formed.");
#define MS_CHAP2_AUTHENTICATEE 0
#define MS_CHAP2_AUTHENTICATOR 1
-void ChapMS __P((u_char *, char *, int, u_char *));
-void ChapMS2 __P((u_char *, u_char *, char *, char *, int,
- u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int));
+void ChapMS (u_char *, char *, int, u_char *);
+void ChapMS2 (u_char *, u_char *, char *, char *, int,
+ u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int);
#ifdef MPPE
-void mppe_set_keys __P((u_char *, u_char[MD4_SIGNATURE_SIZE]));
+void mppe_set_keys (u_char *, u_char[MD4_SIGNATURE_SIZE]);
void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
u_char NTResponse[24], int IsServer);
#endif
-void ChallengeHash __P((u_char[16], u_char *, char *, u_char[8]));
+void ChallengeHash (u_char[16], u_char *, char *, u_char[8]);
void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
u_char NTResponse[24], u_char PeerChallenge[16],
#include "ipcp.h"
#include "lcp.h"
-static const char rcsid[] = RCSID;
char *frame;
int framelen;
struct packet *pend_q;
struct packet *pend_qtail;
-static int active_packet __P((unsigned char *, int));
+static int active_packet(unsigned char *, int);
/*
* demand_conf - configure the interface for doing dial-on-demand.
*/
void
-demand_conf()
+demand_conf(void)
{
int i;
struct protent *protp;
* demand_block - set each network protocol to block further packets.
*/
void
-demand_block()
+demand_block(void)
{
int i;
struct protent *protp;
* with an error.
*/
void
-demand_discard()
+demand_discard(void)
{
struct packet *pkt, *nextpkt;
int i;
* demand_unblock - set each enabled network protocol to pass packets.
*/
void
-demand_unblock()
+demand_unblock(void)
{
int i;
struct protent *protp;
* Return value is 1 if we need to bring up the link, 0 otherwise.
*/
int
-loop_chars(p, n)
- unsigned char *p;
- int n;
+loop_chars(unsigned char *p, int n)
{
int c, rv;
* bring up the link.
*/
int
-loop_frame(frame, len)
- unsigned char *frame;
- int len;
+loop_frame(unsigned char *frame, int len)
{
struct packet *pkt;
* loopback, now that the real serial link is up.
*/
void
-demand_rexmit(proto)
- int proto;
+demand_rexmit(int proto)
{
struct packet *pkt, *prev, *nextpkt;
* that is, whether it is worth bringing up the link for.
*/
static int
-active_packet(p, len)
- unsigned char *p;
- int len;
+active_packet(unsigned char *p, int len)
{
int proto, i;
struct protent *protp;
--- /dev/null
+/* * eap-tls.c - EAP-TLS implementation for PPP
+ *
+ * Copyright (c) Beniamino Galvani 2005 All rights reserved.
+ * Jan Just Keijser 2006-2019 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. The name(s) of the authors of this software must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission.
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <openssl/conf.h>
+#include <openssl/engine.h>
+#include <openssl/hmac.h>
+#include <openssl/err.h>
+#include <openssl/ui.h>
+#include <openssl/x509v3.h>
+
+#include "pppd.h"
+#include "eap.h"
+#include "eap-tls.h"
+#include "fsm.h"
+#include "lcp.h"
+#include "pathnames.h"
+
+typedef struct pw_cb_data
+{
+ const void *password;
+ const char *prompt_info;
+} PW_CB_DATA;
+
+/* The openssl configuration file and engines can be loaded only once */
+static CONF *ssl_config = NULL;
+static ENGINE *cert_engine = NULL;
+static ENGINE *pkey_engine = NULL;
+
+/* TLSv1.3 do we have a session ticket ? */
+static int have_session_ticket = 0;
+
+int ssl_verify_callback(int, X509_STORE_CTX *);
+void ssl_msg_callback(int write_p, int version, int ct, const void *buf,
+ size_t len, SSL * ssl, void *arg);
+int ssl_new_session_cb(SSL *s, SSL_SESSION *sess);
+
+X509 *get_X509_from_file(char *filename);
+int ssl_cmp_certs(char *filename, X509 * a);
+
+#ifdef MPPE
+
+#define EAPTLS_MPPE_KEY_LEN 32
+
+/*
+ * OpenSSL 1.1+ introduced a generic TLS_method()
+ * For older releases we substitute the appropriate method
+ */
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+#define TLS_method SSLv23_method
+
+#define SSL3_RT_HEADER 0x100
+
+#ifndef SSL_CTX_set_max_proto_version
+/** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */
+static inline int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max)
+{
+ long sslopt = 0;
+
+ if (tls_ver_max < TLS1_VERSION)
+ {
+ sslopt |= SSL_OP_NO_TLSv1;
+ }
+#ifdef SSL_OP_NO_TLSv1_1
+ if (tls_ver_max < TLS1_1_VERSION)
+ {
+ sslopt |= SSL_OP_NO_TLSv1_1;
+ }
+#endif
+#ifdef SSL_OP_NO_TLSv1_2
+ if (tls_ver_max < TLS1_2_VERSION)
+ {
+ sslopt |= SSL_OP_NO_TLSv1_2;
+ }
+#endif
+ SSL_CTX_set_options(ctx, sslopt);
+
+ return 1;
+}
+#endif /* SSL_CTX_set_max_proto_version */
+
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
+
+/*
+ * Generate keys according to RFC 2716 and add to reply
+ */
+void eaptls_gen_mppe_keys(struct eaptls_session *ets, int client)
+{
+ unsigned char out[4*EAPTLS_MPPE_KEY_LEN];
+ const char *prf_label;
+ size_t prf_size;
+ unsigned char eap_tls13_context[] = { EAPT_TLS };
+ unsigned char *context = NULL;
+ size_t context_len = 0;
+ unsigned char *p;
+
+ dbglog("EAP-TLS generating MPPE keys");
+ if (ets->tls_v13)
+ {
+ prf_label = "EXPORTER_EAP_TLS_Key_Material";
+ context = eap_tls13_context;
+ context_len = 1;
+ }
+ else
+ {
+ prf_label = "client EAP encryption";
+ }
+
+ dbglog("EAP-TLS PRF label = %s", prf_label);
+ prf_size = strlen(prf_label);
+ if (SSL_export_keying_material(ets->ssl, out, sizeof(out), prf_label, prf_size,
+ context, context_len, 0) != 1)
+ {
+ warn( "EAP-TLS: Failed generating keying material" );
+ return;
+ }
+
+ /*
+ * We now have the master send and receive keys.
+ * From these, generate the session send and receive keys.
+ * (see RFC3079 / draft-ietf-pppext-mppe-keys-03.txt for details)
+ */
+ if (client)
+ {
+ p = out;
+ BCOPY( p, mppe_send_key, sizeof(mppe_send_key) );
+ p += EAPTLS_MPPE_KEY_LEN;
+ BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) );
+ }
+ else
+ {
+ p = out;
+ BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) );
+ p += EAPTLS_MPPE_KEY_LEN;
+ BCOPY( p, mppe_send_key, sizeof(mppe_send_key) );
+ }
+
+ mppe_keys_set = 1;
+}
+
+#endif /* MPPE */
+
+void log_ssl_errors( void )
+{
+ unsigned long ssl_err = ERR_get_error();
+
+ if (ssl_err != 0)
+ dbglog("EAP-TLS SSL error stack:");
+ while (ssl_err != 0) {
+ dbglog( ERR_error_string( ssl_err, NULL ) );
+ ssl_err = ERR_get_error();
+ }
+}
+
+
+int password_callback (char *buf, int size, int rwflag, void *u)
+{
+ if (buf)
+ {
+ strlcpy (buf, passwd, size);
+ return strlen (buf);
+ }
+ return 0;
+}
+
+
+CONF *eaptls_ssl_load_config( void )
+{
+ CONF *config;
+ int ret_code;
+ long error_line = 33;
+
+ config = NCONF_new( NULL );
+ dbglog( "Loading OpenSSL config file" );
+ ret_code = NCONF_load( config, _PATH_OPENSSLCONFFILE, &error_line );
+ if (ret_code == 0)
+ {
+ warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", _PATH_OPENSSLCONFFILE, error_line );
+ NCONF_free( config );
+ config = NULL;
+ ERR_clear_error();
+ }
+
+ dbglog( "Loading OpenSSL built-ins" );
+ ENGINE_load_builtin_engines();
+ OPENSSL_load_builtin_modules();
+
+ dbglog( "Loading OpenSSL configured modules" );
+ if (CONF_modules_load( config, NULL, 0 ) <= 0 )
+ {
+ warn( "EAP-TLS: Error loading OpenSSL modules" );
+ log_ssl_errors();
+ config = NULL;
+ }
+
+ return config;
+}
+
+ENGINE *eaptls_ssl_load_engine( char *engine_name )
+{
+ ENGINE *e = NULL;
+
+ dbglog( "Enabling OpenSSL auto engines" );
+ ENGINE_register_all_complete();
+
+ dbglog( "Loading OpenSSL '%s' engine support", engine_name );
+ e = ENGINE_by_id( engine_name );
+ if (!e)
+ {
+ dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name );
+ e = ENGINE_by_id( "dynamic" );
+ if (e)
+ {
+ if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0)
+ || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
+ {
+ warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name );
+ log_ssl_errors();
+ ENGINE_free(e);
+ e = NULL;
+ }
+ }
+ else
+ {
+ warn( "EAP-TLS: Cannot load dynamic engine support" );
+ }
+ }
+
+ if (e)
+ {
+ dbglog( "Initialising engine" );
+ if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
+ {
+ warn( "EAP-TLS: Cannot use that engine" );
+ log_ssl_errors();
+ ENGINE_free(e);
+ e = NULL;
+ }
+ }
+
+ return e;
+}
+
+
+
+/*
+ * Initialize the SSL stacks and tests if certificates, key and crl
+ * for client or server use can be loaded.
+ */
+SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
+ char *certfile, char *peer_certfile, char *privkeyfile)
+{
+ char *cert_engine_name = NULL;
+ char *cert_identifier = NULL;
+ char *pkey_engine_name = NULL;
+ char *pkey_identifier = NULL;
+ SSL_CTX *ctx;
+ SSL *ssl;
+ X509_STORE *certstore;
+ X509_LOOKUP *lookup;
+ X509 *tmp;
+ int ret;
+#if defined(TLS1_2_VERSION)
+ long tls_version = TLS1_2_VERSION;
+#elif defined(TLS1_1_VERSION)
+ long tls_version = TLS1_1_VERSION;
+#else
+ long tls_version = TLS1_VERSION;
+#endif
+
+ /*
+ * Without these can't continue
+ */
+ if (!(cacertfile[0] || capath[0]))
+ {
+ error("EAP-TLS: CA certificate file or path missing");
+ return NULL;
+ }
+
+ if (!certfile[0])
+ {
+ error("EAP-TLS: Certificate missing");
+ return NULL;
+ }
+
+ if (!privkeyfile[0])
+ {
+ error("EAP-TLS: Private key missing");
+ return NULL;
+ }
+
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ /* load the openssl config file only once and load it before triggering
+ the loading of a global openssl config file via SSL_CTX_new()
+ */
+ if (!ssl_config)
+ ssl_config = eaptls_ssl_load_config();
+
+ ctx = SSL_CTX_new(TLS_method());
+
+ if (!ctx) {
+ error("EAP-TLS: Cannot initialize SSL CTX context");
+ goto fail;
+ }
+
+ /* if the certificate filename is of the form engine:id. e.g.
+ pkcs11:12345
+ then we try to load and use this engine.
+ If the certificate filename starts with a / or . then we
+ ALWAYS assume it is a file and not an engine/pkcs11 identifier
+ */
+ if ( index( certfile, '/' ) == NULL && index( certfile, '.') == NULL )
+ {
+ cert_identifier = index( certfile, ':' );
+
+ if (cert_identifier)
+ {
+ cert_engine_name = certfile;
+ *cert_identifier = '\0';
+ cert_identifier++;
+
+ dbglog( "Found certificate engine '%s'", cert_engine_name );
+ dbglog( "Found certificate identifier '%s'", cert_identifier );
+ }
+ }
+
+ /* if the privatekey filename is of the form engine:id. e.g.
+ pkcs11:12345
+ then we try to load and use this engine.
+ If the privatekey filename starts with a / or . then we
+ ALWAYS assume it is a file and not an engine/pkcs11 identifier
+ */
+ if ( index( privkeyfile, '/' ) == NULL && index( privkeyfile, '.') == NULL )
+ {
+ pkey_identifier = index( privkeyfile, ':' );
+
+ if (pkey_identifier)
+ {
+ pkey_engine_name = privkeyfile;
+ *pkey_identifier = '\0';
+ pkey_identifier++;
+
+ dbglog( "Found privatekey engine '%s'", pkey_engine_name );
+ dbglog( "Found privatekey identifier '%s'", pkey_identifier );
+ }
+ }
+
+ if (cert_identifier && pkey_identifier)
+ {
+ if (strlen( cert_identifier ) == 0)
+ {
+ if (strlen( pkey_identifier ) == 0)
+ error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" );
+ else
+ {
+ dbglog( "Substituting privatekey identifier for certificate identifier" );
+ cert_identifier = pkey_identifier;
+ }
+ }
+ else
+ {
+ if (strlen( pkey_identifier ) == 0)
+ {
+ dbglog( "Substituting certificate identifier for privatekey identifier" );
+ pkey_identifier = cert_identifier;
+ }
+ }
+ }
+
+ if (ssl_config && cert_engine_name)
+ cert_engine = eaptls_ssl_load_engine( cert_engine_name );
+
+ if (ssl_config && pkey_engine_name)
+ {
+ /* don't load the same engine twice */
+ if ( cert_engine && strcmp( cert_engine_name, pkey_engine_name) == 0 )
+ pkey_engine = cert_engine;
+ else
+ pkey_engine = eaptls_ssl_load_engine( pkey_engine_name );
+ }
+
+ SSL_CTX_set_default_passwd_cb (ctx, password_callback);
+
+ if (strlen(cacertfile) == 0) cacertfile = NULL;
+ if (strlen(capath) == 0) capath = NULL;
+
+ if (!SSL_CTX_load_verify_locations(ctx, cacertfile, capath))
+ {
+ error("EAP-TLS: Cannot load verify locations");
+ if (cacertfile) dbglog("CA certificate file = [%s]", cacertfile);
+ if (capath) dbglog("CA certificate path = [%s]", capath);
+ goto fail;
+ }
+
+ if (init_server)
+ SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile));
+
+ if (cert_engine)
+ {
+ struct
+ {
+ const char *s_slot_cert_id;
+ X509 *cert;
+ } cert_info;
+
+ cert_info.s_slot_cert_id = cert_identifier;
+ cert_info.cert = NULL;
+
+ if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) )
+ {
+ error( "EAP-TLS: Error loading certificate with id '%s' from engine", cert_identifier );
+ goto fail;
+ }
+
+ if (cert_info.cert)
+ {
+ dbglog( "Got the certificate, adding it to SSL context" );
+ dbglog( "subject = %s", X509_NAME_oneline( X509_get_subject_name( cert_info.cert ), NULL, 0 ) );
+ if (SSL_CTX_use_certificate(ctx, cert_info.cert) <= 0)
+ {
+ error("EAP-TLS: Cannot use PKCS11 certificate %s", cert_identifier);
+ goto fail;
+ }
+ }
+ else
+ {
+ warn("EAP-TLS: Cannot load PKCS11 key %s", cert_identifier);
+ log_ssl_errors();
+ }
+ }
+ else
+ {
+ if (!SSL_CTX_use_certificate_chain_file(ctx, certfile))
+ {
+ error( "EAP-TLS: Cannot use public certificate %s", certfile );
+ goto fail;
+ }
+ }
+
+
+ /*
+ * Check the Before and After dates of the certificate
+ */
+ ssl = SSL_new(ctx);
+ tmp = SSL_get_certificate(ssl);
+
+ ret = X509_cmp_time(X509_get_notBefore(tmp), NULL);
+ if (ret == 0)
+ {
+ warn( "EAP-TLS: Failed to read certificate notBefore field.");
+ }
+ if (ret > 0)
+ {
+ warn( "EAP-TLS: Your certificate is not yet valid!");
+ }
+
+ ret = X509_cmp_time(X509_get_notAfter(tmp), NULL);
+ if (ret == 0)
+ {
+ warn( "EAP-TLS: Failed to read certificate notAfter field.");
+ }
+ if (ret < 0)
+ {
+ warn( "EAP-TLS: Your certificate has expired!");
+ }
+ SSL_free(ssl);
+
+ if (pkey_engine)
+ {
+ EVP_PKEY *pkey = NULL;
+ PW_CB_DATA cb_data;
+
+ cb_data.password = passwd;
+ cb_data.prompt_info = pkey_identifier;
+
+ if (passwd[0] != 0)
+ {
+ UI_METHOD* transfer_pin = UI_create_method("transfer_pin");
+
+ int writer (UI *ui, UI_STRING *uis)
+ {
+ PW_CB_DATA* cb_data = (PW_CB_DATA*)UI_get0_user_data(ui);
+ UI_set_result(ui, uis, cb_data->password);
+ return 1;
+ };
+ int stub (UI* ui) {return 1;};
+ int stub_reader (UI *ui, UI_STRING *uis) {return 1;};
+
+ UI_method_set_writer(transfer_pin, writer);
+ UI_method_set_opener(transfer_pin, stub);
+ UI_method_set_closer(transfer_pin, stub);
+ UI_method_set_flusher(transfer_pin, stub);
+ UI_method_set_reader(transfer_pin, stub_reader);
+
+ dbglog( "Using our private key '%s' in engine", pkey_identifier );
+ pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, transfer_pin, &cb_data);
+
+ if (transfer_pin) UI_destroy_method(transfer_pin);
+ }
+ else {
+ dbglog( "Loading private key '%s' from engine", pkey_identifier );
+ pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, NULL, NULL);
+ }
+ if (pkey)
+ {
+ dbglog( "Got the private key, adding it to SSL context" );
+ if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0)
+ {
+ error("EAP-TLS: Cannot use PKCS11 key %s", pkey_identifier);
+ goto fail;
+ }
+ }
+ else
+ {
+ warn("EAP-TLS: Cannot load PKCS11 key %s", pkey_identifier);
+ log_ssl_errors();
+ }
+ }
+ else
+ {
+ if (!SSL_CTX_use_PrivateKey_file(ctx, privkeyfile, SSL_FILETYPE_PEM))
+ {
+ error("EAP-TLS: Cannot use private key %s", privkeyfile);
+ goto fail;
+ }
+ }
+
+ if (SSL_CTX_check_private_key(ctx) != 1) {
+ error("EAP-TLS: Private key %s fails security check", privkeyfile);
+ goto fail;
+ }
+
+ /* Explicitly set the NO_TICKETS flag to support Win7/Win8 clients */
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3
+#ifdef SSL_OP_NO_TICKET
+ | SSL_OP_NO_TICKET
+#endif
+ );
+
+ /* OpenSSL 1.1.1+ does not include RC4 ciphers by default.
+ * This causes totally obsolete WinXP clients to fail. If you really
+ * need ppp+EAP-TLS+openssl 1.1.1+WinXP then enable RC4 cipers and
+ * make sure that you use an OpenSSL that supports them
+
+ SSL_CTX_set_cipher_list(ctx, "RC4");
+ */
+
+
+ /* Set up a SSL Session cache with a callback. This is needed for TLSv1.3+.
+ * During the initial handshake the server signals to the client early on
+ * that the handshake is finished, even before the client has sent its
+ * credentials to the server. The actual connection (and moment that the
+ * client sends its credentials) only starts after the arrival of the first
+ * session ticket. The 'ssl_new_session_cb' catches this ticket.
+ */
+ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE);
+ SSL_CTX_sess_set_new_cb(ctx, ssl_new_session_cb);
+
+ /* As EAP-TLS+TLSv1.3 is highly experimental we offer the user a chance to override */
+ if (max_tls_version)
+ {
+ if (strncmp(max_tls_version, "1.0", 3) == 0)
+ tls_version = TLS1_VERSION;
+ else if (strncmp(max_tls_version, "1.1", 3) == 0)
+ tls_version = TLS1_1_VERSION;
+ else if (strncmp(max_tls_version, "1.2", 3) == 0)
+#ifdef TLS1_2_VERSION
+ tls_version = TLS1_2_VERSION;
+#else
+ {
+ warn("TLSv1.2 not available. Defaulting to TLSv1.1");
+ tls_version = TLS_1_1_VERSION;
+ }
+#endif
+ else if (strncmp(max_tls_version, "1.3", 3) == 0)
+#ifdef TLS1_3_VERSION
+ tls_version = TLS1_3_VERSION;
+#else
+ warn("TLSv1.3 not available.");
+#endif
+ }
+
+ dbglog("EAP-TLS: Setting max protocol version to 0x%X", tls_version);
+ SSL_CTX_set_max_proto_version(ctx, tls_version);
+
+ SSL_CTX_set_verify_depth(ctx, 5);
+ SSL_CTX_set_verify(ctx,
+ SSL_VERIFY_PEER |
+ SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+ &ssl_verify_callback);
+
+ if (crl_dir) {
+ if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
+ error("EAP-TLS: Failed to get certificate store");
+ goto fail;
+ }
+
+ if (!(lookup =
+ X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) {
+ error("EAP-TLS: Store lookup for CRL failed");
+
+ goto fail;
+ }
+
+ X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM);
+ X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
+ }
+
+ if (crl_file) {
+ FILE *fp = NULL;
+ X509_CRL *crl = NULL;
+
+ fp = fopen(crl_file, "r");
+ if (!fp) {
+ error("EAP-TLS: Cannot open CRL file '%s'", crl_file);
+ goto fail;
+ }
+
+ crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL);
+ if (!crl) {
+ error("EAP-TLS: Cannot read CRL file '%s'", crl_file);
+ goto fail;
+ }
+
+ if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
+ error("EAP-TLS: Failed to get certificate store");
+ goto fail;
+ }
+ if (!X509_STORE_add_crl(certstore, crl)) {
+ error("EAP-TLS: Cannot add CRL to certificate store");
+ goto fail;
+ }
+ X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
+
+ }
+
+ /*
+ * If a peer certificate file was specified, it must be valid, else fail
+ */
+ if (peer_certfile[0]) {
+ if (!(tmp = get_X509_from_file(peer_certfile))) {
+ error("EAP-TLS: Error loading client certificate from file %s",
+ peer_certfile);
+ goto fail;
+ }
+ X509_free(tmp);
+ }
+
+ return ctx;
+
+fail:
+ log_ssl_errors();
+ SSL_CTX_free(ctx);
+ return NULL;
+}
+
+/*
+ * Determine the maximum packet size by looking at the LCP handshake
+ */
+
+int eaptls_get_mtu(int unit)
+{
+ int mtu, mru;
+
+ lcp_options *wo = &lcp_wantoptions[unit];
+ lcp_options *go = &lcp_gotoptions[unit];
+ lcp_options *ho = &lcp_hisoptions[unit];
+ lcp_options *ao = &lcp_allowoptions[unit];
+
+ mtu = ho->neg_mru? ho->mru: PPP_MRU;
+ mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
+ mtu = MIN(MIN(mtu, mru), ao->mru)- PPP_HDRLEN - 10;
+
+ dbglog("MTU = %d", mtu);
+ return mtu;
+}
+
+
+/*
+ * Init the ssl handshake (server mode)
+ */
+int eaptls_init_ssl_server(eap_state * esp)
+{
+ struct eaptls_session *ets;
+ char servcertfile[MAXWORDLEN];
+ char clicertfile[MAXWORDLEN];
+ char cacertfile[MAXWORDLEN];
+ char capath[MAXWORDLEN];
+ char pkfile[MAXWORDLEN];
+ /*
+ * Allocate new eaptls session
+ */
+ esp->es_server.ea_session = malloc(sizeof(struct eaptls_session));
+ if (!esp->es_server.ea_session)
+ fatal("Allocation error");
+ ets = esp->es_server.ea_session;
+
+ if (!esp->es_server.ea_peer) {
+ error("EAP-TLS: Error: client name not set (BUG)");
+ return 0;
+ }
+
+ strlcpy(ets->peer, esp->es_server.ea_peer, MAXWORDLEN-1);
+
+ dbglog( "getting eaptls secret" );
+ if (!get_eaptls_secret(esp->es_unit, esp->es_server.ea_peer,
+ esp->es_server.ea_name, clicertfile,
+ servcertfile, cacertfile, capath, pkfile, 1)) {
+ error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
+ esp->es_server.ea_peer, esp->es_server.ea_name );
+ return 0;
+ }
+
+ ets->mtu = eaptls_get_mtu(esp->es_unit);
+
+ ets->ctx = eaptls_init_ssl(1, cacertfile, capath, servcertfile, clicertfile, pkfile);
+ if (!ets->ctx)
+ goto fail;
+
+ if (!(ets->ssl = SSL_new(ets->ctx)))
+ goto fail;
+
+ /*
+ * Set auto-retry to avoid timeouts on BIO_read
+ */
+ SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY);
+
+ /*
+ * Initialize the BIOs we use to read/write to ssl engine
+ */
+ ets->into_ssl = BIO_new(BIO_s_mem());
+ ets->from_ssl = BIO_new(BIO_s_mem());
+ SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl);
+
+ SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
+ SSL_set_msg_callback_arg(ets->ssl, ets);
+
+ /*
+ * Attach the session struct to the connection, so we can later
+ * retrieve it when doing certificate verification
+ */
+ SSL_set_ex_data(ets->ssl, 0, ets);
+
+ SSL_set_accept_state(ets->ssl);
+
+ ets->tls_v13 = 0;
+
+ ets->data = NULL;
+ ets->datalen = 0;
+ ets->alert_sent = 0;
+ ets->alert_recv = 0;
+
+ /*
+ * If we specified the client certificate file, store it in ets->peercertfile,
+ * so we can check it later in ssl_verify_callback()
+ */
+ if (clicertfile[0])
+ strlcpy(&ets->peercertfile[0], clicertfile, MAXWORDLEN);
+ else
+ ets->peercertfile[0] = 0;
+
+ return 1;
+
+fail:
+ SSL_CTX_free(ets->ctx);
+ return 0;
+}
+
+/*
+ * Init the ssl handshake (client mode)
+ */
+int eaptls_init_ssl_client(eap_state * esp)
+{
+ struct eaptls_session *ets;
+ char servcertfile[MAXWORDLEN];
+ char clicertfile[MAXWORDLEN];
+ char cacertfile[MAXWORDLEN];
+ char capath[MAXWORDLEN];
+ char pkfile[MAXWORDLEN];
+
+ /*
+ * Allocate new eaptls session
+ */
+ esp->es_client.ea_session = malloc(sizeof(struct eaptls_session));
+ if (!esp->es_client.ea_session)
+ fatal("Allocation error");
+ ets = esp->es_client.ea_session;
+
+ /*
+ * If available, copy server name in ets; it will be used in cert
+ * verify
+ */
+ if (esp->es_client.ea_peer)
+ strlcpy(ets->peer, esp->es_client.ea_peer, MAXWORDLEN-1);
+ else
+ ets->peer[0] = 0;
+
+ ets->mtu = eaptls_get_mtu(esp->es_unit);
+
+ dbglog( "calling get_eaptls_secret" );
+ if (!get_eaptls_secret(esp->es_unit, esp->es_client.ea_name,
+ ets->peer, clicertfile,
+ servcertfile, cacertfile, capath, pkfile, 0)) {
+ error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
+ esp->es_client.ea_name, ets->peer );
+ return 0;
+ }
+
+ dbglog( "calling eaptls_init_ssl" );
+ ets->ctx = eaptls_init_ssl(0, cacertfile, capath, clicertfile, servcertfile, pkfile);
+ if (!ets->ctx)
+ goto fail;
+
+ ets->ssl = SSL_new(ets->ctx);
+
+ if (!ets->ssl)
+ goto fail;
+
+ /*
+ * Initialize the BIOs we use to read/write to ssl engine
+ */
+ dbglog( "Initializing SSL BIOs" );
+ ets->into_ssl = BIO_new(BIO_s_mem());
+ ets->from_ssl = BIO_new(BIO_s_mem());
+ SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl);
+
+ SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
+ SSL_set_msg_callback_arg(ets->ssl, ets);
+
+ /*
+ * Attach the session struct to the connection, so we can later
+ * retrieve it when doing certificate verification
+ */
+ SSL_set_ex_data(ets->ssl, 0, ets);
+
+ SSL_set_connect_state(ets->ssl);
+
+ ets->tls_v13 = 0;
+
+ ets->data = NULL;
+ ets->datalen = 0;
+ ets->alert_sent = 0;
+ ets->alert_recv = 0;
+
+ /*
+ * If we specified the server certificate file, store it in
+ * ets->peercertfile, so we can check it later in
+ * ssl_verify_callback()
+ */
+ if (servcertfile[0])
+ strlcpy(ets->peercertfile, servcertfile, MAXWORDLEN);
+ else
+ ets->peercertfile[0] = 0;
+
+ return 1;
+
+fail:
+ dbglog( "eaptls_init_ssl_client: fail" );
+ SSL_CTX_free(ets->ctx);
+ return 0;
+
+}
+
+void eaptls_free_session(struct eaptls_session *ets)
+{
+ if (ets->ssl)
+ SSL_free(ets->ssl);
+
+ if (ets->ctx)
+ SSL_CTX_free(ets->ctx);
+
+ free(ets);
+}
+
+
+int eaptls_is_init_finished(struct eaptls_session *ets)
+{
+ if (ets->ssl && SSL_is_init_finished(ets->ssl))
+ {
+ if (ets->tls_v13)
+ return have_session_ticket;
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Handle a received packet, reassembling fragmented messages and
+ * passing them to the ssl engine
+ */
+int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len)
+{
+ u_char flags;
+ u_int tlslen = 0;
+ u_char dummy[65536];
+
+ if (len < 1) {
+ warn("EAP-TLS: received no or invalid data");
+ return 1;
+ }
+
+ GETCHAR(flags, inp);
+ len--;
+
+ if (flags & EAP_TLS_FLAGS_LI && len > 4) {
+ /*
+ * LenghtIncluded flag set -> this is the first packet of a message
+ */
+
+ /*
+ * the first 4 octets are the length of the EAP-TLS message
+ */
+ GETLONG(tlslen, inp);
+ len -= 4;
+
+ if (!ets->data) {
+
+ if (tlslen > EAP_TLS_MAX_LEN) {
+ error("EAP-TLS: TLS message length > %d, truncated", EAP_TLS_MAX_LEN);
+ tlslen = EAP_TLS_MAX_LEN;
+ }
+
+ /*
+ * Allocate memory for the whole message
+ */
+ ets->data = malloc(tlslen);
+ if (!ets->data)
+ fatal("EAP-TLS: allocation error\n");
+
+ ets->datalen = 0;
+ ets->tlslen = tlslen;
+ }
+ else
+ warn("EAP-TLS: non-first LI packet? that's odd...");
+ }
+ else if (!ets->data) {
+ /*
+ * A non fragmented message without LI flag
+ */
+
+ ets->data = malloc(len);
+ if (!ets->data)
+ fatal("EAP-TLS: memory allocation error in eaptls_receive\n");
+
+ ets->datalen = 0;
+ ets->tlslen = len;
+ }
+
+ if (flags & EAP_TLS_FLAGS_MF)
+ ets->frag = 1;
+ else
+ ets->frag = 0;
+
+ if (len < 0) {
+ warn("EAP-TLS: received malformed data");
+ return 1;
+ }
+
+ if (len + ets->datalen > ets->tlslen) {
+ warn("EAP-TLS: received data > TLS message length");
+ return 1;
+ }
+
+ BCOPY(inp, ets->data + ets->datalen, len);
+ ets->datalen += len;
+
+ if (!ets->frag) {
+
+ /*
+ * If we have the whole message, pass it to ssl
+ */
+
+ if (ets->datalen != ets->tlslen) {
+ warn("EAP-TLS: received data != TLS message length");
+ return 1;
+ }
+
+ if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1)
+ log_ssl_errors();
+
+ SSL_read(ets->ssl, dummy, 65536);
+
+ free(ets->data);
+ ets->data = NULL;
+ ets->datalen = 0;
+ }
+
+ return 0;
+}
+
+/*
+ * Return an eap-tls packet in outp.
+ * A TLS message read from the ssl engine is buffered in ets->data.
+ * At each call we control if there is buffered data and send a
+ * packet of mtu bytes.
+ */
+int eaptls_send(struct eaptls_session *ets, u_char ** outp)
+{
+ bool first = 0;
+ int size;
+ u_char fromtls[65536];
+ int res;
+ u_char *start;
+
+ start = *outp;
+
+ if (!ets->data)
+ {
+ if(!ets->alert_sent)
+ {
+ res = SSL_read(ets->ssl, fromtls, 65536);
+ }
+
+ /*
+ * Read from ssl
+ */
+ if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1)
+ {
+ warn("EAP-TLS send: No data from BIO_read");
+ return 1;
+ }
+
+ ets->datalen = res;
+
+ ets->data = malloc(ets->datalen);
+ if (!ets->data)
+ fatal("EAP-TLS: memory allocation error in eaptls_send\n");
+
+ BCOPY(fromtls, ets->data, ets->datalen);
+
+ ets->offset = 0;
+ first = 1;
+ }
+
+ size = ets->datalen - ets->offset;
+
+ if (size > ets->mtu) {
+ size = ets->mtu;
+ ets->frag = 1;
+ } else
+ ets->frag = 0;
+
+ PUTCHAR(EAPT_TLS, *outp);
+
+ /*
+ * Set right flags and length if necessary
+ */
+ if (ets->frag && first) {
+ PUTCHAR(EAP_TLS_FLAGS_LI | EAP_TLS_FLAGS_MF, *outp);
+ PUTLONG(ets->datalen, *outp);
+ } else if (ets->frag) {
+ PUTCHAR(EAP_TLS_FLAGS_MF, *outp);
+ } else
+ PUTCHAR(0, *outp);
+
+ /*
+ * Copy the data in outp
+ */
+ BCOPY(ets->data + ets->offset, *outp, size);
+ INCPTR(size, *outp);
+
+ /*
+ * Copy the packet in retransmission buffer
+ */
+ BCOPY(start, &ets->rtx[0], *outp - start);
+ ets->rtx_len = *outp - start;
+
+ ets->offset += size;
+
+ if (ets->offset >= ets->datalen) {
+
+ /*
+ * The whole message has been sent
+ */
+
+ free(ets->data);
+ ets->data = NULL;
+ ets->datalen = 0;
+ ets->offset = 0;
+ }
+
+ return 0;
+}
+
+/*
+ * Get the sent packet from the retransmission buffer
+ */
+void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp)
+{
+ BCOPY(ets->rtx, *outp, ets->rtx_len);
+ INCPTR(ets->rtx_len, *outp);
+}
+
+/*
+ * Verify a certificate.
+ * Most of the work (signatures and issuer attributes checking)
+ * is done by ssl; we check the CN in the peer certificate
+ * against the peer name.
+ */
+int ssl_verify_callback(int ok, X509_STORE_CTX * ctx)
+{
+ char subject[256];
+ char cn_str[256];
+ X509 *peer_cert;
+ int err, depth;
+ SSL *ssl;
+ struct eaptls_session *ets;
+
+ peer_cert = X509_STORE_CTX_get_current_cert(ctx);
+ err = X509_STORE_CTX_get_error(ctx);
+ depth = X509_STORE_CTX_get_error_depth(ctx);
+
+ dbglog("certificate verify depth: %d", depth);
+
+ if (auth_required && !ok) {
+ X509_NAME_oneline(X509_get_subject_name(peer_cert),
+ subject, 256);
+
+ X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
+ NID_commonName, cn_str, 256);
+
+ dbglog("Certificate verification error:\n depth: %d CN: %s"
+ "\n err: %d (%s)\n", depth, cn_str, err,
+ X509_verify_cert_error_string(err));
+
+ return 0;
+ }
+
+ ssl = X509_STORE_CTX_get_ex_data(ctx,
+ SSL_get_ex_data_X509_STORE_CTX_idx());
+
+ ets = (struct eaptls_session *)SSL_get_ex_data(ssl, 0);
+
+ if (ets == NULL) {
+ error("Error: SSL_get_ex_data returned NULL");
+ return 0;
+ }
+
+ log_ssl_errors();
+
+ if (!depth)
+ {
+ /* This is the peer certificate */
+
+ X509_NAME_oneline(X509_get_subject_name(peer_cert),
+ subject, 256);
+
+ X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
+ NID_commonName, cn_str, 256);
+
+ /*
+ * If acting as client and the name of the server wasn't specified
+ * explicitely, we can't verify the server authenticity
+ */
+ if (!ets->peer[0]) {
+ warn("Peer name not specified: no check");
+ return ok;
+ }
+
+ /*
+ * Check the CN
+ */
+ if (strcmp(cn_str, ets->peer)) {
+ error
+ ("Certificate verification error: CN (%s) != peer_name (%s)",
+ cn_str, ets->peer);
+ return 0;
+ }
+
+ warn("Certificate CN: %s , peer name %s", cn_str, ets->peer);
+
+ /*
+ * If a peer certificate file was specified, here we check it
+ */
+ if (ets->peercertfile[0]) {
+ if (ssl_cmp_certs(&ets->peercertfile[0], peer_cert)
+ != 0) {
+ error
+ ("Peer certificate doesn't match stored certificate");
+ return 0;
+ }
+ }
+ }
+
+ return ok;
+}
+
+/*
+ * Compare a certificate with the one stored in a file
+ */
+int ssl_cmp_certs(char *filename, X509 * a)
+{
+ X509 *b;
+ int ret;
+
+ if (!(b = get_X509_from_file(filename)))
+ return 1;
+
+ ret = X509_cmp(a, b);
+ X509_free(b);
+
+ return ret;
+
+}
+
+X509 *get_X509_from_file(char *filename)
+{
+ FILE *fp;
+ X509 *ret;
+
+ if (!(fp = fopen(filename, "r")))
+ return NULL;
+
+ ret = PEM_read_X509(fp, NULL, NULL, NULL);
+
+ fclose(fp);
+
+ return ret;
+}
+
+/*
+ * Every sent & received message this callback function is invoked,
+ * so we know when alert messages have arrived or are sent and
+ * we can print debug information about TLS handshake.
+ */
+void
+ssl_msg_callback(int write_p, int version, int content_type,
+ const void *buf, size_t len, SSL * ssl, void *arg)
+{
+ char string[256];
+ struct eaptls_session *ets = (struct eaptls_session *)arg;
+ unsigned char code;
+ const unsigned char*msg = buf;
+ int hvers = msg[1] << 8 | msg[2];
+
+ if(write_p)
+ strcpy(string, " -> ");
+ else
+ strcpy(string, " <- ");
+
+ switch(content_type) {
+
+ case SSL3_RT_HEADER:
+ strcat(string, "SSL/TLS Header: ");
+ switch(hvers) {
+ case SSL3_VERSION:
+ strcat(string, "SSL 3.0");
+ break;
+ case TLS1_VERSION:
+ strcat(string, "TLS 1.0");
+ break;
+ case TLS1_1_VERSION:
+ strcat(string, "TLS 1.1");
+ break;
+ case TLS1_2_VERSION:
+ strcat(string, "TLS 1.2");
+ break;
+ default:
+ sprintf(string, "SSL/TLS Header: Unknown version (%d)", hvers);
+ }
+ break;
+
+ case SSL3_RT_ALERT:
+ strcat(string, "Alert: ");
+ code = msg[1];
+
+ if (write_p) {
+ ets->alert_sent = 1;
+ ets->alert_sent_desc = code;
+ } else {
+ ets->alert_recv = 1;
+ ets->alert_recv_desc = code;
+ }
+
+ strcat(string, SSL_alert_desc_string_long(code));
+ break;
+
+ case SSL3_RT_CHANGE_CIPHER_SPEC:
+ strcat(string, "ChangeCipherSpec");
+ break;
+
+#ifdef SSL3_RT_INNER_CONTENT_TYPE
+ case SSL3_RT_INNER_CONTENT_TYPE:
+ strcat(string, "InnerContentType (TLS1.3)");
+ break;
+#endif
+
+ case SSL3_RT_HANDSHAKE:
+
+ strcat(string, "Handshake: ");
+ code = msg[0];
+
+ switch(code) {
+ case SSL3_MT_HELLO_REQUEST:
+ strcat(string,"Hello Request");
+ break;
+ case SSL3_MT_CLIENT_HELLO:
+ strcat(string,"Client Hello");
+ break;
+ case SSL3_MT_SERVER_HELLO:
+ strcat(string,"Server Hello");
+ break;
+#ifdef SSL3_MT_NEWSESSION_TICKET
+ case SSL3_MT_NEWSESSION_TICKET:
+ strcat(string,"New Session Ticket");
+ break;
+#endif
+#ifdef SSL3_MT_END_OF_EARLY_DATA
+ case SSL3_MT_END_OF_EARLY_DATA:
+ strcat(string,"End of Early Data");
+ break;
+#endif
+#ifdef SSL3_MT_ENCRYPTED_EXTENSIONS
+ case SSL3_MT_ENCRYPTED_EXTENSIONS:
+ strcat(string,"Encryped Extensions");
+ break;
+#endif
+ case SSL3_MT_CERTIFICATE:
+ strcat(string,"Certificate");
+ break;
+ case SSL3_MT_SERVER_KEY_EXCHANGE:
+ strcat(string,"Server Key Exchange");
+ break;
+ case SSL3_MT_CERTIFICATE_REQUEST:
+ strcat(string,"Certificate Request");
+ break;
+ case SSL3_MT_SERVER_DONE:
+ strcat(string,"Server Hello Done");
+ break;
+ case SSL3_MT_CERTIFICATE_VERIFY:
+ strcat(string,"Certificate Verify");
+ break;
+ case SSL3_MT_CLIENT_KEY_EXCHANGE:
+ strcat(string,"Client Key Exchange");
+ break;
+ case SSL3_MT_FINISHED:
+ strcat(string,"Finished: ");
+ hvers = SSL_version(ssl);
+ switch(hvers){
+ case SSL3_VERSION:
+ strcat(string, "SSL 3.0");
+ break;
+ case TLS1_VERSION:
+ strcat(string, "TLS 1.0");
+ break;
+ case TLS1_1_VERSION:
+ strcat(string, "TLS 1.1");
+ break;
+ case TLS1_2_VERSION:
+ strcat(string, "TLS 1.2");
+ break;
+#ifdef TLS1_3_VERSION
+ case TLS1_3_VERSION:
+ strcat(string, "TLS 1.3 (experimental)");
+ ets->tls_v13 = 1;
+ break;
+#endif
+ default:
+ strcat(string, "Unknown version");
+ }
+ break;
+ default:
+ sprintf( string, "Handshake: Unknown SSL3 code received: %d", code );
+ }
+ break;
+
+ default:
+ sprintf( string, "SSL message contains unknown content type: %d", content_type );
+ }
+
+ /* Alert messages must always be displayed */
+ if(content_type == SSL3_RT_ALERT)
+ error("%s", string);
+ else
+ dbglog("%s", string);
+}
+
+int
+ssl_new_session_cb(SSL *s, SSL_SESSION *sess)
+{
+ dbglog("EAP-TLS: Post-Handshake New Session Ticket arrived:");
+ have_session_ticket = 1;
+
+ /* always return success */
+ return 1;
+}
+
--- /dev/null
+/*
+ * eap-tls.h
+ *
+ * Copyright (c) Beniamino Galvani 2005 All rights reserved.
+ * Jan Just Keijser 2006-2019 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. The name(s) of the authors of this software must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission.
+ *
+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef __EAP_TLS_H__
+#define __EAP_TLS_H__
+
+#include "eap.h"
+
+#include <openssl/ssl.h>
+#include <openssl/bio.h>
+
+#define EAP_TLS_FLAGS_LI 128 /* length included flag */
+#define EAP_TLS_FLAGS_MF 64 /* more fragments flag */
+#define EAP_TLS_FLAGS_START 32 /* start flag */
+
+#define EAP_TLS_MAX_LEN 65536 /* max eap tls packet size */
+
+struct eaptls_session
+{
+ u_char *data; /* buffered data */
+ int datalen; /* buffered data len */
+ int offset; /* from where to send */
+ int tlslen; /* total length of tls data */
+ bool frag; /* packet is fragmented */
+ bool tls_v13; /* whether we've negotiated TLSv1.3 */
+ SSL_CTX *ctx;
+ SSL *ssl; /* ssl connection */
+ BIO *from_ssl;
+ BIO *into_ssl;
+ char peer[MAXWORDLEN]; /* peer name */
+ char peercertfile[MAXWORDLEN];
+ bool alert_sent;
+ u_char alert_sent_desc;
+ bool alert_recv;
+ u_char alert_recv_desc;
+ char rtx[EAP_TLS_MAX_LEN]; /* retransmission buffer */
+ int rtx_len;
+ int mtu; /* unit mtu */
+};
+
+
+SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
+ char *certfile, char *peer_certfile, char *privkeyfile);
+int eaptls_init_ssl_server(eap_state * esp);
+int eaptls_init_ssl_client(eap_state * esp);
+void eaptls_free_session(struct eaptls_session *ets);
+
+int eaptls_is_init_finished(struct eaptls_session *ets);
+
+int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len);
+int eaptls_send(struct eaptls_session *ets, u_char ** outp);
+void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp);
+
+int get_eaptls_secret(int unit, char *client, char *server,
+ char *clicertfile, char *servcertfile, char *cacertfile,
+ char *capath, char *pkfile, int am_server);
+
+#ifdef MPPE
+#include "mppe.h" /* MPPE_MAX_KEY_LEN */
+extern u_char mppe_send_key[MPPE_MAX_KEY_LEN];
+extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN];
+extern int mppe_keys_set;
+
+void eaptls_gen_mppe_keys(struct eaptls_session *ets, int client);
+#endif
+
+#endif
* Based on draft-ietf-pppext-eap-srp-03.txt.
*/
-#define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $"
+/*
+ * Modification by Beniamino Galvani, Mar 2005
+ * Implemented EAP-TLS authentication
+ */
/*
* TODO:
#define SHA_DIGESTSIZE 20
#endif
-static const char rcsid[] = RCSID;
+#ifdef USE_EAPTLS
+#include "eap-tls.h"
+#endif /* USE_EAPTLS */
eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */
#ifdef USE_SRP
/*
* Protocol entry points.
*/
-static void eap_init __P((int unit));
-static void eap_input __P((int unit, u_char *inp, int inlen));
-static void eap_protrej __P((int unit));
-static void eap_lowerup __P((int unit));
-static void eap_lowerdown __P((int unit));
-static int eap_printpkt __P((u_char *inp, int inlen,
- void (*)(void *arg, char *fmt, ...), void *arg));
+static void eap_init (int unit);
+static void eap_input (int unit, u_char *inp, int inlen);
+static void eap_protrej (int unit);
+static void eap_lowerup (int unit);
+static void eap_lowerdown (int unit);
+static int eap_printpkt (u_char *inp, int inlen,
+ void (*)(void *arg, char *fmt, ...), void *arg);
struct protent eap_protent = {
PPP_EAP, /* protocol number */
NULL /* say whether to bring up link for this pkt */
};
+#ifdef USE_SRP
/*
* A well-known 2048 bit modulus.
*/
0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
};
+#endif /* USE_SRP */
/* Local forward declarations. */
-static void eap_server_timeout __P((void *arg));
+static void eap_server_timeout (void *arg);
/*
* Convert EAP state code to printable string for debug.
*/
static const char *
-eap_state_name(esc)
-enum eap_state_code esc;
+eap_state_name(enum eap_state_code esc)
{
static const char *state_names[] = { EAP_STATES };
* called once by main() during start-up.
*/
static void
-eap_init(unit)
-int unit;
+eap_init(int unit)
{
eap_state *esp = &eap_states[unit];
esp->es_server.ea_id = (u_char)(drand48() * 0x100);
esp->es_client.ea_timeout = EAP_DEFREQTIME;
esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
+#ifdef USE_EAPTLS
+ esp->es_client.ea_using_eaptls = 0;
+#endif /* USE_EAPTLS */
}
/*
* Request messages.
*/
static void
-eap_client_timeout(arg)
-void *arg;
+eap_client_timeout(void *arg)
{
eap_state *esp = (eap_state *) arg;
* after eap_lowerup.
*/
void
-eap_authwithpeer(unit, localname)
-int unit;
-char *localname;
+eap_authwithpeer(int unit, char *localname)
{
eap_state *esp = &eap_states[unit];
* (Server operation)
*/
static void
-eap_send_failure(esp)
-eap_state *esp;
+eap_send_failure(eap_state *esp)
{
u_char *outp;
* (Server operation)
*/
static void
-eap_send_success(esp)
-eap_state *esp;
+eap_send_success(eap_state *esp)
{
u_char *outp;
};
static int
-b64enc(bs, inp, inlen, outp)
-struct b64state *bs;
-u_char *inp;
-int inlen;
-u_char *outp;
+b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
{
int outlen = 0;
}
static int
-b64flush(bs, outp)
-struct b64state *bs;
-u_char *outp;
+b64flush(struct b64state *bs, u_char *outp)
{
int outlen = 0;
}
static int
-b64dec(bs, inp, inlen, outp)
-struct b64state *bs;
-u_char *inp;
-int inlen;
-u_char *outp;
+b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp)
{
int outlen = 0;
char *cp;
* 0 for success and non-zero for failure.
*/
static void
-eap_figure_next_state(esp, status)
-eap_state *esp;
-int status;
+eap_figure_next_state(eap_state *esp, int status)
{
#ifdef USE_SRP
unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp;
u_char vals[2];
struct b64state bs;
#endif /* USE_SRP */
+#ifdef USE_EAPTLS
+ struct eaptls_session *ets;
+ int secret_len;
+ char secret[MAXWORDLEN];
+#endif /* USE_EAPTLS */
esp->es_server.ea_timeout = esp->es_savedtime;
+#ifdef USE_EAPTLS
+ esp->es_server.ea_prev_state = esp->es_server.ea_state;
+#endif /* USE_EAPTLS */
switch (esp->es_server.ea_state) {
case eapBadAuth:
return;
break;
}
#endif /* USE_SRP */
+#ifdef USE_EAPTLS
+ if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
+ esp->es_server.ea_name, secret, &secret_len, 1)) {
+
+ esp->es_server.ea_state = eapTlsStart;
+ break;
+ }
+#endif /* USE_EAPTLS */
+
esp->es_server.ea_state = eapMD5Chall;
break;
+#ifdef USE_EAPTLS
+ case eapTlsStart:
+ /* Initialize ssl session */
+ if(!eaptls_init_ssl_server(esp)) {
+ esp->es_server.ea_state = eapBadAuth;
+ break;
+ }
+
+ esp->es_server.ea_state = eapTlsRecv;
+ break;
+
+ case eapTlsRecv:
+ ets = (struct eaptls_session *) esp->es_server.ea_session;
+
+ if(ets->alert_sent) {
+ esp->es_server.ea_state = eapTlsSendAlert;
+ break;
+ }
+
+ if (status) {
+ esp->es_server.ea_state = eapBadAuth;
+ break;
+ }
+ ets = (struct eaptls_session *) esp->es_server.ea_session;
+
+ if(ets->frag)
+ esp->es_server.ea_state = eapTlsSendAck;
+ else
+ esp->es_server.ea_state = eapTlsSend;
+ break;
+
+ case eapTlsSend:
+ ets = (struct eaptls_session *) esp->es_server.ea_session;
+
+ if(ets->frag)
+ esp->es_server.ea_state = eapTlsRecvAck;
+ else
+ if(SSL_is_init_finished(ets->ssl))
+ esp->es_server.ea_state = eapTlsRecvClient;
+ else
+ /* JJK Add "TLS empty record" message here ??? */
+ esp->es_server.ea_state = eapTlsRecv;
+ break;
+
+ case eapTlsSendAck:
+ esp->es_server.ea_state = eapTlsRecv;
+ break;
+
+ case eapTlsRecvAck:
+ if (status)
+ {
+ esp->es_server.ea_state = eapBadAuth;
+ break;
+ }
+
+ esp->es_server.ea_state = eapTlsSend;
+ break;
+
+ case eapTlsSendAlert:
+ esp->es_server.ea_state = eapTlsRecvAlertAck;
+ break;
+#endif /* USE_EAPTLS */
+
case eapSRP1:
#ifdef USE_SRP
ts = (struct t_server *)esp->es_server.ea_session;
}
if (esp->es_server.ea_state == eapBadAuth)
eap_send_failure(esp);
+
+#ifdef USE_EAPTLS
+ dbglog("EAP id=0x%2x '%s' -> '%s'", esp->es_server.ea_id, eap_state_name(esp->es_server.ea_prev_state), eap_state_name(esp->es_server.ea_state));
+#endif /* USE_EAPTLS */
}
/*
* type depends on current state. (Server operation)
*/
static void
-eap_send_request(esp)
-eap_state *esp;
+eap_send_request(eap_state *esp)
{
u_char *outp;
u_char *lenloc;
INCPTR(esp->es_server.ea_namelen, outp);
break;
+#ifdef USE_EAPTLS
+ case eapTlsStart:
+ PUTCHAR(EAPT_TLS, outp);
+ PUTCHAR(EAP_TLS_FLAGS_START, outp);
+ eap_figure_next_state(esp, 0);
+ break;
+
+ case eapTlsSend:
+ eaptls_send(esp->es_server.ea_session, &outp);
+ eap_figure_next_state(esp, 0);
+ break;
+
+ case eapTlsSendAck:
+ PUTCHAR(EAPT_TLS, outp);
+ PUTCHAR(0, outp);
+ eap_figure_next_state(esp, 0);
+ break;
+
+ case eapTlsSendAlert:
+ eaptls_send(esp->es_server.ea_session, &outp);
+ eap_figure_next_state(esp, 0);
+ break;
+#endif /* USE_EAPTLS */
+
#ifdef USE_SRP
case eapSRP1:
PUTCHAR(EAPT_SRP, outp);
* after eap_lowerup.
*/
void
-eap_authpeer(unit, localname)
-int unit;
-char *localname;
+eap_authpeer(int unit, char *localname)
{
eap_state *esp = &eap_states[unit];
* expired.
*/
static void
-eap_server_timeout(arg)
-void *arg;
+eap_server_timeout(void *arg)
{
+#ifdef USE_EAPTLS
+ u_char *outp;
+ u_char *lenloc;
+ int outlen;
+#endif /* USE_EAPTLS */
+
eap_state *esp = (eap_state *) arg;
if (!eap_server_active(esp))
return;
+#ifdef USE_EAPTLS
+ switch(esp->es_server.ea_prev_state) {
+
+ /*
+ * In eap-tls the state changes after a request, so we return to
+ * previous state ...
+ */
+ case(eapTlsStart):
+ case(eapTlsSendAck):
+ esp->es_server.ea_state = esp->es_server.ea_prev_state;
+ break;
+
+ /*
+ * ... or resend the stored data
+ */
+ case(eapTlsSend):
+ case(eapTlsSendAlert):
+ outp = outpacket_buf;
+ MAKEHEADER(outp, PPP_EAP);
+ PUTCHAR(EAP_REQUEST, outp);
+ PUTCHAR(esp->es_server.ea_id, outp);
+ lenloc = outp;
+ INCPTR(2, outp);
+
+ eaptls_retransmit(esp->es_server.ea_session, &outp);
+
+ outlen = (outp - outpacket_buf) - PPP_HDRLEN;
+ PUTSHORT(outlen, lenloc);
+ output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
+ esp->es_server.ea_requests++;
+
+ if (esp->es_server.ea_timeout > 0)
+ TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
+
+ return;
+ default:
+ break;
+ }
+#endif /* USE_EAPTLS */
+
/* EAP ID number must not change on timeout. */
eap_send_request(esp);
}
* will restart the timer. If it fails, then the link is dropped.
*/
static void
-eap_rechallenge(arg)
-void *arg;
+eap_rechallenge(void *arg)
{
eap_state *esp = (eap_state *)arg;
}
static void
-srp_lwrechallenge(arg)
-void *arg;
+srp_lwrechallenge(void *arg)
{
eap_state *esp = (eap_state *)arg;
* thing.
*/
static void
-eap_lowerup(unit)
-int unit;
+eap_lowerup(int unit)
{
eap_state *esp = &eap_states[unit];
* Cancel all timeouts and return to initial state.
*/
static void
-eap_lowerdown(unit)
-int unit;
+eap_lowerdown(int unit)
{
eap_state *esp = &eap_states[unit];
* failure.
*/
static void
-eap_protrej(unit)
-int unit;
+eap_protrej(int unit)
{
eap_state *esp = &eap_states[unit];
* Format and send a regular EAP Response message.
*/
static void
-eap_send_response(esp, id, typenum, str, lenstr)
-eap_state *esp;
-u_char id;
-u_char typenum;
-u_char *str;
-int lenstr;
+eap_send_response(eap_state *esp, u_char id, u_char typenum,
+ u_char *str, int lenstr)
{
u_char *outp;
int msglen;
* Format and send an MD5-Challenge EAP Response message.
*/
static void
-eap_chap_response(esp, id, hash, name, namelen)
-eap_state *esp;
-u_char id;
-u_char *hash;
-char *name;
-int namelen;
+eap_chap_response(eap_state *esp, u_char id, u_char *hash,
+ char *name, int namelen)
{
u_char *outp;
int msglen;
* Format and send a SRP EAP Response message.
*/
static void
-eap_srp_response(esp, id, subtypenum, str, lenstr)
-eap_state *esp;
-u_char id;
-u_char subtypenum;
-u_char *str;
-int lenstr;
+eap_srp_response(eap_state *esp, u_char id, u_char subtypenum,
+ u_char *str, int lenstr)
{
u_char *outp;
int msglen;
* Format and send a SRP EAP Client Validator Response message.
*/
static void
-eap_srpval_response(esp, id, flags, str)
-eap_state *esp;
-u_char id;
-u_int32_t flags;
-u_char *str;
+eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str)
{
u_char *outp;
int msglen;
}
#endif /* USE_SRP */
+#ifdef USE_EAPTLS
+/*
+ * Send an EAP-TLS response message with tls data
+ */
+static void
+eap_tls_response(eap_state *esp, u_char id)
+{
+ u_char *outp;
+ int outlen;
+ u_char *lenloc;
+
+ outp = outpacket_buf;
+
+ MAKEHEADER(outp, PPP_EAP);
+
+ PUTCHAR(EAP_RESPONSE, outp);
+ PUTCHAR(id, outp);
+
+ lenloc = outp;
+ INCPTR(2, outp);
+
+ /*
+ If the id in the request is unchanged, we must retransmit
+ the old data
+ */
+ if(id == esp->es_client.ea_id)
+ eaptls_retransmit(esp->es_client.ea_session, &outp);
+ else
+ eaptls_send(esp->es_client.ea_session, &outp);
+
+ outlen = (outp - outpacket_buf) - PPP_HDRLEN;
+ PUTSHORT(outlen, lenloc);
+
+ output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
+
+ esp->es_client.ea_id = id;
+}
+
+/*
+ * Send an EAP-TLS ack
+ */
static void
-eap_send_nak(esp, id, type)
-eap_state *esp;
-u_char id;
-u_char type;
+eap_tls_sendack(eap_state *esp, u_char id)
+{
+ u_char *outp;
+ int outlen;
+ u_char *lenloc;
+
+ outp = outpacket_buf;
+
+ MAKEHEADER(outp, PPP_EAP);
+
+ PUTCHAR(EAP_RESPONSE, outp);
+ PUTCHAR(id, outp);
+ esp->es_client.ea_id = id;
+
+ lenloc = outp;
+ INCPTR(2, outp);
+
+ PUTCHAR(EAPT_TLS, outp);
+ PUTCHAR(0, outp);
+
+ outlen = (outp - outpacket_buf) - PPP_HDRLEN;
+ PUTSHORT(outlen, lenloc);
+
+ output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
+}
+#endif /* USE_EAPTLS */
+
+static void
+eap_send_nak(eap_state *esp, u_char id, u_char type)
{
u_char *outp;
int msglen;
#ifdef USE_SRP
static char *
-name_of_pn_file()
+name_of_pn_file(void)
{
char *user, *path, *file;
struct passwd *pw;
}
static int
-open_pn_file(modebits)
-mode_t modebits;
+open_pn_file(mode_t modebits)
{
char *path;
int fd, err;
}
static void
-remove_pn_file()
+remove_pn_file(void)
{
char *path;
}
static void
-write_pseudonym(esp, inp, len, id)
-eap_state *esp;
-u_char *inp;
-int len, id;
+write_pseudonym(eap_state *esp, u_char *inp, int len, int id)
{
u_char val;
u_char *datp, *digp;
* eap_request - Receive EAP Request message (client mode).
*/
static void
-eap_request(esp, inp, id, len)
-eap_state *esp;
-u_char *inp;
-int id;
-int len;
+eap_request(eap_state *esp, u_char *inp, int id, int len)
{
u_char typenum;
u_char vallen;
char rhostname[256];
MD5_CTX mdContext;
u_char hash[MD5_SIGNATURE_SIZE];
+#ifdef USE_EAPTLS
+ u_char flags;
+ struct eaptls_session *ets = esp->es_client.ea_session;
+#endif /* USE_EAPTLS */
+
#ifdef USE_SRP
struct t_client *tc;
struct t_num sval, gval, Nval, *Ap, Bval;
int fd;
#endif /* USE_SRP */
+ /*
+ * Ignore requests if we're not open
+ */
+ if (esp->es_client.ea_state <= eapClosed)
+ return;
+
/*
* Note: we update es_client.ea_id *only if* a Response
* message is being generated. Otherwise, we leave it the
esp->es_usedpseudo = 2;
}
#endif /* USE_SRP */
- eap_send_response(esp, id, typenum, esp->es_client.ea_name,
+ eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name,
esp->es_client.ea_namelen);
break;
}
/* Not so likely to happen. */
- if (vallen >= len + sizeof (rhostname)) {
+ if (len - vallen >= sizeof (rhostname)) {
dbglog("EAP: trimming really long peer name down");
BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
rhostname[sizeof (rhostname) - 1] = '\0';
esp->es_client.ea_namelen);
break;
+#ifdef USE_EAPTLS
+ case EAPT_TLS:
+
+ switch(esp->es_client.ea_state) {
+
+ case eapListen:
+
+ if (len < 1) {
+ error("EAP: received EAP-TLS Listen packet with no data");
+ /* Bogus request; wait for something real. */
+ return;
+ }
+ GETCHAR(flags, inp);
+ if(flags & EAP_TLS_FLAGS_START){
+
+ esp->es_client.ea_using_eaptls = 1;
+
+ if (explicit_remote){
+ esp->es_client.ea_peer = strdup(remote_name);
+ esp->es_client.ea_peerlen = strlen(remote_name);
+ } else
+ esp->es_client.ea_peer = NULL;
+
+ /* Init ssl session */
+ if(!eaptls_init_ssl_client(esp)) {
+ dbglog("cannot init ssl");
+ eap_send_nak(esp, id, EAPT_TLS);
+ esp->es_client.ea_using_eaptls = 0;
+ break;
+ }
+
+ ets = esp->es_client.ea_session;
+ eap_tls_response(esp, id);
+ esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
+ break;
+ }
+
+ /* The server has sent a bad start packet. */
+ eap_send_nak(esp, id, EAPT_TLS);
+ break;
+
+ case eapTlsRecvAck:
+ eap_tls_response(esp, id);
+ esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
+ break;
+
+ case eapTlsRecv:
+ if (len < 1) {
+ error("EAP: discarding EAP-TLS Receive packet with no data");
+ /* Bogus request; wait for something real. */
+ return;
+ }
+ eaptls_receive(ets, inp, len);
+
+ if(ets->frag) {
+ eap_tls_sendack(esp, id);
+ esp->es_client.ea_state = eapTlsRecv;
+ break;
+ }
+
+ if(ets->alert_recv) {
+ eap_tls_sendack(esp, id);
+ esp->es_client.ea_state = eapTlsRecvFailure;
+ break;
+ }
+
+ /* Check if TLS handshake is finished */
+ if(eaptls_is_init_finished(ets)) {
+#ifdef MPPE
+ eaptls_gen_mppe_keys(ets, 1);
+#endif
+ eaptls_free_session(ets);
+ eap_tls_sendack(esp, id);
+ esp->es_client.ea_state = eapTlsRecvSuccess;
+ break;
+ }
+
+ eap_tls_response(esp,id);
+ esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv);
+ break;
+
+ default:
+ eap_send_nak(esp, id, EAPT_TLS);
+ esp->es_client.ea_using_eaptls = 0;
+ break;
+ }
+
+ break;
+#endif /* USE_EAPTLS */
+
#ifdef USE_SRP
case EAPT_SRP:
if (len < 1) {
* eap_response - Receive EAP Response message (server mode).
*/
static void
-eap_response(esp, inp, id, len)
-eap_state *esp;
-u_char *inp;
-int id;
-int len;
+eap_response(eap_state *esp, u_char *inp, int id, int len)
{
u_char typenum;
u_char vallen;
struct t_num A;
SHA1_CTX ctxt;
u_char dig[SHA_DIGESTSIZE];
+ SHA1_CTX ctxt;
+ u_char dig[SHA_DIGESTSIZE];
#endif /* USE_SRP */
+#ifdef USE_EAPTLS
+ struct eaptls_session *ets;
+ u_char flags;
+#endif /* USE_EAPTLS */
+
+ /*
+ * Ignore responses if we're not open
+ */
+ if (esp->es_server.ea_state <= eapClosed)
+ return;
+
if (esp->es_server.ea_id != id) {
dbglog("EAP: discarding Response %d; expected ID %d", id,
esp->es_server.ea_id);
eap_figure_next_state(esp, 0);
break;
+#ifdef USE_EAPTLS
+ case EAPT_TLS:
+ switch(esp->es_server.ea_state) {
+
+ case eapTlsRecv:
+
+ ets = (struct eaptls_session *) esp->es_server.ea_session;
+
+ eap_figure_next_state(esp,
+ eaptls_receive(esp->es_server.ea_session, inp, len));
+
+ if(ets->alert_recv) {
+ eap_send_failure(esp);
+ break;
+ }
+ break;
+
+ case eapTlsRecvAck:
+ if(len > 1) {
+ dbglog("EAP-TLS ACK with extra data");
+ }
+ eap_figure_next_state(esp, 0);
+ break;
+
+ case eapTlsRecvClient:
+ /* Receive authentication response from client */
+ if (len > 0) {
+ GETCHAR(flags, inp);
+
+ if(len == 1 && !flags) { /* Ack = ok */
+#ifdef MPPE
+ eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 );
+#endif
+ eap_send_success(esp);
+ }
+ else { /* failure */
+ warn("Server authentication failed");
+ eap_send_failure(esp);
+ }
+ }
+ else
+ warn("Bogus EAP-TLS packet received from client");
+
+ eaptls_free_session(esp->es_server.ea_session);
+
+ break;
+
+ case eapTlsRecvAlertAck:
+ eap_send_failure(esp);
+ break;
+
+ default:
+ eap_figure_next_state(esp, 1);
+ break;
+ }
+ break;
+#endif /* USE_EAPTLS */
+
case EAPT_NOTIFICATION:
dbglog("EAP unexpected Notification; response discarded");
break;
esp->es_server.ea_state = eapMD5Chall;
break;
+#ifdef USE_EAPTLS
+ /* Send EAP-TLS start packet */
+ case EAPT_TLS:
+ esp->es_server.ea_state = eapTlsStart;
+ break;
+#endif /* USE_EAPTLS */
+
default:
dbglog("EAP: peer requesting unknown Type %d", vallen);
switch (esp->es_server.ea_state) {
}
/* Not so likely to happen. */
- if (vallen >= len + sizeof (rhostname)) {
+ if (len - vallen >= sizeof (rhostname)) {
dbglog("EAP: trimming really long peer name down");
BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
rhostname[sizeof (rhostname) - 1] = '\0';
* eap_success - Receive EAP Success message (client mode).
*/
static void
-eap_success(esp, inp, id, len)
-eap_state *esp;
-u_char *inp;
-int id;
-int len;
+eap_success(eap_state *esp, u_char *inp, int id, int len)
{
- if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) {
+ if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
+#ifdef USE_EAPTLS
+ && esp->es_client.ea_state != eapTlsRecvSuccess
+#endif /* USE_EAPTLS */
+ ) {
dbglog("EAP unexpected success message in state %s (%d)",
eap_state_name(esp->es_client.ea_state),
esp->es_client.ea_state);
return;
}
+#ifdef USE_EAPTLS
+ if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
+ eapTlsRecvSuccess) {
+ dbglog("EAP-TLS unexpected success message in state %s (%d)",
+ eap_state_name(esp->es_client.ea_state),
+ esp->es_client.ea_state);
+ return;
+ }
+#endif /* USE_EAPTLS */
+
if (esp->es_client.ea_timeout > 0) {
UNTIMEOUT(eap_client_timeout, (void *)esp);
}
* eap_failure - Receive EAP Failure message (client mode).
*/
static void
-eap_failure(esp, inp, id, len)
-eap_state *esp;
-u_char *inp;
-int id;
-int len;
+eap_failure(eap_state *esp, u_char *inp, int id, int len)
{
+ /*
+ * Ignore failure messages if we're not open
+ */
+ if (esp->es_client.ea_state <= eapClosed)
+ return;
+
if (!eap_client_active(esp)) {
dbglog("EAP unexpected failure message in state %s (%d)",
eap_state_name(esp->es_client.ea_state),
* eap_input - Handle received EAP message.
*/
static void
-eap_input(unit, inp, inlen)
-int unit;
-u_char *inp;
-int inlen;
+eap_input(int unit, u_char *inp, int inlen)
{
eap_state *esp = &eap_states[unit];
u_char code, id;
};
static int
-eap_printpkt(inp, inlen, printer, arg)
-u_char *inp;
-int inlen;
-void (*printer) __P((void *, char *, ...));
-void *arg;
+eap_printpkt(u_char *inp, int inlen,
+ void (*printer) (void *, char *, ...), void *arg)
{
int code, id, len, rtype, vallen;
u_char *pstart;
u_int32_t uval;
+#ifdef USE_EAPTLS
+ u_char flags;
+#endif /* USE_EAPTLS */
if (inlen < EAP_HEADERLEN)
return (0);
}
break;
+#ifdef USE_EAPTLS
+ case EAPT_TLS:
+ if (len < 1)
+ break;
+ GETCHAR(flags, inp);
+ len--;
+
+ if(flags == 0 && len == 0){
+ printer(arg, " Ack");
+ break;
+ }
+
+ printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
+ printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
+ printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
+ break;
+#endif /* USE_EAPTLS */
+
case EAPT_SRP:
if (len < 3)
goto truncated;
}
break;
+#ifdef USE_EAPTLS
+ case EAPT_TLS:
+ if (len < 1)
+ break;
+ GETCHAR(flags, inp);
+ len--;
+
+ if(flags == 0 && len == 0){
+ printer(arg, " Ack");
+ break;
+ }
+
+ printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
+ printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
+ printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
+
+ break;
+#endif /* USE_EAPTLS */
+
case EAPT_NAK:
if (len <= 0) {
printer(arg, " <missing hint>");
eapClosed, /* Authentication not in use */
eapListen, /* Client ready (and timer running) */
eapIdentify, /* EAP Identify sent */
+ eapTlsStart, /* Send EAP-TLS start packet */
+ eapTlsRecv, /* Receive EAP-TLS tls data */
+ eapTlsSendAck, /* Send EAP-TLS ack */
+ eapTlsSend, /* Send EAP-TLS tls data */
+ eapTlsRecvAck, /* Receive EAP-TLS ack */
+ eapTlsRecvClient, /* Receive EAP-TLS auth response from client*/
+ eapTlsSendAlert, /* Send EAP-TLS tls alert (server)*/
+ eapTlsRecvAlertAck, /* Receive EAP-TLS ack after sending alert */
+ eapTlsRecvSuccess, /* Receive EAP success */
+ eapTlsRecvFailure, /* Receive EAP failure */
eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */
eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */
eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */
#define EAP_STATES \
"Initial", "Pending", "Closed", "Listen", "Identify", \
+ "TlsStart", "TlsRecv", "TlsSendAck", "TlsSend", "TlsRecvAck", "TlsRecvClient",\
+ "TlsSendAlert", "TlsRecvAlertAck" , "TlsRecvSuccess", "TlsRecvFailure", \
"SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth"
-#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen)
+#ifdef USE_EAPTLS
+#define eap_client_active(esp) ((esp)->es_client.ea_state != eapInitial &&\
+ (esp)->es_client.ea_state != eapPending &&\
+ (esp)->es_client.ea_state != eapClosed)
+#else
+#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen)
+#endif /* USE_EAPTLS */
+
#define eap_server_active(esp) \
((esp)->es_server.ea_state >= eapIdentify && \
(esp)->es_server.ea_state <= eapMD5Chall)
u_short ea_namelen; /* Length of our name */
u_short ea_peerlen; /* Length of peer's name */
enum eap_state_code ea_state;
+#ifdef USE_EAPTLS
+ enum eap_state_code ea_prev_state;
+#endif
u_char ea_id; /* Current id */
u_char ea_requests; /* Number of Requests sent/received */
u_char ea_responses; /* Number of Responses */
u_char ea_type; /* One of EAPT_* */
u_int32_t ea_keyflags; /* SRP shared key usage flags */
+#ifdef USE_EAPTLS
+ bool ea_using_eaptls;
+#endif
};
/*
* Timeouts.
*/
#define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */
+#ifdef USE_EAPTLS
+#define EAP_DEFTRANSMITS 30 /* max # times to transmit */
+ /* certificates can be long ... */
+#else
#define EAP_DEFTRANSMITS 10 /* max # times to transmit */
+#endif /* USE_EAPTLS */
#define EAP_DEFREQTIME 20 /* Time to wait for peer request */
#define EAP_DEFALLOWREQ 20 /* max # times to accept requests */
extern eap_state eap_states[];
-void eap_authwithpeer __P((int unit, char *localname));
-void eap_authpeer __P((int unit, char *localname));
+void eap_authwithpeer (int unit, char *localname);
+void eap_authpeer (int unit, char *localname);
extern struct protent eap_protent;
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: ecp.c,v 1.4 2004/11/04 10:02:26 paulus Exp $"
-
-static const char rcsid[] = RCSID;
-
#include <string.h>
#include "pppd.h"
/*
* Protocol entry points from main code.
*/
-static void ecp_init __P((int unit));
+static void ecp_init (int unit);
/*
-static void ecp_open __P((int unit));
-static void ecp_close __P((int unit, char *));
-static void ecp_lowerup __P((int unit));
-static void ecp_lowerdown __P((int));
-static void ecp_input __P((int unit, u_char *pkt, int len));
-static void ecp_protrej __P((int unit));
+static void ecp_open (int unit);
+static void ecp_close (int unit, char *);
+static void ecp_lowerup (int unit);
+static void ecp_lowerdown (int);
+static void ecp_input (int unit, u_char *pkt, int len);
+static void ecp_protrej (int unit);
*/
-static int ecp_printpkt __P((u_char *pkt, int len,
- void (*printer) __P((void *, char *, ...)),
- void *arg));
+static int ecp_printpkt (u_char *pkt, int len,
+ void (*printer)(void *, char *, ...),
+ void *arg);
/*
-static void ecp_datainput __P((int unit, u_char *pkt, int len));
+static void ecp_datainput (int unit, u_char *pkt, int len);
*/
struct protent ecp_protent = {
* ecp_init - initialize ECP.
*/
static void
-ecp_init(unit)
- int unit;
+ecp_init(int unit)
{
fsm *f = &ecp_fsm[unit];
static int
-ecp_printpkt(p, plen, printer, arg)
- u_char *p;
- int plen;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+ecp_printpkt(u_char *p, int plen,
+ void (*printer)(void *, char *, ...), void *arg)
{
return 0;
}
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: eui64.c,v 1.6 2002/12/04 23:03:32 paulus Exp $
*/
-#define RCSID "$Id: eui64.c,v 1.6 2002/12/04 23:03:32 paulus Exp $"
-
#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;
+eui64_ntoa(eui64_t e)
{
static char buf[32];
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * $Id: eui64.h,v 1.6 2002/12/04 23:03:32 paulus Exp $
-*/
+ */
#ifndef __EUI64_H__
#define __EUI64_H__
} while (0)
#define eui64_setlo32(e, l) eui64_set32(e, l)
-char *eui64_ntoa __P((eui64_t)); /* Returns ascii representation of id */
+char *eui64_ntoa(eui64_t); /* Returns ascii representation of id */
#endif /* __EUI64_H__ */
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: fsm.c,v 1.23 2004/11/13 02:28:15 paulus Exp $"
-
/*
* TODO:
* Randomize fsm id on link/init.
#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));
+static void fsm_timeout (void *);
+static void fsm_rconfreq (fsm *, int, u_char *, int);
+static void fsm_rconfack (fsm *, int, u_char *, int);
+static void fsm_rconfnakrej (fsm *, int, int, u_char *, int);
+static void fsm_rtermreq (fsm *, int, u_char *, int);
+static void fsm_rtermack (fsm *);
+static void fsm_rcoderej (fsm *, u_char *, int);
+static void fsm_sconfreq (fsm *, int);
#define PROTO_NAME(f) ((f)->callbacks->proto_name)
* Initialize fsm state.
*/
void
-fsm_init(f)
- fsm *f;
+fsm_init(fsm *f)
{
f->state = INITIAL;
f->flags = 0;
* fsm_lowerup - The lower layer is up.
*/
void
-fsm_lowerup(f)
- fsm *f;
+fsm_lowerup(fsm *f)
{
switch( f->state ){
case INITIAL:
* Cancel all timeouts and inform upper layers.
*/
void
-fsm_lowerdown(f)
- fsm *f;
+fsm_lowerdown(fsm *f)
{
switch( f->state ){
case CLOSED:
* fsm_open - Link is allowed to come up.
*/
void
-fsm_open(f)
- fsm *f;
+fsm_open(fsm *f)
{
switch( f->state ){
case INITIAL:
* send a terminate-request message as configured.
*/
static void
-terminate_layer(f, nextstate)
- fsm *f;
- int nextstate;
+terminate_layer(fsm *f, int nextstate)
{
if( f->state != OPENED )
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
* the CLOSED state.
*/
void
-fsm_close(f, reason)
- fsm *f;
- char *reason;
+fsm_close(fsm *f, char *reason)
{
f->term_reason = reason;
f->term_reason_len = (reason == NULL? 0: strlen(reason));
* fsm_timeout - Timeout expired.
*/
static void
-fsm_timeout(arg)
- void *arg;
+fsm_timeout(void *arg)
{
fsm *f = (fsm *) arg;
* fsm_input - Input packet.
*/
void
-fsm_input(f, inpacket, l)
- fsm *f;
- u_char *inpacket;
- int l;
+fsm_input(fsm *f, u_char *inpacket, int l)
{
u_char *inp;
u_char code, id;
* fsm_rconfreq - Receive Configure-Request.
*/
static void
-fsm_rconfreq(f, id, inp, len)
- fsm *f;
- u_char id;
- u_char *inp;
- int len;
+fsm_rconfreq(fsm *f, int id, u_char *inp, int len)
{
int code, reject_if_disagree;
* fsm_rconfack - Receive Configure-Ack.
*/
static void
-fsm_rconfack(f, id, inp, len)
- fsm *f;
- int id;
- u_char *inp;
- int len;
+fsm_rconfack(fsm *f, int id, u_char *inp, int len)
{
if (id != f->reqid || f->seen_ack) /* Expected id? */
return; /* Nope, toss... */
* 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;
+fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len)
{
int ret;
int treat_as_reject;
* fsm_rtermreq - Receive Terminate-Req.
*/
static void
-fsm_rtermreq(f, id, p, len)
- fsm *f;
- int id;
- u_char *p;
- int len;
+fsm_rtermreq(fsm *f, int id, u_char *p, int len)
{
switch (f->state) {
case ACKRCVD:
* fsm_rtermack - Receive Terminate-Ack.
*/
static void
-fsm_rtermack(f)
- fsm *f;
+fsm_rtermack(fsm *f)
{
switch (f->state) {
case CLOSING:
* fsm_rcoderej - Receive an Code-Reject.
*/
static void
-fsm_rcoderej(f, inp, len)
- fsm *f;
- u_char *inp;
- int len;
+fsm_rcoderej(fsm *f, u_char *inp, int len)
{
u_char code, id;
* Treat this as a catastrophic error (RXJ-).
*/
void
-fsm_protreject(f)
- fsm *f;
+fsm_protreject(fsm *f)
{
switch( f->state ){
case CLOSING:
* fsm_sconfreq - Send a Configure-Request.
*/
static void
-fsm_sconfreq(f, retransmit)
- fsm *f;
- int retransmit;
+fsm_sconfreq(fsm *f, int retransmit)
{
u_char *outp;
int cilen;
* 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;
+fsm_sdata(fsm *f, int code, int id, u_char *data, int datalen)
{
u_char *outp;
int outlen;
typedef struct fsm_callbacks {
- void (*resetci) /* Reset our Configuration Information */
- __P((fsm *));
- int (*cilen) /* Length of our Configuration Information */
- __P((fsm *));
+ void (*resetci)(fsm *); /* Reset our Configuration Information */
+ int (*cilen)(fsm *); /* Length of our Configuration Information */
void (*addci) /* Add our Configuration Information */
- __P((fsm *, u_char *, int *));
+ (fsm *, u_char *, int *);
int (*ackci) /* ACK our Configuration Information */
- __P((fsm *, u_char *, int));
+ (fsm *, u_char *, int);
int (*nakci) /* NAK our Configuration Information */
- __P((fsm *, u_char *, int, int));
+ (fsm *, u_char *, int, int);
int (*rejci) /* Reject our Configuration Information */
- __P((fsm *, u_char *, int));
+ (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 *));
+ (fsm *, u_char *, int *, int);
+ void (*up)(fsm *); /* Called when fsm reaches OPENED state */
+ void (*down)(fsm *); /* Called when fsm leaves OPENED state */
+ void (*starting)(fsm *); /* Called when we want the lower layer */
+ void (*finished)(fsm *); /* Called when we don't want the lower layer */
+ void (*protreject)(int); /* Called when Protocol-Reject received */
+ void (*retransmit)(fsm *); /* Retransmission is necessary */
int (*extcode) /* Called when unknown code received */
- __P((fsm *, int, int, u_char *, int));
+ (fsm *, int, int, u_char *, int);
char *proto_name; /* String name for protocol (for messages) */
} fsm_callbacks;
/*
* 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));
+void fsm_init (fsm *);
+void fsm_lowerup (fsm *);
+void fsm_lowerdown (fsm *);
+void fsm_open (fsm *);
+void fsm_close (fsm *, char *);
+void fsm_input (fsm *, u_char *, int);
+void fsm_protreject (fsm *);
+void fsm_sdata (fsm *, int, int, u_char *, int);
/*
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: ipcp.c,v 1.73 2008/05/26 08:33:22 paulus Exp $"
-
/*
* TODO:
*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <net/if.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 */
bool noremoteip = 0; /* Let him have no IP address */
/* Hook for a plugin to know when IP protocol has come up */
-void (*ip_up_hook) __P((void)) = NULL;
+void (*ip_up_hook)(void) = NULL;
/* Hook for a plugin to know when IP protocol has come down */
-void (*ip_down_hook) __P((void)) = NULL;
+void (*ip_down_hook)(void) = NULL;
/* Hook for a plugin to choose the remote IP address */
-void (*ip_choose_hook) __P((u_int32_t *)) = NULL;
+void (*ip_choose_hook)(u_int32_t *) = NULL;
/* Notifiers for when IPCP goes up and down */
struct notifier *ip_up_notifier = NULL;
/*
* 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, 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 */
+static void ipcp_resetci (fsm *); /* Reset our CI */
+static int ipcp_cilen (fsm *); /* Return length of our CI */
+static void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */
+static int ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */
+static int ipcp_nakci (fsm *, u_char *, int, int);/* Peer nak'd our CI */
+static int ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */
+static int ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */
+static void ipcp_up (fsm *); /* We're UP */
+static void ipcp_down (fsm *); /* We're DOWN */
+static void ipcp_finished (fsm *); /* Don't need lower layer */
fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */
/*
* Command-line options.
*/
-static int setvjslots __P((char **));
-static int setdnsaddr __P((char **));
-static int setwinsaddr __P((char **));
-static int setnetmask __P((char **));
-int setipaddr __P((char *, char **, int));
-static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *));
+static int setvjslots (char **);
+static int setdnsaddr (char **);
+static int setwinsaddr (char **);
+static int setnetmask (char **);
+int setipaddr (char *, char **, int);
+static void printipaddr (option_t *, void (*)(void *, char *,...),void *);
static option_t ipcp_option_list[] = {
{ "noip", o_bool, &ipcp_protent.enabled_flag,
{ "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" },
+ { "ms-dns", o_special, (void *)setdnsaddr,
+ "DNS address for the peer's use", OPT_A2LIST },
+ { "ms-wins", o_special, (void *)setwinsaddr,
+ "Nameserver for SMB over TCP/IP for peer", OPT_A2LIST },
{ "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime,
"Set timeout for IPCP", OPT_PRIO },
/*
* 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));
+static void ipcp_init (int);
+static void ipcp_open (int);
+static void ipcp_close (int, char *);
+static void ipcp_lowerup (int);
+static void ipcp_lowerdown (int);
+static void ipcp_input (int, u_char *, int);
+static void ipcp_protrej (int);
+static int ipcp_printpkt (u_char *, int,
+ void (*) (void *, char *, ...), void *);
+static void ip_check_options (void);
+static int ip_demand_conf (int);
+static int ip_active_pkt (u_char *, int);
+static void create_resolv (u_int32_t, u_int32_t);
struct protent ipcp_protent = {
PPP_IPCP,
ip_active_pkt
};
-static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
-static void ipcp_script __P((char *, int)); /* Run an up/down script */
-static void ipcp_script_done __P((void *));
+static void ipcp_clear_addrs (int, u_int32_t, u_int32_t);
+static void ipcp_script (char *, int); /* Run an up/down script */
+static void ipcp_script_done (void *);
/*
* Lengths of configuration options.
* Make a string representation of a network IP address.
*/
char *
-ip_ntoa(ipaddr)
-u_int32_t ipaddr;
+ip_ntoa(u_int32_t ipaddr)
{
static char b[64];
* setvjslots - set maximum number of connection slots for VJ compression
*/
static int
-setvjslots(argv)
- char **argv;
+setvjslots(char **argv)
{
int value;
* setdnsaddr - set the dns address(es)
*/
static int
-setdnsaddr(argv)
- char **argv;
+setdnsaddr(char **argv)
{
u_int32_t dns;
struct hostent *hp;
* the caller to the existing WINS server on a Windows NT platform.
*/
static int
-setwinsaddr(argv)
- char **argv;
+setwinsaddr(char **argv)
{
u_int32_t wins;
struct hostent *hp;
* Not static so that plugins can call it to set the addresses
*/
int
-setipaddr(arg, argv, doit)
- char *arg;
- char **argv;
- int doit;
+setipaddr(char *arg, char **argv, int doit)
{
struct hostent *hp;
char *colon;
}
static void
-printipaddr(opt, printer, arg)
- option_t *opt;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+printipaddr(option_t *opt, void (*printer) (void *, char *, ...), void *arg)
{
ipcp_options *wo = &ipcp_wantoptions[0];
* setnetmask - set the netmask to be used on the interface.
*/
static int
-setnetmask(argv)
- char **argv;
+setnetmask(char **argv)
{
u_int32_t mask;
int n;
}
int
-parse_dotted_ip(p, vp)
- char *p;
- u_int32_t *vp;
+parse_dotted_ip(char *p, u_int32_t *vp)
{
int n;
u_int32_t v, b;
* ipcp_init - Initialize IPCP.
*/
static void
-ipcp_init(unit)
- int unit;
+ipcp_init(int unit)
{
fsm *f = &ipcp_fsm[unit];
ipcp_options *wo = &ipcp_wantoptions[unit];
* ipcp_open - IPCP is allowed to come up.
*/
static void
-ipcp_open(unit)
- int unit;
+ipcp_open(int unit)
{
fsm_open(&ipcp_fsm[unit]);
ipcp_is_open = 1;
* ipcp_close - Take IPCP down.
*/
static void
-ipcp_close(unit, reason)
- int unit;
- char *reason;
+ipcp_close(int unit, char *reason)
{
fsm_close(&ipcp_fsm[unit], reason);
}
* ipcp_lowerup - The lower layer is up.
*/
static void
-ipcp_lowerup(unit)
- int unit;
+ipcp_lowerup(int unit)
{
fsm_lowerup(&ipcp_fsm[unit]);
}
* ipcp_lowerdown - The lower layer is down.
*/
static void
-ipcp_lowerdown(unit)
- int unit;
+ipcp_lowerdown(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;
+ipcp_input(int unit, u_char *p, int len)
{
fsm_input(&ipcp_fsm[unit], p, len);
}
* Pretend the lower layer went down, so we shut up.
*/
static void
-ipcp_protrej(unit)
- int unit;
+ipcp_protrej(int unit)
{
fsm_lowerdown(&ipcp_fsm[unit]);
}
* Called by fsm_sconfreq, Send Configure Request.
*/
static void
-ipcp_resetci(f)
- fsm *f;
+ipcp_resetci(fsm *f)
{
ipcp_options *wo = &ipcp_wantoptions[f->unit];
ipcp_options *go = &ipcp_gotoptions[f->unit];
* Called by fsm_sconfreq, Send Configure Request.
*/
static int
-ipcp_cilen(f)
- fsm *f;
+ipcp_cilen(fsm *f)
{
ipcp_options *go = &ipcp_gotoptions[f->unit];
ipcp_options *wo = &ipcp_wantoptions[f->unit];
* Called by fsm_sconfreq, Send Configure Request.
*/
static void
-ipcp_addci(f, ucp, lenp)
- fsm *f;
- u_char *ucp;
- int *lenp;
+ipcp_addci(fsm *f, u_char *ucp, int *lenp)
{
ipcp_options *go = &ipcp_gotoptions[f->unit];
int len = *lenp;
* 1 - Ack was good.
*/
static int
-ipcp_ackci(f, p, len)
- fsm *f;
- u_char *p;
- int len;
+ipcp_ackci(fsm *f, u_char *p, int len)
{
ipcp_options *go = &ipcp_gotoptions[f->unit];
u_short cilen, citype, cishort;
* 1 - Nak was good.
*/
static int
-ipcp_nakci(f, p, len, treat_as_reject)
- fsm *f;
- u_char *p;
- int len;
- int treat_as_reject;
+ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
{
ipcp_options *go = &ipcp_gotoptions[f->unit];
u_char cimaxslotindex, cicflag;
* Callback from fsm_rconfnakrej.
*/
static int
-ipcp_rejci(f, p, len)
- fsm *f;
- u_char *p;
- int len;
+ipcp_rejci(fsm *f, u_char *p, int len)
{
ipcp_options *go = &ipcp_gotoptions[f->unit];
u_char cimaxslotindex, ciflag, cilen;
* 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_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
{
ipcp_options *wo = &ipcp_wantoptions[f->unit];
ipcp_options *ho = &ipcp_hisoptions[f->unit];
* and assign appropriate defaults.
*/
static void
-ip_check_options()
+ip_check_options(void)
{
struct hostent *hp;
u_int32_t local;
* IPCP were up, for use with dial-on-demand.
*/
static int
-ip_demand_conf(u)
- int u;
+ip_demand_conf(int u)
{
ipcp_options *wo = &ipcp_wantoptions[u];
* Configure the IP network interface appropriately and bring it up.
*/
static void
-ipcp_up(f)
- fsm *f;
+ipcp_up(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];
+ int ifindex;
IPCPDEBUG(("ipcp: up"));
}
#endif
+ ifindex = if_nametoindex(ifname);
+
/* run the pre-up script, if any, and wait for it to finish */
ipcp_script(_PATH_IPPREUP, 1);
+ /* check if preup script renamed the interface */
+ if (!if_indextoname(ifindex, ifname)) {
+ error("Interface index %d failed to get renamed by a pre-up script", ifindex);
+ ipcp_close(f->unit, "Interface configuration failed");
+ return;
+ }
+
/* bring the interface up for IP */
if (!sifup(f->unit)) {
if (debug)
* and delete routes through it.
*/
static void
-ipcp_down(f)
- fsm *f;
+ipcp_down(fsm *f)
{
IPCPDEBUG(("ipcp: down"));
/* XXX a bit IPv4-centric here, we only need to get the stats
* 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 */
+ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr)
{
if (proxy_arp_set[unit]) {
cifproxyarp(unit, hisaddr);
* ipcp_finished - possibly shut down the lower layers.
*/
static void
-ipcp_finished(f)
- fsm *f;
+ipcp_finished(fsm *f)
{
if (ipcp_is_open) {
ipcp_is_open = 0;
* has finished.
*/
static void
-ipcp_script_done(arg)
- void *arg;
+ipcp_script_done(void *arg)
{
ipcp_script_pid = 0;
switch (ipcp_script_state) {
* interface-name tty-name speed local-IP remote-IP.
*/
static void
-ipcp_script(script, wait)
- char *script;
- int wait;
+ipcp_script(char *script, int wait)
{
char strspeed[32], strlocal[32], strremote[32];
char *argv[8];
* create_resolv - create the replacement resolv.conf file
*/
static void
-create_resolv(peerdns1, peerdns2)
- u_int32_t peerdns1, peerdns2;
+create_resolv(u_int32_t peerdns1, u_int32_t peerdns2)
{
FILE *f;
};
static int
-ipcp_printpkt(p, plen, printer, arg)
- u_char *p;
- int plen;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+ipcp_printpkt(u_char *p, int plen,
+ void (*printer) (void *, char *, ...), void *arg)
{
int code, id, len, olen;
u_char *pstart, *optend;
#define get_tcpflags(x) (((unsigned char *)(x))[13])
static int
-ip_active_pkt(pkt, len)
- u_char *pkt;
- int len;
+ip_active_pkt(u_char *pkt, int len)
{
u_char *tcp;
int hlen;
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $Id: ipcp.h,v 1.14 2002/12/04 23:03:32 paulus Exp $
*/
/*
extern ipcp_options ipcp_allowoptions[];
extern ipcp_options ipcp_hisoptions[];
-char *ip_ntoa __P((u_int32_t));
+char *ip_ntoa(u_int32_t);
extern struct protent ipcp_protent;
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $Id: ipv6cp.c,v 1.21 2005/08/25 23:59:34 paulus Exp $
*/
-#define RCSID "$Id: ipv6cp.c,v 1.21 2005/08/25 23:59:34 paulus Exp $"
-
/*
* TODO:
*
#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 */
int no_ifaceid_neg = 0;
/* local vars */
+static int default_route_set[NUM_PPP]; /* Have set up a default route */
static int ipv6cp_is_up;
/* Hook for a plugin to know when IPv6 protocol has come up */
-void (*ipv6_up_hook) __P((void)) = NULL;
+void (*ipv6_up_hook)(void) = NULL;
/* Hook for a plugin to know when IPv6 protocol has come down */
-void (*ipv6_down_hook) __P((void)) = NULL;
+void (*ipv6_down_hook)(void) = NULL;
/* Notifiers for when IPCPv6 goes up and down */
struct notifier *ipv6_up_notifier = NULL;
/*
* 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, 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 */
+static void ipv6cp_resetci (fsm *); /* Reset our CI */
+static int ipv6cp_cilen (fsm *); /* Return length of our CI */
+static void ipv6cp_addci (fsm *, u_char *, int *); /* Add our CI */
+static int ipv6cp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */
+static int ipv6cp_nakci (fsm *, u_char *, int, int);/* Peer nak'd our CI */
+static int ipv6cp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */
+static int ipv6cp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */
+static void ipv6cp_up (fsm *); /* We're UP */
+static void ipv6cp_down (fsm *); /* We're DOWN */
+static void ipv6cp_finished (fsm *); /* Don't need lower layer */
fsm ipv6cp_fsm[NUM_PPP]; /* IPV6CP fsm structure */
/*
* Command-line options.
*/
-static int setifaceid __P((char **arg));
-static void printifaceid __P((option_t *,
- void (*)(void *, char *, ...), void *));
+static int setifaceid (char **arg);
+static void printifaceid (option_t *,
+ void (*)(void *, char *, ...), void *);
static option_t ipv6cp_option_list[] = {
{ "ipv6", o_special, (void *)setifaceid,
{ "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local,
"Accept peer's interface identifier for us", 1 },
+ { "ipv6cp-accept-remote", o_bool, &ipv6cp_allowoptions[0].accept_remote,
+ "Accept peer's interface identifier for itself", 1 },
+
+ { "defaultroute6", o_bool, &ipv6cp_wantoptions[0].default_route,
+ "Add default IPv6 route", OPT_ENABLE|1, &ipv6cp_allowoptions[0].default_route },
+ { "nodefaultroute6", o_bool, &ipv6cp_allowoptions[0].default_route,
+ "disable defaultroute6 option", OPT_A2CLR,
+ &ipv6cp_wantoptions[0].default_route },
+ { "-defaultroute6", o_bool, &ipv6cp_allowoptions[0].default_route,
+ "disable defaultroute6 option", OPT_ALIAS | OPT_A2CLR,
+ &ipv6cp_wantoptions[0].default_route },
{ "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip,
"Use (default) IPv4 address as interface identifier", 1 },
/*
* 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));
+static void ipv6cp_init (int);
+static void ipv6cp_open (int);
+static void ipv6cp_close (int, char *);
+static void ipv6cp_lowerup (int);
+static void ipv6cp_lowerdown (int);
+static void ipv6cp_input (int, u_char *, int);
+static void ipv6cp_protrej (int);
+static int ipv6cp_printpkt (u_char *, int,
+ void (*) (void *, char *, ...), void *);
+static void ipv6_check_options (void);
+static int ipv6_demand_conf (int);
+static int ipv6_active_pkt (u_char *, int);
struct protent ipv6cp_protent = {
PPP_IPV6CP,
ipv6cp_close,
ipv6cp_printpkt,
NULL,
- 0,
+ 1,
"IPV6CP",
"IPV6",
ipv6cp_option_list,
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 *));
+static void ipv6cp_clear_addrs (int, eui64_t, eui64_t);
+static void ipv6cp_script (char *);
+static void ipv6cp_script_done (void *);
/*
* Lengths of configuration options.
* setifaceid - set the interface identifiers manually
*/
static int
-setifaceid(argv)
- char **argv;
+setifaceid(char **argv)
{
char *comma, *arg, c;
ipv6cp_options *wo = &ipv6cp_wantoptions[0];
char *llv6_ntoa(eui64_t ifaceid);
static void
-printifaceid(opt, printer, arg)
- option_t *opt;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+printifaceid(option_t *opt, void (*printer) (void *, char *, ...), void *arg)
{
ipv6cp_options *wo = &ipv6cp_wantoptions[0];
* Make a string representation of a network address.
*/
char *
-llv6_ntoa(ifaceid)
- eui64_t ifaceid;
+llv6_ntoa(eui64_t ifaceid)
{
static char b[64];
* ipv6cp_init - Initialize IPV6CP.
*/
static void
-ipv6cp_init(unit)
- int unit;
+ipv6cp_init(int unit)
{
fsm *f = &ipv6cp_fsm[unit];
ipv6cp_options *wo = &ipv6cp_wantoptions[unit];
memset(wo, 0, sizeof(*wo));
memset(ao, 0, sizeof(*ao));
- wo->accept_local = 1;
+ wo->accept_local = 0;
+ wo->accept_remote = 0;
wo->neg_ifaceid = 1;
ao->neg_ifaceid = 1;
wo->vj_protocol = IPV6CP_COMP;
#endif
+ /*
+ * XXX This controls whether the user may use the defaultroute option.
+ */
+ ao->default_route = 1;
}
* ipv6cp_open - IPV6CP is allowed to come up.
*/
static void
-ipv6cp_open(unit)
- int unit;
+ipv6cp_open(int unit)
{
fsm_open(&ipv6cp_fsm[unit]);
}
* ipv6cp_close - Take IPV6CP down.
*/
static void
-ipv6cp_close(unit, reason)
- int unit;
- char *reason;
+ipv6cp_close(int unit, char *reason)
{
fsm_close(&ipv6cp_fsm[unit], reason);
}
* ipv6cp_lowerup - The lower layer is up.
*/
static void
-ipv6cp_lowerup(unit)
- int unit;
+ipv6cp_lowerup(int unit)
{
fsm_lowerup(&ipv6cp_fsm[unit]);
}
* ipv6cp_lowerdown - The lower layer is down.
*/
static void
-ipv6cp_lowerdown(unit)
- int unit;
+ipv6cp_lowerdown(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;
+ipv6cp_input(int unit, u_char *p, int len)
{
fsm_input(&ipv6cp_fsm[unit], p, len);
}
* Pretend the lower layer went down, so we shut up.
*/
static void
-ipv6cp_protrej(unit)
- int unit;
+ipv6cp_protrej(int unit)
{
fsm_lowerdown(&ipv6cp_fsm[unit]);
}
* ipv6cp_resetci - Reset our CI.
*/
static void
-ipv6cp_resetci(f)
- fsm *f;
+ipv6cp_resetci(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) {
+ wo->accept_local = 1;
eui64_magic_nz(wo->ourid);
}
+ if (!wo->opt_remote)
+ wo->accept_remote = 1;
*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_cilen(fsm *f)
{
ipv6cp_options *go = &ipv6cp_gotoptions[f->unit];
* ipv6cp_addci - Add our desired CIs to a packet.
*/
static void
-ipv6cp_addci(f, ucp, lenp)
- fsm *f;
- u_char *ucp;
- int *lenp;
+ipv6cp_addci(fsm *f, u_char *ucp, int *lenp)
{
ipv6cp_options *go = &ipv6cp_gotoptions[f->unit];
int len = *lenp;
* 1 - Ack was good.
*/
static int
-ipv6cp_ackci(f, p, len)
- fsm *f;
- u_char *p;
- int len;
+ipv6cp_ackci(fsm *f, u_char *p, int len)
{
ipv6cp_options *go = &ipv6cp_gotoptions[f->unit];
u_short cilen, citype, cishort;
* 1 - Nak was good.
*/
static int
-ipv6cp_nakci(f, p, len, treat_as_reject)
- fsm *f;
- u_char *p;
- int len;
- int treat_as_reject;
+ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
{
ipv6cp_options *go = &ipv6cp_gotoptions[f->unit];
u_char citype, cilen, *next;
* ipv6cp_rejci - Reject some of our CIs.
*/
static int
-ipv6cp_rejci(f, p, len)
- fsm *f;
- u_char *p;
- int len;
+ipv6cp_rejci(fsm *f, u_char *p, int len)
{
ipv6cp_options *go = &ipv6cp_gotoptions[f->unit];
u_char cilen;
* 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_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
{
ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit];
ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit];
orc = CONFREJ; /* Reject CI */
break;
}
- if (!eui64_iszero(wo->hisid) &&
+ if (!eui64_iszero(wo->hisid) && !wo->accept_remote &&
!eui64_equals(ifaceid, wo->hisid) &&
eui64_iszero(go->hisid)) {
* and assign appropriate defaults.
*/
static void
-ipv6_check_options()
+ipv6_check_options(void)
{
ipv6cp_options *wo = &ipv6cp_wantoptions[0];
* IPV6CP were up, for use with dial-on-demand.
*/
static int
-ipv6_demand_conf(u)
- int u;
+ipv6_demand_conf(int u)
{
ipv6cp_options *wo = &ipv6cp_wantoptions[u];
#endif
if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE))
return 0;
+ if (wo->default_route)
+ if (sif6defaultroute(u, wo->ourid, wo->hisid))
+ default_route_set[u] = 1;
notice("ipv6_demand_conf");
notice("local LL address %s", llv6_ntoa(wo->ourid));
* Configure the IPv6 network interface appropriately and bring it up.
*/
static void
-ipv6cp_up(f)
- fsm *f;
+ipv6cp_up(fsm *f)
{
ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit];
ipv6cp_options *go = &ipv6cp_gotoptions[f->unit];
return;
}
+ /* assign a default route through the interface if required */
+ if (ipv6cp_wantoptions[f->unit].default_route)
+ if (sif6defaultroute(f->unit, go->ourid, ho->hisid))
+ default_route_set[f->unit] = 1;
}
demand_rexmit(PPP_IPV6);
sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS);
}
sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS);
+ /* assign a default route through the interface if required */
+ if (ipv6cp_wantoptions[f->unit].default_route)
+ if (sif6defaultroute(f->unit, go->ourid, ho->hisid))
+ default_route_set[f->unit] = 1;
+
notice("local LL address %s", llv6_ntoa(go->ourid));
notice("remote LL address %s", llv6_ntoa(ho->hisid));
}
* and delete routes through it.
*/
static void
-ipv6cp_down(f)
- fsm *f;
+ipv6cp_down(fsm *f)
{
IPV6CPDEBUG(("ipv6cp: down"));
update_link_stats(f->unit);
* proxy neighbour discovery entries, etc.
*/
static void
-ipv6cp_clear_addrs(unit, ourid, hisid)
- int unit;
- eui64_t ourid;
- eui64_t hisid;
+ipv6cp_clear_addrs(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;
+ipv6cp_finished(fsm *f)
{
np_finished(f->unit, PPP_IPV6);
}
* has finished.
*/
static void
-ipv6cp_script_done(arg)
- void *arg;
+ipv6cp_script_done(void *arg)
{
ipv6cp_script_pid = 0;
switch (ipv6cp_script_state) {
* interface-name tty-name speed local-LL remote-LL.
*/
static void
-ipv6cp_script(script)
- char *script;
+ipv6cp_script(char *script)
{
char strspeed[32], strlocal[32], strremote[32];
char *argv[8];
};
static int
-ipv6cp_printpkt(p, plen, printer, arg)
- u_char *p;
- int plen;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+ipv6cp_printpkt(u_char *p, int plen,
+ void (*printer) (void *, char *, ...), void *arg)
{
int code, id, len, olen;
u_char *pstart, *optend;
#define get_tcpflags(x) (((unsigned char *)(x))[13])
static int
-ipv6_active_pkt(pkt, len)
- u_char *pkt;
- int len;
+ipv6_active_pkt(u_char *pkt, int len)
{
u_char *tcp;
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $Id: ipv6cp.h,v 1.7 2002/12/04 23:03:32 paulus Exp $
*/
/*
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 default_route; /* Assign default route through interface? */
+ int accept_local; /* accept peer's value for our iface id? */
+ int accept_remote; /* accept peer's value for his iface id? */
int opt_local; /* ourtoken set by option */
int opt_remote; /* histoken set by option */
int use_ip; /* use IP as interface identifier */
#ifdef IPX_CHANGE
-#define RCSID "$Id: ipxcp.c,v 1.24 2005/08/25 23:59:34 paulus Exp $"
-
/*
* TODO:
*/
#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 */
/*
* 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, 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 */
+static void ipxcp_resetci (fsm *); /* Reset our CI */
+static int ipxcp_cilen (fsm *); /* Return length of our CI */
+static void ipxcp_addci (fsm *, u_char *, int *); /* Add our CI */
+static int ipxcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */
+static int ipxcp_nakci (fsm *, u_char *, int, int);/* Peer nak'd our CI */
+static int ipxcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */
+static int ipxcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */
+static void ipxcp_up (fsm *); /* We're UP */
+static void ipxcp_down (fsm *); /* We're DOWN */
+static void ipxcp_finished (fsm *); /* Don't need lower layer */
+static void ipxcp_script (fsm *, char *); /* Run an up/down script */
fsm ipxcp_fsm[NUM_PPP]; /* IPXCP fsm structure */
/*
* Command-line options.
*/
-static int setipxnode __P((char **));
-static void printipxnode __P((option_t *,
- void (*)(void *, char *, ...), void *));
-static int setipxname __P((char **));
+static int setipxnode (char **);
+static void printipxnode (option_t *,
+ void (*)(void *, char *, ...), void *);
+static int setipxname (char **);
static option_t ipxcp_option_list[] = {
{ "ipx", o_bool, &ipxcp_protent.enabled_flag,
* 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 *));
+static void ipxcp_init (int);
+static void ipxcp_open (int);
+static void ipxcp_close (int, char *);
+static void ipxcp_lowerup (int);
+static void ipxcp_lowerdown (int);
+static void ipxcp_input (int, u_char *, int);
+static void ipxcp_protrej (int);
+static int ipxcp_printpkt (u_char *, int,
+ void (*) (void *, char *, ...), void *);
struct protent ipxcp_protent = {
PPP_IPXCP,
static int ipxcp_is_up;
-static char *ipx_ntoa __P((u_int32_t));
+static char *ipx_ntoa (u_int32_t);
/* Used in printing the node number */
#define NODE(base) base[0], base[1], base[2], base[3], base[4], base[5]
*/
static short int
-to_external(internal)
-short int internal;
+to_external(short int internal)
{
short int external;
*/
static char *
-ipx_ntoa(ipxaddr)
-u_int32_t ipxaddr;
+ipx_ntoa(u_int32_t ipxaddr)
{
static char b[64];
slprintf(b, sizeof(b), "%x", ipxaddr);
static u_char *
-setipxnodevalue(src,dst)
-u_char *src, *dst;
+setipxnodevalue(u_char *src, u_char *dst)
{
int indx;
int item;
static int ipx_prio_our, ipx_prio_his;
static int
-setipxnode(argv)
- char **argv;
+setipxnode(char **argv)
{
u_char *end;
int have_his = 0;
memset (our_node, 0, 6);
memset (his_node, 0, 6);
- end = setipxnodevalue (*argv, our_node);
+ end = setipxnodevalue ((u_char *)*argv, our_node);
if (*end == ':') {
have_his = 1;
end = setipxnodevalue (++end, his_node);
}
static void
-printipxnode(opt, printer, arg)
- option_t *opt;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+printipxnode(option_t *opt, void (*printer) (void *, char *, ...), void *arg)
{
unsigned char *p;
}
static int
-setipxname (argv)
- char **argv;
+setipxname (char **argv)
{
u_char *dest = ipxcp_wantoptions[0].name;
char *src = *argv;
* ipxcp_init - Initialize IPXCP.
*/
static void
-ipxcp_init(unit)
- int unit;
+ipxcp_init(int unit)
{
fsm *f = &ipxcp_fsm[unit];
*/
static void
-copy_node (src, dst)
-u_char *src, *dst;
+copy_node (u_char *src, u_char *dst)
{
memcpy (dst, src, sizeof (ipxcp_wantoptions[0].our_node));
}
*/
static int
-compare_node (src, dst)
-u_char *src, *dst;
+compare_node (u_char *src, u_char *dst)
{
return memcmp (dst, src, sizeof (ipxcp_wantoptions[0].our_node)) == 0;
}
*/
static int
-zero_node (node)
-u_char *node;
+zero_node (u_char *node)
{
int indx;
for (indx = 0; indx < sizeof (ipxcp_wantoptions[0].our_node); ++indx)
*/
static void
-inc_node (node)
-u_char *node;
+inc_node (u_char *node)
{
u_char *outp;
u_int32_t magic_num;
* ipxcp_open - IPXCP is allowed to come up.
*/
static void
-ipxcp_open(unit)
- int unit;
+ipxcp_open(int unit)
{
fsm_open(&ipxcp_fsm[unit]);
}
* ipxcp_close - Take IPXCP down.
*/
static void
-ipxcp_close(unit, reason)
- int unit;
- char *reason;
+ipxcp_close(int unit, char *reason)
{
fsm_close(&ipxcp_fsm[unit], reason);
}
* ipxcp_lowerup - The lower layer is up.
*/
static void
-ipxcp_lowerup(unit)
- int unit;
+ipxcp_lowerup(int unit)
{
fsm_lowerup(&ipxcp_fsm[unit]);
}
* ipxcp_lowerdown - The lower layer is down.
*/
static void
-ipxcp_lowerdown(unit)
- int unit;
+ipxcp_lowerdown(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;
+ipxcp_input(int unit, u_char *p, int len)
{
fsm_input(&ipxcp_fsm[unit], p, len);
}
* Pretend the lower layer went down, so we shut up.
*/
static void
-ipxcp_protrej(unit)
- int unit;
+ipxcp_protrej(int unit)
{
fsm_lowerdown(&ipxcp_fsm[unit]);
}
* ipxcp_resetci - Reset our CI.
*/
static void
-ipxcp_resetci(f)
- fsm *f;
+ipxcp_resetci(fsm *f)
{
wo->req_node = wo->neg_node && ao->neg_node;
wo->req_nn = wo->neg_nn && ao->neg_nn;
*/
static int
-ipxcp_cilen(f)
- fsm *f;
+ipxcp_cilen(fsm *f)
{
int len;
* ipxcp_addci - Add our desired CIs to a packet.
*/
static void
-ipxcp_addci(f, ucp, lenp)
- fsm *f;
- u_char *ucp;
- int *lenp;
+ipxcp_addci(fsm *f, u_char *ucp, int *lenp)
{
/*
* Add the options to the record.
* 1 - Ack was good.
*/
static int
-ipxcp_ackci(f, p, len)
- fsm *f;
- u_char *p;
- int len;
+ipxcp_ackci(fsm *f, u_char *p, int len)
{
u_short cilen, citype, cishort;
u_char cichar;
*/
static int
-ipxcp_nakci(f, p, len, treat_as_reject)
- fsm *f;
- u_char *p;
- int len;
- int treat_as_reject;
+ipxcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
{
u_char citype, cilen, *next;
u_short s;
* ipxcp_rejci - Reject some of our CIs.
*/
static int
-ipxcp_rejci(f, p, len)
- fsm *f;
- u_char *p;
- int len;
+ipxcp_rejci(fsm *f, u_char *p, int len)
{
u_short cilen, citype, cishort;
u_char cichar;
* 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;
+ipxcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
{
u_char *cip, *next; /* Pointer to current and next CIs */
u_short cilen, citype; /* Parsed len, type */
*/
static void
-ipxcp_up(f)
- fsm *f;
+ipxcp_up(fsm *f)
{
int unit = f->unit;
*/
static void
-ipxcp_down(f)
- fsm *f;
+ipxcp_down(fsm *f)
{
IPXCPDEBUG(("ipxcp: down"));
* ipxcp_finished - possibly shut down the lower layers.
*/
static void
-ipxcp_finished(f)
- fsm *f;
+ipxcp_finished(fsm *f)
{
np_finished(f->unit, PPP_IPX);
}
* interface-name tty-name speed local-IPX remote-IPX networks.
*/
static void
-ipxcp_script(f, script)
- fsm *f;
- char *script;
+ipxcp_script(fsm *f, char *script)
{
char strspeed[32], strlocal[32], strremote[32];
char strnetwork[32], strpid[32];
};
static int
-ipxcp_printpkt(p, plen, printer, arg)
- u_char *p;
- int plen;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+ipxcp_printpkt(u_char *p, int plen,
+ void (*printer) (void *, char *, ...), void *arg)
{
int code, id, len, olen;
u_char *pstart, *optend;
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $Id: ipxcp.h,v 1.5 2002/12/04 23:03:32 paulus Exp $
*/
/*
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: lcp.c,v 1.76 2006/05/22 00:04:07 paulus Exp $"
-
-/*
- * TODO:
- */
-
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "chap-new.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,
/* steal a bit in fsm flags word */
#define DELAYED_UP 0x100
-static void lcp_delayed_up __P((void *));
+static void lcp_delayed_up(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 lcp_echo_adaptive = 0; /* request echo only if the link was idle */
bool lax_recv = 0; /* accept control chars in asyncmap */
bool noendpoint = 0; /* don't send/accept endpoint discriminator */
-static int noopt __P((char **));
+static int noopt(char **);
#ifdef HAVE_MULTILINK
-static int setendpoint __P((char **));
-static void printendpoint __P((option_t *, void (*)(void *, char *, ...),
- void *));
+static int setendpoint(char **);
+static void printendpoint(option_t *, void (*)(void *, char *, ...), void *);
#endif /* HAVE_MULTILINK */
static option_t lcp_option_list[] = {
OPT_PRIO },
{ "lcp-echo-interval", o_int, &lcp_echo_interval,
"Set time in seconds between LCP echo requests", OPT_PRIO },
+ { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive,
+ "Suppress LCP echo requests if traffic was received", 1 },
{ "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,
/*
* 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, 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));
+static void lcp_resetci(fsm *); /* Reset our CI */
+static int lcp_cilen(fsm *); /* Return length of our CI */
+static void lcp_addci(fsm *, u_char *, int *); /* Add our CI to pkt */
+static int lcp_ackci(fsm *, u_char *, int); /* Peer ack'd our CI */
+static int lcp_nakci(fsm *, u_char *, int, int); /* Peer nak'd our CI */
+static int lcp_rejci(fsm *, u_char *, int); /* Peer rej'd our CI */
+static int lcp_reqci(fsm *, u_char *, int *, int); /* Rcv peer CI */
+static void lcp_up(fsm *); /* We're UP */
+static void lcp_down(fsm *); /* We're DOWN */
+static void lcp_starting(fsm *); /* We need lower layer up */
+static void lcp_finished(fsm *); /* We need lower layer down */
+static int lcp_extcode(fsm *, int, int, u_char *, int);
+static void lcp_rprotrej(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 void lcp_echo_lowerup(int);
+static void lcp_echo_lowerdown(int);
+static void LcpEchoTimeout(void *);
+static void lcp_received_echo_reply(fsm *, int, u_char *, int);
+static void LcpSendEchoRequest(fsm *);
+static void LcpLinkFailure(fsm *);
+static void LcpEchoCheck(fsm *);
static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
lcp_resetci, /* Reset our Configuration Information */
* 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 *));
+static void lcp_init(int);
+static void lcp_input(int, u_char *, int);
+static void lcp_protrej(int);
+static int lcp_printpkt(u_char *, int, void (*)(void *, char *, ...), void *);
struct protent lcp_protent = {
PPP_LCP,
* noopt - Disable all options (why?).
*/
static int
-noopt(argv)
- char **argv;
+noopt(char **argv)
{
BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));
BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));
#ifdef HAVE_MULTILINK
static int
-setendpoint(argv)
- char **argv;
+setendpoint(char **argv)
{
if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) {
lcp_wantoptions[0].neg_endpoint = 1;
}
static void
-printendpoint(opt, printer, arg)
- option_t *opt;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+printendpoint(option_t *opt, void (*printer)(void *, char *, ...), void *arg)
{
printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint));
}
* lcp_init - Initialize LCP.
*/
static void
-lcp_init(unit)
- int unit;
+lcp_init(int unit)
{
fsm *f = &lcp_fsm[unit];
lcp_options *wo = &lcp_wantoptions[unit];
* lcp_open - LCP is allowed to come up.
*/
void
-lcp_open(unit)
- int unit;
+lcp_open(int unit)
{
fsm *f = &lcp_fsm[unit];
lcp_options *wo = &lcp_wantoptions[unit];
* lcp_close - Take LCP down.
*/
void
-lcp_close(unit, reason)
- int unit;
- char *reason;
+lcp_close(int unit, char *reason)
{
fsm *f = &lcp_fsm[unit];
int oldstate;
* lcp_lowerup - The lower layer is up.
*/
void
-lcp_lowerup(unit)
- int unit;
+lcp_lowerup(int unit)
{
lcp_options *wo = &lcp_wantoptions[unit];
fsm *f = &lcp_fsm[unit];
* lcp_lowerdown - The lower layer is down.
*/
void
-lcp_lowerdown(unit)
- int unit;
+lcp_lowerdown(int unit)
{
fsm *f = &lcp_fsm[unit];
* lcp_delayed_up - Bring the lower layer up now.
*/
static void
-lcp_delayed_up(arg)
- void *arg;
+lcp_delayed_up(void *arg)
{
fsm *f = arg;
* lcp_input - Input LCP packet.
*/
static void
-lcp_input(unit, p, len)
- int unit;
- u_char *p;
- int len;
+lcp_input(int unit, u_char *p, int len)
{
fsm *f = &lcp_fsm[unit];
* 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;
+lcp_extcode(fsm *f, int code, int id, u_char *inp, int len)
{
u_char *magp;
* Figure out which protocol is rejected and inform it.
*/
static void
-lcp_rprotrej(f, inp, len)
- fsm *f;
- u_char *inp;
- int len;
+lcp_rprotrej(fsm *f, u_char *inp, int len)
{
int i;
struct protent *protp;
*/
/*ARGSUSED*/
static void
-lcp_protrej(unit)
- int unit;
+lcp_protrej(int unit)
{
/*
* Can't reject LCP!
* lcp_sprotrej - Send a Protocol-Reject for some protocol.
*/
void
-lcp_sprotrej(unit, p, len)
- int unit;
- u_char *p;
- int len;
+lcp_sprotrej(int unit, u_char *p, int len)
{
/*
* Send back the protocol and the information field of the
* lcp_resetci - Reset our CI.
*/
static void
-lcp_resetci(f)
- fsm *f;
+lcp_resetci(fsm *f)
{
lcp_options *wo = &lcp_wantoptions[f->unit];
lcp_options *go = &lcp_gotoptions[f->unit];
* lcp_cilen - Return length of our CI.
*/
static int
-lcp_cilen(f)
- fsm *f;
+lcp_cilen(fsm *f)
{
lcp_options *go = &lcp_gotoptions[f->unit];
* lcp_addci - Add our desired CIs to a packet.
*/
static void
-lcp_addci(f, ucp, lenp)
- fsm *f;
- u_char *ucp;
- int *lenp;
+lcp_addci(fsm *f, u_char *ucp, int *lenp)
{
lcp_options *go = &lcp_gotoptions[f->unit];
u_char *start_ucp = ucp;
* 1 - Ack was good.
*/
static int
-lcp_ackci(f, p, len)
- fsm *f;
- u_char *p;
- int len;
+lcp_ackci(fsm *f, u_char *p, int len)
{
lcp_options *go = &lcp_gotoptions[f->unit];
u_char cilen, citype, cichar;
* 1 - Nak was good.
*/
static int
-lcp_nakci(f, p, len, treat_as_reject)
- fsm *f;
- u_char *p;
- int len;
- int treat_as_reject;
+lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
{
lcp_options *go = &lcp_gotoptions[f->unit];
lcp_options *wo = &lcp_wantoptions[f->unit];
* 1 - Reject was good.
*/
static int
-lcp_rejci(f, p, len)
- fsm *f;
- u_char *p;
- int len;
+lcp_rejci(fsm *f, u_char *p, int len)
{
lcp_options *go = &lcp_gotoptions[f->unit];
u_char cichar;
* 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_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree)
{
lcp_options *go = &lcp_gotoptions[f->unit];
lcp_options *ho = &lcp_hisoptions[f->unit];
* lcp_up - LCP has come UP.
*/
static void
-lcp_up(f)
- fsm *f;
+lcp_up(fsm *f)
{
lcp_options *wo = &lcp_wantoptions[f->unit];
lcp_options *ho = &lcp_hisoptions[f->unit];
* Alert other protocols.
*/
static void
-lcp_down(f)
- fsm *f;
+lcp_down(fsm *f)
{
lcp_options *go = &lcp_gotoptions[f->unit];
* lcp_starting - LCP needs the lower layer up.
*/
static void
-lcp_starting(f)
- fsm *f;
+lcp_starting(fsm *f)
{
link_required(f->unit);
}
* lcp_finished - LCP has finished with the lower layer.
*/
static void
-lcp_finished(f)
- fsm *f;
+lcp_finished(fsm *f)
{
link_terminated(f->unit);
}
};
static int
-lcp_printpkt(p, plen, printer, arg)
- u_char *p;
- int plen;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+lcp_printpkt(u_char *p, int plen, void (*printer)(void *, char *, ...), void *arg)
{
int code, id, len, olen, i;
u_char *pstart, *optend;
*/
static
-void LcpLinkFailure (f)
- fsm *f;
+void LcpLinkFailure (fsm *f)
{
if (f->state == OPENED) {
info("No response to %d echo-requests", lcp_echos_pending);
*/
static void
-LcpEchoCheck (f)
- fsm *f;
+LcpEchoCheck (fsm *f)
{
LcpSendEchoRequest (f);
if (f->state != OPENED)
*/
static void
-LcpEchoTimeout (arg)
- void *arg;
+LcpEchoTimeout (void *arg)
{
if (lcp_echo_timer_running != 0) {
lcp_echo_timer_running = 0;
*/
static void
-lcp_received_echo_reply (f, id, inp, len)
- fsm *f;
- int id;
- u_char *inp;
- int len;
+lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len)
{
u_int32_t magic;
*/
static void
-LcpSendEchoRequest (f)
- fsm *f;
+LcpSendEchoRequest (fsm *f)
{
u_int32_t lcp_magic;
u_char pkt[4], *pktp;
}
}
+ /*
+ * If adaptive echos have been enabled, only send the echo request if
+ * no traffic was received since the last one.
+ */
+ if (lcp_echo_adaptive) {
+ static unsigned int last_pkts_in = 0;
+ struct pppd_stats cur_stats;
+
+ if (get_ppp_stats(f->unit, &cur_stats) && cur_stats.pkts_in != last_pkts_in) {
+ last_pkts_in = cur_stats.pkts_in;
+ return;
+ }
+ }
+
/*
* Make and send the echo request frame.
*/
*/
static void
-lcp_echo_lowerup (unit)
- int unit;
+lcp_echo_lowerup (int unit)
{
fsm *f = &lcp_fsm[unit];
*/
static void
-lcp_echo_lowerdown (unit)
- int unit;
+lcp_echo_lowerdown (int unit)
{
fsm *f = &lcp_fsm[unit];
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $Id: lcp.h,v 1.20 2004/11/14 22:53:42 carlsonj Exp $
*/
/*
#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 */
+void lcp_open(int);
+void lcp_close(int, char *);
+void lcp_lowerup(int);
+void lcp_lowerdown(int);
+void lcp_sprotrej(int, u_char *, int); /* send protocol reject */
extern struct protent lcp_protent;
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: magic.c,v 1.11 2003/06/11 23:56:26 paulus Exp $"
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "pppd.h"
#include "magic.h"
-static const char rcsid[] = RCSID;
-extern long mrand48 __P((void));
-extern void srand48 __P((long));
+extern long mrand48 (void);
+extern void srand48 (long);
/*
* magic_init - Initialize the magic number generator.
* and current time, currently.
*/
void
-magic_init()
+magic_init(void)
{
long seed;
struct timeval t;
* magic - Returns the next magic number.
*/
u_int32_t
-magic()
+magic(void)
{
return (u_int32_t) mrand48();
}
*/
double
-drand48()
+drand48(void)
{
return (double)random() / (double)0x7fffffffL; /* 2**31-1 */
}
long
-mrand48()
+mrand48(void)
{
return random();
}
void
-srand48(seedval)
-long seedval;
+srand48(long seedval)
{
srandom((int)seedval);
}
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $Id: magic.h,v 1.5 2003/06/11 23:56:26 paulus Exp $
*/
-void magic_init __P((void)); /* Initialize the magic number generator */
-u_int32_t magic __P((void)); /* Returns the next magic number */
+void magic_init (void); /* Initialize the magic number generator */
+u_int32_t magic (void); /* Returns the next magic number */
/* Fill buffer with random bytes */
-void random_bytes __P((unsigned char *buf, int len));
+void random_bytes (unsigned char *buf, int len);
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Copyright (c) 1999-2004 Paul Mackerras. All rights reserved.
+ * Copyright (c) 1999-2020 Paul Mackerras. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: main.c,v 1.156 2008/06/23 11:47:18 paulus Exp $"
-
#include <stdio.h>
#include <ctype.h>
#include <stdlib.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 "atcp.h"
#endif
-static const char rcsid[] = RCSID;
/* interface vars */
char ifname[MAXIFNAMELEN]; /* Interface name */
char db_key[32];
-int (*holdoff_hook) __P((void)) = NULL;
-int (*new_phase_hook) __P((int)) = NULL;
-void (*snoop_recv_hook) __P((unsigned char *p, int len)) = NULL;
-void (*snoop_send_hook) __P((unsigned char *p, int len)) = NULL;
+int (*holdoff_hook)(void) = NULL;
+int (*new_phase_hook)(int) = NULL;
+void (*snoop_recv_hook)(unsigned char *p, int len) = NULL;
+void (*snoop_send_hook)(unsigned char *p, int len) = NULL;
static int conn_running; /* we have a [dis]connector running */
static int fd_loop; /* fd for getting demand-dial packets */
static sigset_t signals_handled;
static int waiting;
-static sigjmp_buf sigjmp;
+static int sigpipe[2];
char **script_env; /* Env. variable values for scripts */
int s_env_nalloc; /* # words avail at script_env */
struct subprocess {
pid_t pid;
char *prog;
- void (*done) __P((void *));
+ void (*done)(void *);
void *arg;
int killable;
struct subprocess *next;
/* Prototypes for procedures local to this file. */
-static void setup_signals __P((void));
-static void create_pidfile __P((int pid));
-static void create_linkpidfile __P((int pid));
-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 void forget_child __P((int pid, int status));
-static int reap_kids __P((void));
-static void childwait_end __P((void *));
+static void setup_signals(void);
+static void create_pidfile(int pid);
+static void create_linkpidfile(int pid);
+static void cleanup(void);
+static void get_input(void);
+static void calltimeout(void);
+static struct timeval *timeleft(struct timeval *);
+static void kill_my_pg(int);
+static void hup(int);
+static void term(int);
+static void chld(int);
+static void toggle_debug(int);
+static void open_ccp(int);
+static void bad_signal(int);
+static void holdoff_end(void *);
+static void forget_child(int pid, int status);
+static int reap_kids(void);
+static void childwait_end(void *);
#ifdef USE_TDB
-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 update_db_entry(void);
+static void add_db_key(const char *);
+static void delete_db_key(const char *);
+static void cleanup_db(void);
#endif
-static void handle_events __P((void));
-void print_link_stats __P((void));
-
-extern char *getlogin __P((void));
-int main __P((int, char *[]));
-
-#ifdef ultrix
-#undef O_NONBLOCK
-#define O_NONBLOCK O_NDELAY
-#endif
+static void handle_events(void);
+void print_link_stats(void);
-#ifdef ULTRIX
-#define setlogmask(x)
-#endif
+extern char *getlogin(void);
+int main(int, char *[]);
/*
* PPP Data Link Layer "protocol" table.
};
int
-main(argc, argv)
- int argc;
- char *argv[];
+main(int argc, char *argv[])
{
int i, t;
char *p;
info("Starting link");
}
- gettimeofday(&start_time, NULL);
+ get_time(&start_time);
script_unsetenv("CONNECT_TIME");
script_unsetenv("BYTES_SENT");
script_unsetenv("BYTES_RCVD");
* handle_events - wait for something to happen and respond to it.
*/
static void
-handle_events()
+handle_events(void)
{
struct timeval timo;
+ unsigned char buf[16];
kill_link = open_ccp_flag = 0;
- if (sigsetjmp(sigjmp, 1) == 0) {
- sigprocmask(SIG_BLOCK, &signals_handled, NULL);
- if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) {
- sigprocmask(SIG_UNBLOCK, &signals_handled, NULL);
- } else {
- waiting = 1;
- sigprocmask(SIG_UNBLOCK, &signals_handled, NULL);
- wait_input(timeleft(&timo));
- }
- }
+
+ /* alert via signal pipe */
+ waiting = 1;
+ /* flush signal pipe */
+ for (; read(sigpipe[0], buf, sizeof(buf)) > 0; );
+ add_fd(sigpipe[0]);
+ /* wait if necessary */
+ if (!(got_sighup || got_sigterm || got_sigusr2 || got_sigchld))
+ wait_input(timeleft(&timo));
waiting = 0;
+ remove_fd(sigpipe[0]);
+
calltimeout();
if (got_sighup) {
info("Hangup (SIGHUP)");
* setup_signals - initialize signal handling.
*/
static void
-setup_signals()
+setup_signals(void)
{
struct sigaction sa;
+ /* create pipe to wake up event handler from signal handler */
+ if (pipe(sigpipe) < 0)
+ fatal("Couldn't create signal pipe: %m");
+ fcntl(sigpipe[0], F_SETFD, fcntl(sigpipe[0], F_GETFD) | FD_CLOEXEC);
+ fcntl(sigpipe[1], F_SETFD, fcntl(sigpipe[1], F_GETFD) | FD_CLOEXEC);
+ fcntl(sigpipe[0], F_SETFL, fcntl(sigpipe[0], F_GETFL) | O_NONBLOCK);
+ fcntl(sigpipe[1], F_SETFL, fcntl(sigpipe[1], F_GETFL) | O_NONBLOCK);
+
/*
* Compute mask of all interesting signals and install signal handlers
* for each. Only one signal handler may be active at a time. Therefore,
* unit we are using.
*/
void
-set_ifunit(iskey)
- int iskey;
+set_ifunit(int iskey)
{
+ char ifkey[32];
+
if (req_ifname[0] != '\0')
slprintf(ifname, sizeof(ifname), "%s", req_ifname);
else
slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
info("Using interface %s", ifname);
script_setenv("IFNAME", ifname, iskey);
+ slprintf(ifkey, sizeof(ifkey), "%d", ifunit);
+ script_setenv("UNIT", ifkey, iskey);
if (iskey) {
create_pidfile(getpid()); /* write pid to file */
create_linkpidfile(getpid());
* detach - detach us from the controlling terminal.
*/
void
-detach()
+detach(void)
{
int pid;
char numbuf[16];
* reopen_log - (re)open our connection to syslog.
*/
void
-reopen_log()
+reopen_log(void)
{
openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
setlogmask(LOG_UPTO(LOG_INFO));
* Create a file containing our process ID.
*/
static void
-create_pidfile(pid)
- int pid;
+create_pidfile(int pid)
{
FILE *pidfile;
}
void
-create_linkpidfile(pid)
- int pid;
+create_linkpidfile(int pid)
{
FILE *pidfile;
/*
* remove_pidfile - remove our pid files
*/
-void remove_pidfiles()
+void remove_pidfiles(void)
{
if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT)
warn("unable to delete pid file %s: %m", pidfilename);
* holdoff_end - called via a timeout when the holdoff period ends.
*/
static void
-holdoff_end(arg)
- void *arg;
+holdoff_end(void *arg)
{
new_phase(PHASE_DORMANT);
}
* protocol_name - find a name for a PPP protocol.
*/
const char *
-protocol_name(proto)
- int proto;
+protocol_name(int proto)
{
struct protocol_list *lp;
* get_input - called when incoming data is available.
*/
static void
-get_input()
+get_input(void)
{
int len, i;
u_char *p;
* itself), otherwise 0.
*/
int
-ppp_send_config(unit, mtu, accm, pcomp, accomp)
- int unit, mtu;
- u_int32_t accm;
- int pcomp, accomp;
+ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp)
{
int errs;
* itself), otherwise 0.
*/
int
-ppp_recv_config(unit, mru, accm, pcomp, accomp)
- int unit, mru;
- u_int32_t accm;
- int pcomp, accomp;
+ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp)
{
int errs;
* new_phase - signal the start of a new phase of pppd's operation.
*/
void
-new_phase(p)
- int p;
+new_phase(int p)
{
phase = p;
if (new_phase_hook)
* die - clean up state and exit with the specified status.
*/
void
-die(status)
- int status;
+die(int status)
{
if (!doing_multilink || multilink_master)
print_link_stats();
*/
/* ARGSUSED */
static void
-cleanup()
+cleanup(void)
{
sys_cleanup();
}
void
-print_link_stats()
+print_link_stats(void)
{
/*
* Print connect time and statistics.
* reset_link_stats - "reset" stats when link goes up.
*/
void
-reset_link_stats(u)
- int u;
+reset_link_stats(int u)
{
if (!get_ppp_stats(u, &old_link_stats))
return;
- gettimeofday(&start_time, NULL);
+ get_time(&start_time);
}
/*
* update_link_stats - get stats at link termination.
*/
void
-update_link_stats(u)
- int u;
+update_link_stats(int u)
{
struct timeval now;
char numbuf[32];
if (!get_ppp_stats(u, &link_stats)
- || gettimeofday(&now, NULL) < 0)
+ || get_time(&now) < 0)
return;
link_connect_time = now.tv_sec - start_time.tv_sec;
link_stats_valid = 1;
struct callout {
struct timeval c_time; /* time at which to call routine */
void *c_arg; /* argument to routine */
- void (*c_func) __P((void *)); /* routine */
+ void (*c_func)(void *); /* routine */
struct callout *c_next;
};
* timeout - Schedule a timeout.
*/
void
-timeout(func, arg, secs, usecs)
- void (*func) __P((void *));
- void *arg;
- int secs, usecs;
+timeout(void (*func)(void *), void *arg, int secs, int usecs)
{
struct callout *newp, *p, **pp;
fatal("Out of memory in timeout()!");
newp->c_arg = arg;
newp->c_func = func;
- gettimeofday(&timenow, NULL);
+ get_time(&timenow);
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) {
* untimeout - Unschedule a timeout.
*/
void
-untimeout(func, arg)
- void (*func) __P((void *));
- void *arg;
+untimeout(void (*func)(void *), void *arg)
{
struct callout **copp, *freep;
* calltimeout - Call any timeout routines which are now due.
*/
static void
-calltimeout()
+calltimeout(void)
{
struct callout *p;
while (callout != NULL) {
p = callout;
- if (gettimeofday(&timenow, NULL) < 0)
+ if (get_time(&timenow) < 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
* timeleft - return the length of time until the next timeout is due.
*/
static struct timeval *
-timeleft(tvp)
- struct timeval *tvp;
+timeleft(struct timeval *tvp)
{
if (callout == NULL)
return NULL;
- gettimeofday(&timenow, NULL);
+ get_time(&timenow);
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) {
* We assume that sig is currently blocked.
*/
static void
-kill_my_pg(sig)
- int sig;
+kill_my_pg(int sig)
{
struct sigaction act, oldact;
struct subprocess *chp;
* signal, we just take the link down.
*/
static void
-hup(sig)
- int sig;
+hup(int sig)
{
/* can't log a message here, it can deadlock */
got_sighup = 1;
kill_my_pg(sig);
notify(sigreceived, sig);
if (waiting)
- siglongjmp(sigjmp, 1);
+ write(sigpipe[1], &sig, sizeof(sig));
}
*/
/*ARGSUSED*/
static void
-term(sig)
- int sig;
+term(int sig)
{
/* can't log a message here, it can deadlock */
got_sigterm = sig;
kill_my_pg(sig);
notify(sigreceived, sig);
if (waiting)
- siglongjmp(sigjmp, 1);
+ write(sigpipe[1], &sig, sizeof(sig));
}
* Sets a flag so we will call reap_kids in the mainline.
*/
static void
-chld(sig)
- int sig;
+chld(int sig)
{
got_sigchld = 1;
if (waiting)
- siglongjmp(sigjmp, 1);
+ write(sigpipe[1], &sig, sizeof(sig));
}
*/
/*ARGSUSED*/
static void
-toggle_debug(sig)
- int sig;
+toggle_debug(int sig)
{
debug = !debug;
if (debug) {
*/
/*ARGSUSED*/
static void
-open_ccp(sig)
- int sig;
+open_ccp(int sig)
{
got_sigusr2 = 1;
if (waiting)
- siglongjmp(sigjmp, 1);
+ write(sigpipe[1], &sig, sizeof(sig));
}
* bad_signal - We've caught a fatal signal. Clean up state and exit.
*/
static void
-bad_signal(sig)
- int sig;
+bad_signal(int sig)
{
static int crashed = 0;
/* Executing in the child */
sys_close();
#ifdef USE_TDB
- tdb_close(pppdb);
+ if (pppdb != NULL)
+ tdb_close(pppdb);
#endif
/* make sure infd, outfd and errfd won't get tromped on below */
}
static bool
-add_script_env(pos, newstring)
- int pos;
- char *newstring;
+add_script_env(int pos, char *newstring)
{
if (pos + 1 >= s_env_nalloc) {
int new_n = pos + 17;
}
static void
-remove_script_env(pos)
- int pos;
+remove_script_env(int pos)
{
free(script_env[pos] - 1);
while ((script_env[pos] = script_env[pos + 1]) != NULL)
* and update the system environment.
*/
static void
-update_system_environment()
+update_system_environment(void)
{
struct userenv *uep;
* 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;
+device_script(char *program, int in, int out, int dont_wait)
{
int pid;
int status = -1;
* script_unsetenv() safely after this routine is run.
*/
static void
-update_script_environment()
+update_script_environment(void)
{
struct userenv *uep;
* reap_kids) iff the return value is > 0.
*/
pid_t
-run_program(prog, args, must_exist, done, arg, wait)
- char *prog;
- char **args;
- int must_exist;
- void (*done) __P((void *));
- void *arg;
- int wait;
+run_program(char *prog, char **args, int must_exist, void (*done)(void *), void *arg, int wait)
{
int pid, status;
struct stat sbuf;
* to use.
*/
void
-record_child(pid, prog, done, arg, killable)
- int pid;
- char *prog;
- void (*done) __P((void *));
- void *arg;
- int killable;
+record_child(int pid, char *prog, void (*done)(void *), void *arg, int killable)
{
struct subprocess *chp;
* exit, send them all a SIGTERM.
*/
static void
-childwait_end(arg)
- void *arg;
+childwait_end(void *arg)
{
struct subprocess *chp;
* forget_child - clean up after a dead child
*/
static void
-forget_child(pid, status)
- int pid, status;
+forget_child(int pid, int status)
{
struct subprocess *chp, **prevp;
* and log a message for abnormal terminations.
*/
static int
-reap_kids()
+reap_kids(void)
{
int pid, status;
* 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;
+add_notifier(struct notifier **notif, notify_func func, void *arg)
{
struct notifier *np;
* be called when something happens.
*/
void
-remove_notifier(notif, func, arg)
- struct notifier **notif;
- notify_func func;
- void *arg;
+remove_notifier(struct notifier **notif, notify_func func, void *arg)
{
struct notifier *np;
* notify - call a set of functions registered with add_notifier.
*/
void
-notify(notif, val)
- struct notifier *notif;
- int val;
+notify(struct notifier *notif, int val)
{
struct notifier *np;
* novm - log an error message saying we ran out of memory, and die.
*/
void
-novm(msg)
- char *msg;
+novm(char *msg)
{
fatal("Virtual memory exhausted allocating %s\n", msg);
}
* for scripts that we run (e.g. ip-up, auth-up, etc.)
*/
void
-script_setenv(var, value, iskey)
- char *var, *value;
- int iskey;
+script_setenv(char *var, char *value, int iskey)
{
size_t varl = strlen(var);
size_t vl = varl + strlen(value) + 2;
* for scripts.
*/
void
-script_unsetenv(var)
- char *var;
+script_unsetenv(char *var)
{
int vl = strlen(var);
int i;
* lock_db - get an exclusive lock on the TDB database.
* Used to ensure atomicity of various lookup/modify operations.
*/
-void lock_db()
+void lock_db(void)
{
#ifdef USE_TDB
TDB_DATA key;
/*
* unlock_db - remove the exclusive lock obtained by lock_db.
*/
-void unlock_db()
+void unlock_db(void)
{
#ifdef USE_TDB
TDB_DATA key;
* update_db_entry - update our entry in the database.
*/
static void
-update_db_entry()
+update_db_entry(void)
{
TDB_DATA key, dbuf;
int vlen, i;
* 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;
+add_db_key(const char *str)
{
TDB_DATA key, dbuf;
* delete_db_key - delete a key for looking up our database entry.
*/
static void
-delete_db_key(str)
- const char *str;
+delete_db_key(const char *str)
{
TDB_DATA key;
* cleanup_db - delete all the entries we put in the database.
*/
static void
-cleanup_db()
+cleanup_db(void)
{
TDB_DATA key;
int i;
** This is a user-callable routine.
*/
void
-MD4Print(MDp)
-MD4_CTX *MDp;
+MD4Print(MD4_CTX *MDp)
{
int i,j;
for (i=0;i<4;i++)
** This is a user-callable routine.
*/
void
-MD4Init(MDp)
-MD4_CTX *MDp;
+MD4Init(MD4_CTX *MDp)
{
int i;
MDp->buffer[0] = I0;
** This routine is not user-callable.
*/
static void
-MDblock(MDp,Xb)
-MD4_CTX *MDp;
-unsigned char *Xb;
+MDblock(MD4_CTX *MDp, unsigned char *Xb)
{
register unsigned int tmp, A, B, C, D;
unsigned int X[16];
** if desired.
*/
void
-MD4Update(MDp,X,count)
-MD4_CTX *MDp;
-unsigned char *X;
-unsigned int count;
+MD4Update(MD4_CTX *MDp, unsigned char *X, unsigned int count)
{
unsigned int i, tmp, bit, byte, mask;
unsigned char XX[64];
** Finish up MD4 computation and return message digest.
*/
void
-MD4Final(buf, MD)
-unsigned char *buf;
-MD4_CTX *MD;
+MD4Final(unsigned char *buf, MD4_CTX *MD)
{
int i, j;
unsigned int w;
** ********************************************************************
*/
-#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 {
** Initialize the MD4_CTX prepatory to doing a message digest
** computation.
*/
-extern void MD4Init __P((MD4_CTX *MD));
+extern void MD4Init(MD4_CTX *MD);
/* MD4Update(MD,X,count)
** Input: X -- a pointer to an array of unsigned characters.
** 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));
+extern void MD4Update(MD4_CTX *MD, unsigned char *X, unsigned int count);
/* MD4Print(MD)
** Prints message digest buffer MD as 32 hexadecimal digits.
** of buffer[3].
** Each byte is printed with high-order hexadecimal digit first.
*/
-extern void MD4Print __P((MD4_CTX *));
+extern void MD4Print(MD4_CTX *);
/* MD4Final(buf, MD)
** Returns message digest from MD and terminates the message
** digest computation.
*/
-extern void MD4Final __P((unsigned char *, MD4_CTX *));
+extern void MD4Final(unsigned char *, MD4_CTX *);
/*
** End of md4.h
/* The routine MD5_Init initializes the message-digest context
mdContext. All fields are set to zero.
*/
-void MD5_Init (mdContext)
-MD5_CTX *mdContext;
+void MD5_Init (MD5_CTX *mdContext)
{
mdContext->i[0] = mdContext->i[1] = (UINT4)0;
account for the presence of each of the characters inBuf[0..inLen-1]
in the message whose digest is being computed.
*/
-void MD5_Update (mdContext, inBuf, inLen)
-MD5_CTX *mdContext;
-unsigned char *inBuf;
-unsigned int inLen;
+void MD5_Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
{
UINT4 in[16];
int mdi;
/* The routine MD5Final terminates the message-digest computation and
ends with the desired message digest in mdContext->digest[0...15].
*/
-void MD5_Final (hash, mdContext)
-unsigned char hash[];
-MD5_CTX *mdContext;
+void MD5_Final (unsigned char hash[], MD5_CTX *mdContext)
{
UINT4 in[16];
int mdi;
/* Basic MD5 step. Transforms buf based on in.
*/
-static void Transform (buf, in)
-UINT4 *buf;
-UINT4 *in;
+static void Transform (UINT4 *buf, UINT4 *in)
{
UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
extern TDB_CONTEXT *pppdb;
extern char db_key[];
-static void make_bundle_links __P((int append));
-static void remove_bundle_link __P((void));
-static void iterate_bundle_links __P((void (*func) __P((char *))));
+static void make_bundle_links(int append);
+static void remove_bundle_link(void);
+static void iterate_bundle_links(void (*func)(char *));
-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));
+static int get_default_epdisc(struct epdisc *);
+static int parse_num(char *str, const char *key, int *valp);
+static int owns_unit(TDB_DATA pid, int unit);
#define set_ip_epdisc(ep, addr) do { \
ep->length = 4; \
#define process_exists(n) (kill((n), 0) == 0 || errno != ESRCH)
void
-mp_check_options()
+mp_check_options(void)
{
lcp_options *wo = &lcp_wantoptions[0];
lcp_options *ao = &lcp_allowoptions[0];
* if we are doing multilink.
*/
int
-mp_join_bundle()
+mp_join_bundle(void)
{
lcp_options *go = &lcp_gotoptions[0];
lcp_options *ho = &lcp_hisoptions[0];
/* make sure the string is null-terminated */
rec.dptr[rec.dsize-1] = 0;
/* parse the interface number */
- parse_num(rec.dptr, "IFNAME=ppp", &unit);
+ parse_num(rec.dptr, "UNIT=", &unit);
/* check the pid value */
if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid)
|| !process_exists(pppd_pid)
return 0;
}
-void mp_exit_bundle()
+void mp_exit_bundle(void)
{
lock_db();
remove_bundle_link();
}
}
-void mp_bundle_terminated()
+void mp_bundle_terminated(void)
{
TDB_DATA key;
free(p);
}
-static void remove_bundle_link()
+static void remove_bundle_link(void)
{
TDB_DATA key, rec;
char entry[32];
}
static int
-parse_num(str, key, valp)
- char *str;
- const char *key;
- int *valp;
+parse_num(char *str, const char *key, int *valp)
{
char *p, *endp;
int i;
* Check whether the pppd identified by `key' still owns ppp unit `unit'.
*/
static int
-owns_unit(key, unit)
- TDB_DATA key;
- int unit;
+owns_unit(TDB_DATA key, int unit)
{
char ifkey[32];
TDB_DATA kd, vd;
int ret = 0;
- slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit);
+ slprintf(ifkey, sizeof(ifkey), "UNIT=%d", unit);
kd.dptr = ifkey;
kd.dsize = strlen(ifkey);
vd = tdb_fetch(pppdb, kd);
}
static int
-get_default_epdisc(ep)
- struct epdisc *ep;
+get_default_epdisc(struct epdisc *ep)
{
char *p;
struct hostent *hp;
};
char *
-epdisc_to_str(ep)
- struct epdisc *ep;
+epdisc_to_str(struct epdisc *ep)
{
static char str[MAX_ENDP_LEN*3+8];
u_char *p = ep->value;
}
int
-str_to_epdisc(ep, str)
- struct epdisc *ep;
- char *str;
+str_to_epdisc(struct epdisc *ep, char *str)
{
int i, l;
char *p, *endp;
ep->length = l;
return 1;
}
-
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: options.c,v 1.102 2008/06/15 06:53:06 paulus Exp $"
-
#include <ctype.h>
+#include <stdarg.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include "pathnames.h"
#if defined(ultrix) || defined(NeXT)
-char *strdup __P((char *));
+char *strdup(char *);
#endif
-static const char rcsid[] = RCSID;
struct option_value {
struct option_value *next;
/*
* 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 **));
+static int setdomain(char **);
+static int readfile(char **);
+static int callfile(char **);
+static int showversion(char **);
+static int showhelp(char **);
+static void usage(void);
+static int setlogfile(char **);
#ifdef PLUGIN
-static int loadplugin __P((char **));
+static int loadplugin(char **);
#endif
#ifdef PPP_FILTER
-static int setpassfilter __P((char **));
-static int setactivefilter __P((char **));
+static int setpassfilter(char **);
+static int setactivefilter(char **);
#endif
#ifdef MAXOCTETS
-static int setmodir __P((char **));
+static int setmodir(char **);
#endif
-static int user_setenv __P((char **));
-static void user_setprint __P((option_t *, printer_func, void *));
-static int user_unsetenv __P((char **));
-static void user_unsetprint __P((option_t *, printer_func, void *));
+static int user_setenv(char **);
+static void user_setprint(option_t *, printer_func, void *);
+static int user_unsetenv(char **);
+static void user_unsetprint(option_t *, printer_func, void *);
-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));
+static option_t *find_option(char *name);
+static int process_option(option_t *, char *, char **);
+static int n_arguments(option_t *);
+static int number_option(char *, u_int32_t *, int);
/*
* Structure to store extra lists of options.
* parse_args - parse a string of arguments from the command line.
*/
int
-parse_args(argc, argv)
- int argc;
- char **argv;
+parse_args(int argc, char **argv)
{
char *arg;
option_t *opt;
* and interpret them.
*/
int
-options_from_file(filename, must_exist, check_prot, priv)
- char *filename;
- int must_exist;
- int check_prot;
- int priv;
+options_from_file(char *filename, int must_exist, int check_prot, int priv)
{
FILE *f;
int i, newline, ret, err;
* and if so, interpret options from it.
*/
int
-options_from_user()
+options_from_user(void)
{
char *user, *path, *file;
int ret;
* files a lower priority than the command line.
*/
int
-options_for_tty()
+options_for_tty(void)
{
char *dev, *path, *p;
int ret;
* options_from_list - process a string of options in a wordlist.
*/
int
-options_from_list(w, priv)
- struct wordlist *w;
- int priv;
+options_from_list(struct wordlist *w, int priv)
{
char *argv[MAXARGS];
option_t *opt;
* 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;
+match_option(char *name, option_t *opt, int dowild)
{
- int (*match) __P((char *, char **, int));
+ int (*match)(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;
+ match = (int (*)(char *, char **, int)) opt->addr;
return (*match)(name, NULL, 0);
}
* This could be optimized by using a hash table.
*/
static option_t *
-find_option(name)
- const char *name;
+find_option(char *name)
{
option_t *opt;
struct option_list *list;
* process_option - process one new-style option.
*/
static int
-process_option(opt, cmd, argv)
- option_t *opt;
- char *cmd;
- char **argv;
+process_option(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));
+ int (*parser)(char **);
+ int (*wildp)(char *, char **, int);
char *optopt = (opt->type == o_wild)? "": " option";
int prio = option_priority;
option_t *mainopt = opt;
free(*optptr);
*optptr = sv;
}
+ /* obfuscate original argument for things like password */
+ if (opt->flags & OPT_HIDE) {
+ memset(*argv, '?', strlen(*argv));
+ *argv = "********";
+ }
break;
case o_special_noarg:
case o_special:
- parser = (int (*) __P((char **))) opt->addr;
+ parser = (int (*)(char **)) opt->addr;
curopt = opt;
if (!(*parser)(argv))
return 0;
break;
case o_wild:
- wildp = (int (*) __P((char *, char **, int))) opt->addr;
+ wildp = (int (*)(char *, char **, int)) opt->addr;
if (!(*wildp)(cmd, argv, 1))
return 0;
break;
* and source of the option value. Otherwise returns 0.
*/
int
-override_value(option, priority, source)
- const char *option;
- int priority;
- const char *source;
+override_value(char *option, int priority, const char *source)
{
option_t *opt;
* n_arguments - tell how many arguments an option takes
*/
static int
-n_arguments(opt)
- option_t *opt;
+n_arguments(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;
+add_options(option_t *opt)
{
struct option_list *list;
* check_options - check that options are valid and consistent.
*/
void
-check_options()
+check_options(void)
{
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;
- printer_func printer;
- void *arg;
+print_option(option_t *opt, option_t *mainopt, printer_func printer, void *arg)
{
int i, v;
char *p;
printer(arg, " ");
}
if (opt->flags & OPT_A2PRINTER) {
- void (*oprt) __P((option_t *, printer_func, void *));
- oprt = (void (*) __P((option_t *, printer_func,
- void *)))opt->addr2;
+ void (*oprt)(option_t *, printer_func, void *);
+ oprt = (void (*)(option_t *, printer_func, void *))
+ opt->addr2;
(*oprt)(opt, printer, arg);
} else if (opt->flags & OPT_A2STRVAL) {
p = (char *) opt->addr2;
* array of options.
*/
static void
-print_option_list(opt, printer, arg)
- option_t *opt;
- printer_func printer;
- void *arg;
+print_option_list(option_t *opt, printer_func printer, void *arg)
{
while (opt->name != NULL) {
if (opt->priority != OPRIO_DEFAULT
* print_options - print out what options are in effect.
*/
void
-print_options(printer, arg)
- printer_func printer;
- void *arg;
+print_options(printer_func printer, void *arg)
{
struct option_list *list;
int i;
* usage - print out a message telling how to use the program.
*/
static void
-usage()
+usage(void)
{
if (phase == PHASE_INITIALIZE)
fprintf(stderr, usage_string, VERSION, progname);
* showhelp - print out usage message and exit.
*/
static int
-showhelp(argv)
- char **argv;
+showhelp(char **argv)
{
if (phase == PHASE_INITIALIZE) {
usage();
* showversion - print out the version number and exit.
*/
static int
-showversion(argv)
- char **argv;
+showversion(char **argv)
{
if (phase == PHASE_INITIALIZE) {
- fprintf(stderr, "pppd version %s\n", VERSION);
+ fprintf(stdout, "pppd version %s\n", VERSION);
exit(0);
}
return 0;
* stderr if phase == PHASE_INITIALIZE.
*/
void
-option_error __V((char *fmt, ...))
+option_error(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)
* readable - check if a file is readable by the real user.
*/
int
-readable(fd)
- int fd;
+readable(int fd)
{
uid_t uid;
int i;
* \<newline> is ignored.
*/
int
-getword(f, word, newlinep, filename)
- FILE *f;
- char *word;
- int *newlinep;
- char *filename;
+getword(FILE *f, char *word, int *newlinep, char *filename)
{
int c, len, escape;
int quoted, comment;
c = getc(f);
}
+ word[MAXWORDLEN-1] = 0; /* make sure word is null-terminated */
/*
* End of the word: check for errors.
* 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;
+number_option(char *str, u_int32_t *valp, int base)
{
char *ptr;
* if there is an error.
*/
int
-int_option(str, valp)
- char *str;
- int *valp;
+int_option(char *str, int *valp)
{
u_int32_t v;
* readfile - take commands from a file.
*/
static int
-readfile(argv)
- char **argv;
+readfile(char **argv)
{
return options_from_file(*argv, 1, 1, privileged_option);
}
* Name may not contain /../, start with / or ../, or end in /..
*/
static int
-callfile(argv)
- char **argv;
+callfile(char **argv)
{
char *fname, *arg, *p;
int l, ok;
* setpassfilter - Set the pass filter for packets
*/
static int
-setpassfilter(argv)
- char **argv;
+setpassfilter(char **argv)
{
pcap_t *pc;
int ret = 1;
* setactivefilter - Set the active filter for packets
*/
static int
-setactivefilter(argv)
- char **argv;
+setactivefilter(char **argv)
{
pcap_t *pc;
int ret = 1;
* setdomain - Set domain name to append to hostname
*/
static int
-setdomain(argv)
- char **argv;
+setdomain(char **argv)
{
gethostname(hostname, MAXNAMELEN);
if (**argv != 0) {
}
static int
-setlogfile(argv)
- char **argv;
+setlogfile(char **argv)
{
int fd, err;
uid_t euid;
#ifdef MAXOCTETS
static int
-setmodir(argv)
- char **argv;
+setmodir(char **argv)
{
if(*argv == NULL)
return 0;
#ifdef PLUGIN
static int
-loadplugin(argv)
- char **argv;
+loadplugin(char **argv)
{
char *arg = *argv;
void *handle;
const char *err;
- void (*init) __P((void));
+ void (*init)(void);
char *path = arg;
const char *vers;
* Set an environment variable specified by the user.
*/
static int
-user_setenv(argv)
- char **argv;
+user_setenv(char **argv)
{
char *arg = argv[0];
char *eqp;
}
static void
-user_setprint(opt, printer, arg)
- option_t *opt;
- printer_func printer;
- void *arg;
+user_setprint(option_t *opt, printer_func printer, void *arg)
{
struct userenv *uep, *uepnext;
}
static int
-user_unsetenv(argv)
- char **argv;
+user_unsetenv(char **argv)
{
struct userenv *uep, **insp;
char *arg = argv[0];
}
static void
-user_unsetprint(opt, printer, arg)
- option_t *opt;
- printer_func printer;
- void *arg;
+user_unsetprint(option_t *opt, printer_func printer, void *arg)
{
struct userenv *uep, *uepnext;
-#define VERSION "2.4.7"
-#define DATE "9 August 2014"
+#define VERSION "2.4.8"
+#define DATE "31 December 2019"
/*
* define path names
- *
- * $Id: pathnames.h,v 1.18 2005/08/25 23:59:34 paulus Exp $
*/
#ifdef HAVE_PATHS_H
#define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets"
#define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets"
#define _PATH_SRPFILE _ROOT_PATH "/etc/ppp/srp-secrets"
+
+#ifdef USE_EAPTLS
+#define _PATH_EAPTLSCLIFILE _ROOT_PATH "/etc/ppp/eaptls-client"
+#define _PATH_EAPTLSSERVFILE _ROOT_PATH "/etc/ppp/eaptls-server"
+#define _PATH_OPENSSLCONFFILE _ROOT_PATH "/etc/ppp/openssl.cnf"
+#endif /* USE_EAPTLS */
+
#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"
LDFLAGS_SHARED = -shared
INSTALL = install
+# EAP-TLS
+CFLAGS += -DUSE_EAPTLS=1
+
DESTDIR = $(INSTROOT)@DESTDIR@
BINDIR = $(DESTDIR)/sbin
MANDIR = $(DESTDIR)/share/man/man8
char pppd_version[] = VERSION;
static char promptprog[PATH_MAX+1];
+static int promptprog_refused = 0;
static option_t options[] = {
{ "promptprog", o_string, promptprog,
int readgood, wstat;
ssize_t red;
- if (promptprog[0] == 0 || access(promptprog, X_OK) < 0)
+ if (promptprog_refused || promptprog[0] == 0 || access(promptprog, X_OK) < 0)
return -1; /* sorry, can't help */
if (!passwd)
if (red == 0)
break;
if (red < 0) {
- if (errno == EINTR)
+ if (errno == EINTR && !got_sigterm)
continue;
error("Can't read secret from %s: %m", promptprog);
readgood = -1;
/* now wait for child to exit */
while (waitpid(kid, &wstat, 0) < 0) {
- if (errno != EINTR) {
+ if (errno != EINTR || got_sigterm) {
warn("error waiting for %s: %m", promptprog);
break;
}
passwd[readgood] = 0;
if (!WIFEXITED(wstat))
warn("%s terminated abnormally", promptprog);
- if (WEXITSTATUS(wstat))
- warn("%s exited with code %d", promptprog, WEXITSTATUS(status));
-
+ if (WEXITSTATUS(wstat)) {
+ warn("%s exited with code %d", promptprog, WEXITSTATUS(wstat));
+ /* code when cancel was hit in the prompt prog */
+ if (WEXITSTATUS(wstat) == 128) {
+ promptprog_refused = 1;
+ }
+ return -1;
+ }
return 1;
}
{
add_options(options);
pap_passwd_hook = promptpass;
+#ifdef USE_EAPTLS
+ eaptls_passwd_hook = promptpass;
+#endif
}
chap_check_hook = pwfd_check;
chap_passwd_hook = pwfd_passwd;
+
+#ifdef USE_EAPTLS
+ eaptls_passwd_hook = pwfd_passwd;
+#endif
}
#***********************************************************************
-DESTDIR = @DESTDIR@
+DESTDIR = $(INSTROOT)/@DESTDIR@
LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION)
VERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h)
(*old_pppol2tp_ip_updown_hook)(tunnel_id, session_id, up);
}
+ if (user_name != NULL)
+ free(user_name);
+
return;
}
fatal("PPPoL2TP kernel driver not installed");
}
+ pppol2tp_fd_str = strdup(*argv);
+ if (pppol2tp_fd_str == NULL)
+ novm("PPPoL2TP FD");
+
/* Setup option defaults. Compression options are disabled! */
modem = 0;
if ((vp = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR)))
!= (VALUE_PAIR *) NULL)
{
- strncpy (vp->name, pda->name, sizeof (vp->name));
+ strlcpy (vp->name, pda->name, NAME_LENGTH);
vp->attribute = attrid;
vp->vendorcode = vendorcode;
vp->next = (VALUE_PAIR *) NULL;
}
else
{
- sprintf (buffer, "%ld", pair->lvalue);
+ sprintf (buffer, "%d", pair->lvalue);
strncpy(value, buffer, (size_t) lv);
}
break;
SEND_DATA data;
VALUE_PAIR *adt_vp;
int result;
- time_t start_time, dtime;
+ struct timeval start_time, dtime;
char msg[4096];
int i;
int timeout = rc_conf_int("radius_timeout");
* Fill in Acct-Delay-Time
*/
- dtime = 0;
- if ((adt_vp = rc_avpair_add(&(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime, 0, VENDOR_NONE)) == NULL)
+ dtime.tv_sec = 0;
+ if ((adt_vp = rc_avpair_add(&(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime.tv_sec, 0, VENDOR_NONE)) == NULL)
return (ERROR_RC);
- start_time = time(NULL);
+ get_time(&start_time);
result = ERROR_RC;
for(i=0; (i<acctserver->max) && (result != OK_RC) && (result != BADRESP_RC)
; i++)
rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i],
acctserver->port[i], timeout, retries);
- dtime = time(NULL) - start_time;
- rc_avpair_assign(adt_vp, &dtime, 0);
+ get_time(&dtime);
+ dtime.tv_sec -= start_time.tv_sec;
+ rc_avpair_assign(adt_vp, &dtime.tv_sec, 0);
result = rc_send_server (&data, msg, NULL);
}
if (*name != '/')
strcpy(ttyname, "/dev/");
- strncat(ttyname, name, sizeof(ttyname));
+ strncat(ttyname, name, sizeof(ttyname) - strlen(ttyname) -1);
for(p = map2id_list; p; p = p->next)
if (!strcmp(ttyname, p->name)) return p->id;
*iptr = AUTH_RADIUS_FST;
else {
error("%s: auth_order: unknown keyword: %s", filename, p);
+ free(iptr);
return (-1);
}
*iptr = (*iptr) | AUTH_RADIUS_SND;
else {
error("%s: auth_order: unknown or unexpected keyword: %s", filename, p);
+ free(iptr);
return (-1);
}
}
option = find_option(optname, OT_STR);
if (option == NULL)
- fatal("rc_conf_str: unkown config option requested: %s", optname);
- return (char *)option->val;
+ fatal("rc_conf_str: unknown config option requested: %s", optname);
+ return (char *)option->val;
}
int rc_conf_int(char *optname)
option = find_option(optname, OT_INT|OT_AUO);
if (option == NULL)
- fatal("rc_conf_int: unkown config option requested: %s", optname);
+ fatal("rc_conf_int: unknown config option requested: %s", optname);
return *((int *)option->val);
}
option = find_option(optname, OT_SRV);
if (option == NULL)
- fatal("rc_conf_srv: unkown config option requested: %s", optname);
+ fatal("rc_conf_srv: unknown config option requested: %s", optname);
return (SERVER *)option->val;
}
if ((h = strtok (buffer, " \t\n")) == NULL) /* first hostname */
continue;
- memset (hostnm, '\0', AUTH_ID_LEN);
- len = strlen (h);
- if (len > AUTH_ID_LEN)
- {
- len = AUTH_ID_LEN;
- }
- strncpy (hostnm, h, (size_t) len);
- hostnm[AUTH_ID_LEN] = '\0';
+ memset (hostnm, '\0', AUTH_ID_LEN + 1);
+ strlcpy (hostnm, h, AUTH_ID_LEN + 1);
if ((s = strtok (NULL, " \t\n")) == NULL) /* and secret field */
continue;
- memset (secret, '\0', MAX_SECRET_LENGTH);
- len = strlen (s);
- if (len > MAX_SECRET_LENGTH)
- {
- len = MAX_SECRET_LENGTH;
- }
- strncpy (secret, s, (size_t) len);
- secret[MAX_SECRET_LENGTH] = '\0';
+ memset (secret, '\0', MAX_SECRET_LENGTH + 1);
+ strlcpy (secret, s, MAX_SECRET_LENGTH + 1);
if (!strchr (hostnm, '/')) /* If single name form */
{
rstate.start_time = time(NULL);
- strncpy(rstate.session_id, rc_mksid(), sizeof(rstate.session_id));
+ strlcpy(rstate.session_id, rc_mksid(), MAXSESSIONID);
rc_avpair_add(&send, PW_ACCT_SESSION_ID,
rstate.session_id, 0, VENDOR_NONE);
/* avpair.c */
-VALUE_PAIR *rc_avpair_add __P((VALUE_PAIR **, int, void *, int, int));
-int rc_avpair_assign __P((VALUE_PAIR *, void *, int));
-VALUE_PAIR *rc_avpair_new __P((int, void *, int, int));
-VALUE_PAIR *rc_avpair_gen __P((AUTH_HDR *));
-VALUE_PAIR *rc_avpair_get __P((VALUE_PAIR *, UINT4));
-VALUE_PAIR *rc_avpair_copy __P((VALUE_PAIR *));
-void rc_avpair_insert __P((VALUE_PAIR **, VALUE_PAIR *, VALUE_PAIR *));
-void rc_avpair_free __P((VALUE_PAIR *));
-int rc_avpair_parse __P((char *, VALUE_PAIR **));
-int rc_avpair_tostr __P((VALUE_PAIR *, char *, int, char *, int));
-VALUE_PAIR *rc_avpair_readin __P((FILE *));
+VALUE_PAIR *rc_avpair_add(VALUE_PAIR **, int, void *, int, int);
+int rc_avpair_assign(VALUE_PAIR *, void *, int);
+VALUE_PAIR *rc_avpair_new(int, void *, int, int);
+VALUE_PAIR *rc_avpair_gen(AUTH_HDR *);
+VALUE_PAIR *rc_avpair_get(VALUE_PAIR *, UINT4);
+VALUE_PAIR *rc_avpair_copy(VALUE_PAIR *);
+void rc_avpair_insert(VALUE_PAIR **, VALUE_PAIR *, VALUE_PAIR *);
+void rc_avpair_free(VALUE_PAIR *);
+int rc_avpair_parse(char *, VALUE_PAIR **);
+int rc_avpair_tostr(VALUE_PAIR *, char *, int, char *, int);
+VALUE_PAIR *rc_avpair_readin(FILE *);
/* buildreq.c */
-void rc_buildreq __P((SEND_DATA *, int, char *, unsigned short, int, int));
-unsigned char rc_get_seqnbr __P((void));
-int rc_auth __P((UINT4, VALUE_PAIR *, VALUE_PAIR **, char *, REQUEST_INFO *));
-int rc_auth_using_server __P((SERVER *, UINT4, VALUE_PAIR *, VALUE_PAIR **,
- char *, REQUEST_INFO *));
-int rc_auth_proxy __P((VALUE_PAIR *, VALUE_PAIR **, char *));
-int rc_acct __P((UINT4, VALUE_PAIR *));
-int rc_acct_using_server __P((SERVER *, UINT4, VALUE_PAIR *));
-int rc_acct_proxy __P((VALUE_PAIR *));
-int rc_check __P((char *, unsigned short, char *));
+void rc_buildreq(SEND_DATA *, int, char *, unsigned short, int, int);
+unsigned char rc_get_seqnbr(void);
+int rc_auth(UINT4, VALUE_PAIR *, VALUE_PAIR **, char *, REQUEST_INFO *);
+int rc_auth_using_server(SERVER *, UINT4, VALUE_PAIR *, VALUE_PAIR **,
+ char *, REQUEST_INFO *);
+int rc_auth_proxy(VALUE_PAIR *, VALUE_PAIR **, char *);
+int rc_acct(UINT4, VALUE_PAIR *);
+int rc_acct_using_server(SERVER *, UINT4, VALUE_PAIR *);
+int rc_acct_proxy(VALUE_PAIR *);
+int rc_check(char *, unsigned short, char *);
/* clientid.c */
-int rc_read_mapfile __P((char *));
-UINT4 rc_map2id __P((char *));
+int rc_read_mapfile(char *);
+UINT4 rc_map2id(char *);
/* config.c */
-int rc_read_config __P((char *));
-char *rc_conf_str __P((char *));
-int rc_conf_int __P((char *));
-SERVER *rc_conf_srv __P((char *));
-int rc_find_server __P((char *, UINT4 *, char *));
+int rc_read_config(char *);
+char *rc_conf_str(char *);
+int rc_conf_int(char *);
+SERVER *rc_conf_srv(char *);
+int rc_find_server(char *, UINT4 *, char *);
/* dict.c */
-int rc_read_dictionary __P((char *));
-DICT_ATTR *rc_dict_getattr __P((int, int));
-DICT_ATTR *rc_dict_findattr __P((char *));
-DICT_VALUE *rc_dict_findval __P((char *));
-DICT_VALUE * rc_dict_getval __P((UINT4, char *));
-VENDOR_DICT * rc_dict_findvendor __P((char *));
-VENDOR_DICT * rc_dict_getvendor __P((int));
+int rc_read_dictionary(char *);
+DICT_ATTR *rc_dict_getattr(int, int);
+DICT_ATTR *rc_dict_findattr(char *);
+DICT_VALUE *rc_dict_findval(char *);
+DICT_VALUE * rc_dict_getval(UINT4, char *);
+VENDOR_DICT * rc_dict_findvendor(char *);
+VENDOR_DICT * rc_dict_getvendor(int);
/* ip_util.c */
-UINT4 rc_get_ipaddr __P((char *));
-int rc_good_ipaddr __P((char *));
-const char *rc_ip_hostname __P((UINT4));
-UINT4 rc_own_ipaddress __P((void));
+UINT4 rc_get_ipaddr(char *);
+int rc_good_ipaddr(char *);
+const char *rc_ip_hostname(UINT4);
+UINT4 rc_own_ipaddress(void);
+UINT4 rc_own_bind_ipaddress(void);
/* sendserver.c */
-int rc_send_server __P((SEND_DATA *, char *, REQUEST_INFO *));
+int rc_send_server(SEND_DATA *, char *, REQUEST_INFO *);
/* util.c */
-void rc_str2tm __P((char *, struct tm *));
-char *rc_mksid __P((void));
-void rc_mdelay __P((int));
+void rc_str2tm(char *, struct tm *);
+char *rc_mksid(void);
+void rc_mdelay(int);
/* md5.c */
-void rc_md5_calc __P((unsigned char *, unsigned char *, unsigned int));
+void rc_md5_calc(unsigned char *, unsigned char *, unsigned int);
#endif /* RADIUSCLIENT_H */
if ((fd = fopen(radrealms_config, "r")) == NULL) {
option_error("cannot open %s", radrealms_config);
+ free(auths);
+ free(accts);
return;
- }
+ }
info("Reading %s", radrealms_config);
-
+
while ((fgets(buffer, sizeof(buffer), fd) != NULL)) {
line++;
fclose(fd);
option_error("%s: invalid line %d: %s", radrealms_config,
line, buffer);
+ free(auths);
+ free(accts);
return;
}
info("Parsing '%s' entry:", p);
fclose(fd);
option_error("%s: realm name missing on line %d: %s",
radrealms_config, line, buffer);
+ free(auths);
+ free(accts);
return;
}
fclose(fd);
option_error("%s: server address missing on line %d: %s",
radrealms_config, line, buffer);
+ free(auths);
+ free(accts);
return;
}
s->name[s->max] = strdup(p);
fclose(fd);
option_error("%s: server port missing on line %d: %s",
radrealms_config, line, buffer);
+ free(auths);
+ free(accts);
return;
}
s->port[s->max] = atoi(p);
FD_SET (sockfd, &readfds);
if (select (sockfd + 1, &readfds, NULL, NULL, &authtime) < 0)
{
- if (errno == EINTR)
+ if (errno == EINTR && !got_sigterm)
continue;
error("rc_send_server: select: %m");
memset (secret, '\0', sizeof (secret));
char *
rc_mksid (void)
{
- static char buf[15];
+ static char buf[32];
static unsigned short int cnt = 0;
- sprintf (buf, "%08lX%04X%02hX",
+ slprintf(buf, sizeof(buf), "%08lX%04X%02hX",
(unsigned long int) time (NULL),
(unsigned int) getpid (),
cnt & 0xFF);
$(CC) $(LDFLAGS) -o pppoe-discovery pppoe-discovery.o debug.o
pppoe-discovery.o: pppoe-discovery.c
- $(CC) $(CFLAGS) -c -o pppoe-discovery.o pppoe-discovery.c
+ $(CC) $(CFLAGS) -I../../.. -c -o pppoe-discovery.o pppoe-discovery.c
debug.o: debug.c
- $(CC) $(CFLAGS) -c -o debug.o debug.c
+ $(CC) $(CFLAGS) -I../../.. -c -o debug.o debug.c
rp-pppoe.so: plugin.o discovery.o if.o common.o
$(CC) $(LDFLAGS) -o rp-pppoe.so -shared plugin.o discovery.o if.o common.o
/* Step through the tags */
curTag = packet->payload;
- while(curTag - packet->payload < len) {
+ while (curTag - packet->payload + TAG_HDR_SIZE <= len) {
/* Alignment is not guaranteed, so do this by hand... */
tagType = (curTag[0] << 8) + curTag[1];
tagLen = (curTag[2] << 8) + curTag[3];
conn->session = 0;
/* If we're using Host-Uniq, copy it over */
- if (conn->useHostUniq) {
- PPPoETag hostUniq;
- pid_t pid = getpid();
- hostUniq.type = htons(TAG_HOST_UNIQ);
- hostUniq.length = htons(sizeof(pid));
- memcpy(hostUniq.payload, &pid, sizeof(pid));
- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
- cursor += sizeof(pid) + TAG_HDR_SIZE;
- plen += sizeof(pid) + TAG_HDR_SIZE;
+ if (conn->hostUniq.length) {
+ int len = ntohs(conn->hostUniq.length);
+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
+ cursor += len + TAG_HDR_SIZE;
+ plen += len + TAG_HDR_SIZE;
}
/* Copy error message */
/* Define if you have the <netpacket/packet.h> header file. */
#define HAVE_NETPACKET_PACKET_H 1
-/* Define if you have the <sys/cdefs.h> header file. */
-#define HAVE_SYS_CDEFS_H 1
-
/* Define if you have the <sys/dlpi.h> header file. */
/* #undef HAVE_SYS_DLPI_H */
{
struct timeval now;
- if (gettimeofday(&now, NULL) < 0) {
- error("gettimeofday: %m");
+ if (get_time(&now) < 0) {
+ error("get_time: %m");
return 0;
}
parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data,
void *extra)
{
- int *val = (int *) extra;
- if (type == TAG_HOST_UNIQ && len == sizeof(pid_t)) {
- pid_t tmp;
- memcpy(&tmp, data, len);
- if (tmp == getpid()) {
- *val = 1;
- }
- }
+ PPPoETag *tag = extra;
+
+ if (type == TAG_HOST_UNIQ && len == ntohs(tag->length))
+ tag->length = memcmp(data, tag->payload, len);
}
/**********************************************************************
static int
packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet)
{
- int forMe = 0;
+ PPPoETag hostUniq = conn->hostUniq;
/* If packet is not directed to our MAC address, forget it */
if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
/* If we're not using the Host-Unique tag, then accept the packet */
- if (!conn->useHostUniq) return 1;
+ if (!conn->hostUniq.length) return 1;
- parsePacket(packet, parseForHostUniq, &forMe);
- return forMe;
+ parsePacket(packet, parseForHostUniq, &hostUniq);
+ return !hostUniq.length;
}
/**********************************************************************
}
/* If we're using Host-Uniq, copy it over */
- if (conn->useHostUniq) {
- PPPoETag hostUniq;
- pid_t pid = getpid();
- hostUniq.type = htons(TAG_HOST_UNIQ);
- hostUniq.length = htons(sizeof(pid));
- memcpy(hostUniq.payload, &pid, sizeof(pid));
- CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE);
- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
- cursor += sizeof(pid) + TAG_HDR_SIZE;
- plen += sizeof(pid) + TAG_HDR_SIZE;
+ if (conn->hostUniq.length) {
+ int len = ntohs(conn->hostUniq.length);
+ CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
+ cursor += len + TAG_HDR_SIZE;
+ plen += len + TAG_HDR_SIZE;
}
/* Add our maximum MTU/MRU */
conn->seenMaxPayload = 0;
conn->error = 0;
- if (gettimeofday(&expire_at, NULL) < 0) {
- error("gettimeofday (waitForPADO): %m");
+ if (get_time(&expire_at) < 0) {
+ error("get_time (waitForPADO): %m");
return;
}
expire_at.tv_sec += timeout;
while(1) {
r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
- if (r >= 0 || errno != EINTR) break;
+ if (r >= 0 || errno != EINTR || got_sigterm) break;
}
if (r < 0) {
error("select (waitForPADO): %m");
cursor += namelen + TAG_HDR_SIZE;
/* If we're using Host-Uniq, copy it over */
- if (conn->useHostUniq) {
- PPPoETag hostUniq;
- pid_t pid = getpid();
- hostUniq.type = htons(TAG_HOST_UNIQ);
- hostUniq.length = htons(sizeof(pid));
- memcpy(hostUniq.payload, &pid, sizeof(pid));
- CHECK_ROOM(cursor, packet.payload, sizeof(pid)+TAG_HDR_SIZE);
- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
- cursor += sizeof(pid) + TAG_HDR_SIZE;
- plen += sizeof(pid) + TAG_HDR_SIZE;
+ if (conn->hostUniq.length) {
+ int len = ntohs(conn->hostUniq.length);
+ CHECK_ROOM(cursor, packet.payload, len+TAG_HDR_SIZE);
+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
+ cursor += len + TAG_HDR_SIZE;
+ plen += len + TAG_HDR_SIZE;
}
/* Add our maximum MTU/MRU */
PPPoEPacket packet;
int len;
- if (gettimeofday(&expire_at, NULL) < 0) {
- error("gettimeofday (waitForPADS): %m");
+ if (get_time(&expire_at) < 0) {
+ error("get_time (waitForPADS): %m");
return;
}
expire_at.tv_sec += timeout;
while(1) {
r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
- if (r >= 0 || errno != EINTR) break;
+ if (r >= 0 || errno != EINTR || got_sigterm) break;
}
if (r < 0) {
error("select (waitForPADS): %m");
do {
padiAttempts++;
- if (padiAttempts > MAX_PADI_ATTEMPTS) {
+ if (got_sigterm || padiAttempts > conn->discoveryAttempts) {
warn("Timeout waiting for PADO packets");
close(conn->discoverySocket);
conn->discoverySocket = -1;
timeout = conn->discoveryTimeout;
do {
padrAttempts++;
- if (padrAttempts > MAX_PADI_ATTEMPTS) {
+ if (got_sigterm || padrAttempts > conn->discoveryAttempts) {
warn("Timeout waiting for PADS packets");
close(conn->discoverySocket);
conn->discoverySocket = -1;
}
/* We're done. */
+ close(conn->discoverySocket);
+ conn->discoverySocket = -1;
conn->discoveryState = STATE_SESSION;
return;
}
#include <linux/if_packet.h>
#endif
-#ifdef HAVE_NET_ETHERNET_H
-#include <net/ethernet.h>
-#endif
-
#ifdef HAVE_ASM_TYPES_H
#include <asm/types.h>
#endif
/* Fill in hardware address */
if (hwaddr) {
- strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
error("Can't get hardware address for %s: %m", ifname);
close(fd);
}
/* Sanity check on MTU */
- strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) {
error("Can't get MTU for %s: %m", ifname);
} else if (ifr.ifr_mtu < ETH_DATA_LEN) {
sa.sll_family = AF_PACKET;
sa.sll_protocol = htons(type);
- strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
error("Could not get interface index for %s: %m", ifname);
close(fd);
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
-#include <net/ethernet.h>
#include <net/if_arp.h>
#include <linux/ppp_defs.h>
#include <linux/if_pppox.h>
static int printACNames = 0;
static char *pppoe_reqd_mac = NULL;
unsigned char pppoe_reqd_mac_addr[6];
+static char *host_uniq;
+static int pppoe_padi_timeout = PADI_TIMEOUT;
+static int pppoe_padi_attempts = MAX_PADI_ATTEMPTS;
static int PPPoEDevnameHook(char *cmd, char **argv, int doit);
static option_t Options[] = {
"Be verbose about discovered access concentrators"},
{ "pppoe-mac", o_string, &pppoe_reqd_mac,
"Only connect to specified MAC address" },
+ { "host-uniq", o_string, &host_uniq,
+ "Set the Host-Uniq to the supplied hex string" },
+ { "pppoe-padi-timeout", o_int, &pppoe_padi_timeout,
+ "Initial timeout for discovery packets in seconds" },
+ { "pppoe-padi-attempts", o_int, &pppoe_padi_attempts,
+ "Number of discovery attempts" },
{ NULL }
};
int (*OldDevnameHook)(char *cmd, char **argv, int doit) = NULL;
conn->ifName = devnam;
conn->discoverySocket = -1;
conn->sessionSocket = -1;
- conn->useHostUniq = 1;
conn->printACNames = printACNames;
- conn->discoveryTimeout = PADI_TIMEOUT;
+ conn->discoveryTimeout = pppoe_padi_timeout;
+ conn->discoveryAttempts = pppoe_padi_attempts;
return 1;
}
error("Can't get MTU for %s: %m", conn->ifName);
goto errout;
}
- strncpy(ifr.ifr_name, conn->ifName, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, conn->ifName, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {
error("Can't get MTU for %s: %m", conn->ifName);
close(s);
if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD)
lcp_wantoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD;
+ if (host_uniq) {
+ if (!parseHostUniq(host_uniq, &conn->hostUniq))
+ fatal("Illegal value for host-uniq option");
+ } else {
+ /* if a custom host-uniq is not supplied, use our PID */
+ pid_t pid = getpid();
+ conn->hostUniq.type = htons(TAG_HOST_UNIQ);
+ conn->hostUniq.length = htons(sizeof(pid));
+ memcpy(conn->hostUniq.payload, &pid, sizeof(pid));
+ }
+
conn->acName = acName;
conn->serviceName = pppd_pppoe_service;
strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
static void
PPPOEDeviceOptions(void)
{
- char buf[256];
- snprintf(buf, 256, _PATH_ETHOPT "%s", devnam);
+ char buf[MAXPATHLEN];
+
+ strlcpy(buf, _PATH_ETHOPT, MAXPATHLEN);
+ strlcat(buf, devnam, MAXPATHLEN);
if (!options_from_file(buf, 0, 0, 1))
exit(EXIT_OPTION_ERROR);
/* Try getting interface index */
if (r) {
- strncpy(ifr.ifr_name, cmd, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, cmd, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
r = 0;
} else {
/* Close socket */
close(fd);
if (r && doit) {
- strncpy(devnam, cmd, sizeof(devnam));
+ strlcpy(devnam, cmd, sizeof(devnam));
if (the_channel != &pppoe_channel) {
the_channel = &pppoe_channel;
#include <unistd.h>
#include <errno.h>
#include <string.h>
+#include <time.h>
#include "pppoe.h"
#include <linux/if_packet.h>
#endif
-#ifdef HAVE_NET_ETHERNET_H
-#include <net/ethernet.h>
-#endif
-
#ifdef HAVE_ASM_TYPES_H
#include <asm/types.h>
#endif
sa.sll_family = AF_PACKET;
sa.sll_protocol = htons(type);
- strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ ifr.ifr_name[IFNAMSIZ - 1] = 0;
if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
fatalSys("ioctl(SIOCFIGINDEX): Could not get interface index");
}
parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data,
void *extra)
{
- int *val = (int *) extra;
- if (type == TAG_HOST_UNIQ && len == sizeof(pid_t)) {
- pid_t tmp;
- memcpy(&tmp, data, len);
- if (tmp == getpid()) {
- *val = 1;
- }
- }
+ PPPoETag *tag = extra;
+
+ if (type == TAG_HOST_UNIQ && len == ntohs(tag->length))
+ tag->length = memcmp(data, tag->payload, len);
}
/**********************************************************************
int
packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet)
{
- int forMe = 0;
+ PPPoETag hostUniq = conn->hostUniq;
/* If packet is not directed to our MAC address, forget it */
if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0;
/* If we're not using the Host-Unique tag, then accept the packet */
- if (!conn->useHostUniq) return 1;
+ if (!conn->hostUniq.length) return 1;
- parsePacket(packet, parseForHostUniq, &forMe);
- return forMe;
+ parsePacket(packet, parseForHostUniq, &hostUniq);
+ return !hostUniq.length;
}
/**********************************************************************
cursor += namelen + TAG_HDR_SIZE;
/* If we're using Host-Uniq, copy it over */
- if (conn->useHostUniq) {
- PPPoETag hostUniq;
- pid_t pid = getpid();
- hostUniq.type = htons(TAG_HOST_UNIQ);
- hostUniq.length = htons(sizeof(pid));
- memcpy(hostUniq.payload, &pid, sizeof(pid));
- CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE);
- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE);
- cursor += sizeof(pid) + TAG_HDR_SIZE;
- plen += sizeof(pid) + TAG_HDR_SIZE;
+ if (conn->hostUniq.length) {
+ int len = ntohs(conn->hostUniq.length);
+ CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE);
+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE);
+ cursor += len + TAG_HDR_SIZE;
+ plen += len + TAG_HDR_SIZE;
}
packet.length = htons(plen);
conn->discoveryTimeout = PADI_TIMEOUT;
conn->discoveryAttempts = MAX_PADI_ATTEMPTS;
- while ((opt = getopt(argc, argv, "I:D:VUQS:C:t:a:h")) > 0) {
+ while ((opt = getopt(argc, argv, "I:D:VUQS:C:W:t:a:h")) > 0) {
switch(opt) {
case 'S':
conn->serviceName = xstrdup(optarg);
}
break;
case 'U':
- conn->useHostUniq = 1;
+ if(conn->hostUniq.length) {
+ fprintf(stderr, "-U and -W are mutually exclusive\n");
+ exit(EXIT_FAILURE);
+ } else {
+ pid_t pid = getpid();
+ conn->hostUniq.type = htons(TAG_HOST_UNIQ);
+ conn->hostUniq.length = htons(sizeof(pid));
+ memcpy(conn->hostUniq.payload, &pid, sizeof(pid));
+ }
+ break;
+ case 'W':
+ if(conn->hostUniq.length) {
+ fprintf(stderr, "-U and -W are mutually exclusive\n");
+ exit(EXIT_FAILURE);
+ }
+ if (!parseHostUniq(optarg, &conn->hostUniq)) {
+ fprintf(stderr, "Invalid host-uniq argument: %s\n", optarg);
+ exit(EXIT_FAILURE);
+ }
break;
case 'D':
conn->debugFile = fopen(optarg, "w");
" -S name -- Set desired service name.\n"
" -C name -- Set desired access concentrator name.\n"
" -U -- Use Host-Unique to allow multiple PPPoE sessions.\n"
+ " -W hexvalue -- Set the Host-Unique to the supplied hex string.\n"
" -h -- Print usage information.\n");
fprintf(stderr, "\nVersion " RP_VERSION "\n");
}
#include "config.h"
-#if defined(HAVE_NETPACKET_PACKET_H) || defined(HAVE_LINUX_IF_PACKET_H)
-#define _POSIX_SOURCE 1 /* For sigaction defines */
-#endif
-
#include <stdio.h> /* For FILE */
#include <sys/types.h> /* For pid_t */
+#include <ctype.h>
+#include <string.h>
+
+#include "pppd/pppd.h" /* For error */
/* How do we access raw Ethernet devices? */
#undef USE_LINUX_PACKET
#error Unknown method for accessing raw Ethernet frames
#endif
-#ifdef HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_LINUX_IF_ETHER_H
#include <linux/if_ether.h>
-#endif
+#else
#ifdef HAVE_NETINET_IF_ETHER_H
#include <sys/types.h>
#include <netinet/if_ether.h>
#endif
#endif
-
+#endif
/* Ethernet frame types according to RFC 2516 */
#define ETH_PPPOE_DISCOVERY 0x8863
char *serviceName; /* Desired service name, if any */
char *acName; /* Desired AC name, if any */
int synchronous; /* Use synchronous PPP */
- int useHostUniq; /* Use Host-Uniq tag */
+ PPPoETag hostUniq; /* Use Host-Uniq tag */
int printACNames; /* Just print AC names */
FILE *debugFile; /* Debug file for dumping packets */
int numPADOs; /* Number of PADO packets received */
void (*printer)(void *, char *, ...), void *arg);
void pppoe_log_packet(const char *prefix, PPPoEPacket *packet);
+static inline int parseHostUniq(const char *uniq, PPPoETag *tag)
+{
+ unsigned i, len = strlen(uniq);
+
+#define hex(x) \
+ (((x) <= '9') ? ((x) - '0') : \
+ (((x) <= 'F') ? ((x) - 'A' + 10) : \
+ ((x) - 'a' + 10)))
+
+ if (!len || len % 2 || len / 2 > sizeof(tag->payload))
+ return 0;
+
+ for (i = 0; i < len; i += 2) {
+ if (!isxdigit(uniq[i]) || !isxdigit(uniq[i+1]))
+ return 0;
+
+ tag->payload[i / 2] = (char)(hex(uniq[i]) << 4 | hex(uniq[i+1]));
+ }
+
+#undef hex
+
+ tag->type = htons(TAG_HOST_UNIQ);
+ tag->length = htons(len / 2);
+ return 1;
+}
+
#define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0);
#define CHECK_ROOM(cursor, start, len) \
/* parent */
if (close(child_out[0]) == -1) {
+ close(child_in[1]);
notice("error closing pipe?!? for child OUT[0]");
return NOT_AUTHENTICATED;
}
return NOT_AUTHENTICATED;
}
- while ((wait(&status) == -1) && errno == EINTR)
+ while ((wait(&status) == -1) && errno == EINTR && !got_sigterm)
;
if ((authenticated == AUTHENTICATED) && nt_key && !got_user_session_key) {
#include "pppcrypt.h"
static u_char
-Get7Bits(input, startBit)
-u_char *input;
-int startBit;
+Get7Bits(u_char *input, int startBit)
{
unsigned int word;
}
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 */
+MakeKey(u_char *key, u_char *des_key)
{
+ /* key IN 56 bit DES key missing parity bits */
+ /* 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);
* Note that the low-order "bit" is always ignored by by setkey()
*/
static void
-Expand(in, out)
-u_char *in;
-u_char *out;
+Expand(u_char *in, u_char *out)
{
int j, c;
int i;
/* The inverse of Expand
*/
static void
-Collapse(in, out)
-u_char *in;
-u_char *out;
+Collapse(u_char *in, u_char *out)
{
int j;
int i;
}
bool
-DesSetkey(key)
-u_char *key;
+DesSetkey(u_char *key)
{
u_char des_key[8];
u_char crypt_key[66];
}
bool
-DesEncrypt(clear, cipher)
-u_char *clear; /* IN 8 octets */
-u_char *cipher; /* OUT 8 octets */
+DesEncrypt(u_char *clear, u_char *cipher)
{
u_char des_input[66];
}
bool
-DesDecrypt(cipher, clear)
-u_char *cipher; /* IN 8 octets */
-u_char *clear; /* OUT 8 octets */
+DesDecrypt(u_char *cipher, u_char *clear)
{
u_char des_input[66];
static DES_key_schedule key_schedule;
bool
-DesSetkey(key)
-u_char *key;
+DesSetkey(u_char *key)
{
DES_cblock des_key;
MakeKey(key, des_key);
}
bool
-DesEncrypt(clear, cipher)
-u_char *clear; /* IN 8 octets */
-u_char *cipher; /* OUT 8 octets */
+DesEncrypt(u_char *clear, u_char *cipher)
{
DES_ecb_encrypt((DES_cblock *)clear, (DES_cblock *)cipher,
&key_schedule, 1);
}
bool
-DesDecrypt(cipher, clear)
-u_char *cipher; /* IN 8 octets */
-u_char *clear; /* OUT 8 octets */
+DesDecrypt(u_char *cipher, u_char *clear)
{
DES_ecb_encrypt((DES_cblock *)cipher, (DES_cblock *)clear,
&key_schedule, 0);
#include <des.h>
#endif
-extern bool DesSetkey __P((u_char *));
-extern bool DesEncrypt __P((u_char *, u_char *));
-extern bool DesDecrypt __P((u_char *, u_char *));
+extern bool DesSetkey(u_char *);
+extern bool DesEncrypt(u_char *, u_char *);
+extern bool DesDecrypt(u_char *, u_char *);
#endif /* PPPCRYPT_H */
value of -1, the route is only added if there is no default route at
all.
.TP
+.B defaultroute6
+Add a default IPv6 route to the system routing tables, using the peer as
+the gateway, when IPv6CP negotiation is successfully completed.
+This entry is removed when the PPP connection is broken. This option
+is privileged if the \fInodefaultroute6\fR option has been specified.
+.TP
.B disconnect \fIscript
Execute the command specified by \fIscript\fR, by passing it to a
shell, after
compression in the corresponding direction. Use \fInobsdcomp\fR or
\fIbsdcomp 0\fR to disable BSD-Compress compression entirely.
.TP
+.B ca \fIca-file
+(EAP-TLS) Use the file \fIca-file\fR as the X.509 Certificate Authority
+(CA) file (in PEM format), needed for setting up an EAP-TLS connection.
+This option is used on the client-side in conjunction with the \fBcert\fR
+and \fBkey\fR options.
+.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,
bi-directional flow control. The sacrifice is that this flow
control mode does not permit using DTR as a modem control line.
.TP
+.B cert \fIcertfile
+(EAP-TLS) Use the file \fIcertfile\fR as the X.509 certificate (in PEM
+format), needed for setting up an EAP-TLS connection. This option is
+used on the client-side in conjunction with the \fBca\fR and
+\fBkey\fR options.
+.TP
.B chap\-interval \fIn
If this option is given, pppd will rechallenge the peer every \fIn\fR
seconds.
Set the CHAP restart interval (retransmission timeout for challenges)
to \fIn\fR seconds (default 3).
.TP
+.B chap-timeout \fIn
+Set timeout for CHAP authentication by peer to \fIn\fR seconds (default 60).
+.TP
.B child\-timeout \fIn
When exiting, wait for up to \fIn\fR seconds for any child processes
(such as the command specified with the \fBpty\fR command) to exit
1000 (1 second). This wait period only applies if the \fBconnect\fR
or \fBpty\fR option is used.
.TP
+.B crl \fIfilename
+(EAP-TLS) Use the file \fIfilename\fR as the Certificate Revocation List
+to check for the validity of the peer's certificate. This option is not
+mandatory for setting up an EAP-TLS connection. Also see the \fBcrl-dir\fR
+option.
+.TP
+.B crl-dir \fIdirectory
+(EAP-TLS) Use the directory \fIdirectory\fR to scan for CRL files in
+has format ($hash.r0) to check for the validity of the peer's certificate.
+This option is not mandatory for setting up an EAP-TLS connection.
+Also see the \fBcrl\fR option.
+.TP
.B debug
Enables connection debugging facilities.
If this option is given, pppd will log the contents of all
interface identifier, even if the local IPv6 interface identifier
was specified in an option.
.TP
+.B ipv6cp\-accept\-remote
+With this option, pppd will accept the peer's idea of its (remote)
+IPv6 interface identifier, even if the remote IPv6 interface
+identifier was specified in an option.
+.TP
.B ipv6cp\-max\-configure \fIn
Set the maximum number of IPv6CP configure-request transmissions to
\fIn\fR (default 10).
the kernel are logged by syslog(1) to a file as directed in the
/etc/syslog.conf configuration file.
.TP
+.B key \fIkeyfile
+(EAP-TLS) Use the file \fIkeyfile\fR as the private key file (in PEM
+format), needed for setting up an EAP-TLS connection. This option is
+used on the client-side in conjunction with the \fBca\fR and
+\fBcert\fR options.
+.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
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\-adaptive
+If this option is used with the \fIlcp\-echo\-failure\fR option then
+pppd will send LCP echo\-request frames only if no traffic was received
+from the peer since the last echo\-request was sent.
+.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
Disable Address/Control compression in both directions (send and
receive).
.TP
+.B need-peer-eap
+(EAP-TLS) Require the peer to verify our authentication credentials.
+.TP
.B noauth
Do not require the peer to authenticate itself. This option is
privileged.
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 nodefaultroute6
+Disable the \fIdefaultroute6\fR option. The system administrator who
+wishes to prevent users from adding a default route 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.
stored in ~/.ppp_pseudonym first as the identity, and save in this
file any pseudonym offered by the peer during authentication.
.TP
+.B stop\-bits \fIn
+Set the number of stop bits for the serial port. Valid values are 1 or 2.
+The default value is 1.
+.TP
.B sync
Use synchronous HDLC serial encoding instead of asynchronous.
The device used by pppd with this option must have sync support.
.B xonxoff
Use software flow control (i.e. XON/XOFF) to control the flow of data on
the serial port.
+.SH PPPOE OPTIONS
+To establish PPP link over Ethernet (PPPoE) it is needed to load pppd's
+\fBplugin rp-pppoe.so\fR and then specify option \fBnic-\fIinterface\fR
+instead of modem options \fIttyname\fR and \fIspeed\fR.
+Recognized pppd's PPPoE options are:
+.TP
+.B nic-\fIinterface
+Use the ethernet device \fIinterface\fR to communicate with the peer.
+For example, establishing PPPoE link on \fIeth0\fR interface is done
+by specifying ppp'd option \fBnic-eth0\fR. Prefix \fBnic-\fR for this
+option may be avoided if interface name is unambiguous and does not
+look like any other pppd's option.
+.TP
+.B rp_pppoe_service \fIname
+Connect to specified PPPoE service name.
+.TP
+.B rp_pppoe_ac \fIname
+Connect to specified PPPoE access concentrator name.
+.TP
+.B rp_pppoe_sess \fIsessid\fP:\fImacaddr
+Attach to existing PPPoE session.
+.TP
+.B rp_pppoe_verbose \fIn
+Be verbose about discovered access concentrators.
+.TP
+.B pppoe-mac \fImacaddr
+Connect to specified MAC address.
+.TP
+.B host-uniq \fIstring
+Set the PPPoE Host-Uniq tag to the supplied hex string.
+By default PPPoE Host-Uniq tag is set to the pppd's process PID.
+.TP
+.B pppoe-padi-timeout \fIn
+Initial timeout for discovery packets in seconds (default 5).
+.TP
+.B pppoe-padi-attempts \fIn
+Number of discovery attempts (default 3).
.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
.I PPP in HDLC-like Framing.
July 1994.
.TP
+.B RFC1990
+Sklower, K.; et al.,
+.I The PPP Multilink Protocol (MP).
+August 1996.
+.TP
.B RFC2284
Blunk, L.; Vollbrecht, J.,
.I PPP Extensible Authentication Protocol (EAP).
#define __PPPD_H__
#include <stdio.h> /* for FILE */
+#include <stdlib.h> /* for encrypt */
+#include <unistd.h> /* for setkey */
+#include <stdarg.h>
#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 <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
#define EPD_MAGIC 4
#define EPD_PHONENUM 5
-typedef void (*notify_func) __P((void *, int));
-typedef void (*printer_func) __P((void *, char *, ...));
+typedef void (*notify_func)(void *, int);
+typedef void (*printer_func)(void *, char *, ...);
struct notifier {
struct notifier *next;
* Global variables.
*/
+extern int got_sigterm; /* SIGINT or SIGTERM was received */
extern int hungup; /* Physical layer has disconnected */
extern int ifunit; /* Interface unit number */
extern char ifname[]; /* Interface name */
extern bool dryrun; /* check everything, print options, exit */
extern int child_wait; /* # seconds to wait for children at end */
+#ifdef USE_EAPTLS
+extern char *crl_dir;
+extern char *crl_file;
+extern char *max_tls_version;
+#endif /* USE_EAPTLS */
+
#ifdef MAXOCTETS
extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */
extern int maxoctets_dir; /* Direction :
struct protent {
u_short protocol; /* PPP protocol number */
/* Initialization procedure */
- void (*init) __P((int unit));
+ void (*init)(int unit);
/* Process a received packet */
- void (*input) __P((int unit, u_char *pkt, int len));
+ void (*input)(int unit, u_char *pkt, int len);
/* Process a received protocol-reject */
- void (*protrej) __P((int unit));
+ void (*protrej)(int unit);
/* Lower layer has come up */
- void (*lowerup) __P((int unit));
+ void (*lowerup)(int unit);
/* Lower layer has gone down */
- void (*lowerdown) __P((int unit));
+ void (*lowerdown)(int unit);
/* Open the protocol */
- void (*open) __P((int unit));
+ void (*open)(int unit);
/* Close the protocol */
- void (*close) __P((int unit, char *reason));
+ void (*close)(int unit, char *reason);
/* Print a packet in readable form */
- int (*printpkt) __P((u_char *pkt, int len, printer_func printer,
- void *arg));
+ int (*printpkt)(u_char *pkt, int len, printer_func printer, void *arg);
/* Process a received data packet */
- void (*datainput) __P((int unit, u_char *pkt, int len));
+ void (*datainput)(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));
+ void (*check_options)(void);
/* Configure interface for demand-dial */
- int (*demand_conf) __P((int unit));
+ int (*demand_conf)(int unit);
/* Say whether to bring up link for this pkt */
- int (*active_pkt) __P((u_char *pkt, int len));
+ int (*active_pkt)(u_char *pkt, int len);
};
/* Table of pointers to supported protocols */
/* set of options for this channel */
option_t *options;
/* find and process a per-channel options file */
- void (*process_extra_options) __P((void));
+ void (*process_extra_options)(void);
/* check all the options that have been given */
- void (*check_options) __P((void));
+ void (*check_options)(void);
/* get the channel ready to do PPP, return a file descriptor */
- int (*connect) __P((void));
+ int (*connect)(void);
/* we're finished with the channel */
- void (*disconnect) __P((void));
+ void (*disconnect)(void);
/* put the channel into PPP `mode' */
- int (*establish_ppp) __P((int));
+ int (*establish_ppp)(int);
/* take the channel out of PPP `mode', restore loopback if demand */
- void (*disestablish_ppp) __P((int));
+ void (*disestablish_ppp)(int);
/* set the transmit-side PPP parameters of the channel */
- void (*send_config) __P((int, u_int32_t, int, int));
+ void (*send_config)(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));
+ void (*recv_config)(int, u_int32_t, int, int);
/* cleanup on error or normal exit */
- void (*cleanup) __P((void));
+ void (*cleanup)(void);
/* close the device, called in children after fork */
- void (*close) __P((void));
+ void (*close)(void);
};
extern struct channel *the_channel;
*/
/* 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));
+void set_ifunit(int); /* set stuff that depends on ifunit */
+void detach(void); /* Detach from controlling tty */
+void die(int); /* Cleanup and exit */
+void quit(void); /* like die(1) */
+void novm(char *); /* Say we ran out of memory, and die */
+void timeout(void (*func)(void *), void *arg, int s, int us);
/* Call func(arg) after s.us seconds */
-void untimeout __P((void (*func)(void *), void *arg));
+void untimeout(void (*func)(void *), void *arg);
/* Cancel call to func(arg) */
-void record_child __P((int, char *, void (*) (void *), void *, int));
-pid_t safe_fork __P((int, int, int)); /* Fork & close stuff in child */
-int device_script __P((char *cmd, int in, int out, int dont_wait));
+void record_child(int, char *, void (*) (void *), void *, int);
+pid_t safe_fork(int, int, int); /* Fork & close stuff in child */
+int device_script(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, int wait));
+pid_t run_program(char *prog, char **args, int must_exist,
+ void (*done)(void *), void *arg, int wait);
/* Run program prog with args in child */
-void reopen_log __P((void)); /* (re)open the connection to syslog */
-void print_link_stats __P((void)); /* Print stats, if available */
-void reset_link_stats __P((int)); /* Reset (init) stats when link goes up */
-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));
-int ppp_send_config __P((int, int, u_int32_t, int, int));
-int ppp_recv_config __P((int, int, u_int32_t, int, int));
-const char *protocol_name __P((int));
-void remove_pidfiles __P((void));
-void lock_db __P((void));
-void unlock_db __P((void));
+void reopen_log(void); /* (re)open the connection to syslog */
+void print_link_stats(void); /* Print stats, if available */
+void reset_link_stats(int); /* Reset (init) stats when link goes up */
+void update_link_stats(int); /* Get stats at link termination */
+void script_setenv(char *, char *, int); /* set script env var */
+void script_unsetenv(char *); /* unset script env var */
+void new_phase(int); /* signal start of new phase */
+void add_notifier(struct notifier **, notify_func, void *);
+void remove_notifier(struct notifier **, notify_func, void *);
+void notify(struct notifier *, int);
+int ppp_send_config(int, int, u_int32_t, int, int);
+int ppp_recv_config(int, int, u_int32_t, int, int);
+const char *protocol_name(int);
+void remove_pidfiles(void);
+void lock_db(void);
+void unlock_db(void);
/* Procedures exported from tty.c. */
-void tty_init __P((void));
+void tty_init(void);
/* Procedures exported from utils.c. */
-void log_packet __P((u_char *, int, char *, int));
+void log_packet(u_char *, int, char *, int);
/* Format a packet and log it with syslog */
-void print_string __P((char *, int, printer_func, void *));
+void print_string(char *, int, printer_func, 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((const 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 */
-void dump_packet __P((const char *, u_char *, int));
+int slprintf(char *, int, char *, ...); /* sprintf++ */
+int vslprintf(char *, int, char *, va_list); /* vsprintf++ */
+size_t strlcpy(char *, const char *, size_t); /* safe strcpy */
+size_t strlcat(char *, const char *, size_t); /* safe strncpy */
+void dbglog(char *, ...); /* log a debug message */
+void info(char *, ...); /* log an informational message */
+void notice(char *, ...); /* log a notice-level message */
+void warn(char *, ...); /* log a warning message */
+void error(char *, ...); /* log an error message */
+void fatal(char *, ...); /* log an error message and die(1) */
+void init_pr_log(const char *, int); /* initialize for using pr_log */
+void pr_log(void *, char *, ...); /* printer fn, output to syslog */
+void end_pr_log(void); /* finish up after using pr_log */
+void dump_packet(const char *, u_char *, int);
/* dump packet to debug log if interesting */
-ssize_t complete_read __P((int, void *, size_t));
+ssize_t complete_read(int, void *, size_t);
/* read a complete buffer */
/* Procedures exported from auth.c */
-void link_required __P((int)); /* we are starting to use the link */
-void start_link __P((int)); /* bring the link up now */
-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 upper_layers_down __P((int));/* take all NCPs down */
-void link_established __P((int)); /* the link is up; authenticate now */
-void start_networks __P((int)); /* start all the network control protos */
-void continue_networks __P((int)); /* start network [ip, etc] 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));
+void link_required(int); /* we are starting to use the link */
+void start_link(int); /* bring the link up now */
+void link_terminated(int); /* we are finished with the link */
+void link_down(int); /* the LCP layer has left the Opened state */
+void upper_layers_down(int);/* take all NCPs down */
+void link_established(int); /* the link is up; authenticate now */
+void start_networks(int); /* start all the network control protos */
+void continue_networks(int); /* start network [ip, etc] control protos */
+void np_up(int, int); /* a network protocol has come up */
+void np_down(int, int); /* a network protocol has gone down */
+void np_finished(int, int); /* a network protocol no longer needs link */
+void auth_peer_fail(int, int);
/* peer failed to authenticate itself */
-void auth_peer_success __P((int, int, int, char *, int));
+void auth_peer_success(int, int, int, char *, int);
/* peer successfully authenticated itself */
-void auth_withpeer_fail __P((int, int));
+void auth_withpeer_fail(int, int);
/* we failed to authenticate ourselves */
-void auth_withpeer_success __P((int, int, int));
+void auth_withpeer_success(int, int, int);
/* we successfully authenticated ourselves */
-void auth_check_options __P((void));
+void auth_check_options(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 **));
+void auth_reset(int); /* check what secrets we have */
+int check_passwd(int, char *, int, char *, int, char **);
/* Check peer-supplied username/password */
-int get_secret __P((int, char *, char *, char *, int *, int));
+int get_secret(int, char *, char *, char *, int *, int);
/* get "secret" for chap */
-int get_srp_secret __P((int unit, char *client, char *server, char *secret,
- int am_server));
-int auth_ip_addr __P((int, u_int32_t));
+int get_srp_secret(int unit, char *client, char *server, char *secret,
+ int am_server);
+int auth_ip_addr(int, u_int32_t);
/* check if IP address is authorized */
-int auth_number __P((void)); /* check if remote number is authorized */
-int bad_ip_adrs __P((u_int32_t));
+int auth_number(void); /* check if remote number is authorized */
+int bad_ip_adrs(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? */
+void demand_conf(void); /* config interface(s) for demand-dial */
+void demand_block(void); /* set all NPs to queue up packets */
+void demand_unblock(void); /* set all NPs to pass packets */
+void demand_discard(void); /* set all NPs to discard packets */
+void demand_rexmit(int); /* retransmit saved frames for an NP */
+int loop_chars(unsigned char *, int); /* process chars from loopback */
+int loop_frame(unsigned char *, int); /* should we bring link up? */
/* Procedures exported from multilink.c */
#ifdef HAVE_MULTILINK
-void mp_check_options __P((void)); /* Check multilink-related options */
-int mp_join_bundle __P((void)); /* join our link to an appropriate bundle */
-void mp_exit_bundle __P((void)); /* have disconnected our link from bundle */
-void mp_bundle_terminated __P((void));
-char *epdisc_to_str __P((struct epdisc *)); /* string from endpoint discrim. */
-int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */
+void mp_check_options(void); /* Check multilink-related options */
+int mp_join_bundle(void); /* join our link to an appropriate bundle */
+void mp_exit_bundle(void); /* have disconnected our link from bundle */
+void mp_bundle_terminated(void);
+char *epdisc_to_str(struct epdisc *); /* string from endpoint discrim. */
+int str_to_epdisc(struct epdisc *, char *); /* endpt disc. from str */
#else
#define mp_bundle_terminated() /* nothing */
#define mp_exit_bundle() /* nothing */
#endif
/* 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 generic_disestablish_ppp __P((int dev_fd)); /* Restore device setting */
-int generic_establish_ppp __P((int dev_fd)); /* Make a ppp interface */
-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 destroy_bundle __P((void)); /* Tell driver to destroy 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 *));
+void sys_init(void); /* Do system-dependent initialization */
+void sys_cleanup(void); /* Restore system state before exiting */
+int sys_check_options(void); /* Check options specified */
+void sys_close(void); /* Clean up in a child before execing */
+int ppp_available(void); /* Test whether ppp kernel support exists */
+int get_pty(int *, int *, char *, int); /* Get pty master/slave */
+int open_ppp_loopback(void); /* Open loopback for demand-dialling */
+int tty_establish_ppp(int); /* Turn serial port into a ppp interface */
+void tty_disestablish_ppp(int); /* Restore port to normal operation */
+void generic_disestablish_ppp(int dev_fd); /* Restore device setting */
+int generic_establish_ppp(int dev_fd); /* Make a ppp interface */
+void make_new_bundle(int, int, int, int); /* Create new bundle */
+int bundle_attach(int); /* Attach link to existing bundle */
+void cfg_bundle(int, int, int, int); /* Configure existing bundle */
+void destroy_bundle(void); /* Tell driver to destroy bundle */
+void clean_check(void); /* Check if line was 8-bit clean */
+void set_up_tty(int, int); /* Set up port's speed, parameters, etc. */
+void restore_tty(int); /* Restore port's original parameters */
+void setdtr(int, int); /* Raise or lower port's DTR line */
+void output(int, u_char *, int); /* Output a PPP packet */
+void wait_input(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));
+void add_fd(int); /* Add fd to set to wait for */
+void remove_fd(int); /* Remove fd from set to wait for */
+int read_packet(u_char *); /* Read PPP packet */
+int get_loop_output(void); /* Read pkts from loopback */
+void tty_send_config(int, u_int32_t, int, int);
/* Configure i/f transmit parameters */
-void tty_set_xaccm __P((ext_accm));
+void tty_set_xaccm(ext_accm);
/* Set extended transmit ACCM */
-void tty_recv_config __P((int, u_int32_t, int, int));
+void tty_recv_config(int, u_int32_t, int, int);
/* Configure i/f receive parameters */
-int ccp_test __P((int, u_char *, int, int));
+int ccp_test(int, u_char *, int, int);
/* Test support for compression scheme */
-void ccp_flags_set __P((int, int, int));
+void ccp_flags_set(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 *));
+int ccp_fatal_error(int); /* Test for fatal decomp error in kernel */
+int get_idle_time(int, struct ppp_idle *);
/* Find out how long link has been idle */
-int get_ppp_stats __P((int, struct pppd_stats *));
+int get_ppp_stats(int, struct pppd_stats *);
/* Return link statistics */
-void netif_set_mtu __P((int, int)); /* Set PPP interface MTU */
-int netif_get_mtu __P((int)); /* Get PPP interface MTU */
-int sifvjcomp __P((int, int, int, int));
+void netif_set_mtu(int, int); /* Set PPP interface MTU */
+int netif_get_mtu(int); /* Get PPP interface MTU */
+int sifvjcomp(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));
+int sifup(int); /* Configure i/f up for one protocol */
+int sifnpmode(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));
+int sifdown(int); /* Configure i/f down for one protocol */
+int sifaddr(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));
+int cifaddr(int, u_int32_t, u_int32_t);
/* Reset i/f IP addresses */
#ifdef INET6
int ether_to_eui64(eui64_t *p_eui64); /* convert eth0 hw address to EUI64 */
-int sif6up __P((int)); /* Configure i/f up for IPv6 */
-int sif6down __P((int)); /* Configure i/f down for IPv6 */
-int sif6addr __P((int, eui64_t, eui64_t));
+int sif6up(int); /* Configure i/f up for IPv6 */
+int sif6down(int); /* Configure i/f down for IPv6 */
+int sif6addr(int, eui64_t, eui64_t);
/* Configure IPv6 addresses for i/f */
-int cif6addr __P((int, eui64_t, eui64_t));
+int cif6addr(int, eui64_t, eui64_t);
/* Remove an IPv6 address from i/f */
#endif
-int sifdefaultroute __P((int, u_int32_t, u_int32_t));
+int sifdefaultroute(int, u_int32_t, u_int32_t);
/* Create default route through i/f */
-int cifdefaultroute __P((int, u_int32_t, u_int32_t));
+int cifdefaultroute(int, u_int32_t, u_int32_t);
/* Delete default route through i/f */
-int sifproxyarp __P((int, u_int32_t));
+#ifdef INET6
+int sif6defaultroute(int, eui64_t, eui64_t);
+ /* Create default IPv6 route through i/f */
+int cif6defaultroute(int, eui64_t, eui64_t);
+ /* Delete default IPv6 route through i/f */
+#endif
+int sifproxyarp(int, u_int32_t);
/* Add proxy ARP entry for peer */
-int cifproxyarp __P((int, u_int32_t));
+int cifproxyarp(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 *));
+u_int32_t GetMask(u_int32_t); /* Get appropriate netmask for address */
+int lock(char *); /* Create lock file for device */
+int relock(int); /* Rewrite lock file with new pid */
+void unlock(void); /* Delete previously-created lock file */
+void logwtmp(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 */
+int get_host_seed(void); /* Get host-dependent random number seed */
+int have_route_to(u_int32_t); /* Check if route to addr exists */
#ifdef PPP_FILTER
-int set_filters __P((struct bpf_program *pass, struct bpf_program *active));
+int set_filters(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));
+int sipxfaddr(int, unsigned long, unsigned char *);
+int cipxfaddr(int);
#endif
-int get_if_hwaddr __P((u_char *addr, char *name));
-char *get_first_ethernet __P((void));
+int get_if_hwaddr(u_char *addr, char *name);
+char *get_first_ethernet(void);
+int get_time(struct timeval *);
+ /* Get current time, monotonic if possible. */
/* Procedures exported from options.c */
-int setipaddr __P((char *, char **, int)); /* Set local/remote ip addresses */
-int parse_args __P((int argc, char **argv));
+int setipaddr(char *, char **, int); /* Set local/remote ip addresses */
+int parse_args(int argc, char **argv);
/* Parse options from arguments given */
-int options_from_file __P((char *filename, int must_exist, int check_prot,
- int privileged));
+int options_from_file(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));
+int options_from_user(void); /* Parse options from user's .ppprc */
+int options_for_tty(void); /* Parse options from /etc/ppp/options.tty */
+int options_from_list(struct wordlist *, int privileged);
/* Parse options from a wordlist */
-int getword __P((FILE *f, char *word, int *newlinep, char *filename));
+int getword(FILE *f, char *word, int *newlinep, char *filename);
/* Read a word from a file */
-void option_error __P((char *fmt, ...));
+void option_error(char *fmt, ...);
/* Print an error message about an option */
-int int_option __P((char *, int *));
+int int_option(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 *));
+void add_options(option_t *); /* Add extra options */
+void check_options(void); /* check values after all options parsed */
+int override_value(char *, int, const char *);
/* override value if permitted by priority */
-void print_options __P((printer_func, void *));
+void print_options(printer_func, void *);
/* print out values of all options */
-int parse_dotted_ip __P((char *, u_int32_t *));
+int parse_dotted_ip(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 int (*allowed_address_hook) __P((u_int32_t addr));
-extern void (*ip_up_hook) __P((void));
-extern void (*ip_down_hook) __P((void));
-extern void (*ip_choose_hook) __P((u_int32_t *));
-extern void (*ipv6_up_hook) __P((void));
-extern void (*ipv6_down_hook) __P((void));
-
-extern int (*chap_check_hook) __P((void));
-extern int (*chap_passwd_hook) __P((char *user, char *passwd));
-extern void (*multilink_join_hook) __P((void));
+extern int (*new_phase_hook)(int);
+extern int (*idle_time_hook)(struct ppp_idle *);
+extern int (*holdoff_hook)(void);
+extern int (*pap_check_hook)(void);
+extern int (*pap_auth_hook)(char *user, char *passwd, char **msgp,
+ struct wordlist **paddrs,
+ struct wordlist **popts);
+extern void (*pap_logout_hook)(void);
+extern int (*pap_passwd_hook)(char *user, char *passwd);
+extern int (*allowed_address_hook)(u_int32_t addr);
+extern void (*ip_up_hook)(void);
+extern void (*ip_down_hook)(void);
+extern void (*ip_choose_hook)(u_int32_t *);
+extern void (*ipv6_up_hook)(void);
+extern void (*ipv6_down_hook)(void);
+
+extern int (*chap_check_hook)(void);
+extern int (*chap_passwd_hook)(char *user, char *passwd);
+extern void (*multilink_join_hook)(void);
+
+#ifdef USE_EAPTLS
+extern int (*eaptls_passwd_hook)(char *user, char *passwd);
+#endif
/* Let a plugin snoop sent and received packets. Useful for L2TP */
-extern void (*snoop_recv_hook) __P((unsigned char *p, int len));
-extern void (*snoop_send_hook) __P((unsigned char *p, int len));
+extern void (*snoop_recv_hook)(unsigned char *p, int len);
+extern void (*snoop_send_hook)(unsigned char *p, int len);
/*
* Inline versions of get/put char/short/long.
*/
static int conversation (int num_msg,
-#ifndef SOL2
- const
-#endif
- struct pam_message **msg,
+ const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr)
{
int replies = 0;
#endif /* #ifdef USE_PAM */
int
-session_start(flags, user, passwd, ttyName, msg)
- const int flags;
- const char *user;
- const char *passwd;
- const char *ttyName;
- char **msg;
+session_start(const int flags, const char *user, const char *passwd, const char *ttyName, char **msg)
{
#ifdef USE_PAM
bool ok = 1;
memset((void *)&ll, 0, sizeof(ll));
(void)time(&tnow);
ll.ll_time = tnow;
- (void)strncpy(ll.ll_line, ttyName, sizeof(ll.ll_line));
- (void)strncpy(ll.ll_host, ifname, sizeof(ll.ll_host));
+ strlcpy(ll.ll_line, ttyName, sizeof(ll.ll_line));
+ strlcpy(ll.ll_host, ifname, sizeof(ll.ll_host));
(void)write(fd, (char *)&ll, sizeof(ll));
(void)close(fd);
}
/* #define SHA1HANDSOFF * Copies data before messing with it. */
#include <string.h>
+#include <time.h>
#include <netinet/in.h> /* htonl() */
#include <net/ppp_defs.h>
#include "sha1.h"
#define MAX_ADDR_LEN 7
#endif
-#if __GLIBC__ >= 2
+#if !defined(__GLIBC__) || __GLIBC__ >= 2
#include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
#include <net/if.h>
#include <net/if_arp.h>
eui64_copy(eui64, sin6.s6_addr32[2]); \
} while (0)
+static const eui64_t nulleui64;
#endif /* INET6 */
/* We can get an EIO error on an ioctl if the modem has hung up */
static int if_is_up; /* Interface has been marked up */
static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */
static int have_default_route; /* Gateway for default route added */
+static int have_default_route6; /* Gateway for default IPv6 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 open_route_table (void);
static int read_route_table (struct rtentry *rt);
static int defaultroute_exists (struct rtentry *rt, int metric);
+static int defaultroute6_exists (struct in6_rtmsg *rt, int metric);
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);
*/
if (have_default_route)
cifdefaultroute(0, 0, 0);
+#ifdef INET6
+ if (have_default_route6)
+ cif6defaultroute(0, nulleui64, nulleui64);
+#endif
if (has_proxy_arp)
cifproxyarp(0, proxy_arp_addr);
* make_ppp_unit - make a new ppp unit for ppp_dev_fd.
* Assumes new_style_driver.
*/
-static int make_ppp_unit()
+static int make_ppp_unit(void)
{
int x, flags;
char t[MAXIFNAMELEN];
memset(&ifr, 0, sizeof(struct ifreq));
slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
- strncpy(ifr.ifr_name, t, IF_NAMESIZE);
- strncpy(ifr.ifr_newname, req_ifname, IF_NAMESIZE);
+ strlcpy(ifr.ifr_name, t, IF_NAMESIZE);
+ strlcpy(ifr.ifr_newname, req_ifname, IF_NAMESIZE);
x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
if (x < 0)
error("Couldn't rename interface %s to %s: %m", t, req_ifname);
* get_idle_time - return how long the link has been idle.
*/
int
-get_idle_time(u, ip)
- int u;
- struct ppp_idle *ip;
+get_idle_time(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;
+get_ppp_stats(int u, struct pppd_stats *stats)
{
struct ifpppstatsreq req;
return 1;
}
+#ifdef INET6
+/*
+ * /proc/net/ipv6_route parsing stuff.
+ */
+static int route_dest_plen_col;
+static int open_route6_table (void);
+static int read_route6_table (struct in6_rtmsg *rt);
+
+/********************************************************************
+ *
+ * open_route6_table - open the interface to the route table
+ */
+static int open_route6_table (void)
+{
+ char *path;
+
+ close_route_table();
+
+ path = path_to_procfs("/net/ipv6_route");
+ route_fd = fopen (path, "r");
+ if (route_fd == NULL) {
+ error("can't open routing table %s: %m", path);
+ return 0;
+ }
+
+ /* default to usual columns */
+ route_dest_col = 0;
+ route_dest_plen_col = 1;
+ route_gw_col = 4;
+ route_metric_col = 5;
+ route_flags_col = 8;
+ route_dev_col = 9;
+ route_num_cols = 10;
+
+ return 1;
+}
+
+/********************************************************************
+ *
+ * read_route6_table - read the next entry from the route table
+ */
+
+static void hex_to_in6_addr(struct in6_addr *addr, const char *s)
+{
+ char hex8[9];
+ unsigned i;
+ uint32_t v;
+
+ hex8[8] = 0;
+ for (i = 0; i < 4; i++) {
+ memcpy(hex8, s + 8*i, 8);
+ v = strtoul(hex8, NULL, 16);
+ addr->s6_addr32[i] = v;
+ }
+}
+
+static int read_route6_table(struct in6_rtmsg *rt)
+{
+ char *cols[ROUTE_MAX_COLS], *p;
+ int col;
+
+ memset (rt, '\0', sizeof (struct in6_rtmsg));
+
+ 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;
+ }
+
+ hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]);
+ rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16);
+ hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]);
+
+ rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16);
+ rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16);
+ rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]);
+
+ return 1;
+}
+
+/********************************************************************
+ *
+ * defaultroute6_exists - determine if there is a default route
+ */
+
+static int defaultroute6_exists (struct in6_rtmsg *rt, int metric)
+{
+ int result = 0;
+
+ if (!open_route6_table())
+ return 0;
+
+ while (read_route6_table(rt) != 0) {
+ if ((rt->rtmsg_flags & RTF_UP) == 0)
+ continue;
+
+ if (rt->rtmsg_dst_len != 0)
+ continue;
+ if (rt->rtmsg_dst.s6_addr32[0] == 0L
+ && rt->rtmsg_dst.s6_addr32[1] == 0L
+ && rt->rtmsg_dst.s6_addr32[2] == 0L
+ && rt->rtmsg_dst.s6_addr32[3] == 0L
+ && (metric < 0 || rt->rtmsg_metric == metric)) {
+ result = 1;
+ break;
+ }
+ }
+
+ close_route_table();
+ return result;
+}
+
+/********************************************************************
+ *
+ * sif6defaultroute - assign a default route through the address given.
+ *
+ * If the global default_rt_repl_rest flag is set, then this function
+ * already replaced the original system defaultroute with some other
+ * route and it should just replace the current defaultroute with
+ * another one, without saving the current route. Use: demand mode,
+ * when pppd sets first a defaultroute it it's temporary ppp0 addresses
+ * and then changes the temporary addresses to the addresses for the real
+ * ppp connection when it has come up.
+ */
+
+int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
+{
+ struct in6_rtmsg rt;
+ char buf[IF_NAMESIZE];
+
+ if (defaultroute6_exists(&rt, dfl_route_metric) &&
+ rt.rtmsg_ifindex != if_nametoindex(ifname)) {
+ if (rt.rtmsg_flags & RTF_GATEWAY)
+ error("not replacing existing default route via gateway");
+ else
+ error("not replacing existing default route through %s",
+ if_indextoname(rt.rtmsg_ifindex, buf));
+ return 0;
+ }
+
+ memset (&rt, 0, sizeof (rt));
+
+ rt.rtmsg_ifindex = if_nametoindex(ifname);
+ rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
+ rt.rtmsg_dst_len = 0;
+
+ rt.rtmsg_flags = RTF_UP;
+ if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) {
+ if ( ! ok_error ( errno ))
+ error("default route ioctl(SIOCADDRT): %m");
+ return 0;
+ }
+
+ have_default_route6 = 1;
+ return 1;
+}
+
+/********************************************************************
+ *
+ * cif6defaultroute - delete a default route through the address given.
+ */
+
+int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway)
+{
+ struct in6_rtmsg rt;
+
+ have_default_route6 = 0;
+
+ memset (&rt, '\0', sizeof (rt));
+
+ rt.rtmsg_ifindex = if_nametoindex(ifname);
+ rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
+ rt.rtmsg_dst_len = 0;
+
+ rt.rtmsg_flags = RTF_UP;
+ if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
+ if (still_ppp()) {
+ if ( ! ok_error ( errno ))
+ error("default route ioctl(SIOCDELRT): %m");
+ return 0;
+ }
+ }
+
+ return 1;
+}
+#endif /* INET6 */
+
/********************************************************************
*
* sifproxyarp - Make a proxy ARP entry for the peer.
* interface on this system.
*/
char *
-get_first_ethernet()
+get_first_ethernet(void)
{
return "eth0";
}
}
}
- close (s);
if (!ok) {
slprintf(route_buffer, sizeof(route_buffer),
"Sorry - PPP driver version %d.%d.%d is out of date\n",
}
}
}
+ close(s);
return ok;
}
memset(&ifr6, 0, sizeof(ifr6));
IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
ifr6.ifr6_ifindex = ifr.ifr_ifindex;
- ifr6.ifr6_prefixlen = 10;
+ ifr6.ifr6_prefixlen = 128;
if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
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_dst_len = 128;
rt6.rtmsg_ifindex = ifr.ifr_ifindex;
rt6.rtmsg_metric = 1;
memset(&ifr6, 0, sizeof(ifr6));
IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
ifr6.ifr6_ifindex = ifr.ifr_ifindex;
- ifr6.ifr6_prefixlen = 10;
+ ifr6.ifr6_prefixlen = 128;
if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
if (errno != EADDRNOTAVAIL) {
* 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;
+get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
{
int i, mfd, sfd = -1;
char pty_name[16];
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);
+ close(mfd);
+ }
}
}
#endif /* TIOCGPTN */
*/
int
-sifnpmode(u, proto, mode)
- int u;
- int proto;
- enum NPmode mode;
+sifnpmode(int u, int proto, enum NPmode mode)
{
struct npioctl npi;
* Use the hostname as part of the random number seed.
*/
int
-get_host_seed()
+get_host_seed(void)
{
int h;
char *p = hostname;
return 1;
}
#endif
+
+/********************************************************************
+ *
+ * get_time - Get current time, monotonic if possible.
+ */
+int
+get_time(struct timeval *tv)
+{
+/* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it.
+ * Runtime checking makes it safe. */
+#ifndef CLOCK_MONOTONIC
+#define CLOCK_MONOTONIC 1
+#endif
+ static int monotonic = -1;
+ struct timespec ts;
+ int ret;
+
+ if (monotonic) {
+ ret = clock_gettime(CLOCK_MONOTONIC, &ts);
+ if (ret == 0) {
+ monotonic = 1;
+ if (tv) {
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+ }
+ return ret;
+ } else if (monotonic > 0)
+ return ret;
+
+ monotonic = 0;
+ warn("Couldn't use monotonic clock source: %m");
+ }
+
+ return gettimeofday(tv, NULL);
+}
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: sys-solaris.c,v 1.16 2008/01/30 14:26:53 carlsonj Exp $"
-
#include <limits.h>
#include <stdio.h>
#include <stddef.h>
#include <sys/dlpi.h>
#include <sys/stat.h>
#include <sys/mkdev.h>
+#include <sys/time.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/route.h>
#define UDP6_DEV_NAME "/dev/udp6"
#endif /* !defined(UDP6_DEV_NAME) && defined(SOL2) */
-static const char rcsid[] = RCSID;
#if defined(SOL2)
/*
static int ip6muxid = -1; /* Multiplexer file descriptor */
static int if6_is_up = 0; /* IPv6 interface has been marked up */
+#define IN6_SOCKADDR_FROM_EUI64(s, eui64) do { \
+ (s)->sin6_family = AF_INET6; \
+ (s)->sin6_addr.s6_addr32[0] = htonl(0xfe800000); \
+ eui64_copy(eui64, (s)->sin6_addr.s6_addr32[2]); \
+ } while(0)
+
#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]); \
l.lifr_addr = laddr; \
} while (0)
+#define _IN6A_LLX_FROM_EUI64(s, eui64, as) do { \
+ s->s6_addr32[0] = htonl(as); \
+ eui64_copy(eui64, s->s6_addr32[2]); \
+ } 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)
+#define IN6A_LLADDR_FROM_EUI64(s, eui64) \
+ _IN6A_LLX_FROM_EUI64(s, eui64, 0xfe800000)
+
#endif /* defined(INET6) && defined(SOL2) */
#if defined(INET6) && defined(SOL2)
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 eui64_t default_route_gateway6; /* Gateway for default IPv6 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));
+static int translate_speed(int);
+static int baud_rate_of(int);
+static int get_ether_addr(u_int32_t, struct sockaddr *);
+static int get_hw_addr(char *, u_int32_t, struct sockaddr *);
+static int get_hw_addr_dlpi(char *, struct sockaddr *);
+static int dlpi_attach(int, int);
+static int dlpi_info_req(int);
+static int dlpi_get_reply(int, union DL_primitives *, int, int);
+static int strioctl(int, int, void *, int, int);
#ifdef SOL2
/*
* NOTE: This is the lifreq version (Solaris 8 and above)
*/
char *
-get_first_ethernet()
+get_first_ethernet(void)
{
struct lifnum lifn;
struct lifconf lifc;
* NOTE: This is the ifreq version (before Solaris 8).
*/
char *
-get_first_ethernet()
+get_first_ethernet(void)
{
struct ifconf ifc;
struct ifreq *pifreq;
* be set in order to declare this as an IPv6 interface
*/
static int
-slifname(fd, ppa)
- int fd;
- int ppa;
+slifname(int fd, int ppa)
{
struct lifreq lifr;
int ret;
* sys_init - System-dependent initialization.
*/
void
-sys_init()
+sys_init(void)
{
int ifd, x;
struct ifreq ifr;
* This should call die() because it's called from die().
*/
void
-sys_cleanup()
+sys_cleanup(void)
{
#if defined(SOL2)
struct ifreq ifr;
sifdown(0);
if (default_route_gateway)
cifdefaultroute(0, default_route_gateway, default_route_gateway);
+ if (default_route_gateway6.e32[0] != 0 || default_route_gateway6.e32[1] != 0)
+ cif6defaultroute(0, default_route_gateway6, default_route_gateway6);
if (proxy_arp_addr)
cifproxyarp(0, proxy_arp_addr);
#if defined(SOL2)
* sys_close - Clean up in a child process before execing.
*/
void
-sys_close()
+sys_close(void)
{
close(ipfd);
#if defined(INET6) && defined(SOL2)
* sys_check_options - check the options that the user specified
*/
int
-sys_check_options()
+sys_check_options(void)
{
return 1;
}
* daemon - Detach us from controlling terminal session.
*/
int
-daemon(nochdir, noclose)
- int nochdir, noclose;
+daemon(int nochdir, int noclose)
{
int pid;
* ppp_available - check whether the system has any ppp interfaces
*/
int
-ppp_available()
+ppp_available(void)
{
struct stat buf;
* no point of having the comp module be pushed on the stream.
*/
static int
-any_compressions()
+any_compressions(void)
{
if ((!lcp_wantoptions[0].neg_accompression) &&
(!lcp_wantoptions[0].neg_pcompression) &&
* tty_establish_ppp - Turn the serial port into a ppp interface.
*/
int
-tty_establish_ppp(fd)
- int fd;
+tty_establish_ppp(int fd)
{
int i;
* modules. This shouldn't call die() because it's called from die().
*/
void
-tty_disestablish_ppp(fd)
- int fd;
+tty_disestablish_ppp(int fd)
{
int i;
* Check whether the link seems not to be 8-bit clean.
*/
void
-clean_check()
+clean_check(void)
{
int x;
char *s;
* Translate from bits/second to a speed_t.
*/
static int
-translate_speed(bps)
- int bps;
+translate_speed(int bps)
{
struct speed *speedp;
* Translate from a speed_t to bits/second.
*/
static int
-baud_rate_of(speed)
- int speed;
+baud_rate_of(int speed)
{
struct speed *speedp;
* regardless of whether the modem option was specified.
*/
void
-set_up_tty(fd, local)
- int fd, local;
+set_up_tty(int fd, int local)
{
int speed;
struct termios tios;
* restore_tty - restore the terminal to the saved settings.
*/
void
-restore_tty(fd)
- int fd;
+restore_tty(int fd)
{
if (restore_term) {
if (!default_device) {
* This is called from die(), so it shouldn't call die().
*/
void
-setdtr(fd, on)
-int fd, on;
+setdtr(int fd, int on)
{
int modembits = TIOCM_DTR;
* to the ppp driver.
*/
int
-open_ppp_loopback()
+open_ppp_loopback(void)
{
return pppfd;
}
* output - Output PPP packet.
*/
void
-output(unit, p, len)
- int unit;
- u_char *p;
- int len;
+output(int unit, u_char *p, int len)
{
struct strbuf data;
int retries;
* if timo is NULL).
*/
void
-wait_input(timo)
- struct timeval *timo;
+wait_input(struct timeval *timo)
{
int t;
/*
* add_fd - add an fd to the set that wait_input waits for.
*/
-void add_fd(fd)
- int fd;
+void add_fd(int fd)
{
int n;
/*
* remove_fd - remove an fd from the set that wait_input waits for.
*/
-void remove_fd(fd)
- int fd;
+void remove_fd(int fd)
{
int n;
* if timo is NULL).
*/
void
-wait_loop_output(timo)
- struct timeval *timo;
+wait_loop_output(struct timeval *timo)
{
wait_input(timo);
}
* signal is received.
*/
void
-wait_time(timo)
- struct timeval *timo;
+wait_time(struct timeval *timo)
{
int n;
* read_packet - get a PPP packet from the serial device.
*/
int
-read_packet(buf)
- u_char *buf;
+read_packet(u_char *buf)
{
struct strbuf ctrl, data;
int flags, len;
* Return value is 1 if we need to bring up the link, 0 otherwise.
*/
int
-get_loop_output()
+get_loop_output(void)
{
int len;
int rv = 0;
* netif_set_mtu - set the MTU on the PPP network interface.
*/
void
-netif_set_mtu(unit, mtu)
- int unit, mtu;
+netif_set_mtu(int unit, int mtu)
{
struct ifreq ifr;
#if defined(INET6) && defined(SOL2)
#endif /* defined(INET6) && defined(SOL2) */
}
+
+
+/*
+ * netif_get_mtu - get the MTU on the PPP network interface.
+ */
+int
+netif_get_mtu(int unit)
+{
+ struct ifreq ifr;
+
+ memset (&ifr, '\0', sizeof (ifr));
+ strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+
+ if (ioctl(ipfd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
+ error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
+ return 0;
+ }
+ return ifr.ifr_mtu;
+}
+
/*
* 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;
+tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
{
int cf[2];
* tty_set_xaccm - set the extended transmit ACCM for the interface.
*/
void
-tty_set_xaccm(accm)
- ext_accm accm;
+tty_set_xaccm(ext_accm accm)
{
if (sync_serial)
return;
* the ppp interface.
*/
void
-tty_recv_config(mru, asyncmap, pcomp, accomp)
- int mru;
- u_int32_t asyncmap;
- int pcomp, accomp;
+tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
{
int cf[2];
* is acceptable for use.
*/
int
-ccp_test(unit, opt_ptr, opt_len, for_transmit)
- int unit, opt_len, for_transmit;
- u_char *opt_ptr;
+ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
{
if (strioctl(pppfd, (for_transmit? PPPIO_XCOMP: PPPIO_RCOMP),
opt_ptr, opt_len, 0) >= 0)
* ccp_flags_set - inform kernel about the current state of CCP.
*/
void
-ccp_flags_set(unit, isopen, isup)
- int unit, isopen, isup;
+ccp_flags_set(int unit, int isopen, int isup)
{
int cf[2];
* get_idle_time - return how long the link has been idle.
*/
int
-get_idle_time(u, ip)
- int u;
- struct ppp_idle *ip;
+get_idle_time(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;
+get_ppp_stats(int u, struct pppd_stats *stats)
{
struct ppp_stats s;
* set_filters - transfer the pass and active filters to the kernel.
*/
int
-set_filters(pass, active)
- struct bpf_program *pass, *active;
+set_filters(struct bpf_program *pass, struct bpf_program *active)
{
int ret = 1;
* 0 otherwise. This is necessary because of patent nonsense.
*/
int
-ccp_fatal_error(unit)
- int unit;
+ccp_fatal_error(int unit)
{
int cf[2];
* sifvjcomp - config tcp header compression
*/
int
-sifvjcomp(u, vjcomp, xcidcomp, xmaxcid)
- int u, vjcomp, xcidcomp, xmaxcid;
+sifvjcomp(int u, int vjcomp, int xcidcomp, int xmaxcid)
{
int cf[2];
char maxcid[2];
* sifup - Config the interface up and enable IP packets to pass.
*/
int
-sifup(u)
- int u;
+sifup(int u)
{
struct ifreq ifr;
* sifdown - Config the interface down and disable IP.
*/
int
-sifdown(u)
- int u;
+sifdown(int u)
{
struct ifreq ifr;
* sifnpmode - Set the mode for handling packets for a given NP.
*/
int
-sifnpmode(u, proto, mode)
- int u;
- int proto;
- enum NPmode mode;
+sifnpmode(int u, int proto, enum NPmode mode)
{
int npi[2];
* sif6up - Config the IPv6 interface up and enable IPv6 packets to pass.
*/
int
-sif6up(u)
- int u;
+sif6up(int u)
{
struct lifreq lifr;
int fd;
* sifdown - Config the IPv6 interface down and disable IPv6.
*/
int
-sif6down(u)
- int u;
+sif6down(int u)
{
struct lifreq lifr;
int fd;
* sif6addr - Config the interface with an IPv6 link-local address
*/
int
-sif6addr(u, o, h)
- int u;
- eui64_t o, h;
+sif6addr(int u, eui64_t o, eui64_t h)
{
struct lifreq lifr;
struct sockaddr_storage laddr;
* cif6addr - Remove the IPv6 address from interface
*/
int
-cif6addr(u, o, h)
- int u;
- eui64_t o, h;
+cif6addr(int u, eui64_t o, eui64_t h)
{
return 1;
}
+/*
+ * sif6defaultroute - assign a default route through the address given.
+ */
+int
+sif6defaultroute(int u, eui64_t l, eui64_t g)
+{
+ struct {
+ struct rt_msghdr rtm;
+ struct sockaddr_in6 dst;
+ struct sockaddr_in6 gw;
+ } rmsg;
+ static int seq;
+ int rtsock;
+
+#if defined(__USLC__)
+ g = l; /* use the local address as gateway */
+#endif
+ memset(&rmsg, 0, sizeof(rmsg));
+
+ rmsg.rtm.rtm_msglen = sizeof (rmsg);
+ rmsg.rtm.rtm_version = RTM_VERSION;
+ rmsg.rtm.rtm_type = RTM_ADD;
+ rmsg.rtm.rtm_flags = RTF_GATEWAY;
+ rmsg.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
+ rmsg.rtm.rtm_pid = getpid();
+ rmsg.rtm.rtm_seq = seq++;
+
+ rmsg.dst.sin6_family = AF_INET6;
+
+ rmsg.gw.sin6_family = AF_INET6;
+ IN6_SOCKADDR_FROM_EUI64(&rmsg.gw, g);
+
+ rtsock = socket(PF_ROUTE, SOCK_RAW, 0);
+
+ if (rtsock < 0) {
+ error("Can't add default route: %m");
+ return 0;
+ }
+
+ if (write(rtsock, &rmsg, sizeof(rmsg)) < 0)
+ error("Can't add default route: %m");
+
+ close(rtsock);
+
+ default_route_gateway6 = g;
+ return 1;
+}
+
+/*
+ * cif6defaultroute - delete a default route through the address given.
+ */
+int
+cif6defaultroute(int u, eui64_t l, eui64_t g)
+{
+ /* No need to do this on Solaris; the kernel deletes the
+ route when the interface goes down. */
+ memset(&default_route_gateway6, 0, sizeof(default_route_gateway6));
+ return 1;
+}
+
#endif /* defined(SOL2) && defined(INET6) */
* sifaddr - Config the interface IP addresses and netmask.
*/
int
-sifaddr(u, o, h, m)
- int u;
- u_int32_t o, h, m;
+sifaddr(int u, u_int32_t o, u_int32_t h, u_int32_t m)
{
struct ifreq ifr;
int ret = 1;
* through the interface if possible.
*/
int
-cifaddr(u, o, h)
- int u;
- u_int32_t o, h;
+cifaddr(int u, u_int32_t o, u_int32_t h)
{
#if defined(__USLC__) /* was: #if 0 */
cifroute(unit, ouraddr, hisaddr);
* sifdefaultroute - assign a default route through the address given.
*/
int
-sifdefaultroute(u, l, g)
- int u;
- u_int32_t l, g;
+sifdefaultroute(int u, u_int32_t l, u_int32_t g)
{
struct rtentry rt;
* cifdefaultroute - delete a default route through the address given.
*/
int
-cifdefaultroute(u, l, g)
- int u;
- u_int32_t l, g;
+cifdefaultroute(int u, u_int32_t l, u_int32_t g)
{
struct rtentry rt;
* sifproxyarp - Make a proxy ARP entry for the peer.
*/
int
-sifproxyarp(unit, hisaddr)
- int unit;
- u_int32_t hisaddr;
+sifproxyarp(int unit, u_int32_t hisaddr)
{
struct arpreq arpreq;
* cifproxyarp - Delete the proxy ARP entry for the peer.
*/
int
-cifproxyarp(unit, hisaddr)
- int unit;
- u_int32_t hisaddr;
+cifproxyarp(int unit, u_int32_t hisaddr)
{
struct arpreq arpreq;
#define MAX_IFS 32
static int
-get_ether_addr(ipaddr, hwaddr)
- u_int32_t ipaddr;
- struct sockaddr *hwaddr;
+get_ether_addr(u_int32_t ipaddr, struct sockaddr *hwaddr)
{
struct ifreq *ifr, *ifend, ifreq;
int nif;
* get_hw_addr_dlpi - obtain the hardware address using DLPI
*/
static int
-get_hw_addr_dlpi(name, hwaddr)
- char *name;
- struct sockaddr *hwaddr;
+get_hw_addr_dlpi(char *name, struct sockaddr *hwaddr)
{
char *q;
int unit, iffd, adrlen;
* 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;
+get_hw_addr(char *name, u_int32_t ina, struct sockaddr *hwaddr)
{
/* New way - get the address by doing an arp request. */
int s;
}
static int
-dlpi_attach(fd, ppa)
- int fd, ppa;
+dlpi_attach(int fd, int ppa)
{
dl_attach_req_t req;
struct strbuf buf;
}
static int
-dlpi_info_req(fd)
- int fd;
+dlpi_info_req(int fd)
{
dl_info_req_t req;
struct strbuf buf;
}
static int
-dlpi_get_reply(fd, reply, expected_prim, maxlen)
- union DL_primitives *reply;
- int fd, expected_prim, maxlen;
+dlpi_get_reply(int fd, union DL_primitives *reply, int expected_prim, maxlen)
{
struct strbuf buf;
int flags, n;
pfd.events = POLLIN | POLLPRI;
do {
n = poll(&pfd, 1, 1000);
- } while (n == -1 && errno == EINTR);
+ } while (n == -1 && errno == EINTR && !got_sigterm);
if (n <= 0)
return -1;
* user-specified netmask.
*/
u_int32_t
-GetMask(addr)
- u_int32_t addr;
+GetMask(u_int32_t addr)
{
u_int32_t mask, nmask, ina;
struct ifreq *ifr, *ifend, ifreq;
* logwtmp - write an accounting record to the /var/adm/wtmp file.
*/
void
-logwtmp(line, name, host)
- const char *line, *name, *host;
+logwtmp(const char *line, const char *name, const char *host)
{
static struct utmpx utmpx;
* get_host_seed - return the serial number of this machine.
*/
int
-get_host_seed()
+get_host_seed(void)
{
char buf[32];
}
static int
-strioctl(fd, cmd, ptr, ilen, olen)
- int fd, cmd, ilen, olen;
- void *ptr;
+strioctl(int fd, int cmd, void *ptr, int ilen, int olen)
{
struct strioctl str;
static char lock_file[40]; /* name of lock file created */
int
-lock(dev)
- char *dev;
+lock(char *dev)
{
int n, fd, pid;
struct stat sbuf;
* unlock - remove our lockfile
*/
void
-unlock()
+unlock(void)
{
if (lock_file[0]) {
unlink(lock_file);
* cifroute - delete a route through the addresses given.
*/
int
-cifroute(u, our, his)
- int u;
- u_int32_t our, his;
+cifroute(int u, u_int32_t our, u_int32_t his)
{
struct rtentry rt;
#endif
int
-have_route_to(addr)
- u_int32_t addr;
+have_route_to(u_int32_t addr)
{
#ifdef SOL2
int fd, r, flags, i;
* 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;
+get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
{
int mfd, sfd;
char *pty_name;
return 1;
}
+
+/********************************************************************
+ *
+ * get_time - Get current time, monotonic if possible.
+ */
+int
+get_time(struct timeval *tv)
+{
+ return gettimeofday(tv, NULL);
+}
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: tty.c,v 1.27 2008/07/01 12:27:56 paulus Exp $"
-
#include <stdio.h>
#include <ctype.h>
#include <stdlib.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 "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));
+void tty_process_extra_options(void);
+void tty_check_options(void);
+int connect_tty(void);
+void disconnect_tty(void);
+void tty_close_fds(void);
+void cleanup_tty(void);
+void tty_do_send_config(int, u_int32_t, int, int);
+
+static int setdevname(char *, char **, int);
+static int setspeed(char *, char **, int);
+static int setxonxoff(char **);
+static int setescape(char **);
+static void printescape(option_t *, void (*)(void *, char *,...),void *);
+static void finish_tty(void);
+static int start_charshunt(int, int);
+static void stop_charshunt(void *, int);
+static void charshunt_done(void *);
+static void charshunt(int, int, char *);
+static int record_write(FILE *, int code, u_char *buf, int nb,
+ struct timeval *);
+static int open_socket(char *);
+static void maybe_relock(void *, int);
static int pty_master; /* fd for master side of pty */
static int pty_slave; /* fd for slave side of pty */
* potentially a speed value.
*/
static int
-setspeed(arg, argv, doit)
- char *arg;
- char **argv;
- int doit;
+setspeed(char *arg, char **argv, int doit)
{
char *ptr;
int spd;
* potentially a device name.
*/
static int
-setdevname(cp, argv, doit)
- char *cp;
- char **argv;
- int doit;
+setdevname(char *cp, char **argv, int doit)
{
struct stat statbuf;
char dev[MAXPATHLEN];
}
static int
-setxonxoff(argv)
- char **argv;
+setxonxoff(char **argv)
{
lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */
lcp_wantoptions[0].neg_asyncmap = 1;
* setescape - add chars to the set we escape on transmission.
*/
static int
-setescape(argv)
- char **argv;
+setescape(char **argv)
{
int n, ret;
char *p, *endp;
}
static void
-printescape(opt, printer, arg)
- option_t *opt;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+printescape(option_t *opt, void (*printer)(void *, char *, ...), void *arg)
{
int n;
int first = 1;
/*
* tty_init - do various tty-related initializations.
*/
-void tty_init()
+void tty_init(void)
{
add_notifier(&pidchange, maybe_relock, 0);
the_channel = &tty_channel;
* tty_process_extra_options - work out which tty device we are using
* and read its options file.
*/
-void tty_process_extra_options()
+void tty_process_extra_options(void)
{
using_pty = notty || ptycommand != NULL || pty_socket != NULL;
if (using_pty)
* tty_check_options - do consistency checks on the options we were given.
*/
void
-tty_check_options()
+tty_check_options(void)
{
struct stat statbuf;
int fdflags;
* That is, open the serial port, set its speed and mode, and run
* the connector and/or welcomer.
*/
-int connect_tty()
+int connect_tty(void)
{
char *connector;
int fdflags;
}
-void disconnect_tty()
+void disconnect_tty(void)
{
if (disconnect_script == NULL || hungup)
return;
stop_charshunt(NULL, 0);
}
-void tty_close_fds()
+void tty_close_fds(void)
{
if (pty_slave >= 0)
close(pty_slave);
/* N.B. ttyfd will == either pty_slave or real_ttyfd */
}
-void cleanup_tty()
+void cleanup_tty(void)
{
if (real_ttyfd >= 0)
finish_tty();
* 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_do_send_config(int mtu, u_int32_t accm, int pcomp, int 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()
+finish_tty(void)
{
/* drop dtr to hang up */
if (!default_device && modem) {
* maybe_relock - our PID has changed, maybe update the lock file.
*/
static void
-maybe_relock(arg, pid)
- void *arg;
- int pid;
+maybe_relock(void *arg, int pid)
{
if (locked)
relock(pid);
* host and port.
*/
static int
-open_socket(dest)
- char *dest;
+open_socket(char *dest)
{
char *sep, *endp = NULL;
int sock, port = -1;
* start_charshunt - create a child process to run the character shunt.
*/
static int
-start_charshunt(ifd, ofd)
- int ifd, ofd;
+start_charshunt(int ifd, int ofd)
{
int cpid;
}
static void
-charshunt_done(arg)
- void *arg;
+charshunt_done(void *arg)
{
charshunt_pid = 0;
}
static void
-stop_charshunt(arg, sig)
- void *arg;
- int sig;
+stop_charshunt(void *arg, int sig)
{
if (charshunt_pid)
kill(charshunt_pid, (sig == SIGINT? sig: SIGTERM));
* (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;
+charshunt(int ifd, int ofd, char *record_file)
{
int n, nfds;
fd_set ready, writey;
pty_readable = stdin_readable = 1;
ilevel = olevel = 0;
- gettimeofday(&levelt, NULL);
+ get_time(&levelt);
if (max_data_rate) {
max_level = max_data_rate / 10;
if (max_level < 100)
int nbt;
struct timeval now;
- gettimeofday(&now, NULL);
+ get_time(&now);
dt = (now.tv_sec - levelt.tv_sec
+ (now.tv_usec - levelt.tv_usec) / 1e6);
nbt = (int)(dt * max_data_rate);
}
static int
-record_write(f, code, buf, nb, tp)
- FILE *f;
- int code;
- u_char *buf;
- int nb;
- struct timeval *tp;
+record_write(FILE *f, int code, u_char *buf, int nb, struct timeval *tp)
{
struct timeval now;
int diff;
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: upap.c,v 1.30 2005/07/13 10:41:58 paulus Exp $"
-
/*
* TODO:
*/
#include "pppd.h"
#include "upap.h"
-static const char rcsid[] = RCSID;
static bool hide_password = 1;
/*
* 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 *));
+static void upap_init(int);
+static void upap_lowerup(int);
+static void upap_lowerdown(int);
+static void upap_input(int, u_char *, int);
+static void upap_protrej(int);
+static int upap_printpkt(u_char *, int,
+ void (*)(void *, char *, ...), void *);
struct protent pap_protent = {
PPP_PAP,
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));
+static void upap_timeout(void *);
+static void upap_reqtimeout(void *);
+static void upap_rauthreq(upap_state *, u_char *, int, int);
+static void upap_rauthack(upap_state *, u_char *, int, int);
+static void upap_rauthnak(upap_state *, u_char *, int, int);
+static void upap_sauthreq(upap_state *);
+static void upap_sresp(upap_state *, int, int, char *, int);
/*
* upap_init - Initialize a UPAP unit.
*/
static void
-upap_init(unit)
- int unit;
+upap_init(int unit)
{
upap_state *u = &upap[unit];
* Set new state and send authenticate's.
*/
void
-upap_authwithpeer(unit, user, password)
- int unit;
- char *user, *password;
+upap_authwithpeer(int unit, char *user, char *password)
{
upap_state *u = &upap[unit];
* Set new state.
*/
void
-upap_authpeer(unit)
- int unit;
+upap_authpeer(int unit)
{
upap_state *u = &upap[unit];
* upap_timeout - Retransmission timer for sending auth-reqs expired.
*/
static void
-upap_timeout(arg)
- void *arg;
+upap_timeout(void *arg)
{
upap_state *u = (upap_state *) arg;
* upap_reqtimeout - Give up waiting for the peer to send an auth-req.
*/
static void
-upap_reqtimeout(arg)
- void *arg;
+upap_reqtimeout(void *arg)
{
upap_state *u = (upap_state *) arg;
* Start authenticating if pending.
*/
static void
-upap_lowerup(unit)
- int unit;
+upap_lowerup(int unit)
{
upap_state *u = &upap[unit];
* Cancel all timeouts.
*/
static void
-upap_lowerdown(unit)
- int unit;
+upap_lowerdown(int unit)
{
upap_state *u = &upap[unit];
* This shouldn't happen. In any case, pretend lower layer went down.
*/
static void
-upap_protrej(unit)
- int unit;
+upap_protrej(int unit)
{
upap_state *u = &upap[unit];
* upap_input - Input UPAP packet.
*/
static void
-upap_input(unit, inpacket, l)
- int unit;
- u_char *inpacket;
- int l;
+upap_input(int unit, u_char *inpacket, int l)
{
upap_state *u = &upap[unit];
u_char *inp;
* upap_rauth - Receive Authenticate.
*/
static void
-upap_rauthreq(u, inp, id, len)
- upap_state *u;
- u_char *inp;
- int id;
- int len;
+upap_rauthreq(upap_state *u, u_char *inp, int id, int len)
{
u_char ruserlen, rpasswdlen;
char *ruser, *rpasswd;
* upap_rauthack - Receive Authenticate-Ack.
*/
static void
-upap_rauthack(u, inp, id, len)
- upap_state *u;
- u_char *inp;
- int id;
- int len;
+upap_rauthack(upap_state *u, u_char *inp, int id, int len)
{
u_char msglen;
char *msg;
* upap_rauthnak - Receive Authenticate-Nak.
*/
static void
-upap_rauthnak(u, inp, id, len)
- upap_state *u;
- u_char *inp;
- int id;
- int len;
+upap_rauthnak(upap_state *u, u_char *inp, int id, int len)
{
u_char msglen;
char *msg;
* upap_sauthreq - Send an Authenticate-Request.
*/
static void
-upap_sauthreq(u)
- upap_state *u;
+upap_sauthreq(upap_state *u)
{
u_char *outp;
int outlen;
* 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;
+upap_sresp(upap_state *u, int code, int id, char *msg, int msglen)
{
u_char *outp;
int outlen;
};
static int
-upap_printpkt(p, plen, printer, arg)
- u_char *p;
- int plen;
- void (*printer) __P((void *, char *, ...));
- void *arg;
+upap_printpkt(u_char *p, int plen, void (*printer)(void *, char *, ...), void *arg)
{
int code, id, len;
int mlen, ulen, wlen;
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $Id: upap.h,v 1.8 2002/12/04 23:03:33 paulus Exp $
*/
/*
extern upap_state upap[];
-void upap_authwithpeer __P((int, char *, char *));
-void upap_authpeer __P((int));
+void upap_authwithpeer(int, char *, char *);
+void upap_authpeer(int);
extern struct protent pap_protent;
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: utils.c,v 1.25 2008/06/03 12:06:37 paulus Exp $"
-
+#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include "fsm.h"
#include "lcp.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, printer_func, void *));
+static void logit(int, char *, va_list);
+static void log_write(int, char *);
+static void vslp_printer(void *, char *, ...);
+static void format_packet(u_char *, int, printer_func, void *);
struct buffer_info {
char *ptr;
* always leaves destination null-terminated (for len > 0).
*/
size_t
-strlcpy(dest, src, len)
- char *dest;
- const char *src;
- size_t len;
+strlcpy(char *dest, const char *src, size_t len)
{
size_t ret = strlen(src);
* always leaves destination null-terminated (for len > 0).
*/
size_t
-strlcat(dest, src, len)
- char *dest;
- const char *src;
- size_t len;
+strlcat(char *dest, const char *src, size_t len)
{
size_t dlen = strlen(dest);
* Returns the number of chars put into buf.
*/
int
-slprintf __V((char *buf, int buflen, char *fmt, ...))
+slprintf(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;
#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0)
int
-vslprintf(buf, buflen, fmt, args)
- char *buf;
- int buflen;
- char *fmt;
- va_list args;
+vslprintf(char *buf, int buflen, char *fmt, va_list args)
{
int c, i, n;
int width, prec, fillch;
u_int32_t ip;
static char hexchars[] = "0123456789abcdef";
struct buffer_info bufinfo;
+ int termch;
buf0 = buf;
--buflen;
p = (unsigned char *)"<NULL>";
if (fillch == '0' && prec >= 0) {
n = prec;
+ termch = -1; /* matches no unsigned char value */
} else {
- n = strlen((char *)p);
- if (prec >= 0 && n > prec)
+ n = buflen;
+ if (prec != -1 && n > prec)
n = prec;
+ termch = 0; /* stop on null byte */
}
while (n > 0 && buflen > 0) {
c = *p++;
+ if (c == termch)
+ break;
--n;
if (!quoted && c >= 0x80) {
OUTCHAR('M');
}
len = num + sizeof(num) - 1 - str;
} else {
- len = strlen(str);
- if (prec >= 0 && len > prec)
- len = prec;
+ for (len = 0; len < buflen && (prec == -1 || len < prec); ++len)
+ if (str[len] == 0)
+ break;
}
if (width > 0) {
if (width > buflen)
* vslp_printer - used in processing a %P format
*/
static void
-vslp_printer __V((void *arg, char *fmt, ...))
+vslp_printer(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);
*/
void
-log_packet(p, len, prefix, level)
- u_char *p;
- int len;
- char *prefix;
- int level;
+log_packet(u_char *p, int len, char *prefix, int level)
{
init_pr_log(prefix, level);
format_packet(p, len, pr_log, &level);
* calling `printer(arg, format, ...)' to output it.
*/
static void
-format_packet(p, len, printer, arg)
- u_char *p;
- int len;
- printer_func printer;
- void *arg;
+format_packet(u_char *p, int len, printer_func printer, void *arg)
{
int i, n;
u_short proto;
static int llevel; /* level for logging */
void
-init_pr_log(prefix, level)
- const char *prefix;
- int level;
+init_pr_log(const char *prefix, int level)
{
linep = line;
if (prefix != NULL) {
}
void
-end_pr_log()
+end_pr_log(void)
{
if (linep != line) {
*linep = 0;
* pr_log - printer routine for outputting to syslog
*/
void
-pr_log __V((void *arg, char *fmt, ...))
+pr_log(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);
* printer.
*/
void
-print_string(p, len, printer, arg)
- char *p;
- int len;
- printer_func printer;
- void *arg;
+print_string(char *p, int len, printer_func printer, void *arg)
{
int c;
* logit - does the hard work for fatal et al.
*/
static void
-logit(level, fmt, args)
- int level;
- char *fmt;
- va_list args;
+logit(int level, char *fmt, va_list args)
{
char buf[1024];
}
static void
-log_write(level, buf)
- int level;
- char *buf;
+log_write(int level, char *buf)
{
syslog(level, "%s", buf);
if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) {
* fatal - log an error message and die horribly.
*/
void
-fatal __V((char *fmt, ...))
+fatal(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);
* error - log an error message.
*/
void
-error __V((char *fmt, ...))
+error(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, ...))
+warn(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, ...))
+notice(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, ...))
+info(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, ...))
+dbglog(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);
for (done = 0; done < count; ) {
nb = read(fd, ptr, count - done);
if (nb < 0) {
- if (errno == EINTR)
+ if (errno == EINTR && !got_sigterm)
continue;
return -1;
}
* lock - create a lock file for the named device
*/
int
-lock(dev)
- char *dev;
+lock(char *dev)
{
#ifdef LOCKLIB
int result;
* between when the parent died and the child rewrote the lockfile).
*/
int
-relock(pid)
- int pid;
+relock(int pid)
{
#ifdef LOCKLIB
/* XXX is there a way to do this? */
* unlock - remove our lockfile
*/
void
-unlock()
+unlock(void)
{
if (lock_file[0]) {
#ifdef LOCKLIB
#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));
+static void *bsd_decomp_alloc(u_char *options, int opt_len);
+static void bsd_free(void *state);
+static int bsd_decomp_init(void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int mru, int debug);
+static void bsd_incomp(void *state, u_char *dmsg, int len);
+static int bsd_decompress(void *state, u_char *cmp, int inlen,
+ u_char *dmp, int *outlen);
+static void bsd_reset(void *state);
+static void bsd_comp_stats(void *state, struct compstat *stats);
/*
* Exported procedures.
* clear the dictionary
*/
static void
-bsd_clear(db)
- struct bsd_db *db;
+bsd_clear(struct bsd_db *db)
{
db->clear_count++;
db->max_ent = FIRST-1;
* must compute the same ratio.
*/
static int /* 1=output CLEAR */
-bsd_check(db)
- struct bsd_db *db;
+bsd_check(struct bsd_db *db)
{
u_int new_ratio;
* Return statistics.
*/
static void
-bsd_comp_stats(state, stats)
- void *state;
- struct compstat *stats;
+bsd_comp_stats(void *state, struct compstat *stats)
{
struct bsd_db *db = (struct bsd_db *) state;
u_int out;
* Reset state, as on a CCP ResetReq.
*/
static void
-bsd_reset(state)
- void *state;
+bsd_reset(void *state)
{
struct bsd_db *db = (struct bsd_db *) state;
* Allocate space for a (de) compressor.
*/
static void *
-bsd_alloc(options, opt_len, decomp)
- u_char *options;
- int opt_len, decomp;
+bsd_alloc(u_char *options, int opt_len, int decomp)
{
int bits;
u_int newlen, hsize, hshift, maxmaxcode;
}
static void
-bsd_free(state)
- void *state;
+bsd_free(void *state)
{
struct bsd_db *db = (struct bsd_db *) state;
}
static void *
-bsd_decomp_alloc(options, opt_len)
- u_char *options;
- int opt_len;
+bsd_decomp_alloc(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;
+bsd_init(struct bsd_db *db, u_char *options, int opt_len, int unit,
+ int hdrlen, int mru, int debug, int decomp)
{
int i;
}
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;
+bsd_decomp_init(void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int mru, int debug)
{
return bsd_init((struct bsd_db *) state, options, opt_len,
unit, hdrlen, mru, debug, 1);
* incompressible data by pretending to compress the incoming data.
*/
static void
-bsd_incomp(state, dmsg, mlen)
- void *state;
- u_char *dmsg;
- int mlen;
+bsd_incomp(void *state, u_char *dmsg, int mlen)
{
struct bsd_db *db = (struct bsd_db *) state;
u_int hshift = db->hshift;
* 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;
+bsd_decompress(void *state, u_char *cmsg, int inlen, u_char *dmp, int *outlenp)
{
struct bsd_db *db = (struct bsd_db *) state;
u_int max_ent = db->max_ent;
#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));
+static void *z_alloc(void *, u_int items, u_int size);
+static void z_free(void *, void *ptr, u_int nb);
+static void *z_decomp_alloc(u_char *options, int opt_len);
+static void z_decomp_free(void *state);
+static int z_decomp_init(void *state, u_char *options, int opt_len,
+ int unit, int hdrlen, int mru, int debug);
+static void z_incomp(void *state, u_char *dmsg, int len);
+static int z_decompress(void *state, u_char *cmp, int inlen,
+ u_char *dmp, int *outlenp);
+static void z_decomp_reset(void *state);
+static void z_comp_stats(void *state, struct compstat *stats);
/*
* Procedures exported to if_ppp.c.
* Space allocation and freeing routines for use by zlib routines.
*/
static void *
-z_alloc(notused, items, size)
- void *notused;
- u_int items, size;
+z_alloc(void *notused, u_int items, u_int size)
{
return malloc(items * size);
}
static void
-z_free(notused, ptr, nbytes)
- void *notused;
- void *ptr;
- u_int nbytes;
+z_free(void *notused, void *ptr, u_int nbytes)
{
free(ptr);
}
static void
-z_comp_stats(arg, stats)
- void *arg;
- struct compstat *stats;
+z_comp_stats(void *arg, struct compstat *stats)
{
struct deflate_state *state = (struct deflate_state *) arg;
u_int out;
* Allocate space for a decompressor.
*/
static void *
-z_decomp_alloc(options, opt_len)
- u_char *options;
- int opt_len;
+z_decomp_alloc(u_char *options, int opt_len)
{
struct deflate_state *state;
int w_size;
}
static void
-z_decomp_free(arg)
- void *arg;
+z_decomp_free(void *arg)
{
struct deflate_state *state = (struct deflate_state *) arg;
}
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;
+z_decomp_init(void *arg, u_char *options, int opt_len,
+ int unit, int hdrlen, int mru, int debug)
{
struct deflate_state *state = (struct deflate_state *) arg;
}
static void
-z_decomp_reset(arg)
- void *arg;
+z_decomp_reset(void *arg)
{
struct deflate_state *state = (struct deflate_state *) arg;
* 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;
+z_decompress(void *arg, u_char *mi, int inlen, u_char *mo, int *outlenp)
{
struct deflate_state *state = (struct deflate_state *) arg;
u_char *rptr, *wptr;
* Incompressible data has arrived - add it to the history.
*/
static void
-z_incomp(arg, mi, mlen)
- void *arg;
- u_char *mi;
- int mlen;
+z_incomp(void *arg, u_char *mi, int mlen)
{
struct deflate_state *state = (struct deflate_state *) arg;
u_char *rptr;
int compress_proto; /* CCP compression protocol number */
/* Allocate space for a decompressor (receive side) */
- void *(*decomp_alloc) __P((u_char *options, int opt_len));
+ void *(*decomp_alloc)(u_char *options, int opt_len);
/* Free space used by a decompressor */
- void (*decomp_free) __P((void *state));
+ void (*decomp_free)(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));
+ int (*decomp_init)(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));
+ void (*decomp_reset)(void *state);
/* Decompress a packet. */
- int (*decompress) __P((void *state, u_char *mp, int inlen,
- u_char *dmp, int *outlen));
+ int (*decompress)(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));
+ void (*incomp)(void *state, u_char *mp, int len);
/* Return decompression statistics */
- void (*decomp_stat) __P((void *state, struct compstat *stats));
+ void (*decomp_stat)(void *state, struct compstat *stats);
};
/*
]] [
.B \-r
] [
+.B \-a
+] [
.B \-m \fImru
] [
.I file \fR...
bytes or packets received, and `rcvd' is printed for bytes or packets
sent.
.TP
+.B \-a
+Prints absolute times.
+.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
++r;
++r;
if (endp - r > mru)
- printf(" ERROR: length (%d) > MRU (%d)\n",
+ printf(" ERROR: length (%zd) > MRU (%d)\n",
endp - r, mru);
if (decompress && fcs == PPP_GOODFCS) {
/* See if this is a CCP or compressed packet */
[
.B \-a
] [
+.B \-d
+] [
.B \-v
] [
.B \-r
Without this option, the second and subsequent reports show statistics
for the time since the last report.
.TP
+.B \-d
+Show data rate (kB/s) instead of bytes.
+.TP
.B \-c \fIcount
Repeat the display
.I count
#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));
+static void usage(void);
+static void catchalarm(int);
+static void get_ppp_stats(struct ppp_stats *);
+static void get_ppp_cstats(struct ppp_comp_stats *);
+static void intpr(void);
-int main __P((int, char *argv[]));
+int main(int, char *argv[]);
static void
-usage()
+usage(void)
{
fprintf(stderr, "Usage: %s [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface]\n",
progname);
* Sets a flag to not wait for the alarm.
*/
static void
-catchalarm(arg)
- int arg;
+catchalarm(int arg)
{
signalled = 1;
}
#ifndef STREAMS
static void
-get_ppp_stats(curp)
- struct ppp_stats *curp;
+get_ppp_stats(struct ppp_stats *curp)
{
struct ifpppstatsreq req;
#define ifr_name ifr__name
#endif
- strncpy(req.ifr_name, interface, sizeof(req.ifr_name));
+ strncpy(req.ifr_name, interface, IFNAMSIZ);
+ req.ifr_name[IFNAMSIZ - 1] = 0;
if (ioctl(s, SIOCGPPPSTATS, &req) < 0) {
fprintf(stderr, "%s: ", progname);
if (errno == ENOTTY)
}
static void
-get_ppp_cstats(csp)
- struct ppp_comp_stats *csp;
+get_ppp_cstats(struct ppp_comp_stats *csp)
{
struct ifpppcstatsreq creq;
#define ifr_name ifr__name
#endif
- strncpy(creq.ifr_name, interface, sizeof(creq.ifr_name));
+ strncpy(creq.ifr_name, interface, IFNAMSIZ);
+ creq.ifr_name[IFNAMSIZ - 1] = 0;
if (ioctl(s, SIOCGPPPCSTATS, &creq) < 0) {
fprintf(stderr, "%s: ", progname);
if (errno == ENOTTY) {
#else /* STREAMS */
int
-strioctl(fd, cmd, ptr, ilen, olen)
- int fd, cmd, ilen, olen;
- char *ptr;
+strioctl(int fd, int cmd, char *ptr, int ilen, int olen)
{
struct strioctl str;
}
static void
-get_ppp_stats(curp)
- struct ppp_stats *curp;
+get_ppp_stats(struct ppp_stats *curp)
{
if (strioctl(s, PPPIO_GETSTAT, curp, 0, sizeof(*curp)) < 0) {
fprintf(stderr, "%s: ", progname);
}
static void
-get_ppp_cstats(csp)
- struct ppp_comp_stats *csp;
+get_ppp_cstats(struct ppp_comp_stats *csp)
{
if (strioctl(s, PPPIO_GETCSTAT, csp, 0, sizeof(*csp)) < 0) {
fprintf(stderr, "%s: ", progname);
* First line printed is cumulative.
*/
static void
-intpr()
+intpr(void)
{
register int line = 0;
sigset_t oldmask, mask;
}
int
-main(argc, argv)
- int argc;
- char *argv[];
+main(int argc, char *argv[])
{
int c;
#ifdef STREAMS
#undef ifr_name
#define ifr_name ifr_ifrn.ifrn_name
#endif
- strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name));
+ strncpy(ifr.ifr_name, interface, IFNAMSIZ);
+ ifr.ifr_name[IFNAMSIZ - 1] = 0;
if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
fprintf(stderr, "%s: nonexistent interface '%s' specified\n",
progname, interface);
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $Id: ppp.c,v 1.4 2005/06/27 00:59:57 carlsonj Exp $
*/
/*
#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.
*/
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 *));
+static int pppopen(queue_t *, dev_t *, int, int, cred_t *);
+static int pppclose(queue_t *, int, cred_t *);
#else
-static int pppopen __P((queue_t *, int, int, int));
-static int pppclose __P((queue_t *, int));
+static int pppopen(queue_t *, int, int, int);
+static int pppclose(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 *));
+static int pppurput(queue_t *, mblk_t *);
+static int pppuwput(queue_t *, mblk_t *);
+static int pppursrv(queue_t *);
+static int pppuwsrv(queue_t *);
+static int ppplrput(queue_t *, mblk_t *);
+static int ppplwput(queue_t *, mblk_t *);
+static int ppplrsrv(queue_t *);
+static int ppplwsrv(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));
+static void dlpi_request(queue_t *, mblk_t *, upperstr_t *);
+static void dlpi_error(queue_t *, upperstr_t *, int, int, int);
+static void dlpi_ok(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 int send_data(mblk_t *, upperstr_t *);
+static void new_ppa(queue_t *, mblk_t *);
+static void attach_ppa(queue_t *, mblk_t *);
#ifndef NO_DLPI
-static void detach_ppa __P((queue_t *, mblk_t *));
+static void detach_ppa(queue_t *, mblk_t *);
#endif
-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));
+static void detach_lower(queue_t *, mblk_t *);
+static void debug_dump(queue_t *, mblk_t *);
+static upperstr_t *find_dest(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));
+static upperstr_t *find_promisc(upperstr_t *, int);
+static mblk_t *prepend_ether(upperstr_t *, mblk_t *, int);
+static mblk_t *prepend_udind(upperstr_t *, mblk_t *, int);
+static void promisc_sendup(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));
+static int putctl2(queue_t *, int, int, int);
+static int putctl4(queue_t *, int, int, int);
+static int pass_packet(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));
+static int ip_hard_filter(upperstr_t *ppa, mblk_t *mp, int outbound);
#endif /* FILTER_PACKETS */
#define PPP_ID 0xb1a6
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));
+static int ahdlc_wput(queue_t *, mblk_t *);
+static int ahdlc_rput(queue_t *, mblk_t *);
+static void ahdlc_encode(queue_t *, mblk_t *);
+static void ahdlc_decode(queue_t *, mblk_t *);
+static int msg_byte(mblk_t *, unsigned int);
#if defined(SOL2)
/*
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));
+static int ppp_comp_rput(queue_t *, mblk_t *);
+static int ppp_comp_rsrv(queue_t *);
+static int ppp_comp_wput(queue_t *, mblk_t *);
+static int ppp_comp_wsrv(queue_t *);
+static void ppp_comp_ccp(queue_t *, mblk_t *, int);
+static int msg_byte(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]: \
#ifdef __osf__
-static void ppp_comp_alloc __P((comp_state_t *));
+static void ppp_comp_alloc(comp_state_t *);
typedef struct memreq {
unsigned char comp_opts[20];
int cmd;
#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 **));
+static int ppp_identify(dev_info_t *);
+static int ppp_attach(dev_info_t *, ddi_attach_cmd_t);
+static int ppp_detach(dev_info_t *, ddi_detach_cmd_t);
+static int ppp_devinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
extern struct streamtab pppinfo;
extern krwlock_t ppp_lower_lock;
*/
#ifdef SVR4
#define MOD_OPEN_DECL(name) \
-static int name __P((queue_t *, dev_t *, int, int, cred_t *))
+static int name(queue_t *, dev_t *, int, int, cred_t *)
#define MOD_CLOSE_DECL(name) \
-static int name __P((queue_t *, int, cred_t *))
+static int name(queue_t *, int, cred_t *)
#define MOD_OPEN(name) \
static int name(q, devp, flag, sflag, credp) \
#else /* not SVR4 */
#define MOD_OPEN_DECL(name) \
-static int name __P((queue_t *, int, int, int))
+static int name(queue_t *, int, int, int)
#define MOD_CLOSE_DECL(name) \
-static int name __P((queue_t *, int))
+static int name(queue_t *, int)
#define MOD_OPEN(name) \
static int name(q, dev, flag, sflag) \