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 #ifndef GLOBALS_H
45 #define GLOBALS_H
46 
47 #ifdef HAVE_CONFIG_H
48     #include <config.h>
49 #endif
50 
51 
52 #include <stdio.h>
53 #include <glib.h>
54 #include <string.h>
55 #include <stdlib.h>
56 
57 
58 #ifdef  STDC_HEADERS
59  #ifdef  HAVE_SYS_TIME_H
60   #include <sys/time.h>
61   #ifdef TIME_WITH_SYS_TIME
62    #include <time.h>
63   #endif
64  #endif
65  #ifdef  HAVE_UNISTD_H
66   #include <unistd.h>
67  #endif
68 #endif
69 
70 #ifdef WIN32
71 #include <winsock2.h>
72 #include <time.h>
73 #endif
74 
75 #ifdef FreeBSD
76 #include <netinet/in_systm.h>
77 #include <sys/types.h>
78 #endif
79 
80 #ifdef SOLARIS
81 #include <netinet/in_systm.h>
82 #include <stdarg.h>
83 #endif
84 
85 
86 /* turn on  Posix 1g for compatible cmsg structure */
87 /* #ifdef USE_RFC2292BIS
88      #define _XPG4_2
89   #endif
90 */
91 
92 #ifndef WIN32
93 #include <sys/socket.h>
94 #include <netinet/in.h>
95 #endif
96 
97 #include "messages.h"
98 
99 /* timer granularity in millliseconds..... */
100 #define GRANULARITY		1
101 
102 /* Define a protocol id to be used in the IP Header..... */
103 #ifndef IPPROTO_SCTP
104 #define IPPROTO_SCTP    132
105 #endif
106 
107 /** this parameter specifies the maximum number of addresses that an endpoint may have */
108 #define MAX_NUM_ADDRESSES      32
109 
110 
111 #define SECRET_KEYSIZE  4096
112 #define KEY_INIT     0
113 #ifndef KEY_READ
114 #define KEY_READ     1
115 #endif
116 #define MAX_DEST 	16
117 
118 
119 /* Definition of levels for the logging of events */
120 #define ByteString_log_    0    /* set to != 0 if byte string logging should be done */
121 
122 #define VVERBOSE           6    /* very verbose logging of events   */
123 #define VERBOSE            5    /* more verbose logging of events   */
124 #define INTERNAL_EVENT_0   4    /* pure execution flow trace */
125 #define INTERNAL_EVENT_1   3    /* important internal events */
126 #define EXTERNAL_EVENT     2    /* for events from ULP, peer or Timers */
127 #define EXTERNAL_EVENT_X   1    /* for unexpected external events from ULP, peer or Timers */
128 
129 
130 #define Current_event_log_ 0    /* Defines the level up to which the events are printed.
131                                    VVERBOSE (6) means all events are printed.
132                                    This parameter could also come from a command line option */
133 
134 /* Definition of levels for the logging of errors */
135 #define ERROR_WARNING      4    /* warning, recovery not necessary. */
136 #define ERROR_MINOR        3    /* recovery from error was possible without affecting the system. */
137 #define ERROR_MAJOR        2    /* recovery from error was possible with some affects to the system,
138                                    for instance abort of an association. */
139 #define ERROR_FATAL        1    /* recovery from error was not possible, the program exits. */
140 
141 #define Current_error_log_ 1    /* Defines the level up to which the errors are printed.
142                                    ERROR_WARNING (4) means all events are printed.
143                                    This parameter could also come from a command line option */
144 
145 typedef unsigned char boolean;
146 typedef unsigned int TimerID;
147 
148 #define   TIMER_TYPE_INIT       0
149 #define   TIMER_TYPE_SHUTDOWN   1
150 #define   TIMER_TYPE_RTXM       3
151 #define   TIMER_TYPE_SACK       2
152 #define   TIMER_TYPE_CWND       4
153 #define   TIMER_TYPE_HEARTBEAT  5
154 #define   TIMER_TYPE_USER       6
155 
156 typedef struct chunk_data_struct
157 {
158     unsigned int chunk_len;
159     unsigned int chunk_tsn;     /* for efficiency */
160     unsigned char data[MAX_SCTP_PDU];
161     unsigned int gap_reports;
162     struct timeval transmission_time;
163     /* ack_time : in msecs after transmission time, initially 0, -1 if retransmitted */
164     int ack_time;
165     unsigned int num_of_transmissions;
166     /* time after which chunk should not be retransmitted */
167     struct timeval expiry_time;
168     gboolean dontBundle;
169     /* lst destination used to send chunk to */
170     unsigned int last_destination;
171     int initial_destination;
172     /* this is set to true, whenever chunk is sent/received on unreliable stream */
173     gboolean isUnreliable;
174     gboolean hasBeenAcked;
175     gboolean hasBeenDropped;
176     gboolean hasBeenFastRetransmitted;
177     gboolean hasBeenRequeued;
178     gpointer context;
179 } chunk_data;
180 
181 #ifndef max
182 #define max(x,y)            ((x)>(y))?(x):(y)
183 #endif
184 #ifndef min
185 #define min(x,y)            ((x)<(y))?(x):(y)
186 #endif
187 
188 #define event_log(x,y)        if (Current_event_log_ >= x) event_log1((x), __FILE__, (y))
189 #define event_logi(x,y,z)	  if (Current_event_log_ >= x) event_log1((x), __FILE__, (y), (z))
190 #define event_logii(x,y,z,i)	  if (Current_event_log_ >= x) event_log1((x), __FILE__, (y), (z), (i))
191 #define event_logiii(x,y,z,i,j)	  if (Current_event_log_ >= x) event_log1((x), __FILE__, (y), (z), (i), (j))
192 #define event_logiiii(x,y,z,i,j,k)	  if (Current_event_log_ >= x) event_log1((x), __FILE__, (y), (z), (i), (j),(k))
193 #define event_logiiiii(x,y,z,i,j,k,l)	  if (Current_event_log_ >= x) event_log1((x), __FILE__, (y), (z), (i), (j),(k),(l))
194 #define event_logiiiiiiii(x,y,z,i,j,k,l,m,n,o)	  if (Current_event_log_ >= x) event_log1((x), __FILE__, (y), (z), (i), (j),(k),(l),(m),(n),(o))
195 
196 
197 #define error_log(x,y)        if (Current_error_log_ >= x) error_log1((x), __FILE__, __LINE__, (y))
198 #define error_logi(x,y,z)        if (Current_error_log_ >= x) error_log1((x), __FILE__, __LINE__, (y),(z))
199 #define error_logii(x,y,z,i)        if (Current_error_log_ >= x) error_log1((x), __FILE__, __LINE__, (y),(z),(i))
200 #define error_logiii(x,y,z,i,j)        if (Current_error_log_ >= x) error_log1((x), __FILE__, __LINE__, (y),(z),(i),(j))
201 #define error_logiiii(x,y,z,i,j,k)        if (Current_error_log_ >= x) error_log1((x), __FILE__, __LINE__, (y),(z),(i),(j),(k))
202 #define error_log_sys(x,y)    error_log_sys1((x), __FILE__, __LINE__, (y))
203 #define DLL_error_log(x,y)    if (Current_error_log_ >= x) error_log1((x), __FILE__, __LINE__, (y))
204 
205 #define IF_LOG(x, y)       if (x <= Current_error_log_) {y}
206 /* read_tracelevels reads from a file the tracelevels for errors and events for each module.
207    Modules that are not listed in the file will not be traced. if the file does not exist or
208    is empty, the global tracelevel defined in globals.h will be used.
209    The format of the file is
210    module1.c errorTraceLevel eventTraceLevel
211    module2.c errorTraceLevel eventTraceLevel
212    ....
213 
214    The file must be terminated by a null line.
215 */
216 void read_tracelevels(void);
217 
218 
219 void debug_print(FILE * fd, const char *f, ...);
220 
221 /**
222  * function to output the result of the adl_gettime-call, i.e. the time now
223  */
224 void print_time(short level);
225 
226 /**
227  * print the error string after a system call and exit
228  */
229 void perr_exit(const char *infostring);
230 
231 
232 /* This function logs events.
233    Parameters:
234    @param event_log_level : INTERNAL_EVENT_0 INTERNAL_EVENT_1 EXTERNAL_EVENT_X EXTERNAL_EVENT
235    @param module_name :     the name of the module that received the event.
236    @param log_info :        the info that is printed with the modulename.
237    @param anyno :           optional pointer to unsigned int, which is printed along with log_info.
238                             The conversion specification must be contained in log_info.
239    @author     H�zlwimmer
240 */
241 void event_log1(short event_log_level, const char *module_name, const char *log_info, ...);
242 
243 
244 
245 /* This function logs errors.
246    Parameters:
247    @param error_log_level : ERROR_MINOR ERROR_MAJOR ERROR_FATAL
248    @param module_name :     the name of the module that received the event.
249    @param line_no :         the line number within above module.
250    @param log_info :        the info that is printed with the modulename.
251    @author     H�zlwimmer
252 */
253 void error_log1(short error_log_level, const char *module_name, int line_no, const char *log_info, ...);
254 
255 
256 /* This function logs system call errors.
257    This function calls error_log.
258    Parameters:
259    @param error_log_level : ERROR_MINOR ERROR_MAJOR ERROR_FATAL
260    @param module_name :     the name of the module that received the event.
261    @param line_no :         the line number within above module.
262    @param errnumber :       the errno from systemlibrary.
263    @param log_info :        the info that is printed with the modulename and error text.
264    @author     H�zlwimmer
265 */
266 void error_log_sys1(short error_log_level, const char *module_name, int line_no, short errnumber);
267 
268 
269 /**
270  * helper functions that correctly handle the 32bit wrapround
271  */
272 int before(unsigned int seq1, unsigned int seq2);
273 int after(unsigned int seq1, unsigned int seq2);
274 int sAfter(unsigned short seq1, unsigned short seq2);
275 int sBefore(unsigned short seq1, unsigned short seq2);
276 
277 /**
278  *  is s1 <= s2 <= s3 ?
279  */
280 int between(unsigned int seq1, unsigned int seq2, unsigned int seq3);
281 
282 /**
283  * compute IP checksum yourself. If packet does not have even packet boundaries,
284  * last byte will be set 0 and length increased by one. (should never happen in
285  * this SCTP implementation, since we always have 32 bit boundaries !
286  * Make sure the checksum is computed last thing before sending, and the checksum
287  * field is initialized to 0 before starting the computation
288  */
289 unsigned short in_check(unsigned char *buf, int sz);
290 
291 
292 int sort_prChunk(pr_stream_data* one, pr_stream_data* two);
293 
294 /*
295  * function that correctly sorts TSN values, minding the
296  * wrapround
297  */
298 int sort_tsn(chunk_data * one, chunk_data * two);
299 
300 void free_list_element(gpointer list_element, gpointer user_data);
301 
302 
303 /* shortcut macro to specify address field of struct sockaddr */
304 #define sock2ip(X)   (((struct sockaddr_in *)(X))->sin_addr.s_addr)
305 #ifdef HAVE_IPV6
306     #define sock2ip6(X)  (((struct sockaddr_in6 *)(X))->sin6_addr.s6_addr)
307     #define sock2ip6addr(X)  (((struct sockaddr_in6 *)(X))->sin6_addr)
308 #endif                          /* HAVE_IPV6 */
309 
310 /* union for handling either type of addresses: ipv4 and ipv6 */
311 #ifndef SOCKUNION_DEFINE
312 #define SOCKUNION_DEFINE    1
313 union sockunion
314 {
315     struct sockaddr sa;
316     struct sockaddr_in sin;
317 #ifdef HAVE_IPV6
318     struct sockaddr_in6 sin6;
319 #endif                          /* HAVE_IPV6 */
320 };
321 
322 #endif  /* SOCKUNION_DEFINE */
323 
324 #define sockunion_family(X)  (X)->sa.sa_family
325 
326 #define SUPPORT_ADDRESS_TYPE_IPV4        0x00000001
327 
328 #define SUPPORT_ADDRESS_TYPE_IPV6        0x00000002
329 #define SUPPORT_ADDRESS_TYPE_DNS         0x00000004
330 
331 typedef enum {
332       flag_HideLoopback           = (1 << 0),
333       flag_HideLinkLocal          = (1 << 1),
334       flag_HideSiteLocal          = (1 << 2),
335       flag_HideLocal              = flag_HideLoopback|flag_HideLinkLocal|flag_HideSiteLocal,
336       flag_HideAnycast            = (1 << 3),
337       flag_HideMulticast          = (1 << 4),
338       flag_HideBroadcast          = (1 << 5),
339       flag_HideReserved           = (1 << 6),
340       flag_Default                = flag_HideBroadcast|flag_HideMulticast|flag_HideAnycast,
341       flag_HideAllExceptLoopback  = (1 << 7),
342       flag_HideAllExceptLinkLocal = (1 << 8),
343       flag_HideAllExceptSiteLocal = (1 << 9)
344 } AddressScopingFlags;
345 
346 
347 #define DEFAULT_MTU_CEILING     1500
348 
349 
350 #ifndef CHECK
351 #define CHECK(cond) if(!(cond)) { fprintf(stderr, "INTERNAL ERROR in %s, line %u: condition %s is not satisfied!\n", __FILE__, __LINE__, #cond); abort(); }
352 #endif
353 
354 #endif
355