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