* generate an AUTHentication chunk, if required */
| 13701 | * generate an AUTHentication chunk, if required |
| 13702 | */ |
| 13703 | struct mbuf * |
| 13704 | sctp_add_auth_chunk(struct mbuf *m, struct mbuf **m_end, |
| 13705 | struct sctp_auth_chunk **auth_ret, uint32_t *offset, |
| 13706 | struct sctp_tcb *stcb, uint8_t chunk) |
| 13707 | { |
| 13708 | struct mbuf *m_auth; |
| 13709 | struct sctp_auth_chunk *auth; |
| 13710 | int chunk_len; |
| 13711 | struct mbuf *cn; |
| 13712 | |
| 13713 | if ((m_end == NULL) || (auth_ret == NULL) || (offset == NULL) || |
| 13714 | (stcb == NULL)) |
| 13715 | return (m); |
| 13716 | |
| 13717 | if (stcb->asoc.auth_supported == 0) { |
| 13718 | return (m); |
| 13719 | } |
| 13720 | /* does the requested chunk require auth? */ |
| 13721 | if (!sctp_auth_is_required_chunk(chunk, stcb->asoc.peer_auth_chunks)) { |
| 13722 | return (m); |
| 13723 | } |
| 13724 | m_auth = sctp_get_mbuf_for_msg(sizeof(*auth), 0, M_NOWAIT, 1, MT_HEADER); |
| 13725 | if (m_auth == NULL) { |
| 13726 | /* no mbuf's */ |
| 13727 | return (m); |
| 13728 | } |
| 13729 | /* reserve some space if this will be the first mbuf */ |
| 13730 | if (m == NULL) |
| 13731 | SCTP_BUF_RESV_UF(m_auth, SCTP_MIN_OVERHEAD); |
| 13732 | /* fill in the AUTH chunk details */ |
| 13733 | auth = mtod(m_auth, struct sctp_auth_chunk *); |
| 13734 | memset(auth, 0, sizeof(*auth)); |
| 13735 | auth->ch.chunk_type = SCTP_AUTHENTICATION; |
| 13736 | auth->ch.chunk_flags = 0; |
| 13737 | chunk_len = sizeof(*auth) + |
| 13738 | sctp_get_hmac_digest_len(stcb->asoc.peer_hmac_id); |
| 13739 | auth->ch.chunk_length = htons(chunk_len); |
| 13740 | auth->hmac_id = htons(stcb->asoc.peer_hmac_id); |
| 13741 | /* key id and hmac digest will be computed and filled in upon send */ |
| 13742 | |
| 13743 | /* save the offset where the auth was inserted into the chain */ |
| 13744 | *offset = 0; |
| 13745 | for (cn = m; cn; cn = SCTP_BUF_NEXT(cn)) { |
| 13746 | *offset += SCTP_BUF_LEN(cn); |
| 13747 | } |
| 13748 | |
| 13749 | /* update length and return pointer to the auth chunk */ |
| 13750 | SCTP_BUF_LEN(m_auth) = chunk_len; |
| 13751 | m = sctp_copy_mbufchain(m_auth, m, m_end, 1, chunk_len, 0); |
| 13752 | if (auth_ret != NULL) |
| 13753 | *auth_ret = auth; |
| 13754 | |
| 13755 | return (m); |
| 13756 | } |
| 13757 | |
| 13758 | #ifdef INET6 |
| 13759 | int |
no test coverage detected