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

📄 myarp.c

📁 一个基于linux的TCP/IP协议栈的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
#define MYIN_DEV_ARP_IGNORE(in_dev) \		(max(myipv4_devconf.arp_ignore, (in_dev)->cnf.arp_ignore))#define MYIN_DEV_ARPFILTER(in_dev) \	(myipv4_devconf.arp_filter || (in_dev)->cnf.arp_filter)#define MYIN_DEV_ARP_ANNOUNCE(in_dev)	\	(max(myipv4_devconf.arp_announce, (in_dev)->cnf.arp_announce))static int myarp_ignore(struct in_device *in_dev, struct net_device *dev,				u32 sip, u32 tip){	int scope;	switch( MYIN_DEV_ARP_IGNORE(in_dev) ){	case 0:			return 0;	case 1:		sip = 0;		scope = RT_SCOPE_HOST;		break;	case 2:			scope = RT_SCOPE_HOST;		break;	case 3:		sip = 0;		scope = RT_SCOPE_LINK;		dev = NULL;		break;	case 4:	case 5:	case 6:	case 7:		return 0;	case 8:		return 1;	default:		return 0;	}	return !myinet_confirm_addr( dev, sip, tip, scope );}static void myarp_solicit(struct neighbour *neigh, struct sk_buff *skb){	u32 saddr = 0;	u8  *dst_ha = NULL;	struct net_device *dev = neigh->dev;	u32 target = *(u32*)neigh->primary_key;	int probes = atomic_read(&neigh->probes);	struct in_device *in_dev = in_dev_get(dev);	if (!in_dev)		return;	switch (MYIN_DEV_ARP_ANNOUNCE(in_dev)) {	default:	case 0:		if( skb && myinet_addr_type(skb->nh.iph->saddr) == RTN_LOCAL )			saddr = skb->nh.iph->saddr;		break;	case 1:		if (!skb)			break;		saddr = skb->nh.iph->saddr;		if( myinet_addr_type(saddr) == RTN_LOCAL ){			if( myinet_addr_onlink(in_dev, target, saddr) )				break;		}		saddr = 0;		break;	case 2:		break;	}	if (in_dev)		in_dev_put(in_dev);	if (!saddr)		saddr = myinet_select_addr(dev, target, RT_SCOPE_LINK);	if ((probes -= neigh->parms->ucast_probes) < 0) {		if (!(neigh->nud_state&NUD_VALID))			printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n");		dst_ha = neigh->ha;		read_lock_bh(&neigh->lock);	} else if ((probes -= neigh->parms->app_probes) < 0) {#ifdef CONFIG_ARPD		neigh_app_ns(neigh);#endif		return;	}	myarp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,		 dst_ha, dev->dev_addr, NULL);	if (dst_ha)		read_unlock_bh(&neigh->lock);}static void myarp_error_report(struct neighbour *neigh, struct sk_buff *skb){}static struct neigh_ops myarp_generic_ops = {	.family =			MY_AF_INET,	.solicit =			myarp_solicit,	.error_report =		myarp_error_report,	.output =			neigh_resolve_output,	.connected_output =	neigh_connected_output,	.hh_output =		dev_queue_xmit,	.queue_xmit =		dev_queue_xmit,};static struct neigh_ops myarp_hh_ops = {	.family =			MY_AF_INET,	.solicit =			myarp_solicit,	.error_report =		myarp_error_report,	.output =			neigh_resolve_output,	.connected_output =	neigh_resolve_output,	.hh_output =		dev_queue_xmit,	.queue_xmit =		dev_queue_xmit,};struct neigh_ops myarp_broken_ops = {	.family =			MY_AF_INET,	.solicit =			myarp_solicit,	.error_report =		myarp_error_report,	.output =			neigh_compat_output,	.connected_output =	neigh_compat_output,	.hh_output =		dev_queue_xmit,	.queue_xmit =		dev_queue_xmit,};static struct neigh_ops myarp_direct_ops = {	.family =			MY_AF_INET,	.output =			dev_queue_xmit,	.connected_output =	dev_queue_xmit,	.hh_output =		dev_queue_xmit,	.queue_xmit =		dev_queue_xmit,};int myarp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir){	switch (dev->type) {	case ARPHRD_ETHER:	case ARPHRD_FDDI:	case ARPHRD_IEEE802:		ip_eth_mc_map(addr, haddr);		return 0; 	case ARPHRD_IEEE802_TR:		ip_tr_mc_map(addr, haddr);		return 0;	case ARPHRD_INFINIBAND:		ip_ib_mc_map(addr, haddr);		return 0;	default:		if (dir) {			memcpy(haddr, dev->broadcast, dev->addr_len);			return 0;		}	}	return -EINVAL;}static u32 myarp_hash(const void *pkey, const struct net_device *dev){	return jhash_2words(*(u32 *)pkey, dev->ifindex, myarp_tbl.hash_rnd);}static int myarp_constructor(struct neighbour *neigh){	u32 addr = *(u32*)neigh->primary_key;	struct net_device *dev = neigh->dev;	struct in_device *in_dev;	struct neigh_parms *parms;		neigh->type = myinet_addr_type(addr);	rcu_read_lock();	in_dev = __in_dev_get_rcu(dev);	if (in_dev == NULL) {		rcu_read_unlock();		return -EINVAL;	}	parms = in_dev->arp_parms;	__neigh_parms_put(neigh->parms);	neigh->parms = neigh_parms_clone(parms);	rcu_read_unlock();	if (dev->hard_header == NULL) {		neigh->nud_state = NUD_NOARP;		neigh->ops = &myarp_direct_ops;		neigh->output = neigh->ops->queue_xmit;	}else{		switch (dev->type) {			default:				break;			case ARPHRD_ROSE:	#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)		case ARPHRD_AX25:#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)		case ARPHRD_NETROM:#endif			neigh->ops = &myarp_broken_ops;			neigh->output = neigh->ops->output;			return 0;#endif		;}		if( neigh->type == RTN_MULTICAST ){			neigh->nud_state = NUD_NOARP;			myarp_mc_map(addr, neigh->ha, dev, 1);		}else if( dev->flags & (IFF_NOARP|IFF_LOOPBACK) ){			neigh->nud_state = NUD_NOARP;			memcpy(neigh->ha, dev->dev_addr, dev->addr_len);		}else if( neigh->type == RTN_BROADCAST || dev->flags&IFF_POINTOPOINT ){			neigh->nud_state = NUD_NOARP;			memcpy(neigh->ha, dev->broadcast, dev->addr_len);		}		if (dev->hard_header_cache){			printk(KERN_INFO "arp hh ops!\n");			neigh->ops = &myarp_hh_ops;		}else{			printk(KERN_INFO "arp generic ops!\n");			neigh->ops = &myarp_generic_ops;		}		if( neigh->nud_state & NUD_VALID ){			printk(KERN_INFO "connected output!\n");			neigh->output = neigh->ops->connected_output;		}else			neigh->output = neigh->ops->output;		printk(KERN_INFO "output: %p\n", neigh->output);	}	return 0;}static void myparp_redo(struct sk_buff *skb){}struct neigh_table myarp_tbl = {	.family =		MY_AF_INET,	.entry_size =	sizeof(struct neighbour) + 4,	.key_len =		4,	.hash =			myarp_hash,	.constructor =	myarp_constructor,	.proxy_redo =	myparp_redo,	.id =		"myarp_cache",	.parms = {		.tbl =			&myarp_tbl,		.base_reachable_time =	30 * HZ,		.retrans_time =	1 * HZ,		.gc_staletime =	60 * HZ,		.reachable_time =		30 * HZ,		.delay_probe_time =	5 * HZ,		.queue_len =		3,		.ucast_probes =	3,		.mcast_probes =	3,		.anycast_delay =	1 * HZ,		.proxy_delay =		(8 * HZ) / 10,		.proxy_qlen =		64,		.locktime =		1 * HZ,	},	.gc_interval =	30 * HZ,	.gc_thresh1 =	128,	.gc_thresh2 =	512,	.gc_thresh3 =	1024,};int myarp_bind_neighbour(struct dst_entry *dst){	struct net_device *dev = dst->dev;	struct neighbour *n = dst->neighbour;	if (dev == NULL)		return -EINVAL;	if (n == NULL) {		u32 nexthop = ((struct rtable*)dst)->rt_gateway;		printk(KERN_INFO "nexthop: %u.%u.%u.%u\n", NIPQUAD(nexthop) );		if( dev->flags & (IFF_LOOPBACK|IFF_POINTOPOINT) )			nexthop = 0;		n = __neigh_lookup_errno( &myarp_tbl, &nexthop, dev);		if( IS_ERR(n) )			return PTR_ERR(n);		printk(KERN_INFO "neighbour.parms: %p\n", n->parms );		printk(KERN_INFO "neighbour.used: %lu\n", n->used );		printk(KERN_INFO "neighbour.confirmed: %lu\n", n->confirmed );		printk(KERN_INFO "neighbour.updated: %lu\n", n->updated );		printk(KERN_INFO "neighbour.flags: %x\n", n->flags );		printk(KERN_INFO "neighbour.nud_state: %x\n", n->nud_state );		printk(KERN_INFO "neighbour.type: %d\n", n->type );		printk(KERN_INFO "neighbour.dead: %d\n", n->dead );		printk(KERN_INFO "neighbour.probes: %d\n", atomic_read( &(n->probes) ) );		printk(KERN_INFO "neighbour.ha: %x.%x.%x.%x.%x.%x\n", n->ha[0], n->ha[1], n->ha[2],												n->ha[3], n->ha[4], n->ha[5] );		printk(KERN_INFO "neighbour.hh: %p\n", n->hh);		printk(KERN_INFO "neighbour.refcnt: %d\n", atomic_read( &(n->refcnt) ) );		printk(KERN_INFO "neighbour.primary key: %u.%u.%u.%u\n", NIPQUAD(n->primary_key) );		dst->neighbour = n;	}	return 0;}struct sk_buff *myarp_create(int type, int ptype, u32 dest_ip,				struct net_device *dev, u32 src_ip,				unsigned char *dest_hw, unsigned char *src_hw,				unsigned char *target_hw){	struct sk_buff *skb;	struct arphdr *arp;	unsigned char *arp_ptr;	skb = alloc_skb(sizeof(struct arphdr)+ 2*(dev->addr_len+4)				+ LL_RESERVED_SPACE(dev), GFP_ATOMIC);	if (skb == NULL)		return NULL;	skb_reserve(skb, LL_RESERVED_SPACE(dev));	skb->nh.raw = skb->data;	arp = (struct arphdr *) skb_put(skb,sizeof(struct arphdr) + 2*(dev->addr_len+4));	skb->dev = dev;	skb->protocol = htons(ETH_P_ARP);	if (src_hw == NULL)		src_hw = dev->dev_addr;	if (dest_hw == NULL)		dest_hw = dev->broadcast;	if (dev->hard_header &&	    dev->hard_header(skb,dev,ptype,dest_hw,src_hw,skb->len) < 0)		goto out;	switch (dev->type) {	default:		arp->ar_hrd = htons(dev->type);		arp->ar_pro = htons(ETH_P_IP);		break;#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)	case ARPHRD_AX25:

⌨️ 快捷键说明

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