1、netfilter提供了nf_register_sockopt()和nf_unregister_sockopt()来动态登记或取消sockopt命令字;打开一个网络socket后可以使用set/getsockopt(2)可实现用户空间与内核的通信,本质和ioctl差不多,区别在于set/getsockopt不用新建设备,直接利用系统已有的socket类型就可以进行,可用setsockopt函数向内核写数据,用getsockopt向内核读数据。
module.c:
#include
2、
3、KET_OPS_BASE + 1) #define KMSG "a message from kernel" #define KMSG_LEN sizeof("a message from kernel") MODULE_LICENSE("GPL"); static int recv_msg(struct sock *sk, int cmd, void __user *user, unsigned int len) { int ret = 0; printk(KERN_INFO "sockopt: recv_msg()\n"
4、); if (cmd == SOCKET_OPS_SET) { char umsg[64]; int len = sizeof(char)*64; memset(umsg, 0, len); ret = copy_from_user(umsg, user, len); printk("recv_msg: umsg = %s. ret = %d\n", umsg, ret); } return 0; } static int se
5、nd_msg(struct sock *sk, int cmd, void __user *user, int *len) { int ret = 0; printk(KERN_INFO "sockopt: send_msg()\n"); if (cmd == SOCKET_OPS_GET) { ret = copy_to_user(user, KMSG, KMSG_LEN); printk("send_msg: umsg = %s. ret = %d. success\n", KMSG, ret);
6、 } return 0; } static struct nf_sockopt_ops test_sockops = { .pf = PF_INET, .set_optmin = SOCKET_OPS_SET, .set_optmax = SOCKET_OPS_MAX, .set = recv_msg, .get_optmin = SOCKET_OPS_GET, .get_optmax = SOCKET_OPS_MAX, .get = send_msg, .owner = THIS_MOD
7、ULE, }; static int __init init_sockopt(void) { printk(KERN_INFO "sockopt: init_sockopt()\n"); return nf_register_sockopt(&test_sockops); } static void __exit fini_sockopt(void) { printk(KERN_INFO "sockopt: fini_sockopt()\n"); nf_unregister_sockopt(&test_sockops); }
8、
module_init(init_sockopt);
module_exit(fini_sockopt);
user.c:
#include
9、T_OPS_GET (SOCKET_OPS_BASE) #define SOCKET_OPS_MAX (SOCKET_OPS_BASE + 1) #define UMSG "a message from userspace" #define UMSG_LEN sizeof("a message from userspace") char kmsg[64]; int main(void) { int sockfd; int len; int ret; sockfd = socket(AF
10、INET, SOCK_RAW, IPPROTO_RAW); if(sockfd < 0) { printf("can not create a socket\n"); return -1; } /*call function recv_msg()*/ ret = setsockopt(sockfd, IPPROTO_IP, SOCKET_OPS_SET, UMSG, UMSG_LEN); printf("setsockopt: ret = %d. msg = %s\n", ret, UMSG
11、); len = sizeof(char)*64; /*call function send_msg()*/ ret = getsockopt(sockfd, IPPROTO_IP, SOCKET_OPS_GET, kmsg, &len); printf("getsockopt: ret = %d. msg = %s\n", ret, kmsg); if (ret != 0) { printf("getsockopt error: errno = %d, errstr = %s\n", errno, strer
12、ror(errno)); } close(sockfd); return 0; } Makefile: TARGET = test OBJS = test.o MDIR = drivers/misc EXTRA_CFLAGS = -DEXPORT_SYMTAB CURRENT = $(shell uname -r) KDIR = /lib/modules/$(CURRENT)/build PWD = $(shell pwd) DEST = /lib/modules/$(CURRENT)/kernel/$(MDIR) obj-m
13、 := $(TARGET).o $(TARGET)-objs :=module.o default: make -C $(KDIR) SUBDIRS=$(PWD) modules gcc -o user user.c $(TARGET).o: $(OBJS) $(LD) $(LD_RFLAG) -r -o $@ $(OBJS) ifneq (,$(findstring 2.4.,$(CURRENT))) install: su -c "cp -v $(TARGET).o $(DEST) && /sbin/depmod -a" else install: su -c "cp -v $(TARGET).ko $(DEST) && /sbin/depmod -a" endif clean: -rm -rf *.o *.ko .$(TARGET).ko.cmd .*.flags *.mod.c modules.order Module.symvers .tmp_versions -rm -rf protocol/*.o protocol/.*.o.cmd -rm -rf user -include $(KDIR)/Rules.make
©2010-2025 宁波自信网络信息技术有限公司 版权所有
客服电话:4009-655-100 投诉/维权电话:18658249818