~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: 2007-10-19 19:01:00 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20071019190100-adbg1v6a7uyz2jpx
Tags: 1.0.7.dfsg-2
* debian/control
  - Use the new "Homepage:" field to specify the upstream URL.
  - Update the package recommendations: 
    kernel-image-2.6 is no longer available in the archive, so remove it.
    linux-image-2.6-386 has been superseded by linux-image-2.6-486.

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() */