1 #include <sys/types.h> 2 #include <sys/socket.h> 3 4 #include <arpa/inet.h> 5 #include <netinet/in.h> 6 7 #include <err.h> 8 #include <errno.h> 9 #include <stdio.h> 10 #include <stdint.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <unistd.h> 14 15 static void 16 usage(const char *cmd) 17 { 18 fprintf(stderr, "%s -4 ip4 -p port [-r]\n", cmd); 19 exit(1); 20 } 21 22 int 23 main(int argc, char *argv[]) 24 { 25 struct sockaddr_in in, in2; 26 int s, opt, n, reuseport; 27 uint8_t buf[18]; 28 29 memset(&in, 0, sizeof(in)); 30 in.sin_family = AF_INET; 31 32 reuseport = 0; 33 34 while ((opt = getopt(argc, argv, "4:p:r")) != -1) { 35 switch (opt) { 36 case '4': 37 if (inet_pton(AF_INET, optarg, &in.sin_addr) <= 0) 38 usage(argv[0]); 39 break; 40 41 case 'p': 42 in.sin_port = strtol(optarg, NULL, 10); 43 in.sin_port = htons(in.sin_port); 44 break; 45 46 case 'r': 47 reuseport = 1; 48 break; 49 50 default: 51 usage(argv[0]); 52 } 53 } 54 55 if (in.sin_addr.s_addr == INADDR_ANY || in.sin_port == 0) 56 usage(argv[0]); 57 58 s = socket(AF_INET, SOCK_DGRAM, 0); 59 if (s < 0) 60 err(2, "socket failed"); 61 62 if (reuseport) { 63 if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, 64 &reuseport, sizeof(reuseport)) < 0) 65 err(2, "setsockopt SO_REUSEPORT failed"); 66 } 67 68 if (connect(s, (const struct sockaddr *)&in, sizeof(in)) < 0) 69 err(2, "connect failed"); 70 71 memset(&in2, 0, sizeof(in2)); 72 in2.sin_family = AF_UNSPEC; 73 if (connect(s, (const struct sockaddr *)&in2, sizeof(in2)) < 0) { 74 int error = errno; 75 76 if (error != EAFNOSUPPORT) 77 errc(2, error, "di-connect failed"); 78 } 79 80 n = sendto(s, buf, sizeof(buf), 0, 81 (const struct sockaddr *)&in, sizeof(in)); 82 if (n < 0) 83 err(2, "sendto failed"); 84 else if (n != (int)sizeof(buf)) 85 errx(2, "sent truncated data %d", n); 86 87 n = read(s, buf, sizeof(buf)); 88 if (n < 0) 89 err(2, "read failed"); 90 printf("read %d, done\n", n); 91 92 exit(0); 93 } 94