#include "config.h"
#endif
+#ifndef lint
+static const char rcsid[] =
+ "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.12 2000-12-04 00:35:45 guy Exp $";
+#endif
+
#include <sys/param.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
-#include <net/if.h>
#include <netinet/in.h>
-#include <netinet/if_ether.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
+#include "interface.h"
#include "smb.h"
-extern uchar *startbuf;
+extern const uchar *startbuf;
/*******************************************************************
interpret a 32 bit dos packed date/time to some parameters
/*******************************************************************
create a unix date from a dos date
********************************************************************/
-time_t make_unix_date(void *date_ptr)
+static time_t make_unix_date(const void *date_ptr)
{
uint32 dos_date=0;
struct tm t;
/*******************************************************************
create a unix date from a dos date
********************************************************************/
-time_t make_unix_date2(void *date_ptr)
+static time_t make_unix_date2(const void *date_ptr)
{
uint32 x,x2;
interpret an 8 byte "filetime" structure to a time_t
It's originally in "100ns units since jan 1st 1601"
****************************************************************************/
-time_t interpret_long_date(char *p)
+static time_t interpret_long_date(const char *p)
{
double d;
time_t ret;
/****************************************************************************
-interpret the weird netbios "name". Return the name type
+interpret the weird netbios "name". Return the name type, or -1 if
+we run past the end of the buffer
****************************************************************************/
-static int name_interpret(char *in,char *out)
+static int name_interpret(const uchar *in,const uchar *maxbuf,char *out)
{
int ret;
- int len = (*in++) / 2;
+ int len;
+
+ if (in >= maxbuf)
+ return(-1); /* name goes past the end of the buffer */
+ TCHECK2(*in, 1);
+ len = (*in++) / 2;
*out=0;
while (len--)
{
+ if (in + 1 >= maxbuf)
+ return(-1); /* name goes past the end of the buffer */
+ TCHECK2(*in, 2);
if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
*out = 0;
return(0);
ret = out[-1];
return(ret);
+
+trunc:
+ return(-1);
}
/****************************************************************************
find a pointer to a netbios name
****************************************************************************/
-static char *name_ptr(char *buf,int ofs)
+static const uchar *name_ptr(const uchar *buf,int ofs,const uchar *maxbuf)
{
- unsigned char c = *(unsigned char *)(buf+ofs);
+ const uchar *p;
+ uchar c;
+ p = buf+ofs;
+ if (p >= maxbuf)
+ return(NULL); /* name goes past the end of the buffer */
+ TCHECK2(*p, 1);
+
+ c = *p;
+
+ /* XXX - this should use the same code that the DNS dissector does */
if ((c & 0xC0) == 0xC0)
{
uint16 l = RSVAL(buf, ofs) & 0x3FFF;
+ if (l == 0)
+ {
+ /* We have a pointer that points to itself. */
+ return(NULL);
+ }
+ p = buf + l;
+ if (p >= maxbuf)
+ return(NULL); /* name goes past the end of the buffer */
+ TCHECK2(*p, 1);
return(buf + l);
}
else
return(buf+ofs);
+
+trunc:
+ return(NULL); /* name goes past the end of the buffer */
}
/****************************************************************************
extract a netbios name from a buf
****************************************************************************/
-static int name_extract(char *buf,int ofs,char *name)
+static int name_extract(const uchar *buf,int ofs,const uchar *maxbuf,char *name)
{
- char *p = name_ptr(buf,ofs);
- int d = PTR_DIFF(p,buf+ofs);
+ const uchar *p = name_ptr(buf,ofs,maxbuf);
+ if (p == NULL)
+ return(-1); /* error (probably name going past end of buffer) */
strcpy(name,"");
- return(name_interpret(p,name));
+ return(name_interpret(p,maxbuf,name));
}
/****************************************************************************
return the total storage length of a mangled name
****************************************************************************/
-static int name_len(unsigned char *s)
+static int name_len(const unsigned char *s, const unsigned char *maxbuf)
{
- char *s0 = s;
- unsigned char c = *(unsigned char *)s;
+ const unsigned char *s0 = s;
+ unsigned char c;
+
+ if (s >= maxbuf)
+ return(-1); /* name goes past the end of the buffer */
+ TCHECK2(*s, 1);
+ c = *s;
if ((c & 0xC0) == 0xC0)
- return(2);
- while (*s) s += (*s)+1;
+ return(2);
+ while (*s)
+ {
+ if (s >= maxbuf)
+ return(-1); /* name goes past the end of the buffer */
+ TCHECK2(*s, 1);
+ s += (*s)+1;
+ }
return(PTR_DIFF(s,s0)+1);
+
+trunc:
+ return(-1); /* name goes past the end of the buffer */
}
-void print_asc(unsigned char *buf,int len)
+static void print_asc(const unsigned char *buf,int len)
{
int i;
for (i=0;i<len;i++)
return(f);
}
-void print_data(unsigned char *buf,int len)
+void print_data(const unsigned char *buf, int len)
{
int i=0;
if (len<=0) return;
}
/* convert a unicode string */
-static char *unistr(char *s, int *len)
+static const char *unistr(const char *s, int *len)
{
static char buf[1000];
int l=0;
return buf;
}
-uchar *fdata1(uchar *buf,char *fmt,uchar *maxbuf)
+static const uchar *fdata1(const uchar *buf, const char *fmt, const uchar *maxbuf)
{
int reverse=0;
char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|";
}
case 'S':
{
- printf("%.*s",PTR_DIFF(maxbuf,buf),unistr(buf, &len));
+ printf("%.*s",(int)PTR_DIFF(maxbuf,buf),unistr(buf, &len));
buf += len;
fmt++;
break;
{
if (*buf != 4 && *buf != 2)
printf("Error! ASCIIZ buffer of type %d (safety=%d)\n",
- *buf,PTR_DIFF(maxbuf,buf));
- printf("%.*s",PTR_DIFF(maxbuf,buf+1),unistr(buf+1, &len));
+ *buf,(int)PTR_DIFF(maxbuf,buf));
+ printf("%.*s",(int)PTR_DIFF(maxbuf,buf+1),unistr(buf+1, &len));
buf += len+1;
fmt++;
break;
int t = atoi(fmt+1);
char nbuf[255];
int name_type;
+ int len;
switch (t) {
case 1:
- name_type = name_extract(startbuf,PTR_DIFF(buf,startbuf),nbuf);
- buf += name_len(buf);
+ name_type = name_extract(startbuf,PTR_DIFF(buf,startbuf),maxbuf,
+ nbuf);
+ if (name_type < 0)
+ goto trunc;
+ len = name_len(buf,maxbuf);
+ if (len < 0)
+ goto trunc;
+ buf += len;
printf("%-15.15s NameType=0x%02X (%s)",
nbuf,name_type,name_type_str(name_type));
break;
printf("END OF BUFFER\n");
return(buf);
+
+trunc:
+ printf("\n");
+ printf("WARNING: Short packet. Try increasing the snap length\n");
+ return(NULL);
}
-uchar *fdata(uchar *buf,char *fmt,uchar *maxbuf)
+const uchar *fdata(const uchar *buf, const char *fmt, const uchar *maxbuf)
{
static int depth=0;
char s[128];
case '*':
fmt++;
while (buf < maxbuf) {
- uchar *buf2;
+ const uchar *buf2;
depth++;
buf2 = fdata(buf,fmt,maxbuf);
depth--;
case '[':
fmt++;
if (buf>=maxbuf) return(buf);
- bzero(s,sizeof(s));
+ memset(s, 0, sizeof(s));
p = strchr(fmt,']');
strncpy(s,fmt,p-fmt);
fmt = p+1;
buf = fdata1(buf,s,maxbuf);
+ if (buf == NULL)
+ return(NULL);
break;
default:
for (j=0;err[j].name;j++)
if (num == err[j].code)
{
- sprintf(ret,"%s - %s (%s)",err_classes[i].class,
+ snprintf(ret,sizeof(ret),"%s - %s (%s)",err_classes[i].class,
err[j].name,err[j].message);
return ret;
}
}
- sprintf(ret,"%s - %d",err_classes[i].class,num);
+ snprintf(ret,sizeof(ret),"%s - %d",err_classes[i].class,num);
return ret;
}
- sprintf(ret,"ERROR: Unknown error (%d,%d)",class,num);
+ snprintf(ret,sizeof(ret),"ERROR: Unknown error (%d,%d)",class,num);
return(ret);
}
-
-
-