forked from Rust/Core
Compare commits
1 Commits
feat/net74
...
fix/strlen
| Author | SHA1 | Date | |
|---|---|---|---|
| 4b5642cc4e |
@@ -1,6 +1,5 @@
|
||||
[unstable]
|
||||
build-std = ["core", "compiler_builtins", "alloc"]
|
||||
json-target-spec = true
|
||||
|
||||
[build]
|
||||
target = "i686-kolibri.json"
|
||||
|
||||
@@ -18,10 +18,6 @@ path = "examples/con.rs"
|
||||
name = "dark"
|
||||
path = "examples/dark.rs"
|
||||
|
||||
[[example]]
|
||||
name = "net"
|
||||
path = "examples/net.rs"
|
||||
|
||||
[profile.release]
|
||||
opt-level = "z"
|
||||
lto = "thin"
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::format;
|
||||
use kos::{
|
||||
dll::Console,
|
||||
network::{self, DeviceType},
|
||||
threads::exit,
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
pub fn kol_main() {
|
||||
let con_lib = Console::import(None).expect("Failed to load /sys/lib/console.obj");
|
||||
|
||||
con_lib.init(u32::MAX, u32::MAX, u32::MAX, u32::MAX, c"Network Diagnostics");
|
||||
|
||||
let count = network::device_count();
|
||||
con_lib.write_string("Network Subsystem Diagnostics\n");
|
||||
con_lib.write_string("=============================\n");
|
||||
con_lib.write_string(&format!("Discovered Devices: {}\n\n", count));
|
||||
|
||||
for i in 0..(count as u8) {
|
||||
if let Ok(name) = network::device_name(i) {
|
||||
con_lib.write_string(&format!("INTERFACE [{}]\n", i));
|
||||
con_lib.write_string(&format!(" Name: {}\n", name));
|
||||
|
||||
if let Ok(info) = network::device_info(i) {
|
||||
let dev_type = match info.device_type {
|
||||
DeviceType::Ethernet => "Ethernet",
|
||||
DeviceType::Loopback => "Loopback",
|
||||
DeviceType::Unknown(_id) => "Unknown Hardware",
|
||||
};
|
||||
|
||||
con_lib.write_string(&format!(" Type: {}\n", dev_type));
|
||||
|
||||
let up = if info.link.is_up() { "UP" } else { "DOWN" };
|
||||
let mbps = info.link.speed_mbps().unwrap_or(0);
|
||||
let duplex = if info.link.is_full_duplex() { "Full" } else { "Half" };
|
||||
|
||||
con_lib.write_string(&format!(" State: {} (Speed: {} Mbps, {} Duplex)\n", up, mbps, duplex));
|
||||
}
|
||||
|
||||
if let Ok(stats) = network::device_stats(i) {
|
||||
con_lib.write_string(&format!(" Stats: RX {} bytes | TX {} bytes\n", stats.rx_bytes, stats.tx_bytes));
|
||||
con_lib.write_string(&format!(" RX {} pkts | TX {} pkts\n", stats.rx_packets, stats.tx_packets));
|
||||
|
||||
if stats.rx_errors > 0 || stats.tx_errors > 0 || stats.tx_dropped > 0 {
|
||||
con_lib.write_string(&format!(" [!] Errors detected: RX={} TX={} Drops={}\n",
|
||||
stats.rx_errors, stats.tx_errors, stats.tx_dropped));
|
||||
}
|
||||
}
|
||||
|
||||
con_lib.write_string("\n");
|
||||
} else {
|
||||
con_lib.write_string(&format!("INTERFACE [{}]\n [!] Failed to pull hardware state.\n\n", i));
|
||||
}
|
||||
}
|
||||
|
||||
con_lib.write_string("Diagnostics complete.");
|
||||
|
||||
con_lib.exit(false);
|
||||
exit();
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
"dynamic-linking": false,
|
||||
"executables": true,
|
||||
"has-rpath": true,
|
||||
"is-builtin": false,
|
||||
"linker-flavor": "ld.lld",
|
||||
"linker": "rust-lld",
|
||||
"llvm-target": "i686-unknown-none-code32",
|
||||
@@ -13,9 +14,9 @@
|
||||
"relocation-model": "static",
|
||||
"position-independent-executables": false,
|
||||
"relro-level": "off",
|
||||
"target-c-int-width": 32,
|
||||
"target-c-int-width": "32",
|
||||
"target-endian": "little",
|
||||
"target-pointer-width": 32,
|
||||
"target-pointer-width": "32",
|
||||
"vendor": "unknown",
|
||||
"disable-redzone": true,
|
||||
"panic-strategy": "abort",
|
||||
|
||||
@@ -1,4 +1 @@
|
||||
[toolchain]
|
||||
channel = "nightly"
|
||||
components = ["rust-src", "llvm-tools-preview"]
|
||||
profile = "default"
|
||||
nightly
|
||||
|
||||
14
shell.nix
14
shell.nix
@@ -1,14 +0,0 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
rustup
|
||||
cargo-make
|
||||
cargo-binutils
|
||||
fasm
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
export PATH="$HOME/.cargo/bin:$PATH"
|
||||
'';
|
||||
}
|
||||
@@ -20,21 +20,3 @@ SF_SYS_MISC = 68
|
||||
SSF_MEM_ALLOC = 12
|
||||
SSF_MEM_FREE = 13
|
||||
SSF_LOAD_DLL = 19
|
||||
SF_NETWORK_GET = 74
|
||||
SSF_DEVICE_COUNT = -1
|
||||
SSF_DEVICE_TYPE = 0
|
||||
SSF_DEVICE_NAME = 1
|
||||
SSF_RESET_DEVICE = 2
|
||||
SSF_STOP_DEVICE = 3
|
||||
SSF_DEVICE_POINTER = 4
|
||||
SSF_TX_PACKET_COUNT = 6
|
||||
SSF_RX_PACKET_COUNT = 7
|
||||
SSF_TX_BYTE_COUNT = 8
|
||||
SSF_RX_BYTE_COUNT = 9
|
||||
SSF_LINK_STATUS = 10
|
||||
SSF_TX_PACKET_ERROR_COUNT = 11
|
||||
SSF_TX_PACKET_DROP_COUNT = 12
|
||||
SSF_TX_PACKET_MISS_COUNT = 13
|
||||
SSF_RX_PACKET_ERROR_COUNT = 14
|
||||
SSF_RX_PACKET_DROP_COUNT = 15
|
||||
SSF_RX_PACKET_MISS_COUNT = 16
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
pub mod graphics;
|
||||
pub mod input;
|
||||
pub mod network;
|
||||
pub mod system;
|
||||
pub mod threads;
|
||||
pub mod windows;
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
use crate::sys;
|
||||
use alloc::string::String;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum NetworkError {
|
||||
NoDevice,
|
||||
KernelError(i32),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum DeviceType {
|
||||
Loopback,
|
||||
Ethernet,
|
||||
Unknown(u32),
|
||||
}
|
||||
|
||||
impl DeviceType {
|
||||
fn from_raw(v: u32) -> Self {
|
||||
match v {
|
||||
0 => DeviceType::Loopback,
|
||||
1 => DeviceType::Ethernet,
|
||||
other => DeviceType::Unknown(other),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct LinkStatus(u32);
|
||||
|
||||
impl LinkStatus {
|
||||
pub fn is_up(&self) -> bool {
|
||||
self.0 & 0b0001 != 0
|
||||
}
|
||||
|
||||
pub fn is_full_duplex(&self) -> bool {
|
||||
self.0 & 0b0010 != 0
|
||||
}
|
||||
|
||||
pub fn speed_mbps(&self) -> Option<u32> {
|
||||
match self.0 & 0b1100 {
|
||||
0b0100 => Some(10),
|
||||
0b1000 => Some(100),
|
||||
0b1100 => Some(1000),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DeviceStats {
|
||||
pub tx_packets: u32,
|
||||
pub rx_packets: u32,
|
||||
pub tx_bytes: u64,
|
||||
pub rx_bytes: u64,
|
||||
pub tx_errors: u32,
|
||||
pub tx_dropped: u32,
|
||||
pub tx_missed: u32,
|
||||
pub rx_errors: u32,
|
||||
pub rx_dropped: u32,
|
||||
pub rx_missed: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DeviceInfo {
|
||||
pub device_type: DeviceType,
|
||||
pub link: LinkStatus,
|
||||
}
|
||||
|
||||
fn raw_get(subfunc: u8, device: u8) -> Result<i32, NetworkError> {
|
||||
let r = unsafe { sys::network_get(subfunc, device, 0) };
|
||||
if r == -1 {
|
||||
Err(NetworkError::NoDevice)
|
||||
} else {
|
||||
Ok(r)
|
||||
}
|
||||
}
|
||||
|
||||
fn raw_get_u64(subfunc: u8, device: u8) -> Result<u64, NetworkError> {
|
||||
let mut hi: u32 = 0;
|
||||
let lo = unsafe { sys::network_get_u64(subfunc, device, &mut hi as *mut u32) };
|
||||
if lo == -1 {
|
||||
Err(NetworkError::NoDevice)
|
||||
} else {
|
||||
Ok((hi as u64) << 32 | (lo as u32) as u64)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn device_count() -> u32 {
|
||||
let r = unsafe { sys::network_get(0xFFu8, 0, 0) };
|
||||
if r < 0 {
|
||||
0
|
||||
} else {
|
||||
r as u32
|
||||
}
|
||||
}
|
||||
|
||||
pub fn device_type(device: u8) -> Result<DeviceType, NetworkError> {
|
||||
raw_get(0, device).map(|v| DeviceType::from_raw(v as u32))
|
||||
}
|
||||
|
||||
pub fn device_name(device: u8) -> Result<String, NetworkError> {
|
||||
let mut buf = [0u8; 64];
|
||||
let r = unsafe { sys::network_get(1, device, buf.as_mut_ptr() as u32) };
|
||||
if r == -1 {
|
||||
return Err(NetworkError::NoDevice);
|
||||
}
|
||||
let len = buf.iter().position(|&c| c == 0).unwrap_or(buf.len());
|
||||
Ok(String::from(core::str::from_utf8(&buf[..len]).unwrap_or("?")))
|
||||
}
|
||||
|
||||
pub fn reset_device(device: u8) -> Result<(), NetworkError> {
|
||||
raw_get(2, device).map(|_| ())
|
||||
}
|
||||
|
||||
pub fn stop_device(device: u8) -> Result<(), NetworkError> {
|
||||
raw_get(3, device).map(|_| ())
|
||||
}
|
||||
|
||||
pub fn device_pointer(device: u8) -> Result<u32, NetworkError> {
|
||||
raw_get(4, device).map(|v| v as u32)
|
||||
}
|
||||
|
||||
pub fn tx_packet_count(device: u8) -> Result<u32, NetworkError> {
|
||||
raw_get(6, device).map(|v| v as u32)
|
||||
}
|
||||
|
||||
pub fn rx_packet_count(device: u8) -> Result<u32, NetworkError> {
|
||||
raw_get(7, device).map(|v| v as u32)
|
||||
}
|
||||
|
||||
pub fn tx_byte_count(device: u8) -> Result<u64, NetworkError> {
|
||||
raw_get_u64(8, device)
|
||||
}
|
||||
|
||||
pub fn rx_byte_count(device: u8) -> Result<u64, NetworkError> {
|
||||
raw_get_u64(9, device)
|
||||
}
|
||||
|
||||
pub fn link_status(device: u8) -> Result<LinkStatus, NetworkError> {
|
||||
raw_get(10, device).map(|v| LinkStatus(v as u32))
|
||||
}
|
||||
|
||||
pub fn tx_error_count(device: u8) -> Result<u32, NetworkError> {
|
||||
raw_get(11, device).map(|v| v as u32)
|
||||
}
|
||||
|
||||
pub fn tx_drop_count(device: u8) -> Result<u32, NetworkError> {
|
||||
raw_get(12, device).map(|v| v as u32)
|
||||
}
|
||||
|
||||
pub fn tx_miss_count(device: u8) -> Result<u32, NetworkError> {
|
||||
raw_get(13, device).map(|v| v as u32)
|
||||
}
|
||||
|
||||
pub fn rx_error_count(device: u8) -> Result<u32, NetworkError> {
|
||||
raw_get(14, device).map(|v| v as u32)
|
||||
}
|
||||
|
||||
pub fn rx_drop_count(device: u8) -> Result<u32, NetworkError> {
|
||||
raw_get(15, device).map(|v| v as u32)
|
||||
}
|
||||
|
||||
pub fn rx_miss_count(device: u8) -> Result<u32, NetworkError> {
|
||||
raw_get(16, device).map(|v| v as u32)
|
||||
}
|
||||
|
||||
pub fn device_info(device: u8) -> Result<DeviceInfo, NetworkError> {
|
||||
let device_type = device_type(device)?;
|
||||
let link = link_status(device)?;
|
||||
Ok(DeviceInfo { device_type, link })
|
||||
}
|
||||
|
||||
pub fn device_stats(device: u8) -> Result<DeviceStats, NetworkError> {
|
||||
Ok(DeviceStats {
|
||||
tx_packets: tx_packet_count(device)?,
|
||||
rx_packets: rx_packet_count(device)?,
|
||||
tx_bytes: tx_byte_count(device)?,
|
||||
rx_bytes: rx_byte_count(device)?,
|
||||
tx_errors: tx_error_count(device)?,
|
||||
tx_dropped: tx_drop_count(device)?,
|
||||
tx_missed: tx_miss_count(device)?,
|
||||
rx_errors: rx_error_count(device)?,
|
||||
rx_dropped: rx_drop_count(device)?,
|
||||
rx_missed: rx_miss_count(device)?,
|
||||
})
|
||||
}
|
||||
@@ -67,12 +67,4 @@ extern "C" {
|
||||
// 68.19
|
||||
#[link_name = "_load_dll"]
|
||||
pub fn load_dll(name: *const u8) -> *const u32;
|
||||
|
||||
// 74
|
||||
#[link_name = "_network_get"]
|
||||
pub fn network_get(subfunc: u8, device: u8, ecx: u32) -> i32;
|
||||
|
||||
// 74 (u64 return: eax=lo, ebx=hi via out-ptr)
|
||||
#[link_name = "_network_get_u64"]
|
||||
pub fn network_get_u64(subfunc: u8, device: u8, ebx_out: *mut u32) -> i32;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@ section '.text'
|
||||
public _get_lang
|
||||
public _load_dll
|
||||
public _set_event_mask
|
||||
public _network_get
|
||||
public _network_get_u64
|
||||
|
||||
_exit:
|
||||
mov eax, SF_TERMINATE_PROCESS
|
||||
@@ -145,26 +143,3 @@ _set_event_mask:
|
||||
int 0x40
|
||||
ret
|
||||
|
||||
_network_get:
|
||||
push ebx
|
||||
mov eax, SF_NETWORK_GET
|
||||
movzx ebx, byte [esp + 4 * 2]
|
||||
mov bh, byte [esp + 4 * 3]
|
||||
mov ecx, [esp + 4 * 4]
|
||||
int 0x40
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
_network_get_u64:
|
||||
push ebx
|
||||
push edi
|
||||
mov eax, SF_NETWORK_GET
|
||||
movzx ebx, byte [esp + 4 * 3]
|
||||
mov bh, byte [esp + 4 * 4]
|
||||
xor ecx, ecx
|
||||
mov edi, [esp + 4 * 5]
|
||||
int 0x40
|
||||
mov [edi], ebx
|
||||
pop edi
|
||||
pop ebx
|
||||
ret
|
||||
Reference in New Issue
Block a user