UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » General
  • » Migration C program from Digital Unix to Solaris

#1 2002-08-29 04:09 AM

kkyim
Member
Registered: 2002-08-29
Posts: 2

Re: Migration C program from Digital Unix to Solaris

I've written a C program under Digital Unix environment and it works fine. But now I have to migrate the program to Solaris 8. The problem is: I have to send some socket to a server (Win2000) and the socket includes some binary data. As you know, the binary data is created as Little Endian in Digital Unix but Solaris gives me Big Endian. Similarly, Win2000 also uses Little Endian to read binary data. Now, when I send the socket from the Solaris machine to the server (Win2000), the server cannot interpret my data!

Any idea???

Thanks  :P

Offline

#2 2002-08-29 04:45 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: Migration C program from Digital Unix to Solaris

First, just to get a pet peeve out of the way: it's not the OS that's
enforcing a particular endianness, but rather the hardware platform...
Note that OS's which run on multiple hardware platforms may run
into the same problem...  Ie: if you ran Linux on x86 and tried to
send raw ints to Linux on Sparc, you'd have the same problem...
Not a big deal, just something I see a lot which annoys me... ;-)

Now, of course, the solution is to never send raw data in host byte
order through a socket...  You should always convert it to network
byte order, first...  Then, the receiver should convert it back to its
local host byte order...  That's what the htons(), htonl(), ntohs(),
ntohl() functions are for...

Offline

#3 2002-08-30 02:32 AM

kkyim
Member
Registered: 2002-08-29
Posts: 2

Re: Migration C program from Digital Unix to Solaris

Thank you for your reply!
Actually, the server program on Win2000 is developed by a third party company and thus we cannot request to make a great change!

Therefore, I think what we can do is to make changes to our program!  Can I use any function in C in order to convert the order for me before I send the socket to the server?

Thanks  :P

Offline

#4 2002-08-30 01:40 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: Migration C program from Digital Unix to Solaris

Offline

#5 2002-09-01 09:44 AM

mlampkin
Administrator
From: Sol 3
Registered: 2002-06-12
Posts: 911
Website

Re: Migration C program from Digital Unix to Solaris

Sheez...

Its been days since this was posted... and about 4 months ago I helped some folks at UA(Z?) with the same sorta problem... Windows software (oops, sorry but I programmers only know Windows cut and paste programming and we won't change the code we sent you) and talking to it from some Unix boxes...  why didn't you folks answer them?!   >:-|

Anyway...   as already noted... it probably just a byte swap... unless you are dealing with FP variables...  basic stuff (similar to the bswap macros on many systems) is:

//##Documentation
		//## 
		//## Swaps the order of bytes in val_16 and returns
		//## the resulting value.

               unsigned_16 BYTE_SWAP_CONSTANT
		(
			unsigned_16 val_16
		)
		{
			return
					(
						(unsigned_16) ((unsigned_16)(val_16) << 0x08) | 
     						(unsigned_16) ((unsigned_16)(val_16) >> 0x08) 
					);
		}




		//##Documentation
		//## 
		//## Swaps the order of bytes in val_32 and returns
		//## the resulting value.

		unsigned_32 BYTE_SWAP_CONSTANT
		(
			unsigned_32 val_32
		)
		{
			return
					(
                				(unsigned_32) (((unsigned_32)(val_32)) << 0x18) |
                				(unsigned_32) (((unsigned_32)(val_32)) >> 0x18) | 
                				(unsigned_32) (((unsigned_32)(val_32) << 0x08) & 0x00ff0000UL) | 
                				(unsigned_32) (((unsigned_32)(val_32) & 0x00ff0000UL) >> 0x08)  
					);
		}






		//##Documentation
		//## 
		//## Swaps the order of bytes in val_64 and returns
		//## the resulting value.

		  unsigned_64 BYTE_SWAP_CONSTANT
		(
			unsigned_64 val_64
		)
		{
			return
					(
                				(unsigned_64) (((unsigned_64)(val_64) >> 0x38)) |
                				(unsigned_64) (((unsigned_64)(val_64) << 0x38)) | 

                				(unsigned_64) (((unsigned_64)(val_64) >> 0x28) & (unsigned_64) 0x000000000000ff00ULL) |
                				(unsigned_64) (((unsigned_64)(val_64) & (unsigned_64) 0x000000000000ff00ULL) << 0x28) | 

                				(unsigned_64) (((unsigned_64)(val_64) >> 0x18) & (unsigned_64) 0x0000000000ff0000ULL) |
                				(unsigned_64) (((unsigned_64)(val_64) & (unsigned_64) 0x0000000000ff0000ULL) << 0x18) | 

                				(unsigned_64) (((unsigned_64)(val_64) >> 0x08) & (unsigned_64) 0x00000000ff000000ULL) |
                				(unsigned_64) (((unsigned_64)(val_64) & (unsigned_64) 0x00000000ff000000ULL) << 0x08)  
					);
		}

Ok, so that looks a bit funny... but its a fragment from my personal library... and it uses another one... which follows:


#define	LITTLE_ENDIAN	0
#define BIG_ENDIAN		1


#define IEEE_FP_FALSE	0
#define IEEE_FP_TRUE	1




/*
 * CPU and compiler specific defines.
 *
 * ENDIAN_STYLE         	- 0 if little-endian, 1 if big-endian
 * HAVE_IEEE_FP         	- 0 if not IEEE fp, 1 if uses IEEE floating point representation
 *
 * SIZEOF_CHAR          	- size of a char in bytes (should ALWAYS be 1)
 * SIZEOF_SHORT         	- size of a short in bytes
 * SIZEOF_INT           	- size of an int in bytes
 * SIZEOF_LONG          	- size of a long int in bytes
 * SIZEOF_LONG_LONG			- size of a long long int in bytes
 * SIZEOF_FLOAT         	- size of a float in bytes
 * SIZEOF_DOUBLE        	- size of a double in bytes
 * SIZEOF_VOID_P        	- size of a generic void * pointer in bytes
 *
 * ALIGNMENT_CHAR       	- alignment required for a char in bytes (should ALWAYS be 1)
 * ALIGNMENT_SHORT      	- alignment required for a short in bytes
 * ALIGNMENT_INT        	- alignment required for an int in bytes
 * ALIGNMENT_LONG       	- alignment required for a long in bytes
 * ALIGNMENT_LONG_LONG     	- alignment required for a long long in bytes
 * ALIGNMENT_FLOAT      	- alignment required for a float in bytes
 * ALIGNMENT_DOUBLE     	- alignment required for a double in bytes
 * ALIGNMENT_LONG_DOUBLE	- alignment required for a long double in bytes
 *
 * ALIGNMENT_INT_BITS_8		- alignment required for our 8 bit integral types
 * ALIGNMENT_INT_BITS_16	- alignment required for our 16 bit integral types
 * ALIGNMENT_INT_BITS_32	- alignment required for our 32 bit integral types
 * ALIGNMENT_INT_BITS_64	- alignment required for our 64 bit integral types
 *
 */




#define ENDIAN_STYLE                    LITTLE_ENDIAN
#define HAVE_IEEE_FP                    IEEE_FP_TRUE

#define SIZEOF_CHAR                                             1
#define SIZEOF_SHORT                    2
#define SIZEOF_INT                      4
#define SIZEOF_LONG                     4
#define SIZEOF_LONG_LONG                8
#define SIZEOF_FLOAT                    4
#define SIZEOF_DOUBLE                   8
#define SIZEOF_LONG_DOUBLE              12
#define SIZEOF_VOID_P                   4
#define ALIGNMENT_CHAR                                  1
#define ALIGNMENT_SHORT                 2
#define ALIGNMENT_INT                   4
#define ALIGNMENT_LONG                  4
#define ALIGNMENT_LONG_LONG                             8
#define ALIGNMENT_FLOAT                 4
#define ALIGNMENT_DOUBLE                4
#define ALIGNMENT_LONG_DOUBLE           4




#if defined(i386) || defined(i486) || defined(i586) || defined(ix86)

/*
	Note that x86 is capable of dealing with unaligned data and
	the defines here dealing with alignment are present to attempt
	a speed increase in processing.
*/

#define ENDIAN_STYLE	                LITTLE_ENDIAN
#define HAVE_IEEE_FP                    IEEE_FP_TRUE

#define SIZEOF_CHAR						1
#define SIZEOF_SHORT                    2
#define SIZEOF_INT                      4
#define SIZEOF_LONG                     4
#define SIZEOF_LONG_LONG                8
#define SIZEOF_FLOAT                    4
#define SIZEOF_DOUBLE                   8
#define SIZEOF_LONG_DOUBLE              12
#define SIZEOF_VOID_P                   4
#define ALIGNMENT_CHAR					1
#define ALIGNMENT_SHORT                 2
#define ALIGNMENT_INT                   4
#define ALIGNMENT_LONG                  4
#define ALIGNMENT_LONG_LONG				8
#define ALIGNMENT_FLOAT                 4
#define ALIGNMENT_DOUBLE                4
#define ALIGNMENT_LONG_DOUBLE           4


#elif defined(mips32)


#define ENDIAN_STYLE	                BIG_ENDIAN
#define HAVE_IEEE_FP                    IEEE_FP_TRUE

#define SIZEOF_CHAR						1
#define SIZEOF_SHORT                    2
#define SIZEOF_INT                      4
#define SIZEOF_LONG                     4
#define SIZEOF_LONG_LONG                8
#define SIZEOF_FLOAT                    4
#define SIZEOF_DOUBLE                   8
#define SIZEOF_LONG_DOUBLE              12
#define SIZEOF_VOID_P                   4
#define ALIGNMENT_CHAR					1
#define ALIGNMENT_SHORT                 2
#define ALIGNMENT_INT                   4
#define ALIGNMENT_LONG                  4
#define ALIGNMENT_LONG_LONG				8
#define ALIGNMENT_FLOAT                 4
#define ALIGNMENT_DOUBLE                4
#define ALIGNMENT_LONG_DOUBLE           4

#endif







/* 
	Define our basic 8 bit types.  Until we find otherwise
	assume all platforms use standard 8 bit chars.
*/

#if SIZEOF_CHAR == 1

typedef char signed_8;
typedef unsigned char unsigned_8;

#define ALIGNMENT_INT_BITS_8 ALIGNMENT_CHAR

#else

#error Type xxsigned_8 could not be defined!

#endif






/*
	Define our basic 16 bit types being terribly 
	paranoid about strange platforms out there. 
*/

#if SIZEOF_SHORT == 2

typedef short int signed_16;
typedef unsigned short int unsigned_16;

#define ALIGNMENT_INT_BITS_16 ALIGNMENT_SHORT

#elif SIZEOF_INT == 2

typedef int signed_16;
typedef unsigned int unsigned_16;

#define ALIGNMENT_INT_BITS_16 ALIGNMENT_INT

#else

#error Type xxsigned_16 could not be defined

#endif








/* 
	Define out basic 32 bits types.  Adjust according to
	the specific platform and always paranoid about the
	possible platforms.
*/


#if SIZEOF_INT == 4

typedef int signed_32;
typedef unsigned int unsigned_32;

#define ALIGNMENT_INT_BITS_32 ALIGNMENT_INT

#elif SIZEOF_LONG == 4

typedef long signed_32;
typedef unsigned long unsigned_32;

#define ALIGNMENT_INT_BITS_32 ALIGNMENT_LONG

#else

#error Type xxsigned_32 could not be defined

#endif






/* 
	Define out basic 64 bits types.  Adjust according to
	the specific platform and always paranoid about the
	possible platforms.
*/



#if SIZEOF_LONG == 8

typedef long signed_64;
typedef unsigned long unsigned_64;

#define ALIGNMENT_INT_BITS_64 ALIGNMENT_LONG


#elif SIZEOF_LONG_LONG == 8

typedef long long signed_64;
typedef unsigned long long unsigned_64;

#define ALIGNMENT_INT_BITS_64 ALIGNMENT_LONG_LONG

#else

#error Type xxsigned_64 could not be defined

#endif



Ok, so its ugly and OLD (back when I did some mips work for a company called Cobalt)... but heck, its part of an include file... and I am NOT gonna give you the entire (or most recent) bit...  Its how I make my living...  but it should / may work...  the only place you may have problems is the 64 bit longs...  and thats just a minor tweek...



Michael


"The only difference between me and a madman is that I'm not mad."

Salvador Dali (1904-1989)

Offline

  • Index
  • » General
  • » Migration C program from Digital Unix to Solaris

Board footer

Powered by FluxBB