| 200 | } |
| 201 | |
| 202 | static int |
| 203 | ether_resolve_addr(struct ifnet *ifp, struct mbuf *m, |
| 204 | const struct sockaddr *dst, struct route *ro, u_char *phdr, |
| 205 | uint32_t *pflags, struct llentry **plle) |
| 206 | { |
| 207 | struct ether_header *eh; |
| 208 | uint32_t lleflags = 0; |
| 209 | int error = 0; |
| 210 | #if defined(INET) || defined(INET6) |
| 211 | uint16_t etype; |
| 212 | #endif |
| 213 | |
| 214 | if (plle) |
| 215 | *plle = NULL; |
| 216 | eh = (struct ether_header *)phdr; |
| 217 | |
| 218 | switch (dst->sa_family) { |
| 219 | #ifdef INET |
| 220 | case AF_INET: |
| 221 | if ((m->m_flags & (M_BCAST | M_MCAST)) == 0) |
| 222 | error = arpresolve(ifp, 0, m, dst, phdr, &lleflags, |
| 223 | plle); |
| 224 | else { |
| 225 | if (m->m_flags & M_BCAST) |
| 226 | memcpy(eh->ether_dhost, ifp->if_broadcastaddr, |
| 227 | ETHER_ADDR_LEN); |
| 228 | else { |
| 229 | const struct in_addr *a; |
| 230 | a = &(((const struct sockaddr_in *)dst)->sin_addr); |
| 231 | ETHER_MAP_IP_MULTICAST(a, eh->ether_dhost); |
| 232 | } |
| 233 | etype = htons(ETHERTYPE_IP); |
| 234 | memcpy(&eh->ether_type, &etype, sizeof(etype)); |
| 235 | memcpy(eh->ether_shost, IF_LLADDR(ifp), ETHER_ADDR_LEN); |
| 236 | } |
| 237 | break; |
| 238 | #endif |
| 239 | #ifdef INET6 |
| 240 | case AF_INET6: |
| 241 | if ((m->m_flags & M_MCAST) == 0) |
| 242 | error = nd6_resolve(ifp, 0, m, dst, phdr, &lleflags, |
| 243 | plle); |
| 244 | else { |
| 245 | const struct in6_addr *a6; |
| 246 | a6 = &(((const struct sockaddr_in6 *)dst)->sin6_addr); |
| 247 | ETHER_MAP_IPV6_MULTICAST(a6, eh->ether_dhost); |
| 248 | etype = htons(ETHERTYPE_IPV6); |
| 249 | memcpy(&eh->ether_type, &etype, sizeof(etype)); |
| 250 | memcpy(eh->ether_shost, IF_LLADDR(ifp), ETHER_ADDR_LEN); |
| 251 | } |
| 252 | break; |
| 253 | #endif |
| 254 | default: |
| 255 | if_printf(ifp, "can't handle af%d\n", dst->sa_family); |
| 256 | if (m != NULL) |
| 257 | m_freem(m); |
| 258 | return (EAFNOSUPPORT); |
| 259 | } |
no test coverage detected