linux-stable/tools/testing/selftests/net/sctp_hello.c
Xin Long a61bd7b9fe selftests: add a selftest for sctp vrf
This patch adds 12 small test cases: 01-04 test for the sysctl
net.sctp.l3mdev_accept. 05-10 test for only binding to a right
l3mdev device, the connection can be created. 11-12 test for
two socks binding to different l3mdev devices at the same time,
each of them can process the packets from the corresponding
peer. The tests run for both IPv4 and IPv6 SCTP.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2022-11-18 11:42:54 +00:00

137 lines
2.8 KiB
C

// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
static void set_addr(struct sockaddr_storage *ss, char *ip, char *port, int *len)
{
if (ss->ss_family == AF_INET) {
struct sockaddr_in *a = (struct sockaddr_in *)ss;
a->sin_addr.s_addr = inet_addr(ip);
a->sin_port = htons(atoi(port));
*len = sizeof(*a);
} else {
struct sockaddr_in6 *a = (struct sockaddr_in6 *)ss;
a->sin6_family = AF_INET6;
inet_pton(AF_INET6, ip, &a->sin6_addr);
a->sin6_port = htons(atoi(port));
*len = sizeof(*a);
}
}
static int do_client(int argc, char *argv[])
{
struct sockaddr_storage ss;
char buf[] = "hello";
int csk, ret, len;
if (argc < 5) {
printf("%s client -4|6 IP PORT [IP PORT]\n", argv[0]);
return -1;
}
bzero((void *)&ss, sizeof(ss));
ss.ss_family = !strcmp(argv[2], "-4") ? AF_INET : AF_INET6;
csk = socket(ss.ss_family, SOCK_STREAM, IPPROTO_SCTP);
if (csk < 0) {
printf("failed to create socket\n");
return -1;
}
if (argc >= 7) {
set_addr(&ss, argv[5], argv[6], &len);
ret = bind(csk, (struct sockaddr *)&ss, len);
if (ret < 0) {
printf("failed to bind to address\n");
return -1;
}
}
set_addr(&ss, argv[3], argv[4], &len);
ret = connect(csk, (struct sockaddr *)&ss, len);
if (ret < 0) {
printf("failed to connect to peer\n");
return -1;
}
ret = send(csk, buf, strlen(buf) + 1, 0);
if (ret < 0) {
printf("failed to send msg %d\n", ret);
return -1;
}
close(csk);
return 0;
}
int main(int argc, char *argv[])
{
struct sockaddr_storage ss;
int lsk, csk, ret, len;
char buf[20];
if (argc < 2 || (strcmp(argv[1], "server") && strcmp(argv[1], "client"))) {
printf("%s server|client ...\n", argv[0]);
return -1;
}
if (!strcmp(argv[1], "client"))
return do_client(argc, argv);
if (argc < 5) {
printf("%s server -4|6 IP PORT [IFACE]\n", argv[0]);
return -1;
}
ss.ss_family = !strcmp(argv[2], "-4") ? AF_INET : AF_INET6;
lsk = socket(ss.ss_family, SOCK_STREAM, IPPROTO_SCTP);
if (lsk < 0) {
printf("failed to create lsk\n");
return -1;
}
if (argc >= 6) {
ret = setsockopt(lsk, SOL_SOCKET, SO_BINDTODEVICE,
argv[5], strlen(argv[5]) + 1);
if (ret < 0) {
printf("failed to bind to device\n");
return -1;
}
}
set_addr(&ss, argv[3], argv[4], &len);
ret = bind(lsk, (struct sockaddr *)&ss, len);
if (ret < 0) {
printf("failed to bind to address\n");
return -1;
}
ret = listen(lsk, 5);
if (ret < 0) {
printf("failed to listen on port\n");
return -1;
}
csk = accept(lsk, (struct sockaddr *)NULL, (socklen_t *)NULL);
if (csk < 0) {
printf("failed to accept new client\n");
return -1;
}
ret = recv(csk, buf, sizeof(buf), 0);
if (ret <= 0) {
printf("failed to recv msg %d\n", ret);
return -1;
}
close(csk);
close(lsk);
return 0;
}