From 9aac17936778ef105559ddaa9816fe8f11b456ca Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Wed, 2 Aug 2017 15:01:27 +0200 Subject: [PATCH] ntp: skip IPv6 extension headers Handle IPv6 packets with extension headers received from the error queue on Linux. --- ntp_io_linux.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/ntp_io_linux.c b/ntp_io_linux.c index cee5890..0fa5841 100644 --- a/ntp_io_linux.c +++ b/ntp_io_linux.c @@ -512,14 +512,43 @@ extract_udp_data(unsigned char *msg, NTP_Remote_Address *remote_addr, int len) len -= ihl + 8, msg += ihl + 8; #ifdef FEAT_IPV6 } else if (len >= 48 && msg[0] >> 4 == 6) { - /* IPv6 extension headers are not supported */ - if (msg[6] != 17) - return 0; + int eh_len, next_header = msg[6]; memcpy(&addr.in6.sin6_addr.s6_addr, msg + 24, 16); - addr.in6.sin6_port = *(uint16_t *)(msg + 40 + 2); + len -= 40, msg += 40; + + /* Skip IPv6 extension headers if present */ + while (next_header != 17) { + switch (next_header) { + case 44: /* Fragment Header */ + /* Process only the first fragment */ + if (ntohs(*(uint16_t *)(msg + 2)) >> 3 != 0) + return 0; + eh_len = 8; + break; + case 0: /* Hop-by-Hop Options */ + case 43: /* Routing Header */ + case 60: /* Destination Options */ + case 135: /* Mobility Header */ + eh_len = 8 * (msg[1] + 1); + break; + case 51: /* Authentication Header */ + eh_len = 4 * (msg[1] + 2); + break; + default: + return 0; + } + + if (eh_len < 8 || len < eh_len + 8) + return 0; + + next_header = msg[0]; + len -= eh_len, msg += eh_len; + } + + addr.in6.sin6_port = *(uint16_t *)(msg + 2); addr.in6.sin6_family = AF_INET6; - len -= 48, msg += 48; + len -= 8, msg += 8; #endif } else { return 0;