Another eval question: evaluating array byte order

1 view (last 30 days)
My profuse apologies. I am trying to rid some code of all evals, but cannot find a more graceful approach for this one. (It's probably right under my nose, but I've had 5 hours of sleep in the past 3 days...)
This code reads an IPv4 data file, and saves it's data as an array called "datastream". Now, the data in this array could be Intel byte order or not (little or big endian). The first 4 bytes of the IPv4 header can be checked to figure out the byte-order.
Now, once the byte-order is determined, the rest of the file can be analyzed. Each message in the file is located within certain bytes, e.g. bytes 21:24 of the IPv4 header is the "linktype". However, if the file is big-endian, the bytes are read 21-22-23-24, and if the file is little-endian, the bytes are read 24-23-22-21. So the code I have is this:
%%set byte order:
if file_endian == 0
byte_field = '(bytes(1):bytes(end))';
else
byte_field = '(bytes(end):-1:bytes(1))';
end
%%define bytes and read data in correct order:
bytes = 21:24;
linktype = hex2dec(reshape(flipud(rot90(dec2hex(datastream(eval(byte_field)),2))),1,[]));
Is there a more elegant way of doing datastream(eval(byte_field)) to get datastream(21:24) or datastream(24:-1:21) depending on the endianness? (and without doing an "if" statement for each message - there are hundreds of these messages)

Accepted Answer

Stephen23
Stephen23 on 5 Jan 2016
Edited: Stephen23 on 6 Jan 2016
One easy way would be to define an anonymous function, depending on the byte order:
if file_endian == 0
tmp_fun = @(x)x; % no flip
else
tmp_fun = @fliplr; % flip
end
%
tmp_fun(bytes) % Call function, no eval needed.

More Answers (2)

Steven Lord
Steven Lord on 5 Jan 2016
FLIP (or FLIPLR) it.
You may also find TYPECAST and SWAPBYTES useful.
  3 Comments
Steven Lord
Steven Lord on 5 Jan 2016
if someCondition
doFlip = @fliplr;
else
doFlip = @(x) x; % essentially a no-op
end
y = doFlip(1:24);
Or even easier, if you know you're always going to operate on 1:24:
if someCondition
y = 24:-1:1;
else
y = 1:24;
end
Stephen23
Stephen23 on 5 Jan 2016
That is exactly the answer I proposed earlier.

Sign in to comment.


Walter Roberson
Walter Roberson on 5 Jan 2016
The endianness of binary data in the payload is never determinable from the IPv4 header. The byte order of the IPv4 header is fixed.
It is possible that the entire buffer got byte swapped somehow, but if that happens then instead of byte swapping every value extracted from the payload, you should be byte swapping the packet buffer and the proceeding normally.
Whatever protocol you are speaking on top of IPv4 might have an indication of whether the data following is in Network Byte Order or not, but that is not part of the IPv4 header.
You refer to "linktype". That is not part of IPv4. "linktype" is an OSI concept that talks about Link Layer Control (LLC). You can encapsulate LLC within ethernet packets and LLC is supported in some other kinds of media, and IPv4 can be encapsulated within LLC using SAP/SNAP frames (but usually is not), but that would place the linktype outside of the IPv4. If you are considering looking at linktype then you are probably looking at a wireshark or pcap log and trying to pull payloads out of the packet trace :(
  2 Comments
Art
Art on 5 Jan 2016
You are correct Walter, I misspoke. I am in fact reading a Wireshark capture, which contains the info necessary to determine byte order. (no, I'm not doing anything sleazy :-) I'm trying to validate a program's functionality and data output implementations)
However the point of the question is really if there is a better alternative to using the eval statement in the present code to read the data in the correct order.
Walter Roberson
Walter Roberson on 6 Jan 2016
Again, at what level is the byte order potentially not Network Byte Order? Wireshark capture files are going to be in received byte order unless someone accidentally swapped the entire file. The byte order of headers is fixed. Only the protocol spoken at the application level above TCP might have different orders. If it does then the technique Stephen shows can be used -- though for taking care of buffers larger than one word you should be using swapbytes instead of fliplr()

Sign in to comment.

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!