updated the 3.0 branch from the head branch - ready for alpha18
[sfrench/samba-autobuild/.git] / source3 / libsmb / nmblib.c
index 9d7167f30541eaa6ee28823f1e0b7c6c81038c37..ba0d8cee5de10ea5f61e948904aed16379f6f873 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
    
 
 #include "includes.h"
 
-extern int DEBUGLEVEL;
-
 int num_good_sends = 0;
 int num_good_receives = 0;
 
-static struct opcode_names {
+static const struct opcode_names {
        char *nmb_opcode_name;
        int opcode;
 } nmb_header_opcode_names[] = {
@@ -44,9 +41,9 @@ static struct opcode_names {
 /****************************************************************************
  * Lookup a nmb opcode name.
  ****************************************************************************/
-static char *lookup_opcode_name( int opcode )
+static const char *lookup_opcode_name( int opcode )
 {
-  struct opcode_names *op_namep;
+  const struct opcode_names *op_namep;
   int i;
 
   for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
@@ -173,13 +170,14 @@ static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length,
   parse a nmb name from "compressed" format to something readable
   return the space taken by the name, or 0 if the name is invalid
   ******************************************************************/
-static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name)
+static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
 {
   int m,n=0;
   uchar *ubuf = (uchar *)inbuf;
   int ret = 0;
   BOOL got_pointer=False;
   int loop_count=0;
+  int offset = ofs;
 
   if (length - offset < 2)
     return(0);  
@@ -345,8 +343,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
     int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
     (*offset) += l;
     if (!l || (*offset)+10 > length) {
-      free(*recs);
-      *recs = NULL;
+      SAFE_FREE(*recs);
       return(False);
     }
     (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
@@ -356,8 +353,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
     (*offset) += 10;
     if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || 
        (*offset)+(*recs)[i].rdlength > length) {
-      free(*recs);
-      *recs = NULL;
+      SAFE_FREE(*recs);
       return(False);
     }
     memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
@@ -580,19 +576,10 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
 
 free_and_exit:
 
-  if(copy_nmb->answers) {
-    free((char *)copy_nmb->answers);
-    copy_nmb->answers = NULL;
-  }
-  if(copy_nmb->nsrecs) {
-    free((char *)copy_nmb->nsrecs);
-    copy_nmb->nsrecs = NULL;
-  }
-  if(copy_nmb->additional) {
-    free((char *)copy_nmb->additional);
-    copy_nmb->additional = NULL;
-  }
-  free((char *)pkt_copy);
+  SAFE_FREE(copy_nmb->answers);
+  SAFE_FREE(copy_nmb->nsrecs);
+  SAFE_FREE(copy_nmb->additional);
+  SAFE_FREE(pkt_copy);
 
   DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
   return NULL;
@@ -640,18 +627,9 @@ struct packet_struct *copy_packet(struct packet_struct *packet)
   ******************************************************************/
 static void free_nmb_packet(struct nmb_packet *nmb)
 {  
-  if (nmb->answers) {
-    free(nmb->answers);
-    nmb->answers = NULL;
-  }
-  if (nmb->nsrecs) {
-    free(nmb->nsrecs);
-    nmb->nsrecs = NULL;
-  }
-  if (nmb->additional) {
-    free(nmb->additional);
-    nmb->additional = NULL;
-  }
+  SAFE_FREE(nmb->answers);
+  SAFE_FREE(nmb->nsrecs);
+  SAFE_FREE(nmb->additional);
 }
 
 /*******************************************************************
@@ -674,7 +652,7 @@ void free_packet(struct packet_struct *packet)
   else if (packet->packet_type == DGRAM_PACKET)
     free_dgram_packet(&packet->packet.dgram);
   ZERO_STRUCTPN(packet);
-  free(packet);
+  SAFE_FREE(packet);
 }
 
 /*******************************************************************
@@ -788,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)
 {
@@ -817,8 +803,11 @@ 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);
@@ -831,7 +820,7 @@ 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, 15, STR_TERMINATE|STR_UPPER);
+       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 );
@@ -974,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;
@@ -1056,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++) {
@@ -1082,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);
 }
 
 /****************************************************************************
@@ -1289,5 +1278,3 @@ int name_len(char *s1)
 
        return(len);
 } /* name_len */
-
-