1. bpf_printkのフォーマット指定子%pI4
を使う
2つ目の方法とは違い、ビッグエンディアンに直す必要はない。
フォーマット指定子がp
から始まっていることからわかるように、引数にはアドレスを渡す必要があるので注意。
参考:https://qiita.com/todok-r/items/d754fb29930431c9efa0
struct iphdr *iph = (略); bpf_printk("source addr: %pI4", &iph->saddr);
出力↓
source addr: 192.168.0.1
2. bpf_ntohlでビッグエンディアンに直し、自力でIPアドレスの形式に整形する
bpf_ntohs
という関数もあるが、こちらは16bitの値を返す。IPアドレスは32bitなので、bpf_ntohl
を使う必要がある。
※なお、64bitの値を返すbpf_be64_to_cpu
という関数も定義されているが、詳細は不明。
整形についてはinet_ntoa関数が使えると聞いたが、うまく実行できなかったため自力で関数ip_int2str
を作った。
struct iphdr *iph = (略); char str_saddr[16] = "XXX.XXX.XXX.XXX"; ip_int2str(bpf_ntohl(iph->saddr), str_saddr); bpf_printk("source addr: %s", str_saddr);
void ip_int2str(unsigned int ip, char *ip_str) { // IPv4アドレスは最長15文字のはずなんでNULL終端含めても16文字で足りる BPF_SNPRINTF(ip_str, 16, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); }
出力(方法1と同じ)↓
source addr: 192.168.0.1