[Samba] Session request packet

liqian qli at psh.com.cn
Wed Aug 23 05:13:22 GMT 2006


hello list:
i am learing smb protocol. i lookup NBT SESSION REQUEST PACKET from rfc
1002. 


  SESSION REQUEST PACKET

                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      TYPE     |     FLAGS     |            LENGTH             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   /                          CALLED NAME                          /
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   /                          CALLING NAME                         /
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

i have a program to send this packet to windows-base host, but i cannot
properly send this packet. the result is the following by tcpdump.

>>> NBT Session Packet
NBT Session Request
Flags=0x0
Length=64 (0x40)
Destination=                NameType=0x00 (Workstation)
Source=
 
>>> NBT Session Packet
NBT SessionReject
Flags=0x0
Length=1 (0x1)
Reason=0x8F
Unspecified error 0x8F

why is the Destination field empty??

what is CALLED NAME ????



/***************************************************************************/

#include <iostream.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>

struct NBT_Session_Header
{
    unsigned char type;
    unsigned char flags;
    unsigned short length;
};

struct NBT_NAME
{
  char name[32];
};
  
struct NBT_Request
{
  struct NBT_Session_Header NBTSessionHeader;
  NBT_NAME called;
  NBT_NAME calling;
};

int connectHost(const char* szHost, int iPort);
int sendNBT(void* data, size_t count, int socketid);
bool getnetbiosname(char* netbiosname, const char* hostname, unsigned char type);



//Main function
int main(int argc, char *argv[])
{

  int socketid = 0;
  if((socketid = connectHost("192.168.2.65", 139)) == -1)
    cout << "Connect host error" << endl;
    

  NBT_Request request;
  request.NBTSessionHeader.type = 0x81;
  request.NBTSessionHeader.flags = 0x0;
  request.NBTSessionHeader.length = htons(0x40);

  getnetbiosname(request.called.name, "0", 0x20);

  getnetbiosname(request.calling.name, "0", 0x00);

  cout << sizeof(NBT_Request) << endl;
  sendNBT(&request, sizeof(NBT_Request), socketid);
   
  cout << "Operate finished." << endl;
  return 0;
}


int connectHost(const char* szHost, int iPort)
{
  //Judge if parameter is avalible
  if((szHost == 0) || (iPort <= 0))
    return -1;

    
  int socketid = 0; //identify of socket
  
  //Initial a tcp socket and get identify of socket
  socketid = socket(AF_INET, SOCK_STREAM, 0);
  if(socketid == -1)
    cout << "Scocket error." << endl;
  else
    cout << "Socket is " << socketid << endl;

  //Get name by ip address of host 
  struct hostent* host;
  if((host = gethostbyname(szHost)) != NULL)
    cout << "Get host name is " << host->h_name << endl;
  else
  {
    cout << "Get host name failed." << endl;
    return -1;
  }
    
  //Connect port of host what want to connect
  struct sockaddr_in sockaddr;
  sockaddr.sin_family = AF_INET;
  sockaddr.sin_port = htons(iPort);
  sockaddr.sin_addr = *((struct in_addr*)host->h_addr);

  if(connect(socketid, (struct sockaddr*)&sockaddr, sizeof(struct sockaddr)) == -1)
  {
    cout << "Connect failed." << endl;
    return -1;
  }
  else
    cout << "Connect succeed." << endl;

  return socketid;
}

int sendNBT(void* data, size_t count, int socketid)
{
  int num;
  //htonl
  num = send(socketid, data, count, 0);
  if(num == -1)
    cout << "Send failed." << errno << endl;
  else
    cout << "Send succeed." << endl;
    
  return num;
}

bool getnetbiosname(char* netbiosname, const char* hostname, unsigned char type)
{

  if(strlen(hostname) >= 16)
    return false;

  char src[16];
  memset(src, ' ', 16);
  memcpy(src, hostname, strlen(hostname));
  src[15] = type;

  int i;

  for(i = 0; i < 16; i++)
  {
    netbiosname[i*2] = ((src[i]&0xf0)>>4) + 0x41;
    netbiosname[i*2 + 1] = (src[i]&0x0f) + 0x41;
  }
  return true;
}

/***************************************************************************/
Thanks in advance,
liqian





More information about the samba mailing list