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