Keval Malde
Keval Malde

Reputation: 53

Converting a structure from Little endian to Big endian

My problem is to convert a pointer to structure from little endian to big endian so that I can send it to network, since my structure is of 12 bytes or 92 bits I cannot apply any standard or non standard function given.

I am trying to Implement GTPv1U on my linux system, since my structure pointer is of 96 bits I tried to break it in three chunk of 32 bits each and then do conversion but I am unable to break it and I also doubt that this is not correct way to do it

Code of my structure

typedef struct  __attribute__((__packed__)) GTPv1Uheader{
    UInt8  version              :3;
    UInt8  ProtocolTypeFlag     :1;
    UInt8  Spare                :1;
    UInt8  ExtensionFlag        :1;
    UInt8  SequenceNumberFLAG   :1;
    UInt8  NpduNumberFlag       :1;
    UInt8  MessageType;
    UInt16 Length;
    UInt32 TEID;                    
    UInt16 SequenceNumber;
    UInt8  NPDUNumber;
    UInt8  NextExtensionheader;
} GTPv1UheaderT;

Assignment of values

GTPv1UheaderT * IntializeGTP(){
    GTPv1UheaderT *GTPv1UheaderP;
    GTPv1UheaderP = malloc(sizeof(GTPv1UheaderT));
    memset(GTPv1UheaderP, 0, (sizeof(GTPv1UheaderT)));
    GTPv1UheaderP->version              = 0x1;
    GTPv1UheaderP->ProtocolTypeFlag     = 0x1;
    GTPv1UheaderP->Spare                = 0x0;
    GTPv1UheaderP->ExtensionFlag        = 0x0;
    GTPv1UheaderP->SequenceNumberFLAG   = 0x1;
    GTPv1UheaderP->NpduNumberFlag       = 0x0;
    GTPv1UheaderP->MessageType          = 0x01;
    GTPv1UheaderP->Length               = 0x000C;
    GTPv1UheaderP->TEID                 = 0x00000001;
    GTPv1UheaderP->SequenceNumber       = 0x0000;
    GTPv1UheaderP->NPDUNumber           = 0x00;
    GTPv1UheaderP->NextExtensionheader  = 0x00;
    return GTPv1UheaderP;
}

Expected output: 32 01 00 0C 00 00 00 01 00 00 00 00

Actual output: 49 01 0C 00 01 00 00 00 00 00 00 00

EDIT: This was the swap function

long s; 
unsigned char k;
k=(unsigned char)GTPv1UheaderP;
s=(unsigned int)k;
s=ntohl(s);
printf("%ld\n",s);

I know that this wont work because my long is 32 bits where as pointer is of 96 bits. Any other solution

Upvotes: 2

Views: 1218

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

Converting a whole struct from/to little or big endian does not make sense, because endianness is a property of a multi-byte scalar type representation, e.g. a single UInt16 or UInt32. When converting a struct to its "on-the-wire representation" you go through it one element at a time, and prepare its representation element-by-element.

Bit fields represent a special case, because their ordering is implementation-defined. You need to serialize them into a single byte in the order that you prefer. Use hton/ntoh functions to do the conversion of the individual multi-byte elements, i.e. Length and TEID.

Upvotes: 3

Related Questions