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

* Re: Memory representation of variable length record components
  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
  1 sibling, 0 replies; 4+ messages in thread
From: Lutz Donnerhacke @ 2001-01-17 14:40 UTC (permalink / raw)


* Lutz Donnerhacke wrote:
>Easy question: How to map a IP structure to a given memory location?
>*grin*
>Easier question: How to map a Pascal string ...

Really easy:
with Ada.Text_IO, System.Address_To_Access_Conversions;
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 : aliased pstring (100);
   
   type pstring_ptr is access all pstring;
   pa100 : pstring_ptr := ps100'Access;
   
   package C is new System.Address_To_Access_Conversions (pstring);
   pa1   : C.Object_Pointer := C.To_Pointer (ps1'Address);
   
   raw : String (1 .. 6) := Character'Val (5) & "Hello";
   praw : C.Object_Pointer := C.To_Pointer (raw'Address);
begin
   Put_Line ("ps1"   & Natural'Image (ps1'Size));
   Put_Line ("ps100" & Natural'Image (ps100'Size));
   Put_Line ("pa100" & Natural'Image (pa100.all'Size));
   Put_Line ("pa1"   & Natural'Image (pa1.all'Size));
   Put_Line ("praw" & Natural'Image (praw.all'Size) & praw.s);
   for i in Character'Val (0) .. Character'Val (10) loop
      raw (raw'First) := i;
      Put_Line ("praw" & Natural'Image (praw.all'Size) &
                         Natural'Image (praw.len) &
                         Natural'Image (praw.s'Length));
   end loop;
end t;

Now I only need to know how to use representation clauses with an unusual
discriminat depended memory layout.



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

* Re: Memory representation of variable length record components
  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
  1 sibling, 1 reply; 4+ messages in thread
From: Nick Roberts @ 2001-01-17 22:58 UTC (permalink / raw)


Lutz, it seems to me that you can define a record type for the IP header
(the first 5 32-bit words) in the way you showed. That would then leave you
using something slightly less easy (e.g. streams) to deal with the options
and payload. Not perfect, but not too hard! Am I missing the point?

--
Nick Roberts
http://www.AdaOS.org






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

* Re: Memory representation of variable length record components
  2001-01-17 22:58 ` Nick Roberts
@ 2001-01-18  8:45   ` Lutz Donnerhacke
  0 siblings, 0 replies; 4+ messages in thread
From: Lutz Donnerhacke @ 2001-01-18  8:45 UTC (permalink / raw)


* Nick Roberts wrote:
>Lutz, it seems to me that you can define a record type for the IP header
>(the first 5 32-bit words) in the way you showed.

I currently do this. (http://www.iks-jena.de/mitarb/lutz/ada/net/)

>That would then leave you using something slightly less easy (e.g.
>streams) to deal with the options and payload. Not perfect, but not too
>hard! Am I missing the point?

A little bit, yes. I get a memory image of a frame by the network interface
card. In order to avoid to much copying I'd like to map the data structures
similar to the C code used in actual OSs. But I'd like to have the
advantages of Ada95 typing. That's all ;-)



^ 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