* Builds and sends a single ARP request to locate the L2 address for a given * INET address. * * Return value: * 0 on success * errno on error */
| 224 | * errno on error |
| 225 | */ |
| 226 | static int |
| 227 | debugnet_send_arp(struct debugnet_pcb *pcb, in_addr_t dst) |
| 228 | { |
| 229 | struct ether_addr bcast; |
| 230 | struct arphdr *ah; |
| 231 | struct ifnet *ifp; |
| 232 | struct mbuf *m; |
| 233 | int pktlen; |
| 234 | |
| 235 | ifp = pcb->dp_ifp; |
| 236 | |
| 237 | /* Fill-up a broadcast address. */ |
| 238 | memset(&bcast, 0xFF, ETHER_ADDR_LEN); |
| 239 | m = m_gethdr(M_NOWAIT, MT_DATA); |
| 240 | if (m == NULL) { |
| 241 | printf("%s: Out of mbufs\n", __func__); |
| 242 | return (ENOBUFS); |
| 243 | } |
| 244 | pktlen = arphdr_len2(ETHER_ADDR_LEN, sizeof(struct in_addr)); |
| 245 | m->m_len = pktlen; |
| 246 | m->m_pkthdr.len = pktlen; |
| 247 | MH_ALIGN(m, pktlen); |
| 248 | ah = mtod(m, struct arphdr *); |
| 249 | ah->ar_hrd = htons(ARPHRD_ETHER); |
| 250 | ah->ar_pro = htons(ETHERTYPE_IP); |
| 251 | ah->ar_hln = ETHER_ADDR_LEN; |
| 252 | ah->ar_pln = sizeof(struct in_addr); |
| 253 | ah->ar_op = htons(ARPOP_REQUEST); |
| 254 | memcpy(ar_sha(ah), IF_LLADDR(ifp), ETHER_ADDR_LEN); |
| 255 | ((struct in_addr *)ar_spa(ah))->s_addr = pcb->dp_client; |
| 256 | bzero(ar_tha(ah), ETHER_ADDR_LEN); |
| 257 | ((struct in_addr *)ar_tpa(ah))->s_addr = dst; |
| 258 | return (debugnet_ether_output(m, ifp, bcast, ETHERTYPE_ARP)); |
| 259 | } |
| 260 | |
| 261 | /* |
| 262 | * Handler for ARP packets: checks their sanity and then |
no test coverage detected