1/*	$NetBSD: svr4_net.c,v 1.57 2009/12/09 21:32:58 dsl Exp $	*/
2
3/*-
4 * Copyright (c) 1994, 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * Emulate /dev/{udp,tcp,...}
34 */
35
36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: svr4_net.c,v 1.57 2009/12/09 21:32:58 dsl Exp $");
38
39#define COMPAT_SVR4 1
40
41#include <sys/param.h>
42#include <sys/kernel.h>
43#include <sys/systm.h>
44#include <sys/buf.h>
45#include <sys/malloc.h>
46#include <sys/ioctl.h>
47#include <sys/tty.h>
48#include <sys/file.h>
49#include <sys/filedesc.h>
50#include <sys/fcntl.h>
51#include <sys/select.h>
52#include <sys/socket.h>
53#include <sys/socketvar.h>
54#include <sys/protosw.h>
55#include <sys/domain.h>
56#include <net/if.h>
57#include <netinet/in.h>
58#include <sys/proc.h>
59#include <sys/vnode.h>
60#include <sys/device.h>
61#include <sys/conf.h>
62#include <sys/mount.h>
63
64#include <sys/syscallargs.h>
65
66#include <compat/svr4/svr4_types.h>
67#include <compat/svr4/svr4_util.h>
68#include <compat/svr4/svr4_signal.h>
69#include <compat/svr4/svr4_lwp.h>
70#include <compat/svr4/svr4_ucontext.h>
71#include <compat/svr4/svr4_syscallargs.h>
72#include <compat/svr4/svr4_ioctl.h>
73#include <compat/svr4/svr4_stropts.h>
74#include <compat/svr4/svr4_socket.h>
75
76dev_type_open(svr4_netopen);
77
78const struct cdevsw svr4_net_cdevsw = {
79	svr4_netopen, noclose, noread, nowrite, noioctl,
80	nostop, notty, nopoll, nommap, nokqfilter, D_OTHER,
81};
82
83/*
84 * Device minor numbers
85 */
86enum {
87	dev_arp			= 26,
88	dev_icmp		= 27,
89	dev_ip			= 28,
90	dev_tcp			= 35,
91	dev_udp			= 36,
92	dev_rawip		= 37,
93	dev_unix_dgram		= 38,
94	dev_unix_stream		= 39,
95	dev_unix_ord_stream	= 40
96};
97
98int svr4_netattach(int);
99
100int svr4_soo_close(file_t *);
101
102static const struct fileops svr4_netops = {
103	.fo_read = soo_read,
104	.fo_write = soo_write,
105	.fo_ioctl = soo_ioctl,
106	.fo_fcntl = soo_fcntl,
107	.fo_poll = soo_poll,
108	.fo_stat = soo_stat,
109	.fo_close = svr4_soo_close,
110	.fo_kqfilter = soo_kqfilter,
111	.fo_restart = soo_restart,
112};
113
114
115/*
116 * Used by new config, but we don't need it.
117 */
118int
119svr4_netattach(int n)
120{
121	return 0;
122}
123
124
125int
126svr4_netopen(dev_t dev, int flag, int mode, struct lwp *l)
127{
128	int type, protocol;
129	int fd;
130	file_t *fp;
131	struct socket *so;
132	int error;
133	int family;
134
135	DPRINTF(("netopen("));
136
137	if (curlwp->l_dupfd >= 0)	/* XXX */
138		return ENODEV;
139
140	switch (minor(dev)) {
141	case dev_udp:
142		family = AF_INET;
143		type = SOCK_DGRAM;
144		protocol = IPPROTO_UDP;
145		DPRINTF(("udp, "));
146		break;
147
148	case dev_tcp:
149		family = AF_INET;
150		type = SOCK_STREAM;
151		protocol = IPPROTO_TCP;
152		DPRINTF(("tcp, "));
153		break;
154
155	case dev_ip:
156	case dev_rawip:
157		family = AF_INET;
158		type = SOCK_RAW;
159		protocol = IPPROTO_IP;
160		DPRINTF(("ip, "));
161		break;
162
163	case dev_icmp:
164		family = AF_INET;
165		type = SOCK_RAW;
166		protocol = IPPROTO_ICMP;
167		DPRINTF(("icmp, "));
168		break;
169
170	case dev_unix_dgram:
171		family = AF_LOCAL;
172		type = SOCK_DGRAM;
173		protocol = 0;
174		DPRINTF(("unix-dgram, "));
175		break;
176
177	case dev_unix_stream:
178	case dev_unix_ord_stream:
179		family = AF_LOCAL;
180		type = SOCK_STREAM;
181		protocol = 0;
182		DPRINTF(("unix-stream, "));
183		break;
184
185	default:
186		DPRINTF(("%"PRId32");\n", minor(dev)));
187		return EOPNOTSUPP;
188	}
189
190	if ((error = fd_allocfile(&fp, &fd)) != 0)
191		return error;
192
193	if ((error = socreate(family, &so, type, protocol, l, NULL)) != 0) {
194		DPRINTF(("socreate error %d\n", error));
195		fd_abort(curproc, fp, fd);
196		return error;
197	}
198
199	error = fd_clone(fp, fd, flag, &svr4_netops, so);
200	fp->f_type = DTYPE_SOCKET;
201	(void)svr4_stream_get(fp);
202
203	DPRINTF(("ok);\n"));
204	return error;
205}
206
207
208int
209svr4_soo_close(file_t *fp)
210{
211	struct socket *so = fp->f_data;
212
213	svr4_delete_socket(curproc, fp);
214	free(so->so_internal, M_NETADDR);
215	return soo_close(fp);
216}
217
218
219struct svr4_strm *
220svr4_stream_get(file_t *fp)
221{
222	struct socket *so;
223	struct svr4_strm *st;
224
225	if (fp == NULL || fp->f_type != DTYPE_SOCKET)
226		return NULL;
227
228	so = fp->f_data;
229
230	if (so->so_internal)
231		return so->so_internal;
232
233	/* Allocate a new one. */
234	fp->f_ops = &svr4_netops;
235	st = malloc(sizeof(struct svr4_strm), M_NETADDR, M_WAITOK);
236	st->s_family = so->so_proto->pr_domain->dom_family;
237	st->s_cmd = ~0;
238	st->s_afd = -1;
239	st->s_eventmask = 0;
240	so->so_internal = st;
241
242	return st;
243}
244