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

📄 myarp.c

📁 一个基于linux的TCP/IP协议栈的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		arp->ar_hrd = htons(ARPHRD_AX25);		arp->ar_pro = htons(AX25_P_IP);		break;#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)	case ARPHRD_NETROM:		arp->ar_hrd = htons(ARPHRD_NETROM);		arp->ar_pro = htons(AX25_P_IP);		break;#endif#endif#ifdef CONFIG_FDDI	case ARPHRD_FDDI:		arp->ar_hrd = htons(ARPHRD_ETHER);		arp->ar_pro = htons(ETH_P_IP);		break;#endif#ifdef CONFIG_TR	case ARPHRD_IEEE802_TR:		arp->ar_hrd = htons(ARPHRD_IEEE802);		arp->ar_pro = htons(ETH_P_IP);		break;#endif	}	arp->ar_hln = dev->addr_len;	arp->ar_pln = 4;	arp->ar_op = htons(type);	arp_ptr=(unsigned char *)(arp+1);	memcpy(arp_ptr, src_hw, dev->addr_len);	arp_ptr+=dev->addr_len;	memcpy(arp_ptr, &src_ip,4);	arp_ptr+=4;	if (target_hw != NULL)		memcpy(arp_ptr, target_hw, dev->addr_len);	else		memset(arp_ptr, 0, dev->addr_len);	arp_ptr+=dev->addr_len;	memcpy(arp_ptr, &dest_ip, 4);	return skb;out:	kfree_skb(skb);	return NULL;}void myarp_xmit(struct sk_buff *skb){	NF_HOOK(NF_ARP, NF_ARP_OUT, skb, NULL, skb->dev, dev_queue_xmit);}void myarp_send(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;	if (dev->flags&IFF_NOARP)		return;	skb = myarp_create(type, ptype, dest_ip, dev, src_ip,					dest_hw, src_hw, target_hw);	if( skb == NULL ){		return;	}	myarp_xmit(skb);}static int myarp_filter(__u32 sip, __u32 tip, struct net_device *dev){/*	struct flowi fl = { .nl_u = { .ip4_u = { .daddr = sip,						 .saddr = tip } } };	struct rtable *rt;	int flag = 0; 	if (ip_route_output_key(&rt, &fl) < 0) 		return 1;	if (rt->u.dst.dev != dev) { 		NET_INC_STATS_BH(LINUX_MIB_ARPFILTER);		flag = 1;	} 	ip_rt_put(rt); 	return flag; */} static int myarp_process(struct sk_buff *skb){	struct net_device *dev = skb->dev;	struct in_device *in_dev = in_dev_get(dev);	struct arphdr *arp;	struct rtable *rt;	unsigned char *arp_ptr;	unsigned char *sha, *tha;	int addr_type;	u32 sip, tip;	u16 dev_type = dev->type;	struct neighbour *n;	if (in_dev == NULL)		goto out;	arp = skb->nh.arph;	switch( dev_type ){		default:				if (arp->ar_pro != htons(ETH_P_IP) || htons(dev_type) != arp->ar_hrd)				goto out;			break;#ifdef CONFIG_NET_ETHERNET		case ARPHRD_ETHER:#endif#ifdef CONFIG_TR		case ARPHRD_IEEE802_TR:#endif#ifdef CONFIG_FDDI		case ARPHRD_FDDI:#endif#ifdef CONFIG_NET_FC		case ARPHRD_IEEE802:#endif#if defined(CONFIG_NET_ETHERNET) || defined(CONFIG_TR) \			|| defined(CONFIG_FDDI)	 || defined(CONFIG_NET_FC)			if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&									arp->ar_hrd != htons(ARPHRD_IEEE802)) ||							arp->ar_pro != htons(ETH_P_IP))				goto out;			break;#endif#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)		case ARPHRD_AX25:			if (arp->ar_pro != htons(AX25_P_IP) ||							arp->ar_hrd != htons(ARPHRD_AX25))				goto out;			break;#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)		case ARPHRD_NETROM:			if (arp->ar_pro != htons(AX25_P_IP) ||							arp->ar_hrd != htons(ARPHRD_NETROM))				goto out;			break;#endif#endif	}	if (arp->ar_op != htons(ARPOP_REPLY) &&					arp->ar_op != htons(ARPOP_REQUEST))		goto out;	/*sha: send mac address	  sip: send ip address.	  tha: recv mac address.	  tip: recv ip address.     */		arp_ptr= (unsigned char *)(arp+1);	sha	= arp_ptr;	arp_ptr += dev->addr_len;	memcpy(&sip, arp_ptr, 4);	arp_ptr += 4;	tha	= arp_ptr;	arp_ptr += dev->addr_len;	memcpy(&tip, arp_ptr, 4);	if (LOOPBACK(tip) || MULTICAST(tip))		goto out;	if (dev_type == ARPHRD_DLCI)		sha = dev->broadcast;	if(sip == 0){		if (arp->ar_op == htons(ARPOP_REQUEST) && myinet_addr_type(tip) == RTN_LOCAL &&						!myarp_ignore(in_dev,dev,sip,tip) )			myarp_send(ARPOP_REPLY,ETH_P_ARP,tip,dev,tip,sha,dev->dev_addr,dev->dev_addr);		goto out;	}		if (arp->ar_op == htons(ARPOP_REQUEST) &&					myip_route_input(skb, tip, sip, 0, dev) == 0 ) {		rt = (struct rtable*)skb->dst;		addr_type = rt->rt_type;		if( addr_type == RTN_LOCAL ){			n = neigh_event_ns(&myarp_tbl, sha, &sip, dev);			if (n) {				int dont_send = 0;				if (!dont_send)					dont_send |= myarp_ignore(in_dev,dev,sip,tip);				if (!dont_send && MYIN_DEV_ARPFILTER(in_dev)){					printk(KERN_INFO "have arp filter!\n");					dont_send |= myarp_filter(sip,tip,dev); 				}				if (!dont_send)					myarp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);				neigh_release(n);			}			goto out;		}else{		}	}	n = __neigh_lookup(&myarp_tbl, &sip, dev, 0);#ifdef CONFIG_IP_ACCEPT_UNSOLICITED_ARP	if (n == NULL && arp->ar_op == htons(ARPOP_REPLY) &&					inet_addr_type(sip) == RTN_UNICAST)		n = __neigh_lookup(&arp_tbl, &sip, dev, -1);#endif	if (n) {		int state = NUD_REACHABLE;		int override;		override = time_after(jiffies, n->updated + n->parms->locktime);		if (arp->ar_op != htons(ARPOP_REPLY) || skb->pkt_type != PACKET_HOST)			state = NUD_STALE;		neigh_update(n, sha, state, override ? NEIGH_UPDATE_F_OVERRIDE : 0);		neigh_release(n);	}out:	if (in_dev)		in_dev_put(in_dev);	kfree_skb(skb);	return 0;}int myarp_rcv(struct sk_buff *skb, struct net_device *dev,					struct packet_type *pt, struct net_device *orig_dev){	struct arphdr *arp;	if (!pskb_may_pull(skb, (sizeof(struct arphdr) +									(2 * dev->addr_len) +									(2 * sizeof(u32)))))		goto freeskb;	arp = skb->nh.arph;	if (arp->ar_hln != dev->addr_len || dev->flags & IFF_NOARP ||					skb->pkt_type == PACKET_OTHERHOST || skb->pkt_type == PACKET_LOOPBACK ||					arp->ar_pln != 4)		goto freeskb;	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)		goto out_of_mem;	memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));	return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, myarp_process);freeskb:	kfree_skb(skb);out_of_mem:	return 0;}static struct packet_type myarp_packet_type = {	.type =	__constant_htons(ETH_P_ARP),	.func =	myarp_rcv,};static int myarp_seq_open(struct inode *inode, struct file *file){	return 0;}static struct file_operations myarp_seq_fops = {	.owner		= THIS_MODULE,	.open		= myarp_seq_open,	.read		= myseq_read,	.llseek		= myseq_lseek,	.release	= myseq_release_private,};static int __init myarp_proc_init(void){	if (!proc_net_fops_create("myarp", S_IRUGO, &myarp_seq_fops))		return -ENOMEM;	return 0;}static int myarp_netdev_event(struct notifier_block *this, unsigned long event, void *ptr){	printk("event: %lu\n", event );	return 0;}static struct notifier_block myarp_netdev_notifier = {	.notifier_call = myarp_netdev_event,};void myarp_init(void){	neigh_table_init(&myarp_tbl);		dev_add_pack(&myarp_packet_type);	myarp_proc_init();#ifdef CONFIG_SYSCTL	neigh_sysctl_register(NULL, &myarp_tbl.parms, NET_MYIPV4,					NET_IPV4_NEIGH, "myipv4", NULL, NULL);#endif	register_netdevice_notifier( &myarp_netdev_notifier );}void __exit myarp_exit(void){	int i;	unregister_netdevice_notifier( &myarp_netdev_notifier );    neigh_sysctl_unregister( &myarp_tbl.parms );    proc_net_remove( "myarp" );	dev_remove_pack( &myarp_packet_type );	for( i = 0; i < myarp_tbl.hash_mask + 1; i ++ ){		struct neighbour *n1 = myarp_tbl.hash_buckets[i];		struct neighbour *n2 = n1;		while( n1 != NULL ){			n1 = n1->next;			printk(KERN_INFO "ip: %u.%u.%u.%u\n", NIPQUAD(n2->primary_key) );			printk(KERN_INFO "mac: %x.%x.%x.%x.%x.%x\n", n2->ha[0], n2->ha[1], n2->ha[2],							n2->ha[3], n2->ha[4], n2->ha[5] );			kmem_cache_free( myarp_tbl.kmem_cachep, n2 );			n2 = n1;		}	}	atomic_set( &(myarp_tbl.entries), 0); 	neigh_table_clear( &myarp_tbl );	if( myarp_tbl.kmem_cachep )		kmem_cache_destroy( myarp_tbl.kmem_cachep );	if( myarp_tbl.stats )		free_percpu( myarp_tbl.stats );#ifdef CONFIG_PROC_FS	if( myarp_tbl.pde )		remove_proc_entry( myarp_tbl.id, proc_net_stat );#endif		}

⌨️ 快捷键说明

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