xref: /original-bsd/sys/hp/hpux/hpux_net.c (revision 2575fe00)
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.3 (Berkeley) 06/28/90
15  */
16 
17 /*
18  * Network related HP-UX compatibility routines
19  */
20 
21 #ifdef HPUXCOMPAT
22 
23 #include "param.h"
24 #include "systm.h"
25 #include "kernel.h"
26 #include "time.h"
27 #include "errno.h"
28 #include "proc.h"
29 #include "file.h"
30 #include "mbuf.h"
31 #include "socket.h"
32 #include "socketvar.h"
33 #include "uio.h"
34 #include "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(), accept(), connect(), orecv();
45 extern int osend(), shutdown(), getsockname(), sendto();
46 extern int recvfrom(), getpeername();
47 int hpuxgetsockopt(), hpuxsetsockopt();
48 struct file *getsock();
49 
50 struct hpuxtobsdipc {
51 	int (*rout)();
52 	int nargs;
53 } hpuxtobsdipc[NUMBSDIPC] = {
54 	socket,		3, /* 3ee */	listen,		2, /* 3ef */
55 	bind,		3, /* 3f0 */	accept,		3, /* 3f1 */
56 	connect,	3, /* 3f2 */	orecv,		4, /* 3f3 */
57 	osend,		4, /* 3f4 */	shutdown,	2, /* 3f5 */
58 	getsockname,	3, /* 3f6 */	hpuxsetsockopt,	5, /* 3f7 */
59 	sendto,		6, /* 3f8 */	recvfrom,	6, /* 3f9 */
60 	getpeername,	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 	fp = getsock(uap->s, &error);
125 	if (fp == 0)
126 		return (error);
127 	if (uap->valsize > MLEN)
128 		return (EINVAL);
129 	if (uap->val) {
130 		m = m_get(M_WAIT, MT_SOOPTS);
131 		if (m == NULL)
132 			return (ENOBUFS);
133 		if (error = copyin(uap->val, mtod(m, caddr_t),
134 		    (u_int)uap->valsize)) {
135 			(void) m_free(m);
136 			return (error);
137 		}
138 		if (uap->name == SO_LINGER) {
139 			tmp = *mtod(m, int *);
140 			mtod(m, struct linger *)->l_onoff = 1;
141 			mtod(m, struct linger *)->l_linger = tmp;
142 			m->m_len = sizeof(struct linger);
143 		} else
144 			m->m_len = uap->valsize;
145 	} else if (uap->name == ~SO_LINGER) {
146 		m = m_get(M_WAIT, MT_SOOPTS);
147 		if (m) {
148 			uap->name = SO_LINGER;
149 			mtod(m, struct linger *)->l_onoff = 0;
150 			m->m_len = sizeof(struct linger);
151 		}
152 	}
153 	return (sosetopt((struct socket *)fp->f_data, uap->level,
154 	    uap->name, m));
155 }
156 
157 hpuxgetsockopt(p, uap, retval)
158 	struct proc *p;
159 	struct args {
160 		int	s;
161 		int	level;
162 		int	name;
163 		caddr_t	val;
164 		int	*avalsize;
165 	} *uap;
166 	int *retval;
167 {
168 	struct file *fp;
169 	struct mbuf *m = NULL;
170 	int valsize, error;
171 
172 	fp = getsock(uap->s, &error);
173 	if (fp == 0)
174 		return (error);
175 	if (uap->val) {
176 		if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
177 		    sizeof (valsize)))
178 			return (error);
179 	} else
180 		valsize = 0;
181 	if (error = sogetopt((struct socket *)fp->f_data, uap->level,
182 	    uap->name, &m))
183 		goto bad;
184 	if (uap->val && valsize && m != NULL) {
185 		if (uap->name == SO_LINGER) {
186 			if (mtod(m, struct linger *)->l_onoff)
187 				*mtod(m, int *) = mtod(m, struct linger *)->l_linger;
188 			else
189 				*mtod(m, int *) = 0;
190 			m->m_len = sizeof(int);
191 		}
192 		if (valsize > m->m_len)
193 			valsize = m->m_len;
194 		error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
195 		if (error == 0)
196 			error = copyout((caddr_t)&valsize,
197 			    (caddr_t)uap->avalsize, sizeof (valsize));
198 	}
199 bad:
200 	if (m != NULL)
201 		(void) m_free(m);
202 	return (error);
203 }
204 #endif
205