| 8942 | } |
| 8943 | |
| 8944 | int |
| 8945 | sctp_send_cookie_echo(struct mbuf *m, |
| 8946 | int offset, int limit, |
| 8947 | struct sctp_tcb *stcb, |
| 8948 | struct sctp_nets *net) |
| 8949 | { |
| 8950 | /*- |
| 8951 | * pull out the cookie and put it at the front of the control chunk |
| 8952 | * queue. |
| 8953 | */ |
| 8954 | int at; |
| 8955 | struct mbuf *cookie; |
| 8956 | struct sctp_paramhdr param, *phdr; |
| 8957 | struct sctp_chunkhdr *hdr; |
| 8958 | struct sctp_tmit_chunk *chk; |
| 8959 | uint16_t ptype, plen; |
| 8960 | |
| 8961 | SCTP_TCB_LOCK_ASSERT(stcb); |
| 8962 | /* First find the cookie in the param area */ |
| 8963 | cookie = NULL; |
| 8964 | at = offset + sizeof(struct sctp_init_chunk); |
| 8965 | for (;;) { |
| 8966 | phdr = sctp_get_next_param(m, at, ¶m, sizeof(param)); |
| 8967 | if (phdr == NULL) { |
| 8968 | return (-3); |
| 8969 | } |
| 8970 | ptype = ntohs(phdr->param_type); |
| 8971 | plen = ntohs(phdr->param_length); |
| 8972 | if (plen < sizeof(struct sctp_paramhdr)) { |
| 8973 | return (-6); |
| 8974 | } |
| 8975 | if (ptype == SCTP_STATE_COOKIE) { |
| 8976 | int pad; |
| 8977 | |
| 8978 | /* found the cookie */ |
| 8979 | if (at + plen > limit) { |
| 8980 | return (-7); |
| 8981 | } |
| 8982 | cookie = SCTP_M_COPYM(m, at, plen, M_NOWAIT); |
| 8983 | if (cookie == NULL) { |
| 8984 | /* No memory */ |
| 8985 | return (-2); |
| 8986 | } |
| 8987 | if ((pad = (plen % 4)) > 0) { |
| 8988 | pad = 4 - pad; |
| 8989 | } |
| 8990 | if (pad > 0) { |
| 8991 | if (sctp_pad_lastmbuf(cookie, pad, NULL) == NULL) { |
| 8992 | return (-8); |
| 8993 | } |
| 8994 | } |
| 8995 | #ifdef SCTP_MBUF_LOGGING |
| 8996 | if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) { |
| 8997 | sctp_log_mbc(cookie, SCTP_MBUF_ICOPY); |
| 8998 | } |
| 8999 | #endif |
| 9000 | break; |
| 9001 | } |
no test coverage detected