1. 和内核交互netlink
  • netlink

  • 内核和用户进程交互
  • 用户空间用的是socket,内核空间用的是内部API和一个模块。
  • 向下兼容。
  • 面向数据包的应用。即SOCK_RAW and SOCK_DGRAM
  • 函数原型

#include <asm/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>

netlink_socket = socket(AF_NETLINK, socket_type, netlink_family);
  • socket_type

    • SOCK_RAW and SOCK_DGRAM
    • 对于netlink都是一样的。
  • netlink_family 选择内核模块或者说netlink

    • NETLINK_ROUTE
    接收路由信息,更新链接信息,更新路由表,网络邻居,排队规则,拥塞等等。
    • NETLINK_SELINUX
    linux事件通知
    • NETLINK_AUDIT
    审计模块,用于检测统计内核的操作,比如杀死进程,退出等。aditctl
    • NETLINK_CONNECTOR

    内核链接器5.2版本及以前
  • netlink包协议栈

  • 一个或多个头部struct nlmsghdr
  
  
> ```
> struct nlmsghdr {
>     __u32 nlmsg_len;    /* Length of message including header */
>     __u16 nlmsg_type;   /* Type of message content */
>     __u16 nlmsg_flags;  /* Additional flags */
>     __u32 nlmsg_seq;    /* Sequence number */
>     __u32 nlmsg_pid;    /* Sender port ID */
> };
> 
> ```
> 
> 
> - 多个头部则`nlmsg_flags`是`NLM_F_MULTI`,最后一个是`NLMSG_DONE`
> - `nlmsg_type`标准的信息类型
>       
>         
>         
>       > - 没怎么用
> - `nlmsg_flags`
>       
>         
>         
>       > - `NLM_F_REQUEST`请求信息
>       > - `NLM_F_MULTI`分片中的其中一个包
  • proc_event

  • 用于what区分,what的值决定了后面的类型。
  • 共享体先用一个数组进行占位,最大容量。
  • 根据不同的类型也不同。
  • linux中有很多这样通过变量+共享体的方式进行存储数据。
  
  
> - `TCP/IP`协议栈。
> - `signal`的回调。

======================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

  1. 检测audit
支持指令和函数,没有仔细了解。
  1. 参考资料
  • 博客
  • netlink
  • 文件系统
  • ibm
  • stackoverflow
/* SPDX-License-Identifier: LGPL-2.1 WITH Linux-syscall-note */
/*
 * cn_proc.h - process events connector
 *
 * Copyright (C) Matt Helsley, IBM Corp. 2005
 * Based on cn_fork.h by Nguyen Anh Quynh and Guillaume Thouvenin
 * Copyright (C) 2005 Nguyen Anh Quynh <[email protected]>
 * Copyright (C) 2005 Guillaume Thouvenin <[email protected]>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2.1 of the GNU Lesser General Public License
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifndef _UAPICN_PROC_H
#define _UAPICN_PROC_H

#include <linux/types.h>

/*
 * Userspace sends this enum to register with the kernel that it is listening
 * for events on the connector.
 */
enum proc_cn_mcast_op {
    PROC_CN_MCAST_LISTEN = 1,
    PROC_CN_MCAST_IGNORE = 2
};

/*
 * From the user's point of view, the process
 * ID is the thread group ID and thread ID is the internal
 * kernel "pid". So, fields are assigned as follow:
 *
 *  In user space     -  In  kernel space
 *
 * parent process ID  =  parent->tgid
 * parent thread  ID  =  parent->pid
 * child  process ID  =  child->tgid
 * child  thread  ID  =  child->pid
 */

struct proc_event {
    enum what {
        /* Use successive bits so the enums can be used to record
         * sets of events as well
         */
        PROC_EVENT_NONE = 0x00000000,
        PROC_EVENT_FORK = 0x00000001,
        PROC_EVENT_EXEC = 0x00000002,
        PROC_EVENT_UID  = 0x00000004,
        PROC_EVENT_GID  = 0x00000040,
        PROC_EVENT_SID  = 0x00000080,
        PROC_EVENT_PTRACE = 0x00000100,
        PROC_EVENT_COMM = 0x00000200,
        /* "next" should be 0x00000400 */
        /* "last" is the last process event: exit,
         * while "next to last" is coredumping event */
        PROC_EVENT_COREDUMP = 0x40000000,
        PROC_EVENT_EXIT = 0x80000000
    } what;
    __u32 cpu;
    __u64 __attribute__((aligned(8))) timestamp_ns;
        /* Number of nano seconds since system boot */
    union { /* must be last field of proc_event struct */
        struct {
            __u32 err;
        } ack;

        struct fork_proc_event {
            __kernel_pid_t parent_pid;
            __kernel_pid_t parent_tgid;
            __kernel_pid_t child_pid;
            __kernel_pid_t child_tgid;
        } fork;

        struct exec_proc_event {
            __kernel_pid_t process_pid;
            __kernel_pid_t process_tgid;
        } exec;

        struct id_proc_event {
            __kernel_pid_t process_pid;
            __kernel_pid_t process_tgid;
            union {
                __u32 ruid; /* task uid */
                __u32 rgid; /* task gid */
            } r;
            union {
                __u32 euid;
                __u32 egid;
            } e;
        } id;

        struct sid_proc_event {
            __kernel_pid_t process_pid;
            __kernel_pid_t process_tgid;
        } sid;

        struct ptrace_proc_event {
            __kernel_pid_t process_pid;
            __kernel_pid_t process_tgid;
            __kernel_pid_t tracer_pid;
            __kernel_pid_t tracer_tgid;
        } ptrace;

        struct comm_proc_event {
            __kernel_pid_t process_pid;
            __kernel_pid_t process_tgid;
            char           comm[16];
        } comm;

        struct coredump_proc_event {
            __kernel_pid_t process_pid;
            __kernel_pid_t process_tgid;
            __kernel_pid_t parent_pid;
            __kernel_pid_t parent_tgid;
        } coredump;

        struct exit_proc_event {
            __kernel_pid_t process_pid;
            __kernel_pid_t process_tgid;
            __u32 exit_code, exit_signal;
            __kernel_pid_t parent_pid;
            __kernel_pid_t parent_tgid;
        } exit;

    } event_data;
};

#endif /* _UAPICN_PROC_H */
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _UAPI__LINUX_NETLINK_H
#define _UAPI__LINUX_NETLINK_H

#include <linux/kernel.h>
#include <linux/socket.h> /* for __kernel_sa_family_t */
#include <linux/types.h>

#define NETLINK_ROUTE        0    /* Routing/device hook                */
#define NETLINK_UNUSED        1    /* Unused number                */
#define NETLINK_USERSOCK    2    /* Reserved for user mode socket protocols     */
#define NETLINK_FIREWALL    3    /* Unused number, formerly ip_queue        */
#define NETLINK_SOCK_DIAG    4    /* socket monitoring                */
#define NETLINK_NFLOG        5    /* netfilter/iptables ULOG */
#define NETLINK_XFRM        6    /* ipsec */
#define NETLINK_SELINUX        7    /* SELinux event notifications */
#define NETLINK_ISCSI        8    /* Open-iSCSI */
#define NETLINK_AUDIT        9    /* auditing */
#define NETLINK_FIB_LOOKUP    10    
#define NETLINK_CONNECTOR    11
#define NETLINK_NETFILTER    12    /* netfilter subsystem */
#define NETLINK_IP6_FW        13
#define NETLINK_DNRTMSG        14    /* DECnet routing messages */
#define NETLINK_KOBJECT_UEVENT    15    /* Kernel messages to userspace */
#define NETLINK_GENERIC        16
/* leave room for NETLINK_DM (DM Events) */
#define NETLINK_SCSITRANSPORT    18    /* SCSI Transports */
#define NETLINK_ECRYPTFS    19
#define NETLINK_RDMA        20
#define NETLINK_CRYPTO        21    /* Crypto layer */
#define NETLINK_SMC        22    /* SMC monitoring */

#define NETLINK_INET_DIAG    NETLINK_SOCK_DIAG

#define MAX_LINKS 32        

struct sockaddr_nl {
    __kernel_sa_family_t    nl_family;    /* AF_NETLINK    */
    unsigned short    nl_pad;        /* zero        */
    __u32        nl_pid;        /* port ID    */
           __u32        nl_groups;    /* multicast groups mask */
};

struct nlmsghdr {
    __u32        nlmsg_len;    /* Length of message including header */
    __u16        nlmsg_type;    /* Message content */
    __u16        nlmsg_flags;    /* Additional flags */
    __u32        nlmsg_seq;    /* Sequence number */
    __u32        nlmsg_pid;    /* Sending process port ID */
};

/* Flags values */

#define NLM_F_REQUEST        0x01    /* It is request message.     */
#define NLM_F_MULTI        0x02    /* Multipart message, terminated by NLMSG_DONE */
#define NLM_F_ACK        0x04    /* Reply with ack, with zero or error code */
#define NLM_F_ECHO        0x08    /* Echo this request         */
#define NLM_F_DUMP_INTR        0x10    /* Dump was inconsistent due to sequence change */
#define NLM_F_DUMP_FILTERED    0x20    /* Dump was filtered as requested */

/* Modifiers to GET request */
#define NLM_F_ROOT    0x100    /* specify tree    root    */
#define NLM_F_MATCH    0x200    /* return all matching    */
#define NLM_F_ATOMIC    0x400    /* atomic GET        */
#define NLM_F_DUMP    (NLM_F_ROOT|NLM_F_MATCH)

/* Modifiers to NEW request */
#define NLM_F_REPLACE    0x100    /* Override existing        */
#define NLM_F_EXCL    0x200    /* Do not touch, if it exists    */
#define NLM_F_CREATE    0x400    /* Create, if it does not exist    */
#define NLM_F_APPEND    0x800    /* Add to end of list        */

/* Modifiers to DELETE request */
#define NLM_F_NONREC    0x100    /* Do not delete recursively    */

/* Flags for ACK message */
#define NLM_F_CAPPED    0x100    /* request was capped */
#define NLM_F_ACK_TLVS    0x200    /* extended ACK TVLs were included */

/*
   4.4BSD ADD        NLM_F_CREATE|NLM_F_EXCL
   4.4BSD CHANGE    NLM_F_REPLACE

   True CHANGE        NLM_F_CREATE|NLM_F_REPLACE
   Append        NLM_F_CREATE
   Check        NLM_F_EXCL
 */

#define NLMSG_ALIGNTO    4U
#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
#define NLMSG_HDRLEN     ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
#define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN)
#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
#define NLMSG_DATA(nlh)  ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
#define NLMSG_NEXT(nlh,len)     ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
                  (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
               (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
               (nlh)->nlmsg_len <= (len))
#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))

#define NLMSG_NOOP        0x1    /* Nothing.        */
#define NLMSG_ERROR        0x2    /* Error        */
#define NLMSG_DONE        0x3    /* End of a dump    */
#define NLMSG_OVERRUN        0x4    /* Data lost        */

#define NLMSG_MIN_TYPE        0x10    /* < 0x10: reserved control messages */

struct nlmsgerr {
    int        error;
    struct nlmsghdr msg;
    /*
     * followed by the message contents unless NETLINK_CAP_ACK was set
     * or the ACK indicates success (error == 0)
     * message length is aligned with NLMSG_ALIGN()
     */
    /*
     * followed by TLVs defined in enum nlmsgerr_attrs
     * if NETLINK_EXT_ACK was set
     */
};

/**
 * enum nlmsgerr_attrs - nlmsgerr attributes
 * @NLMSGERR_ATTR_UNUSED: unused
 * @NLMSGERR_ATTR_MSG: error message string (string)
 * @NLMSGERR_ATTR_OFFS: offset of the invalid attribute in the original
 *     message, counting from the beginning of the header (u32)
 * @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to
 *    be used - in the success case - to identify a created
 *    object or operation or similar (binary)
 * @__NLMSGERR_ATTR_MAX: number of attributes
 * @NLMSGERR_ATTR_MAX: highest attribute number
 */
enum nlmsgerr_attrs {
    NLMSGERR_ATTR_UNUSED,
    NLMSGERR_ATTR_MSG,
    NLMSGERR_ATTR_OFFS,
    NLMSGERR_ATTR_COOKIE,

    __NLMSGERR_ATTR_MAX,
    NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1
};

#define NETLINK_ADD_MEMBERSHIP        1
#define NETLINK_DROP_MEMBERSHIP        2
#define NETLINK_PKTINFO            3
#define NETLINK_BROADCAST_ERROR        4
#define NETLINK_NO_ENOBUFS        5
#ifndef __KERNEL__
#define NETLINK_RX_RING            6
#define NETLINK_TX_RING            7
#endif
#define NETLINK_LISTEN_ALL_NSID        8
#define NETLINK_LIST_MEMBERSHIPS    9
#define NETLINK_CAP_ACK            10
#define NETLINK_EXT_ACK            11
#define NETLINK_GET_STRICT_CHK        12

struct nl_pktinfo {
    __u32    group;
};

struct nl_mmap_req {
    unsigned int    nm_block_size;
    unsigned int    nm_block_nr;
    unsigned int    nm_frame_size;
    unsigned int    nm_frame_nr;
};

struct nl_mmap_hdr {
    unsigned int    nm_status;
    unsigned int    nm_len;
    __u32        nm_group;
    /* credentials */
    __u32        nm_pid;
    __u32        nm_uid;
    __u32        nm_gid;
};

#ifndef __KERNEL__
enum nl_mmap_status {
    NL_MMAP_STATUS_UNUSED,
    NL_MMAP_STATUS_RESERVED,
    NL_MMAP_STATUS_VALID,
    NL_MMAP_STATUS_COPY,
    NL_MMAP_STATUS_SKIP,
};

#define NL_MMAP_MSG_ALIGNMENT        NLMSG_ALIGNTO
#define NL_MMAP_MSG_ALIGN(sz)        __ALIGN_KERNEL(sz, NL_MMAP_MSG_ALIGNMENT)
#define NL_MMAP_HDRLEN            NL_MMAP_MSG_ALIGN(sizeof(struct nl_mmap_hdr))
#endif

#define NET_MAJOR 36        /* Major 36 is reserved for networking                         */

enum {
    NETLINK_UNCONNECTED = 0,
    NETLINK_CONNECTED,
};

/*
 *  <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
 * +---------------------+- - -+- - - - - - - - - -+- - -+
 * |        Header       | Pad |     Payload       | Pad |
 * |   (struct nlattr)   | ing |                   | ing |
 * +---------------------+- - -+- - - - - - - - - -+- - -+
 *  <-------------- nlattr->nla_len -------------->
 */

struct nlattr {
    __u16           nla_len;
    __u16           nla_type;
};

/*
 * nla_type (16 bits)
 * +---+---+-------------------------------+
 * | N | O | Attribute Type                |
 * +---+---+-------------------------------+
 * N := Carries nested attributes
 * O := Payload stored in network byte order
 *
 * Note: The N and O flag are mutually exclusive.
 */
#define NLA_F_NESTED        (1 << 15)
#define NLA_F_NET_BYTEORDER    (1 << 14)
#define NLA_TYPE_MASK        ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER)

#define NLA_ALIGNTO        4
#define NLA_ALIGN(len)        (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
#define NLA_HDRLEN        ((int) NLA_ALIGN(sizeof(struct nlattr)))

/* Generic 32 bitflags attribute content sent to the kernel.
 *
 * The value is a bitmap that defines the values being set
 * The selector is a bitmask that defines which value is legit
 *
 * Examples:
 *  value = 0x0, and selector = 0x1
 *  implies we are selecting bit 1 and we want to set its value to 0.
 *
 *  value = 0x2, and selector = 0x2
 *  implies we are selecting bit 2 and we want to set its value to 1.
 *
 */
struct nla_bitfield32 {
    __u32 value;
    __u32 selector;
};

#endif /* _UAPI__LINUX_NETLINK_H */
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
 *     connector.h
 * 
 * 2004-2005 Copyright (c) Evgeniy Polyakov <[email protected]>
 * All rights reserved.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _UAPI__CONNECTOR_H
#define _UAPI__CONNECTOR_H

#include <linux/types.h>

/*
 * Process Events connector unique ids -- used for message routing
 */
#define CN_IDX_PROC            0x1
#define CN_VAL_PROC            0x1
#define CN_IDX_CIFS            0x2
#define CN_VAL_CIFS                     0x1
#define CN_W1_IDX            0x3    /* w1 communication */
#define CN_W1_VAL            0x1
#define CN_IDX_V86D            0x4
#define CN_VAL_V86D_UVESAFB        0x1
#define CN_IDX_BB            0x5    /* BlackBoard, from the TSP GPL sampling framework */
#define CN_DST_IDX            0x6
#define CN_DST_VAL            0x1
#define CN_IDX_DM            0x7    /* Device Mapper */
#define CN_VAL_DM_USERSPACE_LOG        0x1
#define CN_IDX_DRBD            0x8
#define CN_VAL_DRBD            0x1
#define CN_KVP_IDX            0x9    /* HyperV KVP */
#define CN_KVP_VAL            0x1    /* queries from the kernel */
#define CN_VSS_IDX            0xA     /* HyperV VSS */
#define CN_VSS_VAL            0x1     /* queries from the kernel */


#define CN_NETLINK_USERS        11    /* Highest index + 1 */

/*
 * Maximum connector's message size.
 */
#define CONNECTOR_MAX_MSG_SIZE        16384

/*
 * idx and val are unique identifiers which 
 * are used for message routing and 
 * must be registered in connector.h for in-kernel usage.
 */

struct cb_id {
    __u32 idx;
    __u32 val;
};

struct cn_msg {
    struct cb_id id;

    __u32 seq;
    __u32 ack;

    __u16 len;        /* Length of the following data */
    __u16 flags;
    __u8 data[0];
};

#endif /* _UAPI__CONNECTOR_H */
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/connector.h>
#include <linux/cn_proc.h>
#include <signal.h>
#include <errno.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <utmp.h>

enum
{
        PROC_EVENT_NONE = 0x00000000,
        PROC_EVENT_FORK = 0x00000001,
        PROC_EVENT_EXEC = 0x00000002,
        PROC_EVENT_UID  = 0x00000004,
        PROC_EVENT_GID  = 0x00000040,
        PROC_EVENT_SID  = 0x00000080,
        PROC_EVENT_PTRACE = 0x00000100,
        PROC_EVENT_COMM = 0x00000200,
        /* "next" should be 0x00000400 */
        /* "last" is the last process event: exit,
 *          * while "next to last" is coredumping event */
        PROC_EVENT_COREDUMP = 0x40000000,
        PROC_EVENT_EXIT = 0x80000000
};

/*
 *  * connect to netlink
 *   * returns netlink socket, or -1 on error
 *    */
static int nl_connect()
{
    int rc;
    int nl_sock;
    struct sockaddr_nl sa_nl;

    nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
    if (nl_sock == -1) {
        perror("socket");
        return -1;
    }

    sa_nl.nl_family = AF_NETLINK;
    sa_nl.nl_groups = CN_IDX_PROC;
    sa_nl.nl_pid = getpid();

    rc = bind(nl_sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl));
    if (rc == -1) {
        perror("bind");
        close(nl_sock);
        return -1;
    }

    return nl_sock;
}

/*
 *  * subscribe on proc events (process notifications)
 *   */
static int set_proc_ev_listen(int nl_sock, bool enable)
{
    int rc;
    struct __attribute__ ((aligned(NLMSG_ALIGNTO))) {
        struct nlmsghdr nl_hdr;
        struct __attribute__ ((__packed__)) {
            struct cn_msg cn_msg;
            enum proc_cn_mcast_op cn_mcast;
        };
    } nlcn_msg;

    memset(&nlcn_msg, 0, sizeof(nlcn_msg));
    nlcn_msg.nl_hdr.nlmsg_len = sizeof(nlcn_msg);
    nlcn_msg.nl_hdr.nlmsg_pid = getpid();
    nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE;

    nlcn_msg.cn_msg.id.idx = CN_IDX_PROC;
    nlcn_msg.cn_msg.id.val = CN_VAL_PROC;
    nlcn_msg.cn_msg.len = sizeof(enum proc_cn_mcast_op);

    nlcn_msg.cn_mcast = enable ? PROC_CN_MCAST_LISTEN : PROC_CN_MCAST_IGNORE;

    rc = send(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0);
    if (rc == -1) {
        perror("netlink send");
        return -1;
    }

    return 0;
}
#define BUFSIZE 1024
static void getInfo(int);
static void getUserInfo(int pid)
{
    char cmd[BUFSIZE] = {0},buf[32]={0};
    int len = 0;
    bool t = false;
    struct utmp *tUser= NULL;
    sprintf(buf,"/proc/%d/fd/0",pid);
    if(-1 == readlink(buf,cmd,BUFSIZE))
    {
        printf("link error %d\n",pid);
        return ;
    }
    if( 0 == strncmp(cmd,"/dev/",5) )
    {
        sprintf(cmd,"%s",cmd+5);
    }
    while(NULL != (tUser = getutent()))
    {
        if(7 == tUser->ut_type && 0 != tUser->ut_user[0] && 0 == strcmp(tUser->ut_line,cmd))
        {
            t = true;
            printf("from tty=%s pid=%d IP=%s -- ",tUser->ut_line,pid,tUser->ut_host);
        }
    }
    endutent();
    if (!t)
    {
        printf("from main --  ");
    }
    getInfo(pid);
}

static void getInfo(int pid)
{
    FILE * fp = NULL;
    char cmd[BUFSIZE] = {0};
    int len = 0;
    sprintf(cmd,"/proc/%d/cmdline",pid);
    if ( NULL == (fp = fopen(cmd,"r")))
    {
        printf("%s open error\n",cmd);
        return ;
    }
    if( 0 > (len = fread(cmd,1,BUFSIZE,fp)))
    {
        printf("%d read error\n",pid);
        return;
    }
    for( int i = 0 ; i < len ; i ++)
    {
        if(cmd[i] == 0 || cmd[i] == '\n' || cmd[i] == '\r' || cmd[i] == '\t')
        {
            cmd[i] = ' ';
        }
    }
    cmd[len] = 0;
    printf("command %s \n",cmd);
}
#undef BUFSIZE
/*
 *  * handle a single process event
 *   */
static volatile bool need_exit = false;
static int handle_proc_ev(int nl_sock)
{
    int rc;
    struct __attribute__ ((aligned(NLMSG_ALIGNTO))) {
        struct nlmsghdr nl_hdr;
        struct __attribute__ ((__packed__)) {
            struct cn_msg cn_msg;
            struct proc_event proc_ev;
        };
    } nlcn_msg;

    while (!need_exit) {
        rc = recv(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0);
        if (rc == 0) {
            /* shutdown? */
            return 0;
        } else if (rc == -1) {
            if (errno == EINTR) continue;
            perror("netlink recv");
            return -1;
        }
        switch (nlcn_msg.proc_ev.what) {
            case PROC_EVENT_NONE:
                printf("set mcast listen ok\n");
                break;
            case PROC_EVENT_EXEC:
                printf("exec ");
                getUserInfo(nlcn_msg.proc_ev.event_data.exec.process_pid);
                break;
            case PROC_EVENT_EXIT:
                printf("exit ");
                getUserInfo(nlcn_msg.proc_ev.event_data.exit.process_pid);
                break;
            default:
                break;
        }
    }

    return 0;
}

static void on_sigint(int unused)
{
    need_exit = true;
}

int main(int argc, const char *argv[])
{
    int nl_sock;
    int rc = EXIT_SUCCESS;

    signal(SIGINT, &on_sigint);
    siginterrupt(SIGINT, true);

    nl_sock = nl_connect();
    if (nl_sock == -1)
        exit(EXIT_FAILURE);

    rc = set_proc_ev_listen(nl_sock, true);
    if (rc == -1) {
        rc = EXIT_FAILURE;
        goto out;
    }

    rc = handle_proc_ev(nl_sock);
    if (rc == -1) {
        rc = EXIT_FAILURE;
        goto out;
    }

    set_proc_ev_listen(nl_sock, false);

out:
    close(nl_sock);
    exit(rc);
}

标签: 内核, pid, define, struct, 交互, netlink, nl, NETLINK

相关文章推荐

添加新评论,含*的栏目为必填