X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/688cae1eef7476d33d9ed023140bd0e1923f8872..refs/heads/tcpdump-4.1:/smbutil.c diff --git a/smbutil.c b/smbutil.c index 314a9704..5eadb4fd 100644 --- a/smbutil.c +++ b/smbutil.c @@ -11,8 +11,8 @@ #endif #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.26 2003-08-10 19:47:39 guy Exp $"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.39 2007-07-15 19:07:39 guy Exp $"; #endif #include @@ -25,6 +25,7 @@ static const char rcsid[] = #include "extract.h" #include "smb.h" +static u_int32_t stringlen; extern const u_char *startbuf; /* @@ -106,8 +107,6 @@ 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 = (EXTRACT_LE_32BITS(p + 4) * 256.0 + p[3]) * (1.0e-7 * (1 << 24)); @@ -123,8 +122,6 @@ interpret_long_date(const u_char *p) ret = (time_t)d; return(ret); -trunc: - return(0); } /* @@ -186,7 +183,12 @@ name_ptr(const u_char *buf, int ofs, const u_char *maxbuf) /* XXX - this should use the same code that the DNS dissector does */ if ((c & 0xC0) == 0xC0) { - u_int16_t l = EXTRACT_16BITS(buf + ofs) & 0x3FFF; + u_int16_t l; + + TCHECK2(*p, 2); + if ((p + 1) >= maxbuf) + return(NULL); /* name goes past the end of the buffer */ + l = EXTRACT_16BITS(p) & 0x3FFF; if (l == 0) { /* We have a pointer that points to itself. */ return(NULL); @@ -195,9 +197,8 @@ name_ptr(const u_char *buf, int ofs, const u_char *maxbuf) if (p >= maxbuf) return(NULL); /* name goes past the end of the buffer */ TCHECK2(*p, 1); - return(buf + l); - } else - return(buf + ofs); + } + return(p); trunc: return(NULL); /* name goes past the end of the buffer */ @@ -278,6 +279,7 @@ print_data(const unsigned char *buf, int len) return; printf("[%03X] ", i); for (i = 0; i < len; /*nothing*/) { + TCHECK(buf[i]); printf("%02X ", buf[i] & 0xff); i++; if (i%8 == 0) @@ -309,6 +311,11 @@ print_data(const unsigned char *buf, int len) print_asc(&buf[i - n], n); printf("\n"); } + return; + +trunc: + printf("\n"); + printf("WARNING: Short packet. Try increasing the snap length\n"); } @@ -328,61 +335,117 @@ write_bits(unsigned int val, const char *fmt) } /* convert a UCS2 string into iso-8859-1 string */ +#define MAX_UNISTR_SIZE 1000 static const char * -unistr(const u_char *s, int *len) +unistr(const u_char *s, u_int32_t *len, int use_unicode) { - static char buf[1000]; - int l=0; - static int use_unicode = -1; - - if (use_unicode == -1) { - char *p = getenv("USE_UNICODE"); - if (p && (atoi(p) == 1)) - use_unicode = 1; - else - use_unicode = 0; - } - - /* maybe it isn't unicode - a cheap trick */ - if (!use_unicode || (s[0] && s[1])) { - *len = strlen((const char *)s) + 1; - return (const char *)s; + static char buf[MAX_UNISTR_SIZE+1]; + size_t l = 0; + u_int32_t strsize; + const u_char *sp; + + if (use_unicode) { + /* + * Skip padding that puts the string on an even boundary. + */ + if (((s - startbuf) % 2) != 0) { + TCHECK(s[0]); + s++; + } } - - *len = 0; - - if (s[0] == 0 && s[1] != 0) { - s++; - *len = 1; + if (*len == 0) { + /* + * Null-terminated string. + */ + strsize = 0; + sp = s; + if (!use_unicode) { + for (;;) { + TCHECK(sp[0]); + *len += 1; + if (sp[0] == 0) + break; + sp++; + } + strsize = *len - 1; + } else { + for (;;) { + TCHECK2(sp[0], 2); + *len += 2; + if (sp[0] == 0 && sp[1] == 0) + break; + sp += 2; + } + strsize = *len - 2; + } + } else { + /* + * Counted string. + */ + strsize = *len; } - - while (l < (int)(sizeof(buf) - 1) && s[0] && s[1] == 0) { - buf[l] = s[0]; - s += 2; - l++; - *len += 2; + if (!use_unicode) { + while (strsize != 0) { + TCHECK(s[0]); + if (l >= MAX_UNISTR_SIZE) + break; + if (isprint(s[0])) + buf[l] = s[0]; + else { + if (s[0] == 0) + break; + buf[l] = '.'; + } + l++; + s++; + strsize--; + } + } else { + while (strsize != 0) { + TCHECK2(s[0], 2); + if (l >= MAX_UNISTR_SIZE) + break; + if (s[1] == 0 && isprint(s[0])) { + /* It's a printable ASCII character */ + buf[l] = s[0]; + } else { + /* It's a non-ASCII character or a non-printable ASCII character */ + if (s[0] == 0 && s[1] == 0) + break; + buf[l] = '.'; + } + l++; + s += 2; + if (strsize == 1) + break; + strsize -= 2; + } } buf[l] = 0; - *len += 2; return buf; + +trunc: + return NULL; } static const u_char * -smb_fdata1(const u_char *buf, const char *fmt, const u_char *maxbuf) +smb_fdata1(const u_char *buf, const char *fmt, const u_char *maxbuf, + int unicodestr) { int reverse = 0; const char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|"; - int len; while (*fmt && buf