⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arp-ioctl.c

📁 Ubuntu packages of security software。 相当不错的源码
💻 C
字号:
/* * arp-ioctl.c * * Copyright (c) 2001 Dug Song <dugsong@monkey.org> * * $Id: arp-ioctl.c,v 1.25 2005/02/09 22:31:00 dugsong Exp $ */#include "config.h"#include <sys/param.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/socket.h>#ifdef HAVE_STREAMS_MIB2# include <sys/sockio.h># include <sys/stream.h># include <sys/tihdr.h># include <sys/tiuser.h># include <inet/common.h># include <inet/mib2.h># include <inet/ip.h># undef IP_ADDR_LEN#elif defined(HAVE_SYS_MIB_H)# include <sys/mib.h>#endif#include <net/if.h>#include <net/if_arp.h>#ifdef HAVE_STREAMS_MIB2# include <netinet/in.h># include <stropts.h>#endif#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "dnet.h"#ifdef HAVE_LINUX_PROCFS#define PROC_ARP_FILE	"/proc/net/arp"#endifstruct arp_handle {	int	 fd;#ifdef HAVE_ARPREQ_ARP_DEV	intf_t	*intf;#endif};arp_t *arp_open(void){	arp_t *a;		if ((a = calloc(1, sizeof(*a))) != NULL) {#ifdef HAVE_STREAMS_MIB2		if ((a->fd = open(IP_DEV_NAME, O_RDWR)) < 0)#elif defined(HAVE_STREAMS_ROUTE)		if ((a->fd = open("/dev/route", O_WRONLY, 0)) < 0)#else		if ((a->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)#endif			return (arp_close(a));#ifdef HAVE_ARPREQ_ARP_DEV		if ((a->intf = intf_open()) == NULL)			return (arp_close(a));#endif	}	return (a);}#ifdef HAVE_ARPREQ_ARP_DEVstatic int_arp_set_dev(const struct intf_entry *entry, void *arg){	struct arpreq *ar = (struct arpreq *)arg;	struct addr dst;	uint32_t mask;	if (entry->intf_type == INTF_TYPE_ETH &&	    entry->intf_addr.addr_type == ADDR_TYPE_IP) {		addr_btom(entry->intf_addr.addr_bits, &mask, IP_ADDR_LEN);		addr_ston((struct sockaddr *)&ar->arp_pa, &dst);			if ((entry->intf_addr.addr_ip & mask) ==		    (dst.addr_ip & mask)) {			strlcpy(ar->arp_dev, entry->intf_name,			    sizeof(ar->arp_dev));			return (1);		}	}	return (0);}#endifintarp_add(arp_t *a, const struct arp_entry *entry){	struct arpreq ar;	memset(&ar, 0, sizeof(ar));	if (addr_ntos(&entry->arp_pa, &ar.arp_pa) < 0)		return (-1);	/* XXX - see arp(7) for details... */#ifdef __linux__	if (addr_ntos(&entry->arp_ha, &ar.arp_ha) < 0)		return (-1);	ar.arp_ha.sa_family = ARP_HRD_ETH;#else	/* XXX - Solaris, HP-UX, IRIX, other Mentat stacks? */	ar.arp_ha.sa_family = AF_UNSPEC;	memcpy(ar.arp_ha.sa_data, &entry->arp_ha.addr_eth, ETH_ADDR_LEN);#endif#ifdef HAVE_ARPREQ_ARP_DEV	if (intf_loop(a->intf, _arp_set_dev, &ar) != 1) {		errno = ESRCH;		return (-1);	}#endif	ar.arp_flags = ATF_PERM | ATF_COM;#ifdef hpux	/* XXX - screwy extended arpreq struct */	{		struct sockaddr_in *sin;		ar.arp_hw_addr_len = ETH_ADDR_LEN;		sin = (struct sockaddr_in *)&ar.arp_pa_mask;		sin->sin_family = AF_INET;		sin->sin_addr.s_addr = IP_ADDR_BROADCAST;	}#endif	if (ioctl(a->fd, SIOCSARP, &ar) < 0)		return (-1);#ifdef HAVE_STREAMS_MIB2	/* XXX - force entry into ipNetToMediaTable. */	{		struct sockaddr_in sin;		int fd;				addr_ntos(&entry->arp_pa, (struct sockaddr *)&sin);		sin.sin_port = htons(666);				if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)			return (-1);				if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {			close(fd);			return (-1);		}		write(fd, NULL, 0);		close(fd);	}#endif	return (0);}intarp_delete(arp_t *a, const struct arp_entry *entry){	struct arpreq ar;	memset(&ar, 0, sizeof(ar));		if (addr_ntos(&entry->arp_pa, &ar.arp_pa) < 0)		return (-1);		if (ioctl(a->fd, SIOCDARP, &ar) < 0)		return (-1);	return (0);}intarp_get(arp_t *a, struct arp_entry *entry){	struct arpreq ar;	memset(&ar, 0, sizeof(ar));		if (addr_ntos(&entry->arp_pa, &ar.arp_pa) < 0)		return (-1);	#ifdef HAVE_ARPREQ_ARP_DEV	if (intf_loop(a->intf, _arp_set_dev, &ar) != 1) {		errno = ESRCH;		return (-1);	}#endif	if (ioctl(a->fd, SIOCGARP, &ar) < 0)		return (-1);	if ((ar.arp_flags & ATF_COM) == 0) {		errno = ESRCH;		return (-1);	}	return (addr_ston(&ar.arp_ha, &entry->arp_ha));}#ifdef HAVE_LINUX_PROCFSintarp_loop(arp_t *a, arp_handler callback, void *arg){	FILE *fp;	struct arp_entry entry;	char buf[BUFSIZ], ipbuf[100], macbuf[100], maskbuf[100], devbuf[100];	int i, type, flags, ret;	if ((fp = fopen(PROC_ARP_FILE, "r")) == NULL)		return (-1);	ret = 0;	while (fgets(buf, sizeof(buf), fp) != NULL) {		i = sscanf(buf, "%s 0x%x 0x%x %100s %100s %100s\n",		    ipbuf, &type, &flags, macbuf, maskbuf, devbuf);				if (i < 4 || (flags & ATF_COM) == 0)			continue;				if (addr_aton(ipbuf, &entry.arp_pa) == 0 &&		    addr_aton(macbuf, &entry.arp_ha) == 0) {			if ((ret = callback(&entry, arg)) != 0)				break;		}	}	if (ferror(fp)) {		fclose(fp);		return (-1);	}	fclose(fp);		return (ret);}#elif defined (HAVE_STREAMS_MIB2)intarp_loop(arp_t *r, arp_handler callback, void *arg){	struct arp_entry entry;	struct strbuf msg;	struct T_optmgmt_req *tor;	struct T_optmgmt_ack *toa;	struct T_error_ack *tea;	struct opthdr *opt;	mib2_ipNetToMediaEntry_t *arp, *arpend;	u_char buf[8192];	int flags, rc, atable, ret;	tor = (struct T_optmgmt_req *)buf;	toa = (struct T_optmgmt_ack *)buf;	tea = (struct T_error_ack *)buf;	tor->PRIM_type = T_OPTMGMT_REQ;	tor->OPT_offset = sizeof(*tor);	tor->OPT_length = sizeof(*opt);	tor->MGMT_flags = T_CURRENT;		opt = (struct opthdr *)(tor + 1);	opt->level = MIB2_IP;	opt->name = opt->len = 0;		msg.maxlen = sizeof(buf);	msg.len = sizeof(*tor) + sizeof(*opt);	msg.buf = buf;		if (putmsg(r->fd, &msg, NULL, 0) < 0)		return (-1);		opt = (struct opthdr *)(toa + 1);	msg.maxlen = sizeof(buf);		for (;;) {		flags = 0;		if ((rc = getmsg(r->fd, &msg, NULL, &flags)) < 0)			return (-1);		/* See if we're finished. */		if (rc == 0 &&		    msg.len >= sizeof(*toa) &&		    toa->PRIM_type == T_OPTMGMT_ACK &&		    toa->MGMT_flags == T_SUCCESS && opt->len == 0)			break;		if (msg.len >= sizeof(*tea) && tea->PRIM_type == T_ERROR_ACK)			return (-1);				if (rc != MOREDATA || msg.len < (int)sizeof(*toa) ||		    toa->PRIM_type != T_OPTMGMT_ACK ||		    toa->MGMT_flags != T_SUCCESS)			return (-1);				atable = (opt->level == MIB2_IP && opt->name == MIB2_IP_22);				msg.maxlen = sizeof(buf) - (sizeof(buf) % sizeof(*arp));		msg.len = 0;		flags = 0;				do {			rc = getmsg(r->fd, NULL, &msg, &flags);						if (rc != 0 && rc != MOREDATA)				return (-1);						if (!atable)				continue;						arp = (mib2_ipNetToMediaEntry_t *)msg.buf;			arpend = (mib2_ipNetToMediaEntry_t *)			    (msg.buf + msg.len);			entry.arp_pa.addr_type = ADDR_TYPE_IP;			entry.arp_pa.addr_bits = IP_ADDR_BITS;						entry.arp_ha.addr_type = ADDR_TYPE_ETH;			entry.arp_ha.addr_bits = ETH_ADDR_BITS;			for ( ; arp < arpend; arp++) {				entry.arp_pa.addr_ip =				    arp->ipNetToMediaNetAddress;								memcpy(&entry.arp_ha.addr_eth,				    arp->ipNetToMediaPhysAddress.o_bytes,				    ETH_ADDR_LEN);								if ((ret = callback(&entry, arg)) != 0)					return (ret);			}		} while (rc == MOREDATA);	}	return (0);}#elif defined(HAVE_SYS_MIB_H)#define MAX_ARPENTRIES	512	/* XXX */intarp_loop(arp_t *r, arp_handler callback, void *arg){	struct nmparms nm;	struct arp_entry entry;	mib_ipNetToMediaEnt arpentries[MAX_ARPENTRIES];	int fd, i, n, ret;		if ((fd = open_mib("/dev/ip", O_RDWR, 0 /* XXX */, 0)) < 0)		return (-1);		nm.objid = ID_ipNetToMediaTable;	nm.buffer = arpentries;	n = sizeof(arpentries);	nm.len = &n;		if (get_mib_info(fd, &nm) < 0) {		close_mib(fd);		return (-1);	}	close_mib(fd);	entry.arp_pa.addr_type = ADDR_TYPE_IP;	entry.arp_pa.addr_bits = IP_ADDR_BITS;	entry.arp_ha.addr_type = ADDR_TYPE_ETH;	entry.arp_ha.addr_bits = ETH_ADDR_BITS;		n /= sizeof(*arpentries);	ret = 0;		for (i = 0; i < n; i++) {		if (arpentries[i].Type == INTM_INVALID ||		    arpentries[i].PhysAddr.o_length != ETH_ADDR_LEN)			continue;				entry.arp_pa.addr_ip = arpentries[i].NetAddr;		memcpy(&entry.arp_ha.addr_eth, arpentries[i].PhysAddr.o_bytes,		    ETH_ADDR_LEN);				if ((ret = callback(&entry, arg)) != 0)			break;	}	return (ret);}#elif defined(HAVE_NET_RADIX_H) && !defined(_AIX)/* XXX - Tru64, others? */#include <netinet/if_ether.h>#include <nlist.h>static int_kread(int fd, void *addr, void *buf, int len){	if (lseek(fd, (off_t)addr, SEEK_SET) == (off_t)-1L)		return (-1);	return (read(fd, buf, len) == len ? 0 : -1);}static int_radix_walk(int fd, struct radix_node *rn, arp_handler callback, void *arg){	struct radix_node rnode;	struct rtentry rt;	struct sockaddr_in sin;	struct arptab at;	struct arp_entry entry;	int ret = 0; again:	_kread(fd, rn, &rnode, sizeof(rnode));	if (rnode.rn_b < 0) {		if (!(rnode.rn_flags & RNF_ROOT)) {			_kread(fd, rn, &rt, sizeof(rt));			_kread(fd, rt_key(&rt), &sin, sizeof(sin));			addr_ston((struct sockaddr *)&sin, &entry.arp_pa);			_kread(fd, rt.rt_llinfo, &at, sizeof(at));			if (at.at_flags & ATF_COM) {				addr_pack(&entry.arp_ha, ADDR_TYPE_ETH,				    ETH_ADDR_BITS, at.at_hwaddr, ETH_ADDR_LEN);				if ((ret = callback(&entry, arg)) != 0)					return (ret);			}		}		if ((rn = rnode.rn_dupedkey))			goto again;	} else {		rn = rnode.rn_r;		if ((ret = _radix_walk(fd, rnode.rn_l, callback, arg)) != 0)			return (ret);		if ((ret = _radix_walk(fd, rn, callback, arg)) != 0)			return (ret);	}	return (ret);}intarp_loop(arp_t *r, arp_handler callback, void *arg){	struct ifnet *ifp, ifnet;	struct ifnet_arp_cache_head ifarp;	struct radix_node_head *head;		struct nlist nl[2];	int fd, ret = 0;	memset(nl, 0, sizeof(nl));	nl[0].n_name = "ifnet";		if (knlist(nl) < 0 || nl[0].n_type == 0 ||	    (fd = open("/dev/kmem", O_RDONLY, 0)) < 0)		return (-1);	for (ifp = (struct ifnet *)nl[0].n_value;	    ifp != NULL; ifp = ifnet.if_next) {		_kread(fd, ifp, &ifnet, sizeof(ifnet));		if (ifnet.if_arp_cache_head != NULL) {			_kread(fd, ifnet.if_arp_cache_head,			    &ifarp, sizeof(ifarp));			/* XXX - only ever one rnh, only ever AF_INET. */			if ((ret = _radix_walk(fd, ifarp.arp_cache_head.rnh_treetop,				 callback, arg)) != 0)				break;		}	}	close(fd);	return (ret);}#elseintarp_loop(arp_t *a, arp_handler callback, void *arg){	errno = ENOSYS;	return (-1);}#endifarp_t *arp_close(arp_t *a){	if (a != NULL) {		if (a->fd >= 0)			close(a->fd);#ifdef HAVE_ARPREQ_ARP_DEV		if (a->intf != NULL)			intf_close(a->intf);#endif		free(a);	}	return (NULL);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -