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

C/C++

  1. /*****************************************************************************
  2. * ipcp.c - Network PPP IP 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-08 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
  31. * Original.
  32. *****************************************************************************/
  33. /*
  34.  * ipcp.c - PPP IP 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. #include <string.h>
  52. #include "ppp.h"
  53. #if PPP_SUPPORT > 0
  54. #include "auth.h"
  55. #include "fsm.h"
  56. #include "vj.h"
  57. #include "ipcp.h"
  58. #include "pppdebug.h"
  59. /*************************/
  60. /*** LOCAL DEFINITIONS ***/
  61. /*************************/
  62. /* #define OLD_CI_ADDRS 1 */ /* Support deprecated address negotiation. */
  63. /*
  64.  * Lengths of configuration options.
  65.  */
  66. #define CILEN_VOID 2
  67. #define CILEN_COMPRESS 4 /* min length for compression protocol opt. */
  68. #define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */
  69. #define CILEN_ADDR 6 /* new-style single address option */
  70. #define CILEN_ADDRS 10 /* old-style dual address option */
  71. /***********************************/
  72. /*** LOCAL FUNCTION DECLARATIONS ***/
  73. /***********************************/
  74. /*
  75.  * Callbacks for fsm code.  (CI = Configuration Information)
  76.  */
  77. static void ipcp_resetci (fsm *); /* Reset our CI */
  78. static int  ipcp_cilen (fsm *);         /* Return length of our CI */
  79. static void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */
  80. static int  ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */
  81. static int  ipcp_nakci (fsm *, u_char *, int); /* Peer nak'd our CI */
  82. static int  ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */
  83. static int  ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */
  84. static void ipcp_up (fsm *); /* We're UP */
  85. static void ipcp_down (fsm *); /* We're DOWN */
  86. #if 0
  87. static void ipcp_script (fsm *, char *); /* Run an up/down script */
  88. #endif
  89. static void ipcp_finished (fsm *); /* Don't need lower layer */
  90. /*
  91.  * Protocol entry points from main code.
  92.  */
  93. static void ipcp_init (int);
  94. static void ipcp_open (int);
  95. static void ipcp_close (int, char *);
  96. static void ipcp_lowerup (int);
  97. static void ipcp_lowerdown (int);
  98. static void ipcp_input (int, u_char *, int);
  99. static void ipcp_protrej (int);
  100. static void ipcp_clear_addrs (int);
  101. #define CODENAME(x) ((x) == CONFACK ? "ACK" : 
  102.  (x) == CONFNAK ? "NAK" : "REJ")
  103. /******************************/
  104. /*** PUBLIC DATA STRUCTURES ***/
  105. /******************************/
  106. /* global vars */
  107. ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
  108. ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
  109. ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
  110. ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
  111. fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */
  112. struct protent ipcp_protent = {
  113.     PPP_IPCP,
  114.     ipcp_init,
  115.     ipcp_input,
  116.     ipcp_protrej,
  117.     ipcp_lowerup,
  118.     ipcp_lowerdown,
  119.     ipcp_open,
  120.     ipcp_close,
  121. #if 0
  122.     ipcp_printpkt,
  123.     NULL,
  124. #endif
  125.     1,
  126.     "IPCP",
  127. #if 0
  128.     ip_check_options,
  129.     NULL,
  130.     ip_active_pkt
  131. #endif
  132. };
  133. /*****************************/
  134. /*** LOCAL DATA STRUCTURES ***/
  135. /*****************************/
  136. /* local vars */
  137. static int cis_received[NUM_PPP]; /* # Conf-Reqs received */
  138. static int default_route_set[NUM_PPP]; /* Have set up a default route */
  139. static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
  140.     ipcp_resetci, /* Reset our Configuration Information */
  141.     ipcp_cilen, /* Length of our Configuration Information */
  142.     ipcp_addci, /* Add our Configuration Information */
  143.     ipcp_ackci, /* ACK our Configuration Information */
  144.     ipcp_nakci, /* NAK our Configuration Information */
  145.     ipcp_rejci, /* Reject our Configuration Information */
  146.     ipcp_reqci, /* Request peer's Configuration Information */
  147.     ipcp_up, /* Called when fsm reaches OPENED state */
  148.     ipcp_down, /* Called when fsm leaves OPENED state */
  149.     NULL, /* Called when we want the lower layer up */
  150.     ipcp_finished, /* Called when we want the lower layer down */
  151.     NULL, /* Called when Protocol-Reject received */
  152.     NULL, /* Retransmission is necessary */
  153.     NULL, /* Called to handle protocol-specific codes */
  154.     "IPCP" /* String name of protocol */
  155. };
  156. /**********************************/
  157. /*** LOCAL FUNCTION DEFINITIONS ***/
  158. /**********************************/
  159. /*
  160.  * Non-standard inet_ntoa left here for compat with original ppp
  161.  * sources. Assumes u32_t instead of struct in_addr.
  162.  */ 
  163. char * _inet_ntoa(u32_t n)
  164. {
  165. struct in_addr ia;
  166. ia.s_addr = n;
  167. return inet_ntoa(ia);
  168. }
  169. #define inet_ntoa _inet_ntoa
  170. /*
  171.  * ipcp_init - Initialize IPCP.
  172.  */
  173. static void ipcp_init(int unit)
  174. {
  175. fsm *f = &ipcp_fsm[unit];
  176. ipcp_options *wo = &ipcp_wantoptions[unit];
  177. ipcp_options *ao = &ipcp_allowoptions[unit];
  178. f->unit = unit;
  179. f->protocol = PPP_IPCP;
  180. f->callbacks = &ipcp_callbacks;
  181. fsm_init(&ipcp_fsm[unit]);
  182. memset(wo, 0, sizeof(*wo));
  183. memset(ao, 0, sizeof(*ao));
  184. wo->neg_addr = 1;
  185. wo->ouraddr = 0;
  186. #if VJ_SUPPORT > 0
  187. wo->neg_vj = 1;
  188. #else
  189. wo->neg_vj = 0;
  190. #endif
  191. wo->vj_protocol = IPCP_VJ_COMP;
  192. wo->maxslotindex = MAX_SLOTS - 1;
  193. wo->cflag = 0;
  194. wo->default_route = 1;
  195. ao->neg_addr = 1;
  196. #if VJ_SUPPORT > 0
  197. ao->neg_vj = 1;
  198. #else
  199. ao->neg_vj = 0;
  200. #endif
  201. ao->maxslotindex = MAX_SLOTS - 1;
  202. ao->cflag = 1;
  203. ao->default_route = 1;
  204. }
  205. /*
  206.  * ipcp_open - IPCP is allowed to come up.
  207.  */
  208. static void ipcp_open(int unit)
  209. {
  210.        DEBUG_FUNCTION("ipcp_open()");
  211. fsm_open(&ipcp_fsm[unit]);
  212. }
  213. /*
  214.  * ipcp_close - Take IPCP down.
  215.  */
  216. static void ipcp_close(int unit, char *reason)
  217. {
  218.        DEBUG_FUNCTION("ipcp_close()");
  219. fsm_close(&ipcp_fsm[unit], reason);
  220. }
  221. /*
  222.  * ipcp_lowerup - The lower layer is up.
  223.  */
  224. static void ipcp_lowerup(int unit)
  225. {
  226. fsm_lowerup(&ipcp_fsm[unit]);
  227. }
  228. /*
  229.  * ipcp_lowerdown - The lower layer is down.
  230.  */
  231. static void ipcp_lowerdown(int unit)
  232. {
  233. fsm_lowerdown(&ipcp_fsm[unit]);
  234. }
  235. /*
  236.  * ipcp_input - Input IPCP packet.
  237.  */
  238. static void ipcp_input(int unit, u_char *p, int len)
  239. {
  240. fsm_input(&ipcp_fsm[unit], p, len);
  241. }
  242. /*
  243.  * ipcp_protrej - A Protocol-Reject was received for IPCP.
  244.  *
  245.  * Pretend the lower layer went down, so we shut up.
  246.  */
  247. static void ipcp_protrej(int unit)
  248. {
  249. fsm_lowerdown(&ipcp_fsm[unit]);
  250. }
  251. /*
  252.  * ipcp_resetci - Reset our CI.
  253.  */
  254. static void ipcp_resetci(fsm *f)
  255. {
  256. ipcp_options *wo = &ipcp_wantoptions[f->unit];
  257. wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;
  258. if (wo->ouraddr == 0)
  259. wo->accept_local = 1;
  260. if (wo->hisaddr == 0)
  261. wo->accept_remote = 1;
  262. /* Request DNS addresses from the peer */
  263. wo->req_dns1 = ppp_settings.usepeerdns;
  264. wo->req_dns2 = ppp_settings.usepeerdns;
  265. ipcp_gotoptions[f->unit] = *wo;
  266. cis_received[f->unit] = 0;
  267. }
  268. /*
  269.  * ipcp_cilen - Return length of our CI.
  270.  */
  271. static int ipcp_cilen(fsm *f)
  272. {
  273. ipcp_options *go = &ipcp_gotoptions[f->unit];
  274. ipcp_options *wo = &ipcp_wantoptions[f->unit];
  275. ipcp_options *ho = &ipcp_hisoptions[f->unit];
  276. #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
  277. #define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)
  278. #define LENCIDNS(neg) (neg ? (CILEN_ADDR) : 0)
  279. /*
  280.  * First see if we want to change our options to the old
  281.  * forms because we have received old forms from the peer.
  282.  */
  283. if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {
  284. /* use the old style of address negotiation */
  285. go->neg_addr = 1;
  286. go->old_addrs = 1;
  287. }
  288. if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
  289. /* try an older style of VJ negotiation */
  290. if (cis_received[f->unit] == 0) {
  291. /* keep trying the new style until we see some CI from the peer */
  292. go->neg_vj = 1;
  293. } else {
  294. /* use the old style only if the peer did */
  295. if (ho->neg_vj && ho->old_vj) {
  296. go->neg_vj = 1;
  297. go->old_vj = 1;
  298. go->vj_protocol = ho->vj_protocol;
  299. }
  300. }
  301. }
  302. return (LENCIADDR(go->neg_addr, go->old_addrs)
  303. + LENCIVJ(go->neg_vj, go->old_vj) +
  304. LENCIDNS(go->req_dns1) +
  305. LENCIDNS(go->req_dns2));
  306. }
  307. /*
  308.  * ipcp_addci - Add our desired CIs to a packet.
  309.  */
  310. static void ipcp_addci(fsm *f, u_char *ucp, int *lenp)
  311. {
  312. ipcp_options *go = &ipcp_gotoptions[f->unit];
  313. int len = *lenp;
  314. #define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) 
  315. if (neg) { 
  316. int vjlen = old? CILEN_COMPRESS : CILEN_VJ; 
  317. if (len >= vjlen) { 
  318. PUTCHAR(opt, ucp); 
  319. PUTCHAR(vjlen, ucp); 
  320. PUTSHORT(val, ucp); 
  321. if (!old) { 
  322. PUTCHAR(maxslotindex, ucp); 
  323. PUTCHAR(cflag, ucp); 
  324. len -= vjlen; 
  325. } else 
  326. neg = 0; 
  327. }
  328. #define ADDCIADDR(opt, neg, old, val1, val2) 
  329. if (neg) { 
  330. int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); 
  331. if (len >= addrlen) { 
  332. u32_t l; 
  333. PUTCHAR(opt, ucp); 
  334. PUTCHAR(addrlen, ucp); 
  335. l = ntohl(val1); 
  336. PUTLONG(l, ucp); 
  337. if (old) { 
  338. l = ntohl(val2); 
  339. PUTLONG(l, ucp); 
  340. len -= addrlen; 
  341. } else 
  342. neg = 0; 
  343. }
  344. #define ADDCIDNS(opt, neg, addr) 
  345. if (neg) { 
  346. if (len >= CILEN_ADDR) { 
  347. u32_t l; 
  348. PUTCHAR(opt, ucp); 
  349. PUTCHAR(CILEN_ADDR, ucp); 
  350. l = ntohl(addr); 
  351. PUTLONG(l, ucp); 
  352. len -= CILEN_ADDR; 
  353. } else 
  354. neg = 0; 
  355. }
  356. ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
  357.   go->old_addrs, go->ouraddr, go->hisaddr);
  358. ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
  359. go->maxslotindex, go->cflag);
  360. ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
  361. ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
  362. *lenp -= len;
  363. }
  364. /*
  365.  * ipcp_ackci - Ack our CIs.
  366.  *
  367.  * Returns:
  368.  * 0 - Ack was bad.
  369.  * 1 - Ack was good.
  370.  */
  371. static int ipcp_ackci(fsm *f, u_char *p, int len)
  372. {
  373. ipcp_options *go = &ipcp_gotoptions[f->unit];
  374. u_short cilen, citype, cishort;
  375. u32_t cilong;
  376. u_char cimaxslotindex, cicflag;
  377. /*
  378.  * CIs must be in exactly the same order that we sent...
  379.  * Check packet length and CI length at each step.
  380.  * If we find any deviations, then this packet is bad.
  381.  */
  382. #define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) 
  383. if (neg) { 
  384. int vjlen = old? CILEN_COMPRESS : CILEN_VJ; 
  385. if ((len -= vjlen) < 0) 
  386. goto bad; 
  387. GETCHAR(citype, p); 
  388. GETCHAR(cilen, p); 
  389. if (cilen != vjlen || 
  390. citype != opt)  
  391. goto bad; 
  392. GETSHORT(cishort, p); 
  393. if (cishort != val) 
  394. goto bad; 
  395. if (!old) { 
  396. GETCHAR(cimaxslotindex, p); 
  397. if (cimaxslotindex != maxslotindex) 
  398. goto bad; 
  399. GETCHAR(cicflag, p); 
  400. if (cicflag != cflag) 
  401. goto bad; 
  402. }
  403. #define ACKCIADDR(opt, neg, old, val1, val2) 
  404. if (neg) { 
  405. int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); 
  406. u32_t l; 
  407. if ((len -= addrlen) < 0) 
  408. goto bad; 
  409. GETCHAR(citype, p); 
  410. GETCHAR(cilen, p); 
  411. if (cilen != addrlen || 
  412. citype != opt) 
  413. goto bad; 
  414. GETLONG(l, p); 
  415. cilong = htonl(l); 
  416. if (val1 != cilong) 
  417. goto bad; 
  418. if (old) { 
  419. GETLONG(l, p); 
  420. cilong = htonl(l); 
  421. if (val2 != cilong) 
  422. goto bad; 
  423. }
  424. #define ACKCIDNS(opt, neg, addr) 
  425. if (neg) { 
  426. u32_t l; 
  427. if ((len -= CILEN_ADDR) < 0) 
  428. goto bad; 
  429. GETCHAR(citype, p); 
  430. GETCHAR(cilen, p); 
  431. if (cilen != CILEN_ADDR || 
  432. citype != opt) 
  433. goto bad; 
  434. GETLONG(l, p); 
  435. cilong = htonl(l); 
  436. if (addr != cilong) 
  437. goto bad; 
  438. }
  439. ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
  440.   go->old_addrs, go->ouraddr, go->hisaddr);
  441. ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
  442. go->maxslotindex, go->cflag);
  443. ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
  444. ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
  445. /*
  446.  * If there are any remaining CIs, then this packet is bad.
  447.  */
  448. if (len != 0)
  449. goto bad;
  450. return (1);
  451. bad:
  452. IPCPDEBUG((LOG_INFO, "ipcp_ackci: received bad Ack!n"));
  453. return (0);
  454. }
  455. /*
  456.  * ipcp_nakci - Peer has sent a NAK for some of our CIs.
  457.  * This should not modify any state if the Nak is bad
  458.  * or if IPCP is in the OPENED state.
  459.  *
  460.  * Returns:
  461.  * 0 - Nak was bad.
  462.  * 1 - Nak was good.
  463.  */
  464. static int ipcp_nakci(fsm *f, u_char *p, int len)
  465. {
  466. ipcp_options *go = &ipcp_gotoptions[f->unit];
  467. u_char cimaxslotindex, cicflag;
  468. u_char citype, cilen, *next;
  469. u_short cishort;
  470. u32_t ciaddr1, ciaddr2, l, cidnsaddr;
  471. ipcp_options no; /* options we've seen Naks for */
  472. ipcp_options try; /* options to request next time */
  473. BZERO(&no, sizeof(no));
  474. try = *go;
  475. /*
  476.  * Any Nak'd CIs must be in exactly the same order that we sent.
  477.  * Check packet length and CI length at each step.
  478.  * If we find any deviations, then this packet is bad.
  479.  */
  480. #define NAKCIADDR(opt, neg, old, code) 
  481. if (go->neg && 
  482. len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && 
  483. p[1] == cilen && 
  484. p[0] == opt) { 
  485. len -= cilen; 
  486. INCPTR(2, p); 
  487. GETLONG(l, p); 
  488. ciaddr1 = htonl(l); 
  489. if (old) { 
  490. GETLONG(l, p); 
  491. ciaddr2 = htonl(l); 
  492. no.old_addrs = 1; 
  493. } else 
  494. ciaddr2 = 0; 
  495. no.neg = 1; 
  496. code 
  497. }
  498. #define NAKCIVJ(opt, neg, code) 
  499. if (go->neg && 
  500. ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && 
  501. len >= cilen && 
  502. p[0] == opt) { 
  503. len -= cilen; 
  504. INCPTR(2, p); 
  505. GETSHORT(cishort, p); 
  506. no.neg = 1; 
  507. code 
  508. }
  509. #define NAKCIDNS(opt, neg, code) 
  510. if (go->neg && 
  511. ((cilen = p[1]) == CILEN_ADDR) && 
  512. len >= cilen && 
  513. p[0] == opt) { 
  514. len -= cilen; 
  515. INCPTR(2, p); 
  516. GETLONG(l, p); 
  517. cidnsaddr = htonl(l); 
  518. no.neg = 1; 
  519. code 
  520. }
  521. /*
  522.  * Accept the peer's idea of {our,his} address, if different
  523.  * from our idea, only if the accept_{local,remote} flag is set.
  524.  */
  525. NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,
  526.   if (go->accept_local && ciaddr1) { /* Do we know our address? */
  527.   try.ouraddr = ciaddr1;
  528.   IPCPDEBUG((LOG_INFO, "local IP address %sn",
  529.      inet_ntoa(ciaddr1)));
  530.   }
  531.   if (go->accept_remote && ciaddr2) { /* Does he know his? */
  532.   try.hisaddr = ciaddr2;
  533.   IPCPDEBUG((LOG_INFO, "remote IP address %sn",
  534.      inet_ntoa(ciaddr2)));
  535.   }
  536. );
  537. /*
  538.  * Accept the peer's value of maxslotindex provided that it
  539.  * is less than what we asked for.  Turn off slot-ID compression
  540.  * if the peer wants.  Send old-style compress-type option if
  541.  * the peer wants.
  542.  */
  543. NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
  544. if (cilen == CILEN_VJ) {
  545. GETCHAR(cimaxslotindex, p);
  546. GETCHAR(cicflag, p);
  547. if (cishort == IPCP_VJ_COMP) {
  548. try.old_vj = 0;
  549. if (cimaxslotindex < go->maxslotindex)
  550. try.maxslotindex = cimaxslotindex;
  551. if (!cicflag)
  552. try.cflag = 0;
  553. } else {
  554. try.neg_vj = 0;
  555. }
  556. } else {
  557. if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {
  558. try.old_vj = 1;
  559. try.vj_protocol = cishort;
  560. } else {
  561. try.neg_vj = 0;
  562. }
  563. }
  564. );
  565. NAKCIDNS(CI_MS_DNS1, req_dns1,
  566. try.dnsaddr[0] = cidnsaddr;
  567.    IPCPDEBUG((LOG_INFO, "primary DNS address %sn", inet_ntoa(cidnsaddr)));
  568. );
  569. NAKCIDNS(CI_MS_DNS2, req_dns2,
  570. try.dnsaddr[1] = cidnsaddr;
  571.    IPCPDEBUG((LOG_INFO, "secondary DNS address %sn", inet_ntoa(cidnsaddr)));
  572. );
  573. /*
  574. * There may be remaining CIs, if the peer is requesting negotiation
  575. * on an option that we didn't include in our request packet.
  576. * If they want to negotiate about IP addresses, we comply.
  577. * If they want us to ask for compression, we refuse.
  578. */
  579. while (len > CILEN_VOID) {
  580. GETCHAR(citype, p);
  581. GETCHAR(cilen, p);
  582. if( (len -= cilen) < 0 )
  583. goto bad;
  584. next = p + cilen - 2;
  585. switch (citype) {
  586. case CI_COMPRESSTYPE:
  587. if (go->neg_vj || no.neg_vj ||
  588. (cilen != CILEN_VJ && cilen != CILEN_COMPRESS))
  589. goto bad;
  590. no.neg_vj = 1;
  591. break;
  592. case CI_ADDRS:
  593. if ((go->neg_addr && go->old_addrs) || no.old_addrs
  594. || cilen != CILEN_ADDRS)
  595. goto bad;
  596. try.neg_addr = 1;
  597. try.old_addrs = 1;
  598. GETLONG(l, p);
  599. ciaddr1 = htonl(l);
  600. if (ciaddr1 && go->accept_local)
  601. try.ouraddr = ciaddr1;
  602. GETLONG(l, p);
  603. ciaddr2 = htonl(l);
  604. if (ciaddr2 && go->accept_remote)
  605. try.hisaddr = ciaddr2;
  606. no.old_addrs = 1;
  607. break;
  608. case CI_ADDR:
  609. if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)
  610. goto bad;
  611. try.old_addrs = 0;
  612. GETLONG(l, p);
  613. ciaddr1 = htonl(l);
  614. if (ciaddr1 && go->accept_local)
  615. try.ouraddr = ciaddr1;
  616. if (try.ouraddr != 0)
  617. try.neg_addr = 1;
  618. no.neg_addr = 1;
  619. break;
  620. }
  621. p = next;
  622. }
  623. /* If there is still anything left, this packet is bad. */
  624. if (len != 0)
  625. goto bad;
  626. /*
  627.  * OK, the Nak is good.  Now we can update state.
  628.  */
  629. if (f->state != OPENED)
  630. *go = try;
  631. return 1;
  632. bad:
  633. IPCPDEBUG((LOG_INFO, "ipcp_nakci: received bad Nak!n"));
  634. return 0;
  635. }
  636. /*
  637.  * ipcp_rejci - Reject some of our CIs.
  638.  */
  639. static int ipcp_rejci(fsm *f, u_char *p, int len)
  640. {
  641. ipcp_options *go = &ipcp_gotoptions[f->unit];
  642. u_char cimaxslotindex, ciflag, cilen;
  643. u_short cishort;
  644. u32_t cilong;
  645. ipcp_options try; /* options to request next time */
  646. try = *go;
  647. /*
  648.  * Any Rejected CIs must be in exactly the same order that we sent.
  649.  * Check packet length and CI length at each step.
  650.  * If we find any deviations, then this packet is bad.
  651.  */
  652. #define REJCIADDR(opt, neg, old, val1, val2) 
  653. if (go->neg && 
  654. len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && 
  655. p[1] == cilen && 
  656. p[0] == opt) { 
  657. u32_t l; 
  658. len -= cilen; 
  659. INCPTR(2, p); 
  660. GETLONG(l, p); 
  661. cilong = htonl(l); 
  662. /* Check rejected value. */ 
  663. if (cilong != val1) 
  664. goto bad; 
  665. if (old) { 
  666. GETLONG(l, p); 
  667. cilong = htonl(l); 
  668. /* Check rejected value. */ 
  669. if (cilong != val2) 
  670. goto bad; 
  671. try.neg = 0; 
  672. }
  673. #define REJCIVJ(opt, neg, val, old, maxslot, cflag) 
  674. if (go->neg && 
  675. p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && 
  676. len >= p[1] && 
  677. p[0] == opt) { 
  678. len -= p[1]; 
  679. INCPTR(2, p); 
  680. GETSHORT(cishort, p); 
  681. /* Check rejected value. */  
  682. if (cishort != val) 
  683. goto bad; 
  684. if (!old) { 
  685. GETCHAR(cimaxslotindex, p); 
  686. if (cimaxslotindex != maxslot) 
  687. goto bad; 
  688. GETCHAR(ciflag, p); 
  689. if (ciflag != cflag) 
  690. goto bad; 
  691. try.neg = 0; 
  692. }
  693. #define REJCIDNS(opt, neg, dnsaddr) 
  694. if (go->neg && 
  695. ((cilen = p[1]) == CILEN_ADDR) && 
  696. len >= cilen && 
  697. p[0] == opt) { 
  698. u32_t l; 
  699. len -= cilen; 
  700. INCPTR(2, p); 
  701. GETLONG(l, p); 
  702. cilong = htonl(l); 
  703. /* Check rejected value. */ 
  704. if (cilong != dnsaddr) 
  705. goto bad; 
  706. try.neg = 0; 
  707. }
  708. REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr,
  709.   go->old_addrs, go->ouraddr, go->hisaddr);
  710. REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
  711. go->maxslotindex, go->cflag);
  712. REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
  713. REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
  714. /*
  715.  * If there are any remaining CIs, then this packet is bad.
  716.  */
  717. if (len != 0)
  718. goto bad;
  719. /*
  720.  * Now we can update state.
  721.  */
  722. if (f->state != OPENED)
  723. *go = try;
  724. return 1;
  725. bad:
  726. IPCPDEBUG((LOG_INFO, "ipcp_rejci: received bad Reject!n"));
  727. return 0;
  728. }
  729. /*
  730.  * ipcp_reqci - Check the peer's requested CIs and send appropriate response.
  731.  *
  732.  * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
  733.  * appropriately.  If reject_if_disagree is non-zero, doesn't return
  734.  * CONFNAK; returns CONFREJ if it can't return CONFACK.
  735.  */
  736. static int ipcp_reqci(
  737. fsm *f,
  738. u_char *inp, /* Requested CIs */
  739. int *len, /* Length of requested CIs */
  740. int reject_if_disagree
  741. )
  742. {
  743. ipcp_options *wo = &ipcp_wantoptions[f->unit];
  744. ipcp_options *ho = &ipcp_hisoptions[f->unit];
  745. ipcp_options *ao = &ipcp_allowoptions[f->unit];
  746. #ifdef OLD_CI_ADDRS
  747. ipcp_options *go = &ipcp_gotoptions[f->unit];
  748. #endif
  749. u_char *cip, *next; /* Pointer to current and next CIs */
  750. u_short cilen, citype; /* Parsed len, type */
  751. u_short cishort; /* Parsed short value */
  752. u32_t tl, ciaddr1; /* Parsed address values */
  753. #ifdef OLD_CI_ADDRS
  754. u32_t ciaddr2; /* Parsed address values */
  755. #endif
  756. int rc = CONFACK; /* Final packet return code */
  757. int orc; /* Individual option return code */
  758. u_char *p; /* Pointer to next char to parse */
  759. u_char *ucp = inp; /* Pointer to current output char */
  760. int l = *len; /* Length left */
  761. u_char maxslotindex, cflag;
  762. int d;
  763. cis_received[f->unit] = 1;
  764. /*
  765.  * Reset all his options.
  766.  */
  767. BZERO(ho, sizeof(*ho));
  768. /*
  769.  * Process all his options.
  770.  */
  771. next = inp;
  772. while (l) {
  773. orc = CONFACK; /* Assume success */
  774. cip = p = next; /* Remember begining of CI */
  775. if (l < 2 || /* Not enough data for CI header or */
  776. p[1] < 2 || /*  CI length too small or */
  777. p[1] > l) { /*  CI length too big? */
  778. IPCPDEBUG((LOG_INFO, "ipcp_reqci: bad CI length!n"));
  779. orc = CONFREJ; /* Reject bad CI */
  780. cilen = l; /* Reject till end of packet */
  781. l = 0; /* Don't loop again */
  782. goto endswitch;
  783. }
  784. GETCHAR(citype, p); /* Parse CI type */
  785. GETCHAR(cilen, p); /* Parse CI length */
  786. l -= cilen; /* Adjust remaining length */
  787. next += cilen; /* Step to next CI */
  788. switch (citype) { /* Check CI type */
  789. #ifdef OLD_CI_ADDRS /* Need to save space... */
  790. case CI_ADDRS:
  791. IPCPDEBUG((LOG_INFO, "ipcp_reqci: received ADDRSn"));
  792. if (!ao->neg_addr ||
  793. cilen != CILEN_ADDRS) { /* Check CI length */
  794. orc = CONFREJ; /* Reject CI */
  795. break;
  796. }
  797. /*
  798.  * If he has no address, or if we both have his address but
  799.  * disagree about it, then NAK it with our idea.
  800.  * In particular, if we don't know his address, but he does,
  801.  * then accept it.
  802.  */
  803. GETLONG(tl, p); /* Parse source address (his) */
  804. ciaddr1 = htonl(tl);
  805. IPCPDEBUG((LOG_INFO, "his addr %sn", inet_ntoa(ciaddr1)));
  806. if (ciaddr1 != wo->hisaddr
  807. && (ciaddr1 == 0 || !wo->accept_remote)) {
  808. orc = CONFNAK;
  809. if (!reject_if_disagree) {
  810. DECPTR(sizeof(u32_t), p);
  811. tl = ntohl(wo->hisaddr);
  812. PUTLONG(tl, p);
  813. }
  814. } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
  815. /*
  816.  * If neither we nor he knows his address, reject the option.
  817.  */
  818. orc = CONFREJ;
  819. wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
  820. break;
  821. }
  822. /*
  823.  * If he doesn't know our address, or if we both have our address
  824.  * but disagree about it, then NAK it with our idea.
  825.  */
  826. GETLONG(tl, p); /* Parse desination address (ours) */
  827. ciaddr2 = htonl(tl);
  828. IPCPDEBUG((LOG_INFO, "our addr %sn", inet_ntoa(ciaddr2)));
  829. if (ciaddr2 != wo->ouraddr) {
  830. if (ciaddr2 == 0 || !wo->accept_local) {
  831. orc = CONFNAK;
  832. if (!reject_if_disagree) {
  833. DECPTR(sizeof(u32_t), p);
  834. tl = ntohl(wo->ouraddr);
  835. PUTLONG(tl, p);
  836. }
  837. } else {
  838. go->ouraddr = ciaddr2; /* accept peer's idea */
  839. }
  840. }
  841. ho->neg_addr = 1;
  842. ho->old_addrs = 1;
  843. ho->hisaddr = ciaddr1;
  844. ho->ouraddr = ciaddr2;
  845. break;
  846. #endif
  847. case CI_ADDR:
  848. if (!ao->neg_addr) {
  849. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR not allowedn"));
  850. orc = CONFREJ; /* Reject CI */
  851. break;
  852. } else if (cilen != CILEN_ADDR) { /* Check CI length */
  853. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR bad lenn"));
  854. orc = CONFREJ; /* Reject CI */
  855. break;
  856. }
  857. /*
  858.  * If he has no address, or if we both have his address but
  859.  * disagree about it, then NAK it with our idea.
  860.  * In particular, if we don't know his address, but he does,
  861.  * then accept it.
  862.  */
  863. GETLONG(tl, p); /* Parse source address (his) */
  864. ciaddr1 = htonl(tl);
  865. if (ciaddr1 != wo->hisaddr
  866. && (ciaddr1 == 0 || !wo->accept_remote)) {
  867. orc = CONFNAK;
  868. if (!reject_if_disagree) {
  869. DECPTR(sizeof(u32_t), p);
  870. tl = ntohl(wo->hisaddr);
  871. PUTLONG(tl, p);
  872. }
  873. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Nak ADDR %sn", inet_ntoa(ciaddr1)));
  874. } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
  875. /*
  876.  * Don't ACK an address of 0.0.0.0 - reject it instead.
  877.  */
  878. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR %sn", inet_ntoa(ciaddr1)));
  879. orc = CONFREJ;
  880. wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
  881. break;
  882. }
  883. ho->neg_addr = 1;
  884. ho->hisaddr = ciaddr1;
  885. IPCPDEBUG((LOG_INFO, "ipcp_reqci: ADDR %sn", inet_ntoa(ciaddr1)));
  886. break;
  887. case CI_MS_DNS1:
  888. case CI_MS_DNS2:
  889. /* Microsoft primary or secondary DNS request */
  890. d = citype == CI_MS_DNS2;
  891. /* If we do not have a DNS address then we cannot send it */
  892. if (ao->dnsaddr[d] == 0 ||
  893. cilen != CILEN_ADDR) { /* Check CI length */
  894. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting DNS%d Requestn", d+1));
  895. orc = CONFREJ; /* Reject CI */
  896. break;
  897. }
  898. GETLONG(tl, p);
  899. if (htonl(tl) != ao->dnsaddr[d]) {
  900. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking DNS%d Request %dn",
  901. d+1, inet_ntoa(tl)));
  902. DECPTR(sizeof(u32_t), p);
  903. tl = ntohl(ao->dnsaddr[d]);
  904. PUTLONG(tl, p);
  905. orc = CONFNAK;
  906. }
  907. IPCPDEBUG((LOG_INFO, "ipcp_reqci: received DNS%d Requestn", d+1));
  908. break;
  909. case CI_MS_WINS1:
  910. case CI_MS_WINS2:
  911. /* Microsoft primary or secondary WINS request */
  912. d = citype == CI_MS_WINS2;
  913. IPCPDEBUG((LOG_INFO, "ipcp_reqci: received WINS%d Requestn", d+1));
  914. /* If we do not have a DNS address then we cannot send it */
  915. if (ao->winsaddr[d] == 0 ||
  916. cilen != CILEN_ADDR) { /* Check CI length */
  917. orc = CONFREJ; /* Reject CI */
  918. break;
  919. }
  920. GETLONG(tl, p);
  921. if (htonl(tl) != ao->winsaddr[d]) {
  922. DECPTR(sizeof(u32_t), p);
  923. tl = ntohl(ao->winsaddr[d]);
  924. PUTLONG(tl, p);
  925. orc = CONFNAK;
  926. }
  927. break;
  928. case CI_COMPRESSTYPE:
  929. if (!ao->neg_vj) {
  930. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE not allowedn"));
  931. orc = CONFREJ;
  932. break;
  933. } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) {
  934. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE len=%dn", cilen));
  935. orc = CONFREJ;
  936. break;
  937. }
  938. GETSHORT(cishort, p);
  939. if (!(cishort == IPCP_VJ_COMP ||
  940. (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {
  941. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE %dn", cishort));
  942. orc = CONFREJ;
  943. break;
  944. }
  945. ho->neg_vj = 1;
  946. ho->vj_protocol = cishort;
  947. if (cilen == CILEN_VJ) {
  948. GETCHAR(maxslotindex, p);
  949. if (maxslotindex > ao->maxslotindex) { 
  950. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ max slot %dn", maxslotindex));
  951. orc = CONFNAK;
  952. if (!reject_if_disagree){
  953. DECPTR(1, p);
  954. PUTCHAR(ao->maxslotindex, p);
  955. }
  956. }
  957. GETCHAR(cflag, p);
  958. if (cflag && !ao->cflag) {
  959. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ cflag %dn", cflag));
  960. orc = CONFNAK;
  961. if (!reject_if_disagree){
  962. DECPTR(1, p);
  963. PUTCHAR(wo->cflag, p);
  964. }
  965. }
  966. ho->maxslotindex = maxslotindex;
  967. ho->cflag = cflag;
  968. } else {
  969. ho->old_vj = 1;
  970. ho->maxslotindex = MAX_SLOTS - 1;
  971. ho->cflag = 1;
  972. }
  973. IPCPDEBUG((LOG_INFO, 
  974. "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%dn",
  975. ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag));
  976. break;
  977. default:
  978. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting unknown CI type %dn", citype));
  979. orc = CONFREJ;
  980. break;
  981. }
  982. endswitch:
  983. if (orc == CONFACK && /* Good CI */
  984. rc != CONFACK) /*  but prior CI wasnt? */
  985. continue; /* Don't send this one */
  986. if (orc == CONFNAK) { /* Nak this CI? */
  987. if (reject_if_disagree) { /* Getting fed up with sending NAKs? */
  988. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting too many naksn"));
  989. orc = CONFREJ; /* Get tough if so */
  990. } else {
  991. if (rc == CONFREJ) /* Rejecting prior CI? */
  992. continue; /* Don't send this one */
  993. if (rc == CONFACK) { /* Ack'd all prior CIs? */
  994. rc = CONFNAK; /* Not anymore... */
  995. ucp = inp; /* Backup */
  996. }
  997. }
  998. }
  999. if (orc == CONFREJ && /* Reject this CI */
  1000. rc != CONFREJ) { /*  but no prior ones? */
  1001. rc = CONFREJ;
  1002. ucp = inp; /* Backup */
  1003. }
  1004. /* Need to move CI? */
  1005. if (ucp != cip)
  1006. BCOPY(cip, ucp, cilen); /* Move it */
  1007. /* Update output pointer */
  1008. INCPTR(cilen, ucp);
  1009. }
  1010. /*
  1011.  * If we aren't rejecting this packet, and we want to negotiate
  1012.  * their address, and they didn't send their address, then we
  1013.  * send a NAK with a CI_ADDR option appended.  We assume the
  1014.  * input buffer is long enough that we can append the extra
  1015.  * option safely.
  1016.  */
  1017. if (rc != CONFREJ && !ho->neg_addr &&
  1018. wo->req_addr && !reject_if_disagree) {
  1019. IPCPDEBUG((LOG_INFO, "ipcp_reqci: Requesting peer addressn"));
  1020. if (rc == CONFACK) {
  1021. rc = CONFNAK;
  1022. ucp = inp; /* reset pointer */
  1023. wo->req_addr = 0; /* don't ask again */
  1024. }
  1025. PUTCHAR(CI_ADDR, ucp);
  1026. PUTCHAR(CILEN_ADDR, ucp);
  1027. tl = ntohl(wo->hisaddr);
  1028. PUTLONG(tl, ucp);
  1029. }
  1030. *len = (int)(ucp - inp); /* Compute output length */
  1031. IPCPDEBUG((LOG_INFO, "ipcp_reqci: returning Configure-%sn", CODENAME(rc)));
  1032. return (rc); /* Return final code */
  1033. }
  1034. #if 0
  1035. /*
  1036.  * ip_check_options - check that any IP-related options are OK,
  1037.  * and assign appropriate defaults.
  1038.  */
  1039. static void ip_check_options(u_long localAddr)
  1040. {
  1041. ipcp_options *wo = &ipcp_wantoptions[0];
  1042. /*
  1043.  * Load our default IP address but allow the remote host to give us
  1044.  * a new address.
  1045.  */
  1046. if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) {
  1047. wo->accept_local = 1; /* don't insist on this default value */
  1048. wo->ouraddr = htonl(localAddr);
  1049. }
  1050. }
  1051. #endif
  1052. /*
  1053.  * ipcp_up - IPCP has come UP.
  1054.  *
  1055.  * Configure the IP network interface appropriately and bring it up.
  1056.  */
  1057. static void ipcp_up(fsm *f)
  1058. {
  1059. u32_t mask;
  1060. ipcp_options *ho = &ipcp_hisoptions[f->unit];
  1061. ipcp_options *go = &ipcp_gotoptions[f->unit];
  1062. ipcp_options *wo = &ipcp_wantoptions[f->unit];
  1063.        DEBUG_FUNCTION("ipcp_up()");
  1064. np_up(f->unit, PPP_IP);
  1065. IPCPDEBUG((LOG_INFO, "ipcp: upn"));
  1066. /*
  1067.  * We must have a non-zero IP address for both ends of the link.
  1068.  */
  1069. if (!ho->neg_addr)
  1070. ho->hisaddr = wo->hisaddr;
  1071. if (ho->hisaddr == 0) {
  1072. IPCPDEBUG((LOG_ERR, "Could not determine remote IP addressn"));
  1073. ipcp_close(f->unit, "Could not determine remote IP address");
  1074. return;
  1075. }
  1076. if (go->ouraddr == 0) {
  1077. IPCPDEBUG((LOG_ERR, "Could not determine local IP addressn"));
  1078. ipcp_close(f->unit, "Could not determine local IP address");
  1079. return;
  1080. }
  1081. if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) {
  1082. /*pppGotDNSAddrs(go->dnsaddr[0], go->dnsaddr[1]);*/
  1083. }
  1084. /*
  1085.  * Check that the peer is allowed to use the IP address it wants.
  1086.  */
  1087. if (!auth_ip_addr(f->unit, ho->hisaddr)) {
  1088. IPCPDEBUG((LOG_ERR, "Peer is not authorized to use remote address %sn",
  1089. inet_ntoa(ho->hisaddr)));
  1090. ipcp_close(f->unit, "Unauthorized remote IP address");
  1091. return;
  1092. }
  1093. /* set tcp compression */
  1094. sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);
  1095. /*
  1096.  * Set IP addresses and (if specified) netmask.
  1097.  */
  1098. mask = GetMask(go->ouraddr);
  1099. if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) {
  1100. IPCPDEBUG((LOG_WARNING, "sifaddr failedn"));
  1101. ipcp_close(f->unit, "Interface configuration failed");
  1102. return;
  1103. }
  1104. /* bring the interface up for IP */
  1105. if (!sifup(f->unit)) {
  1106. IPCPDEBUG((LOG_WARNING, "sifup failedn"));
  1107. ipcp_close(f->unit, "Interface configuration failed");
  1108. return;
  1109. }
  1110. sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
  1111. /* assign a default route through the interface if required */
  1112. if (ipcp_wantoptions[f->unit].default_route) 
  1113. if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
  1114. default_route_set[f->unit] = 1;
  1115. IPCPDEBUG((LOG_NOTICE, "local  IP address %sn", inet_ntoa(go->ouraddr)));
  1116. IPCPDEBUG((LOG_NOTICE, "remote IP address %sn", inet_ntoa(ho->hisaddr)));
  1117. if (go->dnsaddr[0]) {
  1118. IPCPDEBUG((LOG_NOTICE, "primary   DNS address %sn", inet_ntoa(go->dnsaddr[0])));
  1119. }
  1120. if (go->dnsaddr[1]) {
  1121. IPCPDEBUG((LOG_NOTICE, "secondary DNS address %sn", inet_ntoa(go->dnsaddr[1])));
  1122. }
  1123. }
  1124. /*
  1125.  * ipcp_down - IPCP has gone DOWN.
  1126.  *
  1127.  * Take the IP network interface down, clear its addresses
  1128.  * and delete routes through it.
  1129.  */
  1130. static void ipcp_down(fsm *f)
  1131. {
  1132. IPCPDEBUG((LOG_INFO, "ipcp: downn"));
  1133. np_down(f->unit, PPP_IP);
  1134. sifvjcomp(f->unit, 0, 0, 0);
  1135. sifdown(f->unit);
  1136. ipcp_clear_addrs(f->unit);
  1137. }
  1138. /*
  1139.  * ipcp_clear_addrs() - clear the interface addresses, routes, etc.
  1140.  */
  1141. static void ipcp_clear_addrs(int unit)
  1142. {
  1143. u32_t ouraddr, hisaddr;
  1144. ouraddr = ipcp_gotoptions[unit].ouraddr;
  1145. hisaddr = ipcp_hisoptions[unit].hisaddr;
  1146. if (default_route_set[unit]) {
  1147. cifdefaultroute(unit, ouraddr, hisaddr);
  1148. default_route_set[unit] = 0;
  1149. }
  1150. cifaddr(unit, ouraddr, hisaddr);
  1151. }
  1152. /*
  1153.  * ipcp_finished - possibly shut down the lower layers.
  1154.  */
  1155. static void ipcp_finished(fsm *f)
  1156. {
  1157. np_finished(f->unit, PPP_IP);
  1158. }
  1159. #if 0
  1160. static int ipcp_printpkt(
  1161. u_char *p,
  1162. int plen,
  1163. void (*printer) (void *, char *, ...),
  1164. void *arg
  1165. )
  1166. {
  1167. (void)p;
  1168. (void)plen;
  1169. (void)printer;
  1170. (void)arg;
  1171. return 0;
  1172. }
  1173. /*
  1174.  * ip_active_pkt - see if this IP packet is worth bringing the link up for.
  1175.  * We don't bring the link up for IP fragments or for TCP FIN packets
  1176.  * with no data.
  1177.  */
  1178. #define IP_HDRLEN 20 /* bytes */
  1179. #define IP_OFFMASK 0x1fff
  1180. #define IPPROTO_TCP 6
  1181. #define TCP_HDRLEN 20
  1182. #define TH_FIN 0x01
  1183. /*
  1184.  * We use these macros because the IP header may be at an odd address,
  1185.  * and some compilers might use word loads to get th_off or ip_hl.
  1186.  */
  1187. #define net_short(x) (((x)[0] << 8) + (x)[1])
  1188. #define get_iphl(x) (((unsigned char *)(x))[0] & 0xF)
  1189. #define get_ipoff(x) net_short((unsigned char *)(x) + 6)
  1190. #define get_ipproto(x) (((unsigned char *)(x))[9])
  1191. #define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4)
  1192. #define get_tcpflags(x) (((unsigned char *)(x))[13])
  1193. static int ip_active_pkt(u_char *pkt, int len)
  1194. {
  1195. u_char *tcp;
  1196. int hlen;
  1197. len -= PPP_HDRLEN;
  1198. pkt += PPP_HDRLEN;
  1199. if (len < IP_HDRLEN)
  1200. return 0;
  1201. if ((get_ipoff(pkt) & IP_OFFMASK) != 0)
  1202. return 0;
  1203. if (get_ipproto(pkt) != IPPROTO_TCP)
  1204. return 1;
  1205. hlen = get_iphl(pkt) * 4;
  1206. if (len < hlen + TCP_HDRLEN)
  1207. return 0;
  1208. tcp = pkt + hlen;
  1209. if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)
  1210. return 0;
  1211. return 1;
  1212. }
  1213. #endif
  1214. #endif /* PPP_SUPPORT */