From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,953a175e642a4006,start X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-01-17 03:58:06 PST From: lutz@iks-jena.de (Lutz Donnerhacke) Newsgroups: comp.lang.ada Subject: Memory representation of variable length record components Date: 17 Jan 2001 11:38:54 GMT Organization: IKS GmbH Jena Distribution: world Message-ID: NNTP-Posting-Host: taranis.iks-jena.de Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit User-Agent: slrn/0.9.5.7 (UNIX) Path: supernews.google.com!sn-xit-03!supernews.com!freenix!isdnet!newscore.gigabell.net!newsfeed00.sul.t-online.de!t-online.de!stueberl.r-kom.de!news-ffm.transmedia.de!news1.transmedia.de!news-FFM2.ecrc.net!news.iks-jena.de!lutz Xref: supernews.google.com comp.lang.ada:4088 Date: 2001-01-17T11:38:54+00:00 List-Id: Easy question: How to map a IP structure to a given memory location? *grin* Easier question: How to map a Pascal string ... with Ada.Text_IO; use Ada.Text_IO; procedure t is subtype Length is Natural range 0 .. 255; type pstring (len : Length) is record s : String (1 .. len); end record; pragma Pack (pstring); ps1 : pstring (1); ps100 : pstring (100); begin Put_Line ("ps1" & Natural'Image (ps1'Size)); Put_Line ("ps100" & Natural'Image (ps100'Size)); end t; Fine. Setting the 'Address seems to work for a variable: ps : pstring(0); for ps'Address use ps100'Address; but does not set the discriminant. An other idea: type pstring (len : Length) is record case len is when 0 => null; when 1 => s1 : String (1..1); when 2 => s2 : String (1..2); ... end case; end record; allows a representation clause: for pstring use record len at 0 range 0 .. 7; s1 at 1 range 0 .. 7; s2 at 1 range 0 .. 15; ... end record; which is not allowed for the variable length component s of the first example. But this approach is unusable :-( I'm looking for something like: type ipv4_addr is array (1 .. 4) of Interfaces.Unsigned_8; pragma Pack (ipv4_addr); -- is already network byte order type Version_Type is (v4); for Version_Type use (v4 => 4); type header_length is range 5 .. 15; type fragment_offset is range 0 .. 2**12-1; subtype optblob is Payload_Type; type precedence_type is (Routine, Priority, Immediate, Flash, Flash_Override, CRITIC_ECP, Internetwork_Control, Network_Control); for precedence_type use (Routine => 0, Priority => 1, Immediate => 2, Flash => 3, Flash_Override => 4, CRITIC_ECP => 5, Internetwork_Control => 6, Network_Control => 7); type protocol_type is (HOPOPT, ICMP, IGMP, ... ); for protocol_type use ( HOPOPT => 0, -- IPv6 Hop-by-Hop Option [RFC1883] ICMP => 1, -- Internet Control Message [RFC792] IGMP => 2, -- Internet Group Management [RFC1112] ... ); type Packet (headlen : header_length := 5; totallen : Interfaces.Unsigned_16) is record version : Version_Type := v4; src, dst : ipv4_addr; tos_pred : precedence_type := Routine; tos_delay, tos_thoughput, tos_reliability, dont_fragment, more_fragments : Boolean := False; ttl : Interfaces.Unsigned_8 := 255; identification : Interfaces.Unsigned_16; checksum : Interfaces.Unsigned_16 := 0; offset : fragment_offset := 0; protocol : protocol_type; options : optblob (1 .. 4*headlen - 20); payload : Payload_Type (1 .. totallen - 4*headlen); end record; -- 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 -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- |Version| IHL |Type of Service| Total Length | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- | Identification |Flags| Fragment Offset | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- | Time to Live | Protocol | Header Checksum | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- | Source Address | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- | Destination Address | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -- | Options | Padding | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ for IPv4 use record version at 0 range 0 .. 3; headlen at 0 range 4 .. 7; tos_pred at 1 range 0 .. 2; tos_delay at 1 range 3 .. 3; tos_thoughput at 1 range 4 .. 4; tos_reliability at 1 range 5 .. 5; length at 2 range 0 .. 15; identification at 4 range 0 .. 15; dont_fragment at 6 range 1 .. 1; more_fragments at 6 range 2 .. 2; offset at 6 range 4 .. 15; ttl at 8 range 0 .. 7; protocol at 9 range 0 .. 7; checksum at 10 range 0 .. 15; src at 12 range 0 .. 31; dst at 16 range 0 .. 31; options at 20 range 0 .. 8*options'Last - 1; payload at 4*headlen range 0 .. 8*payload'Last - 1; end record; Unfortunly it does not work. I already searched the public available TCP/IP Stacks in Ada and various mailinglist archives and usenet discussions. I didn't found a solution. Any idea?