| 3555 | } |
| 3556 | |
| 3557 | static int |
| 3558 | sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *error) |
| 3559 | { |
| 3560 | struct cmsghdr cmh; |
| 3561 | struct sctp_initmsg initmsg; |
| 3562 | #ifdef INET |
| 3563 | struct sockaddr_in sin; |
| 3564 | #endif |
| 3565 | #ifdef INET6 |
| 3566 | struct sockaddr_in6 sin6; |
| 3567 | #endif |
| 3568 | int tot_len, rem_len, cmsg_data_len, cmsg_data_off, off; |
| 3569 | |
| 3570 | tot_len = SCTP_BUF_LEN(control); |
| 3571 | for (off = 0; off < tot_len; off += CMSG_ALIGN(cmh.cmsg_len)) { |
| 3572 | rem_len = tot_len - off; |
| 3573 | if (rem_len < (int)CMSG_ALIGN(sizeof(cmh))) { |
| 3574 | /* There is not enough room for one more. */ |
| 3575 | *error = EINVAL; |
| 3576 | return (1); |
| 3577 | } |
| 3578 | m_copydata(control, off, sizeof(cmh), (caddr_t)&cmh); |
| 3579 | if (cmh.cmsg_len < CMSG_ALIGN(sizeof(cmh))) { |
| 3580 | /* We dont't have a complete CMSG header. */ |
| 3581 | *error = EINVAL; |
| 3582 | return (1); |
| 3583 | } |
| 3584 | if ((cmh.cmsg_len > INT_MAX) || ((int)cmh.cmsg_len > rem_len)) { |
| 3585 | /* We don't have the complete CMSG. */ |
| 3586 | *error = EINVAL; |
| 3587 | return (1); |
| 3588 | } |
| 3589 | cmsg_data_len = (int)cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh)); |
| 3590 | cmsg_data_off = off + CMSG_ALIGN(sizeof(cmh)); |
| 3591 | if (cmh.cmsg_level == IPPROTO_SCTP) { |
| 3592 | switch (cmh.cmsg_type) { |
| 3593 | case SCTP_INIT: |
| 3594 | if (cmsg_data_len < (int)sizeof(struct sctp_initmsg)) { |
| 3595 | *error = EINVAL; |
| 3596 | return (1); |
| 3597 | } |
| 3598 | m_copydata(control, cmsg_data_off, sizeof(struct sctp_initmsg), (caddr_t)&initmsg); |
| 3599 | if (initmsg.sinit_max_attempts) |
| 3600 | stcb->asoc.max_init_times = initmsg.sinit_max_attempts; |
| 3601 | if (initmsg.sinit_num_ostreams) |
| 3602 | stcb->asoc.pre_open_streams = initmsg.sinit_num_ostreams; |
| 3603 | if (initmsg.sinit_max_instreams) |
| 3604 | stcb->asoc.max_inbound_streams = initmsg.sinit_max_instreams; |
| 3605 | if (initmsg.sinit_max_init_timeo) |
| 3606 | stcb->asoc.initial_init_rto_max = initmsg.sinit_max_init_timeo; |
| 3607 | if (stcb->asoc.streamoutcnt < stcb->asoc.pre_open_streams) { |
| 3608 | struct sctp_stream_out *tmp_str; |
| 3609 | unsigned int i; |
| 3610 | #if defined(SCTP_DETAILED_STR_STATS) |
| 3611 | int j; |
| 3612 | #endif |
| 3613 | |
| 3614 | /* Default is NOT correct */ |
no test coverage detected