?? 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[] _U_ = "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.39 2007-07-15 19:07:39 guy Exp $";#endif#include <tcpdump-stdinc.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "interface.h"#include "extract.h"#include "smb.h"static u_int32_t stringlen;extern const u_char *startbuf;/* * interpret a 32 bit dos packed date/time to some parameters */static voidinterpret_dos_date(u_int32_t date, struct tm *tp){ u_int32_t p0, p1, p2, p3; p0 = date & 0xFF; p1 = ((date & 0xFF00) >> 8) & 0xFF; p2 = ((date & 0xFF0000) >> 16) & 0xFF; p3 = ((date & 0xFF000000) >> 24) & 0xFF; tp->tm_sec = 2 * (p0 & 0x1F); tp->tm_min = ((p0 >> 5) & 0xFF) + ((p1 & 0x7) << 3); tp->tm_hour = (p1 >> 3) & 0xFF; tp->tm_mday = (p2 & 0x1F); tp->tm_mon = ((p2 >> 5) & 0xFF) + ((p3 & 0x1) << 3) - 1; tp->tm_year = ((p3 >> 1) & 0xFF) + 80;}/* * common portion: * create a unix date from a dos date */static time_tint_unix_date(u_int32_t dos_date){ struct tm t; if (dos_date == 0) return(0); interpret_dos_date(dos_date, &t); t.tm_wday = 1; t.tm_yday = 1; t.tm_isdst = 0; return (mktime(&t));}/* * create a unix date from a dos date * in network byte order */static time_tmake_unix_date(const u_char *date_ptr){ u_int32_t dos_date = 0; dos_date = EXTRACT_LE_32BITS(date_ptr); return int_unix_date(dos_date);}/* * create a unix date from a dos date * in halfword-swapped network byte order! */static time_tmake_unix_date2(const u_char *date_ptr){ u_int32_t x, x2; x = EXTRACT_LE_32BITS(date_ptr); x2 = ((x & 0xFFFF) << 16) | ((x & 0xFFFF0000) >> 16); return int_unix_date(x2);}/* * interpret an 8 byte "filetime" structure to a time_t * It's originally in "100ns units since jan 1st 1601" */static time_tinterpret_long_date(const u_char *p){ double d; time_t ret; /* this gives us seconds since jan 1st 1601 (approx) */ d = (EXTRACT_LE_32BITS(p + 4) * 256.0 + 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 if * we run past the end of the buffer */static intname_interpret(const u_char *in, const u_char *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--) { TCHECK2(*in, 2); if (in + 1 >= maxbuf) return(-1); /* name goes past the end of the buffer */ 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 u_char *name_ptr(const u_char *buf, int ofs, const u_char *maxbuf){ const u_char *p; u_char 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) { u_int16_t l; TCHECK2(*p, 2); if ((p + 1) >= maxbuf) return(NULL); /* name goes past the end of the buffer */ l = EXTRACT_16BITS(p) & 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(p);trunc: return(NULL); /* name goes past the end of the buffer */}/* * extract a netbios name from a buf */static intname_extract(const u_char *buf, int ofs, const u_char *maxbuf, char *name){ const u_char *p = name_ptr(buf, ofs, maxbuf); if (p == NULL) return(-1); /* error (probably name going past end of buffer) */ name[0] = '\0'; return(name_interpret(p, maxbuf, name));}/* * return the total storage length of a mangled name */static intname_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 voidprint_asc(const unsigned char *buf, int len){ int i; for (i = 0; i < len; i++) safeputchar(buf[i]);}static const char *name_type_str(int name_type){ const 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);}voidprint_data(const unsigned char *buf, int len){ int i = 0; if (len <= 0) return; printf("[%03X] ", i); for (i = 0; i < len; /*nothing*/) { TCHECK(buf[i]); printf("%02X ", buf[i] & 0xff); 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 = SMBMIN(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"); } return;trunc: printf("\n"); printf("WARNING: Short packet. Try increasing the snap length\n");}static voidwrite_bits(unsigned int val, const char *fmt){ const char *p = fmt; int i = 0; while ((p = strchr(fmt, '|'))) { size_t l = PTR_DIFF(p, fmt); if (l && (val & (1 << i))) printf("%.*s ", (int)l, fmt); fmt = p + 1; i++; }}/* convert a UCS2 string into iso-8859-1 string */#define MAX_UNISTR_SIZE 1000static const char *unistr(const u_char *s, u_int32_t *len, int use_unicode){ static char buf[MAX_UNISTR_SIZE+1]; size_t l = 0; u_int32_t strsize; const u_char *sp; if (use_unicode) { /* * Skip padding that puts the string on an even boundary. */ if (((s - startbuf) % 2) != 0) { TCHECK(s[0]); s++; } } if (*len == 0) { /* * Null-terminated string. */ strsize = 0; sp = s; if (!use_unicode) { for (;;) { TCHECK(sp[0]); *len += 1; if (sp[0] == 0) break; sp++; } strsize = *len - 1; } else { for (;;) { TCHECK2(sp[0], 2); *len += 2; if (sp[0] == 0 && sp[1] == 0) break; sp += 2; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -