1 /*- 2 * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <sys/param.h> 30 #include <netinet/in_systm.h> 31 #include <netinet/in.h> 32 #include <netinet/ip.h> 33 #include <sys/socket.h> 34 #include <net/route.h> 35 #include <net/if.h> 36 #include <sys/un.h> 37 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <termios.h> 42 43 #include "layer.h" 44 #include "defs.h" 45 #include "mbuf.h" 46 #include "timer.h" 47 #include "fsm.h" 48 #include "iplist.h" 49 #include "throughput.h" 50 #include "slcompress.h" 51 #include "lqr.h" 52 #include "hdlc.h" 53 #include "lcp.h" 54 #include "ncpaddr.h" 55 #include "ip.h" 56 #include "ipcp.h" 57 #include "ipv6cp.h" 58 #include "filter.h" 59 #include "descriptor.h" 60 #include "ccp.h" 61 #include "link.h" 62 #include "mp.h" 63 #ifndef NORADIUS 64 #include "radius.h" 65 #endif 66 #include "ncp.h" 67 #include "bundle.h" 68 #include "route.h" 69 #include "iface.h" 70 #include "log.h" 71 #include "proto.h" 72 #include "command.h" 73 #include "prompt.h" 74 #include "async.h" 75 #include "physical.h" 76 #include "probe.h" 77 78 79 #ifndef NOINET6 80 static int ipv6cp_LayerUp(struct fsm *); 81 static void ipv6cp_LayerDown(struct fsm *); 82 static void ipv6cp_LayerStart(struct fsm *); 83 static void ipv6cp_LayerFinish(struct fsm *); 84 static void ipv6cp_InitRestartCounter(struct fsm *, int); 85 static void ipv6cp_SendConfigReq(struct fsm *); 86 static void ipv6cp_SentTerminateReq(struct fsm *); 87 static void ipv6cp_SendTerminateAck(struct fsm *, u_char); 88 static void ipv6cp_DecodeConfig(struct fsm *, u_char *, u_char *, int, 89 struct fsm_decode *); 90 91 static struct fsm_callbacks ipv6cp_Callbacks = { 92 ipv6cp_LayerUp, 93 ipv6cp_LayerDown, 94 ipv6cp_LayerStart, 95 ipv6cp_LayerFinish, 96 ipv6cp_InitRestartCounter, 97 ipv6cp_SendConfigReq, 98 ipv6cp_SentTerminateReq, 99 ipv6cp_SendTerminateAck, 100 ipv6cp_DecodeConfig, 101 fsm_NullRecvResetReq, 102 fsm_NullRecvResetAck 103 }; 104 105 static u_int32_t 106 GenerateToken(void) 107 { 108 /* Generate random number which will be used as negotiation token */ 109 randinit(); 110 111 return random() + 1; 112 } 113 114 static int 115 ipcp_SetIPv6address(struct ipv6cp *ipv6cp, u_int32_t mytok, u_int32_t histok) 116 { 117 struct bundle *bundle = ipv6cp->fsm.bundle; 118 struct in6_addr myaddr, hisaddr; 119 struct ncprange myrange; 120 struct sockaddr_storage ssdst, ssgw, ssmask; 121 struct sockaddr *sadst, *sagw, *samask; 122 123 sadst = (struct sockaddr *)&ssdst; 124 sagw = (struct sockaddr *)&ssgw; 125 samask = (struct sockaddr *)&ssmask; 126 127 memset(&myaddr, '\0', sizeof myaddr); 128 memset(&hisaddr, '\0', sizeof hisaddr); 129 130 myaddr.s6_addr[0] = 0xfe; 131 myaddr.s6_addr[1] = 0x80; 132 *(u_int32_t *)(myaddr.s6_addr + 12) = htonl(mytok); 133 134 hisaddr.s6_addr[0] = 0xfe; 135 hisaddr.s6_addr[1] = 0x80; 136 *(u_int32_t *)(hisaddr.s6_addr + 12) = htonl(histok); 137 138 ncpaddr_setip6(&ipv6cp->myaddr, &myaddr); 139 ncpaddr_setip6(&ipv6cp->hisaddr, &hisaddr); 140 ncprange_sethost(&myrange, &ipv6cp->myaddr); 141 142 if (!iface_Add(bundle->iface, &bundle->ncp, &myrange, &ipv6cp->hisaddr, 143 IFACE_ADD_FIRST|IFACE_FORCE_ADD|IFACE_SYSTEM)) 144 return 0; 145 146 if (!Enabled(bundle, OPT_IFACEALIAS)) 147 iface_Clear(bundle->iface, &bundle->ncp, AF_INET6, 148 IFACE_CLEAR_ALIASES|IFACE_SYSTEM); 149 150 if (bundle->ncp.cfg.sendpipe > 0 || bundle->ncp.cfg.recvpipe > 0) { 151 ncprange_getsa(&myrange, &ssgw, &ssmask); 152 if (ncpaddr_isset(&ipv6cp->hisaddr)) 153 ncpaddr_getsa(&ipv6cp->hisaddr, &ssdst); 154 else 155 sadst = NULL; 156 rt_Update(bundle, sadst, sagw, samask); 157 } 158 159 if (Enabled(bundle, OPT_SROUTES)) 160 route_Change(bundle, bundle->ncp.route, &ipv6cp->myaddr, &ipv6cp->hisaddr); 161 162 #ifndef NORADIUS 163 if (bundle->radius.valid) 164 route_Change(bundle, bundle->radius.routes, &ipv6cp->myaddr, 165 &ipv6cp->hisaddr); 166 #endif 167 168 return 1; /* Ok */ 169 } 170 171 void 172 ipv6cp_Init(struct ipv6cp *ipv6cp, struct bundle *bundle, struct link *l, 173 const struct fsm_parent *parent) 174 { 175 static const char * const timer_names[] = 176 {"IPV6CP restart", "IPV6CP openmode", "IPV6CP stopped"}; 177 int n; 178 179 fsm_Init(&ipv6cp->fsm, "IPV6CP", PROTO_IPV6CP, 1, IPV6CP_MAXCODE, LogIPV6CP, 180 bundle, l, parent, &ipv6cp_Callbacks, timer_names); 181 182 ipv6cp->cfg.fsm.timeout = DEF_FSMRETRY; 183 ipv6cp->cfg.fsm.maxreq = DEF_FSMTRIES; 184 ipv6cp->cfg.fsm.maxtrm = DEF_FSMTRIES; 185 186 ipv6cp->my_token = GenerateToken(); 187 while ((ipv6cp->peer_token = GenerateToken()) == ipv6cp->my_token) 188 ; 189 190 if (probe.ipv6_available) { 191 n = 100; 192 while (n && 193 !ipcp_SetIPv6address(ipv6cp, ipv6cp->my_token, ipv6cp->peer_token)) { 194 n--; 195 while (n && (ipv6cp->my_token = GenerateToken()) == ipv6cp->peer_token) 196 n--; 197 } 198 } 199 200 throughput_init(&ipv6cp->throughput, SAMPLE_PERIOD); 201 memset(ipv6cp->Queue, '\0', sizeof ipv6cp->Queue); 202 ipv6cp_Setup(ipv6cp); 203 } 204 205 void 206 ipv6cp_Destroy(struct ipv6cp *ipv6cp) 207 { 208 throughput_destroy(&ipv6cp->throughput); 209 } 210 211 void 212 ipv6cp_Setup(struct ipv6cp *ipv6cp) 213 { 214 ncpaddr_init(&ipv6cp->myaddr); 215 ncpaddr_init(&ipv6cp->hisaddr); 216 217 ipv6cp->his_reject = 0; 218 ipv6cp->my_reject = 0; 219 } 220 221 void 222 ipv6cp_SetLink(struct ipv6cp *ipv6cp, struct link *l) 223 { 224 ipv6cp->fsm.link = l; 225 } 226 227 int 228 ipv6cp_Show(struct cmdargs const *arg) 229 { 230 struct ipv6cp *ipv6cp = &arg->bundle->ncp.ipv6cp; 231 232 prompt_Printf(arg->prompt, "%s [%s]\n", ipv6cp->fsm.name, 233 State2Nam(ipv6cp->fsm.state)); 234 if (ipv6cp->fsm.state == ST_OPENED) { 235 prompt_Printf(arg->prompt, " His side: %s\n", 236 ncpaddr_ntoa(&ipv6cp->hisaddr)); 237 prompt_Printf(arg->prompt, " My side: %s\n", 238 ncpaddr_ntoa(&ipv6cp->myaddr)); 239 prompt_Printf(arg->prompt, " Queued packets: %lu\n", 240 (unsigned long)ipv6cp_QueueLen(ipv6cp)); 241 } 242 243 prompt_Printf(arg->prompt, "\nDefaults:\n"); 244 prompt_Printf(arg->prompt, " FSM retry = %us, max %u Config" 245 " REQ%s, %u Term REQ%s\n\n", ipv6cp->cfg.fsm.timeout, 246 ipv6cp->cfg.fsm.maxreq, ipv6cp->cfg.fsm.maxreq == 1 ? "" : "s", 247 ipv6cp->cfg.fsm.maxtrm, ipv6cp->cfg.fsm.maxtrm == 1 ? "" : "s"); 248 249 throughput_disp(&ipv6cp->throughput, arg->prompt); 250 251 return 0; 252 } 253 254 struct mbuf * 255 ipv6cp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) 256 { 257 /* Got PROTO_IPV6CP from link */ 258 m_settype(bp, MB_IPV6CPIN); 259 if (bundle_Phase(bundle) == PHASE_NETWORK) 260 fsm_Input(&bundle->ncp.ipv6cp.fsm, bp); 261 else { 262 if (bundle_Phase(bundle) < PHASE_NETWORK) 263 log_Printf(LogIPV6CP, "%s: Error: Unexpected IPV6CP in phase %s" 264 " (ignored)\n", l->name, bundle_PhaseName(bundle)); 265 m_freem(bp); 266 } 267 return NULL; 268 } 269 270 void 271 ipv6cp_AddInOctets(struct ipv6cp *ipv6cp, int n) 272 { 273 throughput_addin(&ipv6cp->throughput, n); 274 } 275 276 void 277 ipv6cp_AddOutOctets(struct ipv6cp *ipv6cp, int n) 278 { 279 throughput_addout(&ipv6cp->throughput, n); 280 } 281 282 void 283 ipv6cp_IfaceAddrAdded(struct ipv6cp *ipv6cp, const struct iface_addr *addr) 284 { 285 } 286 287 void 288 ipv6cp_IfaceAddrDeleted(struct ipv6cp *ipv6cp, const struct iface_addr *addr) 289 { 290 } 291 292 int 293 ipv6cp_InterfaceUp(struct ipv6cp *ipv6cp) 294 { 295 if (!ipcp_SetIPv6address(ipv6cp, ipv6cp->my_token, ipv6cp->peer_token)) { 296 log_Printf(LogERROR, "ipv6cp_InterfaceUp: unable to set ipv6 address\n"); 297 return 0; 298 } 299 300 if (!iface_SetFlags(ipv6cp->fsm.bundle->iface->name, IFF_UP)) { 301 log_Printf(LogERROR, "ipv6cp_InterfaceUp: Can't set the IFF_UP" 302 " flag on %s\n", ipv6cp->fsm.bundle->iface->name); 303 return 0; 304 } 305 306 return 1; 307 } 308 309 size_t 310 ipv6cp_QueueLen(struct ipv6cp *ipv6cp) 311 { 312 struct mqueue *q; 313 size_t result; 314 315 result = 0; 316 for (q = ipv6cp->Queue; q < ipv6cp->Queue + IPV6CP_QUEUES(ipv6cp); q++) 317 result += q->len; 318 319 return result; 320 } 321 322 int 323 ipv6cp_PushPacket(struct ipv6cp *ipv6cp, struct link *l) 324 { 325 struct bundle *bundle = ipv6cp->fsm.bundle; 326 struct mqueue *queue; 327 struct mbuf *bp; 328 int m_len; 329 u_int32_t secs = 0; 330 unsigned alivesecs = 0; 331 332 if (ipv6cp->fsm.state != ST_OPENED) 333 return 0; 334 335 /* 336 * If ccp is not open but is required, do nothing. 337 */ 338 if (l->ccp.fsm.state != ST_OPENED && ccp_Required(&l->ccp)) { 339 log_Printf(LogPHASE, "%s: Not transmitting... waiting for CCP\n", l->name); 340 return 0; 341 } 342 343 queue = ipv6cp->Queue + IPV6CP_QUEUES(ipv6cp) - 1; 344 do { 345 if (queue->top) { 346 bp = m_dequeue(queue); 347 bp = mbuf_Read(bp, &secs, sizeof secs); 348 bp = m_pullup(bp); 349 m_len = m_length(bp); 350 if (!FilterCheck(MBUF_CTOP(bp), AF_INET6, &bundle->filter.alive, 351 &alivesecs)) { 352 if (secs == 0) 353 secs = alivesecs; 354 bundle_StartIdleTimer(bundle, secs); 355 } 356 link_PushPacket(l, bp, bundle, 0, PROTO_IPV6); 357 ipv6cp_AddOutOctets(ipv6cp, m_len); 358 return 1; 359 } 360 } while (queue-- != ipv6cp->Queue); 361 362 return 0; 363 } 364 365 static int 366 ipv6cp_LayerUp(struct fsm *fp) 367 { 368 /* We're now up */ 369 struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 370 char tbuff[40]; 371 372 log_Printf(LogIPV6CP, "%s: LayerUp.\n", fp->link->name); 373 if (!ipv6cp_InterfaceUp(ipv6cp)) 374 return 0; 375 376 snprintf(tbuff, sizeof tbuff, "%s", ncpaddr_ntoa(&ipv6cp->myaddr)); 377 log_Printf(LogIPV6CP, "myaddr %s hisaddr = %s\n", 378 tbuff, ncpaddr_ntoa(&ipv6cp->hisaddr)); 379 380 /* XXX: Call radius_Account() and system_Select() */ 381 382 fp->more.reqs = fp->more.naks = fp->more.rejs = ipv6cp->cfg.fsm.maxreq * 3; 383 log_DisplayPrompts(); 384 385 return 1; 386 } 387 388 static void 389 ipv6cp_LayerDown(struct fsm *fp) 390 { 391 /* About to come down */ 392 struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 393 static int recursing; 394 char addr[40]; 395 396 if (!recursing++) { 397 snprintf(addr, sizeof addr, "%s", ncpaddr_ntoa(&ipv6cp->myaddr)); 398 log_Printf(LogIPV6CP, "%s: LayerDown: %s\n", fp->link->name, addr); 399 400 /* XXX: Call radius_Account() and system_Select() */ 401 402 ipv6cp_Setup(ipv6cp); 403 } 404 recursing--; 405 } 406 407 static void 408 ipv6cp_LayerStart(struct fsm *fp) 409 { 410 /* We're about to start up ! */ 411 struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 412 413 log_Printf(LogIPV6CP, "%s: LayerStart.\n", fp->link->name); 414 throughput_start(&ipv6cp->throughput, "IPV6CP throughput", 415 Enabled(fp->bundle, OPT_THROUGHPUT)); 416 fp->more.reqs = fp->more.naks = fp->more.rejs = ipv6cp->cfg.fsm.maxreq * 3; 417 ipv6cp->peer_tokenreq = 0; 418 } 419 420 static void 421 ipv6cp_LayerFinish(struct fsm *fp) 422 { 423 /* We're now down */ 424 struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 425 426 log_Printf(LogIPV6CP, "%s: LayerFinish.\n", fp->link->name); 427 throughput_stop(&ipv6cp->throughput); 428 throughput_log(&ipv6cp->throughput, LogIPV6CP, NULL); 429 } 430 431 static void 432 ipv6cp_InitRestartCounter(struct fsm *fp, int what) 433 { 434 /* Set fsm timer load */ 435 struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 436 437 fp->FsmTimer.load = ipv6cp->cfg.fsm.timeout * SECTICKS; 438 switch (what) { 439 case FSM_REQ_TIMER: 440 fp->restart = ipv6cp->cfg.fsm.maxreq; 441 break; 442 case FSM_TRM_TIMER: 443 fp->restart = ipv6cp->cfg.fsm.maxtrm; 444 break; 445 default: 446 fp->restart = 1; 447 break; 448 } 449 } 450 451 static void 452 ipv6cp_SendConfigReq(struct fsm *fp) 453 { 454 /* Send config REQ please */ 455 struct physical *p = link2physical(fp->link); 456 struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 457 u_char buff[6]; 458 struct fsm_opt *o; 459 460 o = (struct fsm_opt *)buff; 461 462 if ((p && !physical_IsSync(p)) || !REJECTED(ipv6cp, TY_TOKEN)) { 463 memcpy(o->data, &ipv6cp->my_token, 4); 464 INC_FSM_OPT(TY_TOKEN, 6, o); 465 } 466 467 fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, (u_char *)o - buff, 468 MB_IPV6CPOUT); 469 } 470 471 static void 472 ipv6cp_SentTerminateReq(struct fsm *fp) 473 { 474 /* Term REQ just sent by FSM */ 475 } 476 477 static void 478 ipv6cp_SendTerminateAck(struct fsm *fp, u_char id) 479 { 480 /* Send Term ACK please */ 481 fsm_Output(fp, CODE_TERMACK, id, NULL, 0, MB_IPV6CPOUT); 482 } 483 484 static const char * 485 protoname(int proto) 486 { 487 static const char *cftypes[] = { "TOKEN", "COMPPROTO" }; 488 489 if (proto > 0 && proto <= sizeof cftypes / sizeof *cftypes) 490 return cftypes[proto - 1]; 491 492 return NumStr(proto, NULL, 0); 493 } 494 495 static void 496 ipv6cp_ValidateToken(struct ipv6cp *ipv6cp, u_int32_t token, 497 struct fsm_decode *dec) 498 { 499 struct fsm_opt opt; 500 501 if (token != 0 && token != ipv6cp->my_token) 502 ipv6cp->peer_token = token; 503 504 opt.hdr.id = TY_TOKEN; 505 opt.hdr.len = 6; 506 memcpy(opt.data, &ipv6cp->peer_token, 4); 507 if (token == ipv6cp->peer_token) 508 fsm_ack(dec, &opt); 509 else 510 fsm_nak(dec, &opt); 511 } 512 513 static void 514 ipv6cp_DecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type, 515 struct fsm_decode *dec) 516 { 517 /* Deal with incoming PROTO_IPV6CP */ 518 struct ipv6cp *ipv6cp = fsm2ipv6cp(fp); 519 int n; 520 char tbuff[100]; 521 u_int32_t token; 522 struct fsm_opt *opt; 523 524 while (end - cp >= sizeof(opt->hdr)) { 525 if ((opt = fsm_readopt(&cp)) == NULL) 526 break; 527 528 snprintf(tbuff, sizeof tbuff, " %s[%d]", protoname(opt->hdr.id), 529 opt->hdr.len); 530 531 switch (opt->hdr.id) { 532 case TY_TOKEN: 533 memcpy(&token, opt->data, 4); 534 log_Printf(LogIPV6CP, "%s 0x%08lx\n", tbuff, (unsigned long)token); 535 536 switch (mode_type) { 537 case MODE_REQ: 538 ipv6cp->peer_tokenreq = 1; 539 ipv6cp_ValidateToken(ipv6cp, token, dec); 540 break; 541 542 case MODE_NAK: 543 if (token == 0) { 544 log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE, 545 "0x00000000: Unacceptable token!\n"); 546 fsm_Close(&ipv6cp->fsm); 547 } else if (token == ipv6cp->peer_token) 548 log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE, 549 "0x%08lx: Unacceptable token!\n", (unsigned long)token); 550 else if (token != ipv6cp->my_token) { 551 n = 100; 552 while (n && !ipcp_SetIPv6address(ipv6cp, token, ipv6cp->peer_token)) { 553 n--; 554 while (n && (token = GenerateToken()) == ipv6cp->peer_token) 555 n--; 556 } 557 558 if (n == 0) { 559 log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE, 560 "0x00000000: Unacceptable token!\n"); 561 fsm_Close(&ipv6cp->fsm); 562 } else { 563 log_Printf(LogIPV6CP, "%s changing token: 0x%08lx --> 0x%08lx\n", 564 tbuff, (unsigned long)ipv6cp->my_token, 565 (unsigned long)token); 566 ipv6cp->my_token = token; 567 bundle_AdjustFilters(fp->bundle, &ipv6cp->myaddr, NULL); 568 } 569 } 570 break; 571 572 case MODE_REJ: 573 ipv6cp->his_reject |= (1 << opt->hdr.id); 574 break; 575 } 576 break; 577 578 default: 579 if (mode_type != MODE_NOP) { 580 ipv6cp->my_reject |= (1 << opt->hdr.id); 581 fsm_rej(dec, opt); 582 } 583 break; 584 } 585 } 586 587 if (mode_type != MODE_NOP) { 588 if (mode_type == MODE_REQ && !ipv6cp->peer_tokenreq) { 589 if (dec->rejend == dec->rej && dec->nakend == dec->nak) { 590 /* 591 * Pretend the peer has requested a TOKEN. 592 * We do this to ensure that we only send one NAK if the only 593 * reason for the NAK is because the peer isn't sending a 594 * TY_TOKEN REQ. This stops us from repeatedly trying to tell 595 * the peer that we have to have an IP address on their end. 596 */ 597 ipv6cp->peer_tokenreq = 1; 598 } 599 ipv6cp_ValidateToken(ipv6cp, 0, dec); 600 } 601 fsm_opt_normalise(dec); 602 } 603 } 604 #endif 605