diff options
-rw-r--r-- | source3/client/client.c | 31 | ||||
-rw-r--r-- | source3/include/includes.h | 4 | ||||
-rw-r--r-- | source3/include/proto.h | 20 | ||||
-rw-r--r-- | source3/lib/interface.c | 421 | ||||
-rw-r--r-- | source3/lib/time.c | 8 | ||||
-rw-r--r-- | source3/lib/util.c | 219 | ||||
-rw-r--r-- | source3/libsmb/nmblib.c | 2 | ||||
-rw-r--r-- | source3/loadparm.h | 1 | ||||
-rw-r--r-- | source3/localnet.h | 4 | ||||
-rw-r--r-- | source3/nameannounce.c | 33 | ||||
-rw-r--r-- | source3/namedb.c | 41 | ||||
-rw-r--r-- | source3/nameelect.c | 62 | ||||
-rw-r--r-- | source3/nameresp.c | 47 | ||||
-rw-r--r-- | source3/nameserv.c | 253 | ||||
-rw-r--r-- | source3/namework.c | 48 | ||||
-rw-r--r-- | source3/nmbd/nmbd.c | 112 | ||||
-rw-r--r-- | source3/nmbsync.c | 7 | ||||
-rw-r--r-- | source3/param/loadparm.c | 113 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 63 | ||||
-rw-r--r-- | source3/smbd/password.c | 4 | ||||
-rw-r--r-- | source3/smbd/server.c | 6 | ||||
-rw-r--r-- | source3/utils/nmblookup.c | 35 |
22 files changed, 836 insertions, 698 deletions
diff --git a/source3/client/client.c b/source3/client/client.c index 5e464ea111..9eb0bf8fd8 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -41,9 +41,7 @@ char *cmdstr=""; BOOL got_pass = False; BOOL connect_as_printer = False; BOOL connect_as_ipc = False; -extern struct in_addr bcast_ip; -static BOOL got_bcast=False; -struct in_addr ipzero; +extern struct in_addr ipzero; char cryptkey[8]; BOOL doencrypt=False; @@ -65,8 +63,6 @@ int max_protocol = PROTOCOL_NT1; time_t newer_than = 0; int archive_level = 0; -extern struct in_addr myip; - extern pstring debugf; extern int DEBUGLEVEL; @@ -3845,14 +3841,14 @@ static BOOL open_sockets(int port ) strcpy(desthost,host); } - DEBUG(3,("Opening sockets\n")); - if (*myname == 0) { get_myname(myname,NULL); strupper(myname); } + DEBUG(3,("Opening sockets\n")); + if (!have_ip) { struct hostent *hp; @@ -3864,17 +3860,12 @@ static BOOL open_sockets(int port ) #ifdef USENMB /* Try and resolve the name with the netbios server */ int bcast; - pstring hs; - struct in_addr ip1, ip2; - - if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3)) != -1) { - set_socket_options (bcast, "SO_BROADCAST"); - if (!got_bcast && get_myname(hs, &ip1)) { - get_broadcast(&ip1, &bcast_ip, &ip2); - } + if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3)) != -1) { + set_socket_options(bcast, "SO_BROADCAST"); - if (name_query(bcast, host, 0x20, True, True, bcast_ip, &dest_ip,0)){ + if (name_query(bcast, host, 0x20, True, True, *iface_bcast(dest_ip), + &dest_ip,0)) { failed = False; } close (bcast); @@ -4181,8 +4172,6 @@ static void usage(char *pname) TimeInit(); charset_initialise(); - ipzero = *interpret_addr2("0.0.0.0"); - pid = getpid(); uid = getuid(); gid = getgid(); @@ -4261,8 +4250,7 @@ static void usage(char *pname) message = True; break; case 'B': - bcast_ip = *interpret_addr2(optarg); - got_bcast = True; + iface_set_default(NULL,optarg,NULL); break; case 'D': strcpy(base_directory,optarg); @@ -4359,7 +4347,8 @@ static void usage(char *pname) DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION)); - get_myname(*myname?NULL:myname,&myip); + load_interfaces(); + get_myname(*myname?NULL:myname,NULL); strupper(myname); if (tar_type) { diff --git a/source3/include/includes.h b/source3/include/includes.h index 5b29b27547..549407bc9e 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -899,10 +899,6 @@ extern char *getsmbpass(char *); #define FD_SETSIZE 255 #endif -#ifndef MAXINT -#define MAXINT ((((unsigned)1)<<(sizeof(int)*8-1))-1) -#endif - #ifndef __STDC__ #define const #endif diff --git a/source3/include/proto.h b/source3/include/proto.h index 8b39c4437b..2c7cb8a126 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -63,6 +63,13 @@ char *DirCacheCheck(char *path,char *name,int snum); void DirCacheFlush(int snum); void fault_setup(void (*fn)()); char *getsmbpass(char *prompt) ; +void load_interfaces(void); +void iface_set_default(char *ip,char *bcast,char *nmask); +BOOL ismyip(struct in_addr ip); +BOOL ismybcast(struct in_addr bcast); +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); int reply_trans(char *inbuf,char *outbuf); int interpret_coding_system(char *str, int def); char *lp_string(char *s); @@ -109,7 +116,8 @@ void announce_master(void); struct work_record *remove_workgroup(struct domain_record *d, struct work_record *work); void expire_browse_cache(time_t t); -struct work_record *find_workgroupstruct(struct domain_record *d, fstring name, BOOL add); +struct work_record *find_workgroupstruct(struct domain_record *d, + fstring name, BOOL add); struct domain_record *find_domain(struct in_addr source_ip); void dump_workgroups(void); struct domain_record *add_domain_entry(struct in_addr source_ip, @@ -164,8 +172,11 @@ void remove_name(struct name_record *n); void dump_names(void); void remove_netbios_name(char *name,int type, enum name_source source, struct in_addr ip); -struct name_record *add_netbios_entry(char *name, int type, int nb_flags, int ttl, - enum name_source source, struct in_addr ip); +struct name_record *add_netbios_entry(char *name, int type, int nb_flags, + int ttl, + enum name_source source, + struct in_addr ip, + BOOL new_only); void remove_name_entry(char *name,int type); void add_name_entry(char *name,int type,int nb_flags); void add_my_names(void); @@ -466,9 +477,6 @@ BOOL string_sub(char *s,char *pattern,char *insert); BOOL do_match(char *str, char *regexp, int case_sig); BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2); void become_daemon(void); -void get_broadcast(struct in_addr *if_ipaddr, - struct in_addr *if_bcast, - struct in_addr *if_nmask); BOOL yesno(char *p); char *fgets_slash(char *s2,int maxlen,FILE *f); int set_filelen(int fd, long len); diff --git a/source3/lib/interface.c b/source3/lib/interface.c new file mode 100644 index 0000000000..a47ef6e47e --- /dev/null +++ b/source3/lib/interface.c @@ -0,0 +1,421 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + multiple interface handling + Copyright (C) Andrew Tridgell 1992-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "loadparm.h" + +extern int DEBUGLEVEL; + +struct in_addr ipzero; +static struct in_addr default_ip; +static struct in_addr default_bcast; +static struct in_addr default_nmask; +static BOOL got_ip=False; +static BOOL got_bcast=False; +static BOOL got_nmask=False; + +static struct interface { + struct interface *next; + struct in_addr ip; + struct in_addr bcast; + struct in_addr nmask; +} *interfaces = NULL; +struct interface *last_iface; + +/**************************************************************************** +calculate the default netmask for an address +****************************************************************************/ +static void default_netmask(struct in_addr *inm, struct in_addr *iad) +{ + unsigned long ad = ntohl(iad->s_addr); + unsigned long nm; + /* + ** Guess a netmask based on the class of the IP address given. + */ + if ( (ad & 0x80000000) == 0 ) { + /* class A address */ + nm = 0xFF000000; + } else if ( (ad & 0xC0000000) == 0x80000000 ) { + /* class B address */ + nm = 0xFFFF0000; + } else if ( (ad & 0xE0000000) == 0xC0000000 ) { + /* class C address */ + nm = 0xFFFFFF00; + } else { + /* class D or E; netmask doesn't make much sense - guess 4 bits */ + nm = 0xFFFFFFF0; + } + inm->s_addr = htonl(nm); +} + + +/**************************************************************************** + get the broadcast address for our address +(troyer@saifr00.ateng.az.honeywell.com) +****************************************************************************/ +static void get_broadcast(struct in_addr *if_ipaddr, + struct in_addr *if_bcast, + struct in_addr *if_nmask) +{ + BOOL found = False; +#ifndef NO_GET_BROADCAST + int sock = -1; /* AF_INET raw socket desc */ + char buff[1024]; + struct ifreq *ifr=NULL; + int i; + +#if defined(EVEREST) + int n_interfaces; + struct ifconf ifc; + struct ifreq *ifreqs; +#elif defined(USE_IFREQ) + struct ifreq ifreq; + struct strioctl strioctl; + struct ifconf *ifc; +#else + struct ifconf ifc; +#endif +#endif + + /* get a default netmask and broadcast */ + default_netmask(if_nmask, if_ipaddr); + +#ifndef NO_GET_BROADCAST + /* Create a socket to the INET kernel. */ +#if USE_SOCKRAW + if ((sock = socket(AF_INET, SOCK_RAW, PF_INET )) < 0) +#else + if ((sock = socket(AF_INET, SOCK_DGRAM, 0 )) < 0) +#endif + { + DEBUG(0,( "Unable to open socket to get broadcast address\n")); + return; + } + + /* Get a list of the configured interfaces */ +#ifdef EVEREST + /* This is part of SCO Openserver 5: The ioctls are no longer part + if the lower level STREAMS interface glue. They are now real + ioctl calls */ + + if (ioctl(sock, SIOCGIFANUM, &n_interfaces) < 0) { + DEBUG(0,( "SIOCGIFANUM: %s\n", strerror(errno))); + } else { + DEBUG(0,( "number of interfaces returned is: %d\n", n_interfaces)); + + ifc.ifc_len = sizeof(struct ifreq) * n_interfaces; + ifc.ifc_buf = (caddr_t) alloca(ifc.ifc_len); + + if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) + DEBUG(0, ( "SIOCGIFCONF: %s\n", strerror(errno))); + else { + ifr = ifc.ifc_req; + + for (i = 0; i < n_interfaces; ++i) { + if (if_ipaddr->s_addr == + ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr.s_addr) { + found = True; + break; + } + } + } + } +#elif defined(USE_IFREQ) + ifc = (struct ifconf *)buff; + ifc->ifc_len = BUFSIZ - sizeof(struct ifconf); + strioctl.ic_cmd = SIOCGIFCONF; + strioctl.ic_dp = (char *)ifc; + strioctl.ic_len = sizeof(buff); + if (ioctl(sock, I_STR, &strioctl) < 0) { + DEBUG(0,( "I_STR/SIOCGIFCONF: %s\n", strerror(errno))); + } else { + ifr = (struct ifreq *)ifc->ifc_req; + + /* Loop through interfaces, looking for given IP address */ + for (i = ifc->ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) { + if (if_ipaddr->s_addr == + (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) { + found = True; + break; + } + } + } +#elif defined(__FreeBSD__) || defined(NETBSD) + ifc.ifc_len = sizeof(buff); + ifc.ifc_buf = buff; + if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { + DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno))); + } else { + ifr = ifc.ifc_req; + /* Loop through interfaces, looking for given IP address */ + i = ifc.ifc_len; + while (i > 0) { + if (if_ipaddr->s_addr == + (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) { + found = True; + break; + } + i -= ifr->ifr_addr.sa_len + IFNAMSIZ; + ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ); + } + } +#else + ifc.ifc_len = sizeof(buff); + ifc.ifc_buf = buff; + if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { + DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno))); + } else { + ifr = ifc.ifc_req; + + /* Loop through interfaces, looking for given IP address */ + for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) { +#ifdef BSDI + if (ioctl(sock, SIOCGIFADDR, ifr) < 0) break; +#endif + if (if_ipaddr->s_addr == + (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) { + found = True; + break; + } + } + } +#endif + + if (!found) { + DEBUG(0,("No interface found for address %s\n", inet_ntoa(*if_ipaddr))); + } else { + /* Get the netmask address from the kernel */ +#ifdef USE_IFREQ + ifreq = *ifr; + + strioctl.ic_cmd = SIOCGIFNETMASK; + strioctl.ic_dp = (char *)&ifreq; + strioctl.ic_len = sizeof(struct ifreq); + if (ioctl(sock, I_STR, &strioctl) < 0) + DEBUG(0,("Failed I_STR/SIOCGIFNETMASK: %s\n", strerror(errno))); + else + *if_nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr; +#else + if (ioctl(sock, SIOCGIFNETMASK, ifr) < 0) + DEBUG(0,("SIOCGIFNETMASK failed\n")); + else + *if_nmask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr; +#endif + + DEBUG(4,("Netmask for %s = %s\n", ifr->ifr_name, + inet_ntoa(*if_nmask))); + } + + /* Close up shop */ + (void) close(sock); + +#endif + + /* sanity check on the netmask */ + { + unsigned long nm = ntohl(if_nmask->s_addr); + if ((nm >> 24) != 0xFF) { + DEBUG(0,("Impossible netmask %s - using defaults\n",inet_ntoa(*if_nmask))); + default_netmask(if_nmask, if_ipaddr); + } + } + + /* derive the broadcast assuming a 1's broadcast, as this is what + all MS operating systems do, we have to comply even if the unix + box is setup differently */ + { + unsigned long ad = ntohl(if_ipaddr->s_addr); + unsigned long nm = ntohl(if_nmask->s_addr); + unsigned long bc = (ad & nm) | (0xffffffff & ~nm); + if_bcast->s_addr = htonl(bc); + } + + DEBUG(4,("Derived broadcast address %s\n", inet_ntoa(*if_bcast))); +} /* get_broadcast */ + + + + +/**************************************************************************** +load a list of network interfaces +****************************************************************************/ +void load_interfaces(void) +{ + char *s = lp_interfaces(); + char *ptr = s; + fstring token; + struct interface *iface; + struct in_addr ip; + + ipzero = *interpret_addr2("0.0.0.0"); + + while (next_token(&ptr,token,NULL)) { + /* parse it into an IP address/netmasklength pair */ + char *p = strchr(token,'/'); + if (p) *p = 0; + + ip = *interpret_addr2(token); + + /* maybe we already have it listed */ + { + struct interface *i; + for (i=interfaces;i;i=i->next) + if (ip_equal(ip,i->ip)) break; + if (i) continue; + } + + iface = (struct interface *)malloc(sizeof(*iface)); + if (!iface) return; + + iface->ip = ip; + + if (p) { + if (strlen(p+1)>2) + iface->nmask = *interpret_addr2(p+1); + else + iface->nmask.s_addr = htonl(~((1<<(32-atoi(p+1)))-1)); + } else { + default_netmask(&iface->nmask,&iface->ip); + } + iface->bcast.s_addr = iface->ip.s_addr | ~iface->nmask.s_addr; + iface->next = NULL; + + if (!interfaces) { + interfaces = iface; + } else { + last_iface->next = iface; + } + last_iface = iface; + DEBUG(1,("Added interface ip=%s ",inet_ntoa(iface->ip))); + DEBUG(1,("bcast=%s ",inet_ntoa(iface->bcast))); + DEBUG(1,("nmask=%s\n",inet_ntoa(iface->nmask))); + } + + if (interfaces) return; + + /* setup a default interface */ + iface = (struct interface *)malloc(sizeof(*iface)); + if (!iface) return; + + if (got_ip) { + iface->ip = default_ip; + } else { + get_myname(NULL,&iface->ip); + } + + if (got_bcast) { + iface->bcast = default_bcast; + } else { + get_broadcast(&iface->ip,&iface->bcast,&iface->nmask); + } + + if (got_nmask) { + iface->nmask = default_nmask; + iface->bcast.s_addr = iface->ip.s_addr | ~iface->nmask.s_addr; + } + + if (iface->bcast.s_addr != (iface->ip.s_addr | ~iface->nmask.s_addr)) { + DEBUG(2,("Warning: inconsistant interface %s\n",inet_ntoa(iface->ip))); + } + + interfaces = last_iface = iface; + + DEBUG(1,("Added interface ip=%s ",inet_ntoa(iface->ip))); + DEBUG(1,("bcast=%s ",inet_ntoa(iface->bcast))); + DEBUG(1,("nmask=%s\n",inet_ntoa(iface->nmask))); +} + + +/**************************************************************************** + override the defaults + **************************************************************************/ +void iface_set_default(char *ip,char *bcast,char *nmask) +{ + if (ip) { + got_ip = True; + default_ip = *interpret_addr2(ip); + } + + if (bcast) { + got_bcast = True; + default_bcast = *interpret_addr2(bcast); + } + + if (nmask) { + got_nmask = True; + default_nmask = *interpret_addr2(nmask); + } +} + + +/**************************************************************************** + check if an IP is one of mine + **************************************************************************/ +BOOL ismyip(struct in_addr ip) +{ + struct interface *i; + for (i=interfaces;i;i=i->next) + if (ip_equal(i->ip,ip)) return True; + return False; +} + +/**************************************************************************** + check if a bcast is one of mine + **************************************************************************/ +BOOL ismybcast(struct in_addr bcast) +{ + struct interface *i; + for (i=interfaces;i;i=i->next) + if (ip_equal(i->bcast,bcast)) return True; + return False; +} + +static struct interface *iface_find(struct in_addr ip) +{ + struct interface *i; + if (zero_ip(ip)) return interfaces; + + for (i=interfaces;i;i=i->next) + if (same_net(i->ip,ip,i->nmask)) return i; + + return interfaces; +} + + +/* these 3 functions return the ip/bcast/nmask for the interface + most appropriate for the given ip address */ + +struct in_addr *iface_bcast(struct in_addr ip) +{ + return(&iface_find(ip)->bcast); +} + +struct in_addr *iface_nmask(struct in_addr ip) +{ + return(&iface_find(ip)->nmask); +} + +struct in_addr *iface_ip(struct in_addr ip) +{ + return(&iface_find(ip)->ip); +} + + diff --git a/source3/lib/time.c b/source3/lib/time.c index 0b6e6df9b0..efcda804c4 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -142,6 +142,10 @@ static int TimeZoneFaster(time_t t) if (t < low) low = TIME_T_MIN; + high = t + MAX_DST_WIDTH/2; + if (high < t) + high = TIME_T_MAX; + /* widen the new entry using two bisection searches */ while (low+60*60 < dst_table[i].start) { if (dst_table[i].start - low > MAX_DST_SKIP*2) @@ -154,10 +158,6 @@ static int TimeZoneFaster(time_t t) low = t; } - high = low + MAX_DST_WIDTH/2; - if (high < t) - high = TIME_T_MAX; - while (high-60*60 > dst_table[i].end) { if (high - dst_table[i].end > MAX_DST_SKIP*2) t = dst_table[i].end + MAX_DST_SKIP; diff --git a/source3/lib/util.c b/source3/lib/util.c index 8c088f306e..6cc9a7e172 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -49,11 +49,6 @@ struct in_addr lastip; /* the last port received from */ int lastport=0; -/* my IP, the broadcast IP and the Netmask */ -struct in_addr myip; -struct in_addr bcast_ip; -struct in_addr Netmask; - int trans_num = 0; /* @@ -2801,216 +2796,6 @@ void become_daemon(void) #endif } -/**************************************************************************** -calculate the default netmask for an address -****************************************************************************/ -static void default_netmask(struct in_addr *inm, struct in_addr *iad) -{ - unsigned long ad = ntohl(iad->s_addr); - unsigned long nm; - /* - ** Guess a netmask based on the class of the IP address given. - */ - if ( (ad & 0x80000000) == 0 ) { - /* class A address */ - nm = 0xFF000000; - } else if ( (ad & 0xC0000000) == 0x80000000 ) { - /* class B address */ - nm = 0xFFFF0000; - } else if ( (ad & 0xE0000000) == 0xC0000000 ) { - /* class C address */ - nm = 0xFFFFFF00; - } else { - /* class D or E; netmask doesn't make much sense - guess 4 bits */ - nm = 0xFFFFFFF0; - } - inm->s_addr = htonl(nm); -} - -/**************************************************************************** - get the broadcast address for our address -(troyer@saifr00.ateng.az.honeywell.com) -****************************************************************************/ -void get_broadcast(struct in_addr *if_ipaddr, - struct in_addr *if_bcast, - struct in_addr *if_nmask) -{ - BOOL found = False; -#ifndef NO_GET_BROADCAST - int sock = -1; /* AF_INET raw socket desc */ - char buff[1024]; - struct ifreq *ifr=NULL; - int i; - -#if defined(EVEREST) - int n_interfaces; - struct ifconf ifc; - struct ifreq *ifreqs; -#elif defined(USE_IFREQ) - struct ifreq ifreq; - struct strioctl strioctl; - struct ifconf *ifc; -#else - struct ifconf ifc; -#endif -#endif - - /* get a default netmask and broadcast */ - default_netmask(if_nmask, if_ipaddr); - -#ifndef NO_GET_BROADCAST - /* Create a socket to the INET kernel. */ -#if USE_SOCKRAW - if ((sock = socket(AF_INET, SOCK_RAW, PF_INET )) < 0) -#else - if ((sock = socket(AF_INET, SOCK_DGRAM, 0 )) < 0) -#endif - { - DEBUG(0,( "Unable to open socket to get broadcast address\n")); - return; - } - - /* Get a list of the configured interfaces */ -#ifdef EVEREST - /* This is part of SCO Openserver 5: The ioctls are no longer part - if the lower level STREAMS interface glue. They are now real - ioctl calls */ - - if (ioctl(sock, SIOCGIFANUM, &n_interfaces) < 0) { - DEBUG(0,( "SIOCGIFANUM: %s\n", strerror(errno))); - } else { - DEBUG(0,( "number of interfaces returned is: %d\n", n_interfaces)); - - ifc.ifc_len = sizeof(struct ifreq) * n_interfaces; - ifc.ifc_buf = (caddr_t) alloca(ifc.ifc_len); - - if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) - DEBUG(0, ( "SIOCGIFCONF: %s\n", strerror(errno))); - else { - ifr = ifc.ifc_req; - - for (i = 0; i < n_interfaces; ++i) { - if (if_ipaddr->s_addr == - ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr.s_addr) { - found = True; - break; - } - } - } - } -#elif defined(USE_IFREQ) - ifc = (struct ifconf *)buff; - ifc->ifc_len = BUFSIZ - sizeof(struct ifconf); - strioctl.ic_cmd = SIOCGIFCONF; - strioctl.ic_dp = (char *)ifc; - strioctl.ic_len = sizeof(buff); - if (ioctl(sock, I_STR, &strioctl) < 0) { - DEBUG(0,( "I_STR/SIOCGIFCONF: %s\n", strerror(errno))); - } else { - ifr = (struct ifreq *)ifc->ifc_req; - - /* Loop through interfaces, looking for given IP address */ - for (i = ifc->ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) { - if (if_ipaddr->s_addr == - (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) { - found = True; - break; - } - } - } -#elif defined(__FreeBSD__) || defined(NETBSD) - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { - DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno))); - } else { - ifr = ifc.ifc_req; - /* Loop through interfaces, looking for given IP address */ - i = ifc.ifc_len; - while (i > 0) { - if (if_ipaddr->s_addr == - (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) { - found = True; - break; - } - i -= ifr->ifr_addr.sa_len + IFNAMSIZ; - ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ); - } - } -#else - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { - DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno))); - } else { - ifr = ifc.ifc_req; - - /* Loop through interfaces, looking for given IP address */ - for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) { -#ifdef BSDI - if (ioctl(sock, SIOCGIFADDR, ifr) < 0) break; -#endif - if (if_ipaddr->s_addr == - (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) { - found = True; - break; - } - } - } -#endif - - if (!found) { - DEBUG(0,("No interface found for address %s\n", inet_ntoa(*if_ipaddr))); - } else { - /* Get the netmask address from the kernel */ -#ifdef USE_IFREQ - ifreq = *ifr; - - strioctl.ic_cmd = SIOCGIFNETMASK; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(sock, I_STR, &strioctl) < 0) - DEBUG(0,("Failed I_STR/SIOCGIFNETMASK: %s\n", strerror(errno))); - else - *if_nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr; -#else - if (ioctl(sock, SIOCGIFNETMASK, ifr) < 0) - DEBUG(0,("SIOCGIFNETMASK failed\n")); - else - *if_nmask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr; -#endif - - DEBUG(2,("Netmask for %s = %s\n", ifr->ifr_name, - inet_ntoa(*if_nmask))); - } - - /* Close up shop */ - (void) close(sock); - -#endif - - /* sanity check on the netmask */ - { - unsigned long nm = ntohl(if_nmask->s_addr); - if ((nm >> 24) != 0xFF) { - DEBUG(0,("Impossible netmask %s - using defaults\n",inet_ntoa(*if_nmask))); - default_netmask(if_nmask, if_ipaddr); - } - } - - /* derive the broadcast assuming a 1's broadcast, as this is what - all MS operating systems do, we have to comply even if the unix - box is setup differently */ - { - unsigned long ad = ntohl(if_ipaddr->s_addr); - unsigned long nm = ntohl(if_nmask->s_addr); - unsigned long bc = (ad & nm) | (0xffffffff & ~nm); - if_bcast->s_addr = htonl(bc); - } - - DEBUG(2,("Derived broadcast address %s\n", inet_ntoa(*if_bcast))); -} /* get_broadcast */ - /**************************************************************************** put up a yes/no prompt @@ -3511,7 +3296,7 @@ struct in_addr *interpret_addr2(char *str) { static struct in_addr ret; unsigned long a = interpret_addr(str); - putip((char *)&ret,(char *)&a); + ret.s_addr = a; return(&ret); } @@ -3731,7 +3516,7 @@ my own panic function - not suitable for general use ********************************************************************/ void ajt_panic(void) { - system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT &"); + system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT"); } #endif diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d82d89f653..e1737cd41c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -21,10 +21,8 @@ */ #include "includes.h" -#include "localnet.h" #include "loadparm.h" -extern struct in_addr myip; extern int DEBUGLEVEL; int num_good_sends = 0; diff --git a/source3/loadparm.h b/source3/loadparm.h index 92c8274767..0e39537c9e 100644 --- a/source3/loadparm.h +++ b/source3/loadparm.h @@ -36,6 +36,7 @@ extern void lp_killunused(BOOL (*snumused)(int )); extern BOOL lp_loaded(void); extern BOOL lp_snum_ok(int iService); extern BOOL lp_manglednames(int iService); +extern char *lp_interfaces(void); extern char *lp_passwordserver(void); extern char *lp_passwd_program(void); extern char *lp_passwd_chat(void); diff --git a/source3/localnet.h b/source3/localnet.h index 7f335e790e..6b2d89c76a 100644 --- a/source3/localnet.h +++ b/source3/localnet.h @@ -1,6 +1,2 @@ -extern struct in_addr myip; -extern struct in_addr bcast_ip; -extern struct in_addr Netmask; - extern int ClientNMB; extern int ClientDGRAM; diff --git a/source3/nameannounce.c b/source3/nameannounce.c index 6b086c9774..197548088b 100644 --- a/source3/nameannounce.c +++ b/source3/nameannounce.c @@ -33,9 +33,6 @@ extern int DEBUGLEVEL; extern BOOL CanRecurse; -extern struct in_addr myip; -extern struct in_addr bcast_ip; -extern struct in_addr Netmask; extern struct in_addr ipzero; extern pstring myname; @@ -84,7 +81,7 @@ void announce_request(struct work_record *work, struct in_addr ip) p = skip_string(p,1); send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf), - myname,work->work_group,0x20,0x0,ip,myip); + myname,work->work_group,0x20,0x1e,ip,*iface_ip(ip)); } @@ -111,7 +108,7 @@ void do_announce_request(char *info, char *to_name, int announce_type, p = skip_string(p,1); send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf), - myname,to_name,from,to,dest_ip,myip); + myname,to_name,from,to,dest_ip,*iface_ip(dest_ip)); } /**************************************************************************** @@ -175,7 +172,8 @@ void announce_backup(void) ClientDGRAM,outbuf, PTR_DIFF(p,outbuf), myname, work->work_group, - 0x0,type,d->bcast_ip,myip); + 0x0,type,d->bcast_ip, + *iface_ip(d->bcast_ip)); } } } @@ -205,7 +203,7 @@ void announce_host(void) { struct work_record *work; - if (!ip_equal(bcast_ip,d->bcast_ip)) + if (!ismybcast(d->bcast_ip)) continue; for (work = d->workgrouplist; work; work = work->next) @@ -231,7 +229,7 @@ void announce_host(void) work->lastannounce_time = t; - if (!ip_equal(bcast_ip,d->bcast_ip)) { + if (!ismybcast(d->bcast_ip)) { stype &= ~(SV_TYPE_POTENTIAL_BROWSER | SV_TYPE_MASTER_BROWSER | SV_TYPE_DOMAIN_MASTER | SV_TYPE_BACKUP_BROWSER | SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_MEMBER); @@ -266,7 +264,7 @@ void announce_host(void) p = p+31; p = skip_string(p,1); - if (ip_equal(bcast_ip,d->bcast_ip)) + if (ismybcast(d->bcast_ip)) { if (AM_MASTER(work)) { @@ -280,7 +278,8 @@ void announce_host(void) send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf, PTR_DIFF(p,outbuf), my_name,work->work_group,0, - 0x1e,d->bcast_ip,myip); + 0x1e,d->bcast_ip, + *iface_ip(d->bcast_ip)); DEBUG(2,("sending domain announce to %s for %s\n", inet_ntoa(d->bcast_ip),work->work_group)); @@ -297,7 +296,8 @@ void announce_host(void) send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf, PTR_DIFF(p,outbuf), - my_name,MSBROWSE,0,0x01,d->bcast_ip,myip); + my_name,MSBROWSE,0,0x01,d->bcast_ip, + *iface_ip(d->bcast_ip)); } else { @@ -309,7 +309,7 @@ void announce_host(void) send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf, PTR_DIFF(p,outbuf), my_name,work->work_group,0,0x1d, - d->bcast_ip,myip); + d->bcast_ip,*iface_ip(d->bcast_ip)); } } } @@ -424,11 +424,10 @@ void announce_master(void) ip = *interpret_addr2(lp_domain_controller()); - if (zero_ip(ip)) - { - ip = bcast_ip; - bcast = True; - } + if (zero_ip(ip)) { + ip = *iface_bcast(d->bcast_ip); + bcast = True; + } DEBUG(2, ("Searching for PDC %s at %s\n", lp_domain_controller(), inet_ntoa(ip))); diff --git a/source3/namedb.c b/source3/namedb.c index 402617ffbd..2e942587be 100644 --- a/source3/namedb.c +++ b/source3/namedb.c @@ -28,14 +28,15 @@ #include "includes.h" #include "smb.h" #include "loadparm.h" -#include "localnet.h" + +extern int ClientNMB; +extern int ClientDGRAM; extern int DEBUGLEVEL; extern time_t StartupTime; extern pstring myname; extern pstring scope; -extern struct in_addr bcast_ip; /* this is our browse master/backup cache database */ struct browse_cache_record *browserlist = NULL; @@ -305,7 +306,8 @@ void expire_browse_cache(time_t t) that it get created/added anyway. this allows us to force entries in lmhosts file to be added. **************************************************************************/ -struct work_record *find_workgroupstruct(struct domain_record *d, fstring name, BOOL add) +struct work_record *find_workgroupstruct(struct domain_record *d, + fstring name, BOOL add) { struct work_record *ret, *work; @@ -323,28 +325,31 @@ struct work_record *find_workgroupstruct(struct domain_record *d, fstring name, return NULL; } - for (ret = d->workgrouplist; ret; ret = ret->next) - { - if (!strcmp(ret->work_group,name)) - { - DEBUG(4, ("found\n")); - return(ret); - } + for (ret = d->workgrouplist; ret; ret = ret->next) { + if (!strcmp(ret->work_group,name)) { + DEBUG(4, ("found\n")); + return(ret); } - - DEBUG(4, ("not found: creating\n")); + } + + if (!add) { + DEBUG(4, ("not found\n")); + return NULL; + } + + DEBUG(4,("not found: creating\n")); if ((work = make_workgroup(name))) { if (lp_preferred_master() && strequal(lp_workgroup(), name) && - ip_equal(d->bcast_ip, bcast_ip)) + ismybcast(d->bcast_ip)) { DEBUG(3, ("preferred master startup for %s\n", work->work_group)); work->needelection = True; work->ElectionCriterion |= (1<<3); } - if (!ip_equal(bcast_ip, d->bcast_ip)) + if (!ismybcast(d->bcast_ip)) { work->needelection = False; } @@ -446,7 +451,8 @@ struct domain_record *add_domain_entry(struct in_addr source_ip, ip = *interpret_addr2("255.255.255.255"); - if (zero_ip(source_ip)) source_ip = bcast_ip; + if (zero_ip(source_ip)) + source_ip = *iface_bcast(source_ip); /* add the domain into our domain database */ if ((d = find_domain(source_ip)) || @@ -516,7 +522,8 @@ struct browse_cache_record *add_browser_entry(char *name, int type, char *wg, b->ip = ip; b->type = type; - if (newentry || ttl < b->sync_time) b->sync_time = ttl; + if (newentry || ttl < b->sync_time) + b->sync_time = ttl; if (newentry) { @@ -576,7 +583,7 @@ struct server_record *add_server_entry(struct domain_record *d, bzero((char *)s,sizeof(*s)); } - if (ip_equal(bcast_ip, d->bcast_ip) && + if (ismybcast(d->bcast_ip) && strequal(lp_workgroup(),work->work_group)) { servertype |= SV_TYPE_LOCAL_LIST_ONLY; diff --git a/source3/nameelect.c b/source3/nameelect.c index 8ceae473a7..a78c8483c5 100644 --- a/source3/nameelect.c +++ b/source3/nameelect.c @@ -27,7 +27,9 @@ #include "includes.h" #include "loadparm.h" -#include "localnet.h" + +extern int ClientNMB; +extern int ClientDGRAM; extern int DEBUGLEVEL; extern pstring scope; @@ -59,7 +61,7 @@ void check_master_browser(void) struct domain_record *d; if (!lastrun) lastrun = t; - if (t < lastrun + 2*60) return; + if (t < lastrun + 5*60) return; lastrun = t; dump_workgroups(); @@ -94,11 +96,13 @@ void browser_gone(char *work_name, struct in_addr ip) if (!work || !d) return; - DEBUG(2,("Forcing election on %s\n",work->work_group)); - if (strequal(work->work_group, lp_workgroup()) && - ip_equal(bcast_ip, d->bcast_ip)) + ismybcast(d->bcast_ip)) { + + DEBUG(2,("Forcing election on %s %s\n", + work->work_group,inet_ntoa(d->bcast_ip))); + /* we can attempt to become master browser */ work->needelection = True; } @@ -116,6 +120,7 @@ void browser_gone(char *work_name, struct in_addr ip) */ } } + /**************************************************************************** send an election packet **************************************************************************/ @@ -144,7 +149,7 @@ void send_election(struct domain_record *d, char *group,uint32 criterion, p = skip_string(p,1); send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf), - name,group,0,0x1e,d->bcast_ip,myip); + name,group,0,0x1e,d->bcast_ip,*iface_ip(d->bcast_ip)); } @@ -188,7 +193,7 @@ static void become_master(struct domain_record *d, struct work_record *work) add_server_entry(d,work,work->work_group,domain_type,0,myname,True); add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True); - if (ip_equal(bcast_ip, d->bcast_ip)) + if (ismybcast(d->bcast_ip)) { /* ask all servers on our local net to announce to us */ announce_request(work, d->bcast_ip); @@ -244,7 +249,8 @@ void run_elections(void) if (work->ElectionCount++ >= 4) { /* I won! now what :-) */ - DEBUG(2,(">>> Won election on %s <<<\n",work->work_group)); + DEBUG(2,(">>> Won election on %s %s <<<\n", + work->work_group,inet_ntoa(d->bcast_ip))); work->RunningElection = False; become_master(d, work); @@ -309,7 +315,7 @@ void process_election(struct packet_struct *p,char *buf) { if (listening_name(work, &dgram->dest_name) && strequal(work->work_group, lp_workgroup()) && - ip_equal(d->bcast_ip, bcast_ip)) + ismybcast(d->bcast_ip)) { if (win_election(work, version,criterion,timeup,name)) { @@ -326,7 +332,8 @@ void process_election(struct packet_struct *p,char *buf) if (work->RunningElection) { work->RunningElection = False; - DEBUG(3,(">>> Lost election on %s <<<\n",work->work_group)); + DEBUG(3,(">>> Lost election on %s %s <<<\n", + work->work_group,inet_ntoa(d->bcast_ip))); /* if we are the master then remove our masterly names */ if (AM_MASTER(work)) @@ -345,25 +352,26 @@ void process_election(struct packet_struct *p,char *buf) ***************************************************************************/ BOOL check_elections(void) { - struct domain_record *d; - BOOL run_any_election = False; + struct domain_record *d; + BOOL run_any_election = False; - for (d = domainlist; d; d = d->next) + for (d = domainlist; d; d = d->next) + { + struct work_record *work; + for (work = d->workgrouplist; work; work = work->next) { - struct work_record *work; - for (work = d->workgrouplist; work; work = work->next) - { - run_any_election |= work->RunningElection; - - if (work->needelection && !work->RunningElection) - { - DEBUG(3,(">>> Starting election on %s <<<\n",work->work_group)); - work->ElectionCount = 0; - work->RunningElection = True; - work->needelection = False; - } - } + run_any_election |= work->RunningElection; + + if (work->needelection && !work->RunningElection) + { + DEBUG(3,(">>> Starting election on %s %s <<<\n", + work->work_group,inet_ntoa(d->bcast_ip))); + work->ElectionCount = 0; + work->RunningElection = True; + work->needelection = False; + } } - return run_any_election; + } + return run_any_election; } diff --git a/source3/nameresp.c b/source3/nameresp.c index 435864a784..78e6274f8c 100644 --- a/source3/nameresp.c +++ b/source3/nameresp.c @@ -21,13 +21,14 @@ */ #include "includes.h" -#include "localnet.h" #include "loadparm.h" +extern int ClientNMB; +extern int ClientDGRAM; + /* this is our initiated name query response database */ struct name_response_record *nameresponselist = NULL; -extern struct in_addr myip; extern int DEBUGLEVEL; static uint16 name_trn_id=0; @@ -75,21 +76,11 @@ void expire_netbios_response_entries(time_t t) DEBUG(3,("Removing dead name query for %s %s (num_msgs=%d)\n", inet_ntoa(n->to_ip), namestr(&n->name), n->num_msgs)); - if (n->cmd_type == CHECK_MASTER && n->num_msgs == 0) + if (n->cmd_type == CHECK_MASTER) { - if (n->num_msgs > 1) - { - /* more than one master browser detected on a subnet. - there is a configuration problem. force an election */ - struct domain_record *d; - if ((d = find_domain(n->to_ip))) - { - send_election(d,n->name.name,0,0,myname); - } - } - /* if no response received, the master browser must have gone */ - browser_gone(n->name.name, n->to_ip); + if (n->num_msgs == 0) + browser_gone(n->name.name, n->to_ip); } nextn = n->next; @@ -230,7 +221,7 @@ uint16 initiate_netbios_packet(int fd,int quest_type,char *name,int name_type, nmb->additional->ttl = quest_type == NMB_REG ? lp_max_ttl() : 0; nmb->additional->rdlength = 6; nmb->additional->rdata[0] = nb_flags; - putip(&nmb->additional->rdata[2],(char *)&myip); + putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip)); } p.ip = to_ip; @@ -434,7 +425,7 @@ void listen_for_packets(BOOL run_election) struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET); if (packet) { #if 1 - if (ip_equal(packet->ip,myip) && + if (ismyip(packet->ip) && (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) { DEBUG(5,("discarding own packet from %s:%d\n", inet_ntoa(packet->ip),packet->port)); @@ -452,7 +443,7 @@ void listen_for_packets(BOOL run_election) struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET); if (packet) { #if 1 - if (ip_equal(packet->ip,myip) && + if (ismyip(packet->ip) && (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) { DEBUG(5,("discarding own packet from %s:%d\n", inet_ntoa(packet->ip),packet->port)); @@ -501,6 +492,7 @@ BOOL interpret_node_status(char *p, struct nmb_name *name,int t, StrnCpy(qname,p,15); type = CVAL(p,15); nb_flags = p[16]; + trim_string(qname,NULL," "); p += 18; @@ -520,17 +512,14 @@ BOOL interpret_node_status(char *p, struct nmb_name *name,int t, struct in_addr nameip; enum name_source src; - if (ip_equal(ip, myip)) - { - nameip = ipzero; - src = SELF; - } - else - { - nameip = ip; - src = STATUS_QUERY; - } - add_netbios_entry(qname,type,nb_flags,2*60*60,src,nameip); + if (ismyip(ip)) { + nameip = ipzero; + src = SELF; + } else { + nameip = ip; + src = STATUS_QUERY; + } + add_netbios_entry(qname,type,nb_flags,2*60*60,src,nameip,True); } /* we want the server name */ diff --git a/source3/nameserv.c b/source3/nameserv.c index b6bc8a4f06..ba61dd3417 100644 --- a/source3/nameserv.c +++ b/source3/nameserv.c @@ -27,8 +27,9 @@ #include "includes.h" #include "loadparm.h" -#include "localnet.h" +extern int ClientNMB; +extern int ClientDGRAM; enum name_search { FIND_SELF, FIND_GLOBAL }; @@ -102,29 +103,31 @@ void remove_name(struct name_record *n) FIND_GLOBAL - the name can be anyone. first look on the client's subnet, then the server's subnet, then all subnets. **************************************************************************/ -static struct name_record *find_name_search(struct nmb_name *name, enum name_search search, +static struct name_record *find_name_search(struct nmb_name *name, + enum name_search search, struct in_addr ip) { - struct name_record *ret; - - /* any number of winpopup names can be added. must search by ip as well */ - if (name->name_type != 0x3) ip = ipzero; - - for (ret = namelist; ret; ret = ret->next) + struct name_record *ret; + + /* any number of winpopup names can be added. must search by ip as + well */ + if (name->name_type != 0x3) ip = ipzero; + + for (ret = namelist; ret; ret = ret->next) + { + if (name_equal(&ret->name,name)) { - if (name_equal(&ret->name,name)) - { - /* self search: self names only */ - if (search == FIND_SELF && ret->source != SELF) continue; - - if (zero_ip(ip) || ip_equal(ip, ret->ip)) - { - return ret; - } - } + /* self search: self names only */ + if (search == FIND_SELF && ret->source != SELF) continue; + + if (zero_ip(ip) || ip_equal(ip, ret->ip)) + { + return ret; + } } - - return NULL; + } + + return NULL; } @@ -133,19 +136,19 @@ static struct name_record *find_name_search(struct nmb_name *name, enum name_sea **************************************************************************/ void dump_names(void) { - struct name_record *n; - time_t t = time(NULL); - - DEBUG(3,("Dump of local name table:\n")); - - for (n = namelist; n; n = n->next) - { - DEBUG(3,("%s %s TTL=%d NBFLAGS=%2x\n", - namestr(&n->name), - inet_ntoa(n->ip), - n->death_time?n->death_time-t:0, - n->nb_flags)); - } + struct name_record *n; + time_t t = time(NULL); + + DEBUG(3,("Dump of local name table:\n")); + + for (n = namelist; n; n = n->next) + { + DEBUG(3,("%s %s TTL=%d NBFLAGS=%2x\n", + namestr(&n->name), + inet_ntoa(n->ip), + n->death_time?n->death_time-t:0, + n->nb_flags)); + } } @@ -155,21 +158,24 @@ void dump_names(void) void remove_netbios_name(char *name,int type, enum name_source source, struct in_addr ip) { - struct nmb_name nn; - struct name_record *n; - - make_nmb_name(&nn, name, type, scope); - n = find_name_search(&nn, FIND_GLOBAL, ip); - - if (n && n->source == source) remove_name(n); + struct nmb_name nn; + struct name_record *n; + + make_nmb_name(&nn, name, type, scope); + n = find_name_search(&nn, FIND_GLOBAL, ip); + + if (n && n->source == source) remove_name(n); } /**************************************************************************** add an entry to the name list ****************************************************************************/ -struct name_record *add_netbios_entry(char *name, int type, int nb_flags, int ttl, - enum name_source source, struct in_addr ip) +struct name_record *add_netbios_entry(char *name, int type, int nb_flags, + int ttl, + enum name_source source, + struct in_addr ip, + BOOL new_only) { struct name_record *n; struct name_record *n2=NULL; @@ -181,9 +187,10 @@ struct name_record *add_netbios_entry(char *name, int type, int nb_flags, int tt make_nmb_name(&n->name,name,type,scope); - if ((n2 = find_name_search(&n->name, FIND_GLOBAL, ip))) + if ((n2 = find_name_search(&n->name, FIND_GLOBAL, new_only?ipzero:ip))) { free(n); + if (new_only || (n2->source==SELF && source!=SELF)) return n2; n = n2; } @@ -209,7 +216,7 @@ void remove_name_entry(char *name,int type) if (lp_wins_support()) { /* we are a WINS server. */ - remove_netbios_name(name,type,SELF,myip); + remove_netbios_name(name,type,SELF,ipzero); } else { @@ -229,7 +236,7 @@ void remove_name_entry(char *name,int type) void add_name_entry(char *name,int type,int nb_flags) { /* always add our own entries */ - add_netbios_entry(name,type,nb_flags,0,SELF,myip); + add_netbios_entry(name,type,nb_flags,0,SELF,ipzero,False); if (!lp_wins_support()) { @@ -257,13 +264,9 @@ void add_my_names(void) add_name_entry(myname,0x00,NB_ACTIVE); add_name_entry(myname,0x1f,NB_ACTIVE); - add_netbios_entry("*",0x0,NB_ACTIVE,0,SELF,ip); - add_netbios_entry("__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip); - add_netbios_entry("__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip); - - if (lp_wins_support()) { - add_netbios_entry(inet_ntoa(myip),0x01,NB_ACTIVE,0,SELF,ip); /* nt as? */ - } + add_netbios_entry("*",0x0,NB_ACTIVE,0,SELF,ip,False); + add_netbios_entry("__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False); + add_netbios_entry("__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False); } /******************************************************************* @@ -328,7 +331,7 @@ void response_name_release(struct packet_struct *p) struct in_addr found_ip; putip((char*)&found_ip,&nmb->answers->rdata[2]); - if (ip_equal(found_ip, myip)) + if (ismyip(found_ip)) { remove_netbios_name(name,type,SELF,found_ip); } @@ -412,9 +415,9 @@ void response_name_reg(struct packet_struct *p) putip((char*)&found_ip,&nmb->answers->rdata[2]); - if (ip_equal(found_ip, myip)) source = SELF; + if (ismyip(found_ip)) source = SELF; - add_netbios_entry(name,type,nb_flags,ttl,source,found_ip); + add_netbios_entry(name,type,nb_flags,ttl,source,found_ip,True); } else { @@ -491,7 +494,7 @@ void reply_name_reg(struct packet_struct *p) else { /* add the name to our subnet/name database */ - n = add_netbios_entry(qname,name_type,nb_flags,ttl,REGISTER,ip); + n = add_netbios_entry(qname,name_type,nb_flags,ttl,REGISTER,ip,False); } if (bcast) return; @@ -667,12 +670,14 @@ struct name_record *search_for_name(struct nmb_name *question, /* no luck with DNS. We could possibly recurse here XXXX */ /* if this isn't a bcast then we should send a negative reply XXXX */ DEBUG(3,("no recursion\n")); - add_netbios_entry(qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip); + add_netbios_entry(qname,name_type,NB_ACTIVE,60*60,DNSFAIL, + dns_ip,False); return NULL; } /* add it to our cache of names. give it 2 hours in the cache */ - n = add_netbios_entry(qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip); + n = add_netbios_entry(qname,name_type,NB_ACTIVE,2*60*60,DNS, + dns_ip,False); /* failed to add it? yikes! */ if (!n) return NULL; @@ -737,7 +742,7 @@ extern void reply_name_query(struct packet_struct *p) struct name_record *n; enum name_search search = dns_type || name_type == 0x1b ? FIND_GLOBAL : FIND_SELF; - + DEBUG(3,("Name query ")); if ((n = search_for_name(question,p->ip,p->timestamp, search))) @@ -746,7 +751,7 @@ extern void reply_name_query(struct packet_struct *p) a name we own or it is for a Primary Domain Controller name */ if (bcast && n->source != SELF && name_type != 0x1b) { - if (!lp_wins_proxy() || same_net(p->ip,n->ip,Netmask)) { + if (!lp_wins_proxy() || same_net(p->ip,n->ip,*iface_nmask(p->ip))) { /* never reply with a negative response to broadcast queries */ return; } @@ -766,9 +771,8 @@ extern void reply_name_query(struct packet_struct *p) /* if asking for a group name (type 0x1e) return 255.255.255.255 */ if (ip_equal(retip, gp_ip) && name_type == 0x1e) retip = gp_ip; - /* if the IP is 0 then substitute my IP - we should see which one is on the - right interface for the caller to do this right XXX */ - if (zero_ip(retip)) retip = myip; + /* if the IP is 0 then substitute my IP */ + if (zero_ip(retip)) retip = *iface_ip(p->ip); if (success) { @@ -897,7 +901,7 @@ static void response_netbios_packet(struct packet_struct *p) fstring serv_name; if (interpret_node_status(nmb->answers->rdata, - &name,0x1d,serv_name,n->to_ip)) + &name,0x1d,serv_name,p->ip)) { if (*serv_name) { @@ -950,7 +954,7 @@ static void response_netbios_packet(struct packet_struct *p) DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip))); add_netbios_entry(nmb->answers->rr_name.name, nmb->answers->rr_name.name_type, - nb_flags,GET_TTL(0),STATUS_QUERY,found_ip); + nb_flags,GET_TTL(0),STATUS_QUERY,found_ip,False); } else { @@ -973,73 +977,72 @@ static void response_netbios_packet(struct packet_struct *p) ****************************************************************************/ void process_nmb(struct packet_struct *p) { - struct nmb_packet *nmb = &p->packet.nmb; + struct nmb_packet *nmb = &p->packet.nmb; - debug_nmb_packet(p); + debug_nmb_packet(p); - switch (nmb->header.opcode) - { - case 5: - case 8: - case 9: + switch (nmb->header.opcode) + { + case 5: + case 8: + case 9: + { + if (nmb->header.qdcount==0 || nmb->header.arcount==0) break; + if (nmb->header.response) + response_name_reg(p); + else + reply_name_reg(p); + break; + } + + case 0: + { + if (nmb->header.response) + { + switch (nmb->question.question_type) + { + case 0x0: { - if (nmb->header.qdcount==0 || nmb->header.arcount==0) break; - if (nmb->header.response) - response_name_reg(p); - else - reply_name_reg(p); - break; + response_netbios_packet(p); + break; } - - case 0: + } + return; + } + else if (nmb->header.qdcount>0) + { + switch (nmb->question.question_type) + { + case NMB_QUERY: { - if (nmb->header.response) - { - switch (nmb->question.question_type) - { - case 0x0: - { - response_netbios_packet(p); - break; - } - } - return; - } - else if (nmb->header.qdcount>0) - { - switch (nmb->question.question_type) - { - case NMB_QUERY: - { - reply_name_query(p); - break; - } - case NMB_STATUS: - { - reply_name_status(p); - break; - } - } - return; - } - break; + reply_name_query(p); + break; } - - case 6: + case NMB_STATUS: { - if (nmb->header.qdcount==0 || nmb->header.arcount==0) - { - DEBUG(2,("netbios release packet rejected\n")); - break; - } - - if (nmb->header.response) - response_name_release(p); - else - reply_name_release(p); - break; + reply_name_status(p); + break; } - } - + } + return; + } + break; + } + + case 6: + { + if (nmb->header.qdcount==0 || nmb->header.arcount==0) + { + DEBUG(2,("netbios release packet rejected\n")); + break; + } + + if (nmb->header.response) + response_name_release(p); + else + reply_name_release(p); + break; + } + } } diff --git a/source3/namework.c b/source3/namework.c index 9697be23ef..cbf65a955f 100644 --- a/source3/namework.c +++ b/source3/namework.c @@ -27,7 +27,9 @@ #include "includes.h" #include "loadparm.h" -#include "localnet.h" + +extern int ClientNMB; +extern int ClientDGRAM; #define TEST_CODE /* want to debug unknown browse packets */ @@ -35,15 +37,13 @@ extern int DEBUGLEVEL; extern pstring scope; extern BOOL CanRecurse; -extern struct in_addr myip; -extern struct in_addr bcast_ip; -extern struct in_addr Netmask; - extern pstring myname; extern int ClientNMB; extern int ClientDGRAM; +extern struct in_addr ipzero; + extern int workgroup_count; /* total number of workgroups we know about */ /* this is our browse cache database */ @@ -99,7 +99,7 @@ void reset_server(char *name, int state, struct in_addr ip) name,inet_ntoa(ip),state)); send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf), - myname,name,0x20,0x1d,ip,myip); + myname,name,0x20,0x1d,ip,*iface_ip(ip)); } @@ -194,7 +194,7 @@ void do_browser_lists(void) static time_t last = 0; time_t t = time(NULL); - if (t-last < 4) return; /* don't do too many of these at once! */ + if (t-last < 20) return; /* don't do too many of these at once! */ last = t; @@ -252,7 +252,7 @@ void update_from_reg(char *name, int type, struct in_addr ip) if (!(work = find_workgroupstruct(d, name, False))) return; /* request the server to announce if on our subnet */ - if (ip_equal(bcast_ip, d->bcast_ip)) announce_request(work, ip); + if (ismybcast(d->bcast_ip)) announce_request(work, ip); /* domain master type or master browser type */ if (type == 0x1b || type == 0x1d) @@ -276,7 +276,9 @@ void add_my_domains(void) if (*lp_workgroup() != '*') { - add_domain_entry(bcast_ip,Netmask,lp_workgroup(), True); + add_domain_entry(*iface_bcast(ipzero), + *iface_nmask(ipzero), + lp_workgroup(), True); } } @@ -409,7 +411,7 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name, } send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf), - myname,theirname,0x20,0,ip,myip); + myname,theirname,0x20,0,ip,*iface_ip(ip)); } @@ -461,8 +463,7 @@ static void process_announce(struct packet_struct *p,int command,char *buf) { struct dgram_packet *dgram = &p->packet.dgram; struct in_addr ip = dgram->header.source_ip; - struct domain_record *d = find_domain(ip); - + struct domain_record *d = find_domain(ip); int update_count = CVAL(buf,0); int ttl = IVAL(buf,1)/1000; char *name = buf+5; @@ -473,7 +474,8 @@ static void process_announce(struct packet_struct *p,int command,char *buf) struct work_record *work; char *work_name; char *serv_name = dgram->source_name.name; - + BOOL add = False; + comment[43] = 0; DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15])); @@ -505,8 +507,17 @@ static void process_announce(struct packet_struct *p,int command,char *buf) } else { work_name = dgram->dest_name.name; } + + /* we need some way of finding out about new workgroups + that appear to be sending packets to us. The name_type checks make + sure we don't add host names as workgroups */ + if (command == ANN_HostAnnouncement && + (dgram->dest_name.name_type == 0x1d || + dgram->dest_name.name_type == 0x1e)) + add = True; - if (!(work = find_workgroupstruct(d, work_name, False))) return; + if (!(work = find_workgroupstruct(d, work_name,add))) + return; DEBUG(4, ("workgroup %s on %s\n", work->work_group, serv_name)); @@ -534,7 +545,7 @@ static void process_master_announce(struct packet_struct *p,char *buf) struct dgram_packet *dgram = &p->packet.dgram; struct in_addr ip = dgram->header.source_ip; struct domain_record *d = find_domain(ip); - struct domain_record *mydomain = find_domain(bcast_ip); + struct domain_record *mydomain = find_domain(*iface_bcast(ip)); char *name = buf; struct work_record *work; name[15] = 0; @@ -752,7 +763,7 @@ static void process_announce_request(struct packet_struct *p,char *buf) if (!d) return; - if (!ip_equal(bcast_ip, d->bcast_ip)) return; + if (!ismybcast(d->bcast_ip)) return; for (work = d->workgrouplist; work; work = work->next) { @@ -842,8 +853,9 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len) q += 2; send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf), - myname,&dgram->source_name.name[0],0x20,0,p->ip,myip); - } + myname,&dgram->source_name.name[0],0x20,0,p->ip, + *iface_ip(p->ip)); +} /**************************************************************************** diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index a977667c2e..b93ac2d580 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -27,7 +27,6 @@ #include "includes.h" #include "loadparm.h" -#include "localnet.h" extern int DEBUGLEVEL; @@ -49,15 +48,11 @@ static BOOL is_daemon = False; /* machine comment for host announcements */ pstring ServerComment=""; -static BOOL got_bcast = False; -static BOOL got_myip = False; -static BOOL got_nmask = False; - /* what server type are we currently */ time_t StartupTime =0; -struct in_addr ipzero; +extern struct in_addr ipzero; /**************************************************************************** @@ -187,6 +182,8 @@ BOOL reload_services(BOOL test) reload_services(True); } + load_interfaces(); + return(ret); } @@ -248,7 +245,7 @@ static void load_hosts_file(char *fname) if (strchr(mask, 'G') || strchr(mask, 'S') || strchr(mask, 'M')) { strcpy(flags, mask ); /* default action for no subnet mask */ - strcpy(mask, inet_ntoa(Netmask)); + strcpy(mask, ""); } DEBUG(4, ("lmhost entry: %s %s %s %s\n", ip, name, mask, flags)); @@ -262,12 +259,15 @@ static void load_hosts_file(char *fname) } ipaddr = *interpret_addr2(ip); - ipmask = *interpret_addr2(mask); + if (*mask) + ipmask = *interpret_addr2(mask); + else + ipmask = *iface_nmask(ipaddr); if (group) { add_domain_entry(ipaddr, ipmask, name, True); } else { - add_netbios_entry(name,0x20,NB_ACTIVE,0,source,ipaddr); + add_netbios_entry(name,0x20,NB_ACTIVE,0,source,ipaddr,False); } } } @@ -347,78 +347,14 @@ static BOOL open_sockets(BOOL isdaemon, int port) } -/******************************************************************* - check that a IP, bcast and netmask and consistent. Must be a 1s - broadcast - ******************************************************************/ -static BOOL ip_consistent(struct in_addr ip,struct in_addr bcast, struct in_addr nmask) -{ - unsigned long a_ip,a_bcast,a_nmask; - - a_ip = ntohl(ip.s_addr); - a_bcast = ntohl(bcast.s_addr); - a_nmask = ntohl(nmask.s_addr); - - /* check the netmask is sane */ - if (((a_nmask>>24)&0xFF) != 0xFF) { - DEBUG(0,("Insane netmask %s\n",inet_ntoa(nmask))); - return(False); - } - - /* check the IP and bcast are on the same net */ - if ((a_ip&a_nmask) != (a_bcast&a_nmask)) { - DEBUG(0,("IP and broadcast are on different nets!\n")); - return(False); - } - - /* check the IP and bcast are on the same net */ - if ((a_bcast|a_nmask) != 0xFFFFFFFF) { - DEBUG(0,("Not a ones based broadcast %s\n",inet_ntoa(bcast))); - return(False); - } - - return(True); -} - - /**************************************************************************** initialise connect, service and file structs ****************************************************************************/ static BOOL init_structs() { - if (!get_myname(myhostname,got_myip?NULL:&myip)) + if (!get_myname(myhostname,NULL)) return(False); - /* Read the broadcast address from the interface */ - { - struct in_addr ip0,ip1,ip2; - - ip0 = myip; - - if (!(got_bcast && got_nmask)) - { - get_broadcast(&ip0,&ip1,&ip2); - - if (!got_myip) - myip = ip0; - - if (!got_bcast) - bcast_ip = ip1; - - if (!got_nmask) - Netmask = ip2; - } - - DEBUG(1,("Using IP %s ",inet_ntoa(myip))); - DEBUG(1,("broadcast %s ",inet_ntoa(bcast_ip))); - DEBUG(1,("netmask %s\n",inet_ntoa(Netmask))); - - if (!ip_consistent(myip,bcast_ip,Netmask)) { - DEBUG(0,("WARNING: The IP address, broadcast and Netmask are not consistent\n")); - DEBUG(0,("You are likely to experience problems with this setup!\n")); - } - } - if (! *myname) { char *p; strcpy(myname,myhostname); @@ -462,7 +398,9 @@ static void usage(char *pname) int opt; extern FILE *dbf; extern char *optarg; + fstring group; + *group = 0; *host_file = 0; StartupTime = time(NULL); @@ -475,8 +413,6 @@ static void usage(char *pname) charset_initialise(); - ipzero = *interpret_addr2("0.0.0.0"); - #ifdef LMHOSTSFILE strcpy(host_file,LMHOSTSFILE); #endif @@ -491,9 +427,6 @@ static void usage(char *pname) signal(SIGHUP,SIGNAL_CAST sig_hup); - bcast_ip = ipzero; - myip = ipzero; - while ((opt = getopt (argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF) { switch (opt) @@ -505,29 +438,19 @@ static void usage(char *pname) strcpy(ServerComment,optarg); break; case 'G': - if (got_bcast && got_nmask) { - add_domain_entry(bcast_ip,Netmask,optarg, True); - } else { - DEBUG(0, ("Warning: option -G %s added before broadcast and netmask.\n", - optarg)); - DEBUG(0, ("Assuming default values: bcast %s netmask %s\n", - inet_ntoa(bcast_ip), inet_ntoa(Netmask))); /* (i hope) */ - } + strcpy(group,optarg); break; case 'H': strcpy(host_file,optarg); break; case 'I': - myip = *interpret_addr2(optarg); - got_myip = True; + iface_set_default(optarg,NULL,NULL); break; case 'B': - bcast_ip = *interpret_addr2(optarg); - got_bcast = True; + iface_set_default(NULL,optarg,NULL); break; case 'N': - Netmask = *interpret_addr2(optarg); - got_nmask = True; + iface_set_default(NULL,NULL,optarg); break; case 'n': strcpy(myname,optarg); @@ -568,6 +491,9 @@ static void usage(char *pname) if (!reload_services(False)) return(-1); + if (*group) + add_domain_entry(*iface_bcast(ipzero),*iface_nmask(ipzero),group, True); + if (!is_daemon && !is_a_socket(0)) { DEBUG(0,("standard input is not a socket, assuming -D option\n")); is_daemon = True; diff --git a/source3/nmbsync.c b/source3/nmbsync.c index 7e8cdd67e1..e86e8d53eb 100644 --- a/source3/nmbsync.c +++ b/source3/nmbsync.c @@ -22,14 +22,13 @@ #include "includes.h" #include "loadparm.h" -#include "localnet.h" +extern int ClientNMB; +extern int ClientDGRAM; extern int DEBUGLEVEL; extern pstring myname; -extern struct in_addr bcast_ip; -extern struct in_addr Netmask; extern int name_type; extern int max_protocol; @@ -114,7 +113,7 @@ static BOOL add_info(struct domain_record *d, struct work_record *work, int serv /* creates workgroup on remote subnet */ if ((w = find_workgroupstruct(d,sname, False))) { - if (ip_equal(bcast_ip, d->bcast_ip)) + if (ismybcast(d->bcast_ip)) { announce_request(w, d->bcast_ip); } diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index bbeb4801d5..876385ab18 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -109,61 +109,62 @@ extern int coding_system; */ typedef struct { - char *szPrintcapname; - char *szLockDir; - char *szRootdir; - char *szDefaultService; - char *szDfree; - char *szMsgCommand; - char *szHostsEquiv; - char *szServerString; - char *szAutoServices; - char *szPasswdProgram; - char *szPasswdChat; - char *szLogFile; - char *szConfigFile; - char *szSMBPasswdFile; - char *szPasswordServer; - char *szSocketOptions; - char *szValidChars; - char *szWorkGroup; - char *szDomainController; - char *szUsernameMap; - char *szCharacterSet; - char *szLogonScript; - char *szSmbrun; - char *szWINSserver; - int max_log_size; - int mangled_stack; - int max_xmit; - int max_mux; - int max_packet; - int pwordlevel; - int deadtime; - int maxprotocol; - int security; - int printing; - int maxdisksize; - int lpqcachetime; - int syslog; - int os_level; - int max_ttl; - BOOL bWINSsupport; - BOOL bWINSproxy; - BOOL bPreferredMaster; - BOOL bDomainMaster; - BOOL bDomainLogons; - BOOL bEncryptPasswords; - BOOL bStripDot; - BOOL bNullPasswords; - BOOL bLoadPrinters; - BOOL bUseRhosts; - BOOL bReadRaw; - BOOL bWriteRaw; - BOOL bReadPrediction; - BOOL bReadbmpx; - BOOL bSyslogOnly; - BOOL bBrowseList; + char *szPrintcapname; + char *szLockDir; + char *szRootdir; + char *szDefaultService; + char *szDfree; + char *szMsgCommand; + char *szHostsEquiv; + char *szServerString; + char *szAutoServices; + char *szPasswdProgram; + char *szPasswdChat; + char *szLogFile; + char *szConfigFile; + char *szSMBPasswdFile; + char *szPasswordServer; + char *szSocketOptions; + char *szValidChars; + char *szWorkGroup; + char *szDomainController; + char *szUsernameMap; + char *szCharacterSet; + char *szLogonScript; + char *szSmbrun; + char *szWINSserver; + char *szInterfaces; + int max_log_size; + int mangled_stack; + int max_xmit; + int max_mux; + int max_packet; + int pwordlevel; + int deadtime; + int maxprotocol; + int security; + int printing; + int maxdisksize; + int lpqcachetime; + int syslog; + int os_level; + int max_ttl; + BOOL bWINSsupport; + BOOL bWINSproxy; + BOOL bPreferredMaster; + BOOL bDomainMaster; + BOOL bDomainLogons; + BOOL bEncryptPasswords; + BOOL bStripDot; + BOOL bNullPasswords; + BOOL bLoadPrinters; + BOOL bUseRhosts; + BOOL bReadRaw; + BOOL bWriteRaw; + BOOL bReadPrediction; + BOOL bReadbmpx; + BOOL bSyslogOnly; + BOOL bBrowseList; } global; static global Globals; @@ -368,6 +369,7 @@ struct parm_struct {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL}, {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL}, {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL}, + {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL}, {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL}, {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL}, {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL}, @@ -704,6 +706,7 @@ FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap) FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet) FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript) FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver) +FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces) FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport) FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy) diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 25979d72f5..916b0fb88e 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -808,7 +808,8 @@ static BOOL filter_server_info(struct srv_info_struct *server, number of entries ******************************************************************/ static int get_server_info(uint32 servertype, - struct srv_info_struct **servers, BOOL domains, char *domain) + struct srv_info_struct **servers, BOOL domains, + char *domain) { FILE *f; pstring fname; @@ -831,7 +832,7 @@ static int get_server_info(uint32 servertype, /* request for everything is code for request all servers */ if (servertype == SV_TYPE_ALL) servertype &= ~SV_TYPE_DOMAIN_ENUM; - DEBUG(4, ("Servertype search: %8x domains:%s\n", servertype,BOOLSTR(domains))); + DEBUG(4,("Servertype search: %8x domains:%s\n",servertype,BOOLSTR(domains))); while (!feof(f)) { @@ -861,10 +862,16 @@ static int get_server_info(uint32 servertype, strcpy(s->domain,my_workgroup()); } - if (sscanf(stype,"%X",&s->type) != 1) { DEBUG(4,("r:host file ")); ok = False; } + if (sscanf(stype,"%X",&s->type) != 1) { + DEBUG(4,("r:host file ")); + ok = False; + } /* doesn't match up: don't want it */ - if (!(servertype & s->type)) { DEBUG(4,("r:serv type ")); ok = False; } + if (!(servertype & s->type)) { + DEBUG(4,("r:serv type ")); + ok = False; + } if ((servertype == ~SV_TYPE_DOMAIN_ENUM) && (s->type & SV_TYPE_DOMAIN_ENUM)) @@ -902,6 +909,7 @@ static int get_server_info(uint32 servertype, return(count); } + /******************************************************************* fill in a server info structure ******************************************************************/ @@ -981,6 +989,11 @@ static int fill_srv_info(struct srv_info_struct *service, } +static BOOL srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2) +{ + return(strcmp(s1->name,s2->name)); +} + /**************************************************************************** view list of servers available (or possibly domains). The info is extracted from lists saved by nmbd on the local host @@ -1038,23 +1051,30 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data, data_len = fixed_len = string_len = 0; + qsort(servers,total,sizeof(servers[0]),QSORT_CAST srv_comp); + { + char *lastname=NULL; + for (i=0;i<total;i++) { struct srv_info_struct *s = &servers[i]; - if (filter_server_info(s,domains,domain,local_request|domain_request)) - { - data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0); - DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n", - s->name, s->type, s->comment, s->domain)); - - if (data_len <= buf_len) + if (filter_server_info(s,domains,domain, + local_request|domain_request)) + { + if (lastname && strequal(lastname,s->name)) continue; + lastname = s->name; + data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0); + DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n", + s->name, s->type, s->comment, s->domain)); + + if (data_len <= buf_len) { counted++; fixed_len += f_len; string_len += s_len; } - } + } } } @@ -1068,18 +1088,21 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data, s_len = string_len; { + char *lastname=NULL; int count2 = counted; for (i = 0; i < total && count2;i++) - { - struct srv_info_struct *s = &servers[i]; - if (filter_server_info(s,domains,domain,local_request|domain_request)) { - fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata); - DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n", - s->name, s->type, s->comment, s->domain)); - count2--; + struct srv_info_struct *s = &servers[i]; + if (filter_server_info(s,domains,domain,local_request|domain_request)) + { + if (lastname && strequal(lastname,s->name)) continue; + lastname = s->name; + fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata); + DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n", + s->name, s->type, s->comment, s->domain)); + count2--; + } } - } } *rparam_len = 8; diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 31d9191271..c2fe8a4f0d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -43,7 +43,6 @@ Get the next challenge value - no repeats. ********************************************************************/ void generate_next_challenge(char *challenge) { - extern void E1(char *,char *,char *); static int counter = 0; struct timeval tval; int v1,v2; @@ -1257,7 +1256,6 @@ BOOL server_cryptkey(char *buf) int len; fstring desthost; struct in_addr dest_ip; - extern struct in_addr myip; int port = SMB_PORT; BOOL ret; @@ -1285,7 +1283,7 @@ BOOL server_cryptkey(char *buf) continue; } - if (memcmp(&dest_ip,&myip,sizeof(dest_ip)) == 0) { + if (ismyip(dest_ip)) { DEBUG(1,("Password server loop - disabling password server %s\n",p)); continue; } diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 206d89423f..25464d861c 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -79,8 +79,6 @@ int unix_ERR_code=0; extern int extra_time_offset; extern pstring myhostname; -extern struct in_addr myip; - static int find_free_connection(int hash); @@ -1778,6 +1776,8 @@ BOOL reload_services(BOOL test) reopen_logs(); + load_interfaces(); + { extern int Client; if (Client != -1) { @@ -3550,7 +3550,7 @@ static void process(void) static void init_structs(void ) { int i; - get_myname(myhostname,&myip); + get_myname(myhostname,NULL); for (i=0;i<MAX_CONNECTIONS;i++) { diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c index 6289ef74b1..43c328a41e 100644 --- a/source3/utils/nmblookup.c +++ b/source3/utils/nmblookup.c @@ -30,11 +30,8 @@ extern int DEBUGLEVEL; extern pstring scope; -extern struct in_addr bcast_ip; extern pstring myhostname; - -static BOOL got_bcast = False; -struct in_addr ipzero; +extern struct in_addr ipzero; int ServerFD= -1; @@ -69,24 +66,9 @@ static BOOL open_sockets(void) ****************************************************************************/ static BOOL init_structs(void ) { - struct in_addr myip; - - if (!get_myname(myhostname,&myip)) + if (!get_myname(myhostname,NULL)) return(False); - /* Read the broadcast address from the interface */ - { - struct in_addr ip0,ip2; - - ip0 = myip; - - if (!got_bcast) { - get_broadcast(&ip0,&bcast_ip,&ip2); - - DEBUG(2,("Using broadcast %s\n",inet_ntoa(bcast_ip))); - } - } - return True; } @@ -124,8 +106,6 @@ int main(int argc,char *argv[]) TimeInit(); - ipzero = *interpret_addr2("0.0.0.0"); - setup_logging(argv[0],True); charset_initialise(); @@ -134,11 +114,7 @@ int main(int argc,char *argv[]) switch (opt) { case 'B': - { - unsigned long a = interpret_addr(optarg); - putip((char *)&bcast_ip,(char *)&a); - got_bcast = True; - } + iface_set_default(NULL,optarg,NULL); break; case 'i': strcpy(scope,optarg); @@ -167,10 +143,11 @@ int main(int argc,char *argv[]) exit(1); } + load_interfaces(); init_structs(); if (!open_sockets()) return(1); - DEBUG(1,("Sending queries to %s\n",inet_ntoa(bcast_ip))); + DEBUG(1,("Sending queries to %s\n",inet_ntoa(*iface_bcast(ipzero)))); for (i=optind;i<argc;i++) @@ -201,7 +178,7 @@ int main(int argc,char *argv[]) } if (name_query(ServerFD,lookup,lookup_type,bcast,True, - bcast_ip,&ip,NULL)) + *iface_bcast(ipzero),&ip,NULL)) { printf("%s %s\n",inet_ntoa(ip),lookup); if (find_status) |