1

Let's say I have some structs similar to this:

struct a {
    uint8_t v1[6];
    uint16_t type;
    uint8_t v2[6];
    uint32_t something_long;
};

struct b {
    uint8_t v3;
    uint8_t v4;
};

struct c{
    a a;
    b b;
}

and I fill data like (is this correct?):

int main() {...

    c my_struct;

    my_struct.a.v1[0] = 0x01;
    my_struct.a.v1[1] = 0x02;
    .
    .
    .

    my_struct.a.type = 2048; // <- does this integer convert to "hex"?

Now what I am trying to achieve is get my_struct and be able to make u_char buff from my_struct

u_char buff[sizeOf(c)]; 

someConversionStuffHere(c, buff);
//function returns data like:
    //buff[0] = 0x01; //wanted result
    //buff[1] = 0x02; //wanted result

so I can take buff and use it in 3rd party library that requires u_char as parameter.

I've tried some crazy things like:

looping in while and using sscanf(), I mean I can print out c in hex using:

u_char *string_ptr = (U_char *)&p;
int i = sizeof(c);

while(i--) {
    u_char c = *string_ptr++;
    printf(" %x ", (u_char) c);
}

This prints "correctly" values uint8_t v1[6] and uint8_t v2[6], but when I try to print out 2048 as hex (it should be 0x800) it prints out 0 8 instead (not 08 00 as I would expect).

I would love debug this but C/C++ isn't PHP where I can primitively print out anything without problem.

Kyslik
  • 8,217
  • 5
  • 54
  • 87
  • 1
    You are looking for "endian-conversion" or "endianness". It would appear your system is using "little endian", so the bigger part is later than the smaller part of values that are more than a single byte. – Mats Petersson May 10 '14 at 00:56
  • 1
    2048 does not fit in a `uint8_t`, it needs two bytes. In order to do a re-interpretation of multiple bytes as a single number, you need to know the "sub-structure" of the buffer. – Sergey Kalinichenko May 10 '14 at 00:59
  • Yes I am trying to use pcap_dump(). `Data contained in each section will always be saved according to the characteristics (little endian / big endian) of the dumping machine.` – Kyslik May 10 '14 at 01:03
  • @dasblinkenlight thanks for comment I looked it up in here http://www.nongnu.org/avr-libc/user-manual/group__avr__stdint.html . I did mistake I am trying to add integer value 2040 to different value I made an edit. What about the other part "saving" struct as u_char ? – Kyslik May 10 '14 at 01:21
  • `my_struct.b.type = 2048;` - there is no member `type` in `b`; only `v3` and `v4`. – M.M May 10 '14 at 02:34
  • You could just write `(uchar *)&my_struct`. Whether or not this does what you want, depends on this mystery function you are calling. – M.M May 10 '14 at 02:36
  • @MattMcNabb thank you that was the solution. Yes it was a typo (b.type), and I think I solved my problem but another popped up, because of (in real code) my struct `a` has length (`sizeof(a)`) 14 and 15th and 16th position is padded with "nothing" - 0xcc and that is not good, any suggestions? – Kyslik May 10 '14 at 02:39
  • 1
    You could insert "dummy" members in your struct so that you can refer to this padding directly. Or you could tell your compiler to not use padding, but that is less portable. – M.M May 10 '14 at 02:41
  • "less portable" what exactly that means? If someone else wants to compile he/she might not be able to? – Kyslik May 10 '14 at 02:44

1 Answers1

1

Yes, what @Mats said is correct: this is because of endianness.. You can see an illustration of what's going on "under the covers" on the Wikipedia page: http://en.m.wikipedia.org/wiki/Endian

Flortify
  • 619
  • 5
  • 15