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

📄 nmbd_packets.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
				inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));			break;	}}/****************************************************************************  Determine if a packet is for us on port 138. Note that to have any chance of  being efficient we need to drop as many packets as possible at this  stage as subsequent processing is expensive. ****************************************************************************/static BOOL listening(struct packet_struct *p,struct nmb_name *nbname){	struct subnet_record *subrec = NULL;	for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {		if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))			break;	}	if(subrec == NULL)		subrec = unicast_subnet;	return (find_name_on_subnet(subrec, nbname, FIND_SELF_NAME) != NULL);}/****************************************************************************  Process udp 138 datagrams****************************************************************************/static void process_dgram(struct packet_struct *p){	char *buf;	char *buf2;	int len;	struct dgram_packet *dgram = &p->packet.dgram;	/* If we aren't listening to the destination name then ignore the packet */	if (!listening(p,&dgram->dest_name)) {			unexpected_packet(p);			DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",				nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));			return;	}	if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {		unexpected_packet(p);		/* Don't process error packets etc yet */		DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));		return;	}	/* Ensure we have a large enough packet before looking inside. */	if (dgram->datasize < (smb_vwv12 - 2)) {		/* That's the offset minus the 4 byte length + 2 bytes of offset. */		DEBUG(0,("process_dgram: ignoring too short dgram packet (%u) sent to name %s from IP %s\n",			(unsigned int)dgram->datasize,			nmb_namestr(&dgram->dest_name),			inet_ntoa(p->ip) ));		return;	}	buf = &dgram->data[0];	buf -= 4; /* XXXX for the pseudo tcp length - someday I need to get rid of this */	if (CVAL(buf,smb_com) != SMBtrans)		return;	len = SVAL(buf,smb_vwv11);	buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);	if (len <= 0 || len > dgram->datasize) {		DEBUG(0,("process_dgram: ignoring malformed1 (datasize = %d, len = %d) datagram \packet sent to name %s from IP %s\n",			dgram->datasize,			len,			nmb_namestr(&dgram->dest_name),			inet_ntoa(p->ip) ));		return;	}	if (buf2 < dgram->data || (buf2 >= dgram->data + dgram->datasize)) {		DEBUG(0,("process_dgram: ignoring malformed2 (datasize = %d, len=%d, off=%d) datagram \packet sent to name %s from IP %s\n",			dgram->datasize,			len,			(int)PTR_DIFF(buf2, dgram->data),			nmb_namestr(&dgram->dest_name),			inet_ntoa(p->ip) ));		return;	}	if ((buf2 + len < dgram->data) || (buf2 + len > dgram->data + dgram->datasize)) {		DEBUG(0,("process_dgram: ignoring malformed3 (datasize = %d, len=%d, off=%d) datagram \packet sent to name %s from IP %s\n",			dgram->datasize,			len,			(int)PTR_DIFF(buf2, dgram->data),			nmb_namestr(&dgram->dest_name),			inet_ntoa(p->ip) ));		return;	}	DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",		nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),		inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));	/* Datagram packet received for the browser mailslot */	if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {		process_browse_packet(p,buf2,len);		return;	}	/* Datagram packet received for the LAN Manager mailslot */	if (strequal(smb_buf(buf),LANMAN_MAILSLOT)) {		process_lanman_packet(p,buf2,len);		return;	}	/* Datagram packet received for the domain logon mailslot */	if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {		process_logon_packet(p,buf2,len,NET_LOGON_MAILSLOT);		return;	}	/* Datagram packet received for the NT domain logon mailslot */	if (strequal(smb_buf(buf),NT_LOGON_MAILSLOT)) {		process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);		return;	}	unexpected_packet(p);}/****************************************************************************  Validate a response nmb packet.****************************************************************************/static BOOL validate_nmb_response_packet( struct nmb_packet *nmb ){	BOOL ignore = False;	switch (nmb->header.opcode) {		case NMB_NAME_REG_OPCODE:		case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */		case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */			if (nmb->header.ancount == 0) {				DEBUG(0,("validate_nmb_response_packet: Bad REG/REFRESH Packet. "));				ignore = True;			}			break;		case NMB_NAME_QUERY_OPCODE:			if ((nmb->header.ancount != 0) && (nmb->header.ancount != 1)) {				DEBUG(0,("validate_nmb_response_packet: Bad QUERY Packet. "));				ignore = True;			}			break;		case NMB_NAME_RELEASE_OPCODE:			if (nmb->header.ancount == 0) {				DEBUG(0,("validate_nmb_response_packet: Bad RELEASE Packet. "));				ignore = True;			}			break;		case NMB_WACK_OPCODE:			/* Check WACK response here. */			if (nmb->header.ancount != 1) {				DEBUG(0,("validate_nmb_response_packet: Bad WACK Packet. "));				ignore = True;			}			break;		default:			DEBUG(0,("validate_nmb_response_packet: Ignoring packet with unknown opcode %d.\n",					nmb->header.opcode));			return True;	}	if(ignore)		DEBUG(0,("Ignoring response packet with opcode %d.\n", nmb->header.opcode));	return ignore;} /****************************************************************************  Validate a request nmb packet.****************************************************************************/static BOOL validate_nmb_packet( struct nmb_packet *nmb ){	BOOL ignore = False;	switch (nmb->header.opcode) {		case NMB_NAME_REG_OPCODE:		case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */		case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */		case NMB_NAME_MULTIHOMED_REG_OPCODE:			if (nmb->header.qdcount==0 || nmb->header.arcount==0) {				DEBUG(0,("validate_nmb_packet: Bad REG/REFRESH Packet. "));				ignore = True;			}			break;		case NMB_NAME_QUERY_OPCODE:			if ((nmb->header.qdcount == 0) || ((nmb->question.question_type != QUESTION_TYPE_NB_QUERY) &&					(nmb->question.question_type != QUESTION_TYPE_NB_STATUS))) {				DEBUG(0,("validate_nmb_packet: Bad QUERY Packet. "));				ignore = True;			}			break;		case NMB_NAME_RELEASE_OPCODE:			if (nmb->header.qdcount==0 || nmb->header.arcount==0) {				DEBUG(0,("validate_nmb_packet: Bad RELEASE Packet. "));				ignore = True;			}			break;		default:			DEBUG(0,("validate_nmb_packet: Ignoring packet with unknown opcode %d.\n",				nmb->header.opcode));			return True;	}	if(ignore)		DEBUG(0,("validate_nmb_packet: Ignoring request packet with opcode %d.\n", nmb->header.opcode));	return ignore;}/****************************************************************************  Find a subnet (and potentially a response record) for a packet.****************************************************************************/static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p,                                                         struct response_record **pprrec){	struct nmb_packet *nmb = &p->packet.nmb;	struct response_record *rrec = NULL;	struct subnet_record *subrec = NULL;	if(pprrec != NULL)		*pprrec = NULL;	if(nmb->header.response) {		/* It's a response packet. Find a record for it or it's an error. */		rrec = find_response_record( &subrec, nmb->header.name_trn_id);		if(rrec == NULL) {			DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",				nmb->header.name_trn_id));			unexpected_packet(p);			return NULL;		}		if(subrec == NULL) {			DEBUG(0,("find_subnet_for_nmb_packet: subnet record not found for response id %hu\n",				nmb->header.name_trn_id));			return NULL;		}		if(pprrec != NULL)			*pprrec = rrec;		return subrec;	}	/* Try and see what subnet this packet belongs to. */	/* WINS server ? */	if(packet_is_for_wins_server(p))		return wins_server_subnet;	/* If it wasn't a broadcast packet then send to the UNICAST subnet. */	if(nmb->header.nm_flags.bcast == False)		return unicast_subnet;	/* Go through all the broadcast subnets and see if the mask matches. */	for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {		if(same_net(p->ip, subrec->bcast_ip, subrec->mask_ip))			return subrec;	}	/* If none match it must have been a directed broadcast - assign the remote_broadcast_subnet. */	return remote_broadcast_subnet;}/****************************************************************************  Process a nmb request packet - validate the packet and route it.****************************************************************************/static void process_nmb_request(struct packet_struct *p){	struct nmb_packet *nmb = &p->packet.nmb;	struct subnet_record *subrec = NULL;	debug_nmb_packet(p);	/* Ensure we have a good packet. */	if(validate_nmb_packet(nmb))		return;	/* Allocate a subnet to this packet - if we cannot - fail. */	if((subrec = find_subnet_for_nmb_packet(p, NULL))==NULL)		return;	switch (nmb->header.opcode) {		case NMB_NAME_REG_OPCODE:			if(subrec == wins_server_subnet)				wins_process_name_registration_request(subrec, p);			else				process_name_registration_request(subrec, p);			break;		case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */		case NMB_NAME_REFRESH_OPCODE_9:			if(subrec == wins_server_subnet)				wins_process_name_refresh_request(subrec, p);			else				process_name_refresh_request(subrec, p);			break;		case NMB_NAME_MULTIHOMED_REG_OPCODE:			if(subrec == wins_server_subnet) {				wins_process_multihomed_name_registration_request(subrec, p);			} else {				DEBUG(0,("process_nmb_request: Multihomed registration request must be \directed at a WINS server.\n"));			}			break;		case NMB_NAME_QUERY_OPCODE:			switch (nmb->question.question_type) {				case QUESTION_TYPE_NB_QUERY:					if(subrec == wins_server_subnet)						wins_process_name_query_request(subrec, p);					else						process_name_query_request(subrec, p);					break;				case QUESTION_TYPE_NB_STATUS:					if(subrec == wins_server_subnet) {						DEBUG(0,("process_nmb_request: NB_STATUS request directed at WINS server is \not allowed.\n"));						break;					} else {						process_node_status_request(subrec, p);					}					break;			}			break;      		case NMB_NAME_RELEASE_OPCODE:			if(subrec == wins_server_subnet)				wins_process_name_release_request(subrec, p);			else				process_name_release_request(subrec, p);			break;	}}/****************************************************************************  Process a nmb response packet - validate the packet and route it.  to either the WINS server or a normal response.****************************************************************************/static void process_nmb_response(struct packet_struct *p){	struct nmb_packet *nmb = &p->packet.nmb;	struct subnet_record *subrec = NULL;	struct response_record *rrec = NULL;	debug_nmb_packet(p);	if(validate_nmb_response_packet(nmb))		return;	if((subrec = find_subnet_for_nmb_packet(p, &rrec))==NULL)		return;	if(rrec == NULL) {		DEBUG(0,("process_nmb_response: response packet received but no response record \found for id = %hu. Ignoring packet.\n", nmb->header.name_trn_id));		return;	}	/* Increment the number of responses received for this record. */	rrec->num_msgs++;

⌨️ 快捷键说明

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