* builds an ASCONF chunk from queued ASCONF params. * returns NULL on error (no mbuf, no ASCONF params queued, etc). */
| 2552 | * returns NULL on error (no mbuf, no ASCONF params queued, etc). |
| 2553 | */ |
| 2554 | struct mbuf * |
| 2555 | sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked) |
| 2556 | { |
| 2557 | struct mbuf *m_asconf, *m_asconf_chk; |
| 2558 | struct sctp_asconf_addr *aa; |
| 2559 | struct sctp_asconf_chunk *acp; |
| 2560 | struct sctp_asconf_paramhdr *aph; |
| 2561 | struct sctp_asconf_addr_param *aap; |
| 2562 | uint32_t p_length; |
| 2563 | uint32_t correlation_id = 1; /* 0 is reserved... */ |
| 2564 | caddr_t ptr, lookup_ptr; |
| 2565 | uint8_t lookup_used = 0; |
| 2566 | |
| 2567 | /* are there any asconf params to send? */ |
| 2568 | TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) { |
| 2569 | if (aa->sent == 0) |
| 2570 | break; |
| 2571 | } |
| 2572 | if (aa == NULL) |
| 2573 | return (NULL); |
| 2574 | |
| 2575 | /* |
| 2576 | * get a chunk header mbuf and a cluster for the asconf params since |
| 2577 | * it's simpler to fill in the asconf chunk header lookup address on |
| 2578 | * the fly |
| 2579 | */ |
| 2580 | m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 0, M_NOWAIT, 1, MT_DATA); |
| 2581 | if (m_asconf_chk == NULL) { |
| 2582 | /* no mbuf's */ |
| 2583 | SCTPDBG(SCTP_DEBUG_ASCONF1, |
| 2584 | "sctp_compose_asconf: couldn't get chunk mbuf!\n"); |
| 2585 | return (NULL); |
| 2586 | } |
| 2587 | m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA); |
| 2588 | if (m_asconf == NULL) { |
| 2589 | /* no mbuf's */ |
| 2590 | SCTPDBG(SCTP_DEBUG_ASCONF1, |
| 2591 | "sctp_compose_asconf: couldn't get mbuf!\n"); |
| 2592 | sctp_m_freem(m_asconf_chk); |
| 2593 | return (NULL); |
| 2594 | } |
| 2595 | SCTP_BUF_LEN(m_asconf_chk) = sizeof(struct sctp_asconf_chunk); |
| 2596 | SCTP_BUF_LEN(m_asconf) = 0; |
| 2597 | acp = mtod(m_asconf_chk, struct sctp_asconf_chunk *); |
| 2598 | memset(acp, 0, sizeof(struct sctp_asconf_chunk)); |
| 2599 | /* save pointers to lookup address and asconf params */ |
| 2600 | lookup_ptr = (caddr_t)(acp + 1); /* after the header */ |
| 2601 | ptr = mtod(m_asconf, caddr_t); /* beginning of cluster */ |
| 2602 | |
| 2603 | /* fill in chunk header info */ |
| 2604 | acp->ch.chunk_type = SCTP_ASCONF; |
| 2605 | acp->ch.chunk_flags = 0; |
| 2606 | acp->serial_number = htonl(stcb->asoc.asconf_seq_out); |
| 2607 | stcb->asoc.asconf_seq_out++; |
| 2608 | |
| 2609 | /* add parameters... up to smallest MTU allowed */ |
| 2610 | TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) { |
| 2611 | if (aa->sent) |
no test coverage detected