/* SCTP kernel Implementation: User API extensions. * * sendmsg.c * * Distributed under the terms of the LGPL v2.1 as described in * http://www.gnu.org/copyleft/lesser.txt * * This file is part of the user library that offers support for the * SCTP kernel Implementation. The main purpose of this * code is to provide the SCTP Socket API mappings for user * application to interface with the SCTP in kernel. * * This implementation is based on the Socket API Extensions for SCTP * defined in * * Copyright (c) 2003 Intel Corp. * * Written or modified by: * Ardelle Fan */ #include #include /* struct sockaddr_storage, setsockopt() */ #include /* This library function assists the user with the advanced features * of SCTP. This is a new SCTP API described in the section 8.7 of the * Sockets API Extensions for SCTP. This is implemented using the * sendmsg() interface. */ int sctp_sendmsg(int s, const void *msg, size_t len, struct sockaddr *to, socklen_t tolen, uint32_t ppid, uint32_t flags, uint16_t stream_no, uint32_t timetolive, uint32_t context) { struct msghdr outmsg; struct iovec iov; char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; struct cmsghdr *cmsg; struct sctp_sndrcvinfo *sinfo; outmsg.msg_name = to; outmsg.msg_namelen = tolen; outmsg.msg_iov = &iov; iov.iov_base = (void *)msg; iov.iov_len = len; outmsg.msg_iovlen = 1; outmsg.msg_control = outcmsg; outmsg.msg_controllen = sizeof(outcmsg); outmsg.msg_flags = 0; cmsg = CMSG_FIRSTHDR(&outmsg); cmsg->cmsg_level = IPPROTO_SCTP; cmsg->cmsg_type = SCTP_SNDRCV; cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); outmsg.msg_controllen = cmsg->cmsg_len; sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo)); sinfo->sinfo_ppid = ppid; sinfo->sinfo_flags = flags; sinfo->sinfo_stream = stream_no; sinfo->sinfo_timetolive = timetolive; sinfo->sinfo_context = context; return sendmsg(s, &outmsg, 0); } /* This library function assist the user with sending a message without * dealing directly with the CMSG header. */ int sctp_send(int s, const void *msg, size_t len, const struct sctp_sndrcvinfo *sinfo, int flags) { struct msghdr outmsg; struct iovec iov; char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; outmsg.msg_name = NULL; outmsg.msg_namelen = 0; outmsg.msg_iov = &iov; iov.iov_base = (void *)msg; iov.iov_len = len; outmsg.msg_iovlen = 1; outmsg.msg_controllen = 0; if (sinfo) { struct cmsghdr *cmsg; outmsg.msg_control = outcmsg; outmsg.msg_controllen = sizeof(outcmsg); outmsg.msg_flags = 0; cmsg = CMSG_FIRSTHDR(&outmsg); cmsg->cmsg_level = IPPROTO_SCTP; cmsg->cmsg_type = SCTP_SNDRCV; cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); outmsg.msg_controllen = cmsg->cmsg_len; memcpy(CMSG_DATA(cmsg), sinfo, sizeof(struct sctp_sndrcvinfo)); } return sendmsg(s, &outmsg, flags); }