4

I need to create an ethernet packet an send it in my kernel module. Someone can help me to do this?

I think i need to create a skb using dev_alloc_skb, then i need to write the mac_ethernet, insert the data and send it using dev_queu_xmit.

But i'm not sure if this work, or if it is the right and easiest way to do it.

Best Regards

EDIT1:

int sendpacket ()
{
    unsigned char dest[ETH_ALEN]={0x00,0x25,0x22,0x05,0xF3,0xF0};
    unsigned char src[ETH_ALEN] = {0x90,0xE6,0xBA,0x48,0x7C,0x87};

struct sk_buff * skbt =alloc_skb(ETH_FRAME_LEN,GFP_KERNEL);      
//skb_reserve(skb,ETH_FRAME_LEN);


dev_hard_header(skbt,dev_eth1,ETH_P_802_3,dest,src,dev_eth1->addr_len);

if(dev_queue_xmit(skbt)!=NET_XMIT_SUCCESS)
{
    printk("Not send!!\n");
}



kfree_skb(skbt);
return 0;

}

> Dmesg command:
> 
>  677.826933] Hello:I'm the hook module!!!! [  677.826937] 2!!!! [  677.826941] skb_under_panic: text:c0723608 len:14 put:14 head:f1843800 data:f18437f2 tail:0xf1843800 end:0xf1843e00 dev:<NULL> [  677.826959]
> ------------[ cut here ]------------ [  677.826961] kernel BUG at net/core/skbuff.c:146! [  677.826964] invalid opcode: 0000 [#1] SMP  [
> 677.826967] last sysfs file: /sys/devices/system/cpu/cpu1/cache/index2/shared_cpu_map [ 
> 677.826969] Modules linked in: sendpacket(+) bluetooth rfkill vfat fat fuse sunrpc cpufreq_ondemand acpi_cpufreq mperf ip6t_REJECT
> nf_conntrack_ipv6 ip6table_filter ip6_tables ipv6 uinput
> snd_hda_codec_atihdmi snd_hda_codec_realtek snd_hda_intel
> snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm snd_timer snd
> soundcore atl1e snd_page_alloc iTCO_wdt iTCO_vendor_support r8169 mii
> i2c_i801 microcode asus_atk0110 pcspkr ata_generic pata_acpi
> usb_storage pata_marvell radeon ttm drm_kms_helper drm i2c_algo_bit
> i2c_core [last unloaded: sendpacket] [  677.827003]  [  677.827003]
> Pid: 4780, comm: insmod Tainted: G        W   2.6.35101 #7 P5QL
> PRO/P5QL PRO [  677.827003] EIP: 0060:[<c070a192>] EFLAGS: 00210246
> CPU: 0 [  677.827003] EIP is at skb_push+0x57/0x62 [  677.827003] EAX:
> 00000088 EBX: c08f9fdc ECX: f156bf10 EDX: c093b4ca [  677.827003] ESI:
> 00000000 EDI: f51ca000 EBP: f156bf38 ESP: f156bf0c [  677.827003]  DS:
> 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 [  677.827003] Process insmod
> (pid: 4780, ti=f156a000 task=f2b071a0 task.ti=f156a000) [  677.827003]
> Stack: [  677.827003]  c093b4ca c0723608 0000000e 0000000e f1843800
> f18437f2 f1843800 f1843e00 [  677.827003] <0> c08f9fdc f156bf64
> f156bf6a f156bf50 c0723608 00000001 c07235e5 f3b6c000 [  677.827003]
> <0> 00835ff4 f156bf78 f7d640a8 f156bf6a f156bf64 00000006 48bae690
> 2500877c [  677.827003] Call Trace: [  677.827003]  [<c0723608>] ?
> eth_header+0x23/0x93 [  677.827003]  [<c0723608>] ?
> eth_header+0x23/0x93 [  677.827003]  [<c07235e5>] ?
> eth_header+0x0/0x93 [  677.827003]  [<f7d640a8>] ?
> sendpacket+0x8f/0xb6 [sendpacket] [  677.827003]  [<f7d67000>] ?
> hook_init+0x0/0x46 [sendpacket] [  677.827003]  [<f7d67044>] ?
> hook_init+0x44/0x46 [sendpacket] [  677.827003]  [<c0401246>] ?
> do_one_initcall+0x4f/0x139 [  677.827003]  [<c0451e29>] ?
> blocking_notifier_call_chain+0x11/0x13 [  677.827003]  [<c046210c>] ?
> sys_init_module+0x7f/0x19b [  677.827003]  [<c040321f>] ?
> sysenter_do_call+0x12/0x28 [  677.827003] Code: c0 85 f6 0f 45 de 53
> ff b0 a8 00 00 00 ff b0 a4 00 00 00 51 ff b0 ac 00 00 00 52 ff 70 50
> ff 75 04 68 ca b4 93 c0 e8 ad 4a 09 00 <0f> 0b 8d 65 f8 89 c8 5b 5e 5d
> c3 55 89 e5 56 53 0f 1f 44 00 00  [  677.827116] EIP: [<c070a192>]
> skb_push+0x57/0x62 SS:ESP 0068:f156bf0c [  677.827154] ---[ end trace
> dee1e3278503a581 ]---
Ricardo
  • 612
  • 2
  • 9
  • 16
  • Roughly speaking your approach sounds valid. Beware though, that sending packets from the kernel is almost certainly the wrong thing to do. What are you trying to accomplish? – Kristof Provost Apr 23 '12 at 10:43
  • I need to create a message to configure a machin. I use a pre-defined ethernet type and i want to insert the data in the payload. What is the best way do it? If you could supply a basic code example i appreciate. Thank You. – Ricardo Apr 23 '12 at 10:51
  • In that case you're much better off using raw packets from user space. – Kristof Provost Apr 23 '12 at 10:55
  • But the ideia is to do that at the kernel module. – Ricardo Apr 23 '12 at 11:01
  • Don't. Do everything possible from user space. – Kristof Provost Apr 23 '12 at 11:03
  • See this question and the answer: http://stackoverflow.com/questions/10245281/using-sk-buff-to-add-an-ethernet-frame-header – ldx Apr 23 '12 at 13:09
  • Can you check my edit 1? If i understand the other topic, i just need to alloc a skb and because i just need an ethernet frame, the function dev_hard_heard makes the heard and it's done? A segmentation fault happens, what can be? I call this function when i inser the module. – Ricardo Apr 23 '12 at 15:24
  • As u are providing the source code, it seems that u are only making ethernet header but there is no code for network & transport layer header. so if u can provide the actual code or full code then it will be helpfull to get the actual problem occuring.... if this is the reason then u have to create these headers with relevant info & then try to send it. – akp Nov 23 '12 at 09:16

2 Answers2

2

In your case you just want to use raw packets from user space instead of dealing with the complexities of kernel code.

This blog post details how to do everything you need.

Kristof Provost
  • 26,018
  • 2
  • 26
  • 28
1

At the risk of sounding like a broken record you're learning why this should be done from user space.

Because you seem determined to make this mistake anyway, let's try to figure out what the problem is.

It's also a good illustration of how helpful it is to have source code. The exception log tells you the problem occurred on line 146 of net/core/skbuff.c. That's within the function skb_under_panic(), which is only used in that file (it's static after all), from within skb_push().

The skb_push() function expands the skb forwards. Basically it creates room in the buffer for a new header. It does this by shifting the internal data pointer forward.

In your case, the internal data pointer is still in its original localtion: at the very from of the skb. You need to reserve some room at the front of the skb first. Use skb_reserve(), pretty much just like you had. Why did you comment that out?

Also, you need to check that the allocation of the skb succeeded. Kernel allocators can (and do) return NULL sometimes.

Kristof Provost
  • 26,018
  • 2
  • 26
  • 28
  • I coment skb_reserve because i the other post, they just reserved headersroom space for others heardes, not for the ethernet. I uncoment that line but the process is Killed : access null point at 0x000000c. I have a kernel module that forwards some kinds of packet based on eth.type, and now i want had there a a configuration packet when a packet of some protocol arrives, and that why i want to do this at kernel level. – Ricardo Apr 24 '12 at 09:58
  • Did you do skb_reserve(skb, ..) or skb_reserve(skbt, ...)? – Kristof Provost Apr 24 '12 at 10:02
  • I did skb_reserve(skbt,ETH_HLEN). The function dev_hard_hearder return the value 14. When i try to send the skb, the kernel crashes. – Ricardo Apr 24 '12 at 10:44
  • Try adding some payload to your packet (and an Ethernet type). I wouldn't be surprised if some network drivers don't like ethernet packets without payload. If that doesn't help post the crash. – Kristof Provost Apr 24 '12 at 12:38
  • I added the payload but the kernel crashs and i can't find error. I solve my problem creating a skb buffer and then complete all the fiels one by one:ethernet header,skb->mac_header,skb->data, skb->dev an now i can create and send some packets. – Ricardo Apr 26 '12 at 14:50