12

netfilter フックを登録するカーネル モジュールを作成しています。sk_buff->saddrメンバーを使用して発信者の IP アドレスを取得しようとしています。人間が読める iexxxx 形式で IP を取得する方法はありますか?

関数は見つかりましたinet_ntop()が、カーネル ヘッダーでは使用できないようです。\xC0\xA8\x00\x01 を 192.168.0.1 に変換するにはどうすればよいですか?

4

6 に答える 6

17

printk() によって提供される %pI4 拡張フォーマット指定子を使用する必要があります。

printk(KERN_DEBUG "IP addres = %pI4\n", &local_ip);
于 2012-11-16T11:52:56.117 に答える
13

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));

お役に立てれば。

于 2009-04-02T15:28:27.093 に答える
2

単純。「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]);
于 2009-02-25T05:07:48.730 に答える
0

strtolを使用して、各ピースを整数形式に変換できます。

于 2009-02-25T05:06:53.693 に答える
0
/* Convinience union to __be32 to ip address  */
union ip_address {
    u8 a[4];
    __be32 saddr;
};

IPアドレスはa[0].a[1].a[2].a[3]で取得できました

于 2009-02-27T04:11:22.267 に答える