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