From 54c4a9c9f2aca2e032cbf41f5eb012e2e9628dd4 Mon Sep 17 00:00:00 2001 From: fenner Date: Sun, 30 Jan 2000 00:45:58 +0000 Subject: Virgin import of tcpdump.org tcpdump v3.5 --- contrib/tcpdump/smbutil.c | 698 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 698 insertions(+) create mode 100644 contrib/tcpdump/smbutil.c (limited to 'contrib/tcpdump/smbutil.c') diff --git a/contrib/tcpdump/smbutil.c b/contrib/tcpdump/smbutil.c new file mode 100644 index 0000000..2ddd3f6 --- /dev/null +++ b/contrib/tcpdump/smbutil.c @@ -0,0 +1,698 @@ +/* + Copyright (C) Andrew Tridgell 1995-1999 + + This software may be distributed either under the terms of the + BSD-style license that accompanies tcpdump or the GNU GPL version 2 + or later */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] = + "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.4.2.1 2000/01/11 06:58:28 fenner Exp $"; +#endif + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include "interface.h" +#include "smb.h" + +extern uchar *startbuf; + +/******************************************************************* + interpret a 32 bit dos packed date/time to some parameters +********************************************************************/ +static void interpret_dos_date(uint32 date,int *year,int *month,int *day,int *hour,int *minute,int *second) +{ + uint32 p0,p1,p2,p3; + + p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF; + p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF; + + *second = 2*(p0 & 0x1F); + *minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3); + *hour = (p1>>3)&0xFF; + *day = (p2&0x1F); + *month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1; + *year = ((p3>>1)&0xFF) + 80; +} + +/******************************************************************* + create a unix date from a dos date +********************************************************************/ +static time_t make_unix_date(const void *date_ptr) +{ + uint32 dos_date=0; + struct tm t; + + dos_date = IVAL(date_ptr,0); + + if (dos_date == 0) return(0); + + interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon, + &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec); + t.tm_wday = 1; + t.tm_yday = 1; + t.tm_isdst = 0; + + return (mktime(&t)); +} + +/******************************************************************* + create a unix date from a dos date +********************************************************************/ +static time_t make_unix_date2(const void *date_ptr) +{ + uint32 x,x2; + + x = IVAL(date_ptr,0); + x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); + SIVAL(&x,0,x2); + + return(make_unix_date((void *)&x)); +} + +/**************************************************************************** +interpret an 8 byte "filetime" structure to a time_t +It's originally in "100ns units since jan 1st 1601" +****************************************************************************/ +static time_t interpret_long_date(const char *p) +{ + double d; + time_t ret; + + /* this gives us seconds since jan 1st 1601 (approx) */ + d = (IVAL(p,4)*256.0 + CVAL(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; + + /* and a fudge factor as we got it wrong by a few days */ + d += (3*24*60*60 + 6*60*60 + 2); + + if (d<0) + return(0); + + ret = (time_t)d; + + return(ret); +} + + +/**************************************************************************** +interpret the weird netbios "name". Return the name type +****************************************************************************/ +static int name_interpret(char *in,char *out) +{ + int ret; + int len = (*in++) / 2; + + *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]; + + return(ret); +} + +/**************************************************************************** +find a pointer to a netbios name +****************************************************************************/ +static char *name_ptr(char *buf,int ofs) +{ + unsigned char c = *(unsigned char *)(buf+ofs); + + if ((c & 0xC0) == 0xC0) + { + uint16 l = RSVAL(buf, ofs) & 0x3FFF; + return(buf + l); + } + else + return(buf+ofs); +} + +/**************************************************************************** +extract a netbios name from a buf +****************************************************************************/ +static int name_extract(char *buf,int ofs,char *name) +{ + char *p = name_ptr(buf,ofs); + strcpy(name,""); + return(name_interpret(p,name)); +} + + +/**************************************************************************** +return the total storage length of a mangled name +****************************************************************************/ +static int name_len(const unsigned char *s) +{ + const char *s0 = s; + unsigned char c = *(unsigned char *)s; + if ((c & 0xC0) == 0xC0) + return(2); + while (*s) s += (*s)+1; + return(PTR_DIFF(s,s0)+1); +} + +static void print_asc(const unsigned char *buf,int len) +{ + int i; + for (i=0;i8) printf(" "); + while (n--) printf(" "); + + n = MIN(8,i%16); + print_asc(&buf[i-(i%16)],n); printf(" "); + n = (i%16) - n; + if (n>0) print_asc(&buf[i-n],n); + printf("\n"); + } +} + + +static void write_bits(unsigned int val,char *fmt) +{ + char *p = fmt; + int i=0; + + while ((p=strchr(fmt,'|'))) { + int l = PTR_DIFF(p,fmt); + if (l && (val & (1<=maxbuf && *fmt) + printf("END OF BUFFER\n"); + + return(buf); +} + +const uchar *fdata(const uchar *buf, const char *fmt, const uchar *maxbuf) +{ + static int depth=0; + char s[128]; + char *p; + + while (*fmt) { + switch (*fmt) { + case '*': + fmt++; + while (buf < maxbuf) { + const uchar *buf2; + depth++; + buf2 = fdata(buf,fmt,maxbuf); + depth--; + if (buf2 == buf) return(buf); + buf = buf2; + } + break; + + case '|': + fmt++; + if (buf>=maxbuf) return(buf); + break; + + case '%': + fmt++; + buf=maxbuf; + break; + + case '#': + fmt++; + return(buf); + break; + + case '[': + fmt++; + if (buf>=maxbuf) return(buf); + bzero(s,sizeof(s)); + p = strchr(fmt,']'); + strncpy(s,fmt,p-fmt); + fmt = p+1; + buf = fdata1(buf,s,maxbuf); + break; + + default: + putchar(*fmt); fmt++; + fflush(stdout); + break; + } + } + if (!depth && buf