M ip/icmp.c => ip/icmp.c +5 -5
@@ 216,7 216,7 @@ icmpttlexceeded(Fs *f, uchar *ia, Block *bp)
}
static void
-icmpunreachable(Fs *f, Block *bp, int code)
+icmpunreachable(Fs *f, Block *bp, int code, int seq)
{
Block *nbp;
Icmp *p, *np;
@@ 247,7 247,7 @@ icmpunreachable(Fs *f, Block *bp, int code)
np->code = code;
np->proto = IP_ICMPPROTO;
hnputs(np->icmpid, 0);
- hnputs(np->seq, 0);
+ hnputs(np->seq, seq);
memset(np->cksum, 0, sizeof(np->cksum));
hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
ipoput4(f, nbp, 0, MAXTTL, DFLTTOS);
@@ 256,13 256,13 @@ icmpunreachable(Fs *f, Block *bp, int code)
extern void
icmpnoconv(Fs *f, Block *bp)
{
- icmpunreachable(f, bp, 3);
+ icmpunreachable(f, bp, 3, 0);
}
extern void
-icmpcantfrag(Fs *f, Block *bp)
+icmpcantfrag(Fs *f, Block *bp, int mtu)
{
- icmpunreachable(f, bp, 4);
+ icmpunreachable(f, bp, 4, mtu);
}
static void
M ip/ip.c => ip/ip.c +5 -1
@@ 317,7 317,7 @@ if((eh->frag[0] & (IP_DF>>8)) && !gating) print("%V: DF set\n", eh->dst);
if(eh->frag[0] & (IP_DF>>8)){
ip->stats[FragFails]++;
ip->stats[OutDiscards]++;
- icmpcantfrag(f, bp);
+ icmpcantfrag(f, bp, medialen);
netlog(f, Logip, "%V: eh->frag[0] & (IP_DF>>8)\n", eh->dst);
goto raise;
}
@@ 528,6 528,10 @@ ipiput4(Fs *f, Ipifc *ifc, Block *bp)
h = (Ip4hdr*)(bp->rp);
}
+ /* don't let any frag info go up the stack */
+ h->frag[0] = 0;
+ h->frag[1] = 0;
+
proto = h->proto;
p = Fsrcvpcol(f, proto);
if(p != nil && p->rcv != nil) {
M ip/ip.h => ip/ip.h +1 -1
@@ 614,7 614,7 @@ extern long ipgateread6(Fs *f, char *cp, ulong offset, int n);
extern void iprouting(Fs*, int);
extern void closeifcconv(Ifcconv*);
extern void icmpnoconv(Fs*, Block*);
-extern void icmpcantfrag(Fs*, Block*);
+extern void icmpcantfrag(Fs*, Block*, int);
extern void icmpttlexceeded(Fs*, uchar*, Block*);
extern ushort ipcsum(uchar*);
extern void ipiput4(Fs*, Ipifc*, Block*);