diff -Nrup linux-2.0.39-ori/drivers/isdn/isdn_net.c linux-2.0.39/drivers/isdn/isdn_net.c --- linux-2.0.39-ori/drivers/isdn/isdn_net.c 1999-06-13 19:21:01.000000000 +0200 +++ linux-2.0.39/drivers/isdn/isdn_net.c 2003-03-18 12:06:56.000000000 +0100 @@ -378,6 +378,7 @@ isdn_net_unreachable(struct device *dev, #if (LINUX_VERSION_CODE < 0x02010f) /* 2.1.15 */ ,dev #endif + ,1 ); } } diff -Nrup linux-2.0.39-ori/include/net/icmp.h linux-2.0.39/include/net/icmp.h --- linux-2.0.39-ori/include/net/icmp.h 1997-12-02 23:20:24.000000000 +0100 +++ linux-2.0.39/include/net/icmp.h 2003-03-18 12:01:05.000000000 +0100 @@ -28,7 +28,8 @@ extern struct icmp_err icmp_err_convert[ extern struct icmp_mib icmp_statistics; extern void icmp_send(struct sk_buff *skb_in, int type, int code, - unsigned long info, struct device *dev); + unsigned long info, struct device *dev, + int hdrincl); extern int icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt, __u32 daddr, unsigned short len, __u32 saddr, diff -Nrup linux-2.0.39-ori/net/ipv4/arp.c linux-2.0.39/net/ipv4/arp.c --- linux-2.0.39-ori/net/ipv4/arp.c 1999-06-13 19:21:04.000000000 +0200 +++ linux-2.0.39/net/ipv4/arp.c 2003-03-18 11:57:40.000000000 +0100 @@ -1430,7 +1430,7 @@ int arp_find(unsigned char *haddr, u32 p */ else { - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev, 1); skb_device_unlock(skb); /* else it is lost forever */ dev_kfree_skb(skb, FREE_WRITE); } diff -Nrup linux-2.0.39-ori/net/ipv4/icmp.c linux-2.0.39/net/ipv4/icmp.c --- linux-2.0.39-ori/net/ipv4/icmp.c 1998-06-04 00:17:50.000000000 +0200 +++ linux-2.0.39/net/ipv4/icmp.c 2003-03-18 12:08:28.000000000 +0100 @@ -532,7 +532,7 @@ static void icmp_build_xmit(struct icmp_ * MUST reply to only the first fragment. */ -void icmp_send(struct sk_buff *skb_in, int type, int code, unsigned long info, struct device *dev) +void icmp_send(struct sk_buff *skb_in, int type, int code, unsigned long info, struct device *dev, int hdrincl) { struct iphdr *iph; struct icmphdr *icmph; @@ -618,11 +618,15 @@ void icmp_send(struct sk_buff *skb_in, i icmp_param.icmph.code=code; icmp_param.icmph.un.gateway = info; icmp_param.data_ptr=iph; + /* RFC says return as much as we can without exceeding 576 bytes */ room = 576 - sizeof(struct iphdr) - icmp_param.replyopts.optlen; - icmp_param.data_len=(iph->ihl<<2)+skb_in->len; /* RFC says return as much as we can without exceeding 576 bytes */ + icmp_param.data_len=skb_in->len; + if (! hdrincl) { + icmp_param.data_len += (iph->ihl<<2); + } if (icmp_param.data_len > room) icmp_param.data_len = room; /* * Build and send the packet. */ diff -Nrup linux-2.0.39-ori/net/ipv4/ip_forward.c linux-2.0.39/net/ipv4/ip_forward.c --- linux-2.0.39-ori/net/ipv4/ip_forward.c 1998-06-04 00:17:50.000000000 +0200 +++ linux-2.0.39/net/ipv4/ip_forward.c 2003-03-18 12:01:47.000000000 +0100 @@ -159,7 +159,7 @@ int ip_forward(struct sk_buff *skb, stru if (iph->ttl <= 0) { /* Tell the sender its packet died... */ - icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, dev); + icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, dev, 1); return -1; } @@ -186,7 +186,7 @@ int ip_forward(struct sk_buff *skb, stru * Tell the sender its packet cannot be delivered. Again * ICMP is screened later. */ - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev, 1); return -1; } @@ -207,7 +207,7 @@ int ip_forward(struct sk_buff *skb, stru */ ip_rt_put(rt); - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0, dev); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0, dev, 1); return -1; } @@ -230,7 +230,7 @@ int ip_forward(struct sk_buff *skb, stru is avoiding sending a frame the receiver will not believe anyway.. */ iph->daddr != raddr/*ANK*/ && !opt->srr) - icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev); + icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev, 1); #endif #ifdef CONFIG_IP_MROUTE @@ -299,7 +299,7 @@ int ip_forward(struct sk_buff *skb, stru case FW_MASQUERADE: break; case FW_REJECT: - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev, 1); /* fall thru */ default: if (rt) @@ -371,10 +371,10 @@ int ip_forward(struct sk_buff *skb, stru if (premasq_len_diff < 0) icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, - htonl(dev2->mtu+premasq_len_diff), dev); + htonl(dev2->mtu+premasq_len_diff), dev, 1); else #endif - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(dev2->mtu), dev); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(dev2->mtu), dev, 1); if(rt) ip_rt_put(rt); return -1; @@ -487,7 +487,7 @@ int ip_forward(struct sk_buff *skb, stru /* FW_ACCEPT and FW_MASQUERADE are treated equal: masquerading is only supported via forward rules */ if (fw_res == FW_REJECT) - icmp_send(skb2, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev); + icmp_send(skb2, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev, 1); if (skb != skb2) kfree_skb(skb2,FREE_WRITE); if (rt) diff -Nrup linux-2.0.39-ori/net/ipv4/ip_fragment.c linux-2.0.39/net/ipv4/ip_fragment.c --- linux-2.0.39-ori/net/ipv4/ip_fragment.c 1998-06-04 00:17:50.000000000 +0200 +++ linux-2.0.39/net/ipv4/ip_fragment.c 2003-03-18 11:59:40.000000000 +0100 @@ -213,7 +213,7 @@ static void ip_expire(unsigned long arg) /* This if is always true... shrug */ if(qp->fragments!=NULL) icmp_send(qp->fragments->skb,ICMP_TIME_EXCEEDED, - ICMP_EXC_FRAGTIME, 0, qp->dev); + ICMP_EXC_FRAGTIME, 0, qp->dev, 1); /* * Nuke the fragment queue. @@ -698,7 +698,7 @@ void ip_fragment(struct sock *sk, struct if(mtu<8) { /* It's wrong but it's better than nothing */ - icmp_send(skb,ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED,htons(dev->mtu), dev); + icmp_send(skb,ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED,htons(dev->mtu), dev, 1); ip_statistics.IpFragFails++; return; } diff -Nrup linux-2.0.39-ori/net/ipv4/ip_input.c linux-2.0.39/net/ipv4/ip_input.c --- linux-2.0.39-ori/net/ipv4/ip_input.c 1998-11-15 19:33:21.000000000 +0100 +++ linux-2.0.39/net/ipv4/ip_input.c 2003-03-18 12:00:17.000000000 +0100 @@ -397,7 +397,7 @@ int ip_rcv(struct sk_buff *skb, struct d if ((fwres=call_in_firewall(PF_INET, skb->dev, iph, &rport)) srrspace) { icmp_send(skb, ICMP_PARAMETERPROB, 0, opt->srr+2, - skb->dev); + skb->dev, 1); kfree_skb(skb, FREE_WRITE); return 0; } @@ -706,7 +706,7 @@ int ip_rcv(struct sk_buff *skb, struct d else if (!flag) /* Free and report errors */ { if (brd != IS_BROADCAST && brd!=IS_MULTICAST) - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0, dev); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0, dev, 1); kfree_skb(skb, FREE_WRITE); } @@ -734,7 +734,7 @@ int ip_rcv(struct sk_buff *skb, struct d if (sysctl_ip_forward) { if (opt && opt->is_strictroute) { - icmp_send(skb, ICMP_PARAMETERPROB, 0, 16, skb->dev); + icmp_send(skb, ICMP_PARAMETERPROB, 0, 16, skb->dev, 1); kfree_skb(skb, FREE_WRITE); return -1; } diff -Nrup linux-2.0.39-ori/net/ipv4/ip_options.c linux-2.0.39/net/ipv4/ip_options.c --- linux-2.0.39-ori/net/ipv4/ip_options.c 1996-04-18 08:47:39.000000000 +0200 +++ linux-2.0.39/net/ipv4/ip_options.c 2003-03-18 12:00:15.000000000 +0100 @@ -466,7 +466,7 @@ eol: error: if (skb) { - icmp_send(skb, ICMP_PARAMETERPROB, 0, pp_ptr-iph, skb->dev); + icmp_send(skb, ICMP_PARAMETERPROB, 0, pp_ptr-iph, skb->dev, 1); kfree_skb(skb, FREE_READ); } return -EINVAL; diff -Nrup linux-2.0.39-ori/net/ipv4/udp.c linux-2.0.39/net/ipv4/udp.c --- linux-2.0.39-ori/net/ipv4/udp.c 1997-12-10 18:14:01.000000000 +0100 +++ linux-2.0.39/net/ipv4/udp.c 2003-03-18 11:54:43.000000000 +0100 @@ -1095,7 +1095,7 @@ int udp_rcv(struct sk_buff *skb, struct udp_statistics.UdpNoPorts++; if (addr_type != IS_BROADCAST && addr_type != IS_MULTICAST) { - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0, dev); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0, dev, 0); } /* * Hmm. We got an UDP broadcast to a port to which we