diff options
Diffstat (limited to 'core/net/interface_linux.odin')
| -rw-r--r-- | core/net/interface_linux.odin | 226 |
1 files changed, 115 insertions, 111 deletions
diff --git a/core/net/interface_linux.odin b/core/net/interface_linux.odin index e889cfa97..7c99cf23b 100644 --- a/core/net/interface_linux.odin +++ b/core/net/interface_linux.odin @@ -21,120 +21,124 @@ package net TODO: When we have raw sockets, split off into its own file for Linux so we can use the NETLINK protocol and bypass libc. */ -import "core:os" -import "core:strings" +//import "core:strings" + +// TODO(flysand): regression +// NOTE(flysand): https://man7.org/linux/man-pages/man7/netlink.7.html +// apparently musl libc uses this to enumerate network interfaces @(private) _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: []Network_Interface, err: Network_Error) { context.allocator = allocator - head: ^os.ifaddrs - - if res := os._getifaddrs(&head); res < 0 { - return {}, .Unable_To_Enumerate_Network_Interfaces - } - - /* - Unlike Windows, *nix regrettably doesn't return all it knows about an interface in one big struct. - We're going to have to iterate over a list and coalesce information as we go. - */ - ifaces: map[string]^Network_Interface - defer delete(ifaces) - - for ifaddr := head; ifaddr != nil; ifaddr = ifaddr.next { - adapter_name := string(ifaddr.name) - - /* - Check if we have seen this interface name before so we can reuse the `Network_Interface`. - Else, create a new one. - */ - if adapter_name not_in ifaces { - ifaces[adapter_name] = new(Network_Interface) - ifaces[adapter_name].adapter_name = strings.clone(adapter_name) - } - iface := ifaces[adapter_name] - - address: Address - netmask: Netmask - - if ifaddr.address != nil { - switch int(ifaddr.address.sa_family) { - case os.AF_INET, os.AF_INET6: - address = _sockaddr_basic_to_endpoint(ifaddr.address).address - - case os.AF_PACKET: - /* - For some obscure reason the 64-bit `getifaddrs` call returns a pointer to a - 32-bit `RTNL_LINK_STATS` structure, which of course means that tx/rx byte count - is truncated beyond usefulness. - - We're not going to retrieve stats now. Instead this serves as a reminder to use - the NETLINK protocol for this purpose. - - But in case you were curious: - stats := transmute(^os.rtnl_link_stats)ifaddr.data - fmt.println(stats) - */ - case: - } - } - - if ifaddr.netmask != nil { - switch int(ifaddr.netmask.sa_family) { - case os.AF_INET, os.AF_INET6: - netmask = Netmask(_sockaddr_basic_to_endpoint(ifaddr.netmask).address) - case: - } - } - - if ifaddr.broadcast_or_dest != nil && .BROADCAST in ifaddr.flags { - switch int(ifaddr.broadcast_or_dest.sa_family) { - case os.AF_INET, os.AF_INET6: - broadcast := _sockaddr_basic_to_endpoint(ifaddr.broadcast_or_dest).address - append(&iface.multicast, broadcast) - case: - } - } - - if address != nil { - lease := Lease{ - address = address, - netmask = netmask, - } - append(&iface.unicast, lease) - } - - /* - TODO: Refine this based on the type of adapter. - */ - state := Link_State{} - - if .UP in ifaddr.flags { - state |= {.Up} - } - - if .DORMANT in ifaddr.flags { - state |= {.Dormant} - } - - if .LOOPBACK in ifaddr.flags { - state |= {.Loopback} - } - iface.link.state = state - } - - /* - Free the OS structures. - */ - os._freeifaddrs(head) - - /* - Turn the map into a slice to return. - */ - _interfaces := make([dynamic]Network_Interface, 0, allocator) - for _, iface in ifaces { - append(&_interfaces, iface^) - free(iface) - } - return _interfaces[:], {} + // head: ^os.ifaddrs + + // if res := os._getifaddrs(&head); res < 0 { + // return {}, .Unable_To_Enumerate_Network_Interfaces + // } + + // /* + // Unlike Windows, *nix regrettably doesn't return all it knows about an interface in one big struct. + // We're going to have to iterate over a list and coalesce information as we go. + // */ + // ifaces: map[string]^Network_Interface + // defer delete(ifaces) + + // for ifaddr := head; ifaddr != nil; ifaddr = ifaddr.next { + // adapter_name := string(ifaddr.name) + + // /* + // Check if we have seen this interface name before so we can reuse the `Network_Interface`. + // Else, create a new one. + // */ + // if adapter_name not_in ifaces { + // ifaces[adapter_name] = new(Network_Interface) + // ifaces[adapter_name].adapter_name = strings.clone(adapter_name) + // } + // iface := ifaces[adapter_name] + + // address: Address + // netmask: Netmask + + // if ifaddr.address != nil { + // switch int(ifaddr.address.sa_family) { + // case os.AF_INET, os.AF_INET6: + // address = _sockaddr_basic_to_endpoint(ifaddr.address).address + + // case os.AF_PACKET: + // /* + // For some obscure reason the 64-bit `getifaddrs` call returns a pointer to a + // 32-bit `RTNL_LINK_STATS` structure, which of course means that tx/rx byte count + // is truncated beyond usefulness. + + // We're not going to retrieve stats now. Instead this serves as a reminder to use + // the NETLINK protocol for this purpose. + + // But in case you were curious: + // stats := transmute(^os.rtnl_link_stats)ifaddr.data + // fmt.println(stats) + // */ + // case: + // } + // } + + // if ifaddr.netmask != nil { + // switch int(ifaddr.netmask.sa_family) { + // case os.AF_INET, os.AF_INET6: + // netmask = Netmask(_sockaddr_basic_to_endpoint(ifaddr.netmask).address) + // case: + // } + // } + + // if ifaddr.broadcast_or_dest != nil && .BROADCAST in ifaddr.flags { + // switch int(ifaddr.broadcast_or_dest.sa_family) { + // case os.AF_INET, os.AF_INET6: + // broadcast := _sockaddr_basic_to_endpoint(ifaddr.broadcast_or_dest).address + // append(&iface.multicast, broadcast) + // case: + // } + // } + + // if address != nil { + // lease := Lease{ + // address = address, + // netmask = netmask, + // } + // append(&iface.unicast, lease) + // } + + // /* + // TODO: Refine this based on the type of adapter. + // */ + // state := Link_State{} + + // if .UP in ifaddr.flags { + // state |= {.Up} + // } + + // if .DORMANT in ifaddr.flags { + // state |= {.Dormant} + // } + + // if .LOOPBACK in ifaddr.flags { + // state |= {.Loopback} + // } + // iface.link.state = state + // } + + // /* + // Free the OS structures. + // */ + // os._freeifaddrs(head) + + // /* + // Turn the map into a slice to return. + // */ + // _interfaces := make([dynamic]Network_Interface, 0, allocator) + // for _, iface in ifaces { + // append(&_interfaces, iface^) + // free(iface) + // } + // return _interfaces[:], {} + return nil, {} }
\ No newline at end of file |