Patch for miniSAPserver-0.2.3 multicast interface specification

John Wehle <[email protected]> Wed, 9 Jun 2004 00:05:28 -0400 (EDT)
Newsgroups gmane.comp.video.videolan.vls.devel
Message-ID <[email protected]>
Currently you can't select which interface to use for multicast.
This can result in the packets going out the wrong interface if
the host has multiple multicast capable network adapters.  This
patch allows the interface to be specified in sap.cfg and uses
the IP_MULTICAST_IF to select the correct interface.  It's been
tested on FreeBSD 4.10 x86.

-- John Wehle
------------------8<------------------------8<------------------------
*** miniSAPserver/parser.h.ORIGINAL	Sun Aug 10 08:44:18 2003
--- miniSAPserver/parser.h	Sat Jun  5 19:12:11 2004
*************** class Config
*** 42,47 ****
--- 42,48 ----
      void SetType(char*);
      int GetType();
      int GetIPVersion();
+     const char *GetInterface();
      char GetScope();
      vector<Program*> Programs;
  
*************** class Config
*** 49,54 ****
--- 50,56 ----
      string file;
      int ttl;
      int ipversion;
+     char * interface;
      char * scope;
      int type;
      bool daemon;
*** miniSAPserver/parser.cpp.ORIGINAL	Sun Nov  9 19:42:30 2003
--- miniSAPserver/parser.cpp	Sat Jun  5 19:11:43 2004
*************** Config::Config(string f)
*** 47,52 ****
--- 47,53 ----
  {
      file	=	f;
      ttl		=	DEFAULT_TTL;
+     interface	=	NULL;
      scope	=	DEFAULT_SCOPE;
      type	=	TYPE_SAP;
      reverse	=	false;
*************** int Config::GetType()
*** 125,130 ****
--- 126,136 ----
      return type;
  }
  
+ const char *Config::GetInterface()
+ {
+     return interface;
+ }
+ 
  char Config::GetScope()
  {
      return scope[0];
*************** int Config::Parse()
*** 213,218 ****
--- 219,231 ----
          {
              strgeta(line,tline,'=');
              ipversion=atoi(tline);
+         }
+ 
+         /* Set SAP Interface  (interface is a member of config) */
+         if(strstr(line,"interface="))
+         {
+             strgeta(line,tline,'=');
+             interface=strdup(tline);
          }
  
          /* Set SAP IPv6 Scope  (scope is a member of config) */
*** miniSAPserver/broadcast.h.ORIGINAL	Mon Jun 16 06:26:47 2003
--- miniSAPserver/broadcast.h	Sun Jun  6 01:26:20 2004
***************
*** 29,41 ****
  
  class Broadcast {
    public:
!     Broadcast(unsigned int t);
      ~Broadcast();
      int Initv4(void);
      int Initv6(char scope);
      int Send(Message*,int);
  
    private:
      int fd;                   /* File descriptor on the socket */
      struct sockaddr_in addr;    /* IP Address to broadcast to */
      struct sockaddr_in6 addr_v6; /* IPv6 Address to broadcast to */
--- 29,42 ----
  
  class Broadcast {
    public:
!     Broadcast(const char *i, unsigned int t);
      ~Broadcast();
      int Initv4(void);
      int Initv6(char scope);
      int Send(Message*,int);
  
    private:
+     const char *interface;
      int fd;                   /* File descriptor on the socket */
      struct sockaddr_in addr;    /* IP Address to broadcast to */
      struct sockaddr_in6 addr_v6; /* IPv6 Address to broadcast to */
*** miniSAPserver/broadcast.cpp.ORIGINAL	Sat Dec 13 17:38:25 2003
--- miniSAPserver/broadcast.cpp	Sun Jun  6 01:25:37 2004
***************
*** 24,35 ****
--- 24,37 ----
  
  #include <sys/types.h>
  #include <sys/socket.h>
+ #include <net/if.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <time.h>
  #include <string.h>
  #include <stdlib.h>
  #include <stdio.h>
+ #include <sys/ioctl.h>
  #include <unistd.h>
  #include <string>
  #include <vector>
*************** using namespace std;
*** 39,46 ****
  #include "message.h"
  #include "broadcast.h"
  
! Broadcast::Broadcast(unsigned int t)
  {
      port=HELLO_PORT;
      ttl=t;
      return;
--- 41,49 ----
  #include "message.h"
  #include "broadcast.h"
  
! Broadcast::Broadcast(const char *i, unsigned int t)
  {
+     interface=i;
      port=HELLO_PORT;
      ttl=t;
      return;
*************** int Broadcast::Initv4(void)
*** 64,69 ****
--- 67,91 ----
      addr.sin_family 	 = AF_INET;
      addr.sin_addr.s_addr = inet_addr(group);
      addr.sin_port	 = htons(port);
+ 
+     if (interface)
+     {
+         struct ifreq sInterface;
+         struct sockaddr_in sin;
+         strncpy(sInterface.ifr_name, interface, IFNAMSIZ);
+         if (ioctl(fd, SIOCGIFADDR, &sInterface) < 0)
+         {
+             perror("SIOCGIFADDR");
+             return -1;
+         }
+         sin = *(struct sockaddr_in *)&sInterface.ifr_addr;
+         if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
+                        (char *)&sin.sin_addr, sizeof (sin.sin_addr)) )
+         {
+             perror("setsockopt");
+             return -1;
+         }
+     }
  
      if(setsockopt( fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl) ))
      {
*** miniSAPserver/sapserver.cpp.ORIGINAL	Fri Oct 17 14:08:23 2003
--- miniSAPserver/sapserver.cpp	Sun Jun  6 01:14:15 2004
*************** int main(int argc, char *argv[])
*** 131,137 ****
  
          /* Create the broadcast object */
          /* IPv4 is the default behavior */
!         broadcast = new Broadcast(config->GetTTL());
          if(config->GetIPVersion() == 6)
          {
              fprintf(stdout,"+ Using IPv6\n");
--- 131,137 ----
  
          /* Create the broadcast object */
          /* IPv4 is the default behavior */
!         broadcast = new Broadcast(config->GetInterface(),config->GetTTL());
          if(config->GetIPVersion() == 6)
          {
              fprintf(stdout,"+ Using IPv6\n");
-------------------------------------------------------------------------
|   Feith Systems  |   Voice: 1-215-646-8000  |  Email: [email protected]  |
|    John Wehle    |     Fax: 1-215-540-5495  |                         |
-------------------------------------------------------------------------

-- 
This is the vls-devel mailing-list, see http://www.videolan.org/streaming/
To unsubscribe, please read http://developers.videolan.org/lists.html
If you are in trouble, please contact <[email protected]>