#include <sys/types.h>
#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 <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "dhcpd.h"
#include "debug.h"
#include "arpping.h"
Include dependency graph for arpping.c:
Go to the source code of this file.
Functions | |
int | arpping (u_int32_t yiaddr, u_int32_t ip, unsigned char *mac, char *interface) |
int arpping | ( | u_int32_t | yiaddr, | |
u_int32_t | ip, | |||
unsigned char * | mac, | |||
char * | interface | |||
) |
Definition at line 35 of file arpping.c.
References DEBUG, LOG, LOG_ERR, LOG_INFO, and MAC_BCAST_ADDR.
00036 { 00037 00038 int timeout = 2; 00039 int optval = 1; 00040 int s; /* socket */ 00041 int rv = 1; /* return value */ 00042 struct sockaddr addr; /* for interface name */ 00043 struct arpMsg arp; 00044 fd_set fdset; 00045 struct timeval tm; 00046 time_t prevTime; 00047 00048 00049 if ((s = socket (PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) == -1) { 00050 LOG(LOG_ERR, "Could not open raw socket"); 00051 return -1; 00052 } 00053 00054 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) == -1) { 00055 LOG(LOG_ERR, "Could not setsocketopt on raw socket"); 00056 close(s); 00057 return -1; 00058 } 00059 00060 /* send arp request */ 00061 memset(&arp, 0, sizeof(arp)); 00062 memcpy(arp.ethhdr.h_dest, MAC_BCAST_ADDR, 6); /* MAC DA */ 00063 memcpy(arp.ethhdr.h_source, mac, 6); /* MAC SA */ 00064 arp.ethhdr.h_proto = htons(ETH_P_ARP); /* protocol type (Ethernet) */ 00065 arp.htype = htons(ARPHRD_ETHER); /* hardware type */ 00066 arp.ptype = htons(ETH_P_IP); /* protocol type (ARP message) */ 00067 arp.hlen = 6; /* hardware address length */ 00068 arp.plen = 4; /* protocol address length */ 00069 arp.operation = htons(ARPOP_REQUEST); /* ARP op code */ 00070 *((u_int *) arp.sInaddr) = ip; /* source IP address */ 00071 memcpy(arp.sHaddr, mac, 6); /* source hardware address */ 00072 *((u_int *) arp.tInaddr) = yiaddr; /* target IP address */ 00073 00074 memset(&addr, 0, sizeof(addr)); 00075 strcpy(addr.sa_data, interface); 00076 if (sendto(s, &arp, sizeof(arp), 0, &addr, sizeof(addr)) < 0) 00077 rv = 0; 00078 00079 /* wait arp reply, and check it */ 00080 tm.tv_usec = 0; 00081 time(&prevTime); 00082 while (timeout > 0) { 00083 FD_ZERO(&fdset); 00084 FD_SET(s, &fdset); 00085 tm.tv_sec = timeout; 00086 if (select(s + 1, &fdset, (fd_set *) NULL, (fd_set *) NULL, &tm) < 0) { 00087 DEBUG(LOG_ERR, "Error on ARPING request: %s", strerror(errno)); 00088 if (errno != EINTR) rv = 0; 00089 } else if (FD_ISSET(s, &fdset)) { 00090 if (recv(s, &arp, sizeof(arp), 0) < 0 ) rv = 0; 00091 if (arp.operation == htons(ARPOP_REPLY) && 00092 bcmp(arp.tHaddr, mac, 6) == 0 && 00093 *((u_int *) arp.sInaddr) == yiaddr) { 00094 DEBUG(LOG_INFO, "Valid arp reply receved for this address"); 00095 rv = 0; 00096 break; 00097 } 00098 } 00099 timeout -= time(NULL) - prevTime; 00100 time(&prevTime); 00101 } 00102 close(s); 00103 DEBUG(LOG_INFO, "%salid arp replies for this address", rv ? "No v" : "V"); 00104 return rv; 00105 }