Commit 2efbe911d3ea518f5d4648954379f9d5aa02e806
1 parent
667f38b1
more set/getsockopt values
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1516 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
71 additions
and
7 deletions
linux-user/syscall.c
@@ -547,7 +547,21 @@ static long do_setsockopt(int sockfd, int level, int optname, | @@ -547,7 +547,21 @@ static long do_setsockopt(int sockfd, int level, int optname, | ||
547 | break; | 547 | break; |
548 | case SOL_IP: | 548 | case SOL_IP: |
549 | switch(optname) { | 549 | switch(optname) { |
550 | + case IP_TOS: | ||
551 | + case IP_TTL: | ||
550 | case IP_HDRINCL: | 552 | case IP_HDRINCL: |
553 | + case IP_ROUTER_ALERT: | ||
554 | + case IP_RECVOPTS: | ||
555 | + case IP_RETOPTS: | ||
556 | + case IP_PKTINFO: | ||
557 | + case IP_MTU_DISCOVER: | ||
558 | + case IP_RECVERR: | ||
559 | + case IP_RECVTOS: | ||
560 | +#ifdef IP_FREEBIND | ||
561 | + case IP_FREEBIND: | ||
562 | +#endif | ||
563 | + case IP_MULTICAST_TTL: | ||
564 | + case IP_MULTICAST_LOOP: | ||
551 | val = 0; | 565 | val = 0; |
552 | if (optlen >= sizeof(uint32_t)) { | 566 | if (optlen >= sizeof(uint32_t)) { |
553 | if (get_user(val, (uint32_t *)optval)) | 567 | if (get_user(val, (uint32_t *)optval)) |
@@ -619,6 +633,45 @@ static long do_getsockopt(int sockfd, int level, int optname, | @@ -619,6 +633,45 @@ static long do_getsockopt(int sockfd, int level, int optname, | ||
619 | /* These don't just return a single integer */ | 633 | /* These don't just return a single integer */ |
620 | goto unimplemented; | 634 | goto unimplemented; |
621 | default: | 635 | default: |
636 | + goto int_case; | ||
637 | + } | ||
638 | + break; | ||
639 | + case SOL_TCP: | ||
640 | + /* TCP options all take an 'int' value. */ | ||
641 | + int_case: | ||
642 | + if (get_user(len, optlen)) | ||
643 | + return -EFAULT; | ||
644 | + if (len < 0) | ||
645 | + return -EINVAL; | ||
646 | + lv = sizeof(int); | ||
647 | + ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); | ||
648 | + if (ret < 0) | ||
649 | + return ret; | ||
650 | + val = tswap32(val); | ||
651 | + if (len > lv) | ||
652 | + len = lv; | ||
653 | + if (copy_to_user(optval, &val, len)) | ||
654 | + return -EFAULT; | ||
655 | + if (put_user(len, optlen)) | ||
656 | + return -EFAULT; | ||
657 | + break; | ||
658 | + case SOL_IP: | ||
659 | + switch(optname) { | ||
660 | + case IP_TOS: | ||
661 | + case IP_TTL: | ||
662 | + case IP_HDRINCL: | ||
663 | + case IP_ROUTER_ALERT: | ||
664 | + case IP_RECVOPTS: | ||
665 | + case IP_RETOPTS: | ||
666 | + case IP_PKTINFO: | ||
667 | + case IP_MTU_DISCOVER: | ||
668 | + case IP_RECVERR: | ||
669 | + case IP_RECVTOS: | ||
670 | +#ifdef IP_FREEBIND | ||
671 | + case IP_FREEBIND: | ||
672 | +#endif | ||
673 | + case IP_MULTICAST_TTL: | ||
674 | + case IP_MULTICAST_LOOP: | ||
622 | if (get_user(len, optlen)) | 675 | if (get_user(len, optlen)) |
623 | return -EFAULT; | 676 | return -EFAULT; |
624 | if (len < 0) | 677 | if (len < 0) |
@@ -627,14 +680,25 @@ static long do_getsockopt(int sockfd, int level, int optname, | @@ -627,14 +680,25 @@ static long do_getsockopt(int sockfd, int level, int optname, | ||
627 | ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); | 680 | ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); |
628 | if (ret < 0) | 681 | if (ret < 0) |
629 | return ret; | 682 | return ret; |
630 | - val = tswap32(val); | ||
631 | - if (len > lv) | ||
632 | - len = lv; | ||
633 | - if (copy_to_user(optval, &val, len)) | ||
634 | - return -EFAULT; | ||
635 | - if (put_user(len, optlen)) | ||
636 | - return -EFAULT; | 683 | + if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) { |
684 | + unsigned char ucval = val; | ||
685 | + len = 1; | ||
686 | + if (put_user(len, optlen)) | ||
687 | + return -EFAULT; | ||
688 | + if (copy_to_user(optval,&ucval,1)) | ||
689 | + return -EFAULT; | ||
690 | + } else { | ||
691 | + val = tswap32(val); | ||
692 | + if (len > sizeof(int)) | ||
693 | + len = sizeof(int); | ||
694 | + if (put_user(len, optlen)) | ||
695 | + return -EFAULT; | ||
696 | + if (copy_to_user(optval, &val, len)) | ||
697 | + return -EFAULT; | ||
698 | + } | ||
637 | break; | 699 | break; |
700 | + default: | ||
701 | + goto unimplemented; | ||
638 | } | 702 | } |
639 | break; | 703 | break; |
640 | default: | 704 | default: |