diff --git a/libc/include/netinet/udp.h b/libc/include/netinet/udp.h index 25e0dfca9..d4eb36806 100644 --- a/libc/include/netinet/udp.h +++ b/libc/include/netinet/udp.h @@ -25,31 +25,29 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + #ifndef _NETINET_UDP_H #define _NETINET_UDP_H -/* - * We would include linux/udp.h, but it brings in too much other stuff - */ +#include -#ifdef __FAVOR_BSD +#include struct udphdr { - u_int16_t uh_sport; /* source port */ - u_int16_t uh_dport; /* destination port */ - u_int16_t uh_ulen; /* udp length */ - u_int16_t uh_sum; /* udp checksum */ + __extension__ union { + struct /* BSD names */ { + u_int16_t uh_sport; + u_int16_t uh_dport; + u_int16_t uh_ulen; + u_int16_t uh_sum; + }; + struct /* Linux names */ { + u_int16_t source; + u_int16_t dest; + u_int16_t len; + u_int16_t check; + }; + }; }; -#else - -struct udphdr { - __u16 source; - __u16 dest; - __u16 len; - __u16 check; -}; - -#endif /* __FAVOR_BSD */ - #endif /* _NETINET_UDP_H */ diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py index 1b6853e51..773d22f00 100644 --- a/libc/kernel/tools/defaults.py +++ b/libc/kernel/tools/defaults.py @@ -64,6 +64,8 @@ kernel_token_replacements = { # The kernel's SIGRTMIN/SIGRTMAX are absolute limits; userspace steals a few. "SIGRTMIN": "__SIGRTMIN", "SIGRTMAX": "__SIGRTMAX", + # We want to support both BSD and Linux member names in struct udphdr. + "udphdr": "__kernel_udphdr", } # this is the set of known static inline functions that we want to keep diff --git a/libc/kernel/uapi/linux/udp.h b/libc/kernel/uapi/linux/udp.h index e1d546cb7..a3e9e9711 100644 --- a/libc/kernel/uapi/linux/udp.h +++ b/libc/kernel/uapi/linux/udp.h @@ -19,7 +19,7 @@ #ifndef _UAPI_LINUX_UDP_H #define _UAPI_LINUX_UDP_H #include -struct udphdr { +struct __kernel_udphdr { /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ __be16 source; __be16 dest; diff --git a/tests/Android.mk b/tests/Android.mk index 3f2fb9195..68c41499a 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -69,6 +69,7 @@ libBionicStandardTests_src_files := \ math_test.cpp \ mntent_test.cpp \ netdb_test.cpp \ + netinet_udp_test.cpp \ pthread_test.cpp \ pty_test.cpp \ regex_test.cpp \ diff --git a/tests/netinet_udp_test.cpp b/tests/netinet_udp_test.cpp new file mode 100644 index 000000000..661458ed1 --- /dev/null +++ b/tests/netinet_udp_test.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +#if defined(__BIONIC__) + #define UDPHDR_USES_ANON_UNION +#elif defined(__GLIBC_PREREQ) + #if __GLIBC_PREREQ(2, 18) + #define UDPHDR_USES_ANON_UNION + #endif +#endif + +TEST(netinet_udp, compat) { +#if defined(UDPHDR_USES_ANON_UNION) + static_assert(offsetof(udphdr, uh_sport) == offsetof(udphdr, source), "udphdr::source"); + static_assert(offsetof(udphdr, uh_dport) == offsetof(udphdr, dest), "udphdr::dest"); + static_assert(offsetof(udphdr, uh_ulen) == offsetof(udphdr, len), "udphdr::len"); + static_assert(offsetof(udphdr, uh_sum) == offsetof(udphdr, check), "udphdr::check"); + + udphdr u; + u.uh_sport = 0x1111; + u.uh_dport = 0x2222; + u.uh_ulen = 0x3333; + u.uh_sum = 0x4444; + ASSERT_EQ(0x1111, u.source); + ASSERT_EQ(0x2222, u.dest); + ASSERT_EQ(0x3333, u.len); + ASSERT_EQ(0x4444, u.check); +#endif +}