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
(This used to be commit b289db62f1a53f1a68ea48dbfa59720cc778d39c)

source3/namedbname.c
source3/namedbsubnet.c
source3/namepacket.c
source3/nameresp.c
source3/nameservreply.c
source3/nameservresp.c
source3/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 */