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