| 169 | } |
| 170 | |
| 171 | struct mbuf * |
| 172 | sctp_build_ctl_nchunk(struct sctp_inpcb *inp, struct sctp_sndrcvinfo *sinfo) |
| 173 | { |
| 174 | struct sctp_extrcvinfo *seinfo; |
| 175 | struct sctp_sndrcvinfo *outinfo; |
| 176 | struct sctp_rcvinfo *rcvinfo; |
| 177 | struct sctp_nxtinfo *nxtinfo; |
| 178 | struct cmsghdr *cmh; |
| 179 | struct mbuf *ret; |
| 180 | int len; |
| 181 | int use_extended; |
| 182 | int provide_nxt; |
| 183 | |
| 184 | if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT) && |
| 185 | sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVRCVINFO) && |
| 186 | sctp_is_feature_off(inp, SCTP_PCB_FLAGS_RECVNXTINFO)) { |
| 187 | /* user does not want any ancillary data */ |
| 188 | return (NULL); |
| 189 | } |
| 190 | |
| 191 | len = 0; |
| 192 | if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO)) { |
| 193 | len += CMSG_SPACE(sizeof(struct sctp_rcvinfo)); |
| 194 | } |
| 195 | seinfo = (struct sctp_extrcvinfo *)sinfo; |
| 196 | if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO) && |
| 197 | (seinfo->serinfo_next_flags & SCTP_NEXT_MSG_AVAIL)) { |
| 198 | provide_nxt = 1; |
| 199 | len += CMSG_SPACE(sizeof(struct sctp_nxtinfo)); |
| 200 | } else { |
| 201 | provide_nxt = 0; |
| 202 | } |
| 203 | if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT)) { |
| 204 | if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO)) { |
| 205 | use_extended = 1; |
| 206 | len += CMSG_SPACE(sizeof(struct sctp_extrcvinfo)); |
| 207 | } else { |
| 208 | use_extended = 0; |
| 209 | len += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)); |
| 210 | } |
| 211 | } else { |
| 212 | use_extended = 0; |
| 213 | } |
| 214 | |
| 215 | ret = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA); |
| 216 | if (ret == NULL) { |
| 217 | /* No space */ |
| 218 | return (ret); |
| 219 | } |
| 220 | SCTP_BUF_LEN(ret) = 0; |
| 221 | |
| 222 | /* We need a CMSG header followed by the struct */ |
| 223 | cmh = mtod(ret, struct cmsghdr *); |
| 224 | /* |
| 225 | * Make sure that there is no un-initialized padding between the |
| 226 | * cmsg header and cmsg data and after the cmsg data. |
| 227 | */ |
| 228 | memset(cmh, 0, len); |
no test coverage detected