Guest
Public paste!

ddn

By: a guest | Sep 25th, 2008 | Syntax: C++ | Size: 4.70 KB | Hits: 127 | Expires: Never
Copy text to clipboard
  1. // mcastrouter.cpp : compiled and tested under Windows Server 2008 + VS 2008
  2.  
  3. #include <windows.h>
  4. #include <winsock2.h>
  5. #include <mstcpip.h>
  6. #include <ws2tcpip.h>
  7.  
  8. #define MULTICASTPORT 5050
  9. #define INPUTMULTICAST_IF "192.168.100.4"
  10. #define OUTPUTMULTICAST_IF "172.16.20.3"
  11.  
  12. struct iphdr {
  13.   BYTE h_len:4;
  14.   BYTE version:4;
  15.   UCHAR  iph_tos;
  16.   USHORT  iph_length;
  17.   USHORT  iph_id;
  18.   USHORT  iph_offset;
  19.   UCHAR  iph_ttl;
  20.   UCHAR  ip_p;
  21.   USHORT  iph_xsum;
  22.   in_addr ip_src;
  23.   in_addr ip_dst;
  24. }ip;
  25.  
  26. struct udphdr
  27. {
  28.   USHORT source;
  29.   USHORT dest;
  30.   USHORT len;
  31.   USHORT check;
  32. };  
  33.  
  34. int _tmain(int argc, _TCHAR* argv[])
  35. {
  36.         SOCKET inSock;
  37.         SOCKET outSock;
  38.         SOCKADDR_IN inSockAddr = {0};
  39.         SOCKADDR_IN outSockAddr = {0};
  40.         SOCKADDR_IN iface_addr = {0};
  41.         fd_set rdSet;
  42.         WSADATA data;
  43.         WORD version;
  44.         int ret;
  45.         int siomode = 1;
  46.         int dwBytesReturned;
  47.         struct sockaddr_in saddr;
  48.         socklen_t saddr_size = sizeof(saddr);
  49.         char buf[2000];
  50.         struct sockaddr_in sa;
  51.  
  52.         version = (MAKEWORD(2, 2));
  53.         ret = WSAStartup(version, &data);
  54.         if(ret != 0)
  55.         {
  56.            printf("WinSock not initialised");
  57.            return 1;
  58.         }
  59.  
  60.         inSock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_UDP, NULL, 0, 0);
  61.         outSock = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0);
  62.  
  63.         inSockAddr.sin_family      = AF_INET;
  64.         inSockAddr.sin_addr.s_addr = inet_addr(INPUTMULTICAST_IF);
  65.         inSockAddr.sin_port        = htons(5555); //not used because of RAW socket I/O...
  66.         ret = bind(inSock, (struct sockaddr*)&inSockAddr, sizeof(inSockAddr));
  67.         if(ret == SOCKET_ERROR)
  68.         {
  69.             printf ("bind1() Err: %d\n", WSAGetLastError());
  70.             return 1;
  71.         }
  72.  
  73.         outSockAddr.sin_family      = AF_INET;
  74.         outSockAddr.sin_addr.s_addr = inet_addr(OUTPUTMULTICAST_IF);
  75.         outSockAddr.sin_port        = htons(5050); //faked, used in output UDP packets as "source port"
  76.         ret = bind(outSock, (struct sockaddr*)&outSockAddr, sizeof(outSockAddr));
  77.         if(ret == SOCKET_ERROR)
  78.         {
  79.                 printf ("bind2() Err: %d\n", WSAGetLastError());
  80.                 return 1;
  81.         }
  82.  
  83.         iface_addr.sin_addr.s_addr = inet_addr(OUTPUTMULTICAST_IF);
  84.         ret = setsockopt(outSock, IPPROTO_IP, IP_MULTICAST_IF, (char *)&iface_addr, sizeof(iface_addr));
  85.         if(ret == SOCKET_ERROR)
  86.         {
  87.                 printf("setsockopt() IP_MULTICAST_IF address Err: %d\n", WSAGetLastError());
  88.                 return 1;
  89.         }
  90.         unsigned char ttl = 1;
  91.         ret = setsockopt(outSock, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl));
  92.         if(ret == SOCKET_ERROR)
  93.         {
  94.                 printf("setsockopt() IP_MULTICAST_TTL address Err: %d\n", WSAGetLastError());
  95.                 return 1;
  96.         }
  97.         unsigned char loopback = 1;
  98.         ret = setsockopt(inSock, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopback, sizeof(loopback));
  99.         if(ret == SOCKET_ERROR)
  100.         {
  101.                 printf("setsockopt() IP_MULTICAST_LOOP address Err: %d\n", WSAGetLastError());
  102.                 return 1;
  103.         }
  104.  
  105.         ret = WSAIoctl(inSock, SIO_RCVALL_MCAST, &siomode, sizeof(siomode), NULL, 0, (LPDWORD)&dwBytesReturned, NULL, NULL);
  106.         if(ret == SOCKET_ERROR)
  107.         {
  108.                 printf ("WSAIoctl() Err: %d\n", WSAGetLastError());
  109.                 return 1;
  110.         }
  111.  
  112.         sa.sin_family = AF_INET;
  113.        
  114.         FD_ZERO(&rdSet);
  115.         FD_SET(inSock, &rdSet);
  116.  
  117.         while(1)
  118.         {
  119.                 if(select(0, &rdSet, NULL, NULL, NULL) == 1)
  120.                 {
  121.                         int packet_len = recvfrom(inSock, buf, sizeof(buf), 0, (struct sockaddr *)&saddr, &saddr_size);
  122.                         iphdr* hdr = (iphdr*)buf;
  123.                         if(hdr->ip_p == IPPROTO_UDP)
  124.                         {
  125.                                 udphdr* hdr2 = (udphdr*)(buf+(hdr->h_len*4));
  126.                                 memcpy((void *)&sa.sin_addr, (void *)&hdr->ip_dst, sizeof(in_addr));
  127.                                 sa.sin_port = hdr2->dest;
  128.                                 if(ntohs(hdr2->dest) == MULTICASTPORT)
  129.                                         sendto(outSock, buf+((hdr->h_len*4)+sizeof(udphdr)), packet_len-(hdr->h_len*4)-sizeof(udphdr), 0, (struct sockaddr *)&sa, sizeof(sa));
  130.                         }
  131.  
  132.                 }
  133.                 else {
  134.                    break;
  135.                 }
  136.         }
  137.        
  138.         closesocket(outSock);
  139.         closesocket(inSock);
  140.  
  141.         WSACleanup();
  142.  
  143.         return 0;
  144. }