Trying to force 32-bit in pack()

B

Brad Walton

I am trying to force 32-bit integers in this pack statement:

pack("iiiaa", 18, 1, 3, "password", "");

18+2+3 should = 22 bytes sent

Instead it is only sending 14 bytes. Is there a way to _force_ 32-bits?

Thanks for any help,
Brad
 
A

A. Sinan Unur

I am trying to force 32-bit integers in this pack statement:

pack("iiiaa", 18, 1, 3, "password", "");

18+2+3 should = 22 bytes sent

Instead it is only sending 14 bytes.

How did you come to that conclusion?

From perldoc -f pack:

With all types except "a", "A", "Z", "b", "B", "h",
"H", "@", "x", "X" and "P" the pack function will
gobble up that many values from the LIST.
Is there a way to _force_ 32-bits?

From the same document:


l A signed long value.
L An unsigned long value.
(This 'long' is _exactly_ 32 bits, which may differ from
what a local C compiler calls 'long'. If you want
native-length longs, use the '!' suffix.)

But this is irrelevant because you have misdiagnosed the problem. Just
looking at the hex dump of the result of your pack should have given you a
clue (which is exactly what I did before anything else, because pack is
magic to me):

0000000: 1200 0000 0100 0000 0300 0000 7000

That is 18, 1, 3 and 'p' and '' on a x86 platform.

The solution is to use:

pack('iiiZ*Z*', 18, 1, 3, 'password', '');

On the other hand, if you are sending this stuff over the network you
probably want something else.

Sinan.
 
B

Brad Walton

But this is irrelevant because you have misdiagnosed the problem. Just
looking at the hex dump of the result of your pack should have given you a
clue (which is exactly what I did before anything else, because pack is
magic to me):

0000000: 1200 0000 0100 0000 0300 0000 7000

That is 18, 1, 3 and 'p' and '' on a x86 platform.

The solution is to use:

pack('iiiZ*Z*', 18, 1, 3, 'password', '');

On the other hand, if you are sending this stuff over the network you
probably want something else.

Sinan.

I broke out a packet sniffer and saw this too. And yes, I am sending this
over a network. I am going to try your suggestion and see what happens. What
else would you suggest?

Thanks,
Brad
 
A

A. Sinan Unur

And yes, I am sending this over a network. I am going to
try your suggestion and see what happens. What else would
you suggest?

Depends on the protocol you are using. That should specify how things get
interpreted at both ends of the connection.

Sinan.
 
B

Brad Walton

And yes, I am sending this over a network. I am going to
Depends on the protocol you are using. That should specify how things get
interpreted at both ends of the connection.

It's a TCP/IP connection. Here's the whole script (with my notes):

#!/usr/bin/perl -w
use strict;
use IO::Socket;

# Connect to the rcon server
print "Connecting to server ... ";
my $sock = new IO::Socket::INET(PeerAddr => '209.209.44.30', PeerPort =>
'27015', proto => 'tcp',);
if (!$sock) {
die "Unable to connect $@\n";
}
print "done\n";

# Now we send something
# The packet structure is as follows:
#
# PACKET {
# 32bits size; # This is the size of the data to follow
# # The 32 bits packet size is not included
# 32bits requestid; # The request identifier. This can be a continuously
# # incrementing value (I think) Used to map responses
# # with requests, (I think).
# 32bits commandid # This rells the server which type of request we are
# # makeing In the example it is a LOGIN #3
#
# Random amounts and types of data follow. The types are allways constant
# for a particular command id.
# };
#
# Note 1 32bit integer would be a size 4. Four * 8 bits.
# A char is 1 8 bits to represent the entire ascii table
#
# The example packet was a login packet #3 with the following structure
#
# COMMAND_LOGIN {
# 32bits size = (requestid + commandid + password + unknown)
# (4 + 4 + (8 + 1) + (0 + 1)) # We count the null char.
# 18; # * 8 bits
# 32bits request = 1; # next is 2, 3....
# 32bits command = 3; # COMMAND_LOGIN
# null terminated char = "password\0"; # \0 == null
# null terminated char = "\0"; #
# };
#
#

# Pack packs the data according to a format string
# integer,integer,integer,null terminated string,null terminated string
print "Constructing packet ... ";
my $login_packet = pack('iiiZ*Z*', 18, 1, 3, 'password', '');
print "done: $login_packet\n";

# Send on the wire
print "Sending packet ... ";
print $sock $login_packet;
print "done\n";

# Dirty hack from Alfred_Reynolds program
# sleep(1);

print "Waiting for response ... ";
my $buf;
if (!$sock->recv($buf, 4)) {
die "bad recv $@\n";
}
my $response_size = unpack("i", $buf);
if (!$sock->recv($buf, $response_size)) {
die "bad recv $@\n";
}
my ($request_id, $command_response, $string1, $string2) = unpack("iiaa",
$buf);
print "received: $request_id, $command_response, $string1, $string2\n";

exit(0);
 
A

A. Sinan Unur

It's a TCP/IP connection. Here's the whole script (with my notes):

What is the application protocol?
# Pack packs the data according to a format string
# integer,integer,integer,null terminated string,null terminated
# string
print "Constructing packet ... ";
my $login_packet = pack('iiiZ*Z*', 18, 1, 3, 'password', '');

You probably want N rather than i.

However, your script will likely have other problems.
print "Waiting for response ... ";
my $buf;
if (!$sock->recv($buf, 4)) {
die "bad recv $@\n";

Do you realize that recv is for UDP whereas you have specified a tcp
socket?

Sinan.
 
B

Brad Walton

What is the application protocol?

Not sure how to answer that, but this is what is sent to/from:

Size,RequestID,Command,String1,String2(String 2 is always null "")
Do you realize that recv is for UDP whereas you have specified a tcp
socket?

No, I did not. One problem I am having, is the response is sent without a
newline. I tried:

$response = <$sock>;

But that expects a newline (right?). I need some way to figure out the
length of data being sent, then read it. I also need to be able to receive
multiple responses to one request. I got lots of issues...

Thanks,
Brad
 
B

Brad Walton

Brad Walton said:
Not sure how to answer that, but this is what is sent to/from:

Size,RequestID,Command,String1,String2(String 2 is always null "")


No, I did not. One problem I am having, is the response is sent without a
newline. I tried:

$response = <$sock>;

But that expects a newline (right?). I need some way to figure out the
length of data being sent, then read it. I also need to be able to receive
multiple responses to one request. I got lots of issues...

Thanks,
Brad

I got it to work. After some research (emails), I found out it needed
little-endian 32 bit 'V'. Thanks again for your help. It is appreciated!

Brad
 
J

Joe Smith

Brad said:
I got it to work. After some research (emails), I found out it needed
little-endian 32 bit 'V'. Thanks again for your help. It is appreciated!

In the case of a protocol that you've invented yourself, it does not make
much difference when using V instead of N, as long as both ends agree
and are the same endian-ness. But if you intend to talk to another
machine that is not based the the x86 architecture, you need to use
the network-byte-order (n and N).
-Joe
 
B

Ben Morrow

Quoth Joe Smith said:
In the case of a protocol that you've invented yourself, it does not make
much difference when using V instead of N, as long as both ends agree
and are the same endian-ness. But if you intend to talk to another
machine that is not based the the x86 architecture, you need to use
the network-byte-order (n and N).

No, both N and V are byte-order-independant (big- and little-endian
respectively). iIlL are the ones you need to watch when talking to
different architectures.

Of course, if you're designing your own protocol you should use N,
because it's the standard, but if you're following someone else's you
have no choice.

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top