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