Reading Hex from File and Putting it in a Packet 
Author Message
 Reading Hex from File and Putting it in a Packet

Hey Everybody,

I'm having a little bit of a problem with this and I was hoping
someone would help.  I'll try to explain it as best I can.  Right now
I have a program that hardcodes hex values into a packet that I want
to send across the network.  I want to move that hard code out to a
file and read it from there.  Here is some example code:

What I have:

 // Defining the hex values I want to put in the packet
 int origin = 0x00010140;
 int asPathFlags =0x40;
 int typecodePath = 0x02;

 // copying the values into a character array
 memmove((char*)updateMsg+23, &origin, 4);
 memmove((char*)updateMsg+27, &asPathFlags,1);
 memmove((char*)updateMsg+28, &typecodePath,1);

What I'm having problems with is the format of the file containing the
hex values.  What would be the best way to do this?  Should I store
the values as decimal then do something like cin >> hex >> value?

0x00010140 0x40 0x02

I want to be able to read from the file into an array and just send
it.  Can someone help me brainstorm?

Thanks in advance
--



Wed, 21 Sep 2005 15:23:21 GMT  
 Reading Hex from File and Putting it in a Packet

Quote:

> I have a program that hardcodes hex values into a packet that I want
> to send across the network.  I want to move that hard code out to a
> file and read it from there.

The values might be expressed as hexadecimal, but they're
just ordered collections of bits.  Since you indicate
network use, presumably the value should be usable with
hosts having arbitrary CPU architectures, so it is
essential to specify the packet format in a machine-
independent way.  While you *could* convert to ASCII
text characters, traditionally network packets are fixed
size binary-encoded fields.  But binary representation of
numeric values varies across architectures.  In
particular, for multiple-octet values (such as

Quote:
>  int origin = 0x00010140;

) you need to transmit those fout octets in a definite
order, e.g. "little endian", and reassemble them in the
same order on the receiving end.  That means that

Quote:
>  memmove((char*)updateMsg+23, &origin, 4);

is a mistake, since that leaves the octet order up to
the specific CPU architecture.  If you have access to
an existing package for machine-independent data
representation, e.g. Sun's XDR, use that; otherwise
define your own standard.  I suggest for integers:
twos-complement, use lowest 8 bits per char (which is
what your network I/O functions probably expect anyway),
least significant octet of integer value at lowest byte
address.  Fortunately, nearly all existing platforms
directly support unpadded twos-complement integer
representation and provide 8-bit byte addressability,
so if you're willing to limit your application to such
platforms, the only thing left to deal with is the
byte ordering.  Replace the memmove with
        le_store_long(&updateMsg[23], 0x00010140L);
                // 4 octets might not fit in plain int!
where the function might be implemented like this:

void
le_store_ulong(unsigned char *buffer, unsigned long value)
        {
        register int i;
        for (i = 0; i < 32; i += 8
                buffer[i] = (unsigned char)
                        ((value & (0xFFUL << i)) >> i);
        }

The converse function at the receiver would be:

unsigned long
le_load_ulong(const unsigned char *buffer)
        {
        register int i;
        register unsigned long value = 0;
        for (i = 0; i < 32; i += 8)
                value |=
                ((unsigned long)buffer[i] & 0xFFUL) << i;
        return value;
        }

If you had a signed (long) integer, somewhat more care
would be needed, but it would suffice to "pun" the integer
value as type (unsigned long) and use the above functions
to convert it.
--



Sat, 24 Sep 2005 07:30:23 GMT  
 Reading Hex from File and Putting it in a Packet

Quote:

>  // Defining the hex values I want to put in the packet
>  int origin = 0x00010140;
>  int asPathFlags =0x40;
>  int typecodePath = 0x02;

Your first misunderstanding shows up here.  These are by no means "hex
values", they're plain integers.  Hexadecimal is just a slightly more
direct view of presenting them to humans than the usual decimal one,
but by no means is that a property of the number itself.

Your machine internally keeps numbers in whatever base it wants ---
typically binary, but you can't rely on that.

Quote:
>  // copying the values into a character array
>  memmove((char*)updateMsg+23, &origin, 4);
>  memmove((char*)updateMsg+27, &asPathFlags,1);
>  memmove((char*)updateMsg+28, &typecodePath,1);

The latter two of these are guaranteed to fail, on about half of the
existing computing platforms.  Avoid them like the plague.

Quote:
> What I'm having problems with is the format of the file containing the
> hex values.  What would be the best way to do this?  Should I store
> the values as decimal then do something like cin >> hex >> value?

[I'll pretend you wrote scanf() instead of cin >> there, since the
latter would be off-topic in this C newsgroup...]

If you want your communication to be able to work between different
computing platforms, writing out hexadecimal (or generally,
"human-readable ASCII") is indeed one of the recommended ways of
achieve that goal.  Others are more complicated to handle, and may
still fail in more obscure cases.  You don't need the "0x" prefix,
either, as long as the receiving party knows about these numbers being
in hexadecimal representation.

--

Even if all the snow were burnt, ashes would remain.
--



Sat, 24 Sep 2005 07:30:26 GMT  
 Reading Hex from File and Putting it in a Packet
Thanks for responding, Douglas

Here is some more background on what I'm trying to do.  This program
is based on Cisco Architectures, more specifically, sniffing packets
off a line from Cisco routers with ethereal.  Taking the data from
ethereal, I am trying to make my program "talk" to the router, so I
have no access to the receiving end.

This is sort of a quick and dirty program designed to do one thing
only.  I would definitely keep what you are saying in mind for future
programs, but at the same time, I'm still unsure of how my (packet)
file should look like...
--



Sun, 25 Sep 2005 10:47:22 GMT  
 Reading Hex from File and Putting it in a Packet

Quote:

> ... I'm still unsure of how my (packet) file should look like...

In a case like this, you have to conform to whatever protocol
the router is already using.  I'm sure there must be a spec (RFC).
--



Wed, 28 Sep 2005 06:24:21 GMT  
 Reading Hex from File and Putting it in a Packet
On 07 Apr 2003 23:30:23 GMT in comp.lang.c.moderated, "Douglas A.

Quote:


>> I have a program that hardcodes hex values into a packet that I want
>> to send across the network.  I want to move that hard code out to a
>> file and read it from there.

>The values might be expressed as hexadecimal, but they're
>just ordered collections of bits.  Since you indicate
>network use, presumably the value should be usable with
>hosts having arbitrary CPU architectures, so it is
>essential to specify the packet format in a machine-
>independent way.  While you *could* convert to ASCII
>text characters, traditionally network packets are fixed
>size binary-encoded fields.  But binary representation of
>numeric values varies across architectures.  In
>particular, for multiple-octet values (such as

>>  int origin = 0x00010140;

>) you need to transmit those fout octets in a definite
>order, e.g. "little endian", and reassemble them in the

big-endian a la Sparc see:
http://www.cs.rpi.edu/courses/sysprog/sockets/byteorder.html

Quote:
>same order on the receiving end.  That means that

>>  memmove((char*)updateMsg+23, &origin, 4);

>is a mistake, since that leaves the octet order up to
>the specific CPU architecture.

Thanks. Take care, Brian Inglis         Calgary, Alberta, Canada
--

    fake address                use address above to reply
--



Fri, 30 Sep 2005 12:25:43 GMT  
 Reading Hex from File and Putting it in a Packet
On 05 Apr 2003 07:23:21 GMT in comp.lang.c.moderated,

Quote:

>I'm having a little bit of a problem with this and I was hoping
>someone would help.  I'll try to explain it as best I can.  Right now
>I have a program that hardcodes hex values into a packet that I want
>to send across the network.  I want to move that hard code out to a
>file and read it from there.  Here is some example code:

>What I have:

> // Defining the hex values I want to put in the packet
> int origin = 0x00010140;
> int asPathFlags =0x40;
> int typecodePath = 0x02;

> // copying the values into a character array

  origin = htonl( origin ); // convert to network byte order
  //www.opengroup.org/onlinepubs/007908799/xns/htonl.html

Quote:
> memmove((char*)updateMsg+23, &origin, 4);
> memmove((char*)updateMsg+27, &asPathFlags,1);

  updateMsg[27] = asPathFlags;

Quote:
> memmove((char*)updateMsg+28, &typecodePath,1);

  updateMsg[28] = typecodePath;

Quote:

>What I'm having problems with is the format of the file containing the
>hex values.  What would be the best way to do this?  Should I store
>the values as decimal then do something like cin >> hex >> value?

>0x00010140 0x40 0x02

You can type these values into a text file as is and read them in
to your variables: do so at program startup, not while shipping
bytes!

Quote:
>I want to be able to read from the file into an array and just send
>it.  Can someone help me brainstorm?

Define the bytes in network order, and stuff them in one by one:

23 0x00
24 0x01
25 0x01
26 0x40
27 0x40
28 0x02

or more generic (with a bit more programming: loop on array,
switch on size, convert and move) and use a file format like:

23 4 0x00010140
27 1 0x40
28 1 0x02

Thanks. Take care, Brian Inglis         Calgary, Alberta, Canada
--

    fake address                use address above to reply
--



Fri, 30 Sep 2005 12:25:47 GMT  
 Reading Hex from File and Putting it in a Packet

(indentation eaten by OE, sorry, I'm working on it):
Quote:
> [snip] If you have access to
> an existing package for machine-independent data
> representation, e.g. Sun's XDR, use that; otherwise
> define your own standard.  I suggest for integers:
> twos-complement, use lowest 8 bits per char (which is
> what your network I/O functions probably expect anyway),
> least significant octet of integer value at lowest byte
> address.  [snip]  Replace the memmove with
> le_store_long(&updateMsg[23], 0x00010140L);
> // 4 octets might not fit in plain int!
> where the function might be implemented like this:

Personally I prefer bigendian because it's easier
to read in traces, but either way is valid.

Quote:
> void
> le_store_ulong(unsigned char *buffer, unsigned long value)
> {
> register int i;
> for (i = 0; i < 32; i += 8

missing )

Quote:
> buffer[i] = (unsigned char)
> ((value & (0xFFUL << i)) >> i);

You obviously meant buffer[i/8].  (Or 8U, which
allows optimization to >>3.)  Or else to step i
by 1 and multiply by 8 in the bitshifts.

Why shift the mask left?  Just
  (value >> i /* or by_1_i * 8 */) & 0xFF
is plenty, and a nicer match to the _load case.

It might be better to call these _u32bit or similar,
or at least _netul, since (platform) ulong *might*
be more than 4*8 bits, and if so we don't want to
(apparently) claim this works for that type.
Although we do have the unfortunate precedent
of BSD-sockets using 'l' to mean 'exactly 32'.

Quote:
> }

> The converse function at the receiver would be:

> unsigned long
> le_load_ulong(const unsigned char *buffer)
> {
> register int i;
> register unsigned long value = 0;
> for (i = 0; i < 32; i += 8)
> value |=
> ((unsigned long)buffer[i] & 0xFFUL) << i;

Same issue for i.

If this buffer contains data created by the store
function, as it presumably should, the mask isn't
needed because more than 8 bits weren't stored,
unless the transport has (or may have) messed it up.

Quote:
> return value;
> }

> If you had a signed (long) integer, somewhat more care
> would be needed, but it would suffice to "pun" the integer
> value as type (unsigned long) and use the above functions
> to convert it.

Or, if you assume full-range 2sC, which is pretty safe
nowadays, just use the implicit conversion in a call to
_store and cast the result of _load (back) to slong.

--
- David.Thompson 1 now at worldnet.att.net
--



Sun, 02 Oct 2005 08:24:29 GMT  
 Reading Hex from File and Putting it in a Packet

Quote:


> missing )

Yeah, sorry, it was typed in a hurry.

Quote:
> You obviously meant buffer[i/8].

Ditto.

Quote:
> Why shift the mask left?

A subtle issue not worth debating.

Quote:
> It might be better to call these _u32bit or similar,
> or at least _netul, since (platform) ulong *might*
> be more than 4*8 bits, ...

No, only the lowest 32 bits of whatever a uns. long
might be were used.  That's all a portable program
would rely on anyway.  If you want maximum robustness
you'll have to figure out what sort of error handling
to do when the conversion to 4 octets loses
information.  My recommendation is to throw an
exception, since returning an error flag as function
value doesn't work (programmers are likely to not
bother to check it).  Of course that presupposes that
one has some exception-handling package for C; there
are several of these in existence.

The signed case would be somewhat more difficult due
to the three possible representation schemes (apart
from padding bits), but for ones- and twos-complement
simply ignoring the high-order bits works.  Sign-
magnitude requires more care (and contrary to what
I indicated before, punning to uns. long doesn't work
for that representation).  Few programmers will ever
encounter implementations using sign-magnitude repr.
for integers, but since they do exist one might as
well ensure that one's code will work if it ever
does happen to be ported to such an implementation.
(Who knows, perhaps your code will be used by lots
of other people some day.)

Quote:
> If this buffer contains data created by the store
> function, as it presumably should, the mask isn't
> needed because more than 8 bits weren't stored,
> unless the transport has (or may have) messed it up.

I prefer to leave that up to the optimizer; the
example was meant to illustrate the concept.
I apologize for missing the /8 in the byte index.
--



Mon, 03 Oct 2005 14:52:09 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Reading Intel Hex files

2. Reading a GIF file and putting it into a dialog

3. Newbie on VC++5 : Problem reading files and putting them in CString

4. Reading Disks Directly (Hex Read)

5. Request: HOWTO on reading network packets

6. reading control characters from a IPv4 packet

7. How to read incoming packets of chars

8. putting end of file character in binary file (cutting the file short)

9. Read/Write in hex?

10. reading hex

11. How to read Binary/Hex data from the registry

12. How to read Binary/Hex data from the registry

 

 
Powered by phpBB® Forum Software