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