/* * Copyright 2024 Google LLC * * 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. */ #pragma once #include // When compiling test, the host OS might have conflicting defines for this: #undef ntohs #undef htons #undef ntohl #undef htonl #undef ltohs #undef ltohl static inline uint16_t ntohs(uint16_t v) { // return ((v & 0x00ff) << 8) | ((v & 0xff00) >> 8); return __builtin_bswap16(v); } static inline uint16_t htons(uint16_t v) { return ntohs(v); } static inline uint32_t ntohl(uint32_t v) { // return ((v & 0x000000ff) << 24) | // ((v & 0x0000ff00) << 8) | // ((v & 0x00ff0000) >> 8) | // ((v & 0xff000000) >> 24); return __builtin_bswap32(v); } static inline uint32_t htonl(uint32_t v) { return ntohl(v); } #define ltohs(v) (v) #define ltohl(v) (v) // Types for values in network byte-order. They are wrapped in structs so that // the compiler will disallow implicit casting of these types to or from // integral types. This way it is a compile error to try using variables of // these types without first performing a byte-order conversion. // There is no overhead for wrapping the values in structs. typedef struct net16 { uint16_t v; } net16; typedef struct net32 { uint32_t v; } net32; static inline uint16_t ntoh16(net16 net) { return ntohs(net.v); } static inline net16 hton16(uint16_t v) { return (net16){ htons(v) }; } static inline uint32_t ntoh32(net32 net) { return ntohl(net.v); } static inline net32 hton32(uint32_t v) { return (net32){ htonl(v) }; }