lcp.c
上传用户:yyhongfa
上传日期:2013-01-18
资源大小:267k
文件大小:50k
开发平台:

C/C++

  1. /*****************************************************************************
  2. * lcp.c - Network Link Control 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-12-01 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
  31. * Original.
  32. *****************************************************************************/
  33. /*
  34.  * lcp.c - PPP Link Control Protocol.
  35.  *
  36.  * Copyright (c) 1989 Carnegie Mellon University.
  37.  * All rights reserved.
  38.  *
  39.  * Redistribution and use in source and binary forms are permitted
  40.  * provided that the above copyright notice and this paragraph are
  41.  * duplicated in all such forms and that any documentation,
  42.  * advertising materials, and other materials related to such
  43.  * distribution and use acknowledge that the software was developed
  44.  * by Carnegie Mellon University.  The name of the
  45.  * University may not be used to endorse or promote products derived
  46.  * from this software without specific prior written permission.
  47.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  48.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  49.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  50.  */
  51.  
  52. #include <string.h>
  53.  
  54. #include "ppp.h"
  55. #if PPP_SUPPORT > 0
  56. #include "fsm.h"
  57. #include "chap.h"
  58. #include "magic.h"
  59. #include "auth.h"
  60. #include "lcp.h"
  61. #include "pppdebug.h"
  62. #include "timer.h"
  63. #include "uart.h"
  64. /*************************/
  65. /*** LOCAL DEFINITIONS ***/
  66. /*************************/
  67. /*
  68.  * Length of each type of configuration option (in octets)
  69.  */
  70. #define CILEN_VOID 2
  71. #define CILEN_CHAR 3
  72. #define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */
  73. #define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */
  74. #define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */
  75. #define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */
  76. #define CILEN_CBCP 3
  77. /***********************************/
  78. /*** LOCAL FUNCTION DECLARATIONS ***/
  79. /***********************************/
  80. /*
  81.  * Callbacks for fsm code.  (CI = Configuration Information)
  82.  */
  83. static void lcp_resetci (fsm*);         /* Reset our CI */
  84. static int  lcp_cilen (fsm*);         /* Return length of our CI */
  85. static void lcp_addci (fsm*, u_char*, int*);       /* Add our CI to pkt */
  86. static int  lcp_ackci (fsm*, u_char*, int);/* Peer ack'd our CI */
  87. static int  lcp_nakci (fsm*, u_char*, int);/* Peer nak'd our CI */
  88. static int  lcp_rejci (fsm*, u_char*, int);/* Peer rej'd our CI */
  89. static int  lcp_reqci (fsm*, u_char*, int*, int);  /* Rcv peer CI */
  90. static void lcp_up (fsm*);             /* We're UP */
  91. static void lcp_down (fsm*);          /* We're DOWN */
  92. static void lcp_starting (fsm*);        /* We need lower layer up */
  93. static void lcp_finished (fsm*);         /* We need lower layer down */
  94. static int  lcp_extcode (fsm*, int, u_char, u_char*, int);
  95. static void lcp_rprotrej (fsm*, u_char*, int);
  96. /*
  97.  * routines to send LCP echos to peer
  98.  */
  99. static void lcp_echo_lowerup (int);
  100. static void lcp_echo_lowerdown (int);
  101. static void LcpEchoTimeout (void*);
  102. static void lcp_received_echo_reply (fsm*, int, u_char*, int);
  103. static void LcpSendEchoRequest (fsm*);
  104. static void LcpLinkFailure (fsm*);
  105. static void LcpEchoCheck (fsm*);
  106. /*
  107.  * Protocol entry points.
  108.  * Some of these are called directly.
  109.  */
  110. static void lcp_input (int, u_char *, int);
  111. static void lcp_protrej (int);
  112. #define CODENAME(x) ((x) == CONFACK ? "ACK" : 
  113.  (x) == CONFNAK ? "NAK" : "REJ")
  114. /******************************/
  115. /*** PUBLIC DATA STRUCTURES ***/
  116. /******************************/
  117. /* global vars */
  118. LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */
  119. lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */
  120. lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
  121. lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
  122. lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
  123. ext_accm xmit_accm[NUM_PPP]; /* extended transmit ACCM */
  124. /*****************************/
  125. /*** LOCAL DATA STRUCTURES ***/
  126. /*****************************/
  127. static fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/
  128. static u_int  lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */
  129. static u_int  lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */
  130. static u32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */
  131. static u32_t lcp_echo_number   = 0; /* ID number of next echo frame */
  132. static u32_t lcp_echo_timer_running = 0;  /* TRUE if a timer is running */
  133. static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */
  134. static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
  135.     lcp_resetci, /* Reset our Configuration Information */
  136.     lcp_cilen, /* Length of our Configuration Information */
  137.     lcp_addci, /* Add our Configuration Information */
  138.     lcp_ackci, /* ACK our Configuration Information */
  139.     lcp_nakci, /* NAK our Configuration Information */
  140.     lcp_rejci, /* Reject our Configuration Information */
  141.     lcp_reqci, /* Request peer's Configuration Information */
  142.     lcp_up, /* Called when fsm reaches OPENED state */
  143.     lcp_down, /* Called when fsm leaves OPENED state */
  144.     lcp_starting, /* Called when we want the lower layer up */
  145.     lcp_finished, /* Called when we want the lower layer down */
  146.     NULL, /* Called when Protocol-Reject received */
  147.     NULL, /* Retransmission is necessary */
  148.     lcp_extcode, /* Called to handle LCP-specific codes */
  149.     "LCP" /* String name of protocol */
  150. };
  151. struct protent lcp_protent = {
  152.     PPP_LCP,
  153.     lcp_init,
  154.     lcp_input,
  155.     lcp_protrej,
  156.     lcp_lowerup,
  157.     lcp_lowerdown,
  158.     lcp_open,
  159.     lcp_close,
  160. #if 0
  161.     lcp_printpkt,
  162.     NULL,
  163. #endif
  164.     1,
  165.     "LCP",
  166. #if 0
  167.     NULL,
  168.     NULL,
  169.     NULL
  170. #endif
  171. };
  172. int lcp_loopbackfail = DEFLOOPBACKFAIL;
  173. /*
  174. *return the state of ppp connect
  175. */
  176. BOOL  ppp_dead(int pd)
  177. {
  178.     if( lcp_phase[pd] == PHASE_DEAD)
  179. return TRUE;
  180.     else 
  181. return FALSE;
  182. }
  183. /***********************************/
  184. /*** PUBLIC FUNCTION DEFINITIONS ***/
  185. /***********************************/
  186. /*
  187.  * lcp_init - Initialize LCP.
  188.  */
  189. void lcp_init(int unit)
  190. {
  191. fsm *f = &lcp_fsm[unit];
  192. lcp_options *wo = &lcp_wantoptions[unit];
  193. lcp_options *ao = &lcp_allowoptions[unit];
  194. f->unit = unit;
  195. f->protocol = PPP_LCP;
  196. f->callbacks = &lcp_callbacks;
  197. fsm_init(f);
  198. wo->passive = 0;
  199. wo->silent = 0;
  200. wo->restart = 0; /* Set to 1 in kernels or multi-line
  201.  * implementations */
  202. wo->neg_mru = 1;
  203. wo->mru = PPP_DEFMRU;
  204. wo->neg_asyncmap = 1;
  205. wo->asyncmap = 0x00000000l; /* Assume don't need to escape any ctl chars. */
  206. wo->neg_chap = 0; /* Set to 1 on server */
  207. wo->neg_upap = 0; /* Set to 1 on server */
  208. wo->chap_mdtype = CHAP_DIGEST_MD5;
  209. wo->neg_magicnumber = 1;
  210. wo->neg_pcompression = 1;
  211. wo->neg_accompression = 1;
  212. wo->neg_lqr = 0; /* no LQR implementation yet */
  213. wo->neg_cbcp = 0;
  214. ao->neg_mru = 1;
  215. ao->mru = PPP_MAXMRU;
  216. ao->neg_asyncmap = 1;
  217. ao->asyncmap = 0x00000000l; /* Assume don't need to escape any ctl chars. */
  218. ao->neg_chap = (CHAP_SUPPORT != 0);
  219. ao->chap_mdtype = CHAP_DIGEST_MD5;
  220. ao->neg_upap = (PAP_SUPPORT != 0);
  221. ao->neg_magicnumber = 1;
  222. ao->neg_pcompression = 1;
  223. ao->neg_accompression = 1;
  224. ao->neg_lqr = 0; /* no LQR implementation yet */
  225. ao->neg_cbcp = (CBCP_SUPPORT != 0);
  226. /* 
  227.  * Set transmit escape for the flag and escape characters plus anything
  228.  * set for the allowable options.
  229.  */
  230. memset(xmit_accm[unit], 0, sizeof(xmit_accm[0]));
  231. xmit_accm[unit][15] = 0x60;
  232. xmit_accm[unit][0] = (u_char)(ao->asyncmap & 0xFF);
  233. xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF);
  234. xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF);
  235. xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF);
  236. LCPDEBUG((LOG_INFO, "lcp_init: xmit_accm=%X %X %X %Xn",
  237. xmit_accm[unit][0],
  238. xmit_accm[unit][1],
  239. xmit_accm[unit][2],
  240. xmit_accm[unit][3]));
  241. lcp_phase[unit] = PHASE_INITIALIZE;
  242. }
  243. /*
  244.  * lcp_open - LCP is allowed to come up.
  245.  */
  246. void lcp_open(int unit)
  247. {
  248. fsm *f = &lcp_fsm[unit];
  249. lcp_options *wo = &lcp_wantoptions[unit];
  250. f->flags = 0;
  251. if (wo->passive)
  252. f->flags |= OPT_PASSIVE;
  253. if (wo->silent)
  254. f->flags |= OPT_SILENT;
  255. fsm_open(f);
  256. lcp_phase[unit] = PHASE_ESTABLISH; 
  257. }
  258. /*
  259.  * lcp_close - Take LCP down.
  260.  */
  261. void lcp_close(int unit, char *reason)
  262. {
  263. fsm *f = &lcp_fsm[unit];
  264. if (lcp_phase[unit] != PHASE_DEAD)
  265. lcp_phase[unit] = PHASE_TERMINATE;
  266. if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
  267. /*
  268.  * This action is not strictly according to the FSM in RFC1548,
  269.  * but it does mean that the program terminates if you do an
  270.  * lcp_close() in passive/silent mode when a connection hasn't
  271.  * been established.
  272.  */
  273. f->state = CLOSED;
  274. lcp_finished(f);
  275. }
  276. else
  277. fsm_close(&lcp_fsm[unit], reason);
  278. }
  279. /*
  280.  * lcp_lowerup - The lower layer is up.
  281.  */
  282. void lcp_lowerup(int unit)
  283. {
  284. lcp_options *wo = &lcp_wantoptions[unit];
  285. /*
  286. * Don't use A/C or protocol compression on transmission,
  287. * but accept A/C and protocol compressed packets
  288. * if we are going to ask for A/C and protocol compression.
  289. */
  290. ppp_set_xaccm(unit, &xmit_accm[unit]);
  291. ppp_send_config(unit, PPP_MRU, 0xffffffffl, 0, 0);
  292. ppp_recv_config(unit, PPP_MRU, 0x00000000l,
  293. wo->neg_pcompression, wo->neg_accompression);
  294. peer_mru[unit] = PPP_MRU;
  295. lcp_allowoptions[unit].asyncmap 
  296. = (u_long)xmit_accm[unit][0]
  297. | ((u_long)xmit_accm[unit][1] << 8)
  298. | ((u_long)xmit_accm[unit][2] << 16)
  299. | ((u_long)xmit_accm[unit][3] << 24);
  300. LCPDEBUG((LOG_INFO, "lcp_lowerup: asyncmap=%X %X %X %Xn",
  301. xmit_accm[unit][3],
  302. xmit_accm[unit][2],
  303. xmit_accm[unit][1],
  304. xmit_accm[unit][0]));
  305. fsm_lowerup(&lcp_fsm[unit]);
  306. }
  307. /*
  308.  * lcp_lowerdown - The lower layer is down.
  309.  */
  310. void lcp_lowerdown(int unit)
  311. {
  312. fsm_lowerdown(&lcp_fsm[unit]);
  313. }
  314. /*
  315.  * lcp_sprotrej - Send a Protocol-Reject for some protocol.
  316.  */
  317. void lcp_sprotrej(int unit, u_char *p, int len)
  318. {
  319. /*
  320. * Send back the protocol and the information field of the
  321. * rejected packet.  We only get here if LCP is in the OPENED state.
  322. */
  323. fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
  324. p, len);
  325. }
  326. /**********************************/
  327. /*** LOCAL FUNCTION DEFINITIONS ***/
  328. /**********************************/
  329. /*
  330.  * lcp_input - Input LCP packet.
  331.  */
  332. static void lcp_input(int unit, u_char *p, int len)
  333. {
  334. fsm *f = &lcp_fsm[unit];
  335. fsm_input(f, p, len);
  336. }
  337. /*
  338.  * lcp_extcode - Handle a LCP-specific code.
  339.  */
  340. static int lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len)
  341. {
  342. u_char *magp;
  343. switch( code ){
  344. case PROTREJ:
  345. lcp_rprotrej(f, inp, len);
  346. break;
  347. case ECHOREQ:
  348. if (f->state != OPENED)
  349. break;
  350. LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %dn", id));
  351. magp = inp;
  352. PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
  353. fsm_sdata(f, ECHOREP, id, inp, len);
  354. break;
  355. case ECHOREP:
  356. lcp_received_echo_reply(f, id, inp, len);
  357. break;
  358. case DISCREQ:
  359. break;
  360. default:
  361. return 0;
  362. }
  363. return 1;
  364. }
  365.     
  366. /*
  367.  * lcp_rprotrej - Receive an Protocol-Reject.
  368.  *
  369.  * Figure out which protocol is rejected and inform it.
  370.  */
  371. static void lcp_rprotrej(fsm *f, u_char *inp, int len)
  372. {
  373. int i;
  374. struct protent *protp;
  375. u_short prot;
  376. if (len < sizeof (u_short)) {
  377. LCPDEBUG((LOG_INFO,
  378. "lcp_rprotrej: Rcvd short Protocol-Reject packet!n"));
  379. return;
  380. }
  381. GETSHORT(prot, inp);
  382. LCPDEBUG((LOG_INFO,
  383. "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!n",
  384. prot));
  385. /*
  386. * Protocol-Reject packets received in any state other than the LCP
  387. * OPENED state SHOULD be silently discarded.
  388. */
  389. if( f->state != OPENED ){
  390. LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %dn",
  391. f->state));
  392. return;
  393. }
  394. /*
  395. * Upcall the proper Protocol-Reject routine.
  396. */
  397. for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i)
  398. if (protp->protocol == prot && protp->enabled_flag) {
  399. (*protp->protrej)(f->unit);
  400. return;
  401. }
  402. LCPDEBUG((LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%xn",
  403. prot));
  404. }
  405. /*
  406.  * lcp_protrej - A Protocol-Reject was received.
  407.  */
  408. static void lcp_protrej(int unit)
  409. {
  410. (void)unit;
  411. /*
  412. * Can't reject LCP!
  413. */
  414. LCPDEBUG((LOG_WARNING,
  415. "lcp_protrej: Received Protocol-Reject for LCP!n"));
  416. fsm_protreject(&lcp_fsm[unit]);
  417. }
  418. /*
  419.  * lcp_resetci - Reset our CI.
  420.  */
  421. static void lcp_resetci(fsm *f)
  422. {
  423. lcp_wantoptions[f->unit].magicnumber = magic();
  424. lcp_wantoptions[f->unit].numloops = 0;
  425. lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
  426. peer_mru[f->unit] = PPP_MRU;
  427. auth_reset(f->unit);
  428. }
  429. /*
  430.  * lcp_cilen - Return length of our CI.
  431.  */
  432. static int lcp_cilen(fsm *f)
  433. {
  434. lcp_options *go = &lcp_gotoptions[f->unit];
  435. #define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0)
  436. #define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0)
  437. #define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0)
  438. #define LENCILONG(neg) ((neg) ? CILEN_LONG : 0)
  439. #define LENCILQR(neg) ((neg) ? CILEN_LQR: 0)
  440. #define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0)
  441. /*
  442. * NB: we only ask for one of CHAP and UPAP, even if we will
  443. * accept either.
  444. */
  445. return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) +
  446.        //(LENCISHORT(go->neg_mru && go->mru == PPP_DEFMRU) +
  447. LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) +
  448. LENCICHAP(go->neg_chap) +
  449. LENCISHORT(!go->neg_chap && go->neg_upap) +
  450. LENCILQR(go->neg_lqr) +
  451. LENCICBCP(go->neg_cbcp) +
  452. LENCILONG(go->neg_magicnumber) +
  453. LENCIVOID(go->neg_pcompression) +
  454. LENCIVOID(go->neg_accompression));
  455. }
  456. /*
  457.  * lcp_addci - Add our desired CIs to a packet.
  458.  */
  459. static void lcp_addci(fsm *f, u_char *ucp, int *lenp)
  460. {
  461. lcp_options *go = &lcp_gotoptions[f->unit];
  462. u_char *start_ucp = ucp;
  463. #define ADDCIVOID(opt, neg) 
  464. if (neg) { 
  465.     LCPDEBUG((LOG_INFO, "lcp_addci: opt=%dn", opt)); 
  466. PUTCHAR(opt, ucp); 
  467. PUTCHAR(CILEN_VOID, ucp); 
  468. }
  469. #define ADDCISHORT(opt, neg, val) 
  470. if (neg) { 
  471.     LCPDEBUG((LOG_INFO, "lcp_addci: INT opt=%d %Xn", opt, val)); 
  472. PUTCHAR(opt, ucp); 
  473. PUTCHAR(CILEN_SHORT, ucp); 
  474. PUTSHORT(val, ucp); 
  475. }
  476. #define ADDCICHAP(opt, neg, val, digest) 
  477. if (neg) { 
  478.     LCPDEBUG((LOG_INFO, "lcp_addci: CHAP opt=%d %Xn", opt, val)); 
  479. PUTCHAR(opt, ucp); 
  480. PUTCHAR(CILEN_CHAP, ucp); 
  481. PUTSHORT(val, ucp); 
  482. PUTCHAR(digest, ucp); 
  483. }
  484. #define ADDCILONG(opt, neg, val) 
  485. if (neg) { 
  486.     LCPDEBUG((LOG_INFO, "lcp_addci: L opt=%d %lXn", opt, val)); 
  487. PUTCHAR(opt, ucp); 
  488. PUTCHAR(CILEN_LONG, ucp); 
  489. PUTLONG(val, ucp); 
  490. }
  491. #define ADDCILQR(opt, neg, val) 
  492. if (neg) { 
  493.     LCPDEBUG((LOG_INFO, "lcp_addci: LQR opt=%d %lXn", opt, val)); 
  494. PUTCHAR(opt, ucp); 
  495. PUTCHAR(CILEN_LQR, ucp); 
  496. PUTSHORT(PPP_LQR, ucp); 
  497. PUTLONG(val, ucp); 
  498. }
  499. #define ADDCICHAR(opt, neg, val) 
  500. if (neg) { 
  501.     LCPDEBUG((LOG_INFO, "lcp_addci: CHAR opt=%d %X '%z'n", opt, val, val)); 
  502. PUTCHAR(opt, ucp); 
  503. PUTCHAR(CILEN_CHAR, ucp); 
  504. PUTCHAR(val, ucp); 
  505. }
  506. ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
  507. //ADDCISHORT(CI_MRU, go->neg_mru && go->mru == PPP_DEFMRU, go->mru);
  508. ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl,
  509. go->asyncmap);
  510. ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
  511. ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
  512. ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
  513. ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
  514. ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
  515. ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
  516. ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
  517. if (ucp - start_ucp != *lenp) {
  518. /* this should never happen, because peer_mtu should be 1500 */
  519. LCPDEBUG((LOG_ERR, "Bug in lcp_addci: wrong lengthn"));
  520. }
  521. }
  522. /*
  523.  * lcp_ackci - Ack our CIs.
  524.  * This should not modify any state if the Ack is bad.
  525.  *
  526.  * Returns:
  527.  * 0 - Ack was bad.
  528.  * 1 - Ack was good.
  529.  */
  530. static int lcp_ackci(fsm *f, u_char *p, int len)
  531. {
  532. lcp_options *go = &lcp_gotoptions[f->unit];
  533. u_char cilen, citype, cichar;
  534. u_short cishort;
  535. u32_t cilong;
  536. /*
  537. * CIs must be in exactly the same order that we sent.
  538. * Check packet length and CI length at each step.
  539. * If we find any deviations, then this packet is bad.
  540. */
  541. #define ACKCIVOID(opt, neg) 
  542. if (neg) { 
  543. if ((len -= CILEN_VOID) < 0) 
  544. goto bad; 
  545. GETCHAR(citype, p); 
  546. GETCHAR(cilen, p); 
  547. if (cilen != CILEN_VOID || 
  548. citype != opt) 
  549. goto bad; 
  550. }
  551. #define ACKCISHORT(opt, neg, val) 
  552. if (neg) { 
  553. if ((len -= CILEN_SHORT) < 0) 
  554. goto bad; 
  555. GETCHAR(citype, p); 
  556. GETCHAR(cilen, p); 
  557. if (cilen != CILEN_SHORT || 
  558. citype != opt) 
  559. goto bad; 
  560. GETSHORT(cishort, p); 
  561. if (cishort != val) 
  562. goto bad; 
  563. }
  564. #define ACKCICHAR(opt, neg, val) 
  565. if (neg) { 
  566. if ((len -= CILEN_CHAR) < 0) 
  567. goto bad; 
  568. GETCHAR(citype, p); 
  569. GETCHAR(cilen, p); 
  570. if (cilen != CILEN_CHAR || 
  571. citype != opt) 
  572. goto bad; 
  573. GETCHAR(cichar, p); 
  574. if (cichar != val) 
  575. goto bad; 
  576. }
  577. #define ACKCICHAP(opt, neg, val, digest) 
  578. if (neg) { 
  579. if ((len -= CILEN_CHAP) < 0) 
  580. goto bad; 
  581. GETCHAR(citype, p); 
  582. GETCHAR(cilen, p); 
  583. if (cilen != CILEN_CHAP || 
  584. citype != opt) 
  585. goto bad; 
  586. GETSHORT(cishort, p); 
  587. if (cishort != val) 
  588. goto bad; 
  589. GETCHAR(cichar, p); 
  590. if (cichar != digest) 
  591. goto bad; 
  592. }
  593. #define ACKCILONG(opt, neg, val) 
  594. if (neg) { 
  595. if ((len -= CILEN_LONG) < 0) 
  596. goto bad; 
  597. GETCHAR(citype, p); 
  598. GETCHAR(cilen, p); 
  599. if (cilen != CILEN_LONG || 
  600. citype != opt) 
  601. goto bad; 
  602. GETLONG(cilong, p); 
  603. if (cilong != val) 
  604. goto bad; 
  605. }
  606. #define ACKCILQR(opt, neg, val) 
  607. if (neg) { 
  608. if ((len -= CILEN_LQR) < 0) 
  609. goto bad; 
  610. GETCHAR(citype, p); 
  611. GETCHAR(cilen, p); 
  612. if (cilen != CILEN_LQR || 
  613. citype != opt) 
  614. goto bad; 
  615. GETSHORT(cishort, p); 
  616. if (cishort != PPP_LQR) 
  617. goto bad; 
  618. GETLONG(cilong, p); 
  619. if (cilong != val) 
  620. goto bad; 
  621. }
  622. ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru);
  623. ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl,
  624. go->asyncmap);
  625. ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
  626. ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
  627. ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
  628. ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
  629. ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
  630. ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
  631. ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
  632. /*
  633.  * If there are any remaining CIs, then this packet is bad.
  634.  */
  635. if (len != 0)
  636. goto bad;
  637. LCPDEBUG((LOG_INFO, "lcp_acki: Ackn"));
  638. return (1);
  639. bad:
  640. LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!n"));
  641. return (0);
  642. }
  643. /*
  644.  * lcp_nakci - Peer has sent a NAK for some of our CIs.
  645.  * This should not modify any state if the Nak is bad
  646.  * or if LCP is in the OPENED state.
  647.  *
  648.  * Returns:
  649.  * 0 - Nak was bad.
  650.  * 1 - Nak was good.
  651.  */
  652. static int lcp_nakci(fsm *f, u_char *p, int len)
  653. {
  654. lcp_options *go = &lcp_gotoptions[f->unit];
  655. lcp_options *wo = &lcp_wantoptions[f->unit];
  656. u_char citype, cichar, *next;
  657. u_short cishort;
  658. u32_t cilong;
  659. lcp_options no; /* options we've seen Naks for */
  660. lcp_options try; /* options to request next time */
  661. int looped_back = 0;
  662. int cilen;
  663. BZERO(&no, sizeof(no));
  664. try = *go;
  665. /*
  666. * Any Nak'd CIs must be in exactly the same order that we sent.
  667. * Check packet length and CI length at each step.
  668. * If we find any deviations, then this packet is bad.
  669. */
  670. #define NAKCIVOID(opt, neg, code) 
  671. if (go->neg && 
  672. len >= CILEN_VOID && 
  673. p[1] == CILEN_VOID && 
  674. p[0] == opt) { 
  675. len -= CILEN_VOID; 
  676. INCPTR(CILEN_VOID, p); 
  677. no.neg = 1; 
  678. code 
  679. }
  680. #define NAKCICHAP(opt, neg, code) 
  681. if (go->neg && 
  682. len >= CILEN_CHAP && 
  683. p[1] == CILEN_CHAP && 
  684. p[0] == opt) { 
  685. len -= CILEN_CHAP; 
  686. INCPTR(2, p); 
  687. GETSHORT(cishort, p); 
  688. GETCHAR(cichar, p); 
  689. no.neg = 1; 
  690. code 
  691. }
  692. #define NAKCICHAR(opt, neg, code) 
  693. if (go->neg && 
  694. len >= CILEN_CHAR && 
  695. p[1] == CILEN_CHAR && 
  696. p[0] == opt) { 
  697. len -= CILEN_CHAR; 
  698. INCPTR(2, p); 
  699. GETCHAR(cichar, p); 
  700. no.neg = 1; 
  701. code 
  702. }
  703. #define NAKCISHORT(opt, neg, code) 
  704. if (go->neg && 
  705. len >= CILEN_SHORT && 
  706. p[1] == CILEN_SHORT && 
  707. p[0] == opt) { 
  708. len -= CILEN_SHORT; 
  709. INCPTR(2, p); 
  710. GETSHORT(cishort, p); 
  711. no.neg = 1; 
  712. code 
  713. }
  714. #define NAKCILONG(opt, neg, code) 
  715. if (go->neg && 
  716. len >= CILEN_LONG && 
  717. p[1] == CILEN_LONG && 
  718. p[0] == opt) { 
  719. len -= CILEN_LONG; 
  720. INCPTR(2, p); 
  721. GETLONG(cilong, p); 
  722. no.neg = 1; 
  723. code 
  724. }
  725. #define NAKCILQR(opt, neg, code) 
  726. if (go->neg && 
  727. len >= CILEN_LQR && 
  728. p[1] == CILEN_LQR && 
  729. p[0] == opt) { 
  730. len -= CILEN_LQR; 
  731. INCPTR(2, p); 
  732. GETSHORT(cishort, p); 
  733. GETLONG(cilong, p); 
  734. no.neg = 1; 
  735. code 
  736. }
  737. /*
  738. * We don't care if they want to send us smaller packets than
  739. * we want.  Therefore, accept any MRU less than what we asked for,
  740. * but then ignore the new value when setting the MRU in the kernel.
  741. * If they send us a bigger MRU than what we asked, accept it, up to
  742. * the limit of the default MRU we'd get if we didn't negotiate.
  743. */
  744. if (go->neg_mru && go->mru != PPP_DEFMRU) {
  745. NAKCISHORT(CI_MRU, neg_mru,
  746. if (cishort <= wo->mru || cishort < PPP_DEFMRU)
  747. try.mru = cishort;
  748. );
  749. }
  750. /*
  751. * Add any characters they want to our (receive-side) asyncmap.
  752. */
  753. if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) {
  754. NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
  755. try.asyncmap = go->asyncmap | cilong;
  756. );
  757. }
  758. /*
  759. * If they've nak'd our authentication-protocol, check whether
  760. * they are proposing a different protocol, or a different
  761. * hash algorithm for CHAP.
  762. */
  763. if ((go->neg_chap || go->neg_upap)
  764. && len >= CILEN_SHORT
  765. && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
  766. cilen = p[1];
  767. len -= cilen;
  768. no.neg_chap = go->neg_chap;
  769. no.neg_upap = go->neg_upap;
  770. INCPTR(2, p);
  771. GETSHORT(cishort, p);
  772. if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
  773. /*
  774.  * If we were asking for CHAP, they obviously don't want to do it.
  775.  * If we weren't asking for CHAP, then we were asking for PAP,
  776.  * in which case this Nak is bad.
  777.  */
  778. if (!go->neg_chap)
  779. goto bad;
  780. try.neg_chap = 0;
  781. } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
  782. GETCHAR(cichar, p);
  783. if (go->neg_chap) {
  784. /*
  785.  * We were asking for CHAP/MD5; they must want a different
  786.  * algorithm.  If they can't do MD5, we'll have to stop
  787.  * asking for CHAP.
  788.  */
  789. if (cichar != go->chap_mdtype)
  790. try.neg_chap = 0;
  791. } else {
  792. /*
  793.  * Stop asking for PAP if we were asking for it.
  794.  */
  795. try.neg_upap = 0;
  796. }
  797. } else {
  798. /*
  799.  * We don't recognize what they're suggesting.
  800.  * Stop asking for what we were asking for.
  801.  */
  802. if (go->neg_chap)
  803. try.neg_chap = 0;
  804. else
  805. try.neg_upap = 0;
  806. p += cilen - CILEN_SHORT;
  807. }
  808. }
  809. /*
  810. * If they can't cope with our link quality protocol, we'll have
  811. * to stop asking for LQR.  We haven't got any other protocol.
  812. * If they Nak the reporting period, take their value XXX ?
  813. */
  814. NAKCILQR(CI_QUALITY, neg_lqr,
  815. if (cishort != PPP_LQR)
  816. try.neg_lqr = 0;
  817. else
  818. try.lqr_period = cilong;
  819. );
  820. /*
  821. * Only implementing CBCP...not the rest of the callback options
  822. */
  823. NAKCICHAR(CI_CALLBACK, neg_cbcp,
  824. try.neg_cbcp = 0;
  825. );
  826. /*
  827. * Check for a looped-back line.
  828. */
  829. NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
  830. try.magicnumber = magic();
  831. looped_back = 1;
  832. );
  833. /*
  834. * Peer shouldn't send Nak for protocol compression or
  835. * address/control compression requests; they should send
  836. * a Reject instead.  If they send a Nak, treat it as a Reject.
  837. */
  838. NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,
  839. try.neg_pcompression = 0;
  840. );
  841. NAKCIVOID(CI_ACCOMPRESSION, neg_accompression,
  842. try.neg_accompression = 0;
  843. );
  844. /*
  845. * There may be remaining CIs, if the peer is requesting negotiation
  846. * on an option that we didn't include in our request packet.
  847. * If we see an option that we requested, or one we've already seen
  848. * in this packet, then this packet is bad.
  849. * If we wanted to respond by starting to negotiate on the requested
  850. * option(s), we could, but we don't, because except for the
  851. * authentication type and quality protocol, if we are not negotiating
  852. * an option, it is because we were told not to.
  853. * For the authentication type, the Nak from the peer means
  854. * `let me authenticate myself with you' which is a bit pointless.
  855. * For the quality protocol, the Nak means `ask me to send you quality
  856. * reports', but if we didn't ask for them, we don't want them.
  857. * An option we don't recognize represents the peer asking to
  858. * negotiate some option we don't support, so ignore it.
  859. */
  860. while (len > CILEN_VOID) {
  861. GETCHAR(citype, p);
  862. GETCHAR(cilen, p);
  863. if (cilen < CILEN_VOID || (len -= cilen) < 0)
  864. goto bad;
  865. next = p + cilen - 2;
  866. switch (citype) {
  867. case CI_MRU:
  868. if ((go->neg_mru && go->mru != PPP_DEFMRU)
  869. || no.neg_mru || cilen != CILEN_SHORT)
  870. goto bad;
  871. GETSHORT(cishort, p);
  872. if (cishort < PPP_DEFMRU)
  873. try.mru = cishort;
  874. break;
  875. case CI_ASYNCMAP:
  876. if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl)
  877. || no.neg_asyncmap || cilen != CILEN_LONG)
  878. goto bad;
  879. break;
  880. case CI_AUTHTYPE:
  881. if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap)
  882. goto bad;
  883. break;
  884. case CI_MAGICNUMBER:
  885. if (go->neg_magicnumber || no.neg_magicnumber ||
  886. cilen != CILEN_LONG)
  887. goto bad;
  888. break;
  889. case CI_PCOMPRESSION:
  890. if (go->neg_pcompression || no.neg_pcompression
  891. || cilen != CILEN_VOID)
  892. goto bad;
  893. break;
  894. case CI_ACCOMPRESSION:
  895. if (go->neg_accompression || no.neg_accompression
  896. || cilen != CILEN_VOID)
  897. goto bad;
  898. break;
  899. case CI_QUALITY:
  900. if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
  901. goto bad;
  902. break;
  903. }
  904. p = next;
  905. }
  906. /* If there is still anything left, this packet is bad. */
  907. if (len != 0)
  908. goto bad;
  909. /*
  910. * OK, the Nak is good.  Now we can update state.
  911. */
  912. if (f->state != OPENED) {
  913. if (looped_back) {
  914. if (++try.numloops >= lcp_loopbackfail) {
  915. LCPDEBUG((LOG_NOTICE, "Serial line is looped back.n"));
  916. lcp_close(f->unit, "Loopback detected");
  917. }
  918. else
  919. try.numloops = 0;
  920. *go = try;
  921. }
  922. return 1;
  923. bad:
  924. LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!n"));
  925. return 0;
  926. }
  927. /*
  928.  * lcp_rejci - Peer has Rejected some of our CIs.
  929.  * This should not modify any state if the Reject is bad
  930.  * or if LCP is in the OPENED state.
  931.  *
  932.  * Returns:
  933.  * 0 - Reject was bad.
  934.  * 1 - Reject was good.
  935.  */
  936. static int lcp_rejci(fsm *f, u_char *p, int len)
  937. {
  938. lcp_options *go = &lcp_gotoptions[f->unit];
  939. u_char cichar;
  940. u_short cishort;
  941. u32_t cilong;
  942. lcp_options try; /* options to request next time */
  943. try = *go;
  944. /*
  945. * Any Rejected CIs must be in exactly the same order that we sent.
  946. * Check packet length and CI length at each step.
  947. * If we find any deviations, then this packet is bad.
  948. */
  949. #define REJCIVOID(opt, neg) 
  950. if (go->neg && 
  951. len >= CILEN_VOID && 
  952. p[1] == CILEN_VOID && 
  953. p[0] == opt) { 
  954. len -= CILEN_VOID; 
  955. INCPTR(CILEN_VOID, p); 
  956. try.neg = 0; 
  957. LCPDEBUG((LOG_INFO, "lcp_rejci: void opt %d rejectedn", opt)); 
  958. }
  959. #define REJCISHORT(opt, neg, val) 
  960. if (go->neg && 
  961. len >= CILEN_SHORT && 
  962. p[1] == CILEN_SHORT && 
  963. p[0] == opt) { 
  964. len -= CILEN_SHORT; 
  965. INCPTR(2, p); 
  966. GETSHORT(cishort, p); 
  967. /* Check rejected value. */ 
  968. if (cishort != val) 
  969. goto bad; 
  970. try.neg = 0; 
  971. LCPDEBUG((LOG_INFO,"lcp_rejci: short opt %d rejectedn", opt)); 
  972. }
  973. #define REJCICHAP(opt, neg, val, digest) 
  974. if (go->neg && 
  975. len >= CILEN_CHAP && 
  976. p[1] == CILEN_CHAP && 
  977. p[0] == opt) { 
  978. len -= CILEN_CHAP; 
  979. INCPTR(2, p); 
  980. GETSHORT(cishort, p); 
  981. GETCHAR(cichar, p); 
  982. /* Check rejected value. */ 
  983. if (cishort != val || cichar != digest) 
  984. goto bad; 
  985. try.neg = 0; 
  986. try.neg_upap = 0; 
  987. LCPDEBUG((LOG_INFO,"lcp_rejci: chap opt %d rejectedn", opt)); 
  988. }
  989. #define REJCILONG(opt, neg, val) 
  990. if (go->neg && 
  991. len >= CILEN_LONG && 
  992. p[1] == CILEN_LONG && 
  993. p[0] == opt) { 
  994. len -= CILEN_LONG; 
  995. INCPTR(2, p); 
  996. GETLONG(cilong, p); 
  997. /* Check rejected value. */ 
  998. if (cilong != val) 
  999. goto bad; 
  1000. try.neg = 0; 
  1001. LCPDEBUG((LOG_INFO,"lcp_rejci: long opt %d rejectedn", opt)); 
  1002. }
  1003. #define REJCILQR(opt, neg, val) 
  1004. if (go->neg && 
  1005. len >= CILEN_LQR && 
  1006. p[1] == CILEN_LQR && 
  1007. p[0] == opt) { 
  1008. len -= CILEN_LQR; 
  1009. INCPTR(2, p); 
  1010. GETSHORT(cishort, p); 
  1011. GETLONG(cilong, p); 
  1012. /* Check rejected value. */ 
  1013. if (cishort != PPP_LQR || cilong != val) 
  1014. goto bad; 
  1015. try.neg = 0; 
  1016. LCPDEBUG((LOG_INFO,"lcp_rejci: LQR opt %d rejectedn", opt)); 
  1017. }
  1018. #define REJCICBCP(opt, neg, val) 
  1019. if (go->neg && 
  1020. len >= CILEN_CBCP && 
  1021. p[1] == CILEN_CBCP && 
  1022. p[0] == opt) { 
  1023. len -= CILEN_CBCP; 
  1024. INCPTR(2, p); 
  1025. GETCHAR(cichar, p); 
  1026. /* Check rejected value. */ 
  1027. if (cichar != val) 
  1028. goto bad; 
  1029. try.neg = 0; 
  1030. LCPDEBUG((LOG_INFO,"lcp_rejci: Callback opt %d rejectedn", opt)); 
  1031. }
  1032. REJCISHORT(CI_MRU, neg_mru, go->mru);
  1033. REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
  1034. REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype);
  1035. if (!go->neg_chap) {
  1036. REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
  1037. }
  1038. REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
  1039. REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
  1040. REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
  1041. REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
  1042. REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
  1043. /*
  1044. * If there are any remaining CIs, then this packet is bad.
  1045. */
  1046. if (len != 0)
  1047. goto bad;
  1048. /*
  1049. * Now we can update state.
  1050. */
  1051. if (f->state != OPENED)
  1052. *go = try;
  1053. return 1;
  1054. bad:
  1055. LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!n"));
  1056. return 0;
  1057. }
  1058. /*
  1059.  * lcp_reqci - Check the peer's requested CIs and send appropriate response.
  1060.  *
  1061.  * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
  1062.  * appropriately.  If reject_if_disagree is non-zero, doesn't return
  1063.  * CONFNAK; returns CONFREJ if it can't return CONFACK.
  1064.  */
  1065. static int lcp_reqci(fsm *f, 
  1066. u_char *inp, /* Requested CIs */
  1067. int *lenp, /* Length of requested CIs */
  1068. int reject_if_disagree)
  1069. {
  1070. lcp_options *go = &lcp_gotoptions[f->unit];
  1071. lcp_options *ho = &lcp_hisoptions[f->unit];
  1072. lcp_options *ao = &lcp_allowoptions[f->unit];
  1073. u_char *cip, *next; /* Pointer to current and next CIs */
  1074. int cilen, citype, cichar; /* Parsed len, type, char value */
  1075. u_short cishort; /* Parsed short value */
  1076. u32_t cilong; /* Parse long value */
  1077. int rc = CONFACK; /* Final packet return code */
  1078. int orc; /* Individual option return code */
  1079. u_char *p; /* Pointer to next char to parse */
  1080. u_char *rejp; /* Pointer to next char in reject frame */
  1081. u_char *nakp; /* Pointer to next char in Nak frame */
  1082. int l = *lenp; /* Length left */
  1083. #if TRACELCP > 0
  1084. char traceBuf[80];
  1085. int traceNdx = 0;
  1086. #endif
  1087. /*
  1088.  * Reset all his options.
  1089.  */
  1090. BZERO(ho, sizeof(*ho));
  1091. /*
  1092.  * Process all his options.
  1093.  */
  1094. next = inp;
  1095. nakp = nak_buffer;
  1096. rejp = inp;
  1097. while (l) {
  1098. orc = CONFACK; /* Assume success */
  1099. cip = p = next; /* Remember begining of CI */
  1100. if (l < 2 || /* Not enough data for CI header or */
  1101. p[1] < 2 || /*  CI length too small or */
  1102. p[1] > l) { /*  CI length too big? */
  1103. LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!n"));
  1104. orc = CONFREJ; /* Reject bad CI */
  1105. cilen = l; /* Reject till end of packet */
  1106. l = 0; /* Don't loop again */
  1107. citype = 0;
  1108. goto endswitch;
  1109. }
  1110. GETCHAR(citype, p); /* Parse CI type */
  1111. GETCHAR(cilen, p); /* Parse CI length */
  1112. l -= cilen; /* Adjust remaining length */
  1113. next += cilen; /* Step to next CI */
  1114. switch (citype) { /* Check CI type */
  1115. case CI_MRU:
  1116. if (!ao->neg_mru) { /* Allow option? */
  1117. LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - not allowedn"));
  1118. orc = CONFREJ; /* Reject CI */
  1119. break;
  1120. } else if (cilen != CILEN_SHORT) { /* Check CI length */
  1121. LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - bad lengthn"));
  1122. orc = CONFREJ; /* Reject CI */
  1123. break;
  1124. }
  1125. GETSHORT(cishort, p); /* Parse MRU */
  1126. /*
  1127.  * He must be able to receive at least our minimum.
  1128.  * No need to check a maximum.  If he sends a large number,
  1129.  * we'll just ignore it.
  1130.  */
  1131. if (cishort < PPP_MINMRU) {
  1132. LCPDEBUG((LOG_INFO, "lcp_reqci: Nak - MRU too smalln"));
  1133. orc = CONFNAK; /* Nak CI */
  1134. PUTCHAR(CI_MRU, nakp);
  1135. PUTCHAR(CILEN_SHORT, nakp);
  1136. PUTSHORT(PPP_MINMRU, nakp); /* Give him a hint */
  1137. break;
  1138. }
  1139. ho->neg_mru = 1; /* Remember he sent MRU */
  1140. ho->mru = cishort; /* And remember value */
  1141. #if TRACELCP > 0
  1142. sprintf(&traceBuf[traceNdx], " MRU %d", cishort);
  1143. traceNdx = strlen(traceBuf);
  1144. #endif
  1145. break;
  1146. case CI_ASYNCMAP:
  1147. if (!ao->neg_asyncmap) {
  1148. LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP not allowedn"));
  1149. orc = CONFREJ;
  1150. break;
  1151. } else if (cilen != CILEN_LONG) {
  1152. LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP bad lengthn"));
  1153. orc = CONFREJ;
  1154. break;
  1155. }
  1156. GETLONG(cilong, p);
  1157. /*
  1158.  * Asyncmap must have set at least the bits
  1159.  * which are set in lcp_allowoptions[unit].asyncmap.
  1160.  */
  1161. if ((ao->asyncmap & ~cilong) != 0) {
  1162. LCPDEBUG((LOG_INFO, "lcp_reqci: Nak ASYNCMAP %lX missing %lXn", 
  1163. cilong, ao->asyncmap));
  1164. orc = CONFNAK;
  1165. PUTCHAR(CI_ASYNCMAP, nakp);
  1166. PUTCHAR(CILEN_LONG, nakp);
  1167. PUTLONG(ao->asyncmap | cilong, nakp);
  1168. break;
  1169. }
  1170. ho->neg_asyncmap = 1;
  1171. ho->asyncmap = cilong;
  1172. #if TRACELCP > 0
  1173. sprintf(&traceBuf[traceNdx], " ASYNCMAP=%lX", cilong);
  1174. traceNdx = strlen(traceBuf);
  1175. #endif
  1176. break;
  1177. case CI_AUTHTYPE:
  1178. if (cilen < CILEN_SHORT) {
  1179. LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE missing argn"));
  1180. orc = CONFREJ;
  1181. break;
  1182. } else if (!(ao->neg_upap || ao->neg_chap)) {
  1183. /*
  1184.  * Reject the option if we're not willing to authenticate.
  1185.  */
  1186. LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE not allowedn"));
  1187. orc = CONFREJ;
  1188. break;
  1189. }
  1190. GETSHORT(cishort, p);
  1191. /*
  1192.  * Authtype must be UPAP or CHAP.
  1193.  *
  1194.  * Note: if both ao->neg_upap and ao->neg_chap are set,
  1195.  * and the peer sends a Configure-Request with two
  1196.  * authenticate-protocol requests, one for CHAP and one
  1197.  * for UPAP, then we will reject the second request.
  1198.  * Whether we end up doing CHAP or UPAP depends then on
  1199.  * the ordering of the CIs in the peer's Configure-Request.
  1200.  */
  1201. if (cishort == PPP_PAP) {
  1202. if (ho->neg_chap) { /* we've already accepted CHAP */
  1203. LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP already acceptedn"));
  1204. orc = CONFREJ;
  1205. break;
  1206. } else if (cilen != CILEN_SHORT) {
  1207. LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP bad lenn"));
  1208. orc = CONFREJ;
  1209. break;
  1210. }
  1211. if (!ao->neg_upap) { /* we don't want to do PAP */
  1212. LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE PAP not allowedn"));
  1213. orc = CONFNAK; /* NAK it and suggest CHAP */
  1214. PUTCHAR(CI_AUTHTYPE, nakp);
  1215. PUTCHAR(CILEN_CHAP, nakp);
  1216. PUTSHORT(PPP_CHAP, nakp);
  1217. PUTCHAR(ao->chap_mdtype, nakp);
  1218. break;
  1219. }
  1220. ho->neg_upap = 1;
  1221. #if TRACELCP > 0
  1222. sprintf(&traceBuf[traceNdx], " PAP (%X)", cishort);
  1223. traceNdx = strlen(traceBuf);
  1224. #endif
  1225. break;
  1226. }
  1227. if (cishort == PPP_CHAP) {
  1228. if (ho->neg_upap) { /* we've already accepted PAP */
  1229. LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP accepted PAPn"));
  1230. orc = CONFREJ;
  1231. break;
  1232. } else if (cilen != CILEN_CHAP) {
  1233. LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP bad lenn"));
  1234. orc = CONFREJ;
  1235. break;
  1236. }
  1237. if (!ao->neg_chap) { /* we don't want to do CHAP */
  1238. LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP not allowedn"));
  1239. orc = CONFNAK; /* NAK it and suggest PAP */
  1240. PUTCHAR(CI_AUTHTYPE, nakp);
  1241. PUTCHAR(CILEN_SHORT, nakp);
  1242. PUTSHORT(PPP_PAP, nakp);
  1243. break;
  1244. }
  1245. GETCHAR(cichar, p); /* get digest type*/
  1246. if (cichar != CHAP_DIGEST_MD5
  1247. #ifdef CHAPMS
  1248. && cichar != CHAP_MICROSOFT
  1249. #endif
  1250. ) {
  1251. LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP digest=%dn", cichar));
  1252. orc = CONFNAK;
  1253. PUTCHAR(CI_AUTHTYPE, nakp);
  1254. PUTCHAR(CILEN_CHAP, nakp);
  1255. PUTSHORT(PPP_CHAP, nakp);
  1256. PUTCHAR(ao->chap_mdtype, nakp);
  1257. break;
  1258. }
  1259. #if TRACELCP > 0
  1260. sprintf(&traceBuf[traceNdx], " CHAP %X,%d", cishort, cichar);
  1261. traceNdx = strlen(traceBuf);
  1262. #endif
  1263. ho->chap_mdtype = cichar; /* save md type */
  1264. ho->neg_chap = 1;
  1265. break;
  1266. }
  1267. /*
  1268.  * We don't recognize the protocol they're asking for.
  1269.  * Nak it with something we're willing to do.
  1270.  * (At this point we know ao->neg_upap || ao->neg_chap.)
  1271.  */
  1272. orc = CONFNAK;
  1273. PUTCHAR(CI_AUTHTYPE, nakp);
  1274. if (ao->neg_chap) {
  1275. LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req CHAPn", cishort));
  1276. PUTCHAR(CILEN_CHAP, nakp);
  1277. PUTSHORT(PPP_CHAP, nakp);
  1278. PUTCHAR(ao->chap_mdtype, nakp);
  1279. else {
  1280. LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req PAPn", cishort));
  1281. PUTCHAR(CILEN_SHORT, nakp);
  1282. PUTSHORT(PPP_PAP, nakp);
  1283. }
  1284. break;
  1285. case CI_QUALITY:
  1286. GETSHORT(cishort, p);
  1287. GETLONG(cilong, p);
  1288. #if TRACELCP > 0
  1289. sprintf(&traceBuf[traceNdx], " QUALITY (%x %x)", cishort, (unsigned int) cilong);
  1290. traceNdx = strlen(traceBuf);
  1291. #endif
  1292. if (!ao->neg_lqr ||
  1293. cilen != CILEN_LQR) {
  1294. orc = CONFREJ;
  1295. break;
  1296. }
  1297. /*
  1298.  * Check the protocol and the reporting period.
  1299.  * XXX When should we Nak this, and what with?
  1300.  */
  1301. if (cishort != PPP_LQR) {
  1302. orc = CONFNAK;
  1303. PUTCHAR(CI_QUALITY, nakp);
  1304. PUTCHAR(CILEN_LQR, nakp);
  1305. PUTSHORT(PPP_LQR, nakp);
  1306. PUTLONG(ao->lqr_period, nakp);
  1307. break;
  1308. }
  1309. break;
  1310. case CI_MAGICNUMBER:
  1311. if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
  1312. cilen != CILEN_LONG) {
  1313. orc = CONFREJ;
  1314. break;
  1315. }
  1316. GETLONG(cilong, p);
  1317. #if TRACELCP > 0
  1318. sprintf(&traceBuf[traceNdx], " MAGICNUMBER (%lX)", cilong);
  1319. traceNdx = strlen(traceBuf);
  1320. #endif
  1321. /*
  1322.  * He must have a different magic number.
  1323.  */
  1324. if (go->neg_magicnumber &&
  1325. cilong == go->magicnumber) {
  1326. cilong = magic(); /* Don't put magic() inside macro! */
  1327. orc = CONFNAK;
  1328. PUTCHAR(CI_MAGICNUMBER, nakp);
  1329. PUTCHAR(CILEN_LONG, nakp);
  1330. PUTLONG(cilong, nakp);
  1331. break;
  1332. }
  1333. ho->neg_magicnumber = 1;
  1334. ho->magicnumber = cilong;
  1335. break;
  1336. case CI_PCOMPRESSION:
  1337. #if TRACELCP > 0
  1338. sprintf(&traceBuf[traceNdx], " PCOMPRESSION");
  1339. traceNdx = strlen(traceBuf);
  1340. #endif
  1341. if (!ao->neg_pcompression ||
  1342. cilen != CILEN_VOID) {
  1343. orc = CONFREJ;
  1344. break;
  1345. }
  1346. ho->neg_pcompression = 1;
  1347. break;
  1348. case CI_ACCOMPRESSION:
  1349. #if TRACELCP > 0
  1350. sprintf(&traceBuf[traceNdx], " ACCOMPRESSION");
  1351. traceNdx = strlen(traceBuf);
  1352. #endif
  1353. if (!ao->neg_accompression ||
  1354. cilen != CILEN_VOID) {
  1355. orc = CONFREJ;
  1356. break;
  1357. }
  1358. ho->neg_accompression = 1;
  1359. break;
  1360. case CI_MRRU:
  1361. #if TRACELCP > 0
  1362. sprintf(&traceBuf[traceNdx], " CI_MRRU");
  1363. traceNdx = strlen(traceBuf);
  1364. #endif
  1365. orc = CONFREJ;
  1366. break;
  1367. case CI_SSNHF:
  1368. #if TRACELCP > 0
  1369. sprintf(&traceBuf[traceNdx], " CI_SSNHF");
  1370. traceNdx = strlen(traceBuf);
  1371. #endif
  1372. orc = CONFREJ;
  1373. break;
  1374. case CI_EPDISC:
  1375. #if TRACELCP > 0
  1376. sprintf(&traceBuf[traceNdx], " CI_EPDISC");
  1377. traceNdx = strlen(traceBuf);
  1378. #endif
  1379. orc = CONFREJ;
  1380. break;
  1381. default:
  1382. #if TRACELCP
  1383. sprintf(&traceBuf[traceNdx], " unknown %d", citype);
  1384. traceNdx = strlen(traceBuf);
  1385. #endif
  1386. orc = CONFREJ;
  1387. break;
  1388. }
  1389. endswitch:
  1390. #if TRACELCP
  1391. if (traceNdx >= 80 - 32) {
  1392. LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd%sn", traceBuf));
  1393. traceNdx = 0;
  1394. }
  1395. #endif
  1396. if (orc == CONFACK && /* Good CI */
  1397. rc != CONFACK) /*  but prior CI wasnt? */
  1398. continue; /* Don't send this one */
  1399. if (orc == CONFNAK) { /* Nak this CI? */
  1400. if (reject_if_disagree /* Getting fed up with sending NAKs? */
  1401. && citype != CI_MAGICNUMBER) {
  1402. orc = CONFREJ; /* Get tough if so */
  1403. else {
  1404. if (rc == CONFREJ) /* Rejecting prior CI? */
  1405. continue; /* Don't send this one */
  1406. rc = CONFNAK;
  1407. }
  1408. }
  1409. if (orc == CONFREJ) { /* Reject this CI */
  1410. rc = CONFREJ;
  1411. if (cip != rejp) /* Need to move rejected CI? */
  1412. BCOPY(cip, rejp, cilen); /* Move it */
  1413. INCPTR(cilen, rejp); /* Update output pointer */
  1414. }
  1415. }
  1416. /*
  1417.  * If we wanted to send additional NAKs (for unsent CIs), the
  1418.  * code would go here.  The extra NAKs would go at *nakp.
  1419.  * At present there are no cases where we want to ask the
  1420.  * peer to negotiate an option.
  1421.  */
  1422. switch (rc) {
  1423. case CONFACK:
  1424. *lenp = (int)(next - inp);
  1425. break;
  1426. case CONFNAK:
  1427. /*
  1428.  * Copy the Nak'd options from the nak_buffer to the caller's buffer.
  1429.  */
  1430. *lenp = (int)(nakp - nak_buffer);
  1431. BCOPY(nak_buffer, inp, *lenp);
  1432. break;
  1433. case CONFREJ:
  1434. *lenp = (int)(rejp - inp);
  1435. break;
  1436. }
  1437. #if TRACELCP > 0
  1438. if (traceNdx > 0) {
  1439. LCPDEBUG((LOG_INFO, "lcp_reqci: %sn", traceBuf));
  1440. }
  1441. #endif
  1442. LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.n", CODENAME(rc)));
  1443. return (rc); /* Return final code */
  1444. }
  1445. /*
  1446.  * lcp_up - LCP has come UP.
  1447.  */
  1448. static void lcp_up(fsm *f)
  1449. {
  1450. lcp_options *wo = &lcp_wantoptions[f->unit];
  1451. lcp_options *ho = &lcp_hisoptions[f->unit];
  1452. lcp_options *go = &lcp_gotoptions[f->unit];
  1453. lcp_options *ao = &lcp_allowoptions[f->unit];
  1454. DEBUG_FUNCTION("lcp_up()");
  1455. if (!go->neg_magicnumber)
  1456. go->magicnumber = 0;
  1457. if (!ho->neg_magicnumber)
  1458. ho->magicnumber = 0;
  1459. /*
  1460. * Set our MTU to the smaller of the MTU we wanted and
  1461. * the MRU our peer wanted.  If we negotiated an MRU,
  1462. * set our MRU to the larger of value we wanted and
  1463. * the value we got in the negotiation.
  1464. */
  1465. ppp_send_config(f->unit, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),
  1466. (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl),
  1467. ho->neg_pcompression, ho->neg_accompression);
  1468. /*
  1469. * If the asyncmap hasn't been negotiated, we really should
  1470. * set the receive asyncmap to ffffffff, but we set it to 0
  1471. * for backwards contemptibility.
  1472. */
  1473. ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU),
  1474. (go->neg_asyncmap? go->asyncmap: 0x00000000),
  1475. go->neg_pcompression, go->neg_accompression);
  1476. if (ho->neg_mru)
  1477. peer_mru[f->unit] = ho->mru;
  1478. lcp_echo_lowerup(f->unit);  /* Enable echo messages */
  1479. link_established(f->unit);
  1480. }
  1481. /*
  1482.  * lcp_down - LCP has gone DOWN.
  1483.  *
  1484.  * Alert other protocols.
  1485.  */
  1486. static void lcp_down(fsm *f)
  1487. {
  1488. lcp_options *go = &lcp_gotoptions[f->unit];
  1489. lcp_echo_lowerdown(f->unit);
  1490. link_down(f->unit);
  1491. ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0);
  1492. ppp_recv_config(f->unit, PPP_MRU,
  1493. (go->neg_asyncmap? go->asyncmap: 0x00000000),
  1494. go->neg_pcompression, go->neg_accompression);
  1495. peer_mru[f->unit] = PPP_MRU;
  1496. }
  1497. /*
  1498.  * lcp_starting - LCP needs the lower layer up.
  1499.  */
  1500. static void lcp_starting(fsm *f)
  1501. {
  1502. link_required(f->unit);
  1503. }
  1504. /*
  1505.  * lcp_finished - LCP has finished with the lower layer.
  1506.  */
  1507. static void lcp_finished(fsm *f)
  1508. {
  1509. link_terminated(f->unit);
  1510. }
  1511. #if 0
  1512. /*
  1513.  * print_string - print a readable representation of a string using
  1514.  * printer.
  1515.  */
  1516. static void print_string(
  1517.     char *p,
  1518.     int len,
  1519.     void (*printer) (void *, char *, ...),
  1520.     void *arg
  1521. )
  1522. {
  1523.     int c;
  1524.     
  1525.     printer(arg, """);
  1526.     for (; len > 0; --len) {
  1527.         c = *p++;
  1528.         if (' ' <= c && c <= '~') {
  1529.             if (c == '\' || c == '"')
  1530.                 printer(arg, "\");
  1531.             printer(arg, "%c", c);
  1532.         } else {
  1533.             switch (c) {
  1534.             case 'n':
  1535.                 printer(arg, "\n");
  1536.                 break;
  1537.             case 'r':
  1538.                 printer(arg, "\r");
  1539.                 break;
  1540.             case 't':
  1541.                 printer(arg, "\t");
  1542.                 break;
  1543.             default:
  1544.                 printer(arg, "\%.3o", c);
  1545.             }
  1546.         }
  1547.     }
  1548.     printer(arg, """);
  1549. }
  1550. /*
  1551.  * lcp_printpkt - print the contents of an LCP packet.
  1552.  */
  1553. static char *lcp_codenames[] = {
  1554. "ConfReq", "ConfAck", "ConfNak", "ConfRej",
  1555. "TermReq", "TermAck", "CodeRej", "ProtRej",
  1556. "EchoReq", "EchoRep", "DiscReq"
  1557. };
  1558. static int lcp_printpkt(
  1559. u_char *p,
  1560. int plen,
  1561. void (*printer) (void *, char *, ...),
  1562. void *arg
  1563. )
  1564. {
  1565. int code, id, len, olen;
  1566. u_char *pstart, *optend;
  1567. u_short cishort;
  1568. u32_t cilong;
  1569. if (plen < HEADERLEN)
  1570. return 0;
  1571. pstart = p;
  1572. GETCHAR(code, p);
  1573. GETCHAR(id, p);
  1574. GETSHORT(len, p);
  1575. if (len < HEADERLEN || len > plen)
  1576. return 0;
  1577. if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))
  1578. printer(arg, " %s", lcp_codenames[code-1]);
  1579. else
  1580. printer(arg, " code=0x%x", code);
  1581. printer(arg, " id=0x%x", id);
  1582. len -= HEADERLEN;
  1583. switch (code) {
  1584. case CONFREQ:
  1585. case CONFACK:
  1586. case CONFNAK:
  1587. case CONFREJ:
  1588. /* print option list */
  1589. while (len >= 2) {
  1590. GETCHAR(code, p);
  1591. GETCHAR(olen, p);
  1592. p -= 2;
  1593. if (olen < 2 || olen > len) {
  1594. break;
  1595. }
  1596. printer(arg, " <");
  1597. len -= olen;
  1598. optend = p + olen;
  1599. switch (code) {
  1600. case CI_MRU:
  1601. if (olen == CILEN_SHORT) {
  1602. p += 2;
  1603. GETSHORT(cishort, p);
  1604. printer(arg, "mru %d", cishort);
  1605. }
  1606. break;
  1607. case CI_ASYNCMAP:
  1608. if (olen == CILEN_LONG) {
  1609. p += 2;
  1610. GETLONG(cilong, p);
  1611. printer(arg, "asyncmap 0x%lx", cilong);
  1612. }
  1613. break;
  1614. case CI_AUTHTYPE:
  1615. if (olen >= CILEN_SHORT) {
  1616. p += 2;
  1617. printer(arg, "auth ");
  1618. GETSHORT(cishort, p);
  1619. switch (cishort) {
  1620. case PPP_PAP:
  1621. printer(arg, "pap");
  1622. break;
  1623. case PPP_CHAP:
  1624. printer(arg, "chap");
  1625. break;
  1626. default:
  1627. printer(arg, "0x%x", cishort);
  1628. }
  1629. }
  1630. break;
  1631. case CI_QUALITY:
  1632. if (olen >= CILEN_SHORT) {
  1633. p += 2;
  1634. printer(arg, "quality ");
  1635. GETSHORT(cishort, p);
  1636. switch (cishort) {
  1637. case PPP_LQR:
  1638. printer(arg, "lqr");
  1639. break;
  1640. default:
  1641. printer(arg, "0x%x", cishort);
  1642. }
  1643. }
  1644. break;
  1645. case CI_CALLBACK:
  1646. if (olen >= CILEN_CHAR) {
  1647. p += 2;
  1648. printer(arg, "callback ");
  1649. GETSHORT(cishort, p);
  1650. switch (cishort) {
  1651. case CBCP_OPT:
  1652. printer(arg, "CBCP");
  1653. break;
  1654. default:
  1655. printer(arg, "0x%x", cishort);
  1656. }
  1657. }
  1658. break;
  1659. case CI_MAGICNUMBER:
  1660. if (olen == CILEN_LONG) {
  1661. p += 2;
  1662. GETLONG(cilong, p);
  1663. printer(arg, "magic 0x%x", cilong);
  1664. }
  1665. break;
  1666. case CI_PCOMPRESSION:
  1667. if (olen == CILEN_VOID) {
  1668. p += 2;
  1669. printer(arg, "pcomp");
  1670. }
  1671. break;
  1672. case CI_ACCOMPRESSION:
  1673. if (olen == CILEN_VOID) {
  1674. p += 2;
  1675. printer(arg, "accomp");
  1676. }
  1677. break;
  1678. }
  1679. while (p < optend) {
  1680. GETCHAR(code, p);
  1681. printer(arg, " %.2x", code);
  1682. }
  1683. printer(arg, ">");
  1684. }
  1685. break;
  1686. case TERMACK:
  1687. case TERMREQ:
  1688. if (len > 0 && *p >= ' ' && *p < 0x7f) {
  1689. printer(arg, " ");
  1690. print_string((char*)p, len, printer, arg);
  1691. p += len;
  1692. len = 0;
  1693. }
  1694. break;
  1695. case ECHOREQ:
  1696. case ECHOREP:
  1697. case DISCREQ:
  1698. if (len >= 4) {
  1699. GETLONG(cilong, p);
  1700. printer(arg, " magic=0x%x", cilong);
  1701. p += 4;
  1702. len -= 4;
  1703. }
  1704. break;
  1705. }
  1706. /* print the rest of the bytes in the packet */
  1707. for (; len > 0; --len) {
  1708. GETCHAR(code, p);
  1709. printer(arg, " %.2x", code);
  1710. }
  1711. return (int)(p - pstart);
  1712. }
  1713. #endif
  1714. /*
  1715.  * Time to shut down the link because there is nothing out there.
  1716.  */
  1717. static void LcpLinkFailure (fsm *f)
  1718. {
  1719. if (f->state == OPENED) {
  1720. LCPDEBUG((LOG_INFO, "No response to %d echo-requestsn", lcp_echos_pending));
  1721. LCPDEBUG((LOG_NOTICE, "Serial link appears to be disconnected.n"));
  1722. lcp_close(f->unit, "Peer not responding");
  1723. }
  1724. }
  1725. /*
  1726.  * Timer expired for the LCP echo requests from this process.
  1727.  */
  1728. static void LcpEchoCheck (fsm *f)
  1729. {
  1730. LcpSendEchoRequest (f);
  1731. /*
  1732.  * Start the timer for the next interval.
  1733.  */
  1734. LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0);
  1735. TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
  1736. lcp_echo_timer_running = 1;
  1737. }
  1738. /*
  1739.  * LcpEchoTimeout - Timer expired on the LCP echo
  1740.  */
  1741. static void LcpEchoTimeout (void *arg)
  1742. {
  1743. if (lcp_echo_timer_running != 0) {
  1744. lcp_echo_timer_running = 0;
  1745. LcpEchoCheck ((fsm *) arg);
  1746. }
  1747. }
  1748. /*
  1749.  * LcpEchoReply - LCP has received a reply to the echo
  1750.  */
  1751. static void lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len)
  1752. {
  1753. u32_t magic;
  1754. (void)id;
  1755. /* Check the magic number - don't count replies from ourselves. */
  1756. if (len < 4) {
  1757. LCPDEBUG((LOG_WARNING, "lcp: received short Echo-Reply, length %dn", len));
  1758. return;
  1759. }
  1760. GETLONG(magic, inp);
  1761. if (lcp_gotoptions[f->unit].neg_magicnumber
  1762. && magic == lcp_gotoptions[f->unit].magicnumber) {
  1763. LCPDEBUG((LOG_WARNING, "appear to have received our own echo-reply!n"));
  1764. return;
  1765. }
  1766. /* Reset the number of outstanding echo frames */
  1767. lcp_echos_pending = 0;
  1768. }
  1769. /*
  1770.  * LcpSendEchoRequest - Send an echo request frame to the peer
  1771.  */
  1772. static void LcpSendEchoRequest (fsm *f)
  1773. {
  1774. u32_t lcp_magic;
  1775. u_char pkt[4], *pktp;
  1776. /*
  1777. * Detect the failure of the peer at this point.
  1778. */
  1779. if (lcp_echo_fails != 0) {
  1780. if (lcp_echos_pending++ >= lcp_echo_fails) {
  1781. LcpLinkFailure(f);
  1782. lcp_echos_pending = 0;
  1783. }
  1784. }
  1785. /*
  1786. * Make and send the echo request frame.
  1787. */
  1788. if (f->state == OPENED) {
  1789. lcp_magic = lcp_gotoptions[f->unit].magicnumber;
  1790. pktp = pkt;
  1791. PUTLONG(lcp_magic, pktp);
  1792. fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt));
  1793. }
  1794. }
  1795. /*
  1796.  * lcp_echo_lowerup - Start the timer for the LCP frame
  1797.  */
  1798. static void lcp_echo_lowerup (int unit)
  1799. {
  1800. fsm *f = &lcp_fsm[unit];
  1801. /* Clear the parameters for generating echo frames */
  1802. lcp_echos_pending      = 0;
  1803. lcp_echo_number        = 0;
  1804. lcp_echo_timer_running = 0;
  1805. /* If a timeout interval is specified then start the timer */
  1806. if (lcp_echo_interval != 0)
  1807. LcpEchoCheck (f);
  1808. }
  1809. /*
  1810.  * lcp_echo_lowerdown - Stop the timer for the LCP frame
  1811.  */
  1812. static void lcp_echo_lowerdown (int unit)
  1813. {
  1814. fsm *f = &lcp_fsm[unit];
  1815. if (lcp_echo_timer_running != 0) {
  1816. UNTIMEOUT (LcpEchoTimeout, f);
  1817. lcp_echo_timer_running = 0;
  1818. }
  1819. }
  1820. #endif /* PPP_SUPPORT */