#include #include #include #include #include #include #include #include #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]; void printk_mem(unsigned char * p,int len) { int num = 0; for(num = 0; num= 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) { printk(KERN_DEBUG "nl_cfg_data_ready() nlmsg_type = %d begin.\n",nlh->nlmsg_type); if(NULL != cfgnl_msg_handlers[nlh->nlmsg_type].doit) { cfgnl_msg_handlers[nlh->nlmsg_type].doit(skb, nlh); } else { 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) { printk(KERN_DEBUG "nl_pdeliv_data_ready() nlmsg_type = %d begin.\n",nlh->nlmsg_type); if(NULL != pdelivnl_msg_handlers[nlh->nlmsg_type].doit) { pdelivnl_msg_handlers[nlh->nlmsg_type].doit(skb, nlh); } else { 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; g_nlcfg->pkt_delev_num = 0; 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; } 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); 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");