diff --git a/c/inet.c b/c/inet.c new file mode 100644 index 0000000..deb1dde --- /dev/null +++ b/c/inet.c @@ -0,0 +1,110 @@ +#include +#include +#include + +#include "inet.h" + +static struct sockaddr *find_address_of(char *name, struct ifaddrs *from) +{ + struct ifaddrs *ifa; + int n; + for (ifa = from, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) { + if (strcmp(ifa->ifa_name, name)) { + continue; + } + + if (ifa->ifa_addr == NULL) { + continue; + } + + int family = ifa->ifa_addr->sa_family; + if (family == AF_INET || family == AF_INET6) { + return ifa->ifa_addr; + } + } + + return NULL; +} + +static struct sockaddr *find_netmask_of(char *name, struct ifaddrs *from) +{ + struct ifaddrs *ifa; + int n; + for (ifa = from, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) { + if (strcmp(ifa->ifa_name, name)) { + continue; + } + + if (ifa->ifa_netmask == NULL) { + continue; + } + + int family = ifa->ifa_netmask->sa_family; + if (family == AF_INET || family == AF_INET6) { + return ifa->ifa_netmask; + } + } + + return NULL; +} + +static int address_to_string(struct sockaddr *addr, char *buffer, int size) +{ + return getnameinfo(addr, + (addr->sa_family == AF_INET) + ? sizeof(struct sockaddr_in) + : sizeof(struct sockaddr_in6), + buffer, size, + NULL, 0, + NI_NUMERICHOST); +} + +int get_ip_addr(char *p_ip, int sz_ip) +{ + struct ifaddrs *ifaddr; + if (getifaddrs(&ifaddr) == -1) { + return -1; + } + + struct sockaddr *address = find_address_of(IFNAME, ifaddr); + if (address == NULL) { + goto ERROR; + } + + int ret = address_to_string(address, p_ip, sz_ip); + if (ret != 0) { + goto ERROR; + } + + freeifaddrs(ifaddr); + return 0; + +ERROR: + freeifaddrs(ifaddr); + return -1; +} + +int get_netmask(char *p_netmask, int sz_netmask) +{ + struct ifaddrs *ifaddr; + if (getifaddrs(&ifaddr) == -1) { + return -1; + } + + struct sockaddr *netmask = find_netmask_of(IFNAME, ifaddr); + if (netmask == NULL) { + goto ERROR; + } + + int ret = address_to_string(netmask, p_netmask, sz_netmask); + if (ret != 0) { + goto ERROR; + } + + freeifaddrs(ifaddr); + return 0; + +ERROR: + freeifaddrs(ifaddr); + return -1; +} diff --git a/c/inet.h b/c/inet.h new file mode 100644 index 0000000..e709570 --- /dev/null +++ b/c/inet.h @@ -0,0 +1,15 @@ +#ifndef INET_H +#define INET_H + +// 인터페이스 이름 +#define IFNAME "eth0" + +// p_ip: ip를 받는 버퍼 +// sz_ip: 버퍼 크기 +int get_ip_addr(char *p_ip, int sz_ip); + +// p_netmask: 넷마스크를 받는 버퍼 +// sz_netmask: 버퍼 크기 +int get_netmask(char *p_netmask, int sz_netmask); + +#endif /* INET_H */