1 /*	$NetBSD: uipc_syscalls_43.c,v 1.2 2002/02/21 07:38:20 itojun Exp $	*/
2 
3 /*
4  * This is regression test for COMPAT_43 code. Tested 4.3 syscalls are:
5  * - getsockname(2), getpeername(2)
6  * - recv(2), recvfrom(2), recvmsg(2)
7  * - send(2), sendmsg(2)
8  *
9  * This program uses inetd echo service. You need to configure
10  * inetd to provide echo for both tcp and udp in order to run
11  * this program successfully, and adjust 'echoserver' to IP address
12  * of the machine running the service.
13  *
14  * Public domain. Do whatever you please with this. Jaromir Dolecek
15  */
16 
17 #include <sys/syscall.h>
18 #include <unistd.h>
19 #include <err.h>
20 #include <sys/types.h>
21 #include <netinet/in.h>
22 #include <sys/un.h>
23 #include <sys/socket.h>
24 #include <sys/uio.h>
25 
26 const char *unixd = "unixdomain";
27 const char *echoserver = "127.0.0.1";
28 const char *localhost = "127.0.0.1";
29 const int echoport = 7;
30 
31 int
32 main()
33 {
34 	int s, descr;
35 	socklen_t sz;
36 	struct sockaddr_in sa;
37 	struct sockaddr_un sun;
38 	struct osockaddr *osa = (struct osockaddr *) &sa;
39 	struct omsghdr msg;
40 	struct iovec iov;
41 	char buf[10];
42 
43 	/*
44 	 * TCP connection, test connect(2), bind(2), recv(2), send(2),
45 	 * getsockname(2), getpeername(2).
46 	 */
47 	if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0)
48 		err(1, "socket");
49 
50 	sa.sin_addr.s_addr = inet_addr(echoserver);
51 	sa.sin_port = htons(echoport);
52 	osa->sa_family = AF_INET;
53 	if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) < 0)
54 		err(1, "connect");
55 
56 	/* ogetpeername */
57 	sz = sizeof(sa);
58 	memset(&sa, '\0', sizeof(sa));
59 	if (syscall(SYS_compat_43_ogetpeername, s, (struct sockaddr *) &sa, &sz))
60 		err(1, "getpeername");
61 
62 	printf("ogetpeername: sz %d:%d name %s port %d family %d\n",
63 		sizeof(sa), sz,
64 		inet_ntoa(sa.sin_addr),
65 		ntohs(sa.sin_port),
66 		osa->sa_family);
67 
68 	/* ogetsockname */
69 	sz = sizeof(sa);
70 	memset(&sa, '\0', sizeof(sa));
71 	if (syscall(SYS_compat_43_ogetsockname, s, (struct sockaddr *) &sa, &sz))
72 		err(1, "getsockname");
73 
74 	printf("osockname: sz %d:%d name %s port %d family %d\n",
75 		sizeof(sa), sz,
76 		inet_ntoa(sa.sin_addr),
77 		ntohs(sa.sin_port),
78 		osa->sa_family);
79 
80 	/* osend */
81 	if (syscall(SYS_compat_43_osend, s, "fobj", 4, 0) < 0)
82 		err(1, "osend");
83 
84 	/* orecv */
85 	memset(buf, '\0', sizeof(buf));
86 	if (syscall(SYS_compat_43_orecv, s, buf, sizeof(buf), 0) < 0)
87 		err(1, "orecv");
88 
89 	printf("orecv: %s\n", buf);
90 
91 	shutdown(s, SHUT_RDWR);
92 	close(s);
93 
94 	/* UDP connection, test sendto()/recvfrom() */
95 
96 	if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
97 		err(1, "socket");
98 
99 	sa.sin_addr.s_addr = INADDR_ANY;
100 	sa.sin_port = htons(65533);
101 	osa->sa_family = AF_INET;
102 	if (bind(s, (struct sockaddr *) &sa, sizeof(sa)))
103 		err(1, "bind1");
104 
105 	/* ogetsockname */
106 	sz = sizeof(sa);
107 	memset(&sa, '\0', sizeof(sa));
108 	if (syscall(SYS_compat_43_ogetsockname, s, (struct sockaddr *) &sa, &sz))
109 		err(1, "getsockname");
110 
111 	printf("osockname2: sz %d:%d name %s port %d family %d\n",
112 		sizeof(sa), sz,
113 		inet_ntoa(sa.sin_addr),
114 		ntohs(sa.sin_port),
115 		osa->sa_family);
116 
117 	sa.sin_addr.s_addr = inet_addr(echoserver);
118 	sa.sin_port = htons(echoport);
119 	osa->sa_family = AF_INET;
120 	/* common sendto(2) - not versioned */
121 	if (sendto(s, "fob2", 4, 0, (struct sockaddr *) &sa, sizeof(sa)) < 0)
122 		err(1, "sendto");
123 
124 	/* orecvfrom */
125 	memset(buf, '\0', sizeof(buf));
126 	memset(&sa, '\0', sizeof(sa));
127 	sz = sizeof(sa);
128 	if (syscall(SYS_compat_43_orecvfrom, s, buf, sizeof(buf), 0, (struct osockaddr *) &sa, &sz) < 0)
129 		err(1, "orecvfrom");
130 	printf("orecvfrom: '%s' sz %d:%d name %s port %d family %d\n",
131 		buf,
132 		sizeof(sa), sz,
133 		inet_ntoa(sa.sin_addr),
134 		ntohs(sa.sin_port),
135 		osa->sa_family);
136 
137 	shutdown(s, SHUT_RDWR);
138 	close(s);
139 
140 	/* UDP connection, test sendmsg()/recvmsg() */
141 
142 	if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
143 		err(1, "socket");
144 
145 	sa.sin_addr.s_addr = INADDR_ANY;
146 	sa.sin_port = htons(65533);
147 	osa->sa_family = AF_INET;
148 	if (bind(s, (struct sockaddr *) &sa, sizeof(sa)))
149 		err(1, "bind2");
150 
151 	sa.sin_addr.s_addr = inet_addr(echoserver);
152 	sa.sin_port = htons(echoport);
153 	osa->sa_family = AF_INET;
154 	memset(&msg, '\0', sizeof(msg));
155 	msg.msg_name = (void *) &sa;
156 	msg.msg_namelen = sizeof(sa);
157 	iov.iov_base = "fob3";
158 	iov.iov_len = 4;
159 	msg.msg_iov = &iov;
160 	msg.msg_iovlen = 1;
161 	/* osendmsg */
162 	if (syscall(SYS_compat_43_osendmsg, s, &msg, 0) < 0)
163 		err(1, "osendmsg");
164 
165 	/* orecvmsg */
166 	memset(&sa, '\0', sizeof(sa));
167 	iov.iov_base = buf;
168 	iov.iov_len = sizeof(buf);
169 	if (syscall(SYS_compat_43_orecvmsg, s, &msg, 0) < 0)
170 		err(1, "orecvmsg");
171 
172 	printf("orecvmsg: '%s' sz %d:%d name %s port %d family %d\n",
173 		buf,
174 		sizeof(sa), msg.msg_namelen,
175 		inet_ntoa(sa.sin_addr),
176 		ntohs(sa.sin_port),
177 		osa->sa_family);
178 
179 	shutdown(s, SHUT_RDWR);
180 	close(s);
181 
182 	/*
183 	 * Local (unix domain) socket, test sendmsg()/recvmsg() with
184 	 * accrights
185 	 */
186 
187 	if ((s = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0)
188 		err(1, "socket");
189 
190 	osa = (struct osockaddr *) &sun;
191 	strcpy(sun.sun_path, unixd);
192 	osa->sa_family = AF_LOCAL;
193 	if (bind(s, (struct sockaddr *) &sun, SUN_LEN(&sun)))
194 		err(1, "bind3");
195 
196 	/* osendmsg, old style descriptor passing */
197 	memset(&msg, '\0', sizeof(msg));
198 	msg.msg_name = (void *) &sun;
199 	msg.msg_namelen = sizeof(sun);
200 	iov.iov_base = "fob4";
201 	iov.iov_len = 4;
202 	msg.msg_iov = &iov;
203 	msg.msg_iovlen = 1;
204 	descr = s;
205 	msg.msg_accrights = (caddr_t) &descr;
206 	msg.msg_accrightslen = sizeof(int);
207 	if (syscall(SYS_compat_43_osendmsg, s, &msg, 0) < 0) {
208 		unlink(unixd);
209 		err(1, "osendmsg");
210 	}
211 
212 	memset(&sun, '\0', sizeof(sa));
213 	iov.iov_base = buf;
214 	iov.iov_len = sizeof(buf);
215 	descr = -1;
216 
217 	/* orecvmsg */
218 	if (syscall(SYS_compat_43_orecvmsg, s, &msg, 0) < 0) {
219 		unlink(unixd);
220 		err(1, "orecvmsg");
221 	}
222 
223 	printf("orecvmsg: '%s' sz %d:%d name '%s' family %d descr %d\n",
224 		buf,
225 		sizeof(sun), msg.msg_namelen, sun.sun_path,
226 		osa->sa_family, descr);
227 
228 	unlink(unixd);
229 	close(s);
230 	close(descr);
231 
232 }
233