summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/libsmb/clidgram.c43
-rw-r--r--source/libsmb/libsmbclient.c4
-rw-r--r--source/libsmb/namequery.c153
3 files changed, 181 insertions, 19 deletions
diff --git a/source/libsmb/clidgram.c b/source/libsmb/clidgram.c
index c58e3fc7967..68ac3b5c455 100644
--- a/source/libsmb/clidgram.c
+++ b/source/libsmb/clidgram.c
@@ -42,6 +42,7 @@ int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len,
struct sockaddr_in sock_out;
char *ptr, *p2;
char tmp[4];
+ int name_size;
bzero((char *)&p, sizeof(p));
@@ -51,8 +52,6 @@ int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len,
if (dgram_sock < 1) {
- int name_size;
-
if ((dgram_sock = open_socket_out(SOCK_DGRAM, &dest_ip, 138, LONG_CONNECT_TIMEOUT)) < 0) {
DEBUG(4, ("open_sock_out failed ..."));
@@ -67,22 +66,35 @@ int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len,
/* Now, bind my addr to it ... */
bzero((char *)&sock_out, sizeof(sock_out));
- putip((char *)&sock_out.sin_addr, (char *)&src_ip);
- sock_out.sin_port = INADDR_ANY;
+ sock_out.sin_addr.s_addr = INADDR_ANY;
+ sock_out.sin_port = htons(138);
sock_out.sin_family = AF_INET;
- bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out));
+ if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) {
+
+ /* Try again on any port ... */
- /* Now, figure out what socket name we were bound to. We want the port */
+ sock_out.sin_port = INADDR_ANY;
- name_size = sizeof(sock_out);
+ if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) {
- getsockname(dgram_sock, (struct sockaddr_in *)&sock_out, &name_size);
+ DEBUG(4, ("failed to bind socket to address ...\n"));
+ return False;
- fprintf(stderr, "Socket bound to IP:%s, port: %d\n", inet_ntoa(sock_out.sin_addr), ntohs(sock_out.sin_port));
+ }
+
+ }
}
+ /* Now, figure out what socket name we were bound to. We want the port */
+
+ name_size = sizeof(sock_out);
+
+ getsockname(dgram_sock, (struct sockaddr_in *)&sock_out, &name_size);
+
+ fprintf(stderr, "Socket bound to IP:%s, port: %d\n", inet_ntoa(sock_out.sin_addr), ntohs(sock_out.sin_port));
+
/*
* Next, build the DGRAM ...
*/
@@ -93,8 +105,10 @@ int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len,
dgram->header.flags.first = True;
dgram->header.flags.more = False;
dgram->header.dgm_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100);
- dgram->header.source_ip = src_ip;
+ dgram->header.source_ip.s_addr = sock_out.sin_addr.s_addr;
+ fprintf(stderr, "Source IP = %0X\n", dgram->header.source_ip);
dgram->header.source_port = ntohs(sock_out.sin_port);
+ fprintf(stderr, "Source Port = %0X\n", dgram->header.source_port);
dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
dgram->header.packet_offset = 0;
@@ -147,7 +161,7 @@ int cli_get_response(BOOL unique, char *mailslot, char *buf, int bufsiz)
{
struct packet_struct *packet;
- packet = read_packet(dgram_sock, DGRAM_PACKET);
+ packet = receive_dgram_packet(dgram_sock, 2, mailslot);
if (packet) { /* We got one, pull what we want out of the SMB data ... */
@@ -166,7 +180,6 @@ int cli_get_response(BOOL unique, char *mailslot, char *buf, int bufsiz)
else
return -1;
- return 0;
}
/*
@@ -187,7 +200,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name)
}
- bzero(&my_ip, 4); /* Cheap way to get 0.0.0.0 in there */
+ my_ip.s_addr = inet_addr("0.0.0.0");
if (!resolve_name(myname, &my_ip, 0x00)) { /* FIXME: Call others here */
@@ -220,7 +233,6 @@ int cli_get_backup_list(const char *myname, const char *send_to_name)
/* Should check the response here ... FIXME */
- return 0;
}
/*
@@ -236,7 +248,4 @@ int cli_get_backup_server(char *my_name, char *target, char *servername, int nam
strncpy(servername, cli_backup_list, MIN(16, namesize));
- /* Should check the response here ... FIXME */
-
- return 0;
}
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index 3541028fb8c..67d5b921000 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -544,8 +544,6 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug)
in_client = True; /* FIXME, make a param */
-
-
if (!lp_load(conf, True, False, False)) {
/*
@@ -563,6 +561,8 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug)
reopen_logs(); /* Get logging working ... */
+ name_register_wins(my_netbios_name, 0);
+
/*
* Now initialize the file descriptor array and figure out what the
* max open files is, so we can return FD's that are above the max
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index 3e4855b0373..f6ada878407 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -190,6 +190,100 @@ BOOL name_status_find(int type, struct in_addr to_ip, char *name)
return True;
}
+/****************************************************************************
+ Do a NetBIOS name registation to try to claim a name ...
+***************************************************************************/
+BOOL name_register(int fd, const char *name, int name_type,
+ struct in_addr name_ip, int opcode,
+ BOOL bcast,
+ struct in_addr to_ip, int *count)
+{
+ int i, retries = 3, retry = bcast?250:2000;
+ struct timeval tval;
+ struct packet_struct p;
+ struct packet_struct *p2;
+ struct nmb_packet *nmb = &p.packet.nmb;
+ struct in_addr register_ip;
+
+ DEBUG(4, ("name_register: %s as %s on %s\n", name, inet_ntoa(name_ip), inet_ntoa(to_ip)));
+
+ register_ip.s_addr = name_ip.s_addr; /* Fix this ... */
+
+ bzero((char *)&p, sizeof(p));
+
+ *count = 0;
+
+ nmb->header.name_trn_id = generate_trn_id();
+ nmb->header.opcode = opcode;
+ nmb->header.response = False;
+ nmb->header.nm_flags.bcast = False;
+ nmb->header.nm_flags.recursion_available = False;
+ nmb->header.nm_flags.recursion_desired = True; /* ? */
+ nmb->header.nm_flags.trunc = False;
+ nmb->header.nm_flags.authoritative = True;
+
+ nmb->header.qdcount = 1;
+ nmb->header.ancount = 0;
+ nmb->header.nscount = 0;
+ nmb->header.arcount = 1;
+
+ make_nmb_name(&nmb->question.question_name, name, name_type);
+
+ nmb->question.question_type = 0x20;
+ nmb->question.question_class = 0x1;
+
+ /* Now, create the additional stuff for a registration request */
+
+ if ((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) {
+
+ DEBUG(0, ("name_register: malloc fail for additional record.\n"));
+ return False;
+
+ }
+
+ bzero((char *)nmb->additional, 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;
+
+ nmb->additional->rdata[0] = NB_MFLAG & 0xFF;
+
+ /* Set the address for the name we are registering. */
+ putip(&nmb->additional->rdata[2], &register_ip);
+
+ p.ip = to_ip;
+ p.port = NMB_PORT;
+ p.fd = fd;
+ p.timestamp = time(NULL);
+ p.packet_type = NMB_PACKET;
+
+ GetTimeOfDay(&tval);
+
+ if (!send_packet(&p))
+ return False;
+
+ retries--;
+
+ if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) {
+ struct nmb_packet *nmb2 = &p2->packet.nmb;
+ debug_nmb_packet(p2);
+
+
+ free(p2); /* No memory leaks ... */
+
+ }
+
+ return True;
+}
/****************************************************************************
Do a netbios name query to find someones IP.
@@ -456,6 +550,65 @@ void endlmhosts(FILE *fp)
fclose(fp);
}
+BOOL name_register_wins(const char *name, int name_type)
+{
+ int sock, i, return_count;
+ int num_interfaces = iface_count();
+ struct in_addr sendto_ip;
+
+ /*
+ * Do a broadcast register ...
+ */
+
+ if (!lp_wins_server())
+ return False;
+
+ DEBUG(4, ("name_register_wins:Registering my name %s on %s\n", name, lp_wins_server()));
+
+ sock = open_socket_in(SOCK_DGRAM, 0, 3,
+ interpret_addr("0.0.0.0"), True);
+
+ if (sock == -1) return False;
+
+ set_socket_options(sock, "SO_BROADCAST");
+
+ sendto_ip.s_addr = inet_addr(lp_wins_server());
+
+ if (num_interfaces > 1) {
+
+ for (i = 0; i < num_interfaces; i++) {
+
+ if (!name_register(sock, name, name_type, *iface_n_ip(i),
+ NMB_NAME_MULTIHOMED_REG_OPCODE,
+ True, sendto_ip, &return_count)) {
+
+ close(sock);
+ return False;
+
+ }
+
+ }
+
+ }
+ else {
+
+ if (!name_register(sock, name, name_type, *iface_n_ip(0),
+ NMB_NAME_REG_OPCODE,
+ True, sendto_ip, &return_count)) {
+
+ close(sock);
+ return False;
+
+ }
+
+ }
+
+ close(sock);
+
+ return True;
+
+}
+
/********************************************************
Resolve via "bcast" method.
*********************************************************/