Default Router를 가져오는 샘플 닫기.
소스를 첨부한다.
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/time.h> #include <sys/socket.h> #include <net/if.h> #include <net/if_dl.h> #include <net/route.h> #include <netinet/in.h>
const char *print_in_addr_t (in_addr_t addr) { struct in_addr ia; static char out[64];
if (addr) { memset((char *)&ia, 0, sizeof(struct in_addr)); ia.s_addr = htonl(addr);
sprintf (out, "%s", inet_ntoa (ia)); } return out; }
struct { struct rt_msghdr m_rtm; char m_space[512]; } m_rtmsg;
#define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
static int get_default_gateway (in_addr_t *ret) { int s, seq, l, pid, rtm_addrs, i; struct sockaddr so_dst, so_mask; char *cp = m_rtmsg.m_space; struct sockaddr *gate = NULL, *sa; struct rt_msghdr *rtm_aux; struct sockaddr_dl *gate_nic = NULL;
#define NEXTADDR(w, u) \ if (rtm_addrs & (w)) {\ l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\ } #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
#define rtm m_rtmsg.m_rtm
pid = getpid(); seq = 0; rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
bzero(&so_dst, sizeof(so_dst)); bzero(&so_mask, sizeof(so_mask)); bzero(&rtm, sizeof(struct rt_msghdr));
rtm.rtm_type = RTM_GET; rtm.rtm_flags = RTF_UP | RTF_GATEWAY; rtm.rtm_version = RTM_VERSION; rtm.rtm_seq = ++seq; rtm.rtm_addrs = rtm_addrs;
so_dst.sa_family = AF_INET; so_dst.sa_len = sizeof(struct sockaddr_in); so_mask.sa_family = AF_INET; so_mask.sa_len = sizeof(struct sockaddr_in);
NEXTADDR(RTA_DST, so_dst); NEXTADDR(RTA_NETMASK, so_mask);
rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
s = socket(PF_ROUTE, SOCK_RAW, 0);
if (write(s, (char *)&m_rtmsg, l) < 0) { warn("writing to routing socket"); close(s); return -1; }
do { l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
close(s);
rtm_aux = &rtm;
cp = ((char *)(rtm_aux + 1)); if (rtm_aux->rtm_addrs) { for (i = 1; i; i <<= 1) if (i & rtm_aux->rtm_addrs) { sa = (struct sockaddr *)cp; if (i == RTA_GATEWAY ) gate = sa;
if (i == RTA_IFP ) { gate_nic = (struct sockaddr_dl *)cp; }
ADVANCE(cp, sa); } } else { return -1; }
if (gate != NULL ) { *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
#if 1 fprintf(stderr, "gw %s, %s\n", print_in_addr_t ((in_addr_t) *ret), gate_nic->sdl_data); #endif return 0; } else { return -1; } }
main() { in_addr_t ret;
get_default_gateway(&ret); }
대략 도는 형태로 참고하면 되겠다.
(참고로, Interface Name이 제대로 출력된건지는.. 잘 모르겠다;)
Default Router를 가져오는 샘플 닫기.