Thread: [Win2k - Version 8.0.2] - StartupMessage Format Question

[Win2k - Version 8.0.2] - StartupMessage Format Question

From
"Tom Pfeifer"
Date:
I don't know where to go with this question.
If this is the wrong place, please disregard.

I'm trying to learn more about how to connect to the backend with perl, not using DBI, just
straight perl (pure perl).  I feel like an idiot asking this question, but I don't seem to
understand what the "zero byte" terminator is.  What is the equivalent ASCII character?  Or is perl
unable to process this "zero byte" terminator?

This is the page I am lookin at in the docs:
http://www.postgresql.org/docs/8.0/static/protocol-message-formats.html

This is the location I am reviewing in the docs:
StartupMessage (F)

This is the attempted connection:
00 00 00 22 00 03 00 00 75 73 65 72 20 70 6F 73  ..."....user pos
74 67 72 65 73 20 64 61 74 61 62 61 73 65 20 6D  tgres database m
61 61 63 68 00 00                                aach..

This is the result:
45 00 00 00 7E 53 46 41 54 41 4C 00 43 30 38 50  E...~SFATAL.C08P
30 31 00 4D 69 6E 76 61 6C 69 64 20 73 74 61 72  01.Minvalid star
74 75 70 20 70 61 63 6B 65 74 20 6C 61 79 6F 75  tup packet layou
74 3A 20 65 78 70 65 63 74 65 64 20 74 65 72 6D  t: expected term
69 6E 61 74 6F 72 20 61 73 20 6C 61 73 74 20 62  inator as last b
79 74 65 00 46 70 6F 73 74 6D 61 73 74 65 72 2E  yte.Fpostmaster.
63 00 4C 31 34 39 31 00 52 50 72 6F 63 65 73 73  c.L1491.RProcess
53 74 61 72 74 75 70 50 61 63 6B 65 74 00 00     StartupPacket..

This is the code:
use IO::Socket;
$string = 'user postgres database maach';
$version = pack('Nnna30', 34, 3, 0, $string);
print "\n";
while ($version =~ m/(.{1,16})/g) {
  my $chunk = $1;
  print join ' ', map {sprintf '%02X', ord $_} split //, $chunk;
  print '   ' x (16 - length $chunk);
  print '  ';
  print join '', map { sprintf '%s', (/[[:graph:] ]/) ? $_ : '.' } split //, $chunk;
  print "\n";
}
$remote = IO::Socket::INET->new(PeerAddr => '127.0.0.1',
                                PeerPort => '5432',
                                Proto => 'tcp', Timeout  => '30') or die "error:$!";
$remote->autoflush(1);
print $remote $version;
while ( <$remote> ) {
  print "\n";
  while ($_ =~ m/(.{1,16})/g) {
    my $chunk = $1;
    print join ' ', map {sprintf '%02X', ord $_} split //, $chunk;
    print '   ' x (16 - length $chunk);
    print '  ';
    print join '', map { sprintf '%s', (/[[:graph:] ]/) ? $_ : '.' } split //, $chunk;
    print "\n";
  }
}
$remote->close;
exit(0);

Thanks,
T Pfeifer

Re: [Win2k - Version 8.0.2] - StartupMessage Format Question

From
Olivier Thauvin
Date:
Le Sunday 15 May 2005 02:04, Tom Pfeifer a écrit :
> I don't know where to go with this question.
> If this is the wrong place, please disregard.
>
> I'm trying to learn more about how to connect to the backend with perl, not
> using DBI, just straight perl (pure perl).  I feel like an idiot asking
> this question, but I don't seem to understand what the "zero byte"
> terminator is.  What is the equivalent ASCII character?  Or is perl unable
> to process this "zero byte" terminator?
>
> This is the page I am lookin at in the docs:
> http://www.postgresql.org/docs/8.0/static/protocol-message-formats.html

Zero byte terminator come from C functions, aka character number 0 (not the
0), this is the first (non printable) character in map. I don't know how to
put in a scalar from perl code, maybe "\0".

Attachment

Re: [Win2k - Version 8.0.2] - StartupMessage Format Question

From
John DeSoi
Date:
On May 14, 2005, at 8:04 PM, Tom Pfeifer wrote:

> I don't know where to go with this question.
> If this is the wrong place, please disregard.
>
> I'm trying to learn more about how to connect to the backend with
> perl, not using DBI, just
> straight perl (pure perl).  I feel like an idiot asking this question,
> but I don't seem to
> understand what the "zero byte" terminator is.  What is the equivalent
> ASCII character?  Or is perl
> unable to process this "zero byte" terminator?
>

The equivalent ASCII character is NULL, a non-printable character with
ASCII code 0.

So in your hex dump you should have 00 after each string. Looks like
you have a space (20)

75 73 65 72 20 70 6F 73  ..."....user pos



John DeSoi, Ph.D.
http://pgedit.com/
Power Tools for PostgreSQL


Re: [Win2k - Version 8.0.2] - StartupMessage Format Question

From
"Tom Pfeifer"
Date:
OK, thanks for the info about the correct ASCII character.
Now I am using ASCII 0 and it still doesn't work.

$string = 'user' . chr(0) . 'postgres' . chr(0) . 'database' . chr(0) .  'maach' . chr(0) . chr(0);
$version = pack('Nnna30', 34, 3, 0, $string);

00 00 00 22 00 03 00 00 75 73 65 72 00 70 6F 73  ..."....user.pos
74 67 72 65 73 00 64 61 74 61 62 61 73 65 00 6D  tgres.database.m
61 61 63 68 00 00                                aach..

45 00 00 00 7E 53 46 41 54 41 4C 00 43 30 38 50  E...~SFATAL.C08P
30 31 00 4D 69 6E 76 61 6C 69 64 20 73 74 61 72  01.Minvalid star
74 75 70 20 70 61 63 6B 65 74 20 6C 61 79 6F 75  tup packet layou
74 3A 20 65 78 70 65 63 74 65 64 20 74 65 72 6D  t: expected term
69 6E 61 74 6F 72 20 61 73 20 6C 61 73 74 20 62  inator as last b
79 74 65 00 46 70 6F 73 74 6D 61 73 74 65 72 2E  yte.Fpostmaster.
63 00 4C 31 34 39 31 00 52 50 72 6F 63 65 73 73  c.L1491.RProcess
53 74 61 72 74 75 70 50 61 63 6B 65 74 00 00     StartupPacket..

I must be missing something else.
Am I calculating the string length correctly?
Is the length/version/revision/string being packed correctly?
Maybe my pack statement is all wrong?
Any help would be much appreciated.

T Pfeifer

Re: [Win2k - Version 8.0.2] - StartupMessage Format Question

From
John DeSoi
Date:
On May 14, 2005, at 10:16 PM, Tom Pfeifer wrote:

> I must be missing something else.
> Am I calculating the string length correctly?
> Is the length/version/revision/string being packed correctly?
> Maybe my pack statement is all wrong?
> Any help would be much appreciated.

I don't know perl, so it is hard for me to check your work. The string
you are building looks correct:

$string = 'user' . chr(0) . 'postgres' . chr(0) . 'database' . chr(0) .
  'maach' . chr(0) . chr(0);

So the length of message should be = 4 + 4 + length($string)
That's 4 bytes for the message length, 4 bytes for the protocol
version, and then the length of the string including the null bytes.

So write the total length, protocol version, and then your connect
string. Any integer you write (Int16 and Int32 in the protocol) needs
to be in network byte order (most significant byte first).


John DeSoi, Ph.D.
http://pgedit.com/
Power Tools for PostgreSQL


Fw: Re: [Win2k - Version 8.0.2] - StartupMessage Format Question

From
"Tom Pfeifer"
Date:
Thank you all for the help.  If your interested in the solution I have put it here in the email for
future reference.  This is broken down step by step and could be combined so the code is more
efficient.  This is just the first step.  I need to take this and create the appropriate steps for
Authentication etc...  But the hard part is done.  I can now connect to the postgres backend and I
get an appropriate message back which asks for the password.

use IO::Socket;
$string = 'user' . chr(0) . 'postgres' . chr(0) . 'database' . chr(0) .  'maach' . chr(0) . chr(0);
$strlen = length($string);
$string = pack("a$strlen", $string);
$version = pack('n', 3);
$verlen = length($version);
$revision = pack('n', 0);
$revlen = length($revision);
$total = 4 + $strlen + $verlen + $revlen;
$len = pack('N', $total);
$send = $len . $version . $revision . $string;
while ($send =~ m/(.{1,16})/g) {
  my $chunk = $1;
  print join ' ', map {sprintf '%02X', ord $_} split //, $chunk;
  print '   ' x (16 - length $chunk);
  print '  ';
  print join '', map { sprintf '%s', (/[[:graph:] ]/) ? $_ : '.' } split //, $chunk;
  print "\n";
}
$remote = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => '5432', Proto => 'tcp',
Timeout  => '30') or die "error:$!";
$remote->autoflush(1);
print $remote "$send\n";
while ( <$remote> ) { 
  print "\n";
  while ($_ =~ m/(.{1,16})/g) {
    my $chunk = $1;
    print join ' ', map {sprintf '%02X', ord $_} split //, $chunk;
    print '   ' x (16 - length $chunk);
    print '  ';
    print join '', map { sprintf '%s', (/[[:graph:] ]/) ? $_ : '.' } split //, $chunk;
    print "\n";
  }
}
$remote->close;
exit(0);

RESULTS::)
00 00 00 26 00 03 00 00 75 73 65 72 00 70 6F 73  ...&....user.pos
74 67 72 65 73 00 64 61 74 61 62 61 73 65 00 6D  tgres.database.m
61 61 63 68 00 00                                aach..

52 00 00 00 0C 00 00 00 05 80 F4 24 B6           R..........$.

Thanks again to all who clued me in on the correct format for the StartupMessage.
T Pfeifer


Re: Fw: Re: [Win2k - Version 8.0.2] - StartupMessage Format Question

From
Volkan YAZICI
Date:
Hi,

Did using your own raw interface instead of DBI cause any
performance/speed change? (Should it?)

Regards.