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

📄 namequery.c

📁 MC Linux/Unix 终端下文件管理器
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/Netbios implementation.   Version 1.9.   name query routines   Copyright (C) Andrew Tridgell 1994-1998      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 "includes.h"extern pstring scope;extern int DEBUGLEVEL;/* nmbd.c sets this to True. */BOOL global_in_nmbd = False;/****************************************************************************interpret a node status response****************************************************************************/static void _interpret_node_status(char *p, char *master,char *rname){  int numnames = CVAL(p,0);  DEBUG(1,("received %d names\n",numnames));  if (rname) *rname = 0;  if (master) *master = 0;  p += 1;  while (numnames--)    {      char qname[17];      int type;      fstring flags;      int i;      *flags = 0;      StrnCpy(qname,p,15);      type = CVAL(p,15);      p += 16;      fstrcat(flags, (p[0] & 0x80) ? "<GROUP> " : "        ");      if ((p[0] & 0x60) == 0x00) fstrcat(flags,"B ");      if ((p[0] & 0x60) == 0x20) fstrcat(flags,"P ");      if ((p[0] & 0x60) == 0x40) fstrcat(flags,"M ");      if ((p[0] & 0x60) == 0x60) fstrcat(flags,"H ");      if (p[0] & 0x10) fstrcat(flags,"<DEREGISTERING> ");      if (p[0] & 0x08) fstrcat(flags,"<CONFLICT> ");      if (p[0] & 0x04) fstrcat(flags,"<ACTIVE> ");      if (p[0] & 0x02) fstrcat(flags,"<PERMANENT> ");      if (master && !*master && type == 0x1d) {	StrnCpy(master,qname,15);	trim_string(master,NULL," ");      }      if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {	StrnCpy(rname,qname,15);	trim_string(rname,NULL," ");      }            for (i = strlen( qname) ; --i >= 0 ; ) {	if (!isprint((int)qname[i])) qname[i] = '.';      }      DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags));      p+=2;    }  DEBUG(1,("num_good_sends=%d num_good_receives=%d\n",	       IVAL(p,20),IVAL(p,24)));}/****************************************************************************  do a netbios name status query on a host  the "master" parameter is a hack used for finding workgroups.  **************************************************************************/BOOL name_status(int fd,char *name,int name_type,BOOL recurse,		 struct in_addr to_ip,char *master,char *rname,		 void (*fn)(struct packet_struct *)){  BOOL found=False;  int retries = 2;  int retry_time = 5000;  struct timeval tval;  struct packet_struct p;  struct packet_struct *p2;  struct nmb_packet *nmb = &p.packet.nmb;  static int name_trn_id = 0;  memset((char *)&p,'\0',sizeof(p));  if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) +     ((unsigned)getpid()%(unsigned)100);  name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;  nmb->header.name_trn_id = name_trn_id;  nmb->header.opcode = 0;  nmb->header.response = False;  nmb->header.nm_flags.bcast = False;  nmb->header.nm_flags.recursion_available = False;  nmb->header.nm_flags.recursion_desired = False;  nmb->header.nm_flags.trunc = False;  nmb->header.nm_flags.authoritative = False;  nmb->header.rcode = 0;  nmb->header.qdcount = 1;  nmb->header.ancount = 0;  nmb->header.nscount = 0;  nmb->header.arcount = 0;  make_nmb_name(&nmb->question.question_name,name,name_type);  nmb->question.question_type = 0x21;  nmb->question.question_class = 0x1;  p.ip = to_ip;  p.port = NMB_PORT;  p.fd = fd;  p.timestamp = time(NULL);  p.packet_type = NMB_PACKET;  GetTimeOfDay(&tval);  if (!send_packet(&p))     return(False);  retries--;  while (1)    {      struct timeval tval2;      GetTimeOfDay(&tval2);      if (TvalDiff(&tval,&tval2) > retry_time) {	if (!retries) break;	if (!found && !send_packet(&p))	  return False;	GetTimeOfDay(&tval);	retries--;      }      if ((p2=receive_packet(fd,NMB_PACKET,90)))	{     	  struct nmb_packet *nmb2 = &p2->packet.nmb;      debug_nmb_packet(p2);	  if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||	      !nmb2->header.response) {	    /* its not for us - maybe deal with it later */	    if (fn) 	      fn(p2);	    else	      free_packet(p2);	    continue;	  }	  	  if (nmb2->header.opcode != 0 ||	      nmb2->header.nm_flags.bcast ||	      nmb2->header.rcode ||	      !nmb2->header.ancount ||	      nmb2->answers->rr_type != 0x21) {	    /* XXXX what do we do with this? could be a redirect, but	       we'll discard it for the moment */	    free_packet(p2);	    continue;	  }	  _interpret_node_status(&nmb2->answers->rdata[0], master,rname);	  free_packet(p2);	  return(True);	}    }    DEBUG(0,("No status response (this is not unusual)\n"));  return(False);}/****************************************************************************  do a netbios name query to find someones IP  returns an array of IP addresses or NULL if none  *count will be set to the number of addresses returned  ****************************************************************************/struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse,         struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *)){  BOOL found=False;  int i, retries = 3;  int retry_time = bcast?250:2000;  struct timeval tval;  struct packet_struct p;  struct packet_struct *p2;  struct nmb_packet *nmb = &p.packet.nmb;  static int name_trn_id = 0;  struct in_addr *ip_list = NULL;  memset((char *)&p,'\0',sizeof(p));  (*count) = 0;  if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) +     ((unsigned)getpid()%(unsigned)100);  name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;  nmb->header.name_trn_id = name_trn_id;  nmb->header.opcode = 0;  nmb->header.response = False;  nmb->header.nm_flags.bcast = bcast;  nmb->header.nm_flags.recursion_available = False;  nmb->header.nm_flags.recursion_desired = recurse;  nmb->header.nm_flags.trunc = False;  nmb->header.nm_flags.authoritative = False;  nmb->header.rcode = 0;  nmb->header.qdcount = 1;  nmb->header.ancount = 0;  nmb->header.nscount = 0;  nmb->header.arcount = 0;  make_nmb_name(&nmb->question.question_name,name,name_type);  nmb->question.question_type = 0x20;  nmb->question.question_class = 0x1;  p.ip = to_ip;  p.port = NMB_PORT;  p.fd = fd;  p.timestamp = time(NULL);  p.packet_type = NMB_PACKET;  GetTimeOfDay(&tval);  if (!send_packet(&p))     return NULL;  retries--;  while (1)  {    struct timeval tval2;    GetTimeOfDay(&tval2);    if (TvalDiff(&tval,&tval2) > retry_time)     {      if (!retries)        break;      if (!found && !send_packet(&p))        return NULL;      GetTimeOfDay(&tval);      retries--;    }    if ((p2=receive_packet(fd,NMB_PACKET,90)))    {           struct nmb_packet *nmb2 = &p2->packet.nmb;      debug_nmb_packet(p2);      if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||          !nmb2->header.response)      {        /*          * Its not for us - maybe deal with it later          * (put it on the queue?).         */        if (fn)           fn(p2);        else          free_packet(p2);        continue;      }	        if (nmb2->header.opcode != 0 ||          nmb2->header.nm_flags.bcast ||          nmb2->header.rcode ||          !nmb2->header.ancount)      {	    /*          * XXXX what do we do with this? Could be a redirect, but         * we'll discard it for the moment.         */        free_packet(p2);        continue;      }      ip_list = (struct in_addr *)Realloc(ip_list, sizeof(ip_list[0]) *                                           ((*count)+nmb2->answers->rdlength/6));      if (ip_list)      {        DEBUG(fn?3:2,("Got a positive name query response from %s ( ",              inet_ntoa(p2->ip)));        for (i=0;i<nmb2->answers->rdlength/6;i++)        {          putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);          DEBUG(fn?3:2,("%s ",inet_ntoa(ip_list[(*count)])));          (*count)++;        }        DEBUG(fn?3:2,(")\n"));      }      found=True;      retries=0;      free_packet(p2);      if (fn)        break;      /*       * If we're doing a unicast lookup we only       * expect one reply. Don't wait the full 2       * seconds if we got one. JRA.       */      if(!bcast && found)        break;    }  }  return ip_list;}/******************************************************** Start parsing the lmhosts file.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -