• 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 #include "tst_kernel.h"
60 
61 char *TCID = __FILE__;
62 int TST_TOTAL = 8;
63 int TST_CNT = 0;
64 
65 int
main(void)66 main(void)
67 {
68         socklen_t len;
69 	int sk,pf_class,lstn_sk,acpt_sk;
70 	int flag = 0;
71 	int fd, err_no = 0;
72 	char filename[21];
73 	struct msghdr inmessage;
74         char *message = "hello, world!\n";
75 	struct iovec iov_rcv;
76         int count;
77 	char * buffer_rcv;
78         char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
79 	char *message1 = "hello, world!\n";
80 
81         struct sockaddr_in conn_addr,lstn_addr,svr_addr;
82 
83 	if (tst_check_driver("sctp"))
84 		tst_brkm(TCONF, tst_exit, "sctp driver not available");
85 
86 	/* Rather than fflush() throughout the code, set stdout to
87          * be unbuffered.
88          */
89         setvbuf(stdout, NULL, _IONBF, 0);
90         setvbuf(stderr, NULL, _IONBF, 0);
91 
92         pf_class = PF_INET;
93 
94         sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
95 
96         lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
97 
98 	conn_addr.sin_family = AF_INET;
99         conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
100         conn_addr.sin_port = htons(SCTP_TESTPORT_1);
101 
102 	lstn_addr.sin_family = AF_INET;
103         lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
104         lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
105 
106 	/*Binding the listen socket*/
107         test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
108 
109         /*Listening the socket*/
110         test_listen(lstn_sk, 10);
111 
112 	len = sizeof(struct sockaddr_in);
113 
114 	test_connect(sk, (struct sockaddr *) &conn_addr, len);
115 
116 	acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len);
117 
118 	memset(&inmessage, 0, sizeof(inmessage));
119         buffer_rcv = malloc(REALLY_BIG);
120 
121         iov_rcv.iov_base = buffer_rcv;
122         iov_rcv.iov_len = REALLY_BIG;
123         inmessage.msg_iov = &iov_rcv;
124         inmessage.msg_iovlen = 1;
125         inmessage.msg_control = incmsg;
126         inmessage.msg_controllen = sizeof(incmsg);
127 
128 	/*recvmsg () TEST1: Bad socket descriptor, EBADF Expected error*/
129 	count = recvmsg(-1, &inmessage, flag);
130 	if (count != -1 || errno != EBADF)
131 		tst_brkm(TBROK, tst_exit, "recvmsg with a bad socket "
132 			 "descriptor count:%d, errno:%d", count, errno);
133 
134 	tst_resm(TPASS, "recvmsg() with a bad socket descriptor - EBADF");
135 
136 	/*recvmsg () TEST2: Invalid socket , ENOTSOCK Expected error*/
137 	strcpy(filename, "/tmp/sctptest.XXXXXX");
138 	fd = mkstemp(filename);
139 	if (fd == -1)
140 		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
141 				filename, strerror(errno));
142 	count = recvmsg(fd, &inmessage, flag);
143 	if (count == -1)
144 		err_no = errno;
145 	close(fd);
146 	unlink(filename);
147 	if (count != -1 || err_no != ENOTSOCK)
148 		tst_brkm(TBROK, tst_exit, "recvmsg with invalid socket "
149 			 "count:%d, errno:%d", count, err_no);
150 
151 	tst_resm(TPASS, "recvmsg() with invalid socket - ENOTSOCK");
152 
153 	/*recvmsg () TEST3: Invalid iovec pointer EFAULT, Expected error*/
154 	inmessage.msg_iov = (struct iovec *)-1;
155 	count = recvmsg(acpt_sk, &inmessage, flag);
156 	if (count != -1 || errno != EFAULT)
157 		tst_brkm(TBROK, tst_exit, "recvmsg with invalid iovec "
158 			 "pointer count:%d, errno:%d", count, errno);
159 
160 	tst_resm(TPASS, "recvmsg() with invalid iovec ptr - EFAULT");
161 
162 	inmessage.msg_iov = &iov_rcv;
163 
164 	/*recvmsg () TEST4: Invalid msghdr pointer EFAULT, Expected error*/
165 	count = recvmsg(acpt_sk, (struct msghdr *)-1, flag);
166 	if (count != -1 || errno != EFAULT)
167 		tst_brkm(TBROK, tst_exit, "recvmsg with invalid msghdr "
168 			 "pointer count:%d, errno:%d", count, errno);
169 
170 	tst_resm(TPASS, "recvmsg() with invalid msghdr ptr - EFAULT");
171 
172 	/*recvmsg () TEST5:recvmsg on listening socket,ENOTCONN Expected error*/
173 	count = recvmsg(lstn_sk, &inmessage, flag);
174 	if (count != -1 || errno != ENOTCONN)
175 		tst_brkm(TBROK, tst_exit, "recvmsg on listening socket "
176 			 "count:%d, errno:%d", count, errno);
177 
178 	tst_resm(TPASS, "recvmsg() on listening socket - ENOTCONN");
179 
180 	count = test_send(acpt_sk, message1, strlen(message), 0);
181 
182 	test_shutdown(sk, SHUT_WR);
183 
184 	flag = MSG_NOSIGNAL;
185 	/*recvmsg () TEST6:reading on a socket that received SHUTDOWN*/
186 	count = recvmsg(acpt_sk, &inmessage, flag);
187 	if (count < 0)
188 		tst_brkm(TBROK, tst_exit, "recvmsg on a socket that has "
189 			 "received shutdown count:%d, errno:%d", count, errno);
190 
191 	tst_resm(TPASS, "recvmsg() on a socket that has received shutdown - "
192 		 "EOF");
193 
194 	/*recvmsg () TEST7:reading the pending message socket that sent
195 	SHUTDOWN*/
196 	count = recvmsg(sk, &inmessage, flag);
197 	if (count < 0)
198 		tst_brkm(TBROK, tst_exit, "recvmsg on a socket with pending "
199 			 "message that has sent shutdown count:%d, errno:%d",
200 			 count, errno);
201 
202 	tst_resm(TPASS, "recvmsg() on a socket with pending message that has "
203 		 "sent shutdown - SUCCESS");
204 
205 	/*recvmsg () TEST8: No more message and association is shutdown,
206 	ENOTCONN Expected error*/
207 	count = recvmsg(sk, &inmessage, flag);
208 	if (count != -1 || errno != ENOTCONN)
209 		tst_brkm(TBROK, tst_exit, "recvmsg on a socket with no "
210 			 "pending messages and has sent shutdown count:%d, "
211 			 "errno:%d", count, errno);
212 
213 	tst_resm(TPASS, "recvmsg() on a socket with no pending messages and "
214 		 " has sent shutdown - ENOTCONN");
215 
216 	close(sk);
217 	close(lstn_sk);
218 	close(acpt_sk);
219 	return 0;
220 }
221