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