~ubuntu-branches/ubuntu/utopic/lksctp-tools/utopic-proposed

« back to all changes in this revision

Viewing changes to test/ft_frame_dftsndparam.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Biebl
  • Date: 2006-10-19 20:23:28 UTC
  • mfrom: (2.1.6 edgy)
  • Revision ID: james.westby@ubuntu.com-20061019202328-ts63rxlpp07yl2nc
Tags: 1.0.6.dfsg-4
Update maintainer email address to biebl@debian.org. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* SCTP kernel reference 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
 * This is the Functional Test for testing SET_DEFAULT_SEND_PARAM sockopt and
 
10
 * use of the SCTP_SNDRCV ancillary data.
 
11
 *
 
12
 * Just test payload protocol id and stream. This is mostly just a simple
 
13
 * wiring test.
 
14
 *
 
15
 * Send/receive two messages.  Each with different stream & ppid.
 
16
 *
 
17
 * Ardelle Fan <ardelle.fan@intel.com>
 
18
 *
 
19
 * We use functions which approximate the user level API defined in
 
20
 * draft-ietf-tsvwg-sctpsocket-07.txt.
 
21
 */
 
22
#include <linux/types.h>
 
23
#include <linux/list.h> /* For struct list_head */
 
24
#include <linux/socket.h>
 
25
#include <linux/ip.h>
 
26
#include <linux/time.h> /* For struct timeval */
 
27
#include <net/sock.h>
 
28
#include <linux/wait.h> /* For wait_queue_head_t */
 
29
#include <linux/skbuff.h>
 
30
#include <linux/errno.h>
 
31
#include <net/sctp/sctp.h>
 
32
#include <net/sctp/sm.h>
 
33
#include <errno.h>
 
34
#include <funtest.h>
 
35
 
 
36
int
 
37
main(int argc, char *argv[])
 
38
{
 
39
        int pf_class, af_family;
 
40
        struct sctp_endpoint *ep1;
 
41
        struct sctp_endpoint *ep2;
 
42
        uint8_t *big_buffer;
 
43
        int addr_len;
 
44
        int error, bytes_sent;
 
45
        union sctp_addr loop1;
 
46
        union sctp_addr loop2;
 
47
        struct sctp_association *asoc1;
 
48
        struct sctp_association *asoc2;
 
49
        struct iovec iov;
 
50
        struct iovec out_iov;
 
51
        struct msghdr inmessage;
 
52
        char cmsghdr[CMSG_SPACE_SNDRCV] = {0};
 
53
        char buf[CMSG_SPACE_INITMSG] = {0};
 
54
        struct cmsghdr *outcmsg;
 
55
        struct sctp_initmsg *initmsg;
 
56
        struct sctp_sndrcvinfo info;
 
57
        struct sctp_assoc_change *sac;
 
58
        sctp_assoc_t associd1;
 
59
        sctp_assoc_t associd2;
 
60
        struct msghdr outmsg;
 
61
        struct sock *sk1;
 
62
        struct sock *sk2;
 
63
        uint16_t stream;
 
64
        uint32_t ppid;
 
65
        uint8_t *message = "hello, world!\n";
 
66
        uint8_t *telephone = "Watson, come here!  I need you!\n";
 
67
 
 
68
        /* Do all that random stuff needed to make a sensible
 
69
         * universe.
 
70
         */
 
71
        sctp_init();
 
72
 
 
73
        /* Set some basic values which depend on the address family. */
 
74
 
 
75
        pf_class = PF_INET;
 
76
        af_family = AF_INET;
 
77
        loop1.v4.sin_family = AF_INET;
 
78
        loop1.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
 
79
        loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
 
80
        loop2.v4.sin_family = AF_INET;
 
81
        loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
 
82
        loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
 
83
 
 
84
 
 
85
        /* Create the two endpoints which will talk to each other.  */
 
86
        sk1 = sctp_socket(pf_class, SOCK_SEQPACKET);
 
87
        sk2 = sctp_socket(pf_class, SOCK_SEQPACKET);
 
88
 
 
89
        /* Bind these sockets to the test ports.  */
 
90
        error = test_bind(sk1, (struct sockaddr *)&loop1, sizeof(loop1));
 
91
        if (error != 0) { DUMP_CORE; }
 
92
 
 
93
        error = test_bind(sk2, (struct sockaddr *)&loop2, sizeof(loop2));
 
94
        if (error != 0) { DUMP_CORE; }
 
95
 
 
96
        /* Mark sk2 as being able to accept new associations. */
 
97
        if (0 != sctp_seqpacket_listen(sk2, 1)) {
 
98
                DUMP_CORE;
 
99
        }
 
100
 
 
101
        /* Make sure that duplicate binding fails.  */
 
102
        error = test_bind(sk1, (struct sockaddr *)&loop1, sizeof(loop1));
 
103
        if (error != -EINVAL) { DUMP_CORE; }
 
104
 
 
105
 
 
106
        /* Build up a msghdr structure we can use for all sending.  */
 
107
        outmsg.msg_name = &loop2;
 
108
        outmsg.msg_namelen = sizeof(loop2);
 
109
        outmsg.msg_iov = &out_iov;
 
110
        outmsg.msg_iovlen = 1;
 
111
        outmsg.msg_flags = 0;
 
112
 
 
113
        outmsg.msg_control = buf;
 
114
        outmsg.msg_controllen = CMSG_SPACE_INITMSG;
 
115
        outcmsg = CMSG_FIRSTHDR(&outmsg);
 
116
        outcmsg->cmsg_level = IPPROTO_SCTP;
 
117
        outcmsg->cmsg_type = SCTP_INIT;
 
118
        outcmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_initmsg));
 
119
 
 
120
        initmsg = (struct sctp_initmsg *)CMSG_DATA(outcmsg);
 
121
        initmsg->sinit_num_ostreams = 20;
 
122
        initmsg->sinit_max_instreams = 5;
 
123
        initmsg->sinit_max_attempts = 0;
 
124
        initmsg->sinit_max_init_timeo = 0;
 
125
 
 
126
        /* Send the first message.  This will create the association.  */
 
127
        outmsg.msg_iov->iov_base = message;
 
128
        outmsg.msg_iov->iov_len = strlen(message) + 1;
 
129
        bytes_sent = sctp_sendmsg(NULL, sk1, &outmsg, strlen(message)+1);
 
130
        if (bytes_sent != strlen(message) + 1) { DUMP_CORE; }
 
131
 
 
132
        /* Walk through the startup sequence.  */
 
133
 
 
134
        /* We should have an INIT sitting on the Internet. */
 
135
        if (!test_for_chunk(SCTP_CID_INIT, TEST_NETWORK0)) {
 
136
                DUMP_CORE;
 
137
        }
 
138
 
 
139
        /* Next we expect an INIT ACK. */
 
140
        if (test_step(SCTP_CID_INIT_ACK, TEST_NETWORK0) <= 0) {
 
141
                DUMP_CORE;
 
142
        }
 
143
        /* We expect a COOKIE ECHO.  */
 
144
        if (test_step(SCTP_CID_COOKIE_ECHO, TEST_NETWORK0) <= 0) {
 
145
                DUMP_CORE;
 
146
        }
 
147
 
 
148
#ifndef NO_COOKIE_ECHO_BUNDLE
 
149
        /* We expect DATA bundled with that COOKIE ECHO.  */
 
150
        if (!test_for_chunk(SCTP_CID_DATA, TEST_NETWORK0)) {
 
151
                DUMP_CORE;
 
152
        }
 
153
#endif /* !NO_COOKIE_ECHO_BUNDLE */
 
154
 
 
155
        /* We expect a COOKIE ACK.  */
 
156
        if (test_step(SCTP_CID_COOKIE_ACK, TEST_NETWORK0) <= 0) {
 
157
                DUMP_CORE;
 
158
        }
 
159
 
 
160
#ifdef NO_COOKIE_ECHO_BUNDLE
 
161
        if (test_step(SCTP_CID_DATA, TEST_NETWORK0) <= 0) {
 
162
                DUMP_CORE;
 
163
        }
 
164
 
 
165
        if (test_step(SCTP_CID_SACK, TEST_NETWORK0) <= 0) {
 
166
                DUMP_CORE;
 
167
        }
 
168
#else
 
169
       /* We should see a SACK next.
 
170
         * We ARE truly clever and bundle the SACK with the COOKIE ACK.
 
171
         */
 
172
        if (!test_for_chunk(SCTP_CID_SACK, TEST_NETWORK0)) {
 
173
                DUMP_CORE;
 
174
        }
 
175
#endif /* NO_COOKIE_ECHO_BUNDLE */
 
176
 
 
177
        /* Process the COOKIE ACK and the SACK.  */
 
178
        error = test_run_network();
 
179
        if (0 != error) { DUMP_CORE; }
 
180
 
 
181
        /* We have two established associations.  Let's extract some
 
182
         * useful details.
 
183
         */
 
184
 
 
185
        ep1 = sctp_sk(sk1)->ep;
 
186
        asoc1= test_ep_first_asoc(ep1);
 
187
        ep2 = sctp_sk(sk2)->ep;
 
188
        asoc2 = test_ep_first_asoc(ep2);
 
189
 
 
190
        if (!sctp_outq_is_empty(&asoc1->outqueue)) {
 
191
                DUMP_CORE;
 
192
        }
 
193
 
 
194
        memset(&inmessage, 0x00, sizeof(inmessage));
 
195
 
 
196
        /* NOW initialize inmessage with enough space for DATA... */
 
197
        big_buffer = kmalloc(REALLY_BIG, GFP_KERNEL);
 
198
        iov.iov_base = big_buffer;
 
199
        iov.iov_len = REALLY_BIG;
 
200
        inmessage.msg_iov = &iov;
 
201
        inmessage.msg_iovlen = 1;
 
202
        /* or a control message.  */
 
203
        inmessage.msg_control = &cmsghdr;
 
204
        inmessage.msg_controllen = CMSG_SPACE_SNDRCV;
 
205
 
 
206
        /* Get the communication up message from sk2.  */
 
207
        error = sctp_recvmsg(NULL, sk2, &inmessage, REALLY_BIG,
 
208
                             /* noblock */ 1, /* flags */ 0,
 
209
                             &addr_len);
 
210
        if (error < 0) {
 
211
                printk("recvmsg:  Something went wrong, error: %d\n",
 
212
                       error);
 
213
                DUMP_CORE;
 
214
        }
 
215
        test_frame_check_notification(&inmessage,
 
216
                                      REALLY_BIG,
 
217
                                      sizeof(struct sctp_assoc_change),
 
218
                                      SCTP_ASSOC_CHANGE,
 
219
                                      SCTP_COMM_UP);
 
220
 
 
221
        sac = (struct sctp_assoc_change *)big_buffer;
 
222
        associd2 = sac->sac_assoc_id;
 
223
        printk("sk2 associd = %x\n", (unsigned int)associd2);
 
224
        if (associd2 != (sctp_assoc_t)asoc2) {
 
225
                DUMP_CORE;
 
226
        }
 
227
 
 
228
 
 
229
        /* Restore the altered values for the next call... */
 
230
        iov.iov_base = big_buffer;
 
231
        iov.iov_len = REALLY_BIG;
 
232
        inmessage.msg_control = &cmsghdr;
 
233
        inmessage.msg_controllen = sizeof(struct sctp_cmsghdr);
 
234
 
 
235
 
 
236
        /* Get the communication up message from sk1.  */
 
237
        error = sctp_recvmsg(NULL, sk1, &inmessage, REALLY_BIG,
 
238
                             /* noblock */ 1, /* flags */ 0,
 
239
                             &addr_len);
 
240
        if (error < 0) {
 
241
                printk("recvmsg:  Something went wrong, error: %d\n",
 
242
                       error);
 
243
                DUMP_CORE;
 
244
        }
 
245
        test_frame_check_notification(&inmessage,
 
246
                                      REALLY_BIG,
 
247
                                      sizeof(struct sctp_assoc_change),
 
248
                                      SCTP_ASSOC_CHANGE,
 
249
                                      SCTP_COMM_UP);
 
250
 
 
251
        sac = (struct sctp_assoc_change *)big_buffer;
 
252
        associd1 = sac->sac_assoc_id;
 
253
        printk("sk1 associd = %x\n", (unsigned int)associd1);
 
254
        if (associd1 != (sctp_assoc_t)asoc1) {
 
255
                DUMP_CORE;
 
256
        }
 
257
 
 
258
        /* Restore the altered values for the next call... */
 
259
        iov.iov_len = REALLY_BIG;
 
260
        inmessage.msg_control = &cmsghdr;
 
261
        inmessage.msg_controllen = sizeof(struct sctp_cmsghdr);
 
262
 
 
263
 
 
264
        /* Get the first message which was sent.  */
 
265
        error = sctp_recvmsg(NULL, sk2, &inmessage, REALLY_BIG,
 
266
                             /* noblock */ 1, /* flags */ 0,
 
267
                             &addr_len);
 
268
        if (error < 0) { DUMP_CORE; }
 
269
 
 
270
 
 
271
        test_frame_check_message(&inmessage,
 
272
                                 /* orig */
 
273
                                 sizeof(struct sctp_cmsghdr),
 
274
                                 REALLY_BIG,
 
275
                                 big_buffer,
 
276
                                 /* expected */
 
277
                                 sizeof(struct sctp_sndrcvinfo),
 
278
                                 strlen(message) + 1,
 
279
                                 message,
 
280
                                 SCTP_SNDRCV);
 
281
 
 
282
        /* Fixup msg_control, as testframe leaves it in a goofy state. */
 
283
        test_frame_fixup_msg_control(&inmessage,
 
284
                                     sizeof(struct sctp_cmsghdr));
 
285
 
 
286
        /* SET_DEFAULT_SEND_PARAM */
 
287
        memset(&info, 0x00, sizeof(struct sctp_sndrcvinfo));
 
288
        ppid = (uint32_t)rand();
 
289
        info.sinfo_ppid = ppid;
 
290
        stream = 2;
 
291
        info.sinfo_stream = stream;
 
292
        info.sinfo_assoc_id = associd1;
 
293
        error = sctp_setsockopt(sk1, IPPROTO_SCTP,
 
294
                                SCTP_DEFAULT_SEND_PARAM, (char *)&info,
 
295
                               sizeof(struct sctp_sndrcvinfo));
 
296
        if (error != 0) { DUMP_CORE; }
 
297
 
 
298
        /* Send a second message */
 
299
 
 
300
        outmsg.msg_control = NULL;
 
301
        outmsg.msg_controllen = 0;
 
302
        outmsg.msg_iov->iov_base = telephone;
 
303
        outmsg.msg_iov->iov_len = strlen(telephone) + 1;
 
304
 
 
305
        bytes_sent = sctp_sendmsg(NULL, sk1, &outmsg, strlen(telephone)+1);
 
306
        if (bytes_sent != strlen(telephone) + 1) { DUMP_CORE; }
 
307
 
 
308
        error = test_run_network();
 
309
        if (error != 0) { DUMP_CORE; }
 
310
 
 
311
        /* Get that message.  */
 
312
        /* Restore the altered values for the next call.  */
 
313
        iov.iov_base = big_buffer;
 
314
        iov.iov_len = REALLY_BIG;
 
315
        inmessage.msg_iov = &iov;
 
316
        inmessage.msg_iovlen = 1;
 
317
        inmessage.msg_control = cmsghdr;
 
318
        inmessage.msg_controllen = CMSG_SPACE_SNDRCV;
 
319
 
 
320
        error = sctp_recvmsg(NULL, sk2, &inmessage, REALLY_BIG,
 
321
                             /* noblock */ 1, /* flags */ 0,
 
322
                             &addr_len);
 
323
        if (error < 0) { DUMP_CORE; }
 
324
        test_frame_check_message(&inmessage,
 
325
                                 /* orig */
 
326
                                 CMSG_SPACE_SNDRCV,
 
327
                                 REALLY_BIG,
 
328
                                 big_buffer,
 
329
                                 /* expected */
 
330
                                 sizeof(struct sctp_sndrcvinfo),
 
331
                                 strlen(telephone) + 1,
 
332
                                 telephone,
 
333
                                 SCTP_SNDRCV);
 
334
 
 
335
        /* Fixup msg_control, as testframe leaves it in a goofy state. */
 
336
        test_frame_fixup_msg_control(&inmessage,
 
337
                                     sizeof(struct sctp_cmsghdr));
 
338
 
 
339
        /* Make sure that the stream and ppid were preserved. */
 
340
        if (!test_check_sndrcvinfo(&inmessage, 0, stream, ppid)) {
 
341
                printf("stream: %d, ppid: %d\n",stream, ppid);
 
342
                DUMP_CORE;
 
343
        }
 
344
 
 
345
        /* Shut down the link.  */
 
346
        sctp_close(sk1, /* timeout */ 0);
 
347
 
 
348
        error = test_run_network();
 
349
        if (error != 0) { DUMP_CORE; }
 
350
 
 
351
        error = 0;
 
352
        sctp_close(sk2, /* timeout */ 0);
 
353
 
 
354
 
 
355
        if (0 == error) {
 
356
                printk("\n\n%s passed\n\n\n", argv[0]);
 
357
        }
 
358
 
 
359
        /* Indicate successful completion.  */
 
360
        exit(error);
 
361
 
 
362
} /* main() */