mirror of
https://github.com/rzuasti/oott.git
synced 2026-07-08 19:21:54 +02:00
Added insertion and deletion of found devices to database
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
[env]
|
[env]
|
||||||
RUST_LOG="debug"
|
RUST_LOG="info"
|
||||||
OOTT_ARP_SENDER_TIMEOUT="30"
|
OOTT_ARP_SENDER_TIMEOUT="30"
|
||||||
OOTT_ARP_SCAN_DURATION="60"
|
OOTT_ARP_SCAN_DURATION="60"
|
||||||
|
|||||||
Generated
+122
@@ -11,6 +11,15 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstream"
|
name = "anstream"
|
||||||
version = "0.6.21"
|
version = "0.6.21"
|
||||||
@@ -61,6 +70,12 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.10.0"
|
version = "2.10.0"
|
||||||
@@ -95,12 +110,31 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.43"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118"
|
||||||
|
dependencies = [
|
||||||
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
|
"num-traits",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colorchoice"
|
name = "colorchoice"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_filter"
|
name = "env_filter"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
@@ -182,6 +216,30 @@ dependencies = [
|
|||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.64"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "include_dir"
|
name = "include_dir"
|
||||||
version = "0.7.4"
|
version = "0.7.4"
|
||||||
@@ -311,6 +369,15 @@ version = "0.6.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65"
|
checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.3"
|
version = "1.21.3"
|
||||||
@@ -327,6 +394,7 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
|||||||
name = "oott"
|
name = "oott"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"include_dir",
|
"include_dir",
|
||||||
"log",
|
"log",
|
||||||
@@ -552,6 +620,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "f1c93dd1c9683b438c392c492109cb702b8090b2bfc8fed6f6e4eb4523f17af3"
|
checksum = "f1c93dd1c9683b438c392c492109cb702b8090b2bfc8fed6f6e4eb4523f17af3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
"chrono",
|
||||||
"fallible-iterator",
|
"fallible-iterator",
|
||||||
"fallible-streaming-iterator",
|
"fallible-streaming-iterator",
|
||||||
"hashlink",
|
"hashlink",
|
||||||
@@ -820,12 +889,65 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.62.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-link",
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.60.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.59.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-link"
|
name = "windows-link"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.60.2"
|
version = "0.60.2"
|
||||||
|
|||||||
+2
-1
@@ -10,6 +10,7 @@ pnet = "0.35.0"
|
|||||||
tokio = { version = "1.0", features = ["full"] }
|
tokio = { version = "1.0", features = ["full"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
rusqlite = { version = "0.38.0", features = ["bundled"] }
|
rusqlite = { version = "0.38.0", features = ["bundled", "chrono"] }
|
||||||
rusqlite_migration = { version = "2.4.0", features = ["from-directory"] }
|
rusqlite_migration = { version = "2.4.0", features = ["from-directory"] }
|
||||||
include_dir = "0.7.4"
|
include_dir = "0.7.4"
|
||||||
|
chrono = "0.4.43"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
CREATE TABLE devices(
|
CREATE TABLE devices(
|
||||||
mac_address TEXT PRIMARY KEY,
|
mac_address TEXT PRIMARY KEY,
|
||||||
ip_address TEXT NOT NULL,
|
ipv4_address TEXT NOT NULL,
|
||||||
vendor_name TEXT,
|
vendor TEXT,
|
||||||
last_seen TEXT NOT NULL
|
last_seen TEXT NOT NULL
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
pub mod devices;
|
||||||
|
|
||||||
use include_dir::{Dir, include_dir};
|
use include_dir::{Dir, include_dir};
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
use log::{debug, error};
|
||||||
|
use rusqlite::{Connection, params};
|
||||||
|
use std::sync::MutexGuard;
|
||||||
|
|
||||||
|
use crate::device_finders::Device;
|
||||||
|
|
||||||
|
// Read device from its MAC address
|
||||||
|
pub fn read(conn: MutexGuard<Connection>, mac_address: String) -> Option<Device> {
|
||||||
|
// TODO: Add last_seen
|
||||||
|
let result: Result<Device, rusqlite::Error> = conn.query_one(
|
||||||
|
"SELECT mac_address, ipv4_address, vendor, last_seen FROM devices WHERE mac_address=?1",
|
||||||
|
params![mac_address],
|
||||||
|
|row| {
|
||||||
|
Ok(Device {
|
||||||
|
mac_address: row.get(0)?,
|
||||||
|
ipv4_address: row.get(1)?,
|
||||||
|
vendor: row.get(2)?,
|
||||||
|
last_seen: row.get(3)?,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(value) => Some(value),
|
||||||
|
Err(error) => {
|
||||||
|
match error {
|
||||||
|
rusqlite::Error::QueryReturnedNoRows => {
|
||||||
|
debug!("No device found for MAC address {mac_address}.")
|
||||||
|
}
|
||||||
|
_ => error!("Error reading device from database: {error}"),
|
||||||
|
};
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(conn: MutexGuard<Connection>, device: Device) -> Result<(), String> {
|
||||||
|
match conn.execute(
|
||||||
|
"INSERT INTO devices (mac_address, ipv4_address, vendor, last_seen) VALUES (?1, ?2, ?3, ?4)",
|
||||||
|
params![device.mac_address, device.ipv4_address, device.vendor, device.last_seen]) {
|
||||||
|
Ok(_) => {
|
||||||
|
debug!("Device inserted into database: {}", device);
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
Err(error) => {
|
||||||
|
error!("Error inserting device ({device}) into database: {error}");
|
||||||
|
Err(format!("Error inserting device ({device}) into database: {error}").to_string())
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(conn: MutexGuard<Connection>, device: Device) -> Result<(), String> {
|
||||||
|
match conn.execute(
|
||||||
|
"UPDATE devices SET ipv4_address=?1, vendor=?2, last_seen=?3 WHERE mac_address=?4",
|
||||||
|
params![
|
||||||
|
device.ipv4_address,
|
||||||
|
device.vendor,
|
||||||
|
device.last_seen,
|
||||||
|
device.mac_address
|
||||||
|
],
|
||||||
|
) {
|
||||||
|
Ok(_) => {
|
||||||
|
debug!("Device updated in database: {}", device);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(error) => {
|
||||||
|
error!("Error updating device ({device}) in database: {error}");
|
||||||
|
Err(format!("Error updating device ({device}) in database: {error}").to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,22 @@
|
|||||||
pub mod arp;
|
pub mod arp;
|
||||||
|
|
||||||
|
use chrono::NaiveDateTime;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Device {
|
pub struct Device {
|
||||||
pub mac_address: String,
|
pub mac_address: String,
|
||||||
pub ipv4_address: String,
|
pub ipv4_address: String,
|
||||||
pub vendor: String,
|
pub vendor: String,
|
||||||
}
|
pub last_seen: NaiveDateTime,
|
||||||
|
|
||||||
impl Device {
|
|
||||||
// pub fn get_mac_prefix(&self) -> String {
|
|
||||||
// self.mac_address.get(0..8).unwrap_or("").to_string()
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Device {
|
impl fmt::Display for Device {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"mac={}, ip={}, vendor={}",
|
"mac={}, ip={}, vendor={}, last_seen={}",
|
||||||
self.mac_address, self.ipv4_address, self.vendor
|
self.mac_address, self.ipv4_address, self.vendor, self.last_seen
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::device_finders::Device;
|
use crate::device_finders::Device;
|
||||||
use crate::mac_vendor_finder;
|
use crate::mac_vendor_finder;
|
||||||
|
use chrono::Local;
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use pnet::datalink::{DataLinkReceiver, DataLinkSender, NetworkInterface};
|
use pnet::datalink::{DataLinkReceiver, DataLinkSender, NetworkInterface};
|
||||||
use pnet::ipnetwork::Ipv4Network;
|
use pnet::ipnetwork::Ipv4Network;
|
||||||
@@ -99,6 +100,7 @@ pub async fn listen_for_packets(
|
|||||||
mac_address: packet_mac_address,
|
mac_address: packet_mac_address,
|
||||||
ipv4_address: packet_ip_address,
|
ipv4_address: packet_ip_address,
|
||||||
vendor: packet_vendor,
|
vendor: packet_vendor,
|
||||||
|
last_seen: Local::now().naive_local(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-5
@@ -1,4 +1,5 @@
|
|||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
mod db;
|
mod db;
|
||||||
@@ -6,22 +7,54 @@ mod device_finders;
|
|||||||
mod mac_vendor_finder;
|
mod mac_vendor_finder;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() -> Result<(), String> {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
info!("Starting up oott");
|
info!("Starting up oott");
|
||||||
|
|
||||||
let db_conn = db::init_db();
|
// Get database connection - thread protected
|
||||||
|
let db_conn = Arc::new(Mutex::new(db::init_db().unwrap()));
|
||||||
|
|
||||||
|
// Find online devices via ARP
|
||||||
let devices = device_finders::arp::find("eno1").await.unwrap();
|
let devices = device_finders::arp::find("eno1").await.unwrap();
|
||||||
|
|
||||||
info!("Done with ARP probes");
|
info!("Done with ARP probes");
|
||||||
info!("Found {} online devices", devices.iter().count());
|
info!("Found {} online devices", devices.iter().count());
|
||||||
|
|
||||||
// mac_vendor_finder.populate_vendors(&devices);
|
// Process found devices
|
||||||
|
|
||||||
for device in devices.iter() {
|
for device in devices.iter() {
|
||||||
debug!("Device found {}", device);
|
debug!("Online device found {}", device);
|
||||||
|
|
||||||
|
// Using just one connection for now, need to update if moved DB portion to multi-thread
|
||||||
|
// need to change to a clone if we need multiple threads
|
||||||
|
let db_conn_clone = Arc::clone(&db_conn);
|
||||||
|
|
||||||
|
// Read device from database
|
||||||
|
let recorded_device_result =
|
||||||
|
db::devices::read(db_conn_clone.lock().unwrap(), device.mac_address.clone());
|
||||||
|
|
||||||
|
match recorded_device_result {
|
||||||
|
Some(recorded_device) => {
|
||||||
|
// If it exists update its last seen date
|
||||||
|
info!(
|
||||||
|
"Device found in database {}. Updating to {}.",
|
||||||
|
recorded_device, device
|
||||||
|
);
|
||||||
|
// TODO: If IPv4 or vendor changed do something
|
||||||
|
db::devices::update(db_conn_clone.lock().unwrap(), device.clone());
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// If it doesn't exist insert it
|
||||||
|
info!(
|
||||||
|
"Device with MAC address {} not found in database. Inserting it.",
|
||||||
|
device.mac_address
|
||||||
|
);
|
||||||
|
|
||||||
|
db::devices::insert(db_conn_clone.lock().unwrap(), device.clone());
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Exiting");
|
info!("Exiting");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user