M ip/icmp.c => ip/icmp.c +21 -0
@@ 121,6 121,27 @@ icmpkick(Conv *c, int l)
ipoput(bp, 0, MAXTTL);
}
+extern void
+icmpnoconv(Block *bp)
+{
+ Block *nbp;
+ Icmp *p, *np;
+
+ p = (Icmp *)bp->rp;
+ nbp = allocb(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8);
+ nbp->wp += ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8;
+ np = (Icmp *)nbp->rp;
+ memmove(np->dst, p->src, sizeof(np->dst));
+ memmove(np->src, p->dst, sizeof(np->src));
+ memmove(np->data, bp->rp, ICMP_IPSIZE + 8);
+ np->type = Unreachable;
+ np->code = 3;
+ p->proto = IP_ICMPPROTO;
+ hnputs(p->icmpid, 0);
+ memset(p->cksum, 0, sizeof(p->cksum));
+ hnputs(p->cksum, ptclcsum(bp, ICMP_IPSIZE, blocklen(bp) - ICMP_IPSIZE));
+ ipoput(nbp, 0, MAXTTL);
+}
static void
goticmpkt(Block *bp)
M ip/ip.h => ip/ip.h +1 -0
@@ 250,6 250,7 @@ int equivip(byte*, byte*);
void fatal(byte*, ...);
void hnputl(byte*, ulong);
void hnputs(byte*, ushort);
+void icmpnoconv(Block*);
void initfrag(int);
ushort ipcsum(byte*);
void (*ipextprotoiput)(Block*);
M ip/udp.c => ip/udp.c +1 -0
@@ 244,6 244,7 @@ udpiput(Media *m, Block *bp)
if(*p == nil) {
netlog(Logudp, "udp: no conv %I.%d -> %I.%d\n", src, rport,
dst, lport);
+ icmpnoconv(bp);
freeblist(bp);
return;
}