--- mopd-2.5.3.orig/patches/mopd-2.5.3-mcast.patch
+++ mopd-2.5.3/patches/mopd-2.5.3-mcast.patch
@@ -0,0 +1,430 @@
+diff -up --recursive --new-file mopd-2.5.3.macro/common/device.c mopd-2.5.3/common/device.c
+--- mopd-2.5.3.macro/common/device.c	Thu Oct 25 22:38:36 2001
++++ mopd-2.5.3/common/device.c	Fri Oct 26 00:37:58 2001
+@@ -162,7 +162,17 @@ deviceOpen(ifname, proto, trans)
+ 		p->eaddr[4]= tmp.eaddr[4];
+ 		p->eaddr[5]= tmp.eaddr[5];
+ #endif	/* DEV_NEW_CONF */
+-	
++
++		switch (proto) {
++		case MOP_K_PROTO_RC:
++			pfAddMulti(-1,p->if_name,&rc_mcst[0]);
++			break;
++		case MOP_K_PROTO_DL:
++			pfAddMulti(-1,p->if_name,&dl_mcst[0]);
++			break;
++		default:
++			break;
++		}
+ 	}
+ }
+ 
+diff -up --recursive --new-file mopd-2.5.3.macro/common/pf-linux.c mopd-2.5.3/common/pf-linux.c
+--- mopd-2.5.3.macro/common/pf-linux.c	Fri Oct 26 00:25:14 2001
++++ mopd-2.5.3/common/pf-linux.c	Fri Oct 26 00:38:29 2001
+@@ -30,8 +30,10 @@
+  *
+  */
+ 
++#include <stdlib.h>
+ #include <stdio.h>
+ #include <syslog.h>
++#include <signal.h>
+ #include <sys/types.h>
+ #include <sys/time.h>
+ #include <sys/ioctl.h>
+@@ -92,10 +94,29 @@ struct socklist {
+ 
+ struct ifreq ifr;
+ extern int errno;
+-extern int promisc;
++extern int nomulti;
+ 
+ struct RDS RDS[NUMRDS];
+ 
++struct mcastent {
++  char *interface;
++  u_char addr[6];
++  struct mcastent *next;
++};
++
++struct mcastent *mcastlist = NULL;
++int mcastreg = 0;
++
++void reg_cleanup();
++void sig_cleanup();
++
++volatile sig_atomic_t sig_in_progress = 0;
++void (*hnd_hup)();
++void (*hnd_int)();
++void (*hnd_quit)();
++void (*hnd_segv)();
++void (*hnd_term)();
++
+ /*
+  * establish protocol filter
+  *
+@@ -187,6 +208,33 @@ u_char *addr;
+ }
+ 
+ /*
++ * add an interface, multicast address pair
++ * to the prune-on-exit list
++ *
++ */
++
++void
++pfRegMulti(interface, addr)
++char *interface;
++u_char *addr;
++{
++  struct mcastent **ml = &mcastlist;
++
++  while (*ml != NULL)
++    ml = &((*ml)->next);
++  if ((*ml = malloc(sizeof(struct mcastent))) == NULL) {
++    syslog(LOG_ERR, "pfRegMulti: %s: malloc: %m", interface);
++    exit(1);
++  }
++  (*ml)->next = NULL;
++  if (((*ml)->interface = strdup(interface)) == NULL) {
++    syslog(LOG_ERR, "pfRegMulti: %s: strdup: %m", interface);
++    exit(1);
++  }
++  memcpy(&((*ml)->addr), addr, 6);
++}
++
++/*
+  * add a multicast address to the interface
+  *
+  */
+@@ -200,6 +248,8 @@ u_char *addr;
+   int sock;
+ 
+ #ifdef	USE_SADDMULTI
++  if (nomulti)
++    return(0);
+ 
+   strcpy(ifr.ifr_name, interface);
+ 
+@@ -211,11 +261,6 @@ u_char *addr;
+   }
+ #endif	UPFILT
+ 
+-
+-
+-  ifr.ifr_addr.sa_family = AF_UNSPEC;
+-  bcopy((char *)addr, ifr.ifr_addr.sa_data, 6);
+-
+   /*
+    * open a socket, temporarily, to use for SIOC* ioctls
+    *
+@@ -224,11 +269,24 @@ u_char *addr;
+     syslog(LOG_ERR, "pfAddMulti: %s: socket: %m", interface);
+     return(-1);
+   }
+-  if (ioctl(sock, SIOCADDMULTI, (caddr_t)&ifr) < 0) {
+-    syslog(LOG_ERR, "pfAddMulti: %s: SIOCADDMULTI: %m", interface);
+-    close(sock);
++  if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
++    syslog(LOG_ERR, "pfAddMulti: %s: SIOCGIFFLAGS: %m", interface);
+     return(-1);
+   }
++  if (ifr.ifr_flags & IFF_MULTICAST) {
++    if (!mcastreg) {
++      reg_cleanup();
++      mcastreg = 1;
++    }
++    ifr.ifr_addr.sa_family = AF_UNSPEC;
++    bcopy((char *)addr, ifr.ifr_addr.sa_data, 6);
++    if (ioctl(sock, SIOCADDMULTI, (caddr_t)&ifr) < 0) {
++      syslog(LOG_ERR, "pfAddMulti: %s: SIOCADDMULTI: %m", interface);
++      close(sock);
++      return(-1);
++    } else
++      pfRegMulti(interface, addr);
++  }
+   close(sock);
+ #endif	USE_SADDMULTI
+   return(0);
+@@ -251,9 +309,6 @@ u_char *addr;
+ 
+   strcpy(ifr.ifr_name, interface);
+ 
+-  ifr.ifr_addr.sa_family = AF_UNSPEC;
+-  bcopy((char *)addr, ifr.ifr_addr.sa_data, 6);
+-
+   /*
+    * open a socket, temporarily, to use for SIOC* ioctls
+    *
+@@ -262,11 +317,19 @@ u_char *addr;
+     syslog(LOG_ERR, "pfDelMulti: %s: socket: %m", interface);
+     return(-1);
+   }
+-  if (ioctl(sock, SIOCDELMULTI, (caddr_t)&ifr) < 0) {
+-    syslog(LOG_ERR, "pfDelMulti: %s: SIOCDELMULTI: %m", interface);
+-    close(sock);
++  if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
++    syslog(LOG_ERR, "pfDelMulti: %s: SIOCGIFFLAGS: %m", interface);
+     return(-1);
+   }
++  if (ifr.ifr_flags & IFF_MULTICAST) {
++    ifr.ifr_addr.sa_family = AF_UNSPEC;
++    bcopy((char *)addr, ifr.ifr_addr.sa_data, 6);
++    if (ioctl(sock, SIOCDELMULTI, (caddr_t)&ifr) < 0) {
++      syslog(LOG_ERR, "pfDelMulti: %s: SIOCDELMULTI: %m", interface);
++      close(sock);
++      return(-1);
++    }
++  }
+   close(sock);
+ #endif	USE_SADDMULTI
+ 
+@@ -275,6 +338,26 @@ u_char *addr;
+ }
+ 
+ /*
++ * remove all registered multicast memeberships
++ *
++ */
++
++void
++pfPruneMulti()
++{
++  struct mcastent **ml = &mcastlist;
++
++  if (!mcastreg)
++    return;
++  mcastreg = 0;
++
++  while (*ml != NULL) {
++    pfDelMulti(-1, (*ml)->interface, (*ml)->addr);
++    ml = &((*ml)->next);
++  }
++}
++
++/*
+  * return 1 if ethernet interface capable of multiple opens
+  *
+  */
+@@ -353,6 +436,81 @@ u_char *buf;
+     return(len);
+ 
+   return(-1);
++}
++
++/*
++ * remove all registered multicast memeberships
++ * when killed
++ *
++ */
++
++void
++sig_cleanup(sig)
++int sig;
++{
++  void (*hnd)();
++  if (sig_in_progress)
++    raise(sig);
++  sig_in_progress = 1;
++
++  pfPruneMulti();
++
++  switch(sig) {
++  case SIGHUP:
++    hnd = hnd_hup;
++    break;
++  case SIGINT:
++    hnd = hnd_int;
++    break;
++  case SIGQUIT:
++    hnd = hnd_quit;
++    break;
++  case SIGSEGV:
++    hnd = hnd_segv;
++    break;
++  case SIGTERM:
++    hnd = hnd_term;
++    break;
++  default:
++    hnd = SIG_DFL;
++    break;
++  }
++  signal(sig, hnd);
++  raise(sig);
++}
++
++/*
++ * register multicast clean-up functions
++ *
++ */
++
++void
++reg_cleanup()
++{
++  if (atexit(pfPruneMulti) < 0) {
++    syslog(LOG_ERR, "pfAddMulti: atexit: %m");
++    exit(1);
++  }
++  if ((hnd_hup = signal(SIGHUP, sig_cleanup)) == SIG_IGN) {
++    signal(SIGHUP, SIG_IGN);
++    hnd_hup = SIG_DFL;
++  }
++  if ((hnd_int = signal(SIGINT, sig_cleanup)) == SIG_IGN) {
++    signal(SIGINT, SIG_IGN);
++    hnd_int = SIG_DFL;
++  }
++  if ((hnd_quit = signal(SIGQUIT, sig_cleanup)) == SIG_IGN) {
++    signal(SIGQUIT, SIG_IGN);
++    hnd_quit = SIG_DFL;
++  }
++  if ((hnd_segv = signal(SIGSEGV, sig_cleanup)) == SIG_IGN) {
++    signal(SIGSEGV, SIG_IGN);
++    hnd_segv = SIG_DFL;
++  }
++  if ((hnd_term = signal(SIGTERM, sig_cleanup)) == SIG_IGN) {
++    signal(SIGTERM, SIG_IGN);
++    hnd_term = SIG_DFL;
++  }
+ }
+ 
+ #endif /* __linux__ */
+diff -up --recursive --new-file mopd-2.5.3.macro/mopchk/mopchk.c mopd-2.5.3/mopchk/mopchk.c
+--- mopd-2.5.3.macro/mopchk/mopchk.c	Fri Aug 16 22:47:15 1996
++++ mopd-2.5.3/mopchk/mopchk.c	Fri Oct 26 00:37:58 2001
+@@ -60,7 +60,7 @@ void   mopProcess    __P((struct if_info
+ 
+ int     AllFlag = 0;		/* listen on "all" interfaces  */
+ int	VersionFlag = 0;	/* Show version */
+-int	promisc = 0;		/* promisc mode not needed */
++int	nomulti = 1;		/* multicast mode not needed */
+ char	*Program;
+ char	version[];
+ 
+diff -up --recursive --new-file mopd-2.5.3.macro/mopd/mopd.c mopd-2.5.3/mopd/mopd.c
+--- mopd-2.5.3.macro/mopd/mopd.c	Sun Mar 31 19:21:00 1996
++++ mopd-2.5.3/mopd/mopd.c	Fri Oct 26 00:38:13 2001
+@@ -72,7 +72,7 @@ int	ForegroundFlag = 0;	/* run in foregr
+ int	VersionFlag = 0;	/* print version              */
+ int	Not3Flag = 0;		/* Not MOP V3 messages.       */
+ int	Not4Flag = 0;		/* Not MOP V4 messages.       */
+-int	promisc = 1;		/* Need promisc mode    */
++int	nomulti = 0;		/* Need multicast mode        */
+ char    *Program;
+ 
+ void
+@@ -94,7 +94,7 @@ main(argc, argv)
+ 	if (*Program == '-')
+ 		Program++;
+ 
+-	while ((c = getopt(argc, argv, "34adfv")) != EOF)
++	while ((c = getopt(argc, argv, "34adfmv")) != EOF)
+ 		switch (c) {
+ 			case '3':
+ 				Not3Flag++;
+@@ -111,6 +111,9 @@ main(argc, argv)
+ 			case 'f':
+ 				ForegroundFlag++;
+ 				break;
++			case 'm':
++				nomulti++;
++				break;
+ 			case 'v':
+ 				VersionFlag++;
+ 				break;
+@@ -192,8 +195,8 @@ main(argc, argv)
+ void
+ Usage()
+ {
+-	(void) fprintf(stderr, "usage: %s -a [ -d -f -v ] [ -3 | -4 ]\n",Program);
+-	(void) fprintf(stderr, "       %s [ -d -f -v ] [ -3 | -4 ] interface\n",Program);
++	(void) fprintf(stderr, "usage: %s -a [ -d -f -m -v ] [ -3 | -4 ]\n",Program);
++	(void) fprintf(stderr, "       %s [ -d -f -m -v ] [ -3 | -4 ] interface\n",Program);
+ 	exit(1);
+ }
+ 
+diff -up --recursive --new-file mopd-2.5.3.macro/mopprobe/mopprobe.c mopd-2.5.3/mopprobe/mopprobe.c
+--- mopd-2.5.3.macro/mopprobe/mopprobe.c	Sun Aug 11 22:31:43 1996
++++ mopd-2.5.3/mopprobe/mopprobe.c	Fri Oct 26 00:38:14 2001
+@@ -69,7 +69,7 @@ int     DebugFlag = 0;		/* print debuggi
+ int	Not3Flag = 0;		/* Not MOP V3 messages         */
+ int	Not4Flag = 0;		/* Not MOP V4 messages         */
+ int     oflag = 0;		/* print only once             */
+-int	promisc = 1;		/* Need promisc mode           */
++int	nomulti = 0;		/* Need multicast mode         */
+ char	*Program;
+ 
+ void
+@@ -93,7 +93,7 @@ main(argc, argv)
+ 	openlog(Program, LOG_PID | LOG_CONS, LOG_DAEMON);
+ 
+ 	opterr = 0;
+-	while ((op = getopt(argc, argv, "ado")) != EOF) {
++	while ((op = getopt(argc, argv, "admo")) != EOF) {
+ 		switch (op) {
+ 		case '3':
+ 			Not3Flag++;
+@@ -107,6 +107,9 @@ main(argc, argv)
+ 		case 'd':
+ 			DebugFlag++;
+ 			break;
++		case 'm':
++			nomulti++;
++			break;
+ 		case 'o':
+ 			oflag++;
+ 			break;
+@@ -134,8 +137,8 @@ main(argc, argv)
+ void
+ Usage()
+ {
+-	(void) fprintf(stderr, "usage: %s -a [ -3 | -4 ]\n",Program);
+-	(void) fprintf(stderr, "       %s [ -3 | -4 ] interface\n",Program);
++	(void) fprintf(stderr, "usage: %s -a [ -m ] [ -3 | -4 ]\n",Program);
++	(void) fprintf(stderr, "       %s [ -m ] [ -3 | -4 ] interface\n",Program);
+ 	exit(1);
+ }
+ 
+diff -up --recursive --new-file mopd-2.5.3.macro/moptrace/moptrace.c mopd-2.5.3/moptrace/moptrace.c
+--- mopd-2.5.3.macro/moptrace/moptrace.c	Wed Aug  7 22:48:04 1996
++++ mopd-2.5.3/moptrace/moptrace.c	Fri Oct 26 00:38:16 2001
+@@ -68,7 +68,7 @@ int     AllFlag = 0;		/* listen on "all"
+ int     DebugFlag = 0;		/* print debugging messages    */
+ int	Not3Flag = 0;		/* Ignore MOP V3 messages      */
+ int	Not4Flag = 0;		/* Ignore MOP V4 messages      */ 
+-int	promisc = 1;		/* Need promisc mode           */
++int	nomulti = 0;		/* Need multicast mode         */
+ char	*Program;
+ 
+ void
+@@ -93,7 +93,7 @@ main(argc, argv)
+ 	openlog(Program, LOG_PID | LOG_CONS, LOG_DAEMON);
+ 
+ 	opterr = 0;
+-	while ((op = getopt(argc, argv, "34ad")) != EOF) {
++	while ((op = getopt(argc, argv, "34adm")) != EOF) {
+ 		switch (op) {
+ 		case '3':
+ 			Not3Flag++;
+@@ -107,6 +107,9 @@ main(argc, argv)
+ 		case 'd':
+ 			DebugFlag++;
+ 			break;
++		case 'm':
++			nomulti++;
++			break;
+ 		default:
+ 			Usage();
+ 			/* NOTREACHED */
+@@ -131,8 +134,8 @@ main(argc, argv)
+ void
+ Usage()
+ {
+-	(void) fprintf(stderr, "usage: %s -a [ -d ] [ -3 | -4 ]\n",Program);
+-	(void) fprintf(stderr, "       %s [ -d ] [ -3 | -4 ] interface\n",
++	(void) fprintf(stderr, "usage: %s -a [ -d -m ] [ -3 | -4 ]\n",Program);
++	(void) fprintf(stderr, "       %s [ -d -m ] [ -3 | -4 ] interface\n",
+ 		       Program);
+ 	exit(1);
+ }
