• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #ifdef _WIN32
3 #define _CRT_SECURE_NO_WARNINGS
4 #endif
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdarg.h>
9 #include <usrsctp.h>
10 
11 #ifndef _WIN32
12 #include <sys/time.h>
13 #include <arpa/inet.h>
14 #else
15 #include <sys/types.h>
16 #include <sys/timeb.h>
17 #include <io.h>
18 #endif
19 
20 #include "programs_helper.h"
21 
22 #ifdef _WIN32
23 static void
gettimeofday(struct timeval * tv,void * ignore)24 gettimeofday(struct timeval *tv, void *ignore)
25 {
26 	struct timeb tb;
27 
28 	ftime(&tb);
29 	tv->tv_sec = (long)tb.time;
30 	tv->tv_usec = (long)(tb.millitm) * 1000L;
31 }
32 #endif
33 
34 void
debug_printf_runtime(void)35 debug_printf_runtime(void) {
36 	static struct timeval time_main;
37 	struct timeval time_now;
38 	struct timeval time_delta;
39 
40 	if (time_main.tv_sec == 0  && time_main.tv_usec == 0) {
41 		gettimeofday(&time_main, NULL);
42 	}
43 
44 	gettimeofday(&time_now, NULL);
45 	timersub(&time_now, &time_main, &time_delta);
46 
47 	fprintf(stderr, "[%u.%03u] ", (unsigned int) time_delta.tv_sec, (unsigned int) time_delta.tv_usec / 1000);
48 }
49 
50 
51 void
debug_printf_stack(const char * format,...)52 debug_printf_stack(const char *format, ...)
53 {
54 	va_list ap;
55 	char charbuf[1024];
56 	static struct timeval time_main;
57 	struct timeval time_now;
58 	struct timeval time_delta;
59 
60 	if (time_main.tv_sec == 0  && time_main.tv_usec == 0) {
61 		gettimeofday(&time_main, NULL);
62 	}
63 
64 	gettimeofday(&time_now, NULL);
65 	timersub(&time_now, &time_main, &time_delta);
66 
67 	va_start(ap, format);
68 	if (vsnprintf(charbuf, 1024, format, ap) < 0) {
69 		charbuf[0] = '\0';
70 	}
71 	va_end(ap);
72 
73 	fprintf(stderr, "[S][%u.%03u] %s", (unsigned int) time_delta.tv_sec, (unsigned int) time_delta.tv_usec / 1000, charbuf);
74 }
75 
76 static void
handle_association_change_event(struct sctp_assoc_change * sac)77 handle_association_change_event(struct sctp_assoc_change *sac)
78 {
79 	unsigned int i, n;
80 
81 	fprintf(stderr, "Association change ");
82 	switch (sac->sac_state) {
83 	case SCTP_COMM_UP:
84 		fprintf(stderr, "SCTP_COMM_UP");
85 		break;
86 	case SCTP_COMM_LOST:
87 		fprintf(stderr, "SCTP_COMM_LOST");
88 		break;
89 	case SCTP_RESTART:
90 		fprintf(stderr, "SCTP_RESTART");
91 		break;
92 	case SCTP_SHUTDOWN_COMP:
93 		fprintf(stderr, "SCTP_SHUTDOWN_COMP");
94 		break;
95 	case SCTP_CANT_STR_ASSOC:
96 		fprintf(stderr, "SCTP_CANT_STR_ASSOC");
97 		break;
98 	default:
99 		fprintf(stderr, "UNKNOWN");
100 		break;
101 	}
102 	fprintf(stderr, ", streams (in/out) = (%u/%u)",
103 	       sac->sac_inbound_streams, sac->sac_outbound_streams);
104 	n = sac->sac_length - sizeof(struct sctp_assoc_change);
105 	if (((sac->sac_state == SCTP_COMM_UP) ||
106 	     (sac->sac_state == SCTP_RESTART)) && (n > 0)) {
107 		fprintf(stderr, ", supports");
108 		for (i = 0; i < n; i++) {
109 			switch (sac->sac_info[i]) {
110 			case SCTP_ASSOC_SUPPORTS_PR:
111 				fprintf(stderr, " PR");
112 				break;
113 			case SCTP_ASSOC_SUPPORTS_AUTH:
114 				fprintf(stderr, " AUTH");
115 				break;
116 			case SCTP_ASSOC_SUPPORTS_ASCONF:
117 				fprintf(stderr, " ASCONF");
118 				break;
119 			case SCTP_ASSOC_SUPPORTS_MULTIBUF:
120 				fprintf(stderr, " MULTIBUF");
121 				break;
122 			case SCTP_ASSOC_SUPPORTS_RE_CONFIG:
123 				fprintf(stderr, " RE-CONFIG");
124 				break;
125 			case SCTP_ASSOC_SUPPORTS_INTERLEAVING:
126 				fprintf(stderr, " INTERLEAVING");
127 				break;
128 			default:
129 				fprintf(stderr, " UNKNOWN(0x%02x)", sac->sac_info[i]);
130 				break;
131 			}
132 		}
133 	} else if (((sac->sac_state == SCTP_COMM_LOST) ||
134 	            (sac->sac_state == SCTP_CANT_STR_ASSOC)) && (n > 0)) {
135 		fprintf(stderr, ", ABORT =");
136 		for (i = 0; i < n; i++) {
137 			fprintf(stderr, " 0x%02x", sac->sac_info[i]);
138 		}
139 	}
140 	fprintf(stderr, ".\n");
141 	return;
142 }
143 
144 static void
handle_peer_address_change_event(struct sctp_paddr_change * spc)145 handle_peer_address_change_event(struct sctp_paddr_change *spc)
146 {
147 	char addr_buf[INET6_ADDRSTRLEN];
148 	const char *addr;
149 	struct sockaddr_in *sin;
150 	struct sockaddr_in6 *sin6;
151 	struct sockaddr_conn *sconn;
152 
153 	switch (spc->spc_aaddr.ss_family) {
154 	case AF_INET:
155 		sin = (struct sockaddr_in *)&spc->spc_aaddr;
156 		addr = inet_ntop(AF_INET, &sin->sin_addr, addr_buf, INET_ADDRSTRLEN);
157 		break;
158 	case AF_INET6:
159 		sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
160 		addr = inet_ntop(AF_INET6, &sin6->sin6_addr, addr_buf, INET6_ADDRSTRLEN);
161 		break;
162 	case AF_CONN:
163 		sconn = (struct sockaddr_conn *)&spc->spc_aaddr;
164 #ifdef _WIN32
165 		if (_snprintf(addr_buf, INET6_ADDRSTRLEN, "%p", sconn->sconn_addr) < 0) {
166 #else
167 		if (snprintf(addr_buf, INET6_ADDRSTRLEN, "%p", sconn->sconn_addr) < 0) {
168 #endif
169 			addr_buf[0] = '\0';
170 		}
171 		addr = addr_buf;
172 		break;
173 	default:
174 #ifdef _WIN32
175 		if (_snprintf(addr_buf, INET6_ADDRSTRLEN, "Unknown family %d", spc->spc_aaddr.ss_family) < 0) {
176 #else
177 		if (snprintf(addr_buf, INET6_ADDRSTRLEN, "Unknown family %d", spc->spc_aaddr.ss_family) < 0) {
178 #endif
179 			addr_buf[0] = '\0';
180 		}
181 		addr = addr_buf;
182 		break;
183 	}
184 	fprintf(stderr, "Peer address %s is now ", addr);
185 	switch (spc->spc_state) {
186 	case SCTP_ADDR_AVAILABLE:
187 		fprintf(stderr, "SCTP_ADDR_AVAILABLE");
188 		break;
189 	case SCTP_ADDR_UNREACHABLE:
190 		fprintf(stderr, "SCTP_ADDR_UNREACHABLE");
191 		break;
192 	case SCTP_ADDR_REMOVED:
193 		fprintf(stderr, "SCTP_ADDR_REMOVED");
194 		break;
195 	case SCTP_ADDR_ADDED:
196 		fprintf(stderr, "SCTP_ADDR_ADDED");
197 		break;
198 	case SCTP_ADDR_MADE_PRIM:
199 		fprintf(stderr, "SCTP_ADDR_MADE_PRIM");
200 		break;
201 	case SCTP_ADDR_CONFIRMED:
202 		fprintf(stderr, "SCTP_ADDR_CONFIRMED");
203 		break;
204 	default:
205 		fprintf(stderr, "UNKNOWN");
206 		break;
207 	}
208 	fprintf(stderr, " (error = 0x%08x).\n", spc->spc_error);
209 	return;
210 }
211 
212 static void
213 handle_send_failed_event(struct sctp_send_failed_event *ssfe)
214 {
215 	size_t i, n;
216 
217 	if (ssfe->ssfe_flags & SCTP_DATA_UNSENT) {
218 		fprintf(stderr, "Unsent ");
219 	}
220 	if (ssfe->ssfe_flags & SCTP_DATA_SENT) {
221 		fprintf(stderr, "Sent ");
222 	}
223 	if (ssfe->ssfe_flags & ~(SCTP_DATA_SENT | SCTP_DATA_UNSENT)) {
224 		fprintf(stderr, "(flags = %x) ", ssfe->ssfe_flags);
225 	}
226 	fprintf(stderr, "message with PPID = %u, SID = %u, flags: 0x%04x due to error = 0x%08x",
227 	       ntohl(ssfe->ssfe_info.snd_ppid), ssfe->ssfe_info.snd_sid,
228 	       ssfe->ssfe_info.snd_flags, ssfe->ssfe_error);
229 	n = ssfe->ssfe_length - sizeof(struct sctp_send_failed_event);
230 	for (i = 0; i < n; i++) {
231 		fprintf(stderr, " 0x%02x", ssfe->ssfe_data[i]);
232 	}
233 	fprintf(stderr, ".\n");
234 	return;
235 }
236 
237 static void
238 handle_adaptation_indication(struct sctp_adaptation_event *sai)
239 {
240 	fprintf(stderr, "Adaptation indication: %x.\n", sai-> sai_adaptation_ind);
241 	return;
242 }
243 
244 static void
245 handle_shutdown_event(struct sctp_shutdown_event *sse)
246 {
247 	fprintf(stderr, "Shutdown event.\n");
248 	/* XXX: notify all channels. */
249 	return;
250 }
251 
252 static void
253 handle_stream_reset_event(struct sctp_stream_reset_event *strrst)
254 {
255 	uint32_t n, i;
256 
257 	n = (strrst->strreset_length - sizeof(struct sctp_stream_reset_event)) / sizeof(uint16_t);
258 	fprintf(stderr, "Stream reset event: flags = %x, ", strrst->strreset_flags);
259 	if (strrst->strreset_flags & SCTP_STREAM_RESET_INCOMING_SSN) {
260 		if (strrst->strreset_flags & SCTP_STREAM_RESET_OUTGOING_SSN) {
261 			fprintf(stderr, "incoming/");
262 		}
263 		fprintf(stderr, "incoming ");
264 	}
265 	if (strrst->strreset_flags & SCTP_STREAM_RESET_OUTGOING_SSN) {
266 		fprintf(stderr, "outgoing ");
267 	}
268 	fprintf(stderr, "stream ids = ");
269 	for (i = 0; i < n; i++) {
270 		if (i > 0) {
271 			fprintf(stderr, ", ");
272 		}
273 		fprintf(stderr, "%d", strrst->strreset_stream_list[i]);
274 	}
275 	fprintf(stderr, ".\n");
276 	return;
277 }
278 
279 static void
280 handle_stream_change_event(struct sctp_stream_change_event *strchg)
281 {
282 	fprintf(stderr, "Stream change event: streams (in/out) = (%u/%u), flags = %x.\n",
283 	       strchg->strchange_instrms, strchg->strchange_outstrms, strchg->strchange_flags);
284 	return;
285 }
286 
287 static void
288 handle_remote_error_event(struct sctp_remote_error *sre)
289 {
290 	size_t i, n;
291 
292 	n = sre->sre_length - sizeof(struct sctp_remote_error);
293 	fprintf(stderr, "Remote Error (error = 0x%04x): ", sre->sre_error);
294 	for (i = 0; i < n; i++) {
295 		fprintf(stderr, " 0x%02x", sre-> sre_data[i]);
296 	}
297 	fprintf(stderr, ".\n");
298 	return;
299 }
300 
301 void
302 handle_notification(union sctp_notification *notif, size_t n)
303 {
304 	if (notif->sn_header.sn_length != (uint32_t)n) {
305 		return;
306 	}
307 
308 	fprintf(stderr, "handle_notification : ");
309 
310 	switch (notif->sn_header.sn_type) {
311 	case SCTP_ASSOC_CHANGE:
312 		fprintf(stderr, "SCTP_ASSOC_CHANGE\n");
313 		handle_association_change_event(&(notif->sn_assoc_change));
314 		break;
315 	case SCTP_PEER_ADDR_CHANGE:
316 		fprintf(stderr, "SCTP_PEER_ADDR_CHANGE\n");
317 		handle_peer_address_change_event(&(notif->sn_paddr_change));
318 		break;
319 	case SCTP_REMOTE_ERROR:
320 		fprintf(stderr, "SCTP_REMOTE_ERROR\n");
321 		handle_remote_error_event(&(notif->sn_remote_error));
322 		break;
323 	case SCTP_SHUTDOWN_EVENT:
324 		fprintf(stderr, "SCTP_SHUTDOWN_EVENT\n");
325 		handle_shutdown_event(&(notif->sn_shutdown_event));
326 		break;
327 	case SCTP_ADAPTATION_INDICATION:
328 		fprintf(stderr, "SCTP_ADAPTATION_INDICATION\n");
329 		handle_adaptation_indication(&(notif->sn_adaptation_event));
330 		break;
331 	case SCTP_PARTIAL_DELIVERY_EVENT:
332 		fprintf(stderr, "SCTP_PARTIAL_DELIVERY_EVENT\n");
333 		break;
334 	case SCTP_AUTHENTICATION_EVENT:
335 		fprintf(stderr, "SCTP_AUTHENTICATION_EVENT\n");
336 		break;
337 	case SCTP_SENDER_DRY_EVENT:
338 		fprintf(stderr, "SCTP_SENDER_DRY_EVENT\n");
339 		break;
340 	case SCTP_NOTIFICATIONS_STOPPED_EVENT:
341 		fprintf(stderr, "SCTP_NOTIFICATIONS_STOPPED_EVENT\n");
342 		break;
343 	case SCTP_SEND_FAILED_EVENT:
344 		fprintf(stderr, "SCTP_SEND_FAILED_EVENT\n");
345 		handle_send_failed_event(&(notif->sn_send_failed_event));
346 		break;
347 	case SCTP_STREAM_RESET_EVENT:
348 		fprintf(stderr, "SCTP_STREAM_RESET_EVENT\n");
349 		handle_stream_reset_event(&(notif->sn_strreset_event));
350 		break;
351 	case SCTP_ASSOC_RESET_EVENT:
352 		fprintf(stderr, "SCTP_ASSOC_RESET_EVENT\n");
353 		break;
354 	case SCTP_STREAM_CHANGE_EVENT:
355 		fprintf(stderr, "SCTP_STREAM_CHANGE_EVENT\n");
356 		handle_stream_change_event(&(notif->sn_strchange_event));
357 		break;
358 	default:
359 		break;
360 	}
361 }
362