//内核部分代码。大家可以COPY ipt_sockopts
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include "hello_sock_opt.h"
#include <linux/kmod.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/smp.h>
#include <linux/cpumask.h>
#include <linux/audit.h>
#include <net/sock.h>
char hello[10][20];
static int hello_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
{
int ret=0;
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
return -EPERM;
printk("%s: len is %d \n",__func__,len);
switch (cmd) {
case HELLO_LISA:
if (copy_from_user(hello[0], user,20) != 0)
return -EFAULT;
break;
case HELLO_MONA:
if (copy_from_user(hello[1], user,20) != 0)
return -EFAULT;
break;
default:
printk("hello_set_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
}
return ret;
}
static int hello_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
{
int ret=0;
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
return -EPERM;
switch (cmd) {
case HELLO_LISA:
if (copy_to_user(user,hello[0] , 20) != 0)
{
break;
}
break;
case HELLO_MONA:
if (copy_to_user(user,hello[1] , 20) != 0)
break;
else
break;
default:
printk("hello_get_ctl: unknown request %i\n", cmd);
ret = -EINVAL;
}
return ret;
}
static struct nf_sockopt_ops arpt_sockopts = {
.pf = PF_INET,
.set_optmin = HELLO_BASE_CTL,
.set_optmax = HELLO_SO_SET_MAX+1,
.set = hello_set_ctl,
.get_optmin = HELLO_BASE_CTL,
.get_optmax = HELLO_SO_SET_MAX+1,
.get = hello_get_ctl,
.owner = THIS_MODULE,
};
static int simple_init(void)
{
int ret;
/* Register setsockopt */
ret = nf_register_sockopt(&arpt_sockopts);
if (ret < 0)
{
printk("nf_register_sockopt error! \n");
return -1;
}
printk("hello !!\n");
return 0;
}
static void simple_cleanup(void)
{
nf_unregister_sockopt(&arpt_sockopts);
printk("Hello byebye\n");
}
module_init(simple_init);
module_exit(simple_cleanup);
/*
上下通信的通用头文件。
*/
#define HELLO_BASE_CTL 102400 //在系统中这个号不能有重复的。建议最好是取较大值。
#define HELLO_LISA HELLO_BASE_CTL+1
#define HELLO_MONA HELLO_BASE_CTL+2
#define HELLO_SO_SET_MAX (HELLO_BASE_CTL+5)
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include "hello_sock_opt.h"
int common_set_sock_opt(int id,void* msg,int len)
{
int sock;
int ret;
sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(sock <=0){
printf("socket error\n");
return -1;
}
ret=setsockopt(sock,0,id,msg,len);
close(sock);
return ret;
}
int common_get_sock_opt(int id,void* msg,int* len)
{
int sock;
int ret;
sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(sock <=0){
printf("socket error\n");
return -1;
}
ret=getsockopt(sock,0,id,msg,len);
close(sock);
return ret;
}
int __set_lisa(char* s)
{
return common_set_sock_opt(HELLO_LISA,s,strlen(s));
}
int __get_lisa(char* s,int *len)
{
return common_get_sock_opt(HELLO_LISA,s,len);
}
void main(int argc,char* argv[])
{
char ret[100]={0};
int len=0;
int t;
if(argc ==2){
printf("argv : %s :%s \n",argv[0],argv[1]);
t = __set_lisa(argv[1]); //把参数配置到内核。
if(t<0)
perror("__set_lisa:");
__get_lisa(ret,&len); //从内核读出信息。
if(t<0)
perror("__GET_lisa:");
else
{
printf("ret %s; len %d\n",ret,len);
}
}
}