Reputation: 1284
I am trying to write my C socket code in Assembly (just kinda bored and thought it'd be an interesting exercise) and in the process of trying to make the sockaddr_in
struct I wrote this little program:
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
void showbytes(char *c, size_t len) {
size_t i;
for (i = 0; i < len; i++)
printf("byte #%lu -> %x\n", i, c[i]);
}
int main(int argc, char* argv[]) {
struct sockaddr_in q;
bzero(&q, sizeof(q));
q.sin_family = 0x02;
q.sin_port = htons(0x1f90);
q.sin_addr.s_addr = htonl(INADDR_ANY);
union {
struct sockaddr_in sai;
char c[sizeof(struct sockaddr_in)];
} un;
un.sai = q;
showbytes(un.c, sizeof(struct sockaddr_in));
return 0;
}
What I don't understand at all is that the output looks like this:
byte #0 -> 2
byte #1 -> 0
byte #2 -> 1f
byte #3 -> ffffff90
byte #4 -> 0
byte #5 -> 0
byte #6 -> 0
byte #7 -> 0
byte #8 -> 0
byte #9 -> 0
byte #10 -> 0
byte #11 -> 0
byte #12 -> 0
byte #13 -> 0
byte #14 -> 0
byte #15 -> 0
Why is byte #3 showing as 4 bytes? I checked sizeof(in_port_t)
and it is definitely 2 bytes, but that isn't even the issue. A char
should only ever be 1 byte.. I assume I am missing something pretty big here.
Upvotes: 2
Views: 73
Reputation: 72639
You are missing that char
is signed on your implementation and a negative value, interpreted as an unsigned int (for %x
), is a large value. You may also be missing that you can't pass a one byte value to a variadic function like printf--integral values are always promoted to at least int
or unsigned int
.
If you compile with gcc or clang, use -funsigned-char
to make the char
type unsigned. Then this problem does not occur.
Upvotes: 4