for (j = 0; j < 16; j++)
{
- unsigned char x = res->rdata[i+j];
+ uchar x = res->rdata[i+j];
if (x < 32 || x > 127) x = '.';
if (i+j >= res->rdlength) break;
for (j = 0; j < 16; j++)
{
if (i+j >= res->rdlength) break;
- DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
+ DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j]));
}
DEBUGADD(4, ("\n"));
/*******************************************************************
handle "compressed" name pointers
******************************************************************/
-static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
+static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length,
BOOL *got_pointer,int *ret)
{
int loop_count=0;
static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name)
{
int m,n=0;
- unsigned char *ubuf = (unsigned char *)inbuf;
+ uchar *ubuf = (uchar *)inbuf;
int ret = 0;
BOOL got_pointer=False;
+ int loop_count=0;
- if (length - offset < 2) return(0);
+ if (length - offset < 2)
+ return(0);
/* handle initial name pointers */
- if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
+ if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
+ return(0);
m = ubuf[offset];
- if (!m) return(0);
- if ((m & 0xC0) || offset+m+2 > length) return(0);
+ if (!m)
+ return(0);
+ if ((m & 0xC0) || offset+m+2 > length)
+ return(0);
- bzero((char *)name,sizeof(*name));
+ memset((char *)name,'\0',sizeof(*name));
/* the "compressed" part */
- if (!got_pointer) ret += m + 2;
+ if (!got_pointer)
+ ret += m + 2;
offset++;
- while (m) {
- unsigned char c1,c2;
+ while (m > 0) {
+ uchar c1,c2;
c1 = ubuf[offset++]-'A';
c2 = ubuf[offset++]-'A';
- if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) return(0);
+ if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
+ return(0);
name->name[n++] = (c1<<4) | c2;
m -= 2;
}
if (n==16) {
/* parse out the name type,
its always in the 16th byte of the name */
- name->name_type = ((unsigned char)name->name[15]) & 0xff;
+ name->name_type = ((uchar)name->name[15]) & 0xff;
/* remove trailing spaces */
name->name[15] = 0;
n = 14;
- while (n && name->name[n]==' ') name->name[n--] = 0;
+ while (n && name->name[n]==' ')
+ name->name[n--] = 0;
}
/* now the domain parts (if any) */
n = 0;
while (ubuf[offset]) {
/* we can have pointers within the domain part as well */
- if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
+ if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
+ return(0);
m = ubuf[offset];
- if (!got_pointer) ret += m+1;
- if (n) name->scope[n++] = '.';
- if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
+ /*
+ * Don't allow null domain parts.
+ */
+ if (!m)
+ return(0);
+ if (!got_pointer)
+ ret += m+1;
+ if (n)
+ name->scope[n++] = '.';
+ if (m+2+offset>length || n+m+1>sizeof(name->scope))
+ return(0);
offset++;
- while (m--) name->scope[n++] = (char)ubuf[offset++];
+ while (m--)
+ name->scope[n++] = (char)ubuf[offset++];
+
+ /*
+ * Watch for malicious loops.
+ */
+ if (loop_count++ == 10)
+ return 0;
}
name->scope[n++] = 0;
if (strcmp(name->name,"*") == 0) {
/* special case for wildcard name */
- bzero(buf1,20);
+ memset(buf1,'\0',20);
buf1[0] = '*';
buf1[15] = name->name_type;
} else {
p = &buf[offset+1];
while ((p = strchr(p,'.'))) {
- buf[offset] = PTR_DIFF(p,&buf[offset]);
- offset += buf[offset];
+ buf[offset] = PTR_DIFF(p,&buf[offset+1]);
+ offset += (buf[offset] + 1);
p = &buf[offset+1];
}
buf[offset] = strlen(&buf[offset+1]);
return(ret);
}
-
/*******************************************************************
useful for debugging messages
******************************************************************/
static fstring ret[4];
char *p = ret[i];
- nmb_safe_namestr(n, p, sizeof(fstring));
+ if (!n->scope[0])
+ slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
+ else
+ slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
i = (i+1)%4;
return(p);
}
-/*******************************************************************
- useful for debugging messages
- ******************************************************************/
-void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len)
-{
- if (!n->scope[0])
- slprintf(str, len-1, "%s<%02x>",n->name,n->name_type);
- else
- slprintf(str, len-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
-}
-
/*******************************************************************
allocate and parse some resource records
******************************************************************/
*recs = (struct res_rec *)malloc(sizeof(**recs)*count);
if (!*recs) return(False);
- bzero(*recs,sizeof(**recs)*count);
+ memset((char *)*recs,'\0',sizeof(**recs)*count);
for (i=0;i<count;i++) {
int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
(*offset) += l;
if (!l || (*offset)+10 > length) {
free(*recs);
+ *recs = NULL;
return(False);
}
(*recs)[i].rr_type = RSVAL(inbuf,(*offset));
if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
(*offset)+(*recs)[i].rdlength > length) {
free(*recs);
+ *recs = NULL;
return(False);
}
memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
/*******************************************************************
put a compressed name pointer record into a packet
******************************************************************/
-static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset)
+static int put_compressed_name_ptr(uchar *buf,int offset,struct res_rec *rec,int ptr_offset)
{
int ret=0;
buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
int offset;
int flags;
- bzero((char *)dgram,sizeof(*dgram));
+ memset((char *)dgram,'\0',sizeof(*dgram));
if (length < 14) return(False);
{
int nm_flags,offset;
- bzero((char *)nmb,sizeof(*nmb));
+ memset((char *)nmb,'\0',sizeof(*nmb));
if (length < 12) return(False);
free_and_exit:
- if(copy_nmb->answers)
+ if(copy_nmb->answers) {
free((char *)copy_nmb->answers);
- if(copy_nmb->nsrecs)
+ copy_nmb->answers = NULL;
+ }
+ if(copy_nmb->nsrecs) {
free((char *)copy_nmb->nsrecs);
- if(copy_nmb->additional)
+ copy_nmb->nsrecs = NULL;
+ }
+ if(copy_nmb->additional) {
free((char *)copy_nmb->additional);
+ copy_nmb->additional = NULL;
+ }
free((char *)pkt_copy);
DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
******************************************************************/
static void free_nmb_packet(struct nmb_packet *nmb)
{
- if (nmb->answers) free(nmb->answers);
- if (nmb->nsrecs) free(nmb->nsrecs);
- if (nmb->additional) free(nmb->additional);
+ 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;
+ }
}
/*******************************************************************
free_nmb_packet(&packet->packet.nmb);
else if (packet->packet_type == DGRAM_PACKET)
free_dgram_packet(&packet->packet.dgram);
+ ZERO_STRUCTPN(packet);
free(packet);
}
+/*******************************************************************
+parse a packet buffer into a packet structure
+ ******************************************************************/
+struct packet_struct *parse_packet(char *buf,int length,
+ enum packet_type packet_type)
+{
+ extern struct in_addr lastip;
+ extern int lastport;
+ struct packet_struct *p;
+ BOOL ok=False;
+
+ p = (struct packet_struct *)malloc(sizeof(*p));
+ if (!p) return(NULL);
+
+ p->next = NULL;
+ p->prev = NULL;
+ p->ip = lastip;
+ p->port = lastport;
+ p->locked = False;
+ p->timestamp = time(NULL);
+ p->packet_type = packet_type;
+
+ switch (packet_type) {
+ case NMB_PACKET:
+ ok = parse_nmb(buf,length,&p->packet.nmb);
+ break;
+
+ case DGRAM_PACKET:
+ ok = parse_dgram(buf,length,&p->packet.dgram);
+ break;
+ }
+
+ if (!ok) {
+ free_packet(p);
+ return NULL;
+ }
+
+ return p;
+}
+
/*******************************************************************
read a packet from a socket and parse it, returning a packet ready
to be used or put on the queue. This assumes a UDP socket
******************************************************************/
struct packet_struct *read_packet(int fd,enum packet_type packet_type)
{
- extern struct in_addr lastip;
- struct nmb_state con;
- extern int lastport;
- struct packet_struct *packet;
- char buf[MAX_DGRAM_SIZE];
- int length;
- BOOL ok=False;
-
- if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
- {
- uint16 trn_id = 0;
- if (!read_nmb_sock(fd, &con))
- {
- return False;
- }
- if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
- {
- return False;
- }
- }
+ struct packet_struct *packet;
+ char buf[MAX_DGRAM_SIZE];
+ int length;
length = read_udp_socket(fd,buf,sizeof(buf));
+ if (length < MIN_DGRAM_SIZE) return(NULL);
- dump_data(100, buf, length);
+ packet = parse_packet(buf, length, packet_type);
+ if (!packet) return NULL;
- if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
- {
- uint16 trn_id = 0;
- if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
- {
- return False;
- }
- }
+ packet->fd = fd;
- if (length < MIN_DGRAM_SIZE) return(NULL);
-
- if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
- {
- lastip = con.ip;
- lastport = con.port;
- }
-
- packet = (struct packet_struct *)malloc(sizeof(*packet));
- if (!packet) return(NULL);
-
- packet->next = NULL;
- packet->prev = NULL;
- packet->ip = lastip;
- packet->port = lastport;
- packet->fd = fd;
- packet->locked = False;
- packet->timestamp = time(NULL);
- packet->packet_type = packet_type;
- switch (packet_type)
- {
- case NMB_PACKET:
- case NMB_SOCK_PACKET:
- ok = parse_nmb(buf,length,&packet->packet.nmb);
- break;
-
- case DGRAM_PACKET:
- case DGRAM_SOCK_PACKET:
- ok = parse_dgram(buf,length,&packet->packet.dgram);
- break;
- }
- if (!ok) {
- DEBUG(10,("read_packet: discarding packet id = %d\n",
- packet->packet.nmb.header.name_trn_id));
- free(packet);
- return(NULL);
- }
-
- num_good_receives++;
-
- DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
- length, inet_ntoa(packet->ip), packet->port ) );
-
- return(packet);
+ num_good_receives++;
+
+ DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
+ length, inet_ntoa(packet->ip), packet->port ) );
+
+ return(packet);
}
******************************************************************/
static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
{
- BOOL ret;
+ BOOL ret = False;
+ int i;
struct sockaddr_in sock_out;
/* set the address and port */
- bzero((char *)&sock_out,sizeof(sock_out));
+ memset((char *)&sock_out,'\0',sizeof(sock_out));
putip((char *)&sock_out.sin_addr,(char *)&ip);
sock_out.sin_port = htons( port );
sock_out.sin_family = AF_INET;
DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
len, inet_ntoa(ip), port ) );
+
+ /*
+ * Patch to fix asynch error notifications from Linux kernel.
+ */
- ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
- sizeof(sock_out)) >= 0);
+ for (i = 0; i < 5; i++) {
+ ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0);
+ if (ret || errno != ECONNREFUSED)
+ break;
+ }
if (!ret)
DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
static int build_dgram(char *buf,struct packet_struct *p)
{
struct dgram_packet *dgram = &p->packet.dgram;
- unsigned char *ubuf = (unsigned char *)buf;
+ uchar *ubuf = (uchar *)buf;
int offset=0;
/* put in the header */
ubuf[0] = dgram->header.msg_type;
- ubuf[1] = (((unsigned int)dgram->header.flags.node_type)<<2);
+ ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
if (dgram->header.flags.more) ubuf[1] |= 1;
if (dgram->header.flags.first) ubuf[1] |= 2;
RSSVAL(ubuf,2,dgram->header.dgm_id);
/*******************************************************************
build a nmb name
*******************************************************************/
-void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope )
+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) );
- StrnCpy( n->name, name, 15 );
- strupper( n->name );
+ push_ascii(n->name, name, 15, STR_TERMINATE|STR_UPPER);
n->name_type = (unsigned int)type & 0xFF;
- StrnCpy( n->scope, this_scope, 63 );
+ StrnCpy( n->scope, global_scope, 63 );
strupper( n->scope );
}
static int build_nmb(char *buf,struct packet_struct *p)
{
struct nmb_packet *nmb = &p->packet.nmb;
- unsigned char *ubuf = (unsigned char *)buf;
+ uchar *ubuf = (uchar *)buf;
int offset=0;
/* put in the header */
}
+/*******************************************************************
+linearise a packet
+ ******************************************************************/
+int build_packet(char *buf, struct packet_struct *p)
+{
+ int len = 0;
+
+ switch (p->packet_type) {
+ case NMB_PACKET:
+ len = build_nmb(buf,p);
+ break;
+
+ case DGRAM_PACKET:
+ len = build_dgram(buf,p);
+ break;
+ }
+
+ return len;
+}
+
/*******************************************************************
send a packet_struct
******************************************************************/
char buf[1024];
int len=0;
- DEBUG(100,("send_packet: %d %d\n", p->fd, p->packet_type));
+ memset(buf,'\0',sizeof(buf));
- bzero(buf,sizeof(buf));
-
- switch (p->packet_type)
- {
- case NMB_PACKET:
- case NMB_SOCK_PACKET:
- len = build_nmb(buf,p);
- debug_nmb_packet(p);
- break;
-
- case DGRAM_PACKET:
- case DGRAM_SOCK_PACKET:
- len = build_dgram(buf,p);
- break;
- }
+ len = build_packet(buf, p);
if (!len) return(False);
- switch (p->packet_type)
- {
- case DGRAM_PACKET:
- case NMB_PACKET:
- return(send_udp(p->fd,buf,len,p->ip,p->port));
- break;
+ return(send_udp(p->fd,buf,len,p->ip,p->port));
+}
- case NMB_SOCK_PACKET:
- case DGRAM_SOCK_PACKET:
- {
- fstring qbuf;
- struct nmb_state nmb;
- int qlen;
- uint16 trn_id;
- char *q = qbuf + 4;
+/****************************************************************************
+ receive a packet with timeout on a open UDP filedescriptor
+ The timeout is in milliseconds
+ ***************************************************************************/
+struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
+{
+ fd_set fds;
+ struct timeval timeout;
+ int ret;
+
+ FD_ZERO(&fds);
+ FD_SET(fd,&fds);
+ timeout.tv_sec = t/1000;
+ timeout.tv_usec = 1000*(t%1000);
+
+ if ((ret = sys_select_intr(fd+1,&fds,&timeout)) == -1) {
+ /* errno should be EBADF or EINVAL. */
+ DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
+ return NULL;
+ }
- nmb.ip = p->ip;
- nmb.port = p->port;
+ if (ret == 0) /* timeout */
+ return NULL;
- SSVAL(q, 0, 0);
- q += 2;
- SSVAL(q, 0, 0);
- q += 2;
- memcpy(q, &nmb, sizeof(nmb));
- q += sizeof(nmb);
+ if (FD_ISSET(fd,&fds))
+ return(read_packet(fd,type));
+
+ return(NULL);
+}
- qlen = PTR_DIFF(q, qbuf);
- SIVAL(qbuf, 0, qlen);
- dump_data(100, qbuf, qlen);
+/****************************************************************************
+ receive a UDP/137 packet either via UDP or from the unexpected packet
+ queue. The packet must be a reply packet and have the specified trn_id
+ The timeout is in milliseconds
+ ***************************************************************************/
+struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
+{
+ struct packet_struct *p;
- if (write(p->fd,qbuf,qlen) != qlen)
- {
- DEBUG(0,("send_packet: write hdr failed\n"));
- return False;
- }
- if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
- {
- DEBUG(0,("send_packet: 1st ack failed\n"));
- return False;
- }
- if (write(p->fd,buf,len) != len)
- {
- DEBUG(0,("send_packet: write packet failed\n"));
- return False;
- }
- if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
- {
- DEBUG(0,("send_packet: 2nd ack failed\n"));
- return False;
- }
- return True;
+ p = receive_packet(fd, NMB_PACKET, t);
+
+ if (p && p->packet.nmb.header.response &&
+ p->packet.nmb.header.name_trn_id == trn_id) {
+ return p;
}
- }
+ if (p) free_packet(p);
- return False;
+ /* try the unexpected packet queue */
+ return receive_unexpected(NMB_PACKET, trn_id, NULL);
}
/****************************************************************************
- receive a packet with timeout on a open UDP filedescriptor
+ receive a UDP/138 packet either via UDP or from the unexpected packet
+ queue. The packet must be a reply packet and have the specified mailslot name
The timeout is in milliseconds
***************************************************************************/
-struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
+struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name)
{
- fd_set fds;
- struct timeval timeout;
+ struct packet_struct *p;
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
- timeout.tv_sec = t/1000;
- timeout.tv_usec = 1000*(t%1000);
+ p = receive_packet(fd, DGRAM_PACKET, t);
- DEBUG(100,("receive_packet: %d %d\n", fd, type));
- sys_select(fd+1,&fds,NULL, &timeout);
+ if (p && match_mailslot_name(p, mailslot_name)) {
+ return p;
+ }
+ if (p) free_packet(p);
- if (FD_ISSET(fd,&fds))
- return(read_packet(fd,type));
+ /* try the unexpected packet queue */
+ return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
+}
- return(NULL);
+
+/****************************************************************************
+ see if a datagram has the right mailslot name
+***************************************************************************/
+BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name)
+{
+ struct dgram_packet *dgram = &p->packet.dgram;
+ char *buf;
+
+ buf = &dgram->data[0];
+ buf -= 4;
+
+ buf = smb_buf(buf);
+
+ if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
+ return True;
+ }
+
+ return False;
}
qsort(data, n, 6, QSORT_CAST name_query_comp);
}
-BOOL read_nmb_sock(int c, struct nmb_state *con)
-{
- fstring buf;
- char *p = buf;
- int rl;
- uint32 len;
- uint16 version;
- uint16 command;
- ZERO_STRUCTP(con);
+#define TRUNCATE_NETBIOS_NAME 1
- rl = read(c, &buf, sizeof(len));
+/*******************************************************************
+ convert, possibly using a stupid microsoft-ism which has destroyed
+ the transport independence of netbios (for CIFS vendors that usually
+ use the Win95-type methods, not for NT to NT communication, which uses
+ DCE/RPC and therefore full-length unicode strings...) a dns name into
+ a netbios name.
- if (rl < 0)
- {
- DEBUG(0,("read_nmb_sock: error\n"));
- return False;
- }
- if (rl != sizeof(len))
+ the netbios name (NOT necessarily null-terminated) is truncated to 15
+ characters.
+
+ ******************************************************************/
+char *dns_to_netbios_name(char *dns_name)
+{
+ static char netbios_name[16];
+ int i;
+ StrnCpy(netbios_name, dns_name, 15);
+ netbios_name[15] = 0;
+
+#ifdef TRUNCATE_NETBIOS_NAME
+ /* ok. this is because of a stupid microsoft-ism. if the called host
+ name contains a '.', microsoft clients expect you to truncate the
+ netbios name up to and including the '.' this even applies, by
+ mistake, to workgroup (domain) names, which is _really_ daft.
+ */
+ for (i = 15; i >= 0; i--)
{
- DEBUG(0,("Unable to read length\n"));
- dump_data(0, buf, sizeof(len));
- return False;
+ if (netbios_name[i] == '.')
+ {
+ netbios_name[i] = 0;
+ break;
+ }
}
+#endif /* TRUNCATE_NETBIOS_NAME */
- len = IVAL(buf, 0);
+ return netbios_name;
+}
- if (len > sizeof(buf))
- {
- DEBUG(0,("length %d too long\n", len));
- return False;
- }
- rl = read(c, buf, len);
+/****************************************************************************
+interpret the weird netbios "name". Return the name type
+****************************************************************************/
+static int name_interpret(char *in,char *out)
+{
+ int ret;
+ int len = (*in++) / 2;
- if (rl < 0)
- {
- DEBUG(0,("Unable to read from connection\n"));
- return False;
- }
-
-#ifdef DEBUG_PASSWORD
- dump_data(100, buf, rl);
+ *out=0;
+
+ if (len > 30 || len<1) return(0);
+
+ while (len--)
+ {
+ if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
+ *out = 0;
+ return(0);
+ }
+ *out = ((in[0]-'A')<<4) + (in[1]-'A');
+ in += 2;
+ out++;
+ }
+ *out = 0;
+ ret = out[-1];
+
+#ifdef NETBIOS_SCOPE
+ /* Handle any scope names */
+ while(*in)
+ {
+ *out++ = '.'; /* Scope names are separated by periods */
+ len = *(uchar *)in++;
+ StrnCpy(out, in, len);
+ out += len;
+ *out=0;
+ in += len;
+ }
#endif
- version = SVAL(p, 0);
- p += 2;
- command = SVAL(p, 0);
- p += 2;
+ return(ret);
+}
- memcpy(con, p, sizeof(*con));
- p += sizeof(*con);
+/****************************************************************************
+mangle a name into netbios format
- DEBUG(10,("read_nmb_sock: ip %s port: %d\n",
- inet_ntoa(con->ip), con->port));
+ Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
+****************************************************************************/
+int name_mangle( char *In, char *Out, char name_type )
+ {
+ int i;
+ int c;
+ 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 );
+ if (strcmp(In,"*") == 0)
+ buf[0] = '*';
+ else
+ (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
- if (PTR_DIFF(p, buf) != rl)
- {
- DEBUG(0,("Buffer size %d %d!\n",
- PTR_DIFF(p, buf), rl));
- return False;
- }
+ /* Place the length of the first field into the output buffer. */
+ p[0] = 32;
+ p++;
- return True;
-}
+ /* Now convert the name to the rfc1001/1002 format. */
+ for( i = 0; i < 16; i++ )
+ {
+ c = toupper( buf[i] );
+ p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
+ p[(i*2)+1] = (c & 0x000F) + 'A';
+ }
+ p += 32;
+ p[0] = '\0';
+
+ /* Add the scope string. */
+ for( i = 0, len = 0; NULL != global_scope; i++, len++ )
+ {
+ switch( global_scope[i] )
+ {
+ case '\0':
+ p[0] = len;
+ if( len > 0 )
+ p[len+1] = 0;
+ return( name_len(Out) );
+ case '.':
+ p[0] = len;
+ p += (len + 1);
+ len = -1;
+ break;
+ default:
+ p[len+1] = global_scope[i];
+ break;
+ }
+ }
+
+ return( name_len(Out) );
+ } /* name_mangle */
-int get_nmb_sock(void)
+
+/****************************************************************************
+find a pointer to a netbios name
+****************************************************************************/
+static char *name_ptr(char *buf,int ofs)
{
- fstring path;
- slprintf(path, sizeof(path)-1, "/tmp/.nmb/agent");
+ uchar c = *(uchar *)(buf+ofs);
- return open_pipe_sock(path);
+ if ((c & 0xC0) == 0xC0)
+ {
+ uint16 l = RSVAL(buf, ofs) & 0x3FFF;
+ DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
+ return(buf + l);
+ }
+ else
+ return(buf+ofs);
+}
+
+/****************************************************************************
+extract a netbios name from a buf
+****************************************************************************/
+int name_extract(char *buf,int ofs,char *name)
+{
+ char *p = name_ptr(buf,ofs);
+ int d = PTR_DIFF(p,buf+ofs);
+ pstrcpy(name,"");
+ if (d < -50 || d > 50) return(0);
+ return(name_interpret(p,name));
}
+
+/****************************************************************************
+return the total storage length of a mangled name
+****************************************************************************/
+int name_len(char *s1)
+{
+ /* NOTE: this argument _must_ be unsigned */
+ uchar *s = (uchar *)s1;
+ int len;
+
+ /* If the two high bits of the byte are set, return 2. */
+ if (0xC0 == (*s & 0xC0))
+ return(2);
+
+ /* Add up the length bytes. */
+ for (len = 1; (*s); s += (*s) + 1) {
+ len += *s + 1;
+ SMB_ASSERT(len < 80);
+ }
+
+ return(len);
+} /* name_len */
+
+