• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SCTP kernel Implementation
2  * (C) Copyright IBM Corp. 2004
3  * Copyright (c) 1999-2001 Motorola, Inc.
4  *
5  * The SCTP implementation is free software;
6  * you can redistribute it and/or modify it under the terms of
7  * the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * The SCTP implementation is distributed in the hope that it
12  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
13  *                 ************************
14  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  * See the GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU CC; see the file COPYING.  If not, write to
19  * the Free Software Foundation, 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  * Please send any bug reports or fixes you make to the
23  * email address(es):
24  *    lksctp developers <lksctp-developers@lists.sourceforge.net>
25  *
26  * Or submit a bug report through the following website:
27  *    http://www.sf.net/projects/lksctp
28  *
29  * Any bugs reported given to us we will try to fix... any fixes shared will
30  * be incorporated into the next SCTP release.
31  *
32  * Written or modified by:
33  *    Sridhar Samudrala		<sri@us.ibm.com>
34  */
35 
36 /* This is a kernel test to verify getsockname() and getpeername() interfaces
37  * for single-homed one-to-one style sockets.
38  */
39 
40 #include <stdio.h>
41 #include <unistd.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <fcntl.h>
45 #include <sys/types.h>
46 #include <sys/socket.h>
47 #include <sys/uio.h>
48 #include <netinet/in.h>
49 #include <errno.h>
50 #include <netinet/sctp.h>
51 #include <sctputil.h>
52 
53 char *TCID = __FILE__;
54 int TST_TOTAL = 13;
55 int TST_CNT = 0;
56 
57 #define MAX_CLIENTS 10
58 
59 int
main(int argc,char * argv[])60 main(int argc, char *argv[])
61 {
62 	int clt_sk, svr_sk, accept_sk;
63 	sockaddr_storage_t svr_loop, accept_loop;
64 	sockaddr_storage_t svr_local_addr, svr_peer_addr;
65 	sockaddr_storage_t clt_local_addr, clt_peer_addr;
66 	socklen_t len;
67 	int error;
68 	int pf_class;
69 	int fd, err_no = 0;
70 	char filename[21];
71 
72         /* Rather than fflush() throughout the code, set stdout to
73 	 * be unbuffered.
74 	 */
75 	setvbuf(stdout, NULL, _IONBF, 0);
76 
77 	/* Initialize the server and client addresses. */
78 #if TEST_V6
79 	pf_class = PF_INET6;
80         svr_loop.v6.sin6_family = AF_INET6;
81         svr_loop.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT;
82         svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1);
83 #else
84 	pf_class = PF_INET;
85 	svr_loop.v4.sin_family = AF_INET;
86 	svr_loop.v4.sin_addr.s_addr = INADDR_ANY;
87 	svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
88 #endif
89 
90 	/* Create and bind the listening server socket.  */
91         svr_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
92 	test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop));
93 
94 	bzero(&svr_local_addr, sizeof(svr_local_addr));
95 	len = sizeof(svr_local_addr);
96 	/* Verify that getsockname() on an unconnected socket works fine. */
97 	error = getsockname(svr_sk, (struct sockaddr *)&svr_local_addr, &len);
98 	if (0 != error)
99 		tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno));
100 
101 	tst_resm(TPASS, "getsockname on an unconnected socket");
102 
103 	bzero(&svr_peer_addr, sizeof(svr_peer_addr));
104 	len = sizeof(svr_peer_addr);
105 	/* Verify that getpeername() on an unconnected socket fails. */
106 	error = getpeername(svr_sk, (struct sockaddr *)&svr_peer_addr, &len);
107 	if ((-1 != error) || (ENOTCONN != errno))
108 		tst_brkm(TBROK, tst_exit, "getpeername on an unconnected "
109 			 "socket error:%d, errno:%d", error, errno);
110 
111 	tst_resm(TPASS, "getpeername on an unconnected socket");
112 
113 	/* Mark svr_sk as being able to accept new associations.  */
114 	test_listen(svr_sk, 5);
115 
116 	/* Create the client socket.  */
117 	clt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
118 
119 	/* Do a blocking connect from clt_sk to svr_sk */
120 #if TEST_V6
121 	svr_loop.v6.sin6_addr = in6addr_loopback;
122 #else
123 	svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
124 #endif
125 	test_connect(clt_sk, &svr_loop.sa, sizeof(svr_loop));
126 
127 	bzero(&clt_local_addr, sizeof(clt_local_addr));
128 	len = sizeof(clt_local_addr);
129 	/* Get the client's local address. */
130 	error = getsockname(clt_sk, (struct sockaddr *)&clt_local_addr, &len);
131 	if (0 != error)
132 		tst_brkm(TBROK, tst_exit, "getsockname on a connected client "
133 			 "socket: %s", strerror(errno));
134 
135 	tst_resm(TPASS, "getsockname on a connected client socket");
136 
137 	bzero(&clt_peer_addr, sizeof(clt_peer_addr));
138 	len = sizeof(clt_peer_addr);
139 	/* Get the client's peer address. */
140 	error = getpeername(clt_sk, (struct sockaddr *)&clt_peer_addr, &len);
141 	if (0 != error)
142 		tst_brkm(TBROK, tst_exit, "getpeername on a connected client "
143 			 "socket: %s", strerror(errno));
144 
145 	tst_resm(TPASS, "getpeername on a connected client socket");
146 
147 	/* Extract the association on the listening socket as a new socket. */
148 	len = sizeof(accept_loop);
149 	accept_sk = test_accept(svr_sk, &accept_loop.sa, &len);
150 
151 	bzero(&svr_local_addr, sizeof(svr_local_addr));
152 	len = sizeof(svr_local_addr);
153 	/* Get the server's local address. */
154 	error = getsockname(accept_sk, (struct sockaddr *)&svr_local_addr,
155 				&len);
156 	if (0 != error)
157 		tst_brkm(TBROK, tst_exit, "getsockname on a connected server "
158 			 "socket: %s", strerror(errno));
159 
160 	tst_resm(TPASS, "getsockname on a connected server socket");
161 
162 	bzero(&svr_peer_addr, sizeof(svr_peer_addr));
163 	len = sizeof(svr_peer_addr);
164 	/* Get the server's peer address. */
165 	error = getpeername(accept_sk, (struct sockaddr *)&svr_peer_addr,
166 				&len);
167 	if (0 != error)
168 		tst_brkm(TBROK, tst_exit, "getpeername on a connected server "
169 			 "socket: %s", strerror(errno));
170 
171 	tst_resm(TPASS, "getpeername on a connected server socket");
172 
173 	if (svr_local_addr.v4.sin_port != clt_peer_addr.v4.sin_port)
174 		tst_brkm(TBROK, tst_exit, "Server's local port(%d) doesn't "
175 			 "match Client's peer port(%d)\n",
176 			 svr_local_addr.v4.sin_port, clt_peer_addr.v4.sin_port);
177 
178 	if (svr_peer_addr.v4.sin_port != clt_local_addr.v4.sin_port)
179 		tst_brkm(TBROK, tst_exit, "Server's peer port(%d) doesn't "
180 			 "match Client's local port(%d)\n",
181 			 svr_peer_addr.v4.sin_port, clt_local_addr.v4.sin_port);
182 #if TEST_V6
183 	if (memcmp(&svr_local_addr, &clt_peer_addr, len) != 0)
184 		tst_brkm(TBROK, tst_exit, "Server's local address and client's "
185 			 "peer addresses do not match\n");
186 
187 	if (memcmp(&svr_peer_addr, &clt_local_addr, len) != 0)
188 		tst_brkm(TBROK, tst_exit, "Server's peer address and client's "
189 			 "local addresses do not match\n");
190 #else
191 	if (svr_local_addr.v4.sin_addr.s_addr !=
192 		 		clt_peer_addr.v4.sin_addr.s_addr)
193 		tst_brkm(TBROK, tst_exit, "Server's local address and client's "
194 			 "peer addresses do not match\n");
195 	if (svr_peer_addr.v4.sin_addr.s_addr !=
196 		 		clt_local_addr.v4.sin_addr.s_addr)
197 		tst_brkm(TBROK, tst_exit, "Server's peer address and client's "
198 			 "local addresses do not match\n");
199 #endif
200 	tst_resm(TPASS, "getsockname/getpeername server/client match");
201 
202 	bzero(&clt_local_addr, sizeof(clt_local_addr));
203 	len = sizeof(clt_local_addr);
204 	/*getsockname():  Bad socket descriptor, EBADF expected error*/
205 	error = getsockname(-1, (struct sockaddr *)&clt_local_addr, &len);
206 	if (error != -1 || errno != EBADF)
207 		tst_brkm(TBROK, tst_exit, "getsockname on a bad socket "
208 			 "descriptor. error:%d errno:%d", error, errno);
209 
210 	tst_resm(TPASS, "getsockname on a bad socket descriptor - EBADF");
211 
212 	/*getsockname(): Invalid socket, ENOTSOCK expected error*/
213 	strcpy(filename, "/tmp/sctptest.XXXXXX");
214 	fd = mkstemp(filename);
215 	if (fd == -1)
216 		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
217 				filename, strerror(errno));
218 	error = getsockname(fd, (struct sockaddr *)&clt_local_addr, &len);
219 	if (error == -1)
220 		err_no = errno;
221 	close(fd);
222 	unlink(filename);
223 	if (error != -1 || err_no != ENOTSOCK)
224 		tst_brkm(TBROK, tst_exit, "getsockname on an invalid socket "
225 			 "error:%d errno:%d", error, err_no);
226 
227 	tst_resm(TPASS, "getsockname on an invalid socket - ENOTSOCK");
228 
229 	/*getsockname(): Invalid structure, EFAULT expected error*/
230 	error = getsockname(clt_sk, (struct sockaddr *)-1, &len);
231 	if (error != -1 || errno != EFAULT)
232 		tst_brkm(TBROK, tst_exit, "getsockname with invalid buffer "
233 			 "error:%d errno:%d", error, errno);
234 
235 	tst_resm(TPASS, "getsockname with invalid buffer - EFAULT");
236 
237 	bzero(&clt_peer_addr, sizeof(clt_peer_addr));
238 	len = sizeof(clt_peer_addr);
239 	/*getpeername():  Bad socket descriptor, EBADF expected error*/
240 	error = getpeername(-1, (struct sockaddr *)&clt_local_addr, &len);
241 	if (error != -1 || errno != EBADF)
242 		tst_brkm(TBROK, tst_exit, "getpeername on a bad socket "
243 			 "descriptor. error:%d errno:%d", error, errno);
244 
245 	tst_resm(TPASS, "getpeername on a bad socket descriptor - EBADF");
246 
247 	/*getpeername(): Invalid socket, ENOTSOCK expected error*/
248 	strcpy(filename, "/tmp/sctptest.XXXXXX");
249 	fd = mkstemp(filename);
250 	if (fd == -1)
251 		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
252 				filename, strerror(errno));
253 	error = getpeername(fd, (struct sockaddr *)&clt_local_addr, &len);
254 	if (error == -1)
255 		err_no = errno;
256 	close(fd);
257 	unlink(filename);
258 	if (error != -1 || err_no != ENOTSOCK)
259 		tst_brkm(TBROK, tst_exit, "getpeername on an invalid socket "
260 			 "error:%d errno:%d", error, err_no);
261 
262 	tst_resm(TPASS, "getpeername on an invalid socket - ENOTSOCK");
263 
264 	/*getpeername(): Invalid structure, EFAULT expected error*/
265 	error = getpeername(clt_sk, (struct sockaddr *)-1, &len);
266 	if (error != -1 || errno != EFAULT)
267 		tst_brkm(TBROK, tst_exit, "getpeername with invalid buffer "
268 			 "error:%d errno:%d", error, errno);
269 
270 	tst_resm(TPASS, "getpeername with invalid buffer - EFAULT");
271 
272 	close(clt_sk);
273 	close(svr_sk);
274 	close(accept_sk);
275 
276         /* Indicate successful completion.  */
277 	return 0;
278 }
279