xref: /original-bsd/sys/hp/hpux/hpux_net.c (revision 6ee97357)
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.2 (Berkeley) 06/22/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 "syscontext.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(p, uap, retval)
75 	struct proc *p;
76 	struct args {
77 		int	call;
78 		int	*args;
79 	} *uap;
80 	int *retval;
81 {
82 	int *args, i;
83 	register int code;
84 	int error;
85 
86 	args = uap->args;
87 	code = uap->call - MINBSDIPCCODE;
88 	if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL)
89 		RETURN (EINVAL);
90 	if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) &&
91 	    (error = copyin((caddr_t)args, (caddr_t)uap, (u_int)i))) {
92 #ifdef KTRACE
93                 if (KTRPOINT(p, KTR_SYSCALL))
94                         ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
95 				   hpuxtobsdipc[code].nargs);
96 #endif
97 		RETURN (error);
98 	}
99 #ifdef KTRACE
100         if (KTRPOINT(p, KTR_SYSCALL))
101                 ktrsyscall(p->p_tracep, code + MINBSDIPCCODE,
102 			   hpuxtobsdipc[code].nargs);
103 #endif
104 	RETURN ((*hpuxtobsdipc[code].rout)(p, uap, retval));
105 }
106 
107 hpuxsetsockopt(p, uap, retval)
108 	struct proc *p;
109 	struct args {
110 		int	s;
111 		int	level;
112 		int	name;
113 		caddr_t	val;
114 		int	valsize;
115 	} *uap;
116 	int *retval;
117 {
118 	struct file *fp;
119 	struct mbuf *m = NULL;
120 	int tmp, error;
121 
122 	fp = getsock(uap->s, &error);
123 	if (fp == 0)
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 	fp = getsock(uap->s, &error);
171 	if (fp == 0)
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