extern pstring scope;
extern struct in_addr loopback_ip;
+static void queue_packet(struct packet_struct *packet);
+
+BOOL rescan_listen_set = False;
+
+
/*******************************************************************
The global packet linked-list. Incoming entries are
added to the end of this list. It is supposed to remain fairly
static void debug_browse_data(char *outbuf, int len)
{
int i,j;
+
+ DEBUG( 4, ( "debug_browse_data():\n" ) );
for (i = 0; i < len; i+= 16)
{
- DEBUG(4, ("%3x char ", i));
+ DEBUGADD( 4, ( "%3x char ", i ) );
for (j = 0; j < 16; j++)
{
if (i+j >= len)
break;
- DEBUG(4, ("%c", x));
+ DEBUGADD( 4, ( "%c", x ) );
}
- DEBUG(4, (" hex ", i));
+ DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
for (j = 0; j < 16; j++)
{
if (i+j >= len)
break;
- DEBUG(4, (" %02x", (unsigned char)outbuf[i+j]));
+ DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
}
- DEBUG(4, ("\n"));
+ DEBUGADD( 4, ("\n") );
}
}
if (!name_trn_id)
{
- name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
+ name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)getpid()%(unsigned)100);
}
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
return name_trn_id;
return NULL;
}
- bzero((char *)packet,sizeof(*packet));
+ memset((char *)packet,'\0',sizeof(*packet));
nmb = &packet->packet.nmb;
return False;
}
- bzero((char *)nmb->additional,sizeof(struct res_rec));
+ memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
nmb->additional->rr_name = nmb->question.question_name;
nmb->additional->rr_type = RR_TYPE_NB;
nmb->additional->rr_class = RR_CLASS_IN;
- nmb->additional->ttl = lp_max_ttl();
+ /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
+ if (nmb->header.nm_flags.bcast)
+ nmb->additional->ttl = PERMANENT_TTL;
+ else
+ nmb->additional->ttl = lp_max_ttl();
nmb->additional->rdlength = 6;
nmb->header.nm_flags.recursion_desired = True;
DEBUG(4,("initiate_name_query_packet: sending query for name %s (bcast=%s) to IP %s\n",
- namestr(&nmb->question.question_name),
+ nmb_namestr(&nmb->question.question_name),
BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
return send_netbios_packet( packet );
}
+/***************************************************************************
+ Sends out a name query - from a WINS server.
+**************************************************************************/
+
+static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
+{
+ struct nmb_packet *nmb = NULL;
+
+ nmb = &packet->packet.nmb;
+
+ nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
+ nmb->header.arcount = 0;
+
+ nmb->header.nm_flags.recursion_desired = False;
+
+ DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
+ nmb_namestr(&nmb->question.question_name),
+ BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
+
+ return send_netbios_packet( packet );
+}
+
/***************************************************************************
Sends out a name register.
**************************************************************************/
return False;
DEBUG(4,("initiate_name_register_packet: sending registration for name %s (bcast=%s) to IP %s\n",
- namestr(&nmb->additional->rr_name),
+ nmb_namestr(&nmb->additional->rr_name),
BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
return send_netbios_packet( packet );
uint16 nb_flags, struct in_addr *register_ip)
{
struct nmb_packet *nmb = &packet->packet.nmb;
- char second_ip_buf[25];
+ fstring second_ip_buf;
- strcpy(second_ip_buf, inet_ntoa(packet->ip));
+ fstrcpy(second_ip_buf, inet_ntoa(packet->ip));
nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
nmb->header.arcount = 1;
DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
for name %s IP %s (bcast=%s) to IP %s\n",
- namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
+ nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
return send_netbios_packet( packet );
return False;
DEBUG(4,("initiate_name_refresh_packet: sending refresh for name %s (bcast=%s) to IP %s\n",
- namestr(&nmb->additional->rr_name),
+ nmb_namestr(&nmb->additional->rr_name),
BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
return send_netbios_packet( packet );
return False;
DEBUG(4,("initiate_name_release_packet: sending release for name %s (bcast=%s) to IP %s\n",
- namestr(&nmb->additional->rr_name),
+ nmb_namestr(&nmb->additional->rr_name),
BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
return send_netbios_packet( packet );
nmb->question.question_type = QUESTION_TYPE_NB_STATUS;
DEBUG(4,("initiate_node_status_packet: sending node status request for name %s to IP %s\n",
- namestr(&nmb->question.question_name),
+ nmb_namestr(&nmb->question.question_name),
inet_ntoa(packet->ip)));
return send_netbios_packet( packet );
return NULL;
}
+ /*
+ * For a broadcast release packet, only send once.
+ * This will cause us to remove the name asap. JRA.
+ */
+
+ if(bcast)
+ {
+ rrec->repeat_count = 0;
+ rrec->repeat_time = 0;
+ }
+
return rrec;
}
subrec->bcast_ip)) == NULL)
return NULL;
- if(initiate_name_refresh_packet( p, namerec->nb_flags, &refresh_ip) == False)
+ if( !initiate_name_refresh_packet( p, namerec->data.nb_flags, &refresh_ip ) )
{
p->locked = False;
free_packet(p);
return rrec;
}
+/****************************************************************************
+ Queue a query name packet to a given address from the WINS subnet.
+****************************************************************************/
+
+struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ query_name_success_function success_fn,
+ query_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname)
+{
+ struct packet_struct *p;
+ struct response_record *rrec;
+ BOOL bcast = False;
+
+ if(( p = create_and_init_netbios_packet(nmbname, bcast, to_ip)) == NULL)
+ return NULL;
+
+ if(initiate_name_query_packet_from_wins_server( p ) == False)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(wins_server_subnet, /* subnet record. */
+ p, /* packet we sent. */
+ resp_fn, /* function to call on response. */
+ timeout_fn, /* function to call on timeout. */
+ (success_function)success_fn, /* function to call on operation success. */
+ (fail_function)fail_fn, /* function to call on operation fail. */
+ userdata)) == NULL)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ return rrec;
+}
+
/****************************************************************************
Queue a node status packet to a given name and address.
****************************************************************************/
default:
{
DEBUG(0,("reply_netbios_packet: Unknown packet type: %s %s to ip %s\n",
- packet_type, namestr(&orig_nmb->question.question_name),
+ packet_type, nmb_namestr(&orig_nmb->question.question_name),
inet_ntoa(packet.ip)));
return;
DEBUG(4,("reply_netbios_packet: sending a reply of packet type: %s %s to ip %s \
for id %hu\n",
- packet_type, namestr(&orig_nmb->question.question_name),
+ packet_type, nmb_namestr(&orig_nmb->question.question_name),
inet_ntoa(packet.ip), orig_nmb->header.name_trn_id));
nmb->header.name_trn_id = orig_nmb->header.name_trn_id;
nmb->header.nscount = 0;
nmb->header.arcount = 0;
- bzero((char*)&nmb->question,sizeof(nmb->question));
+ memset((char*)&nmb->question,'\0',sizeof(nmb->question));
nmb->answers = &answers;
- bzero((char*)nmb->answers,sizeof(*nmb->answers));
+ memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
nmb->answers->rr_name = orig_nmb->question.question_name;
nmb->answers->rr_type = orig_nmb->question.question_type;
/*******************************************************************
Queue a packet into a packet queue
******************************************************************/
-
-void queue_packet(struct packet_struct *packet)
+static void queue_packet(struct packet_struct *packet)
{
struct packet_struct *p;
/****************************************************************************
Dispatch a browse frame from port 138 to the correct processing function.
****************************************************************************/
-
-void process_browse_packet(struct packet_struct *p, char *buf,int len)
+static void process_browse_packet(struct packet_struct *p, char *buf,int len)
{
struct dgram_packet *dgram = &p->packet.dgram;
int command = CVAL(buf,0);
if (is_myname(dgram->source_name.name))
{
DEBUG(0,("process_browse_packet: Discarding datagram from IP %s. Source name \
-%s is one of our names !\n", inet_ntoa(p->ip), namestr(&dgram->source_name)));
+%s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
return;
}
case ANN_GetBackupListReq:
{
debug_browse_data(buf, len);
-
- /* This is one occasion where we change a subnet that is
- given to us. If the packet was sent to WORKGROUP<1b> instead
- of WORKGROUP<1d> then it was unicast to us a domain master
- browser. Change subrec to unicast.
- */
- if(dgram->dest_name.name_type == 0x1b)
- subrec = unicast_subnet;
-
process_get_backup_list_request(subrec, p, buf+1);
break;
}
/* We never send ANN_GetBackupListReq so we
should never get these. */
DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
-packet from %s IP %s\n", namestr(&dgram->source_name), inet_ntoa(p->ip)));
+packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
break;
}
case ANN_ResetBrowserState:
debug_browse_data(buf, len);
DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
command ANN_BecomeBackup from %s IP %s to %s\n",
- subrec->subnet_name, namestr(&dgram->source_name),
- inet_ntoa(p->ip), namestr(&dgram->dest_name)));
+ subrec->subnet_name, nmb_namestr(&dgram->source_name),
+ inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
break;
}
default:
debug_browse_data(buf, len);
DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
command code %d from %s IP %s to %s\n",
- subrec->subnet_name, command, namestr(&dgram->source_name),
- inet_ntoa(p->ip), namestr(&dgram->dest_name)));
+ subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
+ inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
}
}
}
/****************************************************************************
Dispatch a LanMan browse frame from port 138 to the correct processing function.
****************************************************************************/
-
-void process_lanman_packet(struct packet_struct *p, char *buf,int len)
+static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
{
struct dgram_packet *dgram = &p->packet.dgram;
int command = SVAL(buf,0);
if (is_myname(dgram->source_name.name))
{
DEBUG(0,("process_lanman_packet: Discarding datagram from IP %s. Source name \
-%s is one of our names !\n", inet_ntoa(p->ip), namestr(&dgram->source_name)));
+%s is one of our names !\n", inet_ntoa(p->ip), nmb_namestr(&dgram->source_name)));
return;
}
{
DEBUG(0,("process_lanman_packet: On subnet %s ignoring browse packet \
command code %d from %s IP %s to %s\n",
- subrec->subnet_name, command, namestr(&dgram->source_name),
- inet_ntoa(p->ip), namestr(&dgram->dest_name)));
+ subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
+ inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
}
}
}
if (!listening(p,&dgram->dest_name))
{
DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
- namestr(&dgram->dest_name), inet_ntoa(p->ip)));
+ nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
return;
}
/* 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",
- namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
+ nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
return;
}
buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
- namestr(&dgram->source_name),namestr(&dgram->dest_name),
+ nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
Validate a response nmb packet.
****************************************************************************/
-BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
+static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
{
BOOL ignore = False;
Validate a request nmb packet.
****************************************************************************/
-BOOL validate_nmb_packet( struct nmb_packet *nmb )
+static BOOL validate_nmb_packet( struct nmb_packet *nmb )
{
BOOL ignore = False;
Run elements off the packet queue till its empty
******************************************************************/
-void run_packet_queue()
+void run_packet_queue(void)
{
struct packet_struct *p;
on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip),
subrec->subnet_name));
- /* Call the timeout function. This will deal with removing the
- timed out packet. */
- if(rrec->timeout_fn)
- (*rrec->timeout_fn)(subrec, rrec);
- else
+ /*
+ * Check the flag in this record to prevent recursion if we end
+ * up in this function again via the timeout function call.
+ */
+
+ if(!rrec->in_expiration_processing)
{
- /* We must remove the record ourself if there is
- no timeout function. */
- remove_response_record(subrec, rrec);
- }
+
+ /*
+ * Set the recursion protection flag in this record.
+ */
+
+ rrec->in_expiration_processing = True;
+
+ /* Call the timeout function. This will deal with removing the
+ timed out packet. */
+ if(rrec->timeout_fn)
+ (*rrec->timeout_fn)(subrec, rrec);
+ else
+ {
+ /* We must remove the record ourself if there is
+ no timeout function. */
+ remove_response_record(subrec, rrec);
+ }
+ } /* !rrec->in_expitation_processing */
} /* rrec->repeat_count > 0 */
} /* rrec->repeat_time <= t */
} /* end for rrec */
}
*listen_number = (count*2) + 2;
+
+ if (*ppset) free(*ppset);
+ if (*psock_array) free(*psock_array);
+
*ppset = pset;
*psock_array = sock_array;
int dns_fd;
#endif
- if(listen_set == NULL)
+ if(listen_set == NULL || rescan_listen_set)
{
if(create_listen_fdset(&listen_set, &sock_array, &listen_number))
{
DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
return True;
}
+ rescan_listen_set = False;
}
memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
BlockSignals(False, SIGUSR2);
#endif /* SIGUSR2 */
- selrtn = sys_select(&fds,&timeout);
+ selrtn = sys_select(FD_SETSIZE,&fds,&timeout);
/* We can only take signals when we are in the select - block them again here. */
/****************************************************************************
Construct and send a netbios DGRAM.
- Note that this currently sends all packets to port 138.
**************************************************************************/
-
BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
char *srcname, int src_type,
char *dstname, int dest_type,
- struct in_addr dest_ip,struct in_addr src_ip)
+ struct in_addr dest_ip,struct in_addr src_ip,
+ int dest_port)
{
BOOL loopback_this_packet = False;
struct packet_struct p;
char *ptr,*p2;
char tmp[4];
- bzero((char *)&p,sizeof(p));
+ memset((char *)&p,'\0',sizeof(p));
if(ismyip(dest_ip))
loopback_this_packet = True;
SSVAL(ptr,smb_vwv15,1);
SSVAL(ptr,smb_vwv16,2);
p2 = smb_buf(ptr);
- strcpy(p2,mailslot);
+ pstrcpy(p2,mailslot);
p2 = skip_string(p2,1);
memcpy(p2,buf,len);
dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
p.ip = dest_ip;
- p.port = DGRAM_PORT;
+ p.port = dest_port;
p.fd = find_subnet_mailslot_fd_for_address( src_ip );
p.timestamp = time(NULL);
p.packet_type = DGRAM_PACKET;
DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot,
- namestr(&dgram->source_name), inet_ntoa(src_ip)));
- DEBUG(4,("to %s IP %s\n", namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
+ nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
+ DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
debug_browse_data(buf, len);