《教你修改以及重构skb》在2.6.30上的实现

简介: 上次看了ubuntuer兄写的教你修改以及重构skb,受益匪浅,真是经典之作。但ubuntuer兄的代码是基于2.6.18的,比较旧。今天经过摸索,我终于让其可以在2.
上次看了ubuntuer兄写的 教你修改以及重构skb,受益匪浅,真是经典之作。
但ubuntuer兄的代码是基于2.6.18的,比较旧。今天经过摸索,我终于让其可以在2.6.30上运行了,代码如下:
skb_DIY.c

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kenthy@163.com");

#define    ETH     "eth0"
#define    SIP     "192.168.238.180"
#define    DIP     "192.168.1.101"
#define    SPORT   39804
#define    DPORT   80

unsigned char   SMAC[ETH_ALEN] = {0x00,0x0C,0x29,0x4F,0xDE,0xAC};
unsigned char   DMAC[ETH_ALEN] = {0x00,0x50,0x56,0xFA,0x70,0x2A};

int cp_dev_xmit_tcp (char * eth, u_char * smac, u_char * dmac,
             u_char * pkt, int pkt_len,
             u_long sip, u_long dip,
             u_short sport, u_short dport, u_long seq, u_long ack_seq, u_char psh, u_char fin)
{
    struct sk_buff * skb = NULL;
    struct net_device * dev = NULL;
    struct ethhdr * ethdr = NULL;
    struct iphdr * iph = NULL;
    struct tcphdr * tcph = NULL;
    u_char * pdata = NULL;
    int nret = 1;
    if (NULL == smac || NULL == dmac) goto out;
    dev = dev_get_by_name(&init_net, eth);
    if (NULL == dev)
        goto out;
    skb = alloc_skb (pkt_len + sizeof (struct iphdr) + sizeof (struct tcphdr) + LL_RESERVED_SPACE (dev), GFP_ATOMIC);
    /* 
    LL_RESERVED_SPACE(dev) = 16
    alloc_skb返回以后,skb->head = skb_data = skb->tail =  alloc_skb分配的内存区首地址,skb->len = 0;
    skb->end = skb->tail + size;
         注:我的机子是32位x86机器,所以没有定义NET_SKBUFF_DATA_USES_OFFSET,因而,
     skb->tail,skb->mac_header,skb->network_header,skb->transport_header这几个成员都是指针
    */
      if (NULL == skb)
            goto out;
    skb_reserve (skb, LL_RESERVED_SPACE (dev));//add data and tail
    skb->dev = dev;
    skb->pkt_type = PACKET_OTHERHOST;
    skb->protocol = __constant_htons(ETH_P_IP);
    skb->ip_summed = CHECKSUM_NONE;
    skb->priority = 0;
    //skb->nh.iph = (struct iphdr*)skb_put(skb, sizeof (struct iphdr));
    //skb->h.th = (struct tcphdr*)skb_put(skb, sizeof (struct tcphdr));
    skb_set_network_header(skb, 0);    //skb->network_header = skb->data + 0;
    skb_put(skb, sizeof (struct iphdr)); //add tail and len
    skb_set_transport_header(skb, sizeof (struct iphdr));//skb->transport_header = skb->data + sizeof (struct iphdr)
    skb_put(skb, sizeof (struct tcphdr));   
    pdata = skb_put (skb, pkt_len);
      {
            if (NULL != pkt)
                 memcpy (pdata, pkt, pkt_len);
      }

    {
        tcph = tcp_hdr(skb);
        memset (tcph, 0, sizeof (struct tcphdr));
        tcph->source = sport;
        tcph->dest = dport;
        tcph->seq = seq;
        tcph->ack_seq = ack_seq;
        tcph->doff = 5;
        tcph->psh = psh;
        tcph->fin = fin;
        tcph->syn = 1;
        tcph->ack = 0;
        tcph->window = __constant_htons (5840);
        skb->csum = 0;
        tcph->check = 0;
    }

    {
        iph = ip_hdr(skb);
        iph->version = 4;
        iph->ihl = sizeof(struct iphdr)>>2;
        iph->frag_off = 0;
        iph->protocol = IPPROTO_TCP;
        iph->tos = 0;
        iph->daddr = dip;
        iph->saddr = sip;
        iph->ttl = 0x40;
        iph->tot_len = __constant_htons(skb->len);
        iph->check = 0;
    }
      skb->csum = skb_checksum (skb, iph->ihl*4, skb->len - iph->ihl * 4, 0);
    tcph->check = csum_tcpudp_magic (sip, dip, skb->len - iph->ihl * 4, IPPROTO_TCP, skb->csum);
    {
        ethdr = (struct ethhdr*)skb_push (skb, 14);//reduce data and add len
        memcpy (ethdr->h_dest, dmac, ETH_ALEN);
        memcpy (ethdr->h_source, smac, ETH_ALEN);
        ethdr->h_proto = __constant_htons (ETH_P_IP);
    }
     if (0 > dev_queue_xmit(skb)) goto out;
    nret = 0;
out:
    if (0 != nret && NULL != skb)
    {
        dev_put (dev);
        kfree_skb (skb);
    }
      return (nret);
}

static int __init init(void)
{
    printk("%s\n","insmod skb_diy module\n");
        cp_dev_xmit_tcp (ETH, SMAC, DMAC,NULL, 0,
                    in_aton(SIP),in_aton(DIP),
                    htons(SPORT),htons(DPORT),
                    0, 0, 0, 0);
    return 0;
}

static void __exit fini(void)
{
    printk("%s\n","remove skb_diy module.\n");
}

module_init(init);
module_exit(fini);


Makefile:

PWD:=$(shell pwd)
KERNEL_SRC = /lib/modules/`uname -r`/build
obj-m:=skb_DIY.o
skb_DIY-objs:=skb.o
all:
    make -C $(KERNEL_SRC) M=$(PWD) modules
clean:
    rm -f *.o
    rm -f *.ko
    rm -f .*.cmd
    rm -rf .tmp_versions
    rm -f *.mod.c
    rm -f *.symvers
    rm -f *.order

相关文章
|
程序员
你的代码需要重构吗?
你的代码需要重构吗?
70 0
|
5月前
软件复杂度问题之如何判断一个方法是否需要进行重构,重构时需要注意什么
软件复杂度问题之如何判断一个方法是否需要进行重构,重构时需要注意什么
|
5月前
|
数据库
代码的应用重构问题之BaseActivity类的主要功能问题如何解决
代码的应用重构问题之BaseActivity类的主要功能问题如何解决
|
5月前
|
JSON 前端开发 Java
代码的应用重构问题之BaseActivity类的主要功能问题如何解决代码缩减的主要问题如何解决
代码的应用重构问题之BaseActivity类的主要功能问题如何解决代码缩减的主要问题如何解决
|
开发者
重构的核心-让代码保持整洁
很久之前团队师兄向我推荐了《重构:改善既有代码的设计》这本书,粗略翻阅看到很多重构的细节技巧,但当时还处于未接触过工程代码,只关注代码功能,不太考虑后期维护的阶段,读起来觉得枯燥无味,几乎没有共鸣,一直没有细细阅读。在工作一年后,终于在师兄的督促下,利用一个月左右的早起时光读完了这本书,收获很多,感谢师兄的督促,感谢这本书陪伴我找回了阅读习惯。把这本书推荐给已经接触了工程代码、工作一年左右的新同学,相信有了一定的经验积累,再结合日常项目实践中遇到的问题,对这本书的内容会有很多自己的思考感悟
40595 4
重构的核心-让代码保持整洁
|
设计模式 Java
【Java设计模式 规范与重构】 一 重构的目的、内容、时机、方法
【Java设计模式 规范与重构】 一 重构的目的、内容、时机、方法
196 0
|
算法
【重构】重构概要--六大重构模块
【重构】重构概要--六大重构模块
262 0
|
算法 Java 容器
狗屎一样的代码!快,重构我!
狗屎一样的代码如何重构? 重构不止是代码整理,它提供了一种高效且受控的代码整理技术。
133 0
|
消息中间件 设计模式 缓存
系统重构的道与术
准备以重构工作中容易产生误区的地方或容易被忽视的重点来聊聊,既不重复网上千篇一律的各种方案资料,也对重构工作有参考价值。
系统重构的道与术
|
算法 人工智能 机器学习/深度学习
写1行代码影响1000000000人,这是个什么项目?
这些万里挑一的年轻技术人不约而同地聚集在了这里。
1625 0
写1行代码影响1000000000人,这是个什么项目?