When an incoming packet is for secnet itself, secnet checks the
fragmentation field in the IP header.
(Contrary to the spec, secnet discards fragmented packets addressed to
its own private address; however, this is a tolerable defect as secnet
never sends packets of its own apart from ICMP errors and ICMP Echo
Reply.)
However, secnet would incorrectly check the reserved flag bit in the
16-bit fragmentation superfield. Fix this. Also introduce some
manifest constants for the bits in the 16-bit fragmentation
superfield.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
uint16_t tot_len;
uint16_t id;
uint16_t frag_off;
uint16_t tot_len;
uint16_t id;
uint16_t frag_off;
+#define IPHDR_FRAG_OFF ((uint16_t)0x1fff)
+#define IPHDR_FRAG_MORE ((uint16_t)0x2000)
+#define IPHDR_FRAG_DONT ((uint16_t)0x4000)
+/* reserved 0x8000 */
uint8_t ttl;
uint8_t protocol;
uint16_t check;
uint8_t ttl;
uint8_t protocol;
uint16_t check;
}
}
/* How do we spot broadcast destination addresses? */
}
}
/* How do we spot broadcast destination addresses? */
- if (ntohs(iph->frag_off)&0x1fff) return False; /* Non-initial fragment */
+ if (ntohs(iph->frag_off)&IPHDR_FRAG_OFF) return False;
source=ntohl(iph->saddr);
if (source==0) return False;
if ((source&0xff000000)==0x7f000000) return False;
source=ntohl(iph->saddr);
if (source==0) return False;
if ((source&0xff000000)==0x7f000000) return False;
}
h=(struct icmphdr *)buf->start;
}
h=(struct icmphdr *)buf->start;
- if ((ntohs(h->iph.frag_off)&0xbfff)!=0) {
+ if ((ntohs(h->iph.frag_off)&(IPHDR_FRAG_OFF|IPHDR_FRAG_MORE))!=0) {
Message(M_WARNING,"%s: fragmented packet addressed to secnet; "
"ignoring it\n",st->name);
BUF_FREE(buf);
Message(M_WARNING,"%s: fragmented packet addressed to secnet; "
"ignoring it\n",st->name);
BUF_FREE(buf);