VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gvmulticast.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gvmulticast.cpp
19 //
20 
21 #include "gdef.h"
22 #include "gnet.h"
23 #include "gstr.h"
24 #include "gvmulticast.h"
25 #include "gprocess.h"
26 #include <stdexcept>
27 #include <sstream>
28 
29 #ifdef G_UNIX
30 
31 void Gv::Multicast::join( SOCKET fd , const std::string & group )
32 {
33  in_addr a ;
34  a.s_addr = inet_addr( group.c_str() ) ;
35 
36  std::pair<int,int> pair = join_imp( fd , a ) ;
37  if( pair.first < 0 )
38  {
39  std::ostringstream ss ;
40  ss << "multicast join error: " << group << ": " << G::Process::strerror(pair.second) ;
41  throw std::runtime_error( ss.str() ) ;
42  }
43 }
44 
45 void Gv::Multicast::join( SOCKET fd , const in_addr & multiaddr )
46 {
47  std::pair<int,int> pair = join_imp( fd , multiaddr ) ;
48  if( pair.first < 0 )
49  throw std::runtime_error( "multicast join error: " + G::Process::strerror(pair.second) ) ;
50 }
51 
52 std::pair<int,int> Gv::Multicast::join_imp( SOCKET fd , const in_addr & multiaddr )
53 {
54  in_addr any ;
55  any.s_addr = INADDR_ANY ;
56 
57  #if GCONFIG_HAVE_IP_MREQN
58  struct ip_mreqn m ; // man ip(7)
59  m.imr_multiaddr = multiaddr ;
60  m.imr_address = any ;
61  m.imr_ifindex = 0 ;
62  #else
63  struct ip_mreq
64  {
65  struct in_addr imr_multiaddr ;
66  struct in_addr imr_interface ;
67  } ;
68  struct ip_mreq m ; // man ip(4)
69  m.imr_multiaddr = multiaddr ;
70  m.imr_interface = any ;
71  // also set 'multicast=YES' in OpenBSD /etc/rc.conf
72  #endif
73 
74  int rc = setsockopt( fd , IPPROTO_IP , IP_ADD_MEMBERSHIP , reinterpret_cast<void*>(&m) , sizeof(m) ) ;
75  int e = errno ;
76  return std::make_pair(rc,e) ;
77 }
78 
79 
80 
81 
82 #else
83 void Gv::Multicast::join( SOCKET fd , const std::string & group )
84 {
85  throw std::runtime_error( "multicast not implemented" ) ;
86 }
87 void Gv::Multicast::join( SOCKET , const in_addr & )
88 {
89  throw std::runtime_error( "multicast not implemented" ) ;
90 }
91 #endif
92 /// \file gvmulticast.cpp
static void join(SOCKET, const std::string &)
Joins the socket to the multicast group. IPv4 only. Throws on error.
Definition: gvmulticast.cpp:31