2014-10-31 10:00:29 +00:00
|
|
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
|
|
|
|
2014-12-10 22:51:43 +00:00
|
|
|
#include <boost/algorithm/string/split.hpp>
|
|
|
|
#include <boost/algorithm/string/trim.hpp>
|
2014-10-31 10:00:29 +00:00
|
|
|
|
2014-12-03 23:14:02 +00:00
|
|
|
#include <osquery/core.h>
|
|
|
|
#include <osquery/logger.h>
|
|
|
|
#include <osquery/tables.h>
|
2014-10-31 10:00:29 +00:00
|
|
|
|
2014-12-10 22:51:43 +00:00
|
|
|
#include "osquery/events/linux/udev.h"
|
|
|
|
|
2014-10-31 10:00:29 +00:00
|
|
|
namespace osquery {
|
2014-11-01 04:12:25 +00:00
|
|
|
namespace tables {
|
2014-10-31 10:00:29 +00:00
|
|
|
|
2014-12-10 22:51:43 +00:00
|
|
|
const std::string kPCIKeySlot = "PCI_SLOT_NAME";
|
|
|
|
const std::string kPCIKeyClass = "ID_PCI_CLASS_FROM_DATABASE";
|
|
|
|
const std::string kPCIKeyVendor = "ID_VENDOR_FROM_DATABASE";
|
|
|
|
const std::string kPCIKeyModel = "ID_MODEL_FROM_DATABASE";
|
|
|
|
const std::string kPCIKeyID = "PCI_ID";
|
|
|
|
const std::string kPCIKeyDriver = "DRIVER";
|
2014-10-31 10:00:29 +00:00
|
|
|
|
2014-11-30 05:55:14 +00:00
|
|
|
QueryData genPCIDevices(QueryContext &context) {
|
2014-11-01 04:12:25 +00:00
|
|
|
QueryData results;
|
2014-10-31 10:00:29 +00:00
|
|
|
|
2014-12-10 22:51:43 +00:00
|
|
|
auto udev_handle = udev_new();
|
|
|
|
if (udev_handle == nullptr) {
|
|
|
|
VLOG(1) << "Could not get udev handle.";
|
2014-11-01 04:12:25 +00:00
|
|
|
return results;
|
|
|
|
}
|
2014-10-31 10:00:29 +00:00
|
|
|
|
2014-12-10 22:51:43 +00:00
|
|
|
// Perform enumeration/search.
|
|
|
|
auto enumerate = udev_enumerate_new(udev_handle);
|
2014-11-01 04:12:25 +00:00
|
|
|
udev_enumerate_add_match_subsystem(enumerate, "pci");
|
|
|
|
udev_enumerate_scan_devices(enumerate);
|
2014-10-31 10:00:29 +00:00
|
|
|
|
2014-12-10 22:51:43 +00:00
|
|
|
// Get list entries and iterate over entries.
|
|
|
|
struct udev_list_entry *device_entries, *entry;
|
|
|
|
device_entries = udev_enumerate_get_list_entry(enumerate);
|
2014-10-31 10:00:29 +00:00
|
|
|
|
2014-12-10 22:51:43 +00:00
|
|
|
udev_list_entry_foreach(entry, device_entries) {
|
|
|
|
const char *path = udev_list_entry_get_name(entry);
|
|
|
|
auto device = udev_device_new_from_syspath(udev_handle, path);
|
2014-10-31 10:00:29 +00:00
|
|
|
|
2014-11-01 04:12:25 +00:00
|
|
|
Row r;
|
2014-12-10 22:51:43 +00:00
|
|
|
r["pci_slot"] = UdevEventPublisher::getValue(device, kPCIKeySlot);
|
|
|
|
r["pci_class"] = UdevEventPublisher::getValue(device, kPCIKeyClass);
|
|
|
|
r["driver"] = UdevEventPublisher::getValue(device, kPCIKeyDriver);
|
|
|
|
r["vendor"] = UdevEventPublisher::getValue(device, kPCIKeyVendor);
|
|
|
|
r["model"] = UdevEventPublisher::getValue(device, kPCIKeyModel);
|
|
|
|
|
|
|
|
// VENDOR:MODEL ID is in the form of HHHH:HHHH.
|
|
|
|
std::vector<std::string> ids;
|
|
|
|
auto device_id = UdevEventPublisher::getValue(device, kPCIKeyID);
|
|
|
|
boost::split(ids, device_id, boost::is_any_of(":"));
|
|
|
|
if (ids.size() == 2) {
|
|
|
|
r["vendor_id"] = ids[0];
|
|
|
|
r["model_id"] = ids[1];
|
2014-11-03 22:13:49 +00:00
|
|
|
}
|
2014-12-10 22:51:43 +00:00
|
|
|
|
|
|
|
// Set invalid vendor/model IDs to 0.
|
|
|
|
if (r["vendor_id"].size() == 0) {
|
|
|
|
r["vendor_id"] = "0";
|
2014-11-03 22:13:49 +00:00
|
|
|
}
|
2014-12-10 22:51:43 +00:00
|
|
|
|
|
|
|
if (r["model_id"].size() == 0) {
|
|
|
|
r["model_id"] = "0";
|
2014-11-03 22:13:49 +00:00
|
|
|
}
|
2014-12-10 22:51:43 +00:00
|
|
|
|
2014-11-01 04:12:25 +00:00
|
|
|
results.push_back(r);
|
2014-12-10 22:51:43 +00:00
|
|
|
udev_device_unref(device);
|
2014-11-01 04:12:25 +00:00
|
|
|
}
|
2014-12-10 22:51:43 +00:00
|
|
|
|
|
|
|
// Drop references to udev structs.
|
2014-11-03 22:48:42 +00:00
|
|
|
udev_enumerate_unref(enumerate);
|
2014-12-10 22:51:43 +00:00
|
|
|
udev_unref(udev_handle);
|
|
|
|
|
2014-11-01 04:12:25 +00:00
|
|
|
return results;
|
|
|
|
}
|
|
|
|
}
|
2014-10-31 10:00:29 +00:00
|
|
|
}
|