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