xref: /csrg-svn/sys/hp/hpux/hpux_net.c (revision 41486)
1*41486Smckusick /*
2*41486Smckusick  * Copyright (c) 1988 University of Utah.
3*41486Smckusick  * Copyright (c) 1990 The Regents of the University of California.
4*41486Smckusick  * All rights reserved.
5*41486Smckusick  *
6*41486Smckusick  * This code is derived from software contributed to Berkeley by
7*41486Smckusick  * the Systems Programming Group of the University of Utah Computer
8*41486Smckusick  * Science Department.
9*41486Smckusick  *
10*41486Smckusick  * %sccs.include.redist.c%
11*41486Smckusick  *
12*41486Smckusick  * from: Utah $Hdr: hpux_net.c 1.33 89/08/23$
13*41486Smckusick  *
14*41486Smckusick  *	@(#)hpux_net.c	7.1 (Berkeley) 05/08/90
15*41486Smckusick  */
16*41486Smckusick 
17*41486Smckusick /*
18*41486Smckusick  * Network related HP-UX compatibility routines
19*41486Smckusick  */
20*41486Smckusick 
21*41486Smckusick #ifdef HPUXCOMPAT
22*41486Smckusick 
23*41486Smckusick #include "param.h"
24*41486Smckusick #include "systm.h"
25*41486Smckusick #include "user.h"
26*41486Smckusick #include "kernel.h"
27*41486Smckusick #include "proc.h"
28*41486Smckusick #include "file.h"
29*41486Smckusick #include "mbuf.h"
30*41486Smckusick #include "socket.h"
31*41486Smckusick #include "socketvar.h"
32*41486Smckusick #include "ktrace.h"
33*41486Smckusick #include "hpux.h"
34*41486Smckusick 
35*41486Smckusick #define MINBSDIPCCODE	0x3EE
36*41486Smckusick #define NUMBSDIPC	32
37*41486Smckusick 
38*41486Smckusick /*
39*41486Smckusick  * HPUX netioctl() to BSD syscall map.
40*41486Smckusick  * Indexed by callno - MINBSDIPCCODE
41*41486Smckusick  */
42*41486Smckusick extern int socket(), listen(), bind(), accept(), connect(), orecv();
43*41486Smckusick extern int osend(), shutdown(), getsockname(), sendto();
44*41486Smckusick extern int recvfrom(), getpeername();
45*41486Smckusick int hpuxgetsockopt(), hpuxsetsockopt();
46*41486Smckusick struct file *getsock();
47*41486Smckusick 
48*41486Smckusick struct hpuxtobsdipc {
49*41486Smckusick 	int (*rout)();
50*41486Smckusick 	int nargs;
51*41486Smckusick } hpuxtobsdipc[NUMBSDIPC] = {
52*41486Smckusick 	socket,		3, /* 3ee */	listen,		2, /* 3ef */
53*41486Smckusick 	bind,		3, /* 3f0 */	accept,		3, /* 3f1 */
54*41486Smckusick 	connect,	3, /* 3f2 */	orecv,		4, /* 3f3 */
55*41486Smckusick 	osend,		4, /* 3f4 */	shutdown,	2, /* 3f5 */
56*41486Smckusick 	getsockname,	3, /* 3f6 */	hpuxsetsockopt,	5, /* 3f7 */
57*41486Smckusick 	sendto,		6, /* 3f8 */	recvfrom,	6, /* 3f9 */
58*41486Smckusick 	getpeername,	3, /* 3fa */	NULL,		0, /* 3fb */
59*41486Smckusick 	NULL,		0, /* 3fc */	NULL,		0, /* 3fd */
60*41486Smckusick 	NULL,		0, /* 3fe */	NULL,		0, /* 3ff */
61*41486Smckusick 	NULL,		0, /* 400 */	NULL,		0, /* 401 */
62*41486Smckusick 	NULL,		0, /* 402 */	NULL,		0, /* 403 */
63*41486Smckusick 	NULL,		0, /* 404 */	NULL,		0, /* 405 */
64*41486Smckusick 	NULL,		0, /* 406 */	NULL,		0, /* 407 */
65*41486Smckusick 	NULL,		0, /* 408 */	NULL,		0, /* 409 */
66*41486Smckusick 	NULL,		0, /* 40a */	hpuxgetsockopt,	5, /* 40b */
67*41486Smckusick 	NULL,		0, /* 40c */	NULL,		0, /* 40d */
68*41486Smckusick };
69*41486Smckusick 
70*41486Smckusick /*
71*41486Smckusick  * Single system call entry to BSD style IPC.
72*41486Smckusick  * Gleened from disassembled libbsdipc.a syscall entries.
73*41486Smckusick  */
74*41486Smckusick hpuxnetioctl()
75*41486Smckusick {
76*41486Smckusick 	struct a {
77*41486Smckusick 		int	call;
78*41486Smckusick 		int	*args;
79*41486Smckusick 	} *uap = (struct a *)u.u_ap;
80*41486Smckusick 	int *args, i;
81*41486Smckusick 	register int code;
82*41486Smckusick 
83*41486Smckusick 	args = uap->args;
84*41486Smckusick 	code = uap->call - MINBSDIPCCODE;
85*41486Smckusick 	if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL) {
86*41486Smckusick 		u.u_error = EINVAL;
87*41486Smckusick 		return;
88*41486Smckusick 	}
89*41486Smckusick 	if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) &&
90*41486Smckusick 	    (u.u_error = copyin((caddr_t)args, (caddr_t)u.u_arg, (u_int)i))) {
91*41486Smckusick #ifdef KTRACE
92*41486Smckusick                 if (KTRPOINT(u.u_procp, KTR_SYSCALL))
93*41486Smckusick                         ktrsyscall(u.u_procp->p_tracep, code + MINBSDIPCCODE,
94*41486Smckusick 				   hpuxtobsdipc[code].nargs);
95*41486Smckusick #endif
96*41486Smckusick 		return;
97*41486Smckusick 	}
98*41486Smckusick #ifdef KTRACE
99*41486Smckusick         if (KTRPOINT(u.u_procp, KTR_SYSCALL))
100*41486Smckusick                 ktrsyscall(u.u_procp->p_tracep, code + MINBSDIPCCODE,
101*41486Smckusick 			   hpuxtobsdipc[code].nargs);
102*41486Smckusick #endif
103*41486Smckusick 	(*hpuxtobsdipc[code].rout)();
104*41486Smckusick }
105*41486Smckusick 
106*41486Smckusick hpuxsetsockopt()
107*41486Smckusick {
108*41486Smckusick 	struct a {
109*41486Smckusick 		int	s;
110*41486Smckusick 		int	level;
111*41486Smckusick 		int	name;
112*41486Smckusick 		caddr_t	val;
113*41486Smckusick 		int	valsize;
114*41486Smckusick 	} *uap = (struct a *)u.u_ap;
115*41486Smckusick 	struct file *fp;
116*41486Smckusick 	struct mbuf *m = NULL;
117*41486Smckusick 	int tmp;
118*41486Smckusick 
119*41486Smckusick 	fp = getsock(uap->s);
120*41486Smckusick 	if (fp == 0)
121*41486Smckusick 		return;
122*41486Smckusick 	if (uap->valsize > MLEN) {
123*41486Smckusick 		u.u_error = EINVAL;
124*41486Smckusick 		return;
125*41486Smckusick 	}
126*41486Smckusick 	if (uap->val) {
127*41486Smckusick 		m = m_get(M_WAIT, MT_SOOPTS);
128*41486Smckusick 		if (m == NULL) {
129*41486Smckusick 			u.u_error = ENOBUFS;
130*41486Smckusick 			return;
131*41486Smckusick 		}
132*41486Smckusick 		u.u_error =
133*41486Smckusick 		    copyin(uap->val, mtod(m, caddr_t), (u_int)uap->valsize);
134*41486Smckusick 		if (u.u_error) {
135*41486Smckusick 			(void) m_free(m);
136*41486Smckusick 			return;
137*41486Smckusick 		}
138*41486Smckusick 		if (uap->name == SO_LINGER) {
139*41486Smckusick 			tmp = *mtod(m, int *);
140*41486Smckusick 			mtod(m, struct linger *)->l_onoff = 1;
141*41486Smckusick 			mtod(m, struct linger *)->l_linger = tmp;
142*41486Smckusick 			m->m_len = sizeof(struct linger);
143*41486Smckusick 		} else
144*41486Smckusick 			m->m_len = uap->valsize;
145*41486Smckusick 	} else if (uap->name == ~SO_LINGER) {
146*41486Smckusick 		m = m_get(M_WAIT, MT_SOOPTS);
147*41486Smckusick 		if (m) {
148*41486Smckusick 			uap->name = SO_LINGER;
149*41486Smckusick 			mtod(m, struct linger *)->l_onoff = 0;
150*41486Smckusick 			m->m_len = sizeof(struct linger);
151*41486Smckusick 		}
152*41486Smckusick 	}
153*41486Smckusick 	u.u_error =
154*41486Smckusick 	    sosetopt((struct socket *)fp->f_data, uap->level, uap->name, m);
155*41486Smckusick }
156*41486Smckusick 
157*41486Smckusick hpuxgetsockopt()
158*41486Smckusick {
159*41486Smckusick 	struct a {
160*41486Smckusick 		int	s;
161*41486Smckusick 		int	level;
162*41486Smckusick 		int	name;
163*41486Smckusick 		caddr_t	val;
164*41486Smckusick 		int	*avalsize;
165*41486Smckusick 	} *uap = (struct a *)u.u_ap;
166*41486Smckusick 	struct file *fp;
167*41486Smckusick 	struct mbuf *m = NULL;
168*41486Smckusick 	int valsize;
169*41486Smckusick 
170*41486Smckusick 	fp = getsock(uap->s);
171*41486Smckusick 	if (fp == 0)
172*41486Smckusick 		return;
173*41486Smckusick 	if (uap->val) {
174*41486Smckusick 		u.u_error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
175*41486Smckusick 			sizeof (valsize));
176*41486Smckusick 		if (u.u_error)
177*41486Smckusick 			return;
178*41486Smckusick 	} else
179*41486Smckusick 		valsize = 0;
180*41486Smckusick 	u.u_error =
181*41486Smckusick 	    sogetopt((struct socket *)fp->f_data, uap->level, uap->name, &m);
182*41486Smckusick 	if (u.u_error)
183*41486Smckusick 		goto bad;
184*41486Smckusick 	if (uap->val && valsize && m != NULL) {
185*41486Smckusick 		if (uap->name == SO_LINGER) {
186*41486Smckusick 			if (mtod(m, struct linger *)->l_onoff)
187*41486Smckusick 				*mtod(m, int *) = mtod(m, struct linger *)->l_linger;
188*41486Smckusick 			else
189*41486Smckusick 				*mtod(m, int *) = 0;
190*41486Smckusick 			m->m_len = sizeof(int);
191*41486Smckusick 		}
192*41486Smckusick 		if (valsize > m->m_len)
193*41486Smckusick 			valsize = m->m_len;
194*41486Smckusick 		u.u_error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
195*41486Smckusick 		if (u.u_error)
196*41486Smckusick 			goto bad;
197*41486Smckusick 		u.u_error = copyout((caddr_t)&valsize, (caddr_t)uap->avalsize,
198*41486Smckusick 		    sizeof (valsize));
199*41486Smckusick 	}
200*41486Smckusick bad:
201*41486Smckusick 	if (m != NULL)
202*41486Smckusick 		(void) m_free(m);
203*41486Smckusick }
204*41486Smckusick #endif
205