⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smbutil.c

📁 This directory contains source code for tcpdump, a tool for network monitoring and data acquisition
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 
 * 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 + -