Deleted Added
full compact
ibcs2_socksys.c (3672) ibcs2_socksys.c (8876)
1/*-
2 * Copyright (c) 1994 Mostyn Lewis
3 * All rights reserved.
4 *
5 * This software is based on code which is:
6 * Copyright (c) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer
13 * in this position and unchanged.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software withough specific prior written permission
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
1/*-
2 * Copyright (c) 1994 Mostyn Lewis
3 * All rights reserved.
4 *
5 * This software is based on code which is:
6 * Copyright (c) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer
13 * in this position and unchanged.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software withough specific prior written permission
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * $Id: ibcs2_socksys.c,v 1.1 1994/10/14 08:53:08 sos Exp $
31 * $Id: ibcs2_socksys.c,v 1.2 1994/10/17 22:13:08 sos Exp $
32 */
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/filedesc.h>
37#include <sys/file.h>
38#include <sys/kernel.h>
39#include <sys/mbuf.h>
40#include <sys/protosw.h>
41#include <sys/socket.h>
42#include <sys/socketvar.h>
43#include <sys/ioctl.h>
44#include <sys/sockio.h>
45#include <sys/proc.h>
46#include <sys/exec.h>
47#include <sys/stat.h>
48#include <sys/syscall.h>
49#include <sys/sysent.h>
50#include <sys/malloc.h>
51#include <sys/un.h>
52#include <net/if.h>
53#include <net/if_arp.h>
54#include <net/route.h>
55#include <netinet/in.h>
56#include <vm/vm.h>
57#include <i386/ibcs2/ibcs2.h>
58#include <i386/ibcs2/ibcs2_socksys.h>
59
60/* Socksys pseudo driver entry points */
61
62int sockopen (dev_t dev, int mode, int devtype, struct proc *p);
63int sockioctl(dev_t dev, int cmd, caddr_t arg, int fflag, struct proc *p);
64int sockclose(dev_t dev, int flag, int mode, struct proc *p);
65
66/* Socksys internal functions */
67
68static void put_socket_fops(struct proc *p, int fd);
69static int ss_fop_close(struct file *fp, struct proc *p);
70static int ss_fop_ioctl(struct file*fp, int cmd, caddr_t arg, struct proc *p);
71static int ss_syscall(caddr_t arg, struct proc *p);
72
73/*
74 * This structure is setup on first usage. Its address is planted
75 * into a socket's file structure fileops pointer after a successful
76 * socket creation or accept.
77 */
78static struct fileops ss_socket_fops = {
79 NULL, /* normal socket read */
80 NULL, /* normal socket write */
81 NULL, /* socksys ioctl */
82 NULL, /* normal socket select */
83 NULL, /* socksys close */
84};
85
86static int (*close_s)__P((struct file *fp, struct proc *p));
87static int (*ioctl_s)__P((struct file *fp, int cmd, caddr_t data, struct proc *p));
88
89int ss_debug = 10;
90
91static int
92ss_syscall(arg, p)
93 caddr_t arg;
94 struct proc *p;
95{
96 int cmd;
97 int error;
98 int retval[2];
99
100 retval[0] = retval[1] = 0;
101 cmd = ((struct ss_call *)arg)->arg[0];
102
103 if(ss_debug) {
104 static char *ss_syscall_strings[] = {
105 "0?", "accept", "bind", "connect", "getpeername",
106 "getsockname", "getsockopt", "listen", "recv(from)",
107 "recvfrom", "send(to)", "sendto", "setsockopt", "shutdown",
108 "socket", "select", "getipdomain", "setipdomain",
109 "adjtime", "setreuid", "setregid", "gettimeofday",
110 "settimeofday", "getitimer", "setitimer",
111 };
112
113 printf("ss_syscall: [%d] ",p->p_pid);
114 if(cmd < 0 || (cmd > CMD_SO_SETITIMER && cmd != CMD_SO_SS_DEBUG) )
115 printf("? ");
116 else {
117 if(cmd == CMD_SO_SS_DEBUG)
118 printf("%s ","ss_debug");
32 */
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/filedesc.h>
37#include <sys/file.h>
38#include <sys/kernel.h>
39#include <sys/mbuf.h>
40#include <sys/protosw.h>
41#include <sys/socket.h>
42#include <sys/socketvar.h>
43#include <sys/ioctl.h>
44#include <sys/sockio.h>
45#include <sys/proc.h>
46#include <sys/exec.h>
47#include <sys/stat.h>
48#include <sys/syscall.h>
49#include <sys/sysent.h>
50#include <sys/malloc.h>
51#include <sys/un.h>
52#include <net/if.h>
53#include <net/if_arp.h>
54#include <net/route.h>
55#include <netinet/in.h>
56#include <vm/vm.h>
57#include <i386/ibcs2/ibcs2.h>
58#include <i386/ibcs2/ibcs2_socksys.h>
59
60/* Socksys pseudo driver entry points */
61
62int sockopen (dev_t dev, int mode, int devtype, struct proc *p);
63int sockioctl(dev_t dev, int cmd, caddr_t arg, int fflag, struct proc *p);
64int sockclose(dev_t dev, int flag, int mode, struct proc *p);
65
66/* Socksys internal functions */
67
68static void put_socket_fops(struct proc *p, int fd);
69static int ss_fop_close(struct file *fp, struct proc *p);
70static int ss_fop_ioctl(struct file*fp, int cmd, caddr_t arg, struct proc *p);
71static int ss_syscall(caddr_t arg, struct proc *p);
72
73/*
74 * This structure is setup on first usage. Its address is planted
75 * into a socket's file structure fileops pointer after a successful
76 * socket creation or accept.
77 */
78static struct fileops ss_socket_fops = {
79 NULL, /* normal socket read */
80 NULL, /* normal socket write */
81 NULL, /* socksys ioctl */
82 NULL, /* normal socket select */
83 NULL, /* socksys close */
84};
85
86static int (*close_s)__P((struct file *fp, struct proc *p));
87static int (*ioctl_s)__P((struct file *fp, int cmd, caddr_t data, struct proc *p));
88
89int ss_debug = 10;
90
91static int
92ss_syscall(arg, p)
93 caddr_t arg;
94 struct proc *p;
95{
96 int cmd;
97 int error;
98 int retval[2];
99
100 retval[0] = retval[1] = 0;
101 cmd = ((struct ss_call *)arg)->arg[0];
102
103 if(ss_debug) {
104 static char *ss_syscall_strings[] = {
105 "0?", "accept", "bind", "connect", "getpeername",
106 "getsockname", "getsockopt", "listen", "recv(from)",
107 "recvfrom", "send(to)", "sendto", "setsockopt", "shutdown",
108 "socket", "select", "getipdomain", "setipdomain",
109 "adjtime", "setreuid", "setregid", "gettimeofday",
110 "settimeofday", "getitimer", "setitimer",
111 };
112
113 printf("ss_syscall: [%d] ",p->p_pid);
114 if(cmd < 0 || (cmd > CMD_SO_SETITIMER && cmd != CMD_SO_SS_DEBUG) )
115 printf("? ");
116 else {
117 if(cmd == CMD_SO_SS_DEBUG)
118 printf("%s ","ss_debug");
119 else
119 else
120 printf("%s ",ss_syscall_strings[cmd]);
121 }
122 printf("(%d) <0x%x,0x%x,0x%x,0x%x,0x%x,0x%x>\n",
123 cmd,
124 ((struct ss_call *)arg)->arg[1],
125 ((struct ss_call *)arg)->arg[2],
126 ((struct ss_call *)arg)->arg[3],
127 ((struct ss_call *)arg)->arg[4],
128 ((struct ss_call *)arg)->arg[5],
129 ((struct ss_call *)arg)->arg[6]);
130 }
131
132 error = 0;
133
134 switch (cmd) {
135
136 case CMD_SO_SS_DEBUG:
137
138 /* ss_debug = ((struct ss_call *)arg)->arg[1]; */
139 break;
140
141 case CMD_SO_SOCKET: { /* NO CONV */
142
143 if(ss_debug > 1)
144 printf("SO_SOCKET af in %d\n",
145 ((struct ss_call *)arg)->arg[1]);
146 ((struct ss_call *)arg)->arg[1] = ss_convert(
147 af_whatevers,
148 &(((struct ss_call *)arg)->arg[1]),
149 0);
150 if(ss_debug > 1) {
151 printf("SO_SOCKET af out %d\n",
152 ((struct ss_call *)arg)->arg[1]);
153
154 printf("SO_SOCKET type in %d\n",
155 ((struct ss_call *)arg)->arg[2]);
156 }
157 ((struct ss_call *)arg)->arg[2] = ss_convert(
158 type_whatevers,
159 &(((struct ss_call *)arg)->arg[2]),
160 0);
161 if(ss_debug > 1)
162 printf("SO_SOCKET type out %d\n",
163 ((struct ss_call *)arg)->arg[2]);
164
165 SYSCALL(SYS_socket, 0, 0);
166
167 if(ss_debug)
168 printf("ss_syscall: [%d] socket fd=%d\n",
169 p->p_pid, retval[0]);
170 put_socket_fops(p,retval[0]);
171
172 break;
173 }
174
175 case CMD_SO_ACCEPT: { /* CONVERSION in arg 2 */
176
177 SYSCALL(SYS_accept, 2, SS_STRUCT_SOCKADDR);
178
179 if(ss_debug)
180 printf("ss_syscall: [%d] accept fd=%d\n",
181 p->p_pid, retval[0]);
182 put_socket_fops(p,retval[0]);
183
184 break;
185 }
186
187 case CMD_SO_BIND:
188 SYSCALL(SYS_bind, 2, SS_STRUCT_SOCKADDR);
189 break;
190
191 case CMD_SO_CONNECT: {
192 struct alien_sockaddr *sa;
193 unsigned short family;
194
195 /* Remap any INADDR_ANY (0.0.0.0) to localhost */
196
197 sa = (struct alien_sockaddr *)((struct ss_call *)arg)->arg[1];
198 if(error = copyin((caddr_t)&sa->sa_family,
199 (caddr_t)&family, sizeof(short)))
200 return(error);
201 if (family == AF_INET) {
202 unsigned long *addr;
203 unsigned long saddr;
204
205 addr = &(((struct alien_sockaddr_in *)sa)->sin_addr.s_addr);
206 if(error = copyin((caddr_t)addr, (caddr_t)&saddr, sizeof(long)))
207 return(error);
208 if (saddr == INADDR_ANY) {
209 /* 0x0100007f is 127.0.0.1 reversed */
210 saddr = 0x0100007f;
211 if(error = copyout((caddr_t)&saddr,
212 (caddr_t)addr, sizeof(long)))
213 return(error);
214 if (ss_debug)
215 printf("ss_syscall: remapped INADDR_ANY to localhost\n");
216 }
217 }
218 SYSCALL(SYS_connect, 2, SS_STRUCT_SOCKADDR);
219 break;
220 }
221
222 case CMD_SO_GETPEERNAME:
223 SYSCALL(SYS_getpeername, 2, SS_STRUCT_SOCKADDR);
224 break;
225
226 case CMD_SO_GETSOCKNAME:
227 SYSCALL(SYS_getsockname, 2, SS_STRUCT_SOCKADDR);
228 break;
229
230 case CMD_SO_GETSOCKOPT:
231 if(error = ss_getsockopt((caddr_t)(((int *)arg) + 1),retval,p))
232 return(error);
233 break;
234
235 case CMD_SO_LISTEN:
236 SYSCALL(SYS_listen, 0, 0);
237 break;
238
239 case CMD_SO_RECV:
240 ((struct ss_call *)arg)->arg[5] = (int)((struct sockaddr *)NULL);
241 ((struct ss_call *)arg)->arg[6] = 0;
242 SYSCALL(SYS_recvfrom, 0, 0);
243 break;
244
245 case CMD_SO_RECVFROM:
246 SYSCALL(SYS_recvfrom, 5, SS_STRUCT_SOCKADDR);
247 break;
248
249 case CMD_SO_SEND:
250 ((struct ss_call *)arg)->arg[5] = (int)((struct sockaddr *)NULL);
251 ((struct ss_call *)arg)->arg[6] = 0;
252 SYSCALL(SYS_sendto, 0, 0);
253 break;
254
255 case CMD_SO_SENDTO:
256 SYSCALL(SYS_sendto, 5, SS_STRUCT_SOCKADDR);
257 break;
258
259 case CMD_SO_SETSOCKOPT:
260 if(error = ss_setsockopt((caddr_t)(((int *)arg) + 1),retval,p))
261 return(error);
262
263 case CMD_SO_SHUTDOWN:
264 SYSCALL(SYS_shutdown, 0, 0);
265 break;
266
267 case CMD_SO_GETIPDOMAIN:
268 SYSCALL(SYS_getdomainname, 0, 0);
269 break;
270
271 case CMD_SO_SETIPDOMAIN: /* Note check on BSD utsname no change? */
272 SYSCALL(SYS_setdomainname, 0, 0);
273 break;
274
275 case CMD_SO_SETREUID:
276 SYSCALL(126/*SYS_setreuid*/, 0, 0);
277 break;
278
279 case CMD_SO_SETREGID:
280 SYSCALL(127/*SYS_setregid*/, 0, 0);
281 break;
282
283 case CMD_SO_GETTIME:
284 SYSCALL(SYS_gettimeofday, 0, 0);
285 break;
286
287 case CMD_SO_SETTIME:
288 SYSCALL(SYS_settimeofday, 0, 0);
289 break;
290
291 case CMD_SO_GETITIMER:
292 SYSCALL(SYS_getitimer, 0, 0);
293 break;
294
295 case CMD_SO_SETITIMER:
296 SYSCALL(SYS_setitimer, 0, 0);
297 break;
298
299 case CMD_SO_SELECT:
300 SYSCALL(SYS_select, 0, 0);
301 break;
302
303 case CMD_SO_ADJTIME:
304 SYSCALL(SYS_adjtime, 0, 0);
305 break;
306
307 default:
308 printf("ss_syscall: default 0x%x\n",cmd);
309 return (EINVAL);
310 }
311 IBCS2_MAGIC_RETURN(arg);
312}
313
314
315static int
316ss_fop_ioctl(fp, cmd, arg, p)
317 struct file *fp;
318 int cmd;
319 caddr_t arg;
320 struct proc *p;
321{
322 int error;
323 int retval[2];
324
325 if(ss_debug) {
326 static char **ioctl_strings;
327 int fd;
328 struct filedesc *fdp;
329 unsigned int ioctl_type;
330 unsigned int ioctl_len;
331 char cmd_type;
332 int cmd_ordinal;
333
334 static char *ioctl_type_strings[] = {
335 "0?", "SS_IO", "SS_IOR", "3?", "SS_IOW", "5?", "SS_IOWR"
336 };
337 static char *ioctl_S_strings[] = {
338 "0?", "SIOCSHIWAT", "SIOCGHIWAT", "SIOCSLOWAT", "SIOCGLOWAT",
339 "SIOCATMARK", "SIOCSPGRP", "SIOCGPGRP", "FIONREAD",
340 "FIONBIO", "FIOASYNC", "SIOCPROTO", "SIOCGETNAME",
341 "SIOCGETPEER", "IF_UNITSEL", "SIOCXPROTO"
342 };
343 static char *ioctl_R_strings[] = {
344 "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?",
345 "SIOCADDRT", "SIOCDELRT"
346 };
347 static char *ioctl_I_strings[] = {
348 "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?",
349 "9?", "10?", "SIOCSIFADDR", "SIOCGIFADDR", "SIOCSIFDSTADDR",
350 "SIOCGIFDSTADDR", "SIOCSIFFLAGS", "SIOCGIFFLAGS",
351 "SIOCGIFCONF", "18?", "19?", "20?", "SIOCSIFMTU",
352 "SIOCGIFMTU", "23?", "24?", "25?", "SIOCIFDETACH",
353 "SIOCGENPSTATS", "28?", "SIOCX25XMT", "SS_SIOCX25RCV",
354 "SS_SIOCX25TBL", "SIOCGIFBRDADDR" ,"SIOCSIFBRDADDR",
355 "SIOCGIFNETMASK", "SIOCSIFNETMASK", "SIOCGIFMETRIC",
356 "SIOCSIFMETRIC", "SIOCSARP", "SIOCGARP", "SIOCDARP",
357 "SIOCSIFNAME", "SIOCGIFONEP", "SIOCSIFONEP ",
358 "44?", "45?", "46?", "47?", "48?", "49?", "50?", "51?",
359 "52?", "53?", "54?", "55?", "56?", "57?", "58?", "59?",
360 "60?", "61?", "62?", "63?", "64?", "SIOCGENADDR",
361 "SIOCSOCKSYS"
362 };
363
364 cmd_type = (cmd >> 8) & 0xff;
365 cmd_ordinal = cmd & 0xff;
366
367 switch (cmd_type) {
368
369 case 'S':
370 ioctl_strings = ioctl_S_strings;
371 if (cmd_ordinal > 15)
372 cmd_ordinal = -1;
373 break;
374
375 case 'R':
376 ioctl_strings = ioctl_R_strings;
377 if (cmd_ordinal > 10)
378 cmd_ordinal = -1;
379 break;
380
381 case 'I':
382 ioctl_strings = ioctl_I_strings;
383 if (cmd_ordinal > 66)
384 cmd_ordinal = -1;
385 break;
386
387 default:
388 cmd_type = '?';
389 break;
390 }
391 fdp = p->p_fd;
392 fd = -1;
393 while(++fd < NOFILE)
394 if ( fp == fdp->fd_ofiles[fd] )
395 break;
396
397 ioctl_type = (0xe0000000 & cmd) >> 29;
398 ioctl_len = (cmd >> 16) & SS_IOCPARM_MASK;
399
400 printf("ss_fop_ioctl: [%d] fd=%d ",p->p_pid, fd);
401 if(cmd_type != '?'){
402 if(cmd_ordinal != -1)
403 printf("%s %s('%c',%d,l=%d) ",ioctl_strings[cmd_ordinal],
404 ioctl_type_strings[ioctl_type],
405 cmd_type,
406 cmd_ordinal,
407 ioctl_len);
408 else {
409 cmd_ordinal = cmd & 0xff;
410 printf("[unknown ordinal %d] %s('%c',%d,l=%d) ",cmd_ordinal,
411 ioctl_type_strings[ioctl_type],
412 cmd_type,
413 cmd_ordinal,
414 ioctl_len);
415 }
416 }
417 else {
418 printf("? %s('%c',%d,l=%d) ",
419 ioctl_type_strings[ioctl_type],
420 cmd_type,
421 cmd_ordinal,
422 ioctl_len);
423 }
424
425 printf("0x%x (0x%x) <0x%x>\n",
426 fp, cmd, arg);
427 }
428
429 /* No dogs allowed */
430
431 if(*(((int *)arg) - 3) != IBCS2_MAGIC_IN){
432 printf("ss_fop_ioctl: bad magic (sys_generic.c has no socksys mods?)\n");
433 return(EINVAL);
434 }
435
436 if(fp->f_type != DTYPE_SOCKET)
437 return (ENOTSOCK);
438
439 retval[0] = retval[1] = 0;
440
441
442 error = 0;
443
444 switch (cmd) {
445 case SS_SIOCSOCKSYS: /* ss syscall */
446 return ss_syscall(arg, p);
447
448 case SS_SIOCSHIWAT: /* set high watermark */
449 case SS_SIOCSLOWAT: /* set low watermark */
450 break; /* return value of 0 and no error */
451
452 case SS_SIOCGHIWAT: /* get high watermark */
453 case SS_SIOCGLOWAT: /* get low watermark */
454 break; /* return value of 0 and no error */
455
456 case SS_SIOCATMARK: /* at oob mark */
457 IOCTL(SIOCATMARK);
458 break;
459
460 case SS_SIOCSPGRP: /* set process group */
461 IOCTL(SIOCSPGRP);
462 break;
463 case SS_SIOCGPGRP: /* get process group */
464 IOCTL(SIOCGPGRP);
465 break;
466
467 case FIONREAD:
468 case SS_FIONREAD: /* get # bytes to read */
469 IOCTL(FIONREAD);
470 break;
471
472 case SS_FIONBIO: /* set/clear non-blocking i/o */
473 IOCTL(FIONBIO);
474 break;
475
476 case SS_FIOASYNC: /* set/clear async i/o */
477 IOCTL(FIOASYNC);
478 break;
479
480 case SS_SIOCADDRT: /* add route - uses struct ortentry */
481 IOCTL(SIOCADDRT);
482 break;
483
484 case SS_SIOCDELRT: /* delete route - uses struct ortentry */
485 IOCTL(SIOCDELRT);
486 break;
487
488 case SS_SIOCSIFADDR: /* set ifnet address */
489 IOCTL(SIOCSIFADDR);
490 break;
491
492 case SS_SIOCGIFADDR: /* get ifnet address */
493 IOCTL(SIOCGIFADDR);
494 break;
495
496 case SS_SIOCSIFDSTADDR: /* set p-p address */
497 IOCTL(SIOCSIFDSTADDR);
498 break;
499
500 case SS_SIOCGIFDSTADDR: /* get p-p address */
501 IOCTL(SIOCGIFDSTADDR);
502 break;
503
504 case SS_SIOCSIFFLAGS: /* set ifnet flags */
505 IOCTL(SIOCSIFFLAGS);
506 break;
507
508 case SS_SIOCGIFFLAGS: /* get ifnet flags */
509 IOCTL(SIOCGIFFLAGS);
510 break;
511
512 case SS_SIOCGIFCONF: /* get ifnet ltst */
513 IOCTL(SIOCGIFCONF);
514 break;
515
516 case SS_SIOCGIFBRDADDR: /* get broadcast addr */
517 IOCTL(SIOCGIFBRDADDR);
518 break;
519
520 case SS_SIOCSIFBRDADDR: /* set broadcast addr */
521 IOCTL(SIOCSIFBRDADDR);
522 break;
523
524 case SS_SIOCGIFNETMASK: /* get net addr mask */
525 IOCTL(SIOCGIFNETMASK);
526 break;
527
528 case SS_SIOCSIFNETMASK: /* set net addr mask */
529 IOCTL(SIOCSIFNETMASK);
530 break;
531
532 case SS_SIOCGIFMETRIC: /* get IF metric */
533 IOCTL(SIOCGIFMETRIC);
534 break;
535
536 case SS_SIOCSIFMETRIC: /* set IF metric */
537 IOCTL(SIOCSIFMETRIC);
538 break;
539
540/* FreeBSD 2.0 does not have socket ARPs */
541
542#ifdef SIOCSARP
543
544 case SS_SIOCSARP: /* set arp entry */
545 IOCTL(SIOCSARP);
546 break;
547
548 case SS_SIOCGARP: /* get arp entry */
549 IOCTL(SIOCGARP);
550 break;
551
552 case SS_SIOCDARP: /* delete arp entry */
553 IOCTL(SIOCDARP);
554 break;
555
556#else /* SIOCSARP */
557
558 case SS_SIOCSARP: /* set arp entry */
559 return(EINVAL);
560
561 case SS_SIOCGARP: /* get arp entry */
562 return(EINVAL);
563
564 case SS_SIOCDARP: /* delete arp entry */
565 return(EINVAL);
566
567#endif /* SIOCSARP */
568
569 case SS_SIOCGENADDR: /* Get ethernet addr XXX */
570 return (EINVAL);
571/* return (error = ioctl_s(fp, SIOCGIFHWADDR, arg, p)); */
572
573 case SS_SIOCSIFMTU: /* get if_mtu */
574 IOCTL(SIOCSIFMTU);
575 break;
576
577 case SS_SIOCGIFMTU: /* set if_mtu */
578 IOCTL(SIOCGIFMTU);
579 break;
580
581 case SS_SIOCGETNAME: /* getsockname XXX */
582 return (EINVAL);
583/* return (ioctl_s(fp, SIOCGIFNAME, arg, p)); MMM */
584
585 case SS_SIOCGETPEER: { /* getpeername */
586 struct moose {
587 int fd;
588 caddr_t asa;
589 int *alen;
590 int compat_43;
591 } args;
592
593 struct alien_sockaddr uaddr;
594 struct sockaddr nuaddr;
595 int nuaddr_len = sizeof(struct sockaddr);
596 struct filedesc *fdp;
597
598 if(fp->f_type != DTYPE_SOCKET)
599 return (ENOTSOCK);
600
601 bzero((caddr_t)&nuaddr, sizeof(struct sockaddr));
602 fdp = p->p_fd;
603 args.fd = -1;
604 while(++args.fd < NOFILE)
605 if ( fp == fdp->fd_ofiles[args.fd] )
606 break;
607 if(args.fd == NOFILE){
608 printf("ss_fop_ioctl: [%d] SS_SIOCGETPEER args.fd > NOFILE\n", p->p_pid);
609 return(EBADF);
610 }
611 args.asa = (caddr_t)&nuaddr;
612 args.alen = &nuaddr_len;
613 args.compat_43 = 0;
614 error = SYSCALLX(SYS_getpeername, &args);
615 if(error)
616 return(error);
617
618 bzero((caddr_t)&uaddr, sizeof(struct alien_sockaddr));
619 uaddr.sa_family = (unsigned short)nuaddr.sa_family;
620 bcopy(&nuaddr.sa_data, &uaddr.sa_data, __ALIEN_SOCK_SIZE__ - sizeof(unsigned short));
621
622 error = copyout((caddr_t)&uaddr, (caddr_t)arg, sizeof(struct alien_sockaddr));
623 return error;
624 }
625
626 default:
627 printf("ss_fop_ioctl: [%d] %lx unknown ioctl 0x%x, 0x%lx\n",
628 p->p_pid, (unsigned long)fp,
629 cmd, (unsigned long)arg);
630 return (EINVAL);
631 }
632 IBCS2_MAGIC_RETURN(arg);
633}
634
635int
636sockioctl(dev, cmd, arg, fflag, p)
637 dev_t dev;
638 int cmd;
639 caddr_t arg;
640 int fflag;
641 struct proc *p;
642{
643 int error;
644 int retval[2];
645
646 if(ss_debug) {
647 char cmd_type;
648 int cmd_ordinal;
649 static char **ioctl_strings;
650 unsigned int ioctl_type;
651 unsigned int ioctl_len;
652
653 static char *ioctl_type_strings[] = {
654 "NIOCxx", "SS_IO", "SS_IOR", "3?", "SS_IOW", "5?", "SS_IOWR"
655 };
656 static char *ioctl_S_strings[] = {
657 "0?", "SIOCSHIWAT", "SIOCGHIWAT", "SIOCSLOWAT", "SIOCGLOWAT",
658 "SIOCATMARK", "SIOCSPGRP", "SIOCGPGRP", "FIONREAD",
659 "FIONBIO", "FIOASYNC", "SIOCPROTO", "SIOCGETNAME",
660 "SIOCGETPEER", "IF_UNITSEL", "SIOCXPROTO"
661 };
662 static char *ioctl_R_strings[] = {
663 "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?",
664 "SIOCADDRT", "SIOCDELRT"
665 };
666 static char *ioctl_I_strings[] = {
667 "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?",
668 "9?", "10?", "SIOCSIFADDR", "SIOCGIFADDR", "SIOCSIFDSTADDR",
669 "SIOCGIFDSTADDR", "SIOCSIFFLAGS", "SIOCGIFFLAGS",
670 "SIOCGIFCONF", "18?", "19?", "20?", "SIOCSIFMTU",
671 "SIOCGIFMTU", "23?", "24?", "25?", "SIOCIFDETACH",
672 "SIOCGENPSTATS", "28?", "SIOCX25XMT", "SS_SIOCX25RCV",
673 "SS_SIOCX25TBL", "SIOCGIFBRDADDR" ,"SIOCSIFBRDADDR",
674 "SIOCGIFNETMASK", "SIOCSIFNETMASK", "SIOCGIFMETRIC",
675 "SIOCSIFMETRIC", "SIOCSARP", "SIOCGARP", "SIOCDARP",
676 "SIOCSIFNAME", "SIOCGIFONEP", "SIOCSIFONEP ",
677 "44?", "45?", "46?", "47?", "48?", "49?", "50?", "51?",
678 "52?", "53?", "54?", "55?", "56?", "57?", "58?", "59?",
679 "60?", "61?", "62?", "63?", "64?", "SIOCGENADDR",
680 "SIOCSOCKSYS"
681 };
682 static char *ioctl_NIOC_strings[] = {
683 "0?", "NIOCNFSD", "NIOCOLDGETFH", "NIOCASYNCD",
684 "NIOCSETDOMNAM", "NIOCGETDOMNAM", "NIOCCLNTHAND",
685 "NIOCEXPORTFS", "NIOCGETFH", "NIOCLSTAT"
686 };
687
688 cmd_ordinal = cmd & 0xff;
689 cmd_type = (cmd >> 8) & 0xff;
690 switch (cmd_type) {
691
692 case 0:
693 ioctl_strings = ioctl_NIOC_strings;
694 cmd_type = ' ';
695 if (cmd_ordinal > 9)
696 cmd_ordinal = -1;
697 break;
698
699 case 'S':
700 ioctl_strings = ioctl_S_strings;
701 if (cmd_ordinal > 15)
702 cmd_ordinal = -1;
703 break;
704
705 case 'R':
706 ioctl_strings = ioctl_R_strings;
707 if (cmd_ordinal > 10)
708 cmd_ordinal = -1;
709 break;
710
711 case 'I':
712 ioctl_strings = ioctl_I_strings;
713 if (cmd_ordinal > 66)
714 cmd_ordinal = -1;
715 break;
716
717 default:
718 cmd_type = '?';
719 break;
120 printf("%s ",ss_syscall_strings[cmd]);
121 }
122 printf("(%d) <0x%x,0x%x,0x%x,0x%x,0x%x,0x%x>\n",
123 cmd,
124 ((struct ss_call *)arg)->arg[1],
125 ((struct ss_call *)arg)->arg[2],
126 ((struct ss_call *)arg)->arg[3],
127 ((struct ss_call *)arg)->arg[4],
128 ((struct ss_call *)arg)->arg[5],
129 ((struct ss_call *)arg)->arg[6]);
130 }
131
132 error = 0;
133
134 switch (cmd) {
135
136 case CMD_SO_SS_DEBUG:
137
138 /* ss_debug = ((struct ss_call *)arg)->arg[1]; */
139 break;
140
141 case CMD_SO_SOCKET: { /* NO CONV */
142
143 if(ss_debug > 1)
144 printf("SO_SOCKET af in %d\n",
145 ((struct ss_call *)arg)->arg[1]);
146 ((struct ss_call *)arg)->arg[1] = ss_convert(
147 af_whatevers,
148 &(((struct ss_call *)arg)->arg[1]),
149 0);
150 if(ss_debug > 1) {
151 printf("SO_SOCKET af out %d\n",
152 ((struct ss_call *)arg)->arg[1]);
153
154 printf("SO_SOCKET type in %d\n",
155 ((struct ss_call *)arg)->arg[2]);
156 }
157 ((struct ss_call *)arg)->arg[2] = ss_convert(
158 type_whatevers,
159 &(((struct ss_call *)arg)->arg[2]),
160 0);
161 if(ss_debug > 1)
162 printf("SO_SOCKET type out %d\n",
163 ((struct ss_call *)arg)->arg[2]);
164
165 SYSCALL(SYS_socket, 0, 0);
166
167 if(ss_debug)
168 printf("ss_syscall: [%d] socket fd=%d\n",
169 p->p_pid, retval[0]);
170 put_socket_fops(p,retval[0]);
171
172 break;
173 }
174
175 case CMD_SO_ACCEPT: { /* CONVERSION in arg 2 */
176
177 SYSCALL(SYS_accept, 2, SS_STRUCT_SOCKADDR);
178
179 if(ss_debug)
180 printf("ss_syscall: [%d] accept fd=%d\n",
181 p->p_pid, retval[0]);
182 put_socket_fops(p,retval[0]);
183
184 break;
185 }
186
187 case CMD_SO_BIND:
188 SYSCALL(SYS_bind, 2, SS_STRUCT_SOCKADDR);
189 break;
190
191 case CMD_SO_CONNECT: {
192 struct alien_sockaddr *sa;
193 unsigned short family;
194
195 /* Remap any INADDR_ANY (0.0.0.0) to localhost */
196
197 sa = (struct alien_sockaddr *)((struct ss_call *)arg)->arg[1];
198 if(error = copyin((caddr_t)&sa->sa_family,
199 (caddr_t)&family, sizeof(short)))
200 return(error);
201 if (family == AF_INET) {
202 unsigned long *addr;
203 unsigned long saddr;
204
205 addr = &(((struct alien_sockaddr_in *)sa)->sin_addr.s_addr);
206 if(error = copyin((caddr_t)addr, (caddr_t)&saddr, sizeof(long)))
207 return(error);
208 if (saddr == INADDR_ANY) {
209 /* 0x0100007f is 127.0.0.1 reversed */
210 saddr = 0x0100007f;
211 if(error = copyout((caddr_t)&saddr,
212 (caddr_t)addr, sizeof(long)))
213 return(error);
214 if (ss_debug)
215 printf("ss_syscall: remapped INADDR_ANY to localhost\n");
216 }
217 }
218 SYSCALL(SYS_connect, 2, SS_STRUCT_SOCKADDR);
219 break;
220 }
221
222 case CMD_SO_GETPEERNAME:
223 SYSCALL(SYS_getpeername, 2, SS_STRUCT_SOCKADDR);
224 break;
225
226 case CMD_SO_GETSOCKNAME:
227 SYSCALL(SYS_getsockname, 2, SS_STRUCT_SOCKADDR);
228 break;
229
230 case CMD_SO_GETSOCKOPT:
231 if(error = ss_getsockopt((caddr_t)(((int *)arg) + 1),retval,p))
232 return(error);
233 break;
234
235 case CMD_SO_LISTEN:
236 SYSCALL(SYS_listen, 0, 0);
237 break;
238
239 case CMD_SO_RECV:
240 ((struct ss_call *)arg)->arg[5] = (int)((struct sockaddr *)NULL);
241 ((struct ss_call *)arg)->arg[6] = 0;
242 SYSCALL(SYS_recvfrom, 0, 0);
243 break;
244
245 case CMD_SO_RECVFROM:
246 SYSCALL(SYS_recvfrom, 5, SS_STRUCT_SOCKADDR);
247 break;
248
249 case CMD_SO_SEND:
250 ((struct ss_call *)arg)->arg[5] = (int)((struct sockaddr *)NULL);
251 ((struct ss_call *)arg)->arg[6] = 0;
252 SYSCALL(SYS_sendto, 0, 0);
253 break;
254
255 case CMD_SO_SENDTO:
256 SYSCALL(SYS_sendto, 5, SS_STRUCT_SOCKADDR);
257 break;
258
259 case CMD_SO_SETSOCKOPT:
260 if(error = ss_setsockopt((caddr_t)(((int *)arg) + 1),retval,p))
261 return(error);
262
263 case CMD_SO_SHUTDOWN:
264 SYSCALL(SYS_shutdown, 0, 0);
265 break;
266
267 case CMD_SO_GETIPDOMAIN:
268 SYSCALL(SYS_getdomainname, 0, 0);
269 break;
270
271 case CMD_SO_SETIPDOMAIN: /* Note check on BSD utsname no change? */
272 SYSCALL(SYS_setdomainname, 0, 0);
273 break;
274
275 case CMD_SO_SETREUID:
276 SYSCALL(126/*SYS_setreuid*/, 0, 0);
277 break;
278
279 case CMD_SO_SETREGID:
280 SYSCALL(127/*SYS_setregid*/, 0, 0);
281 break;
282
283 case CMD_SO_GETTIME:
284 SYSCALL(SYS_gettimeofday, 0, 0);
285 break;
286
287 case CMD_SO_SETTIME:
288 SYSCALL(SYS_settimeofday, 0, 0);
289 break;
290
291 case CMD_SO_GETITIMER:
292 SYSCALL(SYS_getitimer, 0, 0);
293 break;
294
295 case CMD_SO_SETITIMER:
296 SYSCALL(SYS_setitimer, 0, 0);
297 break;
298
299 case CMD_SO_SELECT:
300 SYSCALL(SYS_select, 0, 0);
301 break;
302
303 case CMD_SO_ADJTIME:
304 SYSCALL(SYS_adjtime, 0, 0);
305 break;
306
307 default:
308 printf("ss_syscall: default 0x%x\n",cmd);
309 return (EINVAL);
310 }
311 IBCS2_MAGIC_RETURN(arg);
312}
313
314
315static int
316ss_fop_ioctl(fp, cmd, arg, p)
317 struct file *fp;
318 int cmd;
319 caddr_t arg;
320 struct proc *p;
321{
322 int error;
323 int retval[2];
324
325 if(ss_debug) {
326 static char **ioctl_strings;
327 int fd;
328 struct filedesc *fdp;
329 unsigned int ioctl_type;
330 unsigned int ioctl_len;
331 char cmd_type;
332 int cmd_ordinal;
333
334 static char *ioctl_type_strings[] = {
335 "0?", "SS_IO", "SS_IOR", "3?", "SS_IOW", "5?", "SS_IOWR"
336 };
337 static char *ioctl_S_strings[] = {
338 "0?", "SIOCSHIWAT", "SIOCGHIWAT", "SIOCSLOWAT", "SIOCGLOWAT",
339 "SIOCATMARK", "SIOCSPGRP", "SIOCGPGRP", "FIONREAD",
340 "FIONBIO", "FIOASYNC", "SIOCPROTO", "SIOCGETNAME",
341 "SIOCGETPEER", "IF_UNITSEL", "SIOCXPROTO"
342 };
343 static char *ioctl_R_strings[] = {
344 "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?",
345 "SIOCADDRT", "SIOCDELRT"
346 };
347 static char *ioctl_I_strings[] = {
348 "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?",
349 "9?", "10?", "SIOCSIFADDR", "SIOCGIFADDR", "SIOCSIFDSTADDR",
350 "SIOCGIFDSTADDR", "SIOCSIFFLAGS", "SIOCGIFFLAGS",
351 "SIOCGIFCONF", "18?", "19?", "20?", "SIOCSIFMTU",
352 "SIOCGIFMTU", "23?", "24?", "25?", "SIOCIFDETACH",
353 "SIOCGENPSTATS", "28?", "SIOCX25XMT", "SS_SIOCX25RCV",
354 "SS_SIOCX25TBL", "SIOCGIFBRDADDR" ,"SIOCSIFBRDADDR",
355 "SIOCGIFNETMASK", "SIOCSIFNETMASK", "SIOCGIFMETRIC",
356 "SIOCSIFMETRIC", "SIOCSARP", "SIOCGARP", "SIOCDARP",
357 "SIOCSIFNAME", "SIOCGIFONEP", "SIOCSIFONEP ",
358 "44?", "45?", "46?", "47?", "48?", "49?", "50?", "51?",
359 "52?", "53?", "54?", "55?", "56?", "57?", "58?", "59?",
360 "60?", "61?", "62?", "63?", "64?", "SIOCGENADDR",
361 "SIOCSOCKSYS"
362 };
363
364 cmd_type = (cmd >> 8) & 0xff;
365 cmd_ordinal = cmd & 0xff;
366
367 switch (cmd_type) {
368
369 case 'S':
370 ioctl_strings = ioctl_S_strings;
371 if (cmd_ordinal > 15)
372 cmd_ordinal = -1;
373 break;
374
375 case 'R':
376 ioctl_strings = ioctl_R_strings;
377 if (cmd_ordinal > 10)
378 cmd_ordinal = -1;
379 break;
380
381 case 'I':
382 ioctl_strings = ioctl_I_strings;
383 if (cmd_ordinal > 66)
384 cmd_ordinal = -1;
385 break;
386
387 default:
388 cmd_type = '?';
389 break;
390 }
391 fdp = p->p_fd;
392 fd = -1;
393 while(++fd < NOFILE)
394 if ( fp == fdp->fd_ofiles[fd] )
395 break;
396
397 ioctl_type = (0xe0000000 & cmd) >> 29;
398 ioctl_len = (cmd >> 16) & SS_IOCPARM_MASK;
399
400 printf("ss_fop_ioctl: [%d] fd=%d ",p->p_pid, fd);
401 if(cmd_type != '?'){
402 if(cmd_ordinal != -1)
403 printf("%s %s('%c',%d,l=%d) ",ioctl_strings[cmd_ordinal],
404 ioctl_type_strings[ioctl_type],
405 cmd_type,
406 cmd_ordinal,
407 ioctl_len);
408 else {
409 cmd_ordinal = cmd & 0xff;
410 printf("[unknown ordinal %d] %s('%c',%d,l=%d) ",cmd_ordinal,
411 ioctl_type_strings[ioctl_type],
412 cmd_type,
413 cmd_ordinal,
414 ioctl_len);
415 }
416 }
417 else {
418 printf("? %s('%c',%d,l=%d) ",
419 ioctl_type_strings[ioctl_type],
420 cmd_type,
421 cmd_ordinal,
422 ioctl_len);
423 }
424
425 printf("0x%x (0x%x) <0x%x>\n",
426 fp, cmd, arg);
427 }
428
429 /* No dogs allowed */
430
431 if(*(((int *)arg) - 3) != IBCS2_MAGIC_IN){
432 printf("ss_fop_ioctl: bad magic (sys_generic.c has no socksys mods?)\n");
433 return(EINVAL);
434 }
435
436 if(fp->f_type != DTYPE_SOCKET)
437 return (ENOTSOCK);
438
439 retval[0] = retval[1] = 0;
440
441
442 error = 0;
443
444 switch (cmd) {
445 case SS_SIOCSOCKSYS: /* ss syscall */
446 return ss_syscall(arg, p);
447
448 case SS_SIOCSHIWAT: /* set high watermark */
449 case SS_SIOCSLOWAT: /* set low watermark */
450 break; /* return value of 0 and no error */
451
452 case SS_SIOCGHIWAT: /* get high watermark */
453 case SS_SIOCGLOWAT: /* get low watermark */
454 break; /* return value of 0 and no error */
455
456 case SS_SIOCATMARK: /* at oob mark */
457 IOCTL(SIOCATMARK);
458 break;
459
460 case SS_SIOCSPGRP: /* set process group */
461 IOCTL(SIOCSPGRP);
462 break;
463 case SS_SIOCGPGRP: /* get process group */
464 IOCTL(SIOCGPGRP);
465 break;
466
467 case FIONREAD:
468 case SS_FIONREAD: /* get # bytes to read */
469 IOCTL(FIONREAD);
470 break;
471
472 case SS_FIONBIO: /* set/clear non-blocking i/o */
473 IOCTL(FIONBIO);
474 break;
475
476 case SS_FIOASYNC: /* set/clear async i/o */
477 IOCTL(FIOASYNC);
478 break;
479
480 case SS_SIOCADDRT: /* add route - uses struct ortentry */
481 IOCTL(SIOCADDRT);
482 break;
483
484 case SS_SIOCDELRT: /* delete route - uses struct ortentry */
485 IOCTL(SIOCDELRT);
486 break;
487
488 case SS_SIOCSIFADDR: /* set ifnet address */
489 IOCTL(SIOCSIFADDR);
490 break;
491
492 case SS_SIOCGIFADDR: /* get ifnet address */
493 IOCTL(SIOCGIFADDR);
494 break;
495
496 case SS_SIOCSIFDSTADDR: /* set p-p address */
497 IOCTL(SIOCSIFDSTADDR);
498 break;
499
500 case SS_SIOCGIFDSTADDR: /* get p-p address */
501 IOCTL(SIOCGIFDSTADDR);
502 break;
503
504 case SS_SIOCSIFFLAGS: /* set ifnet flags */
505 IOCTL(SIOCSIFFLAGS);
506 break;
507
508 case SS_SIOCGIFFLAGS: /* get ifnet flags */
509 IOCTL(SIOCGIFFLAGS);
510 break;
511
512 case SS_SIOCGIFCONF: /* get ifnet ltst */
513 IOCTL(SIOCGIFCONF);
514 break;
515
516 case SS_SIOCGIFBRDADDR: /* get broadcast addr */
517 IOCTL(SIOCGIFBRDADDR);
518 break;
519
520 case SS_SIOCSIFBRDADDR: /* set broadcast addr */
521 IOCTL(SIOCSIFBRDADDR);
522 break;
523
524 case SS_SIOCGIFNETMASK: /* get net addr mask */
525 IOCTL(SIOCGIFNETMASK);
526 break;
527
528 case SS_SIOCSIFNETMASK: /* set net addr mask */
529 IOCTL(SIOCSIFNETMASK);
530 break;
531
532 case SS_SIOCGIFMETRIC: /* get IF metric */
533 IOCTL(SIOCGIFMETRIC);
534 break;
535
536 case SS_SIOCSIFMETRIC: /* set IF metric */
537 IOCTL(SIOCSIFMETRIC);
538 break;
539
540/* FreeBSD 2.0 does not have socket ARPs */
541
542#ifdef SIOCSARP
543
544 case SS_SIOCSARP: /* set arp entry */
545 IOCTL(SIOCSARP);
546 break;
547
548 case SS_SIOCGARP: /* get arp entry */
549 IOCTL(SIOCGARP);
550 break;
551
552 case SS_SIOCDARP: /* delete arp entry */
553 IOCTL(SIOCDARP);
554 break;
555
556#else /* SIOCSARP */
557
558 case SS_SIOCSARP: /* set arp entry */
559 return(EINVAL);
560
561 case SS_SIOCGARP: /* get arp entry */
562 return(EINVAL);
563
564 case SS_SIOCDARP: /* delete arp entry */
565 return(EINVAL);
566
567#endif /* SIOCSARP */
568
569 case SS_SIOCGENADDR: /* Get ethernet addr XXX */
570 return (EINVAL);
571/* return (error = ioctl_s(fp, SIOCGIFHWADDR, arg, p)); */
572
573 case SS_SIOCSIFMTU: /* get if_mtu */
574 IOCTL(SIOCSIFMTU);
575 break;
576
577 case SS_SIOCGIFMTU: /* set if_mtu */
578 IOCTL(SIOCGIFMTU);
579 break;
580
581 case SS_SIOCGETNAME: /* getsockname XXX */
582 return (EINVAL);
583/* return (ioctl_s(fp, SIOCGIFNAME, arg, p)); MMM */
584
585 case SS_SIOCGETPEER: { /* getpeername */
586 struct moose {
587 int fd;
588 caddr_t asa;
589 int *alen;
590 int compat_43;
591 } args;
592
593 struct alien_sockaddr uaddr;
594 struct sockaddr nuaddr;
595 int nuaddr_len = sizeof(struct sockaddr);
596 struct filedesc *fdp;
597
598 if(fp->f_type != DTYPE_SOCKET)
599 return (ENOTSOCK);
600
601 bzero((caddr_t)&nuaddr, sizeof(struct sockaddr));
602 fdp = p->p_fd;
603 args.fd = -1;
604 while(++args.fd < NOFILE)
605 if ( fp == fdp->fd_ofiles[args.fd] )
606 break;
607 if(args.fd == NOFILE){
608 printf("ss_fop_ioctl: [%d] SS_SIOCGETPEER args.fd > NOFILE\n", p->p_pid);
609 return(EBADF);
610 }
611 args.asa = (caddr_t)&nuaddr;
612 args.alen = &nuaddr_len;
613 args.compat_43 = 0;
614 error = SYSCALLX(SYS_getpeername, &args);
615 if(error)
616 return(error);
617
618 bzero((caddr_t)&uaddr, sizeof(struct alien_sockaddr));
619 uaddr.sa_family = (unsigned short)nuaddr.sa_family;
620 bcopy(&nuaddr.sa_data, &uaddr.sa_data, __ALIEN_SOCK_SIZE__ - sizeof(unsigned short));
621
622 error = copyout((caddr_t)&uaddr, (caddr_t)arg, sizeof(struct alien_sockaddr));
623 return error;
624 }
625
626 default:
627 printf("ss_fop_ioctl: [%d] %lx unknown ioctl 0x%x, 0x%lx\n",
628 p->p_pid, (unsigned long)fp,
629 cmd, (unsigned long)arg);
630 return (EINVAL);
631 }
632 IBCS2_MAGIC_RETURN(arg);
633}
634
635int
636sockioctl(dev, cmd, arg, fflag, p)
637 dev_t dev;
638 int cmd;
639 caddr_t arg;
640 int fflag;
641 struct proc *p;
642{
643 int error;
644 int retval[2];
645
646 if(ss_debug) {
647 char cmd_type;
648 int cmd_ordinal;
649 static char **ioctl_strings;
650 unsigned int ioctl_type;
651 unsigned int ioctl_len;
652
653 static char *ioctl_type_strings[] = {
654 "NIOCxx", "SS_IO", "SS_IOR", "3?", "SS_IOW", "5?", "SS_IOWR"
655 };
656 static char *ioctl_S_strings[] = {
657 "0?", "SIOCSHIWAT", "SIOCGHIWAT", "SIOCSLOWAT", "SIOCGLOWAT",
658 "SIOCATMARK", "SIOCSPGRP", "SIOCGPGRP", "FIONREAD",
659 "FIONBIO", "FIOASYNC", "SIOCPROTO", "SIOCGETNAME",
660 "SIOCGETPEER", "IF_UNITSEL", "SIOCXPROTO"
661 };
662 static char *ioctl_R_strings[] = {
663 "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?",
664 "SIOCADDRT", "SIOCDELRT"
665 };
666 static char *ioctl_I_strings[] = {
667 "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?",
668 "9?", "10?", "SIOCSIFADDR", "SIOCGIFADDR", "SIOCSIFDSTADDR",
669 "SIOCGIFDSTADDR", "SIOCSIFFLAGS", "SIOCGIFFLAGS",
670 "SIOCGIFCONF", "18?", "19?", "20?", "SIOCSIFMTU",
671 "SIOCGIFMTU", "23?", "24?", "25?", "SIOCIFDETACH",
672 "SIOCGENPSTATS", "28?", "SIOCX25XMT", "SS_SIOCX25RCV",
673 "SS_SIOCX25TBL", "SIOCGIFBRDADDR" ,"SIOCSIFBRDADDR",
674 "SIOCGIFNETMASK", "SIOCSIFNETMASK", "SIOCGIFMETRIC",
675 "SIOCSIFMETRIC", "SIOCSARP", "SIOCGARP", "SIOCDARP",
676 "SIOCSIFNAME", "SIOCGIFONEP", "SIOCSIFONEP ",
677 "44?", "45?", "46?", "47?", "48?", "49?", "50?", "51?",
678 "52?", "53?", "54?", "55?", "56?", "57?", "58?", "59?",
679 "60?", "61?", "62?", "63?", "64?", "SIOCGENADDR",
680 "SIOCSOCKSYS"
681 };
682 static char *ioctl_NIOC_strings[] = {
683 "0?", "NIOCNFSD", "NIOCOLDGETFH", "NIOCASYNCD",
684 "NIOCSETDOMNAM", "NIOCGETDOMNAM", "NIOCCLNTHAND",
685 "NIOCEXPORTFS", "NIOCGETFH", "NIOCLSTAT"
686 };
687
688 cmd_ordinal = cmd & 0xff;
689 cmd_type = (cmd >> 8) & 0xff;
690 switch (cmd_type) {
691
692 case 0:
693 ioctl_strings = ioctl_NIOC_strings;
694 cmd_type = ' ';
695 if (cmd_ordinal > 9)
696 cmd_ordinal = -1;
697 break;
698
699 case 'S':
700 ioctl_strings = ioctl_S_strings;
701 if (cmd_ordinal > 15)
702 cmd_ordinal = -1;
703 break;
704
705 case 'R':
706 ioctl_strings = ioctl_R_strings;
707 if (cmd_ordinal > 10)
708 cmd_ordinal = -1;
709 break;
710
711 case 'I':
712 ioctl_strings = ioctl_I_strings;
713 if (cmd_ordinal > 66)
714 cmd_ordinal = -1;
715 break;
716
717 default:
718 cmd_type = '?';
719 break;
720
720
721 }
722 ioctl_type = (0xe0000000 & cmd) >> 29;
723 ioctl_len = (cmd >> 16) & SS_IOCPARM_MASK;
724
725 printf("sockioctl: [%d] ",p->p_pid);
726 if(cmd_type != '?'){
727 if(cmd_ordinal != -1)
728 printf("%s %s('%c',%d,l=%d) ",ioctl_strings[cmd_ordinal],
729 ioctl_type_strings[ioctl_type],
730 cmd_type,
731 cmd_ordinal,
732 ioctl_len);
733 else {
734 cmd_ordinal = cmd & 0xff;
735 printf("[unknown ordinal %d] %s('%c',%d,l=%d) ",cmd_ordinal,
736 ioctl_type_strings[ioctl_type],
737 cmd_type,
738 cmd_ordinal,
739 ioctl_len);
740 }
741 }
742 else {
743 printf("? %s('%c',%d,l=%d) ",
744 ioctl_type_strings[ioctl_type],
745 cmd_type,
746 cmd_ordinal,
747 ioctl_len);
748 }
749
750 printf("0x%x (0x%x) <0x%x>\n",
751 dev, cmd, arg);
752 }
753
754 if(*(((int *)arg) - 3) != IBCS2_MAGIC_IN){
755 printf("sockioctl: bad magic (sys_generic.c has no socksys mods?)\n");
756 return(EINVAL);
757 }
758
759 switch (cmd) {
760
761 case SS_SIOCSOCKSYS: /* ss syscall */
762 return ss_syscall(arg, p);
763
764 /* NIOCxx: These ioctls are really just integers
765 * (no other information to go on).
766 */
767
768 case NIOCSETDOMNAM: {
769 struct sgdomarg domargs;
770
771 if(error = copyin((caddr_t)*((caddr_t *)arg), (caddr_t)&domargs, sizeof(struct sgdomarg)))
772 return(error);
773
774 arg = (caddr_t)&domargs;
775 SYSCALL_N(SYS_setdomainname, 0, 0);
776 break;
777 }
778
779 case NIOCGETDOMNAM: {
780 struct sgdomarg domargs;
781
782 if(error = copyin((caddr_t)*((caddr_t *)arg), (caddr_t)&domargs, sizeof(struct sgdomarg)))
783 return(error);
784
785 arg = (caddr_t)&domargs;
786 SYSCALL_N(SYS_getdomainname, 0, 0);
787 break;
788 }
789
790 case NIOCLSTAT: {
791 struct lstatarg st;
792
793 if(error = copyin((caddr_t)*((caddr_t *)arg), (caddr_t)&st, sizeof(struct lstatarg)))
794 return(error);
795
796 /* DO WE HAVE A FOREIGN LSTAT */
797/* return mumbo_lstat(st.fname, st.statb); */
798 return (EINVAL);
799 }
800
801 case NIOCNFSD:
802 case NIOCOLDGETFH:
803 case NIOCASYNCD:
804 case NIOCCLNTHAND:
805 case NIOCEXPORTFS:
806 case NIOCGETFH:
807 return (EINVAL);
808
809
810 case SS_IF_UNITSEL: /* set unit number */
811 case SS_SIOCXPROTO: /* empty proto table */
812
813 case SS_SIOCIFDETACH: /* detach interface */
814 case SS_SIOCGENPSTATS: /* get ENP stats */
815
816 case SS_SIOCSIFNAME: /* set interface name */
817 case SS_SIOCGIFONEP: /* get one-packet params */
818 case SS_SIOCSIFONEP: /* set one-packet params */
819
820 case SS_SIOCPROTO: /* link proto */
821 case SS_SIOCX25XMT:
822 case SS_SIOCX25RCV:
823 case SS_SIOCX25TBL:
824
825 printf("sockioctl: [%d] unsupported ioctl 0x%x , 0x%lx\n",
826 p->p_pid,
827 cmd, (unsigned long)arg);
828 return (EINVAL);
829
830 default:
831 printf("sockioctl: [%d] unknown ioctl 0x%x , 0x%lx\n",
832 p->p_pid,
833 cmd, (unsigned long)arg);
834 return (EINVAL);
835 }
836 IBCS2_MAGIC_RETURN(arg);
837}
838
839
840int sockopen(dev, mode, devtype, p)
841 dev_t dev;
842 int mode;
843 int devtype;
844 struct proc *p;
845{
846
847 if(ss_debug)
848 printf("sockopen: [%d] 0x%x\n", p->p_pid, dev);
849
850 /* minor = 0 is the socksys device itself. No special handling
851 * will be needed as it is controlled by the application
852 * via ioctls.
853 */
854 if (minor(dev) == 0)
855 return 0;
856
857 /* minor = 1 is the spx device. This is the client side of a
858 * streams pipe to the X server. Under SCO and friends
859 * the library code messes around setting the connection
860 * up itself. We do it ourselves - this means we don't
861 * need to worry about the implementation of the server
862 * side (/dev/X0R - which must exist but can be a link
863 * to /dev/null) nor do we need to actually implement
864 * getmsg/putmsg.
865 */
866{ /* SPX */
867 int fd, error, args[3];
868 int retval[2];
869#define SUN_LEN(su) \
870 (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) + 1
871 struct sockaddr_un *Xaddr = (struct sockaddr_un *)UA_ALLOC();
872 retval[0] = retval[1] = 0;
873 if(ss_debug)
874 printf("sockopen: SPX: [%d] opening\n", p->p_pid);
875
876 /* Grab a socket. */
877 if(ss_debug)
878 printf("sockopen: SPX: [%d] get a unix domain socket\n",
879 p->p_pid);
880 args[0] = AF_UNIX;
881 args[1] = SOCK_STREAM;
882 args[2] = 0;
883 error = SYSCALLX(SYS_socket, args);
884 if (error)
885 return error;
886 fd = retval[0];
887 if(fd < 1) {
888 printf("sockopen: SPX: [%d] unexpected fd of %d\n",
889 p->p_pid, fd);
890 return(EOPNOTSUPP); /* MRL whatever */
891 }
892
893 /* Connect the socket to X. */
894 if(ss_debug)
895 printf("sockopen: SPX: [%d] connect to /tmp/X11-unix/X0\n",
896 p->p_pid);
897 args[0] = fd;
898 Xaddr->sun_family = AF_UNIX;
899 copyout("/tmp/.X11-unix/X0", Xaddr->sun_path, 18);
900 Xaddr->sun_len = SUN_LEN(Xaddr);
901 args[1] = (int)Xaddr;
902 args[2] = sizeof(struct sockaddr_un);
903 error = SYSCALLX(SYS_connect, args);
904 if (error) {
905 (void)SYSCALLX(SYS_close, &fd);
906 return error;
907 }
908
909 put_socket_fops(p,fd);
910
911 return 0;
912} /* SPX */
913}
914
915
916int sockclose(dev, flag, mode, p)
917 dev_t dev;
918 int flag;
919 int mode;
920 struct proc *p;
921{
922 if(ss_debug)
923 printf("sockclose: [%d] 0x%x\n", p->p_pid, dev);
924 return(0);
925}
926
927static
928int ss_fop_close(struct file *fp, struct proc *p)
929{
930
931int fd;
932struct filedesc *fdp;
933
934 if(ss_debug){
935 fdp = p->p_fd;
936 fd = -1;
937 while(++fd < NOFILE)
938 if ( fp == fdp->fd_ofiles[fd] )
939 break;
940 printf("ss_fop_close: [%d] fd=%d ", p->p_pid, fd);
941 }
942
943 if(fp->f_type == DTYPE_SOCKET) {
944 if(ss_debug)
945 printf("is a socket\n");
946 return(close_s(fp, p));
947 }
948 else {
949 if(ss_debug)
950 printf("is not a socket\n");
951 return(ENOTSOCK);
952 }
953}
954
955void put_socket_fops(struct proc *p, int fd)
956{
957struct filedesc *fdp;
958struct file *fp;
959
960 fdp = p->p_fd;
961 fp = fdp->fd_ofiles[fd];
962 if (ss_socket_fops.fo_ioctl != fp->f_ops->fo_ioctl) {
963 bcopy(fp->f_ops, &ss_socket_fops, sizeof(struct fileops));
964 ioctl_s = ss_socket_fops.fo_ioctl; /* save standard ioctl */
965 close_s = ss_socket_fops.fo_close; /* save standard close */
966 ss_socket_fops.fo_ioctl = ss_fop_ioctl;
967 ss_socket_fops.fo_close = ss_fop_close;
968 }
969 fp->f_ops = &ss_socket_fops;
970
971 return;
972}
973
974int ss_SYSCALL(n,convert_arg,indicator,arg,p,retval)
975 int n; /* syscall ordinal */
976 int convert_arg; /* if not 0, argument to convert */
977 int indicator; /* type of argument to convert */
978 int *arg; /* address of alien arg */
979 struct proc *p;
980 int *retval;
981{
982int error;
983int rc;
984
985 if(convert_arg){
986 if(rc = ss_convert_struct( (caddr_t)*(arg + convert_arg),
987 indicator,
988 SS_ALIEN_TO_NATIVE))
989 return(rc);
990
991 error = (*sysent[n].sy_call)(p, arg + 1, retval);
992 rc = ss_convert_struct( (caddr_t)*(arg + convert_arg),
993 indicator,
994 SS_NATIVE_TO_ALIEN);
995 if(ss_debug)
996 printf("ss_SYSCALL: [%d] error=%d, rc=%d\n",
997 p->p_pid, error, rc);
998 }
999 else {
1000 rc = 0;
1001 error = (*sysent[n].sy_call)(p, arg + 1, retval);
1002 if(ss_debug)
1003 printf("ss_SYSCALL: [%d] error=%d\n",p->p_pid, error);
1004 }
1005
1006 return(error ? error : rc);
1007}
1008
1009int ss_IOCTL(fp, cmd, arg, p)
1010 struct file *fp;
1011 int cmd;
1012 int *arg; /* address of alien arg */
1013 struct proc *p;
1014{
1015int error, rc;
1016int these[2];
1017char cmd_type;
1018int cmd_ordinal;
1019int indicator;
1020
1021 cmd_type = (cmd >> 8) & 0xff;
1022 cmd_ordinal = cmd & 0xff;
1023 these[0] = cmd_type;
1024 these[1] = cmd_ordinal;
1025 if(ss_debug > 1)
1026 printf("ss_IOCTL: calling ss_convert with %d(%c) %d\n",
1027 these[0],these[0],these[1]);
1028 indicator = ss_convert( struct_whatevers, these, 0);
1029 if(ss_debug > 1)
1030 printf("ss_IOCTL: ss_convert returns indicator %d\n",indicator);
1031 if(indicator){
1032 error = ss_convert_struct((caddr_t)*(arg + 2),
1033 indicator,
1034 SS_ALIEN_TO_NATIVE);
1035 if(ss_debug > 1)
1036 printf("ss_IOCTL: ss_convert_struct returns %d\n",error);
1037 if(error)
1038 return(error);
1039 /* change len in ioctl now - in the general case */
1040 error = ioctl_s(fp, cmd, (caddr_t)arg, p);
1041 rc = ss_convert_struct( (caddr_t)*(arg + 2),
1042 indicator,
1043 SS_NATIVE_TO_ALIEN);
1044 if(ss_debug)
1045 printf("ss_IOCTL: [%d] error=%d, rc=%d\n",p->p_pid,
1046 error, rc);
1047 }
1048 else {
1049 rc = 0;
1050 error = ioctl_s(fp, cmd, (caddr_t)arg, p);
1051 if(ss_debug)
1052 printf("ss_IOCTL: [%d] error=%d\n",p->p_pid, error);
1053 }
1054
1055 return(error ? error : rc);
1056}
1057
1058
1059struct ss_socketopt_args {
1060 int s;
1061 int level;
1062 int name;
1063 caddr_t val;
1064 int valsize;
1065};
1066
1067int
1068ss_setsockopt(arg, ret, p)
1069 struct ss_socketopt_args *arg;
1070 int *ret;
1071 struct proc *p;
1072{
1073 int error, optname;
1074 int retval[2];
1075
1076 if (arg->level != 0xffff) /* FreeBSD, SCO and ? */
1077 return (ENOPROTOOPT);
1078
1079 optname = ss_convert(sopt_whatevers, &arg->name, 0);
1080
1081 switch (optname) {
1082
1083 case SO_ACCEPTCONN:
1084 case SO_BROADCAST:
1085 case SO_DEBUG:
1086 case SO_DONTROUTE:
1087 case SO_LINGER:
1088 case SO_KEEPALIVE:
1089 case SO_OOBINLINE:
1090 case SO_RCVBUF:
1091 case SO_RCVLOWAT:
1092 case SO_RCVTIMEO:
1093 case SO_REUSEADDR:
1094 case SO_SNDBUF:
1095 case SO_SNDLOWAT:
1096 case SO_SNDTIMEO:
1097 case SO_USELOOPBACK:
1098 error = SYSCALLX(SYS_setsockopt, arg);
1099 *ret = retval[0];
1100 *(ret + 1) = retval[1];
1101 return(error);
1102
1103 case SO_ERROR:
1104 case SO_IMASOCKET:
1105 case SO_NO_CHECK:
1106 case SO_ORDREL:
1107 case SO_PRIORITY:
1108 case SO_PROTOTYPE:
1109 case SO_TYPE:
1110 return (ENOPROTOOPT);
1111
1112 }
1113
1114 return (ENOPROTOOPT);
1115}
1116
1117
1118int
1119ss_getsockopt(arg, ret, p)
1120 struct ss_socketopt_args *arg;
1121 int *ret;
1122 struct proc *p;
1123{
1124 int error, optname;
1125 int retval[2];
1126
1127 if (arg->level != 0xffff) /* FreeBSD, SCO and ? */
1128 return (ENOPROTOOPT);
1129
1130 optname = ss_convert(sopt_whatevers, &arg->name, 0);
1131
1132 switch (optname) {
1133
1134 case SO_ACCEPTCONN:
1135 case SO_BROADCAST:
1136 case SO_DEBUG:
1137 case SO_DONTROUTE:
1138 case SO_ERROR:
1139 case SO_KEEPALIVE:
1140 case SO_LINGER:
1141 case SO_OOBINLINE:
1142 case SO_RCVBUF:
1143 case SO_RCVLOWAT:
1144 case SO_RCVTIMEO:
1145 case SO_REUSEADDR:
1146 case SO_SNDBUF:
1147 case SO_SNDLOWAT:
1148 case SO_SNDTIMEO:
1149 case SO_TYPE:
1150 case SO_USELOOPBACK:
1151 error = SYSCALLX(SYS_getsockopt, arg);
1152 *ret = retval[0];
1153 *(ret + 1) = retval[1];
1154 return(error);
1155
1156
1157 case SO_PROTOTYPE: {
1158 int value = 0;
1159
1160 error = copyout((caddr_t)&value, (caddr_t)arg->s, sizeof(int));
1161 return(error);
1162 }
1163
1164
1165 case SO_IMASOCKET: {
1166 int value = 1;
1167
1168 error = copyout((caddr_t)&value, (caddr_t)arg->s, sizeof(int));
1169 return(error);
1170 }
1171
1172 case SO_NO_CHECK:
1173 case SO_ORDREL:
1174 case SO_PRIORITY:
1175 return (ENOPROTOOPT);
1176 }
1177
1178 return (ENOPROTOOPT);
1179}
721 }
722 ioctl_type = (0xe0000000 & cmd) >> 29;
723 ioctl_len = (cmd >> 16) & SS_IOCPARM_MASK;
724
725 printf("sockioctl: [%d] ",p->p_pid);
726 if(cmd_type != '?'){
727 if(cmd_ordinal != -1)
728 printf("%s %s('%c',%d,l=%d) ",ioctl_strings[cmd_ordinal],
729 ioctl_type_strings[ioctl_type],
730 cmd_type,
731 cmd_ordinal,
732 ioctl_len);
733 else {
734 cmd_ordinal = cmd & 0xff;
735 printf("[unknown ordinal %d] %s('%c',%d,l=%d) ",cmd_ordinal,
736 ioctl_type_strings[ioctl_type],
737 cmd_type,
738 cmd_ordinal,
739 ioctl_len);
740 }
741 }
742 else {
743 printf("? %s('%c',%d,l=%d) ",
744 ioctl_type_strings[ioctl_type],
745 cmd_type,
746 cmd_ordinal,
747 ioctl_len);
748 }
749
750 printf("0x%x (0x%x) <0x%x>\n",
751 dev, cmd, arg);
752 }
753
754 if(*(((int *)arg) - 3) != IBCS2_MAGIC_IN){
755 printf("sockioctl: bad magic (sys_generic.c has no socksys mods?)\n");
756 return(EINVAL);
757 }
758
759 switch (cmd) {
760
761 case SS_SIOCSOCKSYS: /* ss syscall */
762 return ss_syscall(arg, p);
763
764 /* NIOCxx: These ioctls are really just integers
765 * (no other information to go on).
766 */
767
768 case NIOCSETDOMNAM: {
769 struct sgdomarg domargs;
770
771 if(error = copyin((caddr_t)*((caddr_t *)arg), (caddr_t)&domargs, sizeof(struct sgdomarg)))
772 return(error);
773
774 arg = (caddr_t)&domargs;
775 SYSCALL_N(SYS_setdomainname, 0, 0);
776 break;
777 }
778
779 case NIOCGETDOMNAM: {
780 struct sgdomarg domargs;
781
782 if(error = copyin((caddr_t)*((caddr_t *)arg), (caddr_t)&domargs, sizeof(struct sgdomarg)))
783 return(error);
784
785 arg = (caddr_t)&domargs;
786 SYSCALL_N(SYS_getdomainname, 0, 0);
787 break;
788 }
789
790 case NIOCLSTAT: {
791 struct lstatarg st;
792
793 if(error = copyin((caddr_t)*((caddr_t *)arg), (caddr_t)&st, sizeof(struct lstatarg)))
794 return(error);
795
796 /* DO WE HAVE A FOREIGN LSTAT */
797/* return mumbo_lstat(st.fname, st.statb); */
798 return (EINVAL);
799 }
800
801 case NIOCNFSD:
802 case NIOCOLDGETFH:
803 case NIOCASYNCD:
804 case NIOCCLNTHAND:
805 case NIOCEXPORTFS:
806 case NIOCGETFH:
807 return (EINVAL);
808
809
810 case SS_IF_UNITSEL: /* set unit number */
811 case SS_SIOCXPROTO: /* empty proto table */
812
813 case SS_SIOCIFDETACH: /* detach interface */
814 case SS_SIOCGENPSTATS: /* get ENP stats */
815
816 case SS_SIOCSIFNAME: /* set interface name */
817 case SS_SIOCGIFONEP: /* get one-packet params */
818 case SS_SIOCSIFONEP: /* set one-packet params */
819
820 case SS_SIOCPROTO: /* link proto */
821 case SS_SIOCX25XMT:
822 case SS_SIOCX25RCV:
823 case SS_SIOCX25TBL:
824
825 printf("sockioctl: [%d] unsupported ioctl 0x%x , 0x%lx\n",
826 p->p_pid,
827 cmd, (unsigned long)arg);
828 return (EINVAL);
829
830 default:
831 printf("sockioctl: [%d] unknown ioctl 0x%x , 0x%lx\n",
832 p->p_pid,
833 cmd, (unsigned long)arg);
834 return (EINVAL);
835 }
836 IBCS2_MAGIC_RETURN(arg);
837}
838
839
840int sockopen(dev, mode, devtype, p)
841 dev_t dev;
842 int mode;
843 int devtype;
844 struct proc *p;
845{
846
847 if(ss_debug)
848 printf("sockopen: [%d] 0x%x\n", p->p_pid, dev);
849
850 /* minor = 0 is the socksys device itself. No special handling
851 * will be needed as it is controlled by the application
852 * via ioctls.
853 */
854 if (minor(dev) == 0)
855 return 0;
856
857 /* minor = 1 is the spx device. This is the client side of a
858 * streams pipe to the X server. Under SCO and friends
859 * the library code messes around setting the connection
860 * up itself. We do it ourselves - this means we don't
861 * need to worry about the implementation of the server
862 * side (/dev/X0R - which must exist but can be a link
863 * to /dev/null) nor do we need to actually implement
864 * getmsg/putmsg.
865 */
866{ /* SPX */
867 int fd, error, args[3];
868 int retval[2];
869#define SUN_LEN(su) \
870 (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) + 1
871 struct sockaddr_un *Xaddr = (struct sockaddr_un *)UA_ALLOC();
872 retval[0] = retval[1] = 0;
873 if(ss_debug)
874 printf("sockopen: SPX: [%d] opening\n", p->p_pid);
875
876 /* Grab a socket. */
877 if(ss_debug)
878 printf("sockopen: SPX: [%d] get a unix domain socket\n",
879 p->p_pid);
880 args[0] = AF_UNIX;
881 args[1] = SOCK_STREAM;
882 args[2] = 0;
883 error = SYSCALLX(SYS_socket, args);
884 if (error)
885 return error;
886 fd = retval[0];
887 if(fd < 1) {
888 printf("sockopen: SPX: [%d] unexpected fd of %d\n",
889 p->p_pid, fd);
890 return(EOPNOTSUPP); /* MRL whatever */
891 }
892
893 /* Connect the socket to X. */
894 if(ss_debug)
895 printf("sockopen: SPX: [%d] connect to /tmp/X11-unix/X0\n",
896 p->p_pid);
897 args[0] = fd;
898 Xaddr->sun_family = AF_UNIX;
899 copyout("/tmp/.X11-unix/X0", Xaddr->sun_path, 18);
900 Xaddr->sun_len = SUN_LEN(Xaddr);
901 args[1] = (int)Xaddr;
902 args[2] = sizeof(struct sockaddr_un);
903 error = SYSCALLX(SYS_connect, args);
904 if (error) {
905 (void)SYSCALLX(SYS_close, &fd);
906 return error;
907 }
908
909 put_socket_fops(p,fd);
910
911 return 0;
912} /* SPX */
913}
914
915
916int sockclose(dev, flag, mode, p)
917 dev_t dev;
918 int flag;
919 int mode;
920 struct proc *p;
921{
922 if(ss_debug)
923 printf("sockclose: [%d] 0x%x\n", p->p_pid, dev);
924 return(0);
925}
926
927static
928int ss_fop_close(struct file *fp, struct proc *p)
929{
930
931int fd;
932struct filedesc *fdp;
933
934 if(ss_debug){
935 fdp = p->p_fd;
936 fd = -1;
937 while(++fd < NOFILE)
938 if ( fp == fdp->fd_ofiles[fd] )
939 break;
940 printf("ss_fop_close: [%d] fd=%d ", p->p_pid, fd);
941 }
942
943 if(fp->f_type == DTYPE_SOCKET) {
944 if(ss_debug)
945 printf("is a socket\n");
946 return(close_s(fp, p));
947 }
948 else {
949 if(ss_debug)
950 printf("is not a socket\n");
951 return(ENOTSOCK);
952 }
953}
954
955void put_socket_fops(struct proc *p, int fd)
956{
957struct filedesc *fdp;
958struct file *fp;
959
960 fdp = p->p_fd;
961 fp = fdp->fd_ofiles[fd];
962 if (ss_socket_fops.fo_ioctl != fp->f_ops->fo_ioctl) {
963 bcopy(fp->f_ops, &ss_socket_fops, sizeof(struct fileops));
964 ioctl_s = ss_socket_fops.fo_ioctl; /* save standard ioctl */
965 close_s = ss_socket_fops.fo_close; /* save standard close */
966 ss_socket_fops.fo_ioctl = ss_fop_ioctl;
967 ss_socket_fops.fo_close = ss_fop_close;
968 }
969 fp->f_ops = &ss_socket_fops;
970
971 return;
972}
973
974int ss_SYSCALL(n,convert_arg,indicator,arg,p,retval)
975 int n; /* syscall ordinal */
976 int convert_arg; /* if not 0, argument to convert */
977 int indicator; /* type of argument to convert */
978 int *arg; /* address of alien arg */
979 struct proc *p;
980 int *retval;
981{
982int error;
983int rc;
984
985 if(convert_arg){
986 if(rc = ss_convert_struct( (caddr_t)*(arg + convert_arg),
987 indicator,
988 SS_ALIEN_TO_NATIVE))
989 return(rc);
990
991 error = (*sysent[n].sy_call)(p, arg + 1, retval);
992 rc = ss_convert_struct( (caddr_t)*(arg + convert_arg),
993 indicator,
994 SS_NATIVE_TO_ALIEN);
995 if(ss_debug)
996 printf("ss_SYSCALL: [%d] error=%d, rc=%d\n",
997 p->p_pid, error, rc);
998 }
999 else {
1000 rc = 0;
1001 error = (*sysent[n].sy_call)(p, arg + 1, retval);
1002 if(ss_debug)
1003 printf("ss_SYSCALL: [%d] error=%d\n",p->p_pid, error);
1004 }
1005
1006 return(error ? error : rc);
1007}
1008
1009int ss_IOCTL(fp, cmd, arg, p)
1010 struct file *fp;
1011 int cmd;
1012 int *arg; /* address of alien arg */
1013 struct proc *p;
1014{
1015int error, rc;
1016int these[2];
1017char cmd_type;
1018int cmd_ordinal;
1019int indicator;
1020
1021 cmd_type = (cmd >> 8) & 0xff;
1022 cmd_ordinal = cmd & 0xff;
1023 these[0] = cmd_type;
1024 these[1] = cmd_ordinal;
1025 if(ss_debug > 1)
1026 printf("ss_IOCTL: calling ss_convert with %d(%c) %d\n",
1027 these[0],these[0],these[1]);
1028 indicator = ss_convert( struct_whatevers, these, 0);
1029 if(ss_debug > 1)
1030 printf("ss_IOCTL: ss_convert returns indicator %d\n",indicator);
1031 if(indicator){
1032 error = ss_convert_struct((caddr_t)*(arg + 2),
1033 indicator,
1034 SS_ALIEN_TO_NATIVE);
1035 if(ss_debug > 1)
1036 printf("ss_IOCTL: ss_convert_struct returns %d\n",error);
1037 if(error)
1038 return(error);
1039 /* change len in ioctl now - in the general case */
1040 error = ioctl_s(fp, cmd, (caddr_t)arg, p);
1041 rc = ss_convert_struct( (caddr_t)*(arg + 2),
1042 indicator,
1043 SS_NATIVE_TO_ALIEN);
1044 if(ss_debug)
1045 printf("ss_IOCTL: [%d] error=%d, rc=%d\n",p->p_pid,
1046 error, rc);
1047 }
1048 else {
1049 rc = 0;
1050 error = ioctl_s(fp, cmd, (caddr_t)arg, p);
1051 if(ss_debug)
1052 printf("ss_IOCTL: [%d] error=%d\n",p->p_pid, error);
1053 }
1054
1055 return(error ? error : rc);
1056}
1057
1058
1059struct ss_socketopt_args {
1060 int s;
1061 int level;
1062 int name;
1063 caddr_t val;
1064 int valsize;
1065};
1066
1067int
1068ss_setsockopt(arg, ret, p)
1069 struct ss_socketopt_args *arg;
1070 int *ret;
1071 struct proc *p;
1072{
1073 int error, optname;
1074 int retval[2];
1075
1076 if (arg->level != 0xffff) /* FreeBSD, SCO and ? */
1077 return (ENOPROTOOPT);
1078
1079 optname = ss_convert(sopt_whatevers, &arg->name, 0);
1080
1081 switch (optname) {
1082
1083 case SO_ACCEPTCONN:
1084 case SO_BROADCAST:
1085 case SO_DEBUG:
1086 case SO_DONTROUTE:
1087 case SO_LINGER:
1088 case SO_KEEPALIVE:
1089 case SO_OOBINLINE:
1090 case SO_RCVBUF:
1091 case SO_RCVLOWAT:
1092 case SO_RCVTIMEO:
1093 case SO_REUSEADDR:
1094 case SO_SNDBUF:
1095 case SO_SNDLOWAT:
1096 case SO_SNDTIMEO:
1097 case SO_USELOOPBACK:
1098 error = SYSCALLX(SYS_setsockopt, arg);
1099 *ret = retval[0];
1100 *(ret + 1) = retval[1];
1101 return(error);
1102
1103 case SO_ERROR:
1104 case SO_IMASOCKET:
1105 case SO_NO_CHECK:
1106 case SO_ORDREL:
1107 case SO_PRIORITY:
1108 case SO_PROTOTYPE:
1109 case SO_TYPE:
1110 return (ENOPROTOOPT);
1111
1112 }
1113
1114 return (ENOPROTOOPT);
1115}
1116
1117
1118int
1119ss_getsockopt(arg, ret, p)
1120 struct ss_socketopt_args *arg;
1121 int *ret;
1122 struct proc *p;
1123{
1124 int error, optname;
1125 int retval[2];
1126
1127 if (arg->level != 0xffff) /* FreeBSD, SCO and ? */
1128 return (ENOPROTOOPT);
1129
1130 optname = ss_convert(sopt_whatevers, &arg->name, 0);
1131
1132 switch (optname) {
1133
1134 case SO_ACCEPTCONN:
1135 case SO_BROADCAST:
1136 case SO_DEBUG:
1137 case SO_DONTROUTE:
1138 case SO_ERROR:
1139 case SO_KEEPALIVE:
1140 case SO_LINGER:
1141 case SO_OOBINLINE:
1142 case SO_RCVBUF:
1143 case SO_RCVLOWAT:
1144 case SO_RCVTIMEO:
1145 case SO_REUSEADDR:
1146 case SO_SNDBUF:
1147 case SO_SNDLOWAT:
1148 case SO_SNDTIMEO:
1149 case SO_TYPE:
1150 case SO_USELOOPBACK:
1151 error = SYSCALLX(SYS_getsockopt, arg);
1152 *ret = retval[0];
1153 *(ret + 1) = retval[1];
1154 return(error);
1155
1156
1157 case SO_PROTOTYPE: {
1158 int value = 0;
1159
1160 error = copyout((caddr_t)&value, (caddr_t)arg->s, sizeof(int));
1161 return(error);
1162 }
1163
1164
1165 case SO_IMASOCKET: {
1166 int value = 1;
1167
1168 error = copyout((caddr_t)&value, (caddr_t)arg->s, sizeof(int));
1169 return(error);
1170 }
1171
1172 case SO_NO_CHECK:
1173 case SO_ORDREL:
1174 case SO_PRIORITY:
1175 return (ENOPROTOOPT);
1176 }
1177
1178 return (ENOPROTOOPT);
1179}
1180
1180
1181#define SS_CONVERT
1182int system_type = SS_FREEBSD; /* FreeBSD */
1183
1184int
1185ss_convert(what, this, otherwise)
1186 struct whatever **what;
1187 int *this;
1188 int otherwise;
1189{
1190 struct whatever *specific;
1191
1192 if(!(specific = what[system_type]))
1193 return *this;
1194
1195 for (; specific->from != -1; specific++)
1196 if(specific->from <= *this && *this <= specific->to)
1197 if(specific->from == specific->to){
1198 if(specific->more){
1199 specific = specific->more;
1200 this++;
1201 continue;
1202 }
1203 else {
1204 return((int)specific->conversion);
1205 }
1206 }
1207 else {
1208 return(specific->conversion ? (
1209 specific->all_the_same ? (int)specific->conversion : specific->conversion[*this - specific->from] ) : *this);
1210 }
1211
1212 return otherwise;
1213}
1214
1215/* Returns 0 - no conversion, no pointer modification
1216 1 - converted, relevant pointer modification
1217 -1 - error
1218 */
1219int
1220ss_convert_struct(alien, indicator, direction)
1221 char *alien;
1222 int indicator;
1223 int direction;
1224{
1225int error, len;
1226
1227 switch (system_type) {
1228
1229 case SS_FREEBSD:
1230 return(0);
1231 case SS_SYSVR4:
1232 case SS_SYSVR3:
1233 case SS_SCO_32:
1234 case SS_WYSE_321:
1235 case SS_ISC:
1236 case SS_LINUX:
1237
1238 switch(direction){
1239
1240 case SS_ALIEN_TO_NATIVE:
1241
1242 error = ss_atn(alien, indicator);
1243 if(ss_debug > 1)
1244 printf("ss_convert: ATN ss_atn error %d\n",error);
1245 return(error);
1246
1247 case SS_NATIVE_TO_ALIEN:
1248
1249 error = ss_nta(alien, indicator);
1250 if(ss_debug > 1)
1251 printf("ss_convert: NTA ss_nta error %d\n",error);
1252 return(error);
1253
1254 }
1255
1256 default:
1257
1258 printf("ss_convert_struct: not expecting system_type %d\n", system_type);
1259 break;
1260
1261 }
1262 return(EINVAL);
1263}
1264
1265/* note sockaddr_un linux unsigned short fam, 108 path
1266 BSD uchar , uchar 104 */
1267int
1268ss_atn(alien, indicator)
1269 char *alien;
1270 int indicator;
1271{
1272int error;
1273
1274 switch (indicator) {
1275
1276 case SS_STRUCT_ARPREQ:
1277 /* compatible */
1278 return(0);
1279
1280 case SS_STRUCT_IFCONF:
1281 /* compatible */
1282 return(0);
1283
1284 case SS_STRUCT_IFREQ:
1285 /* length OK - more unions - function dependent */
1286 return(0);
1287
1288 case SS_STRUCT_ORTENTRY:
1289 /* compatible */
1290 return(0);
1291
1292 case SS_STRUCT_SOCKADDR:{
1293 struct native_hdr {
1294 u_char len;
1295 u_char family;
1296 };
1297 union hdr_part {
1298 struct native_hdr native;
1299 u_short alien_family;
1300 } hdr;
1301
1302 if(error = copyin((caddr_t)alien,(caddr_t)&hdr,sizeof(hdr)))
1303 return(error);
1304 if(ss_debug > 1)
1305 printf("ss_atn:copyin 0x%x\n",hdr.alien_family);
1306
1307 if( hdr.alien_family < AF_MAX){
1308 hdr.native.family = hdr.alien_family >> 8; /* 386 endianess */
1309 /* OR LEN FOM A PARAM ? */
1310 hdr.native.len = sizeof(struct sockaddr);
1311 if(ss_debug > 1)
1312 printf("ss_atn:copyout 0x%x\n",hdr.alien_family);
1313 error = copyout((caddr_t)&hdr,(caddr_t)alien,sizeof(hdr));
1314 return(error);
1315 }
1316 else {
1317 printf("ss_atn: sa_family = %d\n", hdr.alien_family);
1318 return(EINVAL);
1319 }
1320
1321 }
1322
1323 case SS_STRUCT_SOCKNEWPROTO:
1324 /* don't have */
1325 printf("ss_atn: not expecting SS_STRUCT_SOCKNEWPROTO\n");
1326 return(EINVAL);
1327
1328 default:
1329 printf("ss_atn: not expecting case %d\n",indicator);
1330 return(EINVAL);
1331
1332 }
1333}
1334
1335/* note sockaddr_un linux unsigned short fam, 108 path
1336 BSD uchar , uchar 104 */
1337int
1338ss_nta(alien, indicator)
1339 char *alien;
1340 int indicator;
1341{
1342int error;
1343
1344 switch (indicator) {
1345
1346 case SS_STRUCT_ARPREQ:
1347 /* compatible */
1348 return(0);
1349
1350 case SS_STRUCT_IFCONF:
1351 /* compatible */
1352 return(0);
1353
1354 case SS_STRUCT_IFREQ:
1355 /* length OK - more unions - function dependent */
1356 return(0);
1357
1358 case SS_STRUCT_ORTENTRY:
1359 /* compatible */
1360 return(0);
1361
1362 case SS_STRUCT_SOCKADDR:{
1363 struct native_hdr {
1364 u_char len;
1365 u_char family;
1366 };
1367 union hdr_part {
1368 struct native_hdr native;
1369 u_short alien_family;
1370 } hdr;
1371
1372 if(error = copyin((caddr_t)alien,(caddr_t)&hdr,sizeof(hdr)))
1373 return(error);
1374 if(ss_debug > 1)
1375 printf("ss_nta:copyin 0x%x\n",hdr.alien_family);
1376 hdr.alien_family = hdr.native.family;
1377 if(ss_debug > 1)
1378 printf("ss_nta:copyout 0x%x\n",hdr.alien_family);
1379 error = copyout((caddr_t)&hdr,(caddr_t)alien,sizeof(hdr));
1380 return(error);
1381 }
1382
1383 case SS_STRUCT_SOCKNEWPROTO:
1384 /* don't have */
1385 printf("ss_nta: not expecting SS_STRUCT_SOCKNEWPROTO\n");
1386 return(EINVAL);
1387
1388 default:
1389 printf("ss_nta: not expecting case %d\n",indicator);
1390 return(EINVAL);
1391
1392 }
1393}
1181#define SS_CONVERT
1182int system_type = SS_FREEBSD; /* FreeBSD */
1183
1184int
1185ss_convert(what, this, otherwise)
1186 struct whatever **what;
1187 int *this;
1188 int otherwise;
1189{
1190 struct whatever *specific;
1191
1192 if(!(specific = what[system_type]))
1193 return *this;
1194
1195 for (; specific->from != -1; specific++)
1196 if(specific->from <= *this && *this <= specific->to)
1197 if(specific->from == specific->to){
1198 if(specific->more){
1199 specific = specific->more;
1200 this++;
1201 continue;
1202 }
1203 else {
1204 return((int)specific->conversion);
1205 }
1206 }
1207 else {
1208 return(specific->conversion ? (
1209 specific->all_the_same ? (int)specific->conversion : specific->conversion[*this - specific->from] ) : *this);
1210 }
1211
1212 return otherwise;
1213}
1214
1215/* Returns 0 - no conversion, no pointer modification
1216 1 - converted, relevant pointer modification
1217 -1 - error
1218 */
1219int
1220ss_convert_struct(alien, indicator, direction)
1221 char *alien;
1222 int indicator;
1223 int direction;
1224{
1225int error, len;
1226
1227 switch (system_type) {
1228
1229 case SS_FREEBSD:
1230 return(0);
1231 case SS_SYSVR4:
1232 case SS_SYSVR3:
1233 case SS_SCO_32:
1234 case SS_WYSE_321:
1235 case SS_ISC:
1236 case SS_LINUX:
1237
1238 switch(direction){
1239
1240 case SS_ALIEN_TO_NATIVE:
1241
1242 error = ss_atn(alien, indicator);
1243 if(ss_debug > 1)
1244 printf("ss_convert: ATN ss_atn error %d\n",error);
1245 return(error);
1246
1247 case SS_NATIVE_TO_ALIEN:
1248
1249 error = ss_nta(alien, indicator);
1250 if(ss_debug > 1)
1251 printf("ss_convert: NTA ss_nta error %d\n",error);
1252 return(error);
1253
1254 }
1255
1256 default:
1257
1258 printf("ss_convert_struct: not expecting system_type %d\n", system_type);
1259 break;
1260
1261 }
1262 return(EINVAL);
1263}
1264
1265/* note sockaddr_un linux unsigned short fam, 108 path
1266 BSD uchar , uchar 104 */
1267int
1268ss_atn(alien, indicator)
1269 char *alien;
1270 int indicator;
1271{
1272int error;
1273
1274 switch (indicator) {
1275
1276 case SS_STRUCT_ARPREQ:
1277 /* compatible */
1278 return(0);
1279
1280 case SS_STRUCT_IFCONF:
1281 /* compatible */
1282 return(0);
1283
1284 case SS_STRUCT_IFREQ:
1285 /* length OK - more unions - function dependent */
1286 return(0);
1287
1288 case SS_STRUCT_ORTENTRY:
1289 /* compatible */
1290 return(0);
1291
1292 case SS_STRUCT_SOCKADDR:{
1293 struct native_hdr {
1294 u_char len;
1295 u_char family;
1296 };
1297 union hdr_part {
1298 struct native_hdr native;
1299 u_short alien_family;
1300 } hdr;
1301
1302 if(error = copyin((caddr_t)alien,(caddr_t)&hdr,sizeof(hdr)))
1303 return(error);
1304 if(ss_debug > 1)
1305 printf("ss_atn:copyin 0x%x\n",hdr.alien_family);
1306
1307 if( hdr.alien_family < AF_MAX){
1308 hdr.native.family = hdr.alien_family >> 8; /* 386 endianess */
1309 /* OR LEN FOM A PARAM ? */
1310 hdr.native.len = sizeof(struct sockaddr);
1311 if(ss_debug > 1)
1312 printf("ss_atn:copyout 0x%x\n",hdr.alien_family);
1313 error = copyout((caddr_t)&hdr,(caddr_t)alien,sizeof(hdr));
1314 return(error);
1315 }
1316 else {
1317 printf("ss_atn: sa_family = %d\n", hdr.alien_family);
1318 return(EINVAL);
1319 }
1320
1321 }
1322
1323 case SS_STRUCT_SOCKNEWPROTO:
1324 /* don't have */
1325 printf("ss_atn: not expecting SS_STRUCT_SOCKNEWPROTO\n");
1326 return(EINVAL);
1327
1328 default:
1329 printf("ss_atn: not expecting case %d\n",indicator);
1330 return(EINVAL);
1331
1332 }
1333}
1334
1335/* note sockaddr_un linux unsigned short fam, 108 path
1336 BSD uchar , uchar 104 */
1337int
1338ss_nta(alien, indicator)
1339 char *alien;
1340 int indicator;
1341{
1342int error;
1343
1344 switch (indicator) {
1345
1346 case SS_STRUCT_ARPREQ:
1347 /* compatible */
1348 return(0);
1349
1350 case SS_STRUCT_IFCONF:
1351 /* compatible */
1352 return(0);
1353
1354 case SS_STRUCT_IFREQ:
1355 /* length OK - more unions - function dependent */
1356 return(0);
1357
1358 case SS_STRUCT_ORTENTRY:
1359 /* compatible */
1360 return(0);
1361
1362 case SS_STRUCT_SOCKADDR:{
1363 struct native_hdr {
1364 u_char len;
1365 u_char family;
1366 };
1367 union hdr_part {
1368 struct native_hdr native;
1369 u_short alien_family;
1370 } hdr;
1371
1372 if(error = copyin((caddr_t)alien,(caddr_t)&hdr,sizeof(hdr)))
1373 return(error);
1374 if(ss_debug > 1)
1375 printf("ss_nta:copyin 0x%x\n",hdr.alien_family);
1376 hdr.alien_family = hdr.native.family;
1377 if(ss_debug > 1)
1378 printf("ss_nta:copyout 0x%x\n",hdr.alien_family);
1379 error = copyout((caddr_t)&hdr,(caddr_t)alien,sizeof(hdr));
1380 return(error);
1381 }
1382
1383 case SS_STRUCT_SOCKNEWPROTO:
1384 /* don't have */
1385 printf("ss_nta: not expecting SS_STRUCT_SOCKNEWPROTO\n");
1386 return(EINVAL);
1387
1388 default:
1389 printf("ss_nta: not expecting case %d\n",indicator);
1390 return(EINVAL);
1391
1392 }
1393}