- 论坛徽章:
- 0
|
- /*
- * linux-2.6.22.1/net/ipv4/ip_fragment.c
- *
- * Oops, a fragment queue timed out.
- * Kill it and send an ICMP reply.
- *
- * sisi 2007-8-13 02:27pm
- */
- static void ip_expire(unsigned long arg)
- {
- struct ipq *qp = (struct ipq *) arg;
- spin_lock(&qp->lock);
- if (qp->last_in & COMPLETE)
- goto out;
- ipq_kill(qp);
- IP_INC_STATS_BH(IPSTATS_MIB_REASMTIMEOUT);
- IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
- if ((qp->last_in&FIRST_IN) && qp->fragments != NULL) {
- struct sk_buff *head = qp->fragments;
- /*
- * Send an ICMP "Fragment Reassembly Timeout" message.
- *
- * 由这里引发
- */
- if ((head->dev = dev_get_by_index(qp->iif)) != NULL) {
- icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
- dev_put(head->dev);
- }
- }
- out:
- spin_unlock(&qp->lock);
- ipq_put(qp, NULL);
- }
- void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
- {
- struct iphdr *iph;
- int room;
- struct icmp_bxm icmp_param;
- struct rtable *rt = (struct rtable *)skb_in->dst;
- struct ipcm_cookie ipc;
- __be32 saddr;
- u8 tos;
- if (!rt) {
- /* 在这里兑现,
- *
- * defarg, if issued by netfilter,
- * at PRE_ROUTING in normal cases,
- * 谁给skb_in->dst赋值?
- *
- * 本应发送Fragment Reassembly Timeout message,
- * 确没有发。
- */
- goto out;
- }
- }
复制代码
- shot bug by daemeon
- --- linux-2.6.22/net/ipv4/icmp.c 2007-07-09 07:32:17.000000000 +0800
- +++ new/net/ipv4/icmp.c 2007-08-13 17:36:21.000000000 +0800
- @@ -440,9 +440,6 @@ void icmp_send(struct sk_buff *skb_in, i
- __be32 saddr;
- u8 tos;
- - if (!rt)
- - goto out;
- -
- /*
- * Find the original header. It is expected to be valid, of course.
- * Check this, icmp_send is called from the most obscure devices
- @@ -461,16 +458,24 @@ void icmp_send(struct sk_buff *skb_in, i
- goto out;
- /*
- - * Now check at the protocol level
- + * Only reply to fragment 0. We byte re-order the constant
- + * mask for efficiency.
- */
- - if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
- + if (iph->frag_off & htons(IP_OFFSET))
- goto out;
- + if (!rt) {
- + if (ip_route_input(skb_in, iph->daddr, iph->saddr,
- + iph->tos, skb_in->dev) != 0)
- + goto out;
- +
- + rt = (struct rtable *)skb_in->dst;
- + }
- +
- /*
- - * Only reply to fragment 0. We byte re-order the constant
- - * mask for efficiency.
- + * Now check at the protocol level
- */
- - if (iph->frag_off & htons(IP_OFFSET))
- + if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
- goto out;
- /*
复制代码
daemeon won ¥4。
版权问题,请daemeon大哥确认。
- refined by rtable
- + if (!rt) {
- + struct net_device __ndev;
- +
- + if (skb_in->input_dev)
- + __ndev = skb_in->input_dev;
- + else
- + __ndev = get_dev_by_index(skb_in->iif);
- + if (!__ndev)
- + goto out;
- +
- + if (ip_route_input(skb_in, iph->daddr, iph->saddr,
- + iph->tos, __ndev) != 0)
- + goto out;
- +
- + rt = (struct rtable *)skb_in->dst;
- + }
复制代码
[ 本帖最后由 sisi8408 于 2007-8-18 14:37 编辑 ] |
|