Network Byte Order nach Host Byte Order

Gute Tag,
ich versuche auf einem AVR(Little Endian) DHCP zu implementieren, soweit klappt auch alles, ausser, dass ich es nicht schaffe die Lease Time die ich vom Server bekommen, von der Network Byte Order zur Host Byte Order zu konvertieren.

Die Lease Time ist ein unsigned 32-Bit Wert, vom Server bekomme ich die Lease time in 4-Bytes opt_ptr[0-3], diese sollen nun in einer 32-Bit Variable in Little Endian gespeichert werden.

Das wäre wahrscheinlich die Methode wenn die Lease Time bereits in der Host Byte Order vorliegen würde.
Code:
state.lease_time = (opt_ptr[0]) | (opt_ptr[1] << 8) | (opt_ptr[2] << 16) | (opt_ptr[3] << 24);

Vielen Dank im Voraus.
 
Sind htonl / ntohl für die Plattform verfügbar?
Byte Order - The GNU C Library ?
Ansonsten:
Code:
(opt_ptr[0]) | (opt_ptr[1] << 8) | (opt_ptr[2] << 16) | (opt_ptr[3] << 24);
macht für einzelne Bytes keinen Sinn. Es soll ja nur die Bytereihenfolge
geändert werden, keineswegs die Bits selbst (außerdem: 8 Bit Zahl um 8 oder mehr Stellen nach links shiften - da kommt 0 heraus ;) )
Also ganz einfach: wie vertauscht man eigentlich 4 Werte in einem Array?


"Klassisch" könnte man das swapping so machen:
Code:
* Swap bytes in 32 bit value.  */
#define __bswap_constant_32(x) \
     ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >>  8) |          \
      (((x) & 0x0000ff00u) <<  8) | (((x) & 0x000000ffu) << 24))
(code aus "Byteswap.h"/glibc)
Allerdings sollte man den Wert "opt_ptr" dann als 32-Bit Value ansehen und nicht als vier 8-bit Werte.

Empfehlen würde ich aber trotzdem die entsprechenden Funktionen zu verwenden (htons/ntohl), da hier die Libs z.B das Swapping "intern" über Inline-Assemly erledigen können (was auf vielen Plattformen nur eine einzelne Anweisung braucht - und nicht ~30, wie bei dem "naiven" C-Swapping mit dem Rumgeshifte ;) )
 
Danke,
also die avr-libc hat kein htonl/ntohl, aber ich hab mir jetzt aus deinem bzw. aus dem glibc Makro folgende Funktion gebaut:

Code:
uint32_t ntohl(uint32_t x)
{
         return ((x & 0xFF000000UL) >> 24) | ((x & 0x00FF0000UL) >>  8) | ((x & 0x0000FF00UL) <<  8) | ((x & 0x000000FFUL) << 24);
}

Sowie ich das jetzt getestet habe funktioniert das auch.
 
Viele Compiler bieten dafür auch intrinische Funktionen an.

MSVC: _byteswap_ulong()
GCC: __builtin_bswap32()
 
Zurück
Oben