00001
00002
00003
00004
00005
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;
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;
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
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
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
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
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
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 }