groupsock/inet.c

Go to the documentation of this file.
00001 /* Some systems (e.g., SunOS) have header files that erroneously declare
00002  * inet_addr(), inet_ntoa() and gethostbyname() as taking no arguments.
00003  * This confuses C++.  To overcome this, we use our own routines,
00004  * implemented in C.
00005  */
00006 
00007 #ifndef _NET_COMMON_H
00008 #include "NetCommon.h"
00009 #endif
00010 
00011 #include <stdio.h>
00012 
00013 #ifdef VXWORKS
00014 #include <inetLib.h>
00015 #endif
00016 
00017 unsigned our_inet_addr(cp)
00018         char const* cp;
00019 {
00020         return inet_addr(cp);
00021 }
00022 
00023 char *
00024 our_inet_ntoa(in)
00025         struct in_addr in;
00026 {
00027 #ifndef VXWORKS
00028   return inet_ntoa(in);
00029 #else
00030   /* according the man pages of inet_ntoa :
00031 
00032      NOTES
00033      The return value from inet_ntoa() points to a  buffer  which
00034      is  overwritten on each call.  This buffer is implemented as
00035      thread-specific data in multithreaded applications.
00036 
00037      the vxworks version of inet_ntoa allocates a buffer for each
00038      ip address string, and does not reuse the same buffer.
00039 
00040      this is merely to simulate the same behaviour (not multithread
00041      safe though):
00042   */
00043   static char result[INET_ADDR_LEN];
00044   inet_ntoa_b(in, result);
00045   return(result);
00046 #endif
00047 }
00048 
00049 #if defined(__WIN32__) || defined(_WIN32)
00050 #ifndef IMN_PIM
00051 #define WS_VERSION_CHOICE1 0x202/*MAKEWORD(2,2)*/
00052 #define WS_VERSION_CHOICE2 0x101/*MAKEWORD(1,1)*/
00053 int initializeWinsockIfNecessary(void) {
00054         /* We need to call an initialization routine before
00055          * we can do anything with winsock.  (How fucking lame!):
00056          */
00057         static int _haveInitializedWinsock = 0;
00058         WSADATA wsadata;
00059 
00060         if (!_haveInitializedWinsock) {
00061                 if ((WSAStartup(WS_VERSION_CHOICE1, &wsadata) != 0)
00062                     && ((WSAStartup(WS_VERSION_CHOICE2, &wsadata)) != 0)) {
00063                         return 0; /* error in initialization */
00064                 }
00065                 if ((wsadata.wVersion != WS_VERSION_CHOICE1)
00066                     && (wsadata.wVersion != WS_VERSION_CHOICE2)) {
00067                         WSACleanup();
00068                                 return 0; /* desired Winsock version was not available */
00069                 }
00070                 _haveInitializedWinsock = 1;
00071         }
00072 
00073         return 1;
00074 }
00075 #else
00076 int initializeWinsockIfNecessary(void) { return 1; }
00077 #endif
00078 #else
00079 #define initializeWinsockIfNecessary() 1
00080 #endif
00081 
00082 #ifndef NULL
00083 #define NULL 0
00084 #endif
00085 
00086 #if !defined(VXWORKS)
00087 struct hostent* our_gethostbyname(name)
00088      char* name;
00089 {
00090         if (!initializeWinsockIfNecessary()) return NULL;
00091 
00092         return (struct hostent*) gethostbyname(name);
00093 }
00094 #endif
00095 
00096 #ifndef USE_OUR_RANDOM
00097 /* Use the system-supplied "random()" and "srandom()" functions */
00098 #include <stdlib.h>
00099 long our_random() {
00100 #if defined(__WIN32__) || defined(_WIN32)
00101   return rand();
00102 #else
00103   return random();
00104 #endif
00105 }
00106 void our_srandom(unsigned int x) {
00107 #if defined(__WIN32__) || defined(_WIN32)
00108   srand(x);
00109 #else
00110   srandom(x);
00111 #endif
00112 }
00113 
00114 #else
00115 
00116 /* Use our own implementation of the "random()" and "srandom()" functions */
00117 /*
00118  * random.c:
00119  *
00120  * An improved random number generation package.  In addition to the standard
00121  * rand()/srand() like interface, this package also has a special state info
00122  * interface.  The our_initstate() routine is called with a seed, an array of
00123  * bytes, and a count of how many bytes are being passed in; this array is
00124  * then initialized to contain information for random number generation with
00125  * that much state information.  Good sizes for the amount of state
00126  * information are 32, 64, 128, and 256 bytes.  The state can be switched by
00127  * calling the our_setstate() routine with the same array as was initiallized
00128  * with our_initstate().  By default, the package runs with 128 bytes of state
00129  * information and generates far better random numbers than a linear
00130  * congruential generator.  If the amount of state information is less than
00131  * 32 bytes, a simple linear congruential R.N.G. is used.
00132  *
00133  * Internally, the state information is treated as an array of longs; the
00134  * zeroeth element of the array is the type of R.N.G. being used (small
00135  * integer); the remainder of the array is the state information for the
00136  * R.N.G.  Thus, 32 bytes of state information will give 7 longs worth of
00137  * state information, which will allow a degree seven polynomial.  (Note:
00138  * the zeroeth word of state information also has some other information
00139  * stored in it -- see our_setstate() for details).
00140  *
00141  * The random number generation technique is a linear feedback shift register
00142  * approach, employing trinomials (since there are fewer terms to sum up that
00143  * way).  In this approach, the least significant bit of all the numbers in
00144  * the state table will act as a linear feedback shift register, and will
00145  * have period 2^deg - 1 (where deg is the degree of the polynomial being
00146  * used, assuming that the polynomial is irreducible and primitive).  The
00147  * higher order bits will have longer periods, since their values are also
00148  * influenced by pseudo-random carries out of the lower bits.  The total
00149  * period of the generator is approximately deg*(2**deg - 1); thus doubling
00150  * the amount of state information has a vast influence on the period of the
00151  * generator.  Note: the deg*(2**deg - 1) is an approximation only good for
00152  * large deg, when the period of the shift register is the dominant factor.
00153  * With deg equal to seven, the period is actually much longer than the
00154  * 7*(2**7 - 1) predicted by this formula.
00155  */
00156 
00157 /*
00158  * For each of the currently supported random number generators, we have a
00159  * break value on the amount of state information (you need at least this
00160  * many bytes of state info to support this random number generator), a degree
00161  * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
00162  * the separation between the two lower order coefficients of the trinomial.
00163  */
00164 #define TYPE_0          0               /* linear congruential */
00165 #define BREAK_0         8
00166 #define DEG_0           0
00167 #define SEP_0           0
00168 
00169 #define TYPE_1          1               /* x**7 + x**3 + 1 */
00170 #define BREAK_1         32
00171 #define DEG_1           7
00172 #define SEP_1           3
00173 
00174 #define TYPE_2          2               /* x**15 + x + 1 */
00175 #define BREAK_2         64
00176 #define DEG_2           15
00177 #define SEP_2           1
00178 
00179 #define TYPE_3          3               /* x**31 + x**3 + 1 */
00180 #define BREAK_3         128
00181 #define DEG_3           31
00182 #define SEP_3           3
00183 
00184 #define TYPE_4          4               /* x**63 + x + 1 */
00185 #define BREAK_4         256
00186 #define DEG_4           63
00187 #define SEP_4           1
00188 
00189 /*
00190  * Array versions of the above information to make code run faster --
00191  * relies on fact that TYPE_i == i.
00192  */
00193 #define MAX_TYPES       5               /* max number of types above */
00194 
00195 static int const degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
00196 static int const seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
00197 
00198 /*
00199  * Initially, everything is set up as if from:
00200  *
00201  *      our_initstate(1, &randtbl, 128);
00202  *
00203  * Note that this initialization takes advantage of the fact that srandom()
00204  * advances the front and rear pointers 10*rand_deg times, and hence the
00205  * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
00206  * element of the state information, which contains info about the current
00207  * position of the rear pointer is just
00208  *
00209  *      MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
00210  */
00211 
00212 static long randtbl[DEG_3 + 1] = {
00213         TYPE_3,
00214         0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5,
00215         0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
00216         0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88,
00217         0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
00218         0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b,
00219         0x27fb47b9,
00220 };
00221 
00222 /*
00223  * fptr and rptr are two pointers into the state info, a front and a rear
00224  * pointer.  These two pointers are always rand_sep places aparts, as they
00225  * cycle cyclically through the state information.  (Yes, this does mean we
00226  * could get away with just one pointer, but the code for random() is more
00227  * efficient this way).  The pointers are left positioned as they would be
00228  * from the call
00229  *
00230  *      our_initstate(1, randtbl, 128);
00231  *
00232  * (The position of the rear pointer, rptr, is really 0 (as explained above
00233  * in the initialization of randtbl) because the state table pointer is set
00234  * to point to randtbl[1] (as explained below).
00235  */
00236 static long* fptr = &randtbl[SEP_3 + 1];
00237 static long* rptr = &randtbl[1];
00238 
00239 /*
00240  * The following things are the pointer to the state information table, the
00241  * type of the current generator, the degree of the current polynomial being
00242  * used, and the separation between the two pointers.  Note that for efficiency
00243  * of random(), we remember the first location of the state information, not
00244  * the zeroeth.  Hence it is valid to access state[-1], which is used to
00245  * store the type of the R.N.G.  Also, we remember the last location, since
00246  * this is more efficient than indexing every time to find the address of
00247  * the last element to see if the front and rear pointers have wrapped.
00248  */
00249 static long *state = &randtbl[1];
00250 static int rand_type = TYPE_3;
00251 static int rand_deg = DEG_3;
00252 static int rand_sep = SEP_3;
00253 static long* end_ptr = &randtbl[DEG_3 + 1];
00254 
00255 /*
00256  * srandom:
00257  *
00258  * Initialize the random number generator based on the given seed.  If the
00259  * type is the trivial no-state-information type, just remember the seed.
00260  * Otherwise, initializes state[] based on the given "seed" via a linear
00261  * congruential generator.  Then, the pointers are set to known locations
00262  * that are exactly rand_sep places apart.  Lastly, it cycles the state
00263  * information a given number of times to get rid of any initial dependencies
00264  * introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
00265  * for default usage relies on values produced by this routine.
00266  */
00267 long our_random(void); /*forward*/
00268 void
00269 our_srandom(unsigned int x)
00270 {
00271         register int i;
00272 
00273         if (rand_type == TYPE_0)
00274                 state[0] = x;
00275         else {
00276                 state[0] = x;
00277                 for (i = 1; i < rand_deg; i++)
00278                         state[i] = 1103515245 * state[i - 1] + 12345;
00279                 fptr = &state[rand_sep];
00280                 rptr = &state[0];
00281                 for (i = 0; i < 10 * rand_deg; i++)
00282                         (void)our_random();
00283         }
00284 }
00285 
00286 /*
00287  * our_initstate:
00288  *
00289  * Initialize the state information in the given array of n bytes for future
00290  * random number generation.  Based on the number of bytes we are given, and
00291  * the break values for the different R.N.G.'s, we choose the best (largest)
00292  * one we can and set things up for it.  srandom() is then called to
00293  * initialize the state information.
00294  *
00295  * Note that on return from srandom(), we set state[-1] to be the type
00296  * multiplexed with the current value of the rear pointer; this is so
00297  * successive calls to our_initstate() won't lose this information and will be
00298  * able to restart with our_setstate().
00299  *
00300  * Note: the first thing we do is save the current state, if any, just like
00301  * our_setstate() so that it doesn't matter when our_initstate is called.
00302  *
00303  * Returns a pointer to the old state.
00304  */
00305 char *
00306 our_initstate(seed, arg_state, n)
00307         unsigned int seed;              /* seed for R.N.G. */
00308         char *arg_state;                /* pointer to state array */
00309         int n;                          /* # bytes of state info */
00310 {
00311         register char *ostate = (char *)(&state[-1]);
00312 
00313         if (rand_type == TYPE_0)
00314                 state[-1] = rand_type;
00315         else
00316                 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
00317         if (n < BREAK_0) {
00318 #ifdef DEBUG
00319                 (void)fprintf(stderr,
00320                     "random: not enough state (%d bytes); ignored.\n", n);
00321 #endif
00322                 return(0);
00323         }
00324         if (n < BREAK_1) {
00325                 rand_type = TYPE_0;
00326                 rand_deg = DEG_0;
00327                 rand_sep = SEP_0;
00328         } else if (n < BREAK_2) {
00329                 rand_type = TYPE_1;
00330                 rand_deg = DEG_1;
00331                 rand_sep = SEP_1;
00332         } else if (n < BREAK_3) {
00333                 rand_type = TYPE_2;
00334                 rand_deg = DEG_2;
00335                 rand_sep = SEP_2;
00336         } else if (n < BREAK_4) {
00337                 rand_type = TYPE_3;
00338                 rand_deg = DEG_3;
00339                 rand_sep = SEP_3;
00340         } else {
00341                 rand_type = TYPE_4;
00342                 rand_deg = DEG_4;
00343                 rand_sep = SEP_4;
00344         }
00345         state = &(((long *)arg_state)[1]);      /* first location */
00346         end_ptr = &state[rand_deg];     /* must set end_ptr before srandom */
00347         our_srandom(seed);
00348         if (rand_type == TYPE_0)
00349                 state[-1] = rand_type;
00350         else
00351                 state[-1] = MAX_TYPES*(rptr - state) + rand_type;
00352         return(ostate);
00353 }
00354 
00355 /*
00356  * our_setstate:
00357  *
00358  * Restore the state from the given state array.
00359  *
00360  * Note: it is important that we also remember the locations of the pointers
00361  * in the current state information, and restore the locations of the pointers
00362  * from the old state information.  This is done by multiplexing the pointer
00363  * location into the zeroeth word of the state information.
00364  *
00365  * Note that due to the order in which things are done, it is OK to call
00366  * our_setstate() with the same state as the current state.
00367  *
00368  * Returns a pointer to the old state information.
00369  */
00370 char *
00371 our_setstate(arg_state)
00372         char *arg_state;
00373 {
00374         register long *new_state = (long *)arg_state;
00375         register int type = new_state[0] % MAX_TYPES;
00376         register int rear = new_state[0] / MAX_TYPES;
00377         char *ostate = (char *)(&state[-1]);
00378 
00379         if (rand_type == TYPE_0)
00380                 state[-1] = rand_type;
00381         else
00382                 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
00383         switch(type) {
00384         case TYPE_0:
00385         case TYPE_1:
00386         case TYPE_2:
00387         case TYPE_3:
00388         case TYPE_4:
00389                 rand_type = type;
00390                 rand_deg = degrees[type];
00391                 rand_sep = seps[type];
00392                 break;
00393         default:
00394 #ifdef DEBUG
00395                 (void)fprintf(stderr,
00396                     "random: state info corrupted; not changed.\n");
00397 #endif
00398                 break;
00399         }
00400         state = &new_state[1];
00401         if (rand_type != TYPE_0) {
00402                 rptr = &state[rear];
00403                 fptr = &state[(rear + rand_sep) % rand_deg];
00404         }
00405         end_ptr = &state[rand_deg];             /* set end_ptr too */
00406         return(ostate);
00407 }
00408 
00409 /*
00410  * random:
00411  *
00412  * If we are using the trivial TYPE_0 R.N.G., just do the old linear
00413  * congruential bit.  Otherwise, we do our fancy trinomial stuff, which is
00414  * the same in all the other cases due to all the global variables that have
00415  * been set up.  The basic operation is to add the number at the rear pointer
00416  * into the one at the front pointer.  Then both pointers are advanced to
00417  * the next location cyclically in the table.  The value returned is the sum
00418  * generated, reduced to 31 bits by throwing away the "least random" low bit.
00419  *
00420  * Note: the code takes advantage of the fact that both the front and
00421  * rear pointers can't wrap on the same call by not testing the rear
00422  * pointer if the front one has wrapped.
00423  *
00424  * Returns a 31-bit random number.
00425  */
00426 long
00427 our_random()
00428 {
00429         long i;
00430 
00431         if (rand_type == TYPE_0)
00432                 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
00433         else {
00434                 *fptr += *rptr;
00435                 i = (*fptr >> 1) & 0x7fffffff;  /* chucking least random bit */
00436                 if (++fptr >= end_ptr) {
00437                         fptr = state;
00438                         ++rptr;
00439                 } else if (++rptr >= end_ptr)
00440                         rptr = state;
00441         }
00442         return(i);
00443 }
00444 #endif
00445 
00446 u_int32_t our_random32() {
00447   // Return a 32-bit random number.
00448   // Because "our_random()" returns a 31-bit random number, we call it a second
00449   // time, to generate the high bit:
00450   long random1 = our_random();
00451   long random2 = our_random();
00452   return (u_int32_t)((random2<<31) | random1);
00453 }
00454 
00455 #ifdef USE_OUR_BZERO
00456 #ifndef __bzero
00457 void
00458 __bzero (to, count)
00459   char *to;
00460   int count;
00461 {
00462   while (count-- > 0)
00463     {
00464       *to++ = 0;
00465     }
00466 }             
00467 #endif
00468 #endif

Generated on Tue Oct 7 15:38:08 2008 for live by  doxygen 1.5.2