comp.lang.ada
 help / color / mirror / Atom feed
* Memory representation of variable length record components
@ 2001-01-17 11:38 Lutz Donnerhacke
  2001-01-17 14:40 ` Lutz Donnerhacke
  2001-01-17 22:58 ` Nick Roberts
  0 siblings, 2 replies; 4+ messages in thread
From: Lutz Donnerhacke @ 2001-01-17 11:38 UTC (permalink / 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?
 
     



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2001-01-18  8:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-01-17 11:38 Memory representation of variable length record components Lutz Donnerhacke
2001-01-17 14:40 ` Lutz Donnerhacke
2001-01-17 22:58 ` Nick Roberts
2001-01-18  8:45   ` Lutz Donnerhacke

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