diff options
-rw-r--r-- | sys/netinet/ip_ether.c | 44 | ||||
-rw-r--r-- | sys/netinet/ip_ether.h | 17 |
2 files changed, 38 insertions, 23 deletions
diff --git a/sys/netinet/ip_ether.c b/sys/netinet/ip_ether.c index 4514bf29c0f..a3c7dead536 100644 --- a/sys/netinet/ip_ether.c +++ b/sys/netinet/ip_ether.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ether.c,v 1.61 2012/10/05 17:17:04 camield Exp $ */ +/* $OpenBSD: ip_ether.c,v 1.62 2013/01/14 23:06:09 deraadt Exp $ */ /* * The author of this code is Angelos D. Keromytis (kermit@adk.gr) * @@ -189,7 +189,20 @@ etherip_decap(struct mbuf *m, int iphlen) /* Verify EtherIP version number */ m_copydata(m, iphlen, sizeof(struct etherip_header), (caddr_t)&eip); - if ((eip.eip_ver & ETHERIP_VER_VERS_MASK) != ETHERIP_VERSION) { + if (eip.eip_ver == ETHERIP_VERSION && eip.eip_oldver == 0) { + /* Correct */ + } else if (eip.eip_oldver == ETHERIP_VERSION && eip.eip_ver == 0) { + /* + * OpenBSD developers convinced IETF folk to create a + * "version 3" protocol which would solve a byte order + * problem -- our discussion placed "3" into the first byte. + * They knew we were starting to deploy this. When IETF + * published the standard this had changed to a nibble... + * but they failed to inform us. Awesome. + * + * For backwards compat, for a while, we must accept either. + */ + } else { DPRINTF(("etherip_input(): received EtherIP version number " "%d not suppoorted\n", eip.eip_ver)); etheripstat.etherip_adrops++; @@ -197,19 +210,6 @@ etherip_decap(struct mbuf *m, int iphlen) return; } - /* - * Note that the other potential failure of the above check is that the - * second nibble of the EtherIP header (the reserved part) is not - * zero; this is also invalid protocol behaviour. - */ - if (eip.eip_ver & ETHERIP_VER_RSVD_MASK) { - DPRINTF(("etherip_input(): received EtherIP invalid EtherIP " - "header (reserved field non-zero\n")); - etheripstat.etherip_adrops++; - m_freem(m); - return; - } - /* Finally, the pad value must be zero. */ if (eip.eip_pad) { DPRINTF(("etherip_input(): received EtherIP invalid " @@ -561,8 +561,18 @@ etherip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int proto) } if (proto == IPPROTO_ETHERIP) { - /* Set the version number */ - eip.eip_ver = ETHERIP_VERSION & ETHERIP_VER_VERS_MASK; + /* + * OpenBSD developers convinced IETF folk to create a + * "version 3" protocol which would solve a byte order + * problem -- our discussion placed "3" into the first byte. + * They knew we were starting to deploy this. When IETF + * published the standard this had changed to a nibble... + * but they failed to inform us. Awesome. + * + * We will transition step by step to the new model. + */ + eip.eip_ver = 0; + eip.eip_oldver = ETHERIP_VERSION; eip.eip_pad = 0; m_copyback(m, hlen - sizeof(struct etherip_header), sizeof(struct etherip_header), &eip, M_NOWAIT); diff --git a/sys/netinet/ip_ether.h b/sys/netinet/ip_ether.h index 0dec9c768c8..9600b3d674c 100644 --- a/sys/netinet/ip_ether.h +++ b/sys/netinet/ip_ether.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ether.h,v 1.16 2012/05/12 12:58:16 mpf Exp $ */ +/* $OpenBSD: ip_ether.h,v 1.17 2013/01/14 23:06:10 deraadt Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@adk.gr) * @@ -42,11 +42,16 @@ struct etheripstat { }; struct etherip_header { - u_int8_t eip_ver; /* version/reserved */ - u_int8_t eip_pad; /* required padding byte */ -}; -#define ETHERIP_VER_VERS_MASK 0x0f -#define ETHERIP_VER_RSVD_MASK 0xf0 +#if BYTE_ORDER == LITTLE_ENDIAN + u_int eip_oldver:4; /* reserved */ + u_int eip_ver:4; /* version */ +#endif +#if BYTE_ORDER == BIG_ENDIAN + u_int eip_ver:4; /* version */ + u_int eip_oldver:4; /* reserved */ +#endif + u_int8_t eip_pad; /* required padding byte */ +} __packed; #define ETHERIP_VERSION 0x03 |