+/* vi: set sw=4 ts=4: */
/*
* arpping.c
*
* by Yoichi Hariguchi <yoichi@fore.com>
*/
-#include <sys/time.h>
-#include <time.h>
-#include <sys/socket.h>
#include <netinet/if_ether.h>
#include <net/if_arp.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include "dhcpd.h"
-#include "arpping.h"
#include "common.h"
+#include "dhcpd.h"
+
+
+struct arpMsg {
+ /* Ethernet header */
+ uint8_t h_dest[6]; /* destination ether addr */
+ uint8_t h_source[6]; /* source ether addr */
+ uint16_t h_proto; /* packet type ID field */
+
+ /* ARP packet */
+ uint16_t htype; /* hardware type (must be ARPHRD_ETHER) */
+ uint16_t ptype; /* protocol type (must be ETH_P_IP) */
+ uint8_t hlen; /* hardware address length (must be 6) */
+ uint8_t plen; /* protocol address length (must be 4) */
+ uint16_t operation; /* ARP opcode */
+ uint8_t sHaddr[6]; /* sender's hardware address */
+ uint8_t sInaddr[4]; /* sender's IP address */
+ uint8_t tHaddr[6]; /* target's hardware address */
+ uint8_t tInaddr[4]; /* target's IP address */
+ uint8_t pad[18]; /* pad for min. Ethernet payload (60 bytes) */
+} ATTRIBUTE_PACKED;
/* args: yiaddr - what IP to ping
* ip - our ip
/* FIXME: match response against chaddr */
int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *mac, char *interface)
{
-
int timeout = 2;
- int optval = 1;
int s; /* socket */
int rv = 1; /* return value */
struct sockaddr addr; /* for interface name */
time_t prevTime;
- if ((s = socket (PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) == -1) {
-#ifdef IN_BUSYBOX
- LOG(LOG_ERR, bb_msg_can_not_create_raw_socket);
-#else
- LOG(LOG_ERR, "Could not open raw socket");
-#endif
+ s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP));
+ if (s == -1) {
+ bb_perror_msg(bb_msg_can_not_create_raw_socket);
return -1;
}
- if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) == -1) {
- LOG(LOG_ERR, "Could not setsocketopt on raw socket");
+ if (setsockopt_broadcast(s) == -1) {
+ bb_perror_msg("cannot setsocketopt on raw socket");
close(s);
return -1;
}
FD_SET(s, &fdset);
tm.tv_sec = timeout;
if (select(s + 1, &fdset, (fd_set *) NULL, (fd_set *) NULL, &tm) < 0) {
- DEBUG(LOG_ERR, "Error on ARPING request: %m");
+ bb_perror_msg("error on ARPING request");
if (errno != EINTR) rv = 0;
} else if (FD_ISSET(s, &fdset)) {
if (recv(s, &arp, sizeof(arp), 0) < 0 ) rv = 0;
if (arp.operation == htons(ARPOP_REPLY) &&
memcmp(arp.tHaddr, mac, 6) == 0 &&
*((uint32_t *) arp.sInaddr) == yiaddr) {
- DEBUG(LOG_INFO, "Valid arp reply receved for this address");
+ DEBUG("Valid arp reply received for this address");
rv = 0;
break;
}
prevTime = uptime();
}
close(s);
- DEBUG(LOG_INFO, "%salid arp replies for this address", rv ? "No v" : "V");
+ DEBUG("%salid arp replies for this address", rv ? "No v" : "V");
return rv;
}