• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SCTP kernel Implementation
2  * Copyright (c) 2003 Hewlett-Packard Development Company, L.P
3  * (C) Copyright IBM Corp. 2004
4  *
5  * This file has test cases to test the recvmsg() call for 1-1 style sockets
6  *
7  * TEST1: Bad socket descriptor
8  * TEST2: Invalid socket
9  * TEST3: Invalid iovec pointer
10  * TEST4: Invalid msghdr pointer
11  * TEST5: On a listening socket
12  * TEST6: Reading on a socket that received SHUTDOWN
13  * TEST7: Reading the pending message socket that received SHUTDOWN
14  * TEST8: No more message and association is shutdown
15  *
16  * The SCTP implementation is free software;
17  * you can redistribute it and/or modify it under the terms of
18  * the GNU General Public License as published by
19  * the Free Software Foundation; either version 2, or (at your option)
20  * any later version.
21  *
22  * The SCTP implementation is distributed in the hope that it
23  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
24  *                 ************************
25  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26  * See the GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with GNU CC; see the file COPYING.  If not, write to
30  * the Free Software Foundation, 59 Temple Place - Suite 330,
31  * Boston, MA 02111-1307, USA.
32  *
33  * Please send any bug reports or fixes you make to the
34  * email address(es):
35  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
36  *
37  * Or submit a bug report through the following website:
38  *    http://www.sf.net/projects/lksctp
39  *
40  * Any bugs reported given to us we will try to fix... any fixes shared will
41  * be incorporated into the next SCTP release
42  *
43  */
44 
45 #include <stdio.h>
46 #include <unistd.h>
47 #include <fcntl.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <sys/types.h>
51 #include <sys/socket.h>
52 #include <netinet/in.h>         /* for sockaddr_in */
53 #include <arpa/inet.h>
54 #include <errno.h>
55 #include <netinet/sctp.h>
56 #include <sys/uio.h>
57 #include <linux/socket.h>
58 #include <sctputil.h>
59 
60 char *TCID = __FILE__;
61 int TST_TOTAL = 8;
62 int TST_CNT = 0;
63 
64 int
main(int argc,char * argv[])65 main(int argc, char *argv[])
66 {
67         socklen_t len;
68 	int sk,pf_class,lstn_sk,acpt_sk;
69 	int flag = 0;
70 	int fd, err_no = 0;
71 	char filename[21];
72 	struct msghdr inmessage;
73         char *message = "hello, world!\n";
74 	struct iovec iov_rcv;
75         int count;
76 	char * buffer_rcv;
77         char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
78 	char *message1 = "hello, world!\n";
79 
80         struct sockaddr_in conn_addr,lstn_addr,svr_addr;
81 
82 	/* Rather than fflush() throughout the code, set stdout to
83          * be unbuffered.
84          */
85         setvbuf(stdout, NULL, _IONBF, 0);
86         setvbuf(stderr, NULL, _IONBF, 0);
87 
88         pf_class = PF_INET;
89 
90         sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
91 
92         lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
93 
94 	conn_addr.sin_family = AF_INET;
95         conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
96         conn_addr.sin_port = htons(SCTP_TESTPORT_1);
97 
98 	lstn_addr.sin_family = AF_INET;
99         lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
100         lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
101 
102 	/*Binding the listen socket*/
103         test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
104 
105         /*Listening the socket*/
106         test_listen(lstn_sk, 10);
107 
108 	len = sizeof(struct sockaddr_in);
109 
110 	test_connect(sk, (struct sockaddr *) &conn_addr, len);
111 
112 	acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
113 
114 	memset(&inmessage, 0, sizeof(inmessage));
115         buffer_rcv = malloc(REALLY_BIG);
116 
117         iov_rcv.iov_base = buffer_rcv;
118         iov_rcv.iov_len = REALLY_BIG;
119         inmessage.msg_iov = &iov_rcv;
120         inmessage.msg_iovlen = 1;
121         inmessage.msg_control = incmsg;
122         inmessage.msg_controllen = sizeof(incmsg);
123 
124 	/*recvmsg () TEST1: Bad socket descriptor, EBADF Expected error*/
125 	count = recvmsg(-1, &inmessage, flag);
126 	if (count != -1 || errno != EBADF)
127 		tst_brkm(TBROK, tst_exit, "recvmsg with a bad socket "
128 			 "descriptor count:%d, errno:%d", count, errno);
129 
130 	tst_resm(TPASS, "recvmsg() with a bad socket descriptor - EBADF");
131 
132 	/*recvmsg () TEST2: Invalid socket , ENOTSOCK Expected error*/
133 	strcpy(filename, "/tmp/sctptest.XXXXXX");
134 	fd = mkstemp(filename);
135 	if (fd == -1)
136 		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
137 				filename, strerror(errno));
138 	count = recvmsg(fd, &inmessage, flag);
139 	if (count == -1)
140 		err_no = errno;
141 	close(fd);
142 	unlink(filename);
143 	if (count != -1 || err_no != ENOTSOCK)
144 		tst_brkm(TBROK, tst_exit, "recvmsg with invalid socket "
145 			 "count:%d, errno:%d", count, err_no);
146 
147 	tst_resm(TPASS, "recvmsg() with invalid socket - ENOTSOCK");
148 
149 	/*recvmsg () TEST3: Invalid iovec pointer EFAULT, Expected error*/
150 	inmessage.msg_iov = (struct iovec *)-1;
151 	count = recvmsg(acpt_sk, &inmessage, flag);
152 	if (count != -1 || errno != EFAULT)
153 		tst_brkm(TBROK, tst_exit, "recvmsg with invalid iovec "
154 			 "pointer count:%d, errno:%d", count, errno);
155 
156 	tst_resm(TPASS, "recvmsg() with invalid iovec ptr - EFAULT");
157 
158 	inmessage.msg_iov = &iov_rcv;
159 
160 	/*recvmsg () TEST4: Invalid msghdr pointer EFAULT, Expected error*/
161 	count = recvmsg(acpt_sk, (struct msghdr *)-1, flag);
162 	if (count != -1 || errno != EFAULT)
163 		tst_brkm(TBROK, tst_exit, "recvmsg with invalid msghdr "
164 			 "pointer count:%d, errno:%d", count, errno);
165 
166 	tst_resm(TPASS, "recvmsg() with invalid msghdr ptr - EFAULT");
167 
168 	/*recvmsg () TEST5:recvmsg on listening socket,ENOTCONN Expected error*/
169 	count = recvmsg(lstn_sk, &inmessage, flag);
170 	if (count != -1 || errno != ENOTCONN)
171 		tst_brkm(TBROK, tst_exit, "recvmsg on listening socket "
172 			 "count:%d, errno:%d", count, errno);
173 
174 	tst_resm(TPASS, "recvmsg() on listening socket - ENOTCONN");
175 
176 	count = test_send(acpt_sk, message1, strlen(message), 0);
177 
178 	test_shutdown(sk, SHUT_WR);
179 
180 	flag = MSG_NOSIGNAL;
181 	/*recvmsg () TEST6:reading on a socket that received SHUTDOWN*/
182 	count = recvmsg(acpt_sk, &inmessage, flag);
183 	if (count < 0)
184 		tst_brkm(TBROK, tst_exit, "recvmsg on a socket that has "
185 			 "received shutdown count:%d, errno:%d", count, errno);
186 
187 	tst_resm(TPASS, "recvmsg() on a socket that has received shutdown - "
188 		 "EOF");
189 
190 	/*recvmsg () TEST7:reading the pending message socket that sent
191 	SHUTDOWN*/
192 	count = recvmsg(sk, &inmessage, flag);
193 	if (count < 0)
194 		tst_brkm(TBROK, tst_exit, "recvmsg on a socket with pending "
195 			 "message that has sent shutdown count:%d, errno:%d",
196 			 count, errno);
197 
198 	tst_resm(TPASS, "recvmsg() on a socket with pending message that has "
199 		 "sent shutdown - SUCCESS");
200 
201 	/*recvmsg () TEST8: No more message and association is shutdown,
202 	ENOTCONN Expected error*/
203 	count = recvmsg(sk, &inmessage, flag);
204 	if (count != -1 || errno != ENOTCONN)
205 		tst_brkm(TBROK, tst_exit, "recvmsg on a socket with no "
206 			 "pending messages and has sent shutdown count:%d, "
207 			 "errno:%d", count, errno);
208 
209 	tst_resm(TPASS, "recvmsg() on a socket with no pending messages and "
210 		 " has sent shutdown - ENOTCONN");
211 
212 	close(sk);
213 	close(lstn_sk);
214 	close(acpt_sk);
215 	return 0;
216 }
217