summaryrefslogtreecommitdiff
path: root/source3/nmbd/nmbd_packets.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nmbd/nmbd_packets.c')
-rw-r--r--source3/nmbd/nmbd_packets.c334
1 files changed, 158 insertions, 176 deletions
diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c
index a20ebf16fd..a11b30b1dc 100644
--- a/source3/nmbd/nmbd_packets.c
+++ b/source3/nmbd/nmbd_packets.c
@@ -237,44 +237,40 @@ static BOOL create_and_init_additional_record(struct packet_struct *packet,
uint16 nb_flags,
struct in_addr *register_ip)
{
- struct nmb_packet *nmb = &packet->packet.nmb;
-
- if((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) {
- DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
- return False;
- }
-
- 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;
-
- /* 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;
-
- set_nb_flags(nmb->additional->rdata,nb_flags);
-
- /* Set the address for the name we are registering. */
- putip(&nmb->additional->rdata[2], register_ip);
-
- /*
- it turns out that Jeremys code was correct, we are supposed
- to send registrations from the IP we are registering. The
- trick is what to do on timeouts! When we send on a
- non-routable IP then the reply will timeout, and we should
- treat this as success, not failure. That means we go into
- our standard refresh cycle for that name which copes nicely
- with disconnected networks.
- */
- packet->fd = find_subnet_fd_for_address(*register_ip);
-
- return True;
+ struct nmb_packet *nmb = &packet->packet.nmb;
+
+ if((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL)
+ {
+ DEBUG(0,("initiate_name_register_packet: malloc fail for additional record.\n"));
+ return False;
+ }
+
+ 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;
+
+ /* 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;
+
+ set_nb_flags(nmb->additional->rdata,nb_flags);
+
+ /* Set the address for the name we are registering. */
+ putip(&nmb->additional->rdata[2], register_ip);
+
+ /* Ensure that we send out the file descriptor to give us the
+ the specific source address we are registering as our
+ IP source address. */
+
+ packet->fd = find_subnet_fd_for_address( *register_ip );
+
+ return True;
}
/***************************************************************************
@@ -349,28 +345,28 @@ static BOOL initiate_name_register_packet( struct packet_struct *packet,
Sends out a multihomed name register.
**************************************************************************/
-static BOOL initiate_multihomed_name_register_packet(struct packet_struct *packet,
- uint16 nb_flags, struct in_addr *register_ip)
+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;
- fstring second_ip_buf;
+ struct nmb_packet *nmb = &packet->packet.nmb;
+ fstring second_ip_buf;
+
+ fstrcpy(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;
+
+ nmb->header.nm_flags.recursion_desired = True;
- nmb->header.opcode = NMB_NAME_MULTIHOMED_REG_OPCODE;
- nmb->header.arcount = 1;
+ if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
+ return False;
- nmb->header.nm_flags.recursion_desired = True;
-
- if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
- return False;
-
- DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
+ DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
for name %s IP %s (bcast=%s) to IP %s\n",
- nmb_namestr(&nmb->additional->rr_name), inet_ntoa(*register_ip),
- BOOLSTR(nmb->header.nm_flags.bcast), second_ip_buf ));
+ 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 send_netbios_packet( packet );
}
/***************************************************************************
@@ -514,123 +510,65 @@ struct response_record *queue_register_name( struct subnet_record *subrec,
return rrec;
}
-
/****************************************************************************
- Queue a refresh name packet to the broadcast address of a subnet.
-****************************************************************************/
-void queue_wins_refresh(struct nmb_name *nmbname,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- uint16 nb_flags,
- struct in_addr refresh_ip,
- const char *tag)
-{
- struct packet_struct *p;
- struct response_record *rrec;
- struct in_addr wins_ip;
- struct userdata_struct *userdata;
- fstring ip_str;
-
- wins_ip = wins_srv_ip_tag(tag, refresh_ip);
-
- if ((p = create_and_init_netbios_packet(nmbname, False, False, wins_ip)) == NULL) {
- return;
- }
-
- if (!initiate_name_refresh_packet(p, nb_flags, &refresh_ip)) {
- p->locked = False;
- free_packet(p);
- return;
- }
-
- fstrcpy(ip_str, inet_ntoa(refresh_ip));
-
- DEBUG(6,("Refreshing name %s IP %s with WINS server %s using tag '%s'\n",
- nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
-
- userdata = (struct userdata_struct *)malloc(sizeof(*userdata) + strlen(tag) + 1);
- if (!userdata) {
- DEBUG(0,("Failed to allocate userdata structure!\n"));
- return;
- }
- ZERO_STRUCTP(userdata);
- userdata->userdata_len = strlen(tag) + 1;
- strlcpy(userdata->data, tag, userdata->userdata_len);
-
- if ((rrec = make_response_record(unicast_subnet,
- p,
- resp_fn, timeout_fn,
- NULL,
- NULL,
- userdata)) == NULL) {
- p->locked = False;
- free_packet(p);
- return;
- }
-
- free(userdata);
-
- /* we don't want to repeat refresh packets */
- rrec->repeat_count = 0;
-}
-
-
-/****************************************************************************
- Queue a multihomed register name packet to a given WINS server IP
+ Queue a multihomed register name packet to the broadcast address of a subnet.
****************************************************************************/
struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- register_name_success_function success_fn,
- register_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- uint16 nb_flags,
- struct in_addr register_ip,
- struct in_addr wins_ip)
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ register_name_success_function success_fn,
+ register_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname,
+ uint16 nb_flags,
+ struct in_addr register_ip)
{
- struct packet_struct *p;
- struct response_record *rrec;
- BOOL ret;
-
- /* Sanity check. */
- if(subrec != unicast_subnet) {
- DEBUG(0,("queue_register_multihomed_name: should only be done on \
+ struct packet_struct *p;
+ struct response_record *rrec;
+ BOOL ret;
+
+ /* Sanity check. */
+ if(subrec != unicast_subnet)
+ {
+ DEBUG(0,("queue_register_multihomed_name: should only be done on \
unicast subnet. subnet is %s\n.", subrec->subnet_name ));
- return NULL;
- }
+ return NULL;
+ }
- if(assert_check_subnet(subrec))
- return NULL;
+ if(assert_check_subnet(subrec))
+ return NULL;
- if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
- return NULL;
-
- if (nb_flags & NB_GROUP)
- ret = initiate_name_register_packet( p, nb_flags, &register_ip);
- else
- ret = initiate_multihomed_name_register_packet(p, nb_flags, &register_ip);
-
- if (ret == False) {
- p->locked = False;
- free_packet(p);
- return NULL;
- }
+ if(( p = create_and_init_netbios_packet(nmbname, False, True,
+ subrec->bcast_ip)) == NULL)
+ return NULL;
+
+ if (nb_flags & NB_GROUP)
+ ret = initiate_name_register_packet( p, nb_flags, &register_ip);
+ else
+ ret = initiate_multihomed_name_register_packet( p, nb_flags, &register_ip);
+
+ if(ret == False)
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(subrec, /* 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;
+ }
- if ((rrec = make_response_record(subrec, /* 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;
+ return rrec;
}
/****************************************************************************
@@ -638,15 +576,14 @@ unicast subnet. subnet is %s\n.", subrec->subnet_name ));
****************************************************************************/
struct response_record *queue_release_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- release_name_success_function success_fn,
- release_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- uint16 nb_flags,
- struct in_addr release_ip,
- struct in_addr dest_ip)
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ release_name_success_function success_fn,
+ release_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname,
+ uint16 nb_flags,
+ struct in_addr release_ip)
{
struct packet_struct *p;
struct response_record *rrec;
@@ -655,7 +592,7 @@ struct response_record *queue_release_name( struct subnet_record *subrec,
return NULL;
if ((p = create_and_init_netbios_packet(nmbname, (subrec != unicast_subnet), False,
- dest_ip)) == NULL)
+ subrec->bcast_ip)) == NULL)
return NULL;
if(initiate_name_release_packet( p, nb_flags, &release_ip) == False)
@@ -692,6 +629,52 @@ struct response_record *queue_release_name( struct subnet_record *subrec,
}
/****************************************************************************
+ Queue a refresh name packet to the broadcast address of a subnet.
+****************************************************************************/
+
+struct response_record *queue_refresh_name( struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ refresh_name_success_function success_fn,
+ refresh_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct name_record *namerec,
+ struct in_addr refresh_ip)
+{
+ struct packet_struct *p;
+ struct response_record *rrec;
+
+ if(assert_check_subnet(subrec))
+ return NULL;
+
+ if(( p = create_and_init_netbios_packet(&namerec->name, (subrec != unicast_subnet), False,
+ subrec->bcast_ip)) == NULL)
+ return NULL;
+
+ if( !initiate_name_refresh_packet( p, namerec->data.nb_flags, &refresh_ip ) )
+ {
+ p->locked = False;
+ free_packet(p);
+ return NULL;
+ }
+
+ if((rrec = make_response_record(subrec, /* 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 query name packet to the broadcast address of a subnet.
****************************************************************************/
@@ -1866,9 +1849,8 @@ BOOL listen_for_packets(BOOL run_election)
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 &&
- packet->packet.nmb.header.nm_flags.bcast) {
- DEBUG(7,("discarding own bcast packet from %s:%d\n",
+ ismyip(packet->ip)) && packet->port == global_nmb_port) {
+ DEBUG(7,("discarding own packet from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
free_packet(packet);
} else {
@@ -1894,7 +1876,7 @@ BOOL listen_for_packets(BOOL run_election)
free_packet(packet);
} else if ((ip_equal(loopback_ip, packet->ip) ||
ismyip(packet->ip)) && packet->port == DGRAM_PORT) {
- DEBUG(7,("discarding own dgram packet from %s:%d\n",
+ DEBUG(7,("discarding own packet from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
free_packet(packet);
} else {