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.

ipv6-gmp.c 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. * 128bit-gmp.c: Damn! The ipv6 numbers are really BIG ^_.
  20. */
  21. #include "includes.h"
  22. #include "ipv6-gmp.h"
  23. /*y=x+y*/
  24. int
  25. sum_128(unsigned int *x, unsigned int *y)
  26. {
  27. mpz_t xx, yy, res;
  28. size_t count;
  29. mpz_init(res);
  30. mpz_init(xx);
  31. mpz_init(yy);
  32. mpz_import(xx, 4, HOST_ORDER, sizeof(x[0]), NATIVE_ENDIAN, 0, x);
  33. mpz_import(yy, 4, HOST_ORDER, sizeof(y[0]), NATIVE_ENDIAN, 0, y);
  34. mpz_add(res, xx, yy);
  35. memset(y, '\0', sizeof(y[0]) * 4);
  36. mpz_export(y, &count, HOST_ORDER, sizeof(x[0]), NATIVE_ENDIAN, 0, res);
  37. mpz_clear(xx);
  38. mpz_clear(yy);
  39. mpz_clear(res);
  40. return 0;
  41. }
  42. /*y=x+y*/
  43. int
  44. sum_int(unsigned int x, unsigned int *y)
  45. {
  46. unsigned int z[4] = ZERO128;
  47. z[3] = x;
  48. return sum_128(z, y);
  49. }
  50. /*y=x-y*/
  51. int
  52. sub_128(unsigned int *x, unsigned int *y)
  53. {
  54. mpz_t xx, yy, res;
  55. size_t count;
  56. mpz_init(res);
  57. mpz_init(xx);
  58. mpz_init(yy);
  59. mpz_import(xx, 4, HOST_ORDER, sizeof(x[0]), NATIVE_ENDIAN, 0, x);
  60. mpz_import(yy, 4, HOST_ORDER, sizeof(y[0]), NATIVE_ENDIAN, 0, y);
  61. mpz_sub(res, xx, yy);
  62. memset(y, '\0', sizeof(y[0]) * 4);
  63. mpz_export(y, &count, HOST_ORDER, sizeof(x[0]), NATIVE_ENDIAN, 0, res);
  64. mpz_clear(xx);
  65. mpz_clear(yy);
  66. mpz_clear(res);
  67. return 0;
  68. }
  69. /* y=y-x */
  70. int
  71. sub_int(unsigned int *y, unsigned int x)
  72. {
  73. unsigned int z[4] = ZERO128;
  74. z[3] = x;
  75. return sub_128(z, y);
  76. }
  77. /*y=x/y*/
  78. int
  79. div_128(unsigned int *x, unsigned int *y)
  80. {
  81. mpz_t xx, yy, res;
  82. size_t count;
  83. mpz_init(res);
  84. mpz_init(xx);
  85. mpz_init(yy);
  86. mpz_import(xx, 4, HOST_ORDER, sizeof(x[0]), NATIVE_ENDIAN, 0, x);
  87. mpz_import(yy, 4, HOST_ORDER, sizeof(y[0]), NATIVE_ENDIAN, 0, y);
  88. mpz_tdiv_q(res, xx, yy);
  89. memset(y, '\0', sizeof(y[0]) * 4);
  90. mpz_export(y, &count, HOST_ORDER, sizeof(x[0]), NATIVE_ENDIAN, 0, res);
  91. mpz_clear(xx);
  92. mpz_clear(yy);
  93. mpz_clear(res);
  94. return 0;
  95. }
  96. /* y=y/x */
  97. int
  98. div_int(unsigned int *y, unsigned int x)
  99. {
  100. unsigned int z[4] = ZERO128;
  101. z[3] = x;
  102. return div_128(z, y);
  103. }
  104. /* y=y/x */
  105. int
  106. div_mpz(unsigned int *y, mpz_t x)
  107. {
  108. mpz_t yy, res;
  109. size_t count;
  110. mpz_init(res);
  111. mpz_init(yy);
  112. mpz_import(yy, 4, HOST_ORDER, sizeof(y[0]), NATIVE_ENDIAN, 0, y);
  113. mpz_tdiv_q(res, yy, x);
  114. memset(y, '\0', sizeof(y[0]) * 4);
  115. mpz_export(y, &count, HOST_ORDER, sizeof(x[0]), NATIVE_ENDIAN, 0, res);
  116. mpz_clear(yy);
  117. mpz_clear(res);
  118. return 0;
  119. }
  120. /* "ORDER can be 1 for most significant word first or -1 for least significant first." */
  121. int
  122. htonl_128(unsigned int *x, unsigned int *y)
  123. {
  124. mpz_t xx;
  125. size_t count;
  126. mpz_init(xx);
  127. mpz_import(xx, 4, HOST_ORDER, sizeof(x[0]), NATIVE_ENDIAN, 0, x);
  128. memset(y, '\0', sizeof(y[0]) * 4);
  129. mpz_export(y, &count, NETWORK_ORDER, sizeof(x[0]), NETWORK_ENDIAN, 0,
  130. xx);
  131. mpz_clear(xx);
  132. return 0;
  133. }
  134. int
  135. ntohl_128(unsigned int *x, unsigned int *y)
  136. {
  137. mpz_t xx;
  138. size_t count;
  139. mpz_init(xx);
  140. mpz_import(xx, 4, NETWORK_ORDER, sizeof(x[0]), NETWORK_ENDIAN, 0, x);
  141. memset(y, '\0', sizeof(y[0]) * 4);
  142. mpz_export(y, &count, HOST_ORDER, sizeof(x[0]), NATIVE_ENDIAN, 0, xx);
  143. mpz_clear(xx);
  144. return 0;
  145. }