| 1201 | } |
| 1202 | |
| 1203 | static int |
| 1204 | ether_resolvemulti(struct ifnet *ifp, struct sockaddr **llsa, |
| 1205 | struct sockaddr *sa) |
| 1206 | { |
| 1207 | struct sockaddr_dl *sdl; |
| 1208 | #ifdef INET |
| 1209 | struct sockaddr_in *sin; |
| 1210 | #endif |
| 1211 | #ifdef INET6 |
| 1212 | struct sockaddr_in6 *sin6; |
| 1213 | #endif |
| 1214 | u_char *e_addr; |
| 1215 | |
| 1216 | switch(sa->sa_family) { |
| 1217 | case AF_LINK: |
| 1218 | /* |
| 1219 | * No mapping needed. Just check that it's a valid MC address. |
| 1220 | */ |
| 1221 | sdl = (struct sockaddr_dl *)sa; |
| 1222 | e_addr = LLADDR(sdl); |
| 1223 | if (!ETHER_IS_MULTICAST(e_addr)) |
| 1224 | return EADDRNOTAVAIL; |
| 1225 | *llsa = NULL; |
| 1226 | return 0; |
| 1227 | |
| 1228 | #ifdef INET |
| 1229 | case AF_INET: |
| 1230 | sin = (struct sockaddr_in *)sa; |
| 1231 | if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) |
| 1232 | return EADDRNOTAVAIL; |
| 1233 | sdl = link_init_sdl(ifp, *llsa, IFT_ETHER); |
| 1234 | sdl->sdl_alen = ETHER_ADDR_LEN; |
| 1235 | e_addr = LLADDR(sdl); |
| 1236 | ETHER_MAP_IP_MULTICAST(&sin->sin_addr, e_addr); |
| 1237 | *llsa = (struct sockaddr *)sdl; |
| 1238 | return 0; |
| 1239 | #endif |
| 1240 | #ifdef INET6 |
| 1241 | case AF_INET6: |
| 1242 | sin6 = (struct sockaddr_in6 *)sa; |
| 1243 | if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { |
| 1244 | /* |
| 1245 | * An IP6 address of 0 means listen to all |
| 1246 | * of the Ethernet multicast address used for IP6. |
| 1247 | * (This is used for multicast routers.) |
| 1248 | */ |
| 1249 | ifp->if_flags |= IFF_ALLMULTI; |
| 1250 | *llsa = NULL; |
| 1251 | return 0; |
| 1252 | } |
| 1253 | if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) |
| 1254 | return EADDRNOTAVAIL; |
| 1255 | sdl = link_init_sdl(ifp, *llsa, IFT_ETHER); |
| 1256 | sdl->sdl_alen = ETHER_ADDR_LEN; |
| 1257 | e_addr = LLADDR(sdl); |
| 1258 | ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, e_addr); |
| 1259 | *llsa = (struct sockaddr *)sdl; |
| 1260 | return 0; |
nothing calls this directly
no test coverage detected