2010/10/10(Sun)カーネルモジュール内でIPv4/IPv6アドレスをdumpする

2010/10/10 13:51 Software::Linux
Linuxカーネル内でstruct in_addrやstruct in6_addrなIPv4, IPv6アドレスをprintkしたい時のメモ。

マクロがなくなった

一昔前まであったIPv6用のNIP6はどうもObsoleteになっている模様。
IPv4のNIPQUADは少なくともlinux-2.6.32.16では残っているようだけど。

▼NIPQUAD (/include/linux/kernel.h:546)
#define NIPQUAD(addr) \
    ((unsigned char *)&addr)[0], \
    ((unsigned char *)&addr)[1], \
    ((unsigned char *)&addr)[2], \
    ((unsigned char *)&addr)[3]
#define NIPQUAD_FMT "%u.%u.%u.%u"
▼NIP6
#define NIP6(addr) \
	ntohs((addr).s6_addr16[0]), \
	ntohs((addr).s6_addr16[1]), \
	ntohs((addr).s6_addr16[2]), \
	ntohs((addr).s6_addr16[3]), \
	ntohs((addr).s6_addr16[4]), \
	ntohs((addr).s6_addr16[5]), \
	ntohs((addr).s6_addr16[6]), \
	ntohs((addr).s6_addr16[7])
#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
#define NIP6_SEQFMT "%04x%04x%04x%04x%04x%04x%04x%04x"
昔は、このマクロのおかげで
struct in6_addr in6;
printk("IPv6: " NIP6_FMT "\n", NIP6(in6));
なんて書けていたのだけど…

IPアドレス用書式指定子

/include/net/ip_vs.h:90あたりで使われているように、新しい書式指定子が出来た模様。

▼/include/net/ip_vs.h
#ifdef CONFIG_IP_VS_IPV6
    if (af == AF_INET6)
        len = snprintf(&buf[*idx], buf_len - *idx, "[%pI6]",
                   &addr->in6) + 1;
    else
#endif
        len = snprintf(&buf[*idx], buf_len - *idx, "%pI4",
                   &addr->ip) + 1;
というわけで、%pI6を指定して、そこにstruct in6_addr *を与えればよいようです。楽ちんだー。
struct in6_addr in6;
printk("IPv6: %pI6\n", &in6);
この感じからして、NIPQUADも%pI4に置き換わっていくんだろうな。