📄 smbutil.c
字号:
/* 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 lintstatic const char rcsid[] = "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.12 2000/12/04 00:35:45 guy Exp $";#endif#ifndef WIN32
#include <sys/param.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#else
#include <winsock2.h>
#include "bittypes.h"
#include <time.h>
#endif /* WIN32 */
#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include "interface.h"#include "smb.h"extern const 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_tIt'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, or -1 ifwe run past the end of the buffer****************************************************************************/static int name_interpret(const uchar *in,const uchar *maxbuf,char *out){ int ret; int len; if (in >= maxbuf) return(-1); /* name goes past the end of the buffer */ TCHECK2(*in, 1); len = (*in++) / 2; *out=0; if (len > 30 || len<1) return(0); while (len--) { 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); } *out = ((in[0]-'A')<<4) + (in[1]-'A'); in += 2; out++; } *out = 0; ret = out[-1]; return(ret);trunc: return(-1);}/****************************************************************************find a pointer to a netbios name****************************************************************************/static const uchar *name_ptr(const uchar *buf,int ofs,const uchar *maxbuf){ const uchar *p; uchar c; p = buf+ofs; if (p >= maxbuf) return(NULL); /* name goes past the end of the buffer */ TCHECK2(*p, 1); c = *p; /* XXX - this should use the same code that the DNS dissector does */ if ((c & 0xC0) == 0xC0) { uint16 l = RSVAL(buf, ofs) & 0x3FFF; if (l == 0) { /* We have a pointer that points to itself. */ return(NULL); } p = buf + l; if (p >= maxbuf) return(NULL); /* name goes past the end of the buffer */ TCHECK2(*p, 1); return(buf + l); } else return(buf+ofs);trunc: return(NULL); /* name goes past the end of the buffer */} /****************************************************************************extract a netbios name from a buf****************************************************************************/static int name_extract(const uchar *buf,int ofs,const uchar *maxbuf,char *name){ const uchar *p = name_ptr(buf,ofs,maxbuf); if (p == NULL) return(-1); /* error (probably name going past end of buffer) */ strcpy(name,""); return(name_interpret(p,maxbuf,name));} /****************************************************************************return the total storage length of a mangled name****************************************************************************/static int name_len(const unsigned char *s, const unsigned char *maxbuf){ const unsigned char *s0 = s; unsigned char c; if (s >= maxbuf) return(-1); /* name goes past the end of the buffer */ TCHECK2(*s, 1); c = *s; if ((c & 0xC0) == 0xC0) return(2); while (*s) { if (s >= maxbuf) return(-1); /* name goes past the end of the buffer */ TCHECK2(*s, 1); s += (*s)+1; } return(PTR_DIFF(s,s0)+1);trunc: return(-1); /* name goes past the end of the buffer */}static void print_asc(const unsigned char *buf,int len){ int i; for (i=0;i<len;i++) printf("%c",isprint(buf[i])?buf[i]:'.');}static char *name_type_str(int name_type){ static char *f = NULL; switch (name_type) { case 0: f = "Workstation"; break; case 0x03: f = "Client?"; break; case 0x20: f = "Server"; break; case 0x1d: f = "Master Browser"; break; case 0x1b: f = "Domain Controller"; break; case 0x1e: f = "Browser Server"; break; default: f = "Unknown"; break; } return(f);}void print_data(const unsigned char *buf, int len){ int i=0; if (len<=0) return; printf("[%03X] ",i); for (i=0;i<len;) { printf("%02X ",(int)buf[i]); i++; if (i%8 == 0) printf(" "); if (i%16 == 0) { print_asc(&buf[i-16],8); printf(" "); print_asc(&buf[i-8],8); printf("\n"); if (i<len) printf("[%03X] ",i); } } if (i%16) { int n; n = 16 - (i%16); printf(" "); if (n>8) 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<<i))) printf("%.*s ",l,fmt); fmt = p+1; i++; }}/* convert a unicode string */static const char *unistr(const char *s, int *len){ 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(s)+1; return s; } *len = 0; if (s[0] == 0 && s[1] != 0) { s++; *len = 1; } while (l < (sizeof(buf)-1) && s[0] && s[1] == 0) { buf[l] = s[0]; s += 2; l++; *len += 2; } buf[l] = 0; *len += 2; return buf;}static const uchar *fdata1(const uchar *buf, const char *fmt, const uchar *maxbuf){ int reverse=0; 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); buf++; fmt++; break; case 'A': write_bits(SVAL(buf,0),attrib_fmt); buf+=2; fmt++; break; case '{': { char bitfmt[128]; char *p = strchr(++fmt,'}'); int l = PTR_DIFF(p,fmt); strncpy(bitfmt,fmt,l); bitfmt[l]=0; fmt = p+1; write_bits(CVAL(buf,0),bitfmt); buf++; break; } case 'P': { int l = atoi(fmt+1); buf += l; fmt++; while (isdigit(*fmt)) fmt++; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -