linux与应用层通信方式 之nf_sock_opt
- //内核部分代码。大家可以COPY ipt_sockopts
[cpp] view plain copy
- //#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);
[cpp] view plain copy
- /*
- 上下通信的通用头文件。
- */
- #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)
[cpp] view plain copy
- #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);
- }
- }
- }