netfilter フックを登録するカーネル モジュールを作成しています。sk_buff->saddr
メンバーを使用して発信者の IP アドレスを取得しようとしています。人間が読める iexxxx 形式で IP を取得する方法はありますか?
関数は見つかりましたinet_ntop()
が、カーネル ヘッダーでは使用できないようです。\xC0\xA8\x00\x01 を 192.168.0.1 に変換するにはどうすればよいですか?
netfilter フックを登録するカーネル モジュールを作成しています。sk_buff->saddr
メンバーを使用して発信者の IP アドレスを取得しようとしています。人間が読める iexxxx 形式で IP を取得する方法はありますか?
関数は見つかりましたinet_ntop()
が、カーネル ヘッダーでは使用できないようです。\xC0\xA8\x00\x01 を 192.168.0.1 に変換するにはどうすればよいですか?
printk() によって提供される %pI4 拡張フォーマット指定子を使用する必要があります。
printk(KERN_DEBUG "IP addres = %pI4\n", &local_ip);
include/linux/kernel.h には 2 つのマクロが定義されています。
IPv4 アドレスの場合は NIPQUAD、IPv6 アドレスの場合は NIP6。
#define NIPQUAD(addr) \
((unsigned char *)&addr)[0], \
((unsigned char *)&addr)[1], \
((unsigned char *)&addr)[2], \
((unsigned char *)&addr)[3]
#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])
カーネルソースには、これらを利用してIPアドレスを人間が読める形式で出力する例がたくさんあります。例えば:
printk(KERN_DEBUG "Received packet from source address: %d.%d.%d.%d!\n",NIPQUAD(iph->saddr));
お役に立てれば。
単純。「xxxx」形式の IP アドレスは、理由からドット付きクワッドと呼ばれます。各数字は 1 バイトを表し、アドレスは合計 4 バイトになります。
したがって、4 バイトのアドレスを使用すると、各バイトの 10 進値を単純に出力できます。
簡単で汚い例 (printf を選択した出力関数に置き換えます):
unsigned char *addr = (unsigned char*)sk_buff->addr;
printf("%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
strtolを使用して、各ピースを整数形式に変換できます。
/* Convinience union to __be32 to ip address */
union ip_address {
u8 a[4];
__be32 saddr;
};
IPアドレスはa[0].a[1].a[2].a[3]で取得できました