1Starting with version 2.3.10, pppd includes support for `plugins' -
2pieces of code which can be loaded into pppd at runtime and which can
3affect its behaviour in various ways.  The idea of plugins is to
4provide a way for people to customize the behaviour of pppd without
5having to either apply local patches to each version or get their
6patches accepted into the standard distribution.
7
8A plugin is a standard shared library object, typically with a name
9ending in .so.  They are loaded using the standard dlopen() library
10call, so plugins are only supported on systems which support shared
11libraries and the dlopen call.  At present pppd is compiled with
12plugin support only under Linux and Solaris.
13
14Plugins are loaded into pppd using the `plugin' option, which takes
15one argument, the name of a shared object file.  The plugin option is
16a privileged option.  If the name given does not contain a slash, pppd
17will look in the /usr/lib/pppd/<version> directory for the file, where
18<version> is the version number of pppd, for example, 2.4.2.  I
19suggest that you either give the full path name of the shared object
20file or just the base name; if you don't, it may be possible for
21unscrupulous users to substitute another shared object file for the
22one you mean to load, e.g. by setting the LD_LIBRARY_PATH variable.
23
24Plugins are usually written in C and compiled and linked to a shared
25object file in the appropriate manner for your platform.  Using gcc
26under Linux, a plugin called `xyz' could be compiled and linked with
27the following commands:
28
29	gcc -c -O xyz.c
30	gcc -shared -o xyz.so xyz.o
31
32There are some example plugins in the pppd/plugins directory in the
33ppp distribution.  Currently there is one example, minconn.c, which
34implements a `minconnect' option, which specifies a minimum connect
35time before the idle timeout applies.
36
37Plugins can access global variables within pppd, so it is useful for
38them to #include "pppd.h" from the pppd source directory.
39
40Every plugin must contain a global procedure called `plugin_init'.
41This procedure will get called (with no arguments) immediately after
42the plugin is loaded.  Every plugin should also contain a variable
43called pppd_version declared as follows:
44
45char pppd_version[] = VERSION;
46
47If this declaration is included, pppd will not load the module if its
48version number differs from that compiled into the plugin binary.
49
50Plugins can affect the behaviour of pppd in at least four ways:
51
521. They can add extra options which pppd will then recognize.  This is
53   done by calling the add_options() procedure with a pointer to an
54   array of option_t structures.  The last entry in the array must
55   have its name field set to NULL.
56
572. Pppd contains `hook' variables which are procedure pointers.  If a
58   given hook is not NULL, pppd will call the procedure it points to
59   at the appropriate point in its processing.  The plugin can set any
60   of these hooks to point to its own procedures.  See below for a
61   description of the hooks which are currently implemented.
62
633. Plugin code can call any global procedures and access any global
64   variables in pppd.
65
664. Plugins can register procedures to be called when particular events
67   occur, using the `notifier' mechanism in pppd.  The differences
68   between hooks and notifiers are that a hook will only call one
69   function, whereas a notifier can call an arbitrary number, and that
70   a hook usually returns some value to pppd, whereas a notifier
71   function returns nothing.
72
73Here is a list of the currently implemented hooks in pppd.
74
75
76int (*idle_time_hook)(struct ppp_idle *idlep);
77
78The idle_time_hook is called when the link first comes up (i.e. when
79the first network protocol comes up) and at intervals thereafter.  On
80the first call, the idlep parameter is NULL, and the return value is
81the number of seconds before pppd should check the link activity, or 0
82if there is to be no idle timeout.
83
84On subsequent calls, idlep points to a structure giving the number of
85seconds since the last packets were sent and received.  If the return
86value is > 0, pppd will wait that many seconds before checking again.
87If it is <= 0, that indicates that the link should be terminated due
88to lack of activity.
89
90
91int (*holdoff_hook)(void);
92
93The holdoff_hook is called when an attempt to bring up the link fails,
94or the link is terminated, and the persist or demand option was used.
95It returns the number of seconds that pppd should wait before trying
96to reestablish the link (0 means immediately).
97
98
99int (*pap_check_hook)(void);
100int (*pap_passwd_hook)(char *user, char *passwd);
101int (*pap_auth_hook)(char *user, char *passwd, char **msgp,
102		     struct wordlist **paddrs,
103		     struct wordlist **popts);
104void (*pap_logout_hook)(void);
105
106These hooks are designed to allow a plugin to replace the normal PAP
107password processing in pppd with something different (e.g. contacting
108an external server).
109
110The pap_check_hook is called to check whether there is any possibility
111that the peer could authenticate itself to us.  If it returns 1, pppd
112will ask the peer to authenticate itself.  If it returns 0, pppd will
113not ask the peer to authenticate itself (but if authentication is
114required, pppd may exit, or terminate the link before network protocol
115negotiation).  If it returns -1, pppd will look in the pap-secrets
116file as it would normally.
117
118The pap_passwd_hook is called to determine what username and password
119pppd should use in authenticating itself to the peer with PAP.  The
120user string will already be initialized, by the `user' option, the
121`name' option, or from the hostname, but can be changed if necessary.
122MAXNAMELEN bytes of space are available at *user, and MAXSECRETLEN
123bytes of space at *passwd.  If this hook returns 0, pppd will use the
124values at *user and *passwd; if it returns -1, pppd will look in the
125pap-secrets file, or use the value from the +ua or password option, as
126it would normally.
127
128The pap_auth_hook is called to determine whether the username and
129password supplied by the peer are valid.  user and passwd point to
130null-terminated strings containing the username and password supplied
131by the peer, with non-printable characters converted to a printable
132form.  The pap_auth_hook function should set msg to a string to be
133returned to the peer and return 1 if the username/password was valid
134and 0 if not.  If the hook returns -1, pppd will look in the
135pap-secrets file as usual.
136
137If the username/password was valid, the hook can set *paddrs to point
138to a wordlist containing the IP address(es) which the peer is
139permitted to use, formatted as in the pap-secrets file.  It can also
140set *popts to a wordlist containing any extra options for this user
141which pppd should apply at this point.
142
143The pap_logout_hook is called when the link is terminated, instead of
144pppd's internal `plogout' function.  It can be used for accounting
145purposes.  This hook is deprecated and will be replaced by a notifier.
146
147
148int (*chap_check_hook)(void);
149int (*chap_passwd_hook)(char *user, char *passwd);
150int (*chap_verify_hook)(char *name, char *ourname, int id,
151			struct chap_digest_type *digest,
152			unsigned char *challenge, unsigned char *response,
153			char *message, int message_space)
154
155These hooks are designed to allow a plugin to replace the normal CHAP
156password processing in pppd with something different (e.g. contacting
157an external server).
158
159The chap_check_hook is called to check whether there is any possibility
160that the peer could authenticate itself to us.  If it returns 1, pppd
161will ask the peer to authenticate itself.  If it returns 0, pppd will
162not ask the peer to authenticate itself (but if authentication is
163required, pppd may exit, or terminate the link before network protocol
164negotiation).  If it returns -1, pppd will look in the chap-secrets
165file as it would normally.
166
167The chap_passwd_hook is called to determine what password
168pppd should use in authenticating itself to the peer with CHAP.  The
169user string will already be initialized, by the `user' option, the
170`name' option, or from the hostname, but can be changed if necessary.
171This hook is called only if pppd is a client, not if it is a server.
172
173MAXSECRETLEN bytes of space are available at *passwd.  If this hook
174returns 0, pppd will use the value *passwd; if it returns -1, pppd
175will fail to authenticate.
176
177The chap_verify_hook is called to determine whether the peer's
178response to our CHAP challenge is valid -- it should return 1 if valid
179or 0 if not.  The parameters are:
180
181* name points to a null-terminated string containing the username
182  supplied by the peer, or the remote name specified with the
183  "remotename" option.
184* ourname points to a null-terminated string containing the name of
185  the local machine (the hostname, or the name specified with the
186  "name" option).
187* id is the value of the id field from the challenge.
188* digest points to a chap_digest_type struct, which contains an
189  identifier for the type of digest in use plus function pointers for
190  functions for dealing with digests of that type.
191* challenge points to the challenge as a counted string (length byte
192  followed by the actual challenge bytes).
193* response points to the response as a counted string.
194* message points to an area of message_space bytes in which to store
195  any message that should be returned to the peer.
196
197
198int (*null_auth_hook)(struct wordlist **paddrs,
199		      struct wordlist **popts);
200
201This hook allows a plugin to determine what the policy should be if
202the peer refuses to authenticate when it is requested to.  If the
203return value is 0, the link will be terminated; if it is 1, the
204connection is allowed to proceed, and in this case *paddrs and *popts
205can be set as for pap_auth_hook, to specify what IP addresses are
206permitted and any extra options to be applied.  If the return value is
207-1, pppd will look in the pap-secrets file as usual.
208
209
210void (*ip_choose_hook)(u_int32_t *addrp);
211
212This hook is called at the beginning of IPCP negotiation.  It gives a
213plugin the opportunity to set the IP address for the peer; the address
214should be stored in *addrp.  If nothing is stored in *addrp, pppd will
215determine the peer's address in the usual manner.
216
217
218int (*allowed_address_hook)(u_int32_t addr)
219
220This hook is called to see if a peer is allowed to use the specified
221address.  If the hook returns 1, the address is accepted.  If it returns
2220, the address is rejected.  If it returns -1, the address is verified
223in the normal away against the appropriate options and secrets files.
224
225
226void (*snoop_recv_hook)(unsigned char *p, int len)
227void (*snoop_send_hook)(unsigned char *p, int len)
228
229These hooks are called whenever pppd receives or sends a packet.  The
230packet is in p; its length is len.  This allows plugins to "snoop in"
231on the pppd conversation.  The hooks may prove useful in implmenting
232L2TP.
233
234
235void (*multilink_join_hook)();
236
237This is called whenever a new link completes LCP negotiation and joins
238the bundle, if we are doing multilink.
239
240
241A plugin registers itself with a notifier by declaring a procedure of
242the form:
243
244void my_notify_proc(void *opaque, int arg);
245
246and then registering the procedure with the appropriate notifier with
247a call of the form
248
249	add_notifier(&interesting_notifier, my_notify_proc, opaque);
250
251The `opaque' parameter in the add_notifier call will be passed to
252my_notify_proc every time it is called.  The `arg' parameter to
253my_notify_proc depends on the notifier.
254
255A notify procedure can be removed from the list for a notifier with a
256call of the form
257
258	remove_notifier(&interesting_notifier, my_notify_proc, opaque);
259
260Here is a list of the currently-implemented notifiers in pppd.
261
262* pidchange.  This notifier is called in the parent when pppd has
263  forked and the child is continuing pppd's processing, i.e. when pppd
264  detaches from its controlling terminal.  The argument is the pid of
265  the child.
266
267* phasechange.  This is called when pppd moves from one phase of
268  operation to another.  The argument is the new phase number.
269
270* exitnotify.  This is called just before pppd exits.  The argument is
271  the status with which pppd will exit (i.e. the argument to exit()).
272
273* sigreceived.  This is called when a signal is received, from within
274  the signal handler.  The argument is the signal number.
275
276* ip_up_notifier.  This is called when IPCP has come up.
277
278* ip_down_notifier.  This is called when IPCP goes down.
279
280* auth_up_notifier.  This is called when the peer has successfully
281  authenticated itself.
282
283* link_down_notifier.  This is called when the link goes down.
284
285
286
287## $Id: PLUGINS,v 1.8 2008/06/15 07:02:18 paulus Exp $ ##
288