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