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