/*
- * $Id: config.c,v 1.13.6.1 2004-01-10 08:09:12 bfernhomberg Exp $
+ * $Id: config.c,v 1.13.6.2 2004-01-15 06:34:15 bfernhomberg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include "rtmp.h"
#include "zip.h"
#include "list.h"
+#include "main.h"
#ifndef IFF_SLAVE /* a little backward compatibility */
#define IFF_SLAVE 0
#endif /* IFF_SLAVE */
-int router(), dontroute(), seed(), phase(), net(), addr(), zone();
+int router(), dontroute(), seed(), phase(), net(), addr(), zone(), noallmulti();
static struct param {
char *p_name;
{ "net", net },
{ "addr", addr },
{ "zone", zone },
+ { "noallmulti", noallmulti }
};
#define ARGV_CHUNK_SIZE 128
if ( iface->i_flags & IFACE_DONTROUTE) {
fprintf( newconf, " -dontroute");
}
+ if ( !(iface->i_flags & IFACE_ALLMULTI)) {
+ fprintf( newconf, " -noallmulti");
+ }
fprintf( newconf, " -phase %d",
( iface->i_flags & IFACE_PHASE1 ) ? 1 : 2 );
fprintf(stderr, "Can't configure multicast.\n");
goto read_conf_err;
}
+
#endif /* __svr4__ */
if (( niface = newiface( argv[ 0 ] )) == NULL ) {
goto read_conf_err;
}
+#ifdef linux
+ /* Don't set interface to allmulti if it already is, or -noallmulti was given */
+ if ((ifr.ifr_flags & IFF_ALLMULTI))
+ niface->i_flags |= IFACE_WASALLMULTI;
+
+ if ((niface->i_flags & IFACE_ALLMULTI) && !(niface->i_flags & IFACE_WASALLMULTI))
+ ifsetallmulti(ifr.ifr_name, 1);
+#endif
+
if ( interfaces == NULL ) {
interfaces = niface;
} else {
return -1;
}
+int noallmulti( iface, av )
+ struct interface *iface;
+ char **av;
+{
+ /* Linux specific, no effect on other platforms */
+ iface->i_flags &= !IFACE_ALLMULTI;
+
+ return (1);
+}
+
/*ARGSUSED*/
int router( iface, av )
struct interface *iface;
niface->i_caddr.sat_len = sizeof( struct sockaddr_at );
#endif /* BSD4_4 */
niface->i_caddr.sat_family = AF_APPLETALK;
+#ifdef linux
+ niface->i_flags = IFACE_ALLMULTI;
+#endif
return( niface );
}
/*
- * $Id: interface.h,v 1.3 2001-07-31 19:50:14 srittau Exp $
+ * $Id: interface.h,v 1.3.14.1 2004-01-15 06:34:15 bfernhomberg Exp $
* Copyright (c) 1990,1992 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
*/
do routing. */
#define IFACE_DONTROUTE 0x200 /* don't route this interface */
#define IFACE_ISROUTER 0x400 /* act as a router. */
+#define IFACE_ALLMULTI 0x800 /* set allmulti on this interface, linux only */
+#define IFACE_WASALLMULTI 0x1000 /* don't unset allmulti on this interface on shutdown, linux only */
#define UNSTABLE 2
#define STABLE 0
/*
- * $Id: main.c,v 1.17.8.1 2004-01-10 08:09:12 bfernhomberg Exp $
+ * $Id: main.c,v 1.17.8.2 2004-01-15 06:34:15 bfernhomberg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
ntohs(iface->i_addr.sat_addr.s_net),
iface->i_addr.sat_addr.s_node, strerror(errno));
}
+#ifdef linux
+ if (!(iface->i_flags & IFACE_WASALLMULTI) && (iface->i_flags & IFACE_ALLMULTI))
+ ifsetallmulti(iface->i_name, 0);
+#endif /* linux */
}
#endif /* SOPCDOFADDR */
nfds++;
}
+int ifsetallmulti ( iname, set )
+const char *iname;
+int set;
+{
+ int sock;
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+
+ if (( sock = socket( AF_APPLETALK, SOCK_DGRAM, 0 )) < 0 ) {
+ return( -1 );
+ }
+
+ /* get interface config */
+ strncpy(ifr.ifr_name, iname, sizeof(ifr.ifr_name));
+ if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
+ close(sock);
+ return (-1);
+ }
+
+ /* should we set or unset IFF_ALLMULTI */
+ if (set)
+ ifr.ifr_flags |= IFF_ALLMULTI;
+ else
+ ifr.ifr_flags &= ~IFF_ALLMULTI;
+
+ /* set interface config */
+ strncpy(ifr.ifr_name, iname, sizeof(ifr.ifr_name));
+ if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
+ close(sock);
+ return -1;
+ }
+
+ close(sock);
+ return (0);
+}
+
int ifconfig( iname, cmd, sa )
const char *iname;
unsigned long cmd;
/*
- * $Id: main.h,v 1.3 2001-06-25 20:13:45 rufustfirefly Exp $
+ * $Id: main.h,v 1.3.14.1 2004-01-15 06:34:15 bfernhomberg Exp $
*/
#ifndef ATALKD_MAIN_H
#define ATALKD_MAIN_H
#include <sys/cdefs.h>
+#include "config.h"
int ifconfig __P(( const char *, unsigned long, struct sockaddr_at * ));
void setaddr __P(( struct interface *, u_int8_t, u_int16_t,
void bootaddr __P(( struct interface * ));
void dumpconfig __P(( struct interface * ));
+#ifdef linux
+int ifsetallmulti __P(( const char *, int));
+#endif
+
#endif /* ATALKD_MAIN_H */