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