static void netlink_rcv_cb(struct sk_buff *skb) { struct nlmsghdr *nlh; struct net_device *dev; u32 mlen; void *msg; int ifindex; if (skb->len >= NLMSG_SPACE(0)) { nlh = (struct nlmsghdr *)skb->data; if (skb->len < nlh->nlmsg_len || nlh->nlmsg_len > ND_MAX_MSG_LEN) { printk(KERN_ERR "Invalid length (%d,%d)\n", skb->len, nlh->nlmsg_len); return; } memcpy(&ifindex, ND_NLMSG_IFIDX(nlh), ND_IFINDEX_LEN); msg = ND_NLMSG_DATA(nlh); mlen = ND_NLMSG_R_LEN(nlh); if (rcv_cb) { dev = dev_get_by_index(&init_net, ifindex); if (dev) { rcv_cb(dev, nlh->nlmsg_type, msg, mlen); dev_put(dev); } else printk(KERN_ERR "dev_get_by_index(%d) " "is not found.\n", ifindex); } else printk(KERN_ERR "Unregistered Callback\n"); } }
static void netlink_rcv_cb(struct sk_buff *skb) { struct nlmsghdr *nlh; struct net_device *dev; u32 mlen; void *msg; int ifindex; if (!rcv_cb) { pr_err("nl cb - unregistered\n"); return; } if (skb->len < NLMSG_HDRLEN) { pr_err("nl cb - invalid skb length\n"); return; } nlh = (struct nlmsghdr *)skb->data; if (skb->len < nlh->nlmsg_len || nlh->nlmsg_len > ND_MAX_MSG_LEN) { pr_err("nl cb - invalid length (%d,%d)\n", skb->len, nlh->nlmsg_len); return; } memcpy(&ifindex, ND_NLMSG_IFIDX(nlh), ND_IFINDEX_LEN); msg = ND_NLMSG_DATA(nlh); mlen = ND_NLMSG_R_LEN(nlh); dev = dev_get_by_index(&init_net, ifindex); if (dev) { rcv_cb(dev, nlh->nlmsg_type, msg, mlen); dev_put(dev); } else { pr_err("nl cb - dev (%d) not found\n", ifindex); } }