xref: /original-bsd/sys/hp/hpux/hpux_net.c (revision 2bd07fe6)
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.1 (Berkeley) 05/08/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 "user.h"
26 #include "kernel.h"
27 #include "proc.h"
28 #include "file.h"
29 #include "mbuf.h"
30 #include "socket.h"
31 #include "socketvar.h"
32 #include "ktrace.h"
33 #include "hpux.h"
34 
35 #define MINBSDIPCCODE	0x3EE
36 #define NUMBSDIPC	32
37 
38 /*
39  * HPUX netioctl() to BSD syscall map.
40  * Indexed by callno - MINBSDIPCCODE
41  */
42 extern int socket(), listen(), bind(), accept(), connect(), orecv();
43 extern int osend(), shutdown(), getsockname(), sendto();
44 extern int recvfrom(), getpeername();
45 int hpuxgetsockopt(), hpuxsetsockopt();
46 struct file *getsock();
47 
48 struct hpuxtobsdipc {
49 	int (*rout)();
50 	int nargs;
51 } hpuxtobsdipc[NUMBSDIPC] = {
52 	socket,		3, /* 3ee */	listen,		2, /* 3ef */
53 	bind,		3, /* 3f0 */	accept,		3, /* 3f1 */
54 	connect,	3, /* 3f2 */	orecv,		4, /* 3f3 */
55 	osend,		4, /* 3f4 */	shutdown,	2, /* 3f5 */
56 	getsockname,	3, /* 3f6 */	hpuxsetsockopt,	5, /* 3f7 */
57 	sendto,		6, /* 3f8 */	recvfrom,	6, /* 3f9 */
58 	getpeername,	3, /* 3fa */	NULL,		0, /* 3fb */
59 	NULL,		0, /* 3fc */	NULL,		0, /* 3fd */
60 	NULL,		0, /* 3fe */	NULL,		0, /* 3ff */
61 	NULL,		0, /* 400 */	NULL,		0, /* 401 */
62 	NULL,		0, /* 402 */	NULL,		0, /* 403 */
63 	NULL,		0, /* 404 */	NULL,		0, /* 405 */
64 	NULL,		0, /* 406 */	NULL,		0, /* 407 */
65 	NULL,		0, /* 408 */	NULL,		0, /* 409 */
66 	NULL,		0, /* 40a */	hpuxgetsockopt,	5, /* 40b */
67 	NULL,		0, /* 40c */	NULL,		0, /* 40d */
68 };
69 
70 /*
71  * Single system call entry to BSD style IPC.
72  * Gleened from disassembled libbsdipc.a syscall entries.
73  */
74 hpuxnetioctl()
75 {
76 	struct a {
77 		int	call;
78 		int	*args;
79 	} *uap = (struct a *)u.u_ap;
80 	int *args, i;
81 	register int code;
82 
83 	args = uap->args;
84 	code = uap->call - MINBSDIPCCODE;
85 	if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL) {
86 		u.u_error = EINVAL;
87 		return;
88 	}
89 	if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) &&
90 	    (u.u_error = copyin((caddr_t)args, (caddr_t)u.u_arg, (u_int)i))) {
91 #ifdef KTRACE
92                 if (KTRPOINT(u.u_procp, KTR_SYSCALL))
93                         ktrsyscall(u.u_procp->p_tracep, code + MINBSDIPCCODE,
94 				   hpuxtobsdipc[code].nargs);
95 #endif
96 		return;
97 	}
98 #ifdef KTRACE
99         if (KTRPOINT(u.u_procp, KTR_SYSCALL))
100                 ktrsyscall(u.u_procp->p_tracep, code + MINBSDIPCCODE,
101 			   hpuxtobsdipc[code].nargs);
102 #endif
103 	(*hpuxtobsdipc[code].rout)();
104 }
105 
106 hpuxsetsockopt()
107 {
108 	struct a {
109 		int	s;
110 		int	level;
111 		int	name;
112 		caddr_t	val;
113 		int	valsize;
114 	} *uap = (struct a *)u.u_ap;
115 	struct file *fp;
116 	struct mbuf *m = NULL;
117 	int tmp;
118 
119 	fp = getsock(uap->s);
120 	if (fp == 0)
121 		return;
122 	if (uap->valsize > MLEN) {
123 		u.u_error = EINVAL;
124 		return;
125 	}
126 	if (uap->val) {
127 		m = m_get(M_WAIT, MT_SOOPTS);
128 		if (m == NULL) {
129 			u.u_error = ENOBUFS;
130 			return;
131 		}
132 		u.u_error =
133 		    copyin(uap->val, mtod(m, caddr_t), (u_int)uap->valsize);
134 		if (u.u_error) {
135 			(void) m_free(m);
136 			return;
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 	u.u_error =
154 	    sosetopt((struct socket *)fp->f_data, uap->level, uap->name, m);
155 }
156 
157 hpuxgetsockopt()
158 {
159 	struct a {
160 		int	s;
161 		int	level;
162 		int	name;
163 		caddr_t	val;
164 		int	*avalsize;
165 	} *uap = (struct a *)u.u_ap;
166 	struct file *fp;
167 	struct mbuf *m = NULL;
168 	int valsize;
169 
170 	fp = getsock(uap->s);
171 	if (fp == 0)
172 		return;
173 	if (uap->val) {
174 		u.u_error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
175 			sizeof (valsize));
176 		if (u.u_error)
177 			return;
178 	} else
179 		valsize = 0;
180 	u.u_error =
181 	    sogetopt((struct socket *)fp->f_data, uap->level, uap->name, &m);
182 	if (u.u_error)
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 		u.u_error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize);
195 		if (u.u_error)
196 			goto bad;
197 		u.u_error = copyout((caddr_t)&valsize, (caddr_t)uap->avalsize,
198 		    sizeof (valsize));
199 	}
200 bad:
201 	if (m != NULL)
202 		(void) m_free(m);
203 }
204 #endif
205