* INIT-ACK message processing/consumption returns value < 0 on error */
| 428 | * INIT-ACK message processing/consumption returns value < 0 on error |
| 429 | */ |
| 430 | static int |
| 431 | sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, |
| 432 | struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, |
| 433 | struct sctp_init_ack_chunk *cp, struct sctp_tcb *stcb, |
| 434 | struct sctp_nets *net, int *abort_no_unlock, |
| 435 | uint8_t mflowtype, uint32_t mflowid, |
| 436 | uint32_t vrf_id) |
| 437 | { |
| 438 | struct sctp_association *asoc; |
| 439 | struct mbuf *op_err; |
| 440 | int retval, abort_flag, cookie_found; |
| 441 | int initack_limit; |
| 442 | int nat_friendly = 0; |
| 443 | |
| 444 | /* First verify that we have no illegal param's */ |
| 445 | abort_flag = 0; |
| 446 | cookie_found = 0; |
| 447 | |
| 448 | op_err = sctp_arethere_unrecognized_parameters(m, |
| 449 | (offset + sizeof(struct sctp_init_chunk)), |
| 450 | &abort_flag, (struct sctp_chunkhdr *)cp, |
| 451 | &nat_friendly, &cookie_found); |
| 452 | if (abort_flag) { |
| 453 | /* Send an abort and notify peer */ |
| 454 | sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED); |
| 455 | *abort_no_unlock = 1; |
| 456 | return (-1); |
| 457 | } |
| 458 | if (!cookie_found) { |
| 459 | uint16_t len; |
| 460 | |
| 461 | /* Only report the missing cookie parameter */ |
| 462 | if (op_err != NULL) { |
| 463 | sctp_m_freem(op_err); |
| 464 | } |
| 465 | len = (uint16_t)(sizeof(struct sctp_error_missing_param) + sizeof(uint16_t)); |
| 466 | /* We abort with an error of missing mandatory param */ |
| 467 | op_err = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA); |
| 468 | if (op_err != NULL) { |
| 469 | struct sctp_error_missing_param *cause; |
| 470 | |
| 471 | SCTP_BUF_LEN(op_err) = len; |
| 472 | cause = mtod(op_err, struct sctp_error_missing_param *); |
| 473 | /* Subtract the reserved param */ |
| 474 | cause->cause.code = htons(SCTP_CAUSE_MISSING_PARAM); |
| 475 | cause->cause.length = htons(len); |
| 476 | cause->num_missing_params = htonl(1); |
| 477 | cause->type[0] = htons(SCTP_STATE_COOKIE); |
| 478 | } |
| 479 | sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, |
| 480 | src, dst, sh, op_err, |
| 481 | mflowtype, mflowid, |
| 482 | vrf_id, net->port); |
| 483 | *abort_no_unlock = 1; |
| 484 | return (-3); |
| 485 | } |
| 486 | asoc = &stcb->asoc; |
| 487 | asoc->peer_supports_nat = (uint8_t)nat_friendly; |
no test coverage detected