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