summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h1
-rw-r--r--source3/lib/interface.c22
-rw-r--r--source3/nmbd/nmbd_winsserver.c16
3 files changed, 39 insertions, 0 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 991e4f3e31..0312d25f86 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -102,6 +102,7 @@ int iface_count(void);
BOOL we_are_multihomed(void);
struct interface *get_interface(int n);
struct in_addr *iface_n_ip(int n);
+unsigned iface_hash(void);
struct in_addr *iface_bcast(struct in_addr ip);
struct in_addr *iface_nmask(struct in_addr ip);
struct in_addr *iface_ip(struct in_addr ip);
diff --git a/source3/lib/interface.c b/source3/lib/interface.c
index 7aae803abf..8cc5cfb0b1 100644
--- a/source3/lib/interface.c
+++ b/source3/lib/interface.c
@@ -350,6 +350,28 @@ static struct interface *iface_find(struct in_addr ip)
return NULL;
}
+
+/****************************************************************************
+this function provides a simple hash of the configured interfaces. It is
+used to detect a change in interfaces to tell us whether to discard
+the current wins.dat file.
+Note that the result is independent of the order of the interfaces
+ **************************************************************************/
+unsigned iface_hash(void)
+{
+ unsigned ret = 0;
+ struct interface *i;
+
+ for (i=local_interfaces;i;i=i->next) {
+ unsigned x1 = (unsigned)str_checksum(inet_ntoa(i->ip));
+ unsigned x2 = (unsigned)str_checksum(inet_ntoa(i->nmask));
+ ret ^= (x1 ^ x2);
+ }
+
+ return ret;
+}
+
+
/* these 3 functions return the ip/bcast/nmask for the interface
most appropriate for the given ip address. If they can't find
an appropriate interface they return the requested field of the
diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c
index dfa52a65f8..11e0aaecd6 100644
--- a/source3/nmbd/nmbd_winsserver.c
+++ b/source3/nmbd/nmbd_winsserver.c
@@ -24,6 +24,7 @@
#include "includes.h"
#define WINS_LIST "wins.dat"
+#define WINS_VERSION 1
extern int DEBUGLEVEL;
extern struct in_addr ipzero;
@@ -158,6 +159,8 @@ BOOL initialise_wins(void)
BOOL got_token;
BOOL was_ip;
int i;
+ unsigned hash;
+ int version;
/* Read a line from the wins.dat file. Strips whitespace
from the beginning and end of the line.
@@ -168,6 +171,17 @@ BOOL initialise_wins(void)
if (*line == '#')
continue;
+ if (strncmp(line,"VERSION ", 8) == 0) {
+ if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
+ version != WINS_VERSION ||
+ hash != iface_hash()) {
+ DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
+ fclose(fp);
+ return True;
+ }
+ continue;
+ }
+
ptr = line;
/*
@@ -1561,6 +1575,8 @@ void wins_write_database(void)
}
DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
+
+ fprintf(fp,"VERSION %d %u\n", WINS_VERSION, iface_hash());
for( namerec
= (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );