/* * Builds and sends a single ARP request to locate the server * * Return value: * 0 on success * errno on error */ static int netdump_send_arp(in_addr_t dst) { struct ether_addr bcast; struct mbuf *m; struct arphdr *ah; int pktlen; MPASS(nd_ifp != NULL); /* Fill-up a broadcast address. */ memset(&bcast, 0xFF, ETHER_ADDR_LEN); m = m_gethdr(M_NOWAIT, MT_DATA); if (m == NULL) { printf("netdump_send_arp: Out of mbufs\n"); return (ENOBUFS); } pktlen = arphdr_len2(ETHER_ADDR_LEN, sizeof(struct in_addr)); m->m_len = pktlen; m->m_pkthdr.len = pktlen; MH_ALIGN(m, pktlen); ah = mtod(m, struct arphdr *); ah->ar_hrd = htons(ARPHRD_ETHER); ah->ar_pro = htons(ETHERTYPE_IP); ah->ar_hln = ETHER_ADDR_LEN; ah->ar_pln = sizeof(struct in_addr); ah->ar_op = htons(ARPOP_REQUEST); memcpy(ar_sha(ah), IF_LLADDR(nd_ifp), ETHER_ADDR_LEN); ((struct in_addr *)ar_spa(ah))->s_addr = nd_client.s_addr; bzero(ar_tha(ah), ETHER_ADDR_LEN); ((struct in_addr *)ar_tpa(ah))->s_addr = dst; return (netdump_ether_output(m, nd_ifp, bcast, ETHERTYPE_ARP)); }
static int send_arp (interface_t *iface, int op, struct in_addr sip, unsigned char *taddr, struct in_addr tip) { struct arphdr *arp; int arpsize = arphdr_len2 (iface->hwlen, sizeof (struct in_addr)); int retval; arp = xmalloc (arpsize); memset (arp, 0, arpsize); arp->ar_hrd = htons (iface->family); arp->ar_pro = htons (ETHERTYPE_IP); arp->ar_hln = iface->hwlen; arp->ar_pln = sizeof (struct in_addr); arp->ar_op = htons (op); memcpy (ar_sha (arp), &iface->hwaddr, arp->ar_hln); memcpy (ar_spa (arp), &sip, arp->ar_pln); if (taddr) memcpy (ar_tha (arp), taddr, arp->ar_hln); memcpy (ar_tpa (arp), &tip, arp->ar_pln); retval = send_packet (iface, ETHERTYPE_ARP, (unsigned char *) arp, arphdr_len (arp)); free (arp); return (retval); }