Hello.
认真看下错误,iter.ifa_addr 明明是 struct sockaddr *,怎么能随随便便转换为 const char *
呢,建议 man getifaddrs 仔细看看 EXAMPLE 下的 C 例子是如何吐出接口的地址。
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
struct ifaddrs *ifaddr, *ifa;
int family, s;
char host[NI_MAXHOST];
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}
/* Walk through linked list, maintaining head pointer so we
can free list later */
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
/* Display interface name and family (including symbolic
form of the latter for the common families) */
printf("%s address family: %d%s\n",
ifa->ifa_name, family,
(family == AF_PACKET) ? " (AF_PACKET)" :
(family == AF_INET) ? " (AF_INET)" :
(family == AF_INET6) ? " (AF_INET6)" : "");
/* For an AF_INET* interface address, display the address */
if (family == AF_INET || family == AF_INET6) {
s = getnameinfo(ifa->ifa_addr,
(family == AF_INET) ? sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6),
host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s != 0) {
printf("getnameinfo() failed: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
printf("\taddress: <%s>\n", host);
}
}
freeifaddrs(ifaddr);
exit(EXIT_SUCCESS);
}
2017-05-23 16:07 GMT+08:00 ms2008 <ms20...@gmail.com>:
> @agentzh @doujiang
>
> 在 2017年5月22日星期一 UTC+8下午3:45:23,ms2008写道:
>>
>> 用 LuaJIT 获取系统 IP
>>
>> local ffi = require "ffi"
>> local C = ffi.C
>>
>>
>> ffi.cdef([[
>> struct ifaddrs {
>> struct ifaddrs *ifa_next; /* Next item in list */
>> char *ifa_name; /* Name of interface */
>> unsigned int ifa_flags; /* Flags from SIOCGIFFLAGS */
>> struct sockaddr *ifa_addr; /* Address of interface */
>> struct sockaddr *ifa_netmask; /* Netmask of interface */
>> union {
>> struct sockaddr *ifu_broadaddr; /* Broadcast address of interface
>> */
>> struct sockaddr *ifu_dstaddr; /* Point-to-point destination
>> address */
>> } ifa_ifu;
>> void *ifa_data; /* Address-specific data */
>> };
>> // the union will be populated based on the following ifa_flags:
>> enum {
>> IFF_BROADCAST = 0x2, /* broadcast address valid */
>> IFF_POINTOPOINT = 0x10 /* interface is has p-p link */
>> };
>>
>>
>> int getifaddrs(struct ifaddrs **ifap);
>> void freeifaddrs(struct ifaddrs *ifa);
>>
>>
>> ]])
>>
>>
>> -- Returns a Lua array of interfaces retrieved via C.getifaddrs
>> -- The original ifaddrs linked list is stored in ret.ifaddrs and is freed
>> upon GC of ret
>> local function getifaddrs()
>> local ifaddrs_root = ffi.new("struct ifaddrs *[1]")
>> local res = C.getifaddrs( ifaddrs_root )
>> assert( res == 0, ffi.errno() )
>>
>>
>> -- convert linked list to Lua array for convenience
>> local tret = {}
>> local iter = ifaddrs_root[0]
>> while iter ~= nil do
>> tret[#tret + 1] = iter
>> -- print(ffi.string(iter.ifa_name))
>> if ffi.string(iter.ifa_name) ~= "lo" then
>> print(ffi.string(iter.ifa_name), ffi.string(iter.ifa_addr))
>> end
>> iter = iter.ifa_next
>> end
>>
>>
>> -- free ifaddrs when tret is gc'd
>> tret.ifaddrs = ifaddrs_root
>> ffi.gc( ifaddrs_root, function(t) C.freeifaddrs(t[0]) end )
>> return tret
>> end
>>
>>
>> getifaddrs()
>>
>> 目前的问题是 struct sockaddr 无法转换为 lua string, 报
>>
>> luajit: ffi_getaddrinfo.lua:42: bad argument #1 to 'string' (cannot
>> convert 'struct sockaddr *' to 'const char *')
>
> --
>