client.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * Copyright (C) 2011-2013 Michael Tuexen
  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. * 3. Neither the name of the project nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. */
  30. /*
  31. * Usage: client remote_addr remote_port [local_port] [local_encaps_port] [remote_encaps_port]
  32. */
  33. #ifdef _WIN32
  34. #define _CRT_SECURE_NO_WARNINGS
  35. #endif
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <stdarg.h>
  40. #ifndef _WIN32
  41. #include <unistd.h>
  42. #endif
  43. #include <sys/types.h>
  44. #ifndef _WIN32
  45. #include <sys/socket.h>
  46. #include <netinet/in.h>
  47. #include <arpa/inet.h>
  48. #else
  49. #include <io.h>
  50. #endif
  51. #include <usrsctp.h>
  52. #include "programs_helper.h"
  53. int done = 0;
  54. #ifdef _WIN32
  55. typedef char* caddr_t;
  56. #endif
  57. static int
  58. receive_cb(struct socket *sock, union sctp_sockstore addr, void *data,
  59. size_t datalen, struct sctp_rcvinfo rcv, int flags, void *ulp_info)
  60. {
  61. if (data == NULL) {
  62. done = 1;
  63. usrsctp_close(sock);
  64. } else {
  65. if (flags & MSG_NOTIFICATION) {
  66. handle_notification((union sctp_notification *)data, datalen);
  67. } else {
  68. #ifdef _WIN32
  69. _write(_fileno(stdout), data, (unsigned int)datalen);
  70. #else
  71. if (write(fileno(stdout), data, datalen) < 0) {
  72. perror("write");
  73. }
  74. #endif
  75. }
  76. free(data);
  77. }
  78. return (1);
  79. }
  80. int
  81. main(int argc, char *argv[])
  82. {
  83. struct socket *sock;
  84. struct sockaddr *addr, *addrs;
  85. struct sockaddr_in addr4;
  86. struct sockaddr_in6 addr6;
  87. struct sctp_udpencaps encaps;
  88. struct sctpstat stat;
  89. struct sctp_event event;
  90. uint16_t event_types[] = {SCTP_ASSOC_CHANGE,
  91. SCTP_PEER_ADDR_CHANGE,
  92. SCTP_SEND_FAILED_EVENT};
  93. char buffer[80];
  94. unsigned int i;
  95. int n;
  96. if (argc < 3) {
  97. printf("%s", "Usage: client remote_addr remote_port local_port local_encaps_port remote_encaps_port\n");
  98. return (-1);
  99. }
  100. if (argc > 4) {
  101. usrsctp_init(atoi(argv[4]), NULL, debug_printf_stack);
  102. } else {
  103. usrsctp_init(9899, NULL, debug_printf_stack);
  104. }
  105. #ifdef SCTP_DEBUG
  106. usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_NONE);
  107. #endif
  108. usrsctp_sysctl_set_sctp_blackhole(2);
  109. usrsctp_sysctl_set_sctp_no_csum_on_loopback(0);
  110. if ((sock = usrsctp_socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, NULL)) == NULL) {
  111. perror("usrsctp_socket");
  112. }
  113. memset(&event, 0, sizeof(event));
  114. event.se_assoc_id = SCTP_ALL_ASSOC;
  115. event.se_on = 1;
  116. for (i = 0; i < sizeof(event_types)/sizeof(uint16_t); i++) {
  117. event.se_type = event_types[i];
  118. if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event)) < 0) {
  119. perror("setsockopt SCTP_EVENT");
  120. }
  121. }
  122. if (argc > 3) {
  123. memset((void *)&addr6, 0, sizeof(struct sockaddr_in6));
  124. #ifdef HAVE_SIN6_LEN
  125. addr6.sin6_len = sizeof(struct sockaddr_in6);
  126. #endif
  127. addr6.sin6_family = AF_INET6;
  128. addr6.sin6_port = htons(atoi(argv[3]));
  129. addr6.sin6_addr = in6addr_any;
  130. if (usrsctp_bind(sock, (struct sockaddr *)&addr6, sizeof(struct sockaddr_in6)) < 0) {
  131. perror("bind");
  132. }
  133. }
  134. if (argc > 5) {
  135. memset(&encaps, 0, sizeof(struct sctp_udpencaps));
  136. encaps.sue_address.ss_family = AF_INET6;
  137. encaps.sue_port = htons(atoi(argv[5]));
  138. if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_REMOTE_UDP_ENCAPS_PORT, (const void*)&encaps, (socklen_t)sizeof(struct sctp_udpencaps)) < 0) {
  139. perror("setsockopt");
  140. }
  141. }
  142. memset((void *)&addr4, 0, sizeof(struct sockaddr_in));
  143. memset((void *)&addr6, 0, sizeof(struct sockaddr_in6));
  144. #ifdef HAVE_SIN_LEN
  145. addr4.sin_len = sizeof(struct sockaddr_in);
  146. #endif
  147. #ifdef HAVE_SIN6_LEN
  148. addr6.sin6_len = sizeof(struct sockaddr_in6);
  149. #endif
  150. addr4.sin_family = AF_INET;
  151. addr6.sin6_family = AF_INET6;
  152. addr4.sin_port = htons(atoi(argv[2]));
  153. addr6.sin6_port = htons(atoi(argv[2]));
  154. if (inet_pton(AF_INET6, argv[1], &addr6.sin6_addr) == 1) {
  155. if (usrsctp_connect(sock, (struct sockaddr *)&addr6, sizeof(struct sockaddr_in6)) < 0) {
  156. perror("usrsctp_connect");
  157. }
  158. } else if (inet_pton(AF_INET, argv[1], &addr4.sin_addr) == 1) {
  159. if (usrsctp_connect(sock, (struct sockaddr *)&addr4, sizeof(struct sockaddr_in)) < 0) {
  160. perror("usrsctp_connect");
  161. }
  162. } else {
  163. printf("Illegal destination address.\n");
  164. }
  165. if ((n = usrsctp_getladdrs(sock, 0, &addrs)) < 0) {
  166. perror("usrsctp_getladdrs");
  167. } else {
  168. addr = addrs;
  169. printf("Local addresses: ");
  170. for (i = 0; i < (unsigned int)n; i++) {
  171. if (i > 0) {
  172. printf("%s", ", ");
  173. }
  174. switch (addr->sa_family) {
  175. case AF_INET:
  176. {
  177. struct sockaddr_in *sin;
  178. char buf[INET_ADDRSTRLEN];
  179. const char *name;
  180. sin = (struct sockaddr_in *)addr;
  181. name = inet_ntop(AF_INET, &sin->sin_addr, buf, INET_ADDRSTRLEN);
  182. printf("%s", name);
  183. #ifndef HAVE_SA_LEN
  184. addr = (struct sockaddr *)((caddr_t)addr + sizeof(struct sockaddr_in));
  185. #endif
  186. break;
  187. }
  188. case AF_INET6:
  189. {
  190. struct sockaddr_in6 *sin6;
  191. char buf[INET6_ADDRSTRLEN];
  192. const char *name;
  193. sin6 = (struct sockaddr_in6 *)addr;
  194. name = inet_ntop(AF_INET6, &sin6->sin6_addr, buf, INET6_ADDRSTRLEN);
  195. printf("%s", name);
  196. #ifndef HAVE_SA_LEN
  197. addr = (struct sockaddr *)((caddr_t)addr + sizeof(struct sockaddr_in6));
  198. #endif
  199. break;
  200. }
  201. default:
  202. break;
  203. }
  204. #ifdef HAVE_SA_LEN
  205. addr = (struct sockaddr *)((caddr_t)addr + addr->sa_len);
  206. #endif
  207. }
  208. printf(".\n");
  209. usrsctp_freeladdrs(addrs);
  210. }
  211. if ((n = usrsctp_getpaddrs(sock, 0, &addrs)) < 0) {
  212. perror("usrsctp_getpaddrs");
  213. } else {
  214. addr = addrs;
  215. printf("Peer addresses: ");
  216. for (i = 0; i < (unsigned int)n; i++) {
  217. if (i > 0) {
  218. printf("%s", ", ");
  219. }
  220. switch (addr->sa_family) {
  221. case AF_INET:
  222. {
  223. struct sockaddr_in *sin;
  224. char buf[INET_ADDRSTRLEN];
  225. const char *name;
  226. sin = (struct sockaddr_in *)addr;
  227. name = inet_ntop(AF_INET, &sin->sin_addr, buf, INET_ADDRSTRLEN);
  228. printf("%s", name);
  229. #ifndef HAVE_SA_LEN
  230. addr = (struct sockaddr *)((caddr_t)addr + sizeof(struct sockaddr_in));
  231. #endif
  232. break;
  233. }
  234. case AF_INET6:
  235. {
  236. struct sockaddr_in6 *sin6;
  237. char buf[INET6_ADDRSTRLEN];
  238. const char *name;
  239. sin6 = (struct sockaddr_in6 *)addr;
  240. name = inet_ntop(AF_INET6, &sin6->sin6_addr, buf, INET6_ADDRSTRLEN);
  241. printf("%s", name);
  242. #ifndef HAVE_SA_LEN
  243. addr = (struct sockaddr *)((caddr_t)addr + sizeof(struct sockaddr_in6));
  244. #endif
  245. break;
  246. }
  247. default:
  248. break;
  249. }
  250. #ifdef HAVE_SA_LEN
  251. addr = (struct sockaddr *)((caddr_t)addr + addr->sa_len);
  252. #endif
  253. }
  254. printf(".\n");
  255. usrsctp_freepaddrs(addrs);
  256. }
  257. while ((fgets(buffer, sizeof(buffer), stdin) != NULL) && !done) {
  258. usrsctp_sendv(sock, buffer, strlen(buffer), NULL, 0, NULL, 0, SCTP_SENDV_NOINFO, 0);
  259. }
  260. if (!done) {
  261. if (usrsctp_shutdown(sock, SHUT_WR) < 0) {
  262. perror("usrsctp_shutdown");
  263. }
  264. }
  265. while (!done) {
  266. #ifdef _WIN32
  267. Sleep(1 * 1000);
  268. #else
  269. sleep(1);
  270. #endif
  271. }
  272. usrsctp_get_stat(&stat);
  273. printf("Number of packets (sent/received): (%u/%u).\n",
  274. stat.sctps_outpackets, stat.sctps_inpackets);
  275. while (usrsctp_finish() != 0) {
  276. #ifdef _WIN32
  277. Sleep(1 * 1000);
  278. #else
  279. sleep(1);
  280. #endif
  281. }
  282. return(0);
  283. }