Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
ppp.c
00001 /***************************************************************************** 00002 * ppp.c - Network Point to Point Protocol program file. 00003 * 00004 * Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. 00005 * portions Copyright (c) 1997 by Global Election Systems Inc. 00006 * 00007 * The authors hereby grant permission to use, copy, modify, distribute, 00008 * and license this software and its documentation for any purpose, provided 00009 * that existing copyright notices are retained in all copies and that this 00010 * notice and the following disclaimer are included verbatim in any 00011 * distributions. No written agreement, license, or royalty fee is required 00012 * for any of the authorized uses. 00013 * 00014 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR 00015 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00016 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00017 * IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00018 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00019 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00020 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00021 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00023 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00024 * 00025 ****************************************************************************** 00026 * REVISION HISTORY 00027 * 00028 * 03-01-01 Marc Boucher <marc@mbsi.ca> 00029 * Ported to lwIP. 00030 * 97-11-05 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc. 00031 * Original. 00032 *****************************************************************************/ 00033 00034 /* 00035 * ppp_defs.h - PPP definitions. 00036 * 00037 * if_pppvar.h - private structures and declarations for PPP. 00038 * 00039 * Copyright (c) 1994 The Australian National University. 00040 * All rights reserved. 00041 * 00042 * Permission to use, copy, modify, and distribute this software and its 00043 * documentation is hereby granted, provided that the above copyright 00044 * notice appears in all copies. This software is provided without any 00045 * warranty, express or implied. The Australian National University 00046 * makes no representations about the suitability of this software for 00047 * any purpose. 00048 * 00049 * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY 00050 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 00051 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 00052 * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY 00053 * OF SUCH DAMAGE. 00054 * 00055 * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, 00056 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00057 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 00058 * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO 00059 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, 00060 * OR MODIFICATIONS. 00061 */ 00062 00063 /* 00064 * if_ppp.h - Point-to-Point Protocol definitions. 00065 * 00066 * Copyright (c) 1989 Carnegie Mellon University. 00067 * All rights reserved. 00068 * 00069 * Redistribution and use in source and binary forms are permitted 00070 * provided that the above copyright notice and this paragraph are 00071 * duplicated in all such forms and that any documentation, 00072 * advertising materials, and other materials related to such 00073 * distribution and use acknowledge that the software was developed 00074 * by Carnegie Mellon University. The name of the 00075 * University may not be used to endorse or promote products derived 00076 * from this software without specific prior written permission. 00077 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 00078 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 00079 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00080 */ 00081 00082 /** 00083 * @defgroup ppp PPP 00084 * @ingroup netifs 00085 * @verbinclude "ppp.txt" 00086 */ 00087 00088 #include "ppp_opts.h" 00089 #if PPP_SUPPORT /* don't build if not configured for use in ppp_opts.h */ 00090 00091 #include "ppp_impl.h" 00092 #include "pppos.h" 00093 00094 #include "fsm.h" 00095 #include "lcp.h" 00096 #include "magic.h" 00097 00098 #if PAP_SUPPORT 00099 #include "upap.h" 00100 #endif /* PAP_SUPPORT */ 00101 #if CHAP_SUPPORT 00102 #include "chap-new.h" 00103 #endif /* CHAP_SUPPORT */ 00104 #if EAP_SUPPORT 00105 #include "eap.h" 00106 #endif /* EAP_SUPPORT */ 00107 #if CCP_SUPPORT 00108 #include "ccp.h" 00109 #endif /* CCP_SUPPORT */ 00110 #if MPPE_SUPPORT 00111 #include "mppe.h" 00112 #endif /* MPPE_SUPPORT */ 00113 #if ECP_SUPPORT 00114 #include "ecp.h" 00115 #endif /* EAP_SUPPORT */ 00116 #if VJ_SUPPORT 00117 #include "vj.h" 00118 #endif /* VJ_SUPPORT */ 00119 #if PPP_IPV4_SUPPORT 00120 #include "ipcp.h" 00121 #endif /* PPP_IPV4_SUPPORT */ 00122 #if PPP_IPV6_SUPPORT 00123 #include "ipv6cp.h" 00124 #endif /* PPP_IPV6_SUPPORT */ 00125 00126 /*************************/ 00127 /*** LOCAL DEFINITIONS ***/ 00128 /*************************/ 00129 00130 /* Memory pools */ 00131 #if PPPOS_SUPPORT 00132 PPP_MEMPOOL_PROTOTYPE(PPPOS_PCB); 00133 #endif 00134 #if PPPOE_SUPPORT 00135 PPP_MEMPOOL_PROTOTYPE(PPPOE_IF); 00136 #endif 00137 #if PPPOL2TP_SUPPORT 00138 PPP_MEMPOOL_PROTOTYPE(PPPOL2TP_PCB); 00139 #endif 00140 #if PPP_API && PPP_MPU_COMPATIBLE 00141 PPP_MEMPOOL_PROTOTYPE(PPPAPI_MSG); 00142 #endif 00143 PPP_MEMPOOL_DECLARE(PPP_PCB, MEMP_NUM_PPP_PCB, sizeof(ppp_pcb), "PPP_PCB") 00144 00145 /* FIXME: add stats per PPP session */ 00146 #if PPP_STATS_SUPPORT 00147 static struct timeval start_time; /* Time when link was started. */ 00148 static struct pppd_stats old_link_stats; 00149 struct pppd_stats link_stats; 00150 unsigned link_connect_time; 00151 int link_stats_valid; 00152 #endif /* PPP_STATS_SUPPORT */ 00153 00154 /* 00155 * PPP Data Link Layer "protocol" table. 00156 * One entry per supported protocol. 00157 * The last entry must be NULL. 00158 */ 00159 const struct protent* const protocols[] = { 00160 &lcp_protent, 00161 #if PAP_SUPPORT 00162 &pap_protent, 00163 #endif /* PAP_SUPPORT */ 00164 #if CHAP_SUPPORT 00165 &chap_protent, 00166 #endif /* CHAP_SUPPORT */ 00167 #if CBCP_SUPPORT 00168 &cbcp_protent, 00169 #endif /* CBCP_SUPPORT */ 00170 #if PPP_IPV4_SUPPORT 00171 &ipcp_protent, 00172 #endif /* PPP_IPV4_SUPPORT */ 00173 #if PPP_IPV6_SUPPORT 00174 &ipv6cp_protent, 00175 #endif /* PPP_IPV6_SUPPORT */ 00176 #if CCP_SUPPORT 00177 &ccp_protent, 00178 #endif /* CCP_SUPPORT */ 00179 #if ECP_SUPPORT 00180 &ecp_protent, 00181 #endif /* ECP_SUPPORT */ 00182 #ifdef AT_CHANGE 00183 &atcp_protent, 00184 #endif /* AT_CHANGE */ 00185 #if EAP_SUPPORT 00186 &eap_protent, 00187 #endif /* EAP_SUPPORT */ 00188 NULL 00189 }; 00190 00191 /* Prototypes for procedures local to this file. */ 00192 static void ppp_do_connect(void *arg); 00193 static err_t ppp_netif_init_cb(struct netif *netif); 00194 #if PPP_IPV4_SUPPORT 00195 static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, const ip4_addr_t *ipaddr); 00196 #endif /* PPP_IPV4_SUPPORT */ 00197 #if PPP_IPV6_SUPPORT 00198 static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, const ip6_addr_t *ipaddr); 00199 #endif /* PPP_IPV6_SUPPORT */ 00200 static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protocol); 00201 00202 /***********************************/ 00203 /*** PUBLIC FUNCTION DEFINITIONS ***/ 00204 /***********************************/ 00205 #if PPP_AUTH_SUPPORT 00206 void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) { 00207 #if PAP_SUPPORT 00208 pcb->settings.refuse_pap = !(authtype & PPPAUTHTYPE_PAP); 00209 #endif /* PAP_SUPPORT */ 00210 #if CHAP_SUPPORT 00211 pcb->settings.refuse_chap = !(authtype & PPPAUTHTYPE_CHAP); 00212 #if MSCHAP_SUPPORT 00213 pcb->settings.refuse_mschap = !(authtype & PPPAUTHTYPE_MSCHAP); 00214 pcb->settings.refuse_mschap_v2 = !(authtype & PPPAUTHTYPE_MSCHAP_V2); 00215 #endif /* MSCHAP_SUPPORT */ 00216 #endif /* CHAP_SUPPORT */ 00217 #if EAP_SUPPORT 00218 pcb->settings.refuse_eap = !(authtype & PPPAUTHTYPE_EAP); 00219 #endif /* EAP_SUPPORT */ 00220 pcb->settings.user = user; 00221 pcb->settings.passwd = passwd; 00222 } 00223 #endif /* PPP_AUTH_SUPPORT */ 00224 00225 #if MPPE_SUPPORT 00226 /* Set MPPE configuration */ 00227 void ppp_set_mppe(ppp_pcb *pcb, u8_t flags) { 00228 if (flags == PPP_MPPE_DISABLE) { 00229 pcb->settings.require_mppe = 0; 00230 return; 00231 } 00232 00233 pcb->settings.require_mppe = 1; 00234 pcb->settings.refuse_mppe_stateful = !(flags & PPP_MPPE_ALLOW_STATEFUL); 00235 pcb->settings.refuse_mppe_40 = !!(flags & PPP_MPPE_REFUSE_40); 00236 pcb->settings.refuse_mppe_128 = !!(flags & PPP_MPPE_REFUSE_128); 00237 } 00238 #endif /* MPPE_SUPPORT */ 00239 00240 #if PPP_NOTIFY_PHASE 00241 void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb) { 00242 pcb->notify_phase_cb = notify_phase_cb; 00243 notify_phase_cb(pcb, pcb->phase, pcb->ctx_cb); 00244 } 00245 #endif /* PPP_NOTIFY_PHASE */ 00246 00247 /* 00248 * Initiate a PPP connection. 00249 * 00250 * This can only be called if PPP is in the dead phase. 00251 * 00252 * Holdoff is the time to wait (in seconds) before initiating 00253 * the connection. 00254 * 00255 * If this port connects to a modem, the modem connection must be 00256 * established before calling this. 00257 */ 00258 err_t ppp_connect(ppp_pcb *pcb, u16_t holdoff) { 00259 if (pcb->phase != PPP_PHASE_DEAD) { 00260 return ERR_ALREADY; 00261 } 00262 00263 PPPDEBUG(LOG_DEBUG, ("ppp_connect[%d]: holdoff=%d\n", pcb->netif->num, holdoff)); 00264 00265 magic_randomize(); 00266 00267 if (holdoff == 0) { 00268 ppp_do_connect(pcb); 00269 return ERR_OK; 00270 } 00271 00272 new_phase(pcb, PPP_PHASE_HOLDOFF); 00273 sys_timeout((u32_t)(holdoff*1000), ppp_do_connect, pcb); 00274 return ERR_OK; 00275 } 00276 00277 #if PPP_SERVER 00278 /* 00279 * Listen for an incoming PPP connection. 00280 * 00281 * This can only be called if PPP is in the dead phase. 00282 * 00283 * If this port connects to a modem, the modem connection must be 00284 * established before calling this. 00285 */ 00286 err_t ppp_listen(ppp_pcb *pcb) { 00287 if (pcb->phase != PPP_PHASE_DEAD) { 00288 return ERR_ALREADY; 00289 } 00290 00291 PPPDEBUG(LOG_DEBUG, ("ppp_listen[%d]\n", pcb->netif->num)); 00292 00293 magic_randomize(); 00294 00295 if (pcb->link_cb->listen) { 00296 new_phase(pcb, PPP_PHASE_INITIALIZE); 00297 pcb->link_cb->listen(pcb, pcb->link_ctx_cb); 00298 return ERR_OK; 00299 } 00300 return ERR_IF; 00301 } 00302 #endif /* PPP_SERVER */ 00303 00304 /* 00305 * Initiate the end of a PPP connection. 00306 * Any outstanding packets in the queues are dropped. 00307 * 00308 * Setting nocarrier to 1 close the PPP connection without initiating the 00309 * shutdown procedure. Always using nocarrier = 0 is still recommended, 00310 * this is going to take a little longer time if your link is down, but 00311 * is a safer choice for the PPP state machine. 00312 * 00313 * Return 0 on success, an error code on failure. 00314 */ 00315 err_t 00316 ppp_close(ppp_pcb *pcb, u8_t nocarrier) 00317 { 00318 pcb->err_code = PPPERR_USER; 00319 00320 /* holdoff phase, cancel the reconnection */ 00321 if (pcb->phase == PPP_PHASE_HOLDOFF) { 00322 sys_untimeout(ppp_do_connect, pcb); 00323 new_phase(pcb, PPP_PHASE_DEAD); 00324 } 00325 00326 /* dead phase, nothing to do, call the status callback to be consistent */ 00327 if (pcb->phase == PPP_PHASE_DEAD) { 00328 pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); 00329 return ERR_OK; 00330 } 00331 00332 /* Already terminating, nothing to do */ 00333 if (pcb->phase >= PPP_PHASE_TERMINATE) { 00334 return ERR_INPROGRESS; 00335 } 00336 00337 /* LCP not open, close link protocol */ 00338 if (pcb->phase < PPP_PHASE_ESTABLISH) { 00339 new_phase(pcb, PPP_PHASE_DISCONNECT); 00340 ppp_link_terminated(pcb); 00341 return ERR_OK; 00342 } 00343 00344 /* 00345 * Only accept carrier lost signal on the stable running phase in order 00346 * to prevent changing the PPP phase FSM in transition phases. 00347 * 00348 * Always using nocarrier = 0 is still recommended, this is going to 00349 * take a little longer time, but is a safer choice from FSM point of view. 00350 */ 00351 if (nocarrier && pcb->phase == PPP_PHASE_RUNNING) { 00352 PPPDEBUG(LOG_DEBUG, ("ppp_close[%d]: carrier lost -> lcp_lowerdown\n", pcb->netif->num)); 00353 lcp_lowerdown(pcb); 00354 /* forced link termination, this will force link protocol to disconnect. */ 00355 link_terminated(pcb); 00356 return ERR_OK; 00357 } 00358 00359 /* Disconnect */ 00360 PPPDEBUG(LOG_DEBUG, ("ppp_close[%d]: kill_link -> lcp_close\n", pcb->netif->num)); 00361 /* LCP soft close request. */ 00362 lcp_close(pcb, "User request"); 00363 return ERR_OK; 00364 } 00365 00366 /* 00367 * Release the control block. 00368 * 00369 * This can only be called if PPP is in the dead phase. 00370 * 00371 * You must use ppp_close() before if you wish to terminate 00372 * an established PPP session. 00373 * 00374 * Return 0 on success, an error code on failure. 00375 */ 00376 err_t ppp_free(ppp_pcb *pcb) { 00377 err_t err; 00378 if (pcb->phase != PPP_PHASE_DEAD) { 00379 return ERR_CONN; 00380 } 00381 00382 PPPDEBUG(LOG_DEBUG, ("ppp_free[%d]\n", pcb->netif->num)); 00383 00384 ppp_netif_remove(pcb->netif); 00385 00386 err = pcb->link_cb->free(pcb, pcb->link_ctx_cb); 00387 00388 MEMPOOL_FREE(PPP_PCB, pcb); 00389 return err; 00390 } 00391 00392 /* Get and set parameters for the given connection. 00393 * Return 0 on success, an error code on failure. */ 00394 err_t 00395 ppp_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg) 00396 { 00397 if (pcb == NULL) { 00398 return ERR_VAL; 00399 } 00400 00401 switch(cmd) { 00402 case PPPCTLG_UPSTATUS: /* Get the PPP up status. */ 00403 if (!arg) { 00404 goto fail; 00405 } 00406 *(int *)arg = (int)(0 00407 #if PPP_IPV4_SUPPORT 00408 || pcb->if4_up 00409 #endif /* PPP_IPV4_SUPPORT */ 00410 #if PPP_IPV6_SUPPORT 00411 || pcb->if6_up 00412 #endif /* PPP_IPV6_SUPPORT */ 00413 ); 00414 return ERR_OK; 00415 00416 case PPPCTLG_ERRCODE: /* Get the PPP error code. */ 00417 if (!arg) { 00418 goto fail; 00419 } 00420 *(int *)arg = (int)(pcb->err_code); 00421 return ERR_OK; 00422 00423 default: 00424 goto fail; 00425 } 00426 00427 fail: 00428 return ERR_VAL; 00429 } 00430 00431 00432 /**********************************/ 00433 /*** LOCAL FUNCTION DEFINITIONS ***/ 00434 /**********************************/ 00435 00436 static void ppp_do_connect(void *arg) { 00437 ppp_pcb *pcb = (ppp_pcb*)arg; 00438 00439 PPP_ASSERT("pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF", pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF); 00440 00441 new_phase(pcb, PPP_PHASE_INITIALIZE); 00442 pcb->link_cb->connect(pcb, pcb->link_ctx_cb); 00443 } 00444 00445 /* 00446 * ppp_netif_init_cb - netif init callback 00447 */ 00448 static err_t ppp_netif_init_cb(struct netif *netif) { 00449 #if PPP_IPV4_SUPPORT 00450 netif->output = ppp_netif_output_ip4; 00451 #endif /* PPP_IPV4_SUPPORT */ 00452 #if PPP_IPV6_SUPPORT 00453 netif->output_ip6 = ppp_netif_output_ip6; 00454 #endif /* PPP_IPV6_SUPPORT */ 00455 #if PPP_NETIF_HOSTNAME 00456 /* @todo: Initialize interface hostname */ 00457 /* netif_set_hostname(netif, "ppp"); */ 00458 #endif /* PPP_NETIF_HOSTNAME */ 00459 return ERR_OK; 00460 } 00461 00462 #if PPP_IPV4_SUPPORT 00463 /* 00464 * Send an IPv4 packet on the given connection. 00465 */ 00466 static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, const ip4_addr_t *ipaddr) { 00467 PPP_UNUSED_ARG(ipaddr); 00468 return ppp_netif_output(netif, pb, PPP_IP); 00469 } 00470 #endif /* PPP_IPV4_SUPPORT */ 00471 00472 #if PPP_IPV6_SUPPORT 00473 /* 00474 * Send an IPv6 packet on the given connection. 00475 */ 00476 static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, const ip6_addr_t *ipaddr) { 00477 PPP_UNUSED_ARG(ipaddr); 00478 return ppp_netif_output(netif, pb, PPP_IPV6); 00479 } 00480 #endif /* PPP_IPV6_SUPPORT */ 00481 00482 static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protocol) { 00483 ppp_pcb *pcb = (ppp_pcb*)netif->state; 00484 err_t err; 00485 struct pbuf *fpb = NULL; 00486 00487 /* Check that the link is up. */ 00488 if (0 00489 #if PPP_IPV4_SUPPORT 00490 || (protocol == PPP_IP && !pcb->if4_up) 00491 #endif /* PPP_IPV4_SUPPORT */ 00492 #if PPP_IPV6_SUPPORT 00493 || (protocol == PPP_IPV6 && !pcb->if6_up) 00494 #endif /* PPP_IPV6_SUPPORT */ 00495 ) { 00496 PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pcb->netif->num)); 00497 goto err_rte_drop; 00498 } 00499 00500 #if MPPE_SUPPORT 00501 /* If MPPE is required, refuse any IP packet until we are able to crypt them. */ 00502 if (pcb->settings.require_mppe && pcb->ccp_transmit_method != CI_MPPE) { 00503 PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: MPPE required, not up\n", pcb->netif->num)); 00504 goto err_rte_drop; 00505 } 00506 #endif /* MPPE_SUPPORT */ 00507 00508 #if VJ_SUPPORT 00509 /* 00510 * Attempt Van Jacobson header compression if VJ is configured and 00511 * this is an IP packet. 00512 */ 00513 if (protocol == PPP_IP && pcb->vj_enabled) { 00514 switch (vj_compress_tcp(&pcb->vj_comp, &pb)) { 00515 case TYPE_IP: 00516 /* No change... 00517 protocol = PPP_IP; */ 00518 break; 00519 case TYPE_COMPRESSED_TCP: 00520 /* vj_compress_tcp() returns a new allocated pbuf, indicate we should free 00521 * our duplicated pbuf later */ 00522 fpb = pb; 00523 protocol = PPP_VJC_COMP; 00524 break; 00525 case TYPE_UNCOMPRESSED_TCP: 00526 /* vj_compress_tcp() returns a new allocated pbuf, indicate we should free 00527 * our duplicated pbuf later */ 00528 fpb = pb; 00529 protocol = PPP_VJC_UNCOMP; 00530 break; 00531 default: 00532 PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad IP packet\n", pcb->netif->num)); 00533 LINK_STATS_INC(link.proterr); 00534 LINK_STATS_INC(link.drop); 00535 MIB2_STATS_NETIF_INC(pcb->netif, ifoutdiscards); 00536 return ERR_VAL; 00537 } 00538 } 00539 #endif /* VJ_SUPPORT */ 00540 00541 #if CCP_SUPPORT 00542 switch (pcb->ccp_transmit_method) { 00543 case 0: 00544 break; /* Don't compress */ 00545 #if MPPE_SUPPORT 00546 case CI_MPPE: 00547 if ((err = mppe_compress(pcb, &pcb->mppe_comp, &pb, protocol)) != ERR_OK) { 00548 LINK_STATS_INC(link.memerr); 00549 LINK_STATS_INC(link.drop); 00550 MIB2_STATS_NETIF_INC(netif, ifoutdiscards); 00551 goto err; 00552 } 00553 /* if VJ compressor returned a new allocated pbuf, free it */ 00554 if (fpb) { 00555 ppp_memory_buffer_free(fpb); 00556 } 00557 /* mppe_compress() returns a new allocated pbuf, indicate we should free 00558 * our duplicated pbuf later */ 00559 fpb = pb; 00560 protocol = PPP_COMP; 00561 break; 00562 #endif /* MPPE_SUPPORT */ 00563 default: 00564 PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: bad CCP transmit method\n", pcb->netif->num)); 00565 goto err_rte_drop; /* Cannot really happen, we only negotiate what we are able to do */ 00566 } 00567 #endif /* CCP_SUPPORT */ 00568 00569 err = pcb->link_cb->netif_output(pcb, pcb->link_ctx_cb, pb, protocol); 00570 goto err; 00571 00572 err_rte_drop: 00573 err = ERR_RTE; 00574 LINK_STATS_INC(link.rterr); 00575 LINK_STATS_INC(link.drop); 00576 MIB2_STATS_NETIF_INC(netif, ifoutdiscards); 00577 err: 00578 if (fpb) { 00579 ppp_memory_buffer_free(fpb); 00580 } 00581 return err; 00582 } 00583 00584 /************************************/ 00585 /*** PRIVATE FUNCTION DEFINITIONS ***/ 00586 /************************************/ 00587 00588 /* Initialize the PPP subsystem. */ 00589 int ppp_init(void) 00590 { 00591 #if PPPOS_SUPPORT 00592 PPP_MEMPOOL_INIT(PPPOS_PCB); 00593 #endif 00594 #if PPPOE_SUPPORT 00595 PPP_MEMPOOL_INIT(PPPOE_IF); 00596 #endif 00597 #if PPPOL2TP_SUPPORT 00598 PPP_MEMPOOL_INIT(PPPOL2TP_PCB); 00599 #endif 00600 #if PPP_API && PPP_MPU_COMPATIBLE 00601 PPP_MEMPOOL_INIT(PPPAPI_MSG); 00602 #endif 00603 00604 PPP_MEMPOOL_INIT(PPP_PCB); 00605 00606 /* 00607 * Initialize magic number generator now so that protocols may 00608 * use magic numbers in initialization. 00609 */ 00610 magic_init(); 00611 00612 return 0; 00613 } 00614 00615 /* 00616 * Create a new PPP control block. 00617 * 00618 * This initializes the PPP control block but does not 00619 * attempt to negotiate the LCP session. 00620 * 00621 * Return a new PPP connection control block pointer 00622 * on success or a null pointer on failure. 00623 */ 00624 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) { 00625 ppp_pcb *pcb; 00626 const struct protent *protp; 00627 int i; 00628 00629 /* PPP is single-threaded: without a callback, 00630 * there is no way to know when the link is up. */ 00631 if (link_status_cb == NULL) { 00632 return NULL; 00633 } 00634 00635 pcb = (ppp_pcb*)MEMPOOL_ALLOC(PPP_PCB); 00636 if (pcb == NULL) { 00637 return NULL; 00638 } 00639 00640 memset(pcb, 0, sizeof(ppp_pcb)); 00641 00642 /* default configuration */ 00643 #if PAP_SUPPORT 00644 pcb->settings.pap_timeout_time = UPAP_DEFTIMEOUT; 00645 pcb->settings.pap_max_transmits = UPAP_DEFTRANSMITS; 00646 #if PPP_SERVER 00647 pcb->settings.pap_req_timeout = UPAP_DEFREQTIME; 00648 #endif /* PPP_SERVER */ 00649 #endif /* PAP_SUPPORT */ 00650 00651 #if CHAP_SUPPORT 00652 pcb->settings.chap_timeout_time = CHAP_DEFTIMEOUT; 00653 pcb->settings.chap_max_transmits = CHAP_DEFTRANSMITS; 00654 #if PPP_SERVER 00655 pcb->settings.chap_rechallenge_time = CHAP_DEFRECHALLENGETIME; 00656 #endif /* PPP_SERVER */ 00657 #endif /* CHAP_SUPPPORT */ 00658 00659 #if EAP_SUPPORT 00660 pcb->settings.eap_req_time = EAP_DEFREQTIME; 00661 pcb->settings.eap_allow_req = EAP_DEFALLOWREQ; 00662 #if PPP_SERVER 00663 pcb->settings.eap_timeout_time = EAP_DEFTIMEOUT; 00664 pcb->settings.eap_max_transmits = EAP_DEFTRANSMITS; 00665 #endif /* PPP_SERVER */ 00666 #endif /* EAP_SUPPORT */ 00667 00668 pcb->settings.lcp_loopbackfail = LCP_DEFLOOPBACKFAIL; 00669 pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; 00670 pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; 00671 00672 pcb->settings.fsm_timeout_time = FSM_DEFTIMEOUT; 00673 pcb->settings.fsm_max_conf_req_transmits = FSM_DEFMAXCONFREQS; 00674 pcb->settings.fsm_max_term_transmits = FSM_DEFMAXTERMREQS; 00675 pcb->settings.fsm_max_nak_loops = FSM_DEFMAXNAKLOOPS; 00676 00677 pcb->netif = pppif; 00678 MIB2_INIT_NETIF(pppif, snmp_ifType_ppp, 0); 00679 if (!ppp_netif_add(pcb->netif, (void *)pcb, ppp_netif_init_cb)) { 00680 MEMPOOL_FREE(PPP_PCB, pcb); 00681 PPPDEBUG(LOG_ERR, ("ppp_new: netif_add failed\n")); 00682 return NULL; 00683 } 00684 00685 pcb->link_cb = callbacks; 00686 pcb->link_ctx_cb = link_ctx_cb; 00687 pcb->link_status_cb = link_status_cb; 00688 pcb->ctx_cb = ctx_cb; 00689 00690 /* 00691 * Initialize each protocol. 00692 */ 00693 for (i = 0; (protp = protocols[i]) != NULL; ++i) { 00694 (*protp->init)(pcb); 00695 } 00696 00697 new_phase(pcb, PPP_PHASE_DEAD); 00698 return pcb; 00699 } 00700 00701 /** Initiate LCP open request */ 00702 void ppp_start(ppp_pcb *pcb) { 00703 PPPDEBUG(LOG_DEBUG, ("ppp_start[%d]\n", pcb->netif->num)); 00704 00705 /* Clean data not taken care by anything else, mostly shared data. */ 00706 #if PPP_STATS_SUPPORT 00707 link_stats_valid = 0; 00708 #endif /* PPP_STATS_SUPPORT */ 00709 #if MPPE_SUPPORT 00710 pcb->mppe_keys_set = 0; 00711 memset(&pcb->mppe_comp, 0, sizeof(pcb->mppe_comp)); 00712 memset(&pcb->mppe_decomp, 0, sizeof(pcb->mppe_decomp)); 00713 #endif /* MPPE_SUPPORT */ 00714 #if VJ_SUPPORT 00715 vj_compress_init(&pcb->vj_comp); 00716 #endif /* VJ_SUPPORT */ 00717 00718 /* Start protocol */ 00719 new_phase(pcb, PPP_PHASE_ESTABLISH); 00720 lcp_open(pcb); 00721 lcp_lowerup(pcb); 00722 PPPDEBUG(LOG_DEBUG, ("ppp_start[%d]: finished\n", pcb->netif->num)); 00723 } 00724 00725 /** Called when link failed to setup */ 00726 void ppp_link_failed(ppp_pcb *pcb) { 00727 PPPDEBUG(LOG_DEBUG, ("ppp_link_failed[%d]\n", pcb->netif->num)); 00728 new_phase(pcb, PPP_PHASE_DEAD); 00729 pcb->err_code = PPPERR_OPEN; 00730 pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); 00731 } 00732 00733 /** Called when link is normally down (i.e. it was asked to end) */ 00734 void ppp_link_end(ppp_pcb *pcb) { 00735 PPPDEBUG(LOG_DEBUG, ("ppp_link_end[%d]\n", pcb->netif->num)); 00736 new_phase(pcb, PPP_PHASE_DEAD); 00737 if (pcb->err_code == PPPERR_NONE) { 00738 pcb->err_code = PPPERR_CONNECT; 00739 } 00740 pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); 00741 } 00742 00743 /* 00744 * Pass the processed input packet to the appropriate handler. 00745 * This function and all handlers run in the context of the tcpip_thread 00746 */ 00747 //void ppp_input(ppp_pcb *pcb, void *pb) 00748 void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { 00749 u16_t protocol; 00750 u8_t *payload; 00751 #if PPP_DEBUG && PPP_PROTOCOLNAME 00752 const char *pname; 00753 #endif /* PPP_DEBUG && PPP_PROTOCOLNAME */ 00754 00755 magic_randomize(); 00756 00757 if (pb->len < 2) { 00758 PPPDEBUG(LOG_ERR, ("ppp_input[%d]: packet too short\n", pcb->netif->num)); 00759 goto drop; 00760 } 00761 00762 payload = (u8_t *)pb->payload; 00763 protocol = (((u8_t *)payload)[0] << 8) | ((u8_t*)payload)[1]; 00764 00765 #if PRINTPKT_SUPPORT 00766 ppp_dump_packet(pcb, "rcvd", (unsigned char *)payload, mem_mngr->get_len(pb)); 00767 #endif /* PRINTPKT_SUPPORT */ 00768 00769 pbuf_remove_header(pb, sizeof(protocol)); 00770 00771 LINK_STATS_INC(link.recv); 00772 MIB2_STATS_NETIF_INC(pcb->netif, ifinucastpkts); 00773 MIB2_STATS_NETIF_ADD(pcb->netif, ifinoctets, pb->len); 00774 00775 /* 00776 * Toss all non-LCP packets unless LCP is OPEN. 00777 */ 00778 if (protocol != PPP_LCP && pcb->lcp_fsm.state != PPP_FSM_OPENED) { 00779 ppp_dbglog("Discarded non-LCP packet when LCP not open"); 00780 goto drop; 00781 } 00782 00783 /* 00784 * Until we get past the authentication phase, toss all packets 00785 * except LCP, LQR and authentication packets. 00786 */ 00787 if (pcb->phase <= PPP_PHASE_AUTHENTICATE 00788 && !(protocol == PPP_LCP 00789 #if LQR_SUPPORT 00790 || protocol == PPP_LQR 00791 #endif /* LQR_SUPPORT */ 00792 #if PAP_SUPPORT 00793 || protocol == PPP_PAP 00794 #endif /* PAP_SUPPORT */ 00795 #if CHAP_SUPPORT 00796 || protocol == PPP_CHAP 00797 #endif /* CHAP_SUPPORT */ 00798 #if EAP_SUPPORT 00799 || protocol == PPP_EAP 00800 #endif /* EAP_SUPPORT */ 00801 )) { 00802 ppp_dbglog("discarding proto 0x%x in phase %d", protocol, pcb->phase); 00803 goto drop; 00804 } 00805 00806 #if CCP_SUPPORT 00807 #if MPPE_SUPPORT 00808 /* 00809 * MPPE is required and unencrypted data has arrived (this 00810 * should never happen!). We should probably drop the link if 00811 * the protocol is in the range of what should be encrypted. 00812 * At the least, we drop this packet. 00813 */ 00814 if (pcb->settings.require_mppe && protocol != PPP_COMP && protocol < 0x8000) { 00815 PPPDEBUG(LOG_ERR, ("ppp_input[%d]: MPPE required, received unencrypted data!\n", pcb->netif->num)); 00816 goto drop; 00817 } 00818 #endif /* MPPE_SUPPORT */ 00819 00820 if (protocol == PPP_COMP) { 00821 u8_t *pl; 00822 00823 switch (pcb->ccp_receive_method) { 00824 #if MPPE_SUPPORT 00825 case CI_MPPE: 00826 if (mppe_decompress(pcb, &pcb->mppe_decomp, &pb) != ERR_OK) { 00827 goto drop; 00828 } 00829 break; 00830 #endif /* MPPE_SUPPORT */ 00831 default: 00832 PPPDEBUG(LOG_ERR, ("ppp_input[%d]: bad CCP receive method\n", pcb->netif->num)); 00833 goto drop; /* Cannot really happen, we only negotiate what we are able to do */ 00834 } 00835 00836 /* Assume no PFC */ 00837 if (pb->len < 2) { 00838 goto drop; 00839 } 00840 00841 /* Extract and hide protocol (do PFC decompression if necessary) */ 00842 pl = (u8_t*)pb->payload; 00843 if (pl[0] & 0x01) { 00844 protocol = pl[0]; 00845 pbuf_remove_header(pb, 1); 00846 } else { 00847 protocol = (pl[0] << 8) | pl[1]; 00848 pbuf_remove_header(pb, 2); 00849 } 00850 } 00851 #endif /* CCP_SUPPORT */ 00852 00853 switch(protocol) { 00854 00855 #if PPP_IPV4_SUPPORT 00856 case PPP_IP: /* Internet Protocol */ 00857 PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); 00858 ppp_ip_input(pb, pcb->netif); 00859 return; 00860 #endif /* PPP_IPV4_SUPPORT */ 00861 00862 #if PPP_IPV6_SUPPORT 00863 case PPP_IPV6: /* Internet Protocol Version 6 */ 00864 PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip6 in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); 00865 ppp_ip_input(pb, pcb->netif); 00866 return; 00867 #endif /* PPP_IPV6_SUPPORT */ 00868 00869 #if VJ_SUPPORT 00870 case PPP_VJC_COMP: /* VJ compressed TCP */ 00871 /* 00872 * Clip off the VJ header and prepend the rebuilt TCP/IP header and 00873 * pass the result to IP. 00874 */ 00875 PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); 00876 if (pcb->vj_enabled && vj_uncompress_tcp(&pb, &pcb->vj_comp) >= 0) { 00877 ppp_ip4_input(pb, pcb->netif); 00878 return; 00879 } 00880 /* Something's wrong so drop it. */ 00881 PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->netif->num)); 00882 break; 00883 00884 case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ 00885 /* 00886 * Process the TCP/IP header for VJ header compression and then pass 00887 * the packet to IP. 00888 */ 00889 PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); 00890 if (pcb->vj_enabled && vj_uncompress_uncomp(pb, &pcb->vj_comp) >= 0) { 00891 ppp_ip4_input(pb, pcb->netif); 00892 return; 00893 } 00894 /* Something's wrong so drop it. */ 00895 PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->netif->num)); 00896 break; 00897 #endif /* VJ_SUPPORT */ 00898 00899 default: { 00900 int i; 00901 const struct protent *protp; 00902 00903 /* 00904 * Upcall the proper protocol input routine. 00905 */ 00906 for (i = 0; (protp = protocols[i]) != NULL; ++i) { 00907 if (protp->protocol == protocol) { 00908 (*protp->input)(pcb, (u8_t *)pb->payload, (u32_t) pb->len); 00909 goto out; 00910 } 00911 #if 0 /* UNUSED 00912 * 00913 * This is actually a (hacked?) way for the Linux kernel to pass a data 00914 * packet to pppd. pppd in normal condition only do signaling 00915 * (LCP, PAP, CHAP, IPCP, ...) and does not handle any data packet at all. 00916 * 00917 * We don't even need this interface, which is only there because of PPP 00918 * interface limitation between Linux kernel and pppd. For MPPE, which uses 00919 * CCP to negotiate although it is not really a (de)compressor, we added 00920 * ccp_resetrequest() in CCP and MPPE input data flow is calling either 00921 * ccp_resetrequest() or lcp_close() if the issue is, respectively, non-fatal 00922 * or fatal, this is what ccp_datainput() really do. 00923 */ 00924 if (protocol == (protp->protocol & ~0x8000) 00925 && protp->datainput != NULL) { 00926 (*protp->datainput)(pcb, pb->payload, pb->len); 00927 goto out; 00928 } 00929 #endif /* UNUSED */ 00930 } 00931 00932 #if PPP_DEBUG 00933 #if PPP_PROTOCOLNAME 00934 pname = protocol_name(protocol); 00935 if (pname != NULL) { 00936 ppp_warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); 00937 } else 00938 #endif /* PPP_PROTOCOLNAME */ 00939 ppp_warn("Unsupported protocol 0x%x received", protocol); 00940 #endif /* PPP_DEBUG */ 00941 if (pbuf_add_header(pb, sizeof(protocol))) { 00942 PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping (pbuf_add_header failed)\n", pcb->netif->num)); 00943 goto drop; 00944 } 00945 lcp_sprotrej(pcb, (u8_t*)pb->payload, pb->len); 00946 } 00947 break; 00948 } 00949 00950 drop: 00951 LINK_STATS_INC(link.drop); 00952 MIB2_STATS_NETIF_INC(pcb->netif, ifindiscards); 00953 00954 out: 00955 ppp_memory_buffer_free(pb); 00956 } 00957 00958 /* 00959 * Write a pbuf to a ppp link, only used from PPP functions 00960 * to send PPP packets. 00961 * 00962 * IPv4 and IPv6 packets from stack are sent, respectively, 00963 * with ppp_netif_output_ip4() and ppp_netif_output_ip6() 00964 * functions (which are callbacks of the netif PPP interface). 00965 */ 00966 err_t ppp_write(ppp_pcb *pcb, struct pbuf *p) { 00967 #if PRINTPKT_SUPPORT 00968 ppp_dump_packet(pcb, "sent", (unsigned char *)p->payload+2, p->len-2); 00969 #endif /* PRINTPKT_SUPPORT */ 00970 return pcb->link_cb->write(pcb, pcb->link_ctx_cb, p); 00971 } 00972 00973 void ppp_link_terminated(ppp_pcb *pcb) { 00974 PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated[%d]\n", pcb->netif->num)); 00975 pcb->link_cb->disconnect(pcb, pcb->link_ctx_cb); 00976 PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated[%d]: finished.\n", pcb->netif->num)); 00977 } 00978 00979 00980 /************************************************************************ 00981 * Functions called by various PPP subsystems to configure 00982 * the PPP interface or change the PPP phase. 00983 */ 00984 00985 /* 00986 * new_phase - signal the start of a new phase of pppd's operation. 00987 */ 00988 void new_phase(ppp_pcb *pcb, int p) { 00989 pcb->phase = p; 00990 PPPDEBUG(LOG_DEBUG, ("ppp phase changed[%d]: phase=%d\n", pcb->netif->num, pcb->phase)); 00991 #if PPP_NOTIFY_PHASE 00992 if (pcb->notify_phase_cb != NULL) { 00993 pcb->notify_phase_cb(pcb, p, pcb->ctx_cb); 00994 } 00995 #endif /* PPP_NOTIFY_PHASE */ 00996 } 00997 00998 /* 00999 * ppp_send_config - configure the transmit-side characteristics of 01000 * the ppp interface. 01001 */ 01002 int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp) { 01003 PPP_UNUSED_ARG(mtu); 01004 /* pcb->mtu = mtu; -- set correctly with netif_set_mtu */ 01005 01006 if (pcb->link_cb->send_config) { 01007 pcb->link_cb->send_config(pcb, pcb->link_ctx_cb, accm, pcomp, accomp); 01008 } 01009 01010 PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", pcb->netif->num) ); 01011 return 0; 01012 } 01013 01014 /* 01015 * ppp_recv_config - configure the receive-side characteristics of 01016 * the ppp interface. 01017 */ 01018 int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp) { 01019 PPP_UNUSED_ARG(mru); 01020 01021 if (pcb->link_cb->recv_config) { 01022 pcb->link_cb->recv_config(pcb, pcb->link_ctx_cb, accm, pcomp, accomp); 01023 } 01024 01025 PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", pcb->netif->num)); 01026 return 0; 01027 } 01028 01029 #if PPP_IPV4_SUPPORT 01030 /* 01031 * sifaddr - Config the interface IP addresses and netmask. 01032 */ 01033 int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, u32_t netmask) { 01034 ip4_addr_set_u32(&pcb->netif->ipv4_addr, our_adr); 01035 ip4_addr_set_u32(&pcb->netif->ipv4_netmask, netmask); 01036 ip4_addr_set_u32(&pcb->netif->ipv4_gateway, his_adr); 01037 return 1; 01038 } 01039 01040 /******************************************************************** 01041 * 01042 * cifaddr - Clear the interface IP addresses, and delete routes 01043 * through the interface if possible. 01044 */ 01045 int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr) { 01046 PPP_UNUSED_ARG(our_adr); 01047 PPP_UNUSED_ARG(his_adr); 01048 pcb->netif->ipv4_addr.version = NSAPI_UNSPEC ; 01049 pcb->netif->ipv4_netmask.version = NSAPI_UNSPEC ; 01050 pcb->netif->ipv4_gateway.version = NSAPI_UNSPEC ; 01051 return 1; 01052 } 01053 01054 #if 0 /* UNUSED - PROXY ARP */ 01055 /******************************************************************** 01056 * 01057 * sifproxyarp - Make a proxy ARP entry for the peer. 01058 */ 01059 01060 int sifproxyarp(ppp_pcb *pcb, u32_t his_adr) { 01061 PPP_UNUSED_ARG(pcb); 01062 PPP_UNUSED_ARG(his_adr); 01063 return 0; 01064 } 01065 01066 /******************************************************************** 01067 * 01068 * cifproxyarp - Delete the proxy ARP entry for the peer. 01069 */ 01070 01071 int cifproxyarp(ppp_pcb *pcb, u32_t his_adr) { 01072 PPP_UNUSED_ARG(pcb); 01073 PPP_UNUSED_ARG(his_adr); 01074 return 0; 01075 } 01076 #endif /* UNUSED - PROXY ARP */ 01077 01078 #if PPP_DNS 01079 /* 01080 * sdns - Config the DNS servers 01081 */ 01082 int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { 01083 ip_addr_set_ip4_u32_val(pcb->netif->ipv4_dns_server[0], ns1); 01084 ip_addr_set_ip4_u32_val(pcb->netif->ipv4_dns_server[1], ns2); 01085 return 1; 01086 } 01087 01088 /******************************************************************** 01089 * 01090 * cdns - Clear the DNS servers 01091 */ 01092 int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { 01093 01094 PPP_UNUSED_ARG(ns1); 01095 PPP_UNUSED_ARG(ns2); 01096 01097 pcb->netif->ipv4_dns_server[0].version = NSAPI_UNSPEC ; 01098 pcb->netif->ipv4_dns_server[1].version = NSAPI_UNSPEC ; 01099 01100 return 1; 01101 } 01102 #endif /* PPP_DNS */ 01103 01104 #if VJ_SUPPORT 01105 /******************************************************************** 01106 * 01107 * sifvjcomp - config tcp header compression 01108 */ 01109 int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid) { 01110 pcb->vj_enabled = vjcomp; 01111 pcb->vj_comp.compressSlot = cidcomp; 01112 pcb->vj_comp.maxSlotIndex = maxcid; 01113 PPPDEBUG(LOG_INFO, ("sifvjcomp[%d]: VJ compress enable=%d slot=%d max slot=%d\n", 01114 pcb->netif->num, vjcomp, cidcomp, maxcid)); 01115 return 0; 01116 } 01117 #endif /* VJ_SUPPORT */ 01118 01119 /* 01120 * sifup - Config the interface up and enable IP packets to pass. 01121 */ 01122 int sifup(ppp_pcb *pcb) { 01123 pcb->if4_up = 1; 01124 pcb->netif->ipv4_up = 1; 01125 pcb->err_code = PPPERR_NONE; 01126 ppp_set_link_up(pcb->netif); 01127 01128 PPPDEBUG(LOG_DEBUG, ("sifup[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); 01129 pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); 01130 return 1; 01131 } 01132 01133 /******************************************************************** 01134 * 01135 * sifdown - Disable the indicated protocol and config the interface 01136 * down if there are no remaining protocols. 01137 */ 01138 int sifdown(ppp_pcb *pcb) { 01139 01140 pcb->if4_up = 0; 01141 pcb->netif->ipv4_up = 0; 01142 01143 if (1 01144 #if PPP_IPV6_SUPPORT 01145 /* set the interface down if IPv6 is down as well */ 01146 && !pcb->if6_up 01147 #endif /* PPP_IPV6_SUPPORT */ 01148 ) { 01149 /* make sure the netif link callback is called */ 01150 ppp_set_link_down(pcb->netif); 01151 } 01152 PPPDEBUG(LOG_DEBUG, ("sifdown[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); 01153 return 1; 01154 } 01155 01156 /******************************************************************** 01157 * 01158 * Return user specified netmask, modified by any mask we might determine 01159 * for address `addr' (in network byte order). 01160 * Here we scan through the system's list of interfaces, looking for 01161 * any non-point-to-point interfaces which might appear to be on the same 01162 * network as `addr'. If we find any, we OR in their netmask to the 01163 * user-specified netmask. 01164 */ 01165 u32_t get_mask(u32_t addr) { 01166 #if 0 01167 u32_t mask, nmask; 01168 01169 addr = ppp_htonl(addr); 01170 if (IP_CLASSA(addr)) { /* determine network mask for address class */ 01171 nmask = IP_CLASSA_NET; 01172 } else if (IP_CLASSB(addr)) { 01173 nmask = IP_CLASSB_NET; 01174 } else { 01175 nmask = IP_CLASSC_NET; 01176 } 01177 01178 /* class D nets are disallowed by bad_ip_adrs */ 01179 mask = PP_HTONL(0xffffff00UL) | ppp_htonl(nmask); 01180 01181 /* XXX 01182 * Scan through the system's network interfaces. 01183 * Get each netmask and OR them into our mask. 01184 */ 01185 /* return mask; */ 01186 return mask; 01187 #endif /* 0 */ 01188 PPP_UNUSED_ARG(addr); 01189 01190 /** IPv4 255.255.255.255 */ 01191 static const nsapi_addr_t ppp_addr_broadcast = { 01192 .version = NSAPI_IPv4 , 01193 .bytes = {0xff, 0xff, 0xff, 0xff} 01194 }; 01195 01196 return ppp_addr_broadcast.bytes[0]; 01197 } 01198 #endif /* PPP_IPV4_SUPPORT */ 01199 01200 #if PPP_IPV6_SUPPORT 01201 01202 /******************************************************************** 01203 * 01204 * sif6addr - Config the interface with an IPv6 link-local address 01205 */ 01206 int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { 01207 PPP_UNUSED_ARG(his_eui64); 01208 01209 pcb->netif->ipv6_addr.version = NSAPI_IPv6 ; 01210 memset(pcb->netif->ipv6_addr.bytes, 0, NSAPI_IP_BYTES); 01211 pcb->netif->ipv6_addr.bytes[0] = 0xfe; 01212 pcb->netif->ipv6_addr.bytes[1] = 0x80; 01213 memcpy(&pcb->netif->ipv6_addr.bytes[8], &our_eui64, 8); 01214 return 1; 01215 } 01216 01217 /******************************************************************** 01218 * 01219 * cif6addr - Remove IPv6 address from interface 01220 */ 01221 int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { 01222 PPP_UNUSED_ARG(our_eui64); 01223 PPP_UNUSED_ARG(his_eui64); 01224 01225 pcb->netif->ipv6_addr.version = NSAPI_UNSPEC ; 01226 memset(pcb->netif->ipv6_addr.bytes, 0, NSAPI_IP_BYTES); 01227 return 1; 01228 } 01229 01230 /* 01231 * sif6up - Config the interface up and enable IPv6 packets to pass. 01232 */ 01233 int sif6up(ppp_pcb *pcb) { 01234 01235 pcb->if6_up = 1; 01236 pcb->netif->ipv6_up = 1; 01237 pcb->err_code = PPPERR_NONE; 01238 ppp_set_link_up(pcb->netif); 01239 01240 PPPDEBUG(LOG_DEBUG, ("sif6up[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); 01241 pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); 01242 return 1; 01243 } 01244 01245 /******************************************************************** 01246 * 01247 * sif6down - Disable the indicated protocol and config the interface 01248 * down if there are no remaining protocols. 01249 */ 01250 int sif6down(ppp_pcb *pcb) { 01251 01252 pcb->if6_up = 0; 01253 pcb->netif->ipv6_up = 0; 01254 01255 if (1 01256 #if PPP_IPV4_SUPPORT 01257 /* set the interface down if IPv4 is down as well */ 01258 && !pcb->if4_up 01259 #endif /* PPP_IPV4_SUPPORT */ 01260 ) { 01261 /* make sure the netif link callback is called */ 01262 ppp_set_link_down(pcb->netif); 01263 } 01264 PPPDEBUG(LOG_DEBUG, ("sif6down[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); 01265 return 1; 01266 } 01267 #endif /* PPP_IPV6_SUPPORT */ 01268 01269 #if DEMAND_SUPPORT 01270 /* 01271 * sifnpmode - Set the mode for handling packets for a given NP. 01272 */ 01273 int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode) { 01274 PPP_UNUSED_ARG(pcb); 01275 PPP_UNUSED_ARG(proto); 01276 PPP_UNUSED_ARG(mode); 01277 return 0; 01278 } 01279 #endif /* DEMAND_SUPPORT */ 01280 01281 /* 01282 * netif_set_mtu - set the MTU on the PPP network interface. 01283 */ 01284 void netif_set_mtu(ppp_pcb *pcb, int mtu) { 01285 01286 pcb->netif->mtu = mtu; 01287 PPPDEBUG(LOG_INFO, ("netif_set_mtu[%d]: mtu=%d\n", pcb->netif->num, mtu)); 01288 } 01289 01290 /* 01291 * netif_get_mtu - get PPP interface MTU 01292 */ 01293 int netif_get_mtu(ppp_pcb *pcb) { 01294 01295 return pcb->netif->mtu; 01296 } 01297 01298 #if CCP_SUPPORT 01299 #if 0 /* unused */ 01300 /* 01301 * ccp_test - whether a given compression method is acceptable for use. 01302 */ 01303 int 01304 ccp_test(ppp_pcb *pcb, u_char *opt_ptr, int opt_len, int for_transmit) 01305 { 01306 PPP_UNUSED_ARG(pcb); 01307 PPP_UNUSED_ARG(opt_ptr); 01308 PPP_UNUSED_ARG(opt_len); 01309 PPP_UNUSED_ARG(for_transmit); 01310 return -1; 01311 } 01312 #endif /* unused */ 01313 01314 /* 01315 * ccp_set - inform about the current state of CCP. 01316 */ 01317 void 01318 ccp_set(ppp_pcb *pcb, u8_t isopen, u8_t isup, u8_t receive_method, u8_t transmit_method) 01319 { 01320 PPP_UNUSED_ARG(isopen); 01321 PPP_UNUSED_ARG(isup); 01322 pcb->ccp_receive_method = receive_method; 01323 pcb->ccp_transmit_method = transmit_method; 01324 PPPDEBUG(LOG_DEBUG, ("ccp_set[%d]: is_open=%d, is_up=%d, receive_method=%u, transmit_method=%u\n", 01325 pcb->netif->num, isopen, isup, receive_method, transmit_method)); 01326 } 01327 01328 void 01329 ccp_reset_comp(ppp_pcb *pcb) 01330 { 01331 switch (pcb->ccp_transmit_method) { 01332 #if MPPE_SUPPORT 01333 case CI_MPPE: 01334 mppe_comp_reset(pcb, &pcb->mppe_comp); 01335 break; 01336 #endif /* MPPE_SUPPORT */ 01337 default: 01338 break; 01339 } 01340 } 01341 01342 void 01343 ccp_reset_decomp(ppp_pcb *pcb) 01344 { 01345 switch (pcb->ccp_receive_method) { 01346 #if MPPE_SUPPORT 01347 case CI_MPPE: 01348 mppe_decomp_reset(pcb, &pcb->mppe_decomp); 01349 break; 01350 #endif /* MPPE_SUPPORT */ 01351 default: 01352 break; 01353 } 01354 } 01355 01356 #if 0 /* unused */ 01357 /* 01358 * ccp_fatal_error - returns 1 if decompression was disabled as a 01359 * result of an error detected after decompression of a packet, 01360 * 0 otherwise. This is necessary because of patent nonsense. 01361 */ 01362 int 01363 ccp_fatal_error(ppp_pcb *pcb) 01364 { 01365 PPP_UNUSED_ARG(pcb); 01366 return 1; 01367 } 01368 #endif /* unused */ 01369 #endif /* CCP_SUPPORT */ 01370 01371 #if PPP_IDLETIMELIMIT 01372 /******************************************************************** 01373 * 01374 * get_idle_time - return how long the link has been idle. 01375 */ 01376 int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip) { 01377 /* FIXME: add idle time support and make it optional */ 01378 PPP_UNUSED_ARG(pcb); 01379 PPP_UNUSED_ARG(ip); 01380 return 1; 01381 } 01382 #endif /* PPP_IDLETIMELIMIT */ 01383 01384 #if DEMAND_SUPPORT 01385 /******************************************************************** 01386 * 01387 * get_loop_output - get outgoing packets from the ppp device, 01388 * and detect when we want to bring the real link up. 01389 * Return value is 1 if we need to bring up the link, 0 otherwise. 01390 */ 01391 int get_loop_output(void) { 01392 return 0; 01393 } 01394 #endif /* DEMAND_SUPPORT */ 01395 01396 #if PPP_PROTOCOLNAME 01397 /* List of protocol names, to make our messages a little more informative. */ 01398 struct protocol_list { 01399 u_short proto; 01400 const char *name; 01401 } const protocol_list[] = { 01402 { 0x21, "IP" }, 01403 { 0x23, "OSI Network Layer" }, 01404 { 0x25, "Xerox NS IDP" }, 01405 { 0x27, "DECnet Phase IV" }, 01406 { 0x29, "Appletalk" }, 01407 { 0x2b, "Novell IPX" }, 01408 { 0x2d, "VJ compressed TCP/IP" }, 01409 { 0x2f, "VJ uncompressed TCP/IP" }, 01410 { 0x31, "Bridging PDU" }, 01411 { 0x33, "Stream Protocol ST-II" }, 01412 { 0x35, "Banyan Vines" }, 01413 { 0x39, "AppleTalk EDDP" }, 01414 { 0x3b, "AppleTalk SmartBuffered" }, 01415 { 0x3d, "Multi-Link" }, 01416 { 0x3f, "NETBIOS Framing" }, 01417 { 0x41, "Cisco Systems" }, 01418 { 0x43, "Ascom Timeplex" }, 01419 { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" }, 01420 { 0x47, "DCA Remote Lan" }, 01421 { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" }, 01422 { 0x4b, "SNA over 802.2" }, 01423 { 0x4d, "SNA" }, 01424 { 0x4f, "IP6 Header Compression" }, 01425 { 0x51, "KNX Bridging Data" }, 01426 { 0x53, "Encryption" }, 01427 { 0x55, "Individual Link Encryption" }, 01428 { 0x57, "IPv6" }, 01429 { 0x59, "PPP Muxing" }, 01430 { 0x5b, "Vendor-Specific Network Protocol" }, 01431 { 0x61, "RTP IPHC Full Header" }, 01432 { 0x63, "RTP IPHC Compressed TCP" }, 01433 { 0x65, "RTP IPHC Compressed non-TCP" }, 01434 { 0x67, "RTP IPHC Compressed UDP 8" }, 01435 { 0x69, "RTP IPHC Compressed RTP 8" }, 01436 { 0x6f, "Stampede Bridging" }, 01437 { 0x73, "MP+" }, 01438 { 0xc1, "NTCITS IPI" }, 01439 { 0xfb, "single-link compression" }, 01440 { 0xfd, "Compressed Datagram" }, 01441 { 0x0201, "802.1d Hello Packets" }, 01442 { 0x0203, "IBM Source Routing BPDU" }, 01443 { 0x0205, "DEC LANBridge100 Spanning Tree" }, 01444 { 0x0207, "Cisco Discovery Protocol" }, 01445 { 0x0209, "Netcs Twin Routing" }, 01446 { 0x020b, "STP - Scheduled Transfer Protocol" }, 01447 { 0x020d, "EDP - Extreme Discovery Protocol" }, 01448 { 0x0211, "Optical Supervisory Channel Protocol" }, 01449 { 0x0213, "Optical Supervisory Channel Protocol" }, 01450 { 0x0231, "Luxcom" }, 01451 { 0x0233, "Sigma Network Systems" }, 01452 { 0x0235, "Apple Client Server Protocol" }, 01453 { 0x0281, "MPLS Unicast" }, 01454 { 0x0283, "MPLS Multicast" }, 01455 { 0x0285, "IEEE p1284.4 standard - data packets" }, 01456 { 0x0287, "ETSI TETRA Network Protocol Type 1" }, 01457 { 0x0289, "Multichannel Flow Treatment Protocol" }, 01458 { 0x2063, "RTP IPHC Compressed TCP No Delta" }, 01459 { 0x2065, "RTP IPHC Context State" }, 01460 { 0x2067, "RTP IPHC Compressed UDP 16" }, 01461 { 0x2069, "RTP IPHC Compressed RTP 16" }, 01462 { 0x4001, "Cray Communications Control Protocol" }, 01463 { 0x4003, "CDPD Mobile Network Registration Protocol" }, 01464 { 0x4005, "Expand accelerator protocol" }, 01465 { 0x4007, "ODSICP NCP" }, 01466 { 0x4009, "DOCSIS DLL" }, 01467 { 0x400B, "Cetacean Network Detection Protocol" }, 01468 { 0x4021, "Stacker LZS" }, 01469 { 0x4023, "RefTek Protocol" }, 01470 { 0x4025, "Fibre Channel" }, 01471 { 0x4027, "EMIT Protocols" }, 01472 { 0x405b, "Vendor-Specific Protocol (VSP)" }, 01473 { 0x8021, "Internet Protocol Control Protocol" }, 01474 { 0x8023, "OSI Network Layer Control Protocol" }, 01475 { 0x8025, "Xerox NS IDP Control Protocol" }, 01476 { 0x8027, "DECnet Phase IV Control Protocol" }, 01477 { 0x8029, "Appletalk Control Protocol" }, 01478 { 0x802b, "Novell IPX Control Protocol" }, 01479 { 0x8031, "Bridging NCP" }, 01480 { 0x8033, "Stream Protocol Control Protocol" }, 01481 { 0x8035, "Banyan Vines Control Protocol" }, 01482 { 0x803d, "Multi-Link Control Protocol" }, 01483 { 0x803f, "NETBIOS Framing Control Protocol" }, 01484 { 0x8041, "Cisco Systems Control Protocol" }, 01485 { 0x8043, "Ascom Timeplex" }, 01486 { 0x8045, "Fujitsu LBLB Control Protocol" }, 01487 { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" }, 01488 { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" }, 01489 { 0x804b, "SNA over 802.2 Control Protocol" }, 01490 { 0x804d, "SNA Control Protocol" }, 01491 { 0x804f, "IP6 Header Compression Control Protocol" }, 01492 { 0x8051, "KNX Bridging Control Protocol" }, 01493 { 0x8053, "Encryption Control Protocol" }, 01494 { 0x8055, "Individual Link Encryption Control Protocol" }, 01495 { 0x8057, "IPv6 Control Protocol" }, 01496 { 0x8059, "PPP Muxing Control Protocol" }, 01497 { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" }, 01498 { 0x806f, "Stampede Bridging Control Protocol" }, 01499 { 0x8073, "MP+ Control Protocol" }, 01500 { 0x80c1, "NTCITS IPI Control Protocol" }, 01501 { 0x80fb, "Single Link Compression Control Protocol" }, 01502 { 0x80fd, "Compression Control Protocol" }, 01503 { 0x8207, "Cisco Discovery Protocol Control" }, 01504 { 0x8209, "Netcs Twin Routing" }, 01505 { 0x820b, "STP - Control Protocol" }, 01506 { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" }, 01507 { 0x8235, "Apple Client Server Protocol Control" }, 01508 { 0x8281, "MPLSCP" }, 01509 { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, 01510 { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, 01511 { 0x8289, "Multichannel Flow Treatment Protocol" }, 01512 { 0xc021, "Link Control Protocol" }, 01513 { 0xc023, "Password Authentication Protocol" }, 01514 { 0xc025, "Link Quality Report" }, 01515 { 0xc027, "Shiva Password Authentication Protocol" }, 01516 { 0xc029, "CallBack Control Protocol (CBCP)" }, 01517 { 0xc02b, "BACP Bandwidth Allocation Control Protocol" }, 01518 { 0xc02d, "BAP" }, 01519 { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" }, 01520 { 0xc081, "Container Control Protocol" }, 01521 { 0xc223, "Challenge Handshake Authentication Protocol" }, 01522 { 0xc225, "RSA Authentication Protocol" }, 01523 { 0xc227, "Extensible Authentication Protocol" }, 01524 { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" }, 01525 { 0xc26f, "Stampede Bridging Authorization Protocol" }, 01526 { 0xc281, "Proprietary Authentication Protocol" }, 01527 { 0xc283, "Proprietary Authentication Protocol" }, 01528 { 0xc481, "Proprietary Node ID Authentication Protocol" }, 01529 { 0, NULL }, 01530 }; 01531 01532 /* 01533 * protocol_name - find a name for a PPP protocol. 01534 */ 01535 const char * protocol_name(int proto) { 01536 const struct protocol_list *lp; 01537 01538 for (lp = protocol_list; lp->proto != 0; ++lp) { 01539 if (proto == lp->proto) { 01540 return lp->name; 01541 } 01542 } 01543 return NULL; 01544 } 01545 #endif /* PPP_PROTOCOLNAME */ 01546 01547 #if PPP_STATS_SUPPORT 01548 01549 /* ---- Note on PPP Stats support ---- 01550 * 01551 * The one willing link stats support should add the get_ppp_stats() 01552 * to fetch statistics from stacks. 01553 */ 01554 01555 /* 01556 * reset_link_stats - "reset" stats when link goes up. 01557 */ 01558 void reset_link_stats(int u) { 01559 if (!get_ppp_stats(u, &old_link_stats)) { 01560 return; 01561 } 01562 gettimeofday(&start_time, NULL); 01563 } 01564 01565 /* 01566 * update_link_stats - get stats at link termination. 01567 */ 01568 void update_link_stats(int u) { 01569 struct timeval now; 01570 char numbuf[32]; 01571 01572 if (!get_ppp_stats(u, &link_stats) || gettimeofday(&now, NULL) < 0) { 01573 return; 01574 } 01575 link_connect_time = now.tv_sec - start_time.tv_sec; 01576 link_stats_valid = 1; 01577 01578 link_stats.bytes_in -= old_link_stats.bytes_in; 01579 link_stats.bytes_out -= old_link_stats.bytes_out; 01580 link_stats.pkts_in -= old_link_stats.pkts_in; 01581 link_stats.pkts_out -= old_link_stats.pkts_out; 01582 } 01583 01584 void print_link_stats() { 01585 /* 01586 * Print connect time and statistics. 01587 */ 01588 if (link_stats_valid) { 01589 int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ 01590 info("Connect time %d.%d minutes.", t/10, t%10); 01591 info("Sent %u bytes, received %u bytes.", link_stats.bytes_out, link_stats.bytes_in); 01592 link_stats_valid = 0; 01593 } 01594 } 01595 #endif /* PPP_STATS_SUPPORT */ 01596 01597 #endif /* PPP_SUPPORT */
Generated on Tue Jul 12 2022 13:54:42 by
1.7.2