X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Fnamepacket.c;h=418155bbd85b1fa19baa70093f432c3a1e39becc;hb=d98bea900ee694cdba83149620c65bd7f8765f26;hp=5bfa55d4f1646645c4788f97588a99dd3cb6b943;hpb=afd08462ad5ff6b3c4bf621e39c55853a608175e;p=samba.git diff --git a/source3/namepacket.c b/source3/namepacket.c index 5bfa55d4f16..418155bbd85 100644 --- a/source3/namepacket.c +++ b/source3/namepacket.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. NBT netbios routines and daemon - version 2 - Copyright (C) Andrew Tridgell 1994-1995 + Copyright (C) Andrew Tridgell 1994-1997 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 @@ -36,7 +36,7 @@ extern int num_response_packets; BOOL CanRecurse = True; extern pstring scope; -extern struct in_addr ipgrp; +extern struct in_addr wins_ip; static uint16 name_trn_id=0; @@ -91,9 +91,9 @@ static void update_name_trn_id(void) initiate a netbios packet ****************************************************************************/ void initiate_netbios_packet(uint16 *id, - int fd,int quest_type,char *name,int name_type, - int nb_flags,BOOL bcast,BOOL recurse, - struct in_addr to_ip) + int fd,int quest_type,char *name,int name_type, + int nb_flags,BOOL bcast,BOOL recurse, + struct in_addr to_ip) { struct packet_struct p; struct nmb_packet *nmb = &p.packet.nmb; @@ -141,28 +141,29 @@ void initiate_netbios_packet(uint16 *id, make_nmb_name(&nmb->question.question_name,name,name_type,scope); - nmb->question.question_type = quest_type; + nmb->question.question_type = quest_type == NMB_STATUS ? 0x21 : 0x20; nmb->question.question_class = 0x1; if (quest_type == NMB_REG || quest_type == NMB_REG_REFRESH || quest_type == NMB_REL) - { + { nmb->additional = &additional_rec; bzero((char *)nmb->additional,sizeof(*nmb->additional)); nmb->additional->rr_name = nmb->question.question_name; - nmb->additional->rr_type = nmb->question.question_type; - nmb->additional->rr_class = nmb->question.question_class; + nmb->additional->rr_type = 0x20; + nmb->additional->rr_class = 0x1; if (quest_type == NMB_REG || quest_type == NMB_REG_REFRESH) - nmb->additional->ttl = lp_max_ttl(); + nmb->additional->ttl = lp_max_ttl(); else - nmb->additional->ttl = 0; + nmb->additional->ttl = 0; + nmb->additional->rdlength = 6; nmb->additional->rdata[0] = nb_flags; putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip)); - } + } p.ip = to_ip; p.port = NMB_PORT; @@ -170,6 +171,8 @@ void initiate_netbios_packet(uint16 *id, p.timestamp = time(NULL); p.packet_type = NMB_PACKET; + debug_nmb_packet(&p); + if (!send_packet(&p)) { DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port)); *id = 0xffff; @@ -252,7 +255,7 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id, nmb->header.ancount = 1; nmb->header.nscount = 0; nmb->header.arcount = 0; - nmb->header.rcode = 0; + nmb->header.rcode = rcode; bzero((char*)&nmb->question,sizeof(nmb->question)); @@ -320,8 +323,10 @@ static BOOL listening(struct packet_struct *p,struct nmb_name *n) struct subnet_record *d; struct name_record *n1; + /* We explicitly don't search WINS here - this will be done + in find_name_search if it was a packet from a non-local subnet. */ d = find_subnet(p->ip); - + n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip); return (n1 != NULL); @@ -340,13 +345,21 @@ static void process_dgram(struct packet_struct *p) /* if we aren't listening to the destination name then ignore the packet */ if (!listening(p,&dgram->dest_name)) + { + DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s(%x) from %s\n", + dgram->dest_name.name, dgram->dest_name.name_type, inet_ntoa(p->ip))); return; - + } if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && - dgram->header.msg_type != 0x12) { + dgram->header.msg_type != 0x12) + { /* don't process error packets etc yet */ + DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s(%d) from %s as it is \ + an error packet of type %x\n", + dgram->dest_name.name, dgram->dest_name.name_type, + inet_ntoa(p->ip), dgram->header.msg_type)); return; } @@ -359,7 +372,7 @@ static void process_dgram(struct packet_struct *p) len = SVAL(buf,smb_vwv11); buf2 = smb_base(buf) + SVAL(buf,smb_vwv12); - DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n", + DEBUG(4,("process_dgram: datagram from %s to %s for %s of type %d len=%d\n", namestr(&dgram->source_name),namestr(&dgram->dest_name), smb_buf(buf),CVAL(buf2,0),len)); @@ -394,12 +407,17 @@ static void process_nmb(struct packet_struct *p) case NMB_REG: case NMB_REG_REFRESH: { - if (nmb->header.qdcount==0 || nmb->header.arcount==0) break; if (nmb->header.response) + { + if (nmb->header.ancount ==0) break; response_netbios_packet(p); /* response to registration dealt with here */ + } else + { + if (nmb->header.qdcount==0 || nmb->header.arcount==0) break; reply_name_reg(p); + } break; } @@ -439,17 +457,17 @@ static void process_nmb(struct packet_struct *p) case NMB_REL: { - if (nmb->header.qdcount==0 || nmb->header.arcount==0) - { - DEBUG(2,("netbios release packet rejected\n")); - break; - } - if (nmb->header.response) - response_netbios_packet(p); /* response to reply dealt with - in here */ + { + if (nmb->header.ancount ==0) break; + response_netbios_packet(p); /* response to release dealt + with here */ + } else + { + if (nmb->header.qdcount==0 || nmb->header.arcount==0) break; reply_name_release(p); + } break; } } @@ -487,58 +505,63 @@ void run_packet_queue() ***************************************************************************/ void listen_for_packets(BOOL run_election) { - fd_set fds; - int selrtn; - struct timeval timeout; + fd_set fds; + int selrtn; + struct timeval timeout; -try_again: + FD_ZERO(&fds); + FD_SET(ClientNMB,&fds); + FD_SET(ClientDGRAM,&fds); - FD_ZERO(&fds); - FD_SET(ClientNMB,&fds); - FD_SET(ClientDGRAM,&fds); + /* during elections and when expecting a netbios response packet we + need to send election packets at tighter intervals - /* during elections and when expecting a netbios response packet we - need to send election packets at tighter intervals + ideally it needs to be the interval (in ms) between time now and + the time we are expecting the next netbios packet */ - ideally it needs to be the interval (in ms) between time now and - the time we are expecting the next netbios packet */ + timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP; + timeout.tv_usec = 0; - timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP; - timeout.tv_usec = 0; + /* We can only take term signals when we are in the select. */ + BlockSignals(False, SIGTERM); + selrtn = sys_select(&fds,&timeout); + BlockSignals(True, SIGTERM); - selrtn = sys_select(&fds,&timeout); - - if (FD_ISSET(ClientNMB,&fds)) - { - struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET); - if (packet) { - if (ismyip(packet->ip) && - (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) { - DEBUG(7,("discarding own packet from %s:%d\n", - inet_ntoa(packet->ip),packet->port)); - free_packet(packet); - goto try_again; - } else { - queue_packet(packet); + if (FD_ISSET(ClientNMB,&fds)) + { + struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET); + if (packet) + { + if (ismyip(packet->ip) && packet->port == NMB_PORT) + { + DEBUG(7,("discarding own packet from %s:%d\n", + inet_ntoa(packet->ip),packet->port)); + free_packet(packet); + } + else + { + queue_packet(packet); + } + } } - } - } - if (FD_ISSET(ClientDGRAM,&fds)) - { - struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET); - if (packet) { - if (ismyip(packet->ip) && - (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) { - DEBUG(7,("discarding own packet from %s:%d\n", - inet_ntoa(packet->ip),packet->port)); - free_packet(packet); - goto try_again; - } else { - queue_packet(packet); + if (FD_ISSET(ClientDGRAM,&fds)) + { + struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET); + if (packet) + { + if (ismyip(packet->ip) && packet->port == DGRAM_PORT) + { + DEBUG(7,("discarding own packet from %s:%d\n", + inet_ntoa(packet->ip),packet->port)); + free_packet(packet); + } + else + { + queue_packet(packet); + } + } } - } - } } @@ -549,13 +572,12 @@ try_again: Note that this currently sends all answers to port 138. thats the wrong things to do! I should send to the requestors port. XXX **************************************************************************/ -BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname, +BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,char *srcname, char *dstname,int src_type,int dest_type, struct in_addr dest_ip,struct in_addr src_ip) { struct packet_struct p; struct dgram_packet *dgram = &p.packet.dgram; - struct in_addr wins_ip = ipgrp; char *ptr,*p2; char tmp[4]; @@ -566,7 +588,8 @@ BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname, update_name_trn_id(); - dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */ + /* DIRECT GROUP or UNIQUE datagram */ + dgram->header.msg_type = unique ? 0x10 : 0x11; dgram->header.flags.node_type = M_NODE; dgram->header.flags.first = True; dgram->header.flags.more = False;