smbutil.c

来自「TCPDUMP的C语言源代码,是在数据链路层的应用」· C语言 代码 · 共 1,890 行 · 第 1/5 页

C
1,890
字号
/* * 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 + =
减小字号Ctrl + -
显示快捷键?