1/* SCTP kernel Implementation
2 * (C) Copyright IBM Corp. 2001, 2003
3 * Copyright (c) 1999-2000 Cisco, Inc.
4 * Copyright (c) 1999-2001 Motorola, Inc.
5 * Copyright (c) 2001 Intel Corp.
6 * Copyright (c) 2001 Nokia, Inc.
7 * Copyright (c) 2001 La Monte H.P. Yarroll
8 *
9 * The SCTP implementation is free software;
10 * you can redistribute it and/or modify it under the terms of
11 * the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * The SCTP implementation is distributed in the hope that it
16 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
17 *                 ************************
18 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 * See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with GNU CC; see the file COPYING.  If not, write to
23 * the Free Software Foundation, 59 Temple Place - Suite 330,
24 * Boston, MA 02111-1307, USA.
25 *
26 * Please send any bug reports or fixes you make to the
27 * email address(es):
28 *    lksctp developers <lksctp-developers@lists.sourceforge.net>
29 *
30 * Or submit a bug report through the following website:
31 *    http://www.sf.net/projects/lksctp
32 *
33 * Any bugs reported to us we will try to fix... any fixes shared will
34 * be incorporated into the next SCTP release.
35 *
36 * Written or modified by:
37 *    La Monte H.P. Yarroll <piggy@acm.org>
38 *    Karl Knutson <karl@athena.chicago.il.us>
39 *    Randall Stewart <randall@stewart.chicago.il.us>
40 *    Ken Morneau <kmorneau@cisco.com>
41 *    Qiaobing Xie <qxie1@motorola.com>
42 *    Daisy Chang <daisyc@us.ibm.com>
43 *    Jon Grimm <jgrimm@us.ibm.com>
44 *    Sridhar Samudrala <samudrala@us.ibm.com>
45 *    Hui Huang <hui.huang@nokia.com>
46 */
47
48#ifndef __sctputil_h__
49#define __sctputil_h__
50
51#ifdef LTP
52#include <test.h>
53#include <usctest.h>
54#endif
55
56#include <string.h>
57
58typedef union {
59	struct sockaddr_in v4;
60	struct sockaddr_in6 v6;
61	struct sockaddr sa;
62} sockaddr_storage_t;
63
64
65#define REALLY_BIG 65536
66
67/* Literal defines.  */
68#ifdef PROT_SOCK
69#define SCTP_TESTPORT_1 PROT_SOCK
70#else
71#define SCTP_TESTPORT_1 1024
72#endif
73#define SCTP_TESTPORT_2 (SCTP_TESTPORT_1+1)
74
75#define SCTP_IP_BCAST  	htonl(0xffffffff)
76#define SCTP_IP_LOOPBACK  htonl(0x7f000001)
77
78/* These are stolen from <netinet/in.h>.  */
79#define SCTP_IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
80#define SCTP_IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
81
82/* Display an IPv4 address in readable format.  */
83#define NIPQUAD(addr) \
84        ((unsigned char *)&addr)[0], \
85        ((unsigned char *)&addr)[1], \
86        ((unsigned char *)&addr)[2], \
87        ((unsigned char *)&addr)[3]
88
89/* Display an IPv6 address in readable format.  */
90#define NIP6(addr) \
91        ntohs((addr).s6_addr16[0]), \
92        ntohs((addr).s6_addr16[1]), \
93        ntohs((addr).s6_addr16[2]), \
94        ntohs((addr).s6_addr16[3]), \
95        ntohs((addr).s6_addr16[4]), \
96        ntohs((addr).s6_addr16[5]), \
97        ntohs((addr).s6_addr16[6]), \
98        ntohs((addr).s6_addr16[7])
99
100#define DUMP_CORE { 					 \
101	char *diediedie = 0;				 \
102	printf("DUMP_CORE %s: %d\n", __FILE__, __LINE__);\
103	*diediedie = 0;					 \
104}
105
106#ifndef LTP
107enum {
108	TPASS,
109	TINFO,
110};
111
112extern char *TCID;
113extern int TST_TOTAL;
114extern int TST_CNT;
115
116#define tst_brkm(a1, a2, whatever...) \
117	{ \
118		printf("%s %2d BROK : ", TCID, ++TST_CNT); \
119		printf(whatever); \
120		printf("\n"); \
121		DUMP_CORE \
122	}
123#define tst_resm(a1, whatever...) \
124	{ \
125		printf("%s %2d %s : ", TCID, \
126			 (a1 == TPASS)?++TST_CNT:0, \
127			 (a1 == TPASS)?"PASS":"INFO"); \
128		printf(whatever); \
129		printf("\n"); \
130	}
131#endif
132
133static inline int test_socket(int domain, int type, int protocol)
134{
135	int sk = socket(domain, type, protocol);
136        if (-1 == sk)
137                tst_brkm(TBROK, tst_exit, "socket: %s", strerror(errno));
138	return sk;
139}
140
141static inline int test_bind(int sk, struct sockaddr *addr, socklen_t addrlen)
142{
143	int error = bind(sk, addr, addrlen);
144        if (-1 == error)
145                tst_brkm(TBROK, tst_exit, "bind: %s", strerror(errno));
146	return error;
147}
148
149static inline int test_bindx_add(int sk, struct sockaddr *addr, int count)
150{
151	int error = sctp_bindx(sk, addr, count, SCTP_BINDX_ADD_ADDR);
152        if (-1 == error)
153                tst_brkm(TBROK, tst_exit, "bindx (add): %s", strerror(errno));
154	return error;
155}
156
157static inline int test_listen(int sk, int backlog)
158{
159	int error = listen(sk, backlog);
160        if (-1 == error)
161                tst_brkm(TBROK, tst_exit, "listen: %s", strerror(errno));
162	return error;
163}
164
165static inline int test_connect(int sk, struct sockaddr *addr, socklen_t addrlen)
166{
167	int error = connect(sk, addr, addrlen);
168        if (-1 == error)
169                tst_brkm(TBROK, tst_exit, "connect: %s", strerror(errno));
170	return error;
171}
172
173static inline int test_connectx(int sk, struct sockaddr *addr, int count)
174{
175	int error = sctp_connectx(sk, addr, count, NULL);
176        if (-1 == error)
177                tst_brkm(TBROK, tst_exit, "connectx: %s", strerror(errno));
178	return error;
179}
180
181static inline int test_accept(int sk, struct sockaddr *addr, socklen_t *addrlen)
182{
183	int error = accept(sk, addr, addrlen);
184        if (-1 == error)
185                tst_brkm(TBROK, tst_exit, "accept: %s", strerror(errno));
186	return error;
187}
188
189static inline int test_send(int sk, const void *msg, size_t len, int flags)
190{
191	int error = send(sk, msg, len, flags);
192        if (len != error)
193                tst_brkm(TBROK, tst_exit, "send: error:%d errno:%d",
194			 error, errno);
195	return error;
196}
197
198static inline int test_sendto(int sk, const void *msg, size_t len, int flags,
199			      const struct sockaddr *to, socklen_t tolen)
200{
201	int error = sendto(sk, msg, len, flags, to, tolen);
202        if (len != error)
203                tst_brkm(TBROK, tst_exit, "sendto: error:%d errno:%d",
204			 error, errno);
205	return error;
206}
207
208static inline int test_sendmsg(int sk, const struct msghdr *msg, int flags,
209			       int msglen)
210{
211	int error = sendmsg(sk, msg, flags);
212        if (msglen != error)
213                tst_brkm(TBROK, tst_exit, "sendmsg: error:%d errno:%d",
214			 error, errno);
215	return error;
216}
217
218static inline int test_recv(int sk, void *buf, size_t len, int flags)
219{
220	int error = recv(sk, buf, len, flags);
221        if (-1 == error)
222                tst_brkm(TBROK, tst_exit, "recv: %s", strerror(errno));
223	return error;
224}
225
226static inline int test_recvmsg(int sk, struct msghdr *msg, int flags)
227{
228	int error = recvmsg(sk, msg, flags);
229        if (-1 == error)
230                tst_brkm(TBROK, tst_exit, "recvmsg: %s", strerror(errno));
231	return error;
232}
233
234static inline int test_shutdown(int sk, int how)
235{
236	int error = shutdown(sk, how);
237        if (-1 == error)
238                tst_brkm(TBROK, tst_exit, "shutdown: %s", strerror(errno));
239	return error;
240}
241
242static inline int test_getsockopt(int sk, int optname, void *optval,
243				  socklen_t *optlen)
244{
245	int error = getsockopt(sk, SOL_SCTP, optname, optval, optlen);
246	if (error)
247		tst_brkm(TBROK, tst_exit, "getsockopt(%d): %s", optname,
248			 strerror(errno));
249	return error;
250}
251
252static inline int test_setsockopt(int sk, int optname, const void *optval,
253				  socklen_t optlen)
254{
255	int error = setsockopt(sk, SOL_SCTP, optname, optval, optlen);
256	if (error)
257		tst_brkm(TBROK, tst_exit, "setsockopt(%d): %s", optname,
258			 strerror(errno));
259	return error;
260}
261
262static inline int test_sctp_peeloff(int sk, sctp_assoc_t assoc_id)
263{
264	int error = sctp_peeloff(sk, assoc_id);
265        if (-1 == error)
266                tst_brkm(TBROK, tst_exit, "sctp_peeloff: %s", strerror(errno));
267	return error;
268}
269
270static inline int test_sctp_sendmsg(int s, const void *msg, size_t len,
271				    struct sockaddr *to, socklen_t tolen,
272				    uint32_t ppid, uint32_t flags,
273				    uint16_t stream_no, uint32_t timetolive,
274				    uint32_t context)
275{
276	int error = sctp_sendmsg(s, msg, len, to, tolen, ppid, flags, stream_no,
277	  		         timetolive, context);
278	if (len != error)
279		tst_brkm(TBROK, tst_exit, "sctp_sendmsg: error:%d errno:%d",
280			 error, errno);
281	return error;
282}
283
284static inline int test_sctp_send(int s, const void *msg, size_t len,
285				 const struct sctp_sndrcvinfo *sinfo,
286				 int flags)
287{
288	int error = sctp_send(s, msg, len, sinfo, flags);
289	if (len != error)
290		tst_brkm(TBROK, tst_exit, "sctp_send: error:%d errno:%d",
291			 error, errno);
292	return error;
293}
294
295static inline int test_sctp_recvmsg(int sk, void *msg, size_t len,
296				    struct sockaddr *from, socklen_t *fromlen,
297				    struct sctp_sndrcvinfo *sinfo,
298				    int *msg_flags)
299{
300	int error = sctp_recvmsg(sk, msg, len, from, fromlen, sinfo, msg_flags);
301	if (-1 == error)
302		tst_brkm(TBROK, tst_exit, "sctp_recvmsg: %s", strerror(errno));
303	return error;
304}
305
306static inline void *test_malloc(size_t size)
307{
308	void *buf = malloc(size);
309        if (NULL == buf)
310                tst_brkm(TBROK, tst_exit, "malloc failed");
311	return buf;
312}
313
314void test_check_msg_notification(struct msghdr *, int, int, uint16_t, uint32_t);
315void test_check_buf_notification(void *, int, int, int, uint16_t, uint32_t);
316void test_check_msg_data(struct msghdr *, int, int, int, uint16_t, uint32_t);
317void test_check_buf_data(void *, int, int, struct sctp_sndrcvinfo *, int, int,
318			 uint16_t, uint32_t);
319void *test_build_msg(int);
320void test_enable_assoc_change(int);
321void test_print_message(int sk, struct msghdr *msg, size_t msg_len);
322int test_peer_addr(int sk, sctp_assoc_t asoc, sockaddr_storage_t *peers, int count);
323
324#endif /* __sctputil_h__ */
325