Bir paket üzerinde bazı verileri çekirdek alanından eklemeye çalışıyorum. Bir yankı istemcim ve sunucum var. Komut satırına şu şekilde yazdım: ./client "message" ve sunucu sadece onu tekrar yansıtır. Sunucu ./server ile çalıştırıldı.Çekirdek alanından bir pakete nasıl veri eklenir?
Artık, istemci ve sunucu iki farklı makinede (VM olabilir). İstemci makinesinde çalışan bir çekirdek modülü yazıyorum. Paket, makineden çıktığında "mesaj" dan sonra "12345" ibaresini eklemektir. Aşağıdaki kodu ben sunuyorum.
/*
* 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");
ben çekirdek uzaydan istemci makinesinden gönderirken "message12345" olmak "mesajı" almak istiyorum. Böylece sunucu "message12345" mesajını alıp yankılanacak ve istemci sadece "message12345" mesajını okuyacaktır. Ancak skb_put() ve skb_add_data() işlevleriyle ilgili sorun yaşıyorum. Benim için hangi hatanın yapıldığını anlamıyorum. Kimse bana kodla yardım edebilirse, son derece minnettar olacağım. Şimdiden teşekkürler. Ayrıca Makefile'ye kolaylık sağlamak için veriyorum. Bu, bir çekirdek için değil, dağıtım çekirdeği içindir. skb-> kuyruk ben çekirdek uzayda yeni paketleri oluşturmak zorunda kalacak kadar küçüktür ki -
#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
Şimdi skb-> sonu olduğuna ikna olmuş. alloc_skb() skb_reser() skb_header_pointer() ve yeni bir skb oluşturmak için diğer kullanışlı skb işlevlerini kullandım, ancak şu an aklımda olan şey paket akış yolunda yeni oluşturulan paketin nasıl yönlendirileceğidir. . Nasıl kullanılır?
ip_route_me_harder() Öneri için xtables-addons paketine baktım, ancak kullandıkları işlev linux kernelinden farklı. Herhangi bir öneri memnuniyetle karşılanmaktadır.
Yardım için teşekkürler. Evet, uzunluk alanları beni çok rahatsız etti. –
Ayrıca, çekirdek alanında kontrol toplamı benim için oldukça belirsizdi. –
@Fred bunu http://stackoverflow.com/questions/12529497/how-to-append-data-on-a-packet-from-kernel-space – user2087340