github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/ebpf/byteorder.go (about)

     1  package ebpf
     2  
     3  import (
     4  	"encoding/binary"
     5  	"unsafe"
     6  )
     7  
     8  // multi-byte constants in eBPF programs must always be in network order. Since constants in golang are represented in
     9  // the byte order of the host this may cause issues. The functions in this file automatically detect the endianness
    10  // of the host at runtime and converts them to or from network byte order.
    11  
    12  var nativeEndian binary.ByteOrder
    13  
    14  func getNativeEndianness() binary.ByteOrder {
    15  	if nativeEndian != nil {
    16  		return nativeEndian
    17  	}
    18  
    19  	buf := [2]byte{}
    20  	*(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xABCD)
    21  
    22  	switch buf {
    23  	case [2]byte{0xCD, 0xAB}:
    24  		nativeEndian = binary.LittleEndian
    25  	case [2]byte{0xAB, 0xCD}:
    26  		nativeEndian = binary.BigEndian
    27  	default:
    28  		panic("Could not determine native endianness.")
    29  	}
    30  
    31  	return nativeEndian
    32  }
    33  
    34  // HtonU16 converts a uint16 from host-to-network byte order.
    35  func HtonU16(i uint16) uint16 {
    36  	b := make([]byte, 2)
    37  	getNativeEndianness().PutUint16(b, i)
    38  	return binary.BigEndian.Uint16(b)
    39  }
    40  
    41  // Hton16 converts a int16 from host-to-network byte order.
    42  func Hton16(u int16) int16 {
    43  	return int16(HtonU16(uint16(u)))
    44  }
    45  
    46  // HtonU32 converts a uint32 from host-to-network byte order.
    47  func HtonU32(i uint32) uint32 {
    48  	b := make([]byte, 4)
    49  	getNativeEndianness().PutUint32(b, i)
    50  	return binary.BigEndian.Uint32(b)
    51  }
    52  
    53  // Hton32 converts a int32 from host-to-network byte order.
    54  func Hton32(u int32) int32 {
    55  	return int32(HtonU32(uint32(u)))
    56  }
    57  
    58  // HtonU64 converts a uint64 from host-to-network byte order.
    59  func HtonU64(i uint64) uint64 {
    60  	b := make([]byte, 8)
    61  	getNativeEndianness().PutUint64(b, i)
    62  	return binary.BigEndian.Uint64(b)
    63  }
    64  
    65  // Hton64 converts a int64 from host-to-network byte order.
    66  func Hton64(u int64) int64 {
    67  	return int64(HtonU64(uint64(u)))
    68  }
    69  
    70  // NtohU16 converts a uint16 from network-to-host byte order.
    71  func NtohU16(i uint16) uint16 {
    72  	b := make([]byte, 2)
    73  	binary.BigEndian.PutUint16(b, i)
    74  	return getNativeEndianness().Uint16(b)
    75  }
    76  
    77  // Ntoh16 converts a int16 from host-to-network byte order.
    78  func Ntoh16(u int16) int16 {
    79  	return int16(NtohU16(uint16(u)))
    80  }
    81  
    82  // NtohU32 converts a uint32 from network-to-host byte order.
    83  func NtohU32(i uint32) uint32 {
    84  	b := make([]byte, 4)
    85  	binary.BigEndian.PutUint32(b, i)
    86  	return getNativeEndianness().Uint32(b)
    87  }
    88  
    89  // Ntoh32 converts a int32 from host-to-network byte order.
    90  func Ntoh32(u int32) int32 {
    91  	return int32(NtohU32(uint32(u)))
    92  }
    93  
    94  // NtohU64 converts a uint64 from network-to-host byte order.
    95  func NtohU64(i uint64) uint64 {
    96  	b := make([]byte, 8)
    97  	binary.BigEndian.PutUint64(b, i)
    98  	return getNativeEndianness().Uint64(b)
    99  }
   100  
   101  // Ntoh64 converts a int64 from host-to-network byte order.
   102  func Ntoh64(u int64) int64 {
   103  	return int64(NtohU64(uint64(u)))
   104  }