xref: /freebsd/usr.sbin/ppp/ipcp.c (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
1 /*
2  *	PPP IP Control Protocol (IPCP) Module
3  *
4  *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
5  *
6  *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
7  *
8  * Redistribution and use in source and binary forms are permitted
9  * provided that the above copyright notice and this paragraph are
10  * duplicated in all such forms and that any documentation,
11  * advertising materials, and other materials related to such
12  * distribution and use acknowledge that the software was developed
13  * by the Internet Initiative Japan, Inc.  The name of the
14  * IIJ may not be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * $FreeBSD$
21  *
22  *	TODO:
23  *		o Support IPADDRS properly
24  *		o Validate the length in IpcpDecodeConfig
25  */
26 #include <sys/param.h>
27 #include <netinet/in_systm.h>
28 #include <netinet/in.h>
29 #include <netinet/ip.h>
30 #include <arpa/inet.h>
31 #include <sys/socket.h>
32 #include <net/route.h>
33 #include <netdb.h>
34 #include <sys/un.h>
35 
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <resolv.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <termios.h>
42 #include <unistd.h>
43 
44 #ifndef NONAT
45 #ifdef __FreeBSD__
46 #include <alias.h>
47 #else
48 #include "alias.h"
49 #endif
50 #endif
51 #include "layer.h"
52 #include "ua.h"
53 #include "defs.h"
54 #include "command.h"
55 #include "mbuf.h"
56 #include "log.h"
57 #include "timer.h"
58 #include "fsm.h"
59 #include "proto.h"
60 #include "lcp.h"
61 #include "iplist.h"
62 #include "throughput.h"
63 #include "slcompress.h"
64 #include "lqr.h"
65 #include "hdlc.h"
66 #include "ipcp.h"
67 #include "filter.h"
68 #include "descriptor.h"
69 #include "vjcomp.h"
70 #include "async.h"
71 #include "ccp.h"
72 #include "link.h"
73 #include "physical.h"
74 #include "mp.h"
75 #ifndef NORADIUS
76 #include "radius.h"
77 #endif
78 #include "bundle.h"
79 #include "id.h"
80 #include "arp.h"
81 #include "systems.h"
82 #include "prompt.h"
83 #include "route.h"
84 #include "iface.h"
85 #include "ip.h"
86 
87 #undef REJECTED
88 #define	REJECTED(p, x)	((p)->peer_reject & (1<<(x)))
89 #define issep(ch) ((ch) == ' ' || (ch) == '\t')
90 #define isip(ch) (((ch) >= '0' && (ch) <= '9') || (ch) == '.')
91 
92 static u_short default_urgent_tcp_ports[] = {
93   21,	/* ftp */
94   22,	/* ssh */
95   23,	/* telnet */
96   513,	/* login */
97   514,	/* shell */
98   543,	/* klogin */
99   544	/* kshell */
100 };
101 
102 static u_short default_urgent_udp_ports[] = { };
103 
104 #define NDEFTCPPORTS \
105   (sizeof default_urgent_tcp_ports / sizeof default_urgent_tcp_ports[0])
106 #define NDEFUDPPORTS \
107   (sizeof default_urgent_udp_ports / sizeof default_urgent_udp_ports[0])
108 
109 int
110 ipcp_IsUrgentPort(struct port_range *range, u_short src, u_short dst)
111 {
112   int f;
113 
114   for (f = 0; f < range->nports; f++)
115     if (range->port[f] == src || range->port[f] == dst)
116       return 1;
117 
118   return 0;
119 }
120 
121 void
122 ipcp_AddUrgentPort(struct port_range *range, u_short port)
123 {
124   u_short *newport;
125   int p;
126 
127   if (range->nports == range->maxports) {
128     range->maxports += 10;
129     newport = (u_short *)realloc(range->port,
130                                  range->maxports * sizeof(u_short));
131     if (newport == NULL) {
132       log_Printf(LogERROR, "ipcp_AddUrgentPort: realloc: %s\n",
133                  strerror(errno));
134       range->maxports -= 10;
135       return;
136     }
137     range->port = newport;
138   }
139 
140   for (p = 0; p < range->nports; p++)
141     if (range->port[p] == port) {
142       log_Printf(LogWARN, "%u: Port already set to urgent\n", port);
143       break;
144     } else if (range->port[p] > port) {
145       memmove(range->port + p + 1, range->port + p,
146               (range->nports - p) * sizeof(u_short));
147       range->port[p] = port;
148       range->nports++;
149       break;
150     }
151 
152   if (p == range->nports)
153     range->port[range->nports++] = port;
154 }
155 
156 void
157 ipcp_RemoveUrgentPort(struct port_range *range, u_short port)
158 {
159   int p;
160 
161   for (p = 0; p < range->nports; p++)
162     if (range->port[p] == port) {
163       if (p != range->nports - 1)
164         memmove(range->port + p, range->port + p + 1,
165                 (range->nports - p - 1) * sizeof(u_short));
166       range->nports--;
167       return;
168     }
169 
170   if (p == range->nports)
171     log_Printf(LogWARN, "%u: Port not set to urgent\n", port);
172 }
173 
174 void
175 ipcp_ClearUrgentPorts(struct port_range *range)
176 {
177   range->nports = 0;
178 }
179 
180 struct compreq {
181   u_short proto;
182   u_char slots;
183   u_char compcid;
184 };
185 
186 static int IpcpLayerUp(struct fsm *);
187 static void IpcpLayerDown(struct fsm *);
188 static void IpcpLayerStart(struct fsm *);
189 static void IpcpLayerFinish(struct fsm *);
190 static void IpcpInitRestartCounter(struct fsm *, int);
191 static void IpcpSendConfigReq(struct fsm *);
192 static void IpcpSentTerminateReq(struct fsm *);
193 static void IpcpSendTerminateAck(struct fsm *, u_char);
194 static void IpcpDecodeConfig(struct fsm *, u_char *, int, int,
195                              struct fsm_decode *);
196 
197 static struct fsm_callbacks ipcp_Callbacks = {
198   IpcpLayerUp,
199   IpcpLayerDown,
200   IpcpLayerStart,
201   IpcpLayerFinish,
202   IpcpInitRestartCounter,
203   IpcpSendConfigReq,
204   IpcpSentTerminateReq,
205   IpcpSendTerminateAck,
206   IpcpDecodeConfig,
207   fsm_NullRecvResetReq,
208   fsm_NullRecvResetAck
209 };
210 
211 static const char * const cftypes[] = {
212   /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */
213   "???",
214   "IPADDRS",	/* 1: IP-Addresses */	/* deprecated */
215   "COMPPROTO",	/* 2: IP-Compression-Protocol */
216   "IPADDR",	/* 3: IP-Address */
217 };
218 
219 #define NCFTYPES (sizeof cftypes/sizeof cftypes[0])
220 
221 static const char * const cftypes128[] = {
222   /* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */
223   "???",
224   "PRIDNS",	/* 129: Primary DNS Server Address */
225   "PRINBNS",	/* 130: Primary NBNS Server Address */
226   "SECDNS",	/* 131: Secondary DNS Server Address */
227   "SECNBNS",	/* 132: Secondary NBNS Server Address */
228 };
229 
230 #define NCFTYPES128 (sizeof cftypes128/sizeof cftypes128[0])
231 
232 void
233 ipcp_AddInOctets(struct ipcp *ipcp, int n)
234 {
235   throughput_addin(&ipcp->throughput, n);
236 }
237 
238 void
239 ipcp_AddOutOctets(struct ipcp *ipcp, int n)
240 {
241   throughput_addout(&ipcp->throughput, n);
242 }
243 
244 static void
245 getdns(struct ipcp *ipcp, struct in_addr addr[2])
246 {
247   FILE *fp;
248 
249   addr[0].s_addr = addr[1].s_addr = INADDR_ANY;
250   if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
251     char buf[LINE_LEN], *cp, *end;
252     int n;
253 
254     n = 0;
255     buf[sizeof buf - 1] = '\0';
256     while (fgets(buf, sizeof buf - 1, fp)) {
257       if (!strncmp(buf, "nameserver", 10) && issep(buf[10])) {
258         for (cp = buf + 11; issep(*cp); cp++)
259           ;
260         for (end = cp; isip(*end); end++)
261           ;
262         *end = '\0';
263         if (inet_aton(cp, addr+n) && ++n == 2)
264           break;
265       }
266     }
267     if (n == 1)
268       addr[1] = addr[0];
269     fclose(fp);
270   }
271 }
272 
273 static int
274 setdns(struct ipcp *ipcp, struct in_addr addr[2])
275 {
276   FILE *fp;
277   char wbuf[LINE_LEN + 54];
278   int wlen;
279 
280   if (addr[0].s_addr == INADDR_ANY || addr[1].s_addr == INADDR_ANY) {
281     struct in_addr old[2];
282 
283     getdns(ipcp, old);
284     if (addr[0].s_addr == INADDR_ANY)
285       addr[0] = old[0];
286     if (addr[1].s_addr == INADDR_ANY)
287       addr[1] = old[1];
288   }
289 
290   if (addr[0].s_addr == INADDR_ANY && addr[1].s_addr == INADDR_ANY) {
291     log_Printf(LogWARN, "%s not modified: All nameservers NAKd\n",
292               _PATH_RESCONF);
293     return 0;
294   }
295 
296   wlen = 0;
297   if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
298     char buf[LINE_LEN];
299     int len;
300 
301     buf[sizeof buf - 1] = '\0';
302     while (fgets(buf, sizeof buf - 1, fp)) {
303       if (strncmp(buf, "nameserver", 10) || !issep(buf[10])) {
304         len = strlen(buf);
305         if (len > sizeof wbuf - wlen) {
306           log_Printf(LogWARN, "%s: Can only cope with max file size %d\n",
307                     _PATH_RESCONF, LINE_LEN);
308           fclose(fp);
309           return 0;
310         }
311         memcpy(wbuf + wlen, buf, len);
312         wlen += len;
313       }
314     }
315     fclose(fp);
316   }
317 
318   if (addr[0].s_addr != INADDR_ANY) {
319     snprintf(wbuf + wlen, sizeof wbuf - wlen, "nameserver %s\n",
320              inet_ntoa(addr[0]));
321     log_Printf(LogIPCP, "Primary nameserver set to %s", wbuf + wlen + 11);
322     wlen += strlen(wbuf + wlen);
323   }
324 
325   if (addr[1].s_addr != INADDR_ANY && addr[1].s_addr != addr[0].s_addr) {
326     snprintf(wbuf + wlen, sizeof wbuf - wlen, "nameserver %s\n",
327              inet_ntoa(addr[1]));
328     log_Printf(LogIPCP, "Secondary nameserver set to %s", wbuf + wlen + 11);
329     wlen += strlen(wbuf + wlen);
330   }
331 
332   if (wlen) {
333     int fd;
334 
335     if ((fd = ID0open(_PATH_RESCONF, O_WRONLY|O_CREAT, 0644)) != -1) {
336       if (write(fd, wbuf, wlen) != wlen) {
337         log_Printf(LogERROR, "setdns: write(): %s\n", strerror(errno));
338         close(fd);
339         return 0;
340       }
341       if (ftruncate(fd, wlen) == -1) {
342         log_Printf(LogERROR, "setdns: truncate(): %s\n", strerror(errno));
343         close(fd);
344         return 0;
345       }
346       close(fd);
347     } else {
348       log_Printf(LogERROR, "setdns: open(): %s\n", strerror(errno));
349       return 0;
350     }
351   }
352 
353   return 1;
354 }
355 
356 int
357 ipcp_Show(struct cmdargs const *arg)
358 {
359   struct ipcp *ipcp = &arg->bundle->ncp.ipcp;
360   int p;
361 
362   prompt_Printf(arg->prompt, "%s [%s]\n", ipcp->fsm.name,
363                 State2Nam(ipcp->fsm.state));
364   if (ipcp->fsm.state == ST_OPENED) {
365     prompt_Printf(arg->prompt, " His side:        %s, %s\n",
366 	          inet_ntoa(ipcp->peer_ip), vj2asc(ipcp->peer_compproto));
367     prompt_Printf(arg->prompt, " My side:         %s, %s\n",
368 	          inet_ntoa(ipcp->my_ip), vj2asc(ipcp->my_compproto));
369     prompt_Printf(arg->prompt, " Queued packets:  %d\n", ip_QueueLen(ipcp));
370   }
371 
372   if (ipcp->route) {
373     prompt_Printf(arg->prompt, "\n");
374     route_ShowSticky(arg->prompt, ipcp->route, "Sticky routes", 1);
375   }
376 
377   prompt_Printf(arg->prompt, "\nDefaults:\n");
378   prompt_Printf(arg->prompt, " FSM retry = %us, max %u Config"
379                 " REQ%s, %u Term REQ%s\n", ipcp->cfg.fsm.timeout,
380                 ipcp->cfg.fsm.maxreq, ipcp->cfg.fsm.maxreq == 1 ? "" : "s",
381                 ipcp->cfg.fsm.maxtrm, ipcp->cfg.fsm.maxtrm == 1 ? "" : "s");
382   prompt_Printf(arg->prompt, " My Address:      %s/%d",
383 	        inet_ntoa(ipcp->cfg.my_range.ipaddr), ipcp->cfg.my_range.width);
384   prompt_Printf(arg->prompt, ", netmask %s\n", inet_ntoa(ipcp->cfg.netmask));
385   if (ipcp->cfg.HaveTriggerAddress)
386     prompt_Printf(arg->prompt, " Trigger address: %s\n",
387                   inet_ntoa(ipcp->cfg.TriggerAddress));
388 
389   prompt_Printf(arg->prompt, " VJ compression:  %s (%d slots %s slot "
390                 "compression)\n", command_ShowNegval(ipcp->cfg.vj.neg),
391                 ipcp->cfg.vj.slots, ipcp->cfg.vj.slotcomp ? "with" : "without");
392 
393   if (iplist_isvalid(&ipcp->cfg.peer_list))
394     prompt_Printf(arg->prompt, " His Address:     %s\n",
395                   ipcp->cfg.peer_list.src);
396   else
397     prompt_Printf(arg->prompt, " His Address:     %s/%d\n",
398 	          inet_ntoa(ipcp->cfg.peer_range.ipaddr),
399                   ipcp->cfg.peer_range.width);
400 
401   prompt_Printf(arg->prompt, " DNS:             %s, ",
402                 inet_ntoa(ipcp->cfg.ns.dns[0]));
403   prompt_Printf(arg->prompt, "%s, %s\n", inet_ntoa(ipcp->cfg.ns.dns[1]),
404                 command_ShowNegval(ipcp->cfg.ns.dns_neg));
405   prompt_Printf(arg->prompt, " NetBIOS NS:      %s, ",
406 	        inet_ntoa(ipcp->cfg.ns.nbns[0]));
407   prompt_Printf(arg->prompt, "%s\n", inet_ntoa(ipcp->cfg.ns.nbns[1]));
408 
409   prompt_Printf(arg->prompt, " Urgent ports\n");
410   prompt_Printf(arg->prompt, "          TCP:    ");
411   if (ipcp->cfg.urgent.tcp.nports == 0)
412     prompt_Printf(arg->prompt, "none");
413   else
414     for (p = 0; p < ipcp->cfg.urgent.tcp.nports; p++) {
415       if (p)
416         prompt_Printf(arg->prompt, ", ");
417       prompt_Printf(arg->prompt, "%u", ipcp->cfg.urgent.tcp.port[p]);
418     }
419   prompt_Printf(arg->prompt, "\n          UDP:    ");
420   if (ipcp->cfg.urgent.udp.nports == 0)
421     prompt_Printf(arg->prompt, "none");
422   else
423     for (p = 0; p < ipcp->cfg.urgent.udp.nports; p++) {
424       if (p)
425         prompt_Printf(arg->prompt, ", ");
426       prompt_Printf(arg->prompt, "%u", ipcp->cfg.urgent.udp.port[p]);
427     }
428 
429   prompt_Printf(arg->prompt, "\n\n");
430   throughput_disp(&ipcp->throughput, arg->prompt);
431 
432   return 0;
433 }
434 
435 int
436 ipcp_vjset(struct cmdargs const *arg)
437 {
438   if (arg->argc != arg->argn+2)
439     return -1;
440   if (!strcasecmp(arg->argv[arg->argn], "slots")) {
441     int slots;
442 
443     slots = atoi(arg->argv[arg->argn+1]);
444     if (slots < 4 || slots > 16)
445       return 1;
446     arg->bundle->ncp.ipcp.cfg.vj.slots = slots;
447     return 0;
448   } else if (!strcasecmp(arg->argv[arg->argn], "slotcomp")) {
449     if (!strcasecmp(arg->argv[arg->argn+1], "on"))
450       arg->bundle->ncp.ipcp.cfg.vj.slotcomp = 1;
451     else if (!strcasecmp(arg->argv[arg->argn+1], "off"))
452       arg->bundle->ncp.ipcp.cfg.vj.slotcomp = 0;
453     else
454       return 2;
455     return 0;
456   }
457   return -1;
458 }
459 
460 void
461 ipcp_Init(struct ipcp *ipcp, struct bundle *bundle, struct link *l,
462           const struct fsm_parent *parent)
463 {
464   struct hostent *hp;
465   char name[MAXHOSTNAMELEN];
466   static const char * const timer_names[] =
467     {"IPCP restart", "IPCP openmode", "IPCP stopped"};
468 
469   fsm_Init(&ipcp->fsm, "IPCP", PROTO_IPCP, 1, IPCP_MAXCODE, LogIPCP,
470            bundle, l, parent, &ipcp_Callbacks, timer_names);
471 
472   ipcp->route = NULL;
473   ipcp->cfg.vj.slots = DEF_VJ_STATES;
474   ipcp->cfg.vj.slotcomp = 1;
475   memset(&ipcp->cfg.my_range, '\0', sizeof ipcp->cfg.my_range);
476   if (gethostname(name, sizeof name) == 0) {
477     hp = gethostbyname(name);
478     if (hp && hp->h_addrtype == AF_INET)
479       memcpy(&ipcp->cfg.my_range.ipaddr.s_addr, hp->h_addr, hp->h_length);
480   }
481   ipcp->cfg.netmask.s_addr = INADDR_ANY;
482   memset(&ipcp->cfg.peer_range, '\0', sizeof ipcp->cfg.peer_range);
483   iplist_setsrc(&ipcp->cfg.peer_list, "");
484   ipcp->cfg.HaveTriggerAddress = 0;
485 
486   ipcp->cfg.ns.dns[0].s_addr = INADDR_ANY;
487   ipcp->cfg.ns.dns[1].s_addr = INADDR_ANY;
488   ipcp->cfg.ns.dns_neg = 0;
489   ipcp->cfg.ns.nbns[0].s_addr = INADDR_ANY;
490   ipcp->cfg.ns.nbns[1].s_addr = INADDR_ANY;
491 
492   ipcp->cfg.urgent.tcp.nports = ipcp->cfg.urgent.tcp.maxports = NDEFTCPPORTS;
493   ipcp->cfg.urgent.tcp.port = (u_short *)malloc(NDEFTCPPORTS * sizeof(u_short));
494   memcpy(ipcp->cfg.urgent.tcp.port, default_urgent_tcp_ports,
495          NDEFTCPPORTS * sizeof(u_short));
496 
497   ipcp->cfg.urgent.udp.nports = ipcp->cfg.urgent.udp.maxports = NDEFUDPPORTS;
498   ipcp->cfg.urgent.udp.port = (u_short *)malloc(NDEFUDPPORTS * sizeof(u_short));
499   memcpy(ipcp->cfg.urgent.udp.port, default_urgent_udp_ports,
500          NDEFUDPPORTS * sizeof(u_short));
501 
502   ipcp->cfg.fsm.timeout = DEF_FSMRETRY;
503   ipcp->cfg.fsm.maxreq = DEF_FSMTRIES;
504   ipcp->cfg.fsm.maxtrm = DEF_FSMTRIES;
505   ipcp->cfg.vj.neg = NEG_ENABLED|NEG_ACCEPTED;
506 
507   memset(&ipcp->vj, '\0', sizeof ipcp->vj);
508 
509   throughput_init(&ipcp->throughput, SAMPLE_PERIOD);
510   memset(ipcp->Queue, '\0', sizeof ipcp->Queue);
511   ipcp_Setup(ipcp, INADDR_NONE);
512 }
513 
514 void
515 ipcp_Destroy(struct ipcp *ipcp)
516 {
517   if (ipcp->cfg.urgent.tcp.maxports) {
518     ipcp->cfg.urgent.tcp.nports = ipcp->cfg.urgent.tcp.maxports = 0;
519     free(ipcp->cfg.urgent.tcp.port);
520     ipcp->cfg.urgent.tcp.port = NULL;
521   }
522   if (ipcp->cfg.urgent.udp.maxports) {
523     ipcp->cfg.urgent.udp.nports = ipcp->cfg.urgent.udp.maxports = 0;
524     free(ipcp->cfg.urgent.udp.port);
525     ipcp->cfg.urgent.udp.port = NULL;
526   }
527 }
528 
529 void
530 ipcp_SetLink(struct ipcp *ipcp, struct link *l)
531 {
532   ipcp->fsm.link = l;
533 }
534 
535 void
536 ipcp_Setup(struct ipcp *ipcp, u_int32_t mask)
537 {
538   struct iface *iface = ipcp->fsm.bundle->iface;
539   int pos, n;
540 
541   ipcp->fsm.open_mode = 0;
542   ipcp->ifmask.s_addr = mask == INADDR_NONE ? ipcp->cfg.netmask.s_addr : mask;
543 
544   if (iplist_isvalid(&ipcp->cfg.peer_list)) {
545     /* Try to give the peer a previously configured IP address */
546     for (n = 0; n < iface->in_addrs; n++) {
547       pos = iplist_ip2pos(&ipcp->cfg.peer_list, iface->in_addr[n].brd);
548       if (pos != -1) {
549         ipcp->cfg.peer_range.ipaddr =
550           iplist_setcurpos(&ipcp->cfg.peer_list, pos);
551         break;
552       }
553     }
554     if (n == iface->in_addrs)
555       /* Ok, so none of 'em fit.... pick a random one */
556       ipcp->cfg.peer_range.ipaddr = iplist_setrandpos(&ipcp->cfg.peer_list);
557 
558     ipcp->cfg.peer_range.mask.s_addr = INADDR_BROADCAST;
559     ipcp->cfg.peer_range.width = 32;
560   }
561 
562   ipcp->heis1172 = 0;
563 
564   ipcp->peer_ip = ipcp->cfg.peer_range.ipaddr;
565   ipcp->peer_compproto = 0;
566 
567   if (ipcp->cfg.HaveTriggerAddress) {
568     /*
569      * Some implementations of PPP require that we send a
570      * *special* value as our address, even though the rfc specifies
571      * full negotiation (e.g. "0.0.0.0" or Not "0.0.0.0").
572      */
573     ipcp->my_ip = ipcp->cfg.TriggerAddress;
574     log_Printf(LogIPCP, "Using trigger address %s\n",
575               inet_ntoa(ipcp->cfg.TriggerAddress));
576   } else {
577     /*
578      * Otherwise, if we've used an IP number before and it's still within
579      * the network specified on the ``set ifaddr'' line, we really
580      * want to keep that IP number so that we can keep any existing
581      * connections that are bound to that IP (assuming we're not
582      * ``iface-alias''ing).
583      */
584     for (n = 0; n < iface->in_addrs; n++)
585       if ((iface->in_addr[n].ifa.s_addr & ipcp->cfg.my_range.mask.s_addr) ==
586           (ipcp->cfg.my_range.ipaddr.s_addr & ipcp->cfg.my_range.mask.s_addr)) {
587         ipcp->my_ip = iface->in_addr[n].ifa;
588         break;
589       }
590     if (n == iface->in_addrs)
591       ipcp->my_ip = ipcp->cfg.my_range.ipaddr;
592   }
593 
594   if (IsEnabled(ipcp->cfg.vj.neg)
595 #ifndef NORADIUS
596       || (ipcp->fsm.bundle->radius.valid && ipcp->fsm.bundle->radius.vj)
597 #endif
598      )
599     ipcp->my_compproto = (PROTO_VJCOMP << 16) +
600                          ((ipcp->cfg.vj.slots - 1) << 8) +
601                          ipcp->cfg.vj.slotcomp;
602   else
603     ipcp->my_compproto = 0;
604   sl_compress_init(&ipcp->vj.cslc, ipcp->cfg.vj.slots - 1);
605 
606   ipcp->peer_reject = 0;
607   ipcp->my_reject = 0;
608 }
609 
610 static int
611 ipcp_doproxyall(struct bundle *bundle,
612                 int (*proxyfun)(struct bundle *, struct in_addr, int), int s)
613 {
614   int n, ret;
615   struct sticky_route *rp;
616   struct in_addr addr;
617   struct ipcp *ipcp;
618 
619   ipcp = &bundle->ncp.ipcp;
620   for (rp = ipcp->route; rp != NULL; rp = rp->next) {
621     if (rp->mask.s_addr == INADDR_BROADCAST)
622         continue;
623     n = ntohl(INADDR_BROADCAST) - ntohl(rp->mask.s_addr) - 1;
624     if (n > 0 && n <= 254 && rp->dst.s_addr != INADDR_ANY) {
625       addr = rp->dst;
626       while (n--) {
627         addr.s_addr = htonl(ntohl(addr.s_addr) + 1);
628 	log_Printf(LogDEBUG, "ipcp_doproxyall: %s\n", inet_ntoa(addr));
629 	ret = (*proxyfun)(bundle, addr, s);
630 	if (!ret)
631 	  return ret;
632       }
633     }
634   }
635 
636   return 0;
637 }
638 
639 static int
640 ipcp_SetIPaddress(struct bundle *bundle, struct in_addr myaddr,
641                   struct in_addr hisaddr, int silent)
642 {
643   struct in_addr mask, oaddr, none = { INADDR_ANY };
644 
645   mask = addr2mask(myaddr);
646 
647   if (bundle->ncp.ipcp.ifmask.s_addr != INADDR_ANY &&
648       (bundle->ncp.ipcp.ifmask.s_addr & mask.s_addr) == mask.s_addr)
649     mask.s_addr = bundle->ncp.ipcp.ifmask.s_addr;
650 
651   oaddr.s_addr = bundle->iface->in_addrs ?
652                  bundle->iface->in_addr[0].ifa.s_addr : INADDR_ANY;
653   if (!iface_inAdd(bundle->iface, myaddr, mask, hisaddr,
654                  IFACE_ADD_FIRST|IFACE_FORCE_ADD))
655     return -1;
656 
657   if (!Enabled(bundle, OPT_IFACEALIAS) && bundle->iface->in_addrs > 1
658       && myaddr.s_addr != oaddr.s_addr)
659     /* Nuke the old one */
660     iface_inDelete(bundle->iface, oaddr);
661 
662   if (bundle->ncp.ipcp.cfg.sendpipe > 0 || bundle->ncp.ipcp.cfg.recvpipe > 0)
663     bundle_SetRoute(bundle, RTM_CHANGE, hisaddr, myaddr, none, 0, 0);
664 
665   if (Enabled(bundle, OPT_SROUTES))
666     route_Change(bundle, bundle->ncp.ipcp.route, myaddr, hisaddr);
667 
668 #ifndef NORADIUS
669   if (bundle->radius.valid)
670     route_Change(bundle, bundle->radius.routes, myaddr, hisaddr);
671 #endif
672 
673   if (Enabled(bundle, OPT_PROXY) || Enabled(bundle, OPT_PROXYALL)) {
674     int s = ID0socket(AF_INET, SOCK_DGRAM, 0);
675     if (s < 0)
676       log_Printf(LogERROR, "ipcp_SetIPaddress: socket(): %s\n",
677                  strerror(errno));
678     else {
679       if (Enabled(bundle, OPT_PROXYALL))
680         ipcp_doproxyall(bundle, arp_SetProxy, s);
681       else if (Enabled(bundle, OPT_PROXY))
682         arp_SetProxy(bundle, hisaddr, s);
683       close(s);
684     }
685   }
686 
687   return 0;
688 }
689 
690 static struct in_addr
691 ChooseHisAddr(struct bundle *bundle, struct in_addr gw)
692 {
693   struct in_addr try;
694   u_long f;
695 
696   for (f = 0; f < bundle->ncp.ipcp.cfg.peer_list.nItems; f++) {
697     try = iplist_next(&bundle->ncp.ipcp.cfg.peer_list);
698     log_Printf(LogDEBUG, "ChooseHisAddr: Check item %ld (%s)\n",
699               f, inet_ntoa(try));
700     if (ipcp_SetIPaddress(bundle, gw, try, 1) == 0) {
701       log_Printf(LogIPCP, "Selected IP address %s\n", inet_ntoa(try));
702       break;
703     }
704   }
705 
706   if (f == bundle->ncp.ipcp.cfg.peer_list.nItems) {
707     log_Printf(LogDEBUG, "ChooseHisAddr: All addresses in use !\n");
708     try.s_addr = INADDR_ANY;
709   }
710 
711   return try;
712 }
713 
714 static void
715 IpcpInitRestartCounter(struct fsm *fp, int what)
716 {
717   /* Set fsm timer load */
718   struct ipcp *ipcp = fsm2ipcp(fp);
719 
720   fp->FsmTimer.load = ipcp->cfg.fsm.timeout * SECTICKS;
721   switch (what) {
722     case FSM_REQ_TIMER:
723       fp->restart = ipcp->cfg.fsm.maxreq;
724       break;
725     case FSM_TRM_TIMER:
726       fp->restart = ipcp->cfg.fsm.maxtrm;
727       break;
728     default:
729       fp->restart = 1;
730       break;
731   }
732 }
733 
734 static void
735 IpcpSendConfigReq(struct fsm *fp)
736 {
737   /* Send config REQ please */
738   struct physical *p = link2physical(fp->link);
739   struct ipcp *ipcp = fsm2ipcp(fp);
740   u_char buff[24];
741   struct lcp_opt *o;
742 
743   o = (struct lcp_opt *)buff;
744 
745   if ((p && !physical_IsSync(p)) || !REJECTED(ipcp, TY_IPADDR)) {
746     memcpy(o->data, &ipcp->my_ip.s_addr, 4);
747     INC_LCP_OPT(TY_IPADDR, 6, o);
748   }
749 
750   if (ipcp->my_compproto && !REJECTED(ipcp, TY_COMPPROTO)) {
751     if (ipcp->heis1172) {
752       u_int16_t proto = PROTO_VJCOMP;
753 
754       ua_htons(&proto, o->data);
755       INC_LCP_OPT(TY_COMPPROTO, 4, o);
756     } else {
757       struct compreq req;
758 
759       req.proto = htons(ipcp->my_compproto >> 16);
760       req.slots = (ipcp->my_compproto >> 8) & 255;
761       req.compcid = ipcp->my_compproto & 1;
762       memcpy(o->data, &req, 4);
763       INC_LCP_OPT(TY_COMPPROTO, 6, o);
764     }
765   }
766 
767   if (IsEnabled(ipcp->cfg.ns.dns_neg) &&
768       !REJECTED(ipcp, TY_PRIMARY_DNS - TY_ADJUST_NS) &&
769       !REJECTED(ipcp, TY_SECONDARY_DNS - TY_ADJUST_NS)) {
770     struct in_addr dns[2];
771     getdns(ipcp, dns);
772     memcpy(o->data, &dns[0].s_addr, 4);
773     INC_LCP_OPT(TY_PRIMARY_DNS, 6, o);
774     memcpy(o->data, &dns[1].s_addr, 4);
775     INC_LCP_OPT(TY_SECONDARY_DNS, 6, o);
776   }
777 
778   fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, (u_char *)o - buff,
779              MB_IPCPOUT);
780 }
781 
782 static void
783 IpcpSentTerminateReq(struct fsm *fp)
784 {
785   /* Term REQ just sent by FSM */
786 }
787 
788 static void
789 IpcpSendTerminateAck(struct fsm *fp, u_char id)
790 {
791   /* Send Term ACK please */
792   fsm_Output(fp, CODE_TERMACK, id, NULL, 0, MB_IPCPOUT);
793 }
794 
795 static void
796 IpcpLayerStart(struct fsm *fp)
797 {
798   /* We're about to start up ! */
799   struct ipcp *ipcp = fsm2ipcp(fp);
800 
801   log_Printf(LogIPCP, "%s: LayerStart.\n", fp->link->name);
802   throughput_start(&ipcp->throughput, "IPCP throughput",
803                    Enabled(fp->bundle, OPT_THROUGHPUT));
804   fp->more.reqs = fp->more.naks = fp->more.rejs = ipcp->cfg.fsm.maxreq * 3;
805 }
806 
807 static void
808 IpcpLayerFinish(struct fsm *fp)
809 {
810   /* We're now down */
811   struct ipcp *ipcp = fsm2ipcp(fp);
812 
813   log_Printf(LogIPCP, "%s: LayerFinish.\n", fp->link->name);
814   throughput_stop(&ipcp->throughput);
815   throughput_log(&ipcp->throughput, LogIPCP, NULL);
816 }
817 
818 void
819 ipcp_CleanInterface(struct ipcp *ipcp)
820 {
821   struct iface *iface = ipcp->fsm.bundle->iface;
822 
823   route_Clean(ipcp->fsm.bundle, ipcp->route);
824 
825   if (iface->in_addrs && (Enabled(ipcp->fsm.bundle, OPT_PROXY) ||
826                           Enabled(ipcp->fsm.bundle, OPT_PROXYALL))) {
827     int s = ID0socket(AF_INET, SOCK_DGRAM, 0);
828     if (s < 0)
829       log_Printf(LogERROR, "ipcp_CleanInterface: socket: %s\n",
830                  strerror(errno));
831     else {
832       if (Enabled(ipcp->fsm.bundle, OPT_PROXYALL))
833         ipcp_doproxyall(ipcp->fsm.bundle, arp_ClearProxy, s);
834       else if (Enabled(ipcp->fsm.bundle, OPT_PROXY))
835         arp_ClearProxy(ipcp->fsm.bundle, iface->in_addr[0].brd, s);
836       close(s);
837     }
838   }
839 
840   iface_inClear(ipcp->fsm.bundle->iface, IFACE_CLEAR_ALL);
841 }
842 
843 static void
844 IpcpLayerDown(struct fsm *fp)
845 {
846   /* About to come down */
847   static int recursing;
848   struct ipcp *ipcp = fsm2ipcp(fp);
849   const char *s;
850 
851   if (!recursing++) {
852     if (ipcp->fsm.bundle->iface->in_addrs)
853       s = inet_ntoa(ipcp->fsm.bundle->iface->in_addr[0].ifa);
854     else
855       s = "Interface configuration error !";
856     log_Printf(LogIPCP, "%s: LayerDown: %s\n", fp->link->name, s);
857 
858     /*
859      * XXX this stuff should really live in the FSM.  Our config should
860      * associate executable sections in files with events.
861      */
862     if (system_Select(fp->bundle, s, LINKDOWNFILE, NULL, NULL) < 0) {
863       if (bundle_GetLabel(fp->bundle)) {
864          if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle),
865                           LINKDOWNFILE, NULL, NULL) < 0)
866          system_Select(fp->bundle, "MYADDR", LINKDOWNFILE, NULL, NULL);
867       } else
868         system_Select(fp->bundle, "MYADDR", LINKDOWNFILE, NULL, NULL);
869     }
870 
871     ipcp_Setup(ipcp, INADDR_NONE);
872   }
873   recursing--;
874 }
875 
876 int
877 ipcp_InterfaceUp(struct ipcp *ipcp)
878 {
879   if (ipcp_SetIPaddress(ipcp->fsm.bundle, ipcp->my_ip, ipcp->peer_ip, 0) < 0) {
880     log_Printf(LogERROR, "ipcp_InterfaceUp: unable to set ip address\n");
881     return 0;
882   }
883 
884 #ifndef NONAT
885   if (ipcp->fsm.bundle->NatEnabled)
886     PacketAliasSetAddress(ipcp->my_ip);
887 #endif
888 
889   return 1;
890 }
891 
892 static int
893 IpcpLayerUp(struct fsm *fp)
894 {
895   /* We're now up */
896   struct ipcp *ipcp = fsm2ipcp(fp);
897   char tbuff[16];
898 
899   log_Printf(LogIPCP, "%s: LayerUp.\n", fp->link->name);
900   snprintf(tbuff, sizeof tbuff, "%s", inet_ntoa(ipcp->my_ip));
901   log_Printf(LogIPCP, "myaddr %s hisaddr = %s\n",
902              tbuff, inet_ntoa(ipcp->peer_ip));
903 
904   if (ipcp->peer_compproto >> 16 == PROTO_VJCOMP)
905     sl_compress_init(&ipcp->vj.cslc, (ipcp->peer_compproto >> 8) & 255);
906 
907   if (!ipcp_InterfaceUp(ipcp))
908     return 0;
909 
910   /*
911    * XXX this stuff should really live in the FSM.  Our config should
912    * associate executable sections in files with events.
913    */
914   if (system_Select(fp->bundle, tbuff, LINKUPFILE, NULL, NULL) < 0) {
915     if (bundle_GetLabel(fp->bundle)) {
916       if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle),
917                        LINKUPFILE, NULL, NULL) < 0)
918         system_Select(fp->bundle, "MYADDR", LINKUPFILE, NULL, NULL);
919     } else
920       system_Select(fp->bundle, "MYADDR", LINKUPFILE, NULL, NULL);
921   }
922 
923   fp->more.reqs = fp->more.naks = fp->more.rejs = ipcp->cfg.fsm.maxreq * 3;
924   log_DisplayPrompts();
925 
926   return 1;
927 }
928 
929 static int
930 AcceptableAddr(const struct in_range *prange, struct in_addr ipaddr)
931 {
932   /* Is the given IP in the given range ? */
933   return (prange->ipaddr.s_addr & prange->mask.s_addr) ==
934     (ipaddr.s_addr & prange->mask.s_addr) && ipaddr.s_addr;
935 }
936 
937 static void
938 IpcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
939                  struct fsm_decode *dec)
940 {
941   /* Deal with incoming PROTO_IPCP */
942   struct iface *iface = fp->bundle->iface;
943   struct ipcp *ipcp = fsm2ipcp(fp);
944   int type, length, gotdns, gotdnsnak, n;
945   u_int32_t compproto;
946   struct compreq *pcomp;
947   struct in_addr ipaddr, dstipaddr, have_ip, dns[2], dnsnak[2];
948   char tbuff[100], tbuff2[100];
949 
950   gotdns = 0;
951   gotdnsnak = 0;
952   dnsnak[0].s_addr = dnsnak[1].s_addr = INADDR_ANY;
953 
954   while (plen >= sizeof(struct fsmconfig)) {
955     type = *cp;
956     length = cp[1];
957 
958     if (length == 0) {
959       log_Printf(LogIPCP, "%s: IPCP size zero\n", fp->link->name);
960       break;
961     }
962 
963     if (type < NCFTYPES)
964       snprintf(tbuff, sizeof tbuff, " %s[%d] ", cftypes[type], length);
965     else if (type > 128 && type < 128 + NCFTYPES128)
966       snprintf(tbuff, sizeof tbuff, " %s[%d] ", cftypes128[type-128], length);
967     else
968       snprintf(tbuff, sizeof tbuff, " <%d>[%d] ", type, length);
969 
970     switch (type) {
971     case TY_IPADDR:		/* RFC1332 */
972       memcpy(&ipaddr.s_addr, cp + 2, 4);
973       log_Printf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr));
974 
975       switch (mode_type) {
976       case MODE_REQ:
977         if (iplist_isvalid(&ipcp->cfg.peer_list)) {
978           if (ipaddr.s_addr == INADDR_ANY ||
979               iplist_ip2pos(&ipcp->cfg.peer_list, ipaddr) < 0 ||
980               ipcp_SetIPaddress(fp->bundle, ipcp->cfg.my_range.ipaddr,
981                                 ipaddr, 1)) {
982             log_Printf(LogIPCP, "%s: Address invalid or already in use\n",
983                       inet_ntoa(ipaddr));
984             /*
985              * If we've already had a valid address configured for the peer,
986              * try NAKing with that so that we don't have to upset things
987              * too much.
988              */
989             for (n = 0; n < iface->in_addrs; n++)
990               if (iplist_ip2pos(&ipcp->cfg.peer_list, iface->in_addr[n].brd)
991                   >=0) {
992                 ipcp->peer_ip = iface->in_addr[n].brd;
993                 break;
994               }
995 
996             if (n == iface->in_addrs)
997               /* Just pick an IP number from our list */
998               ipcp->peer_ip = ChooseHisAddr
999                 (fp->bundle, ipcp->cfg.my_range.ipaddr);
1000 
1001             if (ipcp->peer_ip.s_addr == INADDR_ANY) {
1002 	      memcpy(dec->rejend, cp, length);
1003 	      dec->rejend += length;
1004             } else {
1005 	      memcpy(dec->nakend, cp, 2);
1006 	      memcpy(dec->nakend + 2, &ipcp->peer_ip.s_addr, length - 2);
1007 	      dec->nakend += length;
1008             }
1009 	    break;
1010           }
1011 	} else if (!AcceptableAddr(&ipcp->cfg.peer_range, ipaddr)) {
1012 	  /*
1013 	   * If destination address is not acceptable, NAK with what we
1014 	   * want to use.
1015 	   */
1016 	  memcpy(dec->nakend, cp, 2);
1017           for (n = 0; n < iface->in_addrs; n++)
1018             if ((iface->in_addr[n].brd.s_addr &
1019                  ipcp->cfg.peer_range.mask.s_addr)
1020                 == (ipcp->cfg.peer_range.ipaddr.s_addr &
1021                     ipcp->cfg.peer_range.mask.s_addr)) {
1022               /* We prefer the already-configured address */
1023 	      memcpy(dec->nakend + 2, &iface->in_addr[n].brd.s_addr,
1024                      length - 2);
1025               break;
1026             }
1027 
1028           if (n == iface->in_addrs)
1029 	    memcpy(dec->nakend + 2, &ipcp->peer_ip.s_addr, length - 2);
1030 
1031 	  dec->nakend += length;
1032 	  break;
1033 	}
1034 	ipcp->peer_ip = ipaddr;
1035 	memcpy(dec->ackend, cp, length);
1036 	dec->ackend += length;
1037 	break;
1038 
1039       case MODE_NAK:
1040 	if (AcceptableAddr(&ipcp->cfg.my_range, ipaddr)) {
1041 	  /* Use address suggested by peer */
1042 	  snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s ", tbuff,
1043 		   inet_ntoa(ipcp->my_ip));
1044 	  log_Printf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr));
1045 	  ipcp->my_ip = ipaddr;
1046           bundle_AdjustFilters(fp->bundle, &ipcp->my_ip, NULL);
1047 	} else {
1048 	  log_Printf(log_IsKept(LogIPCP) ? LogIPCP : LogPHASE,
1049                     "%s: Unacceptable address!\n", inet_ntoa(ipaddr));
1050           fsm_Close(&ipcp->fsm);
1051 	}
1052 	break;
1053 
1054       case MODE_REJ:
1055 	ipcp->peer_reject |= (1 << type);
1056 	break;
1057       }
1058       break;
1059 
1060     case TY_COMPPROTO:
1061       pcomp = (struct compreq *)(cp + 2);
1062       compproto = (ntohs(pcomp->proto) << 16) + (pcomp->slots << 8) +
1063                   pcomp->compcid;
1064       log_Printf(LogIPCP, "%s %s\n", tbuff, vj2asc(compproto));
1065 
1066       switch (mode_type) {
1067       case MODE_REQ:
1068 	if (!IsAccepted(ipcp->cfg.vj.neg)) {
1069 	  memcpy(dec->rejend, cp, length);
1070 	  dec->rejend += length;
1071 	} else {
1072 	  switch (length) {
1073 	  case 4:		/* RFC1172 */
1074 	    if (ntohs(pcomp->proto) == PROTO_VJCOMP) {
1075 	      log_Printf(LogWARN, "Peer is speaking RFC1172 compression "
1076                          "protocol !\n");
1077 	      ipcp->heis1172 = 1;
1078 	      ipcp->peer_compproto = compproto;
1079 	      memcpy(dec->ackend, cp, length);
1080 	      dec->ackend += length;
1081 	    } else {
1082 	      memcpy(dec->nakend, cp, 2);
1083 	      pcomp->proto = htons(PROTO_VJCOMP);
1084 	      memcpy(dec->nakend+2, &pcomp, 2);
1085 	      dec->nakend += length;
1086 	    }
1087 	    break;
1088 	  case 6:		/* RFC1332 */
1089 	    if (ntohs(pcomp->proto) == PROTO_VJCOMP) {
1090               if (pcomp->slots <= MAX_VJ_STATES
1091                   && pcomp->slots >= MIN_VJ_STATES) {
1092                 /* Ok, we can do that */
1093 	        ipcp->peer_compproto = compproto;
1094 	        ipcp->heis1172 = 0;
1095 	        memcpy(dec->ackend, cp, length);
1096 	        dec->ackend += length;
1097 	      } else {
1098                 /* Get as close as we can to what he wants */
1099 	        ipcp->heis1172 = 0;
1100 	        memcpy(dec->nakend, cp, 2);
1101 	        pcomp->slots = pcomp->slots < MIN_VJ_STATES ?
1102                                MIN_VJ_STATES : MAX_VJ_STATES;
1103 	        memcpy(dec->nakend+2, &pcomp, sizeof pcomp);
1104 	        dec->nakend += length;
1105               }
1106 	    } else {
1107               /* What we really want */
1108 	      memcpy(dec->nakend, cp, 2);
1109 	      pcomp->proto = htons(PROTO_VJCOMP);
1110 	      pcomp->slots = DEF_VJ_STATES;
1111 	      pcomp->compcid = 1;
1112 	      memcpy(dec->nakend+2, &pcomp, sizeof pcomp);
1113 	      dec->nakend += length;
1114 	    }
1115 	    break;
1116 	  default:
1117 	    memcpy(dec->rejend, cp, length);
1118 	    dec->rejend += length;
1119 	    break;
1120 	  }
1121 	}
1122 	break;
1123 
1124       case MODE_NAK:
1125 	if (ntohs(pcomp->proto) == PROTO_VJCOMP) {
1126           if (pcomp->slots > MAX_VJ_STATES)
1127             pcomp->slots = MAX_VJ_STATES;
1128           else if (pcomp->slots < MIN_VJ_STATES)
1129             pcomp->slots = MIN_VJ_STATES;
1130           compproto = (ntohs(pcomp->proto) << 16) + (pcomp->slots << 8) +
1131                       pcomp->compcid;
1132         } else
1133           compproto = 0;
1134 	log_Printf(LogIPCP, "%s changing compproto: %08x --> %08x\n",
1135 		  tbuff, ipcp->my_compproto, compproto);
1136         ipcp->my_compproto = compproto;
1137 	break;
1138 
1139       case MODE_REJ:
1140 	ipcp->peer_reject |= (1 << type);
1141 	break;
1142       }
1143       break;
1144 
1145     case TY_IPADDRS:		/* RFC1172 */
1146       memcpy(&ipaddr.s_addr, cp + 2, 4);
1147       memcpy(&dstipaddr.s_addr, cp + 6, 4);
1148       snprintf(tbuff2, sizeof tbuff2, "%s %s,", tbuff, inet_ntoa(ipaddr));
1149       log_Printf(LogIPCP, "%s %s\n", tbuff2, inet_ntoa(dstipaddr));
1150 
1151       switch (mode_type) {
1152       case MODE_REQ:
1153 	memcpy(dec->rejend, cp, length);
1154 	dec->rejend += length;
1155 	break;
1156 
1157       case MODE_NAK:
1158       case MODE_REJ:
1159 	break;
1160       }
1161       break;
1162 
1163     case TY_PRIMARY_DNS:	/* DNS negotiation (rfc1877) */
1164     case TY_SECONDARY_DNS:
1165       memcpy(&ipaddr.s_addr, cp + 2, 4);
1166       log_Printf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr));
1167 
1168       switch (mode_type) {
1169       case MODE_REQ:
1170         if (!IsAccepted(ipcp->cfg.ns.dns_neg)) {
1171           ipcp->my_reject |= (1 << (type - TY_ADJUST_NS));
1172 	  memcpy(dec->rejend, cp, length);
1173 	  dec->rejend += length;
1174 	  break;
1175         }
1176         if (!gotdns) {
1177           dns[0] = ipcp->cfg.ns.dns[0];
1178           dns[1] = ipcp->cfg.ns.dns[1];
1179           if (dns[0].s_addr == INADDR_ANY && dns[1].s_addr == INADDR_ANY)
1180             getdns(ipcp, dns);
1181           gotdns = 1;
1182         }
1183         have_ip = dns[type == TY_PRIMARY_DNS ? 0 : 1];
1184 
1185 	if (ipaddr.s_addr != have_ip.s_addr) {
1186 	  /*
1187 	   * The client has got the DNS stuff wrong (first request) so
1188 	   * we'll tell 'em how it is
1189 	   */
1190 	  memcpy(dec->nakend, cp, 2);	/* copy first two (type/length) */
1191 	  memcpy(dec->nakend + 2, &have_ip.s_addr, length - 2);
1192 	  dec->nakend += length;
1193 	} else {
1194 	  /*
1195 	   * Otherwise they have it right (this time) so we send a ack packet
1196 	   * back confirming it... end of story
1197 	   */
1198 	  memcpy(dec->ackend, cp, length);
1199 	  dec->ackend += length;
1200         }
1201 	break;
1202 
1203       case MODE_NAK:		/* what does this mean?? */
1204         if (IsEnabled(ipcp->cfg.ns.dns_neg)) {
1205           gotdnsnak = 1;
1206           memcpy(&dnsnak[type == TY_PRIMARY_DNS ? 0 : 1].s_addr, cp + 2, 4);
1207 	}
1208 	break;
1209 
1210       case MODE_REJ:		/* Can't do much, stop asking */
1211         ipcp->peer_reject |= (1 << (type - TY_ADJUST_NS));
1212 	break;
1213       }
1214       break;
1215 
1216     case TY_PRIMARY_NBNS:	/* M$ NetBIOS nameserver hack (rfc1877) */
1217     case TY_SECONDARY_NBNS:
1218       memcpy(&ipaddr.s_addr, cp + 2, 4);
1219       log_Printf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr));
1220 
1221       switch (mode_type) {
1222       case MODE_REQ:
1223 	have_ip.s_addr =
1224           ipcp->cfg.ns.nbns[type == TY_PRIMARY_NBNS ? 0 : 1].s_addr;
1225 
1226         if (have_ip.s_addr == INADDR_ANY) {
1227 	  log_Printf(LogIPCP, "NBNS REQ - rejected - nbns not set\n");
1228           ipcp->my_reject |= (1 << (type - TY_ADJUST_NS));
1229 	  memcpy(dec->rejend, cp, length);
1230 	  dec->rejend += length;
1231 	  break;
1232         }
1233 
1234 	if (ipaddr.s_addr != have_ip.s_addr) {
1235 	  memcpy(dec->nakend, cp, 2);
1236 	  memcpy(dec->nakend+2, &have_ip.s_addr, length);
1237 	  dec->nakend += length;
1238 	} else {
1239 	  memcpy(dec->ackend, cp, length);
1240 	  dec->ackend += length;
1241         }
1242 	break;
1243 
1244       case MODE_NAK:
1245 	log_Printf(LogIPCP, "MS NBNS req %d - NAK??\n", type);
1246 	break;
1247 
1248       case MODE_REJ:
1249 	log_Printf(LogIPCP, "MS NBNS req %d - REJ??\n", type);
1250 	break;
1251       }
1252       break;
1253 
1254     default:
1255       if (mode_type != MODE_NOP) {
1256         ipcp->my_reject |= (1 << type);
1257         memcpy(dec->rejend, cp, length);
1258         dec->rejend += length;
1259       }
1260       break;
1261     }
1262     plen -= length;
1263     cp += length;
1264   }
1265 
1266   if (gotdnsnak)
1267     if (!setdns(ipcp, dnsnak)) {
1268       ipcp->peer_reject |= (1 << (TY_PRIMARY_DNS - TY_ADJUST_NS));
1269       ipcp->peer_reject |= (1 << (TY_SECONDARY_DNS - TY_ADJUST_NS));
1270     }
1271 
1272   if (mode_type != MODE_NOP) {
1273     if (dec->rejend != dec->rej) {
1274       /* rejects are preferred */
1275       dec->ackend = dec->ack;
1276       dec->nakend = dec->nak;
1277     } else if (dec->nakend != dec->nak)
1278       /* then NAKs */
1279       dec->ackend = dec->ack;
1280   }
1281 }
1282 
1283 extern struct mbuf *
1284 ipcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
1285 {
1286   /* Got PROTO_IPCP from link */
1287   m_settype(bp, MB_IPCPIN);
1288   if (bundle_Phase(bundle) == PHASE_NETWORK)
1289     fsm_Input(&bundle->ncp.ipcp.fsm, bp);
1290   else {
1291     if (bundle_Phase(bundle) < PHASE_NETWORK)
1292       log_Printf(LogIPCP, "%s: Error: Unexpected IPCP in phase %s (ignored)\n",
1293                  l->name, bundle_PhaseName(bundle));
1294     m_freem(bp);
1295   }
1296   return NULL;
1297 }
1298 
1299 int
1300 ipcp_UseHisIPaddr(struct bundle *bundle, struct in_addr hisaddr)
1301 {
1302   struct ipcp *ipcp = &bundle->ncp.ipcp;
1303 
1304   memset(&ipcp->cfg.peer_range, '\0', sizeof ipcp->cfg.peer_range);
1305   iplist_reset(&ipcp->cfg.peer_list);
1306   ipcp->peer_ip = ipcp->cfg.peer_range.ipaddr = hisaddr;
1307   ipcp->cfg.peer_range.mask.s_addr = INADDR_BROADCAST;
1308   ipcp->cfg.peer_range.width = 32;
1309 
1310   if (ipcp_SetIPaddress(bundle, ipcp->cfg.my_range.ipaddr, hisaddr, 0) < 0)
1311     return 0;
1312 
1313   return 1;	/* Ok */
1314 }
1315 
1316 int
1317 ipcp_UseHisaddr(struct bundle *bundle, const char *hisaddr, int setaddr)
1318 {
1319   struct ipcp *ipcp = &bundle->ncp.ipcp;
1320 
1321   /* Use `hisaddr' for the peers address (set iface if `setaddr') */
1322   memset(&ipcp->cfg.peer_range, '\0', sizeof ipcp->cfg.peer_range);
1323   iplist_reset(&ipcp->cfg.peer_list);
1324   if (strpbrk(hisaddr, ",-")) {
1325     iplist_setsrc(&ipcp->cfg.peer_list, hisaddr);
1326     if (iplist_isvalid(&ipcp->cfg.peer_list)) {
1327       iplist_setrandpos(&ipcp->cfg.peer_list);
1328       ipcp->peer_ip = ChooseHisAddr(bundle, ipcp->my_ip);
1329       if (ipcp->peer_ip.s_addr == INADDR_ANY) {
1330         log_Printf(LogWARN, "%s: None available !\n", ipcp->cfg.peer_list.src);
1331         return 0;
1332       }
1333       ipcp->cfg.peer_range.ipaddr.s_addr = ipcp->peer_ip.s_addr;
1334       ipcp->cfg.peer_range.mask.s_addr = INADDR_BROADCAST;
1335       ipcp->cfg.peer_range.width = 32;
1336     } else {
1337       log_Printf(LogWARN, "%s: Invalid range !\n", hisaddr);
1338       return 0;
1339     }
1340   } else if (ParseAddr(ipcp, hisaddr, &ipcp->cfg.peer_range.ipaddr,
1341 		       &ipcp->cfg.peer_range.mask,
1342                        &ipcp->cfg.peer_range.width) != 0) {
1343     ipcp->peer_ip.s_addr = ipcp->cfg.peer_range.ipaddr.s_addr;
1344 
1345     if (setaddr && ipcp_SetIPaddress(bundle, ipcp->cfg.my_range.ipaddr,
1346                                      ipcp->cfg.peer_range.ipaddr, 0) < 0)
1347       return 0;
1348   } else
1349     return 0;
1350 
1351   bundle_AdjustFilters(bundle, NULL, &ipcp->peer_ip);
1352 
1353   return 1;	/* Ok */
1354 }
1355 
1356 struct in_addr
1357 addr2mask(struct in_addr addr)
1358 {
1359   u_int32_t haddr = ntohl(addr.s_addr);
1360 
1361   haddr = IN_CLASSA(haddr) ? IN_CLASSA_NET :
1362           IN_CLASSB(haddr) ? IN_CLASSB_NET :
1363           IN_CLASSC_NET;
1364   addr.s_addr = htonl(haddr);
1365 
1366   return addr;
1367 }
1368