xref: /original-bsd/sys/hp/hpux/hpux_net.c (revision 3b6250d9)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1990 The Regents of the University of California.
4  * 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.33 89/08/23$
13  *
14  *	@(#)hpux_net.c	7.7 (Berkeley) 02/13/91
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 #include "hpux.h"
36 
37 #define MINBSDIPCCODE	0x3EE
38 #define NUMBSDIPC	32
39 
40 /*
41  * HPUX netioctl() to BSD syscall map.
42  * Indexed by callno - MINBSDIPCCODE
43  */
44 extern int socket(), listen(), bind(), oaccept(), connect(), orecv();
45 extern int osend(), shutdown(), ogetsockname(), sendto();
46 extern int orecvfrom(), ogetpeername();
47 int hpuxgetsockopt(), hpuxsetsockopt();
48 
49 struct hpuxtobsdipc {
50 	int (*rout)();
51 	int nargs;
52 } hpuxtobsdipc[NUMBSDIPC] = {
53 	socket,		3, /* 3ee */	listen,		2, /* 3ef */
54 	bind,		3, /* 3f0 */	oaccept,	3, /* 3f1 */
55 	connect,	3, /* 3f2 */	orecv,		4, /* 3f3 */
56 	osend,		4, /* 3f4 */	shutdown,	2, /* 3f5 */
57 	ogetsockname,	3, /* 3f6 */	hpuxsetsockopt,	5, /* 3f7 */
58 	sendto,		6, /* 3f8 */	orecvfrom,	6, /* 3f9 */
59 	ogetpeername,	3, /* 3fa */	NULL,		0, /* 3fb */
60 	NULL,		0, /* 3fc */	NULL,		0, /* 3fd */
61 	NULL,		0, /* 3fe */	NULL,		0, /* 3ff */
62 	NULL,		0, /* 400 */	NULL,		0, /* 401 */
63 	NULL,		0, /* 402 */	NULL,		0, /* 403 */
64 	NULL,		0, /* 404 */	NULL,		0, /* 405 */
65 	NULL,		0, /* 406 */	NULL,		0, /* 407 */
66 	NULL,		0, /* 408 */	NULL,		0, /* 409 */
67 	NULL,		0, /* 40a */	hpuxgetsockopt,	5, /* 40b */
68 	NULL,		0, /* 40c */	NULL,		0, /* 40d */
69 };
70 
71 /*
72  * Single system call entry to BSD style IPC.
73  * Gleened from disassembled libbsdipc.a syscall entries.
74  */
75 hpuxnetioctl(p, uap, retval)
76 	struct proc *p;
77 	struct args {
78 		int	call;
79 		int	*args;
80 	} *uap;
81 	int *retval;
82 {
83 	int *args, i;
84 	register int code;
85 	int error;
86 
87 	args = uap->args;
88 	code = uap->call - MINBSDIPCCODE;
89 	if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL)
90 		return (EINVAL);
91 	if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) &&
92 	    (error = copyin((caddr_t)args, (caddr_t)uap, (u_int)i))) {
93 #ifdef KTRACE
94                 if (KTRPOINT(p, KTR_SYSCALL))
95                         ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
96 				   hpuxtobsdipc[code].nargs);
97 #endif
98 		return (error);
99 	}
100 #ifdef KTRACE
101         if (KTRPOINT(p, KTR_SYSCALL))
102                 ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
103 			   hpuxtobsdipc[code].nargs);
104 #endif
105 	return ((*hpuxtobsdipc[code].rout)(p, uap, retval));
106 }
107 
108 hpuxsetsockopt(p, uap, retval)
109 	struct proc *p;
110 	struct args {
111 		int	s;
112 		int	level;
113 		int	name;
114 		caddr_t	val;
115 		int	valsize;
116 	} *uap;
117 	int *retval;
118 {
119 	struct file *fp;
120 	struct mbuf *m = NULL;
121 	int tmp, error;
122 
123 	if (error = getsock(p->p_fd, uap->s, &fp))
124 		return (error);
125 	if (uap->valsize > MLEN)
126 		return (EINVAL);
127 	if (uap->val) {
128 		m = m_get(M_WAIT, MT_SOOPTS);
129 		if (m == NULL)
130 			return (ENOBUFS);
131 		if (error = copyin(uap->val, mtod(m, caddr_t),
132 		    (u_int)uap->valsize)) {
133 			(void) m_free(m);
134 			return (error);
135 		}
136 		if (uap->name == SO_LINGER) {
137 			tmp = *mtod(m, int *);
138 			mtod(m, struct linger *)->l_onoff = 1;
139 			mtod(m, struct linger *)->l_linger = tmp;
140 			m->m_len = sizeof(struct linger);
141 		} else
142 			m->m_len = uap->valsize;
143 	} else if (uap->name == ~SO_LINGER) {
144 		m = m_get(M_WAIT, MT_SOOPTS);
145 		if (m) {
146 			uap->name = SO_LINGER;
147 			mtod(m, struct linger *)->l_onoff = 0;
148 			m->m_len = sizeof(struct linger);
149 		}
150 	}
151 	return (sosetopt((struct socket *)fp->f_data, uap->level,
152 	    uap->name, m));
153 }
154 
155 hpuxgetsockopt(p, uap, retval)
156 	struct proc *p;
157 	struct args {
158 		int	s;
159 		int	level;
160 		int	name;
161 		caddr_t	val;
162 		int	*avalsize;
163 	} *uap;
164 	int *retval;
165 {
166 	struct file *fp;
167 	struct mbuf *m = NULL;
168 	int valsize, error;
169 
170 	if (error = getsock(p->p_fd, uap->s, &fp))
171 		return (error);
172 	if (uap->val) {
173 		if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
174 		    sizeof (valsize)))
175 			return (error);
176 	} else
177 		valsize = 0;
178 	if (error = sogetopt((struct socket *)fp->f_data, uap->level,
179 	    uap->name, &m))
180 		goto bad;
181 	if (uap->val && valsize && m != NULL) {
182 		if (uap->name == SO_LINGER) {
183 			if (mtod(m, struct linger *)->l_onoff)
184 				*mtod(m, int *) = mtod(m, struct linger *)->l_linger;
185 			else
186 				*mtod(m, int *) = 0;
187 			m->m_len = sizeof(int);
188 		}
189 		if (valsize > m->m_len)
190 			valsize = m->m_len;
191 		error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
192 		if (error == 0)
193 			error = copyout((caddr_t)&valsize,
194 			    (caddr_t)uap->avalsize, sizeof (valsize));
195 	}
196 bad:
197 	if (m != NULL)
198 		(void) m_free(m);
199 	return (error);
200 }
201 #endif
202