comp.lang.ada
 help / color / mirror / Atom feed
* Adding offset to 'Address
@ 2008-09-12  8:35 Kim Rostgaard Christensen
  2008-09-12  9:47 ` Georg Bauhaus
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Kim Rostgaard Christensen @ 2008-09-12  8:35 UTC (permalink / raw)


Hi

How does one go about setting a 'Address + (size of other record) to a 
record at runtime ?

In brief, I am switching over "Frametype" in a Ethernet frame record, to 
dynamically assign the next record by type (IPv4,IPv6,ARP, etc.)
My "datablob" is a *u_char from a imported C function.

So I have:

  Raw_Bytes : access Unsigned_Char
  for Ethernet_Header'Address use Raw_Bytes.all'Address;

and additionally need something like:
  for IP_Packet'Address use Raw_Bytes.all'Address + Ethernet_Header'Size;

Also, I am not confident that this _the_ solution, so other approaches 
are very welcome. For those curious about what it is all about, I ran a 
gnathtml on the source and made it available at 
http://krc.greenpc.dk/hovedopgave/html/index.htm

Regards
Kim Rostgaard Christensen



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

* Re: Adding offset to 'Address
  2008-09-12  8:35 Adding offset to 'Address Kim Rostgaard Christensen
@ 2008-09-12  9:47 ` Georg Bauhaus
  2008-09-12 10:17   ` Kim Rostgaard Christensen
  2008-09-12 15:23 ` Adam Beneschan
  2008-09-13 10:18 ` Björn
  2 siblings, 1 reply; 13+ messages in thread
From: Georg Bauhaus @ 2008-09-12  9:47 UTC (permalink / raw)


Kim Rostgaard Christensen wrote:
> Hi
> 
> How does one go about setting a 'Address + (size of other record) to a
> record at runtime ?

Have you had a chance to look at Interfaces.C.Pointers?


-- Georg Bauhaus




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

* Re: Adding offset to 'Address
  2008-09-12  9:47 ` Georg Bauhaus
@ 2008-09-12 10:17   ` Kim Rostgaard Christensen
  2008-09-12 11:18     ` petter_fryklund
  0 siblings, 1 reply; 13+ messages in thread
From: Kim Rostgaard Christensen @ 2008-09-12 10:17 UTC (permalink / raw)


Georg Bauhaus wrote:
> Kim Rostgaard Christensen wrote:
>> Hi
>>
>> How does one go about setting a 'Address + (size of other record) to a
>> record at runtime ?
> 
> Have you had a chance to look at Interfaces.C.Pointers?
> 
> 
> -- Georg Bauhaus
> 
I have thought about it, yes - but I cannot figure out witch datatype I 
should instantiate my pointer with (other than Byte & Byte_Array).

Can you give an example ?

regards
Kim Rostgaard Christensen



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

* Re: Adding offset to 'Address
  2008-09-12 10:17   ` Kim Rostgaard Christensen
@ 2008-09-12 11:18     ` petter_fryklund
  0 siblings, 0 replies; 13+ messages in thread
From: petter_fryklund @ 2008-09-12 11:18 UTC (permalink / raw)


On 12 Sep, 12:17, Kim Rostgaard Christensen <k...@greenpc.dk> wrote:
> Georg Bauhaus wrote:
> > Kim Rostgaard Christensen wrote:
> >> Hi
>
> >> How does one go about setting a 'Address + (size of other record) to a
> >> record at runtime ?
>
> > Have you had a chance to look at Interfaces.C.Pointers?
>
> > -- Georg Bauhaus
>
> I have thought about it, yes - but I cannot figure out witch datatype I
> should instantiate my pointer with (other than Byte & Byte_Array).
>
> Can you give an example ?
>
> regards
> Kim Rostgaard Christensen

System.Storage_Elements can be useful for arithmetic on 'Address.



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

* Re: Adding offset to 'Address
  2008-09-12  8:35 Adding offset to 'Address Kim Rostgaard Christensen
  2008-09-12  9:47 ` Georg Bauhaus
@ 2008-09-12 15:23 ` Adam Beneschan
  2008-09-12 21:40   ` Robert A Duff
  2008-09-13  6:21   ` tmoran
  2008-09-13 10:18 ` Björn
  2 siblings, 2 replies; 13+ messages in thread
From: Adam Beneschan @ 2008-09-12 15:23 UTC (permalink / raw)


On Sep 12, 1:35 am, Kim Rostgaard Christensen <k...@greenpc.dk> wrote:
> Hi
>
> How does one go about setting a 'Address + (size of other record) to a
> record at runtime ?
>
> In brief, I am switching over "Frametype" in a Ethernet frame record, to
> dynamically assign the next record by type (IPv4,IPv6,ARP, etc.)
> My "datablob" is a *u_char from a imported C function.
>
> So I have:
>
>   Raw_Bytes : access Unsigned_Char
>   for Ethernet_Header'Address use Raw_Bytes.all'Address;
>
> and additionally need something like:
>   for IP_Packet'Address use Raw_Bytes.all'Address + Ethernet_Header'Size;

Well, 'Size gives you a value in bits, not bytes, so this needs to be
changed.  The value in "storage units" (which is 8-bit bytes on most
machines but is occasionally something different) would be given by

  (Ethernet_Header'Size + System.Storage_Unit - 1) /
System.Storage_Unit

which rounds the size in bits up to the next multiple of
System.Storage_Unit.  [System.Storage_Unit will equal 8 on most
systems.]

Then, there's a "+" function in System.Storage_Elements that adds an
Address to a Storage_Offset and yields an Address (and another "+"
function that takes the arguments in the other order).  If you say
"use System.Storage_Elements" or "use type
System.Storage_Elements.Storage_Offset", then you can say

for IP_Packet'Address use Raw_Bytes.all'Address +
  ((Ethernet_Header'Size + System.Storage_Unit - 1) /
System.Storage_Unit);

assuming that the IP packet always starts at the next memory location
after the Ethernet_Header.

                                  -- Adam





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

* Re: Adding offset to 'Address
  2008-09-12 15:23 ` Adam Beneschan
@ 2008-09-12 21:40   ` Robert A Duff
  2008-09-13  0:37     ` Adam Beneschan
  2008-09-13  6:21   ` tmoran
  1 sibling, 1 reply; 13+ messages in thread
From: Robert A Duff @ 2008-09-12 21:40 UTC (permalink / raw)


Adam Beneschan <adam@irvine.com> writes:

>   (Ethernet_Header'Size + System.Storage_Unit - 1) /
> System.Storage_Unit
>
> which rounds the size in bits up to the next multiple of
> System.Storage_Unit.  [System.Storage_Unit will equal 8 on most
> systems.]

It seems to me that this sort of thing won't work unless
System.Storage_Unit is 8 bits.  So you don't want rounding up.
It seems better to say:

    pragma Assert (System.Storage_Unit = 8);
    ... Raw_Bytes.all'Address + Ethernet_Header'Size/8 ...

If you really need to do this sort of thing, that is.

- Bob



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

* Re: Adding offset to 'Address
  2008-09-12 21:40   ` Robert A Duff
@ 2008-09-13  0:37     ` Adam Beneschan
  0 siblings, 0 replies; 13+ messages in thread
From: Adam Beneschan @ 2008-09-13  0:37 UTC (permalink / raw)


On Sep 12, 2:40 pm, Robert A Duff <bobd...@shell01.TheWorld.com>
wrote:
> Adam Beneschan <a...@irvine.com> writes:
> >   (Ethernet_Header'Size + System.Storage_Unit - 1) /
> > System.Storage_Unit
>
> > which rounds the size in bits up to the next multiple of
> > System.Storage_Unit.  [System.Storage_Unit will equal 8 on most
> > systems.]
>
> It seems to me that this sort of thing won't work unless
> System.Storage_Unit is 8 bits.  So you don't want rounding up.
> It seems better to say:
>
>     pragma Assert (System.Storage_Unit = 8);
>     ... Raw_Bytes.all'Address + Ethernet_Header'Size/8 ...
>
> If you really need to do this sort of thing, that is.

That's very likely to work.  I'd still worry that, since the
definition of 'Size is slightly fuzzy, an implementation could still
choose a value that is not a multiple of 8 in a surprising way:

   type Rec1 is record
      Value_1 : Integer;  -- 32 bits, say
      Value_2 : Integer;
      Control_Flag : Boolean;
   end record;

On an 8-bit machine, is Rec1'Size 72 or 65?  I don't think the RM
provides an answer to this.  The minimum size required to represent
Rec1 is 65, and an implementation *could* decide that if Rec1 were a
component of a larger record, and that larger record has another
Boolean component, it could stick that component in the same byte as
Control_Flag.  Or it could just always allocate 9 bytes for Rec1
regardless.  So I still think rounding up is a good idea:

    pragma Assert (System.Storage_Unit = 8);
     ... Raw_Bytes.all'Address + (Ethernet_Header'Size+7)/8 ...

But the real answer, I think, is that if you're going to be using this
type for communication with other machines, you need to use
representation clauses to specify every detail of the type anyway,
including a 'Size clause:

   for Ethernet_Header'Size use ...;

and now you can make sure that it's a multiple of 8:

     pragma Assert (System.Storage_Unit = 8);
     pragma Assert (Ethernet_Header'Size mod 8 = 0);

     ... Raw_Bytes.all'Address + Ethernet_Header'Size/8 ...

                                    -- Adam



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

* Re: Adding offset to 'Address
  2008-09-12 15:23 ` Adam Beneschan
  2008-09-12 21:40   ` Robert A Duff
@ 2008-09-13  6:21   ` tmoran
  2008-09-17  9:15     ` Kim Rostgaard Christensen
  1 sibling, 1 reply; 13+ messages in thread
From: tmoran @ 2008-09-13  6:21 UTC (permalink / raw)


>  Raw_Bytes : access Unsigned_Char
>  for Ethernet_Header'Address use Raw_Bytes.all'Address;
>
>and additionally need something like:
>  for IP_Packet'Address use Raw_Bytes.all'Address + Ethernet_Header'Size;

It's not clear to me exactly what problem you are trying to get past.
How about something like:

with Ada.Unchecked_Conversion,
     Interfaces.C;
procedure Eiptest is
  type Ethernet_Header_Type is new Integer;          -- or whatever
  type IP_Packet_Type is array (1 .. 5) of Integer;  -- "

  type R_Type is record
    Ethernet_Header: Ethernet_Header_Type;
    IP_Packet: IP_Packet_Type;
    Other_Stuff : Integer;
  end record;
  for R_Type use record
    Ethernet_Header at 0 range 0 .. 31;
    IP_Packet at 4 range 0 .. 159;
    Other_Stuff at 30 range 0 .. 31;
  end record;

  type Lpvoid is access all Interfaces.C.Char;
  type R_Ptr_Type is access all R_Type;

  function Convert is new Ada.Unchecked_Conversion
    (Source => Lpvoid, Target => R_Ptr_Type);

  procedure Process(Raw_Bytes: in Lpvoid) is
    R_Ptr   : constant R_Ptr_Type := Convert(Raw_Bytes);
    This_IP_Packet: IP_Packet_Type renames R_Ptr.IP_Packet;
  begin
    null; -- do something with This_IP_Packet
  end Process;

  Buffer : Interfaces.C.Char_Array(1 .. 100);

begin
  Process(Buffer(1)'access);
end Eiptest;



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

* Re: Adding offset to 'Address
  2008-09-12  8:35 Adding offset to 'Address Kim Rostgaard Christensen
  2008-09-12  9:47 ` Georg Bauhaus
  2008-09-12 15:23 ` Adam Beneschan
@ 2008-09-13 10:18 ` Björn
  2008-09-17  9:18   ` Kim Rostgaard Christensen
  2 siblings, 1 reply; 13+ messages in thread
From: Björn @ 2008-09-13 10:18 UTC (permalink / raw)


On 12 Sep, 10:35, Kim Rostgaard Christensen <k...@greenpc.dk> wrote:
> Hi
>
> How does one go about setting a 'Address + (size of other record) to a
> record at runtime ?
>
> In brief, I am switching over "Frametype" in a Ethernet frame record, to
> dynamically assign the next record by type (IPv4,IPv6,ARP, etc.)
> My "datablob" is a *u_char from a imported C function.
>
> So I have:
>
>   Raw_Bytes : access Unsigned_Char
>   for Ethernet_Header'Address use Raw_Bytes.all'Address;
>
> and additionally need something like:
>   for IP_Packet'Address use Raw_Bytes.all'Address + Ethernet_Header'Size;
>
> Also, I am not confident that this _the_ solution, so other approaches
> are very welcome. For those curious about what it is all about, I ran a
> gnathtml on the source and made it available athttp://krc.greenpc.dk/hovedopgave/html/index.htm
>
> Regards
> Kim Rostgaard Christensen

I was also playing around with PCAP earlier this year. I have not yet
finished what I intended to do but I got basic IP reassembly and TCP
session reconstruction to work. I uploaded the files to
http://www.mediafire.com/?1neezbx5bb1 if you want to have a peek.
However, note that this is work in progress. The application is not
finished and the quality of the code will need improvement. There are
also a lot more special cases in TCP handling that will need to be
handled.

Regards
Björn



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

* Re: Adding offset to 'Address
  2008-09-13  6:21   ` tmoran
@ 2008-09-17  9:15     ` Kim Rostgaard Christensen
  2008-09-19  6:09       ` Randy Brukardt
  0 siblings, 1 reply; 13+ messages in thread
From: Kim Rostgaard Christensen @ 2008-09-17  9:15 UTC (permalink / raw)


tmoran@acm.org wrote:
>>  Raw_Bytes : access Unsigned_Char
>>  for Ethernet_Header'Address use Raw_Bytes.all'Address;
>>
>> and additionally need something like:
>>  for IP_Packet'Address use Raw_Bytes.all'Address + Ethernet_Header'Size;
> 
> It's not clear to me exactly what problem you are trying to get past.

The problem was basically to perform arithmethics on system addresses

> How about something like:
> 
> with Ada.Unchecked_Conversion,
>      Interfaces.C;
> procedure Eiptest is
>   type Ethernet_Header_Type is new Integer;          -- or whatever
>   type IP_Packet_Type is array (1 .. 5) of Integer;  -- "
> 
>   type R_Type is record
>     Ethernet_Header: Ethernet_Header_Type;
>     IP_Packet: IP_Packet_Type;
>     Other_Stuff : Integer;
>   end record;
>   for R_Type use record
>     Ethernet_Header at 0 range 0 .. 31;
>     IP_Packet at 4 range 0 .. 159;
>     Other_Stuff at 30 range 0 .. 31;
>   end record;
> 
>   type Lpvoid is access all Interfaces.C.Char;
>   type R_Ptr_Type is access all R_Type;
> 
>   function Convert is new Ada.Unchecked_Conversion
>     (Source => Lpvoid, Target => R_Ptr_Type);
> 
>   procedure Process(Raw_Bytes: in Lpvoid) is
>     R_Ptr   : constant R_Ptr_Type := Convert(Raw_Bytes);
>     This_IP_Packet: IP_Packet_Type renames R_Ptr.IP_Packet;
>   begin
>     null; -- do something with This_IP_Packet
>   end Process;
> 
>   Buffer : Interfaces.C.Char_Array(1 .. 100);
> 
> begin
>   Process(Buffer(1)'access);
> end Eiptest;

This is a nice approch, I will try it out.

- Kim



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

* Re: Adding offset to 'Address
  2008-09-13 10:18 ` Björn
@ 2008-09-17  9:18   ` Kim Rostgaard Christensen
  0 siblings, 0 replies; 13+ messages in thread
From: Kim Rostgaard Christensen @ 2008-09-17  9:18 UTC (permalink / raw)


Bj�rn wrote:
> On 12 Sep, 10:35, Kim Rostgaard Christensen <k...@greenpc.dk> wrote:
>> Hi
>>
>> How does one go about setting a 'Address + (size of other record) to a
>> record at runtime ?
>>
>> In brief, I am switching over "Frametype" in a Ethernet frame record, to
>> dynamically assign the next record by type (IPv4,IPv6,ARP, etc.)
>> My "datablob" is a *u_char from a imported C function.
>>
>> So I have:
>>
>>   Raw_Bytes : access Unsigned_Char
>>   for Ethernet_Header'Address use Raw_Bytes.all'Address;
>>
>> and additionally need something like:
>>   for IP_Packet'Address use Raw_Bytes.all'Address + Ethernet_Header'Size;
>>
>> Also, I am not confident that this _the_ solution, so other approaches
>> are very welcome. For those curious about what it is all about, I ran a
>> gnathtml on the source and made it available athttp://krc.greenpc.dk/hovedopgave/html/index.htm
>>
>> Regards
>> Kim Rostgaard Christensen
> 
> I was also playing around with PCAP earlier this year. I have not yet
> finished what I intended to do but I got basic IP reassembly and TCP
> session reconstruction to work. I uploaded the files to
> http://www.mediafire.com/?1neezbx5bb1 if you want to have a peek.
> However, note that this is work in progress. The application is not
> finished and the quality of the code will need improvement. There are
> also a lot more special cases in TCP handling that will need to be
> handled.
> 
> Regards
> Bj�rn

Wow, this is a very good source of inspiration, thanks

- krc



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

* Re: Adding offset to 'Address
  2008-09-17  9:15     ` Kim Rostgaard Christensen
@ 2008-09-19  6:09       ` Randy Brukardt
  2008-09-19  9:25         ` anon
  0 siblings, 1 reply; 13+ messages in thread
From: Randy Brukardt @ 2008-09-19  6:09 UTC (permalink / raw)


"Kim Rostgaard Christensen" <krc@greenpc.dk> wrote in message 
news:gaqhs6$690$1@jacob-sparre.dk...
> tmoran@acm.org wrote:
>>>  Raw_Bytes : access Unsigned_Char
>>>  for Ethernet_Header'Address use Raw_Bytes.all'Address;
>>>
>>> and additionally need something like:
>>>  for IP_Packet'Address use Raw_Bytes.all'Address + Ethernet_Header'Size;
>>
>> It's not clear to me exactly what problem you are trying to get past.
>
> The problem was basically to perform arithmethics on system addresses

No, that's a (bad) solution to some problem, not a problem by itself. The 
problem seems to be how to access the data bytes without accessing the 
header, and Tom suggests a good solution for that. (We use versions of it in 
Claw.)

IMHO, the use of Address in Ada 95 or newer code (other than to specify raw, 
absolute machine addresses) is never necessary and represents bad 
programming. I see it fairly often here, and it makes me ill. I much prefer 
general access types and possibly Unchecked_Conversions, because you lose 
much less strong typing that way (and the code is better without the need 
for heroic efforts on the part of the compiler).

                                 Randy.


                                          Randy.





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

* Re: Adding offset to 'Address
  2008-09-19  6:09       ` Randy Brukardt
@ 2008-09-19  9:25         ` anon
  0 siblings, 0 replies; 13+ messages in thread
From: anon @ 2008-09-19  9:25 UTC (permalink / raw)


Well have you looked at Ada-2005 language code, lately. It seams that in every 
upgradde that the maintainer ( Adacore ) are replacing Ada defined type with 
System.Address, more and more. 

But in relooking at this thread maybe the person wants the next version of 
Ada to have the following type of variable attribute for 'Address.

      Variable'Address ( Offset )


Now, for this thread:

    Count : Natural ;
    -- Count is set to the largest index that you may need 

  function Address_Offset ( Source : in System.Address ;
                            Index  : Natural         ) 
            return Array_Element_Type ;

    type Storage_Array is array ( 0..Count ) 
                          of aliased Array_Element_Type ;

    Array_Source : Storage_Array ;
      for Array_Source'Address use Source ;

    begin
      if Index >= 0 and Index <= Count then
        return Array_Source ( Index ) ;
      else
        raise Storage_Error ;
      end if ;
    end ;

This is based on the Memcy package.





In <gavfnq$kgp$1@jacob-sparre.dk>, "Randy Brukardt" <randy@rrsoftware.com> writes:
>"Kim Rostgaard Christensen" <krc@greenpc.dk> wrote in message 
>news:gaqhs6$690$1@jacob-sparre.dk...
>> tmoran@acm.org wrote:
>>>>  Raw_Bytes : access Unsigned_Char
>>>>  for Ethernet_Header'Address use Raw_Bytes.all'Address;
>>>>
>>>> and additionally need something like:
>>>>  for IP_Packet'Address use Raw_Bytes.all'Address + Ethernet_Header'Size;
>>>
>>> It's not clear to me exactly what problem you are trying to get past.
>>
>> The problem was basically to perform arithmethics on system addresses
>
>No, that's a (bad) solution to some problem, not a problem by itself. The 
>problem seems to be how to access the data bytes without accessing the 
>header, and Tom suggests a good solution for that. (We use versions of it in 
>Claw.)
>
>IMHO, the use of Address in Ada 95 or newer code (other than to specify raw, 
>absolute machine addresses) is never necessary and represents bad 
>programming. I see it fairly often here, and it makes me ill. I much prefer 
>general access types and possibly Unchecked_Conversions, because you lose 
>much less strong typing that way (and the code is better without the need 
>for heroic efforts on the part of the compiler).
>
>                                 Randy.
>
>
>                                          Randy.
>
>




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

end of thread, other threads:[~2008-09-19  9:25 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-12  8:35 Adding offset to 'Address Kim Rostgaard Christensen
2008-09-12  9:47 ` Georg Bauhaus
2008-09-12 10:17   ` Kim Rostgaard Christensen
2008-09-12 11:18     ` petter_fryklund
2008-09-12 15:23 ` Adam Beneschan
2008-09-12 21:40   ` Robert A Duff
2008-09-13  0:37     ` Adam Beneschan
2008-09-13  6:21   ` tmoran
2008-09-17  9:15     ` Kim Rostgaard Christensen
2008-09-19  6:09       ` Randy Brukardt
2008-09-19  9:25         ` anon
2008-09-13 10:18 ` Björn
2008-09-17  9:18   ` Kim Rostgaard Christensen

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