| 2986 | } |
| 2987 | |
| 2988 | int |
| 2989 | sosetopt(struct socket *so, struct sockopt *sopt) |
| 2990 | { |
| 2991 | int error, optval; |
| 2992 | struct linger l; |
| 2993 | struct timeval tv; |
| 2994 | sbintime_t val; |
| 2995 | uint32_t val32; |
| 2996 | #ifdef MAC |
| 2997 | struct mac extmac; |
| 2998 | #endif |
| 2999 | |
| 3000 | CURVNET_SET(so->so_vnet); |
| 3001 | error = 0; |
| 3002 | if (sopt->sopt_level != SOL_SOCKET) { |
| 3003 | if (so->so_proto->pr_ctloutput != NULL) |
| 3004 | error = (*so->so_proto->pr_ctloutput)(so, sopt); |
| 3005 | else |
| 3006 | error = ENOPROTOOPT; |
| 3007 | } else { |
| 3008 | switch (sopt->sopt_name) { |
| 3009 | case SO_ACCEPTFILTER: |
| 3010 | error = accept_filt_setopt(so, sopt); |
| 3011 | if (error) |
| 3012 | goto bad; |
| 3013 | break; |
| 3014 | |
| 3015 | case SO_LINGER: |
| 3016 | error = sooptcopyin(sopt, &l, sizeof l, sizeof l); |
| 3017 | if (error) |
| 3018 | goto bad; |
| 3019 | if (l.l_linger < 0 || |
| 3020 | l.l_linger > USHRT_MAX || |
| 3021 | l.l_linger > (INT_MAX / hz)) { |
| 3022 | error = EDOM; |
| 3023 | goto bad; |
| 3024 | } |
| 3025 | SOCK_LOCK(so); |
| 3026 | so->so_linger = l.l_linger; |
| 3027 | if (l.l_onoff) |
| 3028 | so->so_options |= SO_LINGER; |
| 3029 | else |
| 3030 | so->so_options &= ~SO_LINGER; |
| 3031 | SOCK_UNLOCK(so); |
| 3032 | break; |
| 3033 | |
| 3034 | case SO_DEBUG: |
| 3035 | case SO_KEEPALIVE: |
| 3036 | case SO_DONTROUTE: |
| 3037 | case SO_USELOOPBACK: |
| 3038 | case SO_BROADCAST: |
| 3039 | case SO_REUSEADDR: |
| 3040 | case SO_REUSEPORT: |
| 3041 | case SO_REUSEPORT_LB: |
| 3042 | case SO_OOBINLINE: |
| 3043 | case SO_TIMESTAMP: |
| 3044 | case SO_BINTIME: |
| 3045 | case SO_NOSIGPIPE: |
no test coverage detected