Fix an fd leak on the discovery socket.
[ppp.git] / PLUGINS
diff --git a/PLUGINS b/PLUGINS
index 490dad32dde671def636753ccb5a3b3e099dd6e2..af43f51fee859d1cf0f5052e7fcac091e40fb782 100644 (file)
--- a/PLUGINS
+++ b/PLUGINS
@@ -3,20 +3,21 @@ pieces of code which can be loaded into pppd at runtime and which can
 affect its behaviour in various ways.  The idea of plugins is to
 provide a way for people to customize the behaviour of pppd without
 having to either apply local patches to each version or get their
-patches accepted into the standard distribution.  My aim is that
-plugins will be able to be used with successive versions of pppd
-without needing to recompile the plugins.
+patches accepted into the standard distribution.
 
 A plugin is a standard shared library object, typically with a name
 ending in .so.  They are loaded using the standard dlopen() library
 call, so plugins are only supported on systems which support shared
 libraries and the dlopen call.  At present pppd is compiled with
-plugin support only under Linux.
+plugin support only under Linux and Solaris.
 
 Plugins are loaded into pppd using the `plugin' option, which takes
 one argument, the name of a shared object file.  The plugin option is
-a privileged option.  I suggest that you give the full path name of
-the shared object file; if you don't, it may be possible for
+a privileged option.  If the name given does not contain a slash, pppd
+will look in the /usr/lib/pppd/<version> directory for the file, where
+<version> is the version number of pppd, for example, 2.4.2.  I
+suggest that you either give the full path name of the shared object
+file or just the base name; if you don't, it may be possible for
 unscrupulous users to substitute another shared object file for the
 one you mean to load, e.g. by setting the LD_LIBRARY_PATH variable.
 
@@ -28,14 +29,25 @@ the following commands:
        gcc -c -O xyz.c
        gcc -shared -o xyz.so xyz.o
 
+There are some example plugins in the pppd/plugins directory in the
+ppp distribution.  Currently there is one example, minconn.c, which
+implements a `minconnect' option, which specifies a minimum connect
+time before the idle timeout applies.
+
 Plugins can access global variables within pppd, so it is useful for
 them to #include "pppd.h" from the pppd source directory.
 
 Every plugin must contain a global procedure called `plugin_init'.
 This procedure will get called (with no arguments) immediately after
-the plugin is loaded.
+the plugin is loaded.  Every plugin should also contain a variable
+called pppd_version declared as follows:
+
+char pppd_version[] = VERSION;
 
-Plugins can affect the behaviour of pppd in at least three ways:
+If this declaration is included, pppd will not load the module if its
+version number differs from that compiled into the plugin binary.
+
+Plugins can affect the behaviour of pppd in at least four ways:
 
 1. They can add extra options which pppd will then recognize.  This is
    done by calling the add_options() procedure with a pointer to an
@@ -51,6 +63,13 @@ Plugins can affect the behaviour of pppd in at least three ways:
 3. Plugin code can call any global procedures and access any global
    variables in pppd.
 
+4. Plugins can register procedures to be called when particular events
+   occur, using the `notifier' mechanism in pppd.  The differences
+   between hooks and notifiers are that a hook will only call one
+   function, whereas a notifier can call an arbitrary number, and that
+   a hook usually returns some value to pppd, whereas a notifier
+   function returns nothing.
+
 Here is a list of the currently implemented hooks in pppd.
 
 
@@ -79,11 +98,10 @@ to reestablish the link (0 means immediately).
 
 int (*pap_check_hook)(void);
 int (*pap_passwd_hook)(char *user, char *passwd);
-int (*pap_auth_hook)(char *user, int userlen,
-                    char *passwd, int passlen,
-                    char **msgp, int *msglenp,
+int (*pap_auth_hook)(char *user, char *passwd, char **msgp,
                     struct wordlist **paddrs,
                     struct wordlist **popts);
+void (*pap_logout_hook)(void);
 
 These hooks are designed to allow a plugin to replace the normal PAP
 password processing in pppd with something different (e.g. contacting
@@ -122,5 +140,127 @@ permitted to use, formatted as in the pap-secrets file.  It can also
 set *popts to a wordlist containing any extra options for this user
 which pppd should apply at this point.
 
+The pap_logout_hook is called when the link is terminated, instead of
+pppd's internal `plogout' function.  It can be used for accounting
+purposes.  This hook is deprecated and will be replaced by a notifier.
+
+
+int (*chap_check_hook)(void);
+int (*chap_passwd_hook)(char *user, char *passwd);
+int (*chap_auth_hook)(char *user, u_char *remmd,
+                    int remmd_len, chap_state *cstate);
+
+These hooks are designed to allow a plugin to replace the normal CHAP
+password processing in pppd with something different (e.g. contacting
+an external server).
+
+The chap_check_hook is called to check whether there is any possibility
+that the peer could authenticate itself to us.  If it returns 1, pppd
+will ask the peer to authenticate itself.  If it returns 0, pppd will
+not ask the peer to authenticate itself (but if authentication is
+required, pppd may exit, or terminate the link before network protocol
+negotiation).  If it returns -1, pppd will look in the chap-secrets
+file as it would normally.
+
+The chap_passwd_hook is called to determine what password
+pppd should use in authenticating itself to the peer with CHAP.  The
+user string will already be initialized, by the `user' option, the
+`name' option, or from the hostname, but can be changed if necessary.
+This hook is called only if pppd is a client, not if it is a server.
+
+MAXSECRETLEN bytes of space are available at *passwd.  If this hook
+returns 0, pppd will use the value *passwd; if it returns -1, pppd
+will fail to authenticate.
+
+The chap_auth_hook is called to determine whether the response
+to a CHAP challenge provided by the peer is valid.  user points to
+a null-terminated string containing the username supplied
+by the peer.  remmd points to the response provided by the peer, of
+length remmd_len bytes.  cstate is the internal CHAP state structure
+maintained by pppd.  chap_auth_hook is expected to return one of
+CHAP_SUCCESS or CHAP_FAILURE.
+
+
+int (*null_auth_hook)(struct wordlist **paddrs,
+                     struct wordlist **popts);
+
+This hook allows a plugin to determine what the policy should be if
+the peer refuses to authenticate when it is requested to.  If the
+return value is 0, the link will be terminated; if it is 1, the
+connection is allowed to proceed, and in this case *paddrs and *popts
+can be set as for pap_auth_hook, to specify what IP addresses are
+permitted and any extra options to be applied.  If the return value is
+-1, pppd will look in the pap-secrets file as usual.
+
+
+void (*ip_choose_hook)(u_int32_t *addrp);
+
+This hook is called at the beginning of IPCP negotiation.  It gives a
+plugin the opportunity to set the IP address for the peer; the address
+should be stored in *addrp.  If nothing is stored in *addrp, pppd will
+determine the peer's address in the usual manner.
+
+
+int (*allowed_address_hook)(u_int32_t addr)
+
+This hook is called to see if a peer is allowed to use the specified
+address.  If the hook returns 1, the address is accepted.  If it returns
+0, the address is rejected.  If it returns -1, the address is verified
+in the normal away against the appropriate options and secrets files.
+
+
+void (*snoop_recv_hook)(unsigned char *p, int len)
+void (*snoop_send_hook)(unsigned char *p, int len)
+
+These hooks are called whenever pppd receives or sends a packet.  The
+packet is in p; its length is len.  This allows plugins to "snoop in"
+on the pppd conversation.  The hooks may prove useful in implmenting
+L2TP.
+
+A plugin registers itself with a notifier by declaring a procedure of
+the form:
+
+void my_notify_proc(void *opaque, int arg);
+
+and then registering the procedure with the appropriate notifier with
+a call of the form
+
+       add_notifier(&interesting_notifier, my_notify_proc, opaque);
+
+The `opaque' parameter in the add_notifier call will be passed to
+my_notify_proc every time it is called.  The `arg' parameter to
+my_notify_proc depends on the notifier.
+
+A notify procedure can be removed from the list for a notifier with a
+call of the form
+
+       remove_notifier(&interesting_notifier, my_notify_proc, opaque);
+
+Here is a list of the currently-implemented notifiers in pppd.
+
+* pidchange.  This notifier is called in the parent when pppd has
+  forked and the child is continuing pppd's processing, i.e. when pppd
+  detaches from its controlling terminal.  The argument is the pid of
+  the child.
+
+* phasechange.  This is called when pppd moves from one phase of
+  operation to another.  The argument is the new phase number.
+
+* exitnotify.  This is called just before pppd exits.  The argument is
+  the status with which pppd will exit (i.e. the argument to exit()).
+
+* sigreceived.  This is called when a signal is received, from within
+  the signal handler.  The argument is the signal number.
+
+* ip_up_notifier.  This is called when IPCP has come up.
+
+* ip_down_notifier.  This is called when IPCP goes down.
+
+* auth_up_notifier.  This is called when the peer has successfully
+  authenticated itself.
+
+* link_down_notifier.  This is called when the link goes down.
+
+
 
-## $Id: PLUGINS,v 1.1 1999/09/11 12:09:31 paulus Exp $ ##
+## $Id: PLUGINS,v 1.6 2003/02/25 07:43:09 fcusack Exp $ ##