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