Sign in Join

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

Mailing lists / fpc-pascal / 2002-07

Socket problems

3 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

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

Martyn Ranyard

Hi all, this is my first post to this list, lets see if there are any knowledgable eager beavers out there.

I have a program that used to run fine (Compiled with Freepascal on Linux ix86 Slackware), but doesn't anymore - admittedly I am now running on a rebuilt machine, as the hard disk failed.

here's a snippet :

-------- 8<---------
   lSock := Socket(af_inet, sock_stream, 0);
   if lSock = -1 then SockError('Socket: ');
   with sAddr do
   begin
     Family := af_inet;
     Port := htons(ListenPort);
     Addr := 0;
   end;
   Writeln('Listening on port ',ListenPort);
   if not Bind(lSock, sAddr, sizeof(sAddr)) then SockError('Bind: ');
-------- 8<---------

ListenPort is a word containing 7878

Which when compiled with -Sd gives an exception and with -S2 gives an error message :

(ppc386 -Sd program ; ./program)
An unhandled exception occurred at 0x08062E1D :
Access violation
0x08062E1D
0x0805E481
0x08064ECF
0x080480B0

(ppc386 -S2 program ; ./program)

Bind: Permission denied

Now, I am running as a normal user, but as root, the -S2 version runs without error, but does not answer on the port 7878, but on 198. (which explains why as a user I cannot bind to it, but why is it listening on 198?) The htons() is from inetaux.pas, the code for which is at the end of this email, but if I don't have it - and I think I should (the document that I have learned from provided the function) - the program doesn't error as a user, but even an nmap scan doesn't register any new ports open.

This is most confusing, as I'm sure you can appreciate, and any suggestions would be gratefully recieved.

htons() from inetaux.pas :

-------- 8<---------
function htons(i : Integer) : Integer;
begin
    htons := lo(i) shl 8 or hi(i);
end;
-------- 8<---------

Thanks all.

Martyn Ranyard
Free Software Advocate

jabber -
icq - 122500800
irc - Joran on oftc
msn -
y! - ranyardm
e -

Thomas Schatzl
to Martyn Ranyard

Subject: [fpc-pascal]Socket problems

Hi,

Show quoted text 24 lines
ListenPort is a word containing 7878 [...] Now, I am running as a normal user, but as root, the -S2 version runs without error, but does not answer on the port 7878, but on 198. (which explains why as a user I cannot bind to it, but why is it listening on 198?) The htons() is from inetaux.pas, the code for which is at the end of this email, but if I don't have it - and I think I should (the document that I have learned from provided the function) - the program doesn't error as a user, but even an nmap scan doesn't register any new ports open. This is most confusing, as I'm sure you can appreciate, and any suggestions would be gratefully recieved. htons() from inetaux.pas : -------- 8<--------- function htons(i : Integer) : Integer; begin htons := lo(i) shl 8 or hi(i); end; -------- 8<---------

This function is the problem. Due to different sizes of the Integer type in the different compiler modes the htons() function returns wrong values:

In both -Sd and -S2 the Integer type is 32 bit, the lo() and hi() function return the lo() and hi() - *word* (not byte) of the given integer.
E.g. lo(7878) = 7878 and hi(7878) = 0 so htons returns 2016768 which is likely invalid. =)
Using -St or *no* compiler mode switch solves the problem.

The reason why bind() binds to port 198 ist that the hi-byte of the low word (which is used by bind()) of 2016768 is 198 (the low-byte is zero).... Iirc user programs are not allowed to bind to a port < 1024 (at least your system is set up in this way), that also explains the "permission denied" when not logged in as root.

However I don't know why the program crashes when compiled in one mode but not in the other.... Try using the -ghl switches to get more information about the crash location.

I recommend defining und exclusively using own integer types in your code which are automatically mapped to types with the same value ranges independently of the compiler mode to avoid those really nasty problems...

Finally, here's a compiler mode independent (at least atm) version of the htons() function:

function htons(i : Word) : Word;
begin
    htons := lo(i) shl 8 or hi(i);
end;

Because the "Word" - type is always 16 bit unsigned integer sized in FPC supported platforms and modes. ^^

Regards,
Thomas

Martyn Ranyard
to Thomas Schatzl
you wrote 12 lines
Subject: [fpc-pascal]Socket problems This function is the problem. Due to different sizes of the Integer type in the different compiler modes the htons() function returns wrong values: In both -Sd and -S2 the Integer type is 32 bit, the lo() and hi() function return the lo() and hi() - *word* (not byte) of the given integer. E.g. lo(7878) = 7878 and hi(7878) = 0 so htons returns 2016768 which is likely invalid. =) Using -St or *no* compiler mode switch solves the problem.

Aha! So, the fact that I am used to Delphi code (i.e. am using Exceptions and such) and am reading about internet programming in freepascal for the first time has knobbled me!

Thanks very much, reverting the Integers to Words has solved my problem, and I will look out for any changes in future, I'm stumped as to why it compiled and ran previously, but now I don't care. :)

You have made me a happy man. Thank you.

Regards, Thomas

Thank you again

Martyn Ranyard
Free Software Advocate

jabber -
icq - 122500800
irc - Joran on oftc
msn -
y! - ranyardm
e -