📄 smbutil.c
字号:
/*
* Copyright (C) Andrew Tridgell 1995
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include "interfac.h"
#include "smb.h"
extern uchar *nbt_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 = date & 0xFF;
uint32 p1 = ((date & 0xFF00) >> 8) & 0xFF;
uint32 p2 = ((date & 0xFF0000) >> 16) & 0xFF;
uint32 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
*/
time_t make_unix_date (void *date_ptr)
{
uint32 dos_date = IVAL (date_ptr, 0);
struct tm t;
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
*/
time_t make_unix_date2 (void *date_ptr)
{
uint32 x = IVAL (date_ptr, 0);
uint32 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"
*/
time_t interpret_long_date (char *p)
{
double d;
/* 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);
return ((time_t)d);
}
/*
* 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];
/* Handle any scope names */
while (*in)
{
*out++ = '.';
len = *in++;
strncpy (out, in, len);
out += len;
*out = 0;
in += len;
}
return (ret);
}
/*
* find a pointer to a netbios name
*/
static char *name_ptr (char *buf, int ofs)
{
uchar c = *(uchar*) (buf + ofs);
if ((c & 0xC0) == 0xC0)
{
uint16 l;
char p[2];
memcpy (p, buf + ofs, 2);
p[0] &= ~0xC0;
l = RSVAL (p, 0);
return (buf + l);
}
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);
//int d = PTR_DIFF (p, buf + ofs);
strcpy (name, "");
return name_interpret (p, name);
}
/*
* return the total storage length of a mangled name
*/
static int name_len (char *s)
{
char *s0 = s;
uchar c = *(uchar*) s;
if ((c & 0xC0) == 0xC0)
return (2);
while (*s)
s += (*s) + 1;
return (PTR_DIFF (s, s0) + 1);
}
void print_asc (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)
{
switch (name_type)
{
case 0:
return ("Workstation");
case 0x03:
return ("Client?");
case 0x20:
return ("Server");
case 0x1d:
return ("Master Browser");
case 0x1b:
return ("Domain Controller");
case 0x1e:
return ("Browser Server");
}
return ("Unknown");
}
void print_data (uchar *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)
PUTCHAR (' ');
if (i % 16 == 0)
{
print_asc (&buf[i-16], 8);
PUTCHAR (' ');
print_asc (&buf[i-8], 8);
PUTS ("\n");
if (i < len)
PRINTF ("[%03X] ", i);
}
}
if (i % 16)
{
int n = 16 - (i % 16);
PUTCHAR (' ');
if (n > 8)
PUTCHAR (' ');
while (n--)
PUTS (" ");
n = MIN (8, i % 16);
print_asc (&buf[i - (i % 16)], n);
PUTCHAR (' ');
n = (i % 16) - n;
if (n > 0)
print_asc (&buf[i - n], n);
PUTS ("\n");
}
}
static void write_bits (unsigned int val, char *fmt)
{
char *p = fmt;
int i = 0;
while ((p = strchr(fmt, '|')) != NULL)
{
int l = PTR_DIFF (p, fmt);
if (l && (val & (1 << i)))
PRINTF ("%.*s ", l, fmt);
fmt = p + 1;
i++;
}
}
static uchar *fdata1 (uchar *buf, char *fmt, uchar *maxbuf)
{
int reverse = 0;
char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|";
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;
}
case 'r':
reverse = !reverse;
fmt++;
break;
case 'D':
{
unsigned int x = reverse ? RIVAL (buf, 0) : IVAL (buf, 0);
PRINTF ("%d", x);
buf += 4;
fmt++;
break;
}
case 'd':
{
unsigned int x = reverse ? RSVAL (buf, 0) : SVAL (buf, 0);
PRINTF ("%d", x);
buf += 2;
fmt++;
break;
}
case 'W':
{
unsigned int x = reverse ? RIVAL (buf, 0) : IVAL (buf, 0);
PRINTF ("0x%X", x);
buf += 4;
fmt++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -