* Set a particular packet option, as a sticky option or an ancillary data * item. "len" can be 0 only when it's a sticky option. * We have 4 cases of combination of "sticky" and "cmsg": * "sticky=0, cmsg=0": impossible * "sticky=0, cmsg=1": RFC2292 or RFC3542 ancillary data * "sticky=1, cmsg=0": RFC3542 socket option * "sticky=1, cmsg=1": RFC2292 socket option */
| 2881 | * "sticky=1, cmsg=1": RFC2292 socket option |
| 2882 | */ |
| 2883 | static int |
| 2884 | ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt, |
| 2885 | struct ucred *cred, int sticky, int cmsg, int uproto) |
| 2886 | { |
| 2887 | int minmtupolicy, preftemp; |
| 2888 | int error; |
| 2889 | |
| 2890 | if (!sticky && !cmsg) { |
| 2891 | #ifdef DIAGNOSTIC |
| 2892 | printf("ip6_setpktopt: impossible case\n"); |
| 2893 | #endif |
| 2894 | return (EINVAL); |
| 2895 | } |
| 2896 | |
| 2897 | /* |
| 2898 | * IPV6_2292xxx is for backward compatibility to RFC2292, and should |
| 2899 | * not be specified in the context of RFC3542. Conversely, |
| 2900 | * RFC3542 types should not be specified in the context of RFC2292. |
| 2901 | */ |
| 2902 | if (!cmsg) { |
| 2903 | switch (optname) { |
| 2904 | case IPV6_2292PKTINFO: |
| 2905 | case IPV6_2292HOPLIMIT: |
| 2906 | case IPV6_2292NEXTHOP: |
| 2907 | case IPV6_2292HOPOPTS: |
| 2908 | case IPV6_2292DSTOPTS: |
| 2909 | case IPV6_2292RTHDR: |
| 2910 | case IPV6_2292PKTOPTIONS: |
| 2911 | return (ENOPROTOOPT); |
| 2912 | } |
| 2913 | } |
| 2914 | if (sticky && cmsg) { |
| 2915 | switch (optname) { |
| 2916 | case IPV6_PKTINFO: |
| 2917 | case IPV6_HOPLIMIT: |
| 2918 | case IPV6_NEXTHOP: |
| 2919 | case IPV6_HOPOPTS: |
| 2920 | case IPV6_DSTOPTS: |
| 2921 | case IPV6_RTHDRDSTOPTS: |
| 2922 | case IPV6_RTHDR: |
| 2923 | case IPV6_USE_MIN_MTU: |
| 2924 | case IPV6_DONTFRAG: |
| 2925 | case IPV6_TCLASS: |
| 2926 | case IPV6_PREFER_TEMPADDR: /* XXX: not an RFC3542 option */ |
| 2927 | return (ENOPROTOOPT); |
| 2928 | } |
| 2929 | } |
| 2930 | |
| 2931 | switch (optname) { |
| 2932 | case IPV6_2292PKTINFO: |
| 2933 | case IPV6_PKTINFO: |
| 2934 | { |
| 2935 | struct ifnet *ifp = NULL; |
| 2936 | struct in6_pktinfo *pktinfo; |
| 2937 | |
| 2938 | if (len != sizeof(struct in6_pktinfo)) |
| 2939 | return (EINVAL); |
| 2940 |
no test coverage detected