245 lines
6.3 KiB
C
245 lines
6.3 KiB
C
#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 "usercfg_kinit.h"
|
||
|
||
#include "../../../../../Common/commuapinl.h"
|
||
|
||
#include <linux/rtnetlink.h>
|
||
|
||
#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 netlinkk_cfg g_upmnlcfg;
|
||
struct commnl_msgtype_process cfgnl_msg_handlers[COMMCFG_NLMSG_MAX_TYPE];
|
||
|
||
|
||
/*全局变量,存放免认证规则信息,目前只考虑放一条免认证规则,以结构体形式存放,后期考虑链表存放 */
|
||
freeauth_configure_t * kfreeauth;
|
||
|
||
|
||
/*全局变量,存放配置的用户老化时间 */
|
||
int *kaging_time = NULL;
|
||
|
||
|
||
int nl_cfg_data_ready(struct sk_buff *skb, struct nlmsghdr *nlh, struct netlink_ext_ack *extack)
|
||
{
|
||
int ret = 0;
|
||
|
||
printk(KERN_DEBUG "nl_cfg_data_ready() nlmsg_type = %d begin.\n",nlh->nlmsg_type);
|
||
g_upmnlcfg.dfs.rev_total++;
|
||
|
||
if(NULL != cfgnl_msg_handlers[nlh->nlmsg_type].doit)
|
||
{
|
||
cfgnl_msg_handlers[nlh->nlmsg_type].dfs.rev_total++;
|
||
ret = cfgnl_msg_handlers[nlh->nlmsg_type].doit(skb, nlh,extack);
|
||
if(ret >= 0)
|
||
{
|
||
g_upmnlcfg.dfs.rev_cb_sucess++;
|
||
cfgnl_msg_handlers[nlh->nlmsg_type].dfs.rev_cb_sucess++;
|
||
}
|
||
else
|
||
{
|
||
g_upmnlcfg.dfs.rev_cb_fail++;
|
||
cfgnl_msg_handlers[nlh->nlmsg_type].dfs.rev_cb_fail++;
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
cfgnl_msg_handlers[nlh->nlmsg_type].dfs.rev_drop_total++;
|
||
cfgnl_msg_handlers[nlh->nlmsg_type].dfs.rev_drop_nodoit++;
|
||
g_upmnlcfg.dfs.rev_drop_total++;
|
||
g_upmnlcfg.dfs.rev_drop_nodoit++;
|
||
|
||
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 ret;
|
||
}
|
||
|
||
|
||
static void libcfgnl_rcv(struct sk_buff *skb)
|
||
{
|
||
printk(KERN_DEBUG "libcfgnl_rcv:\n");
|
||
netlink_rcv_skb(skb, &nl_cfg_data_ready);
|
||
|
||
}
|
||
|
||
|
||
/*单播,内核态发送给用户态 */
|
||
int cfgnl_unicast(struct sk_buff *skb, u32 portid)
|
||
{
|
||
int ret = -1;
|
||
struct nlmsghdr *nlh = NULL;
|
||
int msgtype = 0;
|
||
|
||
/**
|
||
* 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
|
||
*/
|
||
ret = commnl_unicast(g_upmnlcfg.sk, skb, portid);
|
||
|
||
if(ret < 0)
|
||
{
|
||
g_upmnlcfg.dfs.send_fail++;
|
||
g_upmnlcfg.dfs.send_fail_reason = ret;
|
||
}
|
||
else
|
||
{
|
||
g_upmnlcfg.dfs.send_succ++;
|
||
}
|
||
|
||
|
||
nlh = (struct nlmsghdr *)skb->head;
|
||
msgtype = nlh->nlmsg_type;
|
||
if(msgtype > COMMCFG_NLMSG_MAX_TYPE)
|
||
{
|
||
printk(KERN_ERR "cfg_unicast:msg type invalid.\r\n");
|
||
}
|
||
else
|
||
{
|
||
printk(KERN_DEBUG "cfg_unicast:msg type %d.\r\n",msgtype);
|
||
if(ret < 0)
|
||
{
|
||
cfgnl_msg_handlers[msgtype].dfs.send_fail++;
|
||
}
|
||
else
|
||
{
|
||
cfgnl_msg_handlers[msgtype].dfs.send_succ++;
|
||
}
|
||
}
|
||
|
||
return(ret);
|
||
}
|
||
|
||
|
||
/*免认证规则配置的功能函数,解析出配置信息,存全局变量*/
|
||
int usercfg_freeauth(struct sk_buff *skb, struct nlmsghdr *nlh,struct netlink_ext_ack *extack)
|
||
{
|
||
char *pload;
|
||
struct nlattr *rta;
|
||
char *load;
|
||
|
||
/**
|
||
* nlmsg_data - head of message payload
|
||
* @nlh: netlink message header
|
||
*/
|
||
pload = nlmsg_data(nlh);
|
||
rta = (struct nlattr *)pload;
|
||
load = RTA_DATA(rta);
|
||
|
||
kfreeauth = (freeauth_configure_t *)load;
|
||
|
||
printk("name:%s sip:%d\n", kfreeauth->name, kfreeauth->sip);
|
||
printk("dip:%d dport:%d\n", kfreeauth->dip, kfreeauth->dport);
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*用户老化时间配置的功能函数,解析出配置信息,存全局变量 */
|
||
int usercfg_agingtime(struct sk_buff *skb, struct nlmsghdr *nlh,struct netlink_ext_ack *extack)
|
||
{
|
||
char *pload;
|
||
struct nlattr *rta;
|
||
char *load;
|
||
|
||
pload = nlmsg_data(nlh);
|
||
rta = (struct nlattr *)pload;
|
||
load = RTA_DATA(rta);
|
||
|
||
kaging_time = (int *)load;
|
||
|
||
printk("agingtime: %d\n", *kaging_time);
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
int cfg_msgtype_register( int msgtype,commnl_doit_func doit,
|
||
commnl_dumpit_func dumpit,commnl_calcit_func calcit)
|
||
{
|
||
if(msgtype >= COMMCFG_NLMSG_MAX_TYPE )
|
||
{
|
||
printk(KERN_ERR"netlink.ko-msgtype register invalid msgtype %d,protocl comcfg.\r\n",msgtype);
|
||
return -1;
|
||
}
|
||
|
||
/*函数功能:注册内核态配置接收消息处理函数。 */
|
||
/*输入参数: */
|
||
/*msgtype:注册的消息类型。*/
|
||
/*doit:对应的消息接收处理函数;*/
|
||
/*dumpit,calcit:框架预留接口,暂未使用。填NULL.*/
|
||
/*输出参数: WU */
|
||
/*返回值:0注册成功;< 0,失败*/
|
||
commnl_register(cfgnl_msg_handlers, msgtype, doit, dumpit, calcit);
|
||
|
||
printk(KERN_INFO"netlink.ko-msgtype register sucess msgtype %d,protocl comcfg.\r\n",msgtype);
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
/*commcfgmsgtype:FREEAUTH_CFG = 0x13, 用户态发送给内核态的免认证规则消息*/
|
||
/*AGINGTIME_CFG = 0x14, 用户态发送给内核态的用户老化时间消息 */
|
||
int __init usercfgrcv_init(void)
|
||
{
|
||
int ret = -1;
|
||
|
||
printk(KERN_INFO "usercfgrcv.ko-initialed\n");
|
||
|
||
g_upmnlcfg.msg_processer = &(cfgnl_msg_handlers[0]);
|
||
g_upmnlcfg.msg_processer_num = COMMCFG_NLMSG_MAX_TYPE;
|
||
|
||
/*init for usercfg module */
|
||
g_upmnlcfg.groups = 0;
|
||
g_upmnlcfg.subscriptions = NETLINK_COMMCFG; /*创建配置处理通道 */
|
||
g_upmnlcfg.cfg.input = libcfgnl_rcv;
|
||
|
||
|
||
/*函数功能:在内核态创建报文上送通道,上送的 */
|
||
/*报文内容从链路层头开始。一个netlink协议号只能创建一个通道。 */
|
||
/*输入参数:g_nlcfg */
|
||
/*输出参数: wu */
|
||
/*返回值:0通道创建成果;< 0,失败 */
|
||
ret = libnetlinkk_init_byproto(&g_upmnlcfg);
|
||
if(ret < 0)
|
||
{
|
||
return ret;
|
||
}
|
||
|
||
/*do msg process register */
|
||
ret = cfg_msgtype_register(FREEAUTH_CFG, usercfg_freeauth, NULL, NULL);
|
||
ret = cfg_msgtype_register(AGINGTIME_CFG, usercfg_agingtime, NULL, NULL);
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
void __exit usercfgrcv_exit(void)
|
||
{
|
||
printk(KERN_CRIT "nl_upm existing...\n");
|
||
libnetlinkk_exit(&g_upmnlcfg);
|
||
}
|
||
|
||
|
||
EXPORT_SYMBOL_GPL(cfgnl_unicast);
|
||
EXPORT_SYMBOL_GPL(cfg_msgtype_register);
|
||
|
||
module_init(usercfgrcv_init);
|
||
module_exit(usercfgrcv_exit);
|
||
|