diff --git a/code/anolisos-8.6/linux-4.19.91/net/prip/prip.c b/code/anolisos-8.6/linux-4.19.91/net/prip/prip.c index b69f067c086e69413a024ed8feaf916f1b8dff00..34d3a00c4121711cee39c58f1f2cb0bc1959596b 100644 --- a/code/anolisos-8.6/linux-4.19.91/net/prip/prip.c +++ b/code/anolisos-8.6/linux-4.19.91/net/prip/prip.c @@ -46,7 +46,8 @@ struct prip_hash_list prip_hash[PRIP_HASHSZ]; atomic_t prip_cache_timeout; atomic_t prip_netmask; EXPORT_SYMBOL(prip_netmask); - + struct proc_dir_entry * dir_prip; + struct proc_dir_entry * prip_config_entry; static char config_buff[BUFF_SIZE]; static u32 jhash_prip_initval __read_mostly; unsigned long prip_reboot; @@ -308,6 +309,161 @@ struct prip_priv * prip_priv_only_find(__u32 localip, __u32 peerip){ } EXPORT_SYMBOL(prip_priv_only_find); +static ssize_t write_prip_config( struct file *file,const char __user * buffer,size_t len, loff_t *f_pos) +{ + char data[BUFF_SIZE]; + char ip[3][16]; + __u32 net_one; + __u32 net_two; + __u32 netmask; + __u32 tmp_mask=0; + char *cache; + int i; + int clean=0; + unsigned long tmp=0; + unsigned char tmp_buff[16]; + struct net_device *dev; + struct in_device *in_dev; + int net_one_flag=0; + int net_two_flag=0; + int net_one_ip=0; + int net_two_ip=0; + + if( len > BUFF_SIZE-1) + return -E2BIG; + memset(config_buff,0,BUFF_SIZE); + memset(tmp_buff,0,sizeof(tmp_buff)); + if(copy_from_user(config_buff,buffer,len)){ + return -EINVAL; + } + for(i=0;i 0){ + read_unlock_bh(&prip_config.rwlock); + return -EBUSY; + } + read_unlock_bh(&prip_config.rwlock); + strcpy((char *)data,config_buff); + if(!clean) { + if( len < 17 ) + return -EINVAL; + if(!get_config_ip(config_buff,ip)) + return -EINVAL; + cache =ip[0]; + if(!(net_one=inet_aton(cache))) + return -EINVAL; + cache =ip[1]; + if(!(net_two=inet_aton(cache))) + return -EINVAL; + cache =ip[2]; + if(!(netmask=inet_aton(cache))) + return -EINVAL; + if((netmask <=0) || (netmask >=32)) + return -EINVAL; + for(i=1;i<=netmask;i++){ + tmp_mask |= 1<< (32-i); + } + prip_net_one = net_one; + prip_net_two = net_two; + net_one = net_one & tmp_mask; + net_two = net_two & tmp_mask; + + read_lock_bh(&dev_base_lock); + list_for_each_entry(dev,&(current->nsproxy->net_ns->dev_base_head),dev_list){ + if(dev){ + in_dev = (struct in_device *)(dev->ip_ptr); + if(in_dev && in_dev->ifa_list){ + printk("dwang debug :in_dev->ifa_list->ifa_mask=0x%x,0x%x\n",in_dev->ifa_list->ifa_mask,ntohl(in_dev->ifa_list->ifa_mask)); + if((ntohl(in_dev->ifa_list->ifa_address) & tmp_mask)== net_one){ + net_one_flag=1; + printk("net_one_flag[%d]two_flag[%d]\n",net_one_flag,net_two_flag); + net_one_ip=(ntohl(in_dev->ifa_list->ifa_address) & (~ tmp_mask)); + if(net_two_flag) + break; + }else{ + if((ntohl(in_dev->ifa_list->ifa_address) & tmp_mask)== net_two){ + net_two_flag=1; + printk("net_one_flag[%d]two_flag[%d]\n",net_one_flag,net_two_flag); + net_two_ip=(ntohl(in_dev->ifa_list->ifa_address) & (~ tmp_mask)); + if(net_one_flag) + break; + } + } + } + } + } + read_unlock_bh(&dev_base_lock); +printk("net_one_ip =[%d]two_ip[%d]\n",net_one_ip,net_two_ip); + if(!(net_one_flag && net_two_flag)) + return -ENXIO; + if((net_one_ip != net_two_ip) || (net_one_ip == 0) ||(net_two_ip==0)) + return -ENXIO; + write_lock_bh(&(prip_config.rwlock)); + if(atomic_read(&(prip_config.reference)) > 0){ + write_unlock_bh(&prip_config.rwlock); + return -EBUSY; + } + prip_config.valid=1; + prip_config.net_one=net_one; + prip_config.net_two=net_two; + prip_config.mask=tmp_mask; + atomic_set(&prip_config.reference,0); + write_unlock_bh(&(prip_config.rwlock)); + atomic_set(&prip_netmask,tmp_mask); + + memset((char *)data,0,BUFF_SIZE); + inet_ntoa(tmp_buff,net_one); + i=sprintf((char *)data,"%s ",tmp_buff); + inet_ntoa(tmp_buff,net_two); + i+=sprintf(((char *)data + i),"%s ",tmp_buff); + sprintf(((char *)data+i),"%d\n",netmask); + strcpy(config_buff,data); + } else { + write_lock_bh(&(prip_config.rwlock)); + if(init_net.ipv4.sysctl_prip_set){ + write_unlock_bh(&prip_config.rwlock); + return -EBUSY; + } + if(atomic_read(&(prip_config.reference)) > 0){ + write_unlock_bh(&prip_config.rwlock); + return -EBUSY; + } + prip_config.valid=0; + atomic_set(&prip_config.reference,0); + write_unlock_bh(&(prip_config.rwlock)); + atomic_set(&prip_netmask,0); + *((char *)data)='\0'; + strcpy(config_buff,data); + } + return len; +} + +static int read_prip_config(struct seq_file *seq,void *v) +{ + seq_printf(seq,"%s",config_buff); + return 0; +} + +static int seq_open_prip_config(struct inode *inode, struct file *file) +{ + return single_open(file,read_prip_config,inode->i_private); +} + +static struct file_operations prip_config_ops = { + .open = seq_open_prip_config, + .read = seq_read, + .llseek = seq_lseek, + .write = write_prip_config, + .owner = THIS_MODULE, + .release = single_release, +}; + int set_prip_mode(struct sock * sk,int mode) { struct inet_sock *inet; @@ -530,12 +686,31 @@ static int __init init_prip(void) rwlock_init(&prip_single_list.rwlock); get_random_bytes(&jhash_prip_initval,sizeof(jhash_prip_initval)); + dir_prip = proc_mkdir("prip",NULL); + if(!dir_prip){ + printk("PRIP ERROR: Cannot create /proc/prip .\n"); + err = -1; + goto err_1; + } + prip_config_entry = proc_create("prip_config",S_IRUGO|S_IWUSR,dir_prip, &prip_config_ops); + if(!prip_config_entry){ + printk("PRIP ERROR: Cannot create /proc/prip/prip_config .\n"); + err = -1; + goto err_2; + } + + printk("PRIP modules insmod success.\n"); return 0; - +err_2: + remove_proc_entry("prip",NULL); +err_1: + return err; } static void __exit exit_prip(void){ + remove_proc_entry("prip_config",dir_prip); + remove_proc_entry("prip",NULL); return; } MODULE_LICENSE("GPL");