Sam
03/08/2023, 10:58 PMMiroslav Sobotka
03/09/2023, 8:37 AMephemient
03/09/2023, 10:00 AMimport kotlinx.cinterop.ByteVar
import kotlinx.cinterop.allocArray
import kotlinx.cinterop.allocPointerTo
import kotlinx.cinterop.convert
import kotlinx.cinterop.memScoped
import kotlinx.cinterop.pointed
import kotlinx.cinterop.ptr
import kotlinx.cinterop.reinterpret
import kotlinx.cinterop.toKString
import kotlinx.cinterop.value
import platform.linux.freeifaddrs
import platform.linux.getifaddrs
import platform.linux.ifaddrs
import platform.linux.inet_ntop
import platform.posix.AF_INET
import platform.posix.AF_INET6
import platform.posix.INET6_ADDRSTRLEN
import platform.posix.INET_ADDRSTRLEN
import platform.posix.sa_family_t
import platform.posix.sockaddr_in
import platform.posix.sockaddr_in6
fun getIPAddresses(): List<String> {
val (status, interfaces) = memScoped {
val ifap = allocPointerTo<ifaddrs>()
getifaddrs(ifap.ptr) to ifap.value
}
return try {
generateSequence(interfaces.takeIf { status == 0 }) { it.pointed.ifa_next }
.mapNotNull { it.pointed.ifa_addr }
.mapNotNull {
val addr = when (it.pointed.sa_family) {
AF_INET.convert<sa_family_t>() -> it.reinterpret<sockaddr_in>().pointed.sin_addr
AF_INET6.convert<sa_family_t>() -> it.reinterpret<sockaddr_in6>().pointed.sin6_addr
else -> return@mapNotNull null
}
memScoped {
val len = maxOf(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)
val dst = allocArray<ByteVar>(len)
inet_ntop(it.pointed.sa_family.convert(), addr.ptr, dst, len.convert())?.toKString()
}
}
.toList()
} finally {
freeifaddrs(interfaces)
}
}
and it should be similar on DarwinSam
03/09/2023, 10:03 AMephemient
03/09/2023, 10:44 AMplatform.linux.*
to platform.darwin.*
inet_ntoa
in the 😒tackoverflow: answer only works for IPv4 and is deprecated; inet_ntop
works for IPv4 and IPv6