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 sctp_getladdrs (), sctp_freealddrs (),
6 * sctp_getpaddrs (), sctp_freeapaddrs () for 1-1 style sockets
7 *
8 * sctp_getladdrs () Tests:
9 * -----------------------
10 * TEST1: Bad socket descriptor
11 * TEST2: Invalid socket
12 * TEST3: Socket of different protocol
13 * TEST4: Getting the local addresses
14 *
15 * sctp_freealddrs () Tests:
16 * ------------------------
17 * TEST5: Freeing the local address
18 *
19 * sctp_getpaddrs () Tests:
20 * -----------------------
21 * TEST6: Bad socket descriptor
22 * TEST7: Invalid socket
23 * TEST8: Socket of different protocol
24 * TEST9: Getting the peers addresses
25 *
26 * sctp_freeapddrs () Tests:
27 * ------------------------
28 * TEST10: Freeing the peer's address
29 *
30 * The SCTP implementation is free software;
31 * you can redistribute it and/or modify it under the terms of
32 * the GNU General Public License as published by
33 * the Free Software Foundation; either version 2, or (at your option)
34 * any later version.
35 *
36 * The SCTP implementation is distributed in the hope that it
37 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
38 *                 ************************
39 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
40 * See the GNU General Public License for more details.
41 *
42 * You should have received a copy of the GNU General Public License
43 * along with GNU CC; see the file COPYING.  If not, write to
44 * the Free Software Foundation, 59 Temple Place - Suite 330,
45 * Boston, MA 02111-1307, USA.
46 *
47 * Please send any bug reports or fixes you make to the
48 * email address(es):
49 *    lksctp developers <lksctp-developers@lists.sourceforge.net>
50 *
51 * Or submit a bug report through the following website:
52 *    http://www.sf.net/projects/lksctp
53 *
54 * Any bugs reported given to us we will try to fix... any fixes shared will
55 * be incorporated into the next SCTP release.
56 *
57 */
58
59#include <stdio.h>
60#include <unistd.h>
61#include <fcntl.h>
62#include <stdlib.h>
63#include <string.h>
64#include <sys/types.h>
65#include <sys/socket.h>
66#include <netinet/in.h>         /* for sockaddr_in */
67#include <arpa/inet.h>
68#include <errno.h>
69#include <netinet/sctp.h>
70#include <sys/uio.h>
71#include <sctputil.h>
72
73char *TCID = __FILE__;
74int TST_TOTAL = 10;
75int TST_CNT = 0;
76
77int
78main(int argc, char *argv[])
79{
80        int error;
81	socklen_t len;
82	int lstn_sk,clnt_sk,acpt_sk,pf_class,sk1;
83	struct msghdr outmessage;
84        struct msghdr inmessage;
85        char *message = "hello, world!\n";
86        struct iovec iov_rcv;
87        struct sctp_sndrcvinfo *sinfo;
88        int msg_count;
89        char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
90        struct cmsghdr *cmsg;
91        struct iovec out_iov;
92        char * buffer_rcv;
93	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
94	struct sockaddr *laddrs, *paddrs;
95	int fd, err_no = 0;
96	char filename[21];
97
98        struct sockaddr_in conn_addr,lstn_addr,acpt_addr;
99	struct sockaddr_in *addr;
100
101	/* Rather than fflush() throughout the code, set stdout to
102         * be unbuffered.
103         */
104        setvbuf(stdout, NULL, _IONBF, 0);
105        setvbuf(stderr, NULL, _IONBF, 0);
106
107        pf_class = PF_INET;
108
109	/*Creating a regular socket*/
110	clnt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
111
112	/*Creating a listen socket*/
113        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
114
115	conn_addr.sin_family = AF_INET;
116        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
117        conn_addr.sin_port = htons(SCTP_TESTPORT_1);
118
119	lstn_addr.sin_family = AF_INET;
120        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
121        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
122
123	/*Binding the listen socket*/
124	test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
125
126	/*Listening many sockets as we are calling too many connect here*/
127	test_listen(lstn_sk, 1);
128
129	len = sizeof(struct sockaddr_in);
130
131	test_connect(clnt_sk, (struct sockaddr *) &conn_addr, len);
132
133	acpt_sk = test_accept(lstn_sk, (struct sockaddr *) &acpt_addr, &len);
134
135	memset(&inmessage, 0, sizeof(inmessage));
136        buffer_rcv = malloc(REALLY_BIG);
137
138        iov_rcv.iov_base = buffer_rcv;
139        iov_rcv.iov_len = REALLY_BIG;
140        inmessage.msg_iov = &iov_rcv;
141        inmessage.msg_iovlen = 1;
142        inmessage.msg_control = incmsg;
143        inmessage.msg_controllen = sizeof(incmsg);
144
145        msg_count = strlen(message) + 1;
146
147	memset(&outmessage, 0, sizeof(outmessage));
148        outmessage.msg_name = &lstn_addr;
149        outmessage.msg_namelen = sizeof(lstn_addr);
150        outmessage.msg_iov = &out_iov;
151        outmessage.msg_iovlen = 1;
152        outmessage.msg_control = outcmsg;
153        outmessage.msg_controllen = sizeof(outcmsg);
154        outmessage.msg_flags = 0;
155
156        cmsg = CMSG_FIRSTHDR(&outmessage);
157        cmsg->cmsg_level = IPPROTO_SCTP;
158        cmsg->cmsg_type = SCTP_SNDRCV;
159        cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
160        outmessage.msg_controllen = cmsg->cmsg_len;
161        sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
162        memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
163
164        outmessage.msg_iov->iov_base = message;
165        outmessage.msg_iov->iov_len = msg_count;
166
167	test_sendmsg(clnt_sk, &outmessage, MSG_NOSIGNAL, msg_count);
168
169	test_recvmsg(acpt_sk, &inmessage, MSG_NOSIGNAL);
170
171	/*sctp_getladdrs() TEST1: Bad socket descriptor, EBADF Expected error*/
172	error = sctp_getladdrs(-1, 0, &laddrs);
173	if (error != -1 || errno != EBADF)
174		tst_brkm(TBROK, tst_exit, "sctp_getladdrs with a bad socket "
175			 "descriptor error:%d, errno:%d", error, errno);
176
177	tst_resm(TPASS, "sctp_getladdrs() with a bad socket descriptor - "
178		 "EBADF");
179
180	/*sctp_getladdrs() TEST2: Invalid socket, ENOTSOCK Expected error*/
181	strcpy(filename, "/tmp/sctptest.XXXXXX");
182	fd = mkstemp(filename);
183	if (fd == -1)
184		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
185				filename, strerror(errno));
186	error = sctp_getladdrs(fd, 0, &laddrs);
187	if (error == -1)
188		err_no = errno;
189	close(fd);
190	unlink(filename);
191	if (error != -1 || err_no != ENOTSOCK)
192		tst_brkm(TBROK, tst_exit, "sctp_getladdrs with invalid socket "
193			 "error:%d, errno:%d", error, err_no);
194
195	tst_resm(TPASS, "sctp_getladdrs() with invalid socket - ENOTSOCK");
196
197	/*sctp_getladdrs() TEST3: socket of different protocol
198	EOPNOTSUPP Expected error*/
199        sk1 = socket(pf_class, SOCK_STREAM, IPPROTO_IP);
200	error = sctp_getladdrs(sk1, 0, &laddrs);
201	if (error != -1 || errno != EOPNOTSUPP)
202		tst_brkm(TBROK, tst_exit, "sctp_getladdrs with socket of "
203			 "different protocol error:%d, errno:%d", error, errno);
204
205	tst_resm(TPASS, "sctp_getladdrs() with socket of different protocol - "
206		 "EOPNOTSUPP");
207
208	/*sctp_getladdrs() TEST4: Getting the local addresses*/
209	error = sctp_getladdrs(lstn_sk, 0, &laddrs);
210	if (error < 0)
211		tst_brkm(TBROK, tst_exit, "sctp_getladdrs with valid socket "
212			 "error:%d, errno:%d", error, errno);
213
214	addr = (struct sockaddr_in *)laddrs;
215	if (addr->sin_port != lstn_addr.sin_port ||
216	    addr->sin_family != lstn_addr.sin_family ||
217	    addr->sin_addr.s_addr != lstn_addr.sin_addr.s_addr)
218		tst_brkm(TBROK, tst_exit, "sctp_getladdrs comparision failed");
219
220	tst_resm(TPASS, "sctp_getladdrs() - SUCCESS");
221
222	/*sctp_freealddrs() TEST5: freeing the local address*/
223	if ((sctp_freeladdrs(laddrs)) < 0)
224		tst_brkm(TBROK, tst_exit, "sctp_freeladdrs "
225			 "error:%d, errno:%d", error, errno);
226
227	tst_resm(TPASS, "sctp_freeladdrs() - SUCCESS");
228
229	/*sctp_getpaddrs() TEST6: Bad socket descriptor, EBADF Expected error*/
230	error = sctp_getpaddrs(-1, 0, &paddrs);
231	if (error != -1 || errno != EBADF)
232		tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with a bad socket "
233			 "descriptor error:%d, errno:%d", error, errno);
234
235	tst_resm(TPASS, "sctp_getpaddrs() with a bad socket descriptor - "
236		 "EBADF");
237
238	/*sctp_getpaddrs() TEST7: Invalid socket, ENOTSOCK Expected error*/
239	strcpy(filename, "/tmp/sctptest.XXXXXX");
240	fd = mkstemp(filename);
241	if (fd == -1)
242		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
243				filename, strerror(errno));
244	error = sctp_getpaddrs(fd, 0, &paddrs);
245	if (error == -1)
246		err_no = errno;
247	close(fd);
248	unlink(filename);
249	if (error != -1 || err_no != ENOTSOCK)
250		tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with invalid socket "
251			 "error:%d, errno:%d", error, err_no);
252
253	tst_resm(TPASS, "sctp_getpaddrs() with invalid socket - ENOTSOCK");
254
255	/*sctp_getpaddrs() TEST8: socket of different protocol
256	EOPNOTSUPP Expected error*/
257	error = sctp_getpaddrs(sk1, 0, &laddrs);
258	if (error != -1 || errno != EOPNOTSUPP)
259		tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with socket of "
260			 "different protocol error:%d, errno:%d", error, errno);
261
262	tst_resm(TPASS, "sctp_getpaddrs() with socket of different protocol - "
263		 "EOPNOTSUPP");
264
265	/*sctp_getpaddrs() TEST9: Getting the peer addresses*/
266	error = sctp_getpaddrs(acpt_sk, 0, &paddrs);
267	if (error < 0)
268		tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with valid socket "
269			 "error:%d, errno:%d", error, errno);
270
271	addr = (struct sockaddr_in *)paddrs;
272	if (addr->sin_port != acpt_addr.sin_port ||
273            addr->sin_family != acpt_addr.sin_family ||
274            addr->sin_addr.s_addr != acpt_addr.sin_addr.s_addr)
275		tst_brkm(TBROK, tst_exit, "sctp_getpaddrs comparision failed");
276
277	tst_resm(TPASS, "sctp_getpaddrs() - SUCCESS");
278
279	/*sctp_freeapddrs() TEST10: freeing the peer address*/
280	if ((sctp_freepaddrs(paddrs)) < 0)
281		tst_brkm(TBROK, tst_exit, "sctp_freepaddrs "
282			 "error:%d, errno:%d", error, errno);
283
284	tst_resm(TPASS, "sctp_freepaddrs() - SUCCESS");
285
286	close(clnt_sk);
287
288	return 0;
289}
290