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