| 674 | static |
| 675 | #endif |
| 676 | int |
| 677 | sendit(struct thread *td, int s, struct msghdr *mp, int flags) |
| 678 | { |
| 679 | struct mbuf *control; |
| 680 | struct sockaddr *to; |
| 681 | int error; |
| 682 | |
| 683 | #ifdef CAPABILITY_MODE |
| 684 | if (IN_CAPABILITY_MODE(td) && (mp->msg_name != NULL)) |
| 685 | return (ECAPMODE); |
| 686 | #endif |
| 687 | |
| 688 | if (mp->msg_name != NULL) { |
| 689 | error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); |
| 690 | if (error != 0) { |
| 691 | to = NULL; |
| 692 | goto bad; |
| 693 | } |
| 694 | mp->msg_name = to; |
| 695 | } else { |
| 696 | to = NULL; |
| 697 | } |
| 698 | |
| 699 | if (mp->msg_control) { |
| 700 | if (mp->msg_controllen < sizeof(struct cmsghdr) |
| 701 | #ifdef COMPAT_OLDSOCK |
| 702 | && (mp->msg_flags != MSG_COMPAT || |
| 703 | !SV_PROC_FLAG(td->td_proc, SV_AOUT)) |
| 704 | #endif |
| 705 | ) { |
| 706 | error = EINVAL; |
| 707 | goto bad; |
| 708 | } |
| 709 | error = sockargs(&control, mp->msg_control, |
| 710 | mp->msg_controllen, MT_CONTROL); |
| 711 | if (error != 0) |
| 712 | goto bad; |
| 713 | #ifdef COMPAT_OLDSOCK |
| 714 | if (mp->msg_flags == MSG_COMPAT && |
| 715 | SV_PROC_FLAG(td->td_proc, SV_AOUT)) { |
| 716 | struct cmsghdr *cm; |
| 717 | |
| 718 | M_PREPEND(control, sizeof(*cm), M_WAITOK); |
| 719 | cm = mtod(control, struct cmsghdr *); |
| 720 | cm->cmsg_len = control->m_len; |
| 721 | cm->cmsg_level = SOL_SOCKET; |
| 722 | cm->cmsg_type = SCM_RIGHTS; |
| 723 | } |
| 724 | #endif |
| 725 | } else { |
| 726 | control = NULL; |
| 727 | } |
| 728 | |
| 729 | error = kern_sendit(td, s, mp, flags, control, UIO_USERSPACE); |
| 730 | |
| 731 | bad: |
| 732 | free(to, M_SONAME); |
| 733 | return (error); |
no test coverage detected