èããåŸãç§ã¯é©åã«ããããªã³ã¯ãç解ããèªåã®ã©ã€ãã©ãªãæžãããšã«ããŸããã çŸæç¹ã§ã¯ãéç¥ããããã¯ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ãã«ãŒãã£ã³ã°ããŒãã«ãæäœããããã®ãã¹ãŠã®æ©èœãå®è£ ãããŠããããã¡ããIPv4ãšIPv6ããµããŒããããŠããŸãã ããã«ãã®ãããžã§ã¯ããå ¬éãããŸã:)ä»ã®ãšãããç°¡åãªãããã¯ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ã¢ãã¿ãŒã®äŸã䜿çšããŠãããããªã³ã¯ã®çŸããäžçã«èå³ã®ãããã¹ãŠã®äººã玹ä»ããããšæããŸãã
netlinkãšã¯äœã§ããïŒ
ãããã£ãŠãnetlinkã¯ããŠãŒã¶ãŒç©ºéãšLinuxã«ãŒãã«ã®éã®éä¿¡ã«äŸ¿å©ãªæ¹æ³ã§ãã éä¿¡ã¯ãç¹å¥ãªãããã³ã«-AF_NETLINKã䜿çšããŠãéåžžã®ãœã±ããã䜿çšããŠå®è¡ãããŸãã
Netlinkã䜿çšãããšãã€ã³ã¿ãŒãã§ã€ã¹ãã«ãŒãã£ã³ã°ããããã¯ãŒã¯ãã±ãããã£ã«ã¿ãŒãªã©ãå€æ°ã®ã«ãŒãã«ãµãã·ã¹ãã ãšå¯Ÿè©±ã§ããŸãã ããã«ãã«ãŒãã«ã¢ãžã¥ãŒã«ãšéä¿¡ã§ããŸãã ãã¡ãããåŸè ã¯ãã®ã¿ã€ãã®éä¿¡ããµããŒãããã¯ãã§ãã
åããããªã³ã¯ã¡ãã»ãŒãžã¯ãnlmsghdræ§é ã§è¡šãããããããŒãšãç¹å®ã®ãã€ãæ°ïŒããã€ããŒããïŒã§ãã ãã®ãããŒããã¯ãäœããã®æ§é ããŸãã¯åãªãRAWããŒã¿ã§ããå¯èœæ§ããããŸãã ã¡ãã»ãŒãžã¯ãé ä¿¡äžã«ããã€ãã®éšåã«åå²ã§ããŸãã ãã®ãããªå ŽåãåŸç¶ã®åãã±ããã«ã¯ããã©ã°NLM_F_MULTIãšæåŸã®ãã©ã°NLMSG_DONEã®ããŒã¯ãä»ããããŸãã ã¡ãã»ãŒãžã®åæã®ããã«ãããããŒãã¡ã€ã«netlink.hããã³rtnetlink.hã§å®çŸ©ããããã¯ãã®ã»ããå šäœããããŸãã
netlinkãœã±ãããäœæããŸãã
netlinkãœã±ãã宣èšã¯ããªãæšæºã«èŠããŸãïŒ
socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)
ããã§AF_NETLINK-ããããªã³ã¯ãããã³ã«
SOCK_RAW-ãœã±ããã¿ã€ã
NETLINK_ROUTE-ããããªã³ã¯ãããã³ã«ãã¡ããªã
æåŸã®ãã©ã¡ãŒã¿ãŒã¯ãnetlinkããååŸãããã®ã«å¿ããŠç°ãªãå ŽåããããŸãã
æãèå³æ·±ããã©ã¡ãŒã¿ãŒãå«ãè¡šãæäŸããŸãïŒãã©ã¡ãŒã¿ãŒã®å®å šãªãªã¹ãã¯ããã¥ã¡ã³ãã«èšèŒãããŠããŸãïŒã
NETLINK_ROUTE-ã«ãŒãã£ã³ã°ããŒãã«ãšãããã¯ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ãžã®å€æŽã®éç¥ãåãåããŸãã
äžèšã®ãªããžã§ã¯ãã®ãã¹ãŠã®ãã©ã¡ãŒã¿ãŒãå€æŽããããã«ã䜿çšã§ããŸãã
NETLINK_USERSOCK-ãŠãŒã¶ãŒãããã³ã«ãå®çŸ©ããããã«äºçŽãããŠããŸãã
NETLINK_FIREWALL-ãããã¯ãŒã¯ãã£ã«ã¿ãŒãããŠãŒã¶ãŒã¬ãã«ã«IPv4ãã±ããã転éããŸã
NETLINK_INET_DIAG -inetãœã±ããã®ç£èŠ
NETLINK_NFLOG -ULOGãããã¯ââãŒã¯/ãã±ãããã£ã«ã¿ãŒ
NETLINK_SELINUX -Selinuxã·ã¹ãã ããéç¥ãåãåããŸã
NETLINK_NETFILTER-ãããã¯ãŒã¯ãã£ã«ã¿ãŒãµãã·ã¹ãã ãæäœããŸã
NETLINK_KOBJECT_UEVENT-ã«ãŒãã«ã¡ãã»ãŒãžã®åä¿¡
ããã«ãäœæããããœã±ããã䜿çšããŠãããšãã°ãéä¿¡æ©èœã䜿çšããŠã¡ãã»ãŒãžãéä¿¡ããããrecvmsgã䜿çšããŠã¡ãã»ãŒãžãåä¿¡ãããã§ããŸãã
Netlinkã¡ãã»ãŒãžã
nlmsghdræ§é ã§è¡šãããã¡ãã»ãŒãžããããŒ
struct nlmsghdr { __u32 nlmsg_len; // , __u16 nlmsg_type; // ( ) __u16 nlmsg_flags; // __u32 nlmsg_seq; // __u32 nlmsg_pid; // (PID), };
nlmsg_typeãã£ãŒã«ãã¯ãæšæºã®ã¡ãã»ãŒãžã¿ã€ãã®ãããããæãããšãã§ããŸãã
NLMSG_NOOP-ãã®ã¿ã€ãã®ã¡ãã»ãŒãžã¯ç¡èŠãããŸãã
NLMSG_ERROR-ãšã©ãŒã¡ãã»ãŒãžãããã³nlmsgerræ§é ã¯ãã€ããŒãã»ã¯ã·ã§ã³ã«ãããŸãïŒä»¥äžãåç §ïŒ
NLMSG_DONE-ãã®ãã©ã°ãæã€ã¡ãã»ãŒãžã¯ãããã€ãã®éšåã«åå²ãããã¡ãã»ãŒãžãå®äºããå¿ èŠããããŸã
Nlmsgerræ§é
struct nlmsgerr { int error; // struct nlmsghdr msg; // , };
ã¡ãã»ãŒãžã¯ã1ã€ä»¥äžã®ã¿ã€ãïŒè«ççãªORã䜿çšããŠç°ãªãã¿ã€ããçµåãããïŒã®ã¿ã€ãã®æäœã§ãã
NLM_F_REQUEST-ã¡ãã»ãŒãž-äœãã®ãªã¯ãšã¹ã
NLM_F_MULTI-ã¡ãã»ãŒãžãã¡ãã»ãŒãžã®äžéšã¯è€æ°ã®éšåã«åå²ãããŸã
NLM_F_ACK-ã¡ãã»ãŒãž-確èªèŠæ±
NLM_F_ECHO-ãšã³ãŒèŠæ±ã éåžžã®æ¹åã¯ãã«ãŒãã«ã¬ãã«ãããŠãŒã¶ãŒã¬ãã«ãžã®ã¯ãšãªã§ãã
NLM_F_ROOT-ãã®ã¿ã€ãã®ã¯ãšãªã¯ãç¹å®ã®ãšã³ãã£ãã£å ã®ç¹å®ã®ããŒãã«ãè¿ããŸã
NLM_F_MATCH-ã¯ãšãªã¯èŠã€ãã£ããã¹ãŠã®äžèŽãè¿ããŸã
NLM_F_ATOMIC-ç¹å®ã®ããŒãã«ã®ã¢ãããã¯ã¹ã©ã€ã¹ãè¿ããŸã
NLM_F_DUMP - NLM_F_ROOTã«é¡äŒŒ| NLM_F_MATCH
è¿œå ã®ãã©ã°ïŒ
NLM_F_REPLACE-æ¢åã®é¡äŒŒãªããžã§ã¯ãã眮ãæããŸã
NLM_F_EXCL-ãã®ãããªãªããžã§ã¯ããæ¢ã«ååšããå Žåã¯çœ®ãæããŸãã
NLM_F_CREATE-ãªããžã§ã¯ããååšããªãå Žåã¯äœæããŸã
NLM_F_APPEND-ãªã¹ãã«ãªããžã§ã¯ããæ¢åã®ãã®ã«è¿œå ããŸã
ã¯ã©ã€ã¢ã³ããïŒã«ãŒãã«ã¬ãã«ããã³ãŠãŒã¶ãŒã¬ãã«ã§ïŒèå¥ããããã«ãnladdrãšããç¹å¥ãªã¢ãã¬ã¹æ§é ããããŸãã
struct sockaddr_nl { sa_family_t nl_family; // - AF_NETLINK unsigned short nl_pad; // pid_t nl_pid; // __u32 nl_groups; // / };
nl_pidã¯äžæã®ãœã±ããã¢ãã¬ã¹ã§ãã ã«ãŒãã«å ã®ã¯ã©ã€ã¢ã³ãã®å Žåãåžžã«ãŒãã§ãã ãŠãŒã¶ãŒã¬ãã«ã®ãŠãŒã¶ãŒã®å Žåããœã±ãããææããããã»ã¹ã®èå¥åãšåãã§ãã åèå¥åã¯äžæã§ããå¿ èŠãããããããã«ãã¹ã¬ããã¢ããªã±ãŒã·ã§ã³ã§è€æ°ã®netlinkãœã±ãããäœæããããšãããšåé¡ãçºçããå¯èœæ§ããããŸããæ°ãããœã±ãããäœæãããšããOperation not allowedããšã©ãŒãè¿ãããŸãã ãã®å¶éãåé¿ããã«ã¯ãnl_pidã«æ¬¡ã®åŒã®å€ãå²ãåœãŠãå¿ èŠããããŸãã
pthread_self() << 16 | getpid();
ãœã±ããã«å¯ŸããŠbindïŒïŒãåŒã³åºãããåã«ãèå¥åã®å€ãå²ãåœãŠãå¿ èŠããããŸãã
ãŸããèå¥åã«ãŒãå€ãå²ãåœãŠãããšãã§ããŸãã ãã®å Žåãã«ãŒãã«ã¯äžæã®èå¥åãçæããŸãããã¢ããªã±ãŒã·ã§ã³ã§äœæãããæåã®ãœã±ããã«ã¯åžžã«ãã®ã¢ããªã±ãŒã·ã§ã³ã®èå¥åå€ãå²ãåœãŠãããŸãã
nl_groupsã¯ããããã¹ã¯ã§ãåãããã¯ããããªã³ã¯ã°ã«ãŒãçªå·ãè¡šããŸãã netlinkãœã±ããã§bindïŒïŒãåŒã³åºãå Žåãã¢ããªã±ãŒã·ã§ã³ããã®ã³ã³ããã¹ãã§ãªãã¹ã³ããã°ã«ãŒãã®ããããã¹ã¯ãæå®ããŸãã è«çORã䜿çšããŠç°ãªãã°ã«ãŒããçµã¿åãããããšãã§ããŸãã
ã¡ãžã£ãŒã°ã«ãŒãã¯ãããããªã³ã¯ããããŒãã¡ã€ã«ã§å®çŸ©ãããŸãã
ãããã®ããã€ãã®äŸïŒ
RTMGRP_LINK-ãã®ã°ã«ãŒãã¯ããããã¯ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ã®å€æŽã®éç¥ãåãåããŸãïŒã€ã³ã¿ãŒãã§ã€ã¹ã¯å»æ¢ãè¿œå ãåé€ãäžæïŒ
RTMGRP_IPV4_IFADDR-ãã®ã°ã«ãŒãã¯ãã€ã³ã¿ãŒãã§ãŒã¹ã®IPv4ã¢ãã¬ã¹ã®å€æŽã®éç¥ãåãåããŸãïŒã¢ãã¬ã¹ã¯è¿œå ãŸãã¯åé€ãããŸããïŒ
RTMGRP_IPV6_IFADDR-ãã®ã°ã«ãŒãã¯ãã€ã³ã¿ãŒãã§ãŒã¹ã®IPv6ã¢ãã¬ã¹ã®å€æŽã®éç¥ãåãåããŸãïŒã¢ãã¬ã¹ã¯è¿œå ãŸãã¯åé€ãããŸããïŒ
RTMGRP_IPV4_ROUTE-ãã®ã°ã«ãŒãã¯ãIPv4ã¢ãã¬ã¹ã®ã«ãŒãã£ã³ã°ããŒãã«ã®å€æŽã®éç¥ãåãåããŸã
RTMGRP_IPV6_ROUTE-ãã®ã°ã«ãŒãã¯ãIPv6ã¢ãã¬ã¹ã®ã«ãŒãã£ã³ã°ããŒãã«ã®å€æŽã®éç¥ãåãåããŸã
nlmsghdrããããŒæ§é ã®åŸã«ã¯ãåžžã«ããŒã¿ãããã¯ãžã®ãã€ã³ã¿ãŒããããŸãã ãã¯ããžã®ã¢ã¯ã»ã¹ã¯ãã¯ãã䜿çšããŠååŸã§ããŸãããããã«ã€ããŠã¯åŸã§èª¬æããŸãã
ããããªã³ã¯ãã¯ã
ãã®å Žåãæã䟿å©ãªãã¯ãã¯æ¬¡ã®ãšããã§ãã
NLMSG_ALIGN-ããããªã³ã¯ã¡ãã»ãŒãžã®ãµã€ãºãæãè¿ã倧ããå¢çæŽåå€ã«äžžããŸãã
NLMSG_LENGTH-ãã©ã¡ãŒã¿ãŒãšããŠããŒã¿ãã£ãŒã«ãïŒãã€ããŒãïŒã®ãµã€ãºãååŸããnlmsghdrããããŒã®nlmsg_lenãã£ãŒã«ãã«æžã蟌ãããã®å¢çæŽåãµã€ãºå€ãè¿ããŸãã
NLMSG_SPACE-ããããªã³ã¯ãã±ããå ã®æå®ãããé·ãã®ããŒã¿ãå æãããµã€ãºãè¿ããŸãã
NLMSG_DATA-æž¡ãããnlmsghdrããããŒã«é¢é£ä»ããããããŒã¿ãžã®ãã€ã³ã¿ãŒãè¿ããŸãã
NLMSG_NEXT-å€ãã®éšåã§æ§æãããã¡ãã»ãŒãžã®æ¬¡ã®éšåãè¿ããŸãã ãã®ãã¯ãã¯ããã«ãããŒãã¡ãã»ãŒãžã§æ¬¡ã®nlmsghdrããããŒãåãå ¥ããŸãã åŒã³åºãåŽã¢ããªã±ãŒã·ã§ã³ã¯ãçŸåšã®nlmsghdr ããããŒã® NLMSG_DONEãã©ã°ã確èªããå¿ èŠããããŸããã¡ãã»ãŒãžãåŠçããããšãã«ãé¢æ°ã¯NULLãè¿ããŸããã 2çªç®ã®ãã©ã¡ãŒã¿ãŒã¯ãã¡ãã»ãŒãžãããã¡ãŒã®æ®ãã®éšåã®ãµã€ãºãèšå®ããŸãã ãã¯ãã¯ãã¡ãã»ãŒãžããããŒã®ãµã€ãºã ããã®å€ãæžãããŸãã
NLMSG_OK-ã¡ãã»ãŒãžãåãæšãŠããããéã¢ã»ã³ããªãæåããå Žåãtrueãè¿ããŸãã
NLMSG_PAYLOAD -nlmsghdrããããŒã«é¢é£ä»ããããŠãããã€ããŒãããŒã¿ã®ãµã€ãºãè¿ããŸãã
çè«ããå®è·µãžã
ããã ç§ã¯ãã§ã«éå±ãªçè«ã«éå±ããŠãããšæããŸã:)äœããæ··ä¹±ããããç解ã§ããªãããã«æããããããããŸãã-ç§ã¯èª¬æçãªäŸã§ãã¹ãŠãåãããšããŸããæ¬åœã«ããã«ã¯è€éãªãã®ã¯ãããŸããã
以äžã¯ããããã¯ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ãšã«ãŒãã£ã³ã°ããŒãã«ã®å€æŽã®éç¥ãåãåãçŽæã®ã¢ããªã±ãŒã·ã§ã³ã§ãã
ãã®äŸã§ã¯ãããã€ãã®æ°ããæ§é ãå°å ¥ãããŠããŸãã
struct iovec { void *iov_base; // __kernel_size_t iov_len; // };
ãã®æ§é ã¯ãnetlinkãœã±ãããä»ããŠéä¿¡ãããæçšãªããŒã¿ã®ãªããžããªãšããŠæ©èœããŸãã iov_baseãã£ãŒã«ãã«ã¯ããã€ãé åãžã®ãã€ã³ã¿ãŒãå²ãåœãŠãããŸãã ã¡ãã»ãŒãžããŒã¿ãæžã蟌ãŸããã®ã¯ããã®ãã€ãé åã§ãã
struct msghdr { void *msg_name; // ( ) int msg_namelen; // struct iovec *msg_iov; // __kernel_size_t msg_iovlen; // void *msg_control; // , __kernel_size_t msg_controllen; // unsigned msg_flags; // };
ãã®æ§é ã¯ããœã±ãããä»ããŠçŽæ¥éä¿¡ãããŸãã æçšãªããŒã¿ã®ãããã¯ãžã®ãã€ã³ã¿ããããã¯ããŒã¿ã®éãããã³å€ãã®å ŽåBSDãã©ãããã©ãŒã ããæ¥ãè¿œå ã®ãã©ã°ãšãã£ãŒã«ããå«ãŸããŠããŸãã
struct ifinfomsg { unsigned char ifi_family; // (AF_UNSPEC) unsigned short ifi_type; // int ifi_index; // unsigned int ifi_flags; // unsigned int ifi_change; // , 0xFFFFFFFF };
ãã®æ§é ã¯ããããã¯ãŒã¯ããã€ã¹ããã®ãã¡ããªãã¿ã€ããã€ã³ããã¯ã¹ãããã³ãã©ã°ãè¡šãããã«äœ¿çšãããŸãã
struct ifaddrmsg { unsigned char ifa_family; // (AF_INET AF_INET6) unsigned char ifa_prefixlen; // ( ) unsigned char ifa_flags; // unsigned char ifa_scope; // int ifa_index; // , ifinfomsg };
ãã®æ§é ã¯ããããã¯ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ã«å²ãåœãŠããããããã¯ãŒã¯ã¢ãã¬ã¹ãè¡šãããã«äœ¿çšãããŸãã
struct rtattr { unsigned short rta_len; // unsigned short rta_type; // /* */ }
ãã®æ§é ã¯ãæ¥ç¶ãã©ã¡ãŒã¿ãŒãŸãã¯ã¢ãã¬ã¹ãæ ŒçŽããããã«äœ¿çšãããŸãã
ãœãŒã¹ã³ãŒãã¢ãã¿ãŒ
#include <errno.h> #include <stdio.h> #include <memory.h> #include <net/if.h> #include <arpa/inet.h> #include <sys/socket.h> #include <linux/rtnetlink.h> // , netlink // rtattr void parseRtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) { memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); while (RTA_OK(rta, len)) { // if (rta->rta_type <= max) { tb[rta->rta_type] = rta; // } rta = RTA_NEXT(rta,len); // } } int main() { int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); // if (fd < 0) { printf(" netlink : %s", (char*)strerror(errno)); return 1; } struct sockaddr_nl local; // char buf[8192]; // struct iovec iov; // iov.iov_base = buf; // buf iov iov.iov_len = sizeof(buf); // memset(&local, 0, sizeof(local)); // local.nl_family = AF_NETLINK; // local.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE; // local.nl_pid = getpid(); // // netlink - struct msghdr msg; { msg.msg_name = &local; // - msg.msg_namelen = sizeof(local); // msg.msg_iov = &iov; // msg.msg_iovlen = 1; // } if (bind(fd, (struct sockaddr*)&local, sizeof(local)) < 0) { // printf(" netlink : %s", (char*)strerror(errno)); close(fd); return 1; } // while (1) { ssize_t status = recvmsg(fd, &msg, MSG_DONTWAIT); // bind() // if (status < 0) { if (errno == EINTR || errno == EAGAIN) { usleep(250000); continue; } printf(" netlink: %s", (char*)strerror(errno)); continue; } if (msg.msg_namelen != sizeof(local)) { // , :) printf(" "); continue; } // struct nlmsghdr *h; // for (h = (struct nlmsghdr*)buf; status >= (ssize_t)sizeof(*h); ) { // int len = h->nlmsg_len; // int l = len - sizeof(*h); // char *ifName; // if ((l < 0) || (len > status)) { printf(" : %i", len); continue; } // if ((h->nlmsg_type == RTM_NEWROUTE) || (h->nlmsg_type == RTM_DELROUTE)) { // - printf(" \n"); } else { // char *ifUpp; // char *ifRunn; // struct ifinfomsg *ifi; // , struct rtattr *tb[IFLA_MAX + 1]; // , IFLA_MAX rtnetlink.h ifi = (struct ifinfomsg*) NLMSG_DATA(h); // parseRtattr(tb, IFLA_MAX, IFLA_RTA(ifi), h->nlmsg_len); // if (tb[IFLA_IFNAME]) { // , ifName = (char*)RTA_DATA(tb[IFLA_IFNAME]); // } if (ifi->ifi_flags & IFF_UP) { // UP ifUpp = (char*)"UP"; } else { ifUpp = (char*)"DOWN"; } if (ifi->ifi_flags & IFF_RUNNING) { // RUNNING ifRunn = (char*)"RUNNING"; } else { ifRunn = (char*)"NOT RUNNING"; } char ifAddress[256]; // struct ifaddrmsg *ifa; // struct rtattr *tba[IFA_MAX+1]; // ifa = (struct ifaddrmsg*)NLMSG_DATA(h); // parseRtattr(tba, IFA_MAX, IFA_RTA(ifa), h->nlmsg_len); // if (tba[IFA_LOCAL]) { // inet_ntop(AF_INET, RTA_DATA(tba[IFA_LOCAL]), ifAddress, sizeof(ifAddress)); // IP } switch (h->nlmsg_type) { // case RTM_DELADDR: printf(" %s\n", ifName); break; case RTM_DELLINK: printf(" %s\n", ifName); break; case RTM_NEWLINK: printf(" %s, %s %s\n", ifName, ifUpp, ifRunn); break; case RTM_NEWADDR: printf(" %s: %s\n", ifName, ifAddress); break; } } status -= NLMSG_ALIGN(len); // ( - , :)) h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); // } usleep(250000); // , } close(fd); // return 0; }
ããã°ã©ã ã®ã³ã³ãã€ã«ïŒ
gcc monitor.c -o monitor
ãããŠä»äºã®çµæïŒ
ã³ãŒãã®èª¬æã
ããã°ã©ã ãéå§ããåŸãnetlinkãœã±ãããäœæããäœæã®æåã確èªããŸãã 次ã«ãå¿ èŠãªå€æ°ã宣èšãããããŒã«ã«ã¢ãã¬ã¹æ§é ãèšå®ãããŸãã ããã§ããµãã¹ã¯ã©ã€ãããã¡ãã»ãŒãžã®ã°ã«ãŒãã瀺ããŸãïŒRTMGRP_LINKãRTMGRP_IPV4_IFADDRãRTMGRP_IPV4_ROUTEã
ãŸããã¡ãã»ãŒãžæ§é ã宣èšãã1ã€ã®ããŒã¿ãããã¯ãããã«é¢é£ä»ããŸãã
ãã®åŸãbindïŒïŒã䜿çšããŠãœã±ãããžã®ãã€ã³ããè¡ãããŸãã ãã®åŸãæå®ãããã°ã«ãŒãã®ã¡ãã»ãŒãžã«ãµãã¹ã¯ã©ã€ãããŸãã ãœã±ãããä»ããŠã¡ãã»ãŒãžãåä¿¡ã§ããŸãã
ãã®åŸã«ããœã±ããããã¡ãã»ãŒãžãåä¿¡ããããã®ç¡éã«ãŒããç¶ããŸãã ãªããªã åä¿¡ããããŒã¿ãããã¯ã«ã¯ãããã€ãã®ããããŒãšããŒã¿ãé¢é£ä»ããããšãã§ããŸããããããªã³ã¯ãã¯ãã䜿çšããŠãåä¿¡ãããã¹ãŠã®ããŒã¿ã®äžŠã¹æ¿ããéå§ããŸãã
æ°ããã¡ãã»ãŒãžã¯ããããããã€ã³ã¿ãŒstruct nlmsghdr * hã«ãããŸãã
ããã§ãã¡ãã»ãŒãžèªäœã解æã§ããŸãã nlmsg_typeãã£ãŒã«ããèŠãŠãã©ã®ãããªã¡ãã»ãŒãžãå±ãããã調ã¹ãŸãã ã«ãŒãã£ã³ã°ããŒãã«ã«æ¥ç¶ãããŠããå Žåãã¡ãã»ãŒãžãåºåããŠæ¬¡ã®ã¡ãã»ãŒãžã«é²ã¿ãŸãã ããã§ãªãå Žåã¯ã詳现ã«ç解ãå§ããŸãã
rtattrãªãã·ã§ã³ã®é åã宣èšããããã¹ãŠã®å¿ èŠãªããŒã¿ãè¿œå ãããŸãã parseRtattrãã«ããŒé¢æ°ã¯ããã®ããŒã¿ãååŸããŸãã netlinkãã¯ãã䜿çšããŠãæå®ãããé åã«ãifinfomsgãŸãã¯ifaddrmsgæ§é äœã®ããŒã¿ãããã¯ããã®ãã¹ãŠã®å±æ§ãèšå®ããŸãã
å±æ§ã§æºããããé åãåãåã£ãåŸããããã®å€ãæäœãåæãå°å·ã§ããŸãã
åå±æ§ã¯ãã€ã³ããã¯ã¹ã«ãã£ãŠã¢ã¯ã»ã¹ãããŸãã ãã¹ãŠã®ã€ã³ããã¯ã¹ã¯ããããªã³ã¯ããããŒãã¡ã€ã«ã§å®çŸ©ãããã³ã¡ã³ãåãããŠããŸãã
ãã®å Žåã次ã®ã€ã³ããã¯ã¹ã䜿çšããŸãã
IFLA_IFNAME-ã€ã³ã¿ãŒãã§ã€ã¹åãæã€å±æ§ã€ã³ããã¯ã¹ã
IFA_LOCAL-ããŒã«ã«IPã¢ãã¬ã¹ãæã€å±æ§ã€ã³ããã¯ã¹ã
çµå±ã®ãšãããäœãèµ·ãã£ãã®ãã«ã€ããŠã®å®å šãªæ å ±ããããç»é¢ã«æ å ±ãå°å·ã§ããŸãã
以äžã§ãã ãã®è³æã誰ãã«åœ¹ç«ã€ããšãæ¬åœã«é¡ã£ãŠããŸãã
ååãªäººæ°ïŒè€æ°ã®äººãããå Žå:)ïŒ-ç¶ç·šãæžããŠãããšãã°ã«ãŒãã«ã¢ãžã¥ãŒã«ãšã®çžäºäœçšãIPv6ã§ã®äœæ¥ã®å®è£ ãæ€èšã§ããŸãã
èšäºãæžããšãã次ã®ãã®ã䜿çšãããŸããã
1. tools.ietf.org/html/rfc3549
2. www.linuxjournal.com/article/7356
ãæž èŽããããšãããããŸããã