test-inet6_opt.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #include <netinet/in.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdint.h>
  6. #define OPT_X 42
  7. #define OPT_Y 43
  8. #define OPT_Z 44
  9. static void *
  10. encode_inet6_opt (socklen_t *elp)
  11. {
  12. void *eb = NULL;
  13. socklen_t el;
  14. int cl;
  15. void *db;
  16. int offset;
  17. uint8_t val1;
  18. uint16_t val2;
  19. uint32_t val4;
  20. uint64_t val8;
  21. *elp = 0;
  22. #define CHECK() \
  23. if (cl == -1) \
  24. { \
  25. printf ("cl == -1 on line %d\n", __LINE__); \
  26. free (eb); \
  27. return NULL; \
  28. }
  29. /* Estimate the length */
  30. cl = inet6_opt_init (NULL, 0);
  31. CHECK ();
  32. cl = inet6_opt_append (NULL, 0, cl, OPT_X, 12, 8, NULL);
  33. CHECK ();
  34. cl = inet6_opt_append (NULL, 0, cl, OPT_Y, 7, 4, NULL);
  35. CHECK ();
  36. cl = inet6_opt_append (NULL, 0, cl, OPT_Z, 7, 1, NULL);
  37. CHECK ();
  38. cl = inet6_opt_finish (NULL, 0, cl);
  39. CHECK ();
  40. el = cl;
  41. eb = malloc (el + 8);
  42. if (eb == NULL)
  43. {
  44. puts ("malloc failed");
  45. return NULL;
  46. }
  47. /* Canary. */
  48. memcpy (eb + el, "deadbeef", 8);
  49. cl = inet6_opt_init (eb, el);
  50. CHECK ();
  51. cl = inet6_opt_append (eb, el, cl, OPT_X, 12, 8, &db);
  52. CHECK ();
  53. val4 = 0x12345678;
  54. offset = inet6_opt_set_val (db, 0, &val4, sizeof (val4));
  55. val8 = 0x0102030405060708LL;
  56. inet6_opt_set_val (db, offset, &val8, sizeof (val8));
  57. cl = inet6_opt_append (eb, el, cl, OPT_Y, 7, 4, &db);
  58. CHECK ();
  59. val1 = 0x01;
  60. offset = inet6_opt_set_val (db, 0, &val1, sizeof (val1));
  61. val2 = 0x1331;
  62. offset = inet6_opt_set_val (db, offset, &val2, sizeof (val2));
  63. val4 = 0x01020304;
  64. inet6_opt_set_val (db, offset, &val4, sizeof (val4));
  65. cl = inet6_opt_append (eb, el, cl, OPT_Z, 7, 1, &db);
  66. CHECK ();
  67. inet6_opt_set_val (db, 0, (void *) "abcdefg", 7);
  68. cl = inet6_opt_finish (eb, el, cl);
  69. CHECK ();
  70. if (memcmp (eb + el, "deadbeef", 8) != 0)
  71. {
  72. puts ("Canary corrupted");
  73. free (eb);
  74. return NULL;
  75. }
  76. *elp = el;
  77. return eb;
  78. }
  79. int
  80. decode_inet6_opt (void *eb, socklen_t el)
  81. {
  82. int ret = 0;
  83. int seq = 0;
  84. int cl = 0;
  85. int offset;
  86. uint8_t type;
  87. socklen_t len;
  88. uint8_t val1;
  89. uint16_t val2;
  90. uint32_t val4;
  91. uint64_t val8;
  92. void *db;
  93. char buf[8];
  94. while ((cl = inet6_opt_next (eb, el, cl, &type, &len, &db)) != -1)
  95. switch (type)
  96. {
  97. case OPT_X:
  98. if (seq++ != 0)
  99. {
  100. puts ("OPT_X is not first");
  101. ret = 1;
  102. }
  103. if (len != 12)
  104. {
  105. printf ("OPT_X's length %d != 12\n", len);
  106. ret = 1;
  107. }
  108. offset = inet6_opt_get_val (db, 0, &val4, sizeof (val4));
  109. if (val4 != 0x12345678)
  110. {
  111. printf ("OPT_X's val4 %x != 0x12345678\n", val4);
  112. ret = 1;
  113. }
  114. offset = inet6_opt_get_val (db, offset, &val8, sizeof (val8));
  115. if (offset != len || val8 != 0x0102030405060708LL)
  116. {
  117. printf ("OPT_X's val8 %llx != 0x0102030405060708\n",
  118. (long long) val8);
  119. ret = 1;
  120. }
  121. break;
  122. case OPT_Y:
  123. if (seq++ != 1)
  124. {
  125. puts ("OPT_Y is not second");
  126. ret = 1;
  127. }
  128. if (len != 7)
  129. {
  130. printf ("OPT_Y's length %d != 7\n", len);
  131. ret = 1;
  132. }
  133. offset = inet6_opt_get_val (db, 0, &val1, sizeof (val1));
  134. if (val1 != 0x01)
  135. {
  136. printf ("OPT_Y's val1 %x != 0x01\n", val1);
  137. ret = 1;
  138. }
  139. offset = inet6_opt_get_val (db, offset, &val2, sizeof (val2));
  140. if (val2 != 0x1331)
  141. {
  142. printf ("OPT_Y's val2 %x != 0x1331\n", val2);
  143. ret = 1;
  144. }
  145. offset = inet6_opt_get_val (db, offset, &val4, sizeof (val4));
  146. if (offset != len || val4 != 0x01020304)
  147. {
  148. printf ("OPT_Y's val4 %x != 0x01020304\n", val4);
  149. ret = 1;
  150. }
  151. break;
  152. case OPT_Z:
  153. if (seq++ != 2)
  154. {
  155. puts ("OPT_Z is not third");
  156. ret = 1;
  157. }
  158. if (len != 7)
  159. {
  160. printf ("OPT_Z's length %d != 7\n", len);
  161. ret = 1;
  162. }
  163. offset = inet6_opt_get_val (db, 0, buf, 7);
  164. if (offset != len || memcmp (buf, "abcdefg", 7) != 0)
  165. {
  166. buf[7] = '\0';
  167. printf ("OPT_Z's buf \"%s\" != \"abcdefg\"\n", buf);
  168. ret = 1;
  169. }
  170. break;
  171. default:
  172. printf ("Unknown option %d\n", type);
  173. ret = 1;
  174. break;
  175. }
  176. if (seq != 3)
  177. {
  178. puts ("Didn't see all of OPT_X, OPT_Y and OPT_Z");
  179. ret = 1;
  180. }
  181. return ret;
  182. }
  183. static int
  184. do_test (void)
  185. {
  186. void *eb;
  187. socklen_t el;
  188. eb = encode_inet6_opt (&el);
  189. if (eb == NULL)
  190. return 1;
  191. if (decode_inet6_opt (eb, el))
  192. return 1;
  193. return 0;
  194. }
  195. #define TEST_FUNCTION do_test ()
  196. #include "../test-skeleton.c"