xref: /csrg-svn/sys/hp/hpux/hpux_net.c (revision 57307)
141486Smckusick /*
241486Smckusick  * Copyright (c) 1988 University of Utah.
341486Smckusick  * Copyright (c) 1990 The Regents of the University of California.
441486Smckusick  * All rights reserved.
541486Smckusick  *
641486Smckusick  * This code is derived from software contributed to Berkeley by
741486Smckusick  * the Systems Programming Group of the University of Utah Computer
841486Smckusick  * Science Department.
941486Smckusick  *
1041486Smckusick  * %sccs.include.redist.c%
1141486Smckusick  *
12*57307Shibler  * from: Utah $Hdr: hpux_net.c 1.6 92/12/26$
1341486Smckusick  *
14*57307Shibler  *	@(#)hpux_net.c	7.9 (Berkeley) 12/27/92
1541486Smckusick  */
1641486Smckusick 
1741486Smckusick /*
1841486Smckusick  * Network related HP-UX compatibility routines
1941486Smckusick  */
2041486Smckusick 
2141486Smckusick #ifdef HPUXCOMPAT
2241486Smckusick 
2356506Sbostic #include <sys/param.h>
2456506Sbostic #include <sys/systm.h>
2556506Sbostic #include <sys/kernel.h>
2656506Sbostic #include <sys/time.h>
2756506Sbostic #include <sys/errno.h>
2856506Sbostic #include <sys/proc.h>
2956506Sbostic #include <sys/file.h>
3056506Sbostic #include <sys/mbuf.h>
3156506Sbostic #include <sys/socket.h>
3256506Sbostic #include <sys/socketvar.h>
3356506Sbostic #include <sys/uio.h>
3456506Sbostic #include <sys/ktrace.h>
3541486Smckusick 
3656506Sbostic #include <hp/hpux/hpux.h>
3756506Sbostic 
3841486Smckusick #define MINBSDIPCCODE	0x3EE
3941486Smckusick #define NUMBSDIPC	32
4041486Smckusick 
4141486Smckusick /*
4241486Smckusick  * HPUX netioctl() to BSD syscall map.
4341486Smckusick  * Indexed by callno - MINBSDIPCCODE
4441486Smckusick  */
4545054Skarels extern int socket(), listen(), bind(), oaccept(), connect(), orecv();
4645054Skarels extern int osend(), shutdown(), ogetsockname(), sendto();
4745054Skarels extern int orecvfrom(), ogetpeername();
4841486Smckusick int hpuxgetsockopt(), hpuxsetsockopt();
4941486Smckusick 
5041486Smckusick struct hpuxtobsdipc {
5141486Smckusick 	int (*rout)();
5241486Smckusick 	int nargs;
5341486Smckusick } hpuxtobsdipc[NUMBSDIPC] = {
5441486Smckusick 	socket,		3, /* 3ee */	listen,		2, /* 3ef */
5545054Skarels 	bind,		3, /* 3f0 */	oaccept,	3, /* 3f1 */
5641486Smckusick 	connect,	3, /* 3f2 */	orecv,		4, /* 3f3 */
5741486Smckusick 	osend,		4, /* 3f4 */	shutdown,	2, /* 3f5 */
5845054Skarels 	ogetsockname,	3, /* 3f6 */	hpuxsetsockopt,	5, /* 3f7 */
5945054Skarels 	sendto,		6, /* 3f8 */	orecvfrom,	6, /* 3f9 */
6045054Skarels 	ogetpeername,	3, /* 3fa */	NULL,		0, /* 3fb */
6141486Smckusick 	NULL,		0, /* 3fc */	NULL,		0, /* 3fd */
6241486Smckusick 	NULL,		0, /* 3fe */	NULL,		0, /* 3ff */
6341486Smckusick 	NULL,		0, /* 400 */	NULL,		0, /* 401 */
6441486Smckusick 	NULL,		0, /* 402 */	NULL,		0, /* 403 */
6541486Smckusick 	NULL,		0, /* 404 */	NULL,		0, /* 405 */
6641486Smckusick 	NULL,		0, /* 406 */	NULL,		0, /* 407 */
6741486Smckusick 	NULL,		0, /* 408 */	NULL,		0, /* 409 */
6841486Smckusick 	NULL,		0, /* 40a */	hpuxgetsockopt,	5, /* 40b */
6941486Smckusick 	NULL,		0, /* 40c */	NULL,		0, /* 40d */
7041486Smckusick };
7141486Smckusick 
7241486Smckusick /*
7341486Smckusick  * Single system call entry to BSD style IPC.
7441486Smckusick  * Gleened from disassembled libbsdipc.a syscall entries.
7541486Smckusick  */
76*57307Shibler struct hpuxnetioctl_args {
77*57307Shibler 	int	call;
78*57307Shibler 	int	*args;
79*57307Shibler };
8043453Shibler hpuxnetioctl(p, uap, retval)
8143453Shibler 	struct proc *p;
82*57307Shibler 	struct hpuxnetioctl_args *uap;
8343453Shibler 	int *retval;
8443453Shibler {
8541486Smckusick 	int *args, i;
8641486Smckusick 	register int code;
8743453Shibler 	int error;
8841486Smckusick 
8941486Smckusick 	args = uap->args;
9041486Smckusick 	code = uap->call - MINBSDIPCCODE;
9143453Shibler 	if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL)
9244421Skarels 		return (EINVAL);
9341486Smckusick 	if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) &&
9443453Shibler 	    (error = copyin((caddr_t)args, (caddr_t)uap, (u_int)i))) {
9541486Smckusick #ifdef KTRACE
9643453Shibler                 if (KTRPOINT(p, KTR_SYSCALL))
9743453Shibler                         ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
9841486Smckusick 				   hpuxtobsdipc[code].nargs);
9941486Smckusick #endif
10044421Skarels 		return (error);
10141486Smckusick 	}
10241486Smckusick #ifdef KTRACE
10343453Shibler         if (KTRPOINT(p, KTR_SYSCALL))
10443453Shibler                 ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
10541486Smckusick 			   hpuxtobsdipc[code].nargs);
10641486Smckusick #endif
10744421Skarels 	return ((*hpuxtobsdipc[code].rout)(p, uap, retval));
10841486Smckusick }
10941486Smckusick 
110*57307Shibler socksetsize(size, m)
111*57307Shibler 	int size;
112*57307Shibler 	struct mbuf *m;
113*57307Shibler {
114*57307Shibler 	register int tmp;
115*57307Shibler 
116*57307Shibler 	if (size < sizeof(int)) {
117*57307Shibler 		switch(size) {
118*57307Shibler 	    	case 1:
119*57307Shibler 			tmp = (int) *mtod(m, char *);
120*57307Shibler 			break;
121*57307Shibler 	    	case 2:
122*57307Shibler 			tmp = (int) *mtod(m, short *);
123*57307Shibler 			break;
124*57307Shibler 	    	case 3:
125*57307Shibler 			tmp = (((int) *mtod(m, int *)) >> 8) & 0xffffff;
126*57307Shibler 			break;
127*57307Shibler 		}
128*57307Shibler 		*mtod(m, int *) = tmp;
129*57307Shibler 		m->m_len = sizeof(int);
130*57307Shibler 	} else {
131*57307Shibler 		m->m_len = size;
132*57307Shibler 	}
133*57307Shibler }
134*57307Shibler 
135*57307Shibler struct hpuxsetsockopt_args {
136*57307Shibler 	int	s;
137*57307Shibler 	int	level;
138*57307Shibler 	int	name;
139*57307Shibler 	caddr_t	val;
140*57307Shibler 	int	valsize;
141*57307Shibler };
142*57307Shibler /* ARGSUSED */
14343453Shibler hpuxsetsockopt(p, uap, retval)
14443453Shibler 	struct proc *p;
145*57307Shibler 	struct hpuxsetsockopt_args *uap;
14643453Shibler 	int *retval;
14743453Shibler {
14841486Smckusick 	struct file *fp;
14941486Smckusick 	struct mbuf *m = NULL;
15043453Shibler 	int tmp, error;
15141486Smckusick 
15246403Smckusick 	if (error = getsock(p->p_fd, uap->s, &fp))
15344421Skarels 		return (error);
15443453Shibler 	if (uap->valsize > MLEN)
15544421Skarels 		return (EINVAL);
15641486Smckusick 	if (uap->val) {
15741486Smckusick 		m = m_get(M_WAIT, MT_SOOPTS);
15843453Shibler 		if (m == NULL)
15944421Skarels 			return (ENOBUFS);
16043453Shibler 		if (error = copyin(uap->val, mtod(m, caddr_t),
16143453Shibler 		    (u_int)uap->valsize)) {
16241486Smckusick 			(void) m_free(m);
16344421Skarels 			return (error);
16441486Smckusick 		}
16541486Smckusick 		if (uap->name == SO_LINGER) {
16641486Smckusick 			tmp = *mtod(m, int *);
16741486Smckusick 			mtod(m, struct linger *)->l_onoff = 1;
16841486Smckusick 			mtod(m, struct linger *)->l_linger = tmp;
16941486Smckusick 			m->m_len = sizeof(struct linger);
17041486Smckusick 		} else
171*57307Shibler 			socksetsize(uap->valsize, m);
17241486Smckusick 	} else if (uap->name == ~SO_LINGER) {
17341486Smckusick 		m = m_get(M_WAIT, MT_SOOPTS);
17441486Smckusick 		if (m) {
17541486Smckusick 			uap->name = SO_LINGER;
17641486Smckusick 			mtod(m, struct linger *)->l_onoff = 0;
17741486Smckusick 			m->m_len = sizeof(struct linger);
17841486Smckusick 		}
17941486Smckusick 	}
18044421Skarels 	return (sosetopt((struct socket *)fp->f_data, uap->level,
18143453Shibler 	    uap->name, m));
18241486Smckusick }
18341486Smckusick 
184*57307Shibler struct hpuxsetsockopt2_args {
185*57307Shibler 	int	s;
186*57307Shibler 	int	level;
187*57307Shibler 	int	name;
188*57307Shibler 	caddr_t	val;
189*57307Shibler 	int	valsize;
190*57307Shibler };
191*57307Shibler /* ARGSUSED */
192*57307Shibler hpuxsetsockopt2(p, uap, retval)
193*57307Shibler 	struct proc *p;
194*57307Shibler 	register struct hpuxsetsockopt2_args *uap;
195*57307Shibler 	int *retval;
196*57307Shibler {
197*57307Shibler 	struct file *fp;
198*57307Shibler 	struct mbuf *m = NULL;
199*57307Shibler 	int error;
200*57307Shibler 
201*57307Shibler 	if (error = getsock(p->p_fd, uap->s, &fp))
202*57307Shibler 		return (error);
203*57307Shibler 	if (uap->valsize > MLEN)
204*57307Shibler 		return (EINVAL);
205*57307Shibler 	if (uap->val) {
206*57307Shibler 		m = m_get(M_WAIT, MT_SOOPTS);
207*57307Shibler 		if (m == NULL)
208*57307Shibler 			return (ENOBUFS);
209*57307Shibler 		if (error = copyin(uap->val, mtod(m, caddr_t),
210*57307Shibler 		    (u_int)uap->valsize)) {
211*57307Shibler 			(void) m_free(m);
212*57307Shibler 			return (error);
213*57307Shibler 		}
214*57307Shibler 		socksetsize(uap->valsize, m);
215*57307Shibler 	}
216*57307Shibler 	return (sosetopt((struct socket *)fp->f_data, uap->level,
217*57307Shibler 	    uap->name, m));
218*57307Shibler }
219*57307Shibler 
220*57307Shibler struct hpuxgetsockopt_args {
221*57307Shibler 	int	s;
222*57307Shibler 	int	level;
223*57307Shibler 	int	name;
224*57307Shibler 	caddr_t	val;
225*57307Shibler 	int	*avalsize;
226*57307Shibler };
22743453Shibler hpuxgetsockopt(p, uap, retval)
22843453Shibler 	struct proc *p;
229*57307Shibler 	struct hpuxgetsockopt_args *uap;
23043453Shibler 	int *retval;
23143453Shibler {
23241486Smckusick 	struct file *fp;
23341486Smckusick 	struct mbuf *m = NULL;
23443453Shibler 	int valsize, error;
23541486Smckusick 
23646403Smckusick 	if (error = getsock(p->p_fd, uap->s, &fp))
23744421Skarels 		return (error);
23841486Smckusick 	if (uap->val) {
23943453Shibler 		if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
24043453Shibler 		    sizeof (valsize)))
24144421Skarels 			return (error);
24241486Smckusick 	} else
24341486Smckusick 		valsize = 0;
24443453Shibler 	if (error = sogetopt((struct socket *)fp->f_data, uap->level,
24543453Shibler 	    uap->name, &m))
24641486Smckusick 		goto bad;
24741486Smckusick 	if (uap->val && valsize && m != NULL) {
24841486Smckusick 		if (uap->name == SO_LINGER) {
24941486Smckusick 			if (mtod(m, struct linger *)->l_onoff)
25041486Smckusick 				*mtod(m, int *) = mtod(m, struct linger *)->l_linger;
25141486Smckusick 			else
25241486Smckusick 				*mtod(m, int *) = 0;
25341486Smckusick 			m->m_len = sizeof(int);
25441486Smckusick 		}
25541486Smckusick 		if (valsize > m->m_len)
25641486Smckusick 			valsize = m->m_len;
25743453Shibler 		error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
25843453Shibler 		if (error == 0)
25943453Shibler 			error = copyout((caddr_t)&valsize,
26043453Shibler 			    (caddr_t)uap->avalsize, sizeof (valsize));
26141486Smckusick 	}
26241486Smckusick bad:
26341486Smckusick 	if (m != NULL)
26441486Smckusick 		(void) m_free(m);
26544421Skarels 	return (error);
26641486Smckusick }
26741486Smckusick #endif
268