2019-06-11 03:21:35 +00:00
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/netlink.h>
|
|
|
|
#include <linux/netfilter.h>
|
|
|
|
#include <linux/ip.h>
|
|
|
|
#include <uapi/linux/netfilter_ipv4.h>
|
|
|
|
#include <uapi/linux/ip.h>
|
|
|
|
#include <net/netlink.h>
|
|
|
|
#include <net/net_namespace.h>
|
|
|
|
|
|
|
|
#include "libnetlink_k.h"
|
|
|
|
#include "../../../Common/commuapinl.h"
|
|
|
|
|
|
|
|
struct commnl_msgtype_process pdelivnl_msg_handlers[NLMGS_PDELIVERY_MAX_TYPE];
|
|
|
|
struct commnl_msgtype_process cfgnl_msg_handlers[COMMCFG_NLMSG_MAX_TYPE];
|
2019-06-20 03:20:46 +00:00
|
|
|
struct recv_debugfs recv_dfs;
|
2019-06-11 03:21:35 +00:00
|
|
|
|
|
|
|
|
2019-06-13 06:55:31 +00:00
|
|
|
|
|
|
|
|
2019-06-11 03:21:35 +00:00
|
|
|
void printk_mem(unsigned char * p,int len)
|
|
|
|
{
|
|
|
|
int num = 0;
|
|
|
|
|
|
|
|
for(num = 0; num<len; num++)
|
|
|
|
{
|
|
|
|
printk(KERN_DEBUG"%02x ",*(p+num));
|
|
|
|
if(((num+1)%16 == 0) || ((num+1 ) == len))
|
|
|
|
{
|
|
|
|
printk(KERN_DEBUG"\r\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int commnl_register(int protocol, int msgtype,
|
|
|
|
commnl_doit_func doit, commnl_dumpit_func dumpit,
|
|
|
|
commnl_calcit_func calcit)
|
|
|
|
{
|
|
|
|
switch (protocol)
|
|
|
|
{
|
|
|
|
case NETLINK_PDELIVERY:
|
|
|
|
if(msgtype >= NLMGS_PDELIVERY_MAX_TYPE )
|
|
|
|
{
|
|
|
|
printk(KERN_ERR"commnl_register invalid msgtype %d,protocl pdeliv.\r\n",msgtype);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(NULL != doit)
|
|
|
|
pdelivnl_msg_handlers[msgtype].doit = doit;
|
|
|
|
|
|
|
|
if(NULL != dumpit)
|
|
|
|
pdelivnl_msg_handlers[msgtype].dumpit = dumpit;
|
|
|
|
|
|
|
|
if(NULL != calcit)
|
|
|
|
pdelivnl_msg_handlers[msgtype].calcit = calcit;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NETLINK_COMMCFG:
|
|
|
|
if(msgtype >= COMMCFG_NLMSG_MAX_TYPE )
|
|
|
|
{
|
|
|
|
printk(KERN_ERR"commnl_register invalid msgtype %d,protocl conncfg.\r\n",msgtype);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(NULL != doit)
|
|
|
|
cfgnl_msg_handlers[msgtype].doit = doit;
|
|
|
|
|
|
|
|
if(NULL != dumpit)
|
|
|
|
cfgnl_msg_handlers[msgtype].dumpit = dumpit;
|
|
|
|
|
|
|
|
if(NULL != calcit)
|
|
|
|
cfgnl_msg_handlers[msgtype].calcit = calcit;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
printk(KERN_ERR"commnl_register invalid protocl %d",protocol);
|
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
printk(KERN_DEBUG"commnl_register sucess msgtype %d,protocl %d.\r\n",msgtype,protocol);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int commnl_unregister(int protocol, int msgtype)
|
|
|
|
{
|
|
|
|
switch (protocol)
|
|
|
|
{
|
|
|
|
case NETLINK_PDELIVERY:
|
|
|
|
if(msgtype >= NLMGS_PDELIVERY_MAX_TYPE )
|
|
|
|
{
|
|
|
|
printk(KERN_ERR"commnl_unregister invalid msgtype %d,protocl pdeliv.\r\n",msgtype);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pdelivnl_msg_handlers[msgtype].doit = NULL;
|
|
|
|
pdelivnl_msg_handlers[msgtype].dumpit = NULL;
|
|
|
|
pdelivnl_msg_handlers[msgtype].calcit = NULL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NETLINK_COMMCFG:
|
|
|
|
if(msgtype >= COMMCFG_NLMSG_MAX_TYPE )
|
|
|
|
{
|
|
|
|
printk(KERN_ERR"commnl_unregister invalid msgtype %d,protocl conncfg.\r\n",msgtype);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
cfgnl_msg_handlers[msgtype].doit = NULL;
|
|
|
|
cfgnl_msg_handlers[msgtype].dumpit = NULL;
|
|
|
|
cfgnl_msg_handlers[msgtype].calcit = NULL;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
printk(KERN_ERR"commnl_unregister failed,invalid protocl %d\r\n",protocol);
|
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
printk(KERN_DEBUG"commnl_unregister sucess msgtype %d,protocl %d.\r\n",msgtype,protocol);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int cfg_msgtype_register( int msgtype,commnl_doit_func doit,
|
|
|
|
commnl_dumpit_func dumpit,commnl_calcit_func calcit)
|
|
|
|
{
|
|
|
|
return(commnl_register(NETLINK_COMMCFG, msgtype,
|
|
|
|
doit, dumpit,calcit));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int pdeliv_msgtype_register( int msgtype,commnl_doit_func doit,
|
|
|
|
commnl_dumpit_func dumpit,commnl_calcit_func calcit)
|
|
|
|
{
|
|
|
|
return(commnl_register(NETLINK_PDELIVERY, msgtype,
|
|
|
|
doit, dumpit,calcit));
|
|
|
|
}
|
|
|
|
|
|
|
|
int cfg_msgtype_unregister(int msgtype)
|
|
|
|
{
|
|
|
|
return(commnl_unregister(NETLINK_COMMCFG,msgtype));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int pdeliv_msgtype_unregister(int msgtype)
|
|
|
|
{
|
|
|
|
return(commnl_unregister(NETLINK_PDELIVERY,msgtype));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void printk_ipaddress(unsigned int address)
|
|
|
|
{
|
|
|
|
unsigned int ipa = 0x00000000000000ff;
|
|
|
|
unsigned int ipb = 0x000000000000ff00;
|
|
|
|
unsigned int ipc = 0x0000000000ff0000;
|
|
|
|
unsigned int ipd = 0x00000000ff000000;
|
|
|
|
|
|
|
|
printk(KERN_INFO "%u.%u.%u.%u",address&ipa,(address&ipb)>>8,(address&ipc)>>16,(address&ipd)>>24);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int nl_cfg_data_ready(struct sk_buff *skb, struct nlmsghdr *nlh, struct netlink_ext_ack *extack)
|
2019-06-20 03:20:46 +00:00
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
|
2019-06-11 03:21:35 +00:00
|
|
|
printk(KERN_DEBUG "nl_cfg_data_ready() nlmsg_type = %d begin.\n",nlh->nlmsg_type);
|
|
|
|
|
|
|
|
if(NULL != cfgnl_msg_handlers[nlh->nlmsg_type].doit)
|
|
|
|
{
|
2019-06-20 03:20:46 +00:00
|
|
|
cfgnl_msg_handlers[nlh->nlmsg_type].cfg_recv_succ++;
|
|
|
|
ret = cfgnl_msg_handlers[nlh->nlmsg_type].doit(skb, nlh);
|
|
|
|
recv_dfs.cfg_recv_succ++;
|
|
|
|
|
2019-06-11 03:21:35 +00:00
|
|
|
}
|
2019-06-20 03:20:46 +00:00
|
|
|
|
2019-06-11 03:21:35 +00:00
|
|
|
else
|
|
|
|
{
|
2019-06-20 03:20:46 +00:00
|
|
|
cfgnl_msg_handlers[nlh->nlmsg_type].cfg_recv_fail++;
|
|
|
|
recv_dfs.cfg_recv_fail++;
|
2019-06-11 03:21:35 +00:00
|
|
|
printk(KERN_WARNING "no doit fun register with nlmsg_type = %d .\n",nlh->nlmsg_type);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
printk(KERN_DEBUG "nl_cfg_data_ready() nlmsg_type = %d end.\n",nlh->nlmsg_type);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int nl_pdeliv_data_ready(struct sk_buff *skb, struct nlmsghdr *nlh, struct netlink_ext_ack *extack)
|
|
|
|
{
|
2019-06-20 03:20:46 +00:00
|
|
|
int ret = -1;
|
2019-06-11 03:21:35 +00:00
|
|
|
printk(KERN_DEBUG "nl_pdeliv_data_ready() nlmsg_type = %d begin.\n",nlh->nlmsg_type);
|
|
|
|
|
|
|
|
if(NULL != pdelivnl_msg_handlers[nlh->nlmsg_type].doit)
|
|
|
|
{
|
2019-06-20 03:20:46 +00:00
|
|
|
pdelivnl_msg_handlers[nlh->nlmsg_type].cfg_recv_succ++;
|
|
|
|
ret = pdelivnl_msg_handlers[nlh->nlmsg_type].doit(skb, nlh);
|
|
|
|
recv_dfs.pde_recv_succ++;
|
|
|
|
|
2019-06-11 03:21:35 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-06-20 03:20:46 +00:00
|
|
|
recv_dfs.pde_recv_fail++;
|
|
|
|
pdelivnl_msg_handlers[nlh->nlmsg_type].cfg_recv_fail++;
|
2019-06-11 03:21:35 +00:00
|
|
|
printk(KERN_WARNING "no doit fun register with nlmsg_type = %d .\n",nlh->nlmsg_type);
|
|
|
|
}
|
|
|
|
|
|
|
|
printk(KERN_DEBUG "nl_pdeliv_data_ready() nlmsg_type = %d end.\n",nlh->nlmsg_type);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void libcfgnl_rcv(struct sk_buff *skb)
|
|
|
|
{
|
|
|
|
printk(KERN_DEBUG "libcfgnl_rcv:\n");
|
|
|
|
|
|
|
|
netlink_rcv_skb(skb, &nl_cfg_data_ready);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void libpdelivnl_rcv(struct sk_buff *skb)
|
|
|
|
{
|
|
|
|
printk(KERN_DEBUG "libpdelivnl_rcv:\n");
|
|
|
|
|
|
|
|
netlink_rcv_skb(skb, &nl_pdeliv_data_ready);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int libnetlinkk_init_byproto(struct netlinkk_cfg *g_nlcfg)
|
|
|
|
{
|
|
|
|
printk(KERN_CRIT "libnetlinkk_init:\n");
|
|
|
|
|
|
|
|
if(g_nlcfg->subscriptions == NETLINK_PDELIVERY)
|
|
|
|
{
|
|
|
|
g_nlcfg->cfg.input = libpdelivnl_rcv;
|
|
|
|
}
|
|
|
|
else if(g_nlcfg->subscriptions == NETLINK_COMMCFG )
|
|
|
|
{
|
|
|
|
g_nlcfg->cfg.input = libcfgnl_rcv;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printk(KERN_INFO"libnetlinkk_init_byproto invalid subscriptions %d",g_nlcfg->subscriptions);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_nlcfg->cfg.flags = NL_CFG_F_NONROOT_RECV;
|
|
|
|
g_nlcfg->user_pid = -1;
|
|
|
|
//g_nlcfg->sk = -1;
|
2019-06-14 09:14:06 +00:00
|
|
|
//g_nlcfg->pkt_delev_num = 0;
|
2019-06-11 03:21:35 +00:00
|
|
|
|
|
|
|
g_nlcfg->sk = netlink_kernel_create(&init_net, g_nlcfg->subscriptions, &(g_nlcfg->cfg));
|
|
|
|
if (!g_nlcfg->sk)
|
|
|
|
{
|
|
|
|
printk(KERN_CRIT "pcapk_nl create init socket faild!\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void libnetlinkk_exit(struct netlinkk_cfg *g_nlcfg)
|
|
|
|
{
|
|
|
|
printk(KERN_CRIT "libnetlinkk_exit...\n");
|
|
|
|
netlink_kernel_release(g_nlcfg->sk);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* nlmsg_unicast - unicast a netlink message
|
|
|
|
* @sk: netlink socket to spread message to
|
|
|
|
* @skb: netlink message as socket buffer
|
|
|
|
* @portid: netlink portid of the destination socket
|
|
|
|
*/
|
|
|
|
int commnl_unicast(struct sock *sk, struct sk_buff *skb, u32 portid)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = netlink_unicast(sk, skb, portid, MSG_DONTWAIT);
|
|
|
|
if (err > 0)
|
|
|
|
err = 0;
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2019-06-13 06:55:31 +00:00
|
|
|
|
2019-06-20 03:20:46 +00:00
|
|
|
|
|
|
|
int debugfs_pkt_num_stati(struct netlinkk_cfg *g_nlcfg, struct nlmsghdr *nlh, unsigned long fk_type)
|
2019-06-14 09:14:06 +00:00
|
|
|
{
|
|
|
|
int err;
|
|
|
|
struct sk_buff *out_skb;
|
|
|
|
struct nlmsghdr *out_nlh;
|
2019-06-20 03:20:46 +00:00
|
|
|
unsigned int length = sizeof(struct netlink_debugfs);
|
2019-06-14 09:14:06 +00:00
|
|
|
|
|
|
|
out_skb = nlmsg_new(length, GFP_KERNEL);
|
|
|
|
if (!out_skb) goto failure;
|
|
|
|
out_nlh = nlmsg_put(out_skb, 0, 0, NLMSG_DEBUGFS, length, 0);
|
|
|
|
if (!out_nlh) goto failure;
|
2019-06-20 03:20:46 +00:00
|
|
|
|
|
|
|
g_nlcfg->netlink_dfs.cfg_rev_succ = cfgnl_msg_handlers[fk_type].cfg_recv_succ;
|
|
|
|
g_nlcfg->netlink_dfs.cfg_rev_fail = cfgnl_msg_handlers[fk_type].cfg_recv_fail;
|
|
|
|
g_nlcfg->netlink_dfs.pde_rev_succ = pdelivnl_msg_handlers[fk_type].cfg_recv_succ;
|
|
|
|
g_nlcfg->netlink_dfs.pde_rev_fail = pdelivnl_msg_handlers[fk_type].cfg_recv_fail;
|
|
|
|
|
|
|
|
memcpy(nlmsg_data(out_nlh), &(g_nlcfg->netlink_dfs), length);
|
|
|
|
printk("******************************g_nlcfg->pdeliv_dfs.pde_fail=%d****************\n",g_nlcfg->netlink_dfs.pde_pkt_fail);
|
|
|
|
printk("******************************g_nlcfg->pdeliv_dfs.pde_succ=%d****************\n",g_nlcfg->netlink_dfs.pde_pkt_succ);
|
2019-06-14 09:14:06 +00:00
|
|
|
err = commnl_unicast(g_nlcfg->sk, out_skb, nlh->nlmsg_pid);
|
|
|
|
if (err > 0)
|
|
|
|
err = 0;
|
|
|
|
|
|
|
|
return err;
|
|
|
|
failure:
|
|
|
|
printk(KERN_INFO " failed in fun dataready!\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int nf_nlmsg_multicast(struct netlinkk_cfg *g_nlcfg, struct sk_buff *skb)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
ret = nlmsg_multicast(g_nlcfg->sk,skb,0,PDNLGRP_ALLRAW,0);
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
2019-06-20 03:20:46 +00:00
|
|
|
(g_nlcfg->netlink_dfs.pde_pkt_fail)++;
|
2019-06-14 09:14:06 +00:00
|
|
|
printk(KERN_INFO "Error while sending pkt to user, err id: %d\n", ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ret==0)
|
|
|
|
{
|
2019-06-20 03:20:46 +00:00
|
|
|
(g_nlcfg->netlink_dfs.pde_pkt_succ)++;
|
2019-06-14 09:14:06 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-06-20 03:20:46 +00:00
|
|
|
EXPORT_SYMBOL_GPL(pdeliv_msgtype_register);
|
|
|
|
EXPORT_SYMBOL_GPL(cfg_msgtype_register);
|
|
|
|
EXPORT_SYMBOL_GPL(cfg_msgtype_unregister);
|
|
|
|
EXPORT_SYMBOL_GPL(pdeliv_msgtype_unregister);
|
|
|
|
EXPORT_SYMBOL_GPL(libnetlinkk_init_byproto);
|
|
|
|
EXPORT_SYMBOL_GPL(libnetlinkk_exit);
|
|
|
|
EXPORT_SYMBOL_GPL(commnl_unicast);
|
|
|
|
EXPORT_SYMBOL_GPL(printk_mem);
|
|
|
|
EXPORT_SYMBOL_GPL(printk_ipaddress);
|
|
|
|
EXPORT_SYMBOL_GPL(debugfs_pkt_num_stati);
|
|
|
|
EXPORT_SYMBOL_GPL(nf_nlmsg_multicast);
|
|
|
|
|
2019-06-13 06:55:31 +00:00
|
|
|
int __init libnetlink_k_init(void)
|
|
|
|
{
|
|
|
|
printk(KERN_INFO "insmod netlink.ko...\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
void __exit libnetlink_k_exit(void)
|
|
|
|
{
|
|
|
|
printk(KERN_INFO "rmmod netlink.ko...\n");
|
|
|
|
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
module_init(libnetlink_k_init);
|
|
|
|
module_exit(libnetlink_k_exit);
|
2019-06-11 03:21:35 +00:00
|
|
|
|
2019-06-13 06:55:31 +00:00
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
MODULE_DESCRIPTION("a common channel,made netlink protocal family");
|
|
|
|
MODULE_AUTHOR("RSLjdkt");
|
2019-06-11 03:21:35 +00:00
|
|
|
|