Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2004-02

Local Ip Address

6 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Crabtree, Chad
Hello I am having a dikens of a time getting my IP address on the machine
that I am working on.  I've looked in the mailing list and I found something
that I've been toying with but still I cannot get the xxx.xxx.xxx.xxx style
name I can only get my machine name.  Here's what I have which I can get the
names but not the byte code address.
I know how to do this in python gethostbyname(gethostname()) by I'm having a
hard time with this.
program get_ip;
uses sockets,winsock;
const
	len:integer=256;
var
	lsock,y,z:longint;
	ac: array[0..255] of char;
	phe:phostent;
	xs:pchar;
	Adder:TInetSockAddr;
begin
	writeln(gethostname(ac,len));
	writeln(ac);
	phe:=gethostbyname(ac);
	xs:=phe^.h_addr_list[1];
	writeln(xs);
	phe:=gethostbyaddr(ac,4,PF_INET);
	xs:=phe^.h_name;
	writeln(xs)
end.

------------------------------------------------------------------------------------------- ***National City made the following annotations
-------------------------------------------------------------------------------------------

This communication is a confidential and proprietary business communication. It is intended solely for the use of the designated recipient(s). If this communication is received in error, please contact the sender and delete this communication.
===========================================================================================

Reply by email

Jeremy Cowgar
to Crabtree, Chad
Chad wrote 9 lines
Hello I am having a dikens of a time getting my IP address on the machine that I am working on. I've looked in the mailing list and I found something that I've been toying with but still I cannot get the xxx.xxx.xxx.xxx style name I can only get my machine name. Here's what I have which I can get the names but not the byte code address. I know how to do this in python gethostbyname(gethostname()) by I'm having a hard time with this.

Here's my code that I use:

uses sockets, errors, inet;

{ ... functions cut not important to your question ... }

function Open(host : string; port : integer) : integer;
var
    h : THost;
    addr : TInetSockAddr;
begin
    h.NameLookup(host);
    if h.LastError  0 then
      begin
        Open := 1;
        Exit;
      end;
    addr.family := AF_INET;
    addr.port   := ShortHostToNet(port);
    addr.addr   := HostTonet(longint(h.IPAddress));
    sock := Socket(AF_INET, SOCK_STREAM, 0);
    if Not Connect(sock, addr, sin, sout) then
      begin
        Open := 2;
        Exit;
      end;
    rewrite(sout);
    reset(sin);
    Open := 0;
end;

Hope this helps.

Jeremy

Reply by email

Crabtree, Chad

Here's my code that I use:

>uses sockets, errors, inet;

Well that is part of the problem I cannot compile Inet I'm using win2k

------------------------------------------------------------------------------------------- ***National City made the following annotations
-------------------------------------------------------------------------------------------

This communication is a confidential and proprietary business communication. It is intended solely for the use of the designated recipient(s). If this communication is received in error, please contact the sender and delete this communication.
===========================================================================================

Reply by email

Michalis Kamburelis
to Crabtree, Chad: Hello I am having a dikens of a time getting my IP address on the machine that I am…
Chad wrote 31 lines
Hello I am having a dikens of a time getting my IP address on the machine that I am working on. I've looked in the mailing list and I found something that I've been toying with but still I cannot get the xxx.xxx.xxx.xxx style name I can only get my machine name. Here's what I have which I can get the names but not the byte code address. I know how to do this in python gethostbyname(gethostname()) by I'm having a hard time with this. program get_ip; uses sockets,winsock; const len:integer=256; var lsock,y,z:longint; ac: array[0..255] of char; phe:phostent; xs:pchar; Adder:TInetSockAddr; begin writeln(gethostname(ac,len)); writeln(ac); phe:=gethostbyname(ac); xs:=phe^.h_addr_list[1]; writeln(xs); phe:=gethostbyaddr(ac,4,PF_INET); xs:=phe^.h_name; writeln(xs) end.

I'm attaching some quick&dirty hacks of your code that make everything working. It will also work on Linux (and other UNIXes, probably) when you replace winsock with Libc (in fact, I was doing my fixes while sitting on Linux... but I just checked this on Windows and it works). Note that it may return as address '127.0.0.1' which may or may not be usable to you.

Michalis

Reply by email

Crabtree, Chad

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

------------------------------------------------------------------------------------------- ***National City made the following annotations
-------------------------------------------------------------------------------------------

This communication is a confidential and proprietary business communication. It is intended solely for the use of the designated recipient(s). If this communication is received in error, please contact the sender and delete this communication.
===========================================================================================

Reply by email

Michalis Kamburelis
to Crabtree, Chad
Chad wrote 22 lines
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

Reply by email