1*5f4c09ddSEd Maste /* $NetBSD: cltest.c,v 1.6 2015/01/22 05:44:28 christos Exp $ */
2*5f4c09ddSEd Maste
3*5f4c09ddSEd Maste /*-
4*5f4c09ddSEd Maste * Copyright (c) 2015 The NetBSD Foundation, Inc.
5*5f4c09ddSEd Maste * All rights reserved.
6*5f4c09ddSEd Maste *
7*5f4c09ddSEd Maste * This code is derived from software contributed to The NetBSD Foundation
8*5f4c09ddSEd Maste * by Christos Zoulas.
9*5f4c09ddSEd Maste *
10*5f4c09ddSEd Maste * Redistribution and use in source and binary forms, with or without
11*5f4c09ddSEd Maste * modification, are permitted provided that the following conditions
12*5f4c09ddSEd Maste * are met:
13*5f4c09ddSEd Maste * 1. Redistributions of source code must retain the above copyright
14*5f4c09ddSEd Maste * notice, this list of conditions and the following disclaimer.
15*5f4c09ddSEd Maste * 2. Redistributions in binary form must reproduce the above copyright
16*5f4c09ddSEd Maste * notice, this list of conditions and the following disclaimer in the
17*5f4c09ddSEd Maste * documentation and/or other materials provided with the distribution.
18*5f4c09ddSEd Maste *
19*5f4c09ddSEd Maste * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*5f4c09ddSEd Maste * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*5f4c09ddSEd Maste * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*5f4c09ddSEd Maste * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*5f4c09ddSEd Maste * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*5f4c09ddSEd Maste * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*5f4c09ddSEd Maste * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*5f4c09ddSEd Maste * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*5f4c09ddSEd Maste * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*5f4c09ddSEd Maste * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*5f4c09ddSEd Maste * POSSIBILITY OF SUCH DAMAGE.
30*5f4c09ddSEd Maste */
31*5f4c09ddSEd Maste #ifdef HAVE_CONFIG_H
32*5f4c09ddSEd Maste #include "config.h"
33*5f4c09ddSEd Maste #endif
34*5f4c09ddSEd Maste
35*5f4c09ddSEd Maste #include <sys/cdefs.h>
36*5f4c09ddSEd Maste __RCSID("$NetBSD: cltest.c,v 1.6 2015/01/22 05:44:28 christos Exp $");
37*5f4c09ddSEd Maste
38*5f4c09ddSEd Maste #include <sys/types.h>
39*5f4c09ddSEd Maste #include <sys/socket.h>
40*5f4c09ddSEd Maste #include <netinet/in.h>
41*5f4c09ddSEd Maste #include <arpa/inet.h>
42*5f4c09ddSEd Maste
43*5f4c09ddSEd Maste #include <stdio.h>
44*5f4c09ddSEd Maste #include <string.h>
45*5f4c09ddSEd Maste #include <unistd.h>
46*5f4c09ddSEd Maste #include <stdlib.h>
47*5f4c09ddSEd Maste #include <err.h>
48*5f4c09ddSEd Maste #ifdef HAVE_UTIL_H
49*5f4c09ddSEd Maste #include <util.h>
50*5f4c09ddSEd Maste #endif
51*5f4c09ddSEd Maste
52*5f4c09ddSEd Maste static __dead void
usage(int c)53*5f4c09ddSEd Maste usage(int c)
54*5f4c09ddSEd Maste {
55*5f4c09ddSEd Maste warnx("Unknown option `%c'", (char)c);
56*5f4c09ddSEd Maste fprintf(stderr, "Usage: %s [-u] [-a <addr>] [-m <msg>] [-p <port>]\n",
57*5f4c09ddSEd Maste getprogname());
58*5f4c09ddSEd Maste exit(EXIT_FAILURE);
59*5f4c09ddSEd Maste }
60*5f4c09ddSEd Maste
61*5f4c09ddSEd Maste static void
getaddr(const char * a,in_port_t p,struct sockaddr_storage * ss,socklen_t * slen)62*5f4c09ddSEd Maste getaddr(const char *a, in_port_t p, struct sockaddr_storage *ss,
63*5f4c09ddSEd Maste socklen_t *slen)
64*5f4c09ddSEd Maste {
65*5f4c09ddSEd Maste int c;
66*5f4c09ddSEd Maste
67*5f4c09ddSEd Maste memset(ss, 0, sizeof(*ss));
68*5f4c09ddSEd Maste p = htons(p);
69*5f4c09ddSEd Maste
70*5f4c09ddSEd Maste if (strchr(a, ':')) {
71*5f4c09ddSEd Maste struct sockaddr_in6 *s6 = (void *)ss;
72*5f4c09ddSEd Maste c = inet_pton(AF_INET6, a, &s6->sin6_addr);
73*5f4c09ddSEd Maste s6->sin6_family = AF_INET6;
74*5f4c09ddSEd Maste *slen = sizeof(*s6);
75*5f4c09ddSEd Maste s6->sin6_port = p;
76*5f4c09ddSEd Maste } else {
77*5f4c09ddSEd Maste struct sockaddr_in *s = (void *)ss;
78*5f4c09ddSEd Maste c = inet_pton(AF_INET, a, &s->sin_addr);
79*5f4c09ddSEd Maste s->sin_family = AF_INET;
80*5f4c09ddSEd Maste *slen = sizeof(*s);
81*5f4c09ddSEd Maste s->sin_port = p;
82*5f4c09ddSEd Maste }
83*5f4c09ddSEd Maste #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
84*5f4c09ddSEd Maste ss->ss_len = (uint8_t)*slen;
85*5f4c09ddSEd Maste #endif
86*5f4c09ddSEd Maste if (c == -1)
87*5f4c09ddSEd Maste err(EXIT_FAILURE, "Invalid address `%s'", a);
88*5f4c09ddSEd Maste }
89*5f4c09ddSEd Maste
90*5f4c09ddSEd Maste int
main(int argc,char * argv[])91*5f4c09ddSEd Maste main(int argc, char *argv[])
92*5f4c09ddSEd Maste {
93*5f4c09ddSEd Maste int sfd;
94*5f4c09ddSEd Maste int c;
95*5f4c09ddSEd Maste struct sockaddr_storage ss;
96*5f4c09ddSEd Maste const char *msg = "hello";
97*5f4c09ddSEd Maste const char *addr = "127.0.0.1";
98*5f4c09ddSEd Maste int type = SOCK_STREAM;
99*5f4c09ddSEd Maste in_port_t port = 6161;
100*5f4c09ddSEd Maste socklen_t slen;
101*5f4c09ddSEd Maste char buf[128];
102*5f4c09ddSEd Maste
103*5f4c09ddSEd Maste while ((c = getopt(argc, argv, "a:m:p:u")) != -1) {
104*5f4c09ddSEd Maste switch (c) {
105*5f4c09ddSEd Maste case 'a':
106*5f4c09ddSEd Maste addr = optarg;
107*5f4c09ddSEd Maste break;
108*5f4c09ddSEd Maste case 'm':
109*5f4c09ddSEd Maste msg = optarg;
110*5f4c09ddSEd Maste break;
111*5f4c09ddSEd Maste case 'p':
112*5f4c09ddSEd Maste port = (in_port_t)atoi(optarg);
113*5f4c09ddSEd Maste break;
114*5f4c09ddSEd Maste case 'u':
115*5f4c09ddSEd Maste type = SOCK_DGRAM;
116*5f4c09ddSEd Maste break;
117*5f4c09ddSEd Maste default:
118*5f4c09ddSEd Maste usage(c);
119*5f4c09ddSEd Maste }
120*5f4c09ddSEd Maste }
121*5f4c09ddSEd Maste
122*5f4c09ddSEd Maste getaddr(addr, port, &ss, &slen);
123*5f4c09ddSEd Maste
124*5f4c09ddSEd Maste if ((sfd = socket(AF_INET, type, 0)) == -1)
125*5f4c09ddSEd Maste err(EXIT_FAILURE, "socket");
126*5f4c09ddSEd Maste
127*5f4c09ddSEd Maste sockaddr_snprintf(buf, sizeof(buf), "%a:%p", (const void *)&ss);
128*5f4c09ddSEd Maste printf("connecting to: %s\n", buf);
129*5f4c09ddSEd Maste if (connect(sfd, (const void *)&ss, slen) == -1)
130*5f4c09ddSEd Maste err(EXIT_FAILURE, "connect");
131*5f4c09ddSEd Maste
132*5f4c09ddSEd Maste size_t len = strlen(msg) + 1;
133*5f4c09ddSEd Maste if (write(sfd, msg, len) != (ssize_t)len)
134*5f4c09ddSEd Maste err(EXIT_FAILURE, "write");
135*5f4c09ddSEd Maste return 0;
136*5f4c09ddSEd Maste }
137