#include #include #include "trace_def.h" #include "../netlink_api/libnetlink_k.h" #include "trace_msg.h" #include "commuapinl.h" static int trace_rcv_policy(struct sk_buff *skb, struct nlmsghdr *nlh) { trace_ret_t ret = TRACE_FAILURE; trace_hdr_t *hdr; void *buf; int len; struct sk_buff *reply_skb; struct nlmsghdr *reply_hdr; void *reply_data; trace_reply_t *reply; int reply_ret; trace_policy_t *policy; printk(KERN_DEBUG"Trace recv policy"); switch (nlh->nlmsg_type) { case TRACE_MSG_POLICY_REQ: buf = nlmsg_data(nlh); if (buf == NULL) { printk(KERN_ERR"Receiving data is null"); break; } len = nlmsg_len((const struct nlmsghdr *)nlh); printk(KERN_DEBUG"Receive data of trace is len:%d", len); if (len < TRACE_REQ_SZ) { printk(KERN_WARNING"Receiving data length:%d is less than length:%ld is needed", len, TRACE_REQ_SZ); } hdr = (trace_hdr_t *)buf; policy = (trace_policy_t *)(buf + 1); ret = TRACE_SUCCESS; break; default: printk(KERN_WARNING"Unknow msg type:%u", nlh->nlmsg_type); return 1; break; } if (ret == TRACE_FAILURE) { return 1; } if (hdr->is_reply == REPLY_OP_NO_NEED) { return 0; } reply_skb = nlmsg_new(TRACE_REPLY_SZ, GFP_KERNEL); if (reply_skb == NULL) { printk(KERN_ERR"Allocating skb memory is failure"); goto FAIL; } reply_hdr = nlmsg_put(reply_skb, 0, 0, TRACE_MSG_POLICY_REPLY, TRACE_REPLY_SZ, 0); if (reply_hdr == NULL) { printk(KERN_ERR"Putting length of reply is failure"); goto FAIL; } reply_data = nlmsg_data(reply_hdr); if (reply_data == NULL) { printk(KERN_ERR"Reply data is null"); goto FAIL; } reply = (trace_reply_t *)reply_data; memcpy(&reply->hdr, hdr, sizeof(*hdr)); reply->result = ret; reply_ret = commnl_unicast(NULL, reply_skb, nlh->nlmsg_pid); if (reply_ret != 0) { printk(KERN_ERR"Reply message is failure"); goto FAIL; } nlmsg_free(reply_skb); return 0; FAIL: if (reply_skb != NULL) { nlmsg_free(reply_skb); } return 1; } static int __init trace_init(void) { printk(KERN_INFO"Trace is initiating"); cfg_msgtype_register(TRACE_CFG_POLICY, trace_rcv_policy, NULL, NULL); printk(KERN_INFO"Trace is initiated"); return 0; } static void __exit trace_exit(void) { cfg_msgtype_unregister(TRACE_CFG_POLICY); } module_init(trace_init); module_exit(trace_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Trace process module"); MODULE_AUTHOR("zhangtao");