arp.c revision 24583
157429Smarkm/*
257429Smarkm * arp.c (C) 1995 Darren Reed
357429Smarkm *
457429Smarkm * The author provides this program as-is, with no gaurantee for its
565668Skris * suitability for any specific purpose.  The author takes no responsibility
660573Skris * for the misuse/abuse of this program and provides it for the sole purpose
765668Skris * of testing packet filter policies.  This file maybe distributed freely
865668Skris * providing it is not modified and that this notice remains in tact.
965668Skris */
1065668Skris#if !defined(lint) && defined(LIBC_SCCS)
1165668Skrisstatic	char	sccsid[] = "@(#)arp.c	1.4 1/11/96 (C)1995 Darren Reed";
1260573Skris#endif
1360573Skris#include <stdio.h>
1465668Skris#include <errno.h>
1560573Skris#include <sys/types.h>
1665668Skris#include <sys/socket.h>
1765668Skris#include <sys/sockio.h>
1865668Skris#include <sys/ioctl.h>
1965668Skris#include <netdb.h>
2065668Skris#include <netinet/in.h>
2165668Skris#include <net/if.h>
2265668Skris#include <net/if_arp.h>
2365668Skris#include <netinet/in.h>
2465668Skris#include <netinet/ip_var.h>
2565668Skris#include <netinet/tcp.h>
2665668Skris#include "ipsend.h"
2765668Skris
2865668Skris#if defined(__SVR4) || defined(__svr4__)
2965668Skris#define	bcopy(a,b,c)	memmove(b,a,c)
3065668Skris#define	bzero(a,c)	memset(a,0,c)
3165668Skris#define	bcmp(a,b,c)	memcmp(a,b,c)
3265668Skris#endif
3365668Skris
3465668Skris/*
3565668Skris * lookup host and return
3665668Skris * its IP address in address
3760573Skris * (4 bytes)
3892555Sdes */
3965668Skrisint	resolve(host, address)
4065668Skrischar	*host, *address;
4165668Skris{
4265668Skris        struct	hostent	*hp;
4365668Skris        u_long	add;
4465668Skris
4565668Skris	add = inet_addr(host);
4665668Skris	if (add == -1)
4765668Skris	    {
4865668Skris		if (!(hp = gethostbyname(host)))
4965668Skris		    {
5065668Skris			fprintf(stderr, "unknown host: %s\n", host);
5165668Skris			return -1;
5265668Skris		    }
5365668Skris		bcopy((char *)hp->h_addr, (char *)address, 4);
5465668Skris		return 0;
5565668Skris	}
5665668Skris	bcopy((char*)&add, address, 4);
5765668Skris	return 0;
5865668Skris}
5957429Smarkm
6057429Smarkm/*
6157429Smarkm * ARP for the MAC address corresponding
62137015Sdes * to the IP address.  This taken from
6357429Smarkm * some BSD program, I cant remember which.
6476259Sgreen */
6576259Sgreenint	arp(ip, ether)
6676259Sgreenchar	*ip;
6757429Smarkmchar	*ether;
6857429Smarkm{
6957429Smarkm	static	int	sfd = -1;
7060573Skris	static	char	ethersave[6], ipsave[4];
7160573Skris	struct	arpreq	ar;
7260573Skris	struct	sockaddr_in	*sin, san;
7365668Skris	struct	hostent	*hp;
7465668Skris	int	fd;
7576259Sgreen
7676259Sgreen	if (!bcmp(ipsave, ip, 4)) {
7776259Sgreen		bcopy(ethersave, ether, 6);
7876259Sgreen		return 0;
7976259Sgreen	}
8076259Sgreen	fd = -1;
8176259Sgreen	bzero((char *)&ar, sizeof(ar));
82137015Sdes	sin = (struct sockaddr_in *)&ar.arp_pa;
8376259Sgreen	sin->sin_family = AF_INET;
84137015Sdes	bcopy(ip, (char *)&sin->sin_addr.s_addr, 4);
85137015Sdes	if ((hp = gethostbyaddr(ip, 4, AF_INET)))
86137015Sdes		if (!(ether_hostton(hp->h_name, ether)))
8760573Skris			goto savearp;
8869587Sgreen
8968700Sgreen	if (sfd == -1)
9068700Sgreen		if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
9157429Smarkm		    {
9257429Smarkm			perror("arp: socket");
9357429Smarkm			return -1;
94126274Sdes		    }
95126274Sdestryagain:
96126274Sdes	if (ioctl(sfd, SIOCGARP, (caddr_t)&ar) == -1)
97137015Sdes	    {
98137015Sdes		if (fd == -1)
99137015Sdes		    {
10057429Smarkm			bzero((char *)&san, sizeof(san));
10157429Smarkm			san.sin_family = AF_INET;
10257429Smarkm			san.sin_port = htons(1);
10357429Smarkm			bcopy(ip, &san.sin_addr.s_addr, 4);
10457429Smarkm			fd = socket(AF_INET, SOCK_DGRAM, 0);
10557429Smarkm			(void) sendto(fd, ip, 4, 0,
10657429Smarkm				      (struct sockaddr *)&san, sizeof(san));
10757429Smarkm			sleep(1);
10857429Smarkm			(void) close(fd);
10957429Smarkm			goto tryagain;
11057429Smarkm		    }
11157429Smarkm		fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr));
11257429Smarkm		if (errno != ENXIO)
11392555Sdes			perror("SIOCGARP");
11492555Sdes		return -1;
11557429Smarkm	    }
11657429Smarkm
11757429Smarkm	bcopy(ar.arp_ha.sa_data, ether, 6);
11857429Smarkmsavearp:
11957429Smarkm	bcopy(ether, ethersave, 6);
12065668Skris	bcopy(ip, ipsave, 4);
12165668Skris	return 0;
12257429Smarkm}
12357429Smarkm