Question

I am working on a code that requires me to parse an incoming frame which i receive in form of uint8_t * pointer.

I have written a utility method to fetch mac address from the frame and convert it into uint64_t value for easy calculations.

uint64_t addr = uint64_t(_frm_ptr[0]) << 40 | uint64_t(_frm_ptr[1]) << 32 | 
                       uint64_t(_frm_ptr[2]) << 24 | uint64_t(_frm_ptr[3]) << 16 | 
                       uint64_t(_frm_ptr[4]) << 8 | uint64_t(_frm_ptr[5]);

I need to know that if the source mac address was say "b8:ac:6f:c0:3d:25" on a big endian format, will it be transmitted in the same order ?

How is mac address transmitted on a network ?

Will the above code snippet work on all platforms ?

Was it helpful?

Solution

The bytes in a frame are in a fixed order (big-endian as @Caleb points out), independent of endianness of the host computer.

Since you're copying the bytes one-by-one this will always work. There's only a problem when you would use multi-byte assignments or memcpy's from the frame data into short, int, .... Have a look at ntohs() and friends that convert network-to-host and vice versa.

OTHER TIPS

Network byte order is big-endian, so if you have the address in big-endian format, it'll be transmitted and received that way -- no byte-swapping required.

The standard notation, also called canonical format, for MAC addresses is written in transmission bit order with the least significant bit transmitted first.

IEEE 802.3 (Ethernet) and IEEE 802.4 (Token Bus) send the bytes (octets) over the wire, left-to-right, with least significant bit in each byte first, while IEEE 802.5 (Token Ring) and IEEE 802.6 send the bytes over the wire with the most significant bit first

An address in canonical form 12-34-56-78-9A-BC would be transmitted over the wire as bits 10000100 00101100 01101010 00011110 01011001 00111101 in the standard transmission order (least significant bit first).

But for Token Ring networks, it would be transmitted as bits 00010010 00110100 01010110 01111000 10011010 10111100 in most-significant-bit first order. The latter might be incorrectly displayed as 48-2C-6A-1E-59-3D. This is referred to as bit-reversed order, non-canonical form, MSB format, IBM format, or Token Ring format. Canonical form is generally preferred, and used by all modern implementations.

Like mac address, there is 64bit number used in many other cases like, openflow/sdn. which prefers it to be just 64bit number, Try the following,

union {
   char charId[8];
   uint64_t numId;
} dpId;
char *save_ptr=0;
uint8_t i = 0;
char* dpid_str = "C0:0C:C1:1C:C2:2C:01:00";
char* token = strtok_r(dpid_str, ":", &save_ptr);
while(token != NULL && i < 8){
    dpId.charId[i++] = std::stoi(token,0,16);
    token = strtok_r(NULL,":",&save_ptr);
}
dpId.numId = ntohll(dpId.numId);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top