📄 myarp.c
字号:
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 + -