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;
|
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}
|