TUNTools.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "interface/tuntap/TUNMessageType.h"
  16. #include "interface/tuntap/test/TUNTools.h"
  17. #include "util/events/UDPAddrIface.h"
  18. #include "exception/Er.h"
  19. #include "util/events/Timeout.h"
  20. #include "wire/Ethernet.h"
  21. #include "wire/Headers.h"
  22. #ifdef win32
  23. #include <windows.h>
  24. #define sleep(x) Sleep(1000*x)
  25. #else
  26. #include <unistd.h>
  27. #endif
  28. static struct AddrIface* setupUDP(struct EventBase* base,
  29. struct Sockaddr* bindAddr,
  30. struct Allocator* allocator,
  31. struct Log* logger)
  32. {
  33. // Mac OSX and BSD do not set up their TUN devices synchronously.
  34. // We'll just keep on trying until this works.
  35. struct UDPAddrIface* udp = NULL;
  36. struct Er_Ret* er = NULL;
  37. for (int i = 0; i < 20; i++) {
  38. udp = Er_check(&er, UDPAddrIface_new(base, bindAddr, allocator, logger));
  39. if (udp) {
  40. break;
  41. }
  42. sleep(1);
  43. }
  44. Assert_true(udp);
  45. return &udp->generic;
  46. }
  47. struct TUNTools_pvt
  48. {
  49. struct TUNTools pub;
  50. Identity
  51. };
  52. static void sendHello(void* vctx)
  53. {
  54. struct TUNTools_pvt* ctx = Identity_check((struct TUNTools_pvt*) vctx);
  55. struct Allocator* tempAlloc = Allocator_child(ctx->pub.alloc);
  56. struct Message* msg = Message_new(0, 64, tempAlloc);
  57. Er_assert(Message_epush(msg, "Hello World", 12));
  58. Er_assert(Message_epush(msg, ctx->pub.tunDestAddr, ctx->pub.tunDestAddr->addrLen));
  59. Iface_send(&ctx->pub.udpIface, msg);
  60. Allocator_free(tempAlloc);
  61. }
  62. const uint8_t* TUNTools_testIP6AddrA = (uint8_t[])
  63. {
  64. 0xfd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  65. };
  66. const uint8_t* TUNTools_testIP6AddrB = (uint8_t[])
  67. {
  68. 0xfd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
  69. };
  70. const uint8_t* TUNTools_testIP6AddrC = (uint8_t[])
  71. {
  72. 0xfd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5
  73. };
  74. Iface_DEFUN TUNTools_genericIP6Echo(struct Message* msg, struct TUNTools* tt)
  75. {
  76. uint16_t ethertype = Er_assert(TUNMessageType_pop(msg));
  77. if (ethertype != Ethernet_TYPE_IP6) {
  78. Log_debug(tt->log, "Spurious packet with ethertype [%04x]\n",
  79. Endian_bigEndianToHost16(ethertype));
  80. return Error(INVALID);
  81. }
  82. struct Headers_IP6Header* header = (struct Headers_IP6Header*) msg->msgbytes;
  83. if (Message_getLength(msg) != Headers_IP6Header_SIZE + Headers_UDPHeader_SIZE + 12) {
  84. int type = (Message_getLength(msg) >= Headers_IP6Header_SIZE) ? header->nextHeader : -1;
  85. Log_debug(tt->log, "Message of unexpected length [%u] ip6->nextHeader: [%d]\n",
  86. Message_getLength(msg), type);
  87. return Error(INVALID);
  88. }
  89. uint8_t* address;
  90. Sockaddr_getAddress(tt->tunDestAddr, &address);
  91. Assert_true(!Bits_memcmp(header->destinationAddr, address, 16));
  92. Sockaddr_getAddress(tt->udpBindTo, &address);
  93. Assert_true(!Bits_memcmp(header->sourceAddr, address, 16));
  94. Sockaddr_getAddress(tt->udpBindTo, &address);
  95. Bits_memcpy(header->destinationAddr, address, 16);
  96. Sockaddr_getAddress(tt->tunDestAddr, &address);
  97. Bits_memcpy(header->sourceAddr, address, 16);
  98. Er_assert(TUNMessageType_push(msg, ethertype));
  99. return Iface_next(&tt->tunIface, msg);
  100. }
  101. static Iface_DEFUN receiveMessageTUN(struct Message* msg, struct Iface* tunIface)
  102. {
  103. struct TUNTools_pvt* ctx = Identity_containerOf(tunIface, struct TUNTools_pvt, pub.tunIface);
  104. ctx->pub.receivedMessageTUNCount++;
  105. return ctx->pub.cb(msg, &ctx->pub);
  106. }
  107. static Iface_DEFUN receiveMessageUDP(struct Message* msg, struct Iface* udpIface)
  108. {
  109. struct TUNTools_pvt* ctx = Identity_containerOf(udpIface, struct TUNTools_pvt, pub.udpIface);
  110. if (ctx->pub.receivedMessageTUNCount) {
  111. Log_debug(ctx->pub.log, "test complete");
  112. // Got the message, test successful, tear everything down by freeing the root alloc.
  113. EventBase_endLoop(ctx->pub.base);
  114. }
  115. return Error(NONE);
  116. }
  117. static void fail(void* ignored)
  118. {
  119. Assert_true(!"timeout");
  120. }
  121. void TUNTools_echoTest(struct Sockaddr* udpBindTo,
  122. struct Sockaddr* tunDestAddr,
  123. TUNTools_Callback tunMessageHandler,
  124. struct Iface* tun,
  125. struct EventBase* base,
  126. struct Log* logger,
  127. struct Allocator* allocator)
  128. {
  129. struct Allocator* alloc = Allocator_child(allocator);
  130. struct AddrIface* udp = setupUDP(base, udpBindTo, alloc, logger);
  131. struct Sockaddr* dest = Sockaddr_clone(udp->addr, alloc);
  132. uint8_t* tunDestAddrBytes = NULL;
  133. uint8_t* udpDestPointer = NULL;
  134. int len = Sockaddr_getAddress(dest, &udpDestPointer);
  135. Assert_true(len && len == Sockaddr_getAddress(tunDestAddr, &tunDestAddrBytes));
  136. Bits_memcpy(udpDestPointer, tunDestAddrBytes, len);
  137. struct TUNTools_pvt* ctx = Allocator_calloc(alloc, sizeof(struct TUNTools_pvt), 1);
  138. Identity_set(ctx);
  139. ctx->pub.udpIface.send = receiveMessageUDP;
  140. ctx->pub.tunIface.send = receiveMessageTUN;
  141. Iface_plumb(&ctx->pub.udpIface, &udp->iface);
  142. Iface_plumb(&ctx->pub.tunIface, tun);
  143. ctx->pub.cb = tunMessageHandler;
  144. ctx->pub.tunDestAddr = Sockaddr_clone(dest, alloc);
  145. ctx->pub.udpBindTo = Sockaddr_clone(udpBindTo, alloc);
  146. ctx->pub.alloc = alloc;
  147. ctx->pub.log = logger;
  148. ctx->pub.base = base;
  149. Timeout_setInterval(sendHello, ctx, 1000, base, alloc);
  150. Timeout_setTimeout(fail, NULL, 10000, base, alloc);
  151. EventBase_beginLoop(base);
  152. }