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.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
extern int num_response_packets;
-extern struct in_addr loopback_ip;
-
-static void queue_packet(struct packet_struct *packet);
-
-BOOL rescan_listen_set = False;
+bool rescan_listen_set = False;
/*******************************************************************
struct subnet_record *subrec;
for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- if(ip_equal(local_ip, subrec->myip))
+ if(ip_equal_v4(local_ip, subrec->myip))
return subrec->nmb_sock;
return ClientNMB;
struct subnet_record *subrec;
for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- if(ip_equal(local_ip, subrec->myip))
+ if(ip_equal_v4(local_ip, subrec->myip))
return subrec->dgram_sock;
return ClientDGRAM;
Either loops back or sends out a completed NetBIOS packet.
**************************************************************************/
-static BOOL send_netbios_packet(struct packet_struct *p)
+static bool send_netbios_packet(struct packet_struct *p)
{
- BOOL loopback_this_packet = False;
+ bool loopback_this_packet = False;
/* Check if we are sending to or from ourselves as a WINS server. */
- if(ismyip(p->ip) && (p->port == global_nmb_port))
+ if(ismyip_v4(p->ip) && (p->port == global_nmb_port))
loopback_this_packet = True;
if(loopback_this_packet) {
**************************************************************************/
static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
- BOOL bcast, BOOL rec_des,
+ bool bcast, bool rec_des,
struct in_addr to_ip)
{
struct packet_struct *packet = NULL;
Sets up the common elements of register, refresh or release packet.
**************************************************************************/
-static BOOL create_and_init_additional_record(struct packet_struct *packet,
+static bool create_and_init_additional_record(struct packet_struct *packet,
uint16 nb_flags,
- struct in_addr *register_ip)
+ const struct in_addr *register_ip)
{
struct nmb_packet *nmb = &packet->packet.nmb;
if((nmb->additional = SMB_MALLOC_P(struct res_rec)) == NULL) {
- DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
+ DEBUG(0,("create_and_init_additional_record: malloc fail for additional record.\n"));
return False;
}
Sends out a name query.
**************************************************************************/
-static BOOL initiate_name_query_packet( struct packet_struct *packet)
+static bool initiate_name_query_packet( struct packet_struct *packet)
{
struct nmb_packet *nmb = NULL;
Sends out a name query - from a WINS server.
**************************************************************************/
-static BOOL initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
+static bool initiate_name_query_packet_from_wins_server( struct packet_struct *packet)
{
struct nmb_packet *nmb = NULL;
Sends out a name register.
**************************************************************************/
-static BOOL initiate_name_register_packet( struct packet_struct *packet,
- uint16 nb_flags, struct in_addr *register_ip)
+static bool initiate_name_register_packet( struct packet_struct *packet,
+ uint16 nb_flags, const struct in_addr *register_ip)
{
struct nmb_packet *nmb = &packet->packet.nmb;
Sends out a multihomed name register.
**************************************************************************/
-static BOOL initiate_multihomed_name_register_packet(struct packet_struct *packet,
+static bool initiate_multihomed_name_register_packet(struct packet_struct *packet,
uint16 nb_flags, struct in_addr *register_ip)
{
struct nmb_packet *nmb = &packet->packet.nmb;
Sends out a name refresh.
**************************************************************************/
-static BOOL initiate_name_refresh_packet( struct packet_struct *packet,
+static bool initiate_name_refresh_packet( struct packet_struct *packet,
uint16 nb_flags, struct in_addr *refresh_ip)
{
struct nmb_packet *nmb = &packet->packet.nmb;
Sends out a name release.
**************************************************************************/
-static BOOL initiate_name_release_packet( struct packet_struct *packet,
+static bool initiate_name_release_packet( struct packet_struct *packet,
uint16 nb_flags, struct in_addr *release_ip)
{
struct nmb_packet *nmb = &packet->packet.nmb;
Sends out a node status.
**************************************************************************/
-static BOOL initiate_node_status_packet( struct packet_struct *packet )
+static bool initiate_node_status_packet( struct packet_struct *packet )
{
struct nmb_packet *nmb = &packet->packet.nmb;
broadcast subnet.
****************************************************************************/
-static BOOL assert_check_subnet(struct subnet_record *subrec)
+static bool assert_check_subnet(struct subnet_record *subrec)
{
if( subrec == remote_broadcast_subnet) {
DEBUG(0,("assert_check_subnet: Attempt to send packet on remote broadcast subnet. \
{
struct packet_struct *p;
struct response_record *rrec;
-
+ struct sockaddr_storage ss;
+ const struct sockaddr_storage *pss = NULL;
if(assert_check_subnet(subrec))
return NULL;
subrec->bcast_ip)) == NULL)
return NULL;
- if(initiate_name_register_packet( p, nb_flags, iface_ip(subrec->bcast_ip)) == False) {
+ in_addr_to_sockaddr_storage(&ss, subrec->bcast_ip);
+ pss = iface_ip((struct sockaddr *)&ss);
+ if (!pss || pss->ss_family != AF_INET) {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if(initiate_name_register_packet(p, nb_flags,
+ &((const struct sockaddr_in *)pss)->sin_addr) == False) {
p->locked = False;
free_packet(p);
return NULL;
{
struct packet_struct *p;
struct response_record *rrec;
- BOOL ret;
+ bool ret;
/* Sanity check. */
if(subrec != unicast_subnet) {
/* queries to the WINS server turn up here as queries to IP 0.0.0.0
These need to be handled a bit differently */
- if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
+ if (subrec->type == UNICAST_SUBNET && is_zero_ip_v4(to_ip)) {
/* What we really need to do is loop over each of our wins
* servers and wins server tags here, but that just doesn't
* fit our architecture at the moment (userdata may already
DEBUG(10,("queue_query_name: bind_interfaces_only is set, looking for suitable source IP\n"));
for(i = 0; i < iface_count(); i++) {
- struct in_addr *ifip = iface_n_ip(i);
+ const struct in_addr *ifip = iface_n_ip_v4(i);
- if(ifip == NULL) {
+ if (ifip == NULL) {
DEBUG(0,("queue_query_name: interface %d has NULL IP address !\n", i));
continue;
}
- if (ip_equal(*ifip,loopback_ip)) {
+ if (is_loopback_ip_v4(*ifip)) {
DEBUG(5,("queue_query_name: ignoring loopback interface (%d)\n", i));
continue;
}
/****************************************************************************
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,
/****************************************************************************
Queue a node status packet to a given name and address.
****************************************************************************/
-
+
struct response_record *queue_node_status( struct subnet_record *subrec,
response_function resp_fn,
timeout_response_function timeout_fn,
p->locked = False;
free_packet(p);
return NULL;
- }
+ }
if((rrec = make_response_record(subrec, /* subnet record. */
p, /* packet we sent. */
struct nmb_packet *nmb = NULL;
struct res_rec answers;
struct nmb_packet *orig_nmb = &orig_packet->packet.nmb;
- BOOL loopback_this_packet = False;
+ bool loopback_this_packet = False;
int rr_type = RR_TYPE_NB;
const char *packet_type = "unknown";
-
+
/* Check if we are sending to or from ourselves. */
- if(ismyip(orig_packet->ip) && (orig_packet->port == global_nmb_port))
+ if(ismyip_v4(orig_packet->ip) && (orig_packet->port == global_nmb_port))
loopback_this_packet = True;
-
+
nmb = &packet.packet.nmb;
/* Do a partial copy of the packet. We clear the locked flag and
nmb->header.nm_flags.bcast = False;
nmb->header.nm_flags.trunc = False;
nmb->header.nm_flags.authoritative = True;
-
+
nmb->header.rcode = rcode;
nmb->header.qdcount = 0;
nmb->header.ancount = 1;
nmb->header.nscount = 0;
nmb->header.arcount = 0;
-
+
memset((char*)&nmb->question,'\0',sizeof(nmb->question));
-
+
nmb->answers = &answers;
memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
-
+
nmb->answers->rr_name = orig_nmb->question.question_name;
nmb->answers->rr_type = rr_type;
nmb->answers->rr_class = RR_CLASS_IN;
nmb->answers->ttl = ttl;
-
+
if (data && len) {
+ if (len < 0 || len > sizeof(nmb->answers->rdata)) {
+ DEBUG(5,("reply_netbios_packet: "
+ "invalid packet len (%d)\n",
+ len ));
+ return;
+ }
nmb->answers->rdlength = len;
memcpy(nmb->answers->rdata, data, len);
}
-
+
packet.packet_type = NMB_PACKET;
/* Ensure we send out on the same fd that the original
packet came in on to give the correct source IP address. */
packet.timestamp = time(NULL);
debug_nmb_packet(&packet);
-
+
if(loopback_this_packet) {
struct packet_struct *lo_packet;
DEBUG(5,("reply_netbios_packet: sending packet to ourselves.\n"));
Queue a packet into a packet queue
******************************************************************/
-static void queue_packet(struct packet_struct *packet)
+void queue_packet(struct packet_struct *packet)
{
struct packet_struct *p;
packet_queue = packet;
return;
}
-
+
/* find the bottom */
- for (p=packet_queue;p->next;p=p->next)
+ for (p=packet_queue;p->next;p=p->next)
;
p->next = packet;
/* 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))
+ if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
return subrec;
}
process_master_browser_announce(subrec, p, buf+1);
break;
case ANN_BecomeBackup:
- /*
+ /*
* We don't currently implement this. Log it just in case.
*/
debug_browse_data(buf, len);
command code %d from %s IP %s to %s\n", subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
break;
- }
+ }
}
/****************************************************************************
stage as subsequent processing is expensive.
****************************************************************************/
-static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
+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))
+ if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
break;
}
Validate a response nmb packet.
****************************************************************************/
-static BOOL validate_nmb_response_packet( struct nmb_packet *nmb )
+static bool validate_nmb_response_packet( struct nmb_packet *nmb )
{
- BOOL ignore = False;
+ bool ignore = False;
switch (nmb->header.opcode) {
case NMB_NAME_REG_OPCODE:
return ignore;
}
-
+
/****************************************************************************
Validate a request nmb packet.
****************************************************************************/
-static BOOL validate_nmb_packet( struct nmb_packet *nmb )
+static bool validate_nmb_packet( struct nmb_packet *nmb )
{
- BOOL ignore = False;
+ bool ignore = False;
switch (nmb->header.opcode) {
case NMB_NAME_REG_OPCODE:
/* 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))
+ if(same_net_v4(p->ip, subrec->bcast_ip, subrec->mask_ip))
return subrec;
}
break;
}
break;
-
+
case NMB_NAME_RELEASE_OPCODE:
if(subrec == wins_server_subnet)
wins_process_name_release_request(subrec, p);
rrec->num_msgs++;
/* Ensure we don't re-send the request. */
rrec->repeat_count = 0;
-
+
/* Call the response received function for this packet. */
(*rrec->resp_fn)(subrec, rrec, p);
}
}
free_packet(p);
}
-}
+}
/*******************************************************************
Retransmit or timeout elements from all the outgoing subnet response
for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
struct response_record *rrec, *nextrrec;
+ restart:
+
for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
nextrrec = rrec->next;
-
+
if (rrec->repeat_time <= t) {
if (rrec->repeat_count > 0) {
/* Resend while we have a non-zero repeat_count. */
no timeout function. */
remove_response_record(subrec, rrec);
}
+ /* We have changed subrec->responselist,
+ * restart from the beginning of this list. */
+ goto restart;
} /* !rrec->in_expitation_processing */
} /* rrec->repeat_count > 0 */
} /* rrec->repeat_time <= t */
plus the broadcast sockets.
***************************************************************************/
-static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd)
+static bool create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd)
{
int *sock_array = NULL;
struct subnet_record *subrec = NULL;
*ppset = pset;
*psock_array = sock_array;
-
+
return False;
}
return True if the socket is dead
***************************************************************************/
-BOOL listen_for_packets(BOOL run_election)
+bool listen_for_packets(bool run_election)
{
static fd_set *listen_set = NULL;
static int listen_number = 0;
}
#endif
- /*
+ /* Process a signal and timer events now... */
+ if (run_events(nmbd_event_context(), 0, NULL, NULL)) {
+ return False;
+ }
+
+ /*
* 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
&r_fds, &w_fds, &timeout, &maxfd);
}
- if (timeval_is_zero(&timeout)) {
- /* Process a timed event now... */
- if (run_events(nmbd_event_context(), 0, NULL, NULL)) {
- return False;
- }
- }
-
- /* Prepare for the select - allow certain signals. */
-
- BlockSignals(False, SIGTERM);
-
selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&timeout);
- /* We can only take signals when we are in the select - block them again here. */
-
- BlockSignals(True, SIGTERM);
-
- if(selrtn == -1) {
+ if (run_events(nmbd_event_context(), selrtn, &r_fds, &w_fds)) {
return False;
}
- if (run_events(nmbd_event_context(), selrtn, &r_fds, &w_fds)) {
+ if (selrtn == -1) {
return False;
}
* only is set then check it came from one of our local nets.
*/
if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) &&
- (!is_local_net(packet->ip))) {
+ (!is_local_net_v4(packet->ip))) {
DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
free_packet(packet);
- } else if ((ip_equal(loopback_ip, packet->ip) ||
- ismyip(packet->ip)) && packet->port == global_nmb_port &&
+ } else if ((is_loopback_ip_v4(packet->ip) ||
+ ismyip_v4(packet->ip)) && packet->port == global_nmb_port &&
packet->packet.nmb.header.nm_flags.bcast) {
DEBUG(7,("discarding own bcast packet from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
* only is set then check it came from one of our local nets.
*/
if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) &&
- (!is_local_net(packet->ip))) {
+ (!is_local_net_v4(packet->ip))) {
DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
free_packet(packet);
- } else if ((ip_equal(loopback_ip, packet->ip) ||
- ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
+ } else if ((is_loopback_ip_v4(packet->ip) ||
+ ismyip_v4(packet->ip)) && packet->port == DGRAM_PORT) {
DEBUG(7,("discarding own dgram packet from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
free_packet(packet);
Construct and send a netbios DGRAM.
**************************************************************************/
-BOOL send_mailslot(BOOL unique, const char *mailslot,char *buf, size_t len,
+bool send_mailslot(bool unique, const char *mailslot,char *buf, size_t len,
const char *srcname, int src_type,
const char *dstname, int dest_type,
struct in_addr dest_ip,struct in_addr src_ip,
int dest_port)
{
- BOOL loopback_this_packet = False;
+ bool loopback_this_packet = False;
struct packet_struct p;
struct dgram_packet *dgram = &p.packet.dgram;
char *ptr,*p2;
memset((char *)&p,'\0',sizeof(p));
- if(ismyip(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
+ if(ismyip_v4(dest_ip) && (dest_port == DGRAM_PORT)) /* Only if to DGRAM_PORT */
loopback_this_packet = True;
/* generate_name_trn_id(); */ /* Not used, so gone, RJS */
/* DIRECT GROUP or UNIQUE datagram. */
- dgram->header.msg_type = unique ? 0x10 : 0x11;
+ dgram->header.msg_type = unique ? 0x10 : 0x11;
dgram->header.flags.node_type = M_NODE;
dgram->header.flags.first = True;
dgram->header.flags.more = False;
dgram->header.source_port = DGRAM_PORT;
dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
dgram->header.packet_offset = 0;
-
+
make_nmb_name(&dgram->source_name,srcname,src_type);
make_nmb_name(&dgram->dest_name,dstname,dest_type);
/* Setup the smb part. */
ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
memcpy(tmp,ptr,4);
- set_message(NULL,ptr,17,strlen(mailslot) + 1 + len,True);
+
+ if (smb_size + 17*2 + strlen(mailslot) + 1 + len > MAX_DGRAM_SIZE) {
+ DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
+ return false;
+ }
+
+ cli_set_message(ptr,17,strlen(mailslot) + 1 + len,True);
memcpy(ptr,tmp,4);
SCVAL(ptr,smb_com,SMBtrans);
p2 = smb_buf(ptr);
safe_strcpy_base(p2, mailslot, dgram->data, sizeof(dgram->data));
p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2);
-
+
if (((p2+len) > dgram->data+sizeof(dgram->data)) || ((p2+len) < p2)) {
DEBUG(0, ("send_mailslot: Cannot write beyond end of packet\n"));
return False;