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