diff options
-rw-r--r-- | source3/include/proto.h | 1 | ||||
-rw-r--r-- | source3/lib/interface.c | 22 | ||||
-rw-r--r-- | source3/nmbd/nmbd_winsserver.c | 16 |
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 ); |