brintos

brintos / linux-shallow public Read only

0
0
Text · 2.8 KiB · f02f1f9 Raw
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