[dvblast-devel] udp: add ifname= (BINDTODEVICE) option

Benjamin Cohen git at videolan.org
Mon Sep 29 17:58:50 CEST 2014


dvblast | branch: master | Benjamin Cohen <bencoh at notk.org> | Mon Sep 29 15:11:51 2014 +0200| [e8345e9136e5f8abb45c67a13187eeb529a48511] | committer: Christophe Massiot

udp: add ifname= (BINDTODEVICE) option

Use SO_BINDTODEVICE to bind to a specific interface.
Under Linux, the socket will receive all packets for a given multicast
address, from any interface, even if the interface address is specified.
SO_BINDTODEVICE requires the CAP_NET_RAW capability.

> http://git.videolan.org/gitweb.cgi/dvblast.git/?a=commit;h=e8345e9136e5f8abb45c67a13187eeb529a48511
---

 dvblast.c |    2 +-
 dvblast.h |    1 +
 udp.c     |   21 ++++++++++++++++++++-
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/dvblast.c b/dvblast.c
index f729893..ebd4992 100644
--- a/dvblast.c
+++ b/dvblast.c
@@ -177,7 +177,7 @@ static void config_Defaults( output_config_t *p_config )
     memcpy( p_config->pi_ssrc, pi_ssrc_global, 4 * sizeof(uint8_t) );
 }
 
-static char *config_stropt( char *psz_string )
+char *config_stropt( char *psz_string )
 {
     char *ret, *tmp;
     if ( !psz_string || strlen( psz_string ) == 0 )
diff --git a/dvblast.h b/dvblast.h
index 0caf1b3..7cd981d 100644
--- a/dvblast.h
+++ b/dvblast.h
@@ -275,6 +275,7 @@ void msleep( mtime_t delay );
 void hexDump( uint8_t *p_data, uint32_t i_len );
 struct addrinfo *ParseNodeService( char *_psz_string, char **ppsz_end,
                                    uint16_t i_default_port );
+char *config_stropt( char *psz_string );
 
 uint8_t *psi_pack_section( uint8_t *p_sections, unsigned int *pi_size );
 uint8_t *psi_pack_sections( uint8_t **pp_sections, unsigned int *pi_size );
diff --git a/udp.c b/udp.c
index 0811718..3686286 100644
--- a/udp.c
+++ b/udp.c
@@ -34,6 +34,7 @@
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <net/if.h>
 #include <arpa/inet.h>
 #include <errno.h>
 
@@ -64,6 +65,7 @@ void udp_Open( void )
     int i_if_index = 0;
     in_addr_t i_if_addr = INADDR_ANY;
     int i_mtu = 0;
+    char *psz_ifname = NULL;
 
     char *psz_bind, *psz_string = strdup( psz_udp_src );
     char *psz_save = psz_string;
@@ -109,7 +111,13 @@ void udp_Open( void )
             i_if_index = strtol( ARG_OPTION("ifindex="), NULL, 0 );
         else if ( IS_OPTION("ifaddr=") )
             i_if_addr = inet_addr( ARG_OPTION("ifaddr=") );
-        else
+        else if ( IS_OPTION("ifname=") )
+        {
+            psz_ifname = config_stropt( ARG_OPTION("ifname=") );
+            if (strlen(psz_ifname) >= IFNAMSIZ) {
+                psz_ifname[IFNAMSIZ-1] = '\0';
+            }
+        } else
             msg_Warn( NULL, "unrecognized option %s", psz_string );
 
 #undef IS_OPTION
@@ -229,6 +237,17 @@ void udp_Open( void )
                     msg_Warn( NULL, "couldn't join multicast group (%s)",
                               strerror(errno) );
             }
+#ifdef SO_BINDTODEVICE
+            if (psz_ifname) {
+                if ( setsockopt( i_handle, SOL_SOCKET, SO_BINDTODEVICE,
+                                 psz_ifname, strlen(psz_ifname)+1 ) < 0 ) {
+                    msg_Err( NULL, "couldn't bind to device %s (%s)",
+                             psz_ifname, strerror(errno) );
+                }
+                free(psz_ifname);
+                psz_ifname = NULL;
+            }
+#endif
         }
     }
 



More information about the dvblast-devel mailing list