1135446Strhodes// SPDX-License-Identifier: GPL-2.0
2174187Sdougb#include <stdio.h>
3135446Strhodes#include <errno.h>
4135446Strhodes#include <unistd.h>
5174187Sdougb#include <string.h>
6135446Strhodes#include <sys/types.h>
7135446Strhodes#include <sys/socket.h>
8135446Strhodes#include <netinet/in.h>
9135446Strhodes
10135446Strhodes#include "../kselftest.h"
11135446Strhodes
12135446Strhodesstruct socket_testcase {
13135446Strhodes	int	domain;
14135446Strhodes	int	type;
15135446Strhodes	int	protocol;
16135446Strhodes
17135446Strhodes	/* 0    = valid file descriptor
18180477Sdougb	 * -foo = error foo
19135446Strhodes	 */
20170222Sdougb	int	expect;
21170222Sdougb
22135446Strhodes	/* If non-zero, accept EAFNOSUPPORT to handle the case
23135446Strhodes	 * of the protocol not being configured into the kernel.
24135446Strhodes	 */
25135446Strhodes	int	nosupport_ok;
26135446Strhodes};
27135446Strhodes
28135446Strhodesstatic struct socket_testcase tests[] = {
29135446Strhodes	{ AF_MAX,  0,           0,           -EAFNOSUPPORT,    0 },
30135446Strhodes	{ AF_INET, SOCK_STREAM, IPPROTO_TCP, 0,                1  },
31135446Strhodes	{ AF_INET, SOCK_DGRAM,  IPPROTO_TCP, -EPROTONOSUPPORT, 1  },
32135446Strhodes	{ AF_INET, SOCK_DGRAM,  IPPROTO_UDP, 0,                1  },
33135446Strhodes	{ AF_INET, SOCK_STREAM, IPPROTO_UDP, -EPROTONOSUPPORT, 1  },
34135446Strhodes};
35135446Strhodes
36135446Strhodes#define ERR_STRING_SZ	64
37135446Strhodes
38135446Strhodesstatic int run_tests(void)
39135446Strhodes{
40135446Strhodes	char err_string1[ERR_STRING_SZ];
41135446Strhodes	char err_string2[ERR_STRING_SZ];
42135446Strhodes	int i, err;
43135446Strhodes
44135446Strhodes	err = 0;
45135446Strhodes	for (i = 0; i < ARRAY_SIZE(tests); i++) {
46170222Sdougb		struct socket_testcase *s = &tests[i];
47135446Strhodes		int fd;
48135446Strhodes
49135446Strhodes		fd = socket(s->domain, s->type, s->protocol);
50135446Strhodes		if (fd < 0) {
51170222Sdougb			if (s->nosupport_ok &&
52170222Sdougb			    errno == EAFNOSUPPORT)
53170222Sdougb				continue;
54135446Strhodes
55135446Strhodes			if (s->expect < 0 &&
56135446Strhodes			    errno == -s->expect)
57170222Sdougb				continue;
58135446Strhodes
59135446Strhodes			strerror_r(-s->expect, err_string1, ERR_STRING_SZ);
60135446Strhodes			strerror_r(errno, err_string2, ERR_STRING_SZ);
61135446Strhodes
62135446Strhodes			fprintf(stderr, "socket(%d, %d, %d) expected "
63135446Strhodes				"err (%s) got (%s)\n",
64135446Strhodes				s->domain, s->type, s->protocol,
65135446Strhodes				err_string1, err_string2);
66135446Strhodes
67135446Strhodes			err = -1;
68135446Strhodes			break;
69135446Strhodes		} else {
70135446Strhodes			close(fd);
71135446Strhodes
72135446Strhodes			if (s->expect < 0) {
73135446Strhodes				strerror_r(errno, err_string1, ERR_STRING_SZ);
74135446Strhodes
75135446Strhodes				fprintf(stderr, "socket(%d, %d, %d) expected "
76135446Strhodes					"success got err (%s)\n",
77135446Strhodes					s->domain, s->type, s->protocol,
78135446Strhodes					err_string1);
79135446Strhodes
80135446Strhodes				err = -1;
81135446Strhodes				break;
82135446Strhodes			}
83135446Strhodes		}
84135446Strhodes	}
85135446Strhodes
86135446Strhodes	return err;
87135446Strhodes}
88135446Strhodes
89135446Strhodesint main(void)
90135446Strhodes{
91153816Sdougb	int err = run_tests();
92153816Sdougb
93153816Sdougb	return err;
94153816Sdougb}
95135446Strhodes