ibcs2_socksys.c revision 16310
1262261Sdim/*
2262261Sdim * Copyright (c) 1994, 1995 Scott Bartram
3262261Sdim * Copyright (c) 1994 Arne H Juul
4262261Sdim * All rights reserved.
5262261Sdim *
6262261Sdim * Redistribution and use in source and binary forms, with or without
7262261Sdim * modification, are permitted provided that the following conditions
8262261Sdim * are met:
9262261Sdim * 1. Redistributions of source code must retain the above copyright
10280031Sdim *    notice, this list of conditions and the following disclaimer.
11280031Sdim * 2. The name of the author may not be used to endorse or promote products
12262261Sdim *    derived from this software without specific prior written permission
13262261Sdim *
14262261Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15262261Sdim * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16262261Sdim * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17262261Sdim * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18262261Sdim * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19262261Sdim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20262261Sdim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21276479Sdim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22262261Sdim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23262261Sdim * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24262261Sdim */
25262261Sdim
26262261Sdim#include <sys/param.h>
27262261Sdim#include <sys/systm.h>
28262261Sdim#include <sys/proc.h>
29262261Sdim#include <sys/file.h>
30262261Sdim#include <sys/filedesc.h>
31262261Sdim#include <sys/ioctl.h>
32262261Sdim#include <sys/termios.h>
33276479Sdim#include <sys/tty.h>
34276479Sdim#include <sys/socket.h>
35276479Sdim#include <sys/ioctl.h>
36262261Sdim#include <sys/sysproto.h>
37262261Sdim#include <net/if.h>
38262261Sdim#include <sys/kernel.h>
39262261Sdim#include <sys/sysctl.h>
40262261Sdim
41262261Sdim#include <i386/ibcs2/ibcs2_socksys.h>
42276479Sdim#include <i386/ibcs2/ibcs2_util.h>
43262261Sdim
44276479Sdim/* Local structures */
45276479Sdimstruct getipdomainname_args {
46262261Sdim        char    *ipdomainname;
47262261Sdim        int     len;
48262261Sdim};
49262261Sdim
50struct setipdomainname_args {
51        char    *ipdomainname;
52        int     len;
53};
54
55/* Local prototypes */
56static int ibcs2_getipdomainname __P((struct proc *,
57				      struct getipdomainname_args *, int *));
58static int ibcs2_setipdomainname __P((struct proc *,
59				      struct setipdomainname_args *, int *));
60
61/*
62 * iBCS2 socksys calls.
63 */
64
65int
66ibcs2_socksys(p, uap, retval)
67	register struct proc *p;
68	register struct ibcs2_socksys_args *uap;
69	int *retval;
70{
71	register struct filedesc *fdp = p->p_fd;
72	register struct file *fp;
73	int error;
74	int realargs[7]; /* 1 for command, 6 for recvfrom */
75	void *passargs;
76
77	/*
78	 * SOCKET should only be legal on /dev/socksys.
79	 * GETIPDOMAINNAME should only be legal on /dev/socksys ?
80	 * The others are (and should be) only legal on sockets.
81	 */
82
83	if (error = copyin(uap->argsp, (caddr_t)realargs, sizeof(realargs)))
84		return error;
85	DPRINTF(("ibcs2_socksys: %08x %08x %08x %08x %08x %08x %08x\n",
86	       realargs[0], realargs[1], realargs[2], realargs[3],
87	       realargs[4], realargs[5], realargs[6]));
88
89	passargs = (void *)(realargs + 1);
90	switch (realargs[0]) {
91	case SOCKSYS_ACCEPT:
92		return accept(p, passargs, retval);
93	case SOCKSYS_BIND:
94		return bind(p, passargs, retval);
95	case SOCKSYS_CONNECT:
96		return connect(p, passargs, retval);
97	case SOCKSYS_GETPEERNAME:
98		return getpeername(p, passargs, retval);
99	case SOCKSYS_GETSOCKNAME:
100		return getsockname(p, passargs, retval);
101	case SOCKSYS_GETSOCKOPT:
102		return getsockopt(p, passargs, retval);
103	case SOCKSYS_LISTEN:
104		return listen(p, passargs, retval);
105	case SOCKSYS_RECV:
106		realargs[5] = realargs[6] = 0;
107		/* FALLTHROUGH */
108	case SOCKSYS_RECVFROM:
109		return recvfrom(p, passargs, retval);
110	case SOCKSYS_SEND:
111		realargs[5] = realargs[6] = 0;
112		/* FALLTHROUGH */
113	case SOCKSYS_SENDTO:
114		return sendto(p, passargs, retval);
115	case SOCKSYS_SETSOCKOPT:
116		return setsockopt(p, passargs, retval);
117	case SOCKSYS_SHUTDOWN:
118		return shutdown(p, passargs, retval);
119	case SOCKSYS_SOCKET:
120		return socket(p, passargs, retval);
121	case SOCKSYS_SELECT:
122		return select(p, passargs, retval);
123	case SOCKSYS_GETIPDOMAIN:
124		return ibcs2_getipdomainname(p, passargs, retval);
125	case SOCKSYS_SETIPDOMAIN:
126		return ibcs2_setipdomainname(p, passargs, retval);
127	case SOCKSYS_ADJTIME:
128		return adjtime(p, passargs, retval);
129	case SOCKSYS_SETREUID:
130		return setreuid(p, passargs, retval);
131	case SOCKSYS_SETREGID:
132		return setregid(p, passargs, retval);
133	case SOCKSYS_GETTIME:
134		return gettimeofday(p, passargs, retval);
135	case SOCKSYS_SETTIME:
136		return settimeofday(p, passargs, retval);
137	case SOCKSYS_GETITIMER:
138		return getitimer(p, passargs, retval);
139	case SOCKSYS_SETITIMER:
140		return setitimer(p, passargs, retval);
141
142	default:
143		printf("socksys unknown %08x %08x %08x %08x %08x %08x %08x\n",
144                       realargs[0], realargs[1], realargs[2], realargs[3],
145                       realargs[4], realargs[5], realargs[6]);
146		return EINVAL;
147	}
148	/* NOTREACHED */
149}
150
151/* ARGSUSED */
152static int
153ibcs2_getipdomainname(p, uap, retval)
154        struct proc *p;
155        struct getipdomainname_args *uap;
156        int *retval;
157{
158	char hname[MAXHOSTNAMELEN], *dptr;
159	int len;
160
161	/* Get the domain name */
162	strcpy(hname, hostname);
163	dptr = index(hname, '.');
164	if ( dptr )
165		dptr++;
166	else
167		/* Make it effectively an empty string */
168		dptr = hname + strlen(hname);
169
170	len = strlen(dptr) + 1;
171	if ((u_int)uap->len > len + 1)
172		uap->len = len + 1;
173	return (copyout((caddr_t)dptr, (caddr_t)uap->ipdomainname, uap->len));
174}
175
176/* ARGSUSED */
177static int
178ibcs2_setipdomainname(p, uap, retval)
179        struct proc *p;
180        struct setipdomainname_args *uap;
181        int *retval;
182{
183	char hname[MAXHOSTNAMELEN], *ptr;
184	int error, sctl[2], hlen;
185
186	if ((error = suser(p->p_ucred, &p->p_acflag)))
187		return (error);
188
189	/* W/out a hostname a domain-name is nonsense */
190	if ( strlen(hostname) == 0 )
191		return EINVAL;
192
193	/* Get the host's unqualified name (strip off the domain) */
194	strcpy(hname, hostname);
195	ptr = index(hname, '.');
196	if ( ptr != NULL ) {
197		ptr++;
198		*ptr = '\0';
199	} else
200		strcat(hname, ".");
201
202	/* Set ptr to the end of the string so we can append to it */
203	hlen = strlen(hname);
204	ptr = hname + hlen;
205        if ((u_int)uap->len > (sizeof (hname) - hlen - 1))
206                return EINVAL;
207
208	/* Append the ipdomain to the end */
209	error = copyin((caddr_t)uap->ipdomainname, ptr, uap->len);
210	if (error)
211		return (error);
212
213	/* 'sethostname' with the new information */
214	sctl[0] = CTL_KERN;
215        sctl[1] = KERN_HOSTNAME;
216 	hlen = strlen(hname) + 1;
217        return (kernel_sysctl(p, sctl, 2, 0, 0, hname, hlen, 0));
218}
219