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