Add a --udp-counters-64bit feature to support very long UDP tests.
UDP tests store a packet sequence number in the packets to detect loss and ordering issues. This sequence number is a 32-bit signed integer, which can wrap during very long-running UDP tests. This change adds an option (defaulting to off) which uses a 64-bit unsigned integer to store this quantity in the packet. The option is specified on the client side; the server must support this feature for proper functioning (older servers will interoperate with newer clients, as long as --udp-counters-64-bit is not used). The default might be changed in a future version of iperf3. As a part of this change, the client sends its version string to the server in the parameter block. Uses a public-domain compatibility shim for 64-bit byte order conversions. There are probably some additional platforms that need to be supported, in particular Solaris. We might add some configure-time checks to only enable this feature on platforms where we can support the byte-order conversions. This change is not well-tested. Towards issue #191.
This commit is contained in:
parent
d30a2c8d04
commit
329523a557
12
LICENSE
12
LICENSE
@ -255,3 +255,15 @@ This software contains source code (src/units.{c.h}) that is:
|
|||||||
* -------------------------------------------------------------------
|
* -------------------------------------------------------------------
|
||||||
* input and output numbers, converting with kilo, mega, giga
|
* input and output numbers, converting with kilo, mega, giga
|
||||||
* ------------------------------------------------------------------- */
|
* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
=====
|
||||||
|
|
||||||
|
This software contains source code (src/portable_endian.h) that is:
|
||||||
|
|
||||||
|
// "License": Public Domain
|
||||||
|
// I, Mathias Panzenböck, place this file hereby into the public domain. Use it at your own risk for whatever you like.
|
||||||
|
|
||||||
|
=====
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ struct iperf_settings
|
|||||||
int tos; /* type of service bit */
|
int tos; /* type of service bit */
|
||||||
int flowlabel; /* IPv6 flow label */
|
int flowlabel; /* IPv6 flow label */
|
||||||
iperf_size_t bytes; /* number of bytes to send */
|
iperf_size_t bytes; /* number of bytes to send */
|
||||||
int blocks; /* number of blocks (packets) to send */
|
iperf_size_t blocks; /* number of blocks (packets) to send */
|
||||||
char unit_format; /* -f */
|
char unit_format; /* -f */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -200,6 +200,7 @@ struct iperf_test
|
|||||||
int zerocopy; /* -Z option - use sendfile */
|
int zerocopy; /* -Z option - use sendfile */
|
||||||
int debug; /* -d option - enable debug */
|
int debug; /* -d option - enable debug */
|
||||||
int get_server_output; /* --get-server-output */
|
int get_server_output; /* --get-server-output */
|
||||||
|
int udp_counters_64bit; /* --use-64-bit-udp-counters */
|
||||||
|
|
||||||
int multisend;
|
int multisend;
|
||||||
|
|
||||||
@ -227,7 +228,7 @@ struct iperf_test
|
|||||||
int num_streams; /* total streams in the test (-P) */
|
int num_streams; /* total streams in the test (-P) */
|
||||||
|
|
||||||
iperf_size_t bytes_sent;
|
iperf_size_t bytes_sent;
|
||||||
int blocks_sent;
|
iperf_size_t blocks_sent;
|
||||||
char cookie[COOKIE_SIZE];
|
char cookie[COOKIE_SIZE];
|
||||||
// struct iperf_stream *streams; /* pointer to list of struct stream */
|
// struct iperf_stream *streams; /* pointer to list of struct stream */
|
||||||
SLIST_HEAD(slisthead, iperf_stream) streams;
|
SLIST_HEAD(slisthead, iperf_stream) streams;
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
#include "tcp_window_size.h"
|
#include "tcp_window_size.h"
|
||||||
#include "iperf_util.h"
|
#include "iperf_util.h"
|
||||||
#include "locale.h"
|
#include "locale.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
/* Forwards. */
|
/* Forwards. */
|
||||||
static int send_parameters(struct iperf_test *test);
|
static int send_parameters(struct iperf_test *test);
|
||||||
@ -235,6 +235,12 @@ iperf_get_test_bind_address(struct iperf_test *ipt)
|
|||||||
return ipt->bind_address;
|
return ipt->bind_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
iperf_get_test_udp_counters_64bit(struct iperf_test *ipt)
|
||||||
|
{
|
||||||
|
return ipt->udp_counters_64bit;
|
||||||
|
}
|
||||||
|
|
||||||
/************** Setter routines for some fields inside iperf_test *************/
|
/************** Setter routines for some fields inside iperf_test *************/
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -388,6 +394,12 @@ iperf_set_test_bind_address(struct iperf_test *ipt, char *bind_address)
|
|||||||
ipt->bind_address = strdup(bind_address);
|
ipt->bind_address = strdup(bind_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
iperf_set_test_udp_counters_64bit(struct iperf_test *ipt, int udp_counters_64bit)
|
||||||
|
{
|
||||||
|
ipt->udp_counters_64bit = udp_counters_64bit;
|
||||||
|
}
|
||||||
|
|
||||||
/********************** Get/set test protocol structure ***********************/
|
/********************** Get/set test protocol structure ***********************/
|
||||||
|
|
||||||
struct protocol *
|
struct protocol *
|
||||||
@ -597,6 +609,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
|||||||
{"pidfile", required_argument, NULL, 'I'},
|
{"pidfile", required_argument, NULL, 'I'},
|
||||||
{"logfile", required_argument, NULL, OPT_LOGFILE},
|
{"logfile", required_argument, NULL, OPT_LOGFILE},
|
||||||
{"get-server-output", no_argument, NULL, OPT_GET_SERVER_OUTPUT},
|
{"get-server-output", no_argument, NULL, OPT_GET_SERVER_OUTPUT},
|
||||||
|
{"udp-counters-64bit", no_argument, NULL, OPT_UDP_COUNTERS_64BIT},
|
||||||
{"debug", no_argument, NULL, 'd'},
|
{"debug", no_argument, NULL, 'd'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
@ -834,6 +847,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
|||||||
test->get_server_output = 1;
|
test->get_server_output = 1;
|
||||||
client_flag = 1;
|
client_flag = 1;
|
||||||
break;
|
break;
|
||||||
|
case OPT_UDP_COUNTERS_64BIT:
|
||||||
|
test->udp_counters_64bit = 1;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
default:
|
default:
|
||||||
usage_long();
|
usage_long();
|
||||||
@ -1197,6 +1213,10 @@ send_parameters(struct iperf_test *test)
|
|||||||
cJSON_AddStringToObject(j, "congestion", test->congestion);
|
cJSON_AddStringToObject(j, "congestion", test->congestion);
|
||||||
if (test->get_server_output)
|
if (test->get_server_output)
|
||||||
cJSON_AddIntToObject(j, "get_server_output", iperf_get_test_get_server_output(test));
|
cJSON_AddIntToObject(j, "get_server_output", iperf_get_test_get_server_output(test));
|
||||||
|
if (test->udp_counters_64bit)
|
||||||
|
cJSON_AddIntToObject(j, "udp_counters_64bit", iperf_get_test_udp_counters_64bit(test));
|
||||||
|
|
||||||
|
cJSON_AddStringToObject(j, "client_version", IPERF_VERSION);
|
||||||
|
|
||||||
if (test->debug) {
|
if (test->debug) {
|
||||||
printf("send_parameters:\n%s\n", cJSON_Print(j));
|
printf("send_parameters:\n%s\n", cJSON_Print(j));
|
||||||
@ -1271,6 +1291,8 @@ get_parameters(struct iperf_test *test)
|
|||||||
test->congestion = strdup(j_p->valuestring);
|
test->congestion = strdup(j_p->valuestring);
|
||||||
if ((j_p = cJSON_GetObjectItem(j, "get_server_output")) != NULL)
|
if ((j_p = cJSON_GetObjectItem(j, "get_server_output")) != NULL)
|
||||||
iperf_set_test_get_server_output(test, 1);
|
iperf_set_test_get_server_output(test, 1);
|
||||||
|
if ((j_p = cJSON_GetObjectItem(j, "udp_counters_64bit")) != NULL)
|
||||||
|
iperf_set_test_udp_counters_64bit(test, 1);
|
||||||
if (test->sender && test->protocol->id == Ptcp && has_tcpinfo_retransmits())
|
if (test->sender && test->protocol->id == Ptcp && has_tcpinfo_retransmits())
|
||||||
test->sender_has_retransmits = 1;
|
test->sender_has_retransmits = 1;
|
||||||
cJSON_Delete(j);
|
cJSON_Delete(j);
|
||||||
@ -1883,6 +1905,7 @@ iperf_reset_test(struct iperf_test *test)
|
|||||||
test->settings->mss = 0;
|
test->settings->mss = 0;
|
||||||
memset(test->cookie, 0, COOKIE_SIZE);
|
memset(test->cookie, 0, COOKIE_SIZE);
|
||||||
test->multisend = 10; /* arbitrary */
|
test->multisend = 10; /* arbitrary */
|
||||||
|
test->udp_counters_64bit = 0;
|
||||||
|
|
||||||
/* Free output line buffers, if any (on the server only) */
|
/* Free output line buffers, if any (on the server only) */
|
||||||
struct iperf_textline *t;
|
struct iperf_textline *t;
|
||||||
|
@ -29,6 +29,7 @@ struct iperf_stream;
|
|||||||
#define OPT_SCTP 1
|
#define OPT_SCTP 1
|
||||||
#define OPT_LOGFILE 2
|
#define OPT_LOGFILE 2
|
||||||
#define OPT_GET_SERVER_OUTPUT 3
|
#define OPT_GET_SERVER_OUTPUT 3
|
||||||
|
#define OPT_UDP_COUNTERS_64BIT 4
|
||||||
|
|
||||||
/* states */
|
/* states */
|
||||||
#define TEST_START 1
|
#define TEST_START 1
|
||||||
@ -73,6 +74,7 @@ char* iperf_get_test_json_output_string ( struct iperf_test* ipt );
|
|||||||
int iperf_get_test_zerocopy( struct iperf_test* ipt );
|
int iperf_get_test_zerocopy( struct iperf_test* ipt );
|
||||||
int iperf_get_test_get_server_output( struct iperf_test* ipt );
|
int iperf_get_test_get_server_output( struct iperf_test* ipt );
|
||||||
char* iperf_get_test_bind_address ( struct iperf_test* ipt );
|
char* iperf_get_test_bind_address ( struct iperf_test* ipt );
|
||||||
|
int iperf_get_test_udp_counters_64bit( struct iperf_test* ipt );
|
||||||
|
|
||||||
/* Setter routines for some fields inside iperf_test. */
|
/* Setter routines for some fields inside iperf_test. */
|
||||||
void iperf_set_verbose( struct iperf_test* ipt, int verbose );
|
void iperf_set_verbose( struct iperf_test* ipt, int verbose );
|
||||||
@ -96,6 +98,7 @@ int iperf_has_zerocopy( void );
|
|||||||
void iperf_set_test_zerocopy( struct iperf_test* ipt, int zerocopy );
|
void iperf_set_test_zerocopy( struct iperf_test* ipt, int zerocopy );
|
||||||
void iperf_set_test_get_server_output( struct iperf_test* ipt, int get_server_output );
|
void iperf_set_test_get_server_output( struct iperf_test* ipt, int get_server_output );
|
||||||
void iperf_set_test_bind_address( struct iperf_test* ipt, char *bind_address );
|
void iperf_set_test_bind_address( struct iperf_test* ipt, char *bind_address );
|
||||||
|
void iperf_set_test_udp_counters_64bit( struct iperf_test* ipt, int udp_counters_64bit );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* exchange_parameters - handles the param_Exchange part for client
|
* exchange_parameters - handles the param_Exchange part for client
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2011, The Regents of the University of California,
|
* Copyright (c) 2009-2011, 2014, The Regents of the University of California,
|
||||||
* through Lawrence Berkeley National Laboratory (subject to receipt of any
|
* through Lawrence Berkeley National Laboratory (subject to receipt of any
|
||||||
* required approvals from the U.S. Dept. of Energy). All rights reserved.
|
* required approvals from the U.S. Dept. of Energy). All rights reserved.
|
||||||
*
|
*
|
||||||
@ -28,7 +28,7 @@
|
|||||||
#include "iperf_udp.h"
|
#include "iperf_udp.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
#include "portable_endian.h"
|
||||||
|
|
||||||
/* iperf_udp_recv
|
/* iperf_udp_recv
|
||||||
*
|
*
|
||||||
@ -37,9 +37,10 @@
|
|||||||
int
|
int
|
||||||
iperf_udp_recv(struct iperf_stream *sp)
|
iperf_udp_recv(struct iperf_stream *sp)
|
||||||
{
|
{
|
||||||
|
uint32_t sec, usec;
|
||||||
|
uint64_t pcount;
|
||||||
int r;
|
int r;
|
||||||
int size = sp->settings->blksize;
|
int size = sp->settings->blksize;
|
||||||
uint32_t sec, usec, pcount;
|
|
||||||
double transit = 0, d = 0;
|
double transit = 0, d = 0;
|
||||||
struct timeval sent_time, arrival_time;
|
struct timeval sent_time, arrival_time;
|
||||||
|
|
||||||
@ -51,14 +52,27 @@ iperf_udp_recv(struct iperf_stream *sp)
|
|||||||
sp->result->bytes_received += r;
|
sp->result->bytes_received += r;
|
||||||
sp->result->bytes_received_this_interval += r;
|
sp->result->bytes_received_this_interval += r;
|
||||||
|
|
||||||
memcpy(&sec, sp->buffer, sizeof(sec));
|
if (sp->test->udp_counters_64bit) {
|
||||||
memcpy(&usec, sp->buffer+4, sizeof(usec));
|
memcpy(&sec, sp->buffer, sizeof(sec));
|
||||||
memcpy(&pcount, sp->buffer+8, sizeof(pcount));
|
memcpy(&usec, sp->buffer+4, sizeof(usec));
|
||||||
sec = ntohl(sec);
|
memcpy(&pcount, sp->buffer+8, sizeof(pcount));
|
||||||
usec = ntohl(usec);
|
sec = ntohl(sec);
|
||||||
pcount = ntohl(pcount);
|
usec = ntohl(usec);
|
||||||
sent_time.tv_sec = sec;
|
pcount = be64toh(pcount);
|
||||||
sent_time.tv_usec = usec;
|
sent_time.tv_sec = sec;
|
||||||
|
sent_time.tv_usec = usec;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint32_t pc;
|
||||||
|
memcpy(&sec, sp->buffer, sizeof(sec));
|
||||||
|
memcpy(&usec, sp->buffer+4, sizeof(usec));
|
||||||
|
memcpy(&pc, sp->buffer+8, sizeof(pc));
|
||||||
|
sec = ntohl(sec);
|
||||||
|
usec = ntohl(usec);
|
||||||
|
pcount = ntohl(pc);
|
||||||
|
sent_time.tv_sec = sec;
|
||||||
|
sent_time.tv_usec = usec;
|
||||||
|
}
|
||||||
|
|
||||||
/* Out of order packets */
|
/* Out of order packets */
|
||||||
if (pcount >= sp->packet_count + 1) {
|
if (pcount >= sp->packet_count + 1) {
|
||||||
@ -68,7 +82,7 @@ iperf_udp_recv(struct iperf_stream *sp)
|
|||||||
sp->packet_count = pcount;
|
sp->packet_count = pcount;
|
||||||
} else {
|
} else {
|
||||||
sp->outoforder_packets++;
|
sp->outoforder_packets++;
|
||||||
iperf_err(sp->test, "OUT OF ORDER - incoming packet = %d and received packet = %d AND SP = %d", pcount, sp->packet_count, sp->socket);
|
iperf_err(sp->test, "OUT OF ORDER - incoming packet = %llu and received packet = %d AND SP = %d", pcount, sp->packet_count, sp->socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* jitter measurement */
|
/* jitter measurement */
|
||||||
@ -83,6 +97,10 @@ iperf_udp_recv(struct iperf_stream *sp)
|
|||||||
// J = |(R1 - S1) - (R0 - S0)| [/ number of packets, for average]
|
// J = |(R1 - S1) - (R0 - S0)| [/ number of packets, for average]
|
||||||
sp->jitter += (d - sp->jitter) / 16.0;
|
sp->jitter += (d - sp->jitter) / 16.0;
|
||||||
|
|
||||||
|
if (sp->test->debug) {
|
||||||
|
fprintf(stderr, "packet_count %llu\n", sp->packet_count);
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,20 +113,40 @@ int
|
|||||||
iperf_udp_send(struct iperf_stream *sp)
|
iperf_udp_send(struct iperf_stream *sp)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
uint32_t sec, usec, pcount;
|
|
||||||
int size = sp->settings->blksize;
|
int size = sp->settings->blksize;
|
||||||
struct timeval before;
|
struct timeval before;
|
||||||
|
|
||||||
gettimeofday(&before, 0);
|
gettimeofday(&before, 0);
|
||||||
|
|
||||||
++sp->packet_count;
|
++sp->packet_count;
|
||||||
sec = htonl(before.tv_sec);
|
|
||||||
usec = htonl(before.tv_usec);
|
|
||||||
pcount = htonl(sp->packet_count);
|
|
||||||
|
|
||||||
memcpy(sp->buffer, &sec, sizeof(sec));
|
if (sp->test->udp_counters_64bit) {
|
||||||
memcpy(sp->buffer+4, &usec, sizeof(usec));
|
|
||||||
memcpy(sp->buffer+8, &pcount, sizeof(pcount));
|
uint32_t sec, usec;
|
||||||
|
uint64_t pcount;
|
||||||
|
|
||||||
|
sec = htonl(before.tv_sec);
|
||||||
|
usec = htonl(before.tv_usec);
|
||||||
|
pcount = htobe64(sp->packet_count);
|
||||||
|
|
||||||
|
memcpy(sp->buffer, &sec, sizeof(sec));
|
||||||
|
memcpy(sp->buffer+4, &usec, sizeof(usec));
|
||||||
|
memcpy(sp->buffer+8, &pcount, sizeof(pcount));
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
uint32_t sec, usec, pcount;
|
||||||
|
|
||||||
|
sec = htonl(before.tv_sec);
|
||||||
|
usec = htonl(before.tv_usec);
|
||||||
|
pcount = htonl(sp->packet_count);
|
||||||
|
|
||||||
|
memcpy(sp->buffer, &sec, sizeof(sec));
|
||||||
|
memcpy(sp->buffer+4, &usec, sizeof(usec));
|
||||||
|
memcpy(sp->buffer+8, &pcount, sizeof(pcount));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
r = Nwrite(sp->socket, sp->buffer, size, Pudp);
|
r = Nwrite(sp->socket, sp->buffer, size, Pudp);
|
||||||
|
|
||||||
|
@ -126,6 +126,7 @@ const char usage_longstr[] = "Usage: iperf [-s|-c host] [options]\n"
|
|||||||
" -O, --omit N omit the first n seconds\n"
|
" -O, --omit N omit the first n seconds\n"
|
||||||
" -T, --title str prefix every output line with this string\n"
|
" -T, --title str prefix every output line with this string\n"
|
||||||
" --get-server-output get results from server\n"
|
" --get-server-output get results from server\n"
|
||||||
|
" --udp-counters-64bit use 64-bit counters in UDP test packets\n"
|
||||||
|
|
||||||
#ifdef NOT_YET_SUPPORTED /* still working on these */
|
#ifdef NOT_YET_SUPPORTED /* still working on these */
|
||||||
#endif
|
#endif
|
||||||
|
115
src/portable_endian.h
Normal file
115
src/portable_endian.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// "License": Public Domain
|
||||||
|
// I, Mathias Panzenböck, place this file hereby into the public domain. Use it at your own risk for whatever you like.
|
||||||
|
|
||||||
|
#ifndef PORTABLE_ENDIAN_H__
|
||||||
|
#define PORTABLE_ENDIAN_H__
|
||||||
|
|
||||||
|
#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__)
|
||||||
|
|
||||||
|
# define __WINDOWS__
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__CYGWIN__)
|
||||||
|
|
||||||
|
# include <endian.h>
|
||||||
|
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
|
||||||
|
# include <libkern/OSByteOrder.h>
|
||||||
|
|
||||||
|
# define htobe16(x) OSSwapHostToBigInt16(x)
|
||||||
|
# define htole16(x) OSSwapHostToLittleInt16(x)
|
||||||
|
# define be16toh(x) OSSwapBigToHostInt16(x)
|
||||||
|
# define le16toh(x) OSSwapLittleToHostInt16(x)
|
||||||
|
|
||||||
|
# define htobe32(x) OSSwapHostToBigInt32(x)
|
||||||
|
# define htole32(x) OSSwapHostToLittleInt32(x)
|
||||||
|
# define be32toh(x) OSSwapBigToHostInt32(x)
|
||||||
|
# define le32toh(x) OSSwapLittleToHostInt32(x)
|
||||||
|
|
||||||
|
# define htobe64(x) OSSwapHostToBigInt64(x)
|
||||||
|
# define htole64(x) OSSwapHostToLittleInt64(x)
|
||||||
|
# define be64toh(x) OSSwapBigToHostInt64(x)
|
||||||
|
# define le64toh(x) OSSwapLittleToHostInt64(x)
|
||||||
|
|
||||||
|
# define __BYTE_ORDER BYTE_ORDER
|
||||||
|
# define __BIG_ENDIAN BIG_ENDIAN
|
||||||
|
# define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||||
|
# define __PDP_ENDIAN PDP_ENDIAN
|
||||||
|
|
||||||
|
#elif defined(__OpenBSD__)
|
||||||
|
|
||||||
|
# include <sys/endian.h>
|
||||||
|
|
||||||
|
#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
|
||||||
|
|
||||||
|
# include <sys/endian.h>
|
||||||
|
|
||||||
|
# define be16toh(x) betoh16(x)
|
||||||
|
# define le16toh(x) letoh16(x)
|
||||||
|
|
||||||
|
# define be32toh(x) betoh32(x)
|
||||||
|
# define le32toh(x) letoh32(x)
|
||||||
|
|
||||||
|
# define be64toh(x) betoh64(x)
|
||||||
|
# define le64toh(x) letoh64(x)
|
||||||
|
|
||||||
|
#elif defined(__WINDOWS__)
|
||||||
|
|
||||||
|
# include <winsock2.h>
|
||||||
|
# include <sys/param.h>
|
||||||
|
|
||||||
|
# if BYTE_ORDER == LITTLE_ENDIAN
|
||||||
|
|
||||||
|
# define htobe16(x) htons(x)
|
||||||
|
# define htole16(x) (x)
|
||||||
|
# define be16toh(x) ntohs(x)
|
||||||
|
# define le16toh(x) (x)
|
||||||
|
|
||||||
|
# define htobe32(x) htonl(x)
|
||||||
|
# define htole32(x) (x)
|
||||||
|
# define be32toh(x) ntohl(x)
|
||||||
|
# define le32toh(x) (x)
|
||||||
|
|
||||||
|
# define htobe64(x) htonll(x)
|
||||||
|
# define htole64(x) (x)
|
||||||
|
# define be64toh(x) ntohll(x)
|
||||||
|
# define le64toh(x) (x)
|
||||||
|
|
||||||
|
# elif BYTE_ORDER == BIG_ENDIAN
|
||||||
|
|
||||||
|
/* that would be xbox 360 */
|
||||||
|
# define htobe16(x) (x)
|
||||||
|
# define htole16(x) __builtin_bswap16(x)
|
||||||
|
# define be16toh(x) (x)
|
||||||
|
# define le16toh(x) __builtin_bswap16(x)
|
||||||
|
|
||||||
|
# define htobe32(x) (x)
|
||||||
|
# define htole32(x) __builtin_bswap32(x)
|
||||||
|
# define be32toh(x) (x)
|
||||||
|
# define le32toh(x) __builtin_bswap32(x)
|
||||||
|
|
||||||
|
# define htobe64(x) (x)
|
||||||
|
# define htole64(x) __builtin_bswap64(x)
|
||||||
|
# define be64toh(x) (x)
|
||||||
|
# define le64toh(x) __builtin_bswap64(x)
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
# error byte order not supported
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define __BYTE_ORDER BYTE_ORDER
|
||||||
|
# define __BIG_ENDIAN BIG_ENDIAN
|
||||||
|
# define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||||
|
# define __PDP_ENDIAN PDP_ENDIAN
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
# error platform not supported
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user