1 /*- 2 * Copyright (c) 2001-2006, Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * b) Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the distribution. 13 * 14 * c) Neither the name of Cisco Systems, Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* $KAME: sctp_asconf.c,v 1.24 2005/03/06 16:04:16 itojun Exp $ */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 37 38 #include "opt_ipsec.h" 39 #include "opt_compat.h" 40 #include "opt_inet6.h" 41 #include "opt_inet.h" 42 43 #include "opt_sctp.h" 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/malloc.h> 48 #include <sys/mbuf.h> 49 #include <sys/socket.h> 50 #include <sys/socketvar.h> 51 #include <sys/kernel.h> 52 #include <sys/sysctl.h> 53 54 #include <net/if.h> 55 #include <net/if_types.h> 56 #include <net/route.h> 57 58 #include <netinet/in.h> 59 #include <netinet/in_systm.h> 60 #include <netinet/ip.h> 61 #include <netinet/in_pcb.h> 62 #include <netinet/in_var.h> 63 #include <netinet/ip_var.h> 64 65 #ifdef INET6 66 #include <netinet/ip6.h> 67 #include <netinet6/ip6_var.h> 68 #include <netinet6/in6_pcb.h> 69 #include <netinet/icmp6.h> 70 #include <netinet6/nd6.h> 71 #include <netinet6/scope6_var.h> 72 #endif /* INET6 */ 73 74 #include <netinet/in_pcb.h> 75 76 #include <netinet/sctp_os.h> 77 #include <netinet/sctp_var.h> 78 #include <netinet/sctp_pcb.h> 79 #include <netinet/sctp_header.h> 80 #include <netinet/sctputil.h> 81 #include <netinet/sctp_output.h> 82 #include <netinet/sctp_bsd_addr.h> 83 #include <netinet/sctp_asconf.h> 84 85 /* 86 * debug flags: 87 * SCTP_DEBUG_ASCONF1: protocol info, general info and errors 88 * SCTP_DEBUG_ASCONF2: detailed info 89 */ 90 #ifdef SCTP_DEBUG 91 extern uint32_t sctp_debug_on; 92 93 #endif /* SCTP_DEBUG */ 94 95 96 static int 97 sctp_asconf_get_source_ip(struct mbuf *m, struct sockaddr *sa) 98 { 99 struct ip *iph; 100 struct sockaddr_in *sin; 101 102 #ifdef INET6 103 struct sockaddr_in6 *sin6; 104 105 #endif 106 107 iph = mtod(m, struct ip *); 108 if (iph->ip_v == IPVERSION) { 109 /* IPv4 source */ 110 sin = (struct sockaddr_in *)sa; 111 bzero(sin, sizeof(*sin)); 112 sin->sin_family = AF_INET; 113 sin->sin_len = sizeof(struct sockaddr_in); 114 sin->sin_port = 0; 115 sin->sin_addr.s_addr = iph->ip_src.s_addr; 116 return 0; 117 } 118 #ifdef INET6 119 else if (iph->ip_v == (IPV6_VERSION >> 4)) { 120 /* IPv6 source */ 121 struct ip6_hdr *ip6; 122 123 sin6 = (struct sockaddr_in6 *)sa; 124 bzero(sin6, sizeof(*sin6)); 125 sin6->sin6_family = AF_INET6; 126 sin6->sin6_len = sizeof(struct sockaddr_in6); 127 sin6->sin6_port = 0; 128 ip6 = mtod(m, struct ip6_hdr *); 129 sin6->sin6_addr = ip6->ip6_src; 130 return 0; 131 } 132 #endif /* INET6 */ 133 else 134 return -1; 135 } 136 137 /* 138 * draft-ietf-tsvwg-addip-sctp 139 * 140 * Address management only currently supported For the bound all case: the asoc 141 * local addr list is always a "DO NOT USE" list For the subset bound case: 142 * If ASCONFs are allowed: the endpoint local addr list is the usable address 143 * list the asoc local addr list is the "DO NOT USE" list If ASCONFs are not 144 * allowed: the endpoint local addr list is the default usable list the asoc 145 * local addr list is the usable address list 146 * 147 * An ASCONF parameter queue exists per asoc which holds the pending address 148 * operations. Lists are updated upon receipt of ASCONF-ACK. 149 * 150 * Deleted addresses are always immediately removed from the lists as they will 151 * (shortly) no longer exist in the kernel. We send ASCONFs as a courtesy, 152 * only if allowed. 153 */ 154 155 /* 156 * ASCONF parameter processing response_required: set if a reply is required 157 * (eg. SUCCESS_REPORT) returns a mbuf to an "error" response parameter or 158 * NULL/"success" if ok FIX: allocating this many mbufs on the fly is pretty 159 * inefficient... 160 */ 161 static struct mbuf * 162 sctp_asconf_success_response(uint32_t id) 163 { 164 struct mbuf *m_reply = NULL; 165 struct sctp_asconf_paramhdr *aph; 166 167 m_reply = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_paramhdr), 168 0, M_DONTWAIT, 1, MT_DATA); 169 if (m_reply == NULL) { 170 #ifdef SCTP_DEBUG 171 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 172 printf("asconf_success_response: couldn't get mbuf!\n"); 173 } 174 #endif /* SCTP_DEBUG */ 175 return NULL; 176 } 177 aph = mtod(m_reply, struct sctp_asconf_paramhdr *); 178 aph->correlation_id = id; 179 aph->ph.param_type = htons(SCTP_SUCCESS_REPORT); 180 aph->ph.param_length = sizeof(struct sctp_asconf_paramhdr); 181 SCTP_BUF_LEN(m_reply) = aph->ph.param_length; 182 aph->ph.param_length = htons(aph->ph.param_length); 183 184 return m_reply; 185 } 186 187 static struct mbuf * 188 sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t * error_tlv, 189 uint16_t tlv_length) 190 { 191 struct mbuf *m_reply = NULL; 192 struct sctp_asconf_paramhdr *aph; 193 struct sctp_error_cause *error; 194 uint8_t *tlv; 195 196 m_reply = sctp_get_mbuf_for_msg((sizeof(struct sctp_asconf_paramhdr) + 197 tlv_length + 198 sizeof(struct sctp_error_cause)), 199 0, M_DONTWAIT, 1, MT_DATA); 200 if (m_reply == NULL) { 201 #ifdef SCTP_DEBUG 202 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 203 printf("asconf_error_response: couldn't get mbuf!\n"); 204 } 205 #endif /* SCTP_DEBUG */ 206 return NULL; 207 } 208 aph = mtod(m_reply, struct sctp_asconf_paramhdr *); 209 error = (struct sctp_error_cause *)(aph + 1); 210 211 aph->correlation_id = id; 212 aph->ph.param_type = htons(SCTP_ERROR_CAUSE_IND); 213 error->code = htons(cause); 214 error->length = tlv_length + sizeof(struct sctp_error_cause); 215 aph->ph.param_length = error->length + 216 sizeof(struct sctp_asconf_paramhdr); 217 218 if (aph->ph.param_length > MLEN) { 219 #ifdef SCTP_DEBUG 220 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 221 printf("asconf_error_response: tlv_length (%xh) too big\n", 222 tlv_length); 223 } 224 #endif /* SCTP_DEBUG */ 225 sctp_m_freem(m_reply); /* discard */ 226 return NULL; 227 } 228 if (error_tlv != NULL) { 229 tlv = (uint8_t *) (error + 1); 230 memcpy(tlv, error_tlv, tlv_length); 231 } 232 SCTP_BUF_LEN(m_reply) = aph->ph.param_length; 233 error->length = htons(error->length); 234 aph->ph.param_length = htons(aph->ph.param_length); 235 236 return m_reply; 237 } 238 239 static struct mbuf * 240 sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph, 241 struct sctp_tcb *stcb, int response_required) 242 { 243 struct mbuf *m_reply = NULL; 244 struct sockaddr_storage sa_source, sa_store; 245 struct sctp_ipv4addr_param *v4addr; 246 uint16_t param_type, param_length, aparam_length; 247 struct sockaddr *sa; 248 struct sockaddr_in *sin; 249 int zero_address = 0; 250 251 #ifdef INET6 252 struct sockaddr_in6 *sin6; 253 struct sctp_ipv6addr_param *v6addr; 254 255 #endif /* INET6 */ 256 257 aparam_length = ntohs(aph->ph.param_length); 258 v4addr = (struct sctp_ipv4addr_param *)(aph + 1); 259 #ifdef INET6 260 v6addr = (struct sctp_ipv6addr_param *)(aph + 1); 261 #endif /* INET6 */ 262 param_type = ntohs(v4addr->ph.param_type); 263 param_length = ntohs(v4addr->ph.param_length); 264 265 sa = (struct sockaddr *)&sa_store; 266 switch (param_type) { 267 case SCTP_IPV4_ADDRESS: 268 if (param_length != sizeof(struct sctp_ipv4addr_param)) { 269 /* invalid param size */ 270 return NULL; 271 } 272 sin = (struct sockaddr_in *)&sa_store; 273 bzero(sin, sizeof(*sin)); 274 sin->sin_family = AF_INET; 275 sin->sin_len = sizeof(struct sockaddr_in); 276 sin->sin_port = stcb->rport; 277 sin->sin_addr.s_addr = v4addr->addr; 278 if (sin->sin_addr.s_addr == INADDR_ANY) 279 zero_address = 1; 280 #ifdef SCTP_DEBUG 281 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 282 printf("process_asconf_add_ip: adding "); 283 sctp_print_address(sa); 284 } 285 #endif /* SCTP_DEBUG */ 286 break; 287 case SCTP_IPV6_ADDRESS: 288 #ifdef INET6 289 if (param_length != sizeof(struct sctp_ipv6addr_param)) { 290 /* invalid param size */ 291 return NULL; 292 } 293 sin6 = (struct sockaddr_in6 *)&sa_store; 294 bzero(sin6, sizeof(*sin6)); 295 sin6->sin6_family = AF_INET6; 296 sin6->sin6_len = sizeof(struct sockaddr_in6); 297 sin6->sin6_port = stcb->rport; 298 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr, 299 sizeof(struct in6_addr)); 300 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) 301 zero_address = 1; 302 #ifdef SCTP_DEBUG 303 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 304 printf("process_asconf_add_ip: adding "); 305 sctp_print_address(sa); 306 } 307 #endif /* SCTP_DEBUG */ 308 #else 309 /* IPv6 not enabled! */ 310 /* FIX ME: currently sends back an invalid param error */ 311 m_reply = sctp_asconf_error_response(aph->correlation_id, 312 SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph, aparam_length); 313 #ifdef SCTP_DEBUG 314 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 315 printf("process_asconf_add_ip: v6 disabled- skipping "); 316 sctp_print_address(sa); 317 } 318 #endif /* SCTP_DEBUG */ 319 return m_reply; 320 #endif /* INET6 */ 321 break; 322 default: 323 m_reply = sctp_asconf_error_response(aph->correlation_id, 324 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph, 325 aparam_length); 326 return m_reply; 327 } /* end switch */ 328 329 /* if 0.0.0.0/::0, add the source address instead */ 330 if (zero_address && sctp_nat_friendly) { 331 sa = (struct sockaddr *)&sa_source; 332 sctp_asconf_get_source_ip(m, sa); 333 #ifdef SCTP_DEBUG 334 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 335 printf("process_asconf_add_ip: using source addr "); 336 sctp_print_address(sa); 337 } 338 #endif /* SCTP_DEBUG */ 339 } 340 /* add the address */ 341 if (sctp_add_remote_addr(stcb, sa, SCTP_DONOT_SETSCOPE, 342 SCTP_ADDR_DYNAMIC_ADDED) != 0) { 343 #ifdef SCTP_DEBUG 344 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 345 printf("process_asconf_add_ip: error adding address\n"); 346 } 347 #endif /* SCTP_DEBUG */ 348 m_reply = sctp_asconf_error_response(aph->correlation_id, 349 SCTP_CAUSE_RESOURCE_SHORTAGE, (uint8_t *) aph, 350 aparam_length); 351 } else { 352 /* notify upper layer */ 353 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_ADD_IP, stcb, 0, sa); 354 if (response_required) { 355 m_reply = 356 sctp_asconf_success_response(aph->correlation_id); 357 } 358 sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_ASCONF + SCTP_LOC_1); 359 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, NULL); 360 361 } 362 363 return m_reply; 364 } 365 366 static int 367 sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, 368 struct sockaddr *src) 369 { 370 struct sctp_nets *src_net, *net; 371 372 /* make sure the source address exists as a destination net */ 373 src_net = sctp_findnet(stcb, src); 374 if (src_net == NULL) { 375 /* not found */ 376 return -1; 377 } 378 /* delete all destination addresses except the source */ 379 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 380 if (net != src_net) { 381 /* delete this address */ 382 sctp_remove_net(stcb, net); 383 #ifdef SCTP_DEBUG 384 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 385 printf("asconf_del_remote_addrs_except: deleting "); 386 sctp_print_address((struct sockaddr *)&net->ro._l_addr); 387 } 388 #endif 389 /* notify upper layer */ 390 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, 391 (struct sockaddr *)&net->ro._l_addr); 392 } 393 } 394 return 0; 395 } 396 397 static struct mbuf * 398 sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph, 399 struct sctp_tcb *stcb, int response_required) 400 { 401 struct mbuf *m_reply = NULL; 402 struct sockaddr_storage sa_source, sa_store; 403 struct sctp_ipv4addr_param *v4addr; 404 uint16_t param_type, param_length, aparam_length; 405 struct sockaddr *sa; 406 struct sockaddr_in *sin; 407 int zero_address = 0; 408 int result; 409 410 #ifdef INET6 411 struct sockaddr_in6 *sin6; 412 struct sctp_ipv6addr_param *v6addr; 413 414 #endif /* INET6 */ 415 416 /* get the source IP address for src and 0.0.0.0/::0 delete checks */ 417 sctp_asconf_get_source_ip(m, (struct sockaddr *)&sa_source); 418 419 aparam_length = ntohs(aph->ph.param_length); 420 v4addr = (struct sctp_ipv4addr_param *)(aph + 1); 421 #ifdef INET6 422 v6addr = (struct sctp_ipv6addr_param *)(aph + 1); 423 #endif /* INET6 */ 424 param_type = ntohs(v4addr->ph.param_type); 425 param_length = ntohs(v4addr->ph.param_length); 426 427 sa = (struct sockaddr *)&sa_store; 428 switch (param_type) { 429 case SCTP_IPV4_ADDRESS: 430 if (param_length != sizeof(struct sctp_ipv4addr_param)) { 431 /* invalid param size */ 432 return NULL; 433 } 434 sin = (struct sockaddr_in *)&sa_store; 435 bzero(sin, sizeof(*sin)); 436 sin->sin_family = AF_INET; 437 sin->sin_len = sizeof(struct sockaddr_in); 438 sin->sin_port = stcb->rport; 439 sin->sin_addr.s_addr = v4addr->addr; 440 if (sin->sin_addr.s_addr == INADDR_ANY) 441 zero_address = 1; 442 #ifdef SCTP_DEBUG 443 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 444 printf("process_asconf_delete_ip: deleting "); 445 sctp_print_address(sa); 446 } 447 #endif /* SCTP_DEBUG */ 448 break; 449 case SCTP_IPV6_ADDRESS: 450 if (param_length != sizeof(struct sctp_ipv6addr_param)) { 451 /* invalid param size */ 452 return NULL; 453 } 454 #ifdef INET6 455 sin6 = (struct sockaddr_in6 *)&sa_store; 456 bzero(sin6, sizeof(*sin6)); 457 sin6->sin6_family = AF_INET6; 458 sin6->sin6_len = sizeof(struct sockaddr_in6); 459 sin6->sin6_port = stcb->rport; 460 memcpy(&sin6->sin6_addr, v6addr->addr, 461 sizeof(struct in6_addr)); 462 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) 463 zero_address = 1; 464 #ifdef SCTP_DEBUG 465 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 466 printf("process_asconf_delete_ip: deleting "); 467 sctp_print_address(sa); 468 } 469 #endif /* SCTP_DEBUG */ 470 #else 471 /* IPv6 not enabled! No "action" needed; just ack it */ 472 #ifdef SCTP_DEBUG 473 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 474 printf("process_asconf_delete_ip: v6 disabled- ignoring: "); 475 sctp_print_address(sa); 476 } 477 #endif /* SCTP_DEBUG */ 478 /* just respond with a "success" ASCONF-ACK */ 479 return NULL; 480 #endif /* INET6 */ 481 break; 482 default: 483 m_reply = sctp_asconf_error_response(aph->correlation_id, 484 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph, 485 aparam_length); 486 return m_reply; 487 } 488 489 /* make sure the source address is not being deleted */ 490 if (sctp_cmpaddr(sa, (struct sockaddr *)&sa_source)) { 491 /* trying to delete the source address! */ 492 #ifdef SCTP_DEBUG 493 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 494 printf("process_asconf_delete_ip: tried to delete source addr\n"); 495 } 496 #endif /* SCTP_DEBUG */ 497 m_reply = sctp_asconf_error_response(aph->correlation_id, 498 SCTP_CAUSE_DELETING_SRC_ADDR, (uint8_t *) aph, 499 aparam_length); 500 return m_reply; 501 } 502 /* if deleting 0.0.0.0/::0, delete all addresses except src addr */ 503 if (zero_address && sctp_nat_friendly) { 504 result = sctp_asconf_del_remote_addrs_except(stcb, 505 (struct sockaddr *)&sa_source); 506 507 if (result) { 508 /* src address did not exist? */ 509 #ifdef SCTP_DEBUG 510 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 511 printf("process_asconf_delete_ip: src addr does not exist?\n"); 512 } 513 #endif /* SCTP_DEBUG */ 514 /* what error to reply with?? */ 515 m_reply = 516 sctp_asconf_error_response(aph->correlation_id, 517 SCTP_CAUSE_REQUEST_REFUSED, (uint8_t *) aph, 518 aparam_length); 519 } else if (response_required) { 520 m_reply = 521 sctp_asconf_success_response(aph->correlation_id); 522 } 523 return m_reply; 524 } 525 /* delete the address */ 526 result = sctp_del_remote_addr(stcb, sa); 527 /* 528 * note if result == -2, the address doesn't exist in the asoc but 529 * since it's being deleted anyways, we just ack the delete -- but 530 * this probably means something has already gone awry 531 */ 532 if (result == -1) { 533 /* only one address in the asoc */ 534 #ifdef SCTP_DEBUG 535 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 536 printf("process_asconf_delete_ip: tried to delete last IP addr!\n"); 537 } 538 #endif /* SCTP_DEBUG */ 539 m_reply = sctp_asconf_error_response(aph->correlation_id, 540 SCTP_CAUSE_DELETING_LAST_ADDR, (uint8_t *) aph, 541 aparam_length); 542 } else { 543 if (response_required) { 544 m_reply = sctp_asconf_success_response(aph->correlation_id); 545 } 546 /* notify upper layer */ 547 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, sa); 548 } 549 return m_reply; 550 } 551 552 static struct mbuf * 553 sctp_process_asconf_set_primary(struct mbuf *m, 554 struct sctp_asconf_paramhdr *aph, struct sctp_tcb *stcb, 555 int response_required) 556 { 557 struct mbuf *m_reply = NULL; 558 struct sockaddr_storage sa_source, sa_store; 559 struct sctp_ipv4addr_param *v4addr; 560 uint16_t param_type, param_length, aparam_length; 561 struct sockaddr *sa; 562 struct sockaddr_in *sin; 563 int zero_address = 0; 564 565 #ifdef INET6 566 struct sockaddr_in6 *sin6; 567 struct sctp_ipv6addr_param *v6addr; 568 569 #endif /* INET6 */ 570 571 aparam_length = ntohs(aph->ph.param_length); 572 v4addr = (struct sctp_ipv4addr_param *)(aph + 1); 573 #ifdef INET6 574 v6addr = (struct sctp_ipv6addr_param *)(aph + 1); 575 #endif /* INET6 */ 576 param_type = ntohs(v4addr->ph.param_type); 577 param_length = ntohs(v4addr->ph.param_length); 578 579 sa = (struct sockaddr *)&sa_store; 580 switch (param_type) { 581 case SCTP_IPV4_ADDRESS: 582 if (param_length != sizeof(struct sctp_ipv4addr_param)) { 583 /* invalid param size */ 584 return NULL; 585 } 586 sin = (struct sockaddr_in *)&sa_store; 587 bzero(sin, sizeof(*sin)); 588 sin->sin_family = AF_INET; 589 sin->sin_len = sizeof(struct sockaddr_in); 590 sin->sin_addr.s_addr = v4addr->addr; 591 if (sin->sin_addr.s_addr == INADDR_ANY) 592 zero_address = 1; 593 #ifdef SCTP_DEBUG 594 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 595 printf("process_asconf_set_primary: "); 596 sctp_print_address(sa); 597 } 598 #endif /* SCTP_DEBUG */ 599 break; 600 case SCTP_IPV6_ADDRESS: 601 if (param_length != sizeof(struct sctp_ipv6addr_param)) { 602 /* invalid param size */ 603 return NULL; 604 } 605 #ifdef INET6 606 sin6 = (struct sockaddr_in6 *)&sa_store; 607 bzero(sin6, sizeof(*sin6)); 608 sin6->sin6_family = AF_INET6; 609 sin6->sin6_len = sizeof(struct sockaddr_in6); 610 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr, 611 sizeof(struct in6_addr)); 612 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) 613 zero_address = 1; 614 #ifdef SCTP_DEBUG 615 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 616 printf("process_asconf_set_primary: "); 617 sctp_print_address(sa); 618 } 619 #endif /* SCTP_DEBUG */ 620 #else 621 /* IPv6 not enabled! No "action" needed; just ack it */ 622 #ifdef SCTP_DEBUG 623 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 624 printf("process_asconf_set_primary: v6 disabled- ignoring: "); 625 sctp_print_address(sa); 626 } 627 #endif /* SCTP_DEBUG */ 628 /* just respond with a "success" ASCONF-ACK */ 629 return NULL; 630 #endif /* INET6 */ 631 break; 632 default: 633 m_reply = sctp_asconf_error_response(aph->correlation_id, 634 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph, 635 aparam_length); 636 return m_reply; 637 } 638 639 /* if 0.0.0.0/::0, use the source address instead */ 640 if (zero_address && sctp_nat_friendly) { 641 sa = (struct sockaddr *)&sa_source; 642 sctp_asconf_get_source_ip(m, sa); 643 #ifdef SCTP_DEBUG 644 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 645 printf("process_asconf_set_primary: using source addr "); 646 sctp_print_address(sa); 647 } 648 #endif /* SCTP_DEBUG */ 649 } 650 /* set the primary address */ 651 if (sctp_set_primary_addr(stcb, sa, NULL) == 0) { 652 #ifdef SCTP_DEBUG 653 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 654 printf("process_asconf_set_primary: primary address set\n"); 655 } 656 #endif /* SCTP_DEBUG */ 657 /* notify upper layer */ 658 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_SET_PRIMARY, stcb, 0, sa); 659 660 if (response_required) { 661 m_reply = sctp_asconf_success_response(aph->correlation_id); 662 } 663 } else { 664 /* couldn't set the requested primary address! */ 665 #ifdef SCTP_DEBUG 666 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 667 printf("process_asconf_set_primary: set primary failed!\n"); 668 } 669 #endif /* SCTP_DEBUG */ 670 /* must have been an invalid address, so report */ 671 m_reply = sctp_asconf_error_response(aph->correlation_id, 672 SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph, 673 aparam_length); 674 } 675 676 return m_reply; 677 } 678 679 /* 680 * handles an ASCONF chunk. 681 * if all parameters are processed ok, send a plain (empty) ASCONF-ACK 682 */ 683 void 684 sctp_handle_asconf(struct mbuf *m, unsigned int offset, 685 struct sctp_asconf_chunk *cp, struct sctp_tcb *stcb) 686 { 687 struct sctp_association *asoc; 688 uint32_t serial_num; 689 struct mbuf *m_ack, *m_result, *m_tail; 690 struct sctp_asconf_ack_chunk *ack_cp; 691 struct sctp_asconf_paramhdr *aph, *ack_aph; 692 struct sctp_ipv6addr_param *p_addr; 693 unsigned int asconf_limit; 694 int error = 0; /* did an error occur? */ 695 696 /* asconf param buffer */ 697 static uint8_t aparam_buf[DEFAULT_PARAM_BUFFER]; 698 699 /* verify minimum length */ 700 if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_chunk)) { 701 #ifdef SCTP_DEBUG 702 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 703 printf("handle_asconf: chunk too small = %xh\n", 704 ntohs(cp->ch.chunk_length)); 705 } 706 #endif /* SCTP_DEBUG */ 707 return; 708 } 709 asoc = &stcb->asoc; 710 serial_num = ntohl(cp->serial_number); 711 712 if (serial_num == asoc->asconf_seq_in) { 713 /* got a duplicate ASCONF */ 714 #ifdef SCTP_DEBUG 715 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 716 printf("handle_asconf: got duplicate serial number = %xh\n", 717 serial_num); 718 } 719 #endif /* SCTP_DEBUG */ 720 /* resend last ASCONF-ACK... */ 721 sctp_send_asconf_ack(stcb, 1); 722 return; 723 } else if (serial_num != (asoc->asconf_seq_in + 1)) { 724 #ifdef SCTP_DEBUG 725 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 726 printf("handle_asconf: incorrect serial number = %xh (expected next = %xh)\n", 727 serial_num, asoc->asconf_seq_in + 1); 728 } 729 #endif /* SCTP_DEBUG */ 730 return; 731 } 732 /* it's the expected "next" sequence number, so process it */ 733 asoc->asconf_seq_in = serial_num; /* update sequence */ 734 /* get length of all the param's in the ASCONF */ 735 asconf_limit = offset + ntohs(cp->ch.chunk_length); 736 #ifdef SCTP_DEBUG 737 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 738 printf("handle_asconf: asconf_limit=%u, sequence=%xh\n", 739 asconf_limit, serial_num); 740 } 741 #endif /* SCTP_DEBUG */ 742 if (asoc->last_asconf_ack_sent != NULL) { 743 /* free last ASCONF-ACK message sent */ 744 sctp_m_freem(asoc->last_asconf_ack_sent); 745 asoc->last_asconf_ack_sent = NULL; 746 } 747 m_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_ack_chunk), 0, 748 M_DONTWAIT, 1, MT_DATA); 749 if (m_ack == NULL) { 750 #ifdef SCTP_DEBUG 751 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 752 printf("handle_asconf: couldn't get mbuf!\n"); 753 } 754 #endif /* SCTP_DEBUG */ 755 return; 756 } 757 m_tail = m_ack; /* current reply chain's tail */ 758 759 /* fill in ASCONF-ACK header */ 760 ack_cp = mtod(m_ack, struct sctp_asconf_ack_chunk *); 761 ack_cp->ch.chunk_type = SCTP_ASCONF_ACK; 762 ack_cp->ch.chunk_flags = 0; 763 ack_cp->serial_number = htonl(serial_num); 764 /* set initial lengths (eg. just an ASCONF-ACK), ntohx at the end! */ 765 SCTP_BUF_LEN(m_ack) = sizeof(struct sctp_asconf_ack_chunk); 766 ack_cp->ch.chunk_length = sizeof(struct sctp_asconf_ack_chunk); 767 768 /* skip the lookup address parameter */ 769 offset += sizeof(struct sctp_asconf_chunk); 770 p_addr = (struct sctp_ipv6addr_param *)sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr), (uint8_t *) & aparam_buf); 771 if (p_addr == NULL) { 772 #ifdef SCTP_DEBUG 773 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 774 printf("handle_asconf: couldn't get lookup addr!\n"); 775 } 776 #endif /* SCTP_DEBUG */ 777 778 /* respond with a missing/invalid mandatory parameter error */ 779 return; 780 } 781 /* param_length is already validated in process_control... */ 782 offset += ntohs(p_addr->ph.param_length); /* skip lookup addr */ 783 784 /* get pointer to first asconf param in ASCONF-ACK */ 785 ack_aph = (struct sctp_asconf_paramhdr *)(mtod(m_ack, caddr_t)+sizeof(struct sctp_asconf_ack_chunk)); 786 if (ack_aph == NULL) { 787 #ifdef SCTP_DEBUG 788 printf("Gak in asconf2\n"); 789 #endif 790 return; 791 } 792 /* get pointer to first asconf param in ASCONF */ 793 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, sizeof(struct sctp_asconf_paramhdr), (uint8_t *) & aparam_buf); 794 if (aph == NULL) { 795 #ifdef SCTP_DEBUG 796 printf("Empty ASCONF received?\n"); 797 #endif 798 goto send_reply; 799 } 800 /* process through all parameters */ 801 while (aph != NULL) { 802 unsigned int param_length, param_type; 803 804 param_type = ntohs(aph->ph.param_type); 805 param_length = ntohs(aph->ph.param_length); 806 if (offset + param_length > asconf_limit) { 807 /* parameter goes beyond end of chunk! */ 808 sctp_m_freem(m_ack); 809 return; 810 } 811 m_result = NULL; 812 813 if (param_length > sizeof(aparam_buf)) { 814 #ifdef SCTP_DEBUG 815 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 816 printf("handle_asconf: param length (%u) larger than buffer size!\n", param_length); 817 } 818 #endif /* SCTP_DEBUG */ 819 sctp_m_freem(m_ack); 820 return; 821 } 822 if (param_length <= sizeof(struct sctp_paramhdr)) { 823 #ifdef SCTP_DEBUG 824 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 825 printf("handle_asconf: param length (%u) too short\n", param_length); 826 } 827 #endif /* SCTP_DEBUG */ 828 sctp_m_freem(m_ack); 829 } 830 /* get the entire parameter */ 831 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf); 832 if (aph == NULL) { 833 #ifdef SCTP_DEBUG 834 printf("Gag\n"); 835 #endif 836 sctp_m_freem(m_ack); 837 return; 838 } 839 switch (param_type) { 840 case SCTP_ADD_IP_ADDRESS: 841 asoc->peer_supports_asconf = 1; 842 m_result = sctp_process_asconf_add_ip(m, aph, stcb, 843 error); 844 break; 845 case SCTP_DEL_IP_ADDRESS: 846 asoc->peer_supports_asconf = 1; 847 m_result = sctp_process_asconf_delete_ip(m, aph, stcb, 848 error); 849 break; 850 case SCTP_ERROR_CAUSE_IND: 851 /* not valid in an ASCONF chunk */ 852 break; 853 case SCTP_SET_PRIM_ADDR: 854 asoc->peer_supports_asconf = 1; 855 m_result = sctp_process_asconf_set_primary(m, aph, 856 stcb, error); 857 break; 858 case SCTP_SUCCESS_REPORT: 859 /* not valid in an ASCONF chunk */ 860 break; 861 case SCTP_ULP_ADAPTATION: 862 /* FIX */ 863 break; 864 default: 865 if ((param_type & 0x8000) == 0) { 866 /* Been told to STOP at this param */ 867 asconf_limit = offset; 868 /* 869 * FIX FIX - We need to call 870 * sctp_arethere_unrecognized_parameters() 871 * to get a operr and send it for any 872 * param's with the 0x4000 bit set OR do it 873 * here ourselves... note we still must STOP 874 * if the 0x8000 bit is clear. 875 */ 876 } 877 /* unknown/invalid param type */ 878 break; 879 } /* switch */ 880 881 /* add any (error) result to the reply mbuf chain */ 882 if (m_result != NULL) { 883 SCTP_BUF_NEXT(m_tail) = m_result; 884 m_tail = m_result; 885 /* update lengths, make sure it's aligned too */ 886 SCTP_BUF_LEN(m_result) = SCTP_SIZE32(SCTP_BUF_LEN(m_result)); 887 ack_cp->ch.chunk_length += SCTP_BUF_LEN(m_result); 888 /* set flag to force success reports */ 889 error = 1; 890 } 891 offset += SCTP_SIZE32(param_length); 892 /* update remaining ASCONF message length to process */ 893 if (offset >= asconf_limit) { 894 /* no more data in the mbuf chain */ 895 break; 896 } 897 /* get pointer to next asconf param */ 898 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, 899 sizeof(struct sctp_asconf_paramhdr), 900 (uint8_t *) & aparam_buf); 901 if (aph == NULL) { 902 /* can't get an asconf paramhdr */ 903 #ifdef SCTP_DEBUG 904 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 905 printf("handle_asconf: can't get asconf param hdr!\n"); 906 } 907 #endif /* SCTP_DEBUG */ 908 /* FIX ME - add error here... */ 909 } 910 } /* while */ 911 912 send_reply: 913 ack_cp->ch.chunk_length = htons(ack_cp->ch.chunk_length); 914 /* save the ASCONF-ACK reply */ 915 asoc->last_asconf_ack_sent = m_ack; 916 917 /* see if last_control_chunk_from is set properly (use IP src addr) */ 918 if (stcb->asoc.last_control_chunk_from == NULL) { 919 /* 920 * this could happen if the source address was just newly 921 * added 922 */ 923 struct ip *iph; 924 struct sctphdr *sh; 925 struct sockaddr_storage from_store; 926 struct sockaddr *from = (struct sockaddr *)&from_store; 927 928 #ifdef SCTP_DEBUG 929 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) 930 printf("handle_asconf: looking up net for IP source address\n"); 931 #endif /* SCTP_DEBUG */ 932 /* pullup already done, IP options already stripped */ 933 iph = mtod(m, struct ip *); 934 sh = (struct sctphdr *)((caddr_t)iph + sizeof(*iph)); 935 if (iph->ip_v == IPVERSION) { 936 struct sockaddr_in *from4; 937 938 from4 = (struct sockaddr_in *)&from_store; 939 bzero(from4, sizeof(*from4)); 940 from4->sin_family = AF_INET; 941 from4->sin_len = sizeof(struct sockaddr_in); 942 from4->sin_addr.s_addr = iph->ip_src.s_addr; 943 from4->sin_port = sh->src_port; 944 } else if (iph->ip_v == (IPV6_VERSION >> 4)) { 945 struct ip6_hdr *ip6; 946 struct sockaddr_in6 *from6; 947 948 ip6 = mtod(m, struct ip6_hdr *); 949 from6 = (struct sockaddr_in6 *)&from_store; 950 bzero(from6, sizeof(*from6)); 951 from6->sin6_family = AF_INET6; 952 from6->sin6_len = sizeof(struct sockaddr_in6); 953 from6->sin6_addr = ip6->ip6_src; 954 from6->sin6_port = sh->src_port; 955 /* Get the scopes in properly to the sin6 addr's */ 956 /* we probably don't need these operations */ 957 (void)sa6_recoverscope(from6); 958 sa6_embedscope(from6, ip6_use_defzone); 959 } else { 960 /* unknown address type */ 961 from = NULL; 962 } 963 if (from != NULL) { 964 #ifdef SCTP_DEBUG 965 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 966 printf("Looking for IP source: "); 967 sctp_print_address(from); 968 } 969 #endif /* SCTP_DEBUG */ 970 /* look up the from address */ 971 stcb->asoc.last_control_chunk_from = sctp_findnet(stcb, from); 972 #ifdef SCTP_DEBUG 973 if ((stcb->asoc.last_control_chunk_from == NULL) && 974 (sctp_debug_on & SCTP_DEBUG_ASCONF1)) 975 printf("handle_asconf: IP source address not found?!\n"); 976 #endif /* SCTP_DEBUG */ 977 } 978 } 979 /* and send it (a new one) out... */ 980 sctp_send_asconf_ack(stcb, 0); 981 } 982 983 /* 984 * does the address match? returns 0 if not, 1 if so 985 */ 986 static uint32_t 987 sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa) 988 { 989 #ifdef INET6 990 if (sa->sa_family == AF_INET6) { 991 /* IPv6 sa address */ 992 /* XXX scopeid */ 993 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; 994 995 if ((aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) && 996 (memcmp(&aa->ap.addrp.addr, &sin6->sin6_addr, 997 sizeof(struct in6_addr)) == 0)) { 998 return (1); 999 } 1000 } else 1001 #endif /* INET6 */ 1002 if (sa->sa_family == AF_INET) { 1003 /* IPv4 sa address */ 1004 struct sockaddr_in *sin = (struct sockaddr_in *)sa; 1005 1006 if ((aa->ap.addrp.ph.param_type == SCTP_IPV4_ADDRESS) && 1007 (memcmp(&aa->ap.addrp.addr, &sin->sin_addr, 1008 sizeof(struct in_addr)) == 0)) { 1009 return (1); 1010 } 1011 } 1012 return (0); 1013 } 1014 1015 /* 1016 * Cleanup for non-responded/OP ERR'd ASCONF 1017 */ 1018 void 1019 sctp_asconf_cleanup(struct sctp_tcb *stcb, struct sctp_nets *net) 1020 { 1021 /* mark peer as ASCONF incapable */ 1022 stcb->asoc.peer_supports_asconf = 0; 1023 /* 1024 * clear out any existing asconfs going out 1025 */ 1026 sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_ASCONF + SCTP_LOC_2); 1027 stcb->asoc.asconf_seq_out++; 1028 /* remove the old ASCONF on our outbound queue */ 1029 sctp_toss_old_asconf(stcb); 1030 } 1031 1032 /* 1033 * process an ADD/DELETE IP ack from peer. 1034 * addr corresponding ifaddr to the address being added/deleted. 1035 * type: SCTP_ADD_IP_ADDRESS or SCTP_DEL_IP_ADDRESS. 1036 * flag: 1=success, 0=failure. 1037 */ 1038 static void 1039 sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct ifaddr *addr, 1040 uint16_t type, uint32_t flag) 1041 { 1042 /* 1043 * do the necessary asoc list work- if we get a failure indication, 1044 * leave the address on the "do not use" asoc list if we get a 1045 * success indication, remove the address from the list 1046 */ 1047 /* 1048 * Note: this will only occur for ADD_IP_ADDRESS, since 1049 * DEL_IP_ADDRESS is never actually added to the list... 1050 */ 1051 if (flag) { 1052 /* success case, so remove from the list */ 1053 sctp_del_local_addr_assoc(stcb, addr); 1054 } 1055 /* else, leave it on the list */ 1056 } 1057 1058 /* 1059 * add an asconf add/delete IP address parameter to the queue. 1060 * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR. 1061 * returns 0 if completed, non-zero if not completed. 1062 * NOTE: if adding, but delete already scheduled (and not yet sent out), 1063 * simply remove from queue. Same for deleting an address already scheduled 1064 * for add. If a duplicate operation is found, ignore the new one. 1065 */ 1066 static uint32_t 1067 sctp_asconf_queue_add(struct sctp_tcb *stcb, struct ifaddr *ifa, uint16_t type) 1068 { 1069 struct sctp_asconf_addr *aa, *aa_next; 1070 struct sockaddr *sa; 1071 1072 /* see if peer supports ASCONF */ 1073 if (stcb->asoc.peer_supports_asconf == 0) { 1074 return (-1); 1075 } 1076 /* make sure the request isn't already in the queue */ 1077 for (aa = TAILQ_FIRST(&stcb->asoc.asconf_queue); aa != NULL; 1078 aa = aa_next) { 1079 aa_next = TAILQ_NEXT(aa, next); 1080 /* address match? */ 1081 if (sctp_asconf_addr_match(aa, ifa->ifa_addr) == 0) 1082 continue; 1083 /* is the request already in queue (sent or not) */ 1084 if (aa->ap.aph.ph.param_type == type) { 1085 return (-1); 1086 } 1087 /* is the negative request already in queue, and not sent */ 1088 if (aa->sent == 0 && 1089 /* add requested, delete already queued */ 1090 ((type == SCTP_ADD_IP_ADDRESS && 1091 aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) || 1092 /* delete requested, add already queued */ 1093 (type == SCTP_DEL_IP_ADDRESS && 1094 aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS))) { 1095 /* delete the existing entry in the queue */ 1096 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next); 1097 /* take the entry off the appropriate list */ 1098 sctp_asconf_addr_mgmt_ack(stcb, aa->ifa, type, 1); 1099 /* free the entry */ 1100 SCTP_FREE(aa); 1101 return (-1); 1102 } 1103 } /* for each aa */ 1104 1105 /* adding new request to the queue */ 1106 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa), "AsconfAddr"); 1107 if (aa == NULL) { 1108 /* didn't get memory */ 1109 #ifdef SCTP_DEBUG 1110 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1111 printf("asconf_queue_add: failed to get memory!\n"); 1112 } 1113 #endif /* SCTP_DEBUG */ 1114 return (-1); 1115 } 1116 /* fill in asconf address parameter fields */ 1117 /* top level elements are "networked" during send */ 1118 aa->ap.aph.ph.param_type = type; 1119 aa->ifa = ifa; 1120 /* correlation_id filled in during send routine later... */ 1121 if (ifa->ifa_addr->sa_family == AF_INET6) { 1122 /* IPv6 address */ 1123 struct sockaddr_in6 *sin6; 1124 1125 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 1126 sa = (struct sockaddr *)sin6; 1127 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS; 1128 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param)); 1129 aa->ap.aph.ph.param_length = 1130 sizeof(struct sctp_asconf_paramhdr) + 1131 sizeof(struct sctp_ipv6addr_param); 1132 memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr, 1133 sizeof(struct in6_addr)); 1134 } else if (ifa->ifa_addr->sa_family == AF_INET) { 1135 /* IPv4 address */ 1136 struct sockaddr_in *sin = (struct sockaddr_in *)ifa->ifa_addr; 1137 1138 sa = (struct sockaddr *)sin; 1139 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS; 1140 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param)); 1141 aa->ap.aph.ph.param_length = 1142 sizeof(struct sctp_asconf_paramhdr) + 1143 sizeof(struct sctp_ipv4addr_param); 1144 memcpy(&aa->ap.addrp.addr, &sin->sin_addr, 1145 sizeof(struct in_addr)); 1146 } else { 1147 /* invalid family! */ 1148 return (-1); 1149 } 1150 aa->sent = 0; /* clear sent flag */ 1151 1152 /* 1153 * if we are deleting an address it should go out last otherwise, 1154 * add it to front of the pending queue 1155 */ 1156 if (type == SCTP_ADD_IP_ADDRESS) { 1157 /* add goes to the front of the queue */ 1158 TAILQ_INSERT_HEAD(&stcb->asoc.asconf_queue, aa, next); 1159 #ifdef SCTP_DEBUG 1160 if (sctp_debug_on & SCTP_DEBUG_ASCONF2) { 1161 printf("asconf_queue_add: appended asconf ADD_IP_ADDRESS: "); 1162 sctp_print_address(sa); 1163 } 1164 #endif /* SCTP_DEBUG */ 1165 } else { 1166 /* delete and set primary goes to the back of the queue */ 1167 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next); 1168 #ifdef SCTP_DEBUG 1169 if (sctp_debug_on & SCTP_DEBUG_ASCONF2) { 1170 if (type == SCTP_DEL_IP_ADDRESS) { 1171 printf("asconf_queue_add: inserted asconf DEL_IP_ADDRESS: "); 1172 sctp_print_address(sa); 1173 } else { 1174 printf("asconf_queue_add: inserted asconf SET_PRIM_ADDR: "); 1175 sctp_print_address(sa); 1176 } 1177 } 1178 #endif /* SCTP_DEBUG */ 1179 } 1180 1181 return (0); 1182 } 1183 1184 /* 1185 * add an asconf add/delete IP address parameter to the queue by addr. 1186 * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR. 1187 * returns 0 if completed, non-zero if not completed. 1188 * NOTE: if adding, but delete already scheduled (and not yet sent out), 1189 * simply remove from queue. Same for deleting an address already scheduled 1190 * for add. If a duplicate operation is found, ignore the new one. 1191 */ 1192 static uint32_t 1193 sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa, 1194 uint16_t type) 1195 { 1196 struct sctp_asconf_addr *aa, *aa_next; 1197 1198 /* see if peer supports ASCONF */ 1199 if (stcb->asoc.peer_supports_asconf == 0) { 1200 return (-1); 1201 } 1202 /* make sure the request isn't already in the queue */ 1203 for (aa = TAILQ_FIRST(&stcb->asoc.asconf_queue); aa != NULL; 1204 aa = aa_next) { 1205 aa_next = TAILQ_NEXT(aa, next); 1206 /* address match? */ 1207 if (sctp_asconf_addr_match(aa, sa) == 0) 1208 continue; 1209 /* is the request already in queue (sent or not) */ 1210 if (aa->ap.aph.ph.param_type == type) { 1211 return (-1); 1212 } 1213 /* is the negative request already in queue, and not sent */ 1214 if (aa->sent == 1) 1215 continue; 1216 if (type == SCTP_ADD_IP_ADDRESS && 1217 aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) { 1218 /* add requested, delete already queued */ 1219 1220 /* delete the existing entry in the queue */ 1221 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next); 1222 /* free the entry */ 1223 SCTP_FREE(aa); 1224 return (-1); 1225 } else if (type == SCTP_DEL_IP_ADDRESS && 1226 aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS) { 1227 /* delete requested, add already queued */ 1228 1229 /* delete the existing entry in the queue */ 1230 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next); 1231 /* take the entry off the appropriate list */ 1232 sctp_asconf_addr_mgmt_ack(stcb, aa->ifa, type, 1); 1233 /* free the entry */ 1234 SCTP_FREE(aa); 1235 return (-1); 1236 } 1237 } /* for each aa */ 1238 1239 /* adding new request to the queue */ 1240 SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa), "AsconfAddr"); 1241 if (aa == NULL) { 1242 /* didn't get memory */ 1243 #ifdef SCTP_DEBUG 1244 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1245 printf("asconf_queue_add_sa: failed to get memory!\n"); 1246 } 1247 #endif /* SCTP_DEBUG */ 1248 return (-1); 1249 } 1250 /* fill in asconf address parameter fields */ 1251 /* top level elements are "networked" during send */ 1252 aa->ap.aph.ph.param_type = type; 1253 aa->ifa = sctp_find_ifa_by_addr(sa); 1254 /* correlation_id filled in during send routine later... */ 1255 if (sa->sa_family == AF_INET6) { 1256 /* IPv6 address */ 1257 struct sockaddr_in6 *sin6; 1258 1259 sin6 = (struct sockaddr_in6 *)sa; 1260 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS; 1261 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param)); 1262 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv6addr_param); 1263 memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr, 1264 sizeof(struct in6_addr)); 1265 } else if (sa->sa_family == AF_INET) { 1266 /* IPv4 address */ 1267 struct sockaddr_in *sin = (struct sockaddr_in *)sa; 1268 1269 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS; 1270 aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param)); 1271 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv4addr_param); 1272 memcpy(&aa->ap.addrp.addr, &sin->sin_addr, 1273 sizeof(struct in_addr)); 1274 } else { 1275 /* invalid family! */ 1276 SCTP_FREE(aa); 1277 return (-1); 1278 } 1279 aa->sent = 0; /* clear sent flag */ 1280 1281 /* 1282 * if we are deleting an address it should go out last otherwise, 1283 * add it to front of the pending queue 1284 */ 1285 if (type == SCTP_ADD_IP_ADDRESS) { 1286 /* add goes to the front of the queue */ 1287 TAILQ_INSERT_HEAD(&stcb->asoc.asconf_queue, aa, next); 1288 } else { 1289 /* delete and set primary goes to the back of the queue */ 1290 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next); 1291 } 1292 1293 return (0); 1294 } 1295 1296 /* 1297 * find a specific asconf param on our "sent" queue 1298 */ 1299 static struct sctp_asconf_addr * 1300 sctp_asconf_find_param(struct sctp_tcb *stcb, uint32_t correlation_id) 1301 { 1302 struct sctp_asconf_addr *aa; 1303 1304 TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) { 1305 if (aa->ap.aph.correlation_id == correlation_id && 1306 aa->sent == 1) { 1307 /* found it */ 1308 return (aa); 1309 } 1310 } 1311 /* didn't find it */ 1312 return (NULL); 1313 } 1314 1315 /* 1316 * process an SCTP_ERROR_CAUSE_IND for a ASCONF-ACK parameter and do 1317 * notifications based on the error response 1318 */ 1319 static void 1320 sctp_asconf_process_error(struct sctp_tcb *stcb, 1321 struct sctp_asconf_paramhdr *aph) 1322 { 1323 struct sctp_error_cause *eh; 1324 struct sctp_paramhdr *ph; 1325 uint16_t param_type; 1326 uint16_t error_code; 1327 1328 eh = (struct sctp_error_cause *)(aph + 1); 1329 ph = (struct sctp_paramhdr *)(eh + 1); 1330 /* validate lengths */ 1331 if (htons(eh->length) + sizeof(struct sctp_error_cause) > 1332 htons(aph->ph.param_length)) { 1333 /* invalid error cause length */ 1334 #ifdef SCTP_DEBUG 1335 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1336 printf("asconf_process_error: cause element too long\n"); 1337 } 1338 #endif /* SCTP_DEBUG */ 1339 return; 1340 } 1341 if (htons(ph->param_length) + sizeof(struct sctp_paramhdr) > 1342 htons(eh->length)) { 1343 /* invalid included TLV length */ 1344 #ifdef SCTP_DEBUG 1345 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1346 printf("asconf_process_error: included TLV too long\n"); 1347 } 1348 #endif /* SCTP_DEBUG */ 1349 return; 1350 } 1351 /* which error code ? */ 1352 error_code = ntohs(eh->code); 1353 param_type = ntohs(aph->ph.param_type); 1354 /* FIX: this should go back up the REMOTE_ERROR ULP notify */ 1355 switch (error_code) { 1356 case SCTP_CAUSE_RESOURCE_SHORTAGE: 1357 /* we allow ourselves to "try again" for this error */ 1358 break; 1359 default: 1360 /* peer can't handle it... */ 1361 switch (param_type) { 1362 case SCTP_ADD_IP_ADDRESS: 1363 case SCTP_DEL_IP_ADDRESS: 1364 stcb->asoc.peer_supports_asconf = 0; 1365 break; 1366 case SCTP_SET_PRIM_ADDR: 1367 stcb->asoc.peer_supports_asconf = 0; 1368 break; 1369 default: 1370 break; 1371 } 1372 } 1373 } 1374 1375 /* 1376 * process an asconf queue param aparam: parameter to process, will be 1377 * removed from the queue flag: 1=success, 0=failure 1378 */ 1379 static void 1380 sctp_asconf_process_param_ack(struct sctp_tcb *stcb, 1381 struct sctp_asconf_addr *aparam, uint32_t flag) 1382 { 1383 uint16_t param_type; 1384 1385 /* process this param */ 1386 param_type = aparam->ap.aph.ph.param_type; 1387 switch (param_type) { 1388 case SCTP_ADD_IP_ADDRESS: 1389 #ifdef SCTP_DEBUG 1390 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1391 printf("process_param_ack: added IP address\n"); 1392 } 1393 #endif /* SCTP_DEBUG */ 1394 sctp_asconf_addr_mgmt_ack(stcb, aparam->ifa, param_type, flag); 1395 break; 1396 case SCTP_DEL_IP_ADDRESS: 1397 #ifdef SCTP_DEBUG 1398 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1399 printf("process_param_ack: deleted IP address\n"); 1400 } 1401 #endif /* SCTP_DEBUG */ 1402 /* nothing really to do... lists already updated */ 1403 break; 1404 case SCTP_SET_PRIM_ADDR: 1405 /* nothing to do... peer may start using this addr */ 1406 if (flag == 0) 1407 stcb->asoc.peer_supports_asconf = 0; 1408 break; 1409 default: 1410 /* should NEVER happen */ 1411 break; 1412 } 1413 1414 /* remove the param and free it */ 1415 TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next); 1416 SCTP_FREE(aparam); 1417 } 1418 1419 /* 1420 * cleanup from a bad asconf ack parameter 1421 */ 1422 static void 1423 sctp_asconf_ack_clear(struct sctp_tcb *stcb) 1424 { 1425 /* assume peer doesn't really know how to do asconfs */ 1426 stcb->asoc.peer_supports_asconf = 0; 1427 /* XXX we could free the pending queue here */ 1428 } 1429 1430 void 1431 sctp_handle_asconf_ack(struct mbuf *m, int offset, 1432 struct sctp_asconf_ack_chunk *cp, struct sctp_tcb *stcb, 1433 struct sctp_nets *net) 1434 { 1435 struct sctp_association *asoc; 1436 uint32_t serial_num; 1437 uint16_t ack_length; 1438 struct sctp_asconf_paramhdr *aph; 1439 struct sctp_asconf_addr *aa, *aa_next; 1440 uint32_t last_error_id = 0; /* last error correlation id */ 1441 uint32_t id; 1442 struct sctp_asconf_addr *ap; 1443 1444 /* asconf param buffer */ 1445 static uint8_t aparam_buf[DEFAULT_PARAM_BUFFER]; 1446 1447 /* verify minimum length */ 1448 if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_ack_chunk)) { 1449 #ifdef SCTP_DEBUG 1450 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1451 printf("handle_asconf_ack: chunk too small = %xh\n", 1452 ntohs(cp->ch.chunk_length)); 1453 } 1454 #endif /* SCTP_DEBUG */ 1455 return; 1456 } 1457 asoc = &stcb->asoc; 1458 serial_num = ntohl(cp->serial_number); 1459 1460 /* 1461 * NOTE: we may want to handle this differently- currently, we will 1462 * abort when we get an ack for the expected serial number + 1 (eg. 1463 * we didn't send it), process an ack normally if it is the expected 1464 * serial number, and re-send the previous ack for *ALL* other 1465 * serial numbers 1466 */ 1467 1468 /* 1469 * if the serial number is the next expected, but I didn't send it, 1470 * abort the asoc, since someone probably just hijacked us... 1471 */ 1472 if (serial_num == (asoc->asconf_seq_out + 1)) { 1473 #ifdef SCTP_DEBUG 1474 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1475 printf("handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n"); 1476 } 1477 #endif /* SCTP_DEBUG */ 1478 sctp_abort_an_association(stcb->sctp_ep, stcb, 1479 SCTP_CAUSE_ILLEGAL_ASCONF_ACK, NULL); 1480 return; 1481 } 1482 if (serial_num != asoc->asconf_seq_out) { 1483 /* got a duplicate/unexpected ASCONF-ACK */ 1484 #ifdef SCTP_DEBUG 1485 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1486 printf("handle_asconf_ack: got duplicate/unexpected serial number = %xh (expected = %xh)\n", serial_num, asoc->asconf_seq_out); 1487 } 1488 #endif /* SCTP_DEBUG */ 1489 return; 1490 } 1491 if (stcb->asoc.asconf_sent == 0) { 1492 /* got a unexpected ASCONF-ACK for serial not in flight */ 1493 #ifdef SCTP_DEBUG 1494 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1495 printf("handle_asconf_ack: got serial number = %xh but not in flight\n", serial_num); 1496 } 1497 #endif /* SCTP_DEBUG */ 1498 /* nothing to do... duplicate ACK received */ 1499 return; 1500 } 1501 /* stop our timer */ 1502 sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_ASCONF + SCTP_LOC_3); 1503 1504 /* process the ASCONF-ACK contents */ 1505 ack_length = ntohs(cp->ch.chunk_length) - 1506 sizeof(struct sctp_asconf_ack_chunk); 1507 offset += sizeof(struct sctp_asconf_ack_chunk); 1508 /* process through all parameters */ 1509 while (ack_length >= sizeof(struct sctp_asconf_paramhdr)) { 1510 unsigned int param_length, param_type; 1511 1512 /* get pointer to next asconf parameter */ 1513 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, 1514 sizeof(struct sctp_asconf_paramhdr), aparam_buf); 1515 if (aph == NULL) { 1516 /* can't get an asconf paramhdr */ 1517 sctp_asconf_ack_clear(stcb); 1518 return; 1519 } 1520 param_type = ntohs(aph->ph.param_type); 1521 param_length = ntohs(aph->ph.param_length); 1522 if (param_length > ack_length) { 1523 sctp_asconf_ack_clear(stcb); 1524 return; 1525 } 1526 if (param_length < sizeof(struct sctp_paramhdr)) { 1527 sctp_asconf_ack_clear(stcb); 1528 return; 1529 } 1530 /* get the complete parameter... */ 1531 if (param_length > sizeof(aparam_buf)) { 1532 #ifdef SCTP_DEBUG 1533 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1534 printf("param length (%u) larger than buffer size!\n", param_length); 1535 } 1536 #endif /* SCTP_DEBUG */ 1537 sctp_asconf_ack_clear(stcb); 1538 return; 1539 } 1540 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf); 1541 if (aph == NULL) { 1542 sctp_asconf_ack_clear(stcb); 1543 return; 1544 } 1545 /* correlation_id is transparent to peer, no ntohl needed */ 1546 id = aph->correlation_id; 1547 1548 switch (param_type) { 1549 case SCTP_ERROR_CAUSE_IND: 1550 last_error_id = id; 1551 /* find the corresponding asconf param in our queue */ 1552 ap = sctp_asconf_find_param(stcb, id); 1553 if (ap == NULL) { 1554 /* hmm... can't find this in our queue! */ 1555 break; 1556 } 1557 /* process the parameter, failed flag */ 1558 sctp_asconf_process_param_ack(stcb, ap, 0); 1559 /* process the error response */ 1560 sctp_asconf_process_error(stcb, aph); 1561 break; 1562 case SCTP_SUCCESS_REPORT: 1563 /* find the corresponding asconf param in our queue */ 1564 ap = sctp_asconf_find_param(stcb, id); 1565 if (ap == NULL) { 1566 /* hmm... can't find this in our queue! */ 1567 break; 1568 } 1569 /* process the parameter, success flag */ 1570 sctp_asconf_process_param_ack(stcb, ap, 1); 1571 break; 1572 default: 1573 break; 1574 } /* switch */ 1575 1576 /* update remaining ASCONF-ACK message length to process */ 1577 ack_length -= SCTP_SIZE32(param_length); 1578 if (ack_length <= 0) { 1579 /* no more data in the mbuf chain */ 1580 break; 1581 } 1582 offset += SCTP_SIZE32(param_length); 1583 } /* while */ 1584 1585 /* 1586 * if there are any "sent" params still on the queue, these are 1587 * implicitly "success", or "failed" (if we got an error back) ... 1588 * so process these appropriately 1589 * 1590 * we assume that the correlation_id's are monotonically increasing 1591 * beginning from 1 and that we don't have *that* many outstanding 1592 * at any given time 1593 */ 1594 if (last_error_id == 0) 1595 last_error_id--;/* set to "max" value */ 1596 for (aa = TAILQ_FIRST(&stcb->asoc.asconf_queue); aa != NULL; 1597 aa = aa_next) { 1598 aa_next = TAILQ_NEXT(aa, next); 1599 if (aa->sent == 1) { 1600 /* 1601 * implicitly successful or failed if correlation_id 1602 * < last_error_id, then success else, failure 1603 */ 1604 if (aa->ap.aph.correlation_id < last_error_id) 1605 sctp_asconf_process_param_ack(stcb, aa, 1606 SCTP_SUCCESS_REPORT); 1607 else 1608 sctp_asconf_process_param_ack(stcb, aa, 1609 SCTP_ERROR_CAUSE_IND); 1610 } else { 1611 /* 1612 * since we always process in order (FIFO queue) if 1613 * we reach one that hasn't been sent, the rest 1614 * should not have been sent either. so, we're 1615 * done... 1616 */ 1617 break; 1618 } 1619 } 1620 1621 /* update the next sequence number to use */ 1622 asoc->asconf_seq_out++; 1623 /* remove the old ASCONF on our outbound queue */ 1624 sctp_toss_old_asconf(stcb); 1625 /* clear the sent flag to allow new ASCONFs */ 1626 asoc->asconf_sent = 0; 1627 if (!TAILQ_EMPTY(&stcb->asoc.asconf_queue)) { 1628 /* we have more params, so restart our timer */ 1629 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, 1630 stcb, net); 1631 } 1632 } 1633 1634 /* is this an interface that we care about at all? */ 1635 static uint32_t 1636 sctp_is_desired_interface_type(struct ifaddr *ifa) 1637 { 1638 int result; 1639 1640 /* check the interface type to see if it's one we care about */ 1641 switch (ifa->ifa_ifp->if_type) { 1642 case IFT_ETHER: 1643 case IFT_ISO88023: 1644 case IFT_ISO88025: 1645 case IFT_STARLAN: 1646 case IFT_P10: 1647 case IFT_P80: 1648 case IFT_HY: 1649 case IFT_FDDI: 1650 case IFT_PPP: 1651 case IFT_XETHER: 1652 case IFT_SLIP: 1653 case IFT_GIF: 1654 result = 1; 1655 break; 1656 default: 1657 result = 0; 1658 } 1659 1660 return (result); 1661 } 1662 1663 static uint32_t 1664 sctp_is_scopeid_in_nets(struct sctp_tcb *stcb, struct sockaddr *sa) 1665 { 1666 struct sockaddr_in6 *sin6, *net6; 1667 struct sctp_nets *net; 1668 1669 if (sa->sa_family != AF_INET6) { 1670 /* wrong family */ 1671 return (0); 1672 } 1673 sin6 = (struct sockaddr_in6 *)sa; 1674 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) == 0) { 1675 /* not link local address */ 1676 return (0); 1677 } 1678 /* hunt through our destination nets list for this scope_id */ 1679 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 1680 if (((struct sockaddr *)(&net->ro._l_addr))->sa_family != 1681 AF_INET6) 1682 continue; 1683 net6 = (struct sockaddr_in6 *)&net->ro._l_addr; 1684 if (IN6_IS_ADDR_LINKLOCAL(&net6->sin6_addr) == 0) 1685 continue; 1686 if (sctp_is_same_scope(sin6, net6)) { 1687 /* found one */ 1688 return (1); 1689 } 1690 } 1691 /* didn't find one */ 1692 return (0); 1693 } 1694 1695 /* 1696 * address management functions 1697 */ 1698 static void 1699 sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, 1700 struct ifaddr *ifa, uint16_t type) 1701 { 1702 int status; 1703 1704 1705 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0 && 1706 sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) { 1707 /* subset bound, no ASCONF allowed case, so ignore */ 1708 return; 1709 } 1710 /* 1711 * note: we know this is not the subset bound, no ASCONF case eg. 1712 * this is boundall or subset bound w/ASCONF allowed 1713 */ 1714 1715 /* first, make sure it's a good address family */ 1716 if (ifa->ifa_addr->sa_family != AF_INET6 && 1717 ifa->ifa_addr->sa_family != AF_INET) { 1718 return; 1719 } 1720 /* make sure we're "allowed" to add this type of addr */ 1721 if (ifa->ifa_addr->sa_family == AF_INET6) { 1722 struct in6_ifaddr *ifa6; 1723 1724 /* invalid if we're not a v6 endpoint */ 1725 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) 1726 return; 1727 /* is the v6 addr really valid ? */ 1728 ifa6 = (struct in6_ifaddr *)ifa; 1729 if (IFA6_IS_DEPRECATED(ifa6) || 1730 (ifa6->ia6_flags & 1731 (IN6_IFF_DETACHED | IN6_IFF_ANYCAST | IN6_IFF_NOTREADY))) { 1732 /* can't use an invalid address */ 1733 return; 1734 } 1735 } 1736 /* put this address on the "pending/do not use yet" list */ 1737 /* 1738 * Note: we do this primarily for the subset bind case We don't have 1739 * scoping flags at the EP level, so we must add link local/site 1740 * local addresses to the EP, then need to "negate" them here. 1741 * Recall that this routine is only called for the subset bound 1742 * w/ASCONF allowed case. 1743 */ 1744 1745 /* 1746 * do a scope_id check against any link local addresses in the 1747 * destination nets list to see if we should put this local address 1748 * on the pending list or not eg. don't put on the list if we have a 1749 * link local destination with the same scope_id 1750 */ 1751 if (type == SCTP_ADD_IP_ADDRESS) { 1752 if (sctp_is_scopeid_in_nets(stcb, ifa->ifa_addr) == 0) { 1753 sctp_add_local_addr_assoc(stcb, ifa); 1754 } 1755 } 1756 /* 1757 * check address scope if address is out of scope, don't queue 1758 * anything... note: this would leave the address on both inp and 1759 * asoc lists 1760 */ 1761 if (ifa->ifa_addr->sa_family == AF_INET6) { 1762 struct sockaddr_in6 *sin6; 1763 1764 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 1765 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1766 /* we skip unspecifed addresses */ 1767 return; 1768 } 1769 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 1770 if (stcb->asoc.local_scope == 0) { 1771 return; 1772 } 1773 /* is it the right link local scope? */ 1774 if (sctp_is_scopeid_in_nets(stcb, ifa->ifa_addr) == 0) { 1775 return; 1776 } 1777 } 1778 if (stcb->asoc.site_scope == 0 && 1779 IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { 1780 return; 1781 } 1782 } else if (ifa->ifa_addr->sa_family == AF_INET) { 1783 struct sockaddr_in *sin; 1784 struct in6pcb *inp6; 1785 1786 inp6 = (struct in6pcb *)&inp->ip_inp.inp; 1787 /* invalid if we are a v6 only endpoint */ 1788 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 1789 (inp6->inp_flags & IN6P_IPV6_V6ONLY) 1790 ) 1791 return; 1792 1793 sin = (struct sockaddr_in *)ifa->ifa_addr; 1794 if (sin->sin_addr.s_addr == 0) { 1795 /* we skip unspecifed addresses */ 1796 return; 1797 } 1798 if (stcb->asoc.ipv4_local_scope == 0 && 1799 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { 1800 return; 1801 } 1802 } else { 1803 /* else, not AF_INET or AF_INET6, so skip */ 1804 #ifdef SCTP_DEBUG 1805 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1806 printf("addr_mgmt_assoc: not AF_INET or AF_INET6\n"); 1807 } 1808 #endif /* SCTP_DEBUG */ 1809 return; 1810 } 1811 1812 /* queue an asconf for this address add/delete */ 1813 1814 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) { 1815 /* does the peer do asconf? */ 1816 if (stcb->asoc.peer_supports_asconf) { 1817 /* queue an asconf for this addr */ 1818 status = sctp_asconf_queue_add(stcb, ifa, type); 1819 /* 1820 * if queued ok, and in correct state, set the 1821 * ASCONF timer if in non-open state, we will set 1822 * this timer when the state does go open and do all 1823 * the asconf's 1824 */ 1825 if (status == 0 && 1826 SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) { 1827 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp, 1828 stcb, stcb->asoc.primary_destination); 1829 } 1830 } 1831 } else { 1832 /* this is the boundall, no ASCONF case */ 1833 #if 0 1834 /* Peter: Fixe me? why the if 0? */ 1835 /* 1836 * assume kernel will delete this very shortly; add done 1837 * above 1838 */ 1839 if (type == SCTP_DEL_IP_ADDRESS) { 1840 /* if deleting, add this addr to the do not use list */ 1841 sctp_add_local_addr_assoc(stcb, ifa); 1842 } 1843 #endif 1844 } 1845 } 1846 1847 static void 1848 sctp_addr_mgmt_ep(struct sctp_inpcb *inp, struct ifaddr *ifa, uint16_t type) 1849 { 1850 struct sctp_tcb *stcb; 1851 int s; 1852 1853 1854 SCTP_INP_WLOCK(inp); 1855 /* make sure we're "allowed" to add this type of addr */ 1856 if (ifa->ifa_addr->sa_family == AF_INET6) { 1857 struct in6_ifaddr *ifa6; 1858 1859 /* invalid if we're not a v6 endpoint */ 1860 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { 1861 SCTP_INP_WUNLOCK(inp); 1862 return; 1863 } 1864 /* is the v6 addr really valid ? */ 1865 ifa6 = (struct in6_ifaddr *)ifa; 1866 if (IFA6_IS_DEPRECATED(ifa6) || 1867 (ifa6->ia6_flags & 1868 (IN6_IFF_DETACHED | IN6_IFF_ANYCAST | IN6_IFF_NOTREADY))) { 1869 /* can't use an invalid address */ 1870 SCTP_INP_WUNLOCK(inp); 1871 return; 1872 } 1873 } else if (ifa->ifa_addr->sa_family == AF_INET) { 1874 /* invalid if we are a v6 only endpoint */ 1875 struct in6pcb *inp6; 1876 1877 inp6 = (struct in6pcb *)&inp->ip_inp.inp; 1878 1879 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 1880 (inp6->inp_flags & IN6P_IPV6_V6ONLY) 1881 ) { 1882 SCTP_INP_WUNLOCK(inp); 1883 return; 1884 } 1885 } else { 1886 /* invalid address family */ 1887 SCTP_INP_WUNLOCK(inp); 1888 return; 1889 } 1890 /* is this endpoint subset bound ? */ 1891 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { 1892 /* subset bound endpoint */ 1893 if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) { 1894 /* 1895 * subset bound, but ASCONFs not allowed... if 1896 * adding, nothing to do, since not allowed if 1897 * deleting, remove address from endpoint peer will 1898 * have to "timeout" this addr 1899 */ 1900 if (type == SCTP_DEL_IP_ADDRESS) { 1901 sctp_del_local_addr_ep(inp, ifa); 1902 } 1903 /* no asconfs to queue for this inp... */ 1904 SCTP_INP_WUNLOCK(inp); 1905 return; 1906 } else { 1907 /* 1908 * subset bound, ASCONFs allowed... if adding, add 1909 * address to endpoint list if deleting, remove 1910 * address from endpoint 1911 */ 1912 if (type == SCTP_ADD_IP_ADDRESS) { 1913 sctp_add_local_addr_ep(inp, ifa); 1914 } else { 1915 sctp_del_local_addr_ep(inp, ifa); 1916 } 1917 /* drop through and notify all asocs */ 1918 } 1919 } 1920 s = splnet(); 1921 /* process for all associations for this endpoint */ 1922 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 1923 SCTP_TCB_LOCK(stcb); 1924 sctp_addr_mgmt_assoc(inp, stcb, ifa, type); 1925 SCTP_TCB_UNLOCK(stcb); 1926 } 1927 splx(s); 1928 SCTP_INP_WUNLOCK(inp); 1929 } 1930 1931 /* 1932 * restrict the use of this address 1933 */ 1934 static void 1935 sctp_addr_mgmt_restrict_ep(struct sctp_inpcb *inp, struct ifaddr *ifa) 1936 { 1937 struct sctp_tcb *stcb; 1938 int s; 1939 1940 /* is this endpoint bound to all? */ 1941 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { 1942 /* 1943 * Nothing to do for subset bound case. Allow sctp_bindx() 1944 * to manage the address lists 1945 */ 1946 return; 1947 } 1948 s = splnet(); 1949 SCTP_INP_RLOCK(inp); 1950 /* process for all associations for this endpoint */ 1951 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 1952 /* put this address on the "pending/do not use yet" list */ 1953 SCTP_TCB_LOCK(stcb); 1954 sctp_add_local_addr_assoc(stcb, ifa); 1955 SCTP_TCB_UNLOCK(stcb); 1956 } 1957 splx(s); 1958 SCTP_INP_RUNLOCK(inp); 1959 } 1960 1961 /* 1962 * this is only called for kernel initiated address changes eg. it will check 1963 * the PCB_FLAGS_AUTO_ASCONF flag 1964 */ 1965 static void 1966 sctp_addr_mgmt(struct ifaddr *ifa, uint16_t type) 1967 { 1968 struct sockaddr *sa; 1969 struct sctp_inpcb *inp; 1970 1971 /* make sure we care about this interface... */ 1972 if (!sctp_is_desired_interface_type(ifa)) { 1973 return; 1974 } 1975 sa = ifa->ifa_addr; 1976 if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6) 1977 return; 1978 1979 #ifdef SCTP_DEBUG 1980 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 1981 if (type == SCTP_ADD_IP_ADDRESS) 1982 printf("sctp_addr_mgmt: kernel adds "); 1983 else 1984 printf("sctp_addr_mgmt: kernel deletes "); 1985 sctp_print_address(sa); 1986 } 1987 #endif /* SCTP_DEBUG */ 1988 1989 /* go through all our PCB's */ 1990 LIST_FOREACH(inp, &sctppcbinfo.listhead, sctp_list) { 1991 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF)) { 1992 sctp_addr_mgmt_ep(inp, ifa, type); 1993 } else { 1994 /* this address is going away anyways... */ 1995 if (type == SCTP_DEL_IP_ADDRESS) 1996 return; 1997 /* (temporarily) restrict this address */ 1998 sctp_addr_mgmt_restrict_ep(inp, ifa); 1999 } 2000 /* else, not allowing automatic asconf's, so ignore */ 2001 } 2002 } 2003 2004 /* 2005 * add/delete IP address requests from kernel (via routing change) assumed 2006 * that the address is non-broadcast, non-multicast all addresses are passed 2007 * from any type of interface-- need to filter duplicate addresses may get 2008 * requested 2009 */ 2010 2011 void 2012 sctp_add_ip_address(struct ifaddr *ifa) 2013 { 2014 sctp_addr_mgmt(ifa, SCTP_ADD_IP_ADDRESS); 2015 } 2016 2017 void 2018 sctp_delete_ip_address(struct ifaddr *ifa) 2019 { 2020 struct sctp_inpcb *inp; 2021 2022 /* process the delete */ 2023 sctp_addr_mgmt(ifa, SCTP_DEL_IP_ADDRESS); 2024 2025 /* 2026 * need to remove this ifaddr from any cached routes and also any 2027 * from any assoc "restricted/pending" lists 2028 */ 2029 /* make sure we care about this interface... */ 2030 if (!sctp_is_desired_interface_type(ifa)) { 2031 return; 2032 } 2033 /* go through all our PCB's */ 2034 SCTP_INP_INFO_RLOCK(); 2035 LIST_FOREACH(inp, &sctppcbinfo.listhead, sctp_list) { 2036 struct sctp_tcb *stcb; 2037 struct sctp_laddr *laddr, *laddr_next; 2038 2039 /* process for all associations for this endpoint */ 2040 SCTP_INP_RLOCK(inp); 2041 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 2042 struct sctp_nets *net; 2043 2044 /* process through the nets list */ 2045 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 2046 struct rtentry *rt; 2047 2048 /* delete this address if cached */ 2049 rt = net->ro.ro_rt; 2050 if (rt != NULL && rt->rt_ifa == ifa) { 2051 /* RTFREE(rt); */ 2052 net->ro.ro_rt = NULL; 2053 } 2054 } /* for each net */ 2055 /* process through the asoc "pending" list */ 2056 laddr = LIST_FIRST(&stcb->asoc.sctp_local_addr_list); 2057 while (laddr != NULL) { 2058 laddr_next = LIST_NEXT(laddr, sctp_nxt_addr); 2059 /* remove if in use */ 2060 if (laddr->ifa == ifa) { 2061 sctp_remove_laddr(laddr); 2062 } 2063 laddr = laddr_next; 2064 } /* while */ 2065 } /* for each stcb */ 2066 /* process through the inp bound addr list */ 2067 laddr = LIST_FIRST(&inp->sctp_addr_list); 2068 while (laddr != NULL) { 2069 laddr_next = LIST_NEXT(laddr, sctp_nxt_addr); 2070 /* remove if in use */ 2071 if (laddr->ifa == ifa) { 2072 sctp_remove_laddr(laddr); 2073 } 2074 laddr = laddr_next; 2075 } 2076 SCTP_INP_RUNLOCK(inp); 2077 } 2078 SCTP_INP_INFO_RUNLOCK(); 2079 } 2080 2081 /* 2082 * sa is the sockaddr to ask the peer to set primary to returns: 0 = 2083 * completed, -1 = error 2084 */ 2085 int32_t 2086 sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa) 2087 { 2088 /* NOTE: we currently don't check the validity of the address! */ 2089 2090 /* queue an ASCONF:SET_PRIM_ADDR to be sent */ 2091 if (!sctp_asconf_queue_add_sa(stcb, sa, SCTP_SET_PRIM_ADDR)) { 2092 /* set primary queuing succeeded */ 2093 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) { 2094 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, 2095 stcb->sctp_ep, stcb, 2096 stcb->asoc.primary_destination); 2097 } 2098 #ifdef SCTP_DEBUG 2099 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 2100 printf("set_primary_ip_address_sa: queued on tcb=%p, ", 2101 stcb); 2102 sctp_print_address(sa); 2103 } 2104 #endif /* SCTP_DEBUG */ 2105 } else { 2106 #ifdef SCTP_DEBUG 2107 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 2108 printf("set_primary_ip_address_sa: failed to add to queue on tcb=%p, ", 2109 stcb); 2110 sctp_print_address(sa); 2111 } 2112 #endif /* SCTP_DEBUG */ 2113 return (-1); 2114 } 2115 return (0); 2116 } 2117 2118 void 2119 sctp_set_primary_ip_address(struct ifaddr *ifa) 2120 { 2121 struct sctp_inpcb *inp; 2122 2123 /* make sure we care about this interface... */ 2124 if (!sctp_is_desired_interface_type(ifa)) { 2125 return; 2126 } 2127 /* go through all our PCB's */ 2128 LIST_FOREACH(inp, &sctppcbinfo.listhead, sctp_list) { 2129 struct sctp_tcb *stcb; 2130 2131 /* process for all associations for this endpoint */ 2132 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 2133 /* queue an ASCONF:SET_PRIM_ADDR to be sent */ 2134 if (!sctp_asconf_queue_add(stcb, ifa, 2135 SCTP_SET_PRIM_ADDR)) { 2136 /* set primary queuing succeeded */ 2137 if (SCTP_GET_STATE(&stcb->asoc) == 2138 SCTP_STATE_OPEN) { 2139 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, 2140 stcb->sctp_ep, stcb, 2141 stcb->asoc.primary_destination); 2142 } 2143 #ifdef SCTP_DEBUG 2144 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 2145 printf("set_primary_ip_address: queued on stcb=%p, ", 2146 stcb); 2147 sctp_print_address(ifa->ifa_addr); 2148 } 2149 #endif /* SCTP_DEBUG */ 2150 } 2151 } /* for each stcb */ 2152 } /* for each inp */ 2153 } 2154 2155 static struct sockaddr * 2156 sctp_find_valid_localaddr(struct sctp_tcb *stcb) 2157 { 2158 struct ifnet *ifn; 2159 struct ifaddr *ifa; 2160 2161 2162 TAILQ_FOREACH(ifn, &ifnet, if_list) { 2163 if (stcb->asoc.loopback_scope == 0 && ifn->if_type == IFT_LOOP) { 2164 /* Skip if loopback_scope not set */ 2165 continue; 2166 } 2167 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 2168 if (ifa->ifa_addr->sa_family == AF_INET && 2169 stcb->asoc.ipv4_addr_legal) { 2170 struct sockaddr_in *sin; 2171 2172 sin = (struct sockaddr_in *)ifa->ifa_addr; 2173 if (sin->sin_addr.s_addr == 0) { 2174 /* skip unspecifed addresses */ 2175 continue; 2176 } 2177 if (stcb->asoc.ipv4_local_scope == 0 && 2178 IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) 2179 continue; 2180 2181 if (sctp_is_addr_restricted(stcb, 2182 ifa->ifa_addr)) 2183 continue; 2184 /* found a valid local v4 address to use */ 2185 return (ifa->ifa_addr); 2186 } else if (ifa->ifa_addr->sa_family == AF_INET6 && 2187 stcb->asoc.ipv6_addr_legal) { 2188 struct sockaddr_in6 *sin6; 2189 struct in6_ifaddr *ifa6; 2190 2191 ifa6 = (struct in6_ifaddr *)ifa; 2192 if (IFA6_IS_DEPRECATED(ifa6) || 2193 (ifa6->ia6_flags & (IN6_IFF_DETACHED | 2194 IN6_IFF_ANYCAST | IN6_IFF_NOTREADY))) 2195 continue; 2196 2197 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr; 2198 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 2199 /* we skip unspecifed addresses */ 2200 continue; 2201 } 2202 if (stcb->asoc.local_scope == 0 && 2203 IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) 2204 continue; 2205 if (stcb->asoc.site_scope == 0 && 2206 IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) 2207 continue; 2208 2209 /* found a valid local v6 address to use */ 2210 return (ifa->ifa_addr); 2211 } 2212 } 2213 } 2214 /* no valid addresses found */ 2215 return (NULL); 2216 } 2217 2218 static struct sockaddr * 2219 sctp_find_valid_localaddr_ep(struct sctp_tcb *stcb) 2220 { 2221 struct sctp_laddr *laddr; 2222 2223 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) { 2224 if (laddr->ifa == NULL) { 2225 continue; 2226 } 2227 if (laddr->ifa->ifa_addr == NULL) { 2228 continue; 2229 } 2230 /* is the address restricted ? */ 2231 if (sctp_is_addr_restricted(stcb, laddr->ifa->ifa_addr)) 2232 continue; 2233 2234 /* found a valid local address to use */ 2235 return (laddr->ifa->ifa_addr); 2236 } 2237 /* no valid addresses found */ 2238 return (NULL); 2239 } 2240 2241 /* 2242 * builds an ASCONF chunk from queued ASCONF params returns NULL on error (no 2243 * mbuf, no ASCONF params queued, etc) 2244 */ 2245 struct mbuf * 2246 sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen) 2247 { 2248 struct mbuf *m_asconf, *m_asconf_chk; 2249 struct sctp_asconf_addr *aa; 2250 struct sctp_asconf_chunk *acp; 2251 struct sctp_asconf_paramhdr *aph; 2252 struct sctp_asconf_addr_param *aap; 2253 uint32_t p_length; 2254 uint32_t correlation_id = 1; /* 0 is reserved... */ 2255 caddr_t ptr, lookup_ptr; 2256 uint8_t lookup_used = 0; 2257 2258 /* are there any asconf params to send? */ 2259 if (TAILQ_EMPTY(&stcb->asoc.asconf_queue)) { 2260 return (NULL); 2261 } 2262 /* 2263 * get a chunk header mbuf and a cluster for the asconf params since 2264 * it's simpler to fill in the asconf chunk header lookup address on 2265 * the fly 2266 */ 2267 m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 0, M_DONTWAIT, 1, MT_DATA); 2268 if (m_asconf_chk == NULL) { 2269 /* no mbuf's */ 2270 #ifdef SCTP_DEBUG 2271 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) 2272 printf("compose_asconf: couldn't get chunk mbuf!\n"); 2273 #endif /* SCTP_DEBUG */ 2274 return (NULL); 2275 } 2276 m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA); 2277 if (m_asconf == NULL) { 2278 /* no mbuf's */ 2279 #ifdef SCTP_DEBUG 2280 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) 2281 printf("compose_asconf: couldn't get mbuf!\n"); 2282 #endif /* SCTP_DEBUG */ 2283 sctp_m_freem(m_asconf_chk); 2284 return (NULL); 2285 } 2286 SCTP_BUF_LEN(m_asconf_chk) = sizeof(struct sctp_asconf_chunk); 2287 SCTP_BUF_LEN(m_asconf) = 0; 2288 acp = mtod(m_asconf_chk, struct sctp_asconf_chunk *); 2289 bzero(acp, sizeof(struct sctp_asconf_chunk)); 2290 /* save pointers to lookup address and asconf params */ 2291 lookup_ptr = (caddr_t)(acp + 1); /* after the header */ 2292 ptr = mtod(m_asconf, caddr_t); /* beginning of cluster */ 2293 2294 /* fill in chunk header info */ 2295 acp->ch.chunk_type = SCTP_ASCONF; 2296 acp->ch.chunk_flags = 0; 2297 acp->serial_number = htonl(stcb->asoc.asconf_seq_out); 2298 2299 /* add parameters... up to smallest MTU allowed */ 2300 TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) { 2301 /* get the parameter length */ 2302 p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length); 2303 /* will it fit in current chunk? */ 2304 if (SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) { 2305 /* won't fit, so we're done with this chunk */ 2306 break; 2307 } 2308 /* assign (and store) a correlation id */ 2309 aa->ap.aph.correlation_id = correlation_id++; 2310 2311 /* 2312 * fill in address if we're doing a delete this is a simple 2313 * way for us to fill in the correlation address, which 2314 * should only be used by the peer if we're deleting our 2315 * source address and adding a new address (e.g. renumbering 2316 * case) 2317 */ 2318 if (lookup_used == 0 && 2319 aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) { 2320 struct sctp_ipv6addr_param *lookup; 2321 uint16_t p_size, addr_size; 2322 2323 lookup = (struct sctp_ipv6addr_param *)lookup_ptr; 2324 lookup->ph.param_type = 2325 htons(aa->ap.addrp.ph.param_type); 2326 if (aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) { 2327 /* copy IPv6 address */ 2328 p_size = sizeof(struct sctp_ipv6addr_param); 2329 addr_size = sizeof(struct in6_addr); 2330 } else { 2331 /* copy IPv4 address */ 2332 p_size = sizeof(struct sctp_ipv4addr_param); 2333 addr_size = sizeof(struct in_addr); 2334 } 2335 lookup->ph.param_length = htons(SCTP_SIZE32(p_size)); 2336 memcpy(lookup->addr, &aa->ap.addrp.addr, addr_size); 2337 SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size); 2338 lookup_used = 1; 2339 } 2340 /* copy into current space */ 2341 memcpy(ptr, &aa->ap, p_length); 2342 2343 /* network elements and update lengths */ 2344 aph = (struct sctp_asconf_paramhdr *)ptr; 2345 aap = (struct sctp_asconf_addr_param *)ptr; 2346 /* correlation_id is transparent to peer, no htonl needed */ 2347 aph->ph.param_type = htons(aph->ph.param_type); 2348 aph->ph.param_length = htons(aph->ph.param_length); 2349 aap->addrp.ph.param_type = htons(aap->addrp.ph.param_type); 2350 aap->addrp.ph.param_length = htons(aap->addrp.ph.param_length); 2351 2352 SCTP_BUF_LEN(m_asconf) += SCTP_SIZE32(p_length); 2353 ptr += SCTP_SIZE32(p_length); 2354 2355 /* 2356 * these params are removed off the pending list upon 2357 * getting an ASCONF-ACK back from the peer, just set flag 2358 */ 2359 aa->sent = 1; 2360 } 2361 /* check to see if the lookup addr has been populated yet */ 2362 if (lookup_used == 0) { 2363 /* NOTE: if the address param is optional, can skip this... */ 2364 /* add any valid (existing) address... */ 2365 struct sctp_ipv6addr_param *lookup; 2366 uint16_t p_size, addr_size; 2367 struct sockaddr *found_addr; 2368 caddr_t addr_ptr; 2369 2370 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) 2371 found_addr = sctp_find_valid_localaddr(stcb); 2372 else 2373 found_addr = sctp_find_valid_localaddr_ep(stcb); 2374 2375 lookup = (struct sctp_ipv6addr_param *)lookup_ptr; 2376 if (found_addr != NULL) { 2377 if (found_addr->sa_family == AF_INET6) { 2378 /* copy IPv6 address */ 2379 lookup->ph.param_type = 2380 htons(SCTP_IPV6_ADDRESS); 2381 p_size = sizeof(struct sctp_ipv6addr_param); 2382 addr_size = sizeof(struct in6_addr); 2383 addr_ptr = (caddr_t)&((struct sockaddr_in6 *) 2384 found_addr)->sin6_addr; 2385 } else { 2386 /* copy IPv4 address */ 2387 lookup->ph.param_type = 2388 htons(SCTP_IPV4_ADDRESS); 2389 p_size = sizeof(struct sctp_ipv4addr_param); 2390 addr_size = sizeof(struct in_addr); 2391 addr_ptr = (caddr_t)&((struct sockaddr_in *) 2392 found_addr)->sin_addr; 2393 } 2394 lookup->ph.param_length = htons(SCTP_SIZE32(p_size)); 2395 memcpy(lookup->addr, addr_ptr, addr_size); 2396 SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size); 2397 lookup_used = 1; 2398 } else { 2399 /* uh oh... don't have any address?? */ 2400 #ifdef SCTP_DEBUG 2401 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) 2402 printf("compose_asconf: no lookup addr!\n"); 2403 #endif /* SCTP_DEBUG */ 2404 /* for now, we send a IPv4 address of 0.0.0.0 */ 2405 lookup->ph.param_type = htons(SCTP_IPV4_ADDRESS); 2406 lookup->ph.param_length = htons(SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param))); 2407 bzero(lookup->addr, sizeof(struct in_addr)); 2408 SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param)); 2409 lookup_used = 1; 2410 } 2411 } 2412 /* chain it all together */ 2413 SCTP_BUF_NEXT(m_asconf_chk) = m_asconf; 2414 *retlen = acp->ch.chunk_length = ntohs(SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf)); 2415 2416 /* update "sent" flag */ 2417 stcb->asoc.asconf_sent++; 2418 2419 return (m_asconf_chk); 2420 } 2421 2422 /* 2423 * section to handle address changes before an association is up eg. changes 2424 * during INIT/INIT-ACK/COOKIE-ECHO handshake 2425 */ 2426 2427 /* 2428 * processes the (local) addresses in the INIT-ACK chunk 2429 */ 2430 static void 2431 sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m, 2432 unsigned int offset, unsigned int length) 2433 { 2434 struct sctp_paramhdr tmp_param, *ph; 2435 uint16_t plen, ptype; 2436 struct sctp_ipv6addr_param addr_store; 2437 struct sockaddr_in6 sin6; 2438 struct sockaddr_in sin; 2439 struct sockaddr *sa; 2440 struct ifaddr *ifa; 2441 2442 #ifdef SCTP_DEBUG 2443 if (sctp_debug_on & SCTP_DEBUG_ASCONF2) { 2444 printf("processing init-ack addresses\n"); 2445 } 2446 #endif /* SCTP_DEBUG */ 2447 2448 /* convert to upper bound */ 2449 length += offset; 2450 2451 if ((offset + sizeof(struct sctp_paramhdr)) > length) { 2452 return; 2453 } 2454 /* init the addresses */ 2455 bzero(&sin6, sizeof(sin6)); 2456 sin6.sin6_family = AF_INET6; 2457 sin6.sin6_len = sizeof(sin6); 2458 sin6.sin6_port = stcb->rport; 2459 2460 bzero(&sin, sizeof(sin)); 2461 sin.sin_len = sizeof(sin); 2462 sin.sin_family = AF_INET; 2463 sin.sin_port = stcb->rport; 2464 2465 /* go through the addresses in the init-ack */ 2466 ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, 2467 sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param); 2468 while (ph != NULL) { 2469 ptype = ntohs(ph->param_type); 2470 plen = ntohs(ph->param_length); 2471 if (ptype == SCTP_IPV6_ADDRESS) { 2472 struct sctp_ipv6addr_param *a6p; 2473 2474 /* get the entire IPv6 address param */ 2475 a6p = (struct sctp_ipv6addr_param *) 2476 sctp_m_getptr(m, offset, 2477 sizeof(struct sctp_ipv6addr_param), 2478 (uint8_t *) & addr_store); 2479 if (plen != sizeof(struct sctp_ipv6addr_param) || 2480 a6p == NULL) { 2481 return; 2482 } 2483 memcpy(&sin6.sin6_addr, a6p->addr, 2484 sizeof(struct in6_addr)); 2485 sa = (struct sockaddr *)&sin6; 2486 } else if (ptype == SCTP_IPV4_ADDRESS) { 2487 struct sctp_ipv4addr_param *a4p; 2488 2489 /* get the entire IPv4 address param */ 2490 a4p = (struct sctp_ipv4addr_param *)sctp_m_getptr(m, offset, sizeof(struct sctp_ipv4addr_param), (uint8_t *) & addr_store); 2491 if (plen != sizeof(struct sctp_ipv4addr_param) || 2492 a4p == NULL) { 2493 return; 2494 } 2495 sin.sin_addr.s_addr = a4p->addr; 2496 sa = (struct sockaddr *)&sin; 2497 } else { 2498 goto next_addr; 2499 } 2500 2501 /* see if this address really (still) exists */ 2502 ifa = sctp_find_ifa_by_addr(sa); 2503 if (ifa == NULL) { 2504 /* address doesn't exist anymore */ 2505 int status; 2506 2507 /* are ASCONFs allowed ? */ 2508 if ((sctp_is_feature_on(stcb->sctp_ep, 2509 SCTP_PCB_FLAGS_DO_ASCONF)) && 2510 stcb->asoc.peer_supports_asconf) { 2511 /* queue an ASCONF DEL_IP_ADDRESS */ 2512 status = sctp_asconf_queue_add_sa(stcb, sa, 2513 SCTP_DEL_IP_ADDRESS); 2514 /* 2515 * if queued ok, and in correct state, set 2516 * the ASCONF timer 2517 */ 2518 if (status == 0 && 2519 SCTP_GET_STATE(&stcb->asoc) == 2520 SCTP_STATE_OPEN) { 2521 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, 2522 stcb->sctp_ep, stcb, 2523 stcb->asoc.primary_destination); 2524 } 2525 } 2526 } else { 2527 /* address still exists */ 2528 /* 2529 * if subset bound, ep addr's managed by default if 2530 * not doing ASCONF, add the address to the assoc 2531 */ 2532 if ((stcb->sctp_ep->sctp_flags & 2533 SCTP_PCB_FLAGS_BOUNDALL) == 0 && 2534 (sctp_is_feature_off(stcb->sctp_ep, 2535 SCTP_PCB_FLAGS_DO_ASCONF))) { 2536 #ifdef SCTP_DEBUG 2537 if (sctp_debug_on & SCTP_DEBUG_ASCONF2) { 2538 printf("process_initack_addrs: adding local addr to asoc\n"); 2539 } 2540 #endif /* SCTP_DEBUG */ 2541 sctp_add_local_addr_assoc(stcb, ifa); 2542 } 2543 } 2544 2545 next_addr: 2546 /* 2547 * Sanity check: Make sure the length isn't 0, otherwise 2548 * we'll be stuck in this loop for a long time... 2549 */ 2550 if (SCTP_SIZE32(plen) == 0) { 2551 #ifdef SCTP_DEBUG 2552 printf("process_initack_addrs: bad len (%d) type=%xh\n", 2553 plen, ptype); 2554 #endif 2555 return; 2556 } 2557 /* get next parameter */ 2558 offset += SCTP_SIZE32(plen); 2559 if ((offset + sizeof(struct sctp_paramhdr)) > length) 2560 return; 2561 ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, 2562 sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param); 2563 } /* while */ 2564 } 2565 2566 /* FIX ME: need to verify return result for v6 address type if v6 disabled */ 2567 /* 2568 * checks to see if a specific address is in the initack address list returns 2569 * 1 if found, 0 if not 2570 */ 2571 static uint32_t 2572 sctp_addr_in_initack(struct sctp_tcb *stcb, struct mbuf *m, uint32_t offset, 2573 uint32_t length, struct sockaddr *sa) 2574 { 2575 struct sctp_paramhdr tmp_param, *ph; 2576 uint16_t plen, ptype; 2577 struct sctp_ipv6addr_param addr_store; 2578 struct sockaddr_in *sin; 2579 struct sctp_ipv4addr_param *a4p; 2580 2581 #ifdef INET6 2582 struct sockaddr_in6 *sin6, sin6_tmp; 2583 struct sctp_ipv6addr_param *a6p; 2584 2585 #endif /* INET6 */ 2586 2587 if ( 2588 #ifdef INET6 2589 (sa->sa_family != AF_INET6) && 2590 #endif /* INET6 */ 2591 (sa->sa_family != AF_INET)) 2592 return (0); 2593 2594 #ifdef SCTP_DEBUG 2595 if (sctp_debug_on & SCTP_DEBUG_ASCONF2) { 2596 printf("find_initack_addr: starting search for "); 2597 sctp_print_address(sa); 2598 } 2599 #endif /* SCTP_DEBUG */ 2600 /* convert to upper bound */ 2601 length += offset; 2602 2603 if ((offset + sizeof(struct sctp_paramhdr)) > length) { 2604 #ifdef SCTP_DEBUG 2605 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 2606 printf("find_initack_addr: invalid offset?\n"); 2607 } 2608 #endif /* SCTP_DEBUG */ 2609 return (0); 2610 } 2611 /* go through the addresses in the init-ack */ 2612 ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset, 2613 sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param); 2614 while (ph != NULL) { 2615 ptype = ntohs(ph->param_type); 2616 plen = ntohs(ph->param_length); 2617 #ifdef INET6 2618 if (ptype == SCTP_IPV6_ADDRESS && sa->sa_family == AF_INET6) { 2619 /* get the entire IPv6 address param */ 2620 a6p = (struct sctp_ipv6addr_param *) 2621 sctp_m_getptr(m, offset, 2622 sizeof(struct sctp_ipv6addr_param), 2623 (uint8_t *) & addr_store); 2624 if (plen != sizeof(struct sctp_ipv6addr_param) || 2625 ph == NULL) { 2626 return (0); 2627 } 2628 sin6 = (struct sockaddr_in6 *)sa; 2629 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) { 2630 /* create a copy and clear scope */ 2631 memcpy(&sin6_tmp, sin6, 2632 sizeof(struct sockaddr_in6)); 2633 sin6 = &sin6_tmp; 2634 in6_clearscope(&sin6->sin6_addr); 2635 } 2636 if (memcmp(&sin6->sin6_addr, a6p->addr, 2637 sizeof(struct in6_addr)) == 0) { 2638 /* found it */ 2639 return (1); 2640 } 2641 } else 2642 #endif /* INET6 */ 2643 2644 if (ptype == SCTP_IPV4_ADDRESS && 2645 sa->sa_family == AF_INET) { 2646 /* get the entire IPv4 address param */ 2647 a4p = (struct sctp_ipv4addr_param *)sctp_m_getptr(m, 2648 offset, sizeof(struct sctp_ipv4addr_param), 2649 (uint8_t *) & addr_store); 2650 if (plen != sizeof(struct sctp_ipv4addr_param) || 2651 ph == NULL) { 2652 return (0); 2653 } 2654 sin = (struct sockaddr_in *)sa; 2655 if (sin->sin_addr.s_addr == a4p->addr) { 2656 /* found it */ 2657 return (1); 2658 } 2659 } 2660 /* get next parameter */ 2661 offset += SCTP_SIZE32(plen); 2662 if (offset + sizeof(struct sctp_paramhdr) > length) 2663 return (0); 2664 ph = (struct sctp_paramhdr *) 2665 sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr), 2666 (uint8_t *) & tmp_param); 2667 } /* while */ 2668 /* not found! */ 2669 return (0); 2670 } 2671 2672 /* 2673 * makes sure that the current endpoint local addr list is consistent with 2674 * the new association (eg. subset bound, asconf allowed) adds addresses as 2675 * necessary 2676 */ 2677 static void 2678 sctp_check_address_list_ep(struct sctp_tcb *stcb, struct mbuf *m, int offset, 2679 int length, struct sockaddr *init_addr) 2680 { 2681 struct sctp_laddr *laddr; 2682 2683 /* go through the endpoint list */ 2684 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) { 2685 /* be paranoid and validate the laddr */ 2686 if (laddr->ifa == NULL) { 2687 #ifdef SCTP_DEBUG 2688 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 2689 printf("check_addr_list_ep: laddr->ifa is NULL"); 2690 } 2691 #endif /* SCTP_DEBUG */ 2692 continue; 2693 } 2694 if (laddr->ifa->ifa_addr == NULL) { 2695 #ifdef SCTP_DEBUG 2696 if (sctp_debug_on & SCTP_DEBUG_ASCONF1) { 2697 printf("check_addr_list_ep: laddr->ifa->ifa_addr is NULL"); 2698 } 2699 #endif /* SCTP_DEBUG */ 2700 continue; 2701 } 2702 /* do i have it implicitly? */ 2703 if (sctp_cmpaddr(laddr->ifa->ifa_addr, init_addr)) { 2704 continue; 2705 } 2706 /* check to see if in the init-ack */ 2707 if (!sctp_addr_in_initack(stcb, m, offset, length, 2708 laddr->ifa->ifa_addr)) { 2709 /* try to add it */ 2710 sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb, laddr->ifa, 2711 SCTP_ADD_IP_ADDRESS); 2712 } 2713 } 2714 } 2715 2716 /* 2717 * makes sure that the current kernel address list is consistent with the new 2718 * association (with all addrs bound) adds addresses as necessary 2719 */ 2720 static void 2721 sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset, 2722 int length, struct sockaddr *init_addr, 2723 uint16_t local_scope, uint16_t site_scope, 2724 uint16_t ipv4_scope, uint16_t loopback_scope) 2725 { 2726 struct ifnet *ifn; 2727 struct ifaddr *ifa; 2728 2729 /* go through all our known interfaces */ 2730 TAILQ_FOREACH(ifn, &ifnet, if_list) { 2731 if (loopback_scope == 0 && ifn->if_type == IFT_LOOP) { 2732 /* skip loopback interface */ 2733 continue; 2734 } 2735 /* go through each interface address */ 2736 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 2737 /* do i have it implicitly? */ 2738 if (sctp_cmpaddr(ifa->ifa_addr, init_addr)) { 2739 continue; 2740 } 2741 /* check to see if in the init-ack */ 2742 if (!sctp_addr_in_initack(stcb, m, offset, length, 2743 ifa->ifa_addr)) { 2744 /* try to add it */ 2745 sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb, 2746 ifa, SCTP_ADD_IP_ADDRESS); 2747 } 2748 } /* end foreach ifa */ 2749 } /* end foreach ifn */ 2750 } 2751 2752 /* 2753 * validates an init-ack chunk (from a cookie-echo) with current addresses 2754 * adds addresses from the init-ack into our local address list, if needed 2755 * queues asconf adds/deletes addresses as needed and makes appropriate list 2756 * changes for source address selection m, offset: points to the start of the 2757 * address list in an init-ack chunk length: total length of the address 2758 * params only init_addr: address where my INIT-ACK was sent from 2759 */ 2760 void 2761 sctp_check_address_list(struct sctp_tcb *stcb, struct mbuf *m, int offset, 2762 int length, struct sockaddr *init_addr, 2763 uint16_t local_scope, uint16_t site_scope, 2764 uint16_t ipv4_scope, uint16_t loopback_scope) 2765 { 2766 /* process the local addresses in the initack */ 2767 sctp_process_initack_addresses(stcb, m, offset, length); 2768 2769 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 2770 /* bound all case */ 2771 sctp_check_address_list_all(stcb, m, offset, length, init_addr, 2772 local_scope, site_scope, ipv4_scope, loopback_scope); 2773 } else { 2774 /* subset bound case */ 2775 if (sctp_is_feature_on(stcb->sctp_ep, 2776 SCTP_PCB_FLAGS_DO_ASCONF)) { 2777 /* asconf's allowed */ 2778 sctp_check_address_list_ep(stcb, m, offset, length, 2779 init_addr); 2780 } 2781 /* else, no asconfs allowed, so what we sent is what we get */ 2782 } 2783 } 2784 2785 /* 2786 * sctp_bindx() support 2787 */ 2788 uint32_t 2789 sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa, uint16_t type) 2790 { 2791 struct ifaddr *ifa; 2792 2793 2794 if (sa->sa_len == 0) 2795 return (EINVAL); 2796 2797 ifa = sctp_find_ifa_by_addr(sa); 2798 if (ifa != NULL) { 2799 #ifdef INET6 2800 if (ifa->ifa_addr->sa_family == AF_INET6) { 2801 struct in6_ifaddr *ifa6; 2802 2803 ifa6 = (struct in6_ifaddr *)ifa; 2804 if (IFA6_IS_DEPRECATED(ifa6) || 2805 (ifa6->ia6_flags & (IN6_IFF_DETACHED | 2806 IN6_IFF_ANYCAST | IN6_IFF_NOTREADY))) { 2807 /* Can't bind a non-existent addr. */ 2808 return (EINVAL); 2809 } 2810 } 2811 #endif /* INET6 */ 2812 /* add this address */ 2813 sctp_addr_mgmt_ep(inp, ifa, type); 2814 } else { 2815 /* invalid address! */ 2816 return (EADDRNOTAVAIL); 2817 } 2818 return (0); 2819 } 2820 2821 void 2822 sctp_addr_change(struct ifaddr *ifa, int cmd) 2823 { 2824 struct sctp_laddr *wi; 2825 2826 wi = (struct sctp_laddr *)SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr); 2827 if (wi == NULL) { 2828 /* 2829 * Gak, what can we do? We have lost an address change can 2830 * you say HOSED? 2831 */ 2832 #ifdef SCTP_DEBUG 2833 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 2834 printf("Lost and address change ???\n"); 2835 } 2836 #endif /* SCTP_DEBUG */ 2837 return; 2838 } 2839 SCTP_INCR_LADDR_COUNT(); 2840 bzero(wi, sizeof(*wi)); 2841 wi->ifa = ifa; 2842 IFAREF(ifa); 2843 2844 wi->action = cmd; 2845 SCTP_IPI_ADDR_LOCK(); 2846 /* 2847 * Should this really be a tailq? As it is we will process the 2848 * newest first :-0 2849 */ 2850 LIST_INSERT_HEAD(&sctppcbinfo.addr_wq, wi, sctp_nxt_addr); 2851 sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ, 2852 (struct sctp_inpcb *)NULL, 2853 (struct sctp_tcb *)NULL, 2854 (struct sctp_nets *)NULL); 2855 SCTP_IPI_ADDR_UNLOCK(); 2856 } 2857