• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

ibrcommon/ibrcommon/net/MulticastSocket.cpp

Go to the documentation of this file.
00001 /*
00002  * MulticastSocket.cpp
00003  *
00004  *  Created on: 28.06.2010
00005  *      Author: morgenro
00006  */
00007 
00008 #include "ibrcommon/config.h"
00009 #include "ibrcommon/net/MulticastSocket.h"
00010 #include <string.h>
00011 
00012 #ifndef HAVE_BZERO
00013 #define bzero(s,n) (memset((s), '\0', (n)), (void) 0)
00014 #endif
00015 
00016 namespace ibrcommon
00017 {
00018         MulticastSocket::MulticastSocket()
00019          : udpsocket(0)
00020         {
00021                 int val = 1;
00022                 if ( ::setsockopt(_socket, IPPROTO_IP, IP_MULTICAST_LOOP, (const char *)&val, sizeof(val)) < 0 )
00023                 {
00024                         throw SocketException("MulticastSocket: setsockopt(IP_MULTICAST_LOOP)");
00025                 }
00026 
00027                 u_char ttl = 255; // Multicast TTL
00028                 if ( ::setsockopt(_socket, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0 )
00029                 {
00030                         throw SocketException("MulticastSocket: setsockopt(IP_MULTICAST_TTL)");
00031                 }
00032 
00033                 u_char ittl = 255; // IP TTL
00034                 if ( ::setsockopt(_socket, IPPROTO_IP, IP_TTL, &ittl, sizeof(ittl)) < 0 ) {
00035                         throw SocketException("MulticastSocket: setsockopt(IP_TTL)");
00036                 }
00037         }
00038 
00039         MulticastSocket::~MulticastSocket()
00040         {
00041         }
00042 
00043         bool MulticastSocket::isMulticast(std::string address)
00044         {
00045                 struct sockaddr_in destination;
00046                 bzero(&destination, sizeof(destination));
00047 
00048                 // convert given address
00049                 if (inet_pton(AF_INET, address.c_str(), &destination.sin_addr) <= 0)
00050                 {
00051                         throw SocketException("MulticastSocket: can not parse address " + address);
00052                 }
00053 
00054                 // check if address is in a multicast range
00055                 uint32_t haddr = ntohl((uint32_t&)destination.sin_addr);
00056 
00057                 return (IN_MULTICAST(haddr));
00058         }
00059 
00060         void MulticastSocket::setInterface(const NetInterface &iface)
00061         {
00062                 struct ip_mreq imr;
00063                 ::memset(&imr, 0, sizeof(ip_mreq));
00064 
00065                 // set interface address
00066                 iface.getAddress(&imr.imr_interface);
00067 
00068                 if ( ::setsockopt(_socket, IPPROTO_IP, IP_MULTICAST_IF, (char *)&imr.imr_interface.s_addr, sizeof(imr.imr_interface.s_addr)) < 0 )
00069                 {
00070                         throw SocketException("MulticastSocket: cannot set default interface");
00071                 }
00072         }
00073 
00074         void MulticastSocket::bind(int port)
00075         {
00076                 ::memset(&_sockaddr, 0, sizeof(_sockaddr));
00077                 _sockaddr.sin_family = AF_INET;
00078                 _sockaddr.sin_port = htons(port);
00079 
00080                 if ( ::bind(_socket, (struct sockaddr *) &_sockaddr, sizeof(_sockaddr)) < 0 )
00081                 {
00082                         throw SocketException("MulticastSocket: cannot bind socket");
00083                 }
00084         }
00085 
00086         void MulticastSocket::joinGroup(std::string group)
00087         {
00088                 struct ip_mreq imr;
00089                 ::memset(&imr, 0, sizeof(ip_mreq));
00090 
00091                 if (inet_pton(AF_INET, group.c_str(), &imr.imr_multiaddr) <= 0)
00092                 {
00093                         throw SocketException("MulticastSocket: can not parse address " + group);
00094                 }
00095 
00096                 if ( ::setsockopt(_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&imr, sizeof(struct ip_mreq)) < 0)
00097                 {
00098                         throw SocketException("MulticastSocket: setsockopt(IP_ADD_MEMBERSHIP)");
00099                 }
00100         }
00101 
00102         void MulticastSocket::joinGroup(std::string group, const NetInterface &iface)
00103         {
00104                 struct ip_mreq imr;
00105                 ::memset(&imr, 0, sizeof(ip_mreq));
00106 
00107                 if (inet_pton(AF_INET, group.c_str(), &imr.imr_multiaddr) <= 0)
00108                 {
00109                         throw SocketException("MulticastSocket: can not parse address " + group);
00110                 }
00111 
00112                 // set interface address
00113                 iface.getAddress(&imr.imr_interface);
00114 
00115                 if ( ::setsockopt(_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&imr, sizeof(struct ip_mreq)) < 0)
00116                 {
00117                         throw SocketException("MulticastSocket: setsockopt(IP_ADD_MEMBERSHIP)");
00118                 }
00119         }
00120 
00121         void MulticastSocket::leaveGroup(std::string group)
00122         {
00123                 struct ip_mreq imr;
00124                 ::memset(&imr, 0, sizeof(ip_mreq));
00125 
00126                 if (inet_pton(AF_INET, group.c_str(), &imr.imr_multiaddr) <= 0)
00127                 {
00128                         throw SocketException("MulticastSocket: can not parse address " + group);
00129                 }
00130 
00131                 if ( ::setsockopt(_socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char *)&imr, sizeof(struct ip_mreq)) < 0)
00132                 {
00133                         throw SocketException("MulticastSocket: setsockopt(IP_DROP_MEMBERSHIP)");
00134                 }
00135         }
00136 
00137         void MulticastSocket::leaveGroup(std::string group, const NetInterface &iface)
00138         {
00139                 struct ip_mreq imr;
00140                 ::memset(&imr, 0, sizeof(ip_mreq));
00141 
00142                 if (inet_pton(AF_INET, group.c_str(), &imr.imr_multiaddr) <= 0)
00143                 {
00144                         throw SocketException("MulticastSocket: can not parse address " + group);
00145                 }
00146 
00147                 // set interface address
00148                 iface.getAddress(&imr.imr_interface);
00149 
00150                 if ( ::setsockopt(_socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char *)&imr, sizeof(struct ip_mreq)) < 0)
00151                 {
00152                         throw SocketException("MulticastSocket: setsockopt(IP_ADD_MEMBERSHIP)");
00153                 }
00154         }
00155 }

Generated on Thu Nov 11 2010 09:49:47 for IBR-DTNSuite by  doxygen 1.7.1