A couple of novice questions

38 views
Skip to first unread message

David J. Hughes

unread,
May 11, 1992, 9:28:02 PM5/11/92
to

I decided to use perl as a prototyping platform for components of a
network management system I'll be writing later in the year. Although
I've written a couple of simple admin and stats gather scripts in perl,
this is the first major project I've tried in this language.

After reading all the docs/tutes I can get my hands on (other than the
Camel book) I'm still left scratching my head on a couple of things.

The first part of the program merely test whether a host is up prior to
performing more serious test on it. I decided to implement my own ICMP
Echo routines for this rather than using an external "ping". After
stuffing around with the packet format and the checksum calculations
I'm able to send and receive the Echo frames for a specified host.

My first question came about during the construction of the checksum
in which I had to read each byte from the packet for the calculation. I
tried several incantations of unpack etc. and eventually got it to work
although I still don't understand why my earlier attempts failed.

The winning approach was to use :-

@pkt_array = unpack("C*", $_[0]);

inside the checksum routine and then use each element of the array. My
original effort used something like :-

$pkt = $_[0];
while (($head,$tail) = unpack("C C*",$pkt))
{
push(@pkt_array,$head);
$pkt = $tail;
}

This, I assumed, would rip each byte from the packet and store it in an
element of the array. It didn't and in fact only iterated twice no
matter how large the packet was. Although it now works, I'd like to know
why the above approach failed.


Secondly, how can I have a generic, "binary" data field and stuff any
old thing into it. I've tried using "C*" and packing a test string into
it and then unpacking it. I've also tried packing a string into a
structure and then packing that into a "C*". The two phased unpack
still produced garbage. I can overcome the problem by using "A*" in
the packet spec but then the above "byte by byte" checksum fails. It
also isn't what I'm after as I want to send numeric timing details in
some cases and any other sort of data at another time.


Any pointers? It looks like I've missed some point as far as Perl's
data storage is concerned (in both of the above questions). Other than
that I'm very impressed by the power of Perl. It is the most amazing
"shell" I've ever used.


___ David J. Hughes ba...@bu.oz.au
/ \ / / /
/ __/ __ __ ____/ / / __ Senior Network Programmer
/ \ / \ / \ / / / / / \ / Comms Development & Operation
\____/ \__// / \__/ \___/ / / / AUSTRALIA (+61 75 951450)

Larry Wall

unread,
May 12, 1992, 3:02:38 PM5/12/92
to
In article <1992May12.0...@kirk.bu.oz.au> ba...@bu.oz.au (David J. Hughes) writes:
: My first question came about during the construction of the checksum

: in which I had to read each byte from the packet for the calculation. I
: tried several incantations of unpack etc. and eventually got it to work
: although I still don't understand why my earlier attempts failed.
:
: The winning approach was to use :-
:
: @pkt_array = unpack("C*", $_[0]);
:
: inside the checksum routine and then use each element of the array. My
: original effort used something like :-
:
: $pkt = $_[0];
: while (($head,$tail) = unpack("C C*",$pkt))
: {
: push(@pkt_array,$head);
: $pkt = $tail;
: }
:
: This, I assumed, would rip each byte from the packet and store it in an
: element of the array. It didn't and in fact only iterated twice no
: matter how large the packet was. Although it now works, I'd like to know
: why the above approach failed.

Because unpacking C* results in a list of byte values, and you only
assigned the first of them to $tail. Use "C a*" to do what you wanted.

By the way, you can do checksums directly with unpack using something like:

$sum = unpack("%16c*", $stuff);

You might of course have to complement that afterwards.

: Secondly, how can I have a generic, "binary" data field and stuff any


: old thing into it. I've tried using "C*" and packing a test string into
: it and then unpacking it. I've also tried packing a string into a
: structure and then packing that into a "C*". The two phased unpack
: still produced garbage. I can overcome the problem by using "A*" in
: the packet spec but then the above "byte by byte" checksum fails. It
: also isn't what I'm after as I want to send numeric timing details in
: some cases and any other sort of data at another time.

Use the 'a' specifier for binary data, not 'A', which is for ASCII data,
and strips trailing spaces and nulls. For instance, unpack("a5", "foo\0\0")
will give you "foo\0\0", but unpack("A5", "foo\0\0") gives you "foo".

: Any pointers? It looks like I've missed some point as far as Perl's


: data storage is concerned (in both of the above questions). Other than
: that I'm very impressed by the power of Perl. It is the most amazing
: "shell" I've ever used.

Just don't compare it with a real language, or you'll be unhappy... :-)

Larry

Marc Horowitz

unread,
May 13, 1992, 5:01:16 AM5/13/92
to
|> I'm able to send and receive the Echo frames for a specified host.

That sounds very useful. Could I get a copy of it? Thanks!

Marc

Reply all
Reply to author
Forward
0 new messages