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