मैं कर्नेल स्पेस से पैकेट पर कुछ डेटा जोड़ने की कोशिश कर रहा हूं। मेरे पास एक गूंज क्लाइंट और सर्वर है। मैं कमांड लाइन में टाइप करता हूं जैसे: ./client "message" और सर्वर बस इसे वापस ले जाता है। सर्वर .ssver के साथ चलाया गया था।कर्नेल स्पेस से पैकेट पर डेटा कैसे जोड़ना है?
अब, ग्राहक और सर्वर दो अलग-अलग मशीनों पर हैं (वीएम हो सकते हैं)। मैं एक कर्नेल मॉड्यूल लिख रहा हूं जो क्लाइंट मशीन पर चलता है। इसका काम "संदेश" के बाद "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");
मैं कर्नेल स्पेस से क्लाइंट मशीन से बाहर भेजते समय "संदेश" संदेश "संदेश 12345" प्राप्त करना चाहता हूं। ताकि सर्वर को "message12345" मिले और इसे वापस गूंजें, और क्लाइंट केवल "message12345" पढ़ेगा लेकिन मुझे skb_put() और skb_add_data() फ़ंक्शंस में समस्या हो रही है। मुझे समझ में नहीं आता कि मेरे द्वारा क्या त्रुटि हुई थी। अगर कोई मुझे कोड के साथ मदद कर सकता है, तो मैं बहुत आभारी रहूंगा। अग्रिम में धन्यवाद। मैं सुविधा के लिए मेकफ़ाइल भी दे रहा हूं। यह वितरण कर्नेल के लिए है, न कि एक निर्मित कर्नेल के लिए। skb-> पूंछ इतना छोटा है कि मैं गिरी अंतरिक्ष में नई पैकेट बनाने के लिए होगा -
#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-> अंत कर रहा हूँ। मैं alloc_skb() skb_reserve() skb_header_pointer() और एक नया SKB बनाने के लिए अन्य उपयोगी SKB कार्यों का इस्तेमाल किया है, लेकिन बात मैं विचार से बाहर चल रहा है कि कैसे मार्ग पैकेट बह रास्ते में नव निर्मित पैकेट के लिए ।
ip_route_me_harder() का उपयोग कैसे करें मैंने सुझाव के लिए xtables-addons पैकेज में देखा, लेकिन उनके द्वारा उपयोग किया जाने वाला फ़ंक्शन लिनक्स कर्नेल में से एक से अलग है। किसी भी सुझाव का स्वागत है।
आपकी मदद के लिए धन्यवाद। हां, लंबाई के खेतों ने मुझे बहुत परेशान किया। –
और कर्नेल स्पेस में चेकसमिंग भी पहले मेरे लिए काफी अस्पष्ट था। –
@Fred क्या आप इस पर भी टिप्पणी कर सकते हैं http://stackoverflow.com/questions/12529497/how-to-append-data-on-a-packet-from- कर्नेल- स्पेस – user2087340