cgdbprintfbufferrecvfrom

Unexpected behavior parsing recvfrom() message from UDP socket


Currently working with UDP socket, I am stucked trying to understand the following situation.

A reception buffer has been defined as follow:

char buf[1024];
...
memset(&buf, 0, sizeof(buf));

& is fullfilled by invoking recvfrom()

size = recvfrom(sockdf, buf, sizeof(buf), MSG_WAITALL, (struct sockaddr *) &rx, (socklen_t *)&len);

I am getting these data from remote, confirmed using Wireshark:

01 fe 00 04 00 00 00 21 53 53 53 5f 54 54 54 54 5f 30 31 32 33 34 35 36 37 10 fe 00 10 02 ac ca fe 00 00 00 00 00 00 00 00

Using a simple for loop to identify buffer content, I get :

for (i = 0; i < size; i++)
{
    printf("buf[%d] = 0x%x", i, buf[i]);
}

buf[0] = 0x1
buf[1] = 0xfffffffe
buf[2] = 0x0
buf[3] = 0x4
buf[4] = 0x0
buf[5] = 0x0
buf[6] = 0x0
buf[7] = 0x21
buf[8] = 0x53
buf[9] = 0x53
buf[10] = 0x53
buf[11] = 0x5f
buf[12] = 0x54
buf[13] = 0x54
buf[14] = 0x54
buf[15] = 0x54
buf[16] = 0x5f
buf[17] = 0x30
buf[18] = 0x31
buf[19] = 0x32
buf[20] = 0x33
buf[21] = 0x34
buf[22] = 0x35
buf[23] = 0x36
buf[24] = 0x37
buf[25] = 0x10
buf[26] = 0xfffffffe
buf[27] = 0x0
buf[28] = 0x10
buf[29] = 0x2
buf[30] = 0xffffffac
buf[31] = 0xffffffca
buf[32] = 0xfffffffe
buf[33] = 0x0
buf[34] = 0x0
buf[35] = 0x0
buf[36] = 0x0
buf[37] = 0x0
buf[38] = 0x0
buf[39] = 0x0
buf[40] = 0x0

I certainly misunderstood something trying to get/parse received message, but I cannot explain why printing buf[1], buf[26], buf[30], buf[31] and buf[32] return extra FF ?

Same behavior using gdb

(gdb) p/x buf[26]
$3 = 0xfe
(gdb) call printf("0x%x\n", buf[26])        
0xfffffffe
$4 = 11

Any tips would be appreciated.


Solution

  • It's called sign extension and happens when signed values smaller than int are promoted (for example when used as argument to e.g. printf).

    One simply way of avoiding that is to use unsigned char (or uint8_t) instead of char for the array:

    uint8_t buf[1024];
    

    Or by using the hh prefix in the printf format:

    printf("buf[%d] = 0x%hhx", i, buf[i]);