日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

netlink怎么读_内核交互 netlink,检测部分进程死亡和启动。

發布時間:2023/12/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 netlink怎么读_内核交互 netlink,检测部分进程死亡和启动。 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

和內核交互netlink

netlink

內核和用戶進程交互

用戶空間用的是socket,內核空間用的是內部API和一個模塊。

向下兼容。

面向數據包的應用。即SOCK_RAW and SOCK_DGRAM

函數原型

#include

#include

#include

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的回調。

檢測audit

支持指令和函數,沒有仔細了解。

參考資料

博客

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

* Copyright (C) 2005 Guillaume Thouvenin

*

* 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

/*

* 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

#include /* for __kernel_sa_family_t */

#include

#define NETLINK_ROUTE0/* Routing/device hook*/

#define NETLINK_UNUSED1/* Unused number*/

#define NETLINK_USERSOCK2/* Reserved for user mode socket protocols */

#define NETLINK_FIREWALL3/* Unused number, formerly ip_queue*/

#define NETLINK_SOCK_DIAG4/* socket monitoring*/

#define NETLINK_NFLOG5/* netfilter/iptables ULOG */

#define NETLINK_XFRM6/* ipsec */

#define NETLINK_SELINUX7/* SELinux event notifications */

#define NETLINK_ISCSI8/* Open-iSCSI */

#define NETLINK_AUDIT9/* auditing */

#define NETLINK_FIB_LOOKUP10

#define NETLINK_CONNECTOR11

#define NETLINK_NETFILTER12/* netfilter subsystem */

#define NETLINK_IP6_FW13

#define NETLINK_DNRTMSG14/* DECnet routing messages */

#define NETLINK_KOBJECT_UEVENT15/* Kernel messages to userspace */

#define NETLINK_GENERIC16

/* leave room for NETLINK_DM (DM Events) */

#define NETLINK_SCSITRANSPORT18/* SCSI Transports */

#define NETLINK_ECRYPTFS19

#define NETLINK_RDMA20

#define NETLINK_CRYPTO21/* Crypto layer */

#define NETLINK_SMC22/* SMC monitoring */

#define NETLINK_INET_DIAGNETLINK_SOCK_DIAG

#define MAX_LINKS 32

struct sockaddr_nl {

__kernel_sa_family_tnl_family;/* AF_NETLINK*/

unsigned shortnl_pad;/* zero*/

__u32nl_pid;/* port ID*/

__u32nl_groups;/* multicast groups mask */

};

struct nlmsghdr {

__u32nlmsg_len;/* Length of message including header */

__u16nlmsg_type;/* Message content */

__u16nlmsg_flags;/* Additional flags */

__u32nlmsg_seq;/* Sequence number */

__u32nlmsg_pid;/* Sending process port ID */

};

/* Flags values */

#define NLM_F_REQUEST0x01/* It is request message. */

#define NLM_F_MULTI0x02/* Multipart message, terminated by NLMSG_DONE */

#define NLM_F_ACK0x04/* Reply with ack, with zero or error code */

#define NLM_F_ECHO0x08/* Echo this request */

#define NLM_F_DUMP_INTR0x10/* Dump was inconsistent due to sequence change */

#define NLM_F_DUMP_FILTERED0x20/* Dump was filtered as requested */

/* Modifiers to GET request */

#define NLM_F_ROOT0x100/* specify treeroot*/

#define NLM_F_MATCH0x200/* return all matching*/

#define NLM_F_ATOMIC0x400/* atomic GET*/

#define NLM_F_DUMP(NLM_F_ROOT|NLM_F_MATCH)

/* Modifiers to NEW request */

#define NLM_F_REPLACE0x100/* Override existing*/

#define NLM_F_EXCL0x200/* Do not touch, if it exists*/

#define NLM_F_CREATE0x400/* Create, if it does not exist*/

#define NLM_F_APPEND0x800/* Add to end of list*/

/* Modifiers to DELETE request */

#define NLM_F_NONREC0x100/* Do not delete recursively*/

/* Flags for ACK message */

#define NLM_F_CAPPED0x100/* request was capped */

#define NLM_F_ACK_TLVS0x200/* extended ACK TVLs were included */

/*

4.4BSD ADDNLM_F_CREATE|NLM_F_EXCL

4.4BSD CHANGENLM_F_REPLACE

True CHANGENLM_F_CREATE|NLM_F_REPLACE

AppendNLM_F_CREATE

CheckNLM_F_EXCL

*/

#define NLMSG_ALIGNTO4U

#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_NOOP0x1/* Nothing.*/

#define NLMSG_ERROR0x2/* Error*/

#define NLMSG_DONE0x3/* End of a dump*/

#define NLMSG_OVERRUN0x4/* Data lost*/

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

struct nlmsgerr {

interror;

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_MEMBERSHIP1

#define NETLINK_DROP_MEMBERSHIP2

#define NETLINK_PKTINFO3

#define NETLINK_BROADCAST_ERROR4

#define NETLINK_NO_ENOBUFS5

#ifndef __KERNEL__

#define NETLINK_RX_RING6

#define NETLINK_TX_RING7

#endif

#define NETLINK_LISTEN_ALL_NSID8

#define NETLINK_LIST_MEMBERSHIPS9

#define NETLINK_CAP_ACK10

#define NETLINK_EXT_ACK11

#define NETLINK_GET_STRICT_CHK12

struct nl_pktinfo {

__u32group;

};

struct nl_mmap_req {

unsigned intnm_block_size;

unsigned intnm_block_nr;

unsigned intnm_frame_size;

unsigned intnm_frame_nr;

};

struct nl_mmap_hdr {

unsigned intnm_status;

unsigned intnm_len;

__u32nm_group;

/* credentials */

__u32nm_pid;

__u32nm_uid;

__u32nm_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_ALIGNMENTNLMSG_ALIGNTO

#define NL_MMAP_MSG_ALIGN(sz)__ALIGN_KERNEL(sz, NL_MMAP_MSG_ALIGNMENT)

#define NL_MMAP_HDRLENNL_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,

};

/*

*

* +---------------------+- - -+- - - - - - - - - -+- - -+

* | Header | Pad | Payload | Pad |

* | (struct nlattr) | ing | | ing |

* +---------------------+- - -+- - - - - - - - - -+- - -+

* 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_ALIGNTO4

#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

* 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

/*

* Process Events connector unique ids -- used for message routing

*/

#define CN_IDX_PROC0x1

#define CN_VAL_PROC0x1

#define CN_IDX_CIFS0x2

#define CN_VAL_CIFS 0x1

#define CN_W1_IDX0x3/* w1 communication */

#define CN_W1_VAL0x1

#define CN_IDX_V86D0x4

#define CN_VAL_V86D_UVESAFB0x1

#define CN_IDX_BB0x5/* BlackBoard, from the TSP GPL sampling framework */

#define CN_DST_IDX0x6

#define CN_DST_VAL0x1

#define CN_IDX_DM0x7/* Device Mapper */

#define CN_VAL_DM_USERSPACE_LOG0x1

#define CN_IDX_DRBD0x8

#define CN_VAL_DRBD0x1

#define CN_KVP_IDX0x9/* HyperV KVP */

#define CN_KVP_VAL0x1/* queries from the kernel */

#define CN_VSS_IDX0xA /* HyperV VSS */

#define CN_VSS_VAL0x1 /* queries from the kernel */

#define CN_NETLINK_USERS11/* Highest index + 1 */

/*

* Maximum connector's message size.

*/

#define CONNECTOR_MAX_MSG_SIZE16384

/*

* 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

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

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);

}

標簽:__,netlink,nl,struct,pid,NETLINK,內核,交互,define

來源: https://www.cnblogs.com/98kkkkkkkkkk/p/13324218.html

總結

以上是生活随笔為你收集整理的netlink怎么读_内核交互 netlink,检测部分进程死亡和启动。的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。