/* 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