打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
简化版udev, 抓取uevent事件
  • #include <stdio.h>
  • #include <string.h>
  • #include <sys/socket.h>
  • #include <linux/netlink.h>

  • struct uevent {
  •     const char *action;
  •     const char *path;
  •     const char *subsystem;
  •     const char *firmware;
  •     int major;
  •     int minor;
  • };

  • static int open_uevent_socket(void)
  • {
  •     struct sockaddr_nl addr;
  •     int sz = 64*1024; // XXX larger? udev uses
  •     int on = 1;
  •     int s;

  •     memset(&addr, 0, sizeof(addr));
  •     addr.nl_family = AF_NETLINK;
  •     addr.nl_pid = getpid();
  •     addr.nl_groups = 0xffffffff;

  •     s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
  •     if(s < 0)
  •         return -1;

  •     setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz));
  •     setsockopt(s, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));

  •     if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  •         close(s);
  •         return -1;
  •     }

  •     return s;
  • }

  • static void parse_event(const char *msg, struct uevent *uevent)
  • {
  • #if 1
  •     uevent->action = "";
  •     uevent->path = "";
  •     uevent->subsystem = "";
  •     uevent->firmware = "";
  •     uevent->major = -1;
  •     uevent->minor = -1;

  •         /* currently ignoring SEQNUM */
  •     while(*msg) {
  •         printf("%s\n", msg);
  •         if(!strncmp(msg, "ACTION=", 7)) {
  •             msg += 7;
  •             uevent->action = msg;
  •         } else if(!strncmp(msg, "DEVPATH=", 8)) {
  •             msg += 8;
  •             uevent->path = msg;
  •         } else if(!strncmp(msg, "SUBSYSTEM=", 10)) {
  •             msg += 10;
  •             uevent->subsystem = msg;
  •         } else if(!strncmp(msg, "FIRMWARE=", 9)) {
  •             msg += 9;
  •             uevent->firmware = msg;
  •         } else if(!strncmp(msg, "MAJOR=", 6)) {
  •             msg += 6;
  •             uevent->major = atoi(msg);
  •         } else if(!strncmp(msg, "MINOR=", 6)) {
  •             msg += 6;
  •             uevent->minor = atoi(msg);
  •         }

  •             /* advance to after the next \0 */
  •         while(*msg++)
  •             ;
  •     }

  •     printf("event { '%s', '%s', '%s', '%s', %d, %d }\n",
  •                     uevent->action, uevent->path, uevent->subsystem,
  •                     uevent->firmware, uevent->major, uevent->minor);
  • #endif
  • }

  • #define UEVENT_MSG_LEN 1024
  • void handle_device_fd(int fd)
  • {
  •     printf("enter %s\n", __func__);
  •     for(;;) {
  •         char msg[UEVENT_MSG_LEN+2];
  •         char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
  •         struct iovec iov = {msg, sizeof(msg)};
  •         struct sockaddr_nl snl;
  •         struct msghdr hdr = {&snl, sizeof(snl), &iov, 1, cred_msg, sizeof(cred_msg), 0};

  •         ssize_t n = recvmsg(fd, &hdr, 0);
  •         if (n <= 0) {
  •             break;
  •         }

  •         if ((snl.nl_groups != 1) || (snl.nl_pid != 0)) {
  •             /* ignoring non-kernel netlink multicast message */
  •             continue;
  •         }

  •         struct cmsghdr * cmsg = CMSG_FIRSTHDR(&hdr);
  •         if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
  •             /* no sender credentials received, ignore message */
  •             continue;
  •         }

  •         struct ucred * cred = (struct ucred *)CMSG_DATA(cmsg);
  •         if (cred->uid != 0) {
  •             /* message from non-root user, ignore */
  •             continue;
  •         }

  •         if(n >= UEVENT_MSG_LEN) /* overflow -- discard */
  •             continue;

  •         msg[n] = '\0';
  •         msg[n+1] = '\0';

  •         struct uevent uevent;
  •         parse_event(msg, &uevent);
  •     }
  • }

  • int main(void)
  • {
  •     int fd = 0;
  •     
  •     fd = open_uevent_socket();
  •     if (fd < 0) {
  •         printf("error!\n");
  •         return -1;
  •     }
  •     
  •     handle_device_fd(fd);
  • }
  • 转载:http://blog.chinaunix.net/uid-2630593-id-3014731.html 如有侵权,敬请告知,谢谢
  • 本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
    打开APP,阅读全文并永久保存 查看更多类似文章
    猜你喜欢
    类似文章
    【热】打开小程序,算一算2024你的财运
    【转】android提权漏洞CVE
    进程间传递文件描述符 - UNIX
    【android学习笔记】init.rc中声明的守护进程启动的流程
    linux上的一个简单的多人聊天室
    Linux下send、sendto、sendmsg函数分析
    记一次传递文件句柄引发的血案 (续)
    更多类似文章 >>
    生活服务
    热点新闻
    分享 收藏 导长图 关注 下载文章
    绑定账号成功
    后续可登录账号畅享VIP特权!
    如果VIP功能使用有故障,
    可点击这里联系客服!

    联系客服