Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 74205 Details for
Bug 114694
netkit-rwho- 0.17-r1: rwhod does not work on amd4, does not expire old rwhod entries and does not allow overriding startup flags with /etc/conf.d
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Rwhod debian patch.
netkit-rwho-0.17-debian.patch (text/plain), 22.72 KB, created by
Philippe Troin
on 2005-12-06 21:36:43 UTC
(
hide
)
Description:
Rwhod debian patch.
Filename:
MIME Type:
Creator:
Philippe Troin
Created:
2005-12-06 21:36:43 UTC
Size:
22.72 KB
patch
obsolete
>diff -ruN netkit-rwho-0.17.old/ruptime/ruptime.c netkit-rwho-0.17/ruptime/ruptime.c >--- netkit-rwho-0.17.old/ruptime/ruptime.c 1999-12-12 07:33:39.000000000 -0800 >+++ netkit-rwho-0.17/ruptime/ruptime.c 2005-12-06 21:08:35.000000000 -0800 >@@ -212,7 +212,7 @@ > static char resbuf[32]; > int days, hours, minutes; > >- if (tval < 0 || tval > 999*24*60*60) { >+ if (tval < 0) { > (void)snprintf(resbuf, sizeof(resbuf), "%s ??:??", updown); > return(resbuf); > } >@@ -220,10 +220,10 @@ > hours = minutes / 60; minutes %= 60; > days = hours / 24; hours %= 24; > if (days) >- (void)snprintf(resbuf, sizeof(resbuf), "%s %3d+%02d:%02d", >+ (void)snprintf(resbuf, sizeof(resbuf), "%s %4d+%02d:%02d", > updown, days, hours, minutes); > else >- (void)snprintf(resbuf, sizeof(resbuf), "%s %2d:%02d", >+ (void)snprintf(resbuf, sizeof(resbuf), "%s %2d:%02d", > updown, hours, minutes); > return(resbuf); > } >diff -ruN netkit-rwho-0.17.old/rwho/Makefile netkit-rwho-0.17/rwho/Makefile >--- netkit-rwho-0.17.old/rwho/Makefile 1999-12-12 10:05:05.000000000 -0800 >+++ netkit-rwho-0.17/rwho/Makefile 2005-12-06 21:08:35.000000000 -0800 >@@ -3,8 +3,6 @@ > include ../MCONFIG > include ../MRULES > >-CFLAGS += -I../include >- > rwho: rwho.o > $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ > >diff -ruN netkit-rwho-0.17.old/rwhod/Makefile netkit-rwho-0.17/rwhod/Makefile >--- netkit-rwho-0.17.old/rwhod/Makefile 1999-07-31 23:00:13.000000000 -0700 >+++ netkit-rwho-0.17/rwhod/Makefile 2005-12-06 21:08:35.000000000 -0800 >@@ -3,8 +3,11 @@ > include ../MCONFIG > include ../MRULES > >-CFLAGS += -I../include >-OBJS = rwhod.o daemon.o >+ifneq ($(USE_GLIBC),1) >+CFLAGS += -D_GNU_SOURCE >+endif >+ >+OBJS = rwhod.o > > rwhod: $(OBJS) > $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ >diff -ruN netkit-rwho-0.17.old/rwhod/rwhod.8 netkit-rwho-0.17/rwhod/rwhod.8 >--- netkit-rwho-0.17.old/rwhod/rwhod.8 2000-07-30 16:57:06.000000000 -0700 >+++ netkit-rwho-0.17/rwhod/rwhod.8 2005-12-06 21:08:35.000000000 -0800 >@@ -32,7 +32,10 @@ > .\" from: @(#)rwhod.8 6.5 (Berkeley) 3/16/91 > .\" $Id: rwhod.8,v 1.16 2000/07/30 23:57:06 dholland Exp $ > .\" >-.Dd May 13, 1997 >+.\" Modified by Philippe Troin <phil@fifi.org>: added interface >+.\" options and forwarding. >+ >+.Dd March 10, 1999 > .Dt RWHOD 8 > .Os "Linux NetKit (0.17)" > .Sh NAME >@@ -40,7 +43,8 @@ > .Nd system status server > .Sh SYNOPSIS > .Nm rwhod >-.Op Fl bpa >+.Op Fl bpaf >+.Op -i <if>... > .Op Fl u Ar user > .Sh DESCRIPTION > .Nm Rwhod >@@ -67,22 +71,6 @@ > in the ``rwho'' service specification; see > .Xr services 5 . > .Pp >-If the >-.Fl b >-flag is supplied, only broadcast interfaces, such as ethernets, will >-be used. >-If the >-.Fl p >-flag is supplied, only point-to-point interfaces will be used. If the >-.Fl a >-flag is supplied, or no flags are supplied, all interfaces will be >-used. >-.Pp >-If the >-.Fl u >-flag is supplied, rwhod will run as the specified user instead of as >-root. >-.Pp > The messages sent and received, are of the form: > .Bd -literal -offset indent > struct outmp { >@@ -145,16 +133,78 @@ > .Nm Rwhod > recomputes the system boot time every 30 minutes because on > some (non-Linux) systems it is not a totally reliable process. >+.Sh FLAGS >+If the >+.Fl b >+flag is supplied, only broadcast interfaces, such as ethernets, will >+be used. >+If the >+.Fl p >+flag is supplied, only point-to-point interfaces will be used. If the >+.Fl a >+flag is supplied, or no flags are supplied, all interfaces will be >+used. >+.Pp >+Alternately, you may specify interfaces by name by providing one or >+more >+.Fl i >+options followed by the interface name. >+.Pp >+If the >+.Fl u >+flag is supplied, rwhod will run as the specified user instead of as >+root. >+.Pp >+.Nm Rwhod >+can also forward packets between interfaces if started with >+.Fl f. >+Please read the >+.Xr CAVEATS >+section before enabling >+.Xr rwhod >+forwarding. >+.Sh CAVEATS >+While >+.Xr rwhod >+listens on any interface present on the host, it will only send (or >+forward) to the interfaces determined by the >+.Fl a b p i >+flags. >+.Pp >+When operating in forwarding mode (with >+.Fl f >+), >+.Xr rwhod >+forwards all correct rwhod packets received on an interface to all the >+other interfaces. You can create a broadcast storm if there is a >+loop in your network and all the routers in the loop run in forwarding >+mode. To prevent this from happenning, >+.Xr rwhod >+will shut down forwarding (and log the event to the syslog) if more >+than one >+.Xr rwhod >+packet is forwarded per second on average over the last three >+minutes. If this happens, you must break the loop of forwarding routers. > .Sh SEE ALSO > .Xr rwho 1 , > .Xr ruptime 1 > .Sh BUGS >-There should be a way to relay status information between networks. >+Some kind of proxying feature might be useful if your router doesn't >+run >+.Xr rwhod. >+.Pp > People often interpret the server dying >-or network communtication failures >+or network communication failures > as a machine going down. >+.Pp >+.Xr Rwhod >+doesn't refresh its interface list, which might be useful when using >+.Fl a b p. > .Sh HISTORY > The > .Nm > command appeared in > .Bx 4.2 . >+.Pp >+Philippe Troin <phil@fifi.org> implemented forwarding and interface >+selection flags. >diff -ruN netkit-rwho-0.17.old/rwhod/rwhod.c netkit-rwho-0.17/rwhod/rwhod.c >--- netkit-rwho-0.17.old/rwhod/rwhod.c 2005-12-06 21:08:06.000000000 -0800 >+++ netkit-rwho-0.17/rwhod/rwhod.c 2005-12-06 21:12:57.000000000 -0800 >@@ -29,6 +29,10 @@ > * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > * SUCH DAMAGE. >+ >+ * Modified by Philippe Troin <phil@fifi.org> (added options & implemented >+ * them. >+ > */ > > char copyright[] = >@@ -47,6 +51,7 @@ > #include <signal.h> > #include <sys/ioctl.h> > #include <sys/file.h> >+#include <sys/types.h> > > #include <net/if.h> > #include <netinet/in.h> >@@ -71,10 +76,10 @@ > #include <grp.h> > #include <time.h> > >-#include "daemon.h" >- > #include "../version.h" > >+typedef struct sockaddr_in SA; >+ > #define ENDIAN LITTLE_ENDIAN > > /* >@@ -98,27 +103,44 @@ > static int verify(const char *name); > int getloadavg(double ptr[3], int n); > >+ >+/* This is the list of interface we want to listen on */ >+struct wanted_neigh { >+ struct wanted_neigh *w_next; >+ char *w_ifname; >+ enum { W_USED_NOT, W_USED_ONCE, W_USED_MULTI } w_used; >+}; >+ > /* > * We communicate with each neighbor in > * a list constructed at the time we're > * started up. Neighbors are currently > * directly connected via a hardware interface. > */ >-struct neighbor { >+struct neighbor { > struct neighbor *n_next; > char *n_name; /* interface name */ >- char *n_addr; /* who to send to */ >+ SA *n_myaddr; /* My address on this i/f */ >+ SA *n_mask; /* Netmask on this i/f */ >+ SA *n_dstaddr; /* who to send to */ > int n_addrlen; /* size of address */ > int n_flags; /* should forward?, interface flags */ > }; > >+static struct wanted_neigh *wanted_neigh; > static struct neighbor *neighbors; > static struct servent *sp; > static int sk; >-static int use_pointopoint = 0; >-static int use_broadcast = 0; >+static int use_pointopoint; >+static int use_broadcast; > static int need_init = 1; >-static int child_pid = 0; >+static int child_pid; >+static int use_forwarding; >+static int forwarded_packets; >+ >+/* Max number of packets to forward between each alarm() tick. >+ If this number is exceeded, then the forwarding is switched off. */ >+#define MAX_FWD_PACKETS (AL_INTERVAL) > > #define WHDRSIZE (((caddr_t) &((struct whod *) 0)->wd_we) \ > - ((caddr_t) 0)) >@@ -127,24 +149,48 @@ > static void termhandler(int); > static void sendpacket(struct whod *); > static void getboottime(struct whod *); >+static void forward(const SA *, const struct whod *, int cc); >+static void usage(void); > > int > main(int argc, char *argv[]) > { >+ struct wanted_neigh *wn; >+ int wn_dup; > struct sockaddr_in from; >- struct passwd *pw = 0; >+ struct passwd *pw; > struct stat st; > char path[64]; > char *user = NULL; > int on = 1; > int opt; >+ time_t before; > > if (getuid()) { > fprintf(stderr, "rwhod: not super user\n"); >+ } >+ openlog("rwhod", LOG_PID, LOG_DAEMON); >+ sp = getservbyname("who", "udp"); >+ if (sp == 0) { >+ fprintf(stderr, "rwhod: udp/who: unknown service\n"); >+ exit(1); >+ } >+ if ((sk = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { >+ syslog(LOG_ERR, "socket: %m"); >+ exit(1); >+ } >+ if (setsockopt(sk, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { >+ syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); >+ exit(1); >+ } >+ sine.sin_family = AF_INET; >+ sine.sin_port = sp->s_port; >+ if (bind(sk, (struct sockaddr *)&sine, sizeof(sine)) < 0) { >+ syslog(LOG_ERR, "bind: %m"); > exit(1); > } > >- while ((opt = getopt(argc, argv, "bpau:")) != EOF) { >+ while ((opt = getopt(argc, argv, "bpai:fu:")) != EOF) { > switch (opt) { > case 'b': > use_broadcast = 1; >@@ -156,29 +202,57 @@ > use_broadcast = 1; > use_pointopoint = 1; > break; >+ case 'f': >+ use_forwarding = 1; >+ break; >+ case 'i': >+ wn_dup = 0; >+ for (wn = wanted_neigh; wn; wn = wn->w_next) { >+ if (strcmp(wn->w_ifname, optarg)== 0) { >+ wn_dup = 1; >+ break; >+ } >+ } >+ if (wn_dup) { >+ fprintf(stderr, "rwhod: warning: " >+ "duplicate interface %s in arguments\n", >+ optarg); >+ } else { >+ wn = malloc(sizeof(struct wanted_neigh)); >+ if (wn == NULL) { >+ fprintf(stderr, "rwhod: out of memory\n"); >+ exit(2); >+ } >+ wn->w_next = wanted_neigh; >+ wn->w_ifname = malloc(strlen(optarg)+1); >+ wn->w_used = W_USED_NOT; >+ if (wn->w_ifname == NULL) { >+ fprintf(stderr, "rwhod: out of memory\n"); >+ exit(2); >+ } >+ strcpy(wn->w_ifname, optarg); >+ wanted_neigh = wn; >+ } >+ break; > case 'u': > user = optarg; > break; > case '?': > default: >- fprintf(stderr, "usage: rwhod [-bpa] [-u user]\n"); >- exit(1); >- break; >+ usage(); > } > } > if (optind<argc) { >- fprintf(stderr, "usage: rwhod [-bpa] [-u user]\n"); >- exit(1); >+ usage(); > } >- if (!use_pointopoint && !use_broadcast) { >+ if (!use_pointopoint && !use_broadcast && !wanted_neigh) { > /* use none is nonsensical; default to all */ > use_pointopoint = 1; > use_broadcast = 1; > } >- >- sp = getservbyname("who", "udp"); >- if (sp == 0) { >- fprintf(stderr, "rwhod: udp/who: unknown service\n"); >+ if ((use_pointopoint || use_broadcast) && wanted_neigh) { >+ fprintf(stderr, "rwhod: cannot specify both -i and one of -b " >+ "-p -a\n"); > exit(1); > } > #ifndef DEBUG >@@ -190,26 +264,33 @@ > exit(1); > } > (void) signal(SIGHUP, huphandler); >- openlog("rwhod", LOG_PID, LOG_DAEMON); >- >- if ((sk = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { >- syslog(LOG_ERR, "socket: %m"); >- exit(1); >- } >- if (setsockopt(sk, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { >- syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); >- exit(1); >- } >- sine.sin_family = AF_INET; >- sine.sin_port = sp->s_port; >- if (bind(sk, (struct sockaddr *)&sine, sizeof(sine)) < 0) { >- syslog(LOG_ERR, "bind: %m"); >- exit(1); >- } > > (void) umask(022); > > signal(SIGTERM, termhandler); >+ >+ if (user) { >+ /* We have to drop privs in two steps--first get the >+ * account info, then drop privs after chroot */ >+ if ((pw = getpwnam(user)) == NULL) { >+ syslog(LOG_ERR, "unknown user: %s", user); >+ exit(1); >+ } >+ >+ /* Now drop privs */ >+ if (pw->pw_uid) { >+ if (setgroups(1, &pw->pw_gid) < 0 >+ || setgid(pw->pw_gid) < 0 >+ || setuid(pw->pw_uid) < 0) { >+ syslog(LOG_ERR,"failed to drop privilege: %m"); >+ exit(1); >+ } >+ } >+ } >+ >+ if (!configure(sk)) >+ exit(1); >+ > child_pid = fork(); > if (child_pid < 0) { > syslog(LOG_ERR, "fork: %m"); >@@ -220,35 +301,15 @@ > exit(0); > } > >- /* We have to drop privs in two steps--first get the >- * account info, then drop privs after chroot */ >- if (user && (pw = getpwnam(user)) == NULL) { >- syslog(LOG_ERR, "unknown user: %s", user); >- exit(1); >- } >- >- /* Chroot to the spool directory >- * (note this is already our $cwd) */ >- if (chroot(_PATH_RWHODIR) < 0) { >- syslog(LOG_ERR, "chroot(%s): %m", _PATH_RWHODIR); >- kill(child_pid, SIGTERM); >- exit(1); >- } >- >- /* Now drop privs */ >- if (pw) { >- if (setgroups(1, &pw->pw_gid) < 0 >- || setgid(pw->pw_gid) < 0 >- || setuid(pw->pw_uid) < 0) { >- syslog(LOG_ERR, "failed to drop privilege: %m"); >- exit(1); >- } >- } >- >+ before = 0; > for (;;) { > struct whod wd; > int cc, whod; >+#ifdef __GLIBC__ >+ socklen_t len = sizeof(from); >+#else > size_t len = sizeof(from); >+#endif > > memset(&wd, 0, sizeof(wd)); > cc = recvfrom(sk, (char *)&wd, sizeof(struct whod), 0, >@@ -262,6 +323,12 @@ > syslog(LOG_WARNING, "packet too small"); > continue; > } >+ if (cc < WHDRSIZE) { >+ syslog(LOG_WARNING, "packet too small"); >+ continue; >+ } >+ if (cc < WHDRSIZE) >+ continue; > if (from.sin_port != sp->s_port) { > syslog(LOG_WARNING, "%d: bad from port", > ntohs(from.sin_port)); >@@ -271,14 +338,24 @@ > continue; > if (wd.wd_type != WHODTYPE_STATUS) > continue; >+ >+ if (use_forwarding) { >+ time_t now = time(NULL); >+ if ((uintmax_t) (now - before) >= AL_INTERVAL) { >+ before = now; >+ forwarded_packets = 0; >+ } >+ forward(&from, &wd, cc); >+ } >+ > /* > * Ensure null termination of the name within the packet. > * Otherwise we might overflow or read past the end. > */ > wd.wd_hostname[sizeof(wd.wd_hostname)-1] = 0; > if (!verify(wd.wd_hostname)) { >- syslog(LOG_WARNING, "malformed host name from %x", >- from.sin_addr.s_addr); >+ syslog(LOG_WARNING, "malformed host name from %s", >+ inet_ntoa(from.sin_addr)); > continue; > } > snprintf(path, sizeof(path), "whod.%s", wd.wd_hostname); >@@ -350,9 +427,6 @@ > size_t mynamelen; > struct whod mywd; > >- if (!configure(sk)) >- exit(1); >- > /* > * Establish host name as returned by system. > */ >@@ -362,7 +436,7 @@ > } > if ((cp = index(myname, '.')) != NULL) > *cp = '\0'; >- mynamelen = strlen(myname); >+ mynamelen = strlen(myname) + 1; > if (mynamelen > sizeof(mywd.wd_hostname)) > mynamelen = sizeof(mywd.wd_hostname) - 1; > strncpy(mywd.wd_hostname, myname, mynamelen); >@@ -453,7 +527,9 @@ > } > we = wd->wd_we; > for (i = 0; i < nutmps; i++) { >- if (stat(we->we_utmp.out_line, &stb) >= 0) >+ const char *p = we->we_utmp.out_line; >+ >+ if (!strchr(p, ':') && stat(p, &stb) >= 0) > we->we_idle = htonl(now - stb.st_atime); > we++; > } >@@ -465,10 +541,10 @@ > wd->wd_vers = WHODVERSION; > wd->wd_type = WHODTYPE_STATUS; > for (np = neighbors; np != NULL; np = np->n_next) { >- if (sendto(sk, (char *)wd, cc, 0, >- (struct sockaddr *) np->n_addr, np->n_addrlen) < 0) >+ if (sendto(sk, wd, cc, 0, >+ (struct sockaddr *) np->n_dstaddr, np->n_addrlen) < 0) > syslog(LOG_ERR, "sendto(%s): %m", >- inet_ntoa(((struct sockaddr_in *)np->n_addr)->sin_addr)); >+ inet_ntoa(np->n_dstaddr->sin_addr)); > } > > if (nutmps && chdir(_PATH_RWHODIR)) { >@@ -477,6 +553,7 @@ > } > } > >+#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) > /* > * Taken from: > * >@@ -523,6 +600,7 @@ > fclose(fp); > return 0; > } >+#endif /* __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) */ > > > void >@@ -571,7 +649,7 @@ > exit(1); > } > (void) lseek(kmemf, (long)nl[NL_BOOTTIME].n_value, L_SET); >- (void) read(kmemf, (char *)&wd->wd_boottime, >+ (void) read(kmemf, &wd->wd_boottime, > sizeof (wd->wd_boottime)); > wd->wd_boottime = htonl(wd->wd_boottime); > #endif >@@ -589,10 +667,11 @@ > struct ifreq ifreq, *ifr; > struct sockaddr_in *sn; > register struct neighbor *np; >+ struct wanted_neigh *wn; > > ifc.ifc_len = sizeof (buf); > ifc.ifc_buf = buf; >- if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { >+ if (ioctl(s, SIOCGIFCONF, &ifc) < 0) { > syslog(LOG_ERR, "ioctl (get interface configuration)"); > return (0); > } >@@ -605,7 +684,11 @@ > #endif > cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */ > for (cp = buf; cp < cplim; >+#ifdef linux >+ cp += sizeof(struct ifreq)) { >+#else > cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) { >+#endif > ifr = (struct ifreq *)cp; > for (np = neighbors; np != NULL; np = np->n_next) > if (np->n_name && >@@ -619,63 +702,170 @@ > continue; > np->n_name = malloc(strlen(ifr->ifr_name) + 1); > if (np->n_name == NULL) { >- free((char *)np); >+ free(np); > continue; > } > strcpy(np->n_name, ifr->ifr_name); > np->n_addrlen = sizeof (ifr->ifr_addr); >- np->n_addr = malloc(np->n_addrlen); >- if (np->n_addr == NULL) { >+ >+ np->n_dstaddr = malloc(np->n_addrlen); >+ if (np->n_dstaddr == NULL) { >+ free(np->n_name); >+ free(np); >+ continue; >+ } >+ bzero(np->n_dstaddr, np->n_addrlen); >+ >+ np->n_myaddr = malloc(np->n_addrlen); >+ if (np->n_myaddr == NULL) { >+ free(np->n_dstaddr); > free(np->n_name); >- free((char *)np); >+ free(np); > continue; > } >- bcopy((char *)&ifr->ifr_addr, np->n_addr, np->n_addrlen); >- if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { >+ bzero(np->n_myaddr, np->n_addrlen); >+ >+ np->n_mask = malloc(np->n_addrlen); >+ if (np->n_mask == NULL) { >+ free(np->n_myaddr); >+ free(np->n_dstaddr); >+ free(np->n_name); >+ free(np); >+ continue; >+ } >+ bzero(np->n_mask, np->n_addrlen); >+ >+ /* Initialize both my address and destination address by >+ the interface address. The destination address will be >+ overwritten when the interface has IFF_BROADCAST or >+ IFF_POINTOPOINT. */ >+ bcopy(&ifr->ifr_addr, np->n_dstaddr, np->n_addrlen); >+ bcopy(&ifr->ifr_addr, np->n_myaddr, np->n_addrlen); >+ >+ if (ioctl(s, SIOCGIFFLAGS, &ifreq) < 0) { > syslog(LOG_ERR, "ioctl (get interface flags)"); >- free((char *)np); >+ free(np->n_myaddr); >+ free(np->n_dstaddr); >+ free(np->n_name); >+ free(np); > continue; > } > if ((ifreq.ifr_flags & IFF_UP) == 0 || >- (ifreq.ifr_flags & (IFF_BROADCAST|IFF_POINTOPOINT)) == 0) { >- free((char *)np); >+ (ifreq.ifr_flags & (IFF_BROADCAST|IFF_POINTOPOINT)) == 0 || >+ (ifreq.ifr_flags & IFF_LOOPBACK) != 0) { >+ free(np->n_myaddr); >+ free(np->n_dstaddr); >+ free(np->n_name); >+ free(np); > continue; > } >+ if (wanted_neigh) { >+ int found = 0; >+ for (wn = wanted_neigh; wn; wn = wn->w_next) >+ if (strcmp(wn->w_ifname, ifreq.ifr_name)==0) { >+ found = 1; >+ break; >+ } >+ if (!found) { >+ free(np->n_mask); >+ free(np->n_myaddr); >+ free(np->n_dstaddr); >+ free(np->n_name); >+ free(np); >+ continue; >+ } >+ switch (wn->w_used) { >+ case W_USED_NOT: >+ wn->w_used = W_USED_ONCE; >+ break; >+ case W_USED_ONCE: >+ syslog(LOG_ERR, >+ "specified interface %s more than once", >+ wn->w_ifname); >+ wn->w_used = W_USED_MULTI; >+ break; >+ case W_USED_MULTI: >+ /* oh well... don't tell again... */ >+ break; >+ default: >+ syslog(LOG_CRIT, "w_used=%d on %s", >+ wn->w_used, wn->w_ifname); >+ abort(); >+ } >+ } > np->n_flags = ifreq.ifr_flags; > if (np->n_flags & IFF_POINTOPOINT) { >- if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { >+ if (ioctl(s, SIOCGIFDSTADDR, &ifreq) < 0) { > syslog(LOG_ERR, "ioctl (get dstaddr)"); >+ free(np->n_mask); >+ free(np->n_myaddr); >+ free(np->n_dstaddr); >+ free(np->n_name); > free(np); > continue; > } >- if (!use_pointopoint) { >+ if (!wanted_neigh && !use_pointopoint) { >+ free(np->n_mask); >+ free(np->n_myaddr); >+ free(np->n_dstaddr); >+ free(np->n_name); > free(np); > continue; > } > /* we assume addresses are all the same size */ >- bcopy((char *)&ifreq.ifr_dstaddr, >- np->n_addr, np->n_addrlen); >+ bcopy(&ifreq.ifr_dstaddr, np->n_dstaddr, np->n_addrlen); > } > if (np->n_flags & IFF_BROADCAST) { >- if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { >+ if (ioctl(s, SIOCGIFBRDADDR, &ifreq) < 0) { > syslog(LOG_ERR, "ioctl (get broadaddr)"); >+ free(np->n_mask); >+ free(np->n_myaddr); >+ free(np->n_dstaddr); >+ free(np->n_name); > free(np); > continue; > } >- if (!use_broadcast) { >+ if (!wanted_neigh && !use_broadcast) { >+ free(np->n_mask); >+ free(np->n_myaddr); >+ free(np->n_dstaddr); >+ free(np->n_name); > free(np); > continue; > } > /* we assume addresses are all the same size */ >- bcopy((char *)&ifreq.ifr_broadaddr, >- np->n_addr, np->n_addrlen); >+ bcopy(&ifreq.ifr_broadaddr, np->n_dstaddr, np->n_addrlen); >+ >+ /* Get netmask */ >+ if (ioctl(s, SIOCGIFNETMASK, &ifreq) < 0) { >+ syslog(LOG_ERR, "ioctl (get netmask)"); >+ free(np->n_mask); >+ free(np->n_myaddr); >+ free(np->n_dstaddr); >+ free(np->n_name); >+ free(np); >+ continue; >+ } >+ bcopy((char*)&ifreq.ifr_netmask, >+ np->n_mask, np->n_addrlen); > } > /* gag, wish we could get rid of Internet dependencies */ >- sn = (struct sockaddr_in *)np->n_addr; >+ sn = (SA *)np->n_dstaddr; > sn->sin_port = sp->s_port; > np->n_next = neighbors; > neighbors = np; > } >+ >+ /* Check for unfound i/f */ >+ for (wn = wanted_neigh; wn; wn = wn->w_next) >+ if (wn->w_used == W_USED_NOT) >+ syslog(LOG_WARNING, "didn't find interface %s", >+ wn->w_ifname); >+ >+ /* Dump out used i/f */ >+ for (np = neighbors; np; np = np->n_next) >+ syslog(LOG_INFO, "sending on interface %s", np->n_name); >+ > return (1); > } > >@@ -697,7 +887,7 @@ > { > register struct whod *w = (struct whod *)buf; > register struct whoent *we; >- struct sockaddr_in *sn = (struct sockaddr_in *)to; >+ struct sockaddr_in *sn = (SA *)to; > char *interval(); > > printf("sendto %x.%d\n", ntohl(sn->sin_addr.s_addr), ntohs(sn->sin_port)); >@@ -751,3 +941,63 @@ > return (resbuf); > } > #endif >+ >+/* Eventually forward the packet */ >+static void >+forward(const SA *from, const struct whod *wd, int cc) >+{ >+ struct neighbor *np; >+ int looped_back = 0; >+ >+ /* Scan to see if the packet was sent by us */ >+ for (np = neighbors; np != NULL; np = np->n_next) >+ if (from->sin_addr.s_addr == >+ np->n_myaddr->sin_addr.s_addr) { >+ looped_back = 1; >+ break; >+ } >+ >+ if (!looped_back) { >+ sigset_t saved_set; >+ sigset_t mask_set; >+ >+ sigemptyset(&mask_set); >+ sigaddset(&mask_set, SIGALRM); >+ sigprocmask(SIG_BLOCK, &mask_set, &saved_set); >+ >+ if (++forwarded_packets > MAX_FWD_PACKETS) { >+ syslog(LOG_ERR, "too many forward requests, " >+ "disabling forwarding"); >+ use_forwarding = 0; >+ } >+ >+ sigprocmask(SIG_SETMASK, &saved_set, NULL); >+ >+ /* Re-broadcast packet on all interfaces... */ >+ for (np = neighbors; np != NULL; np = np->n_next) { >+ /* .. but do not rebroadcast on the incoming interface */ >+ if (((np->n_flags & IFF_BROADCAST) && >+ (from->sin_addr.s_addr & >+ np->n_mask->sin_addr.s_addr) != >+ (np->n_myaddr->sin_addr.s_addr & >+ np->n_mask->sin_addr.s_addr)) || >+ ((np->n_flags & IFF_POINTOPOINT) && >+ (from->sin_addr.s_addr) != >+ np->n_dstaddr->sin_addr.s_addr)) { >+ if (sendto(sk, wd, cc, 0, >+ (struct sockaddr *)np->n_dstaddr, >+ np->n_addrlen) < 0) >+ syslog(LOG_ERR, >+ "forwarding sendto(%s): %m", >+ inet_ntoa(np->n_dstaddr->sin_addr)); >+ } >+ } >+ } >+} >+ >+static void >+usage() >+{ >+ fprintf(stderr, "usage: rwhod [-bpaf] [-i <ifname>] [-u user]...\n"); >+ exit(1); >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 114694
: 74205 |
74206
|
74207
|
74208
|
74209