#endif
#ifndef lint
-static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.17 2001-09-17 21:58:05 fenner Exp $";
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.26.2.2 2003-11-16 08:51:56 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 u_char *startbuf;
}
/*
+ * common portion:
* create a unix date from a dos date
*/
static time_t
-make_unix_date(const u_char *date_ptr)
+int_unix_date(u_int32_t dos_date)
{
- u_int32_t 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_date(const u_char *date_ptr)
+{
+ u_int32_t dos_date = 0;
+
+ 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;
- x = IVAL(date_ptr, 0);
+ x = EXTRACT_LE_32BITS(date_ptr);
x2 = ((x & 0xFFFF) << 16) | ((x & 0xFFFF0000) >> 16);
- SIVAL(&x, 0, x2);
-
- return(make_unix_date((void *)&x));
+ 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);
}
/*
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);
/* XXX - this should use the same code that the DNS dissector does */
if ((c & 0xC0) == 0xC0) {
- u_int16_t 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);
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++;
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);
+
+ if ((unsigned int)l > sizeof(bitfmt) - 1)
+ l = sizeof(bitfmt)-1;
+
strncpy(bitfmt, fmt, l);
- bitfmt[l] = 0;
+ 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;
}
depth++;
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);
}
static struct {
int code;
- char *class;
+ const char *class;
err_code_struct *err_msgs;
} err_classes[] = {
{ 0, "SUCCESS", NULL },