- 论坛徽章:
- 2
|
我在工作中和家中运行的ubuntu系统是12.04,发现内核版本已经是至少是3.11版本了,其中struct sk_buff的结构相较于以前变化了不少,下面是我摘取的
一个功能模块,主要是调用dev_queue_xmit发送自己构造的包- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/ip.h>
- #include <linux/tcp.h>
- #include <net/ip.h>
- #include <net/checksum.h>
- int cp_dev_xmit_tcp (const char *dev_name,
- const u_char * smac, const u_char * dmac,
- u_char * pkt, int pkt_len,
- __be32 sip, __be32 dip,
- __be16 sport, __be16 dport,
- __be32 seq, __be32 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 || !dev_name)
- goto out;
- dev = dev_get_by_name(&init_net,dev_name);
- if (NULL == dev)
- {
- pr_info("dev is NULL!!!!\n");
- goto out;
- }
- pr_info("dev->name[%s],mtd[%d]\n",dev->name,dev->mtu);
- skb = alloc_skb (pkt_len + sizeof (struct iphdr) + sizeof (struct tcphdr) + LL_RESERVED_SPACE (dev), GFP_ATOMIC);
- if (NULL == skb)
- {
- dev_put (dev);
- pr_info("alloc skb is NULL!!!!\n");
- goto out;
- }
- memset(skb,0,pkt_len + sizeof (struct iphdr) + sizeof (struct tcphdr) + LL_RESERVED_SPACE (dev));
- pr_info(" skb is start!!\n");
- skb_reserve (skb, LL_RESERVED_SPACE (dev));
- skb->dev = dev;
- skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_IP);
- skb->ip_summed = CHECKSUM_NONE;
- skb->priority = 0;
- skb_put(skb, sizeof (struct iphdr));
- skb_put(skb, sizeof (struct tcphdr));
- skb->network_header = (U8 *)ip_hdr(skb) - skb->head;
- skb->transport_header = (U8 *)tcp_hdr(skb) - skb->head;
- pdata = skb_put (skb, pkt_len);
- {
- if (NULL != pkt)
- memcpy (pdata, pkt, pkt_len);
- }
- pr_info("tcphdr is start!!\n");
- {
- tcph = tcp_hdr(skb);
- pr_info("tcphdr is start!!1\n");
- memset (tcph, 0, sizeof (struct tcphdr));
- pr_info("tcphdr is start!!2\n");
- pr_info("tcphdr is start!!2\n");
- tcph->source = sport;
- pr_info("tcphdr is start!!3\n");
- tcph->dest = dport;
- pr_info("tcphdr is start!!4\n");
- if(seq)
- tcph->seq = seq;
- if(ack_seq)
- tcph->ack_seq = ack_seq;
- pr_info("tcphdr is start!!5\n");
- tcph->doff = 5;
- pr_info("tcphdr is start!!6\n");
- tcph->psh = psh;
- pr_info("tcphdr is start!!7\n");
- tcph->fin = fin;
- pr_info("tcphdr is start!!8\n");
- tcph->ack = 1;
- pr_info("tcphdr is start!!9\n");
- tcph->window = __constant_htons (65535);
- pr_info("tcphdr is start!!10\n");
- skb->csum = 0;
- pr_info("tcphdr is start!!11\n");
- tcph->check = 0;
- pr_info("tcphdr is start!!12\n");
- }
- pr_info("iphdr is start!!13\n");
- {
- 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);
- ip_send_check(iph);
- skb_push (skb, 14);
- { //eth header
- ethdr = (struct ethhdr *) skb->data;
- memcpy (ethdr->h_dest, dmac, ETH_ALEN);
- memcpy (ethdr->h_source, smac, ETH_ALEN);
- ethdr->h_proto = __constant_htons (ETH_P_IP);
- }
- pr_info("fasong is start!!\n");
- 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 hello_kernel(void)
- {
- cp_dev_queue_xmit(.......);
- return 0;
- }
复制代码 结果使用dmesg后查看发现内核打印“protocol 0x0800 is buggy, dev eth0” (eth0是我在调用cp_dev_queue_xmit函数时传递的参数)
请教各位神牛,新版本的内核下,我这个程序有啥问题啊?
谢谢了
|
|