]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
severe debugging session for nmbd. in fact, i'm surprised that browsing
authorSamba Release Account <samba-bugs@samba.org>
Sun, 27 Oct 1996 14:22:56 +0000 (14:22 +0000)
committerSamba Release Account <samba-bugs@samba.org>
Sun, 27 Oct 1996 14:22:56 +0000 (14:22 +0000)
in 1.9.16 works at all!

question and resource record types for queries and response netbios
packets sorted out properly (see rfc1002.txt 4.2.1.3).

receipt of browser announcement packets were playing up

lkcl

source/namedbname.c
source/namedbsubnet.c
source/namepacket.c
source/nameresp.c
source/nameservreply.c
source/nameservresp.c
source/namework.c

index 8f5514be531f92b91f62032147bd771f5e41b04a..c1ec92ea0011bbf9803042cd8ad325c6c45181fc 100644 (file)
@@ -149,10 +149,11 @@ struct name_record *find_name(struct name_record *n,
                if (name_equal(&ret->name,name))
                {
                        /* self search: self names only */
-                       if ((search&FIND_SELF) == FIND_SELF && 
-                           ret->source != SELF)
+                       if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
+                       {
                                continue;
-         
+                       }
+
                        return ret;
                }
        }
index 16eeb6322ebc3001f9b2a4dc6683e3086f5725e0..367179b6c613c6b19a316d8fc401011c7f727cd8 100644 (file)
@@ -87,22 +87,25 @@ struct subnet_record *find_subnet(struct in_addr bcast_ip)
      the source ip address. a subnet 255.255.255.255 represents the
      WINS list. */
   
-  for (d = subnetlist; d; d = d->next)
+       for (d = subnetlist; d; d = d->next)
     {
         if (ip_equal(bcast_ip, wins_ip))
            {
-           if (ip_equal(bcast_ip, d->bcast_ip))
-           {
-               return d;
-           }
+                       if (ip_equal(bcast_ip, d->bcast_ip))
+                       {
+                               return d;
+                       }
         }
         else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
            {
-             return(d);
+                       if (!ip_equal(d->bcast_ip, wins_ip))
+                       {
+                               return d;
+                       }
            }
     }
   
-  return (NULL);
+       return (NULL);
 }
 
 
index e6677ee10dae9b2f0a22bafa0f9f504b6f15af88..84b0a1b355ebbb124c781b59e2ba5d32724e12d7 100644 (file)
@@ -141,28 +141,29 @@ void initiate_netbios_packet(uint16 *id,
   
   make_nmb_name(&nmb->question.question_name,name,name_type,scope);
   
-  nmb->question.question_type = quest_type;
+  nmb->question.question_type = 0x20;
   nmb->question.question_class = 0x1;
   
   if (quest_type == NMB_REG ||
       quest_type == NMB_REG_REFRESH ||
       quest_type == NMB_REL)
-    {
+  {
       nmb->additional = &additional_rec;
       bzero((char *)nmb->additional,sizeof(*nmb->additional));
       
       nmb->additional->rr_name  = nmb->question.question_name;
-      nmb->additional->rr_type  = nmb->question.question_type;
-      nmb->additional->rr_class = nmb->question.question_class;
+      nmb->additional->rr_type  = 0x20;
+      nmb->additional->rr_class = 0x1;
       
       if (quest_type == NMB_REG || quest_type == NMB_REG_REFRESH)
-       nmb->additional->ttl = lp_max_ttl();
+        nmb->additional->ttl = lp_max_ttl();
       else
-       nmb->additional->ttl = 0;
+        nmb->additional->ttl = 0;
+
       nmb->additional->rdlength = 6;
       nmb->additional->rdata[0] = nb_flags;
       putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
-    }
+  }
   
   p.ip = to_ip;
   p.port = NMB_PORT;
@@ -492,58 +493,60 @@ void run_packet_queue()
   ***************************************************************************/
 void listen_for_packets(BOOL run_election)
 {
-  fd_set fds;
-  int selrtn;
-  struct timeval timeout;
+       fd_set fds;
+       int selrtn;
+       struct timeval timeout;
 
-try_again:
+       FD_ZERO(&fds);
+       FD_SET(ClientNMB,&fds);
+       FD_SET(ClientDGRAM,&fds);
 
-  FD_ZERO(&fds);
-  FD_SET(ClientNMB,&fds);
-  FD_SET(ClientDGRAM,&fds);
+       /* during elections and when expecting a netbios response packet we
+       need to send election packets at tighter intervals 
 
-  /* during elections and when expecting a netbios response packet we
-     need to send election packets at tighter intervals 
+       ideally it needs to be the interval (in ms) between time now and
+       the time we are expecting the next netbios packet */
 
-     ideally it needs to be the interval (in ms) between time now and
-     the time we are expecting the next netbios packet */
+       timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP;
+       timeout.tv_usec = 0;
 
-  timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
-  timeout.tv_usec = 0;
+       selrtn = sys_select(&fds,&timeout);
 
-  selrtn = sys_select(&fds,&timeout);
-
-  if (FD_ISSET(ClientNMB,&fds))
-    {
-      struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
-      if (packet) {
-       if (ismyip(packet->ip) &&
-           (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
-         DEBUG(7,("discarding own packet from %s:%d\n",
-                  inet_ntoa(packet->ip),packet->port));          
-         free_packet(packet);
-         goto try_again;
-       } else {
-         queue_packet(packet);
+       if (FD_ISSET(ClientNMB,&fds))
+       {
+               struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
+               if (packet)
+               {
+                       if (ismyip(packet->ip) && packet->port == NMB_PORT)
+                       {
+                               DEBUG(7,("discarding own packet from %s:%d\n",
+                                         inet_ntoa(packet->ip),packet->port));   
+                               free_packet(packet);
+                       }
+                       else
+                       {
+                               queue_packet(packet);
+                       }
+               }
        }
-      }
-    }
 
-  if (FD_ISSET(ClientDGRAM,&fds))
-    {
-      struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
-      if (packet) {
-       if (ismyip(packet->ip) &&
-             (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
-         DEBUG(7,("discarding own packet from %s:%d\n",
-                  inet_ntoa(packet->ip),packet->port));          
-         free_packet(packet);
-         goto try_again;
-       } else {
-         queue_packet(packet);
+       if (FD_ISSET(ClientDGRAM,&fds))
+       {
+               struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
+               if (packet)
+               {
+                       if (ismyip(packet->ip) && packet->port == DGRAM_PORT)
+                       {
+                               DEBUG(7,("discarding own packet from %s:%d\n",
+                                         inet_ntoa(packet->ip),packet->port));   
+                               free_packet(packet);
+                       }
+                       else
+                       {
+                               queue_packet(packet);
+                       }
+               }
        }
-      }
-    }
 }
 
 
index 9be0f4491fdd307ffc6fd53ccc1b0ad95b133b09..949bb366bb94287124ed059d4244f919ab8c13f0 100644 (file)
@@ -134,25 +134,28 @@ static void dead_netbios_entry(struct subnet_record *d,
                 on that subnet. if we are using a WINS server, then the WINS
                 server must be dead or deaf.
           */
-         if (n->bcast)
+         if (n->num_msgs == 0)
          {
-               /* broadcast method: implicit acceptance of the name registration
-                  by not receiving any objections. */
+           if (n->bcast)
+           {
+                 /* broadcast method: implicit acceptance of the name registration
+                    by not receiving any objections. */
 
-               /* IMPORTANT: see response_name_reg() */
+                 /* IMPORTANT: see response_name_reg() */
 
-               name_register_work(d,n->name.name,n->name.name_type,
-                               n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
-         }
-         else if (n->num_msgs == 0)
-         {
-               /* received no response. rfc1001.txt states that after retrying,
-                  we should assume the WINS server is dead, and fall back to
-                  broadcasting (see bits about M nodes: can't find any right
-           now) */
+                 name_register_work(d,n->name.name,n->name.name_type,
+                                 n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
+           }
+        else
+        {
+                 /* received no response. rfc1001.txt states that after retrying,
+                    we should assume the WINS server is dead, and fall back to
+                    broadcasting (see bits about M nodes: can't find any right
+             now) */
                
-               DEBUG(1,("WINS server did not respond to name registration!\n"));
-        /* XXXX whoops. we have problems. must deal with this */
+                 DEBUG(1,("WINS server did not respond to name registration!\n"));
+          /* XXXX whoops. we have problems. must deal with this */
+        }
          }
          break;
        }
index df30e4ac412a17633292c91b46beb8b9cc34c5fb..544cbc62b44ab872bebd883a516f1697fb57b365 100644 (file)
@@ -127,9 +127,9 @@ void reply_name_release(struct packet_struct *p)
   }
 
   if (bcast)
-       search &= FIND_LOCAL;
+       search |= FIND_LOCAL;
   else
-       search &= FIND_WINS;
+       search |= FIND_WINS;
 
   n = find_name_search(&d, &nmb->question.question_name, 
                                        search, ip);
@@ -183,7 +183,7 @@ void reply_name_reg(struct packet_struct *p)
   putip((char *)&from_ip,&nmb->additional->rdata[2]);
   ip = from_ip;
   
-  DEBUG(3,("Name registration for name %s at %s\n",
+  DEBUG(3,("Name registration for name %s at %s - ",
                   namestr(question),inet_ntoa(ip)));
   
   if (group)
@@ -201,15 +201,16 @@ void reply_name_reg(struct packet_struct *p)
   }
 
   if (bcast)
-       search &= FIND_LOCAL;
+       search |= FIND_LOCAL;
   else
-       search &= FIND_WINS;
+       search |= FIND_WINS;
 
   /* see if the name already exists */
   n = find_name_search(&d, question, search, from_ip);
   
   if (n)
   {
+    DEBUG(3,("found\n"));
     if (!group) /* unique names */
        {
          if (n->source == SELF || NAME_GROUP(n->ip_flgs[0].nb_flags))
@@ -259,6 +260,7 @@ void reply_name_reg(struct packet_struct *p)
   }
   else
   {
+      DEBUG(3,("not found\n"));
       /* add the name to our name/subnet, or WINS, database */
       n = add_netbios_entry(d,qname,qname_type,nb_flags,ttl,REGISTER,ip,
                                True,!bcast);
@@ -458,10 +460,8 @@ void reply_name_status(struct packet_struct *p)
   reply_netbios_packet(p,nmb->header.name_trn_id,
                           0,NMB_STATUS,0,True,
                       &nmb->question.question_name,
-                      nmb->question.question_type,
-                      nmb->question.question_class,
-                      0,
-                      rdata,PTR_DIFF(buf,rdata));
+                      0x21, 0x01,
+                      0, rdata,PTR_DIFF(buf,rdata));
 }
 
 
@@ -549,8 +549,8 @@ void reply_name_query(struct packet_struct *p)
     n = find_name_search(&d, question, search, p->ip);
 
     /* it is a name that already failed DNS lookup or it's expired */
-    if (n->source == DNSFAIL ||
-        (n->death_time && n->death_time < p->timestamp))
+    if (n && (n->source == DNSFAIL ||
+              (n->death_time && n->death_time < p->timestamp)))
     {
       success = False;
     }
@@ -625,8 +625,7 @@ void reply_name_query(struct packet_struct *p)
   reply_netbios_packet(p,nmb->header.name_trn_id,
                           rcode,NMB_QUERY,0,True,
                       &nmb->question.question_name,
-                      nmb->question.question_type,
-                      nmb->question.question_class,
+               0x20, 0x01,
                       ttl,
                       rdata, success ? 6 : 0);
 }
index 91f915b760f6d90a34145623ac780c934d9e9064..cc117f9b15a34f5aa361b0c9cb738c1dd24d95d8 100644 (file)
@@ -46,12 +46,12 @@ extern struct in_addr ipzero;
   response for a reg release received. samba has asked a WINS server if it
   could release a name.
   **************************************************************************/
-static void response_name_release(struct subnet_record *d,
-                                                               struct packet_struct *p)
+static void response_name_release(struct nmb_name *ans_name,
+                       struct subnet_record *d, struct packet_struct *p)
 {
   struct nmb_packet *nmb = &p->packet.nmb;
-  char *name = nmb->question.question_name.name;
-  int   type = nmb->question.question_name.name_type;
+  char *name = ans_name->name;
+  int   type = ans_name->name_type;
   
   DEBUG(4,("response name release received\n"));
   
@@ -70,14 +70,12 @@ static void response_name_release(struct subnet_record *d,
     else
     {
       DEBUG(2,("name release for different ip! %s %s\n",
-                  inet_ntoa(found_ip),
-                  namestr(&nmb->question.question_name)));
+                  inet_ntoa(found_ip), namestr(ans_name)));
     }
   }
   else
   {
-    DEBUG(2,("name release for %s rejected!\n",
-              namestr(&nmb->question.question_name)));
+    DEBUG(2,("name release for %s rejected!\n", namestr(ans_name)));
 
     /* XXXX PANIC! what to do if it's one of samba's own names? */
 
@@ -91,12 +89,13 @@ static void response_name_release(struct subnet_record *d,
 /****************************************************************************
 response for a reg request received
 **************************************************************************/
-static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
+static void response_name_reg(struct nmb_name *ans_name,
+                       struct subnet_record *d, struct packet_struct *p)
 {
   struct nmb_packet *nmb = &p->packet.nmb;
-  char *name = nmb->question.question_name.name;
-  int   type = nmb->question.question_name.name_type;
   BOOL bcast = nmb->header.nm_flags.bcast;
+  char *name = ans_name->name;
+  int   type = ans_name->name_type;
   
   DEBUG(4,("response name registration received!\n"));
   
@@ -114,8 +113,7 @@ static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
   }
   else
   {
-    DEBUG(1,("name registration for %s rejected!\n",
-              namestr(&nmb->question.question_name)));
+    DEBUG(2,("name registration for %s rejected!\n", namestr(ans_name)));
 
        /* oh dear. we have problems. possibly unbecome a master browser. */
     name_unregister_work(d,name,type);
@@ -527,7 +525,7 @@ void debug_state_type(int state)
   (responses for certain types of operations are only expected from one host)
   ****************************************************************************/
 static BOOL response_problem_check(struct response_record *n,
-                       struct nmb_packet *nmb, char *qname)
+                       struct nmb_packet *nmb, char *ans_name)
 {
   switch (nmb->answers->rr_type)
   {
@@ -584,7 +582,7 @@ static BOOL response_problem_check(struct response_record *n,
                 case NAME_QUERY_SRV_CHK:
                 case NAME_QUERY_MST_CHK:
                 {
-                     if (!strequal(qname,n->name.name))
+                     if (!strequal(ans_name,n->name.name))
                      {
                             /* one subnet, one master browser per workgroup */
                             /* XXXX force an election? */
@@ -694,13 +692,13 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
   {
     case NAME_RELEASE:
     {
-        response_name_release(d, p);
+        response_name_release(ans_name, d, p);
         break;
     }
 
     case NAME_REGISTER:
     {
-               response_name_reg(d, p);
+               response_name_reg(ans_name, d, p);
         break;
     }
 
@@ -763,9 +761,7 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
 void response_netbios_packet(struct packet_struct *p)
 {
   struct nmb_packet *nmb = &p->packet.nmb;
-  struct nmb_name *question = &nmb->question.question_name;
   struct nmb_name *ans_name = NULL;
-  char *qname = question->name;
   BOOL bcast = nmb->header.nm_flags.bcast;
   struct response_record *n;
   struct subnet_record *d = NULL;
@@ -809,7 +805,7 @@ void response_netbios_packet(struct packet_struct *p)
   debug_state_type(n->state);
 
   /* problem checking: multiple responses etc */
-  if (response_problem_check(n, nmb, qname))
+  if (response_problem_check(n, nmb, ans_name->name))
     return;
 
   /* now deal with the current state */
index 80183dac84fc2c8bbab5814a68715d49bbd69927..f4a9113cea7412cdbf52270e06e500b64159c039 100644 (file)
@@ -175,8 +175,7 @@ BOOL same_context(struct dgram_packet *dgram)
 static void process_announce(struct packet_struct *p,uint16 command,char *buf)
 {
   struct dgram_packet *dgram = &p->packet.dgram;
-  struct in_addr ip = dgram->header.source_ip;
-  struct subnet_record *d = find_subnet(ip); 
+  struct subnet_record *d = find_subnet(p->ip); 
   int update_count = CVAL(buf,0);
 
   int ttl = IVAL(buf,1)/1000;
@@ -213,7 +212,7 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
        dgram->dest_name.name_type != 0x1))
     {
       DEBUG(0,("Announce(%d) from %s should be __MSBROWSE__(1) not %s\n",
-               command, inet_ntoa(ip), namestr(&dgram->dest_name)));
+               command, inet_ntoa(p->ip), namestr(&dgram->dest_name)));
       return;
     }
   
@@ -243,6 +242,9 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
        dgram->dest_name.name_type == 0x1e))
     add = True;
   
+  DEBUG(4,("search for workgroup: %s (add? %s)\n",
+            work_name, BOOLSTR(add)));
+
   if (!(work = find_workgroupstruct(d, work_name,add)))
     return;
   
@@ -265,7 +267,7 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
   if (command == ANN_LocalMasterAnnouncement)
   {
     add_browser_entry(serv_name,dgram->dest_name.name_type,
-                     work->work_group,30,ip,True);
+                     work->work_group,30,p->ip,True);
   }
 }
 
@@ -275,27 +277,25 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
 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 subnet_record *d = find_subnet(ip);
-  struct subnet_record *mydomain = find_subnet(*iface_bcast(ip));
+  struct subnet_record *d = find_subnet(p->ip);
   char *name = buf;
   struct work_record *work;
   name[15] = 0;
   
-  DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(ip)));
+  DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(p->ip)));
   
   if (same_context(dgram)) return;
   
-  if (!d || !mydomain) return;
+  if (!d) return;
   
   if (!lp_domain_master()) return;
   
-  for (work = mydomain->workgrouplist; work; work = work->next)
+  for (work = d->workgrouplist; work; work = work->next)
   {
     if (AM_MASTER(work))
     {
          /* merge browse lists with them */
-         add_browser_entry(name,0x1b, work->work_group,30,ip,True);
+         add_browser_entry(name,0x1b, work->work_group,30,p->ip,True);
     }
   }
 }
@@ -316,13 +316,12 @@ static void process_master_announce(struct packet_struct *p,char *buf)
 static void process_rcv_backup_list(struct packet_struct *p,char *buf)
 {
   struct dgram_packet *dgram = &p->packet.dgram;
-  struct in_addr ip = dgram->header.source_ip;
   int count = CVAL(buf,0);
   uint32 info = IVAL(buf,1); /* XXXX caller's incremental info */
   char *buf1;
   
   DEBUG(3,("Receive Backup ack for %s from %s total=%d info=%d\n",
-          namestr(&dgram->dest_name), inet_ntoa(ip),
+          namestr(&dgram->dest_name), inet_ntoa(p->ip),
           count, info));
   
   if (same_context(dgram)) return;
@@ -336,7 +335,7 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
     /* struct subnet_record *d; */
       
     DEBUG(4,("Searching for backup browser %s at %s...\n",
-              buf1, inet_ntoa(ip)));
+              buf1, inet_ntoa(p->ip)));
       
     /* XXXX assume name is a DNS name NOT a netbios name. a more complete
           approach is to use reply_name_query functionality to find the name */