使用sk_buff中添加以太网帧头 [英] Using sk_buff to add an Ethernet frame header

查看:604
本文介绍了使用sk_buff中添加以太网帧头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个内核模块捕获传出的互联网流量(Netfilter的钩子:LOCAL_OUT)
在这个钩子,还是有没有以太网头。

我建的以太网帧头,它已经准备好使用,但如何将其连接到 SKB ,这样我可以整个SKB结构发送到 dev_queue_xmit()

是否有关于如何处理sk_buff的数据,你可以给我提供进一步信息的任何指导?

作为一个样本,我尝试做什么,我想所有的ICMP ECHO交通做到;这是code我有。
但在另一台机器上使用Wireshark检查的时候,我得到了一个工作以太网报头,无非是虚IP包...怎么来的?


 静态unsigned int类型post_icmp_check(unsigned int类型hooknum,
                 结构的sk_buff * SKB,
                 常量结构的net_device *中,
                 常量结构的net_device *出来,
                 INT(* okfn)(结构的sk_buff *))
{
  结构iphdr * IPH;
  结构icmphdr * icmph;
  结构的sk_buff * SB;
  结构ethhdr * ethh;
  无符号字符*帧= NULL; //只是用来复制&是skb- GT;数据并更换它,这是所有
  无符号字符* PTR;  / *分配和初始幽会* /
  SB = skb_copy(SKB,GFP_ATOMIC); / *制作私人拷贝,因为我们不能修改所有领域中公共的那个* /
  IPH = ip_hdr(某人);  如果(iph->协议== IPPROTO_ICMP){
      printk的(KERN_ALERTPOST ICMP流量\\ n!);      icmph = icmp_hdr(某人);
      如果(icmph->类型== ICMP_ECHO){
          帧=(无符号字符*)的kmalloc(ntohs和(iph-> tot_len)+(ETH_HLEN * 8),GFP_KERNEL);
          PTR =(帧+(ETH_HLEN * 8));          ethh =(结构ethhdr *)帧; // 00:1A:80:7E:96:BA
          ethh-> h_source [0] = 0×00;
          ethh-> h_source [1] = 0X1A;
          ethh-> h_source [2] = 0x80的;
          ethh-> h_source [3] = 0x7e格式;
          ethh-> h_source [4] = 0x96;
          ethh-> h_source [5] = 0xba;
          ethh-> h_dest [0] = 0xff的;
          ethh-> h_dest [1] = 0xff的;
          ethh-> h_dest [2] = 0xff的;
          ethh-> h_dest [3] = 0xff的;
          ethh-> h_dest [4] = 0xff的;
          ethh-> h_dest [5] = 0xff的;
          ethh-> h_proto = htons(ETH_P_IP);
          的memcpy(PTR,&是skb- GT;的数据,还有ntohs(iph-> tot_len)); / *从SKB复制数据的其余部分给某人* /
          SB-GT&;数据=帧;          // icmph = icmp_hdr(某人);          //icmph->un.echo.sequence = htons(我++);
          // icmph->校验= 0;
          // icmph->校验= in_cksum((无符号短*)icmph,还有ntohs(iph-> tot_len) - 的sizeof(结构iphdr));
          SB-GT&;开发=出来;
          printk的(KERN_ALERT%S \\ n,SB-GT&;&dev亡GT;名);
          如果(SB-GT&;开发== NULL)
              printk的(KERN_ALERTdev为空!);
          dev_queue_xmit(某人);
          返回NF_STOLEN;
}


编辑:是的,我硬编码自己的MAC地址和广播帧,为了简单起见,仅

EDIT2:
所以我给这个函数通过net_filter抓住了原来的sk_buff以及相应的net_device
我试图按照你说什么,读一点有关指南的sk_buff中的功能。
然而,当我dev_queue_xmit()这个函数返回的sk_buff中,我得到一个完整的内核崩溃。

 静态结构的sk_buff * set_skb(结构的sk_buff * org_skb,结构的net_device * dev的)
{
    诠释header_size;
    无符号字符*的数据;
    结构icmphdr * icmph;
    结构iphdr * IPH;
    结构icmphdr * temp_icmph;
    结构iphdr * temp_iph;
    unsigned char型MYADDR [] = {0x00,0x1a,0x80,0x7e,0x96,0xba};
    无符号的字符地址[] = {0xFF的,为0xFF,0xFF的,为0xFF,0xFF的,0xFF的};
    结构的sk_buff * SKB;    temp_iph = ip_hdr(org_skb);
    temp_icmph = icmp_hdr(org_skb);    SKB = alloc_skb(ntohs和((temp_iph-> tot_len)+(ETH_HLEN * 8)),GFP_KERNEL); / *的一切分配足够的空间* /    / * icmp_hlen这始终是8,ip_hlen * /
    header_size = 8 + ntohs和(temp_iph->国际人道法* 4);
    / *预留净空这实际上分配IP和ICMP报文头的内存* /
    skb_reserve(SKB,header_size);    / * *负载/
    数据= skb_put(SKB,org_skb-> DATA_LEN); / *这个函数分配空间数据* /
    的memcpy(数据,org_skb->的数据,org_skb-> DATA_LEN);    icmph =(结构icmphdr *)skb_push(SKB,8);
    / *设置ICMP报头位置* /
    的memcpy(icmph,temp_icmph,8);    IPH =(结构iphdr *)skb_push(SKB,temp_iph->国际人道法* 4);
    / *设置IP报头位置* /
    的memcpy(IPH,temp_iph,temp_iph->国际人道法* 4);    / *
     *此功能设置了以太网报头,
     *目的地址地址,源地址MYADDR
     * /
    dev_hard_header(SKB,开发,ETH_P_IP,地址,MYADDR,dev亡> addr_len);
    返回SKB;
}

EDIT3:

  4月20日23时44分09秒DHS-1022CYB内核:[1139.520104]加载试验模块...
4月20日23时44分09秒DHS-1022CYB内核:[1139.520168] ********** HERE WE GO *********** ***********
4月20日23点44分12秒DHS-1022CYB内核:[1142.760448] PGD 114952067 PUD 12d932067 PMD 0
4月20日23点44分12秒DHS-1022CYB内核:[1142.760762] CPU 0
4月20日23点44分12秒DHS-1022CYB内核:中联[1142.760809]模块:Mymodule中(P)binfmt_misc RFCOMM ppdev SCO弥补STP BNEP L2CAP joydev FBCON tileblit字体象素数据softcursor vga16fb vgastate snd_hda_ codec_realtek PCMCIA ARC4 snd_hda_intel snd_hda_ codeC snd_hwdep snd_pcm_oss snd_mixer_oss snd_pcm snd_seq_dummy snd_seq_oss snd_seq_midi snd_rawmidi snd_seq_midi_event iwlagn snd_seq iwlcore snd_timer RADEON TTM drm_kms_helper snd_seq_device mac80211 tifm_7xx1 led_class USBHID yenta_socket藏rsrc_nonstatic btusb蓝牙uvcvideo videodev v4l1_compat v4l2_compat_ioctl32 SND DRM tifm_core i2c_algo_bit psmouse sony_laptop pcmcia_core serio_raw cfg80211声音核心snd_page_alloc视频输出intel_agp LP parport ohci1394 IEEE1394 r8169 MII
4月20日23点44分12秒DHS-1022CYB内核:[1142.762642] PID:3423,通信:平污点:P 2.6.32-33泛型#70 Ubuntu的VGN-CR31Z_R
4月20日23点44分12秒DHS-1022CYB内核:[1142.762753] RIP:0010:< ffffffffa042c081>] [< ffffffffa042c081>] post_icmp_check + 0×81 / 0x1e0 [MyModule的]
4月20日23点44分12秒DHS-1022CYB内核:[1142.762891] RSP:0018:ffff88011494f948 EFLAGS:00010246
4月20日23点44分12秒DHS-1022CYB内核:[1142.762965] RAX:0000000000000000 RBX:ffff88013bb62000 RCX:00000000000000d0
4月20日23点44分12秒DHS-1022CYB内核:[1142.763059] RDX:0000000000000000 RSI:ffff88013bb62000 RDI:0000000000000000
4月20日23点44分12秒DHS-1022CYB内核:[1142.763153] RBP:ffff88011494f988 R08:00000000ffffffff R09:0000000000000001
4月20日23点44分12秒DHS-1022CYB内核:[1142.763248] R10:ffffffff81591000 R11:ffff880137c9c9ef R12:ffff880130ba8100
4月20日23点44分12秒DHS-1022CYB内核:[1142.763346] R13:ffffffff81831070 R14:ffff880130ba8100 R15:0000000000000003
4月20日23点44分12秒DHS-1022CYB内核:[1142.763441] FS:00007f3377ef6700(0000)GS:ffff880028200000(0000)knlGS:0000000000000000
4月20日23点44分12秒DHS-1022CYB内核:[1142.763546] CS:0010 DS:0000 ES:0000 CR0:000000008005003b
4月20日23点44分12秒DHS-1022CYB内核:[1142.763626] CR2:0000000000000000 CR3:0000000114863000 CR4:00000000000006f0
4月20日23点44分12秒DHS-1022CYB内核:[1142.763721] DR0:0000000000000000 DR1:0000000000000000 DR2:0000000000000000
4月20日23点44分12秒DHS-1022CYB内核:[1142.763815] DR3:0000000000000000 DR6:00000000ffff0ff0 DR7:0000000000000400
4月20日23点44分12秒DHS-1022CYB内核:[1142.763910]过程坪(PID:3423,一个ThreadInfo ffff88011494e000,任务ffff880139b6c4d0)
4月20日23点44分12秒DHS-1022CYB内核:[1142.764052] ffff88011494fd​​e8 0000000000000040 0000000000609420 0000000000000000
4月20日23点44分12秒DHS-1022CYB内核:[1142.764195]℃的> ffff88011494fa10 00000000.8亿ffffffff81831070 ffff880130ba8100
4月20日23点44分12秒DHS-1022CYB内核:[1142.768380]℃的> ffff88011494f9d8 ffffffff81486f1c ffff88013bb62000 0000000000000000
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff81486f1c>] nf_iterate + 0x6c / 0XB0
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff81491b20>] dst_output +为0x0 / 0x20的
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff81486fd4>] nf_hook_slow + 0x74 / 0x100的
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff81491b20>] dst_output +为0x0 / 0x20的
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff81493c3f>] __ip_local_out + 0x9f / 0XB0
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff81493c66>] ip_local_out + 0x16 /的0x30
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff81493f0a>] ip_push_pending_frames + 0x28a /量0x410
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff8148cd02>] ip_route_output_flow +为0x82 / 0XB0
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff814b40b5>] raw_sendmsg + 0x3a5 / 0x5c0
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff814be5b9>] inet_sendmsg + 0x29 / 0x60的
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff81285389>] apparmor_socket_sendmsg +的0x19 / 0x20的
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff8145004b>] sock_sendmsg + 0x10b / 0x140
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff81084cc0>] autoremove_wake_function +为0x0 / 0X40
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff8144f5b4>] move_addr_to_kernel + 0x64 / 0x70
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff8145a706>] verify_iovec + 0x66 / 0xd0
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff814504c3>] sys_sendmsg + 0x233 / 0x3a0
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff811131c9>] __do_fault + 0x439 / 0x500处
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff81541845>] _spin_lock_irq +为0x15 / 0x20的
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff810787ae>] do_sigaction + 0x13e / 0x1e0
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff815444a8>] do_page_fault + 0x158 / 0x3b0
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] [< ffffffff810121b2>] system_call_fastpath + 0x16 / 0x1b
4月20日23点44分12秒DHS-1022CYB内核:[1142.770015] RSP< ffff88011494f948>
4月20日23点44分12秒DHS-1022CYB内核:[1142.887370] --- [结束跟踪404e94883c3bf110] ---

这是大跌后的内核日志的结果。

EDIT4:
为了让事情更清晰,这是code的一部分实际上是调用我的set_skb()

 如果(icmph->类型== ICMP_ECHO){
            的memcpy(DEV,出,的sizeof(*总分));
            SB = set_skb(SKB,DEV);
            printk的(KERN_ALERT%S \\ n,SB-GT&;&dev亡GT;名);
            dev_queue_xmit(某人);
            返回NF_STOLEN;
        }


解决方案

哇,你不这样做。不要惹直接SKB内部指针。仅分配一个skb和头和有效载荷复制到新的。

让我们假设你想添加ICMP,IP和以太网头和 orig_skb 复制有效载荷。像这样做:

 结构的skbuff * SKB = skb_alloc(full_len,GFP_KERNEL);/ * icmp_hlen,ip_hlen和payload_size应知* /
INT header_size = icmp_hlen + ip_hlen;/ *储备余量* /
skb_reserve(SKB,header_size);/ * *负载/
无符号字符*数据= skb_put(SKB,payload_size);
的memcpy(数据,orig_skb->的数据,payload_size);结构icmphdr * icmph = skb_push(SKB,icmp_hlen);
/ *设置ICMP报头位置* /结构iphdr * IPH = skb_push(SKB,ip_hlen);
/ *设置IP报头位置* // *
 *此功能设置了以太网报头,
 *目的地址地址,源地址MYADDR
 * /
dev_hard_header(SKB,开发,ETH_P_IP,地址,MYADDR,dev亡> addr_len);

如果您要添加的交通,网络等头可以按下多个头。

I have a kernel module that captures outgoing Internet traffic(Netfilter hook: LOCAL_OUT) At this hook, there's still no Ethernet header.

I built the Ethernet header and it's ready to use, but how can I attach it to the skb so that I can send the whole skb struct to dev_queue_xmit() ?

Is there any guide on how to manipulate sk_buff data that you can provide me for further information?

As a sample, I try to do what I want to do on all ECHO ICMP traffic; this is the code I have. But when checking with Wireshark on the other machine, I get a working Ethernet header but an EMPTY IP packet...how come?

static unsigned int post_icmp_check(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 icmphdr *icmph;
  struct sk_buff *sb;
  struct ethhdr *ethh;
  unsigned char *frame = NULL; //Used just to copy the skb->data and replace it, that's all
  unsigned char *ptr;

  /* Allocations and initial assignations  */
  sb = skb_copy(skb, GFP_ATOMIC); /* Making a private copy because we cannot modify all fields in the public one */
  iph = ip_hdr(sb);

  if(iph->protocol == IPPROTO_ICMP){
      printk(KERN_ALERT"POST ICMP traffic!\n");

      icmph = icmp_hdr(sb);
      if(icmph->type == ICMP_ECHO){
          frame = (unsigned char *)kmalloc(ntohs(iph->tot_len) + (ETH_HLEN*8), GFP_KERNEL);
          ptr = (frame +  (ETH_HLEN * 8));

          ethh = (struct ethhdr*) frame;      //00:1a:80:7e:96:ba
          ethh->h_source[0] = 0x00;   
          ethh->h_source[1] = 0x1a;           
          ethh->h_source[2] = 0x80;
          ethh->h_source[3] = 0x7e;
          ethh->h_source[4] = 0x96;
          ethh->h_source[5] = 0xba;
          ethh->h_dest[0] = 0xff;
          ethh->h_dest[1] = 0xff;
          ethh->h_dest[2] = 0xff;
          ethh->h_dest[3] = 0xff;
          ethh->h_dest[4] = 0xff;
          ethh->h_dest[5] = 0xff;
          ethh->h_proto = htons(ETH_P_IP);
          memcpy(ptr, skb->data, ntohs(iph->tot_len)); /* Copying the rest of the data from the skb to sb */
          sb->data = frame;

          //icmph = icmp_hdr(sb);

          //icmph->un.echo.sequence = htons(i++);         
          //icmph->checksum = 0;
          //icmph->checksum =  in_cksum((unsigned short *)icmph, ntohs(iph->tot_len) - sizeof(struct iphdr));
          sb->dev = out;
          printk(KERN_ALERT"%s\n",sb->dev->name);
          if(sb->dev == NULL)
              printk(KERN_ALERT"dev is NULL!");           
          dev_queue_xmit(sb);
          return NF_STOLEN;
}

EDIT : And yes, I am hardcoding my own MAC and BROADCASTING the frame, for the sake of simplicity only.

EDIT2: So I am giving this function the original sk_buff caught by net_filter and the appropriate net_device I tried to follow what you said and read a little guide about the functions for the sK_buff. Still, when I dev_queue_xmit() the returned sk_buff of this function, I get a complete kernel crash.

static struct sk_buff* set_skb(struct sk_buff *org_skb, struct net_device *dev)
{
    int header_size;
    unsigned char *data;
    struct icmphdr *icmph;
    struct iphdr *iph;      
    struct icmphdr *temp_icmph;
    struct iphdr *temp_iph;         
    unsigned char myaddr[] = {0x00,0x1a,0x80,0x7e,0x96,0xba};
    unsigned char addr [] = {0xff,0xff,0xff,0xff,0xff,0xff};    
    struct sk_buff *skb;

    temp_iph = ip_hdr(org_skb); 
    temp_icmph = icmp_hdr(org_skb);

    skb = alloc_skb(ntohs((temp_iph->tot_len) + (ETH_HLEN*8)), GFP_KERNEL); /* Allocating enough space for everything */

    /* icmp_hlen which is always 8, ip_hlen */
    header_size = 8 + ntohs(temp_iph->ihl*4);


    /* reserve headroom This actually allocates the IP and ICMP headers memory */
    skb_reserve(skb, header_size);

    /* payload */
    data = skb_put(skb, org_skb->data_len);/* This function allocates room for the data */
    memcpy(data, org_skb->data, org_skb->data_len);

    icmph = (struct icmphdr*)skb_push(skb, 8); 
    /* set up icmp header here */
    memcpy(icmph, temp_icmph, 8);   

    iph = (struct iphdr*)skb_push(skb, temp_iph->ihl*4);
    /* set up ip header here */
    memcpy(iph, temp_iph, temp_iph->ihl*4); 

    /*
     * This function sets up the ethernet header,
     * destination address addr, source address myaddr
     */
    dev_hard_header(skb, dev, ETH_P_IP, addr, myaddr, dev->addr_len);
    return skb;
}

EDIT3:

Apr 20 23:44:09 DHS-1022CYB kernel: [ 1139.520104] Loading Test module...
Apr 20 23:44:09 DHS-1022CYB kernel: [ 1139.520168] *********************HERE WE GO**********************
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.760448] PGD 114952067 PUD 12d932067 PMD 0 
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.760762] CPU 0 
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.760809] Modules linked in: myModule(P) binfmt_misc rfcomm ppdev sco bridge stp bnep l2cap joydev fbcon tileblit font bitblit softcursor vga16fb vgastate snd_hda_codec_realtek pcmcia arc4 snd_hda_intel snd_hda_codec snd_hwdep snd_pcm_oss snd_mixer_oss snd_pcm snd_seq_dummy snd_seq_oss snd_seq_midi snd_rawmidi snd_seq_midi_event iwlagn snd_seq iwlcore snd_timer radeon ttm drm_kms_helper snd_seq_device mac80211 tifm_7xx1 led_class usbhid yenta_socket hid rsrc_nonstatic btusb bluetooth uvcvideo videodev v4l1_compat v4l2_compat_ioctl32 snd drm tifm_core i2c_algo_bit psmouse sony_laptop pcmcia_core serio_raw cfg80211 soundcore snd_page_alloc video output intel_agp lp parport ohci1394 ieee1394 r8169 mii
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.762642] Pid: 3423, comm: ping Tainted: P           2.6.32-33-generic #70-Ubuntu VGN-CR31Z_R
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.762753] RIP: 0010:[<ffffffffa042c081>]  [<ffffffffa042c081>] post_icmp_check+0x81/0x1e0 [myModule]
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.762891] RSP: 0018:ffff88011494f948  EFLAGS: 00010246
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.762965] RAX: 0000000000000000 RBX: ffff88013bb62000 RCX: 00000000000000d0
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.763059] RDX: 0000000000000000 RSI: ffff88013bb62000 RDI: 0000000000000000
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.763153] RBP: ffff88011494f988 R08: 00000000ffffffff R09: 0000000000000001
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.763248] R10: ffffffff81591000 R11: ffff880137c9c9ef R12: ffff880130ba8100
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.763346] R13: ffffffff81831070 R14: ffff880130ba8100 R15: 0000000000000003
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.763441] FS:  00007f3377ef6700(0000) GS:ffff880028200000(0000) knlGS:0000000000000000
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.763546] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.763626] CR2: 0000000000000000 CR3: 0000000114863000 CR4: 00000000000006f0
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.763721] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.763815] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.763910] Process ping (pid: 3423, threadinfo ffff88011494e000, task ffff880139b6c4d0)
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.764052]  ffff88011494fde8 0000000000000040 0000000000609420 0000000000000000
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.764195] <0> ffff88011494fa10 0000000080000000 ffffffff81831070 ffff880130ba8100
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.768380] <0> ffff88011494f9d8 ffffffff81486f1c ffff88013bb62000 0000000000000000
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff81486f1c>] nf_iterate+0x6c/0xb0
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff81491b20>] ? dst_output+0x0/0x20
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff81486fd4>] nf_hook_slow+0x74/0x100
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff81491b20>] ? dst_output+0x0/0x20
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff81493c3f>] __ip_local_out+0x9f/0xb0
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff81493c66>] ip_local_out+0x16/0x30
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff81493f0a>] ip_push_pending_frames+0x28a/0x410
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff8148cd02>] ? ip_route_output_flow+0x82/0xb0
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff814b40b5>] raw_sendmsg+0x3a5/0x5c0
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff814be5b9>] inet_sendmsg+0x29/0x60
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff81285389>] ? apparmor_socket_sendmsg+0x19/0x20
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff8145004b>] sock_sendmsg+0x10b/0x140
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff81084cc0>] ? autoremove_wake_function+0x0/0x40
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff8144f5b4>] ? move_addr_to_kernel+0x64/0x70
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff8145a706>] ? verify_iovec+0x66/0xd0
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff814504c3>] sys_sendmsg+0x233/0x3a0
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff811131c9>] ? __do_fault+0x439/0x500
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff81541845>] ? _spin_lock_irq+0x15/0x20
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff810787ae>] ? do_sigaction+0x13e/0x1e0
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff815444a8>] ? do_page_fault+0x158/0x3b0
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  [<ffffffff810121b2>] system_call_fastpath+0x16/0x1b
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.770015]  RSP <ffff88011494f948>
Apr 20 23:44:12 DHS-1022CYB kernel: [ 1142.887370] ---[ end trace 404e94883c3bf110 ]---

And that was the kernel log result after the crash.

EDIT4: To make things clearer, this is the part of the code that actually calls my set_skb()

if(icmph->type == ICMP_ECHO){
            memcpy(dev, out, sizeof(*out)); 
            sb = set_skb(skb, dev);
            printk(KERN_ALERT"%s\n",sb->dev->name);           
            dev_queue_xmit(sb);
            return NF_STOLEN;
        }

解决方案

Wow, you don't do that. Don't mess with skb internal pointers directly. Just allocate an skb and copy the headers and payload to the new one.

Let's assume you want to add ICMP, IP and ethernet headers and copy payload from orig_skb. Do it like this:

struct skbuff *skb = skb_alloc(full_len, GFP_KERNEL);

/* icmp_hlen, ip_hlen and payload_size should be known */
int header_size = icmp_hlen + ip_hlen;

/* reserve headroom */
skb_reserve(skb, header_size);

/* payload */
unsigned char *data = skb_put(skb, payload_size);
memcpy(data, orig_skb->data, payload_size);

struct icmphdr *icmph = skb_push(skb, icmp_hlen);
/* set up icmp header here */

struct iphdr *iph = skb_push(skb, ip_hlen);
/* set up ip header here */

/*
 * This function sets up the ethernet header,
 * destination address addr, source address myaddr
 */
dev_hard_header(skb, dev, ETH_P_IP, addr, myaddr, dev->addr_len);

You can push multiple headers if you want to add transport, network etc headers.

这篇关于使用sk_buff中添加以太网帧头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆