From: Simon Wright <simon@pushface.org>
Subject: Re: AI12-0218: What is the portable representation clause for processing IETF packets on little-endian machines?
Date: Fri, 11 May 2018 08:55:25 +0100
Date: 2018-05-11T08:55:25+01:00 [thread overview]
Message-ID: <lypo22fwya.fsf@pushface.org> (raw)
In-Reply-To: 5c9b9f90-884f-4de7-8663-d39a67949f4f@googlegroups.com
"Dan'l Miller" <optikos@verizon.net> writes:
> Still, standard Ada has no good Ada-esque solution to heterogenous
> endianness at the perimeter of a system, other than writing C-esque
> pointer-arithmetic code with the various unchecked_ constructs (which
> even C programmers don't generally do; they utilize
> conditionally-compiled macros that correctly type-cast
> meticulously*-laid-out structs-of-bitfields onto that packet's header
> or IC register's word.
I've used (effectively) conditionally-compiled sections of code for
this.
From an SNTP implementation: in BE, the first 32 bits of a packet are
-- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-- |LI | VN |Mode | Stratum | Poll | Precision |
-- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
and looking just at the top (first) byte, the package spec contains
type Leap_Indicator is (No_Warning,
Last_Minute_Has_61_Seconds,
Last_Minute_Has_59_Seconds,
Alarm_Condition);
type Version is range 3 .. 4;
type Mode is (Reserved,
Symmetric_Active,
Symmetric_Passive,
Client,
Server,
Broadcast,
Reserved_For_NTP_Control_Message,
Reserved_For_Private_Use);
type Status is record
LI : Leap_Indicator;
VN : Version;
M : Mode;
end record;
in native layout (nowadays I'd be a lot more specific about
sizes). Conversions:
function To_Stream_Element (S : Status) return Ada.Streams.Stream_Element;
function To_Status (S : Ada.Streams.Stream_Element) return Status;
In the body,
Big_Endian : constant Boolean
:= System."=" (System.Default_Bit_Order, System.High_Order_First);
and
function To_Status (S : Ada.Streams.Stream_Element) return Status is
begin
-- these two sections are conditionally compiled (by GNAT,
-- anyway) because Big_Endian is constant.
if Big_Endian then
declare
-- create a BE type with BE representation
type Host_Status is record
LI : Leap_Indicator;
VN : Version;
M : Mode;
end record;
for Host_Status use record
LI at 0 range 0 .. 1;
VN at 0 range 2 .. 4;
M at 0 range 5 .. 7;
end record;
for Host_Status'Size use 8;
function Convert
is new Ada.Unchecked_Conversion (Ada.Streams.Stream_Element,
Host_Status);
V : constant Host_Status := Convert (S);
begin
-- let the compiler convert from BE representation to host
return (LI => V.LI, VN => V.VN, M => V.M);
end;
else
declare
-- create an LE type with LE representation
type Host_Status is record
LI : Leap_Indicator;
VN : Version;
M : Mode;
end record;
for Host_Status use record
LI at 0 range 6 .. 7;
VN at 0 range 3 .. 5;
M at 0 range 0 .. 2;
end record;
for Host_Status'Size use 8;
function Convert
is new Ada.Unchecked_Conversion (Ada.Streams.Stream_Element,
Host_Status);
V : constant Host_Status := Convert (S);
begin
-- let the compiler convert from LE representation to host
return (LI => V.LI, VN => V.VN, M => V.M);
end;
end if;
end To_Status;
No denying it's a lot of work. Much easier for 2-, 4-, 8-byte objects:
type SNTP_Timestamp is delta 2.0 ** (-32) range -2.0 ** 31 .. 2.0 ** 31;
for SNTP_Timestamp'Size use 64;
subtype Timestamp_Slice is Ada.Streams.Stream_Element_Array (1 .. 8);
function To_SNTP_Timestamp (T : Timestamp_Slice) return SNTP_Timestamp is
function Convert is new Ada.Unchecked_Conversion (Timestamp_Slice,
SNTP_Timestamp);
begin
if Big_Endian then
return Convert (T);
else
return Convert ((1 => T (8),
2 => T (7),
3 => T (6),
4 => T (5),
5 => T (4),
6 => T (3),
7 => T (2),
8 => T (1)));
end if;
end To_SNTP_Timestamp;
next prev parent reply other threads:[~2018-05-11 7:55 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-10 17:45 AI12-0218: What is the portable representation clause for processing IETF packets on little-endian machines? Dan'l Miller
2018-05-10 19:24 ` Dan'l Miller
2018-05-10 20:32 ` Paul Rubin
2018-05-10 22:24 ` Dan'l Miller
2018-05-10 22:44 ` Niklas Holsti
2018-05-10 23:14 ` Paul Rubin
2018-05-11 2:38 ` Dan'l Miller
2018-05-11 7:55 ` Simon Wright [this message]
2018-05-11 12:11 ` Lucretia
2018-05-11 13:49 ` Simon Wright
2018-05-11 16:11 ` Jeffrey R. Carter
2018-05-11 16:48 ` Simon Wright
2018-05-11 19:08 ` Jeffrey R. Carter
2018-05-11 21:39 ` Simon Wright
2018-05-11 21:56 ` Jeffrey R. Carter
2018-05-12 7:08 ` Simon Wright
2018-05-12 7:53 ` Jeffrey R. Carter
2018-05-14 22:43 ` Randy Brukardt
2018-05-11 13:46 ` Simon Wright
2018-05-11 22:12 ` Randy Brukardt
2018-05-12 10:33 ` Björn Lundin
2018-05-12 13:08 ` Simon Wright
2018-05-12 14:21 ` Björn Lundin
2018-05-10 23:07 ` Paul Rubin
2018-05-11 0:14 ` Dan'l Miller
2018-05-11 0:30 ` Paul Rubin
2018-05-11 0:50 ` Dan'l Miller
2018-05-11 1:34 ` Paul Rubin
2018-05-11 2:11 ` Dan'l Miller
2018-05-11 22:32 ` Randy Brukardt
2018-05-11 8:02 ` Simon Wright
2018-05-11 22:14 ` Randy Brukardt
2018-05-10 19:28 ` Simon Wright
2018-05-10 22:40 ` Randy Brukardt
2018-05-10 22:50 ` Dan'l Miller
2018-05-11 22:00 ` Randy Brukardt
2018-05-12 1:15 ` Paul Rubin
2018-05-14 22:54 ` Randy Brukardt
2018-05-15 0:43 ` Paul Rubin
2018-05-15 21:39 ` Randy Brukardt
2018-05-15 0:44 ` Dennis Lee Bieber
2018-05-11 8:09 ` Simon Wright
2018-05-10 19:34 ` Dmitry A. Kazakov
2018-05-10 20:06 ` Dan'l Miller
2018-05-10 22:44 ` Paul Rubin
2018-05-10 22:50 ` Randy Brukardt
2018-05-11 9:40 ` Niklas Holsti
2018-05-11 11:40 ` Dan'l Miller
2018-05-11 20:16 ` Niklas Holsti
2018-05-11 9:40 ` Dmitry A. Kazakov
2018-05-11 14:21 ` AdaMagica
2018-05-26 16:15 ` Dan'l Miller
2018-05-26 19:02 ` AdaMagica
2018-05-26 21:01 ` Dan'l Miller
2018-05-27 14:58 ` AdaMagica
2018-05-27 18:03 ` Simon Wright
2018-05-29 22:17 ` Randy Brukardt
2018-05-30 6:39 ` Simon Wright
2018-05-30 7:25 ` Dmitry A. Kazakov
2018-05-30 15:01 ` Simon Wright
2018-05-30 15:59 ` Dan'l Miller
2018-05-30 19:38 ` Randy Brukardt
2018-05-27 18:04 ` Dan'l Miller
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox