\x20\40\x20\40 HEX
HEX
Server: Apache
System: Linux web1.jenscom.net 4.18.0-553.111.1.el8_10.x86_64 #1 SMP Sun Mar 8 20:06:07 EDT 2026 x86_64
User: sps (1059)
PHP: 8.3.30
Disabled: NONE
Upload Files
File: //usr/src/file_protector-1.1-1523/common/transport_protocol.h
/**
@file
@brief    kernel and userspace transport protocol
@details  Copyright (c) 2017 Acronis International GmbH
@author   Mikhail Krivtsov (mikhail.krivtsov@acronis.com)
@since    $Id: $
*/

#pragma once

// Note: This file is shared between kernel and user space transport code.

// Note: Linux kernel build system defines '__KERNEL__'
#if defined __KERNEL__
#include <linux/types.h>	// bool, [u]int(8|16|32|64)_t, pid_t
#else
#include <stdbool.h>		// bool
#include <stdint.h>		// [u]int(8|16|32|64)_t
#include <sys/types.h>		// pid_t
#endif

#if !defined PACKED
#define PACKED __attribute__((packed))
#endif

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

#define TRANSPORT_DEVICE_NAME "apl_transport"

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/*
    Each message is either a 'query' or a 'reply'. Each message contains
    an identifier ('id') necessary to match 'reply' to corresponding
    'query'. Zero 'id' in 'query' means that 'reply' is not necessary.
    'reply' with zero 'id' is not used.
*/

typedef uint64_t msg_id_t;

typedef enum {
	MT_HELLO = 0,
	// reserved 1
	MT_PONG = 2,
	// reserved till 9
	MT_EXEC = 9,
	MT_EXIT,
	MT_FORK,
	// file system events:
	MT_DIR_OPEN,
	MT_DIR_WRITE,
	MT_DIR_CLOSE,
	MT_FILE_PRE_CREATE,
	MT_FILE_CREATE_EX,
	MT_FILE_PRE_OPEN,
	// reserved 18
	MT_FILE_PRE_WRITE_EX = 19,
	// reserved 20-21
	MT_PRE_RENAME_EX = 22,
	MT_RENAME,
	MT_PRE_UNLINK_EX,
	MT_UNLINK,
	MT_FILE_PRE_CLOSE_EX,
	MT_FILE_PRE_READ_EX,
	MT_FILE_PRE_OPEN_EX,
	MT_RENAME_EX,
	MT_UNLINK_EX,
    MT_MAX,
} msg_type_t;

typedef enum {
	// reserved 0 as an error type
	AT_PING = 1,
	// reserved 2
	AT_PID_SET_ST = 3,
	AT_PID_DEL = 4,
	AT_GET_PID_INFO = 5,
	// reserved 6
	AT_GET_FS_ROOT = 7,
	// 8 was reserved but now used for 'AT_GET_VERSION'
	// as it would behave fine - it was not used by ioctl or write
	AT_GET_VERSION = 8,

	AT_OPEN_FILE_FROM_MSG,
	AT_OPEN_FILE_BY_PATH,
	AT_ENABLE_EVENTS,
	AT_DISABLE_EVENTS,
	AT_INIT_SHARED_DATA_QUEUE,
	AT_WAIT_SHARED_DATA_QUEUE,

	AT_EX_EVENTS_SUPPORTED,

	AT_LAST,
} action_type_t;

typedef enum {
	RT_ERROR = 0,
	// reserved till 6
	RT_PID_INFO = 6,
	// reserved 7
	RT_FS_ROOT = 8,
	RT_OPENED_FILE,
	RT_VERSION_INFO,
	RT_DATA_QUEUE_OFFSETS,
} return_type_t;

typedef uint8_t msg_type_img_t;

typedef struct PACKED {
	msg_id_t id;
	msg_type_img_t type;	// msg_type_t
	bool reply;
	uint8_t payload[0];
} msg_img_t;

inline static
msg_id_t msg_img_id(const msg_img_t *msg_img)
{
	return msg_img->id;
}

inline static
msg_type_img_t msg_img_type(const msg_img_t *msg_img)
{
	return msg_img->type;
}

inline static
bool msg_img_is_reply(const msg_img_t *msg_img)
{
	return msg_img->reply;
}

inline static
bool msg_img_is_reply_required(const msg_img_t *msg_img)
{
	return msg_img_id(msg_img) && !msg_img_is_reply(msg_img);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/*
    Generic 'reply' message
*/

// Note: Empty 'reply' may be used as shortcut for 'default' reply
/*
// Legacy 'reply_img_t'
typedef struct PACKED {
	uint8_t reply[0];
} reply_img_t;
*/

typedef enum {
	RT_ALLOW,
	RT_BLOCK,
} reply_type_t;
typedef uint8_t reply_type_img_t;

typedef struct PACKED {
	reply_type_img_t type;
	uint8_t payload[0];
} reply_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/*
    'hello' message is sent on 'first' user space connection.
*/

typedef struct PACKED {
	// TODO: add version information here
	uint8_t payload[0];
} hello_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/*
    'transport' testing

    'pong' message is 'high level' reply to 'ping' message. 'pong'
    message returns 'payload' from 'ping' message.

    'ping' and 'pong' messages can be sent in both 'synchronous' (i.e
    with *_reply') and 'asynchronous' (i.e without *_reply') modes.

    'ping_reply' and 'pong_reply' are respective 'low level'
    confirmations for 'ping' and 'pong' messages. They do not return
    'payload'. Instead they return some arbitrary 'reply'.
*/

typedef uint64_t ping_pong_sequence_t;

typedef struct PACKED {
	ping_pong_sequence_t sequence;
	uint8_t payload[0];
} ping_img_t;

typedef struct PACKED {
	ping_pong_sequence_t sequence;
	uint8_t payload[0];
} pong_img_t;

typedef struct PACKED {
	uint8_t reply[0];
} ping_reply_img_t;

typedef struct PACKED {
	uint8_t reply[0];
} pong_reply_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/*
    task_info_map management
*/

typedef uint32_t pid_img_t;
typedef uint32_t uid_img_t;
typedef uint32_t gid_img_t;

// FIXME: rename 'task_status' to '([fs_]events|monitoring|watch)[ mode]'
typedef enum {
	TS_UNKNOWN,		// 0, initial default
	TS_IGNORE,		// active protection daemon and friends
	TS_WHITE,		// harmless
	TS_BLACK,		// harmful
	TS_GREY,		// FIXME: What is this for?
} task_status_t;

typedef struct PACKED {
	pid_img_t pid;		// pid_t
	task_status_t status;
} pid_set_st_img_t;

typedef struct PACKED {
	pid_img_t pid;		// pid_t
} pid_del_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// AT_GET_PID_INFO
typedef struct PACKED {
	pid_img_t pid;		// pid_t
} get_pid_info_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// RT_PID_INFO
typedef struct PACKED {
	pid_img_t pid;		// pid_t
	pid_img_t tid;		// pid_t
	char path[0];
} pid_info_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// AT_GET_FS_ROOT
typedef struct PACKED {
	pid_img_t pid;		// pid_t
} get_fs_root_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// RT_FS_ROOT
typedef struct PACKED {
	char fs_root[0];
} fs_root_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// AT_OPEN_FILE_FROM_MSG
typedef struct PACKED {
	// useful for 'rename*' message that may refer to 2 files
	int num;
} open_file_from_msg_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// AT_OPEN_FILE_BY_PATH
typedef struct PACKED {
	int flags;
	int mode;
	char path[0];
} open_file_by_path_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// RT_OPENED_FILE
typedef struct PACKED {
	int fd;
} opened_file_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

#define DRIVER_FEATURE_CLOSE_EVENT 0x1

// RT_VERSION_INFO
typedef struct PACKED {
	// Max Action allowed to be called in 'ioctl'/'write' calls
	// If AT_GET_VERSION errors out itself, 'max_action' should be AT_GET_VERSION
	uint8_t max_action;
	// Features exposed by the module that are outside of 'ioctl'/'write' scope
	uint64_t features;
} version_info_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// 'MT_EXEC' is the first event user might want to listen to
#define MT_FIRST_ACTIVITY_EVENT MT_EXEC

// Convert a given MT to the event mask. Only events past MT_EXEC can be selected.
#define MSG_TYPE_TO_EVENT_MASK(mt) (1 << ((mt) - MT_FIRST_ACTIVITY_EVENT))

// AT_ENABLE_EVENTS
// AT_DISABLE_EVENTS
typedef struct PACKED {
	// Mask of events as per 'MSG_TYPE_TO_EVENT_MASK'
	uint64_t events_mask;
} events_mask_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

typedef struct PACKED {
	pid_img_t pid;    // pid_t
	pid_img_t tid;    // pid_t
	pid_img_t ppid;   // pid_t
	pid_img_t ptid;   // pid_t
	int8_t sure;      // false if process is new for task_info_map
	char path[0];
} exec_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

typedef struct PACKED {
	pid_img_t pid;		// pid_t
	pid_img_t tid;		// pid_t
} exit_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

typedef struct PACKED {
	struct PACKED {
		pid_img_t pid;		// pid_t
		pid_img_t tid;		// pid_t
	} parent;
	struct PACKED {
		pid_img_t pid;		// pid_t
		pid_img_t tid;		// pid_t
	} child;
} fork_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/*
    File system events

    Note: File system events must be 'synchronous' to let userspace
    backup affected files prior to any actual modification by kernel.
*/

typedef struct PACKED {
	pid_img_t pid;		// pid_t
	pid_img_t tid;		// pid_t
	uid_img_t fsuid;
	gid_img_t fsgid;
	uint8_t payload[0];
} fs_event_img_t;

typedef uint64_t offset_img_t;	// Note: 'loff_t' is 'signed'
typedef uint64_t size_img_t;

// 'RW' message is for CREAT, OPEN, [PRE_]WRITE
// Note: 'offset' and 'count' are relevant for 'write' only
typedef struct PACKED {
	int64_t ret_val;
	uint32_t flags;
	offset_img_t offset;	// loff_t
	size_img_t count;	// size_t
	char path[0];
} fs_event_rw_img_t;

typedef struct PACKED {
	uint64_t ptr;
	uint64_t ino;
	uint64_t gen;
	uint64_t dev;
} file_key_t;

typedef struct PACKED {
	int64_t ret_val;
	uint32_t flags;
	offset_img_t offset;	// loff_t
	size_img_t count;	// size_t
	file_key_t key;
	char path[0];
} fs_event_rw_ex_img_t;

typedef struct PACKED {
	int64_t ret_val;
	uint32_t flags;
	// oldname = names[0]
	// newname = names[newname_offset]
	uint16_t newname_offset;
	char names[0];
} fs_event_rename_img_t;

typedef struct PACKED {
	int64_t ret_val;
	uint32_t flags;
	file_key_t source_key;
	file_key_t target_key;
	// oldname = names[0]
	// newname = names[newname_offset]
	uint16_t newname_offset;
	uint8_t target_exists;
	char names[0];
} fs_event_rename_ex_img_t;

typedef struct PACKED {
	int64_t ret_val;
	uint32_t flag;
	char path[0];
} fs_event_unlink_img_t;

typedef struct PACKED {
	int64_t ret_val;
	uint32_t flag;
	file_key_t key;
	char path[0];
} fs_event_unlink_ex_img_t;

typedef struct PACKED {
	int64_t ret_val;
	uint32_t flags;
	offset_img_t offset;	// loff_t
	size_img_t count;	// size_t
	file_key_t key;
} fs_event_rw_key_img_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

typedef enum {
	IOCTL_READ_MSG = 1,
	IOCTL_WRITE_MSG = 2,
	IOCTL_WRITE_AND_READ_MSG = 3,
	IOCTL_READ_VERSION = 4,
} ioctl_cmd_t;

typedef uint16_t ioctl_size_img_t;

typedef struct PACKED {
	ioctl_size_img_t capacity; // payload capacity;
	ioctl_size_img_t size; // actual payload size;
	uint8_t payload[0];
} ioctl_hdr_t;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Shared Data queue protocol

// Entry description in the mmap'd buffer
typedef struct {
	uint32_t size;
	uint8_t data[0];
} data_queue_entry_t;

// Params passed to the data_queue init
// AT_INIT_SHARED_DATA_QUEUE
typedef struct PACKED {
	uint32_t size;
} data_queue_params_t;

// Those offsets correspond to values in the 'mmap' buffer
//
/*
struct shared_data_queue {
	uint32_t size ____cacheline_aligned_in_smp;
	uint32_t head ____cacheline_aligned_in_smp;
	uint32_t tail ____cacheline_aligned_in_smp;
	struct data_queue_entry entries[0] ____cacheline_aligned_in_smp;
};
*/
// RT_DATA_QUEUE_OFFSETS
typedef struct {
	uint32_t size; // as size of the whole 'queue'
	uint32_t headOff;
	uint32_t tailOff;
	uint32_t entriesOff;
} data_queue_offsets_t;