Advertisement
tifssoft

tun0_changeip.c

Dec 4th, 2017
916
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.23 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <net/if.h>
  6. #include <linux/if_tun.h>
  7. #include <sys/types.h>
  8. #include <sys/socket.h>
  9. #include <sys/ioctl.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12. #include <arpa/inet.h>
  13. #include <sys/select.h>
  14. #include <sys/time.h>
  15. #include <errno.h>
  16. #include <stdarg.h>
  17. #include <netinet/ip.h>
  18. #include <netinet/ip6.h>
  19. /* for IPPROTO_XXX definitions */
  20. #include <netinet/in.h>
  21. /* for TCP header */
  22. #include <netinet/tcp.h>
  23. /* for UDP header */
  24. #include <netinet/udp.h>
  25.  
  26. /* the code snippet below is taken "as is" from the openvpn project, file src/openvpn/proto.h
  27. /* it's used to correct internet checksums for IP, TCP and UDP headers after IP header modifications
  28. /*
  29.  * The following macro is used to update an
  30.  * internet checksum.  "acc" is a 32-bit
  31.  * accumulation of all the changes to the
  32.  * checksum (adding in old 16-bit words and
  33.  * subtracting out new words), and "cksum"
  34.  * is the checksum value to be updated.
  35.  */
  36. #define ADJUST_CHECKSUM(acc, cksum) { \
  37.   int _acc = acc; \
  38.   _acc += (cksum); \
  39.   if (_acc < 0) { \
  40.     _acc = -_acc; \
  41.     _acc = (_acc >> 16) + (_acc & 0xffff); \
  42.     _acc += _acc >> 16; \
  43.     (cksum) = (uint16_t) ~_acc; \
  44.   } else { \
  45.     _acc = (_acc >> 16) + (_acc & 0xffff); \
  46.     _acc += _acc >> 16; \
  47.     (cksum) = (uint16_t) _acc; \
  48.   } \
  49. }
  50.  
  51. #define ADD_CHECKSUM_32(acc, u32) { \
  52.   acc += (u32) & 0xffff; \
  53.   acc += (u32) >> 16;    \
  54. }
  55.  
  56. #define SUB_CHECKSUM_32(acc, u32) { \
  57.   acc -= (u32) & 0xffff; \
  58.   acc -= (u32) >> 16;    \
  59. }
  60.  
  61. /* buffer for reading from tun/tap interface, must be >= 1500 */
  62. #define BUFSIZE 2000
  63.  
  64. int tun_alloc(char *dev)
  65. {
  66.     struct ifreq ifr;
  67.     int fd, err;
  68.  
  69.     if (!dev) {
  70.       return -1;
  71.     }
  72.  
  73.     memset(&ifr, 0, sizeof(ifr));
  74.     /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
  75.      *        IFF_TAP   - TAP device
  76.      *
  77.      *        IFF_NO_PI - Do not provide packet information
  78.      *        IFF_MULTI_QUEUE - Create a queue of multiqueue device
  79.      */
  80.     ifr.ifr_flags = IFF_TUN;
  81.     strcpy(ifr.ifr_name, dev);
  82.  
  83.     if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
  84.        return fd;
  85.  
  86.     err = ioctl(fd, TUNSETIFF, (void *)&ifr);
  87.     if (err) {
  88.        close(fd);
  89.        goto err;
  90.     }
  91.  
  92.     strcpy(dev, ifr.ifr_name);
  93.  
  94.     return fd;
  95. err:
  96.     close(fd);
  97.     return err;
  98. }
  99.  
  100. static int set_if_flags(char *ifname, short flags)
  101. {
  102.   struct ifreq ifr;
  103.   int res = 0;
  104.   ifr.ifr_flags = flags;
  105.  
  106.   strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
  107.  
  108.   int skfd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
  109.  
  110.   res = ioctl(skfd, SIOCSIFFLAGS, &ifr);
  111.   if (res < 0) {
  112.     puts("Interface '%s': Error: SIOCSIFFLAGS failed: %s\n");
  113.   } else {
  114.     puts("Interface '%s': flags set to %04X.\n");
  115.   }
  116.  
  117.   return res;
  118. }
  119.  
  120. int main() {
  121.  
  122.   char *tun_name;
  123.   tun_name = malloc(IFNAMSIZ);
  124.   tun_name[0] = '\0';
  125.  
  126.   int tun_fd = tun_alloc(tun_name);
  127.   if (tun_fd < 0) {
  128.     puts("Try as root");
  129.     exit(1);
  130.   }
  131.  
  132.   if (ioctl(tun_fd, TUNSETPERSIST, 0) < 0) {
  133.     perror("disabling TUNSETPERSIST");
  134.     exit(1);
  135.   }
  136.   printf("Set interface '%s' nonpersistent\n", tun_name);
  137.  
  138.   set_if_flags(tun_name, IFF_UP);
  139.  
  140.   /* For now just hardcode the source and replacement IP addresses */
  141.   struct in_addr tun_ip_input, tun_ip_output;
  142.   if (!inet_aton("10.0.0.1", &tun_ip_input) || !inet_aton("10.0.0.2", &tun_ip_output)) {
  143.     printf("inet_aton() failed!\n");
  144.     exit(1);
  145.   }
  146.  
  147.   struct layer3_frame
  148.   {
  149.       uint16_t flags; // FLAGS from TUN
  150.       uint16_t proto; // PRPTO from TUN
  151.       unsigned char payload[]; // FRAME/PACKET
  152.   } __attribute__((packed));
  153.  
  154.   int nread;
  155.   char buffer[BUFSIZE];
  156.  
  157.   while(1) {
  158.  
  159.     nread = read(tun_fd, buffer, sizeof(buffer));
  160.     if(nread < 0) {
  161.       perror("Reading from interface");
  162.       close(tun_fd);
  163.       exit(1);
  164.     }
  165.  
  166.     /* Do whatever with the data */
  167.     printf("Read %d bytes from device %s\n", nread, tun_name);
  168.  
  169.     struct layer3_frame* l3p = (struct layer3_frame*)(buffer);
  170.     printf("FLAGS %x, PROTO %x\n", l3p->flags, ntohs(l3p->proto));
  171.  
  172.     int ethertype = ntohs(l3p->proto);
  173.     int ipv = 4;
  174.     if (ethertype == 0x800) {
  175.       ipv = 4;
  176.     } else if (ethertype == 0x86DD) {
  177.       ipv = 6;
  178.     } else {
  179.       printf("Unknown ethertype %x", ethertype);
  180.       exit(1);
  181.     }
  182.  
  183.     if (ipv == 4) {
  184.  
  185.       puts("PARSING V4!");
  186.       struct ip* ippacket = (struct ip*)(l3p->payload);
  187.       printf("VER:%d\n", ippacket->ip_v);
  188.       struct in_addr ip_dst = ippacket->ip_dst;
  189.       struct sockaddr_in sin;
  190.       sin.sin_family = AF_INET;
  191.       sin.sin_addr = ip_dst;
  192.  
  193.       printf("The source IP address is %s\n", inet_ntoa(ippacket->ip_src));
  194.       printf("The destination IP address is %s\n", inet_ntoa(ippacket->ip_dst));
  195.  
  196.       /* Switch IP addresses */
  197.       int accumulate = 0;
  198.       if (ippacket->ip_src.s_addr == tun_ip_input.s_addr) {
  199.         /* pre-adjust IP checksum */
  200.         ADD_CHECKSUM_32(accumulate, ippacket->ip_src.s_addr);
  201.         /* change source IP */
  202.         ippacket->ip_src = tun_ip_output;
  203.         /* post-adjust IP checksum */
  204.         SUB_CHECKSUM_32(accumulate, ippacket->ip_src.s_addr);
  205.       }
  206.       else if (ippacket->ip_dst.s_addr == tun_ip_output.s_addr) {
  207.         /* pre-adjust IP checksum */
  208.         ADD_CHECKSUM_32(accumulate, ippacket->ip_dst.s_addr);
  209.         /* change destination IP */
  210.         ippacket->ip_dst = tun_ip_input;
  211.         /* post-adjust IP checksum */
  212.         SUB_CHECKSUM_32(accumulate, ippacket->ip_dst.s_addr);
  213.       }
  214.  
  215.       printf("New source IP address is %s\n", inet_ntoa(ippacket->ip_src));
  216.       printf("New destination IP address is %s\n", inet_ntoa(ippacket->ip_dst));
  217.  
  218.       /* Correct packet checksums */
  219.       ADJUST_CHECKSUM(accumulate, ippacket->ip_sum);
  220.       if (ippacket->ip_p == IPPROTO_TCP &&
  221.           nread >= sizeof(struct layer3_frame) + sizeof(struct ip) + sizeof(struct tcphdr)) {
  222.         struct tcphdr* tcp_hdr = (struct tcphdr*)(l3p->payload + sizeof(struct ip));
  223.         ADJUST_CHECKSUM(accumulate, tcp_hdr->check);
  224.       }
  225.       else if (ippacket->ip_p == IPPROTO_UDP &&
  226.           nread >= sizeof(struct layer3_frame) + sizeof(struct ip) + sizeof(struct udphdr)) {
  227.         struct udphdr* udp_hdr = (struct udphdr*)(l3p->payload + sizeof(struct ip));
  228.         ADJUST_CHECKSUM(accumulate, udp_hdr->check);
  229.       }
  230.  
  231.       /*
  232.       int s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
  233.       int code = sendto (s, ippacket, nread, 0, (struct sockaddr*)&sin, sizeof (sin));
  234.       if (code < 0) {
  235.         perror("Failed to send");
  236.       } else {
  237.         puts("Sent IPV4");
  238.       }
  239.       */
  240.  
  241.     } else if (ipv == 6) {
  242.  
  243.       puts("PARSING V6!");
  244.       const struct ip6_hdr* ippacket = (struct ip6_hdr*)(l3p->payload);
  245.       struct in6_addr ip_dst = ippacket->ip6_dst;
  246.  
  247.       static struct sockaddr_in6 remote;
  248.       remote.sin6_family= AF_INET;
  249.       remote.sin6_addr = ip_dst;
  250.  
  251.       /*
  252.       int s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
  253.       int code = sendto (s, ippacket, nread, 0, (struct sockaddr*)&remote, sizeof (remote));
  254.       if (code < 0) {
  255.         perror("Failed to send");
  256.       } else {
  257.         puts("Sent IPV6");
  258.       }
  259.       */
  260.  
  261.     }
  262.     write(tun_fd, buffer, nread);
  263.  
  264.   }
  265.  
  266.   return 0;
  267.  
  268. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement