1 /*- 2 * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org> 3 * based on work by Toshiharu OHNO <tony-o@iij.ad.jp> 4 * Internet Initiative Japan, Inc (IIJ) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 #include <sys/param.h> 32 #include <netinet/in_systm.h> 33 #include <netinet/in.h> 34 #include <netinet/ip.h> 35 #include <arpa/inet.h> 36 #include <sys/socket.h> 37 #include <net/if.h> 38 #include <net/route.h> 39 #include <netdb.h> 40 #include <sys/un.h> 41 42 #include <errno.h> 43 #include <fcntl.h> 44 #include <resolv.h> 45 #include <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 104 struct compreq { 105 u_short proto; 106 u_char slots; 107 u_char compcid; 108 }; 109 110 static int IpcpLayerUp(struct fsm *); 111 static void IpcpLayerDown(struct fsm *); 112 static void IpcpLayerStart(struct fsm *); 113 static void IpcpLayerFinish(struct fsm *); 114 static void IpcpInitRestartCounter(struct fsm *, int); 115 static void IpcpSendConfigReq(struct fsm *); 116 static void IpcpSentTerminateReq(struct fsm *); 117 static void IpcpSendTerminateAck(struct fsm *, u_char); 118 static void IpcpDecodeConfig(struct fsm *, u_char *, u_char *, int, 119 struct fsm_decode *); 120 121 static 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 135 static const char * 136 protoname(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 int 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 160 void 161 ipcp_AddInOctets(struct ipcp *ipcp, int n) 162 { 163 throughput_addin(&ipcp->throughput, n); 164 } 165 166 void 167 ipcp_AddOutOctets(struct ipcp *ipcp, int n) 168 { 169 throughput_addout(&ipcp->throughput, n); 170 } 171 172 void 173 ipcp_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 if ((ipcp->ns.resolv_nons = (char *)malloc(st.st_size + 1)) == NULL) 196 log_Printf(LogERROR, "Failed to malloc %lu for %s: %s\n", 197 (unsigned long)st.st_size, _PATH_RESCONF, strerror(errno)); 198 else if ((ipcp->ns.resolv = (char *)malloc(st.st_size + 1)) == NULL) { 199 log_Printf(LogERROR, "Failed(2) to malloc %lu for %s: %s\n", 200 (unsigned long)st.st_size, _PATH_RESCONF, strerror(errno)); 201 free(ipcp->ns.resolv_nons); 202 ipcp->ns.resolv_nons = NULL; 203 } else if ((got = read(fd, ipcp->ns.resolv, st.st_size)) != st.st_size) { 204 if (got == -1) 205 log_Printf(LogERROR, "Failed to read %s: %s\n", 206 _PATH_RESCONF, strerror(errno)); 207 else 208 log_Printf(LogERROR, "Failed to read %s, got %lu not %lu\n", 209 _PATH_RESCONF, (unsigned long)got, 210 (unsigned long)st.st_size); 211 free(ipcp->ns.resolv_nons); 212 ipcp->ns.resolv_nons = NULL; 213 free(ipcp->ns.resolv); 214 ipcp->ns.resolv = NULL; 215 } else { 216 char *cp, *cp_nons, *ncp, ch; 217 int n; 218 219 ipcp->ns.resolv[st.st_size] = '\0'; 220 ipcp->ns.resolver = 1; 221 222 cp_nons = ipcp->ns.resolv_nons; 223 cp = ipcp->ns.resolv; 224 n = 0; 225 226 while ((ncp = strstr(cp, "nameserver")) != NULL) { 227 if (ncp != cp) { 228 memcpy(cp_nons, cp, ncp - cp); 229 cp_nons += ncp - cp; 230 } 231 if ((ncp != cp && ncp[-1] != '\n') || !issep(ncp[10])) { 232 memcpy(cp_nons, ncp, 9); 233 cp_nons += 9; 234 cp = ncp + 9; /* Can't match "nameserver" at cp... */ 235 continue; 236 } 237 238 for (cp = ncp + 11; issep(*cp); cp++) /* Skip whitespace */ 239 ; 240 241 for (ncp = cp; isip(*ncp); ncp++) /* Jump over IP */ 242 ; 243 244 ch = *ncp; 245 *ncp = '\0'; 246 if (n < 2 && inet_aton(cp, ipcp->ns.dns)) 247 n++; 248 *ncp = ch; 249 250 if ((cp = strchr(ncp, '\n')) == NULL) /* Point at next line */ 251 cp = ncp + strlen(ncp); 252 else 253 cp++; 254 } 255 strcpy(cp_nons, cp); /* Copy the end - including the NUL */ 256 cp_nons += strlen(cp_nons) - 1; 257 while (cp_nons >= ipcp->ns.resolv_nons && *cp_nons == '\n') 258 *cp_nons-- = '\0'; 259 if (n == 2 && ipcp->ns.dns[0].s_addr == INADDR_ANY) { 260 ipcp->ns.dns[0].s_addr = ipcp->ns.dns[1].s_addr; 261 ipcp->ns.dns[1].s_addr = INADDR_ANY; 262 } 263 bundle_AdjustDNS(ipcp->fsm.bundle); 264 } 265 } else 266 log_Printf(LogERROR, "Failed to stat opened %s: %s\n", 267 _PATH_RESCONF, strerror(errno)); 268 269 close(fd); 270 } 271 } 272 273 int 274 ipcp_WriteDNS(struct ipcp *ipcp) 275 { 276 const char *paddr; 277 mode_t mask; 278 FILE *fp; 279 280 if (ipcp->ns.dns[0].s_addr == INADDR_ANY && 281 ipcp->ns.dns[1].s_addr == INADDR_ANY) { 282 log_Printf(LogIPCP, "%s not modified: All nameservers NAKd\n", 283 _PATH_RESCONF); 284 return 0; 285 } 286 287 if (ipcp->ns.dns[0].s_addr == INADDR_ANY) { 288 ipcp->ns.dns[0].s_addr = ipcp->ns.dns[1].s_addr; 289 ipcp->ns.dns[1].s_addr = INADDR_ANY; 290 } 291 292 mask = umask(022); 293 if ((fp = ID0fopen(_PATH_RESCONF, "w")) != NULL) { 294 umask(mask); 295 if (ipcp->ns.resolv_nons) 296 fputs(ipcp->ns.resolv_nons, fp); 297 paddr = inet_ntoa(ipcp->ns.dns[0]); 298 log_Printf(LogIPCP, "Primary nameserver set to %s\n", paddr); 299 fprintf(fp, "\nnameserver %s\n", paddr); 300 if (ipcp->ns.dns[1].s_addr != INADDR_ANY && 301 ipcp->ns.dns[1].s_addr != INADDR_NONE && 302 ipcp->ns.dns[1].s_addr != ipcp->ns.dns[0].s_addr) { 303 paddr = inet_ntoa(ipcp->ns.dns[1]); 304 log_Printf(LogIPCP, "Secondary nameserver set to %s\n", paddr); 305 fprintf(fp, "nameserver %s\n", paddr); 306 } 307 if (fclose(fp) == EOF) { 308 log_Printf(LogERROR, "write(): Failed updating %s: %s\n", _PATH_RESCONF, 309 strerror(errno)); 310 return 0; 311 } 312 } else 313 umask(mask); 314 315 return 1; 316 } 317 318 void 319 ipcp_RestoreDNS(struct ipcp *ipcp) 320 { 321 if (ipcp->ns.resolver) { 322 ssize_t got; 323 size_t len; 324 int fd; 325 326 if ((fd = ID0open(_PATH_RESCONF, O_WRONLY|O_TRUNC, 0644)) != -1) { 327 len = strlen(ipcp->ns.resolv); 328 if ((got = write(fd, ipcp->ns.resolv, len)) != len) { 329 if (got == -1) 330 log_Printf(LogERROR, "Failed rewriting %s: write: %s\n", 331 _PATH_RESCONF, strerror(errno)); 332 else 333 log_Printf(LogERROR, "Failed rewriting %s: wrote %lu of %lu\n", 334 _PATH_RESCONF, (unsigned long)got, (unsigned long)len); 335 } 336 close(fd); 337 } else 338 log_Printf(LogERROR, "Failed rewriting %s: open: %s\n", _PATH_RESCONF, 339 strerror(errno)); 340 } else if (remove(_PATH_RESCONF) == -1) 341 log_Printf(LogERROR, "Failed removing %s: %s\n", _PATH_RESCONF, 342 strerror(errno)); 343 344 } 345 346 int 347 ipcp_Show(struct cmdargs const *arg) 348 { 349 struct ipcp *ipcp = &arg->bundle->ncp.ipcp; 350 351 prompt_Printf(arg->prompt, "%s [%s]\n", ipcp->fsm.name, 352 State2Nam(ipcp->fsm.state)); 353 if (ipcp->fsm.state == ST_OPENED) { 354 prompt_Printf(arg->prompt, " His side: %s, %s\n", 355 inet_ntoa(ipcp->peer_ip), vj2asc(ipcp->peer_compproto)); 356 prompt_Printf(arg->prompt, " My side: %s, %s\n", 357 inet_ntoa(ipcp->my_ip), vj2asc(ipcp->my_compproto)); 358 prompt_Printf(arg->prompt, " Queued packets: %lu\n", 359 (unsigned long)ipcp_QueueLen(ipcp)); 360 } 361 362 prompt_Printf(arg->prompt, "\nDefaults:\n"); 363 prompt_Printf(arg->prompt, " FSM retry = %us, max %u Config" 364 " REQ%s, %u Term REQ%s\n", ipcp->cfg.fsm.timeout, 365 ipcp->cfg.fsm.maxreq, ipcp->cfg.fsm.maxreq == 1 ? "" : "s", 366 ipcp->cfg.fsm.maxtrm, ipcp->cfg.fsm.maxtrm == 1 ? "" : "s"); 367 prompt_Printf(arg->prompt, " My Address: %s\n", 368 ncprange_ntoa(&ipcp->cfg.my_range)); 369 if (ipcp->cfg.HaveTriggerAddress) 370 prompt_Printf(arg->prompt, " Trigger address: %s\n", 371 inet_ntoa(ipcp->cfg.TriggerAddress)); 372 373 prompt_Printf(arg->prompt, " VJ compression: %s (%d slots %s slot " 374 "compression)\n", command_ShowNegval(ipcp->cfg.vj.neg), 375 ipcp->cfg.vj.slots, ipcp->cfg.vj.slotcomp ? "with" : "without"); 376 377 if (iplist_isvalid(&ipcp->cfg.peer_list)) 378 prompt_Printf(arg->prompt, " His Address: %s\n", 379 ipcp->cfg.peer_list.src); 380 else 381 prompt_Printf(arg->prompt, " His Address: %s\n", 382 ncprange_ntoa(&ipcp->cfg.peer_range)); 383 384 prompt_Printf(arg->prompt, " DNS: %s", 385 ipcp->cfg.ns.dns[0].s_addr == INADDR_NONE ? 386 "none" : inet_ntoa(ipcp->cfg.ns.dns[0])); 387 if (ipcp->cfg.ns.dns[1].s_addr != INADDR_NONE) 388 prompt_Printf(arg->prompt, ", %s", 389 inet_ntoa(ipcp->cfg.ns.dns[1])); 390 prompt_Printf(arg->prompt, ", %s\n", 391 command_ShowNegval(ipcp->cfg.ns.dns_neg)); 392 prompt_Printf(arg->prompt, " Resolver DNS: %s", 393 ipcp->ns.dns[0].s_addr == INADDR_NONE ? 394 "none" : inet_ntoa(ipcp->ns.dns[0])); 395 if (ipcp->ns.dns[1].s_addr != INADDR_NONE && 396 ipcp->ns.dns[1].s_addr != ipcp->ns.dns[0].s_addr) 397 prompt_Printf(arg->prompt, ", %s", 398 inet_ntoa(ipcp->ns.dns[1])); 399 prompt_Printf(arg->prompt, "\n NetBIOS NS: %s, ", 400 inet_ntoa(ipcp->cfg.ns.nbns[0])); 401 prompt_Printf(arg->prompt, "%s\n\n", 402 inet_ntoa(ipcp->cfg.ns.nbns[1])); 403 404 throughput_disp(&ipcp->throughput, arg->prompt); 405 406 return 0; 407 } 408 409 int 410 ipcp_vjset(struct cmdargs const *arg) 411 { 412 if (arg->argc != arg->argn+2) 413 return -1; 414 if (!strcasecmp(arg->argv[arg->argn], "slots")) { 415 int slots; 416 417 slots = atoi(arg->argv[arg->argn+1]); 418 if (slots < 4 || slots > 16) 419 return 1; 420 arg->bundle->ncp.ipcp.cfg.vj.slots = slots; 421 return 0; 422 } else if (!strcasecmp(arg->argv[arg->argn], "slotcomp")) { 423 if (!strcasecmp(arg->argv[arg->argn+1], "on")) 424 arg->bundle->ncp.ipcp.cfg.vj.slotcomp = 1; 425 else if (!strcasecmp(arg->argv[arg->argn+1], "off")) 426 arg->bundle->ncp.ipcp.cfg.vj.slotcomp = 0; 427 else 428 return 2; 429 return 0; 430 } 431 return -1; 432 } 433 434 void 435 ipcp_Init(struct ipcp *ipcp, struct bundle *bundle, struct link *l, 436 const struct fsm_parent *parent) 437 { 438 struct hostent *hp; 439 struct in_addr host; 440 char name[MAXHOSTNAMELEN]; 441 static const char * const timer_names[] = 442 {"IPCP restart", "IPCP openmode", "IPCP stopped"}; 443 444 fsm_Init(&ipcp->fsm, "IPCP", PROTO_IPCP, 1, IPCP_MAXCODE, LogIPCP, 445 bundle, l, parent, &ipcp_Callbacks, timer_names); 446 447 ipcp->cfg.vj.slots = DEF_VJ_STATES; 448 ipcp->cfg.vj.slotcomp = 1; 449 memset(&ipcp->cfg.my_range, '\0', sizeof ipcp->cfg.my_range); 450 451 host.s_addr = htonl(INADDR_LOOPBACK); 452 ipcp->cfg.netmask.s_addr = INADDR_ANY; 453 if (gethostname(name, sizeof name) == 0) { 454 hp = gethostbyname(name); 455 if (hp && hp->h_addrtype == AF_INET && hp->h_length == sizeof host.s_addr) 456 memcpy(&host.s_addr, hp->h_addr, sizeof host.s_addr); 457 } 458 ncprange_setip4(&ipcp->cfg.my_range, host, ipcp->cfg.netmask); 459 ncprange_setip4(&ipcp->cfg.peer_range, ipcp->cfg.netmask, ipcp->cfg.netmask); 460 461 iplist_setsrc(&ipcp->cfg.peer_list, ""); 462 ipcp->cfg.HaveTriggerAddress = 0; 463 464 ipcp->cfg.ns.dns[0].s_addr = INADDR_NONE; 465 ipcp->cfg.ns.dns[1].s_addr = INADDR_NONE; 466 ipcp->cfg.ns.dns_neg = 0; 467 ipcp->cfg.ns.nbns[0].s_addr = INADDR_ANY; 468 ipcp->cfg.ns.nbns[1].s_addr = INADDR_ANY; 469 470 ipcp->cfg.fsm.timeout = DEF_FSMRETRY; 471 ipcp->cfg.fsm.maxreq = DEF_FSMTRIES; 472 ipcp->cfg.fsm.maxtrm = DEF_FSMTRIES; 473 ipcp->cfg.vj.neg = NEG_ENABLED|NEG_ACCEPTED; 474 475 memset(&ipcp->vj, '\0', sizeof ipcp->vj); 476 477 ipcp->ns.resolv = NULL; 478 ipcp->ns.resolv_nons = NULL; 479 ipcp->ns.writable = 1; 480 ipcp_LoadDNS(ipcp); 481 482 throughput_init(&ipcp->throughput, SAMPLE_PERIOD); 483 memset(ipcp->Queue, '\0', sizeof ipcp->Queue); 484 ipcp_Setup(ipcp, INADDR_NONE); 485 } 486 487 void 488 ipcp_Destroy(struct ipcp *ipcp) 489 { 490 throughput_destroy(&ipcp->throughput); 491 492 if (ipcp->ns.resolv != NULL) { 493 free(ipcp->ns.resolv); 494 ipcp->ns.resolv = NULL; 495 } 496 if (ipcp->ns.resolv_nons != NULL) { 497 free(ipcp->ns.resolv_nons); 498 ipcp->ns.resolv_nons = NULL; 499 } 500 } 501 502 void 503 ipcp_SetLink(struct ipcp *ipcp, struct link *l) 504 { 505 ipcp->fsm.link = l; 506 } 507 508 void 509 ipcp_Setup(struct ipcp *ipcp, u_int32_t mask) 510 { 511 struct iface *iface = ipcp->fsm.bundle->iface; 512 struct ncpaddr ipaddr; 513 struct in_addr peer; 514 int pos, n; 515 516 ipcp->fsm.open_mode = 0; 517 ipcp->ifmask.s_addr = mask == INADDR_NONE ? ipcp->cfg.netmask.s_addr : mask; 518 519 if (iplist_isvalid(&ipcp->cfg.peer_list)) { 520 /* Try to give the peer a previously configured IP address */ 521 for (n = 0; n < iface->addrs; n++) { 522 if (!ncpaddr_getip4(&iface->addr[n].peer, &peer)) 523 continue; 524 if ((pos = iplist_ip2pos(&ipcp->cfg.peer_list, peer)) != -1) { 525 ncpaddr_setip4(&ipaddr, iplist_setcurpos(&ipcp->cfg.peer_list, pos)); 526 break; 527 } 528 } 529 if (n == iface->addrs) 530 /* Ok, so none of 'em fit.... pick a random one */ 531 ncpaddr_setip4(&ipaddr, iplist_setrandpos(&ipcp->cfg.peer_list)); 532 533 ncprange_sethost(&ipcp->cfg.peer_range, &ipaddr); 534 } 535 536 ipcp->heis1172 = 0; 537 ipcp->peer_req = 0; 538 ncprange_getip4addr(&ipcp->cfg.peer_range, &ipcp->peer_ip); 539 ipcp->peer_compproto = 0; 540 541 if (ipcp->cfg.HaveTriggerAddress) { 542 /* 543 * Some implementations of PPP require that we send a 544 * *special* value as our address, even though the rfc specifies 545 * full negotiation (e.g. "0.0.0.0" or Not "0.0.0.0"). 546 */ 547 ipcp->my_ip = ipcp->cfg.TriggerAddress; 548 log_Printf(LogIPCP, "Using trigger address %s\n", 549 inet_ntoa(ipcp->cfg.TriggerAddress)); 550 } else { 551 /* 552 * Otherwise, if we've used an IP number before and it's still within 553 * the network specified on the ``set ifaddr'' line, we really 554 * want to keep that IP number so that we can keep any existing 555 * connections that are bound to that IP. 556 */ 557 for (n = 0; n < iface->addrs; n++) { 558 ncprange_getaddr(&iface->addr[n].ifa, &ipaddr); 559 if (ncprange_contains(&ipcp->cfg.my_range, &ipaddr)) { 560 ncpaddr_getip4(&ipaddr, &ipcp->my_ip); 561 break; 562 } 563 } 564 if (n == iface->addrs) 565 ncprange_getip4addr(&ipcp->cfg.my_range, &ipcp->my_ip); 566 } 567 568 if (IsEnabled(ipcp->cfg.vj.neg) 569 #ifndef NORADIUS 570 || (ipcp->fsm.bundle->radius.valid && ipcp->fsm.bundle->radius.vj) 571 #endif 572 ) 573 ipcp->my_compproto = (PROTO_VJCOMP << 16) + 574 ((ipcp->cfg.vj.slots - 1) << 8) + 575 ipcp->cfg.vj.slotcomp; 576 else 577 ipcp->my_compproto = 0; 578 sl_compress_init(&ipcp->vj.cslc, ipcp->cfg.vj.slots - 1); 579 580 ipcp->peer_reject = 0; 581 ipcp->my_reject = 0; 582 583 /* Copy startup values into ipcp->ns.dns */ 584 if (ipcp->cfg.ns.dns[0].s_addr != INADDR_NONE) 585 memcpy(ipcp->ns.dns, ipcp->cfg.ns.dns, sizeof ipcp->ns.dns); 586 } 587 588 static int 589 numaddresses(struct in_addr mask) 590 { 591 u_int32_t bit, haddr; 592 int n; 593 594 haddr = ntohl(mask.s_addr); 595 bit = 1; 596 n = 1; 597 598 do { 599 if (!(haddr & bit)) 600 n <<= 1; 601 } while (bit <<= 1); 602 603 return n; 604 } 605 606 static int 607 ipcp_proxyarp(struct ipcp *ipcp, 608 int (*proxyfun)(struct bundle *, struct in_addr, int), 609 const struct iface_addr *addr) 610 { 611 struct bundle *bundle = ipcp->fsm.bundle; 612 struct in_addr peer, mask, ip; 613 int n, ret, s; 614 615 if (!ncpaddr_getip4(&addr->peer, &peer)) { 616 log_Printf(LogERROR, "Oops, ipcp_proxyarp() called with unexpected addr\n"); 617 return 0; 618 } 619 620 if ((s = ID0socket(PF_INET, SOCK_DGRAM, 0)) == -1) { 621 log_Printf(LogERROR, "ipcp_proxyarp: socket: %s\n", 622 strerror(errno)); 623 return 0; 624 } 625 626 ret = 0; 627 628 if (Enabled(bundle, OPT_PROXYALL)) { 629 ncprange_getip4mask(&addr->ifa, &mask); 630 if ((n = numaddresses(mask)) > 256) { 631 log_Printf(LogWARN, "%s: Too many addresses for proxyall\n", 632 ncprange_ntoa(&addr->ifa)); 633 return 0; 634 } 635 ip.s_addr = peer.s_addr & mask.s_addr; 636 if (n >= 4) { 637 ip.s_addr = htonl(ntohl(ip.s_addr) + 1); 638 n -= 2; 639 } 640 while (n) { 641 if (!((ip.s_addr ^ peer.s_addr) & mask.s_addr)) { 642 if (!(ret = (*proxyfun)(bundle, ip, s))) 643 break; 644 n--; 645 } 646 ip.s_addr = htonl(ntohl(ip.s_addr) + 1); 647 } 648 ret = !n; 649 } else if (Enabled(bundle, OPT_PROXY)) 650 ret = (*proxyfun)(bundle, peer, s); 651 652 close(s); 653 654 return ret; 655 } 656 657 static int 658 ipcp_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 707 static struct in_addr 708 ChooseHisAddr(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 731 static void 732 IpcpInitRestartCounter(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 751 static void 752 IpcpSendConfigReq(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[24]; 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 800 static void 801 IpcpSentTerminateReq(struct fsm *fp) 802 { 803 /* Term REQ just sent by FSM */ 804 } 805 806 static void 807 IpcpSendTerminateAck(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 813 static void 814 IpcpLayerStart(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 826 static void 827 IpcpLayerFinish(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 */ 840 void 841 ipcp_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 */ 852 void 853 ipcp_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 861 static void 862 IpcpLayerDown(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_Account(&fp->bundle->radius, &fp->bundle->radacct, 875 fp->bundle->links, RAD_STOP, &ipcp->throughput); 876 877 if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) 878 system_Select(fp->bundle, fp->bundle->radius.filterid, LINKDOWNFILE, 879 NULL, NULL); 880 radius_StopTimer(&fp->bundle->radius); 881 #endif 882 883 /* 884 * XXX this stuff should really live in the FSM. Our config should 885 * associate executable sections in files with events. 886 */ 887 if (system_Select(fp->bundle, addr, LINKDOWNFILE, NULL, NULL) < 0) { 888 if (bundle_GetLabel(fp->bundle)) { 889 if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle), 890 LINKDOWNFILE, NULL, NULL) < 0) 891 system_Select(fp->bundle, "MYADDR", LINKDOWNFILE, NULL, NULL); 892 } else 893 system_Select(fp->bundle, "MYADDR", LINKDOWNFILE, NULL, NULL); 894 } 895 896 ipcp_Setup(ipcp, INADDR_NONE); 897 } 898 recursing--; 899 } 900 901 int 902 ipcp_InterfaceUp(struct ipcp *ipcp) 903 { 904 if (!ipcp_SetIPaddress(ipcp, ipcp->my_ip, ipcp->peer_ip)) { 905 log_Printf(LogERROR, "ipcp_InterfaceUp: unable to set ip address\n"); 906 return 0; 907 } 908 909 if (!iface_SetFlags(ipcp->fsm.bundle->iface->name, IFF_UP)) { 910 log_Printf(LogERROR, "ipcp_InterfaceUp: Can't set the IFF_UP flag on %s\n", 911 ipcp->fsm.bundle->iface->name); 912 return 0; 913 } 914 915 #ifndef NONAT 916 if (ipcp->fsm.bundle->NatEnabled) 917 PacketAliasSetAddress(ipcp->my_ip); 918 #endif 919 920 return 1; 921 } 922 923 static int 924 IpcpLayerUp(struct fsm *fp) 925 { 926 /* We're now up */ 927 struct ipcp *ipcp = fsm2ipcp(fp); 928 char tbuff[16]; 929 930 log_Printf(LogIPCP, "%s: LayerUp.\n", fp->link->name); 931 snprintf(tbuff, sizeof tbuff, "%s", inet_ntoa(ipcp->my_ip)); 932 log_Printf(LogIPCP, "myaddr %s hisaddr = %s\n", 933 tbuff, inet_ntoa(ipcp->peer_ip)); 934 935 if (ipcp->peer_compproto >> 16 == PROTO_VJCOMP) 936 sl_compress_init(&ipcp->vj.cslc, (ipcp->peer_compproto >> 8) & 255); 937 938 if (!ipcp_InterfaceUp(ipcp)) 939 return 0; 940 941 #ifndef NORADIUS 942 radius_Account_Set_Ip(&fp->bundle->radacct, &ipcp->peer_ip, &ipcp->ifmask); 943 radius_Account(&fp->bundle->radius, &fp->bundle->radacct, fp->bundle->links, 944 RAD_START, &ipcp->throughput); 945 946 if (fp->bundle->radius.cfg.file && fp->bundle->radius.filterid) 947 system_Select(fp->bundle, fp->bundle->radius.filterid, LINKUPFILE, 948 NULL, NULL); 949 radius_StartTimer(fp->bundle); 950 #endif 951 952 /* 953 * XXX this stuff should really live in the FSM. Our config should 954 * associate executable sections in files with events. 955 */ 956 if (system_Select(fp->bundle, tbuff, LINKUPFILE, NULL, NULL) < 0) { 957 if (bundle_GetLabel(fp->bundle)) { 958 if (system_Select(fp->bundle, bundle_GetLabel(fp->bundle), 959 LINKUPFILE, NULL, NULL) < 0) 960 system_Select(fp->bundle, "MYADDR", LINKUPFILE, NULL, NULL); 961 } else 962 system_Select(fp->bundle, "MYADDR", LINKUPFILE, NULL, NULL); 963 } 964 965 fp->more.reqs = fp->more.naks = fp->more.rejs = ipcp->cfg.fsm.maxreq * 3; 966 log_DisplayPrompts(); 967 968 return 1; 969 } 970 971 static void 972 ipcp_ValidateReq(struct ipcp *ipcp, struct in_addr ip, struct fsm_decode *dec) 973 { 974 struct bundle *bundle = ipcp->fsm.bundle; 975 struct iface *iface = bundle->iface; 976 struct in_addr myaddr, peer; 977 int n; 978 979 if (iplist_isvalid(&ipcp->cfg.peer_list)) { 980 ncprange_getip4addr(&ipcp->cfg.my_range, &myaddr); 981 if (ip.s_addr == INADDR_ANY || 982 iplist_ip2pos(&ipcp->cfg.peer_list, ip) < 0 || 983 !ipcp_SetIPaddress(ipcp, myaddr, ip)) { 984 log_Printf(LogIPCP, "%s: Address invalid or already in use\n", 985 inet_ntoa(ip)); 986 /* 987 * If we've already had a valid address configured for the peer, 988 * try NAKing with that so that we don't have to upset things 989 * too much. 990 */ 991 for (n = 0; n < iface->addrs; n++) { 992 if (!ncpaddr_getip4(&iface->addr[n].peer, &peer)) 993 continue; 994 if (iplist_ip2pos(&ipcp->cfg.peer_list, peer) >= 0) { 995 ipcp->peer_ip = peer; 996 break; 997 } 998 } 999 1000 if (n == iface->addrs) { 1001 /* Just pick an IP number from our list */ 1002 ipcp->peer_ip = ChooseHisAddr(bundle, myaddr); 1003 } 1004 1005 if (ipcp->peer_ip.s_addr == INADDR_ANY) { 1006 *dec->rejend++ = TY_IPADDR; 1007 *dec->rejend++ = 6; 1008 memcpy(dec->rejend, &ip.s_addr, 4); 1009 dec->rejend += 4; 1010 } else { 1011 *dec->nakend++ = TY_IPADDR; 1012 *dec->nakend++ = 6; 1013 memcpy(dec->nakend, &ipcp->peer_ip.s_addr, 4); 1014 dec->nakend += 4; 1015 } 1016 return; 1017 } 1018 } else if (ip.s_addr == INADDR_ANY || 1019 !ncprange_containsip4(&ipcp->cfg.peer_range, ip)) { 1020 /* 1021 * If the destination address is not acceptable, NAK with what we 1022 * want to use. 1023 */ 1024 *dec->nakend++ = TY_IPADDR; 1025 *dec->nakend++ = 6; 1026 for (n = 0; n < iface->addrs; n++) 1027 if (ncprange_contains(&ipcp->cfg.peer_range, &iface->addr[n].peer)) { 1028 /* We prefer the already-configured address */ 1029 ncpaddr_getip4addr(&iface->addr[n].peer, (u_int32_t *)dec->nakend); 1030 break; 1031 } 1032 1033 if (n == iface->addrs) 1034 memcpy(dec->nakend, &ipcp->peer_ip.s_addr, 4); 1035 1036 dec->nakend += 4; 1037 return; 1038 } 1039 1040 ipcp->peer_ip = ip; 1041 *dec->ackend++ = TY_IPADDR; 1042 *dec->ackend++ = 6; 1043 memcpy(dec->ackend, &ip.s_addr, 4); 1044 dec->ackend += 4; 1045 } 1046 1047 static void 1048 IpcpDecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type, 1049 struct fsm_decode *dec) 1050 { 1051 /* Deal with incoming PROTO_IPCP */ 1052 struct ncpaddr ncpaddr; 1053 struct ipcp *ipcp = fsm2ipcp(fp); 1054 int gotdnsnak; 1055 u_int32_t compproto; 1056 struct compreq *pcomp; 1057 struct in_addr ipaddr, dstipaddr, have_ip; 1058 char tbuff[100], tbuff2[100]; 1059 struct fsm_opt *opt, nak; 1060 1061 gotdnsnak = 0; 1062 1063 while (end - cp >= sizeof(opt->hdr)) { 1064 if ((opt = fsm_readopt(&cp)) == NULL) 1065 break; 1066 1067 snprintf(tbuff, sizeof tbuff, " %s[%d]", protoname(opt->hdr.id), 1068 opt->hdr.len); 1069 1070 switch (opt->hdr.id) { 1071 case TY_IPADDR: /* RFC1332 */ 1072 memcpy(&ipaddr.s_addr, opt->data, 4); 1073 log_Printf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 1074 1075 switch (mode_type) { 1076 case MODE_REQ: 1077 ipcp->peer_req = 1; 1078 ipcp_ValidateReq(ipcp, ipaddr, dec); 1079 break; 1080 1081 case MODE_NAK: 1082 if (ncprange_containsip4(&ipcp->cfg.my_range, ipaddr)) { 1083 /* Use address suggested by peer */ 1084 snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s ", tbuff, 1085 inet_ntoa(ipcp->my_ip)); 1086 log_Printf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr)); 1087 ipcp->my_ip = ipaddr; 1088 ncpaddr_setip4(&ncpaddr, ipcp->my_ip); 1089 bundle_AdjustFilters(fp->bundle, &ncpaddr, NULL); 1090 } else { 1091 log_Printf(log_IsKept(LogIPCP) ? LogIPCP : LogPHASE, 1092 "%s: Unacceptable address!\n", inet_ntoa(ipaddr)); 1093 fsm_Close(&ipcp->fsm); 1094 } 1095 break; 1096 1097 case MODE_REJ: 1098 ipcp->peer_reject |= (1 << opt->hdr.id); 1099 break; 1100 } 1101 break; 1102 1103 case TY_COMPPROTO: 1104 pcomp = (struct compreq *)opt->data; 1105 compproto = (ntohs(pcomp->proto) << 16) + (pcomp->slots << 8) + 1106 pcomp->compcid; 1107 log_Printf(LogIPCP, "%s %s\n", tbuff, vj2asc(compproto)); 1108 1109 switch (mode_type) { 1110 case MODE_REQ: 1111 if (!IsAccepted(ipcp->cfg.vj.neg)) 1112 fsm_rej(dec, opt); 1113 else { 1114 switch (opt->hdr.len) { 1115 case 4: /* RFC1172 */ 1116 if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 1117 log_Printf(LogWARN, "Peer is speaking RFC1172 compression " 1118 "protocol !\n"); 1119 ipcp->heis1172 = 1; 1120 ipcp->peer_compproto = compproto; 1121 fsm_ack(dec, opt); 1122 } else { 1123 pcomp->proto = htons(PROTO_VJCOMP); 1124 nak.hdr.id = TY_COMPPROTO; 1125 nak.hdr.len = 4; 1126 memcpy(nak.data, &pcomp, 2); 1127 fsm_nak(dec, &nak); 1128 } 1129 break; 1130 case 6: /* RFC1332 */ 1131 if (ntohs(pcomp->proto) == PROTO_VJCOMP) { 1132 if (pcomp->slots <= MAX_VJ_STATES 1133 && pcomp->slots >= MIN_VJ_STATES) { 1134 /* Ok, we can do that */ 1135 ipcp->peer_compproto = compproto; 1136 ipcp->heis1172 = 0; 1137 fsm_ack(dec, opt); 1138 } else { 1139 /* Get as close as we can to what he wants */ 1140 ipcp->heis1172 = 0; 1141 pcomp->slots = pcomp->slots < MIN_VJ_STATES ? 1142 MIN_VJ_STATES : MAX_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 if (pcomp->slots > MAX_VJ_STATES) 1169 pcomp->slots = MAX_VJ_STATES; 1170 else if (pcomp->slots < MIN_VJ_STATES) 1171 pcomp->slots = MIN_VJ_STATES; 1172 compproto = (ntohs(pcomp->proto) << 16) + (pcomp->slots << 8) + 1173 pcomp->compcid; 1174 } else 1175 compproto = 0; 1176 log_Printf(LogIPCP, "%s changing compproto: %08x --> %08x\n", 1177 tbuff, ipcp->my_compproto, compproto); 1178 ipcp->my_compproto = compproto; 1179 break; 1180 1181 case MODE_REJ: 1182 ipcp->peer_reject |= (1 << opt->hdr.id); 1183 break; 1184 } 1185 break; 1186 1187 case TY_IPADDRS: /* RFC1172 */ 1188 memcpy(&ipaddr.s_addr, opt->data, 4); 1189 memcpy(&dstipaddr.s_addr, opt->data + 4, 4); 1190 snprintf(tbuff2, sizeof tbuff2, "%s %s,", tbuff, inet_ntoa(ipaddr)); 1191 log_Printf(LogIPCP, "%s %s\n", tbuff2, inet_ntoa(dstipaddr)); 1192 1193 switch (mode_type) { 1194 case MODE_REQ: 1195 fsm_rej(dec, opt); 1196 break; 1197 1198 case MODE_NAK: 1199 case MODE_REJ: 1200 break; 1201 } 1202 break; 1203 1204 case TY_PRIMARY_DNS: /* DNS negotiation (rfc1877) */ 1205 case TY_SECONDARY_DNS: 1206 memcpy(&ipaddr.s_addr, opt->data, 4); 1207 log_Printf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 1208 1209 switch (mode_type) { 1210 case MODE_REQ: 1211 if (!IsAccepted(ipcp->cfg.ns.dns_neg)) { 1212 ipcp->my_reject |= (1 << (opt->hdr.id - TY_ADJUST_NS)); 1213 fsm_rej(dec, opt); 1214 break; 1215 } 1216 have_ip = ipcp->ns.dns[opt->hdr.id == TY_PRIMARY_DNS ? 0 : 1]; 1217 1218 if (opt->hdr.id == TY_PRIMARY_DNS && ipaddr.s_addr != have_ip.s_addr && 1219 ipaddr.s_addr == ipcp->ns.dns[1].s_addr) { 1220 /* Swap 'em 'round */ 1221 ipcp->ns.dns[0] = ipcp->ns.dns[1]; 1222 ipcp->ns.dns[1] = have_ip; 1223 have_ip = ipcp->ns.dns[0]; 1224 } 1225 1226 if (ipaddr.s_addr != have_ip.s_addr) { 1227 /* 1228 * The client has got the DNS stuff wrong (first request) so 1229 * we'll tell 'em how it is 1230 */ 1231 nak.hdr.id = opt->hdr.id; 1232 nak.hdr.len = 6; 1233 memcpy(nak.data, &have_ip.s_addr, 4); 1234 fsm_nak(dec, &nak); 1235 } else { 1236 /* 1237 * Otherwise they have it right (this time) so we send an ack packet 1238 * back confirming it... end of story 1239 */ 1240 fsm_ack(dec, opt); 1241 } 1242 break; 1243 1244 case MODE_NAK: 1245 if (IsEnabled(ipcp->cfg.ns.dns_neg)) { 1246 gotdnsnak = 1; 1247 memcpy(&ipcp->ns.dns[opt->hdr.id == TY_PRIMARY_DNS ? 0 : 1].s_addr, 1248 opt->data, 4); 1249 } 1250 break; 1251 1252 case MODE_REJ: /* Can't do much, stop asking */ 1253 ipcp->peer_reject |= (1 << (opt->hdr.id - TY_ADJUST_NS)); 1254 break; 1255 } 1256 break; 1257 1258 case TY_PRIMARY_NBNS: /* M$ NetBIOS nameserver hack (rfc1877) */ 1259 case TY_SECONDARY_NBNS: 1260 memcpy(&ipaddr.s_addr, opt->data, 4); 1261 log_Printf(LogIPCP, "%s %s\n", tbuff, inet_ntoa(ipaddr)); 1262 1263 switch (mode_type) { 1264 case MODE_REQ: 1265 have_ip.s_addr = 1266 ipcp->cfg.ns.nbns[opt->hdr.id == TY_PRIMARY_NBNS ? 0 : 1].s_addr; 1267 1268 if (have_ip.s_addr == INADDR_ANY) { 1269 log_Printf(LogIPCP, "NBNS REQ - rejected - nbns not set\n"); 1270 ipcp->my_reject |= (1 << (opt->hdr.id - TY_ADJUST_NS)); 1271 fsm_rej(dec, opt); 1272 break; 1273 } 1274 1275 if (ipaddr.s_addr != have_ip.s_addr) { 1276 nak.hdr.id = opt->hdr.id; 1277 nak.hdr.len = 6; 1278 memcpy(nak.data, &have_ip.s_addr, 4); 1279 fsm_nak(dec, &nak); 1280 } else 1281 fsm_ack(dec, opt); 1282 break; 1283 1284 case MODE_NAK: 1285 log_Printf(LogIPCP, "MS NBNS req %d - NAK??\n", opt->hdr.id); 1286 break; 1287 1288 case MODE_REJ: 1289 log_Printf(LogIPCP, "MS NBNS req %d - REJ??\n", opt->hdr.id); 1290 break; 1291 } 1292 break; 1293 1294 default: 1295 if (mode_type != MODE_NOP) { 1296 ipcp->my_reject |= (1 << opt->hdr.id); 1297 fsm_rej(dec, opt); 1298 } 1299 break; 1300 } 1301 } 1302 1303 if (gotdnsnak) { 1304 if (ipcp->ns.writable) { 1305 log_Printf(LogDEBUG, "Updating resolver\n"); 1306 if (!ipcp_WriteDNS(ipcp)) { 1307 ipcp->peer_reject |= (1 << (TY_PRIMARY_DNS - TY_ADJUST_NS)); 1308 ipcp->peer_reject |= (1 << (TY_SECONDARY_DNS - TY_ADJUST_NS)); 1309 } else 1310 bundle_AdjustDNS(fp->bundle); 1311 } else { 1312 log_Printf(LogDEBUG, "Not updating resolver (readonly)\n"); 1313 bundle_AdjustDNS(fp->bundle); 1314 } 1315 } 1316 1317 if (mode_type != MODE_NOP) { 1318 if (mode_type == MODE_REQ && !ipcp->peer_req) { 1319 if (dec->rejend == dec->rej && dec->nakend == dec->nak) { 1320 /* 1321 * Pretend the peer has requested an IP. 1322 * We do this to ensure that we only send one NAK if the only 1323 * reason for the NAK is because the peer isn't sending a 1324 * TY_IPADDR REQ. This stops us from repeatedly trying to tell 1325 * the peer that we have to have an IP address on their end. 1326 */ 1327 ipcp->peer_req = 1; 1328 } 1329 ipaddr.s_addr = INADDR_ANY; 1330 ipcp_ValidateReq(ipcp, ipaddr, dec); 1331 } 1332 fsm_opt_normalise(dec); 1333 } 1334 } 1335 1336 extern struct mbuf * 1337 ipcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) 1338 { 1339 /* Got PROTO_IPCP from link */ 1340 m_settype(bp, MB_IPCPIN); 1341 if (bundle_Phase(bundle) == PHASE_NETWORK) 1342 fsm_Input(&bundle->ncp.ipcp.fsm, bp); 1343 else { 1344 if (bundle_Phase(bundle) < PHASE_NETWORK) 1345 log_Printf(LogIPCP, "%s: Error: Unexpected IPCP in phase %s (ignored)\n", 1346 l->name, bundle_PhaseName(bundle)); 1347 m_freem(bp); 1348 } 1349 return NULL; 1350 } 1351 1352 int 1353 ipcp_UseHisIPaddr(struct bundle *bundle, struct in_addr hisaddr) 1354 { 1355 struct ipcp *ipcp = &bundle->ncp.ipcp; 1356 struct in_addr myaddr; 1357 1358 memset(&ipcp->cfg.peer_range, '\0', sizeof ipcp->cfg.peer_range); 1359 iplist_reset(&ipcp->cfg.peer_list); 1360 ipcp->peer_ip = hisaddr; 1361 ncprange_setip4host(&ipcp->cfg.peer_range, hisaddr); 1362 ncprange_getip4addr(&ipcp->cfg.my_range, &myaddr); 1363 1364 return ipcp_SetIPaddress(ipcp, myaddr, hisaddr); 1365 } 1366 1367 int 1368 ipcp_UseHisaddr(struct bundle *bundle, const char *hisaddr, int setaddr) 1369 { 1370 struct in_addr myaddr; 1371 struct ncp *ncp = &bundle->ncp; 1372 struct ipcp *ipcp = &ncp->ipcp; 1373 struct ncpaddr ncpaddr; 1374 1375 /* Use `hisaddr' for the peers address (set iface if `setaddr') */ 1376 memset(&ipcp->cfg.peer_range, '\0', sizeof ipcp->cfg.peer_range); 1377 iplist_reset(&ipcp->cfg.peer_list); 1378 if (strpbrk(hisaddr, ",-")) { 1379 iplist_setsrc(&ipcp->cfg.peer_list, hisaddr); 1380 if (iplist_isvalid(&ipcp->cfg.peer_list)) { 1381 iplist_setrandpos(&ipcp->cfg.peer_list); 1382 ipcp->peer_ip = ChooseHisAddr(bundle, ipcp->my_ip); 1383 if (ipcp->peer_ip.s_addr == INADDR_ANY) { 1384 log_Printf(LogWARN, "%s: None available !\n", ipcp->cfg.peer_list.src); 1385 return 0; 1386 } 1387 ncprange_setip4host(&ipcp->cfg.peer_range, ipcp->peer_ip); 1388 } else { 1389 log_Printf(LogWARN, "%s: Invalid range !\n", hisaddr); 1390 return 0; 1391 } 1392 } else if (ncprange_aton(&ipcp->cfg.peer_range, ncp, hisaddr) != 0) { 1393 if (ncprange_family(&ipcp->cfg.my_range) != AF_INET) { 1394 log_Printf(LogWARN, "%s: Not an AF_INET address !\n", hisaddr); 1395 return 0; 1396 } 1397 ncprange_getip4addr(&ipcp->cfg.my_range, &myaddr); 1398 ncprange_getip4addr(&ipcp->cfg.peer_range, &ipcp->peer_ip); 1399 1400 if (setaddr && !ipcp_SetIPaddress(ipcp, myaddr, ipcp->peer_ip)) 1401 return 0; 1402 } else 1403 return 0; 1404 1405 ncpaddr_setip4(&ncpaddr, ipcp->peer_ip); 1406 bundle_AdjustFilters(bundle, NULL, &ncpaddr); 1407 1408 return 1; /* Ok */ 1409 } 1410 1411 struct in_addr 1412 addr2mask(struct in_addr addr) 1413 { 1414 u_int32_t haddr = ntohl(addr.s_addr); 1415 1416 haddr = IN_CLASSA(haddr) ? IN_CLASSA_NET : 1417 IN_CLASSB(haddr) ? IN_CLASSB_NET : 1418 IN_CLASSC_NET; 1419 addr.s_addr = htonl(haddr); 1420 1421 return addr; 1422 } 1423 1424 size_t 1425 ipcp_QueueLen(struct ipcp *ipcp) 1426 { 1427 struct mqueue *q; 1428 size_t result; 1429 1430 result = 0; 1431 for (q = ipcp->Queue; q < ipcp->Queue + IPCP_QUEUES(ipcp); q++) 1432 result += q->len; 1433 1434 return result; 1435 } 1436 1437 int 1438 ipcp_PushPacket(struct ipcp *ipcp, struct link *l) 1439 { 1440 struct bundle *bundle = ipcp->fsm.bundle; 1441 struct mqueue *queue; 1442 struct mbuf *bp; 1443 int m_len; 1444 u_int32_t secs = 0; 1445 unsigned alivesecs = 0; 1446 1447 if (ipcp->fsm.state != ST_OPENED) 1448 return 0; 1449 1450 /* 1451 * If ccp is not open but is required, do nothing. 1452 */ 1453 if (l->ccp.fsm.state != ST_OPENED && ccp_Required(&l->ccp)) { 1454 log_Printf(LogPHASE, "%s: Not transmitting... waiting for CCP\n", l->name); 1455 return 0; 1456 } 1457 1458 queue = ipcp->Queue + IPCP_QUEUES(ipcp) - 1; 1459 do { 1460 if (queue->top) { 1461 bp = m_dequeue(queue); 1462 bp = mbuf_Read(bp, &secs, sizeof secs); 1463 bp = m_pullup(bp); 1464 m_len = m_length(bp); 1465 if (!FilterCheck(MBUF_CTOP(bp), AF_INET, &bundle->filter.alive, 1466 &alivesecs)) { 1467 if (secs == 0) 1468 secs = alivesecs; 1469 bundle_StartIdleTimer(bundle, secs); 1470 } 1471 link_PushPacket(l, bp, bundle, 0, PROTO_IP); 1472 ipcp_AddOutOctets(ipcp, m_len); 1473 return 1; 1474 } 1475 } while (queue-- != ipcp->Queue); 1476 1477 return 0; 1478 } 1479