xref: /original-bsd/sys/hp/hpux/hpux_net.c (revision 3705696b)
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.6 92/12/26$
13  *
14  *	@(#)hpux_net.c	8.1 (Berkeley) 06/10/93
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(), oaccept(), connect(), orecv();
46 extern int osend(), shutdown(), ogetsockname(), sendto();
47 extern int orecvfrom(), ogetpeername();
48 int hpuxgetsockopt(), hpuxsetsockopt();
49 
50 struct hpuxtobsdipc {
51 	int (*rout)();
52 	int nargs;
53 } hpuxtobsdipc[NUMBSDIPC] = {
54 	socket,		3, /* 3ee */	listen,		2, /* 3ef */
55 	bind,		3, /* 3f0 */	oaccept,	3, /* 3f1 */
56 	connect,	3, /* 3f2 */	orecv,		4, /* 3f3 */
57 	osend,		4, /* 3f4 */	shutdown,	2, /* 3f5 */
58 	ogetsockname,	3, /* 3f6 */	hpuxsetsockopt,	5, /* 3f7 */
59 	sendto,		6, /* 3f8 */	orecvfrom,	6, /* 3f9 */
60 	ogetpeername,	3, /* 3fa */	NULL,		0, /* 3fb */
61 	NULL,		0, /* 3fc */	NULL,		0, /* 3fd */
62 	NULL,		0, /* 3fe */	NULL,		0, /* 3ff */
63 	NULL,		0, /* 400 */	NULL,		0, /* 401 */
64 	NULL,		0, /* 402 */	NULL,		0, /* 403 */
65 	NULL,		0, /* 404 */	NULL,		0, /* 405 */
66 	NULL,		0, /* 406 */	NULL,		0, /* 407 */
67 	NULL,		0, /* 408 */	NULL,		0, /* 409 */
68 	NULL,		0, /* 40a */	hpuxgetsockopt,	5, /* 40b */
69 	NULL,		0, /* 40c */	NULL,		0, /* 40d */
70 };
71 
72 /*
73  * Single system call entry to BSD style IPC.
74  * Gleened from disassembled libbsdipc.a syscall entries.
75  */
76 struct hpuxnetioctl_args {
77 	int	call;
78 	int	*args;
79 };
80 hpuxnetioctl(p, uap, retval)
81 	struct proc *p;
82 	struct hpuxnetioctl_args *uap;
83 	int *retval;
84 {
85 	int *args, i;
86 	register int code;
87 	int error;
88 
89 	args = uap->args;
90 	code = uap->call - MINBSDIPCCODE;
91 	if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL)
92 		return (EINVAL);
93 	if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) &&
94 	    (error = copyin((caddr_t)args, (caddr_t)uap, (u_int)i))) {
95 #ifdef KTRACE
96                 if (KTRPOINT(p, KTR_SYSCALL))
97                         ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
98 				   hpuxtobsdipc[code].nargs);
99 #endif
100 		return (error);
101 	}
102 #ifdef KTRACE
103         if (KTRPOINT(p, KTR_SYSCALL))
104                 ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
105 			   hpuxtobsdipc[code].nargs);
106 #endif
107 	return ((*hpuxtobsdipc[code].rout)(p, uap, retval));
108 }
109 
110 socksetsize(size, m)
111 	int size;
112 	struct mbuf *m;
113 {
114 	register int tmp;
115 
116 	if (size < sizeof(int)) {
117 		switch(size) {
118 	    	case 1:
119 			tmp = (int) *mtod(m, char *);
120 			break;
121 	    	case 2:
122 			tmp = (int) *mtod(m, short *);
123 			break;
124 	    	case 3:
125 			tmp = (((int) *mtod(m, int *)) >> 8) & 0xffffff;
126 			break;
127 		}
128 		*mtod(m, int *) = tmp;
129 		m->m_len = sizeof(int);
130 	} else {
131 		m->m_len = size;
132 	}
133 }
134 
135 struct hpuxsetsockopt_args {
136 	int	s;
137 	int	level;
138 	int	name;
139 	caddr_t	val;
140 	int	valsize;
141 };
142 /* ARGSUSED */
143 hpuxsetsockopt(p, uap, retval)
144 	struct proc *p;
145 	struct hpuxsetsockopt_args *uap;
146 	int *retval;
147 {
148 	struct file *fp;
149 	struct mbuf *m = NULL;
150 	int tmp, error;
151 
152 	if (error = getsock(p->p_fd, uap->s, &fp))
153 		return (error);
154 	if (uap->valsize > MLEN)
155 		return (EINVAL);
156 	if (uap->val) {
157 		m = m_get(M_WAIT, MT_SOOPTS);
158 		if (m == NULL)
159 			return (ENOBUFS);
160 		if (error = copyin(uap->val, mtod(m, caddr_t),
161 		    (u_int)uap->valsize)) {
162 			(void) m_free(m);
163 			return (error);
164 		}
165 		if (uap->name == SO_LINGER) {
166 			tmp = *mtod(m, int *);
167 			mtod(m, struct linger *)->l_onoff = 1;
168 			mtod(m, struct linger *)->l_linger = tmp;
169 			m->m_len = sizeof(struct linger);
170 		} else
171 			socksetsize(uap->valsize, m);
172 	} else if (uap->name == ~SO_LINGER) {
173 		m = m_get(M_WAIT, MT_SOOPTS);
174 		if (m) {
175 			uap->name = SO_LINGER;
176 			mtod(m, struct linger *)->l_onoff = 0;
177 			m->m_len = sizeof(struct linger);
178 		}
179 	}
180 	return (sosetopt((struct socket *)fp->f_data, uap->level,
181 	    uap->name, m));
182 }
183 
184 struct hpuxsetsockopt2_args {
185 	int	s;
186 	int	level;
187 	int	name;
188 	caddr_t	val;
189 	int	valsize;
190 };
191 /* ARGSUSED */
192 hpuxsetsockopt2(p, uap, retval)
193 	struct proc *p;
194 	register struct hpuxsetsockopt2_args *uap;
195 	int *retval;
196 {
197 	struct file *fp;
198 	struct mbuf *m = NULL;
199 	int error;
200 
201 	if (error = getsock(p->p_fd, uap->s, &fp))
202 		return (error);
203 	if (uap->valsize > MLEN)
204 		return (EINVAL);
205 	if (uap->val) {
206 		m = m_get(M_WAIT, MT_SOOPTS);
207 		if (m == NULL)
208 			return (ENOBUFS);
209 		if (error = copyin(uap->val, mtod(m, caddr_t),
210 		    (u_int)uap->valsize)) {
211 			(void) m_free(m);
212 			return (error);
213 		}
214 		socksetsize(uap->valsize, m);
215 	}
216 	return (sosetopt((struct socket *)fp->f_data, uap->level,
217 	    uap->name, m));
218 }
219 
220 struct hpuxgetsockopt_args {
221 	int	s;
222 	int	level;
223 	int	name;
224 	caddr_t	val;
225 	int	*avalsize;
226 };
227 hpuxgetsockopt(p, uap, retval)
228 	struct proc *p;
229 	struct hpuxgetsockopt_args *uap;
230 	int *retval;
231 {
232 	struct file *fp;
233 	struct mbuf *m = NULL;
234 	int valsize, error;
235 
236 	if (error = getsock(p->p_fd, uap->s, &fp))
237 		return (error);
238 	if (uap->val) {
239 		if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
240 		    sizeof (valsize)))
241 			return (error);
242 	} else
243 		valsize = 0;
244 	if (error = sogetopt((struct socket *)fp->f_data, uap->level,
245 	    uap->name, &m))
246 		goto bad;
247 	if (uap->val && valsize && m != NULL) {
248 		if (uap->name == SO_LINGER) {
249 			if (mtod(m, struct linger *)->l_onoff)
250 				*mtod(m, int *) = mtod(m, struct linger *)->l_linger;
251 			else
252 				*mtod(m, int *) = 0;
253 			m->m_len = sizeof(int);
254 		}
255 		if (valsize > m->m_len)
256 			valsize = m->m_len;
257 		error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
258 		if (error == 0)
259 			error = copyout((caddr_t)&valsize,
260 			    (caddr_t)uap->avalsize, sizeof (valsize));
261 	}
262 bad:
263 	if (m != NULL)
264 		(void) m_free(m);
265 	return (error);
266 }
267 #endif
268