1f08c3bdfSopenharmony_ci/* SCTP kernel Implementation: User API extensions. 2f08c3bdfSopenharmony_ci * 3f08c3bdfSopenharmony_ci * sendmsg.c 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * Distributed under the terms of the LGPL v2.1 as described in 6f08c3bdfSopenharmony_ci * http://www.gnu.org/copyleft/lesser.txt 7f08c3bdfSopenharmony_ci * 8f08c3bdfSopenharmony_ci * This file is part of the user library that offers support for the 9f08c3bdfSopenharmony_ci * SCTP kernel Implementation. The main purpose of this 10f08c3bdfSopenharmony_ci * code is to provide the SCTP Socket API mappings for user 11f08c3bdfSopenharmony_ci * application to interface with the SCTP in kernel. 12f08c3bdfSopenharmony_ci * 13f08c3bdfSopenharmony_ci * This implementation is based on the Socket API Extensions for SCTP 14f08c3bdfSopenharmony_ci * defined in <draft-ietf-tsvwg-sctpsocket-10.txt> 15f08c3bdfSopenharmony_ci * 16f08c3bdfSopenharmony_ci * Copyright (c) 2003 Intel Corp. 17f08c3bdfSopenharmony_ci * 18f08c3bdfSopenharmony_ci * Written or modified by: 19f08c3bdfSopenharmony_ci * Ardelle Fan <ardelle.fan@intel.com> 20f08c3bdfSopenharmony_ci */ 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_ci#include <string.h> 23f08c3bdfSopenharmony_ci#include <sys/socket.h> /* struct sockaddr_storage, setsockopt() */ 24f08c3bdfSopenharmony_ci#include <netinet/sctp.h> 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_ci/* This library function assists the user with the advanced features 27f08c3bdfSopenharmony_ci * of SCTP. This is a new SCTP API described in the section 8.7 of the 28f08c3bdfSopenharmony_ci * Sockets API Extensions for SCTP. This is implemented using the 29f08c3bdfSopenharmony_ci * sendmsg() interface. 30f08c3bdfSopenharmony_ci */ 31f08c3bdfSopenharmony_ciint 32f08c3bdfSopenharmony_cisctp_sendmsg(int s, const void *msg, size_t len, struct sockaddr *to, 33f08c3bdfSopenharmony_ci socklen_t tolen, uint32_t ppid, uint32_t flags, 34f08c3bdfSopenharmony_ci uint16_t stream_no, uint32_t timetolive, uint32_t context) 35f08c3bdfSopenharmony_ci{ 36f08c3bdfSopenharmony_ci struct msghdr outmsg; 37f08c3bdfSopenharmony_ci struct iovec iov; 38f08c3bdfSopenharmony_ci char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; 39f08c3bdfSopenharmony_ci struct cmsghdr *cmsg; 40f08c3bdfSopenharmony_ci struct sctp_sndrcvinfo *sinfo; 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_ci outmsg.msg_name = to; 43f08c3bdfSopenharmony_ci outmsg.msg_namelen = tolen; 44f08c3bdfSopenharmony_ci outmsg.msg_iov = &iov; 45f08c3bdfSopenharmony_ci iov.iov_base = (void *)msg; 46f08c3bdfSopenharmony_ci iov.iov_len = len; 47f08c3bdfSopenharmony_ci outmsg.msg_iovlen = 1; 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_ci outmsg.msg_control = outcmsg; 50f08c3bdfSopenharmony_ci outmsg.msg_controllen = sizeof(outcmsg); 51f08c3bdfSopenharmony_ci outmsg.msg_flags = 0; 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_ci cmsg = CMSG_FIRSTHDR(&outmsg); 54f08c3bdfSopenharmony_ci cmsg->cmsg_level = IPPROTO_SCTP; 55f08c3bdfSopenharmony_ci cmsg->cmsg_type = SCTP_SNDRCV; 56f08c3bdfSopenharmony_ci cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); 57f08c3bdfSopenharmony_ci 58f08c3bdfSopenharmony_ci outmsg.msg_controllen = cmsg->cmsg_len; 59f08c3bdfSopenharmony_ci sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); 60f08c3bdfSopenharmony_ci memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo)); 61f08c3bdfSopenharmony_ci sinfo->sinfo_ppid = ppid; 62f08c3bdfSopenharmony_ci sinfo->sinfo_flags = flags; 63f08c3bdfSopenharmony_ci sinfo->sinfo_stream = stream_no; 64f08c3bdfSopenharmony_ci sinfo->sinfo_timetolive = timetolive; 65f08c3bdfSopenharmony_ci sinfo->sinfo_context = context; 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_ci return sendmsg(s, &outmsg, 0); 68f08c3bdfSopenharmony_ci} 69f08c3bdfSopenharmony_ci 70f08c3bdfSopenharmony_ci/* This library function assist the user with sending a message without 71f08c3bdfSopenharmony_ci * dealing directly with the CMSG header. 72f08c3bdfSopenharmony_ci */ 73f08c3bdfSopenharmony_ciint 74f08c3bdfSopenharmony_cisctp_send(int s, const void *msg, size_t len, 75f08c3bdfSopenharmony_ci const struct sctp_sndrcvinfo *sinfo, int flags) 76f08c3bdfSopenharmony_ci{ 77f08c3bdfSopenharmony_ci struct msghdr outmsg; 78f08c3bdfSopenharmony_ci struct iovec iov; 79f08c3bdfSopenharmony_ci char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; 80f08c3bdfSopenharmony_ci 81f08c3bdfSopenharmony_ci outmsg.msg_name = NULL; 82f08c3bdfSopenharmony_ci outmsg.msg_namelen = 0; 83f08c3bdfSopenharmony_ci outmsg.msg_iov = &iov; 84f08c3bdfSopenharmony_ci iov.iov_base = (void *)msg; 85f08c3bdfSopenharmony_ci iov.iov_len = len; 86f08c3bdfSopenharmony_ci outmsg.msg_iovlen = 1; 87f08c3bdfSopenharmony_ci outmsg.msg_controllen = 0; 88f08c3bdfSopenharmony_ci 89f08c3bdfSopenharmony_ci if (sinfo) { 90f08c3bdfSopenharmony_ci struct cmsghdr *cmsg; 91f08c3bdfSopenharmony_ci 92f08c3bdfSopenharmony_ci outmsg.msg_control = outcmsg; 93f08c3bdfSopenharmony_ci outmsg.msg_controllen = sizeof(outcmsg); 94f08c3bdfSopenharmony_ci outmsg.msg_flags = 0; 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_ci cmsg = CMSG_FIRSTHDR(&outmsg); 97f08c3bdfSopenharmony_ci cmsg->cmsg_level = IPPROTO_SCTP; 98f08c3bdfSopenharmony_ci cmsg->cmsg_type = SCTP_SNDRCV; 99f08c3bdfSopenharmony_ci cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_ci outmsg.msg_controllen = cmsg->cmsg_len; 102f08c3bdfSopenharmony_ci memcpy(CMSG_DATA(cmsg), sinfo, sizeof(struct sctp_sndrcvinfo)); 103f08c3bdfSopenharmony_ci } 104f08c3bdfSopenharmony_ci 105f08c3bdfSopenharmony_ci return sendmsg(s, &outmsg, flags); 106f08c3bdfSopenharmony_ci} 107