summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Vater2025-07-16 15:51:14 +0200
committerSebastian Vater2025-07-16 15:51:14 +0200
commit0e5a4ee3859f63f1f84479ad19cc5ff7ff2933da (patch)
tree4e601919bcca7142707025032860e37ab21778a6
parentAdded missing remaining login related text keys in iscsi.h. (diff)
downloaddnbd3-0e5a4ee3859f63f1f84479ad19cc5ff7ff2933da.tar.gz
dnbd3-0e5a4ee3859f63f1f84479ad19cc5ff7ff2933da.tar.xz
dnbd3-0e5a4ee3859f63f1f84479ad19cc5ff7ff2933da.zip
Added little endian to big endian conversion macros using optimized assembly code via builtin intrinsics for GCC/CLang/MSVC and slow C implementation for any other compiler and skeleton C file.
-rw-r--r--src/server/CMakeLists.txt2
-rw-r--r--src/server/iscsi.c22
-rw-r--r--src/server/iscsi.h30
3 files changed, 52 insertions, 2 deletions
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index 9a1e1c4..c66ace4 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -49,6 +49,7 @@ set(DNBD3_SERVER_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/altservers.c
${CMAKE_CURRENT_SOURCE_DIR}/image.c
${CMAKE_CURRENT_SOURCE_DIR}/ini.c
${CMAKE_CURRENT_SOURCE_DIR}/integrity.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/iscsi.c
${CMAKE_CURRENT_SOURCE_DIR}/locks.c
${CMAKE_CURRENT_SOURCE_DIR}/net.c
${CMAKE_CURRENT_SOURCE_DIR}/reference.c
@@ -65,6 +66,7 @@ set(DNBD3_SERVER_HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/altservers.h
${CMAKE_CURRENT_SOURCE_DIR}/image.h
${CMAKE_CURRENT_SOURCE_DIR}/ini.h
${CMAKE_CURRENT_SOURCE_DIR}/integrity.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/iscsi.h
${CMAKE_CURRENT_SOURCE_DIR}/locks.h
${CMAKE_CURRENT_SOURCE_DIR}/net.h
${CMAKE_CURRENT_SOURCE_DIR}/reference.h
diff --git a/src/server/iscsi.c b/src/server/iscsi.c
new file mode 100644
index 0000000..c8f866b
--- /dev/null
+++ b/src/server/iscsi.c
@@ -0,0 +1,22 @@
+ /*
+ * This file is part of the Distributed Network Block Device 3
+ *
+ * Copyright(c) 2025 Sebastian Vater <sebastian.vater@rz.uni-freiburg.de>
+ *
+ * This file may be licensed under the terms of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "iscsi.h"
+
diff --git a/src/server/iscsi.h b/src/server/iscsi.h
index 83aa1e4..e5bcf08 100644
--- a/src/server/iscsi.h
+++ b/src/server/iscsi.h
@@ -23,11 +23,37 @@
#include <types.h>
+#if defined(__BIG_ENDIAN__) || (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+#define iscsi_get_be16(x) (x)
+#define iscsi_get_be32(x) (x)
+#define iscsi_get_be64(x) (x)
+#elif defined(__LITTLE_ENDIAN__) || (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || defined(__i386__) || defined(__i386) || defined(__x86_64)
+#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
+// GCC or CLang
+#define iscsi_get_be16(x) (__builtin_bswap16(x))
+#define iscsi_get_be32(x) (__builtin_bswap32(x))
+#define iscsi_get_be64(x) (__builtin_bswap64(x))
+#elif defined(_MSC_VER)
+#include <intrin.h>
+// MVSC
+#define iscsi_get_be16(x) (_byteswap_ushort(x))
+#define iscsi_get_be32(x) (_byteswap_ulong(x))
+#define iscsi_get_be64(x) (_byteswap_uint64(x))
+#else
+// Other compilers (use slow conversion method with bit rotation, bit shift and logcal AND)
+#define iscsi_get_be16(x) ((((uint16_t) (x)) << 8U) | (((uint16_t) (x)) >> 8U))
+#define iscsi_get_be32(x) ((((uint32_t) (x) & 0xFFUL) << 24UL) | (((uint32_t) (x) & 0xFF00UL) << 8UL) | (((uint32_t) (x) & 0xFF0000UL) >> 8UL) | (((uint32_t) (x) >> 24UL)))
+#define iscsi_get_be64(x) ((uint64_t)((((x) & 0xFFULL) << 56ULL) | (((x) & 0xFF00ULL) << 40ULL) | (((x) & 0xFF0000ull) << 24ULL) | (((x) & 0xFF000000ULL) << 8ULL) | (((x) & 0xFF00000000ULL) >> 8ULL) | (((x) & 0xFF0000000000ULL) >> 24ULL) | (((x) & 0xFF000000000000ULL) >> 40ULL) | (((x) & 0xFF00000000000000ULL) >> 56ULL)))
+#endif
+#else
+#error "Unknown CPU endianness"
+#endif
+
/* iSCSI protocol stuff (all WORD/DWORD/QWORD values are big endian by default
unless specified otherwise). */
-#define ISCSI_BHS_SIZE 48 // iSCSI Basic Header Segment size
-#define ISCSI_AHS_SIZE 48 // iSCSI Additional Header Segment size (multiple AHS packets possible)
+#define ISCSI_BHS_SIZE 48 // iSCSI Basic Header Segment size
+#define ISCSI_AHS_SIZE 48 // iSCSI Additional Header Segment size (multiple AHS packets possible)
// iSCSI initiator (client) command opcodes
#define ISCSI_CLIENT_NOP_OUT 0x00 // NOP-Out