1 /* $OpenBSD: ipcp.c,v 1.15 2015/12/14 03:25:59 mmcc Exp $ */
2
3 /*
4 * ipcp.c - PPP IP Control Protocol.
5 *
6 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The name "Carnegie Mellon University" must not be used to
21 * endorse or promote products derived from this software without
22 * prior written permission. For permission or any legal
23 * details, please contact
24 * Office of Technology Transfer
25 * Carnegie Mellon University
26 * 5000 Forbes Avenue
27 * Pittsburgh, PA 15213-3890
28 * (412) 268-4387, fax: (412) 268-7395
29 * tech-transfer@andrew.cmu.edu
30 *
31 * 4. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by Computing Services
34 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
35 *
36 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
37 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
38 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
39 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
41 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
42 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
43 */
44
45 /*
46 * TODO:
47 */
48
49 #include <sys/types.h>
50 #include <sys/socket.h>
51 #include <netinet/in.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <syslog.h>
56 #include <netdb.h>
57
58 #include "pppd.h"
59 #include "fsm.h"
60 #include "ipcp.h"
61 #include "pathnames.h"
62
63 /* global vars */
64 ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
65 ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
66 ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
67 ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
68
69 /* local vars */
70 static int cis_received[NUM_PPP]; /* # Conf-Reqs received */
71 static int default_route_set[NUM_PPP]; /* Have set up a default route */
72 static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */
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 static void ipcp_script(fsm *, char *); /* Run an up/down script */
87 static void ipcp_finished(fsm *); /* Don't need lower layer */
88
89 fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */
90
91 static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
92 ipcp_resetci, /* Reset our Configuration Information */
93 ipcp_cilen, /* Length of our Configuration Information */
94 ipcp_addci, /* Add our Configuration Information */
95 ipcp_ackci, /* ACK our Configuration Information */
96 ipcp_nakci, /* NAK our Configuration Information */
97 ipcp_rejci, /* Reject our Configuration Information */
98 ipcp_reqci, /* Request peer's Configuration Information */
99 ipcp_up, /* Called when fsm reaches OPENED state */
100 ipcp_down, /* Called when fsm leaves OPENED state */
101 NULL, /* Called when we want the lower layer up */
102 ipcp_finished, /* Called when we want the lower layer down */
103 NULL, /* Called when Protocol-Reject received */
104 NULL, /* Retransmission is necessary */
105 NULL, /* Called to handle protocol-specific codes */
106 "IPCP" /* String name of protocol */
107 };
108
109 /*
110 * Protocol entry points from main code.
111 */
112 static void ipcp_init(int);
113 static void ipcp_open(int);
114 static void ipcp_close(int, char *);
115 static void ipcp_lowerup(int);
116 static void ipcp_lowerdown(int);
117 static void ipcp_input(int, u_char *, int);
118 static void ipcp_protrej(int);
119 static int ipcp_printpkt(u_char *, int, void (*)(void *, char *, ...), void *);
120 static void ip_check_options(void);
121 static int ip_demand_conf(int);
122 static int ip_active_pkt(u_char *, int);
123
124 struct protent ipcp_protent = {
125 PPP_IPCP,
126 ipcp_init,
127 ipcp_input,
128 ipcp_protrej,
129 ipcp_lowerup,
130 ipcp_lowerdown,
131 ipcp_open,
132 ipcp_close,
133 ipcp_printpkt,
134 NULL,
135 1,
136 "IPCP",
137 ip_check_options,
138 ip_demand_conf,
139 ip_active_pkt
140 };
141
142 static void ipcp_clear_addrs(int);
143
144 /*
145 * Lengths of configuration options.
146 */
147 #define CILEN_VOID 2
148 #define CILEN_COMPRESS 4 /* min length for compression protocol opt. */
149 #define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */
150 #define CILEN_ADDR 6 /* new-style single address option */
151 #define CILEN_ADDRS 10 /* old-style dual address option */
152
153
154 #define CODENAME(x) ((x) == CONFACK ? "ACK" : \
155 (x) == CONFNAK ? "NAK" : "REJ")
156
157
158 /*
159 * Make a string representation of a network IP address.
160 */
161 char *
ip_ntoa(ipaddr)162 ip_ntoa(ipaddr)
163 u_int32_t ipaddr;
164 {
165 static char b[64];
166
167 ipaddr = ntohl(ipaddr);
168
169 snprintf(b, sizeof b, "%d.%d.%d.%d",
170 (u_char)(ipaddr >> 24),
171 (u_char)(ipaddr >> 16),
172 (u_char)(ipaddr >> 8),
173 (u_char)(ipaddr));
174 return b;
175 }
176
177
178 /*
179 * ipcp_init - Initialize IPCP.
180 */
181 static void
ipcp_init(unit)182 ipcp_init(unit)
183 int unit;
184 {
185 fsm *f = &ipcp_fsm[unit];
186 ipcp_options *wo = &ipcp_wantoptions[unit];
187 ipcp_options *ao = &ipcp_allowoptions[unit];
188
189 f->unit = unit;
190 f->protocol = PPP_IPCP;
191 f->callbacks = &ipcp_callbacks;
192 fsm_init(&ipcp_fsm[unit]);
193
194 memset(wo, 0, sizeof(*wo));
195 memset(ao, 0, sizeof(*ao));
196
197 wo->neg_addr = 1;
198 wo->neg_vj = 1;
199 wo->vj_protocol = IPCP_VJ_COMP;
200 wo->maxslotindex = MAX_STATES - 1; /* really max index */
201 wo->cflag = 1;
202
203 /* max slots and slot-id compression are currently hardwired in */
204 /* ppp_if.c to 16 and 1, this needs to be changed (among other */
205 /* things) gmc */
206
207 ao->neg_addr = 1;
208 ao->neg_vj = 1;
209 ao->maxslotindex = MAX_STATES - 1;
210 ao->cflag = 1;
211
212 /*
213 * XXX These control whether the user may use the proxyarp
214 * and defaultroute options.
215 */
216 ao->proxy_arp = 1;
217 ao->default_route = 1;
218 }
219
220
221 /*
222 * ipcp_open - IPCP is allowed to come up.
223 */
224 static void
ipcp_open(unit)225 ipcp_open(unit)
226 int unit;
227 {
228 fsm_open(&ipcp_fsm[unit]);
229 }
230
231
232 /*
233 * ipcp_close - Take IPCP down.
234 */
235 static void
ipcp_close(unit,reason)236 ipcp_close(unit, reason)
237 int unit;
238 char *reason;
239 {
240 fsm_close(&ipcp_fsm[unit], reason);
241 }
242
243
244 /*
245 * ipcp_lowerup - The lower layer is up.
246 */
247 static void
ipcp_lowerup(unit)248 ipcp_lowerup(unit)
249 int unit;
250 {
251 fsm_lowerup(&ipcp_fsm[unit]);
252 }
253
254
255 /*
256 * ipcp_lowerdown - The lower layer is down.
257 */
258 static void
ipcp_lowerdown(unit)259 ipcp_lowerdown(unit)
260 int unit;
261 {
262 fsm_lowerdown(&ipcp_fsm[unit]);
263 }
264
265
266 /*
267 * ipcp_input - Input IPCP packet.
268 */
269 static void
ipcp_input(unit,p,len)270 ipcp_input(unit, p, len)
271 int unit;
272 u_char *p;
273 int len;
274 {
275 fsm_input(&ipcp_fsm[unit], p, len);
276 }
277
278
279 /*
280 * ipcp_protrej - A Protocol-Reject was received for IPCP.
281 *
282 * Pretend the lower layer went down, so we shut up.
283 */
284 static void
ipcp_protrej(unit)285 ipcp_protrej(unit)
286 int unit;
287 {
288 fsm_lowerdown(&ipcp_fsm[unit]);
289 }
290
291
292 /*
293 * ipcp_resetci - Reset our CI.
294 */
295 static void
ipcp_resetci(f)296 ipcp_resetci(f)
297 fsm *f;
298 {
299 ipcp_options *wo = &ipcp_wantoptions[f->unit];
300
301 wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;
302 if (wo->ouraddr == 0)
303 wo->accept_local = 1;
304 if (wo->hisaddr == 0)
305 wo->accept_remote = 1;
306 ipcp_gotoptions[f->unit] = *wo;
307 cis_received[f->unit] = 0;
308 }
309
310
311 /*
312 * ipcp_cilen - Return length of our CI.
313 */
314 static int
ipcp_cilen(f)315 ipcp_cilen(f)
316 fsm *f;
317 {
318 ipcp_options *go = &ipcp_gotoptions[f->unit];
319 ipcp_options *wo = &ipcp_wantoptions[f->unit];
320 ipcp_options *ho = &ipcp_hisoptions[f->unit];
321
322 #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
323 #define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)
324
325 /*
326 * First see if we want to change our options to the old
327 * forms because we have received old forms from the peer.
328 */
329 if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {
330 /* use the old style of address negotiation */
331 go->neg_addr = 1;
332 go->old_addrs = 1;
333 }
334 if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
335 /* try an older style of VJ negotiation */
336 if (cis_received[f->unit] == 0) {
337 /* keep trying the new style until we see some CI from the peer */
338 go->neg_vj = 1;
339 } else {
340 /* use the old style only if the peer did */
341 if (ho->neg_vj && ho->old_vj) {
342 go->neg_vj = 1;
343 go->old_vj = 1;
344 go->vj_protocol = ho->vj_protocol;
345 }
346 }
347 }
348
349 return (LENCIADDR(go->neg_addr, go->old_addrs) +
350 LENCIVJ(go->neg_vj, go->old_vj));
351 }
352
353
354 /*
355 * ipcp_addci - Add our desired CIs to a packet.
356 */
357 static void
ipcp_addci(f,ucp,lenp)358 ipcp_addci(f, ucp, lenp)
359 fsm *f;
360 u_char *ucp;
361 int *lenp;
362 {
363 ipcp_options *go = &ipcp_gotoptions[f->unit];
364 int len = *lenp;
365
366 #define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
367 if (neg) { \
368 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
369 if (len >= vjlen) { \
370 PUTCHAR(opt, ucp); \
371 PUTCHAR(vjlen, ucp); \
372 PUTSHORT(val, ucp); \
373 if (!old) { \
374 PUTCHAR(maxslotindex, ucp); \
375 PUTCHAR(cflag, ucp); \
376 } \
377 len -= vjlen; \
378 } else \
379 neg = 0; \
380 }
381
382 #define ADDCIADDR(opt, neg, old, val1, val2) \
383 if (neg) { \
384 int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
385 if (len >= addrlen) { \
386 u_int32_t l; \
387 PUTCHAR(opt, ucp); \
388 PUTCHAR(addrlen, ucp); \
389 l = ntohl(val1); \
390 PUTLONG(l, ucp); \
391 if (old) { \
392 l = ntohl(val2); \
393 PUTLONG(l, ucp); \
394 } \
395 len -= addrlen; \
396 } else \
397 neg = 0; \
398 }
399
400 ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
401 go->old_addrs, go->ouraddr, go->hisaddr);
402
403 ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
404 go->maxslotindex, go->cflag);
405
406 *lenp -= len;
407 }
408
409
410 /*
411 * ipcp_ackci - Ack our CIs.
412 *
413 * Returns:
414 * 0 - Ack was bad.
415 * 1 - Ack was good.
416 */
417 static int
ipcp_ackci(f,p,len)418 ipcp_ackci(f, p, len)
419 fsm *f;
420 u_char *p;
421 int len;
422 {
423 ipcp_options *go = &ipcp_gotoptions[f->unit];
424 u_short cilen, citype, cishort;
425 u_int32_t cilong;
426 u_char cimaxslotindex, cicflag;
427
428 /*
429 * CIs must be in exactly the same order that we sent...
430 * Check packet length and CI length at each step.
431 * If we find any deviations, then this packet is bad.
432 */
433
434 #define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
435 if (neg) { \
436 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
437 if ((len -= vjlen) < 0) \
438 goto bad; \
439 GETCHAR(citype, p); \
440 GETCHAR(cilen, p); \
441 if (cilen != vjlen || \
442 citype != opt) \
443 goto bad; \
444 GETSHORT(cishort, p); \
445 if (cishort != val) \
446 goto bad; \
447 if (!old) { \
448 GETCHAR(cimaxslotindex, p); \
449 if (cimaxslotindex != maxslotindex) \
450 goto bad; \
451 GETCHAR(cicflag, p); \
452 if (cicflag != cflag) \
453 goto bad; \
454 } \
455 }
456
457 #define ACKCIADDR(opt, neg, old, val1, val2) \
458 if (neg) { \
459 int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
460 u_int32_t l; \
461 if ((len -= addrlen) < 0) \
462 goto bad; \
463 GETCHAR(citype, p); \
464 GETCHAR(cilen, p); \
465 if (cilen != addrlen || \
466 citype != opt) \
467 goto bad; \
468 GETLONG(l, p); \
469 cilong = htonl(l); \
470 if (val1 != cilong) \
471 goto bad; \
472 if (old) { \
473 GETLONG(l, p); \
474 cilong = htonl(l); \
475 if (val2 != cilong) \
476 goto bad; \
477 } \
478 }
479
480 ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
481 go->old_addrs, go->ouraddr, go->hisaddr);
482
483 ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
484 go->maxslotindex, go->cflag);
485
486 /*
487 * If there are any remaining CIs, then this packet is bad.
488 */
489 if (len != 0)
490 goto bad;
491 return (1);
492
493 bad:
494 IPCPDEBUG((LOG_INFO, "ipcp_ackci: received bad Ack!"));
495 return (0);
496 }
497
498 /*
499 * ipcp_nakci - Peer has sent a NAK for some of our CIs.
500 * This should not modify any state if the Nak is bad
501 * or if IPCP is in the OPENED state.
502 *
503 * Returns:
504 * 0 - Nak was bad.
505 * 1 - Nak was good.
506 */
507 static int
ipcp_nakci(f,p,len)508 ipcp_nakci(f, p, len)
509 fsm *f;
510 u_char *p;
511 int len;
512 {
513 ipcp_options *go = &ipcp_gotoptions[f->unit];
514 u_char cimaxslotindex, cicflag;
515 u_char citype, cilen, *next;
516 u_short cishort;
517 u_int32_t ciaddr1, ciaddr2, l;
518 ipcp_options no; /* options we've seen Naks for */
519 ipcp_options try; /* options to request next time */
520
521 BZERO(&no, sizeof(no));
522 try = *go;
523
524 /*
525 * Any Nak'd CIs must be in exactly the same order that we sent.
526 * Check packet length and CI length at each step.
527 * If we find any deviations, then this packet is bad.
528 */
529 #define NAKCIADDR(opt, neg, old, code) \
530 if (go->neg && \
531 len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \
532 p[1] == cilen && \
533 p[0] == opt) { \
534 len -= cilen; \
535 INCPTR(2, p); \
536 GETLONG(l, p); \
537 ciaddr1 = htonl(l); \
538 if (old) { \
539 GETLONG(l, p); \
540 ciaddr2 = htonl(l); \
541 no.old_addrs = 1; \
542 } else \
543 ciaddr2 = 0; \
544 no.neg = 1; \
545 code \
546 }
547
548 #define NAKCIVJ(opt, neg, code) \
549 if (go->neg && \
550 ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
551 len >= cilen && \
552 p[0] == opt) { \
553 len -= cilen; \
554 INCPTR(2, p); \
555 GETSHORT(cishort, p); \
556 no.neg = 1; \
557 code \
558 }
559
560 /*
561 * Accept the peer's idea of {our,his} address, if different
562 * from our idea, only if the accept_{local,remote} flag is set.
563 */
564 NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,
565 if (go->accept_local && ciaddr1) { /* Do we know our address? */
566 try.ouraddr = ciaddr1;
567 IPCPDEBUG((LOG_INFO, "local IP address %s",
568 ip_ntoa(ciaddr1)));
569 }
570 if (go->accept_remote && ciaddr2) { /* Does he know his? */
571 try.hisaddr = ciaddr2;
572 IPCPDEBUG((LOG_INFO, "remote IP address %s",
573 ip_ntoa(ciaddr2)));
574 }
575 );
576
577 /*
578 * Accept the peer's value of maxslotindex provided that it
579 * is less than what we asked for. Turn off slot-ID compression
580 * if the peer wants. Send old-style compress-type option if
581 * the peer wants.
582 */
583 NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
584 if (cilen == CILEN_VJ) {
585 GETCHAR(cimaxslotindex, p);
586 GETCHAR(cicflag, p);
587 if (cishort == IPCP_VJ_COMP) {
588 try.old_vj = 0;
589 if (cimaxslotindex < go->maxslotindex)
590 try.maxslotindex = cimaxslotindex;
591 if (!cicflag)
592 try.cflag = 0;
593 } else {
594 try.neg_vj = 0;
595 }
596 } else {
597 if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {
598 try.old_vj = 1;
599 try.vj_protocol = cishort;
600 } else {
601 try.neg_vj = 0;
602 }
603 }
604 );
605
606 /*
607 * There may be remaining CIs, if the peer is requesting negotiation
608 * on an option that we didn't include in our request packet.
609 * If they want to negotiate about IP addresses, we comply.
610 * If they want us to ask for compression, we refuse.
611 */
612 while (len > CILEN_VOID) {
613 GETCHAR(citype, p);
614 GETCHAR(cilen, p);
615 if( (len -= cilen) < 0 )
616 goto bad;
617 next = p + cilen - 2;
618
619 switch (citype) {
620 case CI_COMPRESSTYPE:
621 if (go->neg_vj || no.neg_vj ||
622 (cilen != CILEN_VJ && cilen != CILEN_COMPRESS))
623 goto bad;
624 no.neg_vj = 1;
625 break;
626 case CI_ADDRS:
627 if ((go->neg_addr && go->old_addrs) || no.old_addrs
628 || cilen != CILEN_ADDRS)
629 goto bad;
630 try.neg_addr = 1;
631 try.old_addrs = 1;
632 GETLONG(l, p);
633 ciaddr1 = htonl(l);
634 if (ciaddr1 && go->accept_local)
635 try.ouraddr = ciaddr1;
636 GETLONG(l, p);
637 ciaddr2 = htonl(l);
638 if (ciaddr2 && go->accept_remote)
639 try.hisaddr = ciaddr2;
640 no.old_addrs = 1;
641 break;
642 case CI_ADDR:
643 if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)
644 goto bad;
645 try.old_addrs = 0;
646 GETLONG(l, p);
647 ciaddr1 = htonl(l);
648 if (ciaddr1 && go->accept_local)
649 try.ouraddr = ciaddr1;
650 if (try.ouraddr != 0)
651 try.neg_addr = 1;
652 no.neg_addr = 1;
653 break;
654 }
655 p = next;
656 }
657
658 /* If there is still anything left, this packet is bad. */
659 if (len != 0)
660 goto bad;
661
662 /*
663 * OK, the Nak is good. Now we can update state.
664 */
665 if (f->state != OPENED)
666 *go = try;
667
668 return 1;
669
670 bad:
671 IPCPDEBUG((LOG_INFO, "ipcp_nakci: received bad Nak!"));
672 return 0;
673 }
674
675
676 /*
677 * ipcp_rejci - Reject some of our CIs.
678 */
679 static int
ipcp_rejci(f,p,len)680 ipcp_rejci(f, p, len)
681 fsm *f;
682 u_char *p;
683 int len;
684 {
685 ipcp_options *go = &ipcp_gotoptions[f->unit];
686 u_char cimaxslotindex, ciflag, cilen;
687 u_short cishort;
688 u_int32_t cilong;
689 ipcp_options try; /* options to request next time */
690
691 try = *go;
692 /*
693 * Any Rejected CIs must be in exactly the same order that we sent.
694 * Check packet length and CI length at each step.
695 * If we find any deviations, then this packet is bad.
696 */
697 #define REJCIADDR(opt, neg, old, val1, val2) \
698 if (go->neg && \
699 len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \
700 p[1] == cilen && \
701 p[0] == opt) { \
702 u_int32_t l; \
703 len -= cilen; \
704 INCPTR(2, p); \
705 GETLONG(l, p); \
706 cilong = htonl(l); \
707 /* Check rejected value. */ \
708 if (cilong != val1) \
709 goto bad; \
710 if (old) { \
711 GETLONG(l, p); \
712 cilong = htonl(l); \
713 /* Check rejected value. */ \
714 if (cilong != val2) \
715 goto bad; \
716 } \
717 try.neg = 0; \
718 }
719
720 #define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
721 if (go->neg && \
722 p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
723 len >= p[1] && \
724 p[0] == opt) { \
725 len -= p[1]; \
726 INCPTR(2, p); \
727 GETSHORT(cishort, p); \
728 /* Check rejected value. */ \
729 if (cishort != val) \
730 goto bad; \
731 if (!old) { \
732 GETCHAR(cimaxslotindex, p); \
733 if (cimaxslotindex != maxslot) \
734 goto bad; \
735 GETCHAR(ciflag, p); \
736 if (ciflag != cflag) \
737 goto bad; \
738 } \
739 try.neg = 0; \
740 }
741
742 REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr,
743 go->old_addrs, go->ouraddr, go->hisaddr);
744
745 REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
746 go->maxslotindex, go->cflag);
747
748 /*
749 * If there are any remaining CIs, then this packet is bad.
750 */
751 if (len != 0)
752 goto bad;
753 /*
754 * Now we can update state.
755 */
756 if (f->state != OPENED)
757 *go = try;
758 return 1;
759
760 bad:
761 IPCPDEBUG((LOG_INFO, "ipcp_rejci: received bad Reject!"));
762 return 0;
763 }
764
765
766 /*
767 * ipcp_reqci - Check the peer's requested CIs and send appropriate response.
768 *
769 * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
770 * appropriately. If reject_if_disagree is non-zero, doesn't return
771 * CONFNAK; returns CONFREJ if it can't return CONFACK.
772 */
773 static int
ipcp_reqci(f,inp,len,reject_if_disagree)774 ipcp_reqci(f, inp, len, reject_if_disagree)
775 fsm *f;
776 u_char *inp; /* Requested CIs */
777 int *len; /* Length of requested CIs */
778 int reject_if_disagree;
779 {
780 ipcp_options *wo = &ipcp_wantoptions[f->unit];
781 ipcp_options *ho = &ipcp_hisoptions[f->unit];
782 ipcp_options *ao = &ipcp_allowoptions[f->unit];
783 ipcp_options *go = &ipcp_gotoptions[f->unit];
784 u_char *cip, *next; /* Pointer to current and next CIs */
785 u_short cilen, citype; /* Parsed len, type */
786 u_short cishort; /* Parsed short value */
787 u_int32_t tl, ciaddr1, ciaddr2;/* Parsed address values */
788 int rc = CONFACK; /* Final packet return code */
789 int orc; /* Individual option return code */
790 u_char *p; /* Pointer to next char to parse */
791 u_char *ucp = inp; /* Pointer to current output char */
792 int l = *len; /* Length left */
793 u_char maxslotindex, cflag;
794 int d;
795
796 cis_received[f->unit] = 1;
797
798 /*
799 * Reset all his options.
800 */
801 BZERO(ho, sizeof(*ho));
802
803 /*
804 * Process all his options.
805 */
806 next = inp;
807 while (l) {
808 orc = CONFACK; /* Assume success */
809 cip = p = next; /* Remember beginning of CI */
810 if (l < 2 || /* Not enough data for CI header or */
811 p[1] < 2 || /* CI length too small or */
812 p[1] > l) { /* CI length too big? */
813 IPCPDEBUG((LOG_INFO, "ipcp_reqci: bad CI length!"));
814 orc = CONFREJ; /* Reject bad CI */
815 cilen = l; /* Reject till end of packet */
816 l = 0; /* Don't loop again */
817 goto endswitch;
818 }
819 GETCHAR(citype, p); /* Parse CI type */
820 GETCHAR(cilen, p); /* Parse CI length */
821 l -= cilen; /* Adjust remaining length */
822 next += cilen; /* Step to next CI */
823
824 switch (citype) { /* Check CI type */
825 case CI_ADDRS:
826 IPCPDEBUG((LOG_INFO, "ipcp: received ADDRS "));
827 if (!ao->neg_addr ||
828 cilen != CILEN_ADDRS) { /* Check CI length */
829 orc = CONFREJ; /* Reject CI */
830 break;
831 }
832
833 /*
834 * If he has no address, or if we both have his address but
835 * disagree about it, then NAK it with our idea.
836 * In particular, if we don't know his address, but he does,
837 * then accept it.
838 */
839 GETLONG(tl, p); /* Parse source address (his) */
840 ciaddr1 = htonl(tl);
841 IPCPDEBUG((LOG_INFO, "(%s:", ip_ntoa(ciaddr1)));
842 if (ciaddr1 != wo->hisaddr
843 && (ciaddr1 == 0 || !wo->accept_remote)) {
844 orc = CONFNAK;
845 if (!reject_if_disagree) {
846 DECPTR(sizeof(u_int32_t), p);
847 tl = ntohl(wo->hisaddr);
848 PUTLONG(tl, p);
849 }
850 } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
851 /*
852 * If neither we nor he knows his address, reject the option.
853 */
854 orc = CONFREJ;
855 wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
856 break;
857 }
858
859 /*
860 * If he doesn't know our address, or if we both have our address
861 * but disagree about it, then NAK it with our idea.
862 */
863 GETLONG(tl, p); /* Parse destination address (ours) */
864 ciaddr2 = htonl(tl);
865 IPCPDEBUG((LOG_INFO, "%s)", ip_ntoa(ciaddr2)));
866 if (ciaddr2 != wo->ouraddr) {
867 if (ciaddr2 == 0 || !wo->accept_local) {
868 orc = CONFNAK;
869 if (!reject_if_disagree) {
870 DECPTR(sizeof(u_int32_t), p);
871 tl = ntohl(wo->ouraddr);
872 PUTLONG(tl, p);
873 }
874 } else {
875 go->ouraddr = ciaddr2; /* accept peer's idea */
876 }
877 }
878
879 ho->neg_addr = 1;
880 ho->old_addrs = 1;
881 ho->hisaddr = ciaddr1;
882 ho->ouraddr = ciaddr2;
883 break;
884
885 case CI_ADDR:
886 IPCPDEBUG((LOG_INFO, "ipcp: received ADDR "));
887
888 if (!ao->neg_addr ||
889 cilen != CILEN_ADDR) { /* Check CI length */
890 orc = CONFREJ; /* Reject CI */
891 break;
892 }
893
894 /*
895 * If he has no address, or if we both have his address but
896 * disagree about it, then NAK it with our idea.
897 * In particular, if we don't know his address, but he does,
898 * then accept it.
899 */
900 GETLONG(tl, p); /* Parse source address (his) */
901 ciaddr1 = htonl(tl);
902 IPCPDEBUG((LOG_INFO, "(%s)", ip_ntoa(ciaddr1)));
903 if (ciaddr1 != wo->hisaddr
904 && (ciaddr1 == 0 || !wo->accept_remote)) {
905 orc = CONFNAK;
906 if (!reject_if_disagree) {
907 DECPTR(sizeof(u_int32_t), p);
908 tl = ntohl(wo->hisaddr);
909 PUTLONG(tl, p);
910 }
911 } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
912 /*
913 * Don't ACK an address of 0.0.0.0 - reject it instead.
914 */
915 orc = CONFREJ;
916 wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
917 break;
918 }
919
920 ho->neg_addr = 1;
921 ho->hisaddr = ciaddr1;
922 break;
923
924 case CI_MS_DNS1:
925 case CI_MS_DNS2:
926 /* Microsoft primary or secondary DNS request */
927 d = citype == CI_MS_DNS2;
928 IPCPDEBUG((LOG_INFO, "ipcp: received DNS%d Request ", d+1));
929
930 /* If we do not have a DNS address then we cannot send it */
931 if (ao->dnsaddr[d] == 0 ||
932 cilen != CILEN_ADDR) { /* Check CI length */
933 orc = CONFREJ; /* Reject CI */
934 break;
935 }
936 GETLONG(tl, p);
937 if (htonl(tl) != ao->dnsaddr[d]) {
938 DECPTR(sizeof(u_int32_t), p);
939 tl = ntohl(ao->dnsaddr[d]);
940 PUTLONG(tl, p);
941 orc = CONFNAK;
942 }
943 break;
944
945 case CI_MS_WINS1:
946 case CI_MS_WINS2:
947 /* Microsoft primary or secondary WINS request */
948 d = citype == CI_MS_WINS2;
949 IPCPDEBUG((LOG_INFO, "ipcp: received WINS%d Request ", d+1));
950
951 /* If we do not have a DNS address then we cannot send it */
952 if (ao->winsaddr[d] == 0 ||
953 cilen != CILEN_ADDR) { /* Check CI length */
954 orc = CONFREJ; /* Reject CI */
955 break;
956 }
957 GETLONG(tl, p);
958 if (htonl(tl) != ao->winsaddr[d]) {
959 DECPTR(sizeof(u_int32_t), p);
960 tl = ntohl(ao->winsaddr[d]);
961 PUTLONG(tl, p);
962 orc = CONFNAK;
963 }
964 break;
965
966 case CI_COMPRESSTYPE:
967 IPCPDEBUG((LOG_INFO, "ipcp: received COMPRESSTYPE "));
968 if (!ao->neg_vj ||
969 (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) {
970 orc = CONFREJ;
971 break;
972 }
973 GETSHORT(cishort, p);
974 IPCPDEBUG((LOG_INFO, "(%d)", cishort));
975
976 if (!(cishort == IPCP_VJ_COMP ||
977 (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {
978 orc = CONFREJ;
979 break;
980 }
981
982 ho->neg_vj = 1;
983 ho->vj_protocol = cishort;
984 if (cilen == CILEN_VJ) {
985 GETCHAR(maxslotindex, p);
986 if (maxslotindex > ao->maxslotindex) {
987 orc = CONFNAK;
988 if (!reject_if_disagree){
989 DECPTR(1, p);
990 PUTCHAR(ao->maxslotindex, p);
991 }
992 }
993 GETCHAR(cflag, p);
994 if (cflag && !ao->cflag) {
995 orc = CONFNAK;
996 if (!reject_if_disagree){
997 DECPTR(1, p);
998 PUTCHAR(wo->cflag, p);
999 }
1000 }
1001 ho->maxslotindex = maxslotindex;
1002 ho->cflag = cflag;
1003 } else {
1004 ho->old_vj = 1;
1005 ho->maxslotindex = MAX_STATES - 1;
1006 ho->cflag = 1;
1007 }
1008 break;
1009
1010 default:
1011 orc = CONFREJ;
1012 break;
1013 }
1014
1015 endswitch:
1016 IPCPDEBUG((LOG_INFO, " (%s)\n", CODENAME(orc)));
1017
1018 if (orc == CONFACK && /* Good CI */
1019 rc != CONFACK) /* but prior CI wasnt? */
1020 continue; /* Don't send this one */
1021
1022 if (orc == CONFNAK) { /* Nak this CI? */
1023 if (reject_if_disagree) /* Getting fed up with sending NAKs? */
1024 orc = CONFREJ; /* Get tough if so */
1025 else {
1026 if (rc == CONFREJ) /* Rejecting prior CI? */
1027 continue; /* Don't send this one */
1028 if (rc == CONFACK) { /* Ack'd all prior CIs? */
1029 rc = CONFNAK; /* Not anymore... */
1030 ucp = inp; /* Backup */
1031 }
1032 }
1033 }
1034
1035 if (orc == CONFREJ && /* Reject this CI */
1036 rc != CONFREJ) { /* but no prior ones? */
1037 rc = CONFREJ;
1038 ucp = inp; /* Backup */
1039 }
1040
1041 /* Need to move CI? */
1042 if (ucp != cip)
1043 BCOPY(cip, ucp, cilen); /* Move it */
1044
1045 /* Update output pointer */
1046 INCPTR(cilen, ucp);
1047 }
1048
1049 /*
1050 * If we aren't rejecting this packet, and we want to negotiate
1051 * their address, and they didn't send their address, then we
1052 * send a NAK with a CI_ADDR option appended. We assume the
1053 * input buffer is long enough that we can append the extra
1054 * option safely.
1055 */
1056 if (rc != CONFREJ && !ho->neg_addr &&
1057 wo->req_addr && !reject_if_disagree) {
1058 if (rc == CONFACK) {
1059 rc = CONFNAK;
1060 ucp = inp; /* reset pointer */
1061 wo->req_addr = 0; /* don't ask again */
1062 }
1063 PUTCHAR(CI_ADDR, ucp);
1064 PUTCHAR(CILEN_ADDR, ucp);
1065 tl = ntohl(wo->hisaddr);
1066 PUTLONG(tl, ucp);
1067 }
1068
1069 *len = ucp - inp; /* Compute output length */
1070 IPCPDEBUG((LOG_INFO, "ipcp: returning Configure-%s", CODENAME(rc)));
1071 return (rc); /* Return final code */
1072 }
1073
1074
1075 /*
1076 * ip_check_options - check that any IP-related options are OK,
1077 * and assign appropriate defaults.
1078 */
1079 static void
ip_check_options()1080 ip_check_options()
1081 {
1082 struct hostent *hp;
1083 u_int32_t local;
1084 ipcp_options *wo = &ipcp_wantoptions[0];
1085
1086 /*
1087 * Default our local IP address based on our hostname.
1088 * If local IP address already given, don't bother.
1089 */
1090 if (wo->ouraddr == 0 && !disable_defaultip) {
1091 /*
1092 * Look up our hostname (possibly with domain name appended)
1093 * and take the first IP address as our local IP address.
1094 * If there isn't an IP address for our hostname, too bad.
1095 */
1096 wo->accept_local = 1; /* don't insist on this default value */
1097 if ((hp = gethostbyname(hostname)) != NULL) {
1098 local = *(u_int32_t *)hp->h_addr;
1099 if (local != 0 && !bad_ip_adrs(local))
1100 wo->ouraddr = local;
1101 }
1102 }
1103
1104 if (demand && wo->hisaddr == 0) {
1105 option_error("remote IP address required for demand-dialling\n");
1106 exit(1);
1107 }
1108 #if 0
1109 if (demand && wo->accept_remote) {
1110 option_error("ipcp-accept-remote is incompatible with demand\n");
1111 exit(1);
1112 }
1113 #endif
1114 }
1115
1116
1117 /*
1118 * ip_demand_conf - configure the interface as though
1119 * IPCP were up, for use with dial-on-demand.
1120 */
1121 static int
ip_demand_conf(u)1122 ip_demand_conf(u)
1123 int u;
1124 {
1125 ipcp_options *wo = &ipcp_wantoptions[u];
1126
1127 if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr)))
1128 return 0;
1129 if (!sifup(u))
1130 return 0;
1131 if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
1132 return 0;
1133 if (wo->default_route)
1134 if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
1135 default_route_set[u] = 1;
1136 if (wo->proxy_arp)
1137 if (sifproxyarp(u, wo->hisaddr))
1138 proxy_arp_set[u] = 1;
1139
1140 syslog(LOG_NOTICE, "local IP address %s", ip_ntoa(wo->ouraddr));
1141 syslog(LOG_NOTICE, "remote IP address %s", ip_ntoa(wo->hisaddr));
1142
1143 return 1;
1144 }
1145
1146
1147 /*
1148 * ipcp_up - IPCP has come UP.
1149 *
1150 * Configure the IP network interface appropriately and bring it up.
1151 */
1152 static void
ipcp_up(f)1153 ipcp_up(f)
1154 fsm *f;
1155 {
1156 u_int32_t mask;
1157 ipcp_options *ho = &ipcp_hisoptions[f->unit];
1158 ipcp_options *go = &ipcp_gotoptions[f->unit];
1159 ipcp_options *wo = &ipcp_wantoptions[f->unit];
1160
1161 np_up(f->unit, PPP_IP);
1162 IPCPDEBUG((LOG_INFO, "ipcp: up"));
1163
1164 /*
1165 * We must have a non-zero IP address for both ends of the link.
1166 */
1167 if (!ho->neg_addr)
1168 ho->hisaddr = wo->hisaddr;
1169
1170 if (ho->hisaddr == 0) {
1171 syslog(LOG_ERR, "Could not determine remote IP address");
1172 ipcp_close(f->unit, "Could not determine remote IP address");
1173 return;
1174 }
1175 if (go->ouraddr == 0) {
1176 syslog(LOG_ERR, "Could not determine local IP address");
1177 ipcp_close(f->unit, "Could not determine local IP address");
1178 return;
1179 }
1180 script_setenv("IPLOCAL", ip_ntoa(go->ouraddr));
1181 script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr));
1182
1183 /*
1184 * Check that the peer is allowed to use the IP address it wants.
1185 */
1186 if (!auth_ip_addr(f->unit, ho->hisaddr)) {
1187 syslog(LOG_ERR, "Peer is not authorized to use remote address %s",
1188 ip_ntoa(ho->hisaddr));
1189 ipcp_close(f->unit, "Unauthorized remote IP address");
1190 return;
1191 }
1192
1193 /* set tcp compression */
1194 sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex);
1195
1196 /*
1197 * If we are doing dial-on-demand, the interface is already
1198 * configured, so we put out any saved-up packets, then set the
1199 * interface to pass IP packets.
1200 */
1201 if (demand) {
1202 if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
1203 if (go->ouraddr != wo->ouraddr)
1204 syslog(LOG_WARNING, "Local IP address changed to %s",
1205 ip_ntoa(go->ouraddr));
1206 if (ho->hisaddr != wo->hisaddr)
1207 syslog(LOG_WARNING, "Remote IP address changed to %s",
1208 ip_ntoa(ho->hisaddr));
1209 ipcp_clear_addrs(f->unit);
1210
1211 /* Set the interface to the new addresses */
1212 mask = GetMask(go->ouraddr);
1213 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
1214 IPCPDEBUG((LOG_WARNING, "sifaddr failed"));
1215 ipcp_close(f->unit, "Interface configuration failed");
1216 return;
1217 }
1218
1219 /* assign a default route through the interface if required */
1220 if (ipcp_wantoptions[f->unit].default_route)
1221 if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
1222 default_route_set[f->unit] = 1;
1223
1224 /* Make a proxy ARP entry if requested. */
1225 if (ipcp_wantoptions[f->unit].proxy_arp)
1226 if (sifproxyarp(f->unit, ho->hisaddr))
1227 proxy_arp_set[f->unit] = 1;
1228
1229 }
1230 demand_rexmit(PPP_IP);
1231 sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
1232
1233 } else {
1234 /*
1235 * Set IP addresses and (if specified) netmask.
1236 */
1237 mask = GetMask(go->ouraddr);
1238
1239 #if !(defined(SVR4) && (defined(SNI) || defined(__USLC__)))
1240 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
1241 IPCPDEBUG((LOG_WARNING, "sifaddr failed"));
1242 ipcp_close(f->unit, "Interface configuration failed");
1243 return;
1244 }
1245 #endif
1246
1247 /* bring the interface up for IP */
1248 if (!sifup(f->unit)) {
1249 IPCPDEBUG((LOG_WARNING, "sifup failed"));
1250 ipcp_close(f->unit, "Interface configuration failed");
1251 return;
1252 }
1253
1254 #if (defined(SVR4) && (defined(SNI) || defined(__USLC__)))
1255 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
1256 IPCPDEBUG((LOG_WARNING, "sifaddr failed"));
1257 ipcp_close(f->unit, "Interface configuration failed");
1258 return;
1259 }
1260 #endif
1261 sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
1262
1263 /* assign a default route through the interface if required */
1264 if (ipcp_wantoptions[f->unit].default_route)
1265 if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
1266 default_route_set[f->unit] = 1;
1267
1268 /* Make a proxy ARP entry if requested. */
1269 if (ipcp_wantoptions[f->unit].proxy_arp)
1270 if (sifproxyarp(f->unit, ho->hisaddr))
1271 proxy_arp_set[f->unit] = 1;
1272
1273 syslog(LOG_NOTICE, "local IP address %s", ip_ntoa(go->ouraddr));
1274 syslog(LOG_NOTICE, "remote IP address %s", ip_ntoa(ho->hisaddr));
1275 }
1276
1277 /*
1278 * Execute the ip-up script, like this:
1279 * /etc/ppp/ip-up interface tty speed local-IP remote-IP
1280 */
1281 ipcp_script(f, _PATH_IPUP);
1282
1283 }
1284
1285
1286 /*
1287 * ipcp_down - IPCP has gone DOWN.
1288 *
1289 * Take the IP network interface down, clear its addresses
1290 * and delete routes through it.
1291 */
1292 static void
ipcp_down(f)1293 ipcp_down(f)
1294 fsm *f;
1295 {
1296 IPCPDEBUG((LOG_INFO, "ipcp: down"));
1297 np_down(f->unit, PPP_IP);
1298 sifvjcomp(f->unit, 0, 0, 0);
1299
1300 /*
1301 * If we are doing dial-on-demand, set the interface
1302 * to queue up outgoing packets (for now).
1303 */
1304 if (demand) {
1305 sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE);
1306 } else {
1307 sifdown(f->unit);
1308 ipcp_clear_addrs(f->unit);
1309 }
1310
1311 /* Execute the ip-down script */
1312 ipcp_script(f, _PATH_IPDOWN);
1313 }
1314
1315
1316 /*
1317 * ipcp_clear_addrs() - clear the interface addresses, routes,
1318 * proxy arp entries, etc.
1319 */
1320 static void
ipcp_clear_addrs(unit)1321 ipcp_clear_addrs(unit)
1322 int unit;
1323 {
1324 u_int32_t ouraddr, hisaddr;
1325
1326 ouraddr = ipcp_gotoptions[unit].ouraddr;
1327 hisaddr = ipcp_hisoptions[unit].hisaddr;
1328 if (proxy_arp_set[unit]) {
1329 cifproxyarp(unit, hisaddr);
1330 proxy_arp_set[unit] = 0;
1331 }
1332 if (default_route_set[unit]) {
1333 cifdefaultroute(unit, ouraddr, hisaddr);
1334 default_route_set[unit] = 0;
1335 }
1336 cifaddr(unit, ouraddr, hisaddr);
1337 }
1338
1339
1340 /*
1341 * ipcp_finished - possibly shut down the lower layers.
1342 */
1343 static void
ipcp_finished(f)1344 ipcp_finished(f)
1345 fsm *f;
1346 {
1347 np_finished(f->unit, PPP_IP);
1348 }
1349
1350
1351 /*
1352 * ipcp_script - Execute a script with arguments
1353 * interface-name tty-name speed local-IP remote-IP.
1354 */
1355 static void
ipcp_script(f,script)1356 ipcp_script(f, script)
1357 fsm *f;
1358 char *script;
1359 {
1360 char strspeed[32], strlocal[32], strremote[32];
1361 char *argv[8];
1362
1363 snprintf(strspeed, sizeof strspeed, "%d", baud_rate);
1364 strlcpy(strlocal, ip_ntoa(ipcp_gotoptions[f->unit].ouraddr),
1365 sizeof strlocal);
1366 strlcpy(strremote, ip_ntoa(ipcp_hisoptions[f->unit].hisaddr),
1367 sizeof strremote);
1368
1369 argv[0] = script;
1370 argv[1] = ifname;
1371 argv[2] = devnam;
1372 argv[3] = strspeed;
1373 argv[4] = strlocal;
1374 argv[5] = strremote;
1375 argv[6] = ipparam;
1376 argv[7] = NULL;
1377 run_program(script, argv, 0);
1378 }
1379
1380 /*
1381 * ipcp_printpkt - print the contents of an IPCP packet.
1382 */
1383 static char *ipcp_codenames[] = {
1384 "ConfReq", "ConfAck", "ConfNak", "ConfRej",
1385 "TermReq", "TermAck", "CodeRej"
1386 };
1387
1388 static int
ipcp_printpkt(p,plen,printer,arg)1389 ipcp_printpkt(p, plen, printer, arg)
1390 u_char *p;
1391 int plen;
1392 void (*printer)(void *, char *, ...);
1393 void *arg;
1394 {
1395 int code, id, len, olen;
1396 u_char *pstart, *optend;
1397 u_short cishort;
1398 u_int32_t cilong;
1399
1400 if (plen < HEADERLEN)
1401 return 0;
1402 pstart = p;
1403 GETCHAR(code, p);
1404 GETCHAR(id, p);
1405 GETSHORT(len, p);
1406 if (len < HEADERLEN || len > plen)
1407 return 0;
1408
1409 if (code >= 1 && code <= sizeof(ipcp_codenames) / sizeof(char *))
1410 printer(arg, " %s", ipcp_codenames[code-1]);
1411 else
1412 printer(arg, " code=0x%x", code);
1413 printer(arg, " id=0x%x", id);
1414 len -= HEADERLEN;
1415 switch (code) {
1416 case CONFREQ:
1417 case CONFACK:
1418 case CONFNAK:
1419 case CONFREJ:
1420 /* print option list */
1421 while (len >= 2) {
1422 GETCHAR(code, p);
1423 GETCHAR(olen, p);
1424 p -= 2;
1425 if (olen < 2 || olen > len) {
1426 break;
1427 }
1428 printer(arg, " <");
1429 len -= olen;
1430 optend = p + olen;
1431 switch (code) {
1432 case CI_ADDRS:
1433 if (olen == CILEN_ADDRS) {
1434 p += 2;
1435 GETLONG(cilong, p);
1436 printer(arg, "addrs %I", htonl(cilong));
1437 GETLONG(cilong, p);
1438 printer(arg, " %I", htonl(cilong));
1439 }
1440 break;
1441 case CI_COMPRESSTYPE:
1442 if (olen >= CILEN_COMPRESS) {
1443 p += 2;
1444 GETSHORT(cishort, p);
1445 printer(arg, "compress ");
1446 switch (cishort) {
1447 case IPCP_VJ_COMP:
1448 printer(arg, "VJ");
1449 break;
1450 case IPCP_VJ_COMP_OLD:
1451 printer(arg, "old-VJ");
1452 break;
1453 default:
1454 printer(arg, "0x%x", cishort);
1455 }
1456 }
1457 break;
1458 case CI_ADDR:
1459 if (olen == CILEN_ADDR) {
1460 p += 2;
1461 GETLONG(cilong, p);
1462 printer(arg, "addr %I", htonl(cilong));
1463 }
1464 break;
1465 case CI_MS_DNS1:
1466 case CI_MS_DNS2:
1467 p += 2;
1468 GETLONG(cilong, p);
1469 printer(arg, "ms-dns %I", htonl(cilong));
1470 break;
1471 case CI_MS_WINS1:
1472 case CI_MS_WINS2:
1473 p += 2;
1474 GETLONG(cilong, p);
1475 printer(arg, "ms-wins %I", htonl(cilong));
1476 break;
1477 }
1478 while (p < optend) {
1479 GETCHAR(code, p);
1480 printer(arg, " %.2x", code);
1481 }
1482 printer(arg, ">");
1483 }
1484 break;
1485
1486 case TERMACK:
1487 case TERMREQ:
1488 if (len > 0 && *p >= ' ' && *p < 0x7f) {
1489 printer(arg, " ");
1490 print_string(p, len, printer, arg);
1491 p += len;
1492 len = 0;
1493 }
1494 break;
1495 }
1496
1497 /* print the rest of the bytes in the packet */
1498 for (; len > 0; --len) {
1499 GETCHAR(code, p);
1500 printer(arg, " %.2x", code);
1501 }
1502
1503 return p - pstart;
1504 }
1505
1506 /*
1507 * ip_active_pkt - see if this IP packet is worth bringing the link up for.
1508 * We don't bring the link up for IP fragments or for TCP FIN packets
1509 * with no data.
1510 */
1511 #define IP_HDRLEN 20 /* bytes */
1512 #define IP_OFFMASK 0x1fff
1513 #define IPPROTO_TCP 6
1514 #define TCP_HDRLEN 20
1515 #define TH_FIN 0x01
1516
1517 /*
1518 * We use these macros because the IP header may be at an odd address,
1519 * and some compilers might use word loads to get th_off or ip_hl.
1520 */
1521
1522 #define net_short(x) (((x)[0] << 8) + (x)[1])
1523 #define get_iphl(x) (((unsigned char *)(x))[0] & 0xF)
1524 #define get_ipoff(x) net_short((unsigned char *)(x) + 6)
1525 #define get_ipproto(x) (((unsigned char *)(x))[9])
1526 #define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4)
1527 #define get_tcpflags(x) (((unsigned char *)(x))[13])
1528
1529 static int
ip_active_pkt(pkt,len)1530 ip_active_pkt(pkt, len)
1531 u_char *pkt;
1532 int len;
1533 {
1534 u_char *tcp;
1535 int hlen;
1536
1537 len -= PPP_HDRLEN;
1538 pkt += PPP_HDRLEN;
1539 if (len < IP_HDRLEN)
1540 return 0;
1541 if ((get_ipoff(pkt) & IP_OFFMASK) != 0)
1542 return 0;
1543 if (get_ipproto(pkt) != IPPROTO_TCP)
1544 return 1;
1545 hlen = get_iphl(pkt) * 4;
1546 if (len < hlen + TCP_HDRLEN)
1547 return 0;
1548 tcp = pkt + hlen;
1549 if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)
1550 return 0;
1551 return 1;
1552 }
1553