xref: /original-bsd/sys/hp/hpux/hpux_net.c (revision 27393bdf)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1990, 1993
4  *	The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Systems Programming Group of the University of Utah Computer
8  * Science Department.
9  *
10  * %sccs.include.redist.c%
11  *
12  * from: Utah $Hdr: hpux_net.c 1.8 93/08/02$
13  *
14  *	@(#)hpux_net.c	8.3 (Berkeley) 02/19/95
15  */
16 
17 /*
18  * Network related HP-UX compatibility routines
19  */
20 
21 #ifdef HPUXCOMPAT
22 
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/kernel.h>
26 #include <sys/time.h>
27 #include <sys/errno.h>
28 #include <sys/proc.h>
29 #include <sys/file.h>
30 #include <sys/mbuf.h>
31 #include <sys/socket.h>
32 #include <sys/socketvar.h>
33 #include <sys/uio.h>
34 #include <sys/ktrace.h>
35 
36 #include <hp/hpux/hpux.h>
37 
38 #define MINBSDIPCCODE	0x3EE
39 #define NUMBSDIPC	32
40 
41 /*
42  * HPUX netioctl() to BSD syscall map.
43  * Indexed by callno - MINBSDIPCCODE
44  */
45 extern int socket(), listen(), bind(), compat_43_accept(), connect();
46 extern int compat_43_recv(), compat_43_send(), shutdown();
47 extern int compat_43_getsockname(), sendto(), compat_43_recvfrom();
48 extern int compat_43_getpeername();
49 int hpuxgetsockopt(), hpuxsetsockopt();
50 
51 struct hpuxtobsdipc {
52 	int (*rout)();
53 	int nargs;
54 } hpuxtobsdipc[NUMBSDIPC] = {
55 	socket,		3, /* 3ee */		listen,		2, /* 3ef */
56 	bind,		3, /* 3f0 */	compat_43_accept,	3, /* 3f1 */
57 	connect,	3, /* 3f2 */	compat_43_recv,		4, /* 3f3 */
58 	compat_43_send,		4, /* 3f4 */	shutdown,	2, /* 3f5 */
59 	compat_43_getsockname,	3, /* 3f6 */	hpuxsetsockopt,	5, /* 3f7 */
60 	sendto,		6, /* 3f8 */	compat_43_recvfrom,	6, /* 3f9 */
61 	compat_43_getpeername,	3, /* 3fa */	NULL,		0, /* 3fb */
62 	NULL,		0, /* 3fc */		NULL,		0, /* 3fd */
63 	NULL,		0, /* 3fe */		NULL,		0, /* 3ff */
64 	NULL,		0, /* 400 */		NULL,		0, /* 401 */
65 	NULL,		0, /* 402 */		NULL,		0, /* 403 */
66 	NULL,		0, /* 404 */		NULL,		0, /* 405 */
67 	NULL,		0, /* 406 */		NULL,		0, /* 407 */
68 	NULL,		0, /* 408 */		NULL,		0, /* 409 */
69 	NULL,		0, /* 40a */		hpuxgetsockopt,	5, /* 40b */
70 	NULL,		0, /* 40c */		NULL,		0, /* 40d */
71 };
72 
73 /*
74  * Single system call entry to BSD style IPC.
75  * Gleened from disassembled libbsdipc.a syscall entries.
76  */
77 struct hpuxnetioctl_args {
78 	int	call;
79 	int	*args;
80 };
81 hpuxnetioctl(p, uap, retval)
82 	struct proc *p;
83 	struct hpuxnetioctl_args *uap;
84 	int *retval;
85 {
86 	int *args, i;
87 	register int code;
88 	int error;
89 
90 	args = uap->args;
91 	code = uap->call - MINBSDIPCCODE;
92 	if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL)
93 		return (EINVAL);
94 	if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) &&
95 	    (error = copyin((caddr_t)args, (caddr_t)uap, (u_int)i))) {
96 #ifdef KTRACE
97                 if (KTRPOINT(p, KTR_SYSCALL))
98                         ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
99 				   hpuxtobsdipc[code].nargs, (int *)uap);
100 #endif
101 		return (error);
102 	}
103 #ifdef KTRACE
104         if (KTRPOINT(p, KTR_SYSCALL))
105                 ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
106 			   hpuxtobsdipc[code].nargs, (int *)uap);
107 #endif
108 	return ((*hpuxtobsdipc[code].rout)(p, uap, retval));
109 }
110 
111 socksetsize(size, m)
112 	int size;
113 	struct mbuf *m;
114 {
115 	register int tmp;
116 
117 	if (size < sizeof(int)) {
118 		switch(size) {
119 	    	case 1:
120 			tmp = (int) *mtod(m, char *);
121 			break;
122 	    	case 2:
123 			tmp = (int) *mtod(m, short *);
124 			break;
125 	    	case 3:
126 			tmp = (((int) *mtod(m, int *)) >> 8) & 0xffffff;
127 			break;
128 		}
129 		*mtod(m, int *) = tmp;
130 		m->m_len = sizeof(int);
131 	} else {
132 		m->m_len = size;
133 	}
134 }
135 
136 struct hpuxsetsockopt_args {
137 	int	s;
138 	int	level;
139 	int	name;
140 	caddr_t	val;
141 	int	valsize;
142 };
143 /* ARGSUSED */
144 hpuxsetsockopt(p, uap, retval)
145 	struct proc *p;
146 	struct hpuxsetsockopt_args *uap;
147 	int *retval;
148 {
149 	struct file *fp;
150 	struct mbuf *m = NULL;
151 	int tmp, error;
152 
153 	if (error = getsock(p->p_fd, uap->s, &fp))
154 		return (error);
155 	if (uap->valsize > MLEN)
156 		return (EINVAL);
157 	if (uap->val) {
158 		m = m_get(M_WAIT, MT_SOOPTS);
159 		if (m == NULL)
160 			return (ENOBUFS);
161 		if (error = copyin(uap->val, mtod(m, caddr_t),
162 		    (u_int)uap->valsize)) {
163 			(void) m_free(m);
164 			return (error);
165 		}
166 		if (uap->name == SO_LINGER) {
167 			tmp = *mtod(m, int *);
168 			mtod(m, struct linger *)->l_onoff = 1;
169 			mtod(m, struct linger *)->l_linger = tmp;
170 			m->m_len = sizeof(struct linger);
171 		} else
172 			socksetsize(uap->valsize, m);
173 	} else if (uap->name == ~SO_LINGER) {
174 		m = m_get(M_WAIT, MT_SOOPTS);
175 		if (m) {
176 			uap->name = SO_LINGER;
177 			mtod(m, struct linger *)->l_onoff = 0;
178 			m->m_len = sizeof(struct linger);
179 		}
180 	}
181 	return (sosetopt((struct socket *)fp->f_data, uap->level,
182 	    uap->name, m));
183 }
184 
185 struct hpuxsetsockopt2_args {
186 	int	s;
187 	int	level;
188 	int	name;
189 	caddr_t	val;
190 	int	valsize;
191 };
192 /* ARGSUSED */
193 hpuxsetsockopt2(p, uap, retval)
194 	struct proc *p;
195 	register struct hpuxsetsockopt2_args *uap;
196 	int *retval;
197 {
198 	struct file *fp;
199 	struct mbuf *m = NULL;
200 	int error;
201 
202 	if (error = getsock(p->p_fd, uap->s, &fp))
203 		return (error);
204 	if (uap->valsize > MLEN)
205 		return (EINVAL);
206 	if (uap->val) {
207 		m = m_get(M_WAIT, MT_SOOPTS);
208 		if (m == NULL)
209 			return (ENOBUFS);
210 		if (error = copyin(uap->val, mtod(m, caddr_t),
211 		    (u_int)uap->valsize)) {
212 			(void) m_free(m);
213 			return (error);
214 		}
215 		socksetsize(uap->valsize, m);
216 	}
217 	return (sosetopt((struct socket *)fp->f_data, uap->level,
218 	    uap->name, m));
219 }
220 
221 struct hpuxgetsockopt_args {
222 	int	s;
223 	int	level;
224 	int	name;
225 	caddr_t	val;
226 	int	*avalsize;
227 };
228 hpuxgetsockopt(p, uap, retval)
229 	struct proc *p;
230 	struct hpuxgetsockopt_args *uap;
231 	int *retval;
232 {
233 	struct file *fp;
234 	struct mbuf *m = NULL;
235 	int valsize, error;
236 
237 	if (error = getsock(p->p_fd, uap->s, &fp))
238 		return (error);
239 	if (uap->val) {
240 		if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
241 		    sizeof (valsize)))
242 			return (error);
243 	} else
244 		valsize = 0;
245 	if (error = sogetopt((struct socket *)fp->f_data, uap->level,
246 	    uap->name, &m))
247 		goto bad;
248 	if (uap->val && valsize && m != NULL) {
249 		if (uap->name == SO_LINGER) {
250 			if (mtod(m, struct linger *)->l_onoff)
251 				*mtod(m, int *) = mtod(m, struct linger *)->l_linger;
252 			else
253 				*mtod(m, int *) = 0;
254 			m->m_len = sizeof(int);
255 		}
256 		if (valsize > m->m_len)
257 			valsize = m->m_len;
258 		error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
259 		if (error == 0)
260 			error = copyout((caddr_t)&valsize,
261 			    (caddr_t)uap->avalsize, sizeof (valsize));
262 	}
263 bad:
264 	if (m != NULL)
265 		(void) m_free(m);
266 	return (error);
267 }
268 #endif
269