Try again to fix up 'session request' name exchange. This time we actualy
[tprouty/samba.git] / source / libsmb / nmblib.c
index 0061a4b9772b0599d6e9a5f5c5a18cb11dcd34ad..6ee05f010452c326d2d6b2b9914b7cc13f197db8 100644 (file)
@@ -1,6 +1,5 @@
 /* 
-   Unix SMB/Netbios implementation.
-   Version 1.9.
+   Unix SMB/CIFS implementation.
    NBT netbios library routines
    Copyright (C) Andrew Tridgell 1994-1998
    
@@ -26,17 +25,17 @@ int num_good_sends = 0;
 int num_good_receives = 0;
 
 static const struct opcode_names {
-       char *nmb_opcode_name;
+       const char *nmb_opcode_name;
        int opcode;
 } nmb_header_opcode_names[] = {
-      {"Query",           0 },
-      {"Registration",      5 },
-      {"Release",           6 },
-      {"WACK",              7 },
-      {"Refresh",           8 },
-      {"Refresh(altcode)",  9 },
-      {"Multi-homed Registration", 15 },
-      {0, -1 }
+       {"Query",           0 },
+       {"Registration",      5 },
+       {"Release",           6 },
+       {"WACK",              7 },
+       {"Refresh",           8 },
+       {"Refresh(altcode)",  9 },
+       {"Multi-homed Registration", 15 },
+       {0, -1 }
 };
 
 /****************************************************************************
@@ -58,7 +57,7 @@ static const char *lookup_opcode_name( int opcode )
 /****************************************************************************
   print out a res_rec structure
   ****************************************************************************/
-static void debug_nmb_res_rec(struct res_rec *res, char *hdr)
+static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
 {
   int i, j;
 
@@ -296,7 +295,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
   if (name->scope[0]) {
     /* XXXX this scope handling needs testing */
     ret += strlen(name->scope) + 1;
-    pstrcpy(&buf[offset+1],name->scope);  
+    safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope));  
   
     p = &buf[offset+1];
     while ((p = strchr_m(p,'.'))) {
@@ -767,6 +766,14 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
   XXXX This currently doesn't handle packets too big for one
   datagram. It should split them and use the packet_offset, more and
   first flags to handle the fragmentation. Yuck.
+
+    [...but it isn't clear that we would ever need to send a
+    a fragmented NBT Datagram.  The IP layer does its own
+    fragmentation to ensure that messages can fit into the path
+    MTU.  It *is* important to be able to receive and rebuild
+    fragmented NBT datagrams, just in case someone out there
+    really has implemented this 'feature'.  crh -)------ ]
+
   ******************************************************************/
 static int build_dgram(char *buf,struct packet_struct *p)
 {
@@ -796,24 +803,27 @@ static int build_dgram(char *buf,struct packet_struct *p)
   memcpy(ubuf+offset,dgram->data,dgram->datasize);
   offset += dgram->datasize;
 
-  /* automatically set the dgm_length */
-  dgram->header.dgm_length = offset;
+  /* automatically set the dgm_length
+   * NOTE: RFC1002 says the dgm_length does *not*
+   *       include the fourteen-byte header. crh
+   */
+  dgram->header.dgm_length = (offset - 14);
   RSSVAL(ubuf,10,dgram->header.dgm_length); 
 
   return(offset);
 }
 
 /*******************************************************************
-  build a nmb name
- *******************************************************************/
+ Build a nmb name
+*******************************************************************/
+
 void make_nmb_name( struct nmb_name *n, const char *name, int type)
 {
-       extern pstring global_scope;
        memset( (char *)n, '\0', sizeof(struct nmb_name) );
        push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER);
        n->name_type = (unsigned int)type & 0xFF;
-       StrnCpy( n->scope, global_scope, 63 );
-       strupper( n->scope );
+       StrnCpy( n->scope, global_scope(), 63 );
+       strupper_m( n->scope );
 }
 
 /*******************************************************************
@@ -953,7 +963,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
        timeout.tv_sec = t/1000;
        timeout.tv_usec = 1000*(t%1000);
 
-       if ((ret = sys_select_intr(fd+1,&fds,&timeout)) == -1) {
+       if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
                /* errno should be EBADF or EINVAL. */
                DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
                return NULL;
@@ -995,7 +1005,7 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
   queue. The packet must be a reply packet and have the specified mailslot name
   The timeout is in milliseconds
   ***************************************************************************/
-struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name)
+struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name)
 {
        struct packet_struct *p;
 
@@ -1014,7 +1024,7 @@ struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name)
 /****************************************************************************
  see if a datagram has the right mailslot name
 ***************************************************************************/
-BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name)
+BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
 {
        struct dgram_packet *dgram = &p->packet.dgram;
        char *buf;
@@ -1035,7 +1045,7 @@ BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name)
 /****************************************************************************
 return the number of bits that match between two 4 character buffers
   ***************************************************************************/
-static int matching_bits(uchar *p1, uchar *p2)
+int matching_quad_bits(uchar *p1, uchar *p2)
 {
        int i, j, ret = 0;
        for (i=0; i<4; i++) {
@@ -1061,7 +1071,7 @@ compare two query reply records
   ***************************************************************************/
 static int name_query_comp(uchar *p1, uchar *p2)
 {
-       return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip);
+       return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip);
 }
 
 /****************************************************************************
@@ -1119,12 +1129,14 @@ char *dns_to_netbios_name(char *dns_name)
 
 
 /****************************************************************************
-interpret the weird netbios "name". Return the name type
+interpret the weird netbios "name" into a unix fstring. Return the name type
 ****************************************************************************/
-static int name_interpret(char *in,char *out)
+static int name_interpret(char *in, fstring name)
 {
   int ret;
   int len = (*in++) / 2;
+  fstring out_string;
+  char *out = out_string;
 
   *out=0;
 
@@ -1140,8 +1152,8 @@ static int name_interpret(char *in,char *out)
       in += 2;
       out++;
     }
-  *out = 0;
   ret = out[-1];
+  out[-1] = 0;
 
 #ifdef NETBIOS_SCOPE
   /* Handle any scope names */
@@ -1155,6 +1167,8 @@ static int name_interpret(char *in,char *out)
       in += len;
     }
 #endif
+  pull_ascii(name, out_string, sizeof(fstring), sizeof(out_string), STR_TERMINATE);
+
   return(ret);
 }
 
@@ -1170,7 +1184,6 @@ int name_mangle( char *In, char *Out, char name_type )
   int   len;
   char  buf[20];
   char *p = Out;
-  extern pstring global_scope;
 
   /* Safely copy the input string, In, into buf[]. */
   (void)memset( buf, 0, 20 );
@@ -1194,9 +1207,9 @@ int name_mangle( char *In, char *Out, char name_type )
   p[0] = '\0';
 
   /* Add the scope string. */
-  for( i = 0, len = 0; NULL != global_scope; i++, len++ )
+  for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ )
     {
-    switch( global_scope[i] )
+    switch( (global_scope())[i] )
       {
       case '\0':
         p[0]     = len;
@@ -1209,7 +1222,7 @@ int name_mangle( char *In, char *Out, char name_type )
         len  = -1;
         break;
       default:
-        p[len+1] = global_scope[i];
+        p[len+1] = (global_scope())[i];
         break;
       }
     }
@@ -1236,9 +1249,9 @@ static char *name_ptr(char *buf,int ofs)
 }  
 
 /****************************************************************************
-extract a netbios name from a buf
+extract a netbios name from a buf (into a unix string) return name type
 ****************************************************************************/
-int name_extract(char *buf,int ofs,char *name)
+int name_extract(char *buf,int ofs, fstring name)
 {
   char *p = name_ptr(buf,ofs);
   int d = PTR_DIFF(p,buf+ofs);