#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.16 2001-06-25 21:04:01 itojun Exp $";
+ "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.25 2002-09-05 00:00:25 guy Exp $";
#endif
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
+#include <tcpdump-stdinc.h>
-#include <netinet/in.h>
-
-#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <time.h>
#include "interface.h"
+#include "extract.h"
#include "smb.h"
-extern const uchar *startbuf;
+extern const u_char *startbuf;
/*
* interpret a 32 bit dos packed date/time to some parameters
*/
static void
-interpret_dos_date(uint32 date, struct tm *tp)
+interpret_dos_date(u_int32_t date, struct tm *tp)
{
- uint32 p0, p1, p2, p3;
+ u_int32_t p0, p1, p2, p3;
p0 = date & 0xFF;
p1 = ((date & 0xFF00) >> 8) & 0xFF;
}
/*
+ * common portion:
* create a unix date from a dos date
*/
static time_t
-make_unix_date(const void *date_ptr)
+int_unix_date(u_int32_t dos_date)
{
- uint32 dos_date = 0;
struct tm t;
- dos_date = IVAL(date_ptr, 0);
-
if (dos_date == 0)
return(0);
/*
* create a unix date from a dos date
+ * in network byte order
*/
static time_t
-make_unix_date2(const void *date_ptr)
+make_unix_date(const u_char *date_ptr)
{
- uint32 x, x2;
+ u_int32_t dos_date = 0;
- x = IVAL(date_ptr, 0);
- x2 = ((x & 0xFFFF) << 16) | ((x & 0xFFFF0000) >> 16);
- SIVAL(&x, 0, x2);
+ dos_date = EXTRACT_LE_32BITS(date_ptr);
+
+ return int_unix_date(dos_date);
+}
+
+/*
+ * create a unix date from a dos date
+ * in halfword-swapped network byte order!
+ */
+static time_t
+make_unix_date2(const u_char *date_ptr)
+{
+ u_int32_t x, x2;
- return(make_unix_date((void *)&x));
+ x = EXTRACT_LE_32BITS(date_ptr);
+ x2 = ((x & 0xFFFF) << 16) | ((x & 0xFFFF0000) >> 16);
+ return int_unix_date(x2);
}
/*
* It's originally in "100ns units since jan 1st 1601"
*/
static time_t
-interpret_long_date(const char *p)
+interpret_long_date(const u_char *p)
{
double d;
time_t ret;
+ TCHECK2(p[4], 4);
+
/* this gives us seconds since jan 1st 1601 (approx) */
- d = (IVAL(p, 4) * 256.0 + CVAL(p, 3)) * (1.0e-7 * (1 << 24));
+ d = (EXTRACT_LE_32BITS(p + 4) * 256.0 + p[3]) * (1.0e-7 * (1 << 24));
/* now adjust by 369 years to make the secs since 1970 */
d -= 369.0 * 365.25 * 24 * 60 * 60;
ret = (time_t)d;
return(ret);
+trunc:
+ return(0);
}
/*
* we run past the end of the buffer
*/
static int
-name_interpret(const uchar *in, const uchar *maxbuf, char *out)
+name_interpret(const u_char *in, const u_char *maxbuf, char *out)
{
int ret;
int len;
return(0);
while (len--) {
+ TCHECK2(*in, 2);
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);
/*
* find a pointer to a netbios name
*/
-static const uchar *
-name_ptr(const uchar *buf, int ofs, const uchar *maxbuf)
+static const u_char *
+name_ptr(const u_char *buf, int ofs, const u_char *maxbuf)
{
- const uchar *p;
- uchar c;
+ const u_char *p;
+ u_char c;
p = buf + ofs;
if (p >= maxbuf)
/* XXX - this should use the same code that the DNS dissector does */
if ((c & 0xC0) == 0xC0) {
- uint16 l = RSVAL(buf, ofs) & 0x3FFF;
+ u_int16_t l = EXTRACT_16BITS(buf + ofs) & 0x3FFF;
if (l == 0) {
/* We have a pointer that points to itself. */
return(NULL);
* extract a netbios name from a buf
*/
static int
-name_extract(const uchar *buf, int ofs, const uchar *maxbuf, char *name)
+name_extract(const u_char *buf, int ofs, const u_char *maxbuf, char *name)
{
- const uchar *p = name_ptr(buf, ofs, maxbuf);
+ const u_char *p = name_ptr(buf, ofs, maxbuf);
if (p == NULL)
return(-1); /* error (probably name going past end of buffer) */
name[0] = '\0';
safeputchar(buf[i]);
}
-static char *
+static const char *
name_type_str(int name_type)
{
- char *f = NULL;
+ const char *f = NULL;
switch (name_type) {
case 0: f = "Workstation"; break;
while (n--)
printf(" ");
- n = MIN(8, i % 16);
+ n = SMBMIN(8, i % 16);
print_asc(&buf[i - (i % 16)], n);
printf(" ");
n = (i % 16) - n;
static void
-write_bits(unsigned int val, char *fmt)
+write_bits(unsigned int val, const char *fmt)
{
- char *p = fmt;
+ const char *p = fmt;
int i = 0;
while ((p = strchr(fmt, '|'))) {
/* convert a UCS2 string into iso-8859-1 string */
static const char *
-unistr(const char *s, int *len)
+unistr(const u_char *s, int *len)
{
static char buf[1000];
int l=0;
/* maybe it isn't unicode - a cheap trick */
if (!use_unicode || (s[0] && s[1])) {
- *len = strlen(s) + 1;
- return s;
+ *len = strlen((const char *)s) + 1;
+ return (const char *)s;
}
*len = 0;
*len = 1;
}
- while (l < (sizeof(buf) - 1) && s[0] && s[1] == 0) {
+ while (l < (int)(sizeof(buf) - 1) && s[0] && s[1] == 0) {
buf[l] = s[0];
s += 2;
l++;
return buf;
}
-static const uchar *
-fdata1(const uchar *buf, const char *fmt, const uchar *maxbuf)
+static const u_char *
+smb_fdata1(const u_char *buf, const char *fmt, const u_char *maxbuf)
{
int reverse = 0;
- char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|";
+ const char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|";
int len;
while (*fmt && buf<maxbuf) {
switch (*fmt) {
case 'a':
- write_bits(CVAL(buf,0), attrib_fmt);
+ write_bits(buf[0], attrib_fmt);
buf++;
fmt++;
break;
case 'A':
- write_bits(SVAL(buf, 0), attrib_fmt);
+ write_bits(EXTRACT_LE_16BITS(buf), attrib_fmt);
buf += 2;
fmt++;
break;
case '{':
{
char bitfmt[128];
- char *p = strchr(++fmt, '}');
- int l = PTR_DIFF(p, fmt);
+ char *p;
+ int l;
+
+ p = strchr(++fmt, '}');
+ l = PTR_DIFF(p, fmt);
strncpy(bitfmt, fmt, l);
bitfmt[l] = 0;
fmt = p + 1;
- write_bits(CVAL(buf, 0), bitfmt);
+ write_bits(buf[0], bitfmt);
buf++;
break;
}
int l = atoi(fmt + 1);
buf += l;
fmt++;
- while (isdigit(*fmt))
+ while (isdigit((unsigned char)*fmt))
fmt++;
break;
}
break;
case 'D':
{
- unsigned int x = reverse ? RIVAL(buf, 0) : IVAL(buf, 0);
+ unsigned int x;
+
+ TCHECK2(buf[0], 4);
+ x = reverse ? EXTRACT_32BITS(buf) : EXTRACT_LE_32BITS(buf);
printf("%d (0x%x)", x, x);
buf += 4;
fmt++;
}
case 'L':
{
- unsigned int x1 = reverse ? RIVAL(buf, 0) : IVAL(buf, 0);
- unsigned int x2 = reverse ? RIVAL(buf, 4) : IVAL(buf, 4);
+ unsigned int x1, x2;
+
+ TCHECK2(buf[4], 4);
+ x1 = reverse ? EXTRACT_32BITS(buf) :
+ EXTRACT_LE_32BITS(buf);
+ x2 = reverse ? EXTRACT_32BITS(buf + 4) :
+ EXTRACT_LE_32BITS(buf + 4);
if (x2)
printf("0x%08x:%08x", x2, x1);
else
}
case 'd':
{
- unsigned int x = reverse ? RSVAL(buf, 0) : SVAL(buf, 0);
+ unsigned int x;
+ TCHECK2(buf[0], 2);
+ x = reverse ? EXTRACT_16BITS(buf) :
+ EXTRACT_LE_16BITS(buf);
printf("%d (0x%x)", x, x);
buf += 2;
fmt++;
}
case 'W':
{
- unsigned int x = reverse ? RIVAL(buf, 0) : IVAL(buf, 0);
+ unsigned int x;
+ TCHECK2(buf[0], 4);
+ x = reverse ? EXTRACT_32BITS(buf) :
+ EXTRACT_LE_32BITS(buf);
printf("0x%X", x);
buf += 4;
fmt++;
}
case 'w':
{
- unsigned int x = reverse ? RSVAL(buf, 0) : SVAL(buf, 0);
+ unsigned int x;
+ TCHECK2(buf[0], 2);
+ x = reverse ? EXTRACT_16BITS(buf) :
+ EXTRACT_LE_16BITS(buf);
printf("0x%X", x);
buf += 2;
fmt++;
}
case 'B':
{
- unsigned int x = CVAL(buf,0);
+ unsigned int x;
+ TCHECK(buf[0]);
+ x = buf[0];
printf("0x%X", x);
buf += 1;
fmt++;
}
case 'b':
{
- unsigned int x = CVAL(buf, 0);
+ unsigned int x;
+ TCHECK(buf[0]);
+ x = buf[0];
printf("%u (0x%x)", x, x);
buf += 1;
fmt++;
}
case 'S':
{
+ /*XXX unistr() */
printf("%.*s", (int)PTR_DIFF(maxbuf, buf), unistr(buf, &len));
buf += len;
fmt++;
printf("%-*.*s", l, l, buf);
buf += l;
fmt++;
- while (isdigit(*fmt))
+ while (isdigit((unsigned char)*fmt))
fmt++;
break;
}
while (l--)
printf("%02x", *buf++);
fmt++;
- while (isdigit(*fmt))
+ while (isdigit((unsigned char)*fmt))
fmt++;
break;
}
break;
}
fmt++;
- while (isdigit(*fmt))
+ while (isdigit((unsigned char)*fmt))
fmt++;
break;
}
case 'T':
{
time_t t;
- int x = IVAL(buf,0);
+ struct tm *lt;
+ const char *tstring;
+ u_int32_t x;
+ x = EXTRACT_LE_32BITS(buf);
switch (atoi(fmt + 1)) {
case 1:
- if (x == 0 || x == -1 || x == 0xFFFFFFFF)
+ if (x == 0 || x == 0xFFFFFFFF)
t = 0;
else
t = make_unix_date(buf);
buf += 4;
break;
case 2:
- if (x == 0 || x == -1 || x == 0xFFFFFFFF)
+ if (x == 0 || x == 0xFFFFFFFF)
t = 0;
else
t = make_unix_date2(buf);
buf += 8;
break;
}
- printf("%s", t ? asctime(localtime(&t)) : "NULL\n");
+ if (t != 0) {
+ lt = localtime(&t);
+ if (lt != NULL)
+ tstring = asctime(lt);
+ else
+ tstring = "(Can't convert time)\n";
+ } else
+ tstring = "NULL\n";
+ printf("%s", tstring);
fmt++;
- while (isdigit(*fmt))
+ while (isdigit((unsigned char)*fmt))
fmt++;
break;
}
return(NULL);
}
-const uchar *
-fdata(const uchar *buf, const char *fmt, const uchar *maxbuf)
+const u_char *
+smb_fdata(const u_char *buf, const char *fmt, const u_char *maxbuf)
{
static int depth = 0;
char s[128];
case '*':
fmt++;
while (buf < maxbuf) {
- const uchar *buf2;
+ const u_char *buf2;
depth++;
- buf2 = fdata(buf, fmt, maxbuf);
+ buf2 = smb_fdata(buf, fmt, maxbuf);
depth--;
+ if (buf2 == NULL)
+ return(NULL);
if (buf2 == buf)
return(buf);
buf = buf2;
}
- break;
+ return(buf);
case '|':
fmt++;
return(buf);
memset(s, 0, sizeof(s));
p = strchr(fmt, ']');
- if (p - fmt + 1 > sizeof(s)) {
+ if ((size_t)(p - fmt + 1) > sizeof(s)) {
/* overrun */
return(buf);
}
strncpy(s, fmt, p - fmt);
s[p - fmt] = '\0';
fmt = p + 1;
- buf = fdata1(buf, s, maxbuf);
+ buf = smb_fdata1(buf, s, maxbuf);
if (buf == NULL)
return(NULL);
break;
}
typedef struct {
- char *name;
+ const char *name;
int code;
- char *message;
+ const char *message;
} err_code_struct;
/* Dos Error Messages */
static struct {
int code;
- char *class;
+ const char *class;
err_code_struct *err_msgs;
} err_classes[] = {
{ 0, "SUCCESS", NULL },