sctp_hello.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. static void set_addr(struct sockaddr_storage *ss, char *ip, char *port, int *len)
  10. {
  11. if (ss->ss_family == AF_INET) {
  12. struct sockaddr_in *a = (struct sockaddr_in *)ss;
  13. a->sin_addr.s_addr = inet_addr(ip);
  14. a->sin_port = htons(atoi(port));
  15. *len = sizeof(*a);
  16. } else {
  17. struct sockaddr_in6 *a = (struct sockaddr_in6 *)ss;
  18. a->sin6_family = AF_INET6;
  19. inet_pton(AF_INET6, ip, &a->sin6_addr);
  20. a->sin6_port = htons(atoi(port));
  21. *len = sizeof(*a);
  22. }
  23. }
  24. static int do_client(int argc, char *argv[])
  25. {
  26. struct sockaddr_storage ss;
  27. int csk, ret, len;
  28. if (argc < 5) {
  29. printf("%s client -4|6 IP PORT [IP PORT]\n", argv[0]);
  30. return -1;
  31. }
  32. bzero((void *)&ss, sizeof(ss));
  33. ss.ss_family = !strcmp(argv[2], "-4") ? AF_INET : AF_INET6;
  34. csk = socket(ss.ss_family, SOCK_STREAM, IPPROTO_SCTP);
  35. if (csk < 0) {
  36. printf("failed to create socket\n");
  37. return -1;
  38. }
  39. if (argc >= 7) {
  40. set_addr(&ss, argv[5], argv[6], &len);
  41. ret = bind(csk, (struct sockaddr *)&ss, len);
  42. if (ret < 0) {
  43. printf("failed to bind to address\n");
  44. return -1;
  45. }
  46. }
  47. set_addr(&ss, argv[3], argv[4], &len);
  48. ret = connect(csk, (struct sockaddr *)&ss, len);
  49. if (ret < 0)
  50. return -1;
  51. recv(csk, NULL, 0, 0);
  52. close(csk);
  53. return 0;
  54. }
  55. int main(int argc, char *argv[])
  56. {
  57. struct sockaddr_storage ss;
  58. int lsk, csk, ret, len;
  59. if (argc < 2 || (strcmp(argv[1], "server") && strcmp(argv[1], "client"))) {
  60. printf("%s server|client ...\n", argv[0]);
  61. return -1;
  62. }
  63. if (!strcmp(argv[1], "client"))
  64. return do_client(argc, argv);
  65. if (argc < 5) {
  66. printf("%s server -4|6 IP PORT [IFACE]\n", argv[0]);
  67. return -1;
  68. }
  69. ss.ss_family = !strcmp(argv[2], "-4") ? AF_INET : AF_INET6;
  70. lsk = socket(ss.ss_family, SOCK_STREAM, IPPROTO_SCTP);
  71. if (lsk < 0) {
  72. printf("failed to create lsk\n");
  73. return -1;
  74. }
  75. if (argc >= 6) {
  76. ret = setsockopt(lsk, SOL_SOCKET, SO_BINDTODEVICE,
  77. argv[5], strlen(argv[5]) + 1);
  78. if (ret < 0) {
  79. printf("failed to bind to device\n");
  80. return -1;
  81. }
  82. }
  83. set_addr(&ss, argv[3], argv[4], &len);
  84. ret = bind(lsk, (struct sockaddr *)&ss, len);
  85. if (ret < 0) {
  86. printf("failed to bind to address\n");
  87. return -1;
  88. }
  89. ret = listen(lsk, 5);
  90. if (ret < 0) {
  91. printf("failed to listen on port\n");
  92. return -1;
  93. }
  94. csk = accept(lsk, (struct sockaddr *)NULL, (socklen_t *)NULL);
  95. if (csk < 0) {
  96. printf("failed to accept new client\n");
  97. return -1;
  98. }
  99. close(csk);
  100. close(lsk);
  101. return 0;
  102. }