1 diff -ruNp ppp-2.4.5/pppd/ipcp.c ppp-2.4.5_new/pppd/ipcp.c
2 --- ppp-2.4.5/pppd/ipcp.c 2009-11-17 01:26:07.000000000 +0300
3 +++ ppp-2.4.5_new/pppd/ipcp.c 2010-11-24 17:43:52.236670147 +0300
4 @@ -198,6 +198,14 @@ static option_t ipcp_option_list[] = {
5 "disable defaultroute option", OPT_ALIAS | OPT_A2CLR,
6 &ipcp_wantoptions[0].default_route },
8 + { "replacedefaultroute", o_bool,
9 + &ipcp_wantoptions[0].replace_default_route,
10 + "Replace default route", 1
12 + { "noreplacedefaultroute", o_bool,
13 + &ipcp_allowoptions[0].replace_default_route,
14 + "Never replace default route", OPT_A2COPY,
15 + &ipcp_wantoptions[0].replace_default_route },
16 { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
17 "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
18 { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
19 @@ -271,7 +279,7 @@ struct protent ipcp_protent = {
23 -static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
24 +static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool));
25 static void ipcp_script __P((char *, int)); /* Run an up/down script */
26 static void ipcp_script_done __P((void *));
28 @@ -1742,7 +1750,8 @@ ip_demand_conf(u)
29 if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
31 if (wo->default_route)
32 - if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
33 + if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr,
34 + wo->replace_default_route))
35 default_route_set[u] = 1;
37 if (sifproxyarp(u, wo->hisaddr))
38 @@ -1830,7 +1839,8 @@ ipcp_up(f)
41 if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
42 - ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
43 + ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr,
44 + wo->replace_default_route);
45 if (go->ouraddr != wo->ouraddr) {
46 warn("Local IP address changed to %I", go->ouraddr);
47 script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
48 @@ -1855,7 +1865,8 @@ ipcp_up(f)
50 /* assign a default route through the interface if required */
51 if (ipcp_wantoptions[f->unit].default_route)
52 - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
53 + if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
54 + wo->replace_default_route))
55 default_route_set[f->unit] = 1;
57 /* Make a proxy ARP entry if requested. */
58 @@ -1905,7 +1916,8 @@ ipcp_up(f)
60 /* assign a default route through the interface if required */
61 if (ipcp_wantoptions[f->unit].default_route)
62 - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
63 + if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
64 + wo->replace_default_route))
65 default_route_set[f->unit] = 1;
67 /* Make a proxy ARP entry if requested. */
68 @@ -1983,7 +1995,7 @@ ipcp_down(f)
69 sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
71 ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
72 - ipcp_hisoptions[f->unit].hisaddr);
73 + ipcp_hisoptions[f->unit].hisaddr, 0);
76 /* Execute the ip-down script */
77 @@ -1999,16 +2011,25 @@ ipcp_down(f)
78 * proxy arp entries, etc.
81 -ipcp_clear_addrs(unit, ouraddr, hisaddr)
82 +ipcp_clear_addrs(unit, ouraddr, hisaddr, replacedefaultroute)
84 u_int32_t ouraddr; /* local address */
85 u_int32_t hisaddr; /* remote address */
86 + bool replacedefaultroute;
88 if (proxy_arp_set[unit]) {
89 cifproxyarp(unit, hisaddr);
90 proxy_arp_set[unit] = 0;
92 - if (default_route_set[unit]) {
93 + /* If replacedefaultroute, sifdefaultroute will be called soon
94 + * with replacedefaultroute set and that will overwrite the current
95 + * default route. This is the case only when doing demand, otherwise
96 + * during demand, this cifdefaultroute would restore the old default
97 + * route which is not what we want in this case. In the non-demand
98 + * case, we'll delete the default route and restore the old if there
99 + * is one saved by an sifdefaultroute with replacedefaultroute.
101 + if (!replacedefaultroute && default_route_set[unit]) {
102 cifdefaultroute(unit, ouraddr, hisaddr);
103 default_route_set[unit] = 0;
105 diff -ruNp ppp-2.4.5/pppd/ipcp.c.orig ppp-2.4.5_new/pppd/ipcp.c.orig
106 --- ppp-2.4.5/pppd/ipcp.c.orig 1970-01-01 03:00:00.000000000 +0300
107 +++ ppp-2.4.5_new/pppd/ipcp.c.orig 2010-11-24 17:43:05.266670147 +0300
110 + * ipcp.c - PPP IP Control Protocol.
112 + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
114 + * Redistribution and use in source and binary forms, with or without
115 + * modification, are permitted provided that the following conditions
118 + * 1. Redistributions of source code must retain the above copyright
119 + * notice, this list of conditions and the following disclaimer.
121 + * 2. Redistributions in binary form must reproduce the above copyright
122 + * notice, this list of conditions and the following disclaimer in
123 + * the documentation and/or other materials provided with the
126 + * 3. The name "Carnegie Mellon University" must not be used to
127 + * endorse or promote products derived from this software without
128 + * prior written permission. For permission or any legal
129 + * details, please contact
130 + * Office of Technology Transfer
131 + * Carnegie Mellon University
132 + * 5000 Forbes Avenue
133 + * Pittsburgh, PA 15213-3890
134 + * (412) 268-4387, fax: (412) 268-7395
135 + * tech-transfer@andrew.cmu.edu
137 + * 4. Redistributions of any form whatsoever must retain the following
139 + * "This product includes software developed by Computing Services
140 + * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
142 + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
143 + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
144 + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
145 + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
146 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
147 + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
148 + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
151 +#define RCSID "$Id: ipcp.c,v 1.73 2008/05/26 08:33:22 paulus Exp $"
161 +#include <sys/param.h>
162 +#include <sys/types.h>
163 +#include <sys/socket.h>
164 +#include <netinet/in.h>
165 +#include <arpa/inet.h>
170 +#include "pathnames.h"
172 +static const char rcsid[] = RCSID;
175 +ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
176 +ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
177 +ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
178 +ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
180 +u_int32_t netmask = 0; /* IP netmask to set on interface */
182 +bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */
183 +bool noremoteip = 0; /* Let him have no IP address */
185 +/* Hook for a plugin to know when IP protocol has come up */
186 +void (*ip_up_hook) __P((void)) = NULL;
188 +/* Hook for a plugin to know when IP protocol has come down */
189 +void (*ip_down_hook) __P((void)) = NULL;
191 +/* Hook for a plugin to choose the remote IP address */
192 +void (*ip_choose_hook) __P((u_int32_t *)) = NULL;
194 +/* Notifiers for when IPCP goes up and down */
195 +struct notifier *ip_up_notifier = NULL;
196 +struct notifier *ip_down_notifier = NULL;
199 +static int default_route_set[NUM_PPP]; /* Have set up a default route */
200 +static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */
201 +static bool usepeerdns; /* Ask peer for DNS addrs */
202 +static int ipcp_is_up; /* have called np_up() */
203 +static int ipcp_is_open; /* haven't called np_finished() */
204 +static bool ask_for_local; /* request our address from peer */
205 +static char vj_value[8]; /* string form of vj option value */
206 +static char netmask_str[20]; /* string form of netmask value */
209 + * Callbacks for fsm code. (CI = Configuration Information)
211 +static void ipcp_resetci __P((fsm *)); /* Reset our CI */
212 +static int ipcp_cilen __P((fsm *)); /* Return length of our CI */
213 +static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
214 +static int ipcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
215 +static int ipcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */
216 +static int ipcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
217 +static int ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
218 +static void ipcp_up __P((fsm *)); /* We're UP */
219 +static void ipcp_down __P((fsm *)); /* We're DOWN */
220 +static void ipcp_finished __P((fsm *)); /* Don't need lower layer */
222 +fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */
224 +static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
225 + ipcp_resetci, /* Reset our Configuration Information */
226 + ipcp_cilen, /* Length of our Configuration Information */
227 + ipcp_addci, /* Add our Configuration Information */
228 + ipcp_ackci, /* ACK our Configuration Information */
229 + ipcp_nakci, /* NAK our Configuration Information */
230 + ipcp_rejci, /* Reject our Configuration Information */
231 + ipcp_reqci, /* Request peer's Configuration Information */
232 + ipcp_up, /* Called when fsm reaches OPENED state */
233 + ipcp_down, /* Called when fsm leaves OPENED state */
234 + NULL, /* Called when we want the lower layer up */
235 + ipcp_finished, /* Called when we want the lower layer down */
236 + NULL, /* Called when Protocol-Reject received */
237 + NULL, /* Retransmission is necessary */
238 + NULL, /* Called to handle protocol-specific codes */
239 + "IPCP" /* String name of protocol */
243 + * Command-line options.
245 +static int setvjslots __P((char **));
246 +static int setdnsaddr __P((char **));
247 +static int setwinsaddr __P((char **));
248 +static int setnetmask __P((char **));
249 +int setipaddr __P((char *, char **, int));
250 +static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *));
252 +static option_t ipcp_option_list[] = {
253 + { "noip", o_bool, &ipcp_protent.enabled_flag,
254 + "Disable IP and IPCP" },
255 + { "-ip", o_bool, &ipcp_protent.enabled_flag,
256 + "Disable IP and IPCP", OPT_ALIAS },
258 + { "novj", o_bool, &ipcp_wantoptions[0].neg_vj,
259 + "Disable VJ compression", OPT_A2CLR, &ipcp_allowoptions[0].neg_vj },
260 + { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj,
261 + "Disable VJ compression", OPT_ALIAS | OPT_A2CLR,
262 + &ipcp_allowoptions[0].neg_vj },
264 + { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag,
265 + "Disable VJ connection-ID compression", OPT_A2CLR,
266 + &ipcp_allowoptions[0].cflag },
267 + { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag,
268 + "Disable VJ connection-ID compression", OPT_ALIAS | OPT_A2CLR,
269 + &ipcp_allowoptions[0].cflag },
271 + { "vj-max-slots", o_special, (void *)setvjslots,
272 + "Set maximum VJ header slots",
273 + OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, vj_value },
275 + { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local,
276 + "Accept peer's address for us", 1 },
277 + { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote,
278 + "Accept peer's address for it", 1 },
280 + { "ipparam", o_string, &ipparam,
281 + "Set ip script parameter", OPT_PRIO },
283 + { "noipdefault", o_bool, &disable_defaultip,
284 + "Don't use name for default IP adrs", 1 },
286 + { "ms-dns", 1, (void *)setdnsaddr,
287 + "DNS address for the peer's use" },
288 + { "ms-wins", 1, (void *)setwinsaddr,
289 + "Nameserver for SMB over TCP/IP for peer" },
291 + { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime,
292 + "Set timeout for IPCP", OPT_PRIO },
293 + { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits,
294 + "Set max #xmits for term-reqs", OPT_PRIO },
295 + { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits,
296 + "Set max #xmits for conf-reqs", OPT_PRIO },
297 + { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops,
298 + "Set max #conf-naks for IPCP", OPT_PRIO },
300 + { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route,
301 + "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route },
302 + { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route,
303 + "disable defaultroute option", OPT_A2CLR,
304 + &ipcp_wantoptions[0].default_route },
305 + { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route,
306 + "disable defaultroute option", OPT_ALIAS | OPT_A2CLR,
307 + &ipcp_wantoptions[0].default_route },
309 + { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
310 + "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
311 + { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
312 + "disable proxyarp option", OPT_A2CLR,
313 + &ipcp_wantoptions[0].proxy_arp },
314 + { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
315 + "disable proxyarp option", OPT_ALIAS | OPT_A2CLR,
316 + &ipcp_wantoptions[0].proxy_arp },
318 + { "usepeerdns", o_bool, &usepeerdns,
319 + "Ask peer for DNS address(es)", 1 },
321 + { "netmask", o_special, (void *)setnetmask,
322 + "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str },
324 + { "ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs,
325 + "Disable old-style IP-Addresses usage", OPT_A2CLR,
326 + &ipcp_allowoptions[0].old_addrs },
327 + { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr,
328 + "Disable IP-Address usage", OPT_A2CLR,
329 + &ipcp_allowoptions[0].neg_addr },
331 + { "noremoteip", o_bool, &noremoteip,
332 + "Allow peer to have no IP address", 1 },
334 + { "nosendip", o_bool, &ipcp_wantoptions[0].neg_addr,
335 + "Don't send our IP address to peer", OPT_A2CLR,
336 + &ipcp_wantoptions[0].old_addrs},
338 + { "IP addresses", o_wild, (void *) &setipaddr,
339 + "set local and remote IP addresses",
340 + OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr },
346 + * Protocol entry points from main code.
348 +static void ipcp_init __P((int));
349 +static void ipcp_open __P((int));
350 +static void ipcp_close __P((int, char *));
351 +static void ipcp_lowerup __P((int));
352 +static void ipcp_lowerdown __P((int));
353 +static void ipcp_input __P((int, u_char *, int));
354 +static void ipcp_protrej __P((int));
355 +static int ipcp_printpkt __P((u_char *, int,
356 + void (*) __P((void *, char *, ...)), void *));
357 +static void ip_check_options __P((void));
358 +static int ip_demand_conf __P((int));
359 +static int ip_active_pkt __P((u_char *, int));
360 +static void create_resolv __P((u_int32_t, u_int32_t));
362 +struct protent ipcp_protent = {
382 +static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
383 +static void ipcp_script __P((char *, int)); /* Run an up/down script */
384 +static void ipcp_script_done __P((void *));
387 + * Lengths of configuration options.
389 +#define CILEN_VOID 2
390 +#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */
391 +#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */
392 +#define CILEN_ADDR 6 /* new-style single address option */
393 +#define CILEN_ADDRS 10 /* old-style dual address option */
396 +#define CODENAME(x) ((x) == CONFACK ? "ACK" : \
397 + (x) == CONFNAK ? "NAK" : "REJ")
400 + * This state variable is used to ensure that we don't
401 + * run an ipcp-up/down script while one is already running.
403 +static enum script_state {
406 +} ipcp_script_state;
407 +static pid_t ipcp_script_pid;
410 + * Make a string representation of a network IP address.
418 + slprintf(b, sizeof(b), "%I", ipaddr);
427 + * setvjslots - set maximum number of connection slots for VJ compression
435 + if (!int_option(*argv, &value))
437 + if (value < 2 || value > 16) {
438 + option_error("vj-max-slots value must be between 2 and 16");
441 + ipcp_wantoptions [0].maxslotindex =
442 + ipcp_allowoptions[0].maxslotindex = value - 1;
443 + slprintf(vj_value, sizeof(vj_value), "%d", value);
448 + * setdnsaddr - set the dns address(es)
455 + struct hostent *hp;
457 + dns = inet_addr(*argv);
458 + if (dns == (u_int32_t) -1) {
459 + if ((hp = gethostbyname(*argv)) == NULL) {
460 + option_error("invalid address parameter '%s' for ms-dns option",
464 + dns = *(u_int32_t *)hp->h_addr;
467 + /* We take the last 2 values given, the 2nd-last as the primary
468 + and the last as the secondary. If only one is given it
469 + becomes both primary and secondary. */
470 + if (ipcp_allowoptions[0].dnsaddr[1] == 0)
471 + ipcp_allowoptions[0].dnsaddr[0] = dns;
473 + ipcp_allowoptions[0].dnsaddr[0] = ipcp_allowoptions[0].dnsaddr[1];
475 + /* always set the secondary address value. */
476 + ipcp_allowoptions[0].dnsaddr[1] = dns;
482 + * setwinsaddr - set the wins address(es)
483 + * This is primrarly used with the Samba package under UNIX or for pointing
484 + * the caller to the existing WINS server on a Windows NT platform.
491 + struct hostent *hp;
493 + wins = inet_addr(*argv);
494 + if (wins == (u_int32_t) -1) {
495 + if ((hp = gethostbyname(*argv)) == NULL) {
496 + option_error("invalid address parameter '%s' for ms-wins option",
500 + wins = *(u_int32_t *)hp->h_addr;
503 + /* We take the last 2 values given, the 2nd-last as the primary
504 + and the last as the secondary. If only one is given it
505 + becomes both primary and secondary. */
506 + if (ipcp_allowoptions[0].winsaddr[1] == 0)
507 + ipcp_allowoptions[0].winsaddr[0] = wins;
509 + ipcp_allowoptions[0].winsaddr[0] = ipcp_allowoptions[0].winsaddr[1];
511 + /* always set the secondary address value. */
512 + ipcp_allowoptions[0].winsaddr[1] = wins;
518 + * setipaddr - Set the IP address
519 + * If doit is 0, the call is to check whether this option is
520 + * potentially an IP address specification.
521 + * Not static so that plugins can call it to set the addresses
524 +setipaddr(arg, argv, doit)
529 + struct hostent *hp;
531 + u_int32_t local, remote;
532 + ipcp_options *wo = &ipcp_wantoptions[0];
533 + static int prio_local = 0, prio_remote = 0;
536 + * IP address pair separated by ":".
538 + if ((colon = strchr(arg, ':')) == NULL)
544 + * If colon first character, then no local addr.
546 + if (colon != arg && option_priority >= prio_local) {
548 + if ((local = inet_addr(arg)) == (u_int32_t) -1) {
549 + if ((hp = gethostbyname(arg)) == NULL) {
550 + option_error("unknown host: %s", arg);
553 + local = *(u_int32_t *)hp->h_addr;
555 + if (bad_ip_adrs(local)) {
556 + option_error("bad local IP address %s", ip_ntoa(local));
560 + wo->ouraddr = local;
562 + prio_local = option_priority;
566 + * If colon last character, then no remote addr.
568 + if (*++colon != '\0' && option_priority >= prio_remote) {
569 + if ((remote = inet_addr(colon)) == (u_int32_t) -1) {
570 + if ((hp = gethostbyname(colon)) == NULL) {
571 + option_error("unknown host: %s", colon);
574 + remote = *(u_int32_t *)hp->h_addr;
575 + if (remote_name[0] == 0)
576 + strlcpy(remote_name, colon, sizeof(remote_name));
578 + if (bad_ip_adrs(remote)) {
579 + option_error("bad remote IP address %s", ip_ntoa(remote));
583 + wo->hisaddr = remote;
584 + prio_remote = option_priority;
591 +printipaddr(opt, printer, arg)
593 + void (*printer) __P((void *, char *, ...));
596 + ipcp_options *wo = &ipcp_wantoptions[0];
598 + if (wo->ouraddr != 0)
599 + printer(arg, "%I", wo->ouraddr);
601 + if (wo->hisaddr != 0)
602 + printer(arg, "%I", wo->hisaddr);
606 + * setnetmask - set the netmask to be used on the interface.
617 + * Unfortunately, if we use inet_addr, we can't tell whether
618 + * a result of all 1s is an error or a valid 255.255.255.255.
621 + n = parse_dotted_ip(p, &mask);
623 + mask = htonl(mask);
625 + if (n == 0 || p[n] != 0 || (netmask & ~mask) != 0) {
626 + option_error("invalid netmask value '%s'", *argv);
631 + slprintf(netmask_str, sizeof(netmask_str), "%I", mask);
637 +parse_dotted_ip(p, vp)
643 + char *endp, *p0 = p;
646 + for (n = 3;; --n) {
647 + b = strtoul(p, &endp, 0);
653 + /* accept e.g. 0xffffff00 */
671 + * ipcp_init - Initialize IPCP.
677 + fsm *f = &ipcp_fsm[unit];
678 + ipcp_options *wo = &ipcp_wantoptions[unit];
679 + ipcp_options *ao = &ipcp_allowoptions[unit];
682 + f->protocol = PPP_IPCP;
683 + f->callbacks = &ipcp_callbacks;
684 + fsm_init(&ipcp_fsm[unit]);
687 + * Some 3G modems use repeated IPCP NAKs as a way of stalling
688 + * until they can contact a server on the network, so we increase
689 + * the default number of NAKs we accept before we start treating
692 + f->maxnakloops = 100;
694 + memset(wo, 0, sizeof(*wo));
695 + memset(ao, 0, sizeof(*ao));
697 + wo->neg_addr = wo->old_addrs = 1;
699 + wo->vj_protocol = IPCP_VJ_COMP;
700 + wo->maxslotindex = MAX_STATES - 1; /* really max index */
704 + /* max slots and slot-id compression are currently hardwired in */
705 + /* ppp_if.c to 16 and 1, this needs to be changed (among other */
708 + ao->neg_addr = ao->old_addrs = 1;
710 + ao->maxslotindex = MAX_STATES - 1;
714 + * XXX These control whether the user may use the proxyarp
715 + * and defaultroute options.
718 + ao->default_route = 1;
723 + * ipcp_open - IPCP is allowed to come up.
729 + fsm_open(&ipcp_fsm[unit]);
735 + * ipcp_close - Take IPCP down.
738 +ipcp_close(unit, reason)
742 + fsm_close(&ipcp_fsm[unit], reason);
747 + * ipcp_lowerup - The lower layer is up.
753 + fsm_lowerup(&ipcp_fsm[unit]);
758 + * ipcp_lowerdown - The lower layer is down.
761 +ipcp_lowerdown(unit)
764 + fsm_lowerdown(&ipcp_fsm[unit]);
769 + * ipcp_input - Input IPCP packet.
772 +ipcp_input(unit, p, len)
777 + fsm_input(&ipcp_fsm[unit], p, len);
782 + * ipcp_protrej - A Protocol-Reject was received for IPCP.
784 + * Pretend the lower layer went down, so we shut up.
790 + fsm_lowerdown(&ipcp_fsm[unit]);
795 + * ipcp_resetci - Reset our CI.
796 + * Called by fsm_sconfreq, Send Configure Request.
802 + ipcp_options *wo = &ipcp_wantoptions[f->unit];
803 + ipcp_options *go = &ipcp_gotoptions[f->unit];
804 + ipcp_options *ao = &ipcp_allowoptions[f->unit];
806 + wo->req_addr = (wo->neg_addr || wo->old_addrs) &&
807 + (ao->neg_addr || ao->old_addrs);
808 + if (wo->ouraddr == 0)
809 + wo->accept_local = 1;
810 + if (wo->hisaddr == 0)
811 + wo->accept_remote = 1;
812 + wo->req_dns1 = usepeerdns; /* Request DNS addresses from the peer */
813 + wo->req_dns2 = usepeerdns;
815 + if (!ask_for_local)
817 + if (ip_choose_hook) {
818 + ip_choose_hook(&wo->hisaddr);
820 + wo->accept_remote = 0;
823 + BZERO(&ipcp_hisoptions[f->unit], sizeof(ipcp_options));
828 + * ipcp_cilen - Return length of our CI.
829 + * Called by fsm_sconfreq, Send Configure Request.
835 + ipcp_options *go = &ipcp_gotoptions[f->unit];
836 + ipcp_options *wo = &ipcp_wantoptions[f->unit];
837 + ipcp_options *ho = &ipcp_hisoptions[f->unit];
839 +#define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0)
840 +#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
841 +#define LENCIADDR(neg) (neg ? CILEN_ADDR : 0)
842 +#define LENCIDNS(neg) LENCIADDR(neg)
843 +#define LENCIWINS(neg) LENCIADDR(neg)
846 + * First see if we want to change our options to the old
847 + * forms because we have received old forms from the peer.
849 + if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs)
851 + if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
852 + /* try an older style of VJ negotiation */
853 + /* use the old style only if the peer did */
854 + if (ho->neg_vj && ho->old_vj) {
857 + go->vj_protocol = ho->vj_protocol;
861 + return (LENCIADDRS(!go->neg_addr && go->old_addrs) +
862 + LENCIVJ(go->neg_vj, go->old_vj) +
863 + LENCIADDR(go->neg_addr) +
864 + LENCIDNS(go->req_dns1) +
865 + LENCIDNS(go->req_dns2) +
866 + LENCIWINS(go->winsaddr[0]) +
867 + LENCIWINS(go->winsaddr[1])) ;
872 + * ipcp_addci - Add our desired CIs to a packet.
873 + * Called by fsm_sconfreq, Send Configure Request.
876 +ipcp_addci(f, ucp, lenp)
881 + ipcp_options *go = &ipcp_gotoptions[f->unit];
884 +#define ADDCIADDRS(opt, neg, val1, val2) \
886 + if (len >= CILEN_ADDRS) { \
888 + PUTCHAR(opt, ucp); \
889 + PUTCHAR(CILEN_ADDRS, ucp); \
894 + len -= CILEN_ADDRS; \
896 + go->old_addrs = 0; \
899 +#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
901 + int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
902 + if (len >= vjlen) { \
903 + PUTCHAR(opt, ucp); \
904 + PUTCHAR(vjlen, ucp); \
905 + PUTSHORT(val, ucp); \
907 + PUTCHAR(maxslotindex, ucp); \
908 + PUTCHAR(cflag, ucp); \
915 +#define ADDCIADDR(opt, neg, val) \
917 + if (len >= CILEN_ADDR) { \
919 + PUTCHAR(opt, ucp); \
920 + PUTCHAR(CILEN_ADDR, ucp); \
923 + len -= CILEN_ADDR; \
928 +#define ADDCIDNS(opt, neg, addr) \
930 + if (len >= CILEN_ADDR) { \
932 + PUTCHAR(opt, ucp); \
933 + PUTCHAR(CILEN_ADDR, ucp); \
936 + len -= CILEN_ADDR; \
941 +#define ADDCIWINS(opt, addr) \
943 + if (len >= CILEN_ADDR) { \
945 + PUTCHAR(opt, ucp); \
946 + PUTCHAR(CILEN_ADDR, ucp); \
949 + len -= CILEN_ADDR; \
954 + ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
957 + ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
958 + go->maxslotindex, go->cflag);
960 + ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr);
962 + ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
964 + ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
966 + ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]);
968 + ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]);
975 + * ipcp_ackci - Ack our CIs.
976 + * Called by fsm_rconfack, Receive Configure ACK.
980 + * 1 - Ack was good.
983 +ipcp_ackci(f, p, len)
988 + ipcp_options *go = &ipcp_gotoptions[f->unit];
989 + u_short cilen, citype, cishort;
991 + u_char cimaxslotindex, cicflag;
994 + * CIs must be in exactly the same order that we sent...
995 + * Check packet length and CI length at each step.
996 + * If we find any deviations, then this packet is bad.
999 +#define ACKCIADDRS(opt, neg, val1, val2) \
1002 + if ((len -= CILEN_ADDRS) < 0) \
1004 + GETCHAR(citype, p); \
1005 + GETCHAR(cilen, p); \
1006 + if (cilen != CILEN_ADDRS || \
1010 + cilong = htonl(l); \
1011 + if (val1 != cilong) \
1014 + cilong = htonl(l); \
1015 + if (val2 != cilong) \
1019 +#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
1021 + int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
1022 + if ((len -= vjlen) < 0) \
1024 + GETCHAR(citype, p); \
1025 + GETCHAR(cilen, p); \
1026 + if (cilen != vjlen || \
1029 + GETSHORT(cishort, p); \
1030 + if (cishort != val) \
1033 + GETCHAR(cimaxslotindex, p); \
1034 + if (cimaxslotindex != maxslotindex) \
1036 + GETCHAR(cicflag, p); \
1037 + if (cicflag != cflag) \
1042 +#define ACKCIADDR(opt, neg, val) \
1045 + if ((len -= CILEN_ADDR) < 0) \
1047 + GETCHAR(citype, p); \
1048 + GETCHAR(cilen, p); \
1049 + if (cilen != CILEN_ADDR || \
1053 + cilong = htonl(l); \
1054 + if (val != cilong) \
1058 +#define ACKCIDNS(opt, neg, addr) \
1061 + if ((len -= CILEN_ADDR) < 0) \
1063 + GETCHAR(citype, p); \
1064 + GETCHAR(cilen, p); \
1065 + if (cilen != CILEN_ADDR || citype != opt) \
1068 + cilong = htonl(l); \
1069 + if (addr != cilong) \
1073 + ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
1076 + ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
1077 + go->maxslotindex, go->cflag);
1079 + ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr);
1081 + ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
1083 + ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
1086 + * If there are any remaining CIs, then this packet is bad.
1093 + IPCPDEBUG(("ipcp_ackci: received bad Ack!"));
1098 + * ipcp_nakci - Peer has sent a NAK for some of our CIs.
1099 + * This should not modify any state if the Nak is bad
1100 + * or if IPCP is in the OPENED state.
1101 + * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
1104 + * 0 - Nak was bad.
1105 + * 1 - Nak was good.
1108 +ipcp_nakci(f, p, len, treat_as_reject)
1112 + int treat_as_reject;
1114 + ipcp_options *go = &ipcp_gotoptions[f->unit];
1115 + u_char cimaxslotindex, cicflag;
1116 + u_char citype, cilen, *next;
1118 + u_int32_t ciaddr1, ciaddr2, l, cidnsaddr;
1119 + ipcp_options no; /* options we've seen Naks for */
1120 + ipcp_options try; /* options to request next time */
1122 + BZERO(&no, sizeof(no));
1126 + * Any Nak'd CIs must be in exactly the same order that we sent.
1127 + * Check packet length and CI length at each step.
1128 + * If we find any deviations, then this packet is bad.
1130 +#define NAKCIADDRS(opt, neg, code) \
1132 + (cilen = p[1]) == CILEN_ADDRS && \
1138 + ciaddr1 = htonl(l); \
1140 + ciaddr2 = htonl(l); \
1141 + no.old_addrs = 1; \
1145 +#define NAKCIVJ(opt, neg, code) \
1147 + ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
1152 + GETSHORT(cishort, p); \
1157 +#define NAKCIADDR(opt, neg, code) \
1159 + (cilen = p[1]) == CILEN_ADDR && \
1165 + ciaddr1 = htonl(l); \
1170 +#define NAKCIDNS(opt, neg, code) \
1172 + ((cilen = p[1]) == CILEN_ADDR) && \
1178 + cidnsaddr = htonl(l); \
1184 + * Accept the peer's idea of {our,his} address, if different
1185 + * from our idea, only if the accept_{local,remote} flag is set.
1187 + NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
1188 + if (treat_as_reject) {
1189 + try.old_addrs = 0;
1191 + if (go->accept_local && ciaddr1) {
1192 + /* take his idea of our address */
1193 + try.ouraddr = ciaddr1;
1195 + if (go->accept_remote && ciaddr2) {
1196 + /* take his idea of his address */
1197 + try.hisaddr = ciaddr2;
1203 + * Accept the peer's value of maxslotindex provided that it
1204 + * is less than what we asked for. Turn off slot-ID compression
1205 + * if the peer wants. Send old-style compress-type option if
1208 + NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
1209 + if (treat_as_reject) {
1211 + } else if (cilen == CILEN_VJ) {
1212 + GETCHAR(cimaxslotindex, p);
1213 + GETCHAR(cicflag, p);
1214 + if (cishort == IPCP_VJ_COMP) {
1216 + if (cimaxslotindex < go->maxslotindex)
1217 + try.maxslotindex = cimaxslotindex;
1224 + if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {
1226 + try.vj_protocol = cishort;
1233 + NAKCIADDR(CI_ADDR, neg_addr,
1234 + if (treat_as_reject) {
1236 + try.old_addrs = 0;
1237 + } else if (go->accept_local && ciaddr1) {
1238 + /* take his idea of our address */
1239 + try.ouraddr = ciaddr1;
1243 + NAKCIDNS(CI_MS_DNS1, req_dns1,
1244 + if (treat_as_reject) {
1247 + try.dnsaddr[0] = cidnsaddr;
1251 + NAKCIDNS(CI_MS_DNS2, req_dns2,
1252 + if (treat_as_reject) {
1255 + try.dnsaddr[1] = cidnsaddr;
1260 + * There may be remaining CIs, if the peer is requesting negotiation
1261 + * on an option that we didn't include in our request packet.
1262 + * If they want to negotiate about IP addresses, we comply.
1263 + * If they want us to ask for compression, we refuse.
1264 + * If they want us to ask for ms-dns, we do that, since some
1265 + * peers get huffy if we don't.
1267 + while (len >= CILEN_VOID) {
1268 + GETCHAR(citype, p);
1269 + GETCHAR(cilen, p);
1270 + if ( cilen < CILEN_VOID || (len -= cilen) < 0 )
1272 + next = p + cilen - 2;
1275 + case CI_COMPRESSTYPE:
1276 + if (go->neg_vj || no.neg_vj ||
1277 + (cilen != CILEN_VJ && cilen != CILEN_COMPRESS))
1282 + if ((!go->neg_addr && go->old_addrs) || no.old_addrs
1283 + || cilen != CILEN_ADDRS)
1287 + ciaddr1 = htonl(l);
1288 + if (ciaddr1 && go->accept_local)
1289 + try.ouraddr = ciaddr1;
1291 + ciaddr2 = htonl(l);
1292 + if (ciaddr2 && go->accept_remote)
1293 + try.hisaddr = ciaddr2;
1297 + if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)
1299 + try.old_addrs = 0;
1301 + ciaddr1 = htonl(l);
1302 + if (ciaddr1 && go->accept_local)
1303 + try.ouraddr = ciaddr1;
1304 + if (try.ouraddr != 0)
1309 + if (go->req_dns1 || no.req_dns1 || cilen != CILEN_ADDR)
1312 + try.dnsaddr[0] = htonl(l);
1317 + if (go->req_dns2 || no.req_dns2 || cilen != CILEN_ADDR)
1320 + try.dnsaddr[1] = htonl(l);
1326 + if (cilen != CILEN_ADDR)
1329 + ciaddr1 = htonl(l);
1331 + try.winsaddr[citype == CI_MS_WINS2] = ciaddr1;
1338 + * OK, the Nak is good. Now we can update state.
1339 + * If there are any remaining options, we ignore them.
1341 + if (f->state != OPENED)
1347 + IPCPDEBUG(("ipcp_nakci: received bad Nak!"));
1353 + * ipcp_rejci - Reject some of our CIs.
1354 + * Callback from fsm_rconfnakrej.
1357 +ipcp_rejci(f, p, len)
1362 + ipcp_options *go = &ipcp_gotoptions[f->unit];
1363 + u_char cimaxslotindex, ciflag, cilen;
1366 + ipcp_options try; /* options to request next time */
1370 + * Any Rejected CIs must be in exactly the same order that we sent.
1371 + * Check packet length and CI length at each step.
1372 + * If we find any deviations, then this packet is bad.
1374 +#define REJCIADDRS(opt, neg, val1, val2) \
1376 + (cilen = p[1]) == CILEN_ADDRS && \
1383 + cilong = htonl(l); \
1384 + /* Check rejected value. */ \
1385 + if (cilong != val1) \
1388 + cilong = htonl(l); \
1389 + /* Check rejected value. */ \
1390 + if (cilong != val2) \
1392 + try.old_addrs = 0; \
1395 +#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
1397 + p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
1402 + GETSHORT(cishort, p); \
1403 + /* Check rejected value. */ \
1404 + if (cishort != val) \
1407 + GETCHAR(cimaxslotindex, p); \
1408 + if (cimaxslotindex != maxslot) \
1410 + GETCHAR(ciflag, p); \
1411 + if (ciflag != cflag) \
1417 +#define REJCIADDR(opt, neg, val) \
1419 + (cilen = p[1]) == CILEN_ADDR && \
1426 + cilong = htonl(l); \
1427 + /* Check rejected value. */ \
1428 + if (cilong != val) \
1433 +#define REJCIDNS(opt, neg, dnsaddr) \
1435 + ((cilen = p[1]) == CILEN_ADDR) && \
1442 + cilong = htonl(l); \
1443 + /* Check rejected value. */ \
1444 + if (cilong != dnsaddr) \
1449 +#define REJCIWINS(opt, addr) \
1451 + ((cilen = p[1]) == CILEN_ADDR) && \
1458 + cilong = htonl(l); \
1459 + /* Check rejected value. */ \
1460 + if (cilong != addr) \
1462 + try.winsaddr[opt == CI_MS_WINS2] = 0; \
1465 + REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
1466 + go->ouraddr, go->hisaddr);
1468 + REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
1469 + go->maxslotindex, go->cflag);
1471 + REJCIADDR(CI_ADDR, neg_addr, go->ouraddr);
1473 + REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
1475 + REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
1477 + REJCIWINS(CI_MS_WINS1, go->winsaddr[0]);
1479 + REJCIWINS(CI_MS_WINS2, go->winsaddr[1]);
1482 + * If there are any remaining CIs, then this packet is bad.
1487 + * Now we can update state.
1489 + if (f->state != OPENED)
1494 + IPCPDEBUG(("ipcp_rejci: received bad Reject!"));
1500 + * ipcp_reqci - Check the peer's requested CIs and send appropriate response.
1501 + * Callback from fsm_rconfreq, Receive Configure Request
1503 + * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
1504 + * appropriately. If reject_if_disagree is non-zero, doesn't return
1505 + * CONFNAK; returns CONFREJ if it can't return CONFACK.
1508 +ipcp_reqci(f, inp, len, reject_if_disagree)
1510 + u_char *inp; /* Requested CIs */
1511 + int *len; /* Length of requested CIs */
1512 + int reject_if_disagree;
1514 + ipcp_options *wo = &ipcp_wantoptions[f->unit];
1515 + ipcp_options *ho = &ipcp_hisoptions[f->unit];
1516 + ipcp_options *ao = &ipcp_allowoptions[f->unit];
1517 + u_char *cip, *next; /* Pointer to current and next CIs */
1518 + u_short cilen, citype; /* Parsed len, type */
1519 + u_short cishort; /* Parsed short value */
1520 + u_int32_t tl, ciaddr1, ciaddr2;/* Parsed address values */
1521 + int rc = CONFACK; /* Final packet return code */
1522 + int orc; /* Individual option return code */
1523 + u_char *p; /* Pointer to next char to parse */
1524 + u_char *ucp = inp; /* Pointer to current output char */
1525 + int l = *len; /* Length left */
1526 + u_char maxslotindex, cflag;
1530 + * Reset all his options.
1532 + BZERO(ho, sizeof(*ho));
1535 + * Process all his options.
1539 + orc = CONFACK; /* Assume success */
1540 + cip = p = next; /* Remember begining of CI */
1541 + if (l < 2 || /* Not enough data for CI header or */
1542 + p[1] < 2 || /* CI length too small or */
1543 + p[1] > l) { /* CI length too big? */
1544 + IPCPDEBUG(("ipcp_reqci: bad CI length!"));
1545 + orc = CONFREJ; /* Reject bad CI */
1546 + cilen = l; /* Reject till end of packet */
1547 + l = 0; /* Don't loop again */
1550 + GETCHAR(citype, p); /* Parse CI type */
1551 + GETCHAR(cilen, p); /* Parse CI length */
1552 + l -= cilen; /* Adjust remaining length */
1553 + next += cilen; /* Step to next CI */
1555 + switch (citype) { /* Check CI type */
1557 + if (!ao->old_addrs || ho->neg_addr ||
1558 + cilen != CILEN_ADDRS) { /* Check CI length */
1559 + orc = CONFREJ; /* Reject CI */
1564 + * If he has no address, or if we both have his address but
1565 + * disagree about it, then NAK it with our idea.
1566 + * In particular, if we don't know his address, but he does,
1569 + GETLONG(tl, p); /* Parse source address (his) */
1570 + ciaddr1 = htonl(tl);
1571 + if (ciaddr1 != wo->hisaddr
1572 + && (ciaddr1 == 0 || !wo->accept_remote)) {
1574 + if (!reject_if_disagree) {
1575 + DECPTR(sizeof(u_int32_t), p);
1576 + tl = ntohl(wo->hisaddr);
1579 + } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
1581 + * If neither we nor he knows his address, reject the option.
1584 + wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
1589 + * If he doesn't know our address, or if we both have our address
1590 + * but disagree about it, then NAK it with our idea.
1592 + GETLONG(tl, p); /* Parse desination address (ours) */
1593 + ciaddr2 = htonl(tl);
1594 + if (ciaddr2 != wo->ouraddr) {
1595 + if (ciaddr2 == 0 || !wo->accept_local) {
1597 + if (!reject_if_disagree) {
1598 + DECPTR(sizeof(u_int32_t), p);
1599 + tl = ntohl(wo->ouraddr);
1603 + wo->ouraddr = ciaddr2; /* accept peer's idea */
1607 + ho->old_addrs = 1;
1608 + ho->hisaddr = ciaddr1;
1609 + ho->ouraddr = ciaddr2;
1613 + if (!ao->neg_addr || ho->old_addrs ||
1614 + cilen != CILEN_ADDR) { /* Check CI length */
1615 + orc = CONFREJ; /* Reject CI */
1620 + * If he has no address, or if we both have his address but
1621 + * disagree about it, then NAK it with our idea.
1622 + * In particular, if we don't know his address, but he does,
1625 + GETLONG(tl, p); /* Parse source address (his) */
1626 + ciaddr1 = htonl(tl);
1627 + if (ciaddr1 != wo->hisaddr
1628 + && (ciaddr1 == 0 || !wo->accept_remote)) {
1630 + if (!reject_if_disagree) {
1631 + DECPTR(sizeof(u_int32_t), p);
1632 + tl = ntohl(wo->hisaddr);
1635 + } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
1637 + * Don't ACK an address of 0.0.0.0 - reject it instead.
1640 + wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
1645 + ho->hisaddr = ciaddr1;
1650 + /* Microsoft primary or secondary DNS request */
1651 + d = citype == CI_MS_DNS2;
1653 + /* If we do not have a DNS address then we cannot send it */
1654 + if (ao->dnsaddr[d] == 0 ||
1655 + cilen != CILEN_ADDR) { /* Check CI length */
1656 + orc = CONFREJ; /* Reject CI */
1660 + if (htonl(tl) != ao->dnsaddr[d]) {
1661 + DECPTR(sizeof(u_int32_t), p);
1662 + tl = ntohl(ao->dnsaddr[d]);
1670 + /* Microsoft primary or secondary WINS request */
1671 + d = citype == CI_MS_WINS2;
1673 + /* If we do not have a DNS address then we cannot send it */
1674 + if (ao->winsaddr[d] == 0 ||
1675 + cilen != CILEN_ADDR) { /* Check CI length */
1676 + orc = CONFREJ; /* Reject CI */
1680 + if (htonl(tl) != ao->winsaddr[d]) {
1681 + DECPTR(sizeof(u_int32_t), p);
1682 + tl = ntohl(ao->winsaddr[d]);
1688 + case CI_COMPRESSTYPE:
1689 + if (!ao->neg_vj ||
1690 + (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) {
1694 + GETSHORT(cishort, p);
1696 + if (!(cishort == IPCP_VJ_COMP ||
1697 + (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {
1703 + ho->vj_protocol = cishort;
1704 + if (cilen == CILEN_VJ) {
1705 + GETCHAR(maxslotindex, p);
1706 + if (maxslotindex > ao->maxslotindex) {
1708 + if (!reject_if_disagree){
1710 + PUTCHAR(ao->maxslotindex, p);
1713 + GETCHAR(cflag, p);
1714 + if (cflag && !ao->cflag) {
1716 + if (!reject_if_disagree){
1718 + PUTCHAR(wo->cflag, p);
1721 + ho->maxslotindex = maxslotindex;
1722 + ho->cflag = cflag;
1725 + ho->maxslotindex = MAX_STATES - 1;
1735 + if (orc == CONFACK && /* Good CI */
1736 + rc != CONFACK) /* but prior CI wasnt? */
1737 + continue; /* Don't send this one */
1739 + if (orc == CONFNAK) { /* Nak this CI? */
1740 + if (reject_if_disagree) /* Getting fed up with sending NAKs? */
1741 + orc = CONFREJ; /* Get tough if so */
1743 + if (rc == CONFREJ) /* Rejecting prior CI? */
1744 + continue; /* Don't send this one */
1745 + if (rc == CONFACK) { /* Ack'd all prior CIs? */
1746 + rc = CONFNAK; /* Not anymore... */
1747 + ucp = inp; /* Backup */
1752 + if (orc == CONFREJ && /* Reject this CI */
1753 + rc != CONFREJ) { /* but no prior ones? */
1755 + ucp = inp; /* Backup */
1758 + /* Need to move CI? */
1760 + BCOPY(cip, ucp, cilen); /* Move it */
1762 + /* Update output pointer */
1763 + INCPTR(cilen, ucp);
1767 + * If we aren't rejecting this packet, and we want to negotiate
1768 + * their address, and they didn't send their address, then we
1769 + * send a NAK with a CI_ADDR option appended. We assume the
1770 + * input buffer is long enough that we can append the extra
1773 + if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs &&
1774 + wo->req_addr && !reject_if_disagree && !noremoteip) {
1775 + if (rc == CONFACK) {
1777 + ucp = inp; /* reset pointer */
1778 + wo->req_addr = 0; /* don't ask again */
1780 + PUTCHAR(CI_ADDR, ucp);
1781 + PUTCHAR(CILEN_ADDR, ucp);
1782 + tl = ntohl(wo->hisaddr);
1786 + *len = ucp - inp; /* Compute output length */
1787 + IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc)));
1788 + return (rc); /* Return final code */
1793 + * ip_check_options - check that any IP-related options are OK,
1794 + * and assign appropriate defaults.
1799 + struct hostent *hp;
1801 + ipcp_options *wo = &ipcp_wantoptions[0];
1804 + * Default our local IP address based on our hostname.
1805 + * If local IP address already given, don't bother.
1807 + if (wo->ouraddr == 0 && !disable_defaultip) {
1809 + * Look up our hostname (possibly with domain name appended)
1810 + * and take the first IP address as our local IP address.
1811 + * If there isn't an IP address for our hostname, too bad.
1813 + wo->accept_local = 1; /* don't insist on this default value */
1814 + if ((hp = gethostbyname(hostname)) != NULL) {
1815 + local = *(u_int32_t *)hp->h_addr;
1816 + if (local != 0 && !bad_ip_adrs(local))
1817 + wo->ouraddr = local;
1820 + ask_for_local = wo->ouraddr != 0 || !disable_defaultip;
1825 + * ip_demand_conf - configure the interface as though
1826 + * IPCP were up, for use with dial-on-demand.
1832 + ipcp_options *wo = &ipcp_wantoptions[u];
1834 + if (wo->hisaddr == 0 && !noremoteip) {
1835 + /* make up an arbitrary address for the peer */
1836 + wo->hisaddr = htonl(0x0a707070 + ifunit);
1837 + wo->accept_remote = 1;
1839 + if (wo->ouraddr == 0) {
1840 + /* make up an arbitrary address for us */
1841 + wo->ouraddr = htonl(0x0a404040 + ifunit);
1842 + wo->accept_local = 1;
1843 + ask_for_local = 0; /* don't tell the peer this address */
1845 + if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr)))
1847 + ipcp_script(_PATH_IPPREUP, 1);
1850 + if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
1852 + if (wo->default_route)
1853 + if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
1854 + default_route_set[u] = 1;
1855 + if (wo->proxy_arp)
1856 + if (sifproxyarp(u, wo->hisaddr))
1857 + proxy_arp_set[u] = 1;
1859 + notice("local IP address %I", wo->ouraddr);
1861 + notice("remote IP address %I", wo->hisaddr);
1868 + * ipcp_up - IPCP has come UP.
1870 + * Configure the IP network interface appropriately and bring it up.
1877 + ipcp_options *ho = &ipcp_hisoptions[f->unit];
1878 + ipcp_options *go = &ipcp_gotoptions[f->unit];
1879 + ipcp_options *wo = &ipcp_wantoptions[f->unit];
1881 + IPCPDEBUG(("ipcp: up"));
1884 + * We must have a non-zero IP address for both ends of the link.
1886 + if (!ho->neg_addr && !ho->old_addrs)
1887 + ho->hisaddr = wo->hisaddr;
1889 + if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs)
1890 + && wo->ouraddr != 0) {
1891 + error("Peer refused to agree to our IP address");
1892 + ipcp_close(f->unit, "Refused our IP address");
1895 + if (go->ouraddr == 0) {
1896 + error("Could not determine local IP address");
1897 + ipcp_close(f->unit, "Could not determine local IP address");
1900 + if (ho->hisaddr == 0 && !noremoteip) {
1901 + ho->hisaddr = htonl(0x0a404040 + ifunit);
1902 + warn("Could not determine remote IP address: defaulting to %I",
1905 + script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0);
1906 + if (ho->hisaddr != 0)
1907 + script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1);
1909 + if (!go->req_dns1)
1910 + go->dnsaddr[0] = 0;
1911 + if (!go->req_dns2)
1912 + go->dnsaddr[1] = 0;
1913 + if (go->dnsaddr[0])
1914 + script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0);
1915 + if (go->dnsaddr[1])
1916 + script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0);
1917 + if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
1918 + script_setenv("USEPEERDNS", "1", 0);
1919 + create_resolv(go->dnsaddr[0], go->dnsaddr[1]);
1923 + * Check that the peer is allowed to use the IP address it wants.
1925 + if (ho->hisaddr != 0 && !auth_ip_addr(f->unit, ho->hisaddr)) {
1926 + error("Peer is not authorized to use remote address %I", ho->hisaddr);
1927 + ipcp_close(f->unit, "Unauthorized remote IP address");
1931 + /* set tcp compression */
1932 + sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);
1935 + * If we are doing dial-on-demand, the interface is already
1936 + * configured, so we put out any saved-up packets, then set the
1937 + * interface to pass IP packets.
1940 + if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
1941 + ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
1942 + if (go->ouraddr != wo->ouraddr) {
1943 + warn("Local IP address changed to %I", go->ouraddr);
1944 + script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
1945 + wo->ouraddr = go->ouraddr;
1947 + script_unsetenv("OLDIPLOCAL");
1948 + if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) {
1949 + warn("Remote IP address changed to %I", ho->hisaddr);
1950 + script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);
1951 + wo->hisaddr = ho->hisaddr;
1953 + script_unsetenv("OLDIPREMOTE");
1955 + /* Set the interface to the new addresses */
1956 + mask = GetMask(go->ouraddr);
1957 + if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
1959 + warn("Interface configuration failed");
1960 + ipcp_close(f->unit, "Interface configuration failed");
1964 + /* assign a default route through the interface if required */
1965 + if (ipcp_wantoptions[f->unit].default_route)
1966 + if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
1967 + default_route_set[f->unit] = 1;
1969 + /* Make a proxy ARP entry if requested. */
1970 + if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp)
1971 + if (sifproxyarp(f->unit, ho->hisaddr))
1972 + proxy_arp_set[f->unit] = 1;
1975 + demand_rexmit(PPP_IP);
1976 + sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
1980 + * Set IP addresses and (if specified) netmask.
1982 + mask = GetMask(go->ouraddr);
1984 +#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__)))
1985 + if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
1987 + warn("Interface configuration failed");
1988 + ipcp_close(f->unit, "Interface configuration failed");
1993 + /* run the pre-up script, if any, and wait for it to finish */
1994 + ipcp_script(_PATH_IPPREUP, 1);
1996 + /* bring the interface up for IP */
1997 + if (!sifup(f->unit)) {
1999 + warn("Interface failed to come up");
2000 + ipcp_close(f->unit, "Interface configuration failed");
2004 +#if (defined(SVR4) && (defined(SNI) || defined(__USLC__)))
2005 + if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
2007 + warn("Interface configuration failed");
2008 + ipcp_close(f->unit, "Interface configuration failed");
2012 + sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
2014 + /* assign a default route through the interface if required */
2015 + if (ipcp_wantoptions[f->unit].default_route)
2016 + if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
2017 + default_route_set[f->unit] = 1;
2019 + /* Make a proxy ARP entry if requested. */
2020 + if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp)
2021 + if (sifproxyarp(f->unit, ho->hisaddr))
2022 + proxy_arp_set[f->unit] = 1;
2024 + ipcp_wantoptions[0].ouraddr = go->ouraddr;
2026 + notice("local IP address %I", go->ouraddr);
2027 + if (ho->hisaddr != 0)
2028 + notice("remote IP address %I", ho->hisaddr);
2029 + if (go->dnsaddr[0])
2030 + notice("primary DNS address %I", go->dnsaddr[0]);
2031 + if (go->dnsaddr[1])
2032 + notice("secondary DNS address %I", go->dnsaddr[1]);
2035 + reset_link_stats(f->unit);
2037 + np_up(f->unit, PPP_IP);
2040 + notify(ip_up_notifier, 0);
2045 + * Execute the ip-up script, like this:
2046 + * /etc/ppp/ip-up interface tty speed local-IP remote-IP
2048 + if (ipcp_script_state == s_down && ipcp_script_pid == 0) {
2049 + ipcp_script_state = s_up;
2050 + ipcp_script(_PATH_IPUP, 0);
2056 + * ipcp_down - IPCP has gone DOWN.
2058 + * Take the IP network interface down, clear its addresses
2059 + * and delete routes through it.
2065 + IPCPDEBUG(("ipcp: down"));
2066 + /* XXX a bit IPv4-centric here, we only need to get the stats
2067 + * before the interface is marked down. */
2068 + /* XXX more correct: we must get the stats before running the notifiers,
2069 + * at least for the radius plugin */
2070 + update_link_stats(f->unit);
2071 + notify(ip_down_notifier, 0);
2076 + np_down(f->unit, PPP_IP);
2078 + sifvjcomp(f->unit, 0, 0, 0);
2080 + print_link_stats(); /* _after_ running the notifiers and ip_down_hook(),
2081 + * because print_link_stats() sets link_stats_valid
2085 + * If we are doing dial-on-demand, set the interface
2086 + * to queue up outgoing packets (for now).
2089 + sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE);
2091 + sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
2093 + ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
2094 + ipcp_hisoptions[f->unit].hisaddr);
2097 + /* Execute the ip-down script */
2098 + if (ipcp_script_state == s_up && ipcp_script_pid == 0) {
2099 + ipcp_script_state = s_down;
2100 + ipcp_script(_PATH_IPDOWN, 0);
2106 + * ipcp_clear_addrs() - clear the interface addresses, routes,
2107 + * proxy arp entries, etc.
2110 +ipcp_clear_addrs(unit, ouraddr, hisaddr)
2112 + u_int32_t ouraddr; /* local address */
2113 + u_int32_t hisaddr; /* remote address */
2115 + if (proxy_arp_set[unit]) {
2116 + cifproxyarp(unit, hisaddr);
2117 + proxy_arp_set[unit] = 0;
2119 + if (default_route_set[unit]) {
2120 + cifdefaultroute(unit, ouraddr, hisaddr);
2121 + default_route_set[unit] = 0;
2123 + cifaddr(unit, ouraddr, hisaddr);
2128 + * ipcp_finished - possibly shut down the lower layers.
2134 + if (ipcp_is_open) {
2136 + np_finished(f->unit, PPP_IP);
2142 + * ipcp_script_done - called when the ip-up or ip-down script
2146 +ipcp_script_done(arg)
2149 + ipcp_script_pid = 0;
2150 + switch (ipcp_script_state) {
2152 + if (ipcp_fsm[0].state != OPENED) {
2153 + ipcp_script_state = s_down;
2154 + ipcp_script(_PATH_IPDOWN, 0);
2158 + if (ipcp_fsm[0].state == OPENED) {
2159 + ipcp_script_state = s_up;
2160 + ipcp_script(_PATH_IPUP, 0);
2168 + * ipcp_script - Execute a script with arguments
2169 + * interface-name tty-name speed local-IP remote-IP.
2172 +ipcp_script(script, wait)
2176 + char strspeed[32], strlocal[32], strremote[32];
2179 + slprintf(strspeed, sizeof(strspeed), "%d", baud_rate);
2180 + slprintf(strlocal, sizeof(strlocal), "%I", ipcp_gotoptions[0].ouraddr);
2181 + slprintf(strremote, sizeof(strremote), "%I", ipcp_hisoptions[0].hisaddr);
2186 + argv[3] = strspeed;
2187 + argv[4] = strlocal;
2188 + argv[5] = strremote;
2189 + argv[6] = ipparam;
2192 + run_program(script, argv, 0, NULL, NULL, 1);
2194 + ipcp_script_pid = run_program(script, argv, 0, ipcp_script_done,
2199 + * create_resolv - create the replacement resolv.conf file
2202 +create_resolv(peerdns1, peerdns2)
2203 + u_int32_t peerdns1, peerdns2;
2207 + f = fopen(_PATH_RESOLV, "w");
2209 + error("Failed to create %s: %m", _PATH_RESOLV);
2214 + fprintf(f, "nameserver %s\n", ip_ntoa(peerdns1));
2217 + fprintf(f, "nameserver %s\n", ip_ntoa(peerdns2));
2220 + error("Write failed to %s: %m", _PATH_RESOLV);
2226 + * ipcp_printpkt - print the contents of an IPCP packet.
2228 +static char *ipcp_codenames[] = {
2229 + "ConfReq", "ConfAck", "ConfNak", "ConfRej",
2230 + "TermReq", "TermAck", "CodeRej"
2234 +ipcp_printpkt(p, plen, printer, arg)
2237 + void (*printer) __P((void *, char *, ...));
2240 + int code, id, len, olen;
2241 + u_char *pstart, *optend;
2245 + if (plen < HEADERLEN)
2251 + if (len < HEADERLEN || len > plen)
2254 + if (code >= 1 && code <= sizeof(ipcp_codenames) / sizeof(char *))
2255 + printer(arg, " %s", ipcp_codenames[code-1]);
2257 + printer(arg, " code=0x%x", code);
2258 + printer(arg, " id=0x%x", id);
2265 + /* print option list */
2266 + while (len >= 2) {
2270 + if (olen < 2 || olen > len) {
2273 + printer(arg, " <");
2275 + optend = p + olen;
2278 + if (olen == CILEN_ADDRS) {
2280 + GETLONG(cilong, p);
2281 + printer(arg, "addrs %I", htonl(cilong));
2282 + GETLONG(cilong, p);
2283 + printer(arg, " %I", htonl(cilong));
2286 + case CI_COMPRESSTYPE:
2287 + if (olen >= CILEN_COMPRESS) {
2289 + GETSHORT(cishort, p);
2290 + printer(arg, "compress ");
2291 + switch (cishort) {
2292 + case IPCP_VJ_COMP:
2293 + printer(arg, "VJ");
2295 + case IPCP_VJ_COMP_OLD:
2296 + printer(arg, "old-VJ");
2299 + printer(arg, "0x%x", cishort);
2304 + if (olen == CILEN_ADDR) {
2306 + GETLONG(cilong, p);
2307 + printer(arg, "addr %I", htonl(cilong));
2313 + GETLONG(cilong, p);
2314 + printer(arg, "ms-dns%d %I", (code == CI_MS_DNS1? 1: 2),
2320 + GETLONG(cilong, p);
2321 + printer(arg, "ms-wins %I", htonl(cilong));
2324 + while (p < optend) {
2326 + printer(arg, " %.2x", code);
2328 + printer(arg, ">");
2334 + if (len > 0 && *p >= ' ' && *p < 0x7f) {
2335 + printer(arg, " ");
2336 + print_string((char *)p, len, printer, arg);
2343 + /* print the rest of the bytes in the packet */
2344 + for (; len > 0; --len) {
2346 + printer(arg, " %.2x", code);
2349 + return p - pstart;
2353 + * ip_active_pkt - see if this IP packet is worth bringing the link up for.
2354 + * We don't bring the link up for IP fragments or for TCP FIN packets
2357 +#define IP_HDRLEN 20 /* bytes */
2358 +#define IP_OFFMASK 0x1fff
2359 +#ifndef IPPROTO_TCP
2360 +#define IPPROTO_TCP 6
2362 +#define TCP_HDRLEN 20
2363 +#define TH_FIN 0x01
2366 + * We use these macros because the IP header may be at an odd address,
2367 + * and some compilers might use word loads to get th_off or ip_hl.
2370 +#define net_short(x) (((x)[0] << 8) + (x)[1])
2371 +#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF)
2372 +#define get_ipoff(x) net_short((unsigned char *)(x) + 6)
2373 +#define get_ipproto(x) (((unsigned char *)(x))[9])
2374 +#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4)
2375 +#define get_tcpflags(x) (((unsigned char *)(x))[13])
2378 +ip_active_pkt(pkt, len)
2385 + len -= PPP_HDRLEN;
2386 + pkt += PPP_HDRLEN;
2387 + if (len < IP_HDRLEN)
2389 + if ((get_ipoff(pkt) & IP_OFFMASK) != 0)
2391 + if (get_ipproto(pkt) != IPPROTO_TCP)
2393 + hlen = get_iphl(pkt) * 4;
2394 + if (len < hlen + TCP_HDRLEN)
2397 + if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)
2401 diff -ruNp ppp-2.4.5/pppd/ipcp.h ppp-2.4.5_new/pppd/ipcp.h
2402 --- ppp-2.4.5/pppd/ipcp.h 2009-11-17 01:26:07.000000000 +0300
2403 +++ ppp-2.4.5_new/pppd/ipcp.h 2010-11-24 17:43:52.236670147 +0300
2404 @@ -70,6 +70,7 @@ typedef struct ipcp_options {
2405 bool old_addrs; /* Use old (IP-Addresses) option? */
2406 bool req_addr; /* Ask peer to send IP address? */
2407 bool default_route; /* Assign default route through interface? */
2408 + bool replace_default_route; /* Replace default route through interface? */
2409 bool proxy_arp; /* Make proxy ARP entry for peer? */
2410 bool neg_vj; /* Van Jacobson Compression? */
2411 bool old_vj; /* use old (short) form of VJ option? */
2412 diff -ruNp ppp-2.4.5/pppd/pppd.8 ppp-2.4.5_new/pppd/pppd.8
2413 --- ppp-2.4.5/pppd/pppd.8 2009-11-17 01:26:07.000000000 +0300
2414 +++ ppp-2.4.5_new/pppd/pppd.8 2010-11-24 17:43:52.236670147 +0300
2415 @@ -121,6 +121,11 @@ the gateway, when IPCP negotiation is su
2416 This entry is removed when the PPP connection is broken. This option
2417 is privileged if the \fInodefaultroute\fR option has been specified.
2419 +.B replacedefaultroute
2420 +This option is a flag to the defaultroute option. If defaultroute is
2421 +set and this flag is also set, pppd replaces an existing default route
2422 +with the new default route.
2424 .B disconnect \fIscript
2425 Execute the command specified by \fIscript\fR, by passing it to a
2427 @@ -717,7 +722,12 @@ disable both forms of hardware flow cont
2430 Disable the \fIdefaultroute\fR option. The system administrator who
2431 -wishes to prevent users from creating default routes with pppd
2432 +wishes to prevent users from adding a default route with pppd
2433 +can do so by placing this option in the /etc/ppp/options file.
2435 +.B noreplacedefaultroute
2436 +Disable the \fIreplacedefaultroute\fR option. The system administrator who
2437 +wishes to prevent users from replacing a default route with pppd
2438 can do so by placing this option in the /etc/ppp/options file.
2441 diff -ruNp ppp-2.4.5/pppd/pppd.8.orig ppp-2.4.5_new/pppd/pppd.8.orig
2442 --- ppp-2.4.5/pppd/pppd.8.orig 1970-01-01 03:00:00.000000000 +0300
2443 +++ ppp-2.4.5_new/pppd/pppd.8.orig 2010-11-24 17:43:05.266670147 +0300
2445 +.\" manual page [] for pppd 2.4
2446 +.\" $Id: pppd.8,v 1.90 2008/03/26 12:09:40 paulus Exp $
2447 +.\" SH section heading
2448 +.\" SS subsection heading
2450 +.\" IP indented paragraph
2451 +.\" TP hanging label
2453 +.\" Copyright (c) 1993-2003 Paul Mackerras <paulus@samba.org>
2455 +.\" Permission to use, copy, modify, and distribute this software for any
2456 +.\" purpose with or without fee is hereby granted, provided that the above
2457 +.\" copyright notice and this permission notice appear in all copies.
2459 +.\" THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
2460 +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2461 +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2462 +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2463 +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2464 +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2465 +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2469 +pppd \- Point-to-Point Protocol Daemon
2477 +PPP is the protocol used for establishing internet links over dial-up
2478 +modems, DSL connections, and many other types of point-to-point
2479 +links. The \fIpppd\fR daemon works together with the kernel PPP
2480 +driver to establish and maintain a PPP link with another system
2481 +(called the \fIpeer\fR) and to negotiate Internet Protocol (IP)
2482 +addresses for each end of the link. Pppd can also authenticate the
2483 +peer and/or supply authentication information to the peer. PPP can be
2484 +used with other network protocols besides IP, but such use is becoming
2486 +.SH FREQUENTLY USED OPTIONS
2489 +Use the serial port called \fIttyname\fR to communicate with the
2490 +peer. If \fIttyname\fR does not begin with a slash (/),
2491 +the string "/dev/" is prepended to \fIttyname\fR to form the
2492 +name of the device to open. If no device name is given, or if the
2493 +name of the terminal
2494 +connected to the standard input is given, pppd will use that terminal,
2495 +and will not fork to put itself in the background. A value for this
2496 +option from a privileged source cannot be overridden by a
2497 +non-privileged user.
2500 +An option that is a decimal number is taken as the desired baud rate
2501 +for the serial device. On systems such as
2502 +4.4BSD and NetBSD, any speed can be specified. Other systems
2503 +(e.g. Linux, SunOS) only support the commonly-used baud rates.
2506 +This option sets the Async-Control-Character-Map (ACCM) for this end
2507 +of the link. The ACCM is a set of 32 bits, one for each of the
2508 +ASCII control characters with values from 0 to 31, where a 1 bit
2509 +indicates that the corresponding control character should not be used
2510 +in PPP packets sent to this system. The map is encoded as a
2511 +hexadecimal number (without a leading 0x) where the least significant
2512 +bit (00000001) represents character 0 and the most significant bit
2513 +(80000000) represents character 31.
2514 +Pppd will ask the peer to send these characters as a 2-byte
2516 +If multiple \fIasyncmap\fR options are given, the values are ORed
2517 +together. If no \fIasyncmap\fR option is given, the default is zero,
2518 +so pppd will ask the peer not to escape any control characters.
2519 +To escape transmitted characters, use the \fIescape\fR option.
2522 +Require the peer to authenticate itself before allowing network
2523 +packets to be sent or received. This option is the default if the
2524 +system has a default route. If neither this option nor the
2525 +\fInoauth\fR option is specified, pppd will only allow the peer to use
2526 +IP addresses to which the system does not already have a route.
2529 +Read additional options from the file /etc/ppp/peers/\fIname\fR. This
2530 +file may contain privileged options, such as \fInoauth\fR, even if pppd
2531 +is not being run by root. The \fIname\fR string may not begin with /
2532 +or include .. as a pathname component. The format of the options file
2533 +is described below.
2535 +.B connect \fIscript
2536 +Usually there is something which needs to be done to prepare the link
2537 +before the PPP protocol can be started; for instance, with a dial-up
2538 +modem, commands need to be sent to the modem to dial the appropriate
2539 +phone number. This option specifies an command for pppd to execute
2540 +(by passing it to a shell) before attempting to start PPP negotiation.
2541 +The chat (8) program is often useful here, as it provides a way to
2542 +send arbitrary strings to a modem and respond to received characters.
2544 +for this option from a privileged source cannot be overridden by a
2545 +non-privileged user.
2548 +Specifies that pppd should set the serial port to use hardware flow
2549 +control using the RTS and CTS signals in the RS-232 interface.
2550 +If neither the \fIcrtscts\fR, the
2551 +\fInocrtscts\fR, the \fIcdtrcts\fR nor the \fInocdtrcts\fR option
2552 +is given, the hardware flow control setting for the serial port is
2554 +Some serial ports (such as Macintosh serial ports) lack a true
2555 +RTS output. Such serial ports use this mode to implement
2556 +unidirectional flow control. The serial port will
2557 +suspend transmission when requested by the modem (via CTS)
2558 +but will be unable to request the modem to stop sending to the
2559 +computer. This mode retains the ability to use DTR as
2560 +a modem control line.
2563 +Add a default route to the system routing tables, using the peer as
2564 +the gateway, when IPCP negotiation is successfully completed.
2565 +This entry is removed when the PPP connection is broken. This option
2566 +is privileged if the \fInodefaultroute\fR option has been specified.
2568 +.B disconnect \fIscript
2569 +Execute the command specified by \fIscript\fR, by passing it to a
2571 +pppd has terminated the link. This command could, for example, issue
2572 +commands to the modem to cause it to hang up if hardware modem control
2573 +signals were not available. The disconnect script is not run if the
2574 +modem has already hung up. A value for this option from a privileged
2575 +source cannot be overridden by a non-privileged user.
2577 +.B escape \fIxx,yy,...
2578 +Specifies that certain characters should be escaped on transmission
2579 +(regardless of whether the peer requests them to be escaped with its
2580 +async control character map). The characters to be escaped are
2581 +specified as a list of hex numbers separated by commas. Note that
2582 +almost any character can be specified for the \fIescape\fR option,
2583 +unlike the \fIasyncmap\fR option which only allows control characters
2584 +to be specified. The characters which may not be escaped are those
2585 +with hex values 0x20 - 0x3f or 0x5e.
2588 +Read options from file \fIname\fR (the format is described below).
2589 +The file must be readable by the user who has invoked pppd.
2592 +Execute the command specified by \fIscript\fR, by passing it to a shell, to
2593 +initialize the serial line. This script would typically use the
2594 +chat(8) program to configure the modem to enable auto answer. A value
2595 +for this option from a privileged source cannot be overridden by a
2596 +non-privileged user.
2599 +Specifies that pppd should create a UUCP-style lock file for the
2600 +serial device to ensure exclusive access to the device. By default,
2601 +pppd will not create a lock file.
2604 +Set the MRU [Maximum Receive Unit] value to \fIn\fR. Pppd
2605 +will ask the peer to send packets of no more than \fIn\fR bytes.
2606 +The value of \fIn\fR must be between 128 and 16384; the default is 1500.
2608 +296 works well on very slow links (40 bytes for TCP/IP header + 256
2610 +Note that for the IPv6 protocol, the MRU must be at least 1280.
2613 +Set the MTU [Maximum Transmit Unit] value to \fIn\fR. Unless the
2614 +peer requests a smaller value via MRU negotiation, pppd will
2615 +request that the kernel networking code send data packets of no more
2616 +than \fIn\fR bytes through the PPP network interface. Note that for
2617 +the IPv6 protocol, the MTU must be at least 1280.
2620 +Enables the "passive" option in the LCP. With this option, pppd will
2621 +attempt to initiate a connection; if no reply is received from the
2622 +peer, pppd will then just wait passively for a valid LCP packet from
2623 +the peer, instead of exiting, as it would without this option.
2626 +.I <local_IP_address>\fB:\fI<remote_IP_address>
2627 +Set the local and/or remote interface IP addresses. Either one may be
2628 +omitted. The IP addresses can be specified with a host name or in
2629 +decimal dot notation (e.g. 150.234.56.78). The default local
2630 +address is the (first) IP address of the system (unless the
2632 +option is given). The remote address will be obtained from the peer
2633 +if not specified in any option. Thus, in simple cases, this option is
2634 +not required. If a local and/or remote IP address is specified with
2636 +will not accept a different value from the peer in the IPCP
2637 +negotiation, unless the \fIipcp\-accept\-local\fR and/or
2638 +\fIipcp\-accept\-remote\fR options are given, respectively.
2640 +.B ipv6 \fI<local_interface_identifier>\fR,\fI<remote_interface_identifier>
2641 +Set the local and/or remote 64-bit interface identifier. Either one may be
2642 +omitted. The identifier must be specified in standard ascii notation of
2643 +IPv6 addresses (e.g. ::dead:beef). If the
2644 +\fIipv6cp\-use\-ipaddr\fR
2645 +option is given, the local identifier is the local IPv4 address (see above).
2646 +On systems which supports a unique persistent id, such as EUI\-48 derived
2647 +from the Ethernet MAC address, \fIipv6cp\-use\-persistent\fR option can be
2648 +used to replace the \fIipv6 <local>,<remote>\fR option. Otherwise the
2649 +identifier is randomized.
2651 +.B active\-filter \fIfilter\-expression
2652 +Specifies a packet filter to be applied to data packets to determine
2653 +which packets are to be regarded as link activity, and therefore reset
2654 +the idle timer, or cause the link to be brought up in demand-dialling
2655 +mode. This option is useful in conjunction with the
2656 +\fBidle\fR option if there are packets being sent or received
2657 +regularly over the link (for example, routing information packets)
2658 +which would otherwise prevent the link from ever appearing to be idle.
2659 +The \fIfilter\-expression\fR syntax is as described for tcpdump(1),
2660 +except that qualifiers which are inappropriate for a PPP link, such as
2661 +\fBether\fR and \fBarp\fR, are not permitted. Generally the filter
2662 +expression should be enclosed in single-quotes to prevent whitespace
2663 +in the expression from being interpreted by the shell. This option
2664 +is currently only available under Linux, and requires that the kernel
2665 +was configured to include PPP filtering support (CONFIG_PPP_FILTER).
2667 +is possible to apply different constraints to incoming and outgoing
2668 +packets using the \fBinbound\fR and \fBoutbound\fR qualifiers.
2670 +.B allow\-ip \fIaddress(es)
2671 +Allow peers to use the given IP address or subnet without
2672 +authenticating themselves. The parameter is parsed as for each
2673 +element of the list of allowed IP addresses in the secrets files (see
2674 +the AUTHENTICATION section below).
2676 +.B allow\-number \fInumber
2677 +Allow peers to connect from the given telephone number. A trailing
2678 +`*' character will match all numbers beginning with the leading part.
2680 +.B bsdcomp \fInr,nt
2681 +Request that the peer compress packets that it sends, using the
2682 +BSD-Compress scheme, with a maximum code size of \fInr\fR bits, and
2683 +agree to compress packets sent to the peer with a maximum code size of
2684 +\fInt\fR bits. If \fInt\fR is not specified, it defaults to the value
2685 +given for \fInr\fR. Values in the range 9 to 15 may be used for
2686 +\fInr\fR and \fInt\fR; larger values give better compression but
2687 +consume more kernel memory for compression dictionaries.
2688 +Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables
2689 +compression in the corresponding direction. Use \fInobsdcomp\fR or
2690 +\fIbsdcomp 0\fR to disable BSD-Compress compression entirely.
2693 +Use a non-standard hardware flow control (i.e. DTR/CTS) to control
2694 +the flow of data on the serial port. If neither the \fIcrtscts\fR,
2695 +the \fInocrtscts\fR, the \fIcdtrcts\fR nor the \fInocdtrcts\fR
2696 +option is given, the hardware flow control setting for the serial
2697 +port is left unchanged.
2698 +Some serial ports (such as Macintosh serial ports) lack a true
2699 +RTS output. Such serial ports use this mode to implement true
2700 +bi-directional flow control. The sacrifice is that this flow
2701 +control mode does not permit using DTR as a modem control line.
2703 +.B chap\-interval \fIn
2704 +If this option is given, pppd will rechallenge the peer every \fIn\fR
2707 +.B chap\-max\-challenge \fIn
2708 +Set the maximum number of CHAP challenge transmissions to \fIn\fR
2711 +.B chap\-restart \fIn
2712 +Set the CHAP restart interval (retransmission timeout for challenges)
2713 +to \fIn\fR seconds (default 3).
2715 +.B child\-timeout \fIn
2716 +When exiting, wait for up to \fIn\fR seconds for any child processes
2717 +(such as the command specified with the \fBpty\fR command) to exit
2718 +before exiting. At the end of the timeout, pppd will send a SIGTERM
2719 +signal to any remaining child processes and exit. A value of 0 means
2720 +no timeout, that is, pppd will wait until all child processes have
2723 +.B connect\-delay \fIn
2724 +Wait for up to \fIn\fR milliseconds after the connect script finishes for
2725 +a valid PPP packet from the peer. At the end of this time, or when a
2726 +valid PPP packet is received from the peer, pppd will commence
2727 +negotiation by sending its first LCP packet. The default value is
2728 +1000 (1 second). This wait period only applies if the \fBconnect\fR
2729 +or \fBpty\fR option is used.
2732 +Enables connection debugging facilities.
2733 +If this option is given, pppd will log the contents of all
2734 +control packets sent or received in a readable form. The packets are
2735 +logged through syslog with facility \fIdaemon\fR and level
2736 +\fIdebug\fR. This information can be directed to a file by setting up
2737 +/etc/syslog.conf appropriately (see syslog.conf(5)).
2739 +.B default\-asyncmap
2740 +Disable asyncmap negotiation, forcing all control characters to be
2741 +escaped for both the transmit and the receive direction.
2744 +Disable MRU [Maximum Receive Unit] negotiation. With this option,
2745 +pppd will use the default MRU value of 1500 bytes for both the
2746 +transmit and receive direction.
2748 +.B deflate \fInr,nt
2749 +Request that the peer compress packets that it sends, using the
2750 +Deflate scheme, with a maximum window size of \fI2**nr\fR bytes, and
2751 +agree to compress packets sent to the peer with a maximum window size
2752 +of \fI2**nt\fR bytes. If \fInt\fR is not specified, it defaults to
2753 +the value given for \fInr\fR. Values in the range 9 to 15 may be used
2754 +for \fInr\fR and \fInt\fR; larger values give better compression but
2755 +consume more kernel memory for compression dictionaries.
2756 +Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables
2757 +compression in the corresponding direction. Use \fInodeflate\fR or
2758 +\fIdeflate 0\fR to disable Deflate compression entirely. (Note: pppd
2759 +requests Deflate compression in preference to BSD-Compress if the peer
2763 +Initiate the link only on demand, i.e. when data traffic is present.
2764 +With this option, the remote IP address must be specified by the user
2765 +on the command line or in an options file. Pppd will initially
2766 +configure the interface and enable it for IP traffic without
2767 +connecting to the peer. When traffic is available, pppd will
2768 +connect to the peer and perform negotiation, authentication, etc.
2769 +When this is completed, pppd will commence passing data packets
2770 +(i.e., IP packets) across the link.
2772 +The \fIdemand\fR option implies the \fIpersist\fR option. If this
2773 +behaviour is not desired, use the \fInopersist\fR option after the
2774 +\fIdemand\fR option. The \fIidle\fR and \fIholdoff\fR
2775 +options are also useful in conjuction with the \fIdemand\fR option.
2778 +Append the domain name \fId\fR to the local host name for authentication
2779 +purposes. For example, if gethostname() returns the name porsche, but
2780 +the fully qualified domain name is porsche.Quotron.COM, you could
2781 +specify \fIdomain Quotron.COM\fR. Pppd would then use the name
2782 +\fIporsche.Quotron.COM\fR for looking up secrets in the secrets file,
2783 +and as the default name to send to the peer when authenticating itself
2784 +to the peer. This option is privileged.
2787 +With the \fBdryrun\fR option, pppd will print out all the option
2788 +values which have been set and then exit, after parsing the command
2789 +line and options files and checking the option values, but before
2790 +initiating the link. The option values are logged at level info, and
2791 +also printed to standard output unless the device on standard output
2792 +is the device that pppd would be using to communicate with the peer.
2795 +With the \fBdump\fR option, pppd will print out all the option values
2796 +which have been set. This option is like the \fBdryrun\fR option
2797 +except that pppd proceeds as normal rather than exiting.
2800 +Enables session accounting via PAM or wtwp/wtmpx, as appropriate.
2801 +When PAM is enabled, the PAM "account" and "session" module stacks
2802 +determine behavior, and are enabled for all PPP authentication
2803 +protocols. When PAM is disabled, wtmp/wtmpx entries are recorded
2804 +regardless of whether the peer name identifies a valid user on the
2805 +local system, making peers visible in the last(1) log. This feature
2806 +is automatically enabled when the pppd \fBlogin\fR option is used.
2807 +Session accounting is disabled by default.
2809 +.B endpoint \fI<epdisc>
2810 +Sets the endpoint discriminator sent by the local machine to the peer
2811 +during multilink negotiation to \fI<epdisc>\fR. The default is to use
2812 +the MAC address of the first ethernet interface on the system, if any,
2813 +otherwise the IPv4 address corresponding to the hostname, if any,
2814 +provided it is not in the multicast or locally-assigned IP address
2815 +ranges, or the localhost address. The endpoint discriminator can be
2816 +the string \fBnull\fR or of the form \fItype\fR:\fIvalue\fR, where
2817 +type is a decimal number or one of the strings \fBlocal\fR, \fBIP\fR,
2818 +\fBMAC\fR, \fBmagic\fR, or \fBphone\fR. The value is an IP address in
2819 +dotted-decimal notation for the \fBIP\fR type, or a string of bytes in
2820 +hexadecimal, separated by periods or colons for the other types. For
2821 +the MAC type, the value may also be the name of an ethernet or similar
2822 +network interface. This option is currently only available under
2825 +.B eap\-interval \fIn
2826 +If this option is given and pppd authenticates the peer with EAP
2827 +(i.e., is the server), pppd will restart EAP authentication every
2828 +\fIn\fR seconds. For EAP SRP\-SHA1, see also the \fBsrp\-interval\fR
2829 +option, which enables lightweight rechallenge.
2831 +.B eap\-max\-rreq \fIn
2832 +Set the maximum number of EAP Requests to which pppd will respond (as
2833 +a client) without hearing EAP Success or Failure. (Default is 20.)
2835 +.B eap\-max\-sreq \fIn
2836 +Set the maximum number of EAP Requests that pppd will issue (as a
2837 +server) while attempting authentication. (Default is 10.)
2839 +.B eap\-restart \fIn
2840 +Set the retransmit timeout for EAP Requests when acting as a server
2841 +(authenticator). (Default is 3 seconds.)
2843 +.B eap\-timeout \fIn
2844 +Set the maximum time to wait for the peer to send an EAP Request when
2845 +acting as a client (authenticatee). (Default is 20 seconds.)
2848 +When logging the contents of PAP packets, this option causes pppd to
2849 +exclude the password string from the log. This is the default.
2852 +Specifies how many seconds to wait before re-initiating the link after
2853 +it terminates. This option only has any effect if the \fIpersist\fR
2854 +or \fIdemand\fR option is used. The holdoff period is not applied if
2855 +the link was terminated because it was idle.
2858 +Specifies that pppd should disconnect if the link is idle for \fIn\fR
2859 +seconds. The link is idle when no data packets (i.e. IP packets) are
2860 +being sent or received. Note: it is not advisable to use this option
2861 +with the \fIpersist\fR option without the \fIdemand\fR option.
2862 +If the \fBactive\-filter\fR
2863 +option is given, data packets which are rejected by the specified
2864 +activity filter also count as the link being idle.
2866 +.B ipcp\-accept\-local
2867 +With this option, pppd will accept the peer's idea of our local IP
2868 +address, even if the local IP address was specified in an option.
2870 +.B ipcp\-accept\-remote
2871 +With this option, pppd will accept the peer's idea of its (remote) IP
2872 +address, even if the remote IP address was specified in an option.
2874 +.B ipcp\-max\-configure \fIn
2875 +Set the maximum number of IPCP configure-request transmissions to
2876 +\fIn\fR (default 10).
2878 +.B ipcp\-max\-failure \fIn
2879 +Set the maximum number of IPCP configure-NAKs returned before starting
2880 +to send configure-Rejects instead to \fIn\fR (default 10).
2882 +.B ipcp\-max\-terminate \fIn
2883 +Set the maximum number of IPCP terminate-request transmissions to
2884 +\fIn\fR (default 3).
2886 +.B ipcp\-restart \fIn
2887 +Set the IPCP restart interval (retransmission timeout) to \fIn\fR
2888 +seconds (default 3).
2890 +.B ipparam \fIstring
2891 +Provides an extra parameter to the ip\-up, ip\-pre\-up and ip\-down
2893 +option is given, the \fIstring\fR supplied is given as the 6th
2894 +parameter to those scripts.
2896 +.B ipv6cp\-max\-configure \fIn
2897 +Set the maximum number of IPv6CP configure-request transmissions to
2898 +\fIn\fR (default 10).
2900 +.B ipv6cp\-max\-failure \fIn
2901 +Set the maximum number of IPv6CP configure-NAKs returned before starting
2902 +to send configure-Rejects instead to \fIn\fR (default 10).
2904 +.B ipv6cp\-max\-terminate \fIn
2905 +Set the maximum number of IPv6CP terminate-request transmissions to
2906 +\fIn\fR (default 3).
2908 +.B ipv6cp\-restart \fIn
2909 +Set the IPv6CP restart interval (retransmission timeout) to \fIn\fR
2910 +seconds (default 3).
2913 +Enable the IPXCP and IPX protocols. This option is presently only
2914 +supported under Linux, and only if your kernel has been configured to
2915 +include IPX support.
2917 +.B ipx\-network \fIn
2918 +Set the IPX network number in the IPXCP configure request frame to
2919 +\fIn\fR, a hexadecimal number (without a leading 0x). There is no
2920 +valid default. If this option is not specified, the network number is
2921 +obtained from the peer. If the peer does not have the network number,
2922 +the IPX protocol will not be started.
2924 +.B ipx\-node \fIn\fB:\fIm
2925 +Set the IPX node numbers. The two node numbers are separated from each
2926 +other with a colon character. The first number \fIn\fR is the local
2927 +node number. The second number \fIm\fR is the peer's node number. Each
2928 +node number is a hexadecimal number, at most 10 digits long. The node
2929 +numbers on the ipx\-network must be unique. There is no valid
2930 +default. If this option is not specified then the node numbers are
2931 +obtained from the peer.
2933 +.B ipx\-router\-name \fI<string>
2934 +Set the name of the router. This is a string and is sent to the peer
2935 +as information data.
2937 +.B ipx\-routing \fIn
2938 +Set the routing protocol to be received by this option. More than one
2939 +instance of \fIipx\-routing\fR may be specified. The '\fInone\fR'
2940 +option (0) may be specified as the only instance of ipx\-routing. The
2941 +values may be \fI0\fR for \fINONE\fR, \fI2\fR for \fIRIP/SAP\fR, and
2942 +\fI4\fR for \fINLSP\fR.
2944 +.B ipxcp\-accept\-local
2945 +Accept the peer's NAK for the node number specified in the ipx\-node
2946 +option. If a node number was specified, and non-zero, the default is
2947 +to insist that the value be used. If you include this option then you
2948 +will permit the peer to override the entry of the node number.
2950 +.B ipxcp\-accept\-network
2951 +Accept the peer's NAK for the network number specified in the
2952 +ipx\-network option. If a network number was specified, and non-zero, the
2953 +default is to insist that the value be used. If you include this
2954 +option then you will permit the peer to override the entry of the node
2957 +.B ipxcp\-accept\-remote
2958 +Use the peer's network number specified in the configure request
2959 +frame. If a node number was specified for the peer and this option was
2960 +not specified, the peer will be forced to use the value which you have
2963 +.B ipxcp\-max\-configure \fIn
2964 +Set the maximum number of IPXCP configure request frames which the
2965 +system will send to \fIn\fR. The default is 10.
2967 +.B ipxcp\-max\-failure \fIn
2968 +Set the maximum number of IPXCP NAK frames which the local system will
2969 +send before it rejects the options. The default value is 3.
2971 +.B ipxcp\-max\-terminate \fIn
2972 +Set the maximum nuber of IPXCP terminate request frames before the
2973 +local system considers that the peer is not listening to them. The
2974 +default value is 3.
2977 +Enable debugging code in the kernel-level PPP driver. The argument
2978 +values depend on the specific kernel driver, but in general a value of
2979 +1 will enable general kernel debug messages. (Note that these
2980 +messages are usually only useful for debugging the kernel driver
2981 +itself.) For the Linux 2.2.x kernel driver, the value is a sum of
2983 +enable general debug messages, 2 to request that the contents of
2984 +received packets be printed, and 4 to request that the contents of
2985 +transmitted packets be printed. On most systems, messages printed by
2986 +the kernel are logged by syslog(1) to a file as directed in the
2987 +/etc/syslog.conf configuration file.
2990 +Enables pppd to alter kernel settings as appropriate. Under Linux,
2991 +pppd will enable IP forwarding (i.e. set /proc/sys/net/ipv4/ip_forward
2992 +to 1) if the \fIproxyarp\fR option is used, and will enable the
2993 +dynamic IP address option (i.e. set /proc/sys/net/ipv4/ip_dynaddr to
2994 +1) in demand mode if the local address changes.
2996 +.B lcp\-echo\-failure \fIn
2997 +If this option is given, pppd will presume the peer to be dead
2998 +if \fIn\fR LCP echo\-requests are sent without receiving a valid LCP
2999 +echo\-reply. If this happens, pppd will terminate the
3000 +connection. Use of this option requires a non-zero value for the
3001 +\fIlcp\-echo\-interval\fR parameter. This option can be used to enable
3002 +pppd to terminate after the physical connection has been broken
3003 +(e.g., the modem has hung up) in situations where no hardware modem
3004 +control lines are available.
3006 +.B lcp\-echo\-interval \fIn
3007 +If this option is given, pppd will send an LCP echo\-request frame to
3008 +the peer every \fIn\fR seconds. Normally the peer should respond to
3009 +the echo\-request by sending an echo\-reply. This option can be used
3010 +with the \fIlcp\-echo\-failure\fR option to detect that the peer is no
3013 +.B lcp\-max\-configure \fIn
3014 +Set the maximum number of LCP configure-request transmissions to
3015 +\fIn\fR (default 10).
3017 +.B lcp\-max\-failure \fIn
3018 +Set the maximum number of LCP configure-NAKs returned before starting
3019 +to send configure-Rejects instead to \fIn\fR (default 10).
3021 +.B lcp\-max\-terminate \fIn
3022 +Set the maximum number of LCP terminate-request transmissions to
3023 +\fIn\fR (default 3).
3025 +.B lcp\-restart \fIn
3026 +Set the LCP restart interval (retransmission timeout) to \fIn\fR
3027 +seconds (default 3).
3029 +.B linkname \fIname\fR
3030 +Sets the logical name of the link to \fIname\fR. Pppd will create a
3031 +file named \fBppp\-\fIname\fB.pid\fR in /var/run (or /etc/ppp on some
3032 +systems) containing its process ID. This can be useful in determining
3033 +which instance of pppd is responsible for the link to a given peer
3034 +system. This is a privileged option.
3037 +Don't use the modem control lines. With this option, pppd will ignore
3038 +the state of the CD (Carrier Detect) signal from the modem and will
3039 +not change the state of the DTR (Data Terminal Ready) signal. This is
3040 +the opposite of the \fBmodem\fR option.
3043 +Send log messages to file descriptor \fIn\fR. Pppd will send log
3044 +messages to at most one file or file descriptor (as well as sending
3045 +the log messages to syslog), so this option and the \fBlogfile\fR
3046 +option are mutually exclusive. The default is for pppd to send log
3047 +messages to stdout (file descriptor 1), unless the serial port is
3048 +already open on stdout.
3050 +.B logfile \fIfilename
3051 +Append log messages to the file \fIfilename\fR (as well as sending the
3052 +log messages to syslog). The file is opened with the privileges of
3053 +the user who invoked pppd, in append mode.
3056 +Use the system password database for authenticating the peer using
3057 +PAP, and record the user in the system wtmp file. Note that the peer
3058 +must have an entry in the /etc/ppp/pap\-secrets file as well as the
3059 +system password database to be allowed access. See also the
3060 +\fBenable\-session\fR option.
3063 +Terminate the connection when it has been available for network
3064 +traffic for \fIn\fR seconds (i.e. \fIn\fR seconds after the first
3065 +network control protocol comes up).
3068 +Terminate after \fIn\fR consecutive failed connection attempts. A
3069 +value of 0 means no limit. The default value is 10.
3072 +Use the modem control lines. This option is the default. With this
3073 +option, pppd will wait for the CD (Carrier Detect) signal from the
3074 +modem to be asserted when opening the serial device (unless a connect
3075 +script is specified), and it will drop the DTR (Data Terminal Ready)
3076 +signal briefly when the connection is terminated and before executing
3077 +the connect script. On Ultrix, this option implies hardware flow
3078 +control, as for the \fIcrtscts\fR option. This is the opposite of the
3079 +\fBlocal\fR option.
3082 +Enables the use of PPP multilink; this is an alias for the `multilink'
3083 +option. This option is currently only available under Linux.
3086 +Allow MPPE to use stateful mode. Stateless mode is still attempted first.
3087 +The default is to disallow stateful mode.
3090 +Enables the use of short (12-bit) sequence numbers in multilink
3091 +headers, as opposed to 24-bit sequence numbers. This option is only
3092 +available under Linux, and only has any effect if multilink is
3093 +enabled (see the multilink option).
3096 +Sets the Maximum Reconstructed Receive Unit to \fIn\fR. The MRRU is
3097 +the maximum size for a received packet on a multilink bundle, and is
3098 +analogous to the MRU for the individual links. This option is
3099 +currently only available under Linux, and only has any effect if
3100 +multilink is enabled (see the multilink option).
3102 +.B ms\-dns \fI<addr>
3103 +If pppd is acting as a server for Microsoft Windows clients, this
3104 +option allows pppd to supply one or two DNS (Domain Name Server)
3105 +addresses to the clients. The first instance of this option specifies
3106 +the primary DNS address; the second instance (if given) specifies the
3107 +secondary DNS address. (This option was present in some older
3108 +versions of pppd under the name \fBdns\-addr\fR.)
3110 +.B ms\-wins \fI<addr>
3111 +If pppd is acting as a server for Microsoft Windows or "Samba"
3112 +clients, this option allows pppd to supply one or two WINS (Windows
3113 +Internet Name Services) server addresses to the clients. The first
3114 +instance of this option specifies the primary WINS address; the second
3115 +instance (if given) specifies the secondary WINS address.
3118 +Enables the use of the PPP multilink protocol. If the peer also
3119 +supports multilink, then this link can become part of a bundle between
3120 +the local system and the peer. If there is an existing bundle to the
3121 +peer, pppd will join this link to that bundle, otherwise pppd will
3122 +create a new bundle. See the MULTILINK section below. This option is
3123 +currently only available under Linux.
3126 +Set the name of the local system for authentication purposes to
3127 +\fIname\fR. This is a privileged option. With this option, pppd will
3128 +use lines in the secrets files which have \fIname\fR as the second
3129 +field when looking for a secret to use in authenticating the peer. In
3130 +addition, unless overridden with the \fIuser\fR option, \fIname\fR
3131 +will be used as the name to send to the peer when authenticating the
3132 +local system to the peer. (Note that pppd does not append the domain
3133 +name to \fIname\fR.)
3136 +Disable Address/Control compression in both directions (send and
3140 +Do not require the peer to authenticate itself. This option is
3144 +Disables BSD-Compress compression; \fBpppd\fR will not request or
3145 +agree to compress packets using the BSD-Compress scheme.
3148 +Disable CCP (Compression Control Protocol) negotiation. This option
3149 +should only be required if the peer is buggy and gets confused by
3150 +requests from pppd for CCP negotiation.
3153 +Disable hardware flow control (i.e. RTS/CTS) on the serial port.
3154 +If neither the \fIcrtscts\fR nor the \fInocrtscts\fR nor the
3155 +\fIcdtrcts\fR nor the \fInocdtrcts\fR option is given, the hardware
3156 +flow control setting for the serial port is left unchanged.
3159 +This option is a synonym for \fInocrtscts\fR. Either of these options will
3160 +disable both forms of hardware flow control.
3163 +Disable the \fIdefaultroute\fR option. The system administrator who
3164 +wishes to prevent users from creating default routes with pppd
3165 +can do so by placing this option in the /etc/ppp/options file.
3168 +Disables Deflate compression; pppd will not request or agree to
3169 +compress packets using the Deflate scheme.
3172 +Don't detach from the controlling terminal. Without this option, if a
3173 +serial device other than the terminal on the standard input is
3174 +specified, pppd will fork to become a background process.
3177 +Disables pppd from sending an endpoint discriminator to the peer or
3178 +accepting one from the peer (see the MULTILINK section below). This
3179 +option should only be required if the peer is buggy.
3182 +Disable IPCP negotiation and IP communication. This option should
3183 +only be required if the peer is buggy and gets confused by requests
3184 +from pppd for IPCP negotiation.
3187 +Disable IPv6CP negotiation and IPv6 communication. This option should
3188 +only be required if the peer is buggy and gets confused by requests
3189 +from pppd for IPv6CP negotiation.
3192 +Disables the default behaviour when no local IP address is specified,
3193 +which is to determine (if possible) the local IP address from the
3194 +hostname. With this option, the peer will have to supply the local IP
3195 +address during IPCP negotiation (unless it specified explicitly on the
3196 +command line or in an options file).
3199 +Disable the IPXCP and IPX protocols. This option should only be
3200 +required if the peer is buggy and gets confused by requests from pppd
3201 +for IPXCP negotiation.
3204 +Opposite of the \fIktune\fR option; disables pppd from changing system
3208 +Opposite of the \fIlock\fR option; specifies that pppd should not
3209 +create a UUCP-style lock file for the serial device. This option is
3213 +Do not send log messages to a file or file descriptor. This option
3214 +cancels the \fBlogfd\fR and \fBlogfile\fR options.
3217 +Disable magic number negotiation. With this option, pppd cannot
3218 +detect a looped-back line. This option should only be needed if the
3222 +Disables the use of PPP multilink. This option is currently only
3223 +available under Linux.
3226 +Disables MPPE (Microsoft Point to Point Encryption). This is the default.
3229 +Disable 40-bit encryption with MPPE.
3232 +Disable 128-bit encryption with MPPE.
3234 +.B nomppe\-stateful
3235 +Disable MPPE stateful mode. This is the default.
3238 +Disables the use of short (12-bit) sequence numbers in the PPP
3239 +multilink protocol, forcing the use of 24-bit sequence numbers. This
3240 +option is currently only available under Linux, and only has any
3241 +effect if multilink is enabled.
3244 +Disables the use of PPP multilink. This option is currently only
3245 +available under Linux.
3248 +Disable protocol field compression negotiation in both the receive and
3249 +the transmit direction.
3252 +Exit once a connection has been made and terminated. This is the
3253 +default unless the \fIpersist\fR or \fIdemand\fR option has been
3257 +Do not accept or agree to Predictor\-1 compression.
3260 +Disable the \fIproxyarp\fR option. The system administrator who
3261 +wishes to prevent users from creating proxy ARP entries with pppd can
3262 +do so by placing this option in the /etc/ppp/options file.
3265 +Allow pppd to operate without having an IP address for the peer. This
3266 +option is only available under Linux. Normally, pppd will request the
3267 +peer's IP address, and if the peer does not supply it, pppd will not
3268 +bring up the link for IP traffic. With this option, if the peer does
3269 +not supply its IP address, pppd will not ask the peer for it, and will
3270 +not set the destination address of the ppp interface. In this
3271 +situation, the ppp interface can be used for routing by creating
3272 +device routes, but the peer itself cannot be addressed directly for IP
3276 +Normally, pppd requires a terminal device. With this option, pppd
3277 +will allocate itself a pseudo-tty master/slave pair and use the slave
3278 +as its terminal device. Pppd will create a child process to act as a
3279 +`character shunt' to transfer characters between the pseudo-tty master
3280 +and its standard input and output. Thus pppd will transmit characters
3281 +on its standard output and receive characters on its standard input
3282 +even if they are not terminal devices. This option increases the
3283 +latency and CPU overhead of transferring data over the ppp interface
3284 +as all of the characters sent and received must flow through the
3285 +character shunt process. An explicit device name may not be given if
3286 +this option is used.
3289 +Disable Van Jacobson style TCP/IP header compression in both the
3290 +transmit and the receive direction.
3293 +Disable the connection-ID compression option in Van Jacobson style
3294 +TCP/IP header compression. With this option, pppd will not omit the
3295 +connection-ID byte from Van Jacobson compressed TCP/IP headers, nor
3296 +ask the peer to do so.
3299 +Indicates that all secrets in the /etc/ppp/pap\-secrets file which are
3300 +used for checking the identity of the peer are encrypted, and thus
3301 +pppd should not accept a password which, before encryption, is
3302 +identical to the secret from the /etc/ppp/pap\-secrets file.
3304 +.B pap\-max\-authreq \fIn
3305 +Set the maximum number of PAP authenticate-request transmissions to
3306 +\fIn\fR (default 10).
3308 +.B pap\-restart \fIn
3309 +Set the PAP restart interval (retransmission timeout) to \fIn\fR
3310 +seconds (default 3).
3312 +.B pap\-timeout \fIn
3313 +Set the maximum time that pppd will wait for the peer to authenticate
3314 +itself with PAP to \fIn\fR seconds (0 means no limit).
3316 +.B pass\-filter \fIfilter\-expression
3317 +Specifies a packet filter to applied to data packets being sent or
3318 +received to determine which packets should be allowed to pass.
3319 +Packets which are rejected by the filter are silently discarded. This
3320 +option can be used to prevent specific network daemons (such as
3321 +routed) using up link bandwidth, or to provide a very basic firewall
3323 +The \fIfilter\-expression\fR syntax is as described for tcpdump(1),
3324 +except that qualifiers which are inappropriate for a PPP link, such as
3325 +\fBether\fR and \fBarp\fR, are not permitted. Generally the filter
3326 +expression should be enclosed in single-quotes to prevent whitespace
3327 +in the expression from being interpreted by the shell. Note that it
3328 +is possible to apply different constraints to incoming and outgoing
3329 +packets using the \fBinbound\fR and \fBoutbound\fR qualifiers. This
3330 +option is currently only available under Linux, and requires that the
3331 +kernel was configured to include PPP filtering support (CONFIG_PPP_FILTER).
3333 +.B password \fIpassword\-string
3334 +Specifies the password to use for authenticating to the peer. Use
3335 +of this option is discouraged, as the password is likely to be visible
3336 +to other users on the system (for example, by using ps(1)).
3339 +Do not exit after a connection is terminated; instead try to reopen
3340 +the connection. The \fBmaxfail\fR option still has an effect on
3341 +persistent connections.
3343 +.B plugin \fIfilename
3344 +Load the shared library object file \fIfilename\fR as a plugin. This
3345 +is a privileged option. If \fIfilename\fR does not contain a slash
3346 +(/), pppd will look in the \fB/usr/lib/pppd/\fIversion\fR directory
3347 +for the plugin, where
3348 +\fIversion\fR is the version number of pppd (for example, 2.4.2).
3351 +Request that the peer compress frames that it sends using Predictor-1
3352 +compression, and agree to compress transmitted frames with Predictor-1
3353 +if requested. This option has no effect unless the kernel driver
3354 +supports Predictor-1 compression.
3356 +.B privgroup \fIgroup\-name
3357 +Allows members of group \fIgroup\-name\fR to use privileged options.
3358 +This is a privileged option. Use of this option requires care as
3359 +there is no guarantee that members of \fIgroup\-name\fR cannot use pppd
3360 +to become root themselves. Consider it equivalent to putting the
3361 +members of \fIgroup\-name\fR in the kmem or disk group.
3364 +Add an entry to this system's ARP [Address Resolution Protocol] table
3365 +with the IP address of the peer and the Ethernet address of this
3366 +system. This will have the effect of making the peer appear to other
3367 +systems to be on the local ethernet.
3370 +Specifies that the command \fIscript\fR is to be used to communicate
3371 +rather than a specific terminal device. Pppd will allocate itself a
3372 +pseudo-tty master/slave pair and use the slave as its terminal
3373 +device. The \fIscript\fR will be run in a child process with the
3374 +pseudo-tty master as its standard input and output. An explicit
3375 +device name may not be given if this option is used. (Note: if the
3376 +\fIrecord\fR option is used in conjuction with the \fIpty\fR option,
3377 +the child process will have pipes on its standard input and output.)
3380 +With this option, pppd will accept all control characters from the
3381 +peer, including those marked in the receive asyncmap. Without this
3382 +option, pppd will discard those characters as specified in RFC1662.
3383 +This option should only be needed if the peer is buggy.
3385 +.B record \fIfilename
3386 +Specifies that pppd should record all characters sent and received to
3387 +a file named \fIfilename\fR. This file is opened in append mode,
3388 +using the user's user-ID and permissions. This option is implemented
3389 +using a pseudo-tty and a process to transfer characters between the
3390 +pseudo-tty and the real serial device, so it will increase the latency
3391 +and CPU overhead of transferring data over the ppp interface. The
3392 +characters are stored in a tagged format with timestamps, which can be
3393 +displayed in readable form using the pppdump(8) program.
3395 +.B remotename \fIname
3396 +Set the assumed name of the remote system for authentication purposes
3399 +.B remotenumber \fInumber
3400 +Set the assumed telephone number of the remote system for authentication
3401 +purposes to \fInumber\fR.
3404 +With this option, pppd will not agree to authenticate itself to the
3408 +With this option, pppd will not agree to authenticate itself to the
3409 +peer using MS\-CHAP.
3411 +.B refuse\-mschap\-v2
3412 +With this option, pppd will not agree to authenticate itself to the
3413 +peer using MS\-CHAPv2.
3416 +With this option, pppd will not agree to authenticate itself to the
3420 +With this option, pppd will not agree to authenticate itself to the
3424 +Require the peer to authenticate itself using CHAP [Challenge
3425 +Handshake Authentication Protocol] authentication.
3428 +Require the use of MPPE (Microsoft Point to Point Encryption). This
3429 +option disables all other compression types. This option enables
3430 +both 40-bit and 128-bit encryption. In order for MPPE to successfully
3431 +come up, you must have authenticated with either MS\-CHAP or MS\-CHAPv2.
3432 +This option is presently only supported under Linux, and only if your
3433 +kernel has been configured to include MPPE support.
3435 +.B require\-mppe\-40
3436 +Require the use of MPPE, with 40-bit encryption.
3438 +.B require\-mppe\-128
3439 +Require the use of MPPE, with 128-bit encryption.
3442 +Require the peer to authenticate itself using MS\-CHAP [Microsoft Challenge
3443 +Handshake Authentication Protocol] authentication.
3445 +.B require\-mschap\-v2
3446 +Require the peer to authenticate itself using MS\-CHAPv2 [Microsoft Challenge
3447 +Handshake Authentication Protocol, Version 2] authentication.
3450 +Require the peer to authenticate itself using EAP [Extensible
3451 +Authentication Protocol] authentication.
3454 +Require the peer to authenticate itself using PAP [Password
3455 +Authentication Protocol] authentication.
3458 +When logging the contents of PAP packets, this option causes pppd to
3459 +show the password string in the log message.
3462 +With this option, pppd will not transmit LCP packets to initiate a
3463 +connection until a valid LCP packet is received from the peer (as for
3464 +the `passive' option with ancient versions of pppd).
3466 +.B srp\-interval \fIn
3467 +If this parameter is given and pppd uses EAP SRP\-SHA1 to authenticate
3468 +the peer (i.e., is the server), then pppd will use the optional
3469 +lightweight SRP rechallenge mechanism at intervals of \fIn\fR
3470 +seconds. This option is faster than \fBeap\-interval\fR
3471 +reauthentication because it uses a hash\-based mechanism and does not
3472 +derive a new session key.
3474 +.B srp\-pn\-secret \fIstring
3475 +Set the long-term pseudonym-generating secret for the server. This
3476 +value is optional and if set, needs to be known at the server
3477 +(authenticator) side only, and should be different for each server (or
3478 +poll of identical servers). It is used along with the current date to
3479 +generate a key to encrypt and decrypt the client's identity contained
3482 +.B srp\-use\-pseudonym
3483 +When operating as an EAP SRP\-SHA1 client, attempt to use the pseudonym
3484 +stored in ~/.ppp_psuedonym first as the identity, and save in this
3485 +file any pseudonym offered by the peer during authentication.
3488 +Use synchronous HDLC serial encoding instead of asynchronous.
3489 +The device used by pppd with this option must have sync support.
3490 +Currently supports Microgate SyncLink adapters
3491 +under Linux and FreeBSD 2.2.8 and later.
3494 +Sets the ppp unit number (for a ppp0 or ppp1 etc interface name) for outbound
3498 +With this option, pppd will detach from its controlling terminal once
3499 +it has successfully established the ppp connection (to the point where
3500 +the first network control protocol, usually the IP control protocol,
3504 +Enforce the use of the hostname (with domain name appended, if given)
3505 +as the name of the local system for authentication purposes (overrides
3506 +the \fIname\fR option). This option is not normally needed since the
3507 +\fIname\fR option is privileged.
3510 +Ask the peer for up to 2 DNS server addresses. The addresses supplied
3511 +by the peer (if any) are passed to the /etc/ppp/ip\-up script in the
3512 +environment variables DNS1 and DNS2, and the environment variable
3513 +USEPEERDNS will be set to 1. In addition, pppd will create an
3514 +/etc/ppp/resolv.conf file containing one or two nameserver lines with
3515 +the address(es) supplied by the peer.
3518 +Sets the name used for authenticating the local system to the peer to
3521 +.B vj\-max\-slots \fIn
3522 +Sets the number of connection slots to be used by the Van Jacobson
3523 +TCP/IP header compression and decompression code to \fIn\fR, which
3524 +must be between 2 and 16 (inclusive).
3526 +.B welcome \fIscript
3527 +Run the executable or shell command specified by \fIscript\fR before
3528 +initiating PPP negotiation, after the connect script (if any) has
3529 +completed. A value for this option from a privileged source cannot be
3530 +overridden by a non-privileged user.
3533 +Use software flow control (i.e. XON/XOFF) to control the flow of data on
3536 +Options can be taken from files as well as the command line. Pppd
3537 +reads options from the files /etc/ppp/options, ~/.ppprc and
3538 +/etc/ppp/options.\fIttyname\fR (in that order) before processing the
3539 +options on the command line. (In fact, the command-line options are
3540 +scanned to find the terminal name before the options.\fIttyname\fR
3541 +file is read.) In forming the name of the options.\fIttyname\fR file,
3542 +the initial /dev/ is removed from the terminal name, and any remaining
3543 +/ characters are replaced with dots.
3545 +An options file is parsed into a series of words, delimited by
3546 +whitespace. Whitespace can be included in a word by enclosing the
3547 +word in double-quotes ("). A backslash (\\) quotes the following character.
3548 +A hash (#) starts a comment, which continues until the end of the
3549 +line. There is no restriction on using the \fIfile\fR or \fIcall\fR
3550 +options within an options file.
3553 +provides system administrators with sufficient access control that PPP
3554 +access to a server machine can be provided to legitimate users without
3555 +fear of compromising the security of the server or the network it's
3556 +on. This control is provided through restrictions on which IP
3557 +addresses the peer may use, based on its authenticated identity (if
3558 +any), and through restrictions on which options a non-privileged user
3559 +may use. Several of pppd's options are privileged, in particular
3560 +those which permit potentially insecure configurations; these options
3561 +are only accepted in files which are under the control of the system
3562 +administrator, or if pppd is being run by root.
3564 +The default behaviour of pppd is to allow an unauthenticated peer to
3565 +use a given IP address only if the system does not already have a
3566 +route to that IP address. For example, a system with a
3567 +permanent connection to the wider internet will normally have a
3568 +default route, and thus all peers will have to authenticate themselves
3569 +in order to set up a connection. On such a system, the \fIauth\fR
3570 +option is the default. On the other hand, a system where the
3571 +PPP link is the only connection to the internet will not normally have
3572 +a default route, so the peer will be able to use almost any IP address
3573 +without authenticating itself.
3575 +As indicated above, some security-sensitive options are privileged,
3576 +which means that they may not be used by an ordinary non-privileged
3577 +user running a setuid-root pppd, either on the command line, in the
3578 +user's ~/.ppprc file, or in an options file read using the \fIfile\fR
3579 +option. Privileged options may be used in /etc/ppp/options file or in
3580 +an options file read using the \fIcall\fR option. If pppd is being
3581 +run by the root user, privileged options can be used without
3584 +When opening the device, pppd uses either the invoking user's user ID
3585 +or the root UID (that is, 0), depending on whether the device name was
3586 +specified by the user or the system administrator. If the device name
3587 +comes from a privileged source, that is, /etc/ppp/options or an
3588 +options file read using the \fIcall\fR option, pppd uses full root
3589 +privileges when opening the device. Thus, by creating an appropriate
3590 +file under /etc/ppp/peers, the system administrator can allow users to
3591 +establish a ppp connection via a device which they would not normally
3592 +have permission to access. Otherwise pppd uses the invoking user's
3593 +real UID when opening the device.
3595 +Authentication is the process whereby one peer convinces the other of
3596 +its identity. This involves the first peer sending its name to the
3597 +other, together with some kind of secret information which could only
3598 +come from the genuine authorized user of that name. In such an
3599 +exchange, we will call the first peer the "client" and the other the
3600 +"server". The client has a name by which it identifies itself to the
3601 +server, and the server also has a name by which it identifies itself
3602 +to the client. Generally the genuine client shares some secret (or
3603 +password) with the server, and authenticates itself by proving that it
3604 +knows that secret. Very often, the names used for authentication
3605 +correspond to the internet hostnames of the peers, but this is not
3608 +At present, pppd supports three authentication protocols: the Password
3609 +Authentication Protocol (PAP), Challenge Handshake Authentication
3610 +Protocol (CHAP), and Extensible Authentication Protocol (EAP). PAP
3611 +involves the client sending its name and a cleartext password to the
3612 +server to authenticate itself. In contrast, the server initiates the
3613 +CHAP authentication exchange by sending a challenge to the client (the
3614 +challenge packet includes the server's name). The client must respond
3615 +with a response which includes its name plus a hash value derived from
3616 +the shared secret and the challenge, in order to prove that it knows
3617 +the secret. EAP supports CHAP-style authentication, and also includes
3618 +the SRP\-SHA1 mechanism, which is resistant to dictionary-based attacks
3619 +and does not require a cleartext password on the server side.
3621 +The PPP protocol, being symmetrical, allows both peers to require the
3622 +other to authenticate itself. In that case, two separate and
3623 +independent authentication exchanges will occur. The two exchanges
3624 +could use different authentication protocols, and in principle,
3625 +different names could be used in the two exchanges.
3627 +The default behaviour of pppd is to agree to authenticate if
3628 +requested, and to not require authentication from the peer. However,
3629 +pppd will not agree to authenticate itself with a particular protocol
3630 +if it has no secrets which could be used to do so.
3632 +Pppd stores secrets for use in authentication in secrets
3633 +files (/etc/ppp/pap\-secrets for PAP, /etc/ppp/chap\-secrets for CHAP,
3634 +MS\-CHAP, MS\-CHAPv2, and EAP MD5-Challenge, and /etc/ppp/srp\-secrets
3635 +for EAP SRP\-SHA1).
3636 +All secrets files have the same format. The secrets files can
3637 +contain secrets for pppd to use in authenticating itself to other
3638 +systems, as well as secrets for pppd to use when authenticating other
3641 +Each line in a secrets file contains one secret. A given secret is
3642 +specific to a particular combination of client and server - it can
3643 +only be used by that client to authenticate itself to that server.
3644 +Thus each line in a secrets file has at least 3 fields: the name of
3645 +the client, the name of the server, and the secret. These fields may
3646 +be followed by a list of the IP addresses that the specified client
3647 +may use when connecting to the specified server.
3649 +A secrets file is parsed into words as for a options file, so the
3650 +client name, server name and secrets fields must each be one word,
3651 +with any embedded spaces or other special characters quoted or
3652 +escaped. Note that case is significant in the client and server names
3655 +If the secret starts with an `@', what follows is assumed to be the
3656 +name of a file from which to read the secret. A "*" as the client or
3657 +server name matches any name. When selecting a secret, pppd takes the
3658 +best match, i.e. the match with the fewest wildcards.
3660 +Any following words on the same line are taken to be a list of
3661 +acceptable IP addresses for that client. If there are only 3 words on
3662 +the line, or if the first word is "\-", then all IP addresses are
3663 +disallowed. To allow any address, use "*". A word starting with "!"
3664 +indicates that the specified address is \fInot\fR acceptable. An
3665 +address may be followed by "/" and a number \fIn\fR, to indicate a
3666 +whole subnet, i.e. all addresses which have the same value in the most
3667 +significant \fIn\fR bits. In this form, the address may be followed
3668 +by a plus sign ("+") to indicate that one address from the subnet is
3669 +authorized, based on the ppp network interface unit number in use.
3670 +In this case, the host part of the address will be set to the unit
3673 +Thus a secrets file contains both secrets for use in authenticating
3674 +other hosts, plus secrets which we use for authenticating ourselves to
3675 +others. When pppd is authenticating the peer (checking the peer's
3676 +identity), it chooses a secret with the peer's name in the first
3677 +field and the name of the local system in the second field. The
3678 +name of the local system defaults to the hostname, with the domain
3679 +name appended if the \fIdomain\fR option is used. This default can be
3680 +overridden with the \fIname\fR option, except when the
3681 +\fIusehostname\fR option is used. (For EAP SRP\-SHA1, see the
3682 +srp\-entry(8) utility for generating proper validator entries to be
3683 +used in the "secret" field.)
3685 +When pppd is choosing a secret to use in authenticating itself to the
3686 +peer, it first determines what name it is going to use to identify
3687 +itself to the peer. This name can be specified by the user with the
3688 +\fIuser\fR option. If this option is not used, the name defaults to
3689 +the name of the local system, determined as described in the previous
3690 +paragraph. Then pppd looks for a secret with this name in the first
3691 +field and the peer's name in the second field. Pppd will know the
3692 +name of the peer if CHAP or EAP authentication is being used, because
3693 +the peer will have sent it in the challenge packet. However, if PAP
3694 +is being used, pppd will have to determine the peer's name from the
3695 +options specified by the user. The user can specify the peer's name
3696 +directly with the \fIremotename\fR option. Otherwise, if the remote
3697 +IP address was specified by a name (rather than in numeric form), that
3698 +name will be used as the peer's name. Failing that, pppd will use the
3699 +null string as the peer's name.
3701 +When authenticating the peer with PAP, the supplied password is first
3702 +compared with the secret from the secrets file. If the password
3703 +doesn't match the secret, the password is encrypted using crypt() and
3704 +checked against the secret again. Thus secrets for authenticating the
3705 +peer can be stored in encrypted form if desired. If the
3706 +\fIpapcrypt\fR option is given, the first (unencrypted) comparison is
3707 +omitted, for better security.
3709 +Furthermore, if the \fIlogin\fR option was specified, the username and
3710 +password are also checked against the system password database. Thus,
3711 +the system administrator can set up the pap\-secrets file to allow PPP
3712 +access only to certain users, and to restrict the set of IP addresses
3713 +that each user can use. Typically, when using the \fIlogin\fR option,
3714 +the secret in /etc/ppp/pap\-secrets would be "", which will match any
3715 +password supplied by the peer. This avoids the need to have the same
3716 +secret in two places.
3718 +Authentication must be satisfactorily completed before IPCP (or any
3719 +other Network Control Protocol) can be started. If the peer is
3720 +required to authenticate itself, and fails to do so, pppd will
3721 +terminated the link (by closing LCP). If IPCP negotiates an
3722 +unacceptable IP address for the remote host, IPCP will be closed. IP
3723 +packets can only be sent or received when IPCP is open.
3725 +In some cases it is desirable to allow some hosts which can't
3726 +authenticate themselves to connect and use one of a restricted set of
3727 +IP addresses, even when the local host generally requires
3728 +authentication. If the peer refuses to authenticate itself when
3729 +requested, pppd takes that as equivalent to authenticating with PAP
3730 +using the empty string for the username and password. Thus, by adding
3731 +a line to the pap\-secrets file which specifies the empty string for
3732 +the client and password, it is possible to allow restricted access to
3733 +hosts which refuse to authenticate themselves.
3736 +When IPCP negotiation is completed successfully, pppd will inform the
3737 +kernel of the local and remote IP addresses for the ppp interface.
3738 +This is sufficient to create a host route to the remote end of the
3739 +link, which will enable the peers to exchange IP packets.
3740 +Communication with other machines generally requires further
3741 +modification to routing tables and/or ARP (Address Resolution
3742 +Protocol) tables. In most cases the \fIdefaultroute\fR and/or
3743 +\fIproxyarp\fR options are sufficient for this, but in some cases
3744 +further intervention is required. The /etc/ppp/ip\-up script can be
3747 +Sometimes it is desirable to add a default route through the remote
3748 +host, as in the case of a machine whose only connection to the
3749 +Internet is through the ppp interface. The \fIdefaultroute\fR option
3750 +causes pppd to create such a default route when IPCP comes up, and
3751 +delete it when the link is terminated.
3753 +In some cases it is desirable to use proxy ARP, for example on a
3754 +server machine connected to a LAN, in order to allow other hosts to
3755 +communicate with the remote host. The \fIproxyarp\fR option causes
3756 +pppd to look for a network interface on the same subnet as the remote
3757 +host (an interface supporting broadcast and ARP, which is up and not a
3758 +point-to-point or loopback interface). If found, pppd creates a
3759 +permanent, published ARP entry with the IP address of the remote host
3760 +and the hardware address of the network interface found.
3762 +When the \fIdemand\fR option is used, the interface IP addresses have
3763 +already been set at the point when IPCP comes up. If pppd has not
3764 +been able to negotiate the same addresses that it used to configure
3765 +the interface (for example when the peer is an ISP that uses dynamic
3766 +IP address assignment), pppd has to change the interface IP addresses
3767 +to the negotiated addresses. This may disrupt existing connections,
3768 +and the use of demand dialling with peers that do dynamic IP address
3769 +assignment is not recommended.
3771 +Multilink PPP provides the capability to combine two or more PPP links
3772 +between a pair of machines into a single `bundle', which appears as a
3773 +single virtual PPP link which has the combined bandwidth of the
3774 +individual links. Currently, multilink PPP is only supported under
3777 +Pppd detects that the link it is controlling is connected to the same
3778 +peer as another link using the peer's endpoint discriminator and the
3779 +authenticated identity of the peer (if it authenticates itself). The
3780 +endpoint discriminator is a block of data which is hopefully unique
3781 +for each peer. Several types of data can be used, including
3782 +locally-assigned strings of bytes, IP addresses, MAC addresses,
3783 +randomly strings of bytes, or E\-164 phone numbers. The endpoint
3784 +discriminator sent to the peer by pppd can be set using the endpoint
3787 +In some circumstances the peer may send no endpoint discriminator or a
3788 +non-unique value. The bundle option adds an extra string which is
3789 +added to the peer's endpoint discriminator and authenticated identity
3790 +when matching up links to be joined together in a bundle. The bundle
3791 +option can also be used to allow the establishment of multiple bundles
3792 +between the local system and the peer. Pppd uses a TDB database in
3793 +/var/run/pppd2.tdb to match up links.
3795 +Assuming that multilink is enabled and the peer is willing to
3796 +negotiate multilink, then when pppd is invoked to bring up the first
3797 +link to the peer, it will detect that no other link is connected to
3798 +the peer and create a new bundle, that is, another ppp network
3799 +interface unit. When another pppd is invoked to bring up another link
3800 +to the peer, it will detect the existing bundle and join its link to
3803 +If the first link terminates (for example, because of a hangup or a
3804 +received LCP terminate-request) the bundle is not destroyed unless
3805 +there are no other links remaining in the bundle. Rather than
3806 +exiting, the first pppd keeps running after its link terminates, until
3807 +all the links in the bundle have terminated. If the first pppd
3808 +receives a SIGTERM or SIGINT signal, it will destroy the bundle and
3809 +send a SIGHUP to the pppd processes for each of the links in the
3810 +bundle. If the first pppd receives a SIGHUP signal, it will terminate
3811 +its link but not the bundle.
3813 +Note: demand mode is not currently supported with multilink.
3816 +The following examples assume that the /etc/ppp/options file contains
3817 +the \fIauth\fR option (as in the default /etc/ppp/options file in the
3820 +Probably the most common use of pppd is to dial out to an ISP. This
3821 +can be done with a command such as
3825 +where the /etc/ppp/peers/isp file is set up by the system
3826 +administrator to contain something like this:
3828 +ttyS0 19200 crtscts
3830 +connect '/usr/sbin/chat \-v \-f /etc/ppp/chat\-isp'
3834 +In this example, we are using chat to dial the ISP's modem and go
3835 +through any logon sequence required. The /etc/ppp/chat\-isp file
3836 +contains the script used by chat; it could for example contain
3837 +something like this:
3841 +ABORT "NO DIALTONE"
3849 +ABORT "Username/Password Incorrect"
3857 +"name:" "^Umyuserid"
3859 +"word:" "\\qmypassword"
3865 +See the chat(8) man page for details of chat scripts.
3867 +Pppd can also be used to provide a dial-in ppp service for users. If
3868 +the users already have login accounts, the simplest way to set up the
3869 +ppp service is to let the users log in to their accounts and run pppd
3870 +(installed setuid-root) with a command such as
3874 +To allow a user to use the PPP facilities, you need to allocate an IP
3875 +address for that user's machine and create an entry in
3876 +/etc/ppp/pap\-secrets, /etc/ppp/chap\-secrets, or /etc/ppp/srp\-secrets
3877 +(depending on which authentication method the PPP implementation on
3878 +the user's machine supports), so that the user's machine can
3879 +authenticate itself. For example, if Joe has a machine called
3880 +"joespc" that is to be allowed to dial in to the machine called
3881 +"server" and use the IP address joespc.my.net, you would add an entry
3882 +like this to /etc/ppp/pap\-secrets or /etc/ppp/chap\-secrets:
3884 +joespc server "joe's secret" joespc.my.net
3886 +(See srp\-entry(8) for a means to generate the server's entry when
3887 +SRP\-SHA1 is in use.)
3888 +Alternatively, you can create a username called (for example) "ppp",
3889 +whose login shell is pppd and whose home directory is /etc/ppp.
3890 +Options to be used when pppd is run this way can be put in
3893 +If your serial connection is any more complicated than a piece of
3894 +wire, you may need to arrange for some control characters to be
3895 +escaped. In particular, it is often useful to escape XON (^Q) and
3896 +XOFF (^S), using \fIasyncmap a0000\fR. If the path includes a telnet,
3897 +you probably should escape ^] as well (\fIasyncmap 200a0000\fR). If
3898 +the path includes an rlogin, you will need to use the \fIescape ff\fR
3899 +option on the end which is running the rlogin client, since many
3900 +rlogin implementations are not transparent; they will remove the
3901 +sequence [0xff, 0xff, 0x73, 0x73, followed by any 8 bytes] from the
3905 +Messages are sent to the syslog daemon using facility LOG_DAEMON.
3906 +(This can be overridden by recompiling pppd with the macro
3907 +LOG_PPP defined as the desired facility.) See the syslog(8)
3908 +documentation for details of where the syslog daemon will write the
3909 +messages. On most systems, the syslog daemon uses the
3910 +/etc/syslog.conf file to specify the destination(s) for syslog
3911 +messages. You may need to edit that file to suit.
3913 +The \fIdebug\fR option causes the contents of all control packets sent
3914 +or received to be logged, that is, all LCP, PAP, CHAP, EAP, or IPCP packets.
3915 +This can be useful if the PPP negotiation does not succeed or if
3916 +authentication fails.
3917 +If debugging is enabled at compile time, the \fIdebug\fR option also
3918 +causes other debugging messages to be logged.
3920 +Debugging can also be enabled or disabled by sending a SIGUSR1 signal
3921 +to the pppd process. This signal acts as a toggle.
3923 +The exit status of pppd is set to indicate whether any error was
3924 +detected, or the reason for the link being terminated. The values
3928 +Pppd has detached, or otherwise the connection was successfully
3929 +established and terminated at the peer's request.
3932 +An immediately fatal error of some kind occurred, such as an essential
3933 +system call failing, or running out of virtual memory.
3936 +An error was detected in processing the options given, such as two
3937 +mutually exclusive options being used.
3940 +Pppd is not setuid-root and the invoking user is not root.
3943 +The kernel does not support PPP, for example, the PPP kernel driver is
3944 +not included or cannot be loaded.
3947 +Pppd terminated because it was sent a SIGINT, SIGTERM or SIGHUP
3951 +The serial port could not be locked.
3954 +The serial port could not be opened.
3957 +The connect script failed (returned a non-zero exit status).
3960 +The command specified as the argument to the \fIpty\fR option could
3964 +The PPP negotiation failed, that is, it didn't reach the point where
3965 +at least one network protocol (e.g. IP) was running.
3968 +The peer system failed (or refused) to authenticate itself.
3971 +The link was established successfully and terminated because it was
3975 +The link was established successfully and terminated because the
3976 +connect time limit was reached.
3979 +Callback was negotiated and an incoming call should arrive shortly.
3982 +The link was terminated because the peer is not responding to echo
3986 +The link was terminated by the modem hanging up.
3989 +The PPP negotiation failed because serial loopback was detected.
3992 +The init script failed (returned a non-zero exit status).
3995 +We failed to authenticate ourselves to the peer.
3997 +Pppd invokes scripts at various stages in its processing which can be
3998 +used to perform site-specific ancillary processing. These scripts are
3999 +usually shell scripts, but could be executable code files instead.
4000 +Pppd does not wait for the scripts to finish (except for the ip-pre-up
4001 +script). The scripts are
4002 +executed as root (with the real and effective user-id set to 0), so
4003 +that they can do things such as update routing tables or run
4004 +privileged daemons. Be careful that the contents of these scripts do
4005 +not compromise your system's security. Pppd runs the scripts with
4006 +standard input, output and error redirected to /dev/null, and with an
4007 +environment that is empty except for some environment variables that
4008 +give information about the link. The environment variables that pppd
4012 +The name of the serial tty device being used.
4015 +The name of the network interface being used.
4018 +The IP address for the local end of the link. This is only set when
4022 +The IP address for the remote end of the link. This is only set when
4026 +The authenticated name of the peer. This is only set if the peer
4027 +authenticates itself.
4030 +The baud rate of the tty device.
4033 +The real user-id of the user who invoked pppd.
4036 +The username of the real user-id that invoked pppd. This is always set.
4038 +For the ip-down and auth-down scripts, pppd also sets the following
4039 +variables giving statistics for the connection:
4042 +The number of seconds from when the PPP negotiation started until the
4043 +connection was terminated.
4046 +The number of bytes sent (at the level of the serial port) during the
4050 +The number of bytes received (at the level of the serial port) during
4054 +The logical name of the link, set with the \fIlinkname\fR option.
4057 +If the peer supplies DNS server addresses, this variable is set to the
4058 +first DNS server address supplied.
4061 +If the peer supplies DNS server addresses, this variable is set to the
4062 +second DNS server address supplied.
4064 +Pppd invokes the following scripts, if they exist. It is not an error
4065 +if they don't exist.
4067 +.B /etc/ppp/auth\-up
4068 +A program or script which is executed after the remote system
4069 +successfully authenticates itself. It is executed with the parameters
4071 +\fIinterface\-name peer\-name user\-name tty\-device speed\fR
4073 +Note that this script is not executed if the peer doesn't authenticate
4074 +itself, for example when the \fInoauth\fR option is used.
4076 +.B /etc/ppp/auth\-down
4077 +A program or script which is executed when the link goes down, if
4078 +/etc/ppp/auth\-up was previously executed. It is executed in the same
4079 +manner with the same parameters as /etc/ppp/auth\-up.
4081 +.B /etc/ppp/ip\-pre\-up
4082 +A program or script which is executed just before the ppp network
4083 +interface is brought up. It is executed with the same parameters as
4084 +the ip\-up script (below). At this point the interface exists and has
4085 +IP addresses assigned but is still down. This can be used to
4086 +add firewall rules before any IP traffic can pass through the
4087 +interface. Pppd will wait for this script to finish before bringing
4088 +the interface up, so this script should run quickly.
4091 +A program or script which is executed when the link is available for
4092 +sending and receiving IP packets (that is, IPCP has come up). It is
4093 +executed with the parameters
4095 +\fIinterface\-name tty\-device speed local\-IP\-address
4096 +remote\-IP\-address ipparam\fR
4098 +.B /etc/ppp/ip\-down
4099 +A program or script which is executed when the link is no longer
4100 +available for sending and receiving IP packets. This script can be
4101 +used for undoing the effects of the /etc/ppp/ip\-up and
4102 +/etc/ppp/ip\-pre\-up scripts. It is
4103 +invoked in the same manner and with the same parameters as the ip\-up
4106 +.B /etc/ppp/ipv6\-up
4107 +Like /etc/ppp/ip\-up, except that it is executed when the link is available
4108 +for sending and receiving IPv6 packets. It is executed with the parameters
4110 +\fIinterface\-name tty\-device speed local\-link\-local\-address
4111 +remote\-link\-local\-address ipparam\fR
4113 +.B /etc/ppp/ipv6\-down
4114 +Similar to /etc/ppp/ip\-down, but it is executed when IPv6 packets can no
4115 +longer be transmitted on the link. It is executed with the same parameters
4116 +as the ipv6\-up script.
4118 +.B /etc/ppp/ipx\-up
4119 +A program or script which is executed when the link is available for
4120 +sending and receiving IPX packets (that is, IPXCP has come up). It is
4121 +executed with the parameters
4123 +\fIinterface\-name tty\-device speed network\-number local\-IPX\-node\-address
4124 +remote\-IPX\-node\-address local\-IPX\-routing\-protocol remote\-IPX\-routing\-protocol
4125 +local\-IPX\-router\-name remote\-IPX\-router\-name ipparam pppd\-pid\fR
4127 +The local\-IPX\-routing\-protocol and remote\-IPX\-routing\-protocol field
4128 +may be one of the following:
4130 +NONE to indicate that there is no routing protocol
4132 +RIP to indicate that RIP/SAP should be used
4134 +NLSP to indicate that Novell NLSP should be used
4136 +RIP NLSP to indicate that both RIP/SAP and NLSP should be used
4138 +.B /etc/ppp/ipx\-down
4139 +A program or script which is executed when the link is no longer
4140 +available for sending and receiving IPX packets. This script can be
4141 +used for undoing the effects of the /etc/ppp/ipx\-up script. It is
4142 +invoked in the same manner and with the same parameters as the ipx\-up
4146 +.B /var/run/ppp\fIn\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp\fIn\fB.pid \fR(others)
4147 +Process-ID for pppd process on ppp interface unit \fIn\fR.
4149 +.B /var/run/ppp\-\fIname\fB.pid \fR(BSD or Linux),
4150 +\fB/etc/ppp/ppp\-\fIname\fB.pid \fR(others)
4151 +Process-ID for pppd process for logical link \fIname\fR (see the
4152 +\fIlinkname\fR option).
4154 +.B /var/run/pppd2.tdb
4155 +Database containing information about pppd processes, interfaces and
4156 +links, used for matching links to bundles in multilink operation. May
4157 +be examined by external programs to obtain information about running
4158 +pppd instances, the interfaces and devices they are using, IP address
4160 +.B /etc/ppp/pap\-secrets
4161 +Usernames, passwords and IP addresses for PAP authentication. This
4162 +file should be owned by root and not readable or writable by any other
4163 +user. Pppd will log a warning if this is not the case.
4165 +.B /etc/ppp/chap\-secrets
4166 +Names, secrets and IP addresses for CHAP/MS\-CHAP/MS\-CHAPv2 authentication.
4167 +As for /etc/ppp/pap\-secrets, this file should be owned by root and not
4168 +readable or writable by any other user. Pppd will log a warning if
4169 +this is not the case.
4171 +.B /etc/ppp/srp\-secrets
4172 +Names, secrets, and IP addresses for EAP authentication. As for
4173 +/etc/ppp/pap\-secrets, this file should be owned by root and not
4174 +readable or writable by any other user. Pppd will log a warning if
4175 +this is not the case.
4177 +.B ~/.ppp_pseudonym
4178 +Saved client-side SRP\-SHA1 pseudonym. See the \fIsrp\-use\-pseudonym\fR
4179 +option for details.
4181 +.B /etc/ppp/options
4182 +System default options for pppd, read before user default options or
4183 +command-line options.
4186 +User default options, read before /etc/ppp/options.\fIttyname\fR.
4188 +.B /etc/ppp/options.\fIttyname
4189 +System default options for the serial port being used, read after
4190 +~/.ppprc. In forming the \fIttyname\fR part of this
4191 +filename, an initial /dev/ is stripped from the port name (if
4192 +present), and any slashes in the remaining part are converted to
4196 +A directory containing options files which may contain privileged
4197 +options, even if pppd was invoked by a user other than root. The
4198 +system administrator can create options files in this directory to
4199 +permit non-privileged users to dial out without requiring the peer to
4200 +authenticate, but only to certain trusted peers.
4207 +\fICompressing TCP/IP headers for low-speed serial links.\fR
4212 +.I The MD5 Message-Digest Algorithm.
4217 +.I PPP Internet Protocol Control Protocol (IPCP).
4221 +Lloyd, B.; Simpson, W.A.
4222 +.I PPP authentication protocols.
4227 +.I The Point-to-Point Protocol (PPP).
4232 +.I PPP in HDLC-like Framing.
4236 +Blunk, L.; Vollbrecht, J.,
4237 +.I PPP Extensible Authentication Protocol (EAP).
4242 +.I IP Version 6 over PPP
4247 +.I The SRP Authentication and Key Exchange System
4250 +.B draft\-ietf\-pppext\-eap\-srp\-03.txt
4251 +Carlson, J.; et al.,
4252 +.I EAP SRP\-SHA1 Authentication Protocol.
4255 +Some limited degree of control can be exercised over a running pppd
4256 +process by sending it a signal from the list below.
4259 +These signals cause pppd to terminate the link (by closing LCP),
4260 +restore the serial device settings, and exit. If a connector or
4261 +disconnector process is currently running, pppd will send the same
4262 +signal to its process group, so as to terminate the connector or
4263 +disconnector process.
4266 +This signal causes pppd to terminate the link, restore the serial
4267 +device settings, and close the serial device. If the \fIpersist\fR or
4268 +\fIdemand\fR option has been specified, pppd will try to reopen the
4269 +serial device and start another connection (after the holdoff period).
4270 +Otherwise pppd will exit. If this signal is received during the
4271 +holdoff period, it causes pppd to end the holdoff period immediately.
4272 +If a connector or disconnector process is running, pppd will send the
4273 +same signal to its process group.
4276 +This signal toggles the state of the \fIdebug\fR option.
4279 +This signal causes pppd to renegotiate compression. This can be
4280 +useful to re-enable compression after it has been disabled as a result
4281 +of a fatal decompression error. (Fatal decompression errors generally
4282 +indicate a bug in one or other implementation.)
4285 +Paul Mackerras (paulus@samba.org), based on earlier work by
4294 +Pppd is copyrighted and made available under conditions which provide
4295 +that it may be copied and used in source or binary forms provided that
4296 +the conditions listed below are met. Portions of pppd are covered by
4297 +the following copyright notices:
4299 +Copyright (c) 1984-2000 Carnegie Mellon University. All rights
4302 +Copyright (c) 1993-2004 Paul Mackerras. All rights reserved.
4304 +Copyright (c) 1995 Pedro Roque Marques. All rights reserved.
4306 +Copyright (c) 1995 Eric Rosenquist. All rights reserved.
4308 +Copyright (c) 1999 Tommi Komulainen. All rights reserved.
4310 +Copyright (C) Andrew Tridgell 1999
4312 +Copyright (c) 2000 by Sun Microsystems, Inc. All rights reserved.
4314 +Copyright (c) 2001 by Sun Microsystems, Inc. All rights reserved.
4316 +Copyright (c) 2002 Google, Inc. All rights reserved.
4318 +The copyright notices contain the following statements.
4320 +Redistribution and use in source and binary forms, with or without
4321 +modification, are permitted provided that the following conditions
4324 +1. Redistributions of source code must retain the above copyright
4325 + notice, this list of conditions and the following disclaimer.
4327 +2. Redistributions in binary form must reproduce the above copyright
4328 + notice, this list of conditions and the following disclaimer in
4329 + the documentation and/or other materials provided with the
4332 +3. The name "Carnegie Mellon University" must not be used to
4333 + endorse or promote products derived from this software without
4334 + prior written permission. For permission or any legal
4335 + details, please contact
4337 + Office of Technology Transfer
4339 + Carnegie Mellon University
4341 + 5000 Forbes Avenue
4343 + Pittsburgh, PA 15213-3890
4345 + (412) 268-4387, fax: (412) 268-7395
4347 + tech-transfer@andrew.cmu.edu
4349 +3b. The name(s) of the authors of this software must not be used to
4350 + endorse or promote products derived from this software without
4351 + prior written permission.
4353 +4. Redistributions of any form whatsoever must retain the following
4356 + "This product includes software developed by Computing Services
4357 + at Carnegie Mellon University (http://www.cmu.edu/computing/)."
4359 + "This product includes software developed by Paul Mackerras
4360 + <paulus@samba.org>".
4362 + "This product includes software developed by Pedro Roque Marques
4363 + <pedro_m@yahoo.com>".
4365 + "This product includes software developed by Tommi Komulainen
4366 + <Tommi.Komulainen@iki.fi>".
4368 +CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
4369 +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
4370 +AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
4371 +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
4372 +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
4373 +AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
4374 +OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4376 +THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
4377 +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
4378 +AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
4379 +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
4380 +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
4381 +AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
4382 +OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4383 diff -ruNp ppp-2.4.5/pppd/pppd.h ppp-2.4.5_new/pppd/pppd.h
4384 --- ppp-2.4.5/pppd/pppd.h 2009-11-17 01:26:07.000000000 +0300
4385 +++ ppp-2.4.5_new/pppd/pppd.h 2010-11-24 17:43:52.236670147 +0300
4386 @@ -643,7 +643,7 @@ int sif6addr __P((int, eui64_t, eui64_t
4387 int cif6addr __P((int, eui64_t, eui64_t));
4388 /* Remove an IPv6 address from i/f */
4390 -int sifdefaultroute __P((int, u_int32_t, u_int32_t));
4391 +int sifdefaultroute __P((int, u_int32_t, u_int32_t, bool replace_default_rt));
4392 /* Create default route through i/f */
4393 int cifdefaultroute __P((int, u_int32_t, u_int32_t));
4394 /* Delete default route through i/f */
4395 diff -ruNp ppp-2.4.5/pppd/pppd.h.orig ppp-2.4.5_new/pppd/pppd.h.orig
4396 --- ppp-2.4.5/pppd/pppd.h.orig 1970-01-01 03:00:00.000000000 +0300
4397 +++ ppp-2.4.5_new/pppd/pppd.h.orig 2010-11-24 17:43:05.260003480 +0300
4400 + * pppd.h - PPP daemon global declarations.
4402 + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
4404 + * Redistribution and use in source and binary forms, with or without
4405 + * modification, are permitted provided that the following conditions
4408 + * 1. Redistributions of source code must retain the above copyright
4409 + * notice, this list of conditions and the following disclaimer.
4411 + * 2. Redistributions in binary form must reproduce the above copyright
4412 + * notice, this list of conditions and the following disclaimer in
4413 + * the documentation and/or other materials provided with the
4416 + * 3. The name "Carnegie Mellon University" must not be used to
4417 + * endorse or promote products derived from this software without
4418 + * prior written permission. For permission or any legal
4419 + * details, please contact
4420 + * Office of Technology Transfer
4421 + * Carnegie Mellon University
4422 + * 5000 Forbes Avenue
4423 + * Pittsburgh, PA 15213-3890
4424 + * (412) 268-4387, fax: (412) 268-7395
4425 + * tech-transfer@andrew.cmu.edu
4427 + * 4. Redistributions of any form whatsoever must retain the following
4429 + * "This product includes software developed by Computing Services
4430 + * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
4432 + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
4433 + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
4434 + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
4435 + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
4436 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
4437 + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
4438 + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4440 + * $Id: pppd.h,v 1.96 2008/06/23 11:47:18 paulus Exp $
4450 +#include <stdio.h> /* for FILE */
4451 +#include <limits.h> /* for NGROUPS_MAX */
4452 +#include <sys/param.h> /* for MAXPATHLEN and BSD4_4, if defined */
4453 +#include <sys/types.h> /* for u_int32_t, if defined */
4454 +#include <sys/time.h> /* for struct timeval */
4455 +#include <net/ppp_defs.h>
4456 +#include "patchlevel.h"
4458 +#if defined(__STDC__)
4459 +#include <stdarg.h>
4462 +#include <varargs.h>
4463 +#define __V(x) (va_alist) va_dcl
4476 +#define NUM_PPP 1 /* One PPP interface supported (per process) */
4477 +#define MAXWORDLEN 1024 /* max length of word in file (incl null) */
4478 +#define MAXARGS 1 /* max # args to a command */
4479 +#define MAXNAMELEN 256 /* max length of hostname or name for auth */
4480 +#define MAXSECRETLEN 256 /* max length of password or secret */
4483 + * Option descriptor structure.
4486 +typedef unsigned char bool;
4489 + o_special_noarg = 0,
4499 + char *name; /* name of the option */
4500 + enum opt_type type;
4502 + char *description;
4503 + unsigned int flags;
4507 + const char *source;
4508 + short int priority;
4512 +/* Values for flags */
4513 +#define OPT_VALUE 0xff /* mask for presupplied value */
4514 +#define OPT_HEX 0x100 /* int option is in hex */
4515 +#define OPT_NOARG 0x200 /* option doesn't take argument */
4516 +#define OPT_OR 0x400 /* for u32, OR in argument to value */
4517 +#define OPT_INC 0x400 /* for o_int, increment value */
4518 +#define OPT_A2OR 0x800 /* for o_bool, OR arg to *(u_char *)addr2 */
4519 +#define OPT_PRIV 0x1000 /* privileged option */
4520 +#define OPT_STATIC 0x2000 /* string option goes into static array */
4521 +#define OPT_NOINCR 0x2000 /* for o_int, value mustn't be increased */
4522 +#define OPT_LLIMIT 0x4000 /* check value against lower limit */
4523 +#define OPT_ULIMIT 0x8000 /* check value against upper limit */
4524 +#define OPT_LIMITS (OPT_LLIMIT|OPT_ULIMIT)
4525 +#define OPT_ZEROOK 0x10000 /* 0 value is OK even if not within limits */
4526 +#define OPT_HIDE 0x10000 /* for o_string, print value as ?????? */
4527 +#define OPT_A2LIST 0x20000 /* for o_special, keep list of values */
4528 +#define OPT_A2CLRB 0x20000 /* o_bool, clr val bits in *(u_char *)addr2 */
4529 +#define OPT_ZEROINF 0x40000 /* with OPT_NOINCR, 0 == infinity */
4530 +#define OPT_PRIO 0x80000 /* process option priorities for this option */
4531 +#define OPT_PRIOSUB 0x100000 /* subsidiary member of priority group */
4532 +#define OPT_ALIAS 0x200000 /* option is alias for previous option */
4533 +#define OPT_A2COPY 0x400000 /* addr2 -> second location to rcv value */
4534 +#define OPT_ENABLE 0x800000 /* use *addr2 as enable for option */
4535 +#define OPT_A2CLR 0x1000000 /* clear *(bool *)addr2 */
4536 +#define OPT_PRIVFIX 0x2000000 /* user can't override if set by root */
4537 +#define OPT_INITONLY 0x4000000 /* option can only be set in init phase */
4538 +#define OPT_DEVEQUIV 0x8000000 /* equiv to device name */
4539 +#define OPT_DEVNAM (OPT_INITONLY | OPT_DEVEQUIV)
4540 +#define OPT_A2PRINTER 0x10000000 /* *addr2 is a fn for printing option */
4541 +#define OPT_A2STRVAL 0x20000000 /* *addr2 points to current string value */
4542 +#define OPT_NOPRINT 0x40000000 /* don't print this option at all */
4544 +#define OPT_VAL(x) ((x) & OPT_VALUE)
4546 +/* Values for priority */
4547 +#define OPRIO_DEFAULT 0 /* a default value */
4548 +#define OPRIO_CFGFILE 1 /* value from a configuration file */
4549 +#define OPRIO_CMDLINE 2 /* value from the command line */
4550 +#define OPRIO_SECFILE 3 /* value from options in a secrets file */
4551 +#define OPRIO_ROOT 100 /* added to priority if OPT_PRIVFIX && root */
4553 +#ifndef GIDSET_TYPE
4554 +#define GIDSET_TYPE gid_t
4557 +/* Structure representing a list of permitted IP addresses. */
4558 +struct permitted_ip {
4559 + int permit; /* 1 = permit, 0 = forbid */
4560 + u_int32_t base; /* match if (addr & mask) == base */
4561 + u_int32_t mask; /* base and mask are in network byte order */
4565 + * Unfortunately, the linux kernel driver uses a different structure
4566 + * for statistics from the rest of the ports.
4567 + * This structure serves as a common representation for the bits
4570 +struct pppd_stats {
4571 + unsigned int bytes_in;
4572 + unsigned int bytes_out;
4573 + unsigned int pkts_in;
4574 + unsigned int pkts_out;
4577 +/* Used for storing a sequence of words. Usually malloced. */
4579 + struct wordlist *next;
4583 +/* An endpoint discriminator, used with multilink. */
4584 +#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */
4586 + unsigned char class;
4587 + unsigned char length;
4588 + unsigned char value[MAX_ENDP_LEN];
4591 +/* values for epdisc.class */
4592 +#define EPD_NULL 0 /* null discriminator, no data */
4593 +#define EPD_LOCAL 1
4596 +#define EPD_MAGIC 4
4597 +#define EPD_PHONENUM 5
4599 +typedef void (*notify_func) __P((void *, int));
4602 + struct notifier *next;
4608 + * Global variables.
4611 +extern int hungup; /* Physical layer has disconnected */
4612 +extern int ifunit; /* Interface unit number */
4613 +extern char ifname[]; /* Interface name */
4614 +extern char hostname[]; /* Our hostname */
4615 +extern u_char outpacket_buf[]; /* Buffer for outgoing packets */
4616 +extern int devfd; /* fd of underlying device */
4617 +extern int fd_ppp; /* fd for talking PPP */
4618 +extern int phase; /* Current state of link - see values below */
4619 +extern int baud_rate; /* Current link speed in bits/sec */
4620 +extern char *progname; /* Name of this program */
4621 +extern int redirect_stderr;/* Connector's stderr should go to file */
4622 +extern char peer_authname[];/* Authenticated name of peer */
4623 +extern int auth_done[NUM_PPP]; /* Methods actually used for auth */
4624 +extern int privileged; /* We were run by real-uid root */
4625 +extern int need_holdoff; /* Need holdoff period after link terminates */
4626 +extern char **script_env; /* Environment variables for scripts */
4627 +extern int detached; /* Have detached from controlling tty */
4628 +extern GIDSET_TYPE groups[NGROUPS_MAX]; /* groups the user is in */
4629 +extern int ngroups; /* How many groups valid in groups */
4630 +extern struct pppd_stats link_stats; /* byte/packet counts etc. for link */
4631 +extern int link_stats_valid; /* set if link_stats is valid */
4632 +extern unsigned link_connect_time; /* time the link was up for */
4633 +extern int using_pty; /* using pty as device (notty or pty opt.) */
4634 +extern int log_to_fd; /* logging to this fd as well as syslog */
4635 +extern bool log_default; /* log_to_fd is default (stdout) */
4636 +extern char *no_ppp_msg; /* message to print if ppp not in kernel */
4637 +extern volatile int status; /* exit status for pppd */
4638 +extern bool devnam_fixed; /* can no longer change devnam */
4639 +extern int unsuccess; /* # unsuccessful connection attempts */
4640 +extern int do_callback; /* set if we want to do callback next */
4641 +extern int doing_callback; /* set if this is a callback */
4642 +extern int error_count; /* # of times error() has been called */
4643 +extern char ppp_devnam[MAXPATHLEN];
4644 +extern char remote_number[MAXNAMELEN]; /* Remote telephone number, if avail. */
4645 +extern int ppp_session_number; /* Session number (eg PPPoE session) */
4646 +extern int fd_devnull; /* fd open to /dev/null */
4648 +extern int listen_time; /* time to listen first (ms) */
4649 +extern bool doing_multilink;
4650 +extern bool multilink_master;
4651 +extern bool bundle_eof;
4652 +extern bool bundle_terminating;
4654 +extern struct notifier *pidchange; /* for notifications of pid changing */
4655 +extern struct notifier *phasechange; /* for notifications of phase changes */
4656 +extern struct notifier *exitnotify; /* for notification that we're exiting */
4657 +extern struct notifier *sigreceived; /* notification of received signal */
4658 +extern struct notifier *ip_up_notifier; /* IPCP has come up */
4659 +extern struct notifier *ip_down_notifier; /* IPCP has gone down */
4660 +extern struct notifier *auth_up_notifier; /* peer has authenticated */
4661 +extern struct notifier *link_down_notifier; /* link has gone down */
4662 +extern struct notifier *fork_notifier; /* we are a new child process */
4664 +/* Values for do_callback and doing_callback */
4665 +#define CALLBACK_DIALIN 1 /* we are expecting the call back */
4666 +#define CALLBACK_DIALOUT 2 /* we are dialling out to call back */
4669 + * Variables set by command-line options.
4672 +extern int debug; /* Debug flag */
4673 +extern int kdebugflag; /* Tell kernel to print debug messages */
4674 +extern int default_device; /* Using /dev/tty or equivalent */
4675 +extern char devnam[MAXPATHLEN]; /* Device name */
4676 +extern int crtscts; /* Use hardware flow control */
4677 +extern bool modem; /* Use modem control lines */
4678 +extern int inspeed; /* Input/Output speed requested */
4679 +extern u_int32_t netmask; /* IP netmask to set on interface */
4680 +extern bool lockflag; /* Create lock file to lock the serial dev */
4681 +extern bool nodetach; /* Don't detach from controlling tty */
4682 +extern bool updetach; /* Detach from controlling tty when link up */
4683 +extern char *initializer; /* Script to initialize physical link */
4684 +extern char *connect_script; /* Script to establish physical link */
4685 +extern char *disconnect_script; /* Script to disestablish physical link */
4686 +extern char *welcomer; /* Script to welcome client after connection */
4687 +extern char *ptycommand; /* Command to run on other side of pty */
4688 +extern int maxconnect; /* Maximum connect time (seconds) */
4689 +extern char user[MAXNAMELEN];/* Our name for authenticating ourselves */
4690 +extern char passwd[MAXSECRETLEN]; /* Password for PAP or CHAP */
4691 +extern bool auth_required; /* Peer is required to authenticate */
4692 +extern bool persist; /* Reopen link after it goes down */
4693 +extern bool uselogin; /* Use /etc/passwd for checking PAP */
4694 +extern bool session_mgmt; /* Do session management (login records) */
4695 +extern char our_name[MAXNAMELEN];/* Our name for authentication purposes */
4696 +extern char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
4697 +extern bool explicit_remote;/* remote_name specified with remotename opt */
4698 +extern bool demand; /* Do dial-on-demand */
4699 +extern char *ipparam; /* Extra parameter for ip up/down scripts */
4700 +extern bool cryptpap; /* Others' PAP passwords are encrypted */
4701 +extern int idle_time_limit;/* Shut down link if idle for this long */
4702 +extern int holdoff; /* Dead time before restarting */
4703 +extern bool holdoff_specified; /* true if user gave a holdoff value */
4704 +extern bool notty; /* Stdin/out is not a tty */
4705 +extern char *pty_socket; /* Socket to connect to pty */
4706 +extern char *record_file; /* File to record chars sent/received */
4707 +extern bool sync_serial; /* Device is synchronous serial device */
4708 +extern int maxfail; /* Max # of unsuccessful connection attempts */
4709 +extern char linkname[MAXPATHLEN]; /* logical name for link */
4710 +extern bool tune_kernel; /* May alter kernel settings as necessary */
4711 +extern int connect_delay; /* Time to delay after connect script */
4712 +extern int max_data_rate; /* max bytes/sec through charshunt */
4713 +extern int req_unit; /* interface unit number to use */
4714 +extern bool multilink; /* enable multilink operation */
4715 +extern bool noendpoint; /* don't send or accept endpt. discrim. */
4716 +extern char *bundle_name; /* bundle name for multilink */
4717 +extern bool dump_options; /* print out option values */
4718 +extern bool dryrun; /* check everything, print options, exit */
4719 +extern int child_wait; /* # seconds to wait for children at end */
4722 +extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */
4723 +extern int maxoctets_dir; /* Direction :
4724 + 0 - in+out (default)
4727 + 3 - max(in,out) */
4728 +extern int maxoctets_timeout; /* Timeout for check of octets limit */
4729 +#define PPP_OCTETS_DIRECTION_SUM 0
4730 +#define PPP_OCTETS_DIRECTION_IN 1
4731 +#define PPP_OCTETS_DIRECTION_OUT 2
4732 +#define PPP_OCTETS_DIRECTION_MAXOVERAL 3
4733 +/* same as previos, but little different on RADIUS side */
4734 +#define PPP_OCTETS_DIRECTION_MAXSESSION 4
4738 +extern struct bpf_program pass_filter; /* Filter for pkts to pass */
4739 +extern struct bpf_program active_filter; /* Filter for link-active pkts */
4743 +extern bool ms_lanman; /* Use LanMan password instead of NT */
4744 + /* Has meaning only with MS-CHAP challenges */
4747 +/* Values for auth_pending, auth_done */
4748 +#define PAP_WITHPEER 0x1
4749 +#define PAP_PEER 0x2
4750 +#define CHAP_WITHPEER 0x4
4751 +#define CHAP_PEER 0x8
4752 +#define EAP_WITHPEER 0x10
4753 +#define EAP_PEER 0x20
4755 +/* Values for auth_done only */
4756 +#define CHAP_MD5_WITHPEER 0x40
4757 +#define CHAP_MD5_PEER 0x80
4758 +#define CHAP_MS_SHIFT 8 /* LSB position for MS auths */
4759 +#define CHAP_MS_WITHPEER 0x100
4760 +#define CHAP_MS_PEER 0x200
4761 +#define CHAP_MS2_WITHPEER 0x400
4762 +#define CHAP_MS2_PEER 0x800
4764 +extern char *current_option; /* the name of the option being parsed */
4765 +extern int privileged_option; /* set iff the current option came from root */
4766 +extern char *option_source; /* string saying where the option came from */
4767 +extern int option_priority; /* priority of current options */
4770 + * Values for phase.
4772 +#define PHASE_DEAD 0
4773 +#define PHASE_INITIALIZE 1
4774 +#define PHASE_SERIALCONN 2
4775 +#define PHASE_DORMANT 3
4776 +#define PHASE_ESTABLISH 4
4777 +#define PHASE_AUTHENTICATE 5
4778 +#define PHASE_CALLBACK 6
4779 +#define PHASE_NETWORK 7
4780 +#define PHASE_RUNNING 8
4781 +#define PHASE_TERMINATE 9
4782 +#define PHASE_DISCONNECT 10
4783 +#define PHASE_HOLDOFF 11
4784 +#define PHASE_MASTER 12
4787 + * The following struct gives the addresses of procedures to call
4788 + * for a particular protocol.
4791 + u_short protocol; /* PPP protocol number */
4792 + /* Initialization procedure */
4793 + void (*init) __P((int unit));
4794 + /* Process a received packet */
4795 + void (*input) __P((int unit, u_char *pkt, int len));
4796 + /* Process a received protocol-reject */
4797 + void (*protrej) __P((int unit));
4798 + /* Lower layer has come up */
4799 + void (*lowerup) __P((int unit));
4800 + /* Lower layer has gone down */
4801 + void (*lowerdown) __P((int unit));
4802 + /* Open the protocol */
4803 + void (*open) __P((int unit));
4804 + /* Close the protocol */
4805 + void (*close) __P((int unit, char *reason));
4806 + /* Print a packet in readable form */
4807 + int (*printpkt) __P((u_char *pkt, int len,
4808 + void (*printer) __P((void *, char *, ...)),
4810 + /* Process a received data packet */
4811 + void (*datainput) __P((int unit, u_char *pkt, int len));
4812 + bool enabled_flag; /* 0 iff protocol is disabled */
4813 + char *name; /* Text name of protocol */
4814 + char *data_name; /* Text name of corresponding data protocol */
4815 + option_t *options; /* List of command-line options */
4816 + /* Check requested options, assign defaults */
4817 + void (*check_options) __P((void));
4818 + /* Configure interface for demand-dial */
4819 + int (*demand_conf) __P((int unit));
4820 + /* Say whether to bring up link for this pkt */
4821 + int (*active_pkt) __P((u_char *pkt, int len));
4824 +/* Table of pointers to supported protocols */
4825 +extern struct protent *protocols[];
4828 + * This struct contains pointers to a set of procedures for
4829 + * doing operations on a "channel". A channel provides a way
4830 + * to send and receive PPP packets - the canonical example is
4831 + * a serial port device in PPP line discipline (or equivalently
4832 + * with PPP STREAMS modules pushed onto it).
4835 + /* set of options for this channel */
4836 + option_t *options;
4837 + /* find and process a per-channel options file */
4838 + void (*process_extra_options) __P((void));
4839 + /* check all the options that have been given */
4840 + void (*check_options) __P((void));
4841 + /* get the channel ready to do PPP, return a file descriptor */
4842 + int (*connect) __P((void));
4843 + /* we're finished with the channel */
4844 + void (*disconnect) __P((void));
4845 + /* put the channel into PPP `mode' */
4846 + int (*establish_ppp) __P((int));
4847 + /* take the channel out of PPP `mode', restore loopback if demand */
4848 + void (*disestablish_ppp) __P((int));
4849 + /* set the transmit-side PPP parameters of the channel */
4850 + void (*send_config) __P((int, u_int32_t, int, int));
4851 + /* set the receive-side PPP parameters of the channel */
4852 + void (*recv_config) __P((int, u_int32_t, int, int));
4853 + /* cleanup on error or normal exit */
4854 + void (*cleanup) __P((void));
4855 + /* close the device, called in children after fork */
4856 + void (*close) __P((void));
4859 +extern struct channel *the_channel;
4865 +/* Procedures exported from main.c. */
4866 +void set_ifunit __P((int)); /* set stuff that depends on ifunit */
4867 +void detach __P((void)); /* Detach from controlling tty */
4868 +void die __P((int)); /* Cleanup and exit */
4869 +void quit __P((void)); /* like die(1) */
4870 +void novm __P((char *)); /* Say we ran out of memory, and die */
4871 +void timeout __P((void (*func)(void *), void *arg, int s, int us));
4872 + /* Call func(arg) after s.us seconds */
4873 +void untimeout __P((void (*func)(void *), void *arg));
4874 + /* Cancel call to func(arg) */
4875 +void record_child __P((int, char *, void (*) (void *), void *, int));
4876 +pid_t safe_fork __P((int, int, int)); /* Fork & close stuff in child */
4877 +int device_script __P((char *cmd, int in, int out, int dont_wait));
4878 + /* Run `cmd' with given stdin and stdout */
4879 +pid_t run_program __P((char *prog, char **args, int must_exist,
4880 + void (*done)(void *), void *arg, int wait));
4881 + /* Run program prog with args in child */
4882 +void reopen_log __P((void)); /* (re)open the connection to syslog */
4883 +void print_link_stats __P((void)); /* Print stats, if available */
4884 +void reset_link_stats __P((int)); /* Reset (init) stats when link goes up */
4885 +void update_link_stats __P((int)); /* Get stats at link termination */
4886 +void script_setenv __P((char *, char *, int)); /* set script env var */
4887 +void script_unsetenv __P((char *)); /* unset script env var */
4888 +void new_phase __P((int)); /* signal start of new phase */
4889 +void add_notifier __P((struct notifier **, notify_func, void *));
4890 +void remove_notifier __P((struct notifier **, notify_func, void *));
4891 +void notify __P((struct notifier *, int));
4892 +int ppp_send_config __P((int, int, u_int32_t, int, int));
4893 +int ppp_recv_config __P((int, int, u_int32_t, int, int));
4894 +const char *protocol_name __P((int));
4895 +void remove_pidfiles __P((void));
4896 +void lock_db __P((void));
4897 +void unlock_db __P((void));
4899 +/* Procedures exported from tty.c. */
4900 +void tty_init __P((void));
4902 +/* Procedures exported from utils.c. */
4903 +void log_packet __P((u_char *, int, char *, int));
4904 + /* Format a packet and log it with syslog */
4905 +void print_string __P((char *, int, void (*) (void *, char *, ...),
4906 + void *)); /* Format a string for output */
4907 +int slprintf __P((char *, int, char *, ...)); /* sprintf++ */
4908 +int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */
4909 +size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */
4910 +size_t strlcat __P((char *, const char *, size_t)); /* safe strncpy */
4911 +void dbglog __P((char *, ...)); /* log a debug message */
4912 +void info __P((char *, ...)); /* log an informational message */
4913 +void notice __P((char *, ...)); /* log a notice-level message */
4914 +void warn __P((char *, ...)); /* log a warning message */
4915 +void error __P((char *, ...)); /* log an error message */
4916 +void fatal __P((char *, ...)); /* log an error message and die(1) */
4917 +void init_pr_log __P((const char *, int)); /* initialize for using pr_log */
4918 +void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */
4919 +void end_pr_log __P((void)); /* finish up after using pr_log */
4920 +void dump_packet __P((const char *, u_char *, int));
4921 + /* dump packet to debug log if interesting */
4922 +ssize_t complete_read __P((int, void *, size_t));
4923 + /* read a complete buffer */
4925 +/* Procedures exported from auth.c */
4926 +void link_required __P((int)); /* we are starting to use the link */
4927 +void start_link __P((int)); /* bring the link up now */
4928 +void link_terminated __P((int)); /* we are finished with the link */
4929 +void link_down __P((int)); /* the LCP layer has left the Opened state */
4930 +void upper_layers_down __P((int));/* take all NCPs down */
4931 +void link_established __P((int)); /* the link is up; authenticate now */
4932 +void start_networks __P((int)); /* start all the network control protos */
4933 +void continue_networks __P((int)); /* start network [ip, etc] control protos */
4934 +void np_up __P((int, int)); /* a network protocol has come up */
4935 +void np_down __P((int, int)); /* a network protocol has gone down */
4936 +void np_finished __P((int, int)); /* a network protocol no longer needs link */
4937 +void auth_peer_fail __P((int, int));
4938 + /* peer failed to authenticate itself */
4939 +void auth_peer_success __P((int, int, int, char *, int));
4940 + /* peer successfully authenticated itself */
4941 +void auth_withpeer_fail __P((int, int));
4942 + /* we failed to authenticate ourselves */
4943 +void auth_withpeer_success __P((int, int, int));
4944 + /* we successfully authenticated ourselves */
4945 +void auth_check_options __P((void));
4946 + /* check authentication options supplied */
4947 +void auth_reset __P((int)); /* check what secrets we have */
4948 +int check_passwd __P((int, char *, int, char *, int, char **));
4949 + /* Check peer-supplied username/password */
4950 +int get_secret __P((int, char *, char *, char *, int *, int));
4951 + /* get "secret" for chap */
4952 +int get_srp_secret __P((int unit, char *client, char *server, char *secret,
4954 +int auth_ip_addr __P((int, u_int32_t));
4955 + /* check if IP address is authorized */
4956 +int auth_number __P((void)); /* check if remote number is authorized */
4957 +int bad_ip_adrs __P((u_int32_t));
4958 + /* check if IP address is unreasonable */
4960 +/* Procedures exported from demand.c */
4961 +void demand_conf __P((void)); /* config interface(s) for demand-dial */
4962 +void demand_block __P((void)); /* set all NPs to queue up packets */
4963 +void demand_unblock __P((void)); /* set all NPs to pass packets */
4964 +void demand_discard __P((void)); /* set all NPs to discard packets */
4965 +void demand_rexmit __P((int)); /* retransmit saved frames for an NP */
4966 +int loop_chars __P((unsigned char *, int)); /* process chars from loopback */
4967 +int loop_frame __P((unsigned char *, int)); /* should we bring link up? */
4969 +/* Procedures exported from multilink.c */
4970 +#ifdef HAVE_MULTILINK
4971 +void mp_check_options __P((void)); /* Check multilink-related options */
4972 +int mp_join_bundle __P((void)); /* join our link to an appropriate bundle */
4973 +void mp_exit_bundle __P((void)); /* have disconnected our link from bundle */
4974 +void mp_bundle_terminated __P((void));
4975 +char *epdisc_to_str __P((struct epdisc *)); /* string from endpoint discrim. */
4976 +int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */
4978 +#define mp_bundle_terminated() /* nothing */
4979 +#define mp_exit_bundle() /* nothing */
4980 +#define doing_multilink 0
4981 +#define multilink_master 0
4984 +/* Procedures exported from sys-*.c */
4985 +void sys_init __P((void)); /* Do system-dependent initialization */
4986 +void sys_cleanup __P((void)); /* Restore system state before exiting */
4987 +int sys_check_options __P((void)); /* Check options specified */
4988 +void sys_close __P((void)); /* Clean up in a child before execing */
4989 +int ppp_available __P((void)); /* Test whether ppp kernel support exists */
4990 +int get_pty __P((int *, int *, char *, int)); /* Get pty master/slave */
4991 +int open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */
4992 +int tty_establish_ppp __P((int)); /* Turn serial port into a ppp interface */
4993 +void tty_disestablish_ppp __P((int)); /* Restore port to normal operation */
4994 +void generic_disestablish_ppp __P((int dev_fd)); /* Restore device setting */
4995 +int generic_establish_ppp __P((int dev_fd)); /* Make a ppp interface */
4996 +void make_new_bundle __P((int, int, int, int)); /* Create new bundle */
4997 +int bundle_attach __P((int)); /* Attach link to existing bundle */
4998 +void cfg_bundle __P((int, int, int, int)); /* Configure existing bundle */
4999 +void destroy_bundle __P((void)); /* Tell driver to destroy bundle */
5000 +void clean_check __P((void)); /* Check if line was 8-bit clean */
5001 +void set_up_tty __P((int, int)); /* Set up port's speed, parameters, etc. */
5002 +void restore_tty __P((int)); /* Restore port's original parameters */
5003 +void setdtr __P((int, int)); /* Raise or lower port's DTR line */
5004 +void output __P((int, u_char *, int)); /* Output a PPP packet */
5005 +void wait_input __P((struct timeval *));
5006 + /* Wait for input, with timeout */
5007 +void add_fd __P((int)); /* Add fd to set to wait for */
5008 +void remove_fd __P((int)); /* Remove fd from set to wait for */
5009 +int read_packet __P((u_char *)); /* Read PPP packet */
5010 +int get_loop_output __P((void)); /* Read pkts from loopback */
5011 +void tty_send_config __P((int, u_int32_t, int, int));
5012 + /* Configure i/f transmit parameters */
5013 +void tty_set_xaccm __P((ext_accm));
5014 + /* Set extended transmit ACCM */
5015 +void tty_recv_config __P((int, u_int32_t, int, int));
5016 + /* Configure i/f receive parameters */
5017 +int ccp_test __P((int, u_char *, int, int));
5018 + /* Test support for compression scheme */
5019 +void ccp_flags_set __P((int, int, int));
5020 + /* Set kernel CCP state */
5021 +int ccp_fatal_error __P((int)); /* Test for fatal decomp error in kernel */
5022 +int get_idle_time __P((int, struct ppp_idle *));
5023 + /* Find out how long link has been idle */
5024 +int get_ppp_stats __P((int, struct pppd_stats *));
5025 + /* Return link statistics */
5026 +void netif_set_mtu __P((int, int)); /* Set PPP interface MTU */
5027 +int netif_get_mtu __P((int)); /* Get PPP interface MTU */
5028 +int sifvjcomp __P((int, int, int, int));
5029 + /* Configure VJ TCP header compression */
5030 +int sifup __P((int)); /* Configure i/f up for one protocol */
5031 +int sifnpmode __P((int u, int proto, enum NPmode mode));
5032 + /* Set mode for handling packets for proto */
5033 +int sifdown __P((int)); /* Configure i/f down for one protocol */
5034 +int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t));
5035 + /* Configure IPv4 addresses for i/f */
5036 +int cifaddr __P((int, u_int32_t, u_int32_t));
5037 + /* Reset i/f IP addresses */
5039 +int sif6addr __P((int, eui64_t, eui64_t));
5040 + /* Configure IPv6 addresses for i/f */
5041 +int cif6addr __P((int, eui64_t, eui64_t));
5042 + /* Remove an IPv6 address from i/f */
5044 +int sifdefaultroute __P((int, u_int32_t, u_int32_t));
5045 + /* Create default route through i/f */
5046 +int cifdefaultroute __P((int, u_int32_t, u_int32_t));
5047 + /* Delete default route through i/f */
5048 +int sifproxyarp __P((int, u_int32_t));
5049 + /* Add proxy ARP entry for peer */
5050 +int cifproxyarp __P((int, u_int32_t));
5051 + /* Delete proxy ARP entry for peer */
5052 +u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */
5053 +int lock __P((char *)); /* Create lock file for device */
5054 +int relock __P((int)); /* Rewrite lock file with new pid */
5055 +void unlock __P((void)); /* Delete previously-created lock file */
5056 +void logwtmp __P((const char *, const char *, const char *));
5057 + /* Write entry to wtmp file */
5058 +int get_host_seed __P((void)); /* Get host-dependent random number seed */
5059 +int have_route_to __P((u_int32_t)); /* Check if route to addr exists */
5061 +int set_filters __P((struct bpf_program *pass, struct bpf_program *active));
5062 + /* Set filter programs in kernel */
5065 +int sipxfaddr __P((int, unsigned long, unsigned char *));
5066 +int cipxfaddr __P((int));
5068 +int get_if_hwaddr __P((u_char *addr, char *name));
5069 +char *get_first_ethernet __P((void));
5071 +/* Procedures exported from options.c */
5072 +int setipaddr __P((char *, char **, int)); /* Set local/remote ip addresses */
5073 +int parse_args __P((int argc, char **argv));
5074 + /* Parse options from arguments given */
5075 +int options_from_file __P((char *filename, int must_exist, int check_prot,
5077 + /* Parse options from an options file */
5078 +int options_from_user __P((void)); /* Parse options from user's .ppprc */
5079 +int options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */
5080 +int options_from_list __P((struct wordlist *, int privileged));
5081 + /* Parse options from a wordlist */
5082 +int getword __P((FILE *f, char *word, int *newlinep, char *filename));
5083 + /* Read a word from a file */
5084 +void option_error __P((char *fmt, ...));
5085 + /* Print an error message about an option */
5086 +int int_option __P((char *, int *));
5087 + /* Simplified number_option for decimal ints */
5088 +void add_options __P((option_t *)); /* Add extra options */
5089 +void check_options __P((void)); /* check values after all options parsed */
5090 +int override_value __P((const char *, int, const char *));
5091 + /* override value if permitted by priority */
5092 +void print_options __P((void (*) __P((void *, char *, ...)), void *));
5093 + /* print out values of all options */
5095 +int parse_dotted_ip __P((char *, u_int32_t *));
5098 + * Hooks to enable plugins to change various things.
5100 +extern int (*new_phase_hook) __P((int));
5101 +extern int (*idle_time_hook) __P((struct ppp_idle *));
5102 +extern int (*holdoff_hook) __P((void));
5103 +extern int (*pap_check_hook) __P((void));
5104 +extern int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp,
5105 + struct wordlist **paddrs,
5106 + struct wordlist **popts));
5107 +extern void (*pap_logout_hook) __P((void));
5108 +extern int (*pap_passwd_hook) __P((char *user, char *passwd));
5109 +extern int (*allowed_address_hook) __P((u_int32_t addr));
5110 +extern void (*ip_up_hook) __P((void));
5111 +extern void (*ip_down_hook) __P((void));
5112 +extern void (*ip_choose_hook) __P((u_int32_t *));
5114 +extern int (*chap_check_hook) __P((void));
5115 +extern int (*chap_passwd_hook) __P((char *user, char *passwd));
5116 +extern void (*multilink_join_hook) __P((void));
5118 +/* Let a plugin snoop sent and received packets. Useful for L2TP */
5119 +extern void (*snoop_recv_hook) __P((unsigned char *p, int len));
5120 +extern void (*snoop_send_hook) __P((unsigned char *p, int len));
5123 + * Inline versions of get/put char/short/long.
5124 + * Pointer is advanced; we assume that both arguments
5125 + * are lvalues and will already be in registers.
5126 + * cp MUST be u_char *.
5128 +#define GETCHAR(c, cp) { \
5131 +#define PUTCHAR(c, cp) { \
5132 + *(cp)++ = (u_char) (c); \
5136 +#define GETSHORT(s, cp) { \
5137 + (s) = *(cp)++ << 8; \
5140 +#define PUTSHORT(s, cp) { \
5141 + *(cp)++ = (u_char) ((s) >> 8); \
5142 + *(cp)++ = (u_char) (s); \
5145 +#define GETLONG(l, cp) { \
5146 + (l) = *(cp)++ << 8; \
5147 + (l) |= *(cp)++; (l) <<= 8; \
5148 + (l) |= *(cp)++; (l) <<= 8; \
5151 +#define PUTLONG(l, cp) { \
5152 + *(cp)++ = (u_char) ((l) >> 24); \
5153 + *(cp)++ = (u_char) ((l) >> 16); \
5154 + *(cp)++ = (u_char) ((l) >> 8); \
5155 + *(cp)++ = (u_char) (l); \
5158 +#define INCPTR(n, cp) ((cp) += (n))
5159 +#define DECPTR(n, cp) ((cp) -= (n))
5162 + * System dependent definitions for user-level 4.3BSD UNIX implementation.
5165 +#define TIMEOUT(r, f, t) timeout((r), (f), (t), 0)
5166 +#define UNTIMEOUT(r, f) untimeout((r), (f))
5168 +#define BCOPY(s, d, l) memcpy(d, s, l)
5169 +#define BZERO(s, n) memset(s, 0, n)
5170 +#define BCMP(s1, s2, l) memcmp(s1, s2, l)
5172 +#define PRINTMSG(m, l) { info("Remote message: %0.*v", l, m); }
5175 + * MAKEHEADER - Add Header fields to a packet.
5177 +#define MAKEHEADER(p, t) { \
5178 + PUTCHAR(PPP_ALLSTATIONS, p); \
5179 + PUTCHAR(PPP_UI, p); \
5183 + * Exit status values.
5186 +#define EXIT_FATAL_ERROR 1
5187 +#define EXIT_OPTION_ERROR 2
5188 +#define EXIT_NOT_ROOT 3
5189 +#define EXIT_NO_KERNEL_SUPPORT 4
5190 +#define EXIT_USER_REQUEST 5
5191 +#define EXIT_LOCK_FAILED 6
5192 +#define EXIT_OPEN_FAILED 7
5193 +#define EXIT_CONNECT_FAILED 8
5194 +#define EXIT_PTYCMD_FAILED 9
5195 +#define EXIT_NEGOTIATION_FAILED 10
5196 +#define EXIT_PEER_AUTH_FAILED 11
5197 +#define EXIT_IDLE_TIMEOUT 12
5198 +#define EXIT_CONNECT_TIME 13
5199 +#define EXIT_CALLBACK 14
5200 +#define EXIT_PEER_DEAD 15
5201 +#define EXIT_HANGUP 16
5202 +#define EXIT_LOOPBACK 17
5203 +#define EXIT_INIT_FAILED 18
5204 +#define EXIT_AUTH_TOPEER_FAILED 19
5206 +#define EXIT_TRAFFIC_LIMIT 20
5208 +#define EXIT_CNID_AUTH_FAILED 21
5211 + * Debug macros. Slightly useful for finding bugs in pppd, not particularly
5212 + * useful for finding out why your connection isn't being established.
5215 +#define DEBUGMAIN 1
5218 +#define DEBUGIPCP 1
5219 +#define DEBUGIPV6CP 1
5220 +#define DEBUGUPAP 1
5221 +#define DEBUGCHAP 1
5224 +#ifndef LOG_PPP /* we use LOG_LOCAL2 for syslog by default */
5225 +#if defined(DEBUGMAIN) || defined(DEBUGFSM) || defined(DEBUGSYS) \
5226 + || defined(DEBUGLCP) || defined(DEBUGIPCP) || defined(DEBUGUPAP) \
5227 + || defined(DEBUGCHAP) || defined(DEBUG) || defined(DEBUGIPV6CP)
5228 +#define LOG_PPP LOG_LOCAL2
5230 +#define LOG_PPP LOG_DAEMON
5232 +#endif /* LOG_PPP */
5235 +#define MAINDEBUG(x) if (debug) dbglog x
5237 +#define MAINDEBUG(x)
5241 +#define SYSDEBUG(x) if (debug) dbglog x
5243 +#define SYSDEBUG(x)
5247 +#define FSMDEBUG(x) if (debug) dbglog x
5249 +#define FSMDEBUG(x)
5253 +#define LCPDEBUG(x) if (debug) dbglog x
5255 +#define LCPDEBUG(x)
5259 +#define IPCPDEBUG(x) if (debug) dbglog x
5261 +#define IPCPDEBUG(x)
5265 +#define IPV6CPDEBUG(x) if (debug) dbglog x
5267 +#define IPV6CPDEBUG(x)
5271 +#define UPAPDEBUG(x) if (debug) dbglog x
5273 +#define UPAPDEBUG(x)
5277 +#define CHAPDEBUG(x) if (debug) dbglog x
5279 +#define CHAPDEBUG(x)
5283 +#define IPXCPDEBUG(x) if (debug) dbglog x
5285 +#define IPXCPDEBUG(x)
5289 +#if defined(sun) || defined(SYSV) || defined(POSIX_SOURCE)
5290 +#define SIGTYPE void
5292 +#define SIGTYPE int
5293 +#endif /* defined(sun) || defined(SYSV) || defined(POSIX_SOURCE) */
5294 +#endif /* SIGTYPE */
5297 +#define MIN(a, b) ((a) < (b)? (a): (b))
5300 +#define MAX(a, b) ((a) > (b)? (a): (b))
5304 +#define offsetof(type, member) ((size_t) &((type *)0)->member)
5307 +#endif /* __PPP_H__ */
5308 diff -ruNp ppp-2.4.5/pppd/sys-linux.c ppp-2.4.5_new/pppd/sys-linux.c
5309 --- ppp-2.4.5/pppd/sys-linux.c 2009-11-17 01:26:07.000000000 +0300
5310 +++ ppp-2.4.5_new/pppd/sys-linux.c 2010-11-24 17:43:52.240003480 +0300
5311 @@ -206,6 +206,8 @@ static unsigned char inbuf[512]; /* buff
5313 static int if_is_up; /* Interface has been marked up */
5314 static int have_default_route; /* Gateway for default route added */
5315 +static struct rtentry old_def_rt; /* Old default route */
5316 +static int default_rt_repl_rest; /* replace and restore old default rt */
5317 static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
5318 static char proxy_arp_dev[16]; /* Device for proxy arp entry */
5319 static u_int32_t our_old_addr; /* for detecting address changes */
5320 @@ -1537,6 +1539,9 @@ static int read_route_table(struct rtent
5324 + SET_SA_FAMILY (rt->rt_dst, AF_INET);
5325 + SET_SA_FAMILY (rt->rt_gateway, AF_INET);
5327 SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
5328 SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
5329 SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
5330 @@ -1606,20 +1611,51 @@ int have_route_to(u_int32_t addr)
5331 /********************************************************************
5333 * sifdefaultroute - assign a default route through the address given.
5336 -int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
5338 - struct rtentry rt;
5340 - if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
5341 - if (rt.rt_flags & RTF_GATEWAY)
5342 - error("not replacing existing default route via %I",
5343 - SIN_ADDR(rt.rt_gateway));
5346 + * If the global default_rt_repl_rest flag is set, then this function
5347 + * already replaced the original system defaultroute with some other
5348 + * route and it should just replace the current defaultroute with
5349 + * another one, without saving the current route. Use: demand mode,
5350 + * when pppd sets first a defaultroute it it's temporary ppp0 addresses
5351 + * and then changes the temporary addresses to the addresses for the real
5352 + * ppp connection when it has come up.
5355 +int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
5357 + struct rtentry rt, tmp_rt;
5358 + struct rtentry *del_rt = NULL;
5360 + if (default_rt_repl_rest) {
5361 + /* We have already reclaced the original defaultroute, if we
5362 + are called again, we will delete the current default route
5363 + and set the new default route in this function.
5364 + - this is normally only the case the doing demand: */
5365 + if (defaultroute_exists(&tmp_rt))
5367 + } else if (defaultroute_exists(&old_def_rt) &&
5368 + strcmp(old_def_rt.rt_dev, ifname) != 0) {
5369 + /* We did not yet replace an existing default route, let's
5370 + check if we should save and replace a default route: */
5371 + if (old_def_rt.rt_flags & RTF_GATEWAY) {
5373 + error("not replacing existing default route via %I",
5374 + SIN_ADDR(old_def_rt.rt_gateway));
5377 + /* we need to copy rt_dev because we need it permanent too: */
5378 + char *tmp_dev = malloc(strlen(old_def_rt.rt_dev) + 1);
5379 + strcpy(tmp_dev, old_def_rt.rt_dev);
5380 + old_def_rt.rt_dev = tmp_dev;
5382 + notice("replacing old default route to %s [%I]",
5383 + old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
5384 + default_rt_repl_rest = 1;
5385 + del_rt = &old_def_rt;
5388 error("not replacing existing default route through %s",
5391 + old_def_rt.rt_dev);
5394 memset (&rt, 0, sizeof (rt));
5395 @@ -1634,10 +1670,16 @@ int sifdefaultroute (int unit, u_int32_t
5397 rt.rt_flags = RTF_UP;
5398 if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
5399 - if ( ! ok_error ( errno ))
5400 + if (!ok_error(errno))
5401 error("default route ioctl(SIOCADDRT): %m");
5404 + if (default_rt_repl_rest && del_rt)
5405 + if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
5406 + if (!ok_error(errno))
5407 + error("del old default route ioctl(SIOCDELRT): %m");
5411 have_default_route = 1;
5413 @@ -1668,11 +1710,21 @@ int cifdefaultroute (int unit, u_int32_t
5414 rt.rt_flags = RTF_UP;
5415 if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
5417 - if ( ! ok_error ( errno ))
5418 + if (!ok_error(errno))
5419 error("default route ioctl(SIOCDELRT): %m");
5423 + if (default_rt_repl_rest) {
5424 + notice("restoring old default route to %s [%I]",
5425 + old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
5426 + if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
5427 + if (!ok_error(errno))
5428 + error("restore default route ioctl(SIOCADDRT): %m");
5431 + default_rt_repl_rest = 0;
5436 diff -ruNp ppp-2.4.5/pppd/sys-linux.c.orig ppp-2.4.5_new/pppd/sys-linux.c.orig
5437 --- ppp-2.4.5/pppd/sys-linux.c.orig 1970-01-01 03:00:00.000000000 +0300
5438 +++ ppp-2.4.5_new/pppd/sys-linux.c.orig 2010-11-24 17:43:05.266670147 +0300
5441 + * sys-linux.c - System-dependent procedures for setting up
5442 + * PPP interfaces on Linux systems
5444 + * Copyright (c) 1994-2004 Paul Mackerras. All rights reserved.
5446 + * Redistribution and use in source and binary forms, with or without
5447 + * modification, are permitted provided that the following conditions
5450 + * 1. Redistributions of source code must retain the above copyright
5451 + * notice, this list of conditions and the following disclaimer.
5453 + * 2. The name(s) of the authors of this software must not be used to
5454 + * endorse or promote products derived from this software without
5455 + * prior written permission.
5457 + * 3. Redistributions of any form whatsoever must retain the following
5459 + * "This product includes software developed by Paul Mackerras
5460 + * <paulus@samba.org>".
5462 + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
5463 + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
5464 + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
5465 + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
5466 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
5467 + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
5468 + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5470 + * Derived from main.c and pppd.h, which are:
5472 + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
5474 + * Redistribution and use in source and binary forms, with or without
5475 + * modification, are permitted provided that the following conditions
5478 + * 1. Redistributions of source code must retain the above copyright
5479 + * notice, this list of conditions and the following disclaimer.
5481 + * 2. Redistributions in binary form must reproduce the above copyright
5482 + * notice, this list of conditions and the following disclaimer in
5483 + * the documentation and/or other materials provided with the
5486 + * 3. The name "Carnegie Mellon University" must not be used to
5487 + * endorse or promote products derived from this software without
5488 + * prior written permission. For permission or any legal
5489 + * details, please contact
5490 + * Office of Technology Transfer
5491 + * Carnegie Mellon University
5492 + * 5000 Forbes Avenue
5493 + * Pittsburgh, PA 15213-3890
5494 + * (412) 268-4387, fax: (412) 268-7395
5495 + * tech-transfer@andrew.cmu.edu
5497 + * 4. Redistributions of any form whatsoever must retain the following
5499 + * "This product includes software developed by Computing Services
5500 + * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
5502 + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
5503 + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
5504 + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
5505 + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
5506 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
5507 + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
5508 + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5511 +#include <sys/ioctl.h>
5512 +#include <sys/types.h>
5513 +#include <sys/socket.h>
5514 +#include <sys/time.h>
5515 +#include <sys/errno.h>
5516 +#include <sys/file.h>
5517 +#include <sys/stat.h>
5518 +#include <sys/utsname.h>
5519 +#include <sys/sysmacros.h>
5522 +#include <stdlib.h>
5523 +#include <syslog.h>
5524 +#include <string.h>
5526 +#include <memory.h>
5528 +#include <mntent.h>
5529 +#include <signal.h>
5532 +#include <termios.h>
5533 +#include <unistd.h>
5535 +/* This is in netdevice.h. However, this compile will fail miserably if
5536 + you attempt to include netdevice.h because it has so many references
5537 + to __memcpy functions which it should not attempt to do. So, since I
5538 + really don't use it, but it must be defined, define it now. */
5540 +#ifndef MAX_ADDR_LEN
5541 +#define MAX_ADDR_LEN 7
5545 +#include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
5546 +#include <net/if.h>
5547 +#include <net/if_arp.h>
5548 +#include <net/route.h>
5549 +#include <netinet/if_ether.h>
5551 +#include <linux/types.h>
5552 +#include <linux/if.h>
5553 +#include <linux/if_arp.h>
5554 +#include <linux/route.h>
5555 +#include <linux/if_ether.h>
5557 +#include <netinet/in.h>
5558 +#include <arpa/inet.h>
5560 +#include <linux/ppp_defs.h>
5561 +#include <linux/if_ppp.h>
5569 +#if __GLIBC__ >= 2 && \
5570 + !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
5571 +#include <netipx/ipx.h>
5573 +#include <linux/ipx.h>
5575 +#endif /* IPX_CHANGE */
5578 +#include <pcap-bpf.h>
5579 +#include <linux/filter.h>
5580 +#endif /* PPP_FILTER */
5583 +#include <sys/locks.h>
5587 +#ifndef _LINUX_IN6_H
5589 + * This is in linux/include/net/ipv6.h.
5593 + struct in6_addr ifr6_addr;
5594 + __u32 ifr6_prefixlen;
5595 + unsigned int ifr6_ifindex;
5599 +#define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \
5600 + memset(&sin6.s6_addr, 0, sizeof(struct in6_addr)); \
5601 + sin6.s6_addr16[0] = htons(0xfe80); \
5602 + eui64_copy(eui64, sin6.s6_addr32[2]); \
5607 +/* We can get an EIO error on an ioctl if the modem has hung up */
5608 +#define ok_error(num) ((num)==EIO)
5610 +static int tty_disc = N_TTY; /* The TTY discipline */
5611 +static int ppp_disc = N_PPP; /* The PPP discpline */
5612 +static int initfdflags = -1; /* Initial file descriptor flags for fd */
5613 +static int ppp_fd = -1; /* fd which is set to PPP discipline */
5614 +static int sock_fd = -1; /* socket for doing interface ioctls */
5615 +static int slave_fd = -1; /* pty for old-style demand mode, slave */
5616 +static int master_fd = -1; /* pty for old-style demand mode, master */
5618 +static int sock6_fd = -1;
5622 + * For the old-style kernel driver, this is the same as ppp_fd.
5623 + * For the new-style driver, it is the fd of an instance of /dev/ppp
5624 + * which is attached to the ppp unit and is used for controlling it.
5626 +int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */
5628 +static int chindex; /* channel index (new style driver) */
5630 +static fd_set in_fds; /* set of fds that wait_input waits for */
5631 +static int max_in_fd; /* highest fd set in in_fds */
5633 +static int has_proxy_arp = 0;
5634 +static int driver_version = 0;
5635 +static int driver_modification = 0;
5636 +static int driver_patch = 0;
5637 +static int driver_is_old = 0;
5638 +static int restore_term = 0; /* 1 => we've munged the terminal */
5639 +static struct termios inittermios; /* Initial TTY termios */
5641 +int new_style_driver = 0;
5643 +static char loop_name[20];
5644 +static unsigned char inbuf[512]; /* buffer for chars read from loopback */
5646 +static int if_is_up; /* Interface has been marked up */
5647 +static int have_default_route; /* Gateway for default route added */
5648 +static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */
5649 +static char proxy_arp_dev[16]; /* Device for proxy arp entry */
5650 +static u_int32_t our_old_addr; /* for detecting address changes */
5651 +static int dynaddr_set; /* 1 if ip_dynaddr set */
5652 +static int looped; /* 1 if using loop */
5653 +static int link_mtu; /* mtu for the link (not bundle) */
5655 +static struct utsname utsname; /* for the kernel version */
5656 +static int kernel_version;
5657 +#define KVERSION(j,n,p) ((j)*1000000 + (n)*1000 + (p))
5659 +#define MAX_IFS 100
5661 +#define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
5662 +#define FLAGS_MASK (IFF_UP | IFF_BROADCAST | \
5663 + IFF_POINTOPOINT | IFF_LOOPBACK | IFF_NOARP)
5665 +#define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
5667 +/* Prototypes for procedures local to this file. */
5668 +static int modify_flags(int fd, int clear_bits, int set_bits);
5669 +static int translate_speed (int bps);
5670 +static int baud_rate_of (int speed);
5671 +static void close_route_table (void);
5672 +static int open_route_table (void);
5673 +static int read_route_table (struct rtentry *rt);
5674 +static int defaultroute_exists (struct rtentry *rt);
5675 +static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
5676 + char *name, int namelen);
5677 +static void decode_version (char *buf, int *version, int *mod, int *patch);
5678 +static int set_kdebugflag(int level);
5679 +static int ppp_registered(void);
5680 +static int make_ppp_unit(void);
5682 +extern u_char inpacket_buf[]; /* borrowed from main.c */
5685 + * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
5689 +#define SET_SA_FAMILY(addr, family) \
5690 + memset ((char *) &(addr), '\0', sizeof(addr)); \
5691 + addr.sa_family = (family);
5694 + * Determine if the PPP connection should still be present.
5699 +/* new_fd is the fd of a tty */
5700 +static void set_ppp_fd (int new_fd)
5703 + if (!new_style_driver)
5704 + ppp_dev_fd = new_fd;
5707 +static int still_ppp(void)
5709 + if (new_style_driver)
5710 + return !hungup && ppp_fd >= 0;
5711 + if (!hungup || ppp_fd == slave_fd)
5713 + if (slave_fd >= 0) {
5714 + set_ppp_fd(slave_fd);
5721 + * modify_flags - set and clear flag bits controlling the kernel
5724 +static int modify_flags(int fd, int clear_bits, int set_bits)
5728 + if (ioctl(fd, PPPIOCGFLAGS, &flags) == -1)
5730 + flags = (flags & ~clear_bits) | set_bits;
5731 + if (ioctl(fd, PPPIOCSFLAGS, &flags) == -1)
5738 + error("Failed to set PPP kernel option flags: %m");
5742 +/********************************************************************
5744 + * sys_init - System-dependent initialization.
5747 +void sys_init(void)
5749 + /* Get an internet socket for doing socket ioctls. */
5750 + sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
5752 + fatal("Couldn't create IP socket: %m(%d)", errno);
5755 + sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
5757 + sock6_fd = -errno; /* save errno for later */
5764 +/********************************************************************
5766 + * sys_cleanup - restore any system state we modified before exiting:
5767 + * mark the interface down, delete default route and/or proxy arp entry.
5768 + * This shouldn't call die() because it's called from die().
5771 +void sys_cleanup(void)
5774 + * Take down the device
5781 + * Delete any routes through the device.
5783 + if (have_default_route)
5784 + cifdefaultroute(0, 0, 0);
5786 + if (has_proxy_arp)
5787 + cifproxyarp(0, proxy_arp_addr);
5790 +/********************************************************************
5792 + * sys_close - Clean up in a child process before execing.
5797 + if (new_style_driver && ppp_dev_fd >= 0)
5798 + close(ppp_dev_fd);
5802 + if (sock6_fd >= 0)
5805 + if (slave_fd >= 0)
5807 + if (master_fd >= 0)
5811 +/********************************************************************
5813 + * set_kdebugflag - Define the debugging level for the kernel
5816 +static int set_kdebugflag (int requested_level)
5818 + if (ppp_dev_fd < 0)
5820 + if (ioctl(ppp_dev_fd, PPPIOCSDEBUG, &requested_level) < 0) {
5821 + if ( ! ok_error (errno) )
5822 + error("ioctl(PPPIOCSDEBUG): %m (line %d)", __LINE__);
5828 +/********************************************************************
5830 + * tty_establish_ppp - Turn the serial port into a ppp interface.
5833 +int tty_establish_ppp (int tty_fd)
5838 + * Ensure that the tty device is in exclusive mode.
5840 + if (ioctl(tty_fd, TIOCEXCL, 0) < 0) {
5841 + if ( ! ok_error ( errno ))
5842 + warn("Couldn't make tty exclusive: %m");
5845 + * Demand mode - prime the old ppp device to relinquish the unit.
5847 + if (!new_style_driver && looped
5848 + && ioctl(slave_fd, PPPIOCXFERUNIT, 0) < 0) {
5849 + error("ioctl(transfer ppp unit): %m, line %d", __LINE__);
5853 + * Set the current tty to the PPP discpline
5857 +#define N_SYNC_PPP 14
5859 + ppp_disc = (new_style_driver && sync_serial)? N_SYNC_PPP: N_PPP;
5860 + if (ioctl(tty_fd, TIOCSETD, &ppp_disc) < 0) {
5861 + if ( ! ok_error (errno) ) {
5862 + error("Couldn't set tty to PPP discipline: %m");
5867 + ret_fd = generic_establish_ppp(tty_fd);
5869 +#define SC_RCVB (SC_RCV_B7_0 | SC_RCV_B7_1 | SC_RCV_EVNP | SC_RCV_ODDP)
5870 +#define SC_LOGB (SC_DEBUG | SC_LOG_INPKT | SC_LOG_OUTPKT | SC_LOG_RAWIN \
5873 + if (ret_fd >= 0) {
5874 + modify_flags(ppp_fd, SC_RCVB | SC_LOGB,
5875 + (kdebugflag * SC_DEBUG) & SC_LOGB);
5877 + if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0 && !ok_error(errno))
5878 + warn("Couldn't reset tty to normal line discipline: %m");
5884 +/********************************************************************
5886 + * generic_establish_ppp - Turn the fd into a ppp interface.
5888 +int generic_establish_ppp (int fd)
5892 + if (new_style_driver) {
5895 + /* Open an instance of /dev/ppp and connect the channel to it */
5896 + if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
5897 + error("Couldn't get channel number: %m");
5900 + dbglog("using channel %d", chindex);
5901 + fd = open("/dev/ppp", O_RDWR);
5903 + error("Couldn't reopen /dev/ppp: %m");
5906 + (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
5907 + if (ioctl(fd, PPPIOCATTCHAN, &chindex) < 0) {
5908 + error("Couldn't attach to channel %d: %m", chindex);
5911 + flags = fcntl(fd, F_GETFL);
5912 + if (flags == -1 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
5913 + warn("Couldn't set /dev/ppp (channel) to nonblock: %m");
5918 + if (!looped && !multilink) {
5920 + * Create a new PPP unit.
5922 + if (make_ppp_unit() < 0)
5927 + modify_flags(ppp_dev_fd, SC_LOOP_TRAFFIC, 0);
5930 + add_fd(ppp_dev_fd);
5931 + if (ioctl(fd, PPPIOCCONNECT, &ifunit) < 0) {
5932 + error("Couldn't attach to PPP unit %d: %m", ifunit);
5939 + * Old-style driver: find out which interface we were given.
5942 + if (ioctl(fd, PPPIOCGUNIT, &x) < 0) {
5943 + if (ok_error (errno))
5945 + fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
5947 + /* Check that we got the same unit again. */
5948 + if (looped && x != ifunit)
5949 + fatal("transfer_ppp failed: wanted unit %d, got %d", ifunit, x);
5953 + * Fetch the initial file flags and reset blocking mode on the file.
5955 + initfdflags = fcntl(fd, F_GETFL);
5956 + if (initfdflags == -1 ||
5957 + fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) {
5958 + if ( ! ok_error (errno))
5959 + warn("Couldn't set device to non-blocking mode: %m");
5964 + * Enable debug in the driver if requested.
5967 + set_kdebugflag (kdebugflag);
5979 +/********************************************************************
5981 + * tty_disestablish_ppp - Restore the serial port to normal operation.
5982 + * This shouldn't call die() because it's called from die().
5985 +void tty_disestablish_ppp(int tty_fd)
5989 + * Flush the tty output buffer so that the TIOCSETD doesn't hang.
5991 + if (tcflush(tty_fd, TCIOFLUSH) < 0)
5993 + warn("tcflush failed: %m");
5997 + * Restore the previous line discipline
5999 + if (ioctl(tty_fd, TIOCSETD, &tty_disc) < 0) {
6000 + if ( ! ok_error (errno))
6001 + error("ioctl(TIOCSETD, N_TTY): %m (line %d)", __LINE__);
6004 + if (ioctl(tty_fd, TIOCNXCL, 0) < 0) {
6005 + if ( ! ok_error (errno))
6006 + warn("ioctl(TIOCNXCL): %m (line %d)", __LINE__);
6009 + /* Reset non-blocking mode on fd. */
6010 + if (initfdflags != -1 && fcntl(tty_fd, F_SETFL, initfdflags) < 0) {
6011 + if ( ! ok_error (errno))
6012 + warn("Couldn't restore device fd flags: %m");
6018 + generic_disestablish_ppp(tty_fd);
6021 +/********************************************************************
6023 + * generic_disestablish_ppp - Restore device components to normal
6024 + * operation, and reconnect the ppp unit to the loopback if in demand
6025 + * mode. This shouldn't call die() because it's called from die().
6027 +void generic_disestablish_ppp(int dev_fd)
6029 + if (new_style_driver) {
6033 + modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
6035 + } else if (!doing_multilink && ppp_dev_fd >= 0) {
6036 + close(ppp_dev_fd);
6037 + remove_fd(ppp_dev_fd);
6041 + /* old-style driver */
6043 + set_ppp_fd(slave_fd);
6050 + * make_ppp_unit - make a new ppp unit for ppp_dev_fd.
6051 + * Assumes new_style_driver.
6053 +static int make_ppp_unit()
6057 + if (ppp_dev_fd >= 0) {
6058 + dbglog("in make_ppp_unit, already had /dev/ppp open?");
6059 + close(ppp_dev_fd);
6061 + ppp_dev_fd = open("/dev/ppp", O_RDWR);
6062 + if (ppp_dev_fd < 0)
6063 + fatal("Couldn't open /dev/ppp: %m");
6064 + flags = fcntl(ppp_dev_fd, F_GETFL);
6066 + || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1)
6067 + warn("Couldn't set /dev/ppp to nonblock: %m");
6069 + ifunit = req_unit;
6070 + x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
6071 + if (x < 0 && req_unit >= 0 && errno == EEXIST) {
6072 + warn("Couldn't allocate PPP unit %d as it is already in use", req_unit);
6074 + x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit);
6077 + error("Couldn't create new ppp unit: %m");
6082 + * cfg_bundle - configure the existing bundle.
6083 + * Used in demand mode.
6085 +void cfg_bundle(int mrru, int mtru, int rssn, int tssn)
6087 + if (!new_style_driver)
6090 + /* set the mrru, mtu and flags */
6091 + if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0)
6092 + error("Couldn't set MRRU: %m");
6094 + modify_flags(ppp_dev_fd, SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ|SC_MULTILINK,
6095 + ((rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0)
6096 + | (mrru? SC_MULTILINK: 0)));
6098 + /* connect up the channel */
6099 + if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0)
6100 + fatal("Couldn't attach to PPP unit %d: %m", ifunit);
6101 + add_fd(ppp_dev_fd);
6105 + * make_new_bundle - create a new PPP unit (i.e. a bundle)
6106 + * and connect our channel to it. This should only get called
6107 + * if `multilink' was set at the time establish_ppp was called.
6108 + * In demand mode this uses our existing bundle instead of making
6111 +void make_new_bundle(int mrru, int mtru, int rssn, int tssn)
6113 + if (!new_style_driver)
6116 + /* make us a ppp unit */
6117 + if (make_ppp_unit() < 0)
6120 + /* set the mrru and flags */
6121 + cfg_bundle(mrru, mtru, rssn, tssn);
6125 + * bundle_attach - attach our link to a given PPP unit.
6126 + * We assume the unit is controlled by another pppd.
6128 +int bundle_attach(int ifnum)
6132 + if (!new_style_driver)
6135 + master_fd = open("/dev/ppp", O_RDWR);
6136 + if (master_fd < 0)
6137 + fatal("Couldn't open /dev/ppp: %m");
6138 + if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
6139 + if (errno == ENXIO) {
6141 + return 0; /* doesn't still exist */
6143 + fatal("Couldn't attach to interface unit %d: %m\n", ifnum);
6145 + if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0)
6146 + fatal("Couldn't connect to interface unit %d: %m", ifnum);
6147 + modify_flags(master_fd, 0, SC_MULTILINK);
6155 + * destroy_bundle - tell the driver to destroy our bundle.
6157 +void destroy_bundle(void)
6159 + if (ppp_dev_fd >= 0) {
6160 + close(ppp_dev_fd);
6161 + remove_fd(ppp_dev_fd);
6166 +/********************************************************************
6168 + * clean_check - Fetch the flags for the device and generate
6169 + * appropriate error messages.
6171 +void clean_check(void)
6176 + if (still_ppp()) {
6177 + if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) {
6179 + switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) {
6181 + s = "all had bit 7 set to 1";
6185 + s = "all had bit 7 set to 0";
6189 + s = "all had odd parity";
6193 + s = "all had even parity";
6198 + warn("Receive serial link is not 8-bit clean:");
6199 + warn("Problem: %s", s);
6207 + * List of valid speeds.
6211 + int speed_int, speed_val;
6262 + { 19200, B19200 },
6265 + { 38400, B38400 },
6268 + { 57600, B57600 },
6271 + { 76800, B76800 },
6274 + { 115200, B115200 },
6283 + { 230400, B230400 },
6286 + { 460800, B460800 },
6289 + { 921600, B921600 },
6292 + { 1000000, B1000000 },
6295 + { 1152000, B1152000 },
6298 + { 1500000, B1500000 },
6301 + { 2000000, B2000000 },
6304 + { 2500000, B2500000 },
6307 + { 3000000, B3000000 },
6310 + { 3500000, B3500000 },
6313 + { 4000000, B4000000 },
6318 +/********************************************************************
6320 + * Translate from bits/second to a speed_t.
6323 +static int translate_speed (int bps)
6325 + struct speed *speedp;
6328 + for (speedp = speeds; speedp->speed_int; speedp++) {
6329 + if (bps == speedp->speed_int)
6330 + return speedp->speed_val;
6332 + warn("speed %d not supported", bps);
6337 +/********************************************************************
6339 + * Translate from a speed_t to bits/second.
6342 +static int baud_rate_of (int speed)
6344 + struct speed *speedp;
6347 + for (speedp = speeds; speedp->speed_int; speedp++) {
6348 + if (speed == speedp->speed_val)
6349 + return speedp->speed_int;
6355 +/********************************************************************
6357 + * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
6358 + * at the requested speed, etc. If `local' is true, set CLOCAL
6359 + * regardless of whether the modem option was specified.
6362 +void set_up_tty(int tty_fd, int local)
6365 + struct termios tios;
6367 + setdtr(tty_fd, 1);
6368 + if (tcgetattr(tty_fd, &tios) < 0) {
6369 + if (!ok_error(errno))
6370 + fatal("tcgetattr: %m (line %d)", __LINE__);
6374 + if (!restore_term)
6375 + inittermios = tios;
6377 + tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
6378 + tios.c_cflag |= CS8 | CREAD | HUPCL;
6380 + tios.c_iflag = IGNBRK | IGNPAR;
6383 + tios.c_cc[VMIN] = 1;
6384 + tios.c_cc[VTIME] = 0;
6386 + if (local || !modem)
6387 + tios.c_cflag ^= (CLOCAL | HUPCL);
6389 + switch (crtscts) {
6391 + tios.c_cflag |= CRTSCTS;
6395 + tios.c_iflag |= IXON | IXOFF;
6396 + tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
6397 + tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
6401 + tios.c_cflag &= ~CRTSCTS;
6408 + speed = translate_speed(inspeed);
6410 + cfsetospeed (&tios, speed);
6411 + cfsetispeed (&tios, speed);
6414 + * We can't proceed if the serial port speed is B0,
6415 + * since that implies that the serial port is disabled.
6418 + speed = cfgetospeed(&tios);
6420 + fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
6423 + while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
6424 + if (errno != EINTR)
6425 + fatal("tcsetattr: %m (line %d)", __LINE__);
6427 + baud_rate = baud_rate_of(speed);
6431 +/********************************************************************
6433 + * setdtr - control the DTR line on the serial port.
6434 + * This is called from die(), so it shouldn't call die().
6437 +void setdtr (int tty_fd, int on)
6439 + int modembits = TIOCM_DTR;
6441 + ioctl(tty_fd, (on ? TIOCMBIS : TIOCMBIC), &modembits);
6444 +/********************************************************************
6446 + * restore_tty - restore the terminal to the saved settings.
6449 +void restore_tty (int tty_fd)
6451 + if (restore_term) {
6454 + * Turn off echoing, because otherwise we can get into
6455 + * a loop with the tty and the modem echoing to each other.
6456 + * We presume we are the sole user of this tty device, so
6457 + * when we close it, it will revert to its defaults anyway.
6459 + if (!default_device)
6460 + inittermios.c_lflag &= ~(ECHO | ECHONL);
6462 + if (tcsetattr(tty_fd, TCSAFLUSH, &inittermios) < 0) {
6463 + if (! ok_error (errno))
6464 + warn("tcsetattr: %m (line %d)", __LINE__);
6469 +/********************************************************************
6471 + * output - Output PPP packet.
6474 +void output (int unit, unsigned char *p, int len)
6479 + dump_packet("sent", p, len);
6480 + if (snoop_send_hook) snoop_send_hook(p, len);
6482 + if (len < PPP_HDRLEN)
6484 + if (new_style_driver) {
6487 + proto = (p[0] << 8) + p[1];
6488 + if (ppp_dev_fd >= 0 && !(proto >= 0xc000 || proto == PPP_CCPFRAG))
6491 + if (write(fd, p, len) < 0) {
6492 + if (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS
6493 + || errno == ENXIO || errno == EIO || errno == EINTR)
6494 + warn("write: warning: %m (%d)", errno);
6496 + error("write: %m (%d)", errno);
6500 +/********************************************************************
6502 + * wait_input - wait until there is data available,
6503 + * for the length of time specified by *timo (indefinite
6504 + * if timo is NULL).
6507 +void wait_input(struct timeval *timo)
6509 + fd_set ready, exc;
6514 + n = select(max_in_fd + 1, &ready, NULL, &exc, timo);
6515 + if (n < 0 && errno != EINTR)
6516 + fatal("select: %m");
6520 + * add_fd - add an fd to the set that wait_input waits for.
6522 +void add_fd(int fd)
6524 + if (fd >= FD_SETSIZE)
6525 + fatal("internal error: file descriptor too large (%d)", fd);
6526 + FD_SET(fd, &in_fds);
6527 + if (fd > max_in_fd)
6532 + * remove_fd - remove an fd from the set that wait_input waits for.
6534 +void remove_fd(int fd)
6536 + FD_CLR(fd, &in_fds);
6540 +/********************************************************************
6542 + * read_packet - get a PPP packet from the serial device.
6545 +int read_packet (unsigned char *buf)
6549 + len = PPP_MRU + PPP_HDRLEN;
6550 + if (new_style_driver) {
6551 + *buf++ = PPP_ALLSTATIONS;
6556 + if (ppp_fd >= 0) {
6557 + nr = read(ppp_fd, buf, len);
6558 + if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
6559 + && errno != EIO && errno != EINTR)
6560 + error("read: %m");
6561 + if (nr < 0 && errno == ENXIO)
6564 + if (nr < 0 && new_style_driver && ppp_dev_fd >= 0 && !bundle_eof) {
6565 + /* N.B. we read ppp_fd first since LCP packets come in there. */
6566 + nr = read(ppp_dev_fd, buf, len);
6567 + if (nr < 0 && errno != EWOULDBLOCK && errno != EAGAIN
6568 + && errno != EIO && errno != EINTR)
6569 + error("read /dev/ppp: %m");
6570 + if (nr < 0 && errno == ENXIO)
6572 + if (nr == 0 && doing_multilink) {
6573 + remove_fd(ppp_dev_fd);
6577 + if (new_style_driver && ppp_fd < 0 && ppp_dev_fd < 0)
6579 + return (new_style_driver && nr > 0)? nr+2: nr;
6582 +/********************************************************************
6584 + * get_loop_output - get outgoing packets from the ppp device,
6585 + * and detect when we want to bring the real link up.
6586 + * Return value is 1 if we need to bring up the link, 0 otherwise.
6589 +get_loop_output(void)
6594 + if (new_style_driver) {
6595 + while ((n = read_packet(inpacket_buf)) > 0)
6596 + if (loop_frame(inpacket_buf, n))
6601 + while ((n = read(master_fd, inbuf, sizeof(inbuf))) > 0)
6602 + if (loop_chars(inbuf, n))
6606 + fatal("eof on loopback");
6608 + if (errno != EWOULDBLOCK && errno != EAGAIN)
6609 + fatal("read from loopback: %m(%d)", errno);
6615 + * netif_set_mtu - set the MTU on the PPP network interface.
6618 +netif_set_mtu(int unit, int mtu)
6622 + memset (&ifr, '\0', sizeof (ifr));
6623 + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
6624 + ifr.ifr_mtu = mtu;
6626 + if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0)
6627 + error("ioctl(SIOCSIFMTU): %m (line %d)", __LINE__);
6631 + * netif_get_mtu - get the MTU on the PPP network interface.
6634 +netif_get_mtu(int unit)
6638 + memset (&ifr, '\0', sizeof (ifr));
6639 + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
6641 + if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) {
6642 + error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__);
6645 + return ifr.ifr_mtu;
6648 +/********************************************************************
6650 + * tty_send_config - configure the transmit characteristics of
6651 + * the ppp interface.
6654 +void tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp)
6661 + if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) {
6662 + if (errno != EIO && errno != ENOTTY)
6663 + error("Couldn't set transmit async character map: %m");
6668 + x = (pcomp? SC_COMP_PROT: 0) | (accomp? SC_COMP_AC: 0)
6669 + | (sync_serial? SC_SYNC: 0);
6670 + modify_flags(ppp_fd, SC_COMP_PROT|SC_COMP_AC|SC_SYNC, x);
6673 +/********************************************************************
6675 + * tty_set_xaccm - set the extended transmit ACCM for the interface.
6678 +void tty_set_xaccm (ext_accm accm)
6682 + if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) {
6683 + if ( ! ok_error (errno))
6684 + warn("ioctl(set extended ACCM): %m (line %d)", __LINE__);
6688 +/********************************************************************
6690 + * tty_recv_config - configure the receive-side characteristics of
6691 + * the ppp interface.
6694 +void tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp)
6697 + * If we were called because the link has gone down then there is nothing
6698 + * which may be done. Just return without incident.
6703 + * Set the receiver parameters
6705 + if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) {
6706 + if (errno != EIO && errno != ENOTTY)
6707 + error("Couldn't set channel receive MRU: %m");
6709 + if (new_style_driver && ppp_dev_fd >= 0
6710 + && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0)
6711 + error("Couldn't set MRU in generic PPP layer: %m");
6713 + if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) {
6714 + if (errno != EIO && errno != ENOTTY)
6715 + error("Couldn't set channel receive asyncmap: %m");
6719 +/********************************************************************
6721 + * ccp_test - ask kernel whether a given compression method
6722 + * is acceptable for use.
6726 +ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit)
6728 + struct ppp_option_data data;
6730 + memset (&data, '\0', sizeof (data));
6731 + data.ptr = opt_ptr;
6732 + data.length = opt_len;
6733 + data.transmit = for_transmit;
6735 + if (ioctl(ppp_dev_fd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0)
6738 + return (errno == ENOBUFS)? 0: -1;
6741 +/********************************************************************
6743 + * ccp_flags_set - inform kernel about the current state of CCP.
6746 +void ccp_flags_set (int unit, int isopen, int isup)
6750 + x = (isopen? SC_CCP_OPEN: 0) | (isup? SC_CCP_UP: 0);
6751 + if (still_ppp() && ppp_dev_fd >= 0)
6752 + modify_flags(ppp_dev_fd, SC_CCP_OPEN|SC_CCP_UP, x);
6757 + * set_filters - set the active and pass filters in the kernel driver.
6759 +int set_filters(struct bpf_program *pass, struct bpf_program *active)
6761 + struct sock_fprog fp;
6763 + fp.len = pass->bf_len;
6764 + fp.filter = (struct sock_filter *) pass->bf_insns;
6765 + if (ioctl(ppp_dev_fd, PPPIOCSPASS, &fp) < 0) {
6766 + if (errno == ENOTTY)
6767 + warn("kernel does not support PPP filtering");
6769 + error("Couldn't set pass-filter in kernel: %m");
6772 + fp.len = active->bf_len;
6773 + fp.filter = (struct sock_filter *) active->bf_insns;
6774 + if (ioctl(ppp_dev_fd, PPPIOCSACTIVE, &fp) < 0) {
6775 + error("Couldn't set active-filter in kernel: %m");
6780 +#endif /* PPP_FILTER */
6782 +/********************************************************************
6784 + * get_idle_time - return how long the link has been idle.
6787 +get_idle_time(u, ip)
6789 + struct ppp_idle *ip;
6791 + return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0;
6794 +/********************************************************************
6796 + * get_ppp_stats - return statistics for the link.
6799 +get_ppp_stats(u, stats)
6801 + struct pppd_stats *stats;
6803 + struct ifpppstatsreq req;
6805 + memset (&req, 0, sizeof (req));
6807 + req.stats_ptr = (caddr_t) &req.stats;
6808 + strlcpy(req.ifr__name, ifname, sizeof(req.ifr__name));
6809 + if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) {
6810 + error("Couldn't get PPP statistics: %m");
6813 + stats->bytes_in = req.stats.p.ppp_ibytes;
6814 + stats->bytes_out = req.stats.p.ppp_obytes;
6815 + stats->pkts_in = req.stats.p.ppp_ipackets;
6816 + stats->pkts_out = req.stats.p.ppp_opackets;
6820 +/********************************************************************
6822 + * ccp_fatal_error - returns 1 if decompression was disabled as a
6823 + * result of an error detected after decompression of a packet,
6824 + * 0 otherwise. This is necessary because of patent nonsense.
6827 +int ccp_fatal_error (int unit)
6831 + if (ioctl(ppp_dev_fd, PPPIOCGFLAGS, &flags) < 0) {
6832 + error("Couldn't read compression error flags: %m");
6835 + return flags & SC_DC_FERROR;
6838 +/********************************************************************
6840 + * path_to_procfs - find the path to the proc file system mount point
6842 +static char proc_path[MAXPATHLEN];
6843 +static int proc_path_len;
6845 +static char *path_to_procfs(const char *tail)
6847 + struct mntent *mntent;
6850 + if (proc_path_len == 0) {
6851 + /* Default the mount location of /proc */
6852 + strlcpy (proc_path, "/proc", sizeof(proc_path));
6853 + proc_path_len = 5;
6854 + fp = fopen(MOUNTED, "r");
6856 + while ((mntent = getmntent(fp)) != NULL) {
6857 + if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
6859 + if (strcmp(mntent->mnt_type, "proc") == 0) {
6860 + strlcpy(proc_path, mntent->mnt_dir, sizeof(proc_path));
6861 + proc_path_len = strlen(proc_path);
6869 + strlcpy(proc_path + proc_path_len, tail,
6870 + sizeof(proc_path) - proc_path_len);
6875 + * /proc/net/route parsing stuff.
6877 +#define ROUTE_MAX_COLS 12
6878 +FILE *route_fd = (FILE *) 0;
6879 +static char route_buffer[512];
6880 +static int route_dev_col, route_dest_col, route_gw_col;
6881 +static int route_flags_col, route_mask_col;
6882 +static int route_num_cols;
6884 +static int open_route_table (void);
6885 +static void close_route_table (void);
6886 +static int read_route_table (struct rtentry *rt);
6888 +/********************************************************************
6890 + * close_route_table - close the interface to the route table
6893 +static void close_route_table (void)
6895 + if (route_fd != (FILE *) 0) {
6896 + fclose (route_fd);
6897 + route_fd = (FILE *) 0;
6901 +/********************************************************************
6903 + * open_route_table - open the interface to the route table
6905 +static char route_delims[] = " \t\n";
6907 +static int open_route_table (void)
6911 + close_route_table();
6913 + path = path_to_procfs("/net/route");
6914 + route_fd = fopen (path, "r");
6915 + if (route_fd == NULL) {
6916 + error("can't open routing table %s: %m", path);
6920 + route_dev_col = 0; /* default to usual columns */
6921 + route_dest_col = 1;
6923 + route_flags_col = 3;
6924 + route_mask_col = 7;
6925 + route_num_cols = 8;
6927 + /* parse header line */
6928 + if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) {
6929 + char *p = route_buffer, *q;
6931 + for (col = 0; col < ROUTE_MAX_COLS; ++col) {
6933 + if ((q = strtok(p, route_delims)) == 0)
6935 + if (strcasecmp(q, "iface") == 0)
6936 + route_dev_col = col;
6937 + else if (strcasecmp(q, "destination") == 0)
6938 + route_dest_col = col;
6939 + else if (strcasecmp(q, "gateway") == 0)
6940 + route_gw_col = col;
6941 + else if (strcasecmp(q, "flags") == 0)
6942 + route_flags_col = col;
6943 + else if (strcasecmp(q, "mask") == 0)
6944 + route_mask_col = col;
6947 + if (used && col >= route_num_cols)
6948 + route_num_cols = col + 1;
6956 +/********************************************************************
6958 + * read_route_table - read the next entry from the route table
6961 +static int read_route_table(struct rtentry *rt)
6963 + char *cols[ROUTE_MAX_COLS], *p;
6966 + memset (rt, '\0', sizeof (struct rtentry));
6968 + if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0)
6972 + for (col = 0; col < route_num_cols; ++col) {
6973 + cols[col] = strtok(p, route_delims);
6974 + if (cols[col] == NULL)
6975 + return 0; /* didn't get enough columns */
6979 + SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
6980 + SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
6981 + SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
6983 + rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
6984 + rt->rt_dev = cols[route_dev_col];
6989 +/********************************************************************
6991 + * defaultroute_exists - determine if there is a default route
6994 +static int defaultroute_exists (struct rtentry *rt)
6998 + if (!open_route_table())
7001 + while (read_route_table(rt) != 0) {
7002 + if ((rt->rt_flags & RTF_UP) == 0)
7005 + if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
7007 + if (SIN_ADDR(rt->rt_dst) == 0L) {
7013 + close_route_table();
7018 + * have_route_to - determine if the system has any route to
7019 + * a given IP address. `addr' is in network byte order.
7020 + * Return value is 1 if yes, 0 if no, -1 if don't know.
7021 + * For demand mode to work properly, we have to ignore routes
7022 + * through our own interface.
7024 +int have_route_to(u_int32_t addr)
7026 + struct rtentry rt;
7029 + if (!open_route_table())
7030 + return -1; /* don't know */
7032 + while (read_route_table(&rt)) {
7033 + if ((rt.rt_flags & RTF_UP) == 0 || strcmp(rt.rt_dev, ifname) == 0)
7035 + if ((addr & SIN_ADDR(rt.rt_genmask)) == SIN_ADDR(rt.rt_dst)) {
7041 + close_route_table();
7045 +/********************************************************************
7047 + * sifdefaultroute - assign a default route through the address given.
7050 +int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
7052 + struct rtentry rt;
7054 + if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
7055 + if (rt.rt_flags & RTF_GATEWAY)
7056 + error("not replacing existing default route via %I",
7057 + SIN_ADDR(rt.rt_gateway));
7059 + error("not replacing existing default route through %s",
7064 + memset (&rt, 0, sizeof (rt));
7065 + SET_SA_FAMILY (rt.rt_dst, AF_INET);
7067 + rt.rt_dev = ifname;
7069 + if (kernel_version > KVERSION(2,1,0)) {
7070 + SET_SA_FAMILY (rt.rt_genmask, AF_INET);
7071 + SIN_ADDR(rt.rt_genmask) = 0L;
7074 + rt.rt_flags = RTF_UP;
7075 + if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
7076 + if ( ! ok_error ( errno ))
7077 + error("default route ioctl(SIOCADDRT): %m");
7081 + have_default_route = 1;
7085 +/********************************************************************
7087 + * cifdefaultroute - delete a default route through the address given.
7090 +int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
7092 + struct rtentry rt;
7094 + have_default_route = 0;
7096 + memset (&rt, '\0', sizeof (rt));
7097 + SET_SA_FAMILY (rt.rt_dst, AF_INET);
7098 + SET_SA_FAMILY (rt.rt_gateway, AF_INET);
7100 + rt.rt_dev = ifname;
7102 + if (kernel_version > KVERSION(2,1,0)) {
7103 + SET_SA_FAMILY (rt.rt_genmask, AF_INET);
7104 + SIN_ADDR(rt.rt_genmask) = 0L;
7107 + rt.rt_flags = RTF_UP;
7108 + if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
7109 + if (still_ppp()) {
7110 + if ( ! ok_error ( errno ))
7111 + error("default route ioctl(SIOCDELRT): %m");
7119 +/********************************************************************
7121 + * sifproxyarp - Make a proxy ARP entry for the peer.
7124 +int sifproxyarp (int unit, u_int32_t his_adr)
7126 + struct arpreq arpreq;
7129 + if (has_proxy_arp == 0) {
7130 + memset (&arpreq, '\0', sizeof(arpreq));
7132 + SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
7133 + SIN_ADDR(arpreq.arp_pa) = his_adr;
7134 + arpreq.arp_flags = ATF_PERM | ATF_PUBL;
7136 + * Get the hardware address of an interface on the same subnet
7137 + * as our local address.
7139 + if (!get_ether_addr(his_adr, &arpreq.arp_ha, proxy_arp_dev,
7140 + sizeof(proxy_arp_dev))) {
7141 + error("Cannot determine ethernet address for proxy ARP");
7144 + strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
7146 + if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) {
7147 + if ( ! ok_error ( errno ))
7148 + error("ioctl(SIOCSARP): %m");
7151 + proxy_arp_addr = his_adr;
7152 + has_proxy_arp = 1;
7154 + if (tune_kernel) {
7155 + forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
7156 + if (forw_path != 0) {
7157 + int fd = open(forw_path, O_WRONLY);
7159 + if (write(fd, "1", 1) != 1)
7160 + error("Couldn't enable IP forwarding: %m");
7170 +/********************************************************************
7172 + * cifproxyarp - Delete the proxy ARP entry for the peer.
7175 +int cifproxyarp (int unit, u_int32_t his_adr)
7177 + struct arpreq arpreq;
7179 + if (has_proxy_arp) {
7180 + has_proxy_arp = 0;
7181 + memset (&arpreq, '\0', sizeof(arpreq));
7182 + SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
7183 + SIN_ADDR(arpreq.arp_pa) = his_adr;
7184 + arpreq.arp_flags = ATF_PERM | ATF_PUBL;
7185 + strlcpy(arpreq.arp_dev, proxy_arp_dev, sizeof(arpreq.arp_dev));
7187 + if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) {
7188 + if ( ! ok_error ( errno ))
7189 + warn("ioctl(SIOCDARP): %m");
7196 +/********************************************************************
7198 + * get_ether_addr - get the hardware address of an interface on the
7199 + * the same subnet as ipaddr.
7202 +static int get_ether_addr (u_int32_t ipaddr,
7203 + struct sockaddr *hwaddr,
7204 + char *name, int namelen)
7206 + struct ifreq *ifr, *ifend;
7207 + u_int32_t ina, mask;
7209 + struct ifreq ifreq, bestifreq;
7210 + struct ifconf ifc;
7211 + struct ifreq ifs[MAX_IFS];
7213 + u_int32_t bestmask=0;
7214 + int found_interface = 0;
7216 + ifc.ifc_len = sizeof(ifs);
7217 + ifc.ifc_req = ifs;
7218 + if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
7219 + if ( ! ok_error ( errno ))
7220 + error("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
7225 + * Scan through looking for an interface with an Internet
7226 + * address on the same subnet as `ipaddr'.
7228 + ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
7229 + for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
7230 + if (ifr->ifr_addr.sa_family == AF_INET) {
7231 + ina = SIN_ADDR(ifr->ifr_addr);
7232 + strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
7234 + * Check that the interface is up, and not point-to-point
7237 + if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
7240 + if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
7243 + * Get its netmask and check that it's on the right subnet.
7245 + if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
7248 + mask = SIN_ADDR(ifreq.ifr_addr);
7250 + if (((ipaddr ^ ina) & mask) != 0)
7251 + continue; /* no match */
7253 + if (mask >= bestmask) {
7254 + /* Compare using >= instead of > -- it is possible for
7255 + an interface to have a netmask of 0.0.0.0 */
7256 + found_interface = 1;
7257 + bestifreq = ifreq;
7263 + if (!found_interface) return 0;
7265 + strlcpy(name, bestifreq.ifr_name, namelen);
7267 + /* trim off the :1 in eth0:1 */
7268 + aliasp = strchr(name, ':');
7272 + info("found interface %s for proxy arp", name);
7274 + * Now get the hardware address.
7276 + memset (&bestifreq.ifr_hwaddr, 0, sizeof (struct sockaddr));
7277 + if (ioctl (sock_fd, SIOCGIFHWADDR, &bestifreq) < 0) {
7278 + error("SIOCGIFHWADDR(%s): %m", bestifreq.ifr_name);
7283 + &bestifreq.ifr_hwaddr,
7284 + sizeof (struct sockaddr));
7290 + * get_if_hwaddr - get the hardware address for the specified
7291 + * network interface device.
7294 +get_if_hwaddr(u_char *addr, char *name)
7296 + struct ifreq ifreq;
7299 + sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
7302 + memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
7303 + strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
7304 + ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
7307 + memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6);
7312 + * get_first_ethernet - return the name of the first ethernet-style
7313 + * interface on this system.
7316 +get_first_ethernet()
7321 +/********************************************************************
7323 + * Return user specified netmask, modified by any mask we might determine
7324 + * for address `addr' (in network byte order).
7325 + * Here we scan through the system's list of interfaces, looking for
7326 + * any non-point-to-point interfaces which might appear to be on the same
7327 + * network as `addr'. If we find any, we OR in their netmask to the
7328 + * user-specified netmask.
7331 +u_int32_t GetMask (u_int32_t addr)
7333 + u_int32_t mask, nmask, ina;
7334 + struct ifreq *ifr, *ifend, ifreq;
7335 + struct ifconf ifc;
7336 + struct ifreq ifs[MAX_IFS];
7338 + addr = ntohl(addr);
7340 + if (IN_CLASSA(addr)) /* determine network mask for address class */
7341 + nmask = IN_CLASSA_NET;
7342 + else if (IN_CLASSB(addr))
7343 + nmask = IN_CLASSB_NET;
7345 + nmask = IN_CLASSC_NET;
7347 + /* class D nets are disallowed by bad_ip_adrs */
7348 + mask = netmask | htonl(nmask);
7350 + * Scan through the system's network interfaces.
7352 + ifc.ifc_len = sizeof(ifs);
7353 + ifc.ifc_req = ifs;
7354 + if (ioctl(sock_fd, SIOCGIFCONF, &ifc) < 0) {
7355 + if ( ! ok_error ( errno ))
7356 + warn("ioctl(SIOCGIFCONF): %m (line %d)", __LINE__);
7360 + ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
7361 + for (ifr = ifc.ifc_req; ifr < ifend; ifr++) {
7363 + * Check the interface's internet address.
7365 + if (ifr->ifr_addr.sa_family != AF_INET)
7367 + ina = SIN_ADDR(ifr->ifr_addr);
7368 + if (((ntohl(ina) ^ addr) & nmask) != 0)
7371 + * Check that the interface is up, and not point-to-point nor loopback.
7373 + strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
7374 + if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0)
7377 + if (((ifreq.ifr_flags ^ FLAGS_GOOD) & FLAGS_MASK) != 0)
7380 + * Get its netmask and OR it into our mask.
7382 + if (ioctl(sock_fd, SIOCGIFNETMASK, &ifreq) < 0)
7384 + mask |= SIN_ADDR(ifreq.ifr_addr);
7390 +/********************************************************************
7392 + * Internal routine to decode the version.modification.patch level
7395 +static void decode_version (char *buf, int *version,
7396 + int *modification, int *patch)
7400 + *version = (int) strtoul (buf, &endp, 10);
7401 + *modification = 0;
7404 + if (endp != buf && *endp == '.') {
7406 + *modification = (int) strtoul (buf, &endp, 10);
7407 + if (endp != buf && *endp == '.') {
7409 + *patch = (int) strtoul (buf, &buf, 10);
7414 +/********************************************************************
7416 + * Procedure to determine if the PPP line discipline is registered.
7420 +ppp_registered(void)
7428 + * We used to open the serial device and set it to the ppp line
7429 + * discipline here, in order to create a ppp unit. But that is
7430 + * not a good idea - the user might have specified a device that
7431 + * they can't open (permission, or maybe it doesn't really exist).
7432 + * So we grab a pty master/slave pair and use that.
7434 + if (!get_pty(&mfd, &local_fd, slave, 0)) {
7435 + no_ppp_msg = "Couldn't determine if PPP is supported (no free ptys)";
7440 + * Try to put the device into the PPP discipline.
7442 + if (ioctl(local_fd, TIOCSETD, &ppp_disc) < 0) {
7443 + error("ioctl(TIOCSETD(PPP)): %m (line %d)", __LINE__);
7452 +/********************************************************************
7454 + * ppp_available - check whether the system has any ppp interfaces
7455 + * (in fact we check whether we can do an ioctl on ppp0).
7458 +int ppp_available(void)
7460 + int s, ok, fd, err;
7463 + int my_version, my_modification, my_patch;
7464 + int osmaj, osmin, ospatch;
7466 + /* get the kernel version now, since we are called before sys_init */
7468 + osmaj = osmin = ospatch = 0;
7469 + sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
7470 + kernel_version = KVERSION(osmaj, osmin, ospatch);
7472 + fd = open("/dev/ppp", O_RDWR);
7474 + new_style_driver = 1;
7476 + /* XXX should get from driver */
7477 + driver_version = 2;
7478 + driver_modification = 4;
7485 + if (kernel_version >= KVERSION(2,3,13)) {
7486 + error("Couldn't open the /dev/ppp device: %m");
7487 + if (errno == ENOENT)
7489 + "You need to create the /dev/ppp device node by\n"
7490 + "executing the following command as root:\n"
7491 + " mknod /dev/ppp c 108 0\n";
7492 + else if (errno == ENODEV || errno == ENXIO)
7494 + "Please load the ppp_generic kernel module.\n";
7498 + /* we are running on a really really old kernel */
7500 + "This system lacks kernel support for PPP. This could be because\n"
7501 + "the PPP kernel module could not be loaded, or because PPP was not\n"
7502 + "included in the kernel configuration. If PPP was included as a\n"
7503 + "module, try `/sbin/modprobe -v ppp'. If that fails, check that\n"
7504 + "ppp.o exists in /lib/modules/`uname -r`/net.\n"
7505 + "See README.linux file in the ppp distribution for more details.\n";
7508 + * Open a socket for doing the ioctl operations.
7510 + s = socket(AF_INET, SOCK_DGRAM, 0);
7514 + strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
7515 + ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
7517 + * If the device did not exist then attempt to create one by putting the
7518 + * current tty into the PPP discipline. If this works then obtain the
7519 + * flags for the device again.
7522 + if (ppp_registered()) {
7523 + strlcpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
7524 + ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
7528 + * Ensure that the hardware address is for PPP and not something else
7531 + ok = ioctl (s, SIOCGIFHWADDR, (caddr_t) &ifr) >= 0;
7533 + if (ok && ((ifr.ifr_hwaddr.sa_family & ~0xFF) != ARPHRD_PPP))
7537 + * This is the PPP device. Validate the version of the driver at this
7538 + * point to ensure that this program will work with the driver.
7541 + char abBuffer [1024];
7543 + ifr.ifr_data = abBuffer;
7544 + size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr);
7546 + error("Couldn't read driver version: %m");
7548 + no_ppp_msg = "Sorry, couldn't verify kernel driver version\n";
7551 + decode_version(abBuffer,
7553 + &driver_modification,
7556 + * Validate the version of the driver against the version that we used.
7558 + decode_version(VERSION,
7563 + /* The version numbers must match */
7564 + if (driver_version != my_version)
7567 + /* The modification levels must be legal */
7568 + if (driver_modification < 3) {
7569 + if (driver_modification >= 2) {
7570 + /* we can cope with 2.2.0 and above */
7571 + driver_is_old = 1;
7579 + slprintf(route_buffer, sizeof(route_buffer),
7580 + "Sorry - PPP driver version %d.%d.%d is out of date\n",
7581 + driver_version, driver_modification, driver_patch);
7583 + no_ppp_msg = route_buffer;
7590 +/********************************************************************
7592 + * Update the wtmp file with the appropriate user name and tty device.
7595 +void logwtmp (const char *line, const char *name, const char *host)
7597 + struct utmp ut, *utp;
7598 + pid_t mypid = getpid();
7604 + * Update the signon database for users.
7605 + * Christoph Lameter: Copied from poeigl-1.36 Jan 3, 1996
7607 + utmpname(_PATH_UTMP);
7609 + while ((utp = getutent()) && (utp->ut_pid != mypid))
7613 + memcpy(&ut, utp, sizeof(ut));
7615 + /* some gettys/telnetds don't initialize utmp... */
7616 + memset(&ut, 0, sizeof(ut));
7618 + if (ut.ut_id[0] == 0)
7619 + strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id));
7621 + strncpy(ut.ut_user, name, sizeof(ut.ut_user));
7622 + strncpy(ut.ut_line, line, sizeof(ut.ut_line));
7624 + time(&ut.ut_time);
7626 + ut.ut_type = USER_PROCESS;
7627 + ut.ut_pid = mypid;
7629 + /* Insert the host name if one is supplied */
7631 + strncpy (ut.ut_host, host, sizeof(ut.ut_host));
7633 + /* Insert the IP address of the remote system if IP is enabled */
7634 + if (ipcp_protent.enabled_flag && ipcp_hisoptions[0].neg_addr)
7635 + memcpy(&ut.ut_addr, (char *) &ipcp_hisoptions[0].hisaddr,
7636 + sizeof(ut.ut_addr));
7638 + /* CL: Makes sure that the logout works */
7639 + if (*host == 0 && *name==0)
7645 + * Update the wtmp file.
7648 + updwtmp(_PATH_WTMP, &ut);
7650 + wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY);
7652 + flock(wtmp, LOCK_EX);
7654 + if (write (wtmp, (char *)&ut, sizeof(ut)) != sizeof(ut))
7655 + warn("error writing %s: %m", _PATH_WTMP);
7657 + flock(wtmp, LOCK_UN);
7665 +/********************************************************************
7667 + * sifvjcomp - config tcp header compression
7670 +int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
7675 + if (ioctl(ppp_dev_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0)
7676 + error("Couldn't set up TCP header compression: %m");
7680 + x = (vjcomp? SC_COMP_TCP: 0) | (cidcomp? 0: SC_NO_TCP_CCID);
7681 + modify_flags(ppp_dev_fd, SC_COMP_TCP|SC_NO_TCP_CCID, x);
7686 +/********************************************************************
7688 + * sifup - Config the interface up and enable IP packets to pass.
7695 + memset (&ifr, '\0', sizeof (ifr));
7696 + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
7697 + if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
7698 + if (! ok_error (errno))
7699 + error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
7703 + ifr.ifr_flags |= (IFF_UP | IFF_POINTOPOINT);
7704 + if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
7705 + if (! ok_error (errno))
7706 + error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
7714 +/********************************************************************
7716 + * sifdown - Disable the indicated protocol and config the interface
7717 + * down if there are no remaining protocols.
7720 +int sifdown (int u)
7724 + if (if_is_up && --if_is_up > 0)
7727 + memset (&ifr, '\0', sizeof (ifr));
7728 + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
7729 + if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
7730 + if (! ok_error (errno))
7731 + error("ioctl (SIOCGIFFLAGS): %m (line %d)", __LINE__);
7735 + ifr.ifr_flags &= ~IFF_UP;
7736 + ifr.ifr_flags |= IFF_POINTOPOINT;
7737 + if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
7738 + if (! ok_error (errno))
7739 + error("ioctl(SIOCSIFFLAGS): %m (line %d)", __LINE__);
7745 +/********************************************************************
7747 + * sifaddr - Config the interface IP addresses and netmask.
7750 +int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
7751 + u_int32_t net_mask)
7754 + struct rtentry rt;
7756 + memset (&ifr, '\0', sizeof (ifr));
7757 + memset (&rt, '\0', sizeof (rt));
7759 + SET_SA_FAMILY (ifr.ifr_addr, AF_INET);
7760 + SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET);
7761 + SET_SA_FAMILY (ifr.ifr_netmask, AF_INET);
7763 + strlcpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
7765 + * Set our IP address
7767 + SIN_ADDR(ifr.ifr_addr) = our_adr;
7768 + if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
7769 + if (errno != EEXIST) {
7770 + if (! ok_error (errno))
7771 + error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
7774 + warn("ioctl(SIOCSIFADDR): Address already exists");
7779 + * Set the gateway address
7781 + if (his_adr != 0) {
7782 + SIN_ADDR(ifr.ifr_dstaddr) = his_adr;
7783 + if (ioctl(sock_fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
7784 + if (! ok_error (errno))
7785 + error("ioctl(SIOCSIFDSTADDR): %m (line %d)", __LINE__);
7790 + * Set the netmask.
7791 + * For recent kernels, force the netmask to 255.255.255.255.
7793 + if (kernel_version >= KVERSION(2,1,16))
7795 + if (net_mask != 0) {
7796 + SIN_ADDR(ifr.ifr_netmask) = net_mask;
7797 + if (ioctl(sock_fd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) {
7798 + if (! ok_error (errno))
7799 + error("ioctl(SIOCSIFNETMASK): %m (line %d)", __LINE__);
7804 + * Add the device route
7806 + if (kernel_version < KVERSION(2,1,16)) {
7807 + SET_SA_FAMILY (rt.rt_dst, AF_INET);
7808 + SET_SA_FAMILY (rt.rt_gateway, AF_INET);
7809 + rt.rt_dev = ifname;
7811 + SIN_ADDR(rt.rt_gateway) = 0L;
7812 + SIN_ADDR(rt.rt_dst) = his_adr;
7813 + rt.rt_flags = RTF_UP | RTF_HOST;
7815 + if (kernel_version > KVERSION(2,1,0)) {
7816 + SET_SA_FAMILY (rt.rt_genmask, AF_INET);
7817 + SIN_ADDR(rt.rt_genmask) = -1L;
7820 + if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
7821 + if (! ok_error (errno))
7822 + error("ioctl(SIOCADDRT) device route: %m (line %d)", __LINE__);
7827 + /* set ip_dynaddr in demand mode if address changes */
7828 + if (demand && tune_kernel && !dynaddr_set
7829 + && our_old_addr && our_old_addr != our_adr) {
7830 + /* set ip_dynaddr if possible */
7834 + path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
7835 + if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
7836 + if (write(fd, "1", 1) != 1)
7837 + error("Couldn't enable dynamic IP addressing: %m");
7840 + dynaddr_set = 1; /* only 1 attempt */
7847 +/********************************************************************
7849 + * cifaddr - Clear the interface IP addresses, and delete routes
7850 + * through the interface if possible.
7853 +int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
7857 + if (kernel_version < KVERSION(2,1,16)) {
7859 + * Delete the route through the device
7861 + struct rtentry rt;
7862 + memset (&rt, '\0', sizeof (rt));
7864 + SET_SA_FAMILY (rt.rt_dst, AF_INET);
7865 + SET_SA_FAMILY (rt.rt_gateway, AF_INET);
7866 + rt.rt_dev = ifname;
7868 + SIN_ADDR(rt.rt_gateway) = 0;
7869 + SIN_ADDR(rt.rt_dst) = his_adr;
7870 + rt.rt_flags = RTF_UP | RTF_HOST;
7872 + if (kernel_version > KVERSION(2,1,0)) {
7873 + SET_SA_FAMILY (rt.rt_genmask, AF_INET);
7874 + SIN_ADDR(rt.rt_genmask) = -1L;
7877 + if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
7878 + if (still_ppp() && ! ok_error (errno))
7879 + error("ioctl(SIOCDELRT) device route: %m (line %d)", __LINE__);
7884 + /* This way it is possible to have an IPX-only or IPv6-only interface */
7885 + memset(&ifr, 0, sizeof(ifr));
7886 + SET_SA_FAMILY(ifr.ifr_addr, AF_INET);
7887 + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7889 + if (ioctl(sock_fd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
7890 + if (! ok_error (errno)) {
7891 + error("ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
7896 + our_old_addr = our_adr;
7902 +/********************************************************************
7904 + * sif6addr - Config the interface with an IPv6 link-local address
7906 +int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
7908 + struct in6_ifreq ifr6;
7910 + struct in6_rtmsg rt6;
7912 + if (sock6_fd < 0) {
7913 + errno = -sock6_fd;
7914 + error("IPv6 socket creation failed: %m");
7917 + memset(&ifr, 0, sizeof (ifr));
7918 + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7919 + if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
7920 + error("sif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
7924 + /* Local interface */
7925 + memset(&ifr6, 0, sizeof(ifr6));
7926 + IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
7927 + ifr6.ifr6_ifindex = ifr.ifr_ifindex;
7928 + ifr6.ifr6_prefixlen = 10;
7930 + if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
7931 + error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
7935 + /* Route to remote host */
7936 + memset(&rt6, 0, sizeof(rt6));
7937 + IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
7938 + rt6.rtmsg_flags = RTF_UP;
7939 + rt6.rtmsg_dst_len = 10;
7940 + rt6.rtmsg_ifindex = ifr.ifr_ifindex;
7941 + rt6.rtmsg_metric = 1;
7943 + if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) {
7944 + error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__);
7952 +/********************************************************************
7954 + * cif6addr - Remove IPv6 address from interface
7956 +int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
7959 + struct in6_ifreq ifr6;
7961 + if (sock6_fd < 0) {
7962 + errno = -sock6_fd;
7963 + error("IPv6 socket creation failed: %m");
7966 + memset(&ifr, 0, sizeof(ifr));
7967 + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7968 + if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) {
7969 + error("cif6addr: ioctl(SIOCGIFINDEX): %m (line %d)", __LINE__);
7973 + memset(&ifr6, 0, sizeof(ifr6));
7974 + IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
7975 + ifr6.ifr6_ifindex = ifr.ifr_ifindex;
7976 + ifr6.ifr6_prefixlen = 10;
7978 + if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) {
7979 + if (errno != EADDRNOTAVAIL) {
7980 + if (! ok_error (errno))
7981 + error("cif6addr: ioctl(SIOCDIFADDR): %m (line %d)", __LINE__);
7984 + warn("cif6addr: ioctl(SIOCDIFADDR): No such address");
7993 + * get_pty - get a pty master/slave pair and chown the slave side
7994 + * to the uid given. Assumes slave_name points to >= 16 bytes of space.
7997 +get_pty(master_fdp, slave_fdp, slave_name, uid)
8003 + int i, mfd, sfd = -1;
8004 + char pty_name[16];
8005 + struct termios tios;
8009 + * Try the unix98 way first.
8011 + mfd = open("/dev/ptmx", O_RDWR);
8014 + if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
8015 + slprintf(pty_name, sizeof(pty_name), "/dev/pts/%d", ptn);
8016 + chmod(pty_name, S_IRUSR | S_IWUSR);
8019 + if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
8020 + warn("Couldn't unlock pty slave %s: %m", pty_name);
8022 + if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
8023 + warn("Couldn't open pty slave %s: %m", pty_name);
8026 +#endif /* TIOCGPTN */
8029 + /* the old way - scan through the pty name space */
8030 + for (i = 0; i < 64; ++i) {
8031 + slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
8032 + 'p' + i / 16, i % 16);
8033 + mfd = open(pty_name, O_RDWR, 0);
8035 + pty_name[5] = 't';
8036 + sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
8038 + fchown(sfd, uid, -1);
8039 + fchmod(sfd, S_IRUSR | S_IWUSR);
8050 + strlcpy(slave_name, pty_name, 16);
8051 + *master_fdp = mfd;
8053 + if (tcgetattr(sfd, &tios) == 0) {
8054 + tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB);
8055 + tios.c_cflag |= CS8 | CREAD | CLOCAL;
8056 + tios.c_iflag = IGNPAR;
8059 + if (tcsetattr(sfd, TCSAFLUSH, &tios) < 0)
8060 + warn("couldn't set attributes on pty: %m");
8062 + warn("couldn't get attributes on pty: %m");
8067 +/********************************************************************
8069 + * open_loopback - open the device we use for getting packets
8070 + * in demand mode. Under Linux, we use a pty master/slave pair.
8073 +open_ppp_loopback(void)
8078 + if (new_style_driver) {
8079 + /* allocate ourselves a ppp unit */
8080 + if (make_ppp_unit() < 0)
8082 + modify_flags(ppp_dev_fd, 0, SC_LOOP_TRAFFIC);
8083 + set_kdebugflag(kdebugflag);
8085 + return ppp_dev_fd;
8088 + if (!get_pty(&master_fd, &slave_fd, loop_name, 0))
8089 + fatal("No free pty for loopback");
8091 + set_ppp_fd(slave_fd);
8093 + flags = fcntl(master_fd, F_GETFL);
8094 + if (flags == -1 ||
8095 + fcntl(master_fd, F_SETFL, flags | O_NONBLOCK) == -1)
8096 + warn("couldn't set master loopback to nonblock: %m");
8098 + flags = fcntl(ppp_fd, F_GETFL);
8099 + if (flags == -1 ||
8100 + fcntl(ppp_fd, F_SETFL, flags | O_NONBLOCK) == -1)
8101 + warn("couldn't set slave loopback to nonblock: %m");
8103 + if (ioctl(ppp_fd, TIOCSETD, &ppp_disc) < 0)
8104 + fatal("ioctl(TIOCSETD): %m (line %d)", __LINE__);
8106 + * Find out which interface we were given.
8108 + if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0)
8109 + fatal("ioctl(PPPIOCGUNIT): %m (line %d)", __LINE__);
8111 + * Enable debug in the driver if requested.
8113 + set_kdebugflag (kdebugflag);
8118 +/********************************************************************
8120 + * sifnpmode - Set the mode for handling packets for a given NP.
8124 +sifnpmode(u, proto, mode)
8129 + struct npioctl npi;
8131 + npi.protocol = proto;
8133 + if (ioctl(ppp_dev_fd, PPPIOCSNPMODE, (caddr_t) &npi) < 0) {
8134 + if (! ok_error (errno))
8135 + error("ioctl(PPPIOCSNPMODE, %d, %d): %m", proto, mode);
8142 +/********************************************************************
8144 + * sipxfaddr - Config the interface IPX networknumber
8147 +int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
8154 + struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
8156 + skfd = socket (AF_IPX, SOCK_DGRAM, 0);
8158 + if (! ok_error (errno))
8159 + dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
8163 + memset (&ifr, '\0', sizeof (ifr));
8164 + strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
8166 + memcpy (sipx->sipx_node, node, IPX_NODE_LEN);
8167 + sipx->sipx_family = AF_IPX;
8168 + sipx->sipx_port = 0;
8169 + sipx->sipx_network = htonl (network);
8170 + sipx->sipx_type = IPX_FRAME_ETHERII;
8171 + sipx->sipx_action = IPX_CRTITF;
8173 + * Set the IPX device
8175 + if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
8177 + if (errno != EEXIST) {
8178 + if (! ok_error (errno))
8179 + dbglog("ioctl(SIOCSIFADDR, CRTITF): %m (line %d)", __LINE__);
8182 + warn("ioctl(SIOCSIFADDR, CRTITF): Address already exists");
8191 +/********************************************************************
8193 + * cipxfaddr - Clear the information for the IPX network. The IPX routes
8194 + * are removed and the device is no longer able to pass IPX
8198 +int cipxfaddr (int unit)
8205 + struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
8207 + skfd = socket (AF_IPX, SOCK_DGRAM, 0);
8209 + if (! ok_error (errno))
8210 + dbglog("socket(AF_IPX): %m (line %d)", __LINE__);
8214 + memset (&ifr, '\0', sizeof (ifr));
8215 + strlcpy (ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
8217 + sipx->sipx_type = IPX_FRAME_ETHERII;
8218 + sipx->sipx_action = IPX_DLTITF;
8219 + sipx->sipx_family = AF_IPX;
8221 + * Set the IPX device
8223 + if (ioctl(skfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) {
8224 + if (! ok_error (errno))
8225 + info("ioctl(SIOCSIFADDR, IPX_DLTITF): %m (line %d)", __LINE__);
8235 + * Use the hostname as part of the random number seed.
8241 + char *p = hostname;
8244 + for (p = hostname; *p != 0; ++p)
8249 +/********************************************************************
8251 + * sys_check_options - check the options that the user specified
8255 +sys_check_options(void)
8259 + * Disable the IPX protocol if the support is not present in the kernel.
8263 + if (ipxcp_protent.enabled_flag) {
8264 + struct stat stat_buf;
8265 + if ( ((path = path_to_procfs("/net/ipx/interface")) == NULL
8266 + && (path = path_to_procfs("/net/ipx_interface")) == NULL)
8267 + || lstat(path, &stat_buf) < 0) {
8268 + error("IPX support is not present in the kernel\n");
8269 + ipxcp_protent.enabled_flag = 0;
8273 + if (demand && driver_is_old) {
8274 + option_error("demand dialling is not supported by kernel driver "
8275 + "version %d.%d.%d", driver_version, driver_modification,
8279 + if (multilink && !new_style_driver) {
8280 + warn("Warning: multilink is not supported by the kernel driver");
8288 + * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
8290 + * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
8291 + * that the system has a properly configured Ethernet interface for this
8292 + * function to return non-zero.
8295 +ether_to_eui64(eui64_t *p_eui64)
8299 + const unsigned char *ptr;
8301 + skfd = socket(PF_INET6, SOCK_DGRAM, 0);
8304 + warn("could not open IPv6 socket");
8308 + strcpy(ifr.ifr_name, "eth0");
8309 + if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
8312 + warn("could not obtain hardware address for eth0");
8318 + * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
8320 + ptr = ifr.ifr_hwaddr.sa_data;
8321 + p_eui64->e8[0] = ptr[0] | 0x02;
8322 + p_eui64->e8[1] = ptr[1];
8323 + p_eui64->e8[2] = ptr[2];
8324 + p_eui64->e8[3] = 0xFF;
8325 + p_eui64->e8[4] = 0xFE;
8326 + p_eui64->e8[5] = ptr[3];
8327 + p_eui64->e8[6] = ptr[4];
8328 + p_eui64->e8[7] = ptr[5];
8333 diff -ruNp ppp-2.4.5/pppd/sys-solaris.c ppp-2.4.5_new/pppd/sys-solaris.c
8334 --- ppp-2.4.5/pppd/sys-solaris.c 2009-11-17 01:26:07.000000000 +0300
8335 +++ ppp-2.4.5_new/pppd/sys-solaris.c 2010-11-24 17:43:52.240003480 +0300
8336 @@ -2036,12 +2036,18 @@ cifaddr(u, o, h)
8337 * sifdefaultroute - assign a default route through the address given.
8340 -sifdefaultroute(u, l, g)
8341 +sifdefaultroute(u, l, g, replace)
8349 + error("replacedefaultroute not supported on this platform");
8353 #if defined(__USLC__)
8354 g = l; /* use the local address as gateway */