pastebin - collaborative debugging

pastebin is a collaborative debugging tool allowing you to share and modify code snippets while chatting on IRC, IM or a message board.

This site is developed to XHTML and CSS2 W3C standards. If you see this paragraph, your browser does not support those standards and you need to upgrade. Visit WaSP for a variety of options.

C++ pastebin - collaborative debugging tool View Help


Posted by ddn on Thu 25 Sep 16:03
report abuse | download | new post

  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. }

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with @@


Remember me so that I can delete my post