xref: /csrg-svn/sys/hp/hpux/hpux_net.c (revision 68374)
141486Smckusick /*
241486Smckusick  * Copyright (c) 1988 University of Utah.
363148Sbostic  * Copyright (c) 1990, 1993
463148Sbostic  *	The Regents of the University of California.  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  *
1264477Shibler  * from: Utah $Hdr: hpux_net.c 1.8 93/08/02$
1341486Smckusick  *
14*68374Scgd  *	@(#)hpux_net.c	8.3 (Berkeley) 02/19/95
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  */
45*68374Scgd extern int socket(), listen(), bind(), compat_43_accept(), connect();
46*68374Scgd extern int compat_43_recv(), compat_43_send(), shutdown();
47*68374Scgd extern int compat_43_getsockname(), sendto(), compat_43_recvfrom();
48*68374Scgd extern int compat_43_getpeername();
4941486Smckusick int hpuxgetsockopt(), hpuxsetsockopt();
5041486Smckusick 
5141486Smckusick struct hpuxtobsdipc {
5241486Smckusick 	int (*rout)();
5341486Smckusick 	int nargs;
5441486Smckusick } hpuxtobsdipc[NUMBSDIPC] = {
55*68374Scgd 	socket,		3, /* 3ee */		listen,		2, /* 3ef */
56*68374Scgd 	bind,		3, /* 3f0 */	compat_43_accept,	3, /* 3f1 */
57*68374Scgd 	connect,	3, /* 3f2 */	compat_43_recv,		4, /* 3f3 */
58*68374Scgd 	compat_43_send,		4, /* 3f4 */	shutdown,	2, /* 3f5 */
59*68374Scgd 	compat_43_getsockname,	3, /* 3f6 */	hpuxsetsockopt,	5, /* 3f7 */
60*68374Scgd 	sendto,		6, /* 3f8 */	compat_43_recvfrom,	6, /* 3f9 */
61*68374Scgd 	compat_43_getpeername,	3, /* 3fa */	NULL,		0, /* 3fb */
62*68374Scgd 	NULL,		0, /* 3fc */		NULL,		0, /* 3fd */
63*68374Scgd 	NULL,		0, /* 3fe */		NULL,		0, /* 3ff */
64*68374Scgd 	NULL,		0, /* 400 */		NULL,		0, /* 401 */
65*68374Scgd 	NULL,		0, /* 402 */		NULL,		0, /* 403 */
66*68374Scgd 	NULL,		0, /* 404 */		NULL,		0, /* 405 */
67*68374Scgd 	NULL,		0, /* 406 */		NULL,		0, /* 407 */
68*68374Scgd 	NULL,		0, /* 408 */		NULL,		0, /* 409 */
69*68374Scgd 	NULL,		0, /* 40a */		hpuxgetsockopt,	5, /* 40b */
70*68374Scgd 	NULL,		0, /* 40c */		NULL,		0, /* 40d */
7141486Smckusick };
7241486Smckusick 
7341486Smckusick /*
7441486Smckusick  * Single system call entry to BSD style IPC.
7541486Smckusick  * Gleened from disassembled libbsdipc.a syscall entries.
7641486Smckusick  */
7757307Shibler struct hpuxnetioctl_args {
7857307Shibler 	int	call;
7957307Shibler 	int	*args;
8057307Shibler };
8143453Shibler hpuxnetioctl(p, uap, retval)
8243453Shibler 	struct proc *p;
8357307Shibler 	struct hpuxnetioctl_args *uap;
8443453Shibler 	int *retval;
8543453Shibler {
8641486Smckusick 	int *args, i;
8741486Smckusick 	register int code;
8843453Shibler 	int error;
8941486Smckusick 
9041486Smckusick 	args = uap->args;
9141486Smckusick 	code = uap->call - MINBSDIPCCODE;
9243453Shibler 	if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL)
9344421Skarels 		return (EINVAL);
9441486Smckusick 	if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) &&
9543453Shibler 	    (error = copyin((caddr_t)args, (caddr_t)uap, (u_int)i))) {
9641486Smckusick #ifdef KTRACE
9743453Shibler                 if (KTRPOINT(p, KTR_SYSCALL))
9843453Shibler                         ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
9964477Shibler 				   hpuxtobsdipc[code].nargs, (int *)uap);
10041486Smckusick #endif
10144421Skarels 		return (error);
10241486Smckusick 	}
10341486Smckusick #ifdef KTRACE
10443453Shibler         if (KTRPOINT(p, KTR_SYSCALL))
10543453Shibler                 ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
10664477Shibler 			   hpuxtobsdipc[code].nargs, (int *)uap);
10741486Smckusick #endif
10844421Skarels 	return ((*hpuxtobsdipc[code].rout)(p, uap, retval));
10941486Smckusick }
11041486Smckusick 
socksetsize(size,m)11157307Shibler socksetsize(size, m)
11257307Shibler 	int size;
11357307Shibler 	struct mbuf *m;
11457307Shibler {
11557307Shibler 	register int tmp;
11657307Shibler 
11757307Shibler 	if (size < sizeof(int)) {
11857307Shibler 		switch(size) {
11957307Shibler 	    	case 1:
12057307Shibler 			tmp = (int) *mtod(m, char *);
12157307Shibler 			break;
12257307Shibler 	    	case 2:
12357307Shibler 			tmp = (int) *mtod(m, short *);
12457307Shibler 			break;
12557307Shibler 	    	case 3:
12657307Shibler 			tmp = (((int) *mtod(m, int *)) >> 8) & 0xffffff;
12757307Shibler 			break;
12857307Shibler 		}
12957307Shibler 		*mtod(m, int *) = tmp;
13057307Shibler 		m->m_len = sizeof(int);
13157307Shibler 	} else {
13257307Shibler 		m->m_len = size;
13357307Shibler 	}
13457307Shibler }
13557307Shibler 
13657307Shibler struct hpuxsetsockopt_args {
13757307Shibler 	int	s;
13857307Shibler 	int	level;
13957307Shibler 	int	name;
14057307Shibler 	caddr_t	val;
14157307Shibler 	int	valsize;
14257307Shibler };
14357307Shibler /* ARGSUSED */
14443453Shibler hpuxsetsockopt(p, uap, retval)
14543453Shibler 	struct proc *p;
14657307Shibler 	struct hpuxsetsockopt_args *uap;
14743453Shibler 	int *retval;
14843453Shibler {
14941486Smckusick 	struct file *fp;
15041486Smckusick 	struct mbuf *m = NULL;
15143453Shibler 	int tmp, error;
15241486Smckusick 
15346403Smckusick 	if (error = getsock(p->p_fd, uap->s, &fp))
15444421Skarels 		return (error);
15543453Shibler 	if (uap->valsize > MLEN)
15644421Skarels 		return (EINVAL);
15741486Smckusick 	if (uap->val) {
15841486Smckusick 		m = m_get(M_WAIT, MT_SOOPTS);
15943453Shibler 		if (m == NULL)
16044421Skarels 			return (ENOBUFS);
16143453Shibler 		if (error = copyin(uap->val, mtod(m, caddr_t),
16243453Shibler 		    (u_int)uap->valsize)) {
16341486Smckusick 			(void) m_free(m);
16444421Skarels 			return (error);
16541486Smckusick 		}
16641486Smckusick 		if (uap->name == SO_LINGER) {
16741486Smckusick 			tmp = *mtod(m, int *);
16841486Smckusick 			mtod(m, struct linger *)->l_onoff = 1;
16941486Smckusick 			mtod(m, struct linger *)->l_linger = tmp;
17041486Smckusick 			m->m_len = sizeof(struct linger);
17141486Smckusick 		} else
17257307Shibler 			socksetsize(uap->valsize, m);
17341486Smckusick 	} else if (uap->name == ~SO_LINGER) {
17441486Smckusick 		m = m_get(M_WAIT, MT_SOOPTS);
17541486Smckusick 		if (m) {
17641486Smckusick 			uap->name = SO_LINGER;
17741486Smckusick 			mtod(m, struct linger *)->l_onoff = 0;
17841486Smckusick 			m->m_len = sizeof(struct linger);
17941486Smckusick 		}
18041486Smckusick 	}
18144421Skarels 	return (sosetopt((struct socket *)fp->f_data, uap->level,
18243453Shibler 	    uap->name, m));
18341486Smckusick }
18441486Smckusick 
18557307Shibler struct hpuxsetsockopt2_args {
18657307Shibler 	int	s;
18757307Shibler 	int	level;
18857307Shibler 	int	name;
18957307Shibler 	caddr_t	val;
19057307Shibler 	int	valsize;
19157307Shibler };
19257307Shibler /* ARGSUSED */
19357307Shibler hpuxsetsockopt2(p, uap, retval)
19457307Shibler 	struct proc *p;
19557307Shibler 	register struct hpuxsetsockopt2_args *uap;
19657307Shibler 	int *retval;
19757307Shibler {
19857307Shibler 	struct file *fp;
19957307Shibler 	struct mbuf *m = NULL;
20057307Shibler 	int error;
20157307Shibler 
20257307Shibler 	if (error = getsock(p->p_fd, uap->s, &fp))
20357307Shibler 		return (error);
20457307Shibler 	if (uap->valsize > MLEN)
20557307Shibler 		return (EINVAL);
20657307Shibler 	if (uap->val) {
20757307Shibler 		m = m_get(M_WAIT, MT_SOOPTS);
20857307Shibler 		if (m == NULL)
20957307Shibler 			return (ENOBUFS);
21057307Shibler 		if (error = copyin(uap->val, mtod(m, caddr_t),
21157307Shibler 		    (u_int)uap->valsize)) {
21257307Shibler 			(void) m_free(m);
21357307Shibler 			return (error);
21457307Shibler 		}
21557307Shibler 		socksetsize(uap->valsize, m);
21657307Shibler 	}
21757307Shibler 	return (sosetopt((struct socket *)fp->f_data, uap->level,
21857307Shibler 	    uap->name, m));
21957307Shibler }
22057307Shibler 
22157307Shibler struct hpuxgetsockopt_args {
22257307Shibler 	int	s;
22357307Shibler 	int	level;
22457307Shibler 	int	name;
22557307Shibler 	caddr_t	val;
22657307Shibler 	int	*avalsize;
22757307Shibler };
22843453Shibler hpuxgetsockopt(p, uap, retval)
22943453Shibler 	struct proc *p;
23057307Shibler 	struct hpuxgetsockopt_args *uap;
23143453Shibler 	int *retval;
23243453Shibler {
23341486Smckusick 	struct file *fp;
23441486Smckusick 	struct mbuf *m = NULL;
23543453Shibler 	int valsize, error;
23641486Smckusick 
23746403Smckusick 	if (error = getsock(p->p_fd, uap->s, &fp))
23844421Skarels 		return (error);
23941486Smckusick 	if (uap->val) {
24043453Shibler 		if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
24143453Shibler 		    sizeof (valsize)))
24244421Skarels 			return (error);
24341486Smckusick 	} else
24441486Smckusick 		valsize = 0;
24543453Shibler 	if (error = sogetopt((struct socket *)fp->f_data, uap->level,
24643453Shibler 	    uap->name, &m))
24741486Smckusick 		goto bad;
24841486Smckusick 	if (uap->val && valsize && m != NULL) {
24941486Smckusick 		if (uap->name == SO_LINGER) {
25041486Smckusick 			if (mtod(m, struct linger *)->l_onoff)
25141486Smckusick 				*mtod(m, int *) = mtod(m, struct linger *)->l_linger;
25241486Smckusick 			else
25341486Smckusick 				*mtod(m, int *) = 0;
25441486Smckusick 			m->m_len = sizeof(int);
25541486Smckusick 		}
25641486Smckusick 		if (valsize > m->m_len)
25741486Smckusick 			valsize = m->m_len;
25843453Shibler 		error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
25943453Shibler 		if (error == 0)
26043453Shibler 			error = copyout((caddr_t)&valsize,
26143453Shibler 			    (caddr_t)uap->avalsize, sizeof (valsize));
26241486Smckusick 	}
26341486Smckusick bad:
26441486Smckusick 	if (m != NULL)
26541486Smckusick 		(void) m_free(m);
26644421Skarels 	return (error);
26741486Smckusick }
26841486Smckusick #endif
269