You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

endianness.c 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /* This file is part of Netsukuku
  2. * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
  3. *
  4. * This source code is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as published
  6. * by the Free Software Foundation; either version 2 of the License,
  7. * or (at your option) any later version.
  8. *
  9. * This source code is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. * Please refer to the GNU Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Public License along with
  15. * this source code; if not, write to:
  16. * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. *
  18. * --
  19. * endian.c:
  20. * stuff to handle endianess mischief.
  21. */
  22. #include "includes.h"
  23. #include "common.h"
  24. #include "log.h"
  25. #include "endianness.h"
  26. #ifdef DEBUG
  27. /* Call fatal if `i' is equal to IINFO_DYNAMIC_VALUE.
  28. * Note: this is needed only for debugging purpose */
  29. #define IS_DYNAMIC(i) \
  30. ({ \
  31. if((i) == IINFO_DYNAMIC_VALUE) \
  32. fatal("%s:%d: IINFO_DYNAMIC_VALUE encountered", ERROR_POS); \
  33. })
  34. #else
  35. #define IS_DYNAMIC(i) ({do_nothing();})
  36. #endif /*DEBUG*/
  37. void *
  38. int_info_copy(int_info * dst, const int_info * src)
  39. {
  40. return memcpy(dst, src, sizeof(int_info));
  41. }
  42. void
  43. ints_array_ntohl(int *hostlong, int nmemb)
  44. {
  45. #if BYTE_ORDER == LITTLE_ENDIAN
  46. int i;
  47. for (i = 0; i < nmemb; i++)
  48. hostlong[i] = ntohl(hostlong[i]);
  49. #endif
  50. }
  51. void
  52. ints_array_htonl(int *netlong, int nmemb)
  53. {
  54. #if BYTE_ORDER == LITTLE_ENDIAN
  55. int i;
  56. for (i = 0; i < nmemb; i++)
  57. netlong[i] = htonl(netlong[i]);
  58. #endif
  59. }
  60. void
  61. ints_array_ntohs(short *hostshort, int nmemb)
  62. {
  63. #if BYTE_ORDER == LITTLE_ENDIAN
  64. int i;
  65. for (i = 0; i < nmemb; i++)
  66. hostshort[i] = ntohs(hostshort[i]);
  67. #endif
  68. }
  69. void
  70. ints_array_htons(short *netshort, int nmemb)
  71. {
  72. #if BYTE_ORDER == LITTLE_ENDIAN
  73. int i;
  74. for (i = 0; i < nmemb; i++)
  75. netshort[i] = htons(netshort[i]);
  76. #endif
  77. }
  78. /*
  79. * ints_network_to_host: converts all the int/short variables present in the
  80. * struct `s' from network order to host order. The `s' struct must be
  81. * described in the `iinfo' struct.
  82. */
  83. void
  84. ints_network_to_host(void *s, int_info iinfo)
  85. {
  86. #if BYTE_ORDER == LITTLE_ENDIAN
  87. int i;
  88. char *p;
  89. IS_DYNAMIC(iinfo.total_ints);
  90. for (i = 0; i < iinfo.total_ints; i++) {
  91. if (!iinfo.int_type[i])
  92. continue;
  93. IS_DYNAMIC(iinfo.int_offset[i]);
  94. p = (char *) s + iinfo.int_offset[i];
  95. IS_DYNAMIC(iinfo.int_nmemb[i]);
  96. IS_DYNAMIC(iinfo.int_type[i]);
  97. /*
  98. * Swap the entire array if it is a single integer and if we
  99. * are on a little endian machine.
  100. */
  101. if (iinfo.int_type[i] & INT_TYPE_WORDS) {
  102. if (iinfo.int_type[i] & INT_TYPE_32BIT)
  103. swap_ints(iinfo.int_nmemb[i], (u_int *) p, (u_int *) p);
  104. else
  105. swap_shorts(iinfo.int_nmemb[i], (u_short *) p,
  106. (u_short *) p);
  107. }
  108. if (iinfo.int_type[i] & INT_TYPE_32BIT)
  109. ints_array_ntohl((int *) p, iinfo.int_nmemb[i]);
  110. else
  111. ints_array_ntohs((short *) p, iinfo.int_nmemb[i]);
  112. }
  113. #endif
  114. }
  115. /*
  116. * ints_host_to_network: converts all the int/short variables present in the
  117. * struct `s' from host order to network order. The `s' struct must be
  118. * described in the `iinfo' struct.
  119. */
  120. void
  121. ints_host_to_network(void *s, int_info iinfo)
  122. {
  123. #if BYTE_ORDER == LITTLE_ENDIAN
  124. int i;
  125. char *p;
  126. IS_DYNAMIC(iinfo.total_ints);
  127. for (i = 0; i < iinfo.total_ints; i++) {
  128. if (!iinfo.int_type[i])
  129. continue;
  130. IS_DYNAMIC(iinfo.int_offset[i]);
  131. p = (char *) s + iinfo.int_offset[i];
  132. IS_DYNAMIC(iinfo.int_nmemb[i]);
  133. IS_DYNAMIC(iinfo.int_type[i]);
  134. /*
  135. * Swap the entire array if it is a single integer and if we
  136. * are on a little endian machine.
  137. */
  138. if (iinfo.int_type[i] & INT_TYPE_WORDS) {
  139. if (iinfo.int_type[i] & INT_TYPE_32BIT)
  140. swap_ints(iinfo.int_nmemb[i], (u_int *) p, (u_int *) p);
  141. else
  142. swap_shorts(iinfo.int_nmemb[i], (u_short *) p,
  143. (u_short *) p);
  144. }
  145. if (iinfo.int_type[i] & INT_TYPE_32BIT)
  146. ints_array_htonl((int *) p, iinfo.int_nmemb[i]);
  147. else
  148. ints_array_htons((short *) p, iinfo.int_nmemb[i]);
  149. }
  150. #endif
  151. }
  152. /*
  153. * ints_printf: prints all the int/short vars present in the `s' struct
  154. * described by `iinfo'. It uses `print_func' as the the printing function
  155. */
  156. void
  157. ints_printf(void *s, int_info iinfo, void (*print_func(const char *, ...)))
  158. {
  159. int i, e, *i32;
  160. short *i16;
  161. char *p;
  162. IS_DYNAMIC(iinfo.total_ints);
  163. for (i = 0; i < iinfo.total_ints; i++) {
  164. if (!iinfo.int_type[i])
  165. continue;
  166. IS_DYNAMIC(iinfo.int_offset[i]);
  167. p = (char *) s + iinfo.int_offset[i];
  168. IS_DYNAMIC(iinfo.int_nmemb[i]);
  169. IS_DYNAMIC(iinfo.int_type[i]);
  170. for (e = 0; e < iinfo.int_nmemb[i]; e++) {
  171. print_func("ints_printf: offset %d, nmemb %d, ",
  172. iinfo.int_offset[i], e);
  173. if (iinfo.int_type[i] & INT_TYPE_32BIT) {
  174. i32 = (int *) (p + (sizeof(int) * e));
  175. print_func("32bit value %d\n", *i32);
  176. } else {
  177. i16 = (short *) (p + (sizeof(short) * e));
  178. print_func("16bit value %d\n", *i16);
  179. }
  180. }
  181. }
  182. }