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