1 /* SCTP kernel Implementation: User API extensions. 2 * 3 * sctp_recvmsg.c 4 * 5 * Distributed under the terms of the LGPL v2.1 as described in 6 * http://www.gnu.org/copyleft/lesser.txt 7 * 8 * This file is part of the user library that offers support for the 9 * SCTP kernel Implementation. The main purpose of this 10 * code is to provide the SCTP Socket API mappings for user 11 * application to interface with the SCTP in kernel. 12 * 13 * This implementation is based on the Socket API Extensions for SCTP 14 * defined in <draft-ietf-tsvwg-sctpsocket-10.txt> 15 * 16 * Copyright (c) 2003 International Business Machines, Corp. 17 * 18 * Written or modified by: 19 * Ryan Layer <rmlayer (at) us.ibm.com> 20 * 21 * An implementation may provide a library function (or possibly system 22 * call) to assist the user with the advanced features of SCTP. Note 23 * that in order for the sctp_sndrcvinfo structure to be filled in by 24 * sctp_recvmsg() the caller must enable the sctp_data_io_events with 25 * the SCTP_EVENTS option. 26 * 27 * sctp_recvmsg(). Its syntax is, 28 * 29 * int sctp_recvmsg(int s, 30 * void *msg, 31 * size_t len, 32 * struct sockaddr *from, 33 * socklen_t *fromlen, 34 * struct sctp_sndrcvinfo *sinfo, 35 * int *msg_flags) 36 * 37 * 38 * s - is the socket descriptor 39 * msg - is a message buffer to be filled. 40 * len - is the length of the message buffer. 41 * from - is a pointer to a address to be filled with 42 * the sender of this messages address. 43 * fromlen - is the from length. 44 * sinfo - A pointer to a sctp_sndrcvinfo structure 45 * to be filled upon receipt of the message. 46 * msg_flags - A pointer to a integer to be filled with 47 * any message flags (e.g. MSG_NOTIFICATION). 48 */ 49 50 #include <string.h> 51 #include <errno.h> 52 #include <sys/socket.h> /* struct sockaddr_storage, setsockopt() */ 53 #include <netinet/sctp.h> 54 55 int sctp_recvmsg(int s, void *msg, size_t len, struct sockaddr *from, 56 socklen_t *fromlen, struct sctp_sndrcvinfo *sinfo, 57 int *msg_flags) 58 { 59 int error; 60 struct iovec iov; 61 struct msghdr inmsg; 62 char incmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; 63 struct cmsghdr *cmsg = NULL; 64 65 memset(&inmsg, 0, sizeof (inmsg)); 66 67 iov.iov_base = msg; 68 iov.iov_len = len; 69 70 inmsg.msg_name = from; 71 inmsg.msg_namelen = fromlen ? *fromlen : 0; 72 inmsg.msg_iov = &iov; 73 inmsg.msg_iovlen = 1; 74 inmsg.msg_control = incmsg; 75 inmsg.msg_controllen = sizeof(incmsg); 76 77 error = recvmsg(s, &inmsg, msg_flags ? *msg_flags : 0); 78 if (error < 0) 79 return error; 80 81 if (fromlen) 82 *fromlen = inmsg.msg_namelen; 83 if (msg_flags) 84 *msg_flags = inmsg.msg_flags; 85 86 if (!sinfo) 87 return error; 88 89 for (cmsg = CMSG_FIRSTHDR(&inmsg); cmsg != NULL; 90 cmsg = CMSG_NXTHDR(&inmsg, cmsg)){ 91 if ((IPPROTO_SCTP == cmsg->cmsg_level) && 92 (SCTP_SNDRCV == cmsg->cmsg_type)) 93 break; 94 } 95 96 /* Copy sinfo. */ 97 if (cmsg) 98 memcpy(sinfo, CMSG_DATA(cmsg), sizeof(struct sctp_sndrcvinfo)); 99 100 return (error); 101 } 102