xref: /original-bsd/sys/hp/hpux/hpux_net.c (revision be1f24e8)
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.8 (Berkeley) 10/11/92
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 hpuxnetioctl(p, uap, retval)
77 	struct proc *p;
78 	struct args {
79 		int	call;
80 		int	*args;
81 	} *uap;
82 	int *retval;
83 {
84 	int *args, i;
85 	register int code;
86 	int error;
87 
88 	args = uap->args;
89 	code = uap->call - MINBSDIPCCODE;
90 	if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL)
91 		return (EINVAL);
92 	if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) &&
93 	    (error = copyin((caddr_t)args, (caddr_t)uap, (u_int)i))) {
94 #ifdef KTRACE
95                 if (KTRPOINT(p, KTR_SYSCALL))
96                         ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
97 				   hpuxtobsdipc[code].nargs);
98 #endif
99 		return (error);
100 	}
101 #ifdef KTRACE
102         if (KTRPOINT(p, KTR_SYSCALL))
103                 ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
104 			   hpuxtobsdipc[code].nargs);
105 #endif
106 	return ((*hpuxtobsdipc[code].rout)(p, uap, retval));
107 }
108 
109 hpuxsetsockopt(p, uap, retval)
110 	struct proc *p;
111 	struct args {
112 		int	s;
113 		int	level;
114 		int	name;
115 		caddr_t	val;
116 		int	valsize;
117 	} *uap;
118 	int *retval;
119 {
120 	struct file *fp;
121 	struct mbuf *m = NULL;
122 	int tmp, error;
123 
124 	if (error = getsock(p->p_fd, uap->s, &fp))
125 		return (error);
126 	if (uap->valsize > MLEN)
127 		return (EINVAL);
128 	if (uap->val) {
129 		m = m_get(M_WAIT, MT_SOOPTS);
130 		if (m == NULL)
131 			return (ENOBUFS);
132 		if (error = copyin(uap->val, mtod(m, caddr_t),
133 		    (u_int)uap->valsize)) {
134 			(void) m_free(m);
135 			return (error);
136 		}
137 		if (uap->name == SO_LINGER) {
138 			tmp = *mtod(m, int *);
139 			mtod(m, struct linger *)->l_onoff = 1;
140 			mtod(m, struct linger *)->l_linger = tmp;
141 			m->m_len = sizeof(struct linger);
142 		} else
143 			m->m_len = uap->valsize;
144 	} else if (uap->name == ~SO_LINGER) {
145 		m = m_get(M_WAIT, MT_SOOPTS);
146 		if (m) {
147 			uap->name = SO_LINGER;
148 			mtod(m, struct linger *)->l_onoff = 0;
149 			m->m_len = sizeof(struct linger);
150 		}
151 	}
152 	return (sosetopt((struct socket *)fp->f_data, uap->level,
153 	    uap->name, m));
154 }
155 
156 hpuxgetsockopt(p, uap, retval)
157 	struct proc *p;
158 	struct args {
159 		int	s;
160 		int	level;
161 		int	name;
162 		caddr_t	val;
163 		int	*avalsize;
164 	} *uap;
165 	int *retval;
166 {
167 	struct file *fp;
168 	struct mbuf *m = NULL;
169 	int valsize, error;
170 
171 	if (error = getsock(p->p_fd, uap->s, &fp))
172 		return (error);
173 	if (uap->val) {
174 		if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
175 		    sizeof (valsize)))
176 			return (error);
177 	} else
178 		valsize = 0;
179 	if (error = sogetopt((struct socket *)fp->f_data, uap->level,
180 	    uap->name, &m))
181 		goto bad;
182 	if (uap->val && valsize && m != NULL) {
183 		if (uap->name == SO_LINGER) {
184 			if (mtod(m, struct linger *)->l_onoff)
185 				*mtod(m, int *) = mtod(m, struct linger *)->l_linger;
186 			else
187 				*mtod(m, int *) = 0;
188 			m->m_len = sizeof(int);
189 		}
190 		if (valsize > m->m_len)
191 			valsize = m->m_len;
192 		error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
193 		if (error == 0)
194 			error = copyout((caddr_t)&valsize,
195 			    (caddr_t)uap->avalsize, sizeof (valsize));
196 	}
197 bad:
198 	if (m != NULL)
199 		(void) m_free(m);
200 	return (error);
201 }
202 #endif
203