| 1080 | } |
| 1081 | |
| 1082 | static int |
| 1083 | udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td) |
| 1084 | { |
| 1085 | struct inpcb *inp; |
| 1086 | struct inpcbinfo *pcbinfo; |
| 1087 | int error; |
| 1088 | u_char vflagsav; |
| 1089 | |
| 1090 | pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol); |
| 1091 | inp = sotoinpcb(so); |
| 1092 | KASSERT(inp != NULL, ("udp6_bind: inp == NULL")); |
| 1093 | |
| 1094 | INP_WLOCK(inp); |
| 1095 | INP_HASH_WLOCK(pcbinfo); |
| 1096 | vflagsav = inp->inp_vflag; |
| 1097 | inp->inp_vflag &= ~INP_IPV4; |
| 1098 | inp->inp_vflag |= INP_IPV6; |
| 1099 | if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) { |
| 1100 | struct sockaddr_in6 *sin6_p; |
| 1101 | |
| 1102 | sin6_p = (struct sockaddr_in6 *)nam; |
| 1103 | |
| 1104 | if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr)) |
| 1105 | inp->inp_vflag |= INP_IPV4; |
| 1106 | #ifdef INET |
| 1107 | else if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) { |
| 1108 | struct sockaddr_in sin; |
| 1109 | |
| 1110 | in6_sin6_2_sin(&sin, sin6_p); |
| 1111 | inp->inp_vflag |= INP_IPV4; |
| 1112 | inp->inp_vflag &= ~INP_IPV6; |
| 1113 | error = in_pcbbind(inp, (struct sockaddr *)&sin, |
| 1114 | td->td_ucred); |
| 1115 | goto out; |
| 1116 | } |
| 1117 | #endif |
| 1118 | } |
| 1119 | |
| 1120 | error = in6_pcbbind(inp, nam, td->td_ucred); |
| 1121 | #ifdef INET |
| 1122 | out: |
| 1123 | #endif |
| 1124 | if (error != 0) |
| 1125 | inp->inp_vflag = vflagsav; |
| 1126 | INP_HASH_WUNLOCK(pcbinfo); |
| 1127 | INP_WUNLOCK(inp); |
| 1128 | return (error); |
| 1129 | } |
| 1130 | |
| 1131 | static void |
| 1132 | udp6_close(struct socket *so) |
nothing calls this directly
no test coverage detected