#include #include #include #include #include "byteorder.h" #define PSTRING_LEN 1024 #define FSTRING_LEN 256 #define uint16 unsigned short typedef char pstring[PSTRING_LEN]; typedef char fstring[FSTRING_LEN]; /* pointer difference macro */ #define PTR_DIFF(p1,p2) ((unsigned int)(((const char *)(p1)) - (const char *)(p2))) /**************************************************************************** Return the total storage length of a mangled name. ****************************************************************************/ int name_len(char *s1) { /* NOTE: this argument _must_ be unsigned */ unsigned char *s = (unsigned char *)s1; int len; /* If the two high bits of the byte are set, return 2. */ if (0xC0 == (*s & 0xC0)) return(2); /* Add up the length bytes. */ for (len = 1; (*s); s += (*s) + 1) { len += *s + 1; //SMB_ASSERT(len < 80); if(len < 80) { fprintf(stderr, "Assert: len < 80; %d\n", len); } } return(len); } /**************************************************************************** Find a pointer to a netbios name. ****************************************************************************/ static char *name_ptr(char *buf,int ofs) { unsigned char c = *(unsigned char *)(buf+ofs); if ((c & 0xC0) == 0xC0) { uint16 l = RSVAL(buf, ofs) & 0x3FFF; fprintf(stderr, "name ptr to pos %d from %d is %s\n",l,ofs,buf+l); return(buf + l); } else { return(buf+ofs); } } /**************************************************************************** Interpret the weird netbios "name" into a unix fstring. Return the name type. ****************************************************************************/ static int name_interpret(char *in, fstring name) { int ret; int len = (*in++) / 2; fstring out_string; char *out = out_string; *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++; } ret = out[-1]; out[-1] = 0; #ifdef NETBIOS_SCOPE /* Handle any scope names */ while(*in) { *out++ = '.'; /* Scope names are separated by periods */ len = *(unsigned char *)in++; StrnCpy(out, in, len); out += len; *out=0; in += len; } #endif //pull_ascii_fstring(name, out_string); strcpy(name, out_string); return(ret); } /**************************************************************************** Extract a netbios name from a buf (into a unix string) return name type. ****************************************************************************/ int name_extract(char *buf,int ofs, fstring name) { char *p = name_ptr(buf,ofs); int d = PTR_DIFF(p,buf+ofs); name[0] = '\0'; if (d < -50 || d > 50) return(0); return(name_interpret(p,name)); } int main(int argc, char *argv[]) { int fd, len; char buf[4096]; fstring name1, name2; *name1 = *name2 = 0; fd=open(argv[1], O_RDONLY); if(fd < 0) { err(1, "Failed to open the file"); } read(fd, buf, sizeof(buf)); close(fd); len = name_len(buf+4); printf("Len: %d\n", len); name_extract(buf,4,name1); printf("|%s|\n", name1); name_extract(buf,4 + name_len(buf + 4),name2); printf("|%s|\n", name2); }