我想從內核空間附加一些數據包。我有一個回聲客戶端和服務器。我輸入如下命令行:./client「message」,服務器只是回顯它。該服務器使用./server運行。如何在內核空間追加數據包?
現在,客戶端和服務器位於兩臺不同的機器上(可能是虛擬機)。我正在編寫一個在客戶端機器上運行的內核模塊。它的工作是在數據包離開機器時在「消息」之後附加「12345」。我正在呈現下面的代碼。
/*
* This is ibss_obsf_cat.c
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/udp.h>
#include <linux/ip.h>
#undef __KERNEL__
#include <linux/netfilter_ipv4.h>
#define __KERNEL__
/*
* Function prototypes ...
*/
static unsigned int cat_obsf_begin (unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *));
static void hex_dump (char str[], int len)
{
}
/*
* struct nf_hook_ops instance initialization
*/
static struct nf_hook_ops cat_obsf_ops __read_mostly = {
.pf = NFPROTO_IPV4,
.priority = 1,
.hooknum = NF_IP_POST_ROUTING,
.hook = cat_obsf_begin,
};
/*
* Module init and exit functions.
* No need to worry about that.
*/
static int __init cat_obsf_init (void)
{
printk(KERN_ALERT "cat_obsf module started...\n");
return nf_register_hook(&cat_obsf_ops);
}
static void __exit cat_obsf_exit (void)
{
nf_unregister_hook(&cat_obsf_ops);
printk(KERN_ALERT "cat_obsf module stopped...\n");
}
/*
* Modification of the code begins here.
* Here are all the functions and other things.
*/
static unsigned int cat_obsf_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 dt[] = "12345";
unsigned char *tmp;
unsigned char *ptr;
int i, j, len;
if (skb){
iph = ip_hdr(skb);
if (iph && iph->protocol && (iph->protocol == IPPROTO_UDP)){
udph = (struct udphdr *) ((__u32 *)iph + iph->ihl);
data = (char *)udph + 8;
if(ntohs(udph->dest) == 6000){
for (i=0; data[i]; i++);
len = i;
//printk(KERN_ALERT "\nData length without skb: %d", len);
//printk(KERN_ALERT "Data is: %s", data);
//printk(KERN_ALERT "dt size: %lu", sizeof(dt));
//printk(KERN_ALERT "skb->len: %d", skb->len);
tmp = kmalloc(200*sizeof(char), GFP_KERNEL);
memcpy(tmp, data, len);
ptr = tmp + len;
memcpy(ptr, dt, sizeof(dt));
printk(KERN_ALERT "tmp: %s", tmp);
printk(KERN_ALERT "skb->tail: %d", skb->tail);
//skb_put(skb, sizeof(dt));
printk(KERN_ALERT "skb->end: %d", skb->end);
printk(KERN_ALERT "skb->tail: %d", skb->tail);
printk(KERN_ALERT "skb->tail(int): %d", (unsigned int)skb->tail);
//memset(data, 0, len + sizeof(dt));
//memcpy(data, tmp, len + sizeof(dt));
//skb_add_data(skb, tmp, len+sizeof(dt));
printk(KERN_ALERT "Now data is: %s", data);
for(i=0; data[i]; i++);
printk(KERN_ALERT "data length: %d", i);
kfree(tmp);
}
}
}
return NF_ACCEPT;
}
/*
* Nothing to be touched hereafter
*/
module_init(cat_obsf_init);
module_exit(cat_obsf_exit);
MODULE_AUTHOR("Rifat");
MODULE_DESCRIPTION("Module for packet mangling");
MODULE_LICENSE("GPL");
我想在從內核空間發出客戶機時將「消息」設置爲「message12345」。所以服務器會得到「message12345」並回顯,客戶端將只讀「message12345」但我在使用skb_put()和skb_add_data()函數時遇到了問題。我不明白我犯了什麼錯誤。如果任何人都可以幫助我的代碼,我將非常感激。提前致謝。爲了方便,我也給了Makefile。這是爲了分發內核,而不是爲了構建內核。
#If KERNELRELEASE is defined, we've been invoked from the
#kernel build system and use its language
ifneq ($(KERNELRELEASE),)
obj-m := ibss_obsf_cat.o
#Otherwise we were called directly from the command
#line; invoke the kernel build system.
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
現在,我很相信, 是skb->結束 - 是skb->尾 是如此之小,我必須創建在內核空間的新包。我已經使用 alloc_skb() skb_reserve() skb_header_pointer() 和其他有用的skb函數來創建一個新的skb,但我想到的東西是如何路由新創建的數據包在數據包的流動路徑。如何使用
ip_route_me_harder() 我查看了xtables-addons軟件包中的建議,但是它們使用的函數與linux內核中的函數不同。歡迎任何建議。
感謝您的幫助。是的,長度的領域很困擾我。 –
而且內核空間中的校驗起初對我來說相當模糊。 –
@Fred你可以評論這也http://stackoverflow.com/questions/12529497/how-to-append-data-on-a-packet-from-kernel-space – user2087340