diff options
Diffstat (limited to 'fw/src/ether.c')
| -rw-r--r-- | fw/src/ether.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/fw/src/ether.c b/fw/src/ether.c index 54f5068..dd20971 100644 --- a/fw/src/ether.c +++ b/fw/src/ether.c @@ -38,6 +38,7 @@ enum Arplen = 28, Eminlen = 60, /* ethernet minimum frame, devether enforces it */ + Maxframe = Ehdrlen + 16*1024, Arpreq = 1, Arpreply = 2, @@ -323,11 +324,16 @@ etherisip(uchar *f, int n) int etherwriteip(uchar *p, int n, uchar *mask) { - uchar f[Ehdrlen + 64*1024], dst[IPaddrlen], hop[IPaddrlen]; + /* + * On a proc stack, which libthread keeps small: 64K here + * overran it and corrupted the data segment. pktmedium's maxtu + * is 4096, so this is already generous. + */ + uchar f[Maxframe], dst[IPaddrlen], hop[IPaddrlen]; uchar net[IPaddrlen], ournet[IPaddrlen], mac[Eaddrlen]; int type, len; - if(n < 20 || n > 64*1024 - Ehdrlen) + if(n < 20 || n > Maxframe - Ehdrlen) return -1; switch(p[0] >> 4){ case 4: @@ -355,6 +361,20 @@ etherwriteip(uchar *p, int n, uchar *mask) ipmove(hop, dst); if(!arpget(hop, mac)){ + /* + * v6 has no ARP; resolving a neighbour needs ICMPv6 + * solicitation, which is not implemented. Say so once, + * rather than dropping every v6 unicast in silence. + */ + if(!isv4(hop)){ + static int said; + + if(!said++) + fprint(2, "fw: cannot resolve %I: " + "IPv6 neighbour discovery is not implemented, " + "so v6 unicast is dropped\n", hop); + return -1; + } if(etherdebug) fprint(2, "arp: no entry for %I, dropping and asking\n", hop); arpask(hop); |
