This is an archived low-energy page for bots and other anonmyous visitors.
Please sign up if you are a human and want to interact.
⭐ in reply to Re: IP Header in thread IP Header
My understanding of the way IP headers are formed is that $ver should equal 4 when all is said and done. So, while grabbing it all in one swoop solves the repeating data I am still not obtaining the expected results.
If you have 4 bits that represent, say, an integer how do you unpack to a usable value?
Re^3: IP Header⭐
by Aristotle (Chancellor) on Nov 02, 2002 at 17:13 UTC
|
Oh. Silly me. You have a problem there: unpack consumes its input in byte chunks. Even if you specify b4, it will consume a full byte. (If you specificy b10, it will eat two full bytes.) Note also that b8 will return something of the form 00011111, not 31 - for that purpose you need C (unsigned character).
For in-byte bit fiddling, you need vec:
my ($ver_hlen, $tos, $len) = unpack "C2n", $foo;
my ($ver, $hlen) = (vec($ver_hlen, 4, 0), vec($ver_hlen, 4, 1));
or more compactly
my ($ver, $hlen) = map( vec($ver_hlen, 4, $_), (0 .. 1) );
See perldoc -f vec for details.
Makeshifts last the longest. | [reply] [d/l] [select] |
|
|
Thank you for your help thus far. I am now getting the expected results for $tos and $len, however, $ver and $hlen are still not right.
first, your "vec($ver_hlen, 4, 0)" brings up "illegal number of bits", due to 0 but being a power of 2 between 1 and 32 (from perldoc -f vec).
I am having trouble understanding exactly what the bits field is. Is that the number of bits that you want to read in? if so, wouldn't:
my ($ver, $hlen) = (vec($ver_hlen, 0, 4), vec($ver_hlen, 4, 4));
be better? Using the the changes i made above, I get unexpected results for the values for $ver and $hlen, which leads me to believe I am wrong. | [reply] [d/l] |
|
|
| [reply] [d/l] [select] |
|
|
In addition to the problems Aristotle outlined above, there is one more problem. The functions unpack("b") and vec() unpack the bits in the wrong order within bytes.
If you unpack("B*", $foo), you will get all the bits (as a string) in the right order. Here is one way to get your final answer, although I'm not sure that eval "0b$_" is the best solution:
($ver, $hlen, $tos, $len) = map { eval "0b$_" } unpack "A4A4A8A16", un
+pack("B*", $a);
| [reply] [d/l] [select] |
|
|
|
|