[fpc-pascal]Local Ip Address

Michalis Kamburelis michalis at camelot.homedns.org
Mon Feb 23 18:40:08 CET 2004


Crabtree, Chad wrote:
> Ok.  Thank you that worked however I'd like to ask some questions.  I tried
> to find the answer by looking at the source code however I'm confused by
> this code
> 
>         abcd:=PABCD(phe^.h_addr_list[0])^;
> 
> I beleive this automaticly parses h_addr_list[0] into the record.  Not sure
> why but that's ok. However when I looked at the winsock source most specifly
> hostent record type I was not able to winnow any meaning out of.
> 
>           case byte of
>              0: (h_addr_list: ^pchar);
>              1: (h_addr: ^pchar)
> 
> Which is the last part of the record.  Now please correct me if I'm wrong.
> but the h_addr_list is an array of bytes, however the type that's declared
> is a pointer to pchar right?  It's just muddy for me.  This is my first real
> forray into compiled languages, I can do what I want to with python or perl
> but this is a little beyond me.
> 
> Thanks 
> Chad

I perfectly understand your confusion -- hostent record type isn't a 
good example of "nice and clean type design". It was designed in C so 
it's rather "follow-the-pointers type design".

First of all, forget about "PChar". As you said, h_addr_list[0]^ is not 
a null-terminated array of chars. It's just array of bytes. You have to 
look at h_length to now how long (in bytes) it is.

h_addr_list is a "null-terminated list of pointers to addresses". This 
means that if you want to enumerate all addresses from hostent you have 
to do something like that

i:=0;
whle phe^.h_addr_list[i] <> nil do
begin
   ... here is the code to do something with an i-th address.
       phe^.h_addr_list[i] is a *pointer* to this address.
       phe^.h_length tells you how long is this address, in bytes.

   Inc(i);
end;

That's why I wrote in code attached to last mail that h_length should be 
4 for normal Internet address (as long as you forget about IPv6). This 
means that phe^.h_addr_list[0] is a pointer to four-byte array that 
contains the address you want to get.

So now we want to extract those four bytes. There are many ways to do 
this in Pascal. I wrote
   abcd:=PABCD(phe^.h_addr_list[0])^;
This line was not doing any "automatic string parsing" -- it was rather 
telling the compiler "treat phe^.h_addr_list[0] as a pointer to a record 
TABCD". And record TABCD is just a four-byte array.

One may also write something like that, maybe this will be more clear:
type
   TFourByteArray = array[0..3]of byte;
   PFourByteArray = ^TFourByteArray;
....
   Writeln(Format('%d.%d.%d.%d', [
     PFourByteArray(phe^.h_addr_list[0])^[0],
     PFourByteArray(phe^.h_addr_list[0])^[1],
     PFourByteArray(phe^.h_addr_list[0])^[2],
     PFourByteArray(phe^.h_addr_list[0])^[3]
     ]));

Hope this helps,
Michalis




More information about the fpc-pascal mailing list