ip/icmp: only reply to echo request when directed to us and source is unicast
This commit is contained in:
parent
a8d00e5d56
commit
ef5c862ce9
2 changed files with 42 additions and 25 deletions
|
@ -190,6 +190,30 @@ icmpkick(void *x, Block *bp)
|
||||||
ipoput4(c->p->f, bp, 0, c->ttl, c->tos, nil);
|
ipoput4(c->p->f, bp, 0, c->ttl, c->tos, nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ip4reply(Fs *f, uchar ip4[4])
|
||||||
|
{
|
||||||
|
uchar addr[IPaddrlen];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
v4tov6(addr, ip4);
|
||||||
|
if(ipismulticast(addr))
|
||||||
|
return 0;
|
||||||
|
i = ipforme(f, addr);
|
||||||
|
return i == 0 || (i & Runi) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ip4me(Fs *f, uchar ip4[4])
|
||||||
|
{
|
||||||
|
uchar addr[IPaddrlen];
|
||||||
|
|
||||||
|
v4tov6(addr, ip4);
|
||||||
|
if(ipismulticast(addr))
|
||||||
|
return 0;
|
||||||
|
return (ipforme(f, addr) & Runi) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
icmpttlexceeded(Fs *f, uchar *ia, Block *bp)
|
icmpttlexceeded(Fs *f, uchar *ia, Block *bp)
|
||||||
{
|
{
|
||||||
|
@ -197,6 +221,8 @@ icmpttlexceeded(Fs *f, uchar *ia, Block *bp)
|
||||||
Icmp *p, *np;
|
Icmp *p, *np;
|
||||||
|
|
||||||
p = (Icmp *)bp->rp;
|
p = (Icmp *)bp->rp;
|
||||||
|
if(!ip4reply(f, p->src))
|
||||||
|
return;
|
||||||
|
|
||||||
netlog(f, Logicmp, "sending icmpttlexceeded -> %V\n", p->src);
|
netlog(f, Logicmp, "sending icmpttlexceeded -> %V\n", p->src);
|
||||||
nbp = allocb(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8);
|
nbp = allocb(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8);
|
||||||
|
@ -214,7 +240,6 @@ icmpttlexceeded(Fs *f, uchar *ia, Block *bp)
|
||||||
memset(np->cksum, 0, sizeof(np->cksum));
|
memset(np->cksum, 0, sizeof(np->cksum));
|
||||||
hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
|
hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
|
||||||
ipoput4(f, nbp, 0, MAXTTL, DFLTTOS, nil);
|
ipoput4(f, nbp, 0, MAXTTL, DFLTTOS, nil);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -222,19 +247,9 @@ icmpunreachable(Fs *f, Block *bp, int code, int seq)
|
||||||
{
|
{
|
||||||
Block *nbp;
|
Block *nbp;
|
||||||
Icmp *p, *np;
|
Icmp *p, *np;
|
||||||
int i;
|
|
||||||
uchar addr[IPaddrlen];
|
|
||||||
|
|
||||||
p = (Icmp *)bp->rp;
|
p = (Icmp *)bp->rp;
|
||||||
|
if(!ip4me(f, p->dst) || !ip4reply(f, p->src))
|
||||||
/* only do this for unicast sources and destinations */
|
|
||||||
v4tov6(addr, p->dst);
|
|
||||||
i = ipforme(f, addr);
|
|
||||||
if((i&Runi) == 0)
|
|
||||||
return;
|
|
||||||
v4tov6(addr, p->src);
|
|
||||||
i = ipforme(f, addr);
|
|
||||||
if(i != 0 && (i&Runi) == 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
netlog(f, Logicmp, "sending icmpnoconv -> %V\n", p->src);
|
netlog(f, Logicmp, "sending icmpnoconv -> %V\n", p->src);
|
||||||
|
@ -283,9 +298,7 @@ goticmpkt(Proto *icmp, Block *bp)
|
||||||
s = *c;
|
s = *c;
|
||||||
if(s->lport == recid)
|
if(s->lport == recid)
|
||||||
if(ipcmp(s->raddr, dst) == 0){
|
if(ipcmp(s->raddr, dst) == 0){
|
||||||
bp = concatblock(bp);
|
qpass(s->rq, concatblock(bp));
|
||||||
if(bp != nil)
|
|
||||||
qpass(s->rq, bp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,12 +306,14 @@ goticmpkt(Proto *icmp, Block *bp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Block *
|
static Block *
|
||||||
mkechoreply(Block *bp)
|
mkechoreply(Block *bp, Fs *f)
|
||||||
{
|
{
|
||||||
Icmp *q;
|
Icmp *q;
|
||||||
uchar ip[4];
|
uchar ip[4];
|
||||||
|
|
||||||
q = (Icmp *)bp->rp;
|
q = (Icmp *)bp->rp;
|
||||||
|
if(!ip4me(f, q->dst) || !ip4reply(f, q->src))
|
||||||
|
return nil;
|
||||||
q->vihl = IP_VER4;
|
q->vihl = IP_VER4;
|
||||||
memmove(ip, q->src, sizeof(q->dst));
|
memmove(ip, q->src, sizeof(q->dst));
|
||||||
memmove(q->src, q->dst, sizeof(q->src));
|
memmove(q->src, q->dst, sizeof(q->src));
|
||||||
|
@ -376,7 +391,11 @@ icmpiput(Proto *icmp, Ipifc*, Block *bp)
|
||||||
case EchoRequest:
|
case EchoRequest:
|
||||||
if (iplen < n)
|
if (iplen < n)
|
||||||
bp = trimblock(bp, 0, iplen);
|
bp = trimblock(bp, 0, iplen);
|
||||||
r = mkechoreply(concatblock(bp));
|
if(bp->next)
|
||||||
|
bp = concatblock(bp);
|
||||||
|
r = mkechoreply(bp, icmp->f);
|
||||||
|
if(r == nil)
|
||||||
|
goto raise;
|
||||||
ipriv->out[EchoReply]++;
|
ipriv->out[EchoReply]++;
|
||||||
ipoput4(icmp->f, r, 0, MAXTTL, DFLTTOS, nil);
|
ipoput4(icmp->f, r, 0, MAXTTL, DFLTTOS, nil);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -312,9 +312,7 @@ goticmpkt6(Proto *icmp, Block *bp, int muxkey)
|
||||||
for(c = icmp->conv; *c; c++){
|
for(c = icmp->conv; *c; c++){
|
||||||
s = *c;
|
s = *c;
|
||||||
if(s->lport == recid && ipcmp(s->raddr, addr) == 0){
|
if(s->lport == recid && ipcmp(s->raddr, addr) == 0){
|
||||||
bp = concatblock(bp);
|
qpass(s->rq, concatblock(bp));
|
||||||
if(bp != nil)
|
|
||||||
qpass(s->rq, bp);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,6 +326,8 @@ mkechoreply6(Block *bp, Ipifc *ifc)
|
||||||
uchar addr[IPaddrlen];
|
uchar addr[IPaddrlen];
|
||||||
IPICMP *p = (IPICMP *)(bp->rp);
|
IPICMP *p = (IPICMP *)(bp->rp);
|
||||||
|
|
||||||
|
if(isv6mcast(p->src))
|
||||||
|
return nil;
|
||||||
ipmove(addr, p->src);
|
ipmove(addr, p->src);
|
||||||
if(!isv6mcast(p->dst))
|
if(!isv6mcast(p->dst))
|
||||||
ipmove(p->src, p->dst);
|
ipmove(p->src, p->dst);
|
||||||
|
@ -730,7 +730,9 @@ icmpiput6(Proto *icmp, Ipifc *ipifc, Block *bp)
|
||||||
|
|
||||||
switch(p->type) {
|
switch(p->type) {
|
||||||
case EchoRequestV6:
|
case EchoRequestV6:
|
||||||
r = mkechoreply6(concatblock(bp), ipifc);
|
if(bp->next)
|
||||||
|
bp = concatblock(bp);
|
||||||
|
r = mkechoreply6(bp, ipifc);
|
||||||
if(r == nil)
|
if(r == nil)
|
||||||
goto raise;
|
goto raise;
|
||||||
ipriv->out[EchoReply]++;
|
ipriv->out[EchoReply]++;
|
||||||
|
@ -866,10 +868,6 @@ icmpstats6(Proto *icmp6, char *buf, int len)
|
||||||
if(icmpnames6[i])
|
if(icmpnames6[i])
|
||||||
p = seprint(p, e, "%s: %lud %lud\n", icmpnames6[i],
|
p = seprint(p, e, "%s: %lud %lud\n", icmpnames6[i],
|
||||||
priv->in[i], priv->out[i]);
|
priv->in[i], priv->out[i]);
|
||||||
/* else
|
|
||||||
p = seprint(p, e, "%d: %lud %lud\n", i, priv->in[i],
|
|
||||||
priv->out[i]);
|
|
||||||
*/
|
|
||||||
return p - buf;
|
return p - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue