1 /* $Id$
2 * --------------------------------------------------------------------------
3 *
4 * //===== //===== ===//=== //===// // // //===//
5 * // // // // // // // // //
6 * //====// // // //===// // // //===<<
7 * // // // // // // // //
8 * ======// //===== // // //===== // //===//
9 *
10 * -------------- An SCTP implementation according to RFC 4960 --------------
11 *
12 * Copyright (C) 2000 by Siemens AG, Munich, Germany.
13 * Copyright (C) 2001-2004 Andreas Jungmaier
14 * Copyright (C) 2004-2019 Thomas Dreibholz
15 *
16 * Acknowledgements:
17 * Realized in co-operation between Siemens AG and the University of
18 * Duisburg-Essen, Institute for Experimental Mathematics, Computer
19 * Networking Technology group.
20 * This work was partially funded by the Bundesministerium fuer Bildung und
21 * Forschung (BMBF) of the Federal Republic of Germany
22 * (Förderkennzeichen 01AK045).
23 * The authors alone are responsible for the contents.
24 *
25 * This library is free software: you can redistribute it and/or modify it
26 * under the terms of the GNU Lesser General Public License as published by
27 * the Free Software Foundation, either version 2.1 of the License, or
28 * (at your option) any later version.
29 *
30 * This library is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
34 *
35 * You should have received a copy of the GNU Lesser General Public License
36 * along with this program. If not, see <http://www.gnu.org/licenses/>.
37 *
38 * Contact: sctp-discussion@sctp.de
39 * dreibh@iem.uni-due.de
40 * tuexen@fh-muenster.de
41 * andreas.jungmaier@web.de
42 */
43
44 #include "sctp_wrapper.h"
45
46 #define POLLIN 0x001
47 #define POLLPRI 0x002
48 #define POLLOUT 0x004
49 #define POLLERR 0x008
50
51 #include <stdio.h>
52 #include <stdlib.h>
53
54 int
SCTP_setLibraryParameters(SCTP_LibraryParameters * params)55 SCTP_setLibraryParameters(SCTP_LibraryParameters *params)
56 {
57 int result;
58
59 if ((result = sctp_setLibraryParameters(params)) != SCTP_SUCCESS) {
60 if (result == SCTP_PARAMETER_PROBLEM) {
61 fprintf(stderr, "sctp_setLibraryParameters: parameter problem.\n");
62 } else
63 if (result == SCTP_LIBRARY_NOT_INITIALIZED) {
64 fprintf(stderr, "sctp_setLibraryParameters: Library not initialized.\n");
65 } else {
66 fprintf(stderr, "sctp_setLibraryParameters: unknown value (%i) returned.\n", result);
67 }
68 fflush(stderr);
69 exit(result);
70 }
71 return result;
72 }
73
74 int
SCTP_getLibraryParameters(SCTP_LibraryParameters * params)75 SCTP_getLibraryParameters(SCTP_LibraryParameters *params)
76 {
77 int result;
78
79 if ((result = sctp_getLibraryParameters(params)) != SCTP_SUCCESS) {
80 if (result == SCTP_PARAMETER_PROBLEM) {
81 fprintf(stderr, "sctp_getLibraryParameters: parameter problem.\n");
82 } else
83 if (result == SCTP_LIBRARY_NOT_INITIALIZED) {
84 fprintf(stderr, "sctp_getLibraryParameters: Library not initialized.\n");
85 } else {
86 fprintf(stderr, "sctp_getLibraryParameters: unknown value (%i) returned.\n", result);
87 }
88 fflush(stderr);
89 exit(result);
90 }
91 return result;
92 }
93
94 int
SCTP_initLibrary(void)95 SCTP_initLibrary(void)
96 {
97 int result;
98
99 if ((result = sctp_initLibrary()) != SCTP_SUCCESS) {
100 if (result == SCTP_LIBRARY_ALREADY_INITIALIZED) {
101 fprintf(stderr, "sctp_initLibrary: called muliple times.\n");
102 } else
103 if (result == SCTP_INSUFFICIENT_PRIVILEGES) {
104 fprintf(stderr, "sctp_initLibrary: could not open raw socket for SCTP. You must have root provileges !\n");
105 } else
106 if (result == SCTP_SPECIFIC_FUNCTION_ERROR) {
107 fprintf(stderr, "sctp_initLibrary: Unknown error in Adaptation-Module !\n");
108 } else {
109 fprintf(stderr, "sctp_initLibrary: unknown value (%i) returned.\n", result);
110 }
111 fflush(stderr);
112 exit(result);
113 }
114 return result;
115 }
116
117 int
SCTP_registerInstance(unsigned short port,unsigned short noOfInStreams,unsigned short noOfOutStreams,unsigned int noOfLocalAddresses,unsigned char localAddressList[][SCTP_MAX_IP_LEN],SCTP_ulpCallbacks ULPcallbackFunctions)118 SCTP_registerInstance(unsigned short port,
119 unsigned short noOfInStreams,
120 unsigned short noOfOutStreams,
121 unsigned int noOfLocalAddresses,
122 unsigned char localAddressList[][SCTP_MAX_IP_LEN],
123 SCTP_ulpCallbacks ULPcallbackFunctions)
124 {
125 int result;
126
127 result = sctp_registerInstance(port, noOfInStreams, noOfOutStreams,
128 noOfLocalAddresses, localAddressList,
129 ULPcallbackFunctions);
130 if (result == SCTP_PARAMETER_PROBLEM) {
131 fprintf(stderr, "sctp_registerInstance: an error occured.\n");
132 fflush(stderr);
133 exit(result);
134 } else if (result == SCTP_WRONG_ADDRESS) {
135 fprintf(stderr, "sctp_registerInstance: you passed an invalid/wrong address.\n");
136 fflush(stderr);
137 exit(result);
138 } else if (result == SCTP_OUT_OF_RESOURCES) {
139 fprintf(stderr, "sctp_registerInstance: you passed an invalid/wrong address.\n");
140 fflush(stderr);
141 exit(result);
142 }
143 return result;
144 }
145
SCTP_unregisterInstance(unsigned short instance_name)146 int SCTP_unregisterInstance(unsigned short instance_name)
147 {
148 int result;
149
150 if ((result = sctp_unregisterInstance(instance_name)) != 0) {
151 fprintf(stderr, "sctp_unregisterInstance: an error occured.\n");
152 fflush(stderr);
153 }
154 return result;
155 }
156
157 int
SCTP_deleteAssociation(unsigned int associationID)158 SCTP_deleteAssociation(unsigned int associationID)
159 {
160 int result;
161
162 if ((result = sctp_deleteAssociation(associationID))!=0) {
163 if (result == SCTP_LIBRARY_NOT_INITIALIZED) {
164 fprintf(stderr, "sctp_deleteAssociation: library not initialized:\n");
165 } else
166 if (result == SCTP_SPECIFIC_FUNCTION_ERROR) {
167 fprintf(stderr, "sctp_deleteAssociation: assoc not ready for deletion or lib not initialized:\n");
168 } else
169 if (result == SCTP_ASSOC_NOT_FOUND) {
170 fprintf(stderr, "sctp_deleteAssociation: assoc does not exists.\n");
171 }
172 fflush(stderr);
173 }
174 return result;
175 }
176
177 int
SCTP_send(unsigned int associationID,unsigned short streamID,unsigned char * buffer,unsigned int length,unsigned int protocolId,short path_id,void * context,unsigned int lifetime,int unorderedDelivery,int dontBundle)178 SCTP_send(unsigned int associationID, unsigned short streamID,
179 unsigned char *buffer, unsigned int length, unsigned int protocolId, short path_id,
180 void* context,
181 unsigned int lifetime,
182 int unorderedDelivery,
183 int dontBundle)
184 {
185 int result;
186
187 if ((result = sctp_send(associationID, streamID,
188 buffer, length, protocolId, path_id,
189 context,
190 lifetime,
191 unorderedDelivery,
192 dontBundle))!= SCTP_SUCCESS) {
193 if (result == SCTP_QUEUE_EXCEEDED) {
194 /* fprintf(stderr, "sctp_send: Queue size exceeded.\n");*/
195 } else
196 if (result == SCTP_LIBRARY_NOT_INITIALIZED) {
197 fprintf(stderr, "sctp_send: library not initialized.\n");
198 } else
199 if (result == SCTP_ASSOC_NOT_FOUND) {
200 fprintf(stderr, "sctp_send: association not found.\n");
201 } else
202 if (result == SCTP_SPECIFIC_FUNCTION_ERROR) {
203 fprintf(stderr, "sctp_send: association in shutdown state - don't send any more data !\n");
204 } else
205 if (result == SCTP_MODULE_NOT_FOUND) {
206 fprintf(stderr, "sctp_send: internal error !\n");
207 } else
208 if (result == SCTP_PARAMETER_PROBLEM) {
209 fprintf(stderr, "sctp_send: Parameter Problem (invalid path or stream id).\n");
210 } else {
211 fprintf(stderr, "sctp_send: unkown result (%i) returned.\n", result);
212 }
213 fflush(stderr);
214 }
215 return result;
216 }
217
218 int
SCTP_receive(unsigned int associationID,unsigned short streamID,unsigned char * buffer,unsigned int * length,unsigned short * streamSN,unsigned int * tsn,unsigned int flags)219 SCTP_receive(unsigned int associationID, unsigned short streamID, unsigned char *buffer,
220 unsigned int *length, unsigned short* streamSN, unsigned int * tsn, unsigned int flags)
221 {
222 int result;
223
224 if ((result = sctp_receive(associationID, streamID, buffer, length, streamSN, tsn, flags))!=0) {
225 if (result == SCTP_LIBRARY_NOT_INITIALIZED) {
226 fprintf(stderr, "sctp_receive: library not initialized.\n");
227 } else
228 if (result == SCTP_ASSOC_NOT_FOUND) {
229 fprintf(stderr, "sctp_receive: association not found.\n");
230 } else
231 if (result == SCTP_MODULE_NOT_FOUND) {
232 fprintf(stderr, "sctp_receive: internal error.\n");
233 } else
234 if (result == SCTP_SPECIFIC_FUNCTION_ERROR) {
235 /* fprintf(stderr, "sctp_receive: NO DATA AVAILABLE.\n"); */
236 } else
237 if (result == SCTP_PARAMETER_PROBLEM) {
238 fprintf(stderr, "sctp_receive: parameter problem (Null-Pointers, PathID ?)\n");
239 }
240 fflush(stderr);
241 }
242 return result;
243 }
244
245 int
SCTP_shutdown(unsigned int associationID)246 SCTP_shutdown(unsigned int associationID)
247 {
248 int result;
249
250 if ((result = sctp_shutdown(associationID))!= SCTP_SUCCESS) {
251 if (result == SCTP_LIBRARY_NOT_INITIALIZED) {
252 fprintf(stderr, "sctp_shutdown: library not initialized.\n");
253 } else
254 if (result == SCTP_ASSOC_NOT_FOUND) {
255 fprintf(stderr, "sctp_shutdown: association not found.\n");
256 }
257 fflush(stderr);
258 }
259 return result;
260 }
261
262 int
SCTP_abort(unsigned int associationID)263 SCTP_abort(unsigned int associationID)
264 {
265 int result;
266
267 if ((result = sctp_abort(associationID)) != SCTP_SUCCESS) {
268 if (result == SCTP_LIBRARY_NOT_INITIALIZED) {
269 fprintf(stderr, "sctp_abort: library not initialized.\n");
270 } else
271 if (result == SCTP_ASSOC_NOT_FOUND) {
272 fprintf(stderr, "sctp_abort: association not found.\n");
273 }
274 fflush(stderr);
275 }
276 return result;
277 }
278
SCTP_getAssocStatus(unsigned int associationID,SCTP_AssociationStatus * status)279 int SCTP_getAssocStatus(unsigned int associationID, SCTP_AssociationStatus* status)
280 {
281 int result;
282
283 if ((result = sctp_getAssocStatus(associationID, status)) != SCTP_SUCCESS) {
284 if (result == SCTP_LIBRARY_NOT_INITIALIZED) {
285 fprintf(stderr, "sctp_getAssocStatus: library not initialized.\n");
286 } else
287 if (result == SCTP_ASSOC_NOT_FOUND) {
288 fprintf(stderr, "sctp_getAssocStatus: association not found.\n");
289 } else
290 if (result == SCTP_PARAMETER_PROBLEM) {
291 fprintf(stderr, "sctp_getAssocStatus: parameter problem (NULL pointer ?)\n");
292 } else {
293 fprintf(stderr, "sctp_getAssocStatus: unknown value (%i) returned.\n", result);
294 }
295 fflush(stderr);
296 }
297 return result;
298 }
299
300 int
SCTP_receiveUnacked(unsigned int associationID,unsigned char * buffer,unsigned int * length,unsigned int * tsn,unsigned short * streamID,unsigned short * streamSN,unsigned int * protocolId)301 SCTP_receiveUnacked(unsigned int associationID, unsigned char *buffer, unsigned int *length, unsigned int* tsn,
302 unsigned short *streamID, unsigned short *streamSN,unsigned int* protocolId)
303 {
304 int result;
305 unsigned char flags;
306 void* ctx;
307
308 if ((result = sctp_receiveUnacked(associationID, buffer, length, tsn,
309 streamID, streamSN, protocolId, &flags, &ctx)) < 0) {
310
311 if (result == SCTP_WRONG_STATE) {
312 fprintf(stderr, "SCTP_receiveUnacked: Association is not in state CLOSED. \n");
313 }else if (result ==SCTP_ASSOC_NOT_FOUND){
314 fprintf(stderr, "SCTP_receiveUnacked: Association not found \n");
315 }else if (result == SCTP_NO_CHUNKS_IN_QUEUE){
316 /* fprintf(stderr, "SCTP_receiveUnacked: Queue is already empty.\n"); */
317 }else if (result == SCTP_LIBRARY_NOT_INITIALIZED){
318 fprintf(stderr, "SCTP_receiveUnacked: Library not Initialized \n");
319 }else if (result == SCTP_PARAMETER_PROBLEM){
320 fprintf(stderr, "SCTP_receiveUnacked: parameter problem, NULL pointer passed ?\n");
321 } else {
322 fprintf(stderr, "SCTP_receiveUnacked: unknown value (%i) returned.\n", result);
323 }
324 fflush(stderr);
325 }
326 return result;
327 }
328
329 int
SCTP_receiveUnsent(unsigned int associationID,unsigned char * buffer,unsigned int * length,unsigned int * tsn,unsigned short * streamID,unsigned short * streamSN,unsigned int * protocolId)330 SCTP_receiveUnsent(unsigned int associationID, unsigned char *buffer, unsigned int *length, unsigned int* tsn,
331 unsigned short *streamID, unsigned short *streamSN,unsigned int* protocolId)
332 {
333 int result;
334 unsigned char flags;
335 void* ctx;
336
337 if ((result = sctp_receiveUnsent(associationID, buffer, length, tsn,
338 streamID, streamSN, protocolId, &flags, &ctx)) < 0) {
339 if (result == SCTP_WRONG_STATE) {
340 fprintf(stderr, "sctp_receiveUnsent: Association is not in state CLOSED. \n");
341 }else if (result ==SCTP_ASSOC_NOT_FOUND){
342 fprintf(stderr, "sctp_receiveUnsent: Association not found \n");
343 }else if (result == SCTP_PARAMETER_PROBLEM){
344 fprintf(stderr, "sctp_receiveUnsent: parameter problem, NULL pointer passed ?\n");
345 }else if (result == SCTP_LIBRARY_NOT_INITIALIZED){
346 fprintf(stderr, "sctp_receiveUnsent: Library not Initialized.\n");
347 }else if (result == SCTP_NO_CHUNKS_IN_QUEUE){
348 /* fprintf(stderr, "sctp_receiveUnsent: Queue is already empty.\n"); */
349 } else {
350 fprintf(stderr, "sctp_receiveUnsent: unknown value (%i) returned.\n", result);
351 }
352 fflush(stderr);
353 }
354 return result;
355 }
356
357 short
SCTP_setPrimary(unsigned int associationID,short path_id)358 SCTP_setPrimary(unsigned int associationID, short path_id)
359 {
360 int result;
361
362 if ((result = sctp_setPrimary(associationID, path_id)) != 0) {
363 if (result == SCTP_LIBRARY_NOT_INITIALIZED) {
364 fprintf(stderr, "sctp_setPrimary: library not initialized.\n");
365 } else
366 if (result == SCTP_ASSOC_NOT_FOUND) {
367 fprintf(stderr, "sctp_setPrimary: association not found.\n");
368 } else
369 if (result == SCTP_MODULE_NOT_FOUND) {
370 fprintf(stderr, "sctp_setPrimary: internal error.\n");
371 } else
372 if (result == SCTP_UNSPECIFIED_ERROR) {
373 fprintf(stderr, "sctp_setPrimary: internal error (data structure not yet allocated).\n");
374 } else
375 if (result == SCTP_PARAMETER_PROBLEM) {
376 fprintf(stderr, "sctp_setPrimary: Path Id invalid.\n");
377 } else
378 if (result == SCTP_SPECIFIC_FUNCTION_ERROR) {
379 fprintf(stderr, "sctp_setPrimary: association is not in state established, or primary path inactive\n");
380 }
381 fflush(stderr);
382 }
383 return result;
384 }
385
386 short
SCTP_getPrimary(unsigned int associationID)387 SCTP_getPrimary(unsigned int associationID)
388 {
389 int result;
390
391 if ((result = sctp_getPrimary(associationID)) < 0) {
392 fprintf(stderr, "sctp_setPrimary: error value (%i) returned.\n", result);
393 fflush(stderr);
394 }
395 return result;
396 }
397
398 int
SCTP_eventLoop(void)399 SCTP_eventLoop(void)
400 {
401 int result;
402
403 if ((result = sctp_eventLoop()) < 0) {
404 if (result == -1) {
405 fprintf(stderr, "sctp_eventLoop: an error occured.\n");
406 } else {
407 fprintf(stderr, "sctp_eventLoop: unknown value (%i) returned.\n", result);
408 }
409 fflush(stderr);
410 }
411 return result;
412 }
413
414 int
SCTP_getPathStatus(unsigned int associationID,short path_id,SCTP_PathStatus * status)415 SCTP_getPathStatus(unsigned int associationID, short path_id, SCTP_PathStatus* status)
416 {
417 int result;
418
419 if ((result = sctp_getPathStatus(associationID, path_id, status)) != 0) {
420 if (result == SCTP_LIBRARY_NOT_INITIALIZED) {
421 fprintf(stderr, "sctp_getP: library not initialized.\n");
422 } else
423 if (result == SCTP_ASSOC_NOT_FOUND) {
424 fprintf(stderr, ": association not found.\n");
425 } else
426 if (result == SCTP_PARAMETER_PROBLEM) {
427 fprintf(stderr, ": Path Id invalid.\n");
428 } else {
429 fprintf(stderr, "sctp_getPathStatus: error value (%i) returned.\n", result);
430 fflush(stderr);
431 }
432 }
433 return result;
434 }
435
436 unsigned int
SCTP_associate(unsigned short SCTP_InstanceName,unsigned short noOfOutStreams,unsigned char destinationAddress[],unsigned short destinationPort,void * ulp_data)437 SCTP_associate(unsigned short SCTP_InstanceName,
438 unsigned short noOfOutStreams,
439 unsigned char destinationAddress[],
440 unsigned short destinationPort,
441 void* ulp_data)
442 {
443 unsigned short result;
444
445 if ((result = sctp_associate(SCTP_InstanceName,
446 noOfOutStreams,
447 destinationAddress,
448 destinationPort,
449 ulp_data)) == 0) {
450 fprintf(stderr, "sctp_associate: an error occured.\n");
451 fflush(stderr);
452 }
453 return result;
454 }
455
456
SCTP_changeHeartBeat(unsigned int associationID,short path_id,int heartbeatON,unsigned int timeInterval)457 int SCTP_changeHeartBeat(unsigned int associationID,
458 short path_id, int heartbeatON, unsigned int timeInterval)
459 {
460 int result;
461
462 if ((result = sctp_changeHeartBeat(associationID, path_id, heartbeatON, timeInterval)) < 0) {
463 fprintf(stderr, "sctp_changeHeartBeat: an error occured.\n");
464 fflush(stderr);
465 }
466 return result;
467 }
468
469 int
SCTP_registerStdinCallback(sctp_StdinCallback sdf,char * buffer,int length)470 SCTP_registerStdinCallback(sctp_StdinCallback sdf, char* buffer, int length)
471 {
472 int result;
473
474 if ((result = sctp_registerStdinCallback(sdf, buffer, length)) < 0) {
475 fprintf(stderr, "sctp_registerStdinCallback: error value (%i) returned.\n", result);
476 fflush(stderr);
477 }
478 return result;
479 }
480
SCTP_unregisterStdinCallback()481 int SCTP_unregisterStdinCallback()
482 {
483 int result;
484
485 if ((result = sctp_unregisterStdinCallback()) < 0) {
486 fprintf(stderr, "sctp_unregisterStdinCallback: error value (%i) returned.\n", result);
487 fflush(stderr);
488 }
489 return result;
490 }
491
492 #ifndef WIN32
493 int
SCTP_registerUserCallback(int fd,sctp_userCallback sdf,void * userData)494 SCTP_registerUserCallback(int fd, sctp_userCallback sdf, void* userData)
495 {
496 int result;
497
498 if ((result = sctp_registerUserCallback(fd, sdf, userData, POLLIN|POLLPRI)) < 0) {
499 fprintf(stderr, "sctp_registerUserCallback: error value (%i) returned.\n", result);
500 fflush(stderr);
501 }
502 return result;
503 }
504 #endif
505
506 int
SCTP_getAssocDefaults(unsigned short SCTP_InstanceName,SCTP_InstanceParameters * params)507 SCTP_getAssocDefaults(unsigned short SCTP_InstanceName, SCTP_InstanceParameters* params)
508 {
509 int result;
510
511 if ((result = sctp_getAssocDefaults(SCTP_InstanceName, params)) != 0) {
512 fprintf(stderr, "sctp_getAssocDefaults: error value (%i) returned.\n", result);
513 fflush(stderr);
514 }
515 return result;
516 }
517
518 int
SCTP_setAssocDefaults(unsigned short SCTP_InstanceName,SCTP_InstanceParameters * params)519 SCTP_setAssocDefaults(unsigned short SCTP_InstanceName, SCTP_InstanceParameters* params)
520 {
521 int result;
522
523 if ((result = sctp_setAssocDefaults(SCTP_InstanceName, params)) != 0) {
524 fprintf(stderr, "sctp_setAssocDefaults: error value (%i) returned.\n", result);
525 fflush(stderr);
526 }
527 return result;
528 }
529
530 unsigned int
SCTP_startTimer(unsigned int milliseconds,sctp_timerCallback timer_cb,void * param1,void * param2)531 SCTP_startTimer(unsigned int milliseconds, sctp_timerCallback timer_cb,
532 void *param1, void *param2)
533 {
534 return sctp_startTimer(milliseconds/1000, (milliseconds%1000)*1000, timer_cb, param1, param2);
535 }
536
537