BSDMessageTypeWrapper.c 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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/Iface.h"
  16. #include "interface/tuntap/BSDMessageTypeWrapper.h"
  17. #include "util/platform/Sockaddr.h"
  18. #include "memory/Allocator.h"
  19. #include "util/Assert.h"
  20. #include "util/Identity.h"
  21. #include "wire/Ethernet.h"
  22. #include "wire/Message.h"
  23. #include "wire/Error.h"
  24. /**
  25. * OSX and BSD is expect you to send the platform dependent address family type
  26. * rather than the ethertype, this InterfaceWrapper converts AF_INET and AF_INET6 to the
  27. * corrisponding ethertypes and back.
  28. */
  29. struct BSDMessageTypeWrapper_pvt
  30. {
  31. struct BSDMessageTypeWrapper pub;
  32. uint16_t afInet_be;
  33. uint16_t afInet6_be;
  34. struct Log* logger;
  35. Identity
  36. };
  37. static Iface_DEFUN receiveMessage(Message_t* msg, struct Iface* wireSide)
  38. {
  39. struct BSDMessageTypeWrapper_pvt* ctx =
  40. Identity_containerOf(wireSide, struct BSDMessageTypeWrapper_pvt, pub.wireSide);
  41. if (Message_getLength(msg) < 4) { return Error(msg, "RUNT"); }
  42. uint16_t afType_be = ((uint16_t*) Message_bytes(msg))[1];
  43. uint16_t ethertype = 0;
  44. if (afType_be == ctx->afInet_be) {
  45. ethertype = Ethernet_TYPE_IP4;
  46. } else if (afType_be == ctx->afInet6_be) {
  47. ethertype = Ethernet_TYPE_IP6;
  48. } else {
  49. Log_debug(ctx->logger, "Message of unhandled aftype [0x%04x]",
  50. Endian_bigEndianToHost16(afType_be));
  51. return Error(msg, "INVALID");
  52. }
  53. ((uint16_t*) Message_bytes(msg))[0] = 0;
  54. ((uint16_t*) Message_bytes(msg))[1] = ethertype;
  55. return Iface_next(&ctx->pub.inside, msg);
  56. }
  57. static Iface_DEFUN sendMessage(Message_t* msg, struct Iface* inside)
  58. {
  59. struct BSDMessageTypeWrapper_pvt* ctx =
  60. Identity_containerOf(inside, struct BSDMessageTypeWrapper_pvt, pub.inside);
  61. Assert_true(Message_getLength(msg) >= 4);
  62. uint16_t ethertype = ((uint16_t*) Message_bytes(msg))[1];
  63. uint16_t afType_be = 0;
  64. if (ethertype == Ethernet_TYPE_IP6) {
  65. afType_be = ctx->afInet6_be;
  66. } else if (ethertype == Ethernet_TYPE_IP4) {
  67. afType_be = ctx->afInet_be;
  68. } else {
  69. Assert_true(!"Unsupported ethertype");
  70. }
  71. ((uint16_t*) Message_bytes(msg))[0] = 0;
  72. ((uint16_t*) Message_bytes(msg))[1] = afType_be;
  73. return Iface_next(&ctx->pub.wireSide, msg);
  74. }
  75. struct BSDMessageTypeWrapper* BSDMessageTypeWrapper_new(struct Allocator* alloc, struct Log* log)
  76. {
  77. struct BSDMessageTypeWrapper_pvt* context =
  78. Allocator_calloc(alloc, sizeof(struct BSDMessageTypeWrapper_pvt), 1);
  79. Identity_set(context);
  80. context->pub.wireSide.send = receiveMessage;
  81. context->pub.inside.send = sendMessage;
  82. context->afInet6_be = Endian_hostToBigEndian16(Sockaddr_AF_INET6);
  83. context->afInet_be = Endian_hostToBigEndian16(Sockaddr_AF_INET);
  84. context->logger = log;
  85. return &context->pub;
  86. }