DSM-G600, DNS-3xx and NSA-220 Hack Forum

Unfortunately no one can be told what fun_plug is - you have to see it for yourself.

You are not logged in.

Announcement

#1 2008-10-27 14:46:30

boilerjt
Member
From: Minnesota, USA
Registered: 2008-09-15
Posts: 122

Question for fonz RE: Byte Order

I am wondering if you've seen what I have.  I've seen instances in two different applications when converting to host byte order isn't working, even though it compiles with no errors.  Both times involved 32 and 64 bit "words" and I had to hack the application's source code to force the byte order.  The last instance involved calling ntohl() and it didn't get the byte order correct.  I am wondering if this is common to Marvell Orion hardware, specific to the DNS-323, or the ffp 0.5 toolchain may have a bug.

Thanks smile

Last edited by boilerjt (2008-10-27 14:47:39)

Offline

 

#2 2008-10-27 15:12:47

fonz
Member / Developer
From: Berlin
Registered: 2007-02-06
Posts: 1716
Website

Re: Question for fonz RE: Byte Order

ntohs, ntohl, htons, htonl work fine here. Note that short means 16 bits, and long 32 bits.

Offline

 

#3 2008-10-27 16:07:33

boilerjt
Member
From: Minnesota, USA
Registered: 2008-09-15
Posts: 122

Re: Question for fonz RE: Byte Order

fonz wrote:

ntohs, ntohl, htons, htonl work fine here. Note that short means 16 bits, and long 32 bits.

Thanks for the information.  To be more specific here is what I saw in libmp4v2:

Here is the original function that did not work:

inline u_int32_t STRTOINT32(const char* s) {
  return ntohl(*(uint32_t *)s);
}

You would expect something returned like 0x66726565 returned (ascii "free") and you'd actually get 0x66000000.  It looks to me like the 4 bytes were read starting from the pointer address reading in the negative direction instead of the positive direction.

I changed the function to this and it works correctly:

inline u_int32_t STRTOINT32(const char* s) {

     u_int32_t D0 = s[0] << 24;
     u_int32_t D1 = s[1] << 16;
     u_int32_t D2 = s[2] << 8;
     u_int32_t D3 = s[3];
     u_int32_t s2 = D0 + D1 + D2 + D3;
     return s2;
}

I am a beginner with linux programming (I am a Windows developer in my real life).  Any insight?  I'm just trying to understand this.

Offline

 

#4 2008-10-27 16:22:53

fonz
Member / Developer
From: Berlin
Registered: 2007-02-06
Posts: 1716
Website

Re: Question for fonz RE: Byte Order

boilerjt wrote:

You would expect something returned like 0x66726565 returned (ascii "free")

Code:

root@bob:/tmp# cat test2.c 
#include <stdio.h>
#include <stdint.h>

inline uint32_t STRTOINT32(const char* s) {
  return ntohl(*(uint32_t *)s);
}

int main(int argc, char **argv)
{
        char *str = "free";
        
        printf("str %s\n", str);
        printf("f(str) %lx\n", STRTOINT32(str));

        return 0;
}

root@bob:/tmp# make test2
cc     test2.c   -o test2
root@bob:/tmp# ./test2 
str free
f(str) 66726565

Seems to work!?

Offline

 

#5 2008-10-27 16:36:42

fonz
Member / Developer
From: Berlin
Registered: 2007-02-06
Posts: 1716
Website

Re: Question for fonz RE: Byte Order

boilerjt wrote:

You would expect something returned like 0x66726565 returned (ascii "free") and you'd actually get 0x66000000.  It looks to me like the 4 bytes were read starting from the pointer address reading in the negative direction instead of the positive direction.

Found it. It's a bug in your program. You cannot use ntohl on unaligned addresses (i.e. address  of the string must be a multiple of 4). Your replacement function works on unaligned values, too. Add -Wcast-align to the CFLAGS to see it:

Code:

root@bob:/tmp# cat test2.c
#include <stdio.h>
#include <stdint.h>

inline uint32_t STRTOINT32(const char* s) {
  return ntohl(*(uint32_t *)s);
}

int main(int argc, char **argv)
{
        char *str = "free";
        char *str2 = "0free";
                
        printf("str %s\n", str);
        printf("f(str) %lx\n", STRTOINT32(str));
        printf("f(str2+1) %lx\n", STRTOINT32(str2+1));

        return 0;
}



root@bob:/tmp# gcc -o test2 -Wcast-align test2.c
test2.c: In function 'STRTOINT32':
test2.c:5: warning: cast increases required alignment of target type


root@bob:/tmp# ./test2
str free
f(str) 66726565
f(str2+1) 66726530

Offline

 

#6 2008-10-27 17:11:22

boilerjt
Member
From: Minnesota, USA
Registered: 2008-09-15
Posts: 122

Re: Question for fonz RE: Byte Order

Thanks a lot for this info smile  What is weird is that this lib works when compiled on my Ubuntu VM (i386).  Does i386 automatically align the address? Actually, I am happy to see it was a bug in the program and not a quirk with the DNS-323.  Too bad the mpeg4ip project is dead right now and there is no one to officially fix it...

fonz wrote:

boilerjt wrote:

You would expect something returned like 0x66726565 returned (ascii "free") and you'd actually get 0x66000000.  It looks to me like the 4 bytes were read starting from the pointer address reading in the negative direction instead of the positive direction.

Found it. It's a bug in your program. You cannot use ntohl on unaligned addresses (i.e. address  of the string must be a multiple of 4). Your replacement function works on unaligned values, too. Add -Wcast-align to the CFLAGS to see it:

Offline

 

#7 2008-10-27 17:37:07

fonz
Member / Developer
From: Berlin
Registered: 2007-02-06
Posts: 1716
Website

Re: Question for fonz RE: Byte Order

boilerjt wrote:

Does i386 automatically align the address?

The question is a different one: On ARM (and a number of other architectures), you can read 4-byte values only from addresses that are multiples of 4. Afaict, there's no such restriction on x86.

Offline

 

#8 2008-10-27 17:50:29

boilerjt
Member
From: Minnesota, USA
Registered: 2008-09-15
Posts: 122

Re: Question for fonz RE: Byte Order

fonz wrote:

boilerjt wrote:

Does i386 automatically align the address?

The question is a different one: On ARM (and a number of other architectures), you can read 4-byte values only from addresses that are multiples of 4. Afaict, there's no such restriction on x86.

Now I understand smile  Thank you for all of the help.  Since I've run across this twice in two different programs, it sounds like it might be something that happens occasionally when porting code written primarily for x86 to ARM.

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2010 PunBB