Advertisement
tifssoft

tun0_changeip.diff

Dec 4th, 2017
691
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 4.15 KB | None | 0 0
  1. --- tun0.c  2017-11-29 22:57:44.000000000 +0300
  2. +++ tun0_changeip.c 2017-12-04 17:36:04.000000000 +0300
  3. @@ -16,6 +16,47 @@
  4.  #include <stdarg.h>
  5.  #include <netinet/ip.h>
  6.  #include <netinet/ip6.h>
  7. +/* for IPPROTO_XXX definitions */
  8. +#include <netinet/in.h>
  9. +/* for TCP header */
  10. +#include <netinet/tcp.h>
  11. +/* for UDP header */
  12. +#include <netinet/udp.h>
  13. +
  14. +/* the code snippet below is taken "as is" from the openvpn project, file src/openvpn/proto.h
  15. +/* it's used to correct internet checksums for IP, TCP and UDP headers after IP header modifications
  16. +/*
  17. + * The following macro is used to update an
  18. + * internet checksum.  "acc" is a 32-bit
  19. + * accumulation of all the changes to the
  20. + * checksum (adding in old 16-bit words and
  21. + * subtracting out new words), and "cksum"
  22. + * is the checksum value to be updated.
  23. + */
  24. +#define ADJUST_CHECKSUM(acc, cksum) { \
  25. +  int _acc = acc; \
  26. +  _acc += (cksum); \
  27. +  if (_acc < 0) { \
  28. +    _acc = -_acc; \
  29. +    _acc = (_acc >> 16) + (_acc & 0xffff); \
  30. +    _acc += _acc >> 16; \
  31. +    (cksum) = (uint16_t) ~_acc; \
  32. +  } else { \
  33. +    _acc = (_acc >> 16) + (_acc & 0xffff); \
  34. +    _acc += _acc >> 16; \
  35. +    (cksum) = (uint16_t) _acc; \
  36. +  } \
  37. +}
  38. +
  39. +#define ADD_CHECKSUM_32(acc, u32) { \
  40. +  acc += (u32) & 0xffff; \
  41. +  acc += (u32) >> 16;   \
  42. +}
  43. +
  44. +#define SUB_CHECKSUM_32(acc, u32) { \
  45. +  acc -= (u32) & 0xffff; \
  46. +  acc -= (u32) >> 16;   \
  47. +}
  48.  
  49.  /* buffer for reading from tun/tap interface, must be >= 1500 */
  50.  #define BUFSIZE 2000
  51. @@ -96,6 +137,13 @@
  52.  
  53.    set_if_flags(tun_name, IFF_UP);
  54.  
  55. +  /* For now just hardcode the source and replacement IP addresses */
  56. +  struct in_addr tun_ip_input, tun_ip_output;
  57. +  if (!inet_aton("10.0.0.1", &tun_ip_input) || !inet_aton("10.0.0.2", &tun_ip_output)) {
  58. +    printf("inet_aton() failed!\n");
  59. +    exit(1);
  60. +  }
  61. +
  62.    struct layer3_frame
  63.    {
  64.        uint16_t flags; // FLAGS from TUN
  65. @@ -135,14 +183,50 @@
  66.      if (ipv == 4) {
  67.  
  68.        puts("PARSING V4!");
  69. -      const struct ip* ippacket = (struct ip*)(l3p->payload);
  70. +      struct ip* ippacket = (struct ip*)(l3p->payload);
  71.        printf("VER:%d\n", ippacket->ip_v);
  72.        struct in_addr ip_dst = ippacket->ip_dst;
  73.        struct sockaddr_in sin;
  74.        sin.sin_family = AF_INET;
  75.        sin.sin_addr = ip_dst;
  76.  
  77. -      printf("The IP address is %s\n", inet_ntoa(ip_dst));
  78. +      printf("The source IP address is %s\n", inet_ntoa(ippacket->ip_src));
  79. +      printf("The destination IP address is %s\n", inet_ntoa(ippacket->ip_dst));
  80. +
  81. +      /* Switch IP addresses */
  82. +      int accumulate = 0;
  83. +      if (ippacket->ip_src.s_addr == tun_ip_input.s_addr) {
  84. +        /* pre-adjust IP checksum */
  85. +        ADD_CHECKSUM_32(accumulate, ippacket->ip_src.s_addr);
  86. +        /* change source IP */
  87. +        ippacket->ip_src = tun_ip_output;
  88. +        /* post-adjust IP checksum */
  89. +        SUB_CHECKSUM_32(accumulate, ippacket->ip_src.s_addr);
  90. +      }
  91. +      else if (ippacket->ip_dst.s_addr == tun_ip_output.s_addr) {
  92. +        /* pre-adjust IP checksum */
  93. +        ADD_CHECKSUM_32(accumulate, ippacket->ip_dst.s_addr);
  94. +        /* change destination IP */
  95. +        ippacket->ip_dst = tun_ip_input;
  96. +        /* post-adjust IP checksum */
  97. +        SUB_CHECKSUM_32(accumulate, ippacket->ip_dst.s_addr);
  98. +      }
  99. +
  100. +      printf("New source IP address is %s\n", inet_ntoa(ippacket->ip_src));
  101. +      printf("New destination IP address is %s\n", inet_ntoa(ippacket->ip_dst));
  102. +
  103. +      /* Correct packet checksums */
  104. +      ADJUST_CHECKSUM(accumulate, ippacket->ip_sum);
  105. +      if (ippacket->ip_p == IPPROTO_TCP &&
  106. +          nread >= sizeof(struct layer3_frame) + sizeof(struct ip) + sizeof(struct tcphdr)) {
  107. +        struct tcphdr* tcp_hdr = (struct tcphdr*)(l3p->payload + sizeof(struct ip));
  108. +        ADJUST_CHECKSUM(accumulate, tcp_hdr->check);
  109. +      }
  110. +      else if (ippacket->ip_p == IPPROTO_UDP &&
  111. +          nread >= sizeof(struct layer3_frame) + sizeof(struct ip) + sizeof(struct udphdr)) {
  112. +        struct udphdr* udp_hdr = (struct udphdr*)(l3p->payload + sizeof(struct ip));
  113. +        ADJUST_CHECKSUM(accumulate, udp_hdr->check);
  114. +      }
  115.  
  116.        /*
  117.        int s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement