CQueue::CQueue(size_t size) { buffer_ = NULL; size_ = 0; max_read_ = NULL; read_ = NULL; fd_ = -1; const char *filename = "/dev/osquery"; osquery_buf_allocate_args_t alloc; alloc.size = size; alloc.buffer = NULL; fd_ = open(filename, O_RDWR); if (fd_ < 0) { throw CQueueException("Could not open character device."); } if (ioctl(fd_, OSQUERY_IOCTL_BUF_ALLOCATE, &alloc)) { throw CQueueException("Could not allocate shared buffer."); } buffer_ = (uint8_t *)alloc.buffer; size_ = size; read_ = (uint8_t *)alloc.buffer; max_read_ = (uint8_t *)alloc.buffer; }
CQueue::CQueue(const std::string &device, size_t size) { buffer_ = nullptr; size_ = 0; max_read_ = nullptr; read_ = nullptr; fd_ = -1; osquery_buf_allocate_args_t alloc; alloc.size = size; alloc.buffer = nullptr; alloc.version = OSQUERY_KERNEL_COMM_VERSION; fd_ = open(device.c_str(), O_RDWR); if (fd_ < 0) { throw CQueueException("Could not open character device"); } if (ioctl(fd_, OSQUERY_IOCTL_BUF_ALLOCATE, &alloc)) { throw CQueueException("Could not allocate shared buffer"); } buffer_ = (uint8_t *)alloc.buffer; size_ = size; read_ = (uint8_t *)alloc.buffer; max_read_ = (uint8_t *)alloc.buffer; }
void CQueue::subscribe(osquery_event_t event) { osquery_subscription_args_t sub; sub.event = event; sub.subscribe = 1; if (ioctl(fd_, OSQUERY_IOCTL_SUBSCRIPTION, &sub)) { throw CQueueException("Could not subscribe to event"); } }
// return positive idicates drop, 0 is all good in the hood. // options are listed in kernel feeds. primarily OSQUERY_NO_BLOCK. int CQueue::kernelSync(int options) { osquery_buf_sync_args_t sync; sync.read_offset = read_ - buffer_; sync.options = options; int err = 0; if ((err = ioctl(fd_, OSQUERY_IOCTL_BUF_SYNC, &sync))) { throw CQueueException("Could not sync buffer with kernel properly."); } uint8_t *new_max_read = sync.max_read_offset + buffer_; max_read_ = new_max_read; if (err) { read_ = max_read_; } return sync.drops; }
int CQueue::kernelSync(int options) { // A positive return indicates drops, 0 is all good in the hood. // Options are listed in kernel feeds; primarily OSQUERY_NO_BLOCK. osquery_buf_sync_args_t sync; sync.read_offset = read_ - buffer_; sync.options = options; int err = 0; err = ioctl(fd_, OSQUERY_IOCTL_BUF_SYNC, &sync); uint8_t *new_max_read = sync.max_read_offset + buffer_; max_read_ = new_max_read; if (err) { read_ = max_read_; throw CQueueException("Could not sync buffer with kernel properly"); } return sync.drops; }