programs_helper.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. /*-
  2. * Copyright (c) 2019 -2020 Felix Weinrank
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  16. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  22. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25. * SUCH DAMAGE.
  26. */
  27. #ifdef _WIN32
  28. #define _CRT_SECURE_NO_WARNINGS
  29. #endif
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <stdarg.h>
  33. #include <usrsctp.h>
  34. #ifndef _WIN32
  35. #include <sys/time.h>
  36. #include <arpa/inet.h>
  37. #else
  38. #include <sys/types.h>
  39. #include <sys/timeb.h>
  40. #include <io.h>
  41. #endif
  42. #include "programs_helper.h"
  43. #define DEFAULT_TARGET stdout;
  44. static FILE *debug_target = NULL;
  45. #ifdef _WIN32
  46. static void
  47. gettimeofday(struct timeval *tv, void *ignore)
  48. {
  49. FILETIME filetime;
  50. ULARGE_INTEGER ularge;
  51. GetSystemTimeAsFileTime(&filetime);
  52. ularge.LowPart = filetime.dwLowDateTime;
  53. ularge.HighPart = filetime.dwHighDateTime;
  54. /* Change base from Jan 1 1601 00:00:00 to Jan 1 1970 00:00:00 */
  55. #if defined(__MINGW32__)
  56. ularge.QuadPart -= 116444736000000000ULL;
  57. #else
  58. ularge.QuadPart -= 116444736000000000UI64;
  59. #endif
  60. /*
  61. * ularge.QuadPart is now the number of 100-nanosecond intervals
  62. * since Jan 1 1970 00:00:00.
  63. */
  64. #if defined(__MINGW32__)
  65. tv->tv_sec = (long)(ularge.QuadPart / 10000000ULL);
  66. tv->tv_usec = (long)((ularge.QuadPart % 10000000ULL) / 10ULL);
  67. #else
  68. tv->tv_sec = (long)(ularge.QuadPart / 10000000UI64);
  69. tv->tv_usec = (long)((ularge.QuadPart % 10000000UI64) / 10UI64);
  70. #endif
  71. }
  72. #endif
  73. void
  74. debug_set_target(FILE *fp) {
  75. debug_target = fp;
  76. }
  77. void
  78. debug_printf_clean(const char *format, ...) {
  79. char charbuf[1024];
  80. va_list ap;
  81. if (debug_target == NULL) {
  82. debug_target = DEFAULT_TARGET;
  83. }
  84. va_start(ap, format);
  85. if (vsnprintf(charbuf, 1024, format, ap) < 0) {
  86. charbuf[0] = '\0';
  87. }
  88. va_end(ap);
  89. fprintf(debug_target, "%s", charbuf);
  90. fflush(debug_target);
  91. }
  92. void
  93. debug_printf(const char *format, ...) {
  94. va_list ap;
  95. char charbuf[1024];
  96. static struct timeval time_main;
  97. struct timeval time_now;
  98. struct timeval time_delta;
  99. if (debug_target == NULL) {
  100. debug_target = DEFAULT_TARGET;
  101. }
  102. if (time_main.tv_sec == 0 && time_main.tv_usec == 0) {
  103. gettimeofday(&time_main, NULL);
  104. }
  105. gettimeofday(&time_now, NULL);
  106. timersub(&time_now, &time_main, &time_delta);
  107. va_start(ap, format);
  108. if (vsnprintf(charbuf, 1024, format, ap) < 0) {
  109. charbuf[0] = '\0';
  110. }
  111. va_end(ap);
  112. fprintf(debug_target, "[P][%u.%03u] %s", (unsigned int) time_delta.tv_sec, (unsigned int) time_delta.tv_usec / 1000, charbuf);
  113. fflush(debug_target);
  114. }
  115. void
  116. debug_printf_stack(const char *format, ...)
  117. {
  118. va_list ap;
  119. char charbuf[1024];
  120. static struct timeval time_main;
  121. struct timeval time_now;
  122. struct timeval time_delta;
  123. if (debug_target == NULL) {
  124. debug_target = DEFAULT_TARGET;
  125. }
  126. if (time_main.tv_sec == 0 && time_main.tv_usec == 0) {
  127. gettimeofday(&time_main, NULL);
  128. }
  129. gettimeofday(&time_now, NULL);
  130. timersub(&time_now, &time_main, &time_delta);
  131. va_start(ap, format);
  132. if (vsnprintf(charbuf, 1024, format, ap) < 0) {
  133. charbuf[0] = '\0';
  134. }
  135. va_end(ap);
  136. fprintf(debug_target, "[S][%u.%03u] %s", (unsigned int) time_delta.tv_sec, (unsigned int) time_delta.tv_usec / 1000, charbuf);
  137. fflush(debug_target);
  138. }
  139. static void
  140. handle_association_change_event(struct sctp_assoc_change *sac)
  141. {
  142. unsigned int i, n;
  143. if (debug_target == NULL) {
  144. debug_target = DEFAULT_TARGET;
  145. }
  146. fprintf(debug_target, "Association change ");
  147. switch (sac->sac_state) {
  148. case SCTP_COMM_UP:
  149. fprintf(debug_target, "SCTP_COMM_UP");
  150. break;
  151. case SCTP_COMM_LOST:
  152. fprintf(debug_target, "SCTP_COMM_LOST");
  153. break;
  154. case SCTP_RESTART:
  155. fprintf(debug_target, "SCTP_RESTART");
  156. break;
  157. case SCTP_SHUTDOWN_COMP:
  158. fprintf(debug_target, "SCTP_SHUTDOWN_COMP");
  159. break;
  160. case SCTP_CANT_STR_ASSOC:
  161. fprintf(debug_target, "SCTP_CANT_STR_ASSOC");
  162. break;
  163. default:
  164. fprintf(debug_target, "UNKNOWN");
  165. break;
  166. }
  167. fprintf(debug_target, ", streams (in/out) = (%u/%u)",
  168. sac->sac_inbound_streams, sac->sac_outbound_streams);
  169. n = sac->sac_length - sizeof(struct sctp_assoc_change);
  170. if (((sac->sac_state == SCTP_COMM_UP) ||
  171. (sac->sac_state == SCTP_RESTART)) && (n > 0)) {
  172. fprintf(debug_target, ", supports");
  173. for (i = 0; i < n; i++) {
  174. switch (sac->sac_info[i]) {
  175. case SCTP_ASSOC_SUPPORTS_PR:
  176. fprintf(debug_target, " PR");
  177. break;
  178. case SCTP_ASSOC_SUPPORTS_AUTH:
  179. fprintf(debug_target, " AUTH");
  180. break;
  181. case SCTP_ASSOC_SUPPORTS_ASCONF:
  182. fprintf(debug_target, " ASCONF");
  183. break;
  184. case SCTP_ASSOC_SUPPORTS_MULTIBUF:
  185. fprintf(debug_target, " MULTIBUF");
  186. break;
  187. case SCTP_ASSOC_SUPPORTS_RE_CONFIG:
  188. fprintf(debug_target, " RE-CONFIG");
  189. break;
  190. case SCTP_ASSOC_SUPPORTS_INTERLEAVING:
  191. fprintf(debug_target, " INTERLEAVING");
  192. break;
  193. default:
  194. fprintf(debug_target, " UNKNOWN(0x%02x)", sac->sac_info[i]);
  195. break;
  196. }
  197. }
  198. } else if (((sac->sac_state == SCTP_COMM_LOST) ||
  199. (sac->sac_state == SCTP_CANT_STR_ASSOC)) && (n > 0)) {
  200. fprintf(debug_target, ", ABORT =");
  201. for (i = 0; i < n; i++) {
  202. fprintf(debug_target, " 0x%02x", sac->sac_info[i]);
  203. }
  204. }
  205. fprintf(debug_target, ".\n");
  206. return;
  207. }
  208. static void
  209. handle_peer_address_change_event(struct sctp_paddr_change *spc)
  210. {
  211. char addr_buf[INET6_ADDRSTRLEN];
  212. const char *addr;
  213. struct sockaddr_in *sin;
  214. struct sockaddr_in6 *sin6;
  215. struct sockaddr_conn *sconn;
  216. if (debug_target == NULL) {
  217. debug_target = DEFAULT_TARGET;
  218. }
  219. switch (spc->spc_aaddr.ss_family) {
  220. case AF_INET:
  221. sin = (struct sockaddr_in *)&spc->spc_aaddr;
  222. addr = inet_ntop(AF_INET, &sin->sin_addr, addr_buf, INET_ADDRSTRLEN);
  223. break;
  224. case AF_INET6:
  225. sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
  226. addr = inet_ntop(AF_INET6, &sin6->sin6_addr, addr_buf, INET6_ADDRSTRLEN);
  227. break;
  228. case AF_CONN:
  229. sconn = (struct sockaddr_conn *)&spc->spc_aaddr;
  230. #ifdef _WIN32
  231. if (_snprintf(addr_buf, INET6_ADDRSTRLEN, "%p", sconn->sconn_addr) < 0) {
  232. #else
  233. if (snprintf(addr_buf, INET6_ADDRSTRLEN, "%p", sconn->sconn_addr) < 0) {
  234. #endif
  235. addr_buf[0] = '\0';
  236. }
  237. addr = addr_buf;
  238. break;
  239. default:
  240. #ifdef _WIN32
  241. if (_snprintf(addr_buf, INET6_ADDRSTRLEN, "Unknown family %d", spc->spc_aaddr.ss_family) < 0) {
  242. #else
  243. if (snprintf(addr_buf, INET6_ADDRSTRLEN, "Unknown family %d", spc->spc_aaddr.ss_family) < 0) {
  244. #endif
  245. addr_buf[0] = '\0';
  246. }
  247. addr = addr_buf;
  248. break;
  249. }
  250. fprintf(debug_target, "Peer address %s is now ", addr);
  251. switch (spc->spc_state) {
  252. case SCTP_ADDR_AVAILABLE:
  253. fprintf(debug_target, "SCTP_ADDR_AVAILABLE");
  254. break;
  255. case SCTP_ADDR_UNREACHABLE:
  256. fprintf(debug_target, "SCTP_ADDR_UNREACHABLE");
  257. break;
  258. case SCTP_ADDR_REMOVED:
  259. fprintf(debug_target, "SCTP_ADDR_REMOVED");
  260. break;
  261. case SCTP_ADDR_ADDED:
  262. fprintf(debug_target, "SCTP_ADDR_ADDED");
  263. break;
  264. case SCTP_ADDR_MADE_PRIM:
  265. fprintf(debug_target, "SCTP_ADDR_MADE_PRIM");
  266. break;
  267. case SCTP_ADDR_CONFIRMED:
  268. fprintf(debug_target, "SCTP_ADDR_CONFIRMED");
  269. break;
  270. default:
  271. fprintf(debug_target, "UNKNOWN");
  272. break;
  273. }
  274. fprintf(debug_target, " (error = 0x%08x).\n", spc->spc_error);
  275. return;
  276. }
  277. static void
  278. handle_send_failed_event(struct sctp_send_failed_event *ssfe)
  279. {
  280. size_t i, n;
  281. if (debug_target == NULL) {
  282. debug_target = DEFAULT_TARGET;
  283. }
  284. if (ssfe->ssfe_flags & SCTP_DATA_UNSENT) {
  285. fprintf(debug_target, "Unsent ");
  286. }
  287. if (ssfe->ssfe_flags & SCTP_DATA_SENT) {
  288. fprintf(debug_target, "Sent ");
  289. }
  290. if (ssfe->ssfe_flags & ~(SCTP_DATA_SENT | SCTP_DATA_UNSENT)) {
  291. fprintf(debug_target, "(flags = %x) ", ssfe->ssfe_flags);
  292. }
  293. fprintf(debug_target, "message with PPID = %u, SID = %u, flags: 0x%04x due to error = 0x%08x",
  294. (uint32_t)ntohl(ssfe->ssfe_info.snd_ppid), ssfe->ssfe_info.snd_sid,
  295. ssfe->ssfe_info.snd_flags, ssfe->ssfe_error);
  296. n = ssfe->ssfe_length - sizeof(struct sctp_send_failed_event);
  297. for (i = 0; i < n; i++) {
  298. fprintf(debug_target, " 0x%02x", ssfe->ssfe_data[i]);
  299. }
  300. fprintf(debug_target, ".\n");
  301. return;
  302. }
  303. static void
  304. handle_adaptation_indication(struct sctp_adaptation_event *sai)
  305. {
  306. if (debug_target == NULL) {
  307. debug_target = DEFAULT_TARGET;
  308. }
  309. fprintf(debug_target, "Adaptation indication: %x.\n", sai-> sai_adaptation_ind);
  310. return;
  311. }
  312. static void
  313. handle_shutdown_event(struct sctp_shutdown_event *sse)
  314. {
  315. if (debug_target == NULL) {
  316. debug_target = DEFAULT_TARGET;
  317. }
  318. fprintf(debug_target, "Shutdown event.\n");
  319. /* XXX: notify all channels. */
  320. return;
  321. }
  322. static void
  323. handle_stream_reset_event(struct sctp_stream_reset_event *strrst)
  324. {
  325. uint32_t n, i;
  326. if (debug_target == NULL) {
  327. debug_target = DEFAULT_TARGET;
  328. }
  329. n = (strrst->strreset_length - sizeof(struct sctp_stream_reset_event)) / sizeof(uint16_t);
  330. fprintf(debug_target, "Stream reset event: flags = %x, ", strrst->strreset_flags);
  331. if (strrst->strreset_flags & SCTP_STREAM_RESET_INCOMING_SSN) {
  332. if (strrst->strreset_flags & SCTP_STREAM_RESET_OUTGOING_SSN) {
  333. fprintf(debug_target, "incoming/");
  334. }
  335. fprintf(debug_target, "incoming ");
  336. }
  337. if (strrst->strreset_flags & SCTP_STREAM_RESET_OUTGOING_SSN) {
  338. fprintf(debug_target, "outgoing ");
  339. }
  340. fprintf(debug_target, "stream ids = ");
  341. for (i = 0; i < n; i++) {
  342. if (i > 0) {
  343. fprintf(debug_target, ", ");
  344. }
  345. fprintf(debug_target, "%d", strrst->strreset_stream_list[i]);
  346. }
  347. fprintf(debug_target, ".\n");
  348. return;
  349. }
  350. static void
  351. handle_stream_change_event(struct sctp_stream_change_event *strchg)
  352. {
  353. if (debug_target == NULL) {
  354. debug_target = DEFAULT_TARGET;
  355. }
  356. fprintf(debug_target, "Stream change event: streams (in/out) = (%u/%u), flags = %x.\n",
  357. strchg->strchange_instrms, strchg->strchange_outstrms, strchg->strchange_flags);
  358. return;
  359. }
  360. static void
  361. handle_remote_error_event(struct sctp_remote_error *sre)
  362. {
  363. size_t i, n;
  364. if (debug_target == NULL) {
  365. debug_target = DEFAULT_TARGET;
  366. }
  367. n = sre->sre_length - sizeof(struct sctp_remote_error);
  368. fprintf(debug_target, "Remote Error (error = 0x%04x): ", sre->sre_error);
  369. for (i = 0; i < n; i++) {
  370. fprintf(debug_target, " 0x%02x", sre-> sre_data[i]);
  371. }
  372. fprintf(debug_target, ".\n");
  373. return;
  374. }
  375. void
  376. handle_notification(union sctp_notification *notif, size_t n)
  377. {
  378. if (notif->sn_header.sn_length != (uint32_t)n) {
  379. return;
  380. }
  381. if (debug_target == NULL) {
  382. debug_target = DEFAULT_TARGET;
  383. }
  384. fprintf(debug_target, "handle_notification : ");
  385. switch (notif->sn_header.sn_type) {
  386. case SCTP_ASSOC_CHANGE:
  387. fprintf(debug_target, "SCTP_ASSOC_CHANGE\n");
  388. handle_association_change_event(&(notif->sn_assoc_change));
  389. break;
  390. case SCTP_PEER_ADDR_CHANGE:
  391. fprintf(debug_target, "SCTP_PEER_ADDR_CHANGE\n");
  392. handle_peer_address_change_event(&(notif->sn_paddr_change));
  393. break;
  394. case SCTP_REMOTE_ERROR:
  395. fprintf(debug_target, "SCTP_REMOTE_ERROR\n");
  396. handle_remote_error_event(&(notif->sn_remote_error));
  397. break;
  398. case SCTP_SHUTDOWN_EVENT:
  399. fprintf(debug_target, "SCTP_SHUTDOWN_EVENT\n");
  400. handle_shutdown_event(&(notif->sn_shutdown_event));
  401. break;
  402. case SCTP_ADAPTATION_INDICATION:
  403. fprintf(debug_target, "SCTP_ADAPTATION_INDICATION\n");
  404. handle_adaptation_indication(&(notif->sn_adaptation_event));
  405. break;
  406. case SCTP_PARTIAL_DELIVERY_EVENT:
  407. fprintf(debug_target, "SCTP_PARTIAL_DELIVERY_EVENT\n");
  408. break;
  409. case SCTP_AUTHENTICATION_EVENT:
  410. fprintf(debug_target, "SCTP_AUTHENTICATION_EVENT\n");
  411. break;
  412. case SCTP_SENDER_DRY_EVENT:
  413. fprintf(debug_target, "SCTP_SENDER_DRY_EVENT\n");
  414. break;
  415. case SCTP_NOTIFICATIONS_STOPPED_EVENT:
  416. fprintf(debug_target, "SCTP_NOTIFICATIONS_STOPPED_EVENT\n");
  417. break;
  418. case SCTP_SEND_FAILED_EVENT:
  419. fprintf(debug_target, "SCTP_SEND_FAILED_EVENT\n");
  420. handle_send_failed_event(&(notif->sn_send_failed_event));
  421. break;
  422. case SCTP_STREAM_RESET_EVENT:
  423. fprintf(debug_target, "SCTP_STREAM_RESET_EVENT\n");
  424. handle_stream_reset_event(&(notif->sn_strreset_event));
  425. break;
  426. case SCTP_ASSOC_RESET_EVENT:
  427. fprintf(debug_target, "SCTP_ASSOC_RESET_EVENT\n");
  428. break;
  429. case SCTP_STREAM_CHANGE_EVENT:
  430. fprintf(debug_target, "SCTP_STREAM_CHANGE_EVENT\n");
  431. handle_stream_change_event(&(notif->sn_strchange_event));
  432. break;
  433. default:
  434. break;
  435. }
  436. }