- 论坛徽章:
- 0
|
本帖最后由 boonie 于 2010-06-08 12:08 编辑
我在2.6.9内核下,改造内核中的send_reset函数,可以把自己构造的skb发送出去,但是再2.6.29下,会出现内核错误
方法是改造send_reset函数
构造skb的函数:
- int send_packet_to_nf(char *data, int data_len)
- {
- static struct sk_buff *skb;
- static unsigned int headroom = 14 + 2; // ll is 14, and Force 16 byte alignment
- unsigned int len = data + headroom ; // data是从三层协议开始
- int ret;
-
- if (data == NULL) return -1;
- skb = alloc_skb(len, GFP_ATOMIC);
- if (skb == NULL) {
- printk("alloc skb error\n");
- return -1;
- }
- skb_reserve(skb, headroom);
- skb_put(skb, data_len);
- memcpy(skb->data, data, data_len);
-
- skb->protocol = 8; // IP type
-
- if (connect_type == 1)
- skb->pkt_type = PACKET_HOST; // dest mac == host mac
- else if(connect_type == 2)
- skb->pkt_type = PACKET_OUTGOING; // dest mac != host mac
- skb->mac.raw = skb->data;
- skb->nh.raw = skb->data;
- ret = send_skb(skb, hook);
- kfree_skb(skb);
-
- return ret;
- }
复制代码 改造后的send_reset的函数名为send_skb()
- static void connection_attach(struct sk_buff *new_skb, struct sk_buff *skb)
- {
- void (*attach)(struct sk_buff *, struct sk_buff *);
- /* Avoid module unload race with ip_ct_attach being NULLed out */
- if (skb->nfct && (attach = ip_ct_attach) != NULL) {
- mb(); /* Just to be sure: must be read before executing this */
- attach(new_skb, skb);
- }
- }
- static int send_skb(struct sk_buff *oldskb, int hook)
- {
- struct sk_buff *nskb;
- struct tcphdr _otcph, *oth;
- struct rtable *rt;
- //int needs_ack;
- int hh_len;
- if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)) return -1;
- /* FIXME: Check checksum --RR */
- if ((rt = route_reverse(oldskb, hook)) == NULL) return -1;
- hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
- nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
- GFP_ATOMIC);
- if (!nskb) {
- dst_release(&rt->u.dst);
- return -1;
- }
- dst_release(nskb->dst);
- nskb->dst = &rt->u.dst;
- /* This packet will not be the same as the other: clear nf fields */
- nf_reset(nskb);
- nskb->nfcache = 0;
- nskb->nfmark = 0;
- #ifdef CONFIG_BRIDGE_NETFILTER
- nf_bridge_put(nskb->nf_bridge);
- nskb->nf_bridge = NULL;
- #endif
- connection_attach(nskb, oldskb);
- NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
- ip_finish_output);
- return 0;
- }
复制代码 2.6.29下改造后的send_reset的函数名为send_skb
- static int send_skb(struct sk_buff *oldskb, int hook)
- {
- struct sk_buff *nskb;
- const struct iphdr *oiph;
- struct iphdr *niph;
- const struct tcphdr *oth;
- struct tcphdr _otcph, *tcph;
- unsigned int addr_type;
- oiph = ip_hdr(oldskb);
- nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
- LL_MAX_HEADER, GFP_ATOMIC);
- if (!nskb)
- return -1;
- skb_reserve(nskb, LL_MAX_HEADER);
- skb_reset_network_header(nskb);
- addr_type = RTN_UNSPEC;
- if (hook != NF_INET_FORWARD
- #ifdef CONFIG_BRIDGE_NETFILTER
- || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED)
- #endif
- )
- addr_type = RTN_LOCAL;
- /* ip_route_me_harder expects skb->dst to be set */
- dst_hold(oldskb->dst);
- nskb->dst = oldskb->dst;
- if (ip_route_me_harder(nskb, addr_type))
- goto free_nskb;
- niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
- nskb->ip_summed = CHECKSUM_NONE;
- /* "Never happens" */
- if (nskb->len > dst_mtu(nskb->dst))
- goto free_nskb;
- nf_ct_attach(nskb, oldskb);
- ip_local_out(nskb);
- return 0;
- free_nskb:
- kfree_skb(nskb);
- return -1;
- }
复制代码 有在2.6.29做过类似的事情吗? |
|