]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/lwip/lib/contrib/src/netif/ppp/ppp.c
Update
[l4.git] / l4 / pkg / lwip / lib / contrib / src / netif / ppp / ppp.c
1 /*****************************************************************************
2 * ppp.c - Network Point to Point Protocol program file.
3 *
4 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
5 * portions Copyright (c) 1997 by Global Election Systems Inc.
6 *
7 * The authors hereby grant permission to use, copy, modify, distribute,
8 * and license this software and its documentation for any purpose, provided
9 * that existing copyright notices are retained in all copies and that this
10 * notice and the following disclaimer are included verbatim in any
11 * distributions. No written agreement, license, or royalty fee is required
12 * for any of the authorized uses.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 ******************************************************************************
26 * REVISION HISTORY
27 *
28 * 03-01-01 Marc Boucher <marc@mbsi.ca>
29 *   Ported to lwIP.
30 * 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
31 *   Original.
32 *****************************************************************************/
33
34 /*
35  * ppp_defs.h - PPP definitions.
36  *
37  * if_pppvar.h - private structures and declarations for PPP.
38  *
39  * Copyright (c) 1994 The Australian National University.
40  * All rights reserved.
41  *
42  * Permission to use, copy, modify, and distribute this software and its
43  * documentation is hereby granted, provided that the above copyright
44  * notice appears in all copies.  This software is provided without any
45  * warranty, express or implied. The Australian National University
46  * makes no representations about the suitability of this software for
47  * any purpose.
48  *
49  * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
50  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
51  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
52  * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
53  * OF SUCH DAMAGE.
54  *
55  * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
56  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
57  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
58  * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
59  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
60  * OR MODIFICATIONS.
61  */
62
63 /*
64  * if_ppp.h - Point-to-Point Protocol definitions.
65  *
66  * Copyright (c) 1989 Carnegie Mellon University.
67  * All rights reserved.
68  *
69  * Redistribution and use in source and binary forms are permitted
70  * provided that the above copyright notice and this paragraph are
71  * duplicated in all such forms and that any documentation,
72  * advertising materials, and other materials related to such
73  * distribution and use acknowledge that the software was developed
74  * by Carnegie Mellon University.  The name of the
75  * University may not be used to endorse or promote products derived
76  * from this software without specific prior written permission.
77  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
78  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
79  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
80  */
81
82 #include "lwip/opt.h"
83 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
84
85 #include "lwip/pbuf.h"
86 #include "lwip/stats.h"
87 #include "lwip/sys.h"
88 #include "lwip/tcpip.h"
89 #include "lwip/api.h"
90 #include "lwip/snmp_mib2.h"
91 #include "lwip/sio.h"
92 #include "lwip/sys.h"
93 #include "lwip/ip4.h" /* for ip4_input() */
94 #if PPP_IPV6_SUPPORT
95 #include "lwip/ip6.h" /* for ip6_input() */
96 #endif /* PPP_IPV6_SUPPORT */
97 #include "lwip/dns.h"
98
99 #include "netif/ppp/ppp_impl.h"
100 #include "netif/ppp/pppos.h"
101
102 #include "netif/ppp/fsm.h"
103 #include "netif/ppp/lcp.h"
104 #include "netif/ppp/magic.h"
105
106 #if PAP_SUPPORT
107 #include "netif/ppp/upap.h"
108 #endif /* PAP_SUPPORT */
109 #if CHAP_SUPPORT
110 #include "netif/ppp/chap-new.h"
111 #endif /* CHAP_SUPPORT */
112 #if EAP_SUPPORT
113 #include "netif/ppp/eap.h"
114 #endif /* EAP_SUPPORT */
115 #if CCP_SUPPORT
116 #include "netif/ppp/ccp.h"
117 #endif /* CCP_SUPPORT */
118 #if MPPE_SUPPORT
119 #include "netif/ppp/mppe.h"
120 #endif /* MPPE_SUPPORT */
121 #if ECP_SUPPORT
122 #include "netif/ppp/ecp.h"
123 #endif /* EAP_SUPPORT */
124 #if VJ_SUPPORT
125 #include "netif/ppp/vj.h"
126 #endif /* VJ_SUPPORT */
127 #if PPP_IPV4_SUPPORT
128 #include "netif/ppp/ipcp.h"
129 #endif /* PPP_IPV4_SUPPORT */
130 #if PPP_IPV6_SUPPORT
131 #include "netif/ppp/ipv6cp.h"
132 #endif /* PPP_IPV6_SUPPORT */
133
134 /*************************/
135 /*** LOCAL DEFINITIONS ***/
136 /*************************/
137
138 /* FIXME: add stats per PPP session */
139 #if PPP_STATS_SUPPORT
140 static struct timeval start_time; /* Time when link was started. */
141 static struct pppd_stats old_link_stats;
142 struct pppd_stats link_stats;
143 unsigned link_connect_time;
144 int link_stats_valid;
145 #endif /* PPP_STATS_SUPPORT */
146
147 /*
148  * PPP Data Link Layer "protocol" table.
149  * One entry per supported protocol.
150  * The last entry must be NULL.
151  */
152 const struct protent* const protocols[] = {
153     &lcp_protent,
154 #if PAP_SUPPORT
155     &pap_protent,
156 #endif /* PAP_SUPPORT */
157 #if CHAP_SUPPORT
158     &chap_protent,
159 #endif /* CHAP_SUPPORT */
160 #if CBCP_SUPPORT
161     &cbcp_protent,
162 #endif /* CBCP_SUPPORT */
163 #if PPP_IPV4_SUPPORT
164     &ipcp_protent,
165 #endif /* PPP_IPV4_SUPPORT */
166 #if PPP_IPV6_SUPPORT
167     &ipv6cp_protent,
168 #endif /* PPP_IPV6_SUPPORT */
169 #if CCP_SUPPORT
170     &ccp_protent,
171 #endif /* CCP_SUPPORT */
172 #if ECP_SUPPORT
173     &ecp_protent,
174 #endif /* ECP_SUPPORT */
175 #ifdef AT_CHANGE
176     &atcp_protent,
177 #endif /* AT_CHANGE */
178 #if EAP_SUPPORT
179     &eap_protent,
180 #endif /* EAP_SUPPORT */
181     NULL
182 };
183
184 /* Prototypes for procedures local to this file. */
185 static void ppp_do_connect(void *arg);
186 static err_t ppp_netif_init_cb(struct netif *netif);
187 #if LWIP_IPV4
188 static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, const ip4_addr_t *ipaddr);
189 #endif /* LWIP_IPV4 */
190 #if PPP_IPV6_SUPPORT
191 static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, const ip6_addr_t *ipaddr);
192 #endif /* PPP_IPV6_SUPPORT */
193 static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protocol);
194
195 /***********************************/
196 /*** PUBLIC FUNCTION DEFINITIONS ***/
197 /***********************************/
198 void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) {
199 #if PPP_AUTH_SUPPORT
200 #if PAP_SUPPORT
201   pcb->settings.refuse_pap = !(authtype & PPPAUTHTYPE_PAP);
202 #endif /* PAP_SUPPORT */
203 #if CHAP_SUPPORT
204   pcb->settings.refuse_chap = !(authtype & PPPAUTHTYPE_CHAP);
205 #if MSCHAP_SUPPORT
206   pcb->settings.refuse_mschap = !(authtype & PPPAUTHTYPE_MSCHAP);
207   pcb->settings.refuse_mschap_v2 = !(authtype & PPPAUTHTYPE_MSCHAP_V2);
208 #endif /* MSCHAP_SUPPORT */
209 #endif /* CHAP_SUPPORT */
210 #if EAP_SUPPORT
211   pcb->settings.refuse_eap = !(authtype & PPPAUTHTYPE_EAP);
212 #endif /* EAP_SUPPORT */
213   pcb->settings.user = user;
214   pcb->settings.passwd = passwd;
215 #else /* PPP_AUTH_SUPPORT */
216   LWIP_UNUSED_ARG(pcb);
217   LWIP_UNUSED_ARG(authtype);
218   LWIP_UNUSED_ARG(user);
219   LWIP_UNUSED_ARG(passwd);
220 #endif /* PPP_AUTH_SUPPORT */
221 }
222
223 #if PPP_NOTIFY_PHASE
224 void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb) {
225   pcb->notify_phase_cb = notify_phase_cb;
226   notify_phase_cb(pcb, pcb->phase, pcb->ctx_cb);
227 }
228 #endif /* PPP_NOTIFY_PHASE */
229
230 /*
231  * Initiate a PPP connection.
232  *
233  * This can only be called if PPP is in the dead phase.
234  *
235  * Holdoff is the time to wait (in seconds) before initiating
236  * the connection.
237  *
238  * If this port connects to a modem, the modem connection must be
239  * established before calling this.
240  */
241 err_t ppp_connect(ppp_pcb *pcb, u16_t holdoff) {
242   if (pcb->phase != PPP_PHASE_DEAD) {
243     return ERR_ALREADY;
244   }
245
246   PPPDEBUG(LOG_DEBUG, ("ppp_connect[%d]: holdoff=%d\n", pcb->netif->num, holdoff));
247
248   if (holdoff == 0) {
249     return pcb->link_cb->connect(pcb, pcb->link_ctx_cb);
250   }
251
252   new_phase(pcb, PPP_PHASE_HOLDOFF);
253   sys_timeout((u32_t)(holdoff*1000), ppp_do_connect, pcb);
254   return ERR_OK;
255 }
256
257 #if PPP_SERVER
258 /*
259  * Listen for an incoming PPP connection.
260  *
261  * This can only be called if PPP is in the dead phase.
262  *
263  * Local and remote interface IP addresses, as well as DNS are
264  * provided through a previously filled struct ppp_addrs.
265  *
266  * If this port connects to a modem, the modem connection must be
267  * established before calling this.
268  */
269 err_t ppp_listen(ppp_pcb *pcb, struct ppp_addrs *addrs) {
270   if (pcb->phase != PPP_PHASE_DEAD) {
271     return ERR_ALREADY;
272   }
273
274   PPPDEBUG(LOG_DEBUG, ("ppp_listen[%d]\n", pcb->netif->num));
275
276   if (pcb->link_cb->listen) {
277     return pcb->link_cb->listen(pcb, pcb->link_ctx_cb, addrs);
278   }
279   return ERR_IF;
280 }
281 #endif /* PPP_SERVER */
282
283 /*
284  * Initiate the end of a PPP connection.
285  * Any outstanding packets in the queues are dropped.
286  *
287  * Setting nocarrier to 1 close the PPP connection without initiating the
288  * shutdown procedure. Always using nocarrier = 0 is still recommended,
289  * this is going to take a little longer time if your link is down, but
290  * is a safer choice for the PPP state machine.
291  *
292  * Return 0 on success, an error code on failure.
293  */
294 err_t
295 ppp_close(ppp_pcb *pcb, u8_t nocarrier)
296 {
297   pcb->err_code = PPPERR_USER;
298
299   /* holdoff phase, cancel the reconnection */
300   if (pcb->phase == PPP_PHASE_HOLDOFF) {
301     sys_untimeout(ppp_do_connect, pcb);
302     new_phase(pcb, PPP_PHASE_DEAD);
303   }
304
305   /* dead phase, nothing to do, call the status callback to be consistent */
306   if (pcb->phase == PPP_PHASE_DEAD) {
307     pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb);
308     return ERR_OK;
309   }
310
311   /*
312    * Only accept carrier lost signal on the stable running phase in order
313    * to prevent changing the PPP phase FSM in transition phases.
314    *
315    * Always using nocarrier = 0 is still recommended, this is going to
316    * take a little longer time, but is a safer choice from FSM point of view.
317    */
318   if (nocarrier && pcb->phase == PPP_PHASE_RUNNING) {
319     PPPDEBUG(LOG_DEBUG, ("ppp_close[%d]: carrier lost -> lcp_lowerdown\n", pcb->netif->num));
320     lcp_lowerdown(pcb);
321     /* forced link termination, this will leave us at PPP_PHASE_DEAD. */
322     link_terminated(pcb);
323     return ERR_OK;
324   }
325
326   /* Disconnect */
327   PPPDEBUG(LOG_DEBUG, ("ppp_close[%d]: kill_link -> lcp_close\n", pcb->netif->num));
328   /* LCP close request, this will leave us at PPP_PHASE_DEAD. */
329   lcp_close(pcb, "User request");
330   return ERR_OK;
331 }
332
333 /*
334  * Release the control block.
335  *
336  * This can only be called if PPP is in the dead phase.
337  *
338  * You must use ppp_close() before if you wish to terminate
339  * an established PPP session.
340  *
341  * Return 0 on success, an error code on failure.
342  */
343 err_t ppp_free(ppp_pcb *pcb) {
344   err_t err;
345   if (pcb->phase != PPP_PHASE_DEAD) {
346     return ERR_CONN;
347   }
348
349   PPPDEBUG(LOG_DEBUG, ("ppp_free[%d]\n", pcb->netif->num));
350
351   netif_remove(pcb->netif);
352
353   err = pcb->link_cb->free(pcb, pcb->link_ctx_cb);
354
355   memp_free(MEMP_PPP_PCB, pcb);
356   return err;
357 }
358
359 /* Get and set parameters for the given connection.
360  * Return 0 on success, an error code on failure. */
361 err_t
362 ppp_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg)
363 {
364   if (pcb == NULL) {
365     return ERR_VAL;
366   }
367
368   switch(cmd) {
369     case PPPCTLG_UPSTATUS:      /* Get the PPP up status. */
370       if (!arg) {
371         goto fail;
372       }
373       *(int *)arg = (int)(0
374 #if PPP_IPV4_SUPPORT
375            || pcb->if4_up
376 #endif /* PPP_IPV4_SUPPORT */
377 #if PPP_IPV6_SUPPORT
378            || pcb->if6_up
379 #endif /* PPP_IPV6_SUPPORT */
380            );
381       return ERR_OK;
382
383     case PPPCTLG_ERRCODE:       /* Get the PPP error code. */
384       if (!arg) {
385         goto fail;
386       }
387       *(int *)arg = (int)(pcb->err_code);
388       return ERR_OK;
389
390     default:
391       goto fail;
392   }
393
394 fail:
395   return ERR_VAL;
396 }
397
398
399 /**********************************/
400 /*** LOCAL FUNCTION DEFINITIONS ***/
401 /**********************************/
402
403 static void ppp_do_connect(void *arg) {
404   ppp_pcb *pcb = (ppp_pcb*)arg;
405
406   LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF", pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF);
407
408   pcb->link_cb->connect(pcb, pcb->link_ctx_cb);
409 }
410
411 /*
412  * ppp_netif_init_cb - netif init callback
413  */
414 static err_t ppp_netif_init_cb(struct netif *netif) {
415   netif->name[0] = 'p';
416   netif->name[1] = 'p';
417 #if LWIP_IPV4
418   /* FIXME: change that when netif_null_output_ip4() will materialize */
419   netif->output = ppp_netif_output_ip4;
420 #endif /* LWIP_IPV4 */
421 #if PPP_IPV6_SUPPORT
422   netif->output_ip6 = ppp_netif_output_ip6;
423 #endif /* PPP_IPV6_SUPPORT */
424   netif->flags = NETIF_FLAG_UP;
425 #if LWIP_NETIF_HOSTNAME
426   /* @todo: Initialize interface hostname */
427   /* netif_set_hostname(netif, "lwip"); */
428 #endif /* LWIP_NETIF_HOSTNAME */
429   return ERR_OK;
430 }
431
432 #if LWIP_IPV4
433 /*
434  * Send an IPv4 packet on the given connection.
435  */
436 static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, const ip4_addr_t *ipaddr) {
437   LWIP_UNUSED_ARG(ipaddr);
438 #if PPP_IPV4_SUPPORT
439   return ppp_netif_output(netif, pb, PPP_IP);
440 #else /* PPP_IPV4_SUPPORT */
441   LWIP_UNUSED_ARG(netif);
442   LWIP_UNUSED_ARG(pb);
443   return ERR_IF;
444 #endif /* PPP_IPV4_SUPPORT */
445 }
446 #endif /* LWIP_IPV4 */
447
448 #if PPP_IPV6_SUPPORT
449 /*
450  * Send an IPv6 packet on the given connection.
451  */
452 static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, const ip6_addr_t *ipaddr) {
453   LWIP_UNUSED_ARG(ipaddr);
454   return ppp_netif_output(netif, pb, PPP_IPV6);
455 }
456 #endif /* PPP_IPV6_SUPPORT */
457
458 static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protocol) {
459   ppp_pcb *pcb = (ppp_pcb*)netif->state;
460
461   /* Check that the link is up. */
462   if (0
463 #if PPP_IPV4_SUPPORT
464       || (protocol == PPP_IP && !pcb->if4_up)
465 #endif /* PPP_IPV4_SUPPORT */
466 #if PPP_IPV6_SUPPORT
467       || (protocol == PPP_IPV6 && !pcb->if6_up)
468 #endif /* PPP_IPV6_SUPPORT */
469       ) {
470     PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pcb->netif->num));
471     goto err_rte_drop;
472   }
473
474 #if MPPE_SUPPORT
475   /* If MPPE is required, refuse any IP packet until we are able to crypt them. */
476   if (pcb->settings.require_mppe &&
477             (!pcb->ccp_is_up || pcb->ccp_transmit_method != CI_MPPE) ) {
478     PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: MPPE required, not up\n", pcb->netif->num));
479     goto err_rte_drop;
480   }
481 #endif /* MPPE_SUPPORT */
482
483 #if VJ_SUPPORT
484   /*
485    * Attempt Van Jacobson header compression if VJ is configured and
486    * this is an IP packet.
487    */
488   if (protocol == PPP_IP && pcb->vj_enabled) {
489     switch (vj_compress_tcp(&pcb->vj_comp, pb)) {
490       case TYPE_IP:
491         /* No change...
492            protocol = PPP_IP_PROTOCOL; */
493         break;
494       case TYPE_COMPRESSED_TCP:
495         protocol = PPP_VJC_COMP;
496         break;
497       case TYPE_UNCOMPRESSED_TCP:
498         protocol = PPP_VJC_UNCOMP;
499         break;
500       default:
501         PPPDEBUG(LOG_WARNING, ("pppos_netif_output[%d]: bad IP packet\n", pcb->netif->num));
502         LINK_STATS_INC(link.proterr);
503         LINK_STATS_INC(link.drop);
504         MIB2_STATS_NETIF_INC(pcb->netif, ifoutdiscards);
505         return ERR_VAL;
506     }
507   }
508 #endif /* VJ_SUPPORT */
509
510 #if CCP_SUPPORT
511   if (pcb->ccp_is_up) {
512 #if MPPE_SUPPORT
513     err_t err;
514 #endif /* MPPE_SUPPORT */
515
516     switch (pcb->ccp_transmit_method) {
517 #if MPPE_SUPPORT
518     case CI_MPPE:
519       if ((err = mppe_compress(pcb, &pcb->mppe_comp, &pb, protocol)) != ERR_OK) {
520         LINK_STATS_INC(link.memerr);
521         LINK_STATS_INC(link.drop);
522         MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
523         return err;
524       }
525
526       err = pcb->link_cb->netif_output(pcb, pcb->link_ctx_cb, pb, PPP_COMP);
527       pbuf_free(pb);
528       return err;
529 #endif /* MPPE_SUPPORT */
530     default:
531       goto err_rte_drop; /* Cannot really happen, we only negotiate what we are able to do */
532     }
533   }
534 #endif /* CCP_SUPPORT */
535
536   return pcb->link_cb->netif_output(pcb, pcb->link_ctx_cb, pb, protocol);
537
538 err_rte_drop:
539   LINK_STATS_INC(link.rterr);
540   LINK_STATS_INC(link.drop);
541   MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
542   return ERR_RTE;
543 }
544
545 /************************************/
546 /*** PRIVATE FUNCTION DEFINITIONS ***/
547 /************************************/
548
549 /* Initialize the PPP subsystem. */
550 int ppp_init(void) {
551
552     /*
553      * Initialize magic number generator now so that protocols may
554      * use magic numbers in initialization.
555      */
556     magic_init();
557
558     return 0;
559 }
560
561 /*
562  * Create a new PPP control block.
563  *
564  * This initializes the PPP control block but does not
565  * attempt to negotiate the LCP session.
566  *
567  * Return a new PPP connection control block pointer
568  * on success or a null pointer on failure.
569  */
570 ppp_pcb *ppp_new(struct netif *pppif, const struct link_callbacks *callbacks, void *link_ctx_cb, ppp_link_status_cb_fn link_status_cb, void *ctx_cb) {
571   ppp_pcb *pcb;
572
573   /* PPP is single-threaded: without a callback,
574    * there is no way to know when the link is up. */
575   if (link_status_cb == NULL) {
576     return NULL;
577   }
578
579   pcb = (ppp_pcb*)memp_malloc(MEMP_PPP_PCB);
580   if (pcb == NULL) {
581     return NULL;
582   }
583
584   memset(pcb, 0, sizeof(ppp_pcb));
585
586   /* default configuration */
587 #if LWIP_DNS
588   pcb->settings.usepeerdns = 1;
589 #endif /* LWIP_DNS */
590
591 #if PAP_SUPPORT
592   pcb->settings.pap_timeout_time = UPAP_DEFTIMEOUT;
593   pcb->settings.pap_max_transmits = UPAP_DEFTRANSMITS;
594 #if PPP_SERVER
595   pcb->settings.pap_req_timeout = UPAP_DEFREQTIME;
596 #endif /* PPP_SERVER */
597 #endif /* PAP_SUPPORT */
598
599 #if CHAP_SUPPORT
600   pcb->settings.chap_timeout_time = CHAP_DEFTIMEOUT;
601   pcb->settings.chap_max_transmits = CHAP_DEFTRANSMITS;
602 #if PPP_SERVER
603   pcb->settings.chap_rechallenge_time = CHAP_DEFRECHALLENGETIME;
604 #endif /* PPP_SERVER */
605 #endif /* CHAP_SUPPPORT */
606
607 #if EAP_SUPPORT
608   pcb->settings.eap_req_time = EAP_DEFREQTIME;
609   pcb->settings.eap_allow_req = EAP_DEFALLOWREQ;
610 #if PPP_SERVER
611   pcb->settings.eap_timeout_time = EAP_DEFTIMEOUT;
612   pcb->settings.eap_max_transmits = EAP_DEFTRANSMITS;
613 #endif /* PPP_SERVER */
614 #endif /* EAP_SUPPORT */
615
616 #if MPPE_SUPPORT
617   pcb->settings.refuse_mppe_stateful = 1;
618 #endif /* MPPE_SUPPORT */
619
620   pcb->settings.lcp_loopbackfail = LCP_DEFLOOPBACKFAIL;
621   pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL;
622   pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS;
623
624   pcb->settings.fsm_timeout_time = FSM_DEFTIMEOUT;
625   pcb->settings.fsm_max_conf_req_transmits = FSM_DEFMAXCONFREQS;
626   pcb->settings.fsm_max_term_transmits = FSM_DEFMAXTERMREQS;
627   pcb->settings.fsm_max_nak_loops = FSM_DEFMAXNAKLOOPS;
628
629   pcb->netif = pppif;
630   if (!netif_add(pcb->netif,
631 #if LWIP_IPV4
632                  IP4_ADDR_ANY, IP4_ADDR_BROADCAST, IP4_ADDR_ANY,
633 #endif /* LWIP_IPV4 */
634                  (void *)pcb, ppp_netif_init_cb, NULL)) {
635     memp_free(MEMP_PPP_PCB, pcb);
636     PPPDEBUG(LOG_ERR, ("ppp_new: netif_add failed\n"));
637     return NULL;
638   }
639
640   pcb->link_cb = callbacks;
641   pcb->link_ctx_cb = link_ctx_cb;
642   pcb->link_status_cb = link_status_cb;
643   pcb->ctx_cb = ctx_cb;
644   new_phase(pcb, PPP_PHASE_DEAD);
645   return pcb;
646 }
647
648 /* Set a PPP PCB to its initial state */
649 void ppp_clear(ppp_pcb *pcb) {
650   const struct protent *protp;
651   int i;
652
653   LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF", pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF);
654
655 #if PPP_STATS_SUPPORT
656   link_stats_valid = 0;
657 #endif /* PPP_STATS_SUPPORT */
658
659   memset(&pcb->phase, 0, sizeof(ppp_pcb) - ( (char*)&((ppp_pcb*)0)->phase - (char*)0 ) );
660
661   /*
662    * Initialize each protocol.
663    */
664   for (i = 0; (protp = protocols[i]) != NULL; ++i) {
665       (*protp->init)(pcb);
666   }
667
668 #if VJ_SUPPORT
669   vj_compress_init(&pcb->vj_comp);
670 #endif /* VJ_SUPPORT */
671
672   new_phase(pcb, PPP_PHASE_INITIALIZE);
673 }
674
675 /** Initiate LCP open request */
676 void ppp_start(ppp_pcb *pcb) {
677   PPPDEBUG(LOG_DEBUG, ("ppp_start[%d]\n", pcb->netif->num));
678   lcp_open(pcb); /* Start protocol */
679   lcp_lowerup(pcb);
680   PPPDEBUG(LOG_DEBUG, ("ppp_start[%d]: finished\n", pcb->netif->num));
681 }
682
683 /** Called when link failed to setup */
684 void ppp_link_failed(ppp_pcb *pcb) {
685   PPPDEBUG(LOG_DEBUG, ("ppp_failed[%d]\n", pcb->netif->num));
686   new_phase(pcb, PPP_PHASE_DEAD);
687   pcb->err_code = PPPERR_OPEN;
688   pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb);
689 }
690
691 /** Called when link is normally down (i.e. it was asked to end) */
692 void ppp_link_end(ppp_pcb *pcb) {
693   PPPDEBUG(LOG_DEBUG, ("ppp_end[%d]\n", pcb->netif->num));
694   if (pcb->err_code == PPPERR_NONE) {
695     pcb->err_code = PPPERR_CONNECT;
696   }
697   pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb);
698 }
699
700 /*
701  * Pass the processed input packet to the appropriate handler.
702  * This function and all handlers run in the context of the tcpip_thread
703  */
704 void ppp_input(ppp_pcb *pcb, struct pbuf *pb) {
705   u16_t protocol;
706 #if PPP_DEBUG && PPP_PROTOCOLNAME
707     const char *pname;
708 #endif /* PPP_DEBUG && PPP_PROTOCOLNAME */
709
710   magic_randomize();
711
712   if (pb->len < 2) {
713     PPPDEBUG(LOG_ERR, ("ppp_input[%d]: packet too short\n", pcb->netif->num));
714     goto drop;
715   }
716   protocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1];
717
718 #if PRINTPKT_SUPPORT
719   ppp_dump_packet("rcvd", (unsigned char *)pb->payload, pb->len);
720 #endif /* PRINTPKT_SUPPORT */
721
722   pbuf_header(pb, -(s16_t)sizeof(protocol));
723
724   LINK_STATS_INC(link.recv);
725   MIB2_STATS_NETIF_INC(pcb->netif, ifinucastpkts);
726   MIB2_STATS_NETIF_ADD(pcb->netif, ifinoctets, pb->tot_len);
727
728   /*
729    * Toss all non-LCP packets unless LCP is OPEN.
730    */
731   if (protocol != PPP_LCP && pcb->lcp_fsm.state != PPP_FSM_OPENED) {
732     ppp_dbglog("Discarded non-LCP packet when LCP not open");
733     goto drop;
734   }
735
736   /*
737    * Until we get past the authentication phase, toss all packets
738    * except LCP, LQR and authentication packets.
739    */
740   if (pcb->phase <= PPP_PHASE_AUTHENTICATE
741    && !(protocol == PPP_LCP
742 #if LQR_SUPPORT
743    || protocol == PPP_LQR
744 #endif /* LQR_SUPPORT */
745 #if PAP_SUPPORT
746    || protocol == PPP_PAP
747 #endif /* PAP_SUPPORT */
748 #if CHAP_SUPPORT
749    || protocol == PPP_CHAP
750 #endif /* CHAP_SUPPORT */
751 #if EAP_SUPPORT
752    || protocol == PPP_EAP
753 #endif /* EAP_SUPPORT */
754    )) {
755     ppp_dbglog("discarding proto 0x%x in phase %d", protocol, pcb->phase);
756     goto drop;
757   }
758
759 #if CCP_SUPPORT
760 #if MPPE_SUPPORT
761   /*
762    * MPPE is required and unencrypted data has arrived (this
763    * should never happen!). We should probably drop the link if
764    * the protocol is in the range of what should be encrypted.
765    * At the least, we drop this packet.
766    */
767   if (pcb->settings.require_mppe && protocol != PPP_COMP && protocol < 0x8000) {
768     PPPDEBUG(LOG_ERR, ("ppp_input[%d]: MPPE required, received unencrypted data!\n", pcb->netif->num));
769     goto drop;
770   }
771 #endif /* MPPE_SUPPORT */
772
773   if (protocol == PPP_COMP) {
774     u8_t *pl;
775
776     if (!pcb->ccp_is_up) {
777       goto drop;
778     }
779
780     switch (pcb->ccp_receive_method) {
781 #if MPPE_SUPPORT
782     case CI_MPPE:
783       if (mppe_decompress(pcb, &pcb->mppe_decomp, &pb) != ERR_OK) {
784         goto drop;
785       }
786       break;
787 #endif /* MPPE_SUPPORT */
788     default:
789       goto drop; /* Cannot really happen, we only negotiate what we are able to do */
790     }
791
792     /* Assume no PFC */
793     if (pb->len < 2) {
794       goto drop;
795     }
796
797     /* Extract and hide protocol (do PFC decompression if necessary) */
798     pl = (u8_t*)pb->payload;
799     if (pl[0] & 0x01) {
800       protocol = pl[0];
801       pbuf_header(pb, -(s16_t)1);
802     } else {
803       protocol = (pl[0] << 8) | pl[1];
804       pbuf_header(pb, -(s16_t)2);
805     }
806   }
807 #endif /* CCP_SUPPORT */
808
809   switch(protocol) {
810
811 #if PPP_IPV4_SUPPORT
812     case PPP_IP:            /* Internet Protocol */
813       PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->netif->num, pb->tot_len));
814       ip4_input(pb, pcb->netif);
815       return;
816 #endif /* PPP_IPV4_SUPPORT */
817
818 #if PPP_IPV6_SUPPORT
819     case PPP_IPV6:          /* Internet Protocol Version 6 */
820       PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip6 in pbuf len=%d\n", pcb->netif->num, pb->tot_len));
821       ip6_input(pb, pcb->netif);
822       return;
823 #endif /* PPP_IPV6_SUPPORT */
824
825 #if VJ_SUPPORT
826     case PPP_VJC_COMP:      /* VJ compressed TCP */
827       /*
828        * Clip off the VJ header and prepend the rebuilt TCP/IP header and
829        * pass the result to IP.
830        */
831       PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->netif->num, pb->len));
832       if (pcb->vj_enabled && vj_uncompress_tcp(&pb, &pcb->vj_comp) >= 0) {
833         ip4_input(pb, pcb->netif);
834         return;
835       }
836       /* Something's wrong so drop it. */
837       PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->netif->num));
838       break;
839
840     case PPP_VJC_UNCOMP:    /* VJ uncompressed TCP */
841       /*
842        * Process the TCP/IP header for VJ header compression and then pass
843        * the packet to IP.
844        */
845       PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->netif->num, pb->len));
846       if (pcb->vj_enabled && vj_uncompress_uncomp(pb, &pcb->vj_comp) >= 0) {
847         ip4_input(pb, pcb->netif);
848         return;
849       }
850       /* Something's wrong so drop it. */
851       PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->netif->num));
852       break;
853 #endif /* VJ_SUPPORT */
854
855     default: {
856       int i;
857       const struct protent *protp;
858
859       /*
860        * Upcall the proper protocol input routine.
861        */
862       for (i = 0; (protp = protocols[i]) != NULL; ++i) {
863         if (protp->protocol == protocol) {
864           pb = ppp_singlebuf(pb);
865           (*protp->input)(pcb, (u8_t*)pb->payload, pb->len);
866           goto out;
867         }
868 #if 0   /* UNUSED
869          *
870          * This is actually a (hacked?) way for the Linux kernel to pass a data
871          * packet to pppd. pppd in normal condition only do signaling
872          * (LCP, PAP, CHAP, IPCP, ...) and does not handle any data packet at all.
873          *
874          * We don't even need this interface, which is only there because of PPP
875          * interface limitation between Linux kernel and pppd. For MPPE, which uses
876          * CCP to negotiate although it is not really a (de)compressor, we added
877          * ccp_resetrequest() in CCP and MPPE input data flow is calling either
878          * ccp_resetrequest() or lcp_close() if the issue is, respectively, non-fatal
879          * or fatal, this is what ccp_datainput() really do.
880          */
881         if (protocol == (protp->protocol & ~0x8000)
882           && protp->datainput != NULL) {
883           (*protp->datainput)(pcb, pb->payload, pb->len);
884           goto out;
885         }
886 #endif /* UNUSED */
887       }
888
889 #if PPP_DEBUG
890 #if PPP_PROTOCOLNAME
891       pname = protocol_name(protocol);
892       if (pname != NULL) {
893         ppp_warn("Unsupported protocol '%s' (0x%x) received", pname, protocol);
894       } else
895 #endif /* PPP_PROTOCOLNAME */
896         ppp_warn("Unsupported protocol 0x%x received", protocol);
897 #endif /* PPP_DEBUG */
898         pbuf_header(pb, (s16_t)sizeof(protocol));
899         lcp_sprotrej(pcb, (u8_t*)pb->payload, pb->len);
900       }
901       break;
902   }
903
904 drop:
905   LINK_STATS_INC(link.drop);
906   MIB2_STATS_NETIF_INC(pcb->netif, ifindiscards);
907
908 out:
909   pbuf_free(pb);
910 }
911
912 /* merge a pbuf chain into one pbuf */
913 struct pbuf *ppp_singlebuf(struct pbuf *p) {
914   struct pbuf *q, *b;
915   u8_t *pl;
916
917   if(p->tot_len == p->len) {
918     return p;
919   }
920
921   q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
922   if(!q) {
923     PPPDEBUG(LOG_ERR,
924              ("ppp_singlebuf: unable to alloc new buf (%d)\n", p->tot_len));
925     return p; /* live dangerously */
926   }
927
928   for(b = p, pl = (u8_t*)q->payload; b != NULL; b = b->next) {
929     MEMCPY(pl, b->payload, b->len);
930     pl += b->len;
931   }
932
933   pbuf_free(p);
934
935   return q;
936 }
937
938 /*
939  * Write a pbuf to a ppp link, only used from PPP functions
940  * to send PPP packets.
941  *
942  * IPv4 and IPv6 packets from lwIP are sent, respectively,
943  * with ppp_netif_output_ip4() and ppp_netif_output_ip6()
944  * functions (which are callbacks of the netif PPP interface).
945  *
946  *  RETURN: >= 0 Number of characters written
947  *           -1 Failed to write to device
948  */
949 err_t ppp_write(ppp_pcb *pcb, struct pbuf *p) {
950 #if PRINTPKT_SUPPORT
951   ppp_dump_packet("sent", (unsigned char *)p->payload+2, p->len-2);
952 #endif /* PRINTPKT_SUPPORT */
953   return pcb->link_cb->write(pcb, pcb->link_ctx_cb, p);
954 }
955
956 void ppp_link_terminated(ppp_pcb *pcb) {
957   PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated[%d]\n", pcb->netif->num));
958   pcb->link_cb->disconnect(pcb, pcb->link_ctx_cb);
959   PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated[%d]: finished.\n", pcb->netif->num));
960 }
961
962
963 /************************************************************************
964  * Functions called by various PPP subsystems to configure
965  * the PPP interface or change the PPP phase.
966  */
967
968 /*
969  * new_phase - signal the start of a new phase of pppd's operation.
970  */
971 void new_phase(ppp_pcb *pcb, int p) {
972   pcb->phase = p;
973   PPPDEBUG(LOG_DEBUG, ("ppp phase changed[%d]: phase=%d\n", pcb->netif->num, pcb->phase));
974 #if PPP_NOTIFY_PHASE
975   if (pcb->notify_phase_cb != NULL) {
976     pcb->notify_phase_cb(pcb, p, pcb->ctx_cb);
977   }
978 #endif /* PPP_NOTIFY_PHASE */
979 }
980
981 /*
982  * ppp_send_config - configure the transmit-side characteristics of
983  * the ppp interface.
984  */
985 int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp) {
986   LWIP_UNUSED_ARG(mtu);
987   /* pcb->mtu = mtu; -- set correctly with netif_set_mtu */
988
989   if (pcb->link_cb->send_config) {
990     pcb->link_cb->send_config(pcb, pcb->link_ctx_cb, accm, pcomp, accomp);
991   }
992
993   PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", pcb->netif->num) );
994   return 0;
995 }
996
997 /*
998  * ppp_recv_config - configure the receive-side characteristics of
999  * the ppp interface.
1000  */
1001 int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp) {
1002   LWIP_UNUSED_ARG(mru);
1003
1004   if (pcb->link_cb->recv_config) {
1005     pcb->link_cb->recv_config(pcb, pcb->link_ctx_cb, accm, pcomp, accomp);
1006   }
1007
1008   PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", pcb->netif->num));
1009   return 0;
1010 }
1011
1012 #if PPP_IPV4_SUPPORT
1013 /*
1014  * sifaddr - Config the interface IP addresses and netmask.
1015  */
1016 int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, u32_t netmask) {
1017   ip4_addr_t ip, nm, gw;
1018
1019   ip4_addr_set_u32(&ip, our_adr);
1020   ip4_addr_set_u32(&nm, netmask);
1021   ip4_addr_set_u32(&gw, his_adr);
1022   netif_set_addr(pcb->netif, &ip, &nm, &gw);
1023   return 1;
1024 }
1025
1026 /********************************************************************
1027  *
1028  * cifaddr - Clear the interface IP addresses, and delete routes
1029  * through the interface if possible.
1030  */
1031 int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr) {
1032   LWIP_UNUSED_ARG(our_adr);
1033   LWIP_UNUSED_ARG(his_adr);
1034
1035   netif_set_addr(pcb->netif, IP4_ADDR_ANY, IP4_ADDR_BROADCAST, IP4_ADDR_ANY);
1036   return 1;
1037 }
1038
1039 #if 0 /* UNUSED - PROXY ARP */
1040 /********************************************************************
1041  *
1042  * sifproxyarp - Make a proxy ARP entry for the peer.
1043  */
1044
1045 int sifproxyarp(ppp_pcb *pcb, u32_t his_adr) {
1046   LWIP_UNUSED_ARG(pcb);
1047   LWIP_UNUSED_ARG(his_adr);
1048   return 0;
1049 }
1050
1051 /********************************************************************
1052  *
1053  * cifproxyarp - Delete the proxy ARP entry for the peer.
1054  */
1055
1056 int cifproxyarp(ppp_pcb *pcb, u32_t his_adr) {
1057   LWIP_UNUSED_ARG(pcb);
1058   LWIP_UNUSED_ARG(his_adr);
1059   return 0;
1060 }
1061 #endif /* UNUSED - PROXY ARP */
1062
1063 #if LWIP_DNS
1064 /*
1065  * sdns - Config the DNS servers
1066  */
1067 int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) {
1068   ip_addr_t ns;
1069   LWIP_UNUSED_ARG(pcb);
1070
1071   ip_addr_set_ip4_u32(&ns, ns1);
1072   dns_setserver(0, &ns);
1073   ip_addr_set_ip4_u32(&ns, ns2);
1074   dns_setserver(1, &ns);
1075   return 1;
1076 }
1077
1078 /********************************************************************
1079  *
1080  * cdns - Clear the DNS servers
1081  */
1082 int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) {
1083   ip_addr_t nsa, nsb;
1084   LWIP_UNUSED_ARG(pcb);
1085
1086   nsa = dns_getserver(0);
1087   ip_addr_set_ip4_u32(&nsb, ns1);
1088   if (ip_addr_cmp(&nsa, &nsb)) {
1089     dns_setserver(0, IP_ADDR_ANY);
1090   }
1091   nsa = dns_getserver(1);
1092   ip_addr_set_ip4_u32(&nsb, ns2);
1093   if (ip_addr_cmp(&nsa, &nsb)) {
1094     dns_setserver(1, IP_ADDR_ANY);
1095   }
1096   return 1;
1097 }
1098 #endif /* LWIP_DNS */
1099
1100 #if VJ_SUPPORT
1101 /********************************************************************
1102  *
1103  * sifvjcomp - config tcp header compression
1104  */
1105 int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid) {
1106   pcb->vj_enabled = vjcomp;
1107   pcb->vj_comp.compressSlot = cidcomp;
1108   pcb->vj_comp.maxSlotIndex = maxcid;
1109   PPPDEBUG(LOG_INFO, ("sifvjcomp[%d]: VJ compress enable=%d slot=%d max slot=%d\n",
1110             pcb->netif->num, vjcomp, cidcomp, maxcid));
1111   return 0;
1112 }
1113 #endif /* VJ_SUPPORT */
1114
1115 /*
1116  * sifup - Config the interface up and enable IP packets to pass.
1117  */
1118 int sifup(ppp_pcb *pcb) {
1119   pcb->if4_up = 1;
1120   pcb->err_code = PPPERR_NONE;
1121   netif_set_link_up(pcb->netif);
1122
1123   PPPDEBUG(LOG_DEBUG, ("sifup[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code));
1124   pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb);
1125   return 1;
1126 }
1127
1128 /********************************************************************
1129  *
1130  * sifdown - Disable the indicated protocol and config the interface
1131  *           down if there are no remaining protocols.
1132  */
1133 int sifdown(ppp_pcb *pcb) {
1134
1135   pcb->if4_up = 0;
1136
1137   if (1
1138 #if PPP_IPV6_SUPPORT
1139    /* set the interface down if IPv6 is down as well */
1140    && !pcb->if6_up
1141 #endif /* PPP_IPV6_SUPPORT */
1142   ) {
1143     /* make sure the netif link callback is called */
1144     netif_set_link_down(pcb->netif);
1145   }
1146   PPPDEBUG(LOG_DEBUG, ("sifdown[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code));
1147   return 1;
1148 }
1149
1150 /********************************************************************
1151  *
1152  * Return user specified netmask, modified by any mask we might determine
1153  * for address `addr' (in network byte order).
1154  * Here we scan through the system's list of interfaces, looking for
1155  * any non-point-to-point interfaces which might appear to be on the same
1156  * network as `addr'.  If we find any, we OR in their netmask to the
1157  * user-specified netmask.
1158  */
1159 u32_t get_mask(u32_t addr) {
1160 #if 0
1161   u32_t mask, nmask;
1162
1163   addr = htonl(addr);
1164   if (IP_CLASSA(addr)) { /* determine network mask for address class */
1165     nmask = IP_CLASSA_NET;
1166   } else if (IP_CLASSB(addr)) {
1167     nmask = IP_CLASSB_NET;
1168   } else {
1169     nmask = IP_CLASSC_NET;
1170   }
1171
1172   /* class D nets are disallowed by bad_ip_adrs */
1173   mask = PP_HTONL(0xffffff00UL) | htonl(nmask);
1174
1175   /* XXX
1176    * Scan through the system's network interfaces.
1177    * Get each netmask and OR them into our mask.
1178    */
1179   /* return mask; */
1180   return mask;
1181 #endif /* 0 */
1182   LWIP_UNUSED_ARG(addr);
1183   return IPADDR_BROADCAST;
1184 }
1185 #endif /* PPP_IPV4_SUPPORT */
1186
1187 #if PPP_IPV6_SUPPORT
1188 #define IN6_LLADDR_FROM_EUI64(ip6, eui64) do {    \
1189   ip6.addr[0] = PP_HTONL(0xfe800000);             \
1190   ip6.addr[1] = 0;                                \
1191   eui64_copy(eui64, ip6.addr[2]);                 \
1192   } while (0)
1193
1194 /********************************************************************
1195  *
1196  * sif6addr - Config the interface with an IPv6 link-local address
1197  */
1198 int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) {
1199   ip6_addr_t ip6;
1200   LWIP_UNUSED_ARG(his_eui64);
1201
1202   IN6_LLADDR_FROM_EUI64(ip6, our_eui64);
1203   netif_ip6_addr_set(pcb->netif, 0, &ip6);
1204   netif_ip6_addr_set_state(pcb->netif, 0, IP6_ADDR_PREFERRED);
1205   /* FIXME: should we add an IPv6 static neighbor using his_eui64 ? */
1206   return 1;
1207 }
1208
1209 /********************************************************************
1210  *
1211  * cif6addr - Remove IPv6 address from interface
1212  */
1213 int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) {
1214   LWIP_UNUSED_ARG(our_eui64);
1215   LWIP_UNUSED_ARG(his_eui64);
1216
1217   netif_ip6_addr_set(pcb->netif, 0, IP6_ADDR_ANY6);
1218   netif_ip6_addr_set_state(pcb->netif, 0, IP6_ADDR_INVALID);
1219   return 1;
1220 }
1221
1222 /*
1223  * sif6up - Config the interface up and enable IPv6 packets to pass.
1224  */
1225 int sif6up(ppp_pcb *pcb) {
1226
1227   pcb->if6_up = 1;
1228   pcb->err_code = PPPERR_NONE;
1229   netif_set_link_up(pcb->netif);
1230
1231   PPPDEBUG(LOG_DEBUG, ("sif6up[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code));
1232   pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb);
1233   return 1;
1234 }
1235
1236 /********************************************************************
1237  *
1238  * sif6down - Disable the indicated protocol and config the interface
1239  *            down if there are no remaining protocols.
1240  */
1241 int sif6down(ppp_pcb *pcb) {
1242
1243   pcb->if6_up = 0;
1244
1245   if (1
1246 #if PPP_IPV4_SUPPORT
1247    /* set the interface down if IPv4 is down as well */
1248    && !pcb->if4_up
1249 #endif /* PPP_IPV4_SUPPORT */
1250   ) {
1251     /* make sure the netif link callback is called */
1252     netif_set_link_down(pcb->netif);
1253   }
1254   PPPDEBUG(LOG_DEBUG, ("sif6down[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code));
1255   return 1;
1256 }
1257 #endif /* PPP_IPV6_SUPPORT */
1258
1259 #if DEMAND_SUPPORT
1260 /*
1261  * sifnpmode - Set the mode for handling packets for a given NP.
1262  */
1263 int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode) {
1264   LWIP_UNUSED_ARG(pcb);
1265   LWIP_UNUSED_ARG(proto);
1266   LWIP_UNUSED_ARG(mode);
1267   return 0;
1268 }
1269 #endif /* DEMAND_SUPPORT */
1270
1271 /*
1272  * netif_set_mtu - set the MTU on the PPP network interface.
1273  */
1274 void netif_set_mtu(ppp_pcb *pcb, int mtu) {
1275
1276   pcb->netif->mtu = mtu;
1277   PPPDEBUG(LOG_INFO, ("netif_set_mtu[%d]: mtu=%d\n", pcb->netif->num, mtu));
1278 }
1279
1280 /*
1281  * netif_get_mtu - get PPP interface MTU
1282  */
1283 int netif_get_mtu(ppp_pcb *pcb) {
1284
1285   return pcb->netif->mtu;
1286 }
1287
1288 #if CCP_SUPPORT
1289 #if 0 /* unused */
1290 /*
1291  * ccp_test - whether a given compression method is acceptable for use.
1292  */
1293 int
1294 ccp_test(ppp_pcb *pcb, u_char *opt_ptr, int opt_len, int for_transmit)
1295 {
1296   LWIP_UNUSED_ARG(pcb);
1297   LWIP_UNUSED_ARG(opt_ptr);
1298   LWIP_UNUSED_ARG(opt_len);
1299   LWIP_UNUSED_ARG(for_transmit);
1300   return -1;
1301 }
1302 #endif /* unused */
1303
1304 /*
1305  * ccp_set - inform about the current state of CCP.
1306  */
1307 void
1308 ccp_set(ppp_pcb *pcb, u8_t isopen, u8_t isup, u8_t receive_method, u8_t transmit_method)
1309 {
1310   pcb->ccp_is_open = isopen;
1311   pcb->ccp_is_up = isup;
1312   pcb->ccp_receive_method = receive_method;
1313   pcb->ccp_transmit_method = transmit_method;
1314   PPPDEBUG(LOG_DEBUG, ("ccp_set[%d]: is_open=%d, is_up=%d, receive_method=%u, transmit_method=%u\n",
1315            pcb->netif->num, isopen, isup, receive_method, transmit_method));
1316 }
1317
1318 void
1319 ccp_reset_comp(ppp_pcb *pcb)
1320 {
1321   switch (pcb->ccp_transmit_method) {
1322 #if MPPE_SUPPORT
1323   case CI_MPPE:
1324     mppe_comp_reset(pcb, &pcb->mppe_comp);
1325     break;
1326 #endif /* MPPE_SUPPORT */
1327   default:
1328     break;
1329   }
1330 }
1331
1332 void
1333 ccp_reset_decomp(ppp_pcb *pcb)
1334 {
1335   switch (pcb->ccp_receive_method) {
1336 #if MPPE_SUPPORT
1337   case CI_MPPE:
1338     mppe_decomp_reset(pcb, &pcb->mppe_decomp);
1339     break;
1340 #endif /* MPPE_SUPPORT */
1341   default:
1342     break;
1343   }
1344 }
1345
1346 #if 0 /* unused */
1347 /*
1348  * ccp_fatal_error - returns 1 if decompression was disabled as a
1349  * result of an error detected after decompression of a packet,
1350  * 0 otherwise.  This is necessary because of patent nonsense.
1351  */
1352 int
1353 ccp_fatal_error(ppp_pcb *pcb)
1354 {
1355   LWIP_UNUSED_ARG(pcb);
1356   return 1;
1357 }
1358 #endif /* unused */
1359 #endif /* CCP_SUPPORT */
1360
1361 #if PPP_IDLETIMELIMIT
1362 /********************************************************************
1363  *
1364  * get_idle_time - return how long the link has been idle.
1365  */
1366 int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip) {
1367   /* FIXME: add idle time support and make it optional */
1368   LWIP_UNUSED_ARG(pcb);
1369   LWIP_UNUSED_ARG(ip);
1370   return 1;
1371 }
1372 #endif /* PPP_IDLETIMELIMIT */
1373
1374 #if DEMAND_SUPPORT
1375 /********************************************************************
1376  *
1377  * get_loop_output - get outgoing packets from the ppp device,
1378  * and detect when we want to bring the real link up.
1379  * Return value is 1 if we need to bring up the link, 0 otherwise.
1380  */
1381 int get_loop_output(void) {
1382   return 0;
1383 }
1384 #endif /* DEMAND_SUPPORT */
1385
1386 #if PPP_PROTOCOLNAME
1387 /* List of protocol names, to make our messages a little more informative. */
1388 struct protocol_list {
1389   u_short proto;
1390   const char *name;
1391 } protocol_list[] = {
1392   { 0x21, "IP" },
1393   { 0x23, "OSI Network Layer" },
1394   { 0x25, "Xerox NS IDP" },
1395   { 0x27, "DECnet Phase IV" },
1396   { 0x29, "Appletalk" },
1397   { 0x2b, "Novell IPX" },
1398   { 0x2d, "VJ compressed TCP/IP" },
1399   { 0x2f, "VJ uncompressed TCP/IP" },
1400   { 0x31, "Bridging PDU" },
1401   { 0x33, "Stream Protocol ST-II" },
1402   { 0x35, "Banyan Vines" },
1403   { 0x39, "AppleTalk EDDP" },
1404   { 0x3b, "AppleTalk SmartBuffered" },
1405   { 0x3d, "Multi-Link" },
1406   { 0x3f, "NETBIOS Framing" },
1407   { 0x41, "Cisco Systems" },
1408   { 0x43, "Ascom Timeplex" },
1409   { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" },
1410   { 0x47, "DCA Remote Lan" },
1411   { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" },
1412   { 0x4b, "SNA over 802.2" },
1413   { 0x4d, "SNA" },
1414   { 0x4f, "IP6 Header Compression" },
1415   { 0x51, "KNX Bridging Data" },
1416   { 0x53, "Encryption" },
1417   { 0x55, "Individual Link Encryption" },
1418   { 0x57, "IPv6" },
1419   { 0x59, "PPP Muxing" },
1420   { 0x5b, "Vendor-Specific Network Protocol" },
1421   { 0x61, "RTP IPHC Full Header" },
1422   { 0x63, "RTP IPHC Compressed TCP" },
1423   { 0x65, "RTP IPHC Compressed non-TCP" },
1424   { 0x67, "RTP IPHC Compressed UDP 8" },
1425   { 0x69, "RTP IPHC Compressed RTP 8" },
1426   { 0x6f, "Stampede Bridging" },
1427   { 0x73, "MP+" },
1428   { 0xc1, "NTCITS IPI" },
1429   { 0xfb, "single-link compression" },
1430   { 0xfd, "Compressed Datagram" },
1431   { 0x0201, "802.1d Hello Packets" },
1432   { 0x0203, "IBM Source Routing BPDU" },
1433   { 0x0205, "DEC LANBridge100 Spanning Tree" },
1434   { 0x0207, "Cisco Discovery Protocol" },
1435   { 0x0209, "Netcs Twin Routing" },
1436   { 0x020b, "STP - Scheduled Transfer Protocol" },
1437   { 0x020d, "EDP - Extreme Discovery Protocol" },
1438   { 0x0211, "Optical Supervisory Channel Protocol" },
1439   { 0x0213, "Optical Supervisory Channel Protocol" },
1440   { 0x0231, "Luxcom" },
1441   { 0x0233, "Sigma Network Systems" },
1442   { 0x0235, "Apple Client Server Protocol" },
1443   { 0x0281, "MPLS Unicast" },
1444   { 0x0283, "MPLS Multicast" },
1445   { 0x0285, "IEEE p1284.4 standard - data packets" },
1446   { 0x0287, "ETSI TETRA Network Protocol Type 1" },
1447   { 0x0289, "Multichannel Flow Treatment Protocol" },
1448   { 0x2063, "RTP IPHC Compressed TCP No Delta" },
1449   { 0x2065, "RTP IPHC Context State" },
1450   { 0x2067, "RTP IPHC Compressed UDP 16" },
1451   { 0x2069, "RTP IPHC Compressed RTP 16" },
1452   { 0x4001, "Cray Communications Control Protocol" },
1453   { 0x4003, "CDPD Mobile Network Registration Protocol" },
1454   { 0x4005, "Expand accelerator protocol" },
1455   { 0x4007, "ODSICP NCP" },
1456   { 0x4009, "DOCSIS DLL" },
1457   { 0x400B, "Cetacean Network Detection Protocol" },
1458   { 0x4021, "Stacker LZS" },
1459   { 0x4023, "RefTek Protocol" },
1460   { 0x4025, "Fibre Channel" },
1461   { 0x4027, "EMIT Protocols" },
1462   { 0x405b, "Vendor-Specific Protocol (VSP)" },
1463   { 0x8021, "Internet Protocol Control Protocol" },
1464   { 0x8023, "OSI Network Layer Control Protocol" },
1465   { 0x8025, "Xerox NS IDP Control Protocol" },
1466   { 0x8027, "DECnet Phase IV Control Protocol" },
1467   { 0x8029, "Appletalk Control Protocol" },
1468   { 0x802b, "Novell IPX Control Protocol" },
1469   { 0x8031, "Bridging NCP" },
1470   { 0x8033, "Stream Protocol Control Protocol" },
1471   { 0x8035, "Banyan Vines Control Protocol" },
1472   { 0x803d, "Multi-Link Control Protocol" },
1473   { 0x803f, "NETBIOS Framing Control Protocol" },
1474   { 0x8041, "Cisco Systems Control Protocol" },
1475   { 0x8043, "Ascom Timeplex" },
1476   { 0x8045, "Fujitsu LBLB Control Protocol" },
1477   { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" },
1478   { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" },
1479   { 0x804b, "SNA over 802.2 Control Protocol" },
1480   { 0x804d, "SNA Control Protocol" },
1481   { 0x804f, "IP6 Header Compression Control Protocol" },
1482   { 0x8051, "KNX Bridging Control Protocol" },
1483   { 0x8053, "Encryption Control Protocol" },
1484   { 0x8055, "Individual Link Encryption Control Protocol" },
1485   { 0x8057, "IPv6 Control Protocol" },
1486   { 0x8059, "PPP Muxing Control Protocol" },
1487   { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" },
1488   { 0x806f, "Stampede Bridging Control Protocol" },
1489   { 0x8073, "MP+ Control Protocol" },
1490   { 0x80c1, "NTCITS IPI Control Protocol" },
1491   { 0x80fb, "Single Link Compression Control Protocol" },
1492   { 0x80fd, "Compression Control Protocol" },
1493   { 0x8207, "Cisco Discovery Protocol Control" },
1494   { 0x8209, "Netcs Twin Routing" },
1495   { 0x820b, "STP - Control Protocol" },
1496   { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" },
1497   { 0x8235, "Apple Client Server Protocol Control" },
1498   { 0x8281, "MPLSCP" },
1499   { 0x8285, "IEEE p1284.4 standard - Protocol Control" },
1500   { 0x8287, "ETSI TETRA TNP1 Control Protocol" },
1501   { 0x8289, "Multichannel Flow Treatment Protocol" },
1502   { 0xc021, "Link Control Protocol" },
1503   { 0xc023, "Password Authentication Protocol" },
1504   { 0xc025, "Link Quality Report" },
1505   { 0xc027, "Shiva Password Authentication Protocol" },
1506   { 0xc029, "CallBack Control Protocol (CBCP)" },
1507   { 0xc02b, "BACP Bandwidth Allocation Control Protocol" },
1508   { 0xc02d, "BAP" },
1509   { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" },
1510   { 0xc081, "Container Control Protocol" },
1511   { 0xc223, "Challenge Handshake Authentication Protocol" },
1512   { 0xc225, "RSA Authentication Protocol" },
1513   { 0xc227, "Extensible Authentication Protocol" },
1514   { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" },
1515   { 0xc26f, "Stampede Bridging Authorization Protocol" },
1516   { 0xc281, "Proprietary Authentication Protocol" },
1517   { 0xc283, "Proprietary Authentication Protocol" },
1518   { 0xc481, "Proprietary Node ID Authentication Protocol" },
1519   { 0, NULL },
1520 };
1521
1522 /*
1523  * protocol_name - find a name for a PPP protocol.
1524  */
1525 const char * protocol_name(int proto) {
1526   struct protocol_list *lp;
1527
1528   for (lp = protocol_list; lp->proto != 0; ++lp) {
1529     if (proto == lp->proto) {
1530       return lp->name;
1531     }
1532   }
1533   return NULL;
1534 }
1535 #endif /* PPP_PROTOCOLNAME */
1536
1537 #if PPP_STATS_SUPPORT
1538
1539 /* ---- Note on PPP Stats support ----
1540  *
1541  * The one willing link stats support should add the get_ppp_stats()
1542  * to fetch statistics from lwIP.
1543  */
1544
1545 /*
1546  * reset_link_stats - "reset" stats when link goes up.
1547  */
1548 void reset_link_stats(int u) {
1549   if (!get_ppp_stats(u, &old_link_stats)) {
1550     return;
1551   }
1552   gettimeofday(&start_time, NULL);
1553 }
1554
1555 /*
1556  * update_link_stats - get stats at link termination.
1557  */
1558 void update_link_stats(int u) {
1559   struct timeval now;
1560   char numbuf[32];
1561
1562   if (!get_ppp_stats(u, &link_stats) || gettimeofday(&now, NULL) < 0) {
1563     return;
1564   }
1565   link_connect_time = now.tv_sec - start_time.tv_sec;
1566   link_stats_valid = 1;
1567
1568   link_stats.bytes_in  -= old_link_stats.bytes_in;
1569   link_stats.bytes_out -= old_link_stats.bytes_out;
1570   link_stats.pkts_in   -= old_link_stats.pkts_in;
1571   link_stats.pkts_out  -= old_link_stats.pkts_out;
1572 }
1573
1574 void print_link_stats() {
1575   /*
1576    * Print connect time and statistics.
1577    */
1578   if (link_stats_valid) {
1579     int t = (link_connect_time + 5) / 6;    /* 1/10ths of minutes */
1580     info("Connect time %d.%d minutes.", t/10, t%10);
1581     info("Sent %u bytes, received %u bytes.", link_stats.bytes_out, link_stats.bytes_in);
1582     link_stats_valid = 0;
1583   }
1584 }
1585 #endif /* PPP_STATS_SUPPORT */
1586
1587 #endif /* PPP_SUPPORT */