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