TUNTools.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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 <http://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/Jmp.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* setupUDP2(struct EventBase* base,
  29. struct Sockaddr* bindAddr,
  30. struct Allocator* allocator,
  31. struct Log* logger)
  32. {
  33. struct Jmp jmp;
  34. Jmp_try(jmp) {
  35. struct UDPAddrIface* ua = UDPAddrIface_new(base, bindAddr, allocator, &jmp.handler, logger);
  36. return &ua->generic;
  37. } Jmp_catch {
  38. sleep(1);
  39. return NULL;
  40. }
  41. }
  42. static struct AddrIface* setupUDP(struct EventBase* base,
  43. struct Sockaddr* bindAddr,
  44. struct Allocator* allocator,
  45. struct Log* logger)
  46. {
  47. // Mac OSX and BSD do not set up their TUN devices synchronously.
  48. // We'll just keep on trying until this works.
  49. struct AddrIface* udp = NULL;
  50. for (int i = 0; i < 20; i++) {
  51. if ((udp = setupUDP2(base, bindAddr, allocator, logger))) {
  52. break;
  53. }
  54. }
  55. Assert_true(udp);
  56. return udp;
  57. }
  58. struct TUNTools_pvt
  59. {
  60. struct TUNTools pub;
  61. Identity
  62. };
  63. static void sendHello(void* vctx)
  64. {
  65. struct TUNTools_pvt* ctx = Identity_check((struct TUNTools_pvt*) vctx);
  66. struct Allocator* tempAlloc = Allocator_child(ctx->pub.alloc);
  67. struct Message* msg = Message_new(0, 64, tempAlloc);
  68. Message_push(msg, "Hello World", 12, NULL);
  69. Message_push(msg, ctx->pub.tunDestAddr, ctx->pub.tunDestAddr->addrLen, NULL);
  70. Iface_send(&ctx->pub.udpIface, msg);
  71. Allocator_free(tempAlloc);
  72. }
  73. const uint8_t* TUNTools_testIP6AddrA = (uint8_t[])
  74. {
  75. 0xfd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
  76. };
  77. const uint8_t* TUNTools_testIP6AddrB = (uint8_t[])
  78. {
  79. 0xfd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2
  80. };
  81. const uint8_t* TUNTools_testIP6AddrC = (uint8_t[])
  82. {
  83. 0xfd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5
  84. };
  85. Iface_DEFUN TUNTools_genericIP6Echo(struct Message* msg, struct TUNTools* tt)
  86. {
  87. uint16_t ethertype = TUNMessageType_pop(msg, NULL);
  88. if (ethertype != Ethernet_TYPE_IP6) {
  89. Log_debug(tt->log, "Spurious packet with ethertype [%04x]\n",
  90. Endian_bigEndianToHost16(ethertype));
  91. return 0;
  92. }
  93. struct Headers_IP6Header* header = (struct Headers_IP6Header*) msg->bytes;
  94. if (msg->length != Headers_IP6Header_SIZE + Headers_UDPHeader_SIZE + 12) {
  95. int type = (msg->length >= Headers_IP6Header_SIZE) ? header->nextHeader : -1;
  96. Log_debug(tt->log, "Message of unexpected length [%u] ip6->nextHeader: [%d]\n",
  97. msg->length, type);
  98. return 0;
  99. }
  100. uint8_t* address;
  101. Sockaddr_getAddress(tt->tunDestAddr, &address);
  102. Assert_true(!Bits_memcmp(header->destinationAddr, address, 16));
  103. Sockaddr_getAddress(tt->udpBindTo, &address);
  104. Assert_true(!Bits_memcmp(header->sourceAddr, address, 16));
  105. Sockaddr_getAddress(tt->udpBindTo, &address);
  106. Bits_memcpy(header->destinationAddr, address, 16);
  107. Sockaddr_getAddress(tt->tunDestAddr, &address);
  108. Bits_memcpy(header->sourceAddr, address, 16);
  109. TUNMessageType_push(msg, ethertype, NULL);
  110. return Iface_next(&tt->tunIface, msg);
  111. }
  112. static Iface_DEFUN receiveMessageTUN(struct Message* msg, struct Iface* tunIface)
  113. {
  114. struct TUNTools_pvt* ctx = Identity_containerOf(tunIface, struct TUNTools_pvt, pub.tunIface);
  115. ctx->pub.receivedMessageTUNCount++;
  116. return ctx->pub.cb(msg, &ctx->pub);
  117. }
  118. static Iface_DEFUN receiveMessageUDP(struct Message* msg, struct Iface* udpIface)
  119. {
  120. struct TUNTools_pvt* ctx = Identity_containerOf(udpIface, struct TUNTools_pvt, pub.udpIface);
  121. if (ctx->pub.receivedMessageTUNCount) {
  122. Log_debug(ctx->pub.log, "test complete");
  123. // Got the message, test successful, tear everything down by freeing the root alloc.
  124. EventBase_endLoop(ctx->pub.base);
  125. }
  126. return NULL;
  127. }
  128. static void fail(void* ignored)
  129. {
  130. Assert_true(!"timeout");
  131. }
  132. void TUNTools_echoTest(struct Sockaddr* udpBindTo,
  133. struct Sockaddr* tunDestAddr,
  134. TUNTools_Callback tunMessageHandler,
  135. struct Iface* tun,
  136. struct EventBase* base,
  137. struct Log* logger,
  138. struct Allocator* allocator)
  139. {
  140. struct Allocator* alloc = Allocator_child(allocator);
  141. struct AddrIface* udp = setupUDP(base, udpBindTo, alloc, logger);
  142. struct Sockaddr* dest = Sockaddr_clone(udp->addr, alloc);
  143. uint8_t* tunDestAddrBytes = NULL;
  144. uint8_t* udpDestPointer = NULL;
  145. int len = Sockaddr_getAddress(dest, &udpDestPointer);
  146. Assert_true(len && len == Sockaddr_getAddress(tunDestAddr, &tunDestAddrBytes));
  147. Bits_memcpy(udpDestPointer, tunDestAddrBytes, len);
  148. struct TUNTools_pvt* ctx = Allocator_calloc(alloc, sizeof(struct TUNTools_pvt), 1);
  149. Identity_set(ctx);
  150. ctx->pub.udpIface.send = receiveMessageUDP;
  151. ctx->pub.tunIface.send = receiveMessageTUN;
  152. Iface_plumb(&ctx->pub.udpIface, &udp->iface);
  153. Iface_plumb(&ctx->pub.tunIface, tun);
  154. ctx->pub.cb = tunMessageHandler;
  155. ctx->pub.tunDestAddr = Sockaddr_clone(dest, alloc);
  156. ctx->pub.udpBindTo = Sockaddr_clone(udpBindTo, alloc);
  157. ctx->pub.alloc = alloc;
  158. ctx->pub.log = logger;
  159. ctx->pub.base = base;
  160. Timeout_setInterval(sendHello, ctx, 1000, base, alloc);
  161. Timeout_setTimeout(fail, NULL, 10000, base, alloc);
  162. EventBase_beginLoop(base);
  163. }