comp.lang.ada
 help / color / mirror / Atom feed
From: lutz@iks-jena.de (Lutz Donnerhacke)
Subject: Memory representation of variable length record components
Date: 17 Jan 2001 11:38:54 GMT
Date: 2001-01-17T11:38:54+00:00	[thread overview]
Message-ID: <slrn96b0tc.18v.lutz@taranis.iks-jena.de> (raw)

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?
 
     



             reply	other threads:[~2001-01-17 11:38 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-01-17 11:38 Lutz Donnerhacke [this message]
2001-01-17 14:40 ` Memory representation of variable length record components Lutz Donnerhacke
2001-01-17 22:58 ` Nick Roberts
2001-01-18  8:45   ` Lutz Donnerhacke
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox