Home | History | Annotate | Download | only in lib
      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