我想在內核空間中回顯一個數據包。我使用端口6000在這臺機器上運行一個回顯服務器。 現在客戶端在另一臺機器上運行,將數據發送到回顯服務器。現在,我想要做的是從內核空間回顯數據包。我不想用數據包來困擾服務器,它會從內核空間靜靜地迴應。我在下面提供我的代碼:如何使用netfilter掛鉤在內核空間中回顯數據包?
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
#include <linux/netdevice.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/mm.h>
#include <linux/err.h>
#include <linux/crypto.h>
#include <linux/init.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <net/ip.h>
#include <net/udp.h>
#include <net/route.h>
#include <net/checksum.h>
#include <linux/netfilter_ipv4.h>
#define IP_HDR_LEN 20
#define UDP_HDR_LEN 8
#define TOT_HDR_LEN 28
static unsigned int pkt_echo_begin(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *));
static struct nf_hook_ops pkt_echo_ops __read_mostly = {
.pf = NFPROTO_IPV4,
.priority = 1,
.hooknum = NF_INET_PRE_ROUTING,
.hook = pkt_echo_begin,
};
static int __init pkt_echo_init(void)
{
printk(KERN_ALERT "\npkt_echo module started ...");
return nf_register_hook(&pkt_echo_ops);
}
static void __exit pkt_echo_exit(void)
{
nf_unregister_hook(&pkt_echo_ops);
printk(KERN_ALERT "pkt_echo module stopped ...");
}
static unsigned int pkt_echo_begin (unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct iphdr *iph;
struct udphdr *udph;
unsigned char *data;
unsigned char *temp;
__u16 dst_port, src_port;
int data_len;
if (skb) {
iph = (struct iphdr *) skb_header_pointer (skb, 0, 0, NULL);
if (iph && iph->protocol &&(iph->protocol == IPPROTO_UDP)) {
udph = (struct udphdr *) skb_header_pointer (skb, IP_HDR_LEN, 0, NULL);
src_port = ntohs (udph->source);
dst_port = ntohs (udph->dest);
if (dst_port == 6000) {
printk(KERN_ALERT "\nUDP packet goes in");
data = (unsigned char *) skb_header_pointer (skb, TOT_HDR_LEN, 0, NULL);
data_len = skb->len - TOT_HDR_LEN;
struct sk_buff *newskb;
struct iphdr *newiph;
struct udphdr *newudph;
unsigned char *newdata;
unsigned int newdata_len;
newskb = skb_copy(skb, GFP_ATOMIC);
newiph = (struct iphdr *) skb_header_pointer (newskb, 0, 0, NULL);
newudph = (struct udphdr *) skb_header_pointer (newskb, IP_HDR_LEN, 0, NULL);
newdata = (unsigned char *) skb_header_pointer (newskb, TOT_HDR_LEN, 0, NULL);
newiph->saddr = iph->daddr;
newiph->daddr = iph->saddr;
newudph->source = udph->dest;
newudph->dest = udph->source;
struct sk_buff *tempskb;
tempskb = skb_copy(skb, GFP_ATOMIC);
*tempskb = *skb;
*skb = *newskb;
*newskb = *tempskb;
kfree_skb(newskb);
}
}
}
return NF_ACCEPT;
}
module_init(pkt_echo_init);
module_exit(pkt_echo_exit);
MODULE_AUTHOR("Rifat Rahman Ovi: <[email protected]>");
MODULE_DESCRIPTION("Echoing a packet from kernel space.");
MODULE_LICENSE("GPL");
現在我不明白需要什麼。我在PRE_ROUTING鉤子中捕獲了數據包。 然後我創建了一個新的skb,從舊接收的skb中填充它,然後更改源地址(saddr),目標地址(daddr),源端口(源)和目標端口(dest),以便數據包可以從PRE_ROUTING鉤子轉發。由於路由 的決定是在數據包從鉤子傳遞之後做出的,我尋找要轉發到它的源的數據包。但由於某種原因,它不是這樣做的。數據包被接收,並且所有內容都被更改,但數據包似乎沒有向後移動。我不明白缺失的是什麼,還有什麼需要讓它工作。更具體地說,從PRE_ROUTING鉤子發送數據包到網絡需要什麼?
你卡在哪裏?什麼不起作用? **你的問題是什麼?**(「任何人都可以幫助我嗎?」不是一個可以接受的問題) –
感謝提示:「任何人都可以幫助我嗎?」不是一個可以接受的問題「......我永遠不會發布像這樣的任何東西..不久我會編輯該問題是具體的。放置代碼並尋求幫助實際上是無稽之談。 –
在內核空間中做這件事的原因是什麼?或只是學習? – Fingolfin