#include #include #include #include #include #include #include #include #include "../netlink_api/libnetlink_k.h" #include "../../../Common/commuapinl.h" #define strict_strtoul kstrtoul /**************************************************************************************************************/ #include #define NLMSG_TAIL(nmsg) \ ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len)) #define RTA_ALIGNTO 4U #define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) ) struct policyconfmsg { __u8 policy_id; }; /**************************************************************************************************************/ //int nf_nlmsg_multicast(struct netlinkk_cfg *g_nlcfg, struct sk_buff *skb); unsigned int pdelivery_hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state); //int debugfs_pkt_num_stati(struct netlinkk_cfg *g_nlcfg, struct nlmsghdr *nlh); struct netlinkk_cfg g_nlcfg = {0}; static struct nf_hook_ops upm_nfho = { .hook = pdelivery_hook_func, .hooknum = 1, /* should be NF_IP_FORWARD,use NF_IP_LOCAL_IN=1 for test */ .pf = PF_INET, .priority = NF_IP_PRI_FILTER, }; int pdeliv_rcv_stat(struct sk_buff *skb, struct nlmsghdr *nlh) { printk(KERN_INFO "pdeliv_rcv_stat, From: %d\n", nlh->nlmsg_pid); /**************************************************************************************************************/ char *pload; struct nlattr *rta; char* load; unsigned long fk_type; pload = nlmsg_data(nlh) + NLMSG_ALIGN(sizeof(struct policyconfmsg)); rta = (struct nlattr *)pload; load = RTA_DATA(rta); printk("***************************rta->nla_type=%d********************\n", rta->nla_type); //nla_type printk("**************************load=*****%s**********\n",(char *)load); //string printf strict_strtoul(load, 10, &fk_type); printk("***************************fk_type%d********************\n", fk_type); /**************************************************************************************************************/ /**************************************************************************************************************/ switch(nlh->nlmsg_type) { //case COMMNMSG_POLICYCONF:/**/ case NLMSG_DEBUGFS: if(nlh->nlmsg_type == NLMSG_DEBUGFS) { debugfs_pkt_num_stati(&g_nlcfg, nlh, fk_type); printk("*****************biduichengong********%d*******\n", nlh->nlmsg_type); return 0; } break; default: printk(KERN_INFO "libnetlink Unknow msgtype recieved!\n"); return 0; } /**************************************************************************************************************/ return 0; } int __init pdelivery_init(void) { int ret = -1; printk(KERN_CRIT "nl_upm initialed ok!\n"); /*init for pdelivery module*/ g_nlcfg.groups = PDELIVERY_NLGRP_MAX; g_nlcfg.subscriptions = NETLINK_PDELIVERY; //g_nlcfg.cfg.input = libnetlink_rcv; ret = libnetlinkk_init_byproto(&g_nlcfg); if(ret < 0) { printk (KERN_CRIT "pdelivery_init netlink init fail!.\n"); return ret; } /*init the netfilter hook for upm*/ printk (KERN_INFO "upm register netfilter module.\n"); nf_register_net_hook (&init_net,&upm_nfho); /*do msg process register*/ pdeliv_msgtype_register(PDNLGRP_REQUEST,pdeliv_rcv_stat,NULL,NULL); pdeliv_msgtype_register(NLMSG_DEBUGFS,pdeliv_rcv_stat,NULL,NULL); return 0; } void __exit pdelivery_exit(void) { printk(KERN_CRIT "nl_upm existing...\n"); libnetlinkk_exit(&g_nlcfg); /*init the netfilter hook for upm*/ printk (KERN_INFO "upm unregister netfilter module.\n"); nf_unregister_net_hook (&init_net,&upm_nfho); return; } /****************************************************************/ /*函数功能:pdelivery模块注册的netfilter钩子回调函数,用于从 */ /*netfilter框架接收到报文,然后调用netlink发送接口将报文上送到*/ /*用户态。报文内容从链路层头开始。 */ /*输入参数:priv:优先级;skb 报文;state:netfilter钩子状态。 */ /*输出参数: 无*/ /*返回值:固定返回NF_ACCEPT表示放行报文。 */ /****************************************************************/ unsigned int pdelivery_hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { void *payload; struct sk_buff *out_skb; void *out_payload; struct nlmsghdr *out_nlh; int payload_len; // with padding, but ok for echo struct iphdr *iph; int ret = -1; iph = ip_hdr(skb); printk(KERN_INFO "pdelivery_hook_func:pktlen=%d,mac_header = %d IP:",skb->len,skb->mac_len); printk_ipaddress(iph->saddr); printk(KERN_INFO "-->"); printk_ipaddress(iph->daddr); payload = skb_mac_header(skb); payload_len = skb->len + skb->mac_len;/**/ out_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); //分配足以存放默认大小的sk_buff if (!out_skb) goto failure; out_nlh = nlmsg_put(out_skb, 0, 0, NLMSG_RECV_RAW_PKT, payload_len, 0); //填充协议头数据 if (!out_nlh) goto failure; out_payload = nlmsg_data(out_nlh); memcpy(out_payload, payload,payload_len);/**/ #if 1 printk(KERN_INFO "%02x %02x %02x %02x %02x %02x %02x %02x\r\n", *((char*)out_payload),*((char*)out_payload+1), *((char*)out_payload+2),*((char*)out_payload+3), *((char*)out_payload+4),*((char*)out_payload+5), *((char*)out_payload+6),*((char*)out_payload+7)); #endif ret = nf_nlmsg_multicast(&g_nlcfg, out_skb); #if 0 ret = nlmsg_multicast(g_nlcfg.sk,out_skb,0,PDNLGRP_ALLRAW,0); if (ret < 0) { printk(KERN_INFO "Error while sending pkt to user, err id: %d\n", ret); } g_nlcfg.pkt_delev_num ++; #endif //g_nlcfg.pkt_delev_num ++; printk(KERN_INFO "pdelivery_hook_func() end.\n"); return NF_ACCEPT;/*must return a value*/ failure: printk(KERN_INFO " failed in pdelivery_hook_func!\n"); return NF_ACCEPT;/*must return a value*/ } module_init(pdelivery_init); module_exit(pdelivery_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("a simple example for upm(user policy manage) netlink protocal family"); MODULE_AUTHOR("RSLjdkt");