私は基本的に与えられたインターフェイス(下のコード)のすべてのパケットにメッセージを印刷する単純なカーネルモジュールを持っています。どのカーネルを使用してコンパイルして実行しても、システムの実行中に数秒間中断されます。 Linux自体では何のメッセージも受け取れませんが、VMWareはゲストOSがCPUを停止したと言います。モジュールはエラーなしでコンパイルされロードされます。どんなアイデアがありますか?どのようにデバッグするのですか? Journalctlは何も表示しません。どんな助けでも大変感謝します。私はこれについてあまり慣れておらず、デバッグ方法がわかりません。
仮想マシンログ:
2024-02-01T11:57:03.994Z In(05) vcpu-0 MsgHint: msg.monitorevent.halt
2024-02-01T11:57:03.994Z In(05)+ vcpu-0 The CPU has been disabled by the guest operating system. Power off or reset the virtual machine.
2024-02-01T11:57:03.994Z In(05)+ vcpu-0 ---------------------------------------```
カーネルモジュールのソースコード:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/inet.h>
static struct nf_hook_ops netfilter_ops;
static char *interface = "ens33";
module_param(interface, charp, 0);
static unsigned int hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) {
char source[16], dest[16];
if (!skb) {
return NF_ACCEPT;
}
if (strcmp(state->in->name, interface) == 0 || strcmp(state->out->name, interface) == 0) {
struct iphdr *ip_header = ip_hdr(skb);
if (!ip_header) {
return NF_ACCEPT;
}
snprintf(source, 16, "%pI4", &ip_header->saddr);
snprintf(dest, 16, "%pI4", &ip_header->daddr);
printk(KERN_INFO "Packet logged on %s: Source IP: %s, Destination IP: %s\n", interface, source, dest);
}
return NF_ACCEPT;
}
static int __init my_module_init(void) {
netfilter_ops.hook = hook_func;
netfilter_ops.pf = PF_INET;
netfilter_ops.hooknum = NF_INET_PRE_ROUTING;
netfilter_ops.priority = NF_IP_PRI_FIRST;
nf_register_net_hook(&init_net, &netfilter_ops);
printk(KERN_INFO "Kernel module initialized on interface %s\n", interface);
return 0;
}
static void __exit my_module_exit(void) {
nf_unregister_net_hook(&init_net, &netfilter_ops);
printk(KERN_INFO "Kernel module removed\n");
}
module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("foo bar baz");
MODULE_DESCRIPTION("Netfilter packet logging module");
MODULE_VERSION("0.1");
ベストアンサー1
まあ、私は直接答えを見つけたようです。問題は、フックメソッドが呼び出されたときにステータス->インまたはステータス->アウトのいずれかを設定できることです(明らかに)。修正後の関連行は次のとおりです。
if ((state->in && strcmp(state->in->name, interface) == 0) || (state->out && strcmp(state->out->name, interface) == 0)) {