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