Tôi đang cố nối thêm một số dữ liệu trên một gói từ không gian hạt nhân. Tôi có một máy khách và máy chủ echo. Tôi gõ vào dòng lệnh như: ./client "message" và server chỉ lặp lại nó. Máy chủ được chạy với ./server.Làm cách nào để nối thêm dữ liệu trên gói từ không gian hạt nhân?
Bây giờ, máy khách và máy chủ nằm trên hai máy khác nhau (có thể là máy ảo). Tôi đang viết một mô-đun hạt nhân chạy trên máy khách. Công việc của nó là để thêm "12345" sau khi "tin nhắn" trong khi gói tin đi ra khỏi máy. Tôi đang trình bày mã dưới đây.
/*
* 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");
Tôi muốn nhận được "tin nhắn" là "message12345" trong khi gửi ra khỏi máy khách từ không gian hạt nhân. Vì vậy, máy chủ sẽ nhận được "message12345" và echo nó trở lại, và khách hàng sẽ chỉ đọc "message12345" Nhưng tôi gặp rắc rối với skb_put() và skb_add_data() chức năng. Tôi không hiểu tôi đã mắc lỗi gì. Nếu bất cứ ai có thể giúp tôi với mã, tôi sẽ rất biết ơn. Cảm ơn trước. Tôi cũng cho Makefile để thuận tiện. Điều này là dành cho hạt nhân phân phối, không phải cho một hạt nhân được xây dựng.
#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
Bây giờ tôi khá thuyết phục rằng skb-> cuối - skb-> đuôi là quá nhỏ mà tôi sẽ phải tạo gói mới trong không gian hạt nhân. Tôi đã sử dụng alloc_skb() skb_reserve() skb_header_pointer() và các chức năng skb hữu ích khác để tạo skb mới, nhưng điều tôi đang hết ý tưởng là cách định tuyến gói mới được tạo trong đường dẫn gói . Cách sử dụng
ip_route_me_harder() Tôi đã xem gói xtables-addons để gợi ý, nhưng chức năng mà họ đã sử dụng khác với chức năng trong hạt nhân Linux. Bất kỳ đề nghị được hoan nghênh.
Cảm ơn sự giúp đỡ của bạn. Vâng, các trường độ dài làm tôi lo lắng rất nhiều. –
Và cũng kiểm tra trong không gian hạt nhân khá mơ hồ với tôi lúc đầu. –
@Fred bạn có thể nhận xét về điều này cũng http://stackoverflow.com/questions/12529497/how-to-append-data-on-a-packet-from-kernel-space – user2087340