#include #include #include #include #include #include #include #include #include "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) ) /**************************************************************************************************************/ void printk_mem(unsigned char * p,int len) { int num = 0; for(num = 0; numdoit = doit; if(NULL != dumpit) (msg_handlers+msgtype)->dumpit = dumpit; if(NULL != calcit) (msg_handlers+msgtype)->calcit = calcit; return 0; } int commnl_unregister(struct commnl_msgtype_process *msg_handlers, int msgtype) { (msg_handlers + msgtype)->doit = NULL; (msg_handlers + msgtype)->dumpit = NULL; (msg_handlers + msgtype)->calcit = NULL; return 0; } 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 libnetlinkk_init_byproto(struct netlinkk_cfg *g_nlcfg) { if(g_nlcfg == NULL) { printk(KERN_ERR "netlink.ko-libnetlinkk_init():invaliv input params g_nlcfg is NULL.\n"); return -1; } g_nlcfg->cfg.flags = NL_CFG_F_NONROOT_RECV; g_nlcfg->user_pid = -1; //g_nlcfg->sk = -1; g_nlcfg->sk = netlink_kernel_create(&init_net, g_nlcfg->subscriptions, &(g_nlcfg->cfg)); if (!g_nlcfg->sk) { printk(KERN_CRIT "netlink.ko-netlink_kernel create socket faild!\n"); return -1; } printk(KERN_INFO "netlink.ko-netlink sock init sucess:proto %s.\n", (g_nlcfg->subscriptions == NETLINK_PDELIVERY)?"pdeliv":"comcfg"); 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; } int debugfs_prk_onoff(struct netlinkk_cfg *g_nlcfg, struct nlmsghdr *nlh,struct netlink_ext_ack *extack) { unsigned char * cookies = "test cookies"; int len = 0; char *pload; struct nlattr *rta; char* load; unsigned long fk_type; pload = nlmsg_data(nlh); rta = (struct nlattr *)pload; load = RTA_DATA(rta); strict_strtoul(load, 10, &fk_type); g_nlcfg->debugfs_prk_enable = fk_type; NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, "***gift***%s", __func__); len = strlen(cookies); if(len > sizeof(extack->cookie) )/*check len*/ { NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, "debugfs_pkt_num_stati:cookies oversize the netlinkt cookies.\r\n"); extack->cookie_len = sizeof(extack->cookie); } else { extack->cookie_len = len; } memcpy(extack->cookie, cookies, extack->cookie_len);/*becare:size must small than 20 u8!!!!!!!!!!*/ NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, "-debugfs_pkt_num_stati ack type=%d,seq=%d,extack->cookie_len=%d.\n", nlh->nlmsg_type,nlh->nlmsg_seq,extack->cookie_len); return 0; } int debugfs_pkt_num_stati(struct netlinkk_cfg *g_nlcfg, struct nlmsghdr *nlh,struct netlink_ext_ack *extack) { unsigned char * cookies = "test cookies"; int len = 0; NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, "debugfs_pkt_num_stati.\r\n"); len = strlen(cookies); if(len > sizeof(extack->cookie) )/*check len*/ { NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, "debugfs_pkt_num_stati:cookies oversize the netlinkt cookies.\r\n"); extack->cookie_len = sizeof(extack->cookie); } else { extack->cookie_len = len; } memcpy(extack->cookie, cookies, extack->cookie_len);/*becare:size must small than 20 u8!!!!!!!!!!*/ NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, "-debugfs_pkt_num_stati ack type=%d,seq=%d,extack->cookie_len=%d.\n", nlh->nlmsg_type,nlh->nlmsg_seq,extack->cookie_len); return 0; } int debugfs_pkt_num_stati_witisend(struct netlinkk_cfg *g_nlcfg, struct nlmsghdr *nlh,struct commnl_msgtype_process* msg_process) { int err; struct sk_buff *out_skb; struct nlmsghdr *out_nlh; unsigned int length = sizeof(struct netlink_debugfs); char *pload; struct nlattr *rta; char* load; unsigned long fk_type; struct netlink_debugfs * tmp_dfs = NULL; pload = nlmsg_data(nlh); rta = (struct nlattr *)pload; load = RTA_DATA(rta); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, "*******rta->nla_type=%d*********\n", rta->nla_type); //nla_type NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, "*******load=*****%s**********\n",(char *)load); //string printf strict_strtoul(load, 10, &fk_type); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, "*******fk_type%lu********************\n", fk_type); out_skb = nlmsg_new(2*length, GFP_KERNEL); if (!out_skb) goto failure; out_nlh = nlmsg_put(out_skb,nlh->nlmsg_pid, nlh->nlmsg_seq, 0x11, 2*length, 0); if (!out_nlh) goto failure; tmp_dfs = &((msg_process+fk_type)->dfs); //nla_put_nohdr(out_skb, length, &(g_nlcfg->dfs)); //nla_put_nohdr(out_skb, length, tmp_dfs); memcpy(nlmsg_data(out_nlh), &(g_nlcfg->dfs), length); memcpy(nlmsg_data(out_nlh)+length, tmp_dfs, length); #if 1 NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " netlink total msg stats:\r\n"); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " rev_total = %d\n",g_nlcfg->dfs.rev_total); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " rev_cb_sucess = %d\n",g_nlcfg->dfs.rev_cb_sucess); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " rev_cb_fail = %d\n",g_nlcfg->dfs.rev_cb_fail); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " rev_drop_total = %d\n",g_nlcfg->dfs.rev_drop_total); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " rev_drop_nodoit = %d\n",g_nlcfg->dfs.rev_drop_nodoit); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " send_succ = %d\n",g_nlcfg->dfs.send_succ); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " send_fail = %d\n",g_nlcfg->dfs.send_fail); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " netlink msg stats:\r\n"); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " rev_total = %d\n",tmp_dfs->rev_total); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " rev_cb_sucess = %d\n",tmp_dfs->rev_cb_sucess); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " rev_cb_fail = %d\n",tmp_dfs->rev_cb_fail); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " rev_drop_total = %d\n",tmp_dfs->rev_drop_total); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " rev_drop_nodoit = %d\n",tmp_dfs->rev_drop_nodoit); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " send_succ = %d\n",tmp_dfs->send_succ); NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " send_fail = %d\n",tmp_dfs->send_fail); #endif NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, "------------------debugfs_pkt_num_stati ack msg_type %d,seq=%d!\n",out_nlh->nlmsg_type,nlh->nlmsg_seq); err = commnl_unicast(g_nlcfg->sk, out_skb, nlh->nlmsg_pid); if (err > 0) { err = 0; } else { goto failure; } return err; failure: if(out_skb != NULL) { //kfree_skb(out_skb); } NETLINK_DEBUG(g_nlcfg->debugfs_prk_enable, " 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) { //g_nlcfg->dfs.send_fail ++; //printk(KERN_ERR "Error while sending pkt to user, ret id: %d\n", ret); } else { //g_nlcfg.dfs.send_succ++; } return ret; } EXPORT_SYMBOL_GPL(commnl_register); EXPORT_SYMBOL_GPL(commnl_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(debugfs_pkt_num_stati_witisend); EXPORT_SYMBOL_GPL(nf_nlmsg_multicast); EXPORT_SYMBOL_GPL(debugfs_prk_onoff); 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); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("a common channel,made netlink protocal family"); MODULE_AUTHOR("RSLjdkt");