xref: /netbsd-src/tests/net/inpcb/broadcast_bind.c (revision eedb766f768f680d2141fa76dc9464cc9ad7c3c3)
1*eedb766fSozaki-r /* $NetBSD: broadcast_bind.c,v 1.2 2022/11/17 08:42:06 ozaki-r Exp $ */
2a86cd60eSozaki-r /* $OpenBSD: broadcast_bind.c,v 1.2 2015/12/02 20:45:00 mpi Exp $ */
3a86cd60eSozaki-r 
4a86cd60eSozaki-r /*
5a86cd60eSozaki-r  * Copyright (c) 2015 Vincent Gross <vgross@openbsd.org>
6a86cd60eSozaki-r  *
7a86cd60eSozaki-r  * Permission to use, copy, modify, and distribute this software for any
8a86cd60eSozaki-r  * purpose with or without fee is hereby granted, provided that the above
9a86cd60eSozaki-r  * copyright notice and this permission notice appear in all copies.
10a86cd60eSozaki-r  *
11a86cd60eSozaki-r  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12a86cd60eSozaki-r  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13a86cd60eSozaki-r  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14a86cd60eSozaki-r  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15a86cd60eSozaki-r  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16a86cd60eSozaki-r  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17a86cd60eSozaki-r  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18a86cd60eSozaki-r  */
19a86cd60eSozaki-r 
20a86cd60eSozaki-r #include <err.h>
21a86cd60eSozaki-r #include <errno.h>
22a86cd60eSozaki-r #include <stdio.h>
23a86cd60eSozaki-r #include <unistd.h>
24a86cd60eSozaki-r #include <stdlib.h>
25a86cd60eSozaki-r #include <string.h>
26a86cd60eSozaki-r 
27a86cd60eSozaki-r #include <arpa/inet.h>
28a86cd60eSozaki-r 
29a86cd60eSozaki-r #include <sys/socket.h>
30a86cd60eSozaki-r 
31a86cd60eSozaki-r #include <netinet/in.h>
32a86cd60eSozaki-r 
33a86cd60eSozaki-r 
34*eedb766fSozaki-r static int
test_bind(char * paddr,struct in_addr * addr,u_int16_t port,int type,int expected_errno)35a86cd60eSozaki-r test_bind(char *paddr, struct in_addr *addr, u_int16_t port, int type,
36a86cd60eSozaki-r     int expected_errno)
37a86cd60eSozaki-r {
38a86cd60eSozaki-r 	int s, rc;
39a86cd60eSozaki-r 	struct sockaddr_in sin;
40a86cd60eSozaki-r 
41a86cd60eSozaki-r 	memset(&sin, 0, sizeof(sin));
42a86cd60eSozaki-r 	sin.sin_family = AF_INET;
43a86cd60eSozaki-r 	sin.sin_len = sizeof(sin);
44a86cd60eSozaki-r 	sin.sin_port = htons(port);
45a86cd60eSozaki-r 	memcpy(&sin.sin_addr, addr, sizeof(*addr));
46a86cd60eSozaki-r 
47a86cd60eSozaki-r 	s = socket(PF_INET, type, 0);
48a86cd60eSozaki-r 	if (s < 0) {
49a86cd60eSozaki-r 		warn("socket(PF_INET, %d, 0)", type);
50a86cd60eSozaki-r 		return (1);
51a86cd60eSozaki-r 	}
52a86cd60eSozaki-r 
53a86cd60eSozaki-r 	rc = bind(s, (struct sockaddr *)&sin, sin.sin_len);
54a86cd60eSozaki-r 	if ((rc == 0 && expected_errno == 0) ||
55a86cd60eSozaki-r 	    (rc != 0 && expected_errno == errno)) {
56a86cd60eSozaki-r 		close(s);
57a86cd60eSozaki-r 		return (0);
58a86cd60eSozaki-r 	}
59a86cd60eSozaki-r 
60a86cd60eSozaki-r 	warn("bind(%s,%d) (type %d) expected %d, got %d", paddr, port, type,
61a86cd60eSozaki-r 	    expected_errno, errno);
62a86cd60eSozaki-r 	close(s);
63a86cd60eSozaki-r 
64a86cd60eSozaki-r 	return (1);
65a86cd60eSozaki-r }
66a86cd60eSozaki-r 
67a86cd60eSozaki-r int
main(int argc,char * argv[])68a86cd60eSozaki-r main(int argc, char *argv[])
69a86cd60eSozaki-r {
70a86cd60eSozaki-r 	int rc;
71a86cd60eSozaki-r 	struct in_addr uc_addr, err_addr, bc_addr;
72a86cd60eSozaki-r 	int port = 30000;
73a86cd60eSozaki-r 
74a86cd60eSozaki-r 	if (argc != 4)
75a86cd60eSozaki-r 		errx(1, "needs 2 arguments: <unicast> <error> <broadcast>");
76a86cd60eSozaki-r 
77a86cd60eSozaki-r 	rc = inet_pton(AF_INET, argv[1], &uc_addr);
78a86cd60eSozaki-r 	if (rc != 1) {
79a86cd60eSozaki-r 		if (rc)
80a86cd60eSozaki-r 			err(1, "inet_pton(unicast)");
81a86cd60eSozaki-r 		else
82a86cd60eSozaki-r 			errx(1, "inet_pton(unicast): error parsing %s",
83a86cd60eSozaki-r 			    argv[1]);
84a86cd60eSozaki-r 	}
85a86cd60eSozaki-r 	rc = inet_pton(AF_INET, argv[2], &err_addr);
86a86cd60eSozaki-r 	if (rc != 1) {
87a86cd60eSozaki-r 		if (rc)
88a86cd60eSozaki-r 			err(1, "inet_pton(error)");
89a86cd60eSozaki-r 		else
90a86cd60eSozaki-r 			errx(1, "inet_pton(error): error parsing %s", argv[2]);
91a86cd60eSozaki-r 	}
92a86cd60eSozaki-r 	rc = inet_pton(AF_INET, argv[3], &bc_addr);
93a86cd60eSozaki-r 	if (rc != 1) {
94a86cd60eSozaki-r 		if (rc)
95a86cd60eSozaki-r 			err(1, "inet_pton(broadcast)");
96a86cd60eSozaki-r 		else
97a86cd60eSozaki-r 			errx(1, "inet_pton(broadcast): error parsing %s",
98a86cd60eSozaki-r 			    argv[3]);
99a86cd60eSozaki-r 	}
100a86cd60eSozaki-r 
101a86cd60eSozaki-r 	rc = 0;
102a86cd60eSozaki-r 	rc |= test_bind(argv[1], &uc_addr, port, SOCK_STREAM, 0);
103a86cd60eSozaki-r 	rc |= test_bind(argv[2], &err_addr, port, SOCK_STREAM, EADDRNOTAVAIL);
104*eedb766fSozaki-r #ifdef __NetBSD__
105*eedb766fSozaki-r 	rc |= test_bind(argv[3], &bc_addr, port, SOCK_STREAM, 0);
106*eedb766fSozaki-r #else
107a86cd60eSozaki-r 	rc |= test_bind(argv[3], &bc_addr, port, SOCK_STREAM, EADDRNOTAVAIL);
108*eedb766fSozaki-r #endif
109a86cd60eSozaki-r 
110a86cd60eSozaki-r 	rc |= test_bind(argv[2], &err_addr, port, SOCK_STREAM, EADDRNOTAVAIL);
111a86cd60eSozaki-r 	rc |= test_bind(argv[3], &bc_addr, port, SOCK_DGRAM, 0);
112a86cd60eSozaki-r 
113a86cd60eSozaki-r 	return (rc);
114a86cd60eSozaki-r }
115