1 /* SCTP kernel Implementation: User API extensions. 2 * 3 * bindx.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 * (C) Copyright IBM Corp. 2001, 2003 17 * Copyright (c) 2002 Intel Corporation. 18 * 19 * Written or modified by: 20 * La Monte H.P. Yarroll <piggy (at) acm.org> 21 * Daisy Chang <daisyc (at) us.ibm.com> 22 * Inaky Perez-Gonzalez <inaky.gonzalez (at) intel.com> 23 * Sridhar Samudrala <sri (at) us.ibm.com> 24 */ 25 26 #include <sys/socket.h> /* struct sockaddr_storage, setsockopt() */ 27 #include <netinet/in.h> 28 #include <netinet/sctp.h> /* SCTP_SOCKOPT_BINDX_* */ 29 #include <errno.h> 30 31 /* Support the sctp_bindx() interface. 32 * 33 * See Sockets API Extensions for SCTP. Section 8.1. 34 * 35 * Instead of implementing through a socket call in sys_socketcall(), 36 * tunnel the request through setsockopt(). 37 */ 38 int 39 sctp_bindx(int fd, struct sockaddr *addrs, int addrcnt, int flags) 40 { 41 int setsock_option = 0; 42 void *addrbuf; 43 struct sockaddr *sa_addr; 44 socklen_t addrs_size = 0; 45 int i; 46 47 switch (flags) { 48 case SCTP_BINDX_ADD_ADDR: 49 setsock_option = SCTP_SOCKOPT_BINDX_ADD; 50 break; 51 case SCTP_BINDX_REM_ADDR: 52 setsock_option = SCTP_SOCKOPT_BINDX_REM; 53 break; 54 default: 55 errno = EINVAL; 56 return -1; 57 } 58 59 addrbuf = addrs; 60 for (i = 0; i < addrcnt; i++) { 61 sa_addr = (struct sockaddr *)addrbuf; 62 switch (sa_addr->sa_family) { 63 case AF_INET: 64 addrs_size += sizeof(struct sockaddr_in); 65 addrbuf += sizeof(struct sockaddr_in); 66 break; 67 case AF_INET6: 68 addrs_size += sizeof(struct sockaddr_in6); 69 addrbuf += sizeof(struct sockaddr_in6); 70 break; 71 default: 72 errno = EINVAL; 73 return -1; 74 } 75 } 76 77 return setsockopt(fd, SOL_SCTP, setsock_option, addrs, addrs_size); 78 } 79