summaryrefslogtreecommitdiff
path: root/fw/src/ether.c
diff options
context:
space:
mode:
Diffstat (limited to 'fw/src/ether.c')
-rw-r--r--fw/src/ether.c24
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);