1145519Sdarrenr/*	$FreeBSD$	*/
2145510Sdarrenr
322514Sdarrenr/*
422514Sdarrenr * Based upon 4.4BSD's /usr/sbin/arp
522514Sdarrenr */
622514Sdarrenr#include <sys/param.h>
722514Sdarrenr#include <sys/file.h>
822514Sdarrenr#include <sys/socket.h>
922514Sdarrenr#include <sys/sysctl.h>
1022514Sdarrenr#include <net/if.h>
11145510Sdarrenr#if __FreeBSD_version >= 300000
12145510Sdarrenr# include <net/if_var.h>
13145510Sdarrenr#endif
1422514Sdarrenr#include <net/if_dl.h>
1522514Sdarrenr#include <net/if_types.h>
16145510Sdarrenr#if defined(__FreeBSD__)
17145510Sdarrenr# include "radix_ipf.h"
18145510Sdarrenr#endif
19170268Sdarrenr#ifndef __osf__
20170268Sdarrenr# include <net/route.h>
21170268Sdarrenr#endif
2222514Sdarrenr#include <netinet/in.h>
2322514Sdarrenr#include <netinet/if_ether.h>
2422514Sdarrenr#include <arpa/inet.h>
25145510Sdarrenr#include <netinet/in.h>
26145510Sdarrenr#include <netinet/in_systm.h>
27145510Sdarrenr#include <netinet/ip.h>
28145510Sdarrenr#include <netinet/ip_var.h>
29145510Sdarrenr#include <netinet/tcp.h>
30145510Sdarrenr#include <unistd.h>
31145510Sdarrenr#include <string.h>
32145510Sdarrenr#include <stdlib.h>
3322514Sdarrenr#include <netdb.h>
3422514Sdarrenr#include <errno.h>
3522514Sdarrenr#include <nlist.h>
3622514Sdarrenr#include <stdio.h>
3724583Sdarrenr#include "ipsend.h"
3853024Sguido#include "iplang/iplang.h"
3922514Sdarrenr
4024583Sdarrenr
4122514Sdarrenr/*
4222514Sdarrenr * lookup host and return
4322514Sdarrenr * its IP address in address
4422514Sdarrenr * (4 bytes)
4522514Sdarrenr */
46145510Sdarrenrint	resolve(host, address)
4722514Sdarrenrchar	*host, *address;
4822514Sdarrenr{
4922514Sdarrenr        struct	hostent	*hp;
5022514Sdarrenr        u_long	add;
5122514Sdarrenr
5222514Sdarrenr	add = inet_addr(host);
5322514Sdarrenr	if (add == -1)
5422514Sdarrenr	    {
5522514Sdarrenr		if (!(hp = gethostbyname(host)))
5622514Sdarrenr		    {
5722514Sdarrenr			fprintf(stderr, "unknown host: %s\n", host);
5822514Sdarrenr			return -1;
5922514Sdarrenr		    }
6022514Sdarrenr		bcopy((char *)hp->h_addr, (char *)address, 4);
6122514Sdarrenr		return 0;
6222514Sdarrenr	}
6322514Sdarrenr	bcopy((char*)&add, address, 4);
6422514Sdarrenr	return 0;
6522514Sdarrenr}
6622514Sdarrenr
6722514Sdarrenr
6822514Sdarrenrint	arp(addr, eaddr)
6922514Sdarrenrchar	*addr, *eaddr;
7022514Sdarrenr{
7122514Sdarrenr	int	mib[6];
7222514Sdarrenr	size_t	needed;
7323279Speter	char	*lim, *buf, *next;
7422514Sdarrenr	struct	rt_msghdr	*rtm;
7522514Sdarrenr	struct	sockaddr_inarp	*sin;
7622514Sdarrenr	struct	sockaddr_dl	*sdl;
7722514Sdarrenr
7853024Sguido#ifdef	IPSEND
7967615Sdarrenr	if (arp_getipv4(addr, ether) == 0)
8053024Sguido		return 0;
8153024Sguido#endif
8253024Sguido
83145510Sdarrenr	if (!addr)
84145510Sdarrenr		return -1;
85145510Sdarrenr
8622514Sdarrenr	mib[0] = CTL_NET;
8722514Sdarrenr	mib[1] = PF_ROUTE;
8822514Sdarrenr	mib[2] = 0;
8922514Sdarrenr	mib[3] = AF_INET;
9022514Sdarrenr	mib[4] = NET_RT_FLAGS;
91186119Sqingli#ifdef RTF_LLINFO
9222514Sdarrenr	mib[5] = RTF_LLINFO;
93186119Sqingli#else
94186119Sqingli	mib[5] = 0;
95186119Sqingli#endif
96186119Sqingli
9722514Sdarrenr	if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1)
9822514Sdarrenr	    {
9922514Sdarrenr		perror("route-sysctl-estimate");
10022514Sdarrenr		exit(-1);
10122514Sdarrenr	    }
10222514Sdarrenr	if ((buf = malloc(needed)) == NULL)
10322514Sdarrenr	    {
10422514Sdarrenr		perror("malloc");
10522514Sdarrenr		exit(-1);
10622514Sdarrenr	    }
10722514Sdarrenr	if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1)
10822514Sdarrenr	    {
10922514Sdarrenr		perror("actual retrieval of routing table");
11022514Sdarrenr		exit(-1);
11122514Sdarrenr	    }
11222514Sdarrenr	lim = buf + needed;
11322514Sdarrenr	for (next = buf; next < lim; next += rtm->rtm_msglen)
11422514Sdarrenr	    {
11522514Sdarrenr		rtm = (struct rt_msghdr *)next;
11622514Sdarrenr		sin = (struct sockaddr_inarp *)(rtm + 1);
11722514Sdarrenr		sdl = (struct sockaddr_dl *)(sin + 1);
118145510Sdarrenr		if (!bcmp(addr, (char *)&sin->sin_addr,
119145510Sdarrenr			  sizeof(struct in_addr)))
12022514Sdarrenr		    {
12122514Sdarrenr			bcopy(LLADDR(sdl), eaddr, sdl->sdl_alen);
12222514Sdarrenr			return 0;
12322514Sdarrenr		    }
12422514Sdarrenr	    }
12522514Sdarrenr	return -1;
12622514Sdarrenr}
127