Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <net/sock.h>
- #include <linux/socket.h>
- #include <linux/net.h>
- #include <asm/types.h>
- #include <linux/netlink.h>
- #include <linux/skbuff.h>
- #include <linux/netdevice.h>
- #include <linux/if_link.h>
- #define MAX_PAYLOAD_SIZE 4096
- #define NETLINK_USER 2
- /* Module info */
- MODULE_AUTHOR("Yury Sokolov <yura1703@yandex.ru>");
- MODULE_LICENSE("GPL");
- /* Global variables */
- struct sock *nl_sk = NULL;
- int i = 0;
- /* Logging info about all network devices */
- int get_dev_info_logged(char **res_info)
- {
- int pos = 0;
- *res_info = (char *) kcalloc(MAX_PAYLOAD_SIZE, sizeof(char), GFP_USER);
- if (!*res_info)
- {
- printk(KERN_ERR "[NL_KERNEL] unable to allocate memory.");
- return -ENOMEM;
- }
- /* Proceeding dev_net */
- struct net_device *dev;
- dev = first_net_device(&init_net);
- pos += snprintf(*res_info+pos, MAX_PAYLOAD_SIZE-pos,
- "%6s %3s %1s %6s %2s %17s %6s %6s %6s %6s %7s %3s\n",
- "Name", "T", "S", "MTU", "UP", "HWaddr", "TxP", "TxB", "RxP", "RxB", "Baddr", "Irq");
- while (dev)
- {
- int is_up;
- if (IFF_UP & dev->flags)
- is_up = 1;
- else
- is_up = 0;
- struct rtnl_link_stats64 rtnl_stats;
- dev_get_stats(dev, &rtnl_stats);
- pos += snprintf(*res_info+pos, MAX_PAYLOAD_SIZE-pos,
- "%6s %3d %1u %6lu %2d %02x:%02x:%02x:%02x:%02x:%02x %6llu %6llu %6llu %6llu %7x %3d\n",
- dev->name,
- dev->type,
- dev->state,
- dev->mtu,
- is_up,
- dev->dev_addr[0],
- dev->dev_addr[1],
- dev->dev_addr[2],
- dev->dev_addr[3],
- dev->dev_addr[4],
- dev->dev_addr[5],
- rtnl_stats.tx_packets,
- rtnl_stats.tx_bytes,
- rtnl_stats.rx_packets,
- rtnl_stats.rx_bytes,
- dev->base_addr,
- dev->irq);
- dev = next_net_device(dev);
- }
- return 0;
- }
- /* Getting netlink message from userspace application */
- static void my_nl_recv_msg(struct sk_buff *skb)
- {
- printk(KERN_INFO "[NL_KERNEL] Entering: %s\n", __FUNCTION__);
- struct nlmsghdr *nlh;
- int pid;
- struct sk_buff *skb_out;
- int msg_size;
- char *msg;
- if (get_dev_info_logged(&msg) < 0) // here we allocate memory
- return;
- int res;
- msg_size = strlen(msg);
- nlh = (struct nlmsghdr *)skb->data;
- //printk(KERN_INFO "[NL_KERNEL] Netlink received msg payload:%s\n", (char *)nlmsg_data(nlh));
- pid = nlh->nlmsg_pid; /*pid of sending process */
- skb_out = nlmsg_new(msg_size, 0);
- if (!skb_out)
- {
- printk(KERN_ERR "[NL_KERNEL] Failed to allocate new skb\n");
- return;
- }
- nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, msg_size, 0);
- NETLINK_CB(skb_out).dst_group = 0; /* not in mcast group */
- strncpy(nlmsg_data(nlh), msg, msg_size);
- res = nlmsg_unicast(nl_sk, skb_out, pid);
- kfree(msg);
- if (res < 0)
- printk(KERN_ERR "[NL_KERNEL] Error while sending back to user\n");
- }
- /* Module init function */
- int __init nl_kernel_init(void)
- {
- printk(KERN_INFO "[NL_KERNEL] Init module.\n");
- /* Creating netlink socket */
- struct netlink_kernel_cfg cfg = {
- .input = my_nl_recv_msg,
- };
- nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, &cfg);
- if(!nl_sk)
- {
- printk(KERN_ERR "[NL_KERNEL] Error creating socket.\n");
- return -ENOMEM;
- }
- printk(KERN_INFO "[NL_KERNEL] Now module is running.\n");
- return 0;
- }
- /* Module exit function */
- void __exit nl_kernel_exit(void)
- {
- printk(KERN_INFO "[NL_KERNEL] Exit module.\n");
- netlink_kernel_release(nl_sk);
- printk(KERN_INFO "[NL_KERNEL] Module is not running anymore.\n");
- }
- /* Initializing module */
- module_init(nl_kernel_init);
- module_exit(nl_kernel_exit);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement