Linux之netlink学习
来源:互联网 发布:冒险岛2韩服pk数据榜 编辑:程序博客网 时间:2024/05/16 05:37
//imp2.h#ifndef __IMP2_H__#define __IMP2_H__#define IMP2_U_PID 0#define IMP2_K_MSG 1#define IMP2_CLOSE 2#define NL_IMP2 31struct packet_info{ __u32 src; __u32 dest;};#endif//内核态程序imp2_k_my.c#ifndef __KERNEL__#define __KERNEL__#endif#ifndef MODULE#define MODULE#endif#include <linux/netfilter.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/types.h>#include <linux/netdevice.h>#include <linux/skbuff.h>#include <linux/netfilter_ipv4.h>#include <linux/inet.h>#include <linux/in.h>#include <linux/ip.h>#include <linux/netlink.h>#include <linux/spinlock.h>#include <net/sock.h>#include "imp2.h"MODULE_LICENSE("Dual BSD/GPL");#define IMP2_K_MY "imp2_k_my:"//#define printk(arg) //printkk(KERN_ALERT IMP2_K_MY arg)DECLARE_MUTEX(receive_sem);static struct sock *mysock;struct{ __u32 pid; rwlock_t lock;} user_proc;static int send_to_user(struct packet_info *info){ int ret = 0; int size; //unsigned char *old_tail; sk_buff_data_t old_tail; struct sk_buff *skb; struct nlmsghdr *nlh; struct packet_info *packet; printk("%s, begin !!! \n", __func__); size = NLMSG_SPACE(sizeof(*info)); skb = alloc_skb(size, GFP_ATOMIC); old_tail = skb->tail; nlh = NLMSG_PUT(skb, 0, 0, IMP2_K_MSG, size - sizeof(*nlh)); packet = NLMSG_DATA(nlh); memset(packet, 0, sizeof(struct packet_info)); packet->src = info->src; packet->dest = info->dest; nlh->nlmsg_len = (__u32)(skb->tail - old_tail); NETLINK_CB(skb).dst_group = 0; read_lock_bh(&user_proc.lock); ret = netlink_unicast(mysock, skb, user_proc.pid, MSG_DONTWAIT); read_unlock_bh(&user_proc.lock); printk("%s, end !!! \n", __func__); return ret; nlmsg_failure: if(skb) kfree_skb(skb); return -1;}static unsigned int icmp_hook_func(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)){ struct iphdr *iph = ip_hdr(skb); struct packet_info info; //printk("%s, begin !!! \n", __func__); if (iph->protocol == IPPROTO_ICMP) { read_lock_bh(&user_proc.lock); if (user_proc.pid != 0) { info.src = iph->saddr; info.dest = iph->daddr; printk("%s, src=%u.%u.%u.%u, dst=%u.%u.%u.%u\n", __func__, NIPQUAD(info.src), NIPQUAD(info.dest)); send_to_user(&info); } else { printk("%s, no user process running..!\n", __func__); } read_unlock_bh(&user_proc.lock); } //printk("%s, end !!! \n", __func__); return NF_ACCEPT;}#define NF_IP_PRE_ROUTING 0static struct nf_hook_ops my_icmp_hook = { .hook = icmp_hook_func, .pf = PF_INET, .hooknum = NF_IP_PRE_ROUTING, .owner = THIS_MODULE, .priority = NF_IP_PRI_FILTER - 1,};static void my_receive(struct sk_buff *skb){ struct nlmsghdr *nlh; int len; printk("%s, begin !!!!!\n", __func__); nlh = nlmsg_hdr(skb); len = skb->len; while (NLMSG_OK(nlh, len)) { printk("%s, skb_len = %d!!!!!\n", __func__, len); if (nlh->nlmsg_type == IMP2_U_PID) { write_lock_bh(&user_proc.lock); user_proc.pid = nlh->nlmsg_pid; write_unlock_bh(&user_proc.lock); } else if (nlh->nlmsg_type == IMP2_CLOSE) { write_lock_bh(&user_proc.lock); if(nlh->nlmsg_pid == user_proc.pid) user_proc.pid = 0; write_unlock_bh(&user_proc.lock); } netlink_ack(skb, nlh, 0); nlh = NLMSG_NEXT(nlh, len); } printk("%s, end !!!!!\n", __func__);}static int __init imp2_k_my_init(void){ printk("%s, begin !!!!!\n", __func__); rwlock_init(&user_proc.lock); mysock = netlink_kernel_create(&init_net, NL_IMP2, 0, my_receive, NULL, THIS_MODULE); if (!mysock) { printk("%s, netlink_kernel_create fail.. !!!!!\n", __func__); return -1; } printk("%s, end !!!!!\n", __func__); return nf_register_hook(&my_icmp_hook);}static void __exit imp2_k_my_exit(void){ printk("%s, begin !!!!!\n", __func__); netlink_kernel_release(mysock); nf_unregister_hook(&my_icmp_hook); printk("%s, end !!!!!\n", __func__);}module_init(imp2_k_my_init);module_exit(imp2_k_my_exit); //用户态程序imp2_u_my.c#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <error.h>#include <linux/types.h>#include <string.h>#include <sys/socket.h>#include <arpa/inet.h>#include <asm/types.h>#include <linux/netlink.h>#include <signal.h>#include "imp2.h"struct msg_to_kernel{ struct nlmsghdr hdr;};struct u_packet_info{ struct nlmsghdr hdr; struct packet_info icmp_info;};static int skfd;static void sig_int(int signo){ struct sockaddr_nl kpeer; struct msg_to_kernel message; memset(&kpeer, 0, sizeof(kpeer)); kpeer.nl_family = AF_NETLINK; kpeer.nl_pid = 0; kpeer.nl_groups = 0; memset(&message, 0, sizeof(message)); message.hdr.nlmsg_len = NLMSG_LENGTH(0); message.hdr.nlmsg_flags = 0; message.hdr.nlmsg_type = IMP2_CLOSE; message.hdr.nlmsg_pid = getpid(); sendto(skfd, &message, message.hdr.nlmsg_len, 0, (struct sockaddr *)(&kpeer), sizeof(kpeer)); close(skfd); exit(0);}int main(void){ struct sockaddr_nl local; struct sockaddr_nl kpeer; int kpeerlen; struct msg_to_kernel message; struct u_packet_info info; int sendlen = 0; int rcvlen = 0; struct in_addr addr; skfd = socket(PF_NETLINK, SOCK_RAW, NL_IMP2); if(skfd < 0) { printf("can not create a netlink socket\n"); exit(0); } memset(&local, 0, sizeof(local)); local.nl_family = AF_NETLINK; local.nl_pid = getpid(); local.nl_groups = 0; if(bind(skfd, (struct sockaddr*)&local, sizeof(local)) != 0) { printf("bind() error\n"); return -1; } signal(SIGINT, sig_int); memset(&kpeer, 0, sizeof(kpeer)); kpeer.nl_family = AF_NETLINK; kpeer.nl_pid = 0; kpeer.nl_groups = 0; memset(&message, 0, sizeof(message)); message.hdr.nlmsg_len = NLMSG_LENGTH(0); message.hdr.nlmsg_flags = 0; message.hdr.nlmsg_type = IMP2_U_PID; message.hdr.nlmsg_pid = local.nl_pid; sendto(skfd, &message, message.hdr.nlmsg_len, 0, (struct sockaddr*)&kpeer, sizeof(kpeer)); while(1) { kpeerlen = sizeof(struct sockaddr_nl); rcvlen = recvfrom(skfd, &info, sizeof(struct u_packet_info), 0, (struct sockaddr*)&kpeer, &kpeerlen); addr.s_addr = info.icmp_info.src; printf("src: %s, ", inet_ntoa(addr)); addr.s_addr = info.icmp_info.dest; printf("dest: %s\n", inet_ntoa(addr)); } return 0;}
0 0
- Linux之netlink学习
- linux之netlink
- Linux 之Netlink机制
- linux内核编程之netlink
- 网卡驱动学习之netlink
- linux学习笔记:netlink实践演练
- linux netlink套接字学习资料
- linux学习笔记:netlink实践演练
- linux netlink套接字学习资料
- Linux netlink之添加一个简单协议
- Linux-内核通信之netlink机制-详解
- Linux-内核通信之netlink机制-详解
- Linux Kernel 学习笔记9:内核与用户层通信之netlink
- Linux Kernel 学习笔记9:内核与用户层通信之netlink
- linux netlink
- Linux Netlink
- Linux Netlink
- linux netlink
- Apache吃空内存,频繁宕机
- MAC 系统清理
- CocosBuilder 多分辨率基础 分享2
- Foundation框架NSDictionary
- 大数据的存储和管理
- Linux之netlink学习
- CGridView详解
- poj 1558-Segment set (并查集+计算几何)
- 跟踪计算机视觉前沿必读的列表(各种论文)
- 在Java语言JDBC代码中的Select语句中缺少了一个逗号
- 图文并茂使用CocosBuilder制作Cocos2D游戏
- HDFS的JAVA接口API操作实例
- ubuntu13.10开启root账户
- UVA 11383 Golden Tiger Claw(KM算法)