138 lines · c
1// SPDX-License-Identifier: GPL-2.02 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 11static 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 29static 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 74int 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