M ip/icmp.c => ip/icmp.c +15 -3
@@ 215,8 215,8 @@ icmpttlexceeded(Fs *f, uchar *ia, Block *bp)
}
-extern void
-icmpnoconv(Fs *f, Block *bp)
+static void
+icmpunreachable(Fs *f, Block *bp, int code)
{
Block *nbp;
Icmp *p, *np;
@@ 244,7 244,7 @@ icmpnoconv(Fs *f, Block *bp)
memmove(np->src, p->dst, sizeof(np->src));
memmove(np->data, bp->rp, ICMP_IPSIZE + 8);
np->type = Unreachable;
- np->code = 3;
+ np->code = code;
np->proto = IP_ICMPPROTO;
hnputs(np->icmpid, 0);
hnputs(np->seq, 0);
@@ 253,6 253,18 @@ icmpnoconv(Fs *f, Block *bp)
ipoput4(f, nbp, 0, MAXTTL, DFLTTOS);
}
+extern void
+icmpnoconv(Fs *f, Block *bp)
+{
+ icmpunreachable(f, bp, 3);
+}
+
+extern void
+icmpcantfrag(Fs *f, Block *bp)
+{
+ icmpunreachable(f, bp, 4);
+}
+
static void
goticmpkt(Proto *icmp, Block *bp)
{
M ip/ip.c => ip/ip.c +3 -0
@@ 312,9 312,12 @@ ipoput4(Fs *f, Block *bp, int gating, int ttl, int tos)
return;
}
+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);
netlog(f, Logip, "%V: eh->frag[0] & (IP_DF>>8)\n", eh->dst);
goto raise;
}
M ip/ip.h => ip/ip.h +1 -0
@@ 614,6 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 icmpttlexceeded(Fs*, uchar*, Block*);
extern ushort ipcsum(uchar*);
extern void ipiput4(Fs*, Ipifc*, Block*);