summaryrefslogtreecommitdiff
path: root/sys/src/9/ip
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2019-03-04 03:13:29 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2019-03-04 03:13:29 +0100
commite2d310e6235b2f75bd0a1423ea424169247d5ae1 (patch)
treee95ca044b864d79f0de2633bac29854c1bc07a47 /sys/src/9/ip
parent2af6b0896040ab24c2d411a36781d7588935c6cf (diff)
devip: handle packet too big advise for icmp6, remove fragment header
Diffstat (limited to 'sys/src/9/ip')
-rw-r--r--sys/src/9/ip/icmp6.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/sys/src/9/ip/icmp6.c b/sys/src/9/ip/icmp6.c
index 018528b7a..783408076 100644
--- a/sys/src/9/ip/icmp6.c
+++ b/sys/src/9/ip/icmp6.c
@@ -704,13 +704,28 @@ icmpiput6(Proto *icmp, Ipifc *ifc, Block *bp)
msg = unreachcode[Icmp6_unknown];
else
msg = unreachcode[p->code];
-
+ Advise:
bp->rp += IPICMPSZ;
if(BLEN(bp) < MinAdvise){
ipriv->stats[LenErrs6]++;
goto raise;
}
p = (IPICMP *)bp->rp;
+
+ /* get rid of fragment header if this is the first fragment */
+ if(p->proto == FH && BLEN(bp) >= MinAdvise+IP6FHDR && MinAdvise > IP6HDR){
+ Fraghdr6 *fh = (Fraghdr6*)(bp->rp + IP6HDR);
+ if((nhgets(fh->offsetRM) & ~7) == 0){ /* first fragment */
+ p->proto = fh->nexthdr;
+ /* copy down payload over fragment header */
+ bp->rp += IP6HDR;
+ bp->wp -= IP6FHDR;
+ memmove(bp->rp, bp->rp+IP6FHDR, BLEN(bp));
+ hnputs(p->ploadlen, BLEN(bp));
+ bp->rp -= IP6HDR;
+ }
+ }
+
pr = Fsrcvpcolx(icmp->f, p->proto);
if(pr != nil && pr->advise != nil) {
(*pr->advise)(pr, bp, msg);
@@ -722,24 +737,21 @@ icmpiput6(Proto *icmp, Ipifc *ifc, Block *bp)
case TimeExceedV6:
if(p->code == 0){
- sprint(m2, "ttl exceeded at %I", p->src);
-
- bp->rp += IPICMPSZ;
- if(BLEN(bp) < MinAdvise){
- ipriv->stats[LenErrs6]++;
- goto raise;
- }
- p = (IPICMP *)bp->rp;
- pr = Fsrcvpcolx(icmp->f, p->proto);
- if(pr != nil && pr->advise != nil) {
- (*pr->advise)(pr, bp, m2);
- return;
- }
- bp->rp -= IPICMPSZ;
+ snprint(msg = m2, sizeof m2, "ttl exceeded at %I", p->src);
+ goto Advise;
+ }
+ if(p->code == 1){
+ snprint(msg = m2, sizeof m2, "frag time exceeded at %I", p->src);
+ goto Advise;
}
goticmpkt6(icmp, bp, 0);
break;
+ case PacketTooBigV6:
+ snprint(msg = m2, sizeof(m2), "packet too big for %lud mtu at %I",
+ (ulong)nhgetl(p->icmpid), p->src);
+ goto Advise;
+
case RouterAdvert:
case RouterSolicit:
goticmpkt6(icmp, bp, p->type);
@@ -793,7 +805,6 @@ icmpiput6(Proto *icmp, Ipifc *ifc, Block *bp)
freeblist(bp);
break;
- case PacketTooBigV6:
default:
goticmpkt6(icmp, bp, 0);
break;