1 /*
2 * ipcp.c - PPP IP Control Protocol.
3 *
4 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5 * Use is subject to license terms.
6 *
7 * Copyright (c) 1989 Carnegie Mellon University.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms are permitted
11 * provided that the above copyright notice and this paragraph are
12 * duplicated in all such forms and that any documentation,
13 * advertising materials, and other materials related to such
14 * distribution and use acknowledge that the software was developed
15 * by Carnegie Mellon University. The name of the
16 * University may not be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 */
22
23 #define RCSID "$Id: ipcp.c,v 1.54 2000/04/15 01:27:11 masputra Exp $"
24
25 /*
26 * TODO:
27 */
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <netdb.h>
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #if defined(_linux_) || defined(__linux__)
36 #define __FAVOR_BSD
37 #endif
38 #include <netinet/in.h>
39 #include <netinet/tcp.h>
40 #include <arpa/inet.h>
41
42 #include "pppd.h"
43 #include "fsm.h"
44 #include "ipcp.h"
45 #include "pathnames.h"
46
47 #if !defined(lint) && !defined(_lint)
48 static const char rcsid[] = RCSID;
49 #endif
50
51 /* global vars */
52 ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
53 ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
54 ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
55 ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
56
57 bool ipcp_from_hostname = 0; /* Local IP address is from hostname lookup */
58
59 /* Hook for a plugin to know when IP protocol has come up */
60 void (*ip_up_hook) __P((void)) = NULL;
61
62 /* Hook for a plugin to know when IP protocol has come down */
63 void (*ip_down_hook) __P((void)) = NULL;
64
65 /* local vars */
66 static bool default_route_set[NUM_PPP]; /* Have set up a default route */
67 static bool proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */
68 static bool ipcp_is_up[NUM_PPP]; /* have called np_up() */
69 static bool proxy_arp_quiet[NUM_PPP]; /* We should be quiet on error */
70 static bool disable_defaultip = 0; /* Don't use hostname for IP addr */
71
72 /*
73 * Callbacks for fsm code. (CI = Configuration Information)
74 */
75 static void ipcp_resetci __P((fsm *)); /* Reset our CI */
76 static int ipcp_cilen __P((fsm *)); /* Return length of our CI */
77 static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
78 static int ipcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
79 static int ipcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */
80 static int ipcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
81 static int ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
82 static void ipcp_up __P((fsm *)); /* We're UP */
83 static void ipcp_down __P((fsm *)); /* We're DOWN */
84 static void ipcp_finished __P((fsm *)); /* Don't need lower layer */
85 static int setmsservaddr __P((char *, u_int32_t *));
86
87 fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */
88
89 static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
90 ipcp_resetci, /* Reset our Configuration Information */
91 ipcp_cilen, /* Length of our Configuration Information */
92 ipcp_addci, /* Add our Configuration Information */
93 ipcp_ackci, /* ACK our Configuration Information */
94 ipcp_nakci, /* NAK our Configuration Information */
95 ipcp_rejci, /* Reject our Configuration Information */
96 ipcp_reqci, /* Request peer's Configuration Information */
97 ipcp_up, /* Called when fsm reaches OPENED state */
98 ipcp_down, /* Called when fsm leaves OPENED state */
99 NULL, /* Called when we want the lower layer up */
100 ipcp_finished, /* Called when we want the lower layer down */
101 NULL, /* Retransmission is necessary */
102 NULL, /* Called to handle protocol-specific codes */
103 "IPCP", /* String name of protocol */
104 NULL /* Peer rejected a code number */
105 };
106
107 /*
108 * Command-line options.
109 */
110 static int setvjslots __P((char **));
111 static int setdnsaddr __P((char **));
112 static int setwinsaddr __P((char **));
113 static int autoproxyarp __P((char **));
114
115 static option_t ipcp_option_list[] = {
116 { "noip", o_bool, &ipcp_protent.enabled_flag,
117 "Disable IP and IPCP" },
118 { "-ip", o_bool, &ipcp_protent.enabled_flag,
119 "Disable IP and IPCP" },
120 { "novj", o_bool, &ipcp_wantoptions[0].neg_vj,
121 "Disable VJ compression", OPT_A2COPY, &ipcp_allowoptions[0].neg_vj },
122 { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj,
123 "Disable VJ compression", OPT_A2COPY, &ipcp_allowoptions[0].neg_vj },
124 { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag,
125 "Disable VJ connection-ID compression", OPT_A2COPY,
126 &ipcp_allowoptions[0].cflag },
127 { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag,
128 "Disable VJ connection-ID compression", OPT_A2COPY,
129 &ipcp_allowoptions[0].cflag },
130 { "vj-max-slots", o_special, (void *)setvjslots,
131 "Set maximum VJ header slots" },
132 { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local,
133 "Accept peer's address for us", 1 },
134 { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote,
135 "Accept peer's address for it", 1 },
136 { "ipparam", o_string, &ipparam,
137 "Set ip script parameter" },
138 { "noipdefault", o_bool, &disable_defaultip,
139 "Don't use name for default IP adrs", 1 },
140 { "ms-dns", o_special, (void *)setdnsaddr,
141 "DNS address for the peer's use" },
142 { "ms-wins", o_special, (void *)setwinsaddr,
143 "Nameserver for SMB over TCP/IP for peer" },
144 { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime,
145 "Set timeout for IPCP" },
146 { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits,
147 "Set max #xmits for term-reqs" },
148 { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits,
149 "Set max #xmits for conf-reqs" },
150 { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops,
151 "Set max #conf-naks for IPCP" },
152 { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route,
153 "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route },
154 { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route,
155 "disable defaultroute option", OPT_A2COPY,
156 &ipcp_wantoptions[0].default_route },
157 { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route,
158 "disable defaultroute option", OPT_A2COPY,
159 &ipcp_wantoptions[0].default_route },
160 { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
161 "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
162 { "autoproxyarp", o_special_noarg, (void *)autoproxyarp,
163 "Add proxy ARP entry if needed", OPT_ENABLE,
164 &ipcp_allowoptions[0].proxy_arp },
165 { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
166 "disable proxyarp option", OPT_A2COPY, &ipcp_wantoptions[0].proxy_arp },
167 { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
168 "disable proxyarp option", OPT_A2COPY, &ipcp_wantoptions[0].proxy_arp },
169 { "usepeerdns", o_bool, &ipcp_wantoptions[0].req_dns1,
170 "Ask peer for DNS address(es)", OPT_A2COPY|1,
171 &ipcp_wantoptions[0].req_dns2 },
172 { NULL }
173 };
174
175 /*
176 * Protocol entry points from main code.
177 */
178 static void ipcp_init __P((int));
179 static void ipcp_open __P((int));
180 static void ipcp_close __P((int, char *));
181 static void ipcp_lowerup __P((int));
182 static void ipcp_lowerdown __P((int));
183 static void ipcp_input __P((int, u_char *, int));
184 static void ipcp_protrej __P((int));
185 static int ipcp_printpkt __P((u_char *, int,
186 void (*) __P((void *, const char *, ...)), void *));
187 static void ip_check_options __P((void));
188 static int ip_demand_conf __P((int));
189 static int ip_active_pkt __P((u_char *, int));
190 static void ipcp_print_stat __P((int, FILE *));
191
192 static void create_resolv __P((u_int32_t, u_int32_t));
193
194 struct protent ipcp_protent = {
195 PPP_IPCP,
196 ipcp_init,
197 ipcp_input,
198 ipcp_protrej,
199 ipcp_lowerup,
200 ipcp_lowerdown,
201 ipcp_open,
202 ipcp_close,
203 ipcp_printpkt,
204 NULL,
205 1,
206 "IPCP",
207 "IP",
208 ipcp_option_list,
209 ip_check_options,
210 ip_demand_conf,
211 ip_active_pkt,
212 ipcp_print_stat
213 };
214
215 static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
216 static void ipcp_script __P((char *)); /* Run an up/down script */
217 static void ipcp_script_done __P((void *, int));
218
219 /*
220 * Lengths of configuration options.
221 */
222 #define CILEN_VOID 2
223 #define CILEN_COMPRESS 4 /* min length for compression protocol opt. */
224 #define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */
225 #define CILEN_ADDR 6 /* new-style single address option */
226 #define CILEN_ADDRS 10 /* old-style dual address option */
227
228
229 /*
230 * This state variable is used to ensure that we don't
231 * run an ipcp-up/down script while one is already running.
232 */
233 static enum script_state {
234 s_down,
235 s_up
236 } ipcp_script_state;
237 static pid_t ipcp_script_pid;
238
239 /*
240 * Make a string representation of a network IP address.
241 */
242 char *
ip_ntoa(ipaddr)243 ip_ntoa(ipaddr)
244 u_int32_t ipaddr;
245 {
246 static char b[64];
247
248 (void) slprintf(b, sizeof(b), "%I", ipaddr);
249 return b;
250 }
251
252 /*
253 * Option parsing.
254 */
255
256 /*
257 * setvjslots - set maximum number of connection slots for VJ compression
258 */
259 static int
setvjslots(argv)260 setvjslots(argv)
261 char **argv;
262 {
263 int value;
264
265 if (!int_option(*argv, &value))
266 return 0;
267 if (value < 2 || value > 16) {
268 option_error("vj-max-slots value must be between 2 and 16");
269 return 0;
270 }
271 ipcp_wantoptions [0].maxslotindex =
272 ipcp_allowoptions[0].maxslotindex = value - 1;
273 return 1;
274 }
275
276 /*
277 * setmsservaddr - Set the primary and secondary server addresses in the
278 * array. setdnsaddr() and setwinsaddr() call this function with either
279 * dnsaddr[] or winsaddr[] as the serverarray argument.
280 */
281 static int
setmsservaddr(servname,serverarray)282 setmsservaddr(servname, serverarray)
283 char *servname;
284 u_int32_t *serverarray;
285 {
286 u_int32_t addr;
287 struct hostent *hp = NULL;
288
289 addr = inet_addr(servname);
290 if (addr == (u_int32_t) -1) {
291 if ((hp = gethostbyname(servname)) == NULL)
292 return 0;
293 BCOPY(hp->h_addr, &addr, sizeof (u_int32_t));
294 }
295
296 /*
297 * If there is no primary then this is the first instance of the
298 * option, we must set the primary. In that case, try to set the
299 * secondary to h_addr_list[1]. If the primary is already set, then
300 * this is the second instance of the option, and we must set
301 * the secondary.
302 */
303 if (serverarray[0] == 0) {
304 serverarray[0] = addr;
305 if (hp != NULL && hp->h_addr_list[1] != NULL)
306 BCOPY(hp->h_addr_list[1], &serverarray[1], sizeof (u_int32_t));
307 else
308 serverarray[1] = addr;
309 } else {
310 serverarray[1] = addr;
311 }
312
313 return (1);
314 }
315
316 /*
317 * setdnsaddr - set the dns address(es)
318 */
319 static int
setdnsaddr(argv)320 setdnsaddr(argv)
321 char **argv;
322 {
323 if (setmsservaddr(*argv, &(ipcp_allowoptions[0].dnsaddr[0])) == 0) {
324 option_error("invalid address parameter '%s' for ms-dns option", *argv);
325 return (0);
326 }
327
328 return (1);
329 }
330
331 /*
332 * setwinsaddr - set the wins address(es)
333 * This is primrarly used with the Samba package under UNIX or for pointing
334 * the caller to the existing WINS server on a Windows NT platform.
335 */
336 static int
setwinsaddr(argv)337 setwinsaddr(argv)
338 char **argv;
339 {
340 if (setmsservaddr(*argv, &(ipcp_allowoptions[0].winsaddr[0])) == 0) {
341 option_error("invalid address parameter '%s' for ms-wins option",
342 *argv);
343 return (0);
344 }
345
346 return (1);
347 }
348
349 /*
350 * autoproxyarp -- enable proxy ARP but don't emit error messages if
351 * it's not actually needed.
352 */
353 /*ARGSUSED*/
354 static int
autoproxyarp(argv)355 autoproxyarp(argv)
356 char **argv;
357 {
358 ipcp_wantoptions[0].proxy_arp = 1;
359 proxy_arp_quiet[0] = 1;
360
361 return (1);
362 }
363
364
365 /*
366 * ipcp_init - Initialize IPCP.
367 */
368 static void
ipcp_init(unit)369 ipcp_init(unit)
370 int unit;
371 {
372 fsm *f = &ipcp_fsm[unit];
373 ipcp_options *wo = &ipcp_wantoptions[unit];
374 ipcp_options *ao = &ipcp_allowoptions[unit];
375
376 f->unit = unit;
377 f->protocol = PPP_IPCP;
378 f->callbacks = &ipcp_callbacks;
379 fsm_init(&ipcp_fsm[unit]);
380
381 BZERO(wo, sizeof(*wo));
382 BZERO(ao, sizeof(*ao));
383
384 wo->neg_addr = wo->old_addrs = 1;
385 wo->neg_vj = 1;
386 wo->vj_protocol = IPCP_VJ_COMP;
387 wo->maxslotindex = MAX_STATES - 1; /* really max index */
388 wo->cflag = 1;
389
390 ao->neg_addr = ao->old_addrs = 1;
391 ao->neg_vj = 1;
392 ao->maxslotindex = MAX_STATES - 1;
393 ao->cflag = 1;
394
395 /*
396 * These aren't actually negotiated. Instead, they control
397 * whether the user may use the proxyarp and defaultroute options.
398 */
399 ao->proxy_arp = 1;
400 ao->default_route = 1;
401 proxy_arp_quiet[unit] = 0;
402 }
403
404
405 /*
406 * ipcp_open - IPCP is allowed to come up.
407 */
408 static void
ipcp_open(unit)409 ipcp_open(unit)
410 int unit;
411 {
412 fsm_open(&ipcp_fsm[unit]);
413 }
414
415
416 /*
417 * ipcp_close - Take IPCP down.
418 */
419 static void
ipcp_close(unit,reason)420 ipcp_close(unit, reason)
421 int unit;
422 char *reason;
423 {
424 fsm_close(&ipcp_fsm[unit], reason);
425 }
426
427
428 /*
429 * ipcp_lowerup - The lower layer is up.
430 */
431 static void
ipcp_lowerup(unit)432 ipcp_lowerup(unit)
433 int unit;
434 {
435 fsm_lowerup(&ipcp_fsm[unit]);
436 }
437
438
439 /*
440 * ipcp_lowerdown - The lower layer is down.
441 */
442 static void
ipcp_lowerdown(unit)443 ipcp_lowerdown(unit)
444 int unit;
445 {
446 fsm_lowerdown(&ipcp_fsm[unit]);
447 }
448
449
450 /*
451 * ipcp_input - Input IPCP packet.
452 */
453 static void
ipcp_input(unit,p,len)454 ipcp_input(unit, p, len)
455 int unit;
456 u_char *p;
457 int len;
458 {
459 fsm_input(&ipcp_fsm[unit], p, len);
460 }
461
462
463 /*
464 * ipcp_protrej - A Protocol-Reject was received for IPCP.
465 */
466 static void
ipcp_protrej(unit)467 ipcp_protrej(unit)
468 int unit;
469 {
470 fsm_protreject(&ipcp_fsm[unit]);
471 }
472
473
474 /*
475 * ipcp_resetci - Reset our CI.
476 * Called by fsm_sconfreq, Send Configure Request.
477 */
478 static void
ipcp_resetci(f)479 ipcp_resetci(f)
480 fsm *f;
481 {
482 ipcp_options *wo = &ipcp_wantoptions[f->unit];
483 ipcp_options *go = &ipcp_gotoptions[f->unit];
484 ipcp_options *ao = &ipcp_allowoptions[f->unit];
485
486 wo->req_addr = (wo->neg_addr || wo->old_addrs) &&
487 (ao->neg_addr || ao->old_addrs);
488 if (wo->ouraddr == 0 || disable_defaultip)
489 wo->accept_local = 1;
490 if (wo->hisaddr == 0)
491 wo->accept_remote = 1;
492 *go = *wo;
493 if (disable_defaultip)
494 go->ouraddr = 0;
495 }
496
497
498 /*
499 * ipcp_cilen - Return length of our CI.
500 * Called by fsm_sconfreq, Send Configure Request.
501 */
502 static int
ipcp_cilen(f)503 ipcp_cilen(f)
504 fsm *f;
505 {
506 ipcp_options *go = &ipcp_gotoptions[f->unit];
507 ipcp_options *wo = &ipcp_wantoptions[f->unit];
508 ipcp_options *ho = &ipcp_hisoptions[f->unit];
509
510 #define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0)
511 #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
512 #define LENCIADDR(neg) (neg ? (CILEN_ADDR) : 0)
513
514 /*
515 * First see if we want to change our options to the old
516 * forms because we have received old forms from the peer.
517 */
518 if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs)
519 /* use the old style of address negotiation */
520 go->neg_addr = 0;
521 if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
522 /* try an older style of VJ negotiation */
523 /* use the old style only if the peer did */
524 if (ho->neg_vj && ho->old_vj) {
525 go->neg_vj = 1;
526 go->old_vj = 1;
527 go->vj_protocol = ho->vj_protocol;
528 }
529 }
530
531 return (LENCIADDRS(!go->neg_addr && go->old_addrs) +
532 LENCIVJ(go->neg_vj, go->old_vj) +
533 LENCIADDR(go->neg_addr) +
534 LENCIADDR(go->req_dns1) +
535 LENCIADDR(go->req_dns2)) ;
536 }
537
538
539 /*
540 * ipcp_addci - Add our desired CIs to a packet.
541 * Called by fsm_sconfreq, Send Configure Request.
542 */
543 static void
ipcp_addci(f,ucp,lenp)544 ipcp_addci(f, ucp, lenp)
545 fsm *f;
546 u_char *ucp;
547 int *lenp;
548 {
549 ipcp_options *go = &ipcp_gotoptions[f->unit];
550 int len = *lenp;
551
552 #define ADDCIADDRS(opt, neg, val1, val2) \
553 if (neg) { \
554 if (len >= CILEN_ADDRS) { \
555 PUTCHAR(opt, ucp); \
556 PUTCHAR(CILEN_ADDRS, ucp); \
557 PUTNLONG(val1, ucp); \
558 PUTNLONG(val2, ucp); \
559 len -= CILEN_ADDRS; \
560 } else \
561 go->old_addrs = 0; \
562 }
563
564 #define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
565 if (neg) { \
566 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
567 if (len >= vjlen) { \
568 PUTCHAR(opt, ucp); \
569 PUTCHAR(vjlen, ucp); \
570 PUTSHORT(val, ucp); \
571 if (!old) { \
572 PUTCHAR(maxslotindex, ucp); \
573 PUTCHAR(cflag, ucp); \
574 } \
575 len -= vjlen; \
576 } else \
577 neg = 0; \
578 }
579
580 #define ADDCIADDR(opt, neg, val) \
581 if (neg) { \
582 if (len >= CILEN_ADDR) { \
583 PUTCHAR(opt, ucp); \
584 PUTCHAR(CILEN_ADDR, ucp); \
585 PUTNLONG(val, ucp); \
586 len -= CILEN_ADDR; \
587 } else \
588 neg = 0; \
589 }
590
591 ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
592 go->hisaddr);
593
594 ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
595 go->maxslotindex, go->cflag);
596
597 ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr);
598
599 ADDCIADDR(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
600
601 ADDCIADDR(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
602
603 *lenp -= len;
604 }
605
606
607 /*
608 * ipcp_ackci - Ack our CIs.
609 * Called by fsm_rconfack, Receive Configure ACK.
610 *
611 * Returns:
612 * 0 - Ack was bad.
613 * 1 - Ack was good.
614 */
615 static int
ipcp_ackci(f,p,len)616 ipcp_ackci(f, p, len)
617 fsm *f;
618 u_char *p;
619 int len;
620 {
621 ipcp_options *go = &ipcp_gotoptions[f->unit];
622 u_short cilen, citype, cishort;
623 u_int32_t cilong;
624 u_char cimaxslotindex, cicflag;
625
626 /*
627 * CIs must be in exactly the same order that we sent...
628 * Check packet length and CI length at each step.
629 * If we find any deviations, then this packet is bad.
630 */
631
632 #define ACKCHECK(opt, olen) \
633 if ((len -= olen) < 0) \
634 goto bad; \
635 GETCHAR(citype, p); \
636 GETCHAR(cilen, p); \
637 if (cilen != olen || \
638 citype != opt) \
639 goto bad;
640
641 #define ACKCIADDRS(opt, neg, val1, val2) \
642 if (neg) { \
643 ACKCHECK(opt, CILEN_ADDRS) \
644 GETNLONG(cilong, p); \
645 if (val1 != cilong) \
646 goto bad; \
647 GETNLONG(cilong, p); \
648 if (val2 != cilong) \
649 goto bad; \
650 }
651
652 #define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
653 if (neg) { \
654 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
655 ACKCHECK(opt, vjlen) \
656 GETSHORT(cishort, p); \
657 if (cishort != val) \
658 goto bad; \
659 if (!old) { \
660 GETCHAR(cimaxslotindex, p); \
661 if (cimaxslotindex != maxslotindex) \
662 goto bad; \
663 GETCHAR(cicflag, p); \
664 if (cicflag != cflag) \
665 goto bad; \
666 } \
667 }
668
669 #define ACKCIADDR(opt, neg, val) \
670 if (neg) { \
671 ACKCHECK(opt, CILEN_ADDR) \
672 GETNLONG(cilong, p); \
673 if (val != cilong) \
674 goto bad; \
675 }
676
677 ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
678 go->hisaddr);
679
680 ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
681 go->maxslotindex, go->cflag);
682
683 ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr);
684
685 ACKCIADDR(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
686
687 ACKCIADDR(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
688
689 /*
690 * If there are any remaining CIs, then this packet is bad.
691 */
692 if (len != 0)
693 goto bad;
694 return (1);
695
696 bad:
697 IPCPDEBUG(("ipcp_ackci: received bad Ack!"));
698 return (0);
699 }
700
701 /*
702 * ipcp_nakci - Peer has sent a NAK for some of our CIs.
703 * This should not modify any state if the Nak is bad
704 * or if IPCP is in the OPENED state.
705 * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject.
706 *
707 * Returns:
708 * 0 - Nak was bad.
709 * 1 - Nak was good.
710 */
711 static int
ipcp_nakci(f,p,len)712 ipcp_nakci(f, p, len)
713 fsm *f;
714 u_char *p;
715 int len;
716 {
717 ipcp_options *go = &ipcp_gotoptions[f->unit];
718 u_char cimaxslotindex, cicflag;
719 u_char citype, cilen, *next;
720 u_short cishort;
721 u_int32_t ciaddr1, ciaddr2;
722 ipcp_options no; /* options we've seen Naks for */
723 ipcp_options try; /* options to request next time */
724
725 BZERO(&no, sizeof(no));
726 try = *go;
727
728 /*
729 * Any Nak'd CIs must be in exactly the same order that we sent.
730 * Check packet length and CI length at each step.
731 * If we find any deviations, then this packet is bad.
732 */
733 #define NAKCIADDRS(opt, neg, code) \
734 if ((neg) && \
735 (cilen = p[1]) == CILEN_ADDRS && \
736 len >= cilen && \
737 p[0] == opt) { \
738 len -= cilen; \
739 INCPTR(2, p); \
740 GETNLONG(ciaddr1, p); \
741 GETNLONG(ciaddr2, p); \
742 no.old_addrs = 1; \
743 code \
744 }
745
746 #define NAKCIVJ(opt, neg, code) \
747 if (go->neg && \
748 ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \
749 len >= cilen && \
750 p[0] == opt) { \
751 len -= cilen; \
752 INCPTR(2, p); \
753 GETSHORT(cishort, p); \
754 no.neg = 1; \
755 code \
756 }
757
758 #define NAKCIADDR(opt, neg, code) \
759 if (go->neg && \
760 (cilen = p[1]) == CILEN_ADDR && \
761 len >= cilen && \
762 p[0] == opt) { \
763 len -= cilen; \
764 INCPTR(2, p); \
765 GETNLONG(ciaddr1, p); \
766 no.neg = 1; \
767 code \
768 }
769
770 /*
771 * Accept the peer's idea of {our,his} address, if different
772 * from our idea, only if the accept_{local,remote} flag is set.
773 */
774 NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
775 if (go->accept_local && ciaddr1) { /* Do we know our address? */
776 try.ouraddr = ciaddr1;
777 }
778 if (go->accept_remote && ciaddr2) { /* Does he know his? */
779 try.hisaddr = ciaddr2;
780 }
781 );
782
783 /*
784 * Accept the peer's value of maxslotindex provided that it
785 * is less than what we asked for. Turn off slot-ID compression
786 * if the peer wants. Send old-style compress-type option if
787 * the peer wants.
788 */
789 NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
790 if (cilen == CILEN_VJ) {
791 GETCHAR(cimaxslotindex, p);
792 GETCHAR(cicflag, p);
793 if (cishort == IPCP_VJ_COMP) {
794 try.old_vj = 0;
795 if (cimaxslotindex < go->maxslotindex)
796 try.maxslotindex = cimaxslotindex;
797 if (!cicflag)
798 try.cflag = 0;
799 } else {
800 try.neg_vj = 0;
801 }
802 } else {
803 if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) {
804 try.old_vj = 1;
805 try.vj_protocol = cishort;
806 } else {
807 try.neg_vj = 0;
808 }
809 }
810 );
811
812 NAKCIADDR(CI_ADDR, neg_addr,
813 if (go->accept_local && ciaddr1) { /* Do we know our address? */
814 try.ouraddr = ciaddr1;
815 }
816 );
817
818 NAKCIADDR(CI_MS_DNS1, req_dns1,
819 try.dnsaddr[0] = ciaddr1;
820 );
821
822 NAKCIADDR(CI_MS_DNS2, req_dns2,
823 try.dnsaddr[1] = ciaddr1;
824 );
825
826 /*
827 * There may be remaining CIs, if the peer is requesting negotiation
828 * on an option that we didn't include in our request packet.
829 * If they want to negotiate about IP addresses, we comply.
830 * If they want us to ask for compression, we refuse.
831 */
832 while (len > CILEN_VOID) {
833 GETCHAR(citype, p);
834 GETCHAR(cilen, p);
835 if( (len -= cilen) < 0 )
836 goto bad;
837 next = p + cilen - 2;
838
839 switch (citype) {
840 case CI_COMPRESSTYPE:
841 if (go->neg_vj || no.neg_vj ||
842 (cilen != CILEN_VJ && cilen != CILEN_COMPRESS))
843 goto bad;
844 no.neg_vj = 1;
845 break;
846 case CI_ADDRS:
847 if ((!go->neg_addr && go->old_addrs) || no.old_addrs
848 || cilen != CILEN_ADDRS)
849 goto bad;
850 try.neg_addr = 1;
851 try.old_addrs = 1;
852 GETNLONG(ciaddr1, p);
853 if (ciaddr1 && go->accept_local)
854 try.ouraddr = ciaddr1;
855 GETNLONG(ciaddr2, p);
856 if (ciaddr2 && go->accept_remote)
857 try.hisaddr = ciaddr2;
858 no.old_addrs = 1;
859 break;
860 case CI_ADDR:
861 if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR)
862 goto bad;
863 try.old_addrs = 0;
864 GETNLONG(ciaddr1, p);
865 if (ciaddr1 && go->accept_local)
866 try.ouraddr = ciaddr1;
867 if (try.ouraddr != 0)
868 try.neg_addr = 1;
869 no.neg_addr = 1;
870 break;
871 }
872 p = next;
873 }
874
875 /*
876 * OK, the Nak is good. Now we can update state.
877 * If there are any remaining options, we ignore them.
878 */
879 if (f->state != OPENED)
880 *go = try;
881
882 return 1;
883
884 bad:
885 IPCPDEBUG(("ipcp_nakci: received bad Nak!"));
886 return 0;
887 }
888
889
890 /*
891 * ipcp_rejci - Reject some of our CIs.
892 * Callback from fsm_rconfnakrej.
893 */
894 static int
ipcp_rejci(f,p,len)895 ipcp_rejci(f, p, len)
896 fsm *f;
897 u_char *p;
898 int len;
899 {
900 ipcp_options *go = &ipcp_gotoptions[f->unit];
901 u_char cimaxslotindex, ciflag, cilen;
902 u_short cishort;
903 u_int32_t cilong;
904 ipcp_options try; /* options to request next time */
905
906 try = *go;
907 /*
908 * Any Rejected CIs must be in exactly the same order that we sent.
909 * Check packet length and CI length at each step.
910 * If we find any deviations, then this packet is bad.
911 */
912 #define REJCIADDRS(opt, neg, val1, val2) \
913 if ((neg) && \
914 (cilen = p[1]) == CILEN_ADDRS && \
915 len >= cilen && \
916 p[0] == opt) { \
917 len -= cilen; \
918 INCPTR(2, p); \
919 GETNLONG(cilong, p); \
920 /* Check rejected value. */ \
921 if (cilong != val1) \
922 goto bad; \
923 GETNLONG(cilong, p); \
924 /* Check rejected value. */ \
925 if (cilong != val2) \
926 goto bad; \
927 try.old_addrs = 0; \
928 }
929
930 #define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
931 if (go->neg && \
932 p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \
933 len >= p[1] && \
934 p[0] == opt) { \
935 len -= p[1]; \
936 INCPTR(2, p); \
937 GETSHORT(cishort, p); \
938 /* Check rejected value. */ \
939 if (cishort != val) \
940 goto bad; \
941 if (!old) { \
942 GETCHAR(cimaxslotindex, p); \
943 if (cimaxslotindex != maxslot) \
944 goto bad; \
945 GETCHAR(ciflag, p); \
946 if (ciflag != cflag) \
947 goto bad; \
948 } \
949 try.neg = 0; \
950 }
951
952 #define REJCIADDR(opt, neg, addr) \
953 if (go->neg && \
954 ((cilen = p[1]) == CILEN_ADDR) && \
955 len >= cilen && \
956 p[0] == opt) { \
957 len -= cilen; \
958 INCPTR(2, p); \
959 GETNLONG(cilong, p); \
960 /* Check rejected value. */ \
961 if (cilong != addr) \
962 goto bad; \
963 try.neg = 0; \
964 }
965
966 REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
967 go->ouraddr, go->hisaddr);
968
969 REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
970 go->maxslotindex, go->cflag);
971
972 REJCIADDR(CI_ADDR, neg_addr, go->ouraddr);
973
974 REJCIADDR(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
975
976 REJCIADDR(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
977
978 /*
979 * If there are any remaining CIs, then this packet is bad.
980 */
981 if (len != 0)
982 goto bad;
983 /*
984 * Now we can update state.
985 */
986 if (f->state != OPENED)
987 *go = try;
988 return 1;
989
990 bad:
991 IPCPDEBUG(("ipcp_rejci: received bad Reject!"));
992 return 0;
993 }
994
995
996 /*
997 * ipcp_reqci - Check the peer's requested CIs and send appropriate response.
998 * Callback from fsm_rconfreq, Receive Configure Request
999 *
1000 * Returns: CODE_CONFACK, CODE_CONFNAK or CODE_CONFREJ and input
1001 * packet modified appropriately. If reject_if_disagree is non-zero,
1002 * doesn't return CODE_CONFNAK; returns CODE_CONFREJ if it can't
1003 * return CODE_CONFACK.
1004 */
1005 static int
ipcp_reqci(f,p,lenp,dont_nak)1006 ipcp_reqci(f, p, lenp, dont_nak)
1007 fsm *f;
1008 u_char *p; /* Requested CIs */
1009 int *lenp; /* Length of requested CIs */
1010 bool dont_nak;
1011 {
1012 ipcp_options *wo = &ipcp_wantoptions[f->unit];
1013 ipcp_options *ho = &ipcp_hisoptions[f->unit];
1014 ipcp_options *ao = &ipcp_allowoptions[f->unit];
1015 ipcp_options *go = &ipcp_gotoptions[f->unit];
1016 int ret, newret;
1017 u_char *p0, *nakp, *rejp, *prev;
1018 u_short cishort;
1019 int len, cilen, type;
1020 u_int32_t tl, ciaddr1, ciaddr2; /* Parsed address values */
1021 u_char maxslotindex, cflag;
1022 int d;
1023
1024 ret = CODE_CONFACK;
1025 rejp = p0 = p;
1026 nakp = nak_buffer;
1027
1028 /*
1029 * Reset all his options.
1030 */
1031 BZERO(ho, sizeof(*ho));
1032
1033 /*
1034 * Process all his options.
1035 */
1036 for (len = *lenp; len > 0; len -= cilen, p = prev + cilen) {
1037 if ((len < 2) || p[1] > len) {
1038 /*
1039 * RFC 1661 page 40 -- if the option extends beyond the
1040 * packet, then discard the entire packet.
1041 */
1042 return (0);
1043 }
1044
1045 newret = CODE_CONFACK;
1046 prev = p;
1047 GETCHAR(type, p);
1048 GETCHAR(cilen, p);
1049
1050 switch (type) { /* Check CI type */
1051 case CI_ADDRS:
1052 if (!ao->old_addrs || ho->neg_addr) {
1053 newret = CODE_CONFREJ;
1054 break;
1055 }
1056
1057 if (cilen != CILEN_ADDRS) {
1058 /*
1059 * rfc1661, page 40 -- a recongnized option with an
1060 * invalid length should be Nak'ed.
1061 */
1062 newret = CODE_CONFNAK;
1063 ciaddr1 = wo->hisaddr;
1064 ciaddr2 = wo->ouraddr;
1065 } else {
1066
1067 /*
1068 * If he has no address, or if we both have his
1069 * address but disagree about it, then NAK it with our
1070 * idea. In particular, if we don't know his address,
1071 * but he does, then accept it.
1072 */
1073 GETNLONG(ciaddr1, p);
1074 if (ciaddr1 != wo->hisaddr &&
1075 (ciaddr1 == 0 || !wo->accept_remote)) {
1076 newret = CODE_CONFNAK;
1077 ciaddr1 = wo->hisaddr;
1078 } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
1079 /*
1080 * If neither we nor he knows his address, reject
1081 * the option.
1082 */
1083 newret = CODE_CONFREJ;
1084 wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
1085 break;
1086 } else if (ciaddr1 != 0) {
1087 go->hisaddr = ciaddr1;
1088 }
1089
1090 /*
1091 * If he doesn't know our address, or if we both have
1092 * our address * but disagree about it, then NAK it
1093 * with our idea.
1094 */
1095 GETNLONG(ciaddr2, p);
1096 if (ciaddr2 != wo->ouraddr) {
1097 if (ciaddr2 == 0 || !wo->accept_local) {
1098 newret = CODE_CONFNAK;
1099 ciaddr2 = wo->ouraddr;
1100 } else {
1101 go->ouraddr = ciaddr2; /* accept peer's idea */
1102 }
1103 }
1104 }
1105
1106 if (newret == CODE_CONFNAK) {
1107 PUTCHAR(type, nakp);
1108 PUTCHAR(CILEN_ADDRS, nakp);
1109 PUTNLONG(ciaddr1, nakp);
1110 PUTNLONG(ciaddr2, nakp);
1111 }
1112
1113 ho->old_addrs = 1;
1114 ho->hisaddr = ciaddr1;
1115 ho->ouraddr = ciaddr2;
1116 break;
1117
1118 case CI_ADDR:
1119 if (!ao->neg_addr || ho->old_addrs) {
1120 newret = CODE_CONFREJ;
1121 break;
1122 }
1123
1124 if (cilen != CILEN_ADDR) {
1125 /*
1126 * rfc1661, page 40 -- a recongnized option with an
1127 * invalid length should be Nak'ed.
1128 */
1129 newret = CODE_CONFNAK;
1130 ciaddr1 = wo->hisaddr;
1131 } else {
1132
1133 /*
1134 * If he has no address, or if we both have his
1135 * address but disagree about it, then NAK it with our
1136 * idea. In particular, if we don't know his address,
1137 * but he does, then accept it.
1138 */
1139 GETNLONG(ciaddr1, p);
1140 if (ciaddr1 != wo->hisaddr &&
1141 (ciaddr1 == 0 || !wo->accept_remote)) {
1142 newret = CODE_CONFNAK;
1143 ciaddr1 = wo->hisaddr;
1144 } else if (ciaddr1 == 0 && wo->hisaddr == 0 &&
1145 wo->default_route != 0) {
1146 newret = CODE_CONFNAK;
1147 /*
1148 * If this is a dialup line (default_route is
1149 * set), and neither side knows about his address,
1150 * suggest an arbitrary rfc1918 address.
1151 */
1152 ciaddr1 = htonl(0xc0a80101 + ifunit);
1153 dbglog("Peer address unknown; suggesting %I", ciaddr1);
1154 } else if (ciaddr1 == 0 && wo->hisaddr == 0) {
1155 /*
1156 * If this is not a dialup line, don't ACK an
1157 * address of 0.0.0.0 - reject it instead.
1158 */
1159 newret = CODE_CONFREJ;
1160 wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
1161 break;
1162 }
1163 }
1164
1165 if (newret == CODE_CONFNAK) {
1166 PUTCHAR(type, nakp);
1167 PUTCHAR(CILEN_ADDR, nakp);
1168 PUTNLONG(ciaddr1, nakp);
1169 }
1170
1171 ho->neg_addr = 1;
1172 ho->hisaddr = ciaddr1;
1173 break;
1174
1175 case CI_MS_DNS1:
1176 case CI_MS_DNS2:
1177 /* Warning -- these options work backwards. */
1178 /* Microsoft primary or secondary DNS request */
1179 d = (type == CI_MS_DNS2 ? 1 : 0);
1180
1181 if (ao->dnsaddr[d] == 0) {
1182 newret = CODE_CONFREJ;
1183 break;
1184 }
1185
1186 if (cilen != CILEN_ADDR) {
1187 newret = CODE_CONFNAK;
1188 } else {
1189 GETNLONG(tl, p);
1190 if (tl != ao->dnsaddr[d]) {
1191 newret = CODE_CONFNAK;
1192 }
1193 }
1194
1195 if (newret == CODE_CONFNAK) {
1196 PUTCHAR(type, nakp);
1197 PUTCHAR(CILEN_ADDR, nakp);
1198 PUTNLONG(ao->dnsaddr[d], nakp);
1199 }
1200 break;
1201
1202 case CI_MS_WINS1:
1203 case CI_MS_WINS2:
1204 /* Warning -- these options work backwards. */
1205 /* Microsoft primary or secondary WINS request */
1206 d = (type == CI_MS_WINS2 ? 1 : 0);
1207
1208 if (ao->winsaddr[d] == 0) {
1209 newret = CODE_CONFREJ;
1210 break;
1211 }
1212
1213 if (cilen != CILEN_ADDR) {
1214 newret = CODE_CONFNAK;
1215 } else {
1216 GETNLONG(tl, p);
1217 if (tl != ao->winsaddr[d]) {
1218 newret = CODE_CONFNAK;
1219 }
1220 }
1221
1222 if (newret == CODE_CONFNAK) {
1223 PUTCHAR(type, nakp);
1224 PUTCHAR(CILEN_ADDR, nakp);
1225 PUTNLONG(ao->winsaddr[d], nakp);
1226 }
1227 break;
1228
1229 case CI_COMPRESSTYPE:
1230 if (!ao->neg_vj) {
1231 newret = CODE_CONFREJ;
1232 break;
1233 }
1234
1235 maxslotindex = ao->maxslotindex;
1236 cflag = ao->cflag;
1237 if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) {
1238 newret = CODE_CONFNAK;
1239 cishort = IPCP_VJ_COMP;
1240 } else {
1241 GETSHORT(cishort, p);
1242 if (cishort != IPCP_VJ_COMP &&
1243 (cishort != IPCP_VJ_COMP_OLD || cilen != CILEN_COMPRESS)) {
1244 newret = CODE_CONFNAK;
1245 cishort = IPCP_VJ_COMP;
1246 } else if (cilen == CILEN_VJ) {
1247 GETCHAR(maxslotindex, p);
1248 if (maxslotindex > ao->maxslotindex) {
1249 newret = CODE_CONFNAK;
1250 maxslotindex = ao->maxslotindex;
1251 }
1252 GETCHAR(cflag, p);
1253 if (cflag != 0 && ao->cflag == 0) {
1254 newret = CODE_CONFNAK;
1255 cflag = 0;
1256 }
1257 } else {
1258 ho->old_vj = 1;
1259 maxslotindex = MAX_STATES - 1;
1260 cflag = 1;
1261 }
1262 }
1263
1264 if (newret == CODE_CONFNAK) {
1265 PUTCHAR(type, nakp);
1266 if (cishort == IPCP_VJ_COMP) {
1267 PUTCHAR(CILEN_VJ, nakp);
1268 PUTSHORT(cishort, nakp);
1269 PUTCHAR(maxslotindex, nakp);
1270 PUTCHAR(cflag, nakp);
1271 } else {
1272 PUTCHAR(CILEN_COMPRESS, nakp);
1273 PUTSHORT(cishort, nakp);
1274 }
1275 }
1276 ho->neg_vj = 1;
1277 ho->vj_protocol = cishort;
1278 ho->maxslotindex = maxslotindex;
1279 ho->cflag = cflag;
1280 break;
1281
1282 default:
1283 newret = CODE_CONFREJ;
1284 break;
1285 }
1286
1287 /* Cope with confused peers. */
1288 if (cilen < 2)
1289 cilen = 2;
1290
1291 /*
1292 * If this is an Ack'able CI, but we're sending back a Nak,
1293 * don't include this CI.
1294 */
1295 if (newret == CODE_CONFACK && ret != CODE_CONFACK)
1296 continue;
1297
1298 if (newret == CODE_CONFNAK) {
1299 if (dont_nak) {
1300 newret = CODE_CONFREJ;
1301 } else {
1302 /* Ignore subsequent Nak'able things if rejecting. */
1303 if (ret == CODE_CONFREJ)
1304 continue;
1305 ret = CODE_CONFNAK;
1306 }
1307 }
1308
1309 if (newret == CODE_CONFREJ) {
1310 ret = CODE_CONFREJ;
1311 if (prev != rejp)
1312 BCOPY(prev, rejp, cilen);
1313 rejp += cilen;
1314 }
1315 }
1316
1317 /*
1318 * If we aren't rejecting this packet, and we want to negotiate
1319 * their address, and they didn't send their address, then we
1320 * send a NAK with a CI_ADDR option appended. We assume the
1321 * input buffer is long enough that we can append the extra
1322 * option safely.
1323 */
1324 if (ret != CODE_CONFREJ && !ho->neg_addr && !ho->old_addrs &&
1325 wo->req_addr && !dont_nak) {
1326 if (ret == CODE_CONFACK)
1327 wo->req_addr = 0; /* don't ask again */
1328 ret = CODE_CONFNAK;
1329 PUTCHAR(CI_ADDR, nakp);
1330 PUTCHAR(CILEN_ADDR, nakp);
1331 PUTNLONG(wo->hisaddr, nakp);
1332 }
1333
1334 switch (ret) {
1335 case CODE_CONFACK:
1336 *lenp = p - p0;
1337 sys_block_proto(PPP_IP);
1338 break;
1339 case CODE_CONFNAK:
1340 *lenp = nakp - nak_buffer;
1341 BCOPY(nak_buffer, p0, *lenp);
1342 break;
1343 case CODE_CONFREJ:
1344 *lenp = rejp - p0;
1345 break;
1346 }
1347
1348 return (ret); /* Return final code */
1349 }
1350
1351
1352 /*
1353 * ip_check_options - check that any IP-related options are OK,
1354 * and assign appropriate defaults.
1355 */
1356 static void
ip_check_options()1357 ip_check_options()
1358 {
1359 struct hostent *hp;
1360 u_int32_t local;
1361 ipcp_options *wo = &ipcp_wantoptions[0];
1362
1363 /*
1364 * Default our local IP address based on our hostname.
1365 * If local IP address already given, don't bother.
1366 */
1367 if (wo->ouraddr == 0) {
1368 /*
1369 * Look up our hostname (possibly with domain name appended)
1370 * and take the first IP address as our local IP address.
1371 * If there isn't an IP address for our hostname, too bad.
1372 */
1373 wo->accept_local = 1; /* don't insist on this default value */
1374 if ((hp = gethostbyname(hostname)) != NULL) {
1375 BCOPY(hp->h_addr, &local, sizeof (hp->h_addr));
1376 if (local != 0 && !bad_ip_adrs(local)) {
1377 wo->ouraddr = local;
1378 ipcp_from_hostname = 1;
1379 }
1380 }
1381 }
1382 }
1383
1384
1385 /*
1386 * ip_demand_conf - configure the interface as though
1387 * IPCP were up, for use with dial-on-demand.
1388 */
1389 static int
ip_demand_conf(u)1390 ip_demand_conf(u)
1391 int u;
1392 {
1393 ipcp_options *wo = &ipcp_wantoptions[u];
1394
1395 if (wo->hisaddr == 0) {
1396 /* make up an arbitrary address for the peer */
1397 wo->hisaddr = htonl(0x0a707070 + ifunit);
1398 wo->accept_remote = 1;
1399 }
1400 if (wo->ouraddr == 0) {
1401 /* make up an arbitrary address for us */
1402 wo->ouraddr = htonl(0x0a404040 + ifunit);
1403 wo->accept_local = 1;
1404 disable_defaultip = 1; /* don't tell the peer this address */
1405 }
1406 if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr)))
1407 return 0;
1408 if (!sifup(u))
1409 return 0;
1410 if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
1411 return 0;
1412 if (wo->default_route && sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
1413 default_route_set[u] = 1;
1414 if (wo->proxy_arp && sifproxyarp(u, wo->hisaddr, proxy_arp_quiet[u]))
1415 proxy_arp_set[u] = 1;
1416
1417 notice("local IP address %I", wo->ouraddr);
1418 notice("remote IP address %I", wo->hisaddr);
1419
1420 return 1;
1421 }
1422
1423
1424 /*
1425 * ipcp_up - IPCP has come UP.
1426 *
1427 * Configure the IP network interface appropriately and bring it up.
1428 */
1429 static void
ipcp_up(f)1430 ipcp_up(f)
1431 fsm *f;
1432 {
1433 u_int32_t mask;
1434 ipcp_options *ho = &ipcp_hisoptions[f->unit];
1435 ipcp_options *go = &ipcp_gotoptions[f->unit];
1436 ipcp_options *wo = &ipcp_wantoptions[f->unit];
1437
1438 IPCPDEBUG(("ipcp: up"));
1439
1440 /*
1441 * We must have a non-zero IP address for both ends of the link.
1442 */
1443 if (ho->hisaddr == 0)
1444 ho->hisaddr = wo->hisaddr;
1445
1446 if (ho->hisaddr == 0) {
1447 if (wo->accept_remote) {
1448 /* Pick some rfc1918 address. */
1449 ho->hisaddr = htonl(0xc0a80101 + ifunit);
1450 dbglog("Peer refused to provide his address; assuming %I",
1451 ho->hisaddr);
1452 } else {
1453 error("Could not determine remote IP address");
1454 ipcp_close(f->unit, "Could not determine remote IP address");
1455 return;
1456 }
1457 }
1458 if (go->ouraddr == 0) {
1459 error("Could not determine local IP address");
1460 ipcp_close(f->unit, "Could not determine local IP address");
1461 return;
1462 }
1463 script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0);
1464 script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1);
1465
1466 /*
1467 * Check that the peer is allowed to use the IP address it wants.
1468 */
1469 if (!auth_ip_addr(f->unit, ho->hisaddr)) {
1470 error("Peer is not authorized to use remote address %I", ho->hisaddr);
1471 ipcp_close(f->unit, "Unauthorized remote IP address");
1472 return;
1473 }
1474
1475 if ((go->req_dns1 && go->dnsaddr[0] != 0) ||
1476 (go->req_dns2 && go->dnsaddr[1] != 0)) {
1477 script_setenv("USEPEERDNS", "1", 0);
1478 if (go->dnsaddr[0] != 0)
1479 script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0);
1480 if (go->dnsaddr[1] != 0)
1481 script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0);
1482 create_resolv(go->dnsaddr[0], go->dnsaddr[1]);
1483 }
1484
1485 /* set tcp compression */
1486 if (sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex) != 1) {
1487 ipcp_close(f->unit, "Could not enable VJ TCP header compression");
1488 return;
1489 }
1490
1491 /*
1492 * If we are doing dial-on-demand, the interface is already
1493 * configured, so we put out any saved-up packets, then set the
1494 * interface to pass IP packets.
1495 */
1496 if (demand) {
1497 if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
1498 ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
1499 if (go->ouraddr != wo->ouraddr) {
1500 warn("Local IP address changed to %I", go->ouraddr);
1501 script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
1502 wo->ouraddr = go->ouraddr;
1503 } else
1504 script_unsetenv("OLDIPLOCAL");
1505 if (ho->hisaddr != wo->hisaddr) {
1506 warn("Remote IP address changed to %I", ho->hisaddr);
1507 script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);
1508 wo->hisaddr = ho->hisaddr;
1509 } else
1510 script_unsetenv("OLDIPREMOTE");
1511
1512 /* Set the interface to the new addresses */
1513 mask = GetMask(go->ouraddr);
1514 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
1515 warn("Interface configuration failed");
1516 ipcp_close(f->unit, "Interface configuration failed");
1517 return;
1518 }
1519
1520 /* assign a default route through the interface if required */
1521 if (wo->default_route)
1522 if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
1523 default_route_set[f->unit] = 1;
1524
1525 /* Make a proxy ARP entry if requested. */
1526 if (wo->proxy_arp &&
1527 sifproxyarp(f->unit, ho->hisaddr, proxy_arp_quiet[f->unit]))
1528 proxy_arp_set[f->unit] = 1;
1529
1530 }
1531 demand_rexmit(PPP_IP);
1532 if (sifnpmode(f->unit, PPP_IP, NPMODE_PASS) != 1) {
1533 ipcp_close(f->unit, "Interface configuration failed.");
1534 return;
1535 }
1536
1537 } else {
1538 /*
1539 * Set IP addresses and (if specified) netmask.
1540 */
1541 mask = GetMask(go->ouraddr);
1542
1543 #if SIFUPFIRST
1544 /* bring the interface up for IP */
1545 if (!sifup(f->unit)) {
1546 warn("Interface failed to come up");
1547 ipcp_close(f->unit, "Interface configuration failed");
1548 return;
1549 }
1550 #endif
1551
1552 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
1553 warn("Interface configuration failed");
1554 ipcp_close(f->unit, "Interface configuration failed");
1555 return;
1556 }
1557
1558 #if !SIFUPFIRST
1559 /* bring the interface up for IP */
1560 if (!sifup(f->unit)) {
1561 warn("Interface failed to come up");
1562 ipcp_close(f->unit, "Interface configuration failed");
1563 return;
1564 }
1565 #endif
1566
1567 if (sifnpmode(f->unit, PPP_IP, NPMODE_PASS) != 1) {
1568 ipcp_close(f->unit, "Interface configuration failed.");
1569 return;
1570 }
1571
1572 /* assign a default route through the interface if required */
1573 if (wo->default_route)
1574 if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
1575 default_route_set[f->unit] = 1;
1576
1577 /* Make a proxy ARP entry if requested. */
1578 if (wo->proxy_arp &&
1579 sifproxyarp(f->unit, ho->hisaddr, proxy_arp_quiet[f->unit]))
1580 proxy_arp_set[f->unit] = 1;
1581
1582 wo->ouraddr = go->ouraddr;
1583
1584 notice("local IP address %I", go->ouraddr);
1585 notice("remote IP address %I", ho->hisaddr);
1586 if (go->dnsaddr[0] != 0)
1587 notice("primary DNS address %I", go->dnsaddr[0]);
1588 if (go->dnsaddr[1] != 0)
1589 notice("secondary DNS address %I", go->dnsaddr[1]);
1590 }
1591
1592 np_up(f->unit, PPP_IP);
1593 ipcp_is_up[f->unit] = 1;
1594
1595 if (ip_up_hook != NULL)
1596 (*ip_up_hook)();
1597
1598 /*
1599 * Execute the ip-up script, like this:
1600 * /etc/ppp/ip-up interface tty speed local-IP remote-IP
1601 */
1602 if (ipcp_script_state == s_down && ipcp_script_pid == 0) {
1603 ipcp_script_state = s_up;
1604 ipcp_script(_PATH_IPUP);
1605 }
1606 sys_unblock_proto(PPP_IP);
1607 }
1608
1609
1610 /*
1611 * ipcp_down - IPCP has gone DOWN.
1612 *
1613 * Take the IP network interface down, clear its addresses
1614 * and delete routes through it.
1615 */
1616 static void
ipcp_down(f)1617 ipcp_down(f)
1618 fsm *f;
1619 {
1620 IPCPDEBUG(("ipcp: down"));
1621 /* XXX a bit IPv4-centric here, we only need to get the stats
1622 * before the interface is marked down. */
1623 update_link_stats(f->unit);
1624 if (ip_down_hook != NULL)
1625 (*ip_down_hook)();
1626 if (ipcp_is_up[f->unit]) {
1627 ipcp_is_up[f->unit] = 0;
1628 np_down(f->unit, PPP_IP);
1629 }
1630 if (sifvjcomp(f->unit, 0, 0, 0) != 1) {
1631 if (debug)
1632 warn("Failed to disable VJ TCP header compression.");
1633 }
1634
1635 /*
1636 * If we are doing dial-on-demand, set the interface
1637 * to queue up outgoing packets (for now).
1638 */
1639 if (demand) {
1640 if (sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE) != 1) {
1641 if (debug)
1642 warn("Failed to enable Queueing on outgoing packets.");
1643 }
1644 } else {
1645 if (sifnpmode(f->unit, PPP_IP, NPMODE_ERROR) != 1) {
1646 if (debug)
1647 warn("Could not set interface to drop packets.");
1648 }
1649 if (sifdown(f->unit) != 1)
1650 warn("Could not bring interface down.");
1651 ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
1652 ipcp_hisoptions[f->unit].hisaddr);
1653 }
1654
1655 /* Execute the ip-down script */
1656 if (ipcp_script_state == s_up && ipcp_script_pid == 0) {
1657 ipcp_script_state = s_down;
1658 ipcp_script(_PATH_IPDOWN);
1659 }
1660 }
1661
1662
1663 /*
1664 * ipcp_clear_addrs() - clear the interface addresses, routes,
1665 * proxy arp entries, etc.
1666 */
1667 static void
ipcp_clear_addrs(unit,ouraddr,hisaddr)1668 ipcp_clear_addrs(unit, ouraddr, hisaddr)
1669 int unit;
1670 u_int32_t ouraddr; /* local address */
1671 u_int32_t hisaddr; /* remote address */
1672 {
1673 if (proxy_arp_set[unit]) {
1674 (void) cifproxyarp(unit, hisaddr);
1675 proxy_arp_set[unit] = 0;
1676 }
1677 if (default_route_set[unit]) {
1678 (void) cifdefaultroute(unit, ouraddr, hisaddr);
1679 default_route_set[unit] = 0;
1680 }
1681 if (cifaddr(unit, ouraddr, hisaddr) != 1)
1682 warn("Could not clear addresses");
1683 }
1684
1685
1686 /*
1687 * ipcp_finished - possibly shut down the lower layers.
1688 */
1689 static void
ipcp_finished(f)1690 ipcp_finished(f)
1691 fsm *f;
1692 {
1693 np_finished(f->unit, PPP_IP);
1694 }
1695
1696
1697 /*
1698 * ipcp_script_done - called when the ip-up or ip-down script
1699 * has finished.
1700 */
1701 /*ARGSUSED*/
1702 static void
ipcp_script_done(arg,status)1703 ipcp_script_done(arg, status)
1704 void *arg;
1705 int status;
1706 {
1707 ipcp_script_pid = 0;
1708 switch (ipcp_script_state) {
1709 case s_up:
1710 if (ipcp_fsm[0].state != OPENED) {
1711 ipcp_script_state = s_down;
1712 ipcp_script(_PATH_IPDOWN);
1713 }
1714 break;
1715 case s_down:
1716 if (ipcp_fsm[0].state == OPENED) {
1717 ipcp_script_state = s_up;
1718 ipcp_script(_PATH_IPUP);
1719 }
1720 break;
1721 }
1722 }
1723
1724
1725 /*
1726 * ipcp_script - Execute a script with arguments
1727 * interface-name tty-name speed local-IP remote-IP.
1728 */
1729 static void
ipcp_script(script)1730 ipcp_script(script)
1731 char *script;
1732 {
1733 char strspeed[32], strlocal[32], strremote[32];
1734 char *argv[8];
1735
1736 (void) slprintf(strspeed, sizeof(strspeed), "%d", baud_rate);
1737 (void) slprintf(strlocal, sizeof(strlocal), "%I",
1738 ipcp_gotoptions[0].ouraddr);
1739 (void) slprintf(strremote, sizeof(strremote), "%I",
1740 ipcp_hisoptions[0].hisaddr);
1741
1742 argv[0] = script;
1743 argv[1] = ifname;
1744 argv[2] = devnam;
1745 argv[3] = strspeed;
1746 argv[4] = strlocal;
1747 argv[5] = strremote;
1748 argv[6] = ipparam;
1749 argv[7] = NULL;
1750 ipcp_script_pid = run_program(script, argv, 0, ipcp_script_done, NULL);
1751 }
1752
1753 /*
1754 * create_resolv - create the replacement resolv.conf file
1755 */
1756 static void
create_resolv(peerdns1,peerdns2)1757 create_resolv(peerdns1, peerdns2)
1758 u_int32_t peerdns1, peerdns2;
1759 {
1760 FILE *f;
1761
1762 f = fopen(_PATH_RESOLV, "w");
1763 if (f == NULL) {
1764 error("Failed to create %s: %m", _PATH_RESOLV);
1765 return;
1766 }
1767
1768 if (peerdns1)
1769 if (fprintf(f, "nameserver %s\n", ip_ntoa(peerdns1)) <= 0)
1770 error("Write failed to %s: %m", _PATH_RESOLV);
1771
1772 if (peerdns2)
1773 if (fprintf(f, "nameserver %s\n", ip_ntoa(peerdns2)) <= 0)
1774 error("Write failed to %s: %m", _PATH_RESOLV);
1775
1776 if (fclose(f) != 0)
1777 error("Failed to close %s: %m", _PATH_RESOLV);
1778 }
1779
1780 /*
1781 * ipcp_printpkt - print the contents of an IPCP packet.
1782 */
1783 static int
ipcp_printpkt(p,plen,printer,arg)1784 ipcp_printpkt(p, plen, printer, arg)
1785 u_char *p;
1786 int plen;
1787 void (*printer) __P((void *, const char *, ...));
1788 void *arg;
1789 {
1790 int code, id, len, olen;
1791 u_char *pstart, *optend;
1792 u_short cishort;
1793 u_int32_t cilong;
1794
1795 if (plen < HEADERLEN)
1796 return 0;
1797 pstart = p;
1798 GETCHAR(code, p);
1799 GETCHAR(id, p);
1800 GETSHORT(len, p);
1801 if (len < HEADERLEN || len > plen)
1802 return 0;
1803
1804 printer(arg, " %s id=0x%x", code_name(code, 1), id);
1805 len -= HEADERLEN;
1806 switch (code) {
1807 case CODE_CONFREQ:
1808 case CODE_CONFACK:
1809 case CODE_CONFNAK:
1810 case CODE_CONFREJ:
1811 /* print option list */
1812 while (len >= 2) {
1813 GETCHAR(code, p);
1814 GETCHAR(olen, p);
1815 p -= 2;
1816 if (olen < 2 || olen > len) {
1817 break;
1818 }
1819 printer(arg, " <");
1820 len -= olen;
1821 optend = p + olen;
1822 switch (code) {
1823 case CI_ADDRS:
1824 if (olen == CILEN_ADDRS) {
1825 p += 2;
1826 GETNLONG(cilong, p);
1827 printer(arg, "addrs %I", cilong);
1828 GETNLONG(cilong, p);
1829 printer(arg, " %I", cilong);
1830 }
1831 break;
1832 case CI_COMPRESSTYPE:
1833 if (olen >= CILEN_COMPRESS) {
1834 p += 2;
1835 GETSHORT(cishort, p);
1836 printer(arg, "compress ");
1837 switch (cishort) {
1838 case IPCP_VJ_COMP:
1839 printer(arg, "VJ");
1840 break;
1841 case IPCP_VJ_COMP_OLD:
1842 printer(arg, "old-VJ");
1843 break;
1844 default:
1845 printer(arg, "0x%x", cishort);
1846 }
1847 }
1848 break;
1849 case CI_ADDR:
1850 if (olen == CILEN_ADDR) {
1851 p += 2;
1852 GETNLONG(cilong, p);
1853 printer(arg, "addr %I", cilong);
1854 }
1855 break;
1856 case CI_MS_DNS1:
1857 case CI_MS_DNS2:
1858 p += 2;
1859 GETNLONG(cilong, p);
1860 printer(arg, "ms-dns%d %I", (code == CI_MS_DNS1 ? 1 : 2),
1861 cilong);
1862 break;
1863 case CI_MS_WINS1:
1864 case CI_MS_WINS2:
1865 p += 2;
1866 GETNLONG(cilong, p);
1867 printer(arg, "ms-wins%d %I", (code == CI_MS_WINS1 ? 1 : 2),
1868 cilong);
1869 break;
1870 case CI_SUBNET:
1871 p += 2;
1872 GETNLONG(cilong, p);
1873 printer(arg, "subnet %I", cilong);
1874 break;
1875 }
1876 while (p < optend) {
1877 GETCHAR(code, p);
1878 printer(arg, " %.2x", code);
1879 }
1880 printer(arg, ">");
1881 }
1882 break;
1883
1884 case CODE_TERMACK:
1885 case CODE_TERMREQ:
1886 if (len > 0 && *p >= ' ' && *p < 0x7f) {
1887 printer(arg, " ");
1888 print_string((char *)p, len, printer, arg);
1889 p += len;
1890 len = 0;
1891 }
1892 break;
1893 }
1894
1895 /* print the rest of the bytes in the packet */
1896 for (; len > 0; --len) {
1897 GETCHAR(code, p);
1898 printer(arg, " %.2x", code);
1899 }
1900
1901 return p - pstart;
1902 }
1903
1904 char *
tcp_flag_decode(val)1905 tcp_flag_decode(val)
1906 int val;
1907 {
1908 static char buf[32];
1909 char *cp = buf;
1910
1911 if (val & TH_URG)
1912 *cp++ = 'U';
1913 if (val & TH_ACK)
1914 *cp++ = 'A';
1915 if (val & TH_PUSH)
1916 *cp++ = 'P';
1917 if (val & TH_RST)
1918 *cp++ = 'R';
1919 if (val & TH_SYN)
1920 *cp++ = 'S';
1921 if (val & TH_FIN)
1922 *cp++ = 'F';
1923 if (cp != buf)
1924 *cp++ = ' ';
1925 *cp = '\0';
1926 return buf;
1927 }
1928
1929 /*
1930 * ip_active_pkt - see if this IP packet is worth bringing the link up for.
1931 * We don't bring the link up for IP fragments or for TCP FIN packets
1932 * with no data.
1933 */
1934
1935 static int
ip_active_pkt(pkt,len)1936 ip_active_pkt(pkt, len)
1937 u_char *pkt;
1938 int len;
1939 {
1940 u_char *tcp;
1941 struct protoent *pep;
1942 int val;
1943 int hlen;
1944 char buf[32], *cp;
1945 u_int32_t src, dst;
1946
1947 len -= PPP_HDRLEN;
1948 pkt += PPP_HDRLEN;
1949 if (len < IP_HDRLEN) {
1950 dbglog("IP packet of length %d is not activity", len);
1951 return 0;
1952 }
1953 src = get_ipsrc(pkt);
1954 dst = get_ipdst(pkt);
1955 if ((get_ipoff(pkt) & IP_OFFMASK) != 0) {
1956 dbglog("IP fragment from %I->%I is not activity", src, dst);
1957 return 0;
1958 }
1959 val = get_ipproto(pkt);
1960 if (val != IPPROTO_TCP) {
1961 if (debug) {
1962 if ((pep = getprotobynumber(val)) != NULL) {
1963 cp = pep->p_name;
1964 } else {
1965 (void) slprintf(buf, sizeof (buf), "IP proto %d", val);
1966 cp = buf;
1967 }
1968 info("%s from %I->%I is activity", cp, src, dst);
1969 }
1970 return 1;
1971 }
1972 hlen = get_iphl(pkt) * 4;
1973 if (len < hlen + TCP_HDRLEN) {
1974 dbglog("Bad TCP length %d<%d+%d %I->%I is not activity", len, hlen,
1975 TCP_HDRLEN, src, dst);
1976 return 0;
1977 }
1978 tcp = pkt + hlen;
1979 val = get_tcpflags(tcp);
1980 hlen += get_tcpoff(tcp) * 4;
1981 if ((val & TH_FIN) != 0 && len == hlen) {
1982 dbglog("Empty TCP FIN %I->%I is not activity", src, dst);
1983 return 0;
1984 }
1985 info("TCP %d data %s%I->%I is activity", len - hlen,
1986 tcp_flag_decode(get_tcpflags(tcp)), src, dst);
1987 return 1;
1988 }
1989
1990 static void
ipcp_print_stat(unit,strptr)1991 ipcp_print_stat(unit, strptr)
1992 int unit;
1993 FILE *strptr;
1994 {
1995 ipcp_options *go = &ipcp_gotoptions[unit];
1996 ipcp_options *ho = &ipcp_hisoptions[unit];
1997 char *proto_name = ipcp_protent.name;
1998
1999 if (!ipcp_protent.enabled_flag) {
2000 (void) flprintf(strptr, "%s disabled\n", proto_name);
2001 return;
2002 }
2003
2004 (void) flprintf(strptr, "%s state: %s", proto_name,
2005 fsm_state(ipcp_fsm[unit].state));
2006 (void) flprintf(strptr, "%s local %I remote %I", proto_name, go->ouraddr,
2007 ho->ouraddr);
2008 }
2009