summaryrefslogtreecommitdiff
path: root/source3/libsmb/clidgram.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb/clidgram.c')
-rw-r--r--source3/libsmb/clidgram.c135
1 files changed, 73 insertions, 62 deletions
diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c
index 68ac3b5c45..28041e1b76 100644
--- a/source3/libsmb/clidgram.c
+++ b/source3/libsmb/clidgram.c
@@ -29,72 +29,20 @@
* cli_send_mailslot, send a mailslot for client code ...
*/
-static int dgram_sock = -1;
-
-int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len,
+int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot,
+ char *buf, int 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)
+ int dest_port, int src_port)
{
struct packet_struct p;
struct dgram_packet *dgram = &p.packet.dgram;
- struct sockaddr_in sock_out;
char *ptr, *p2;
char tmp[4];
- int name_size;
bzero((char *)&p, sizeof(p));
- /*
- * First, check if we have an open socket to the dest IP
- */
-
- if (dgram_sock < 1) {
-
- if ((dgram_sock = open_socket_out(SOCK_DGRAM, &dest_ip, 138, LONG_CONNECT_TIMEOUT)) < 0) {
-
- DEBUG(4, ("open_sock_out failed ..."));
- return False;
-
- }
-
- /* Make it a broadcast socket ... */
-
- set_socket_options(dgram_sock, "SO_BROADCAST");
-
- /* Now, bind my addr to it ... */
-
- bzero((char *)&sock_out, sizeof(sock_out));
- sock_out.sin_addr.s_addr = INADDR_ANY;
- sock_out.sin_port = htons(138);
- sock_out.sin_family = AF_INET;
-
- if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) {
-
- /* Try again on any port ... */
-
- sock_out.sin_port = INADDR_ANY;
-
- if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) {
-
- DEBUG(4, ("failed to bind socket to address ...\n"));
- return False;
-
- }
-
- }
-
- }
-
- /* 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 ...
*/
@@ -105,9 +53,9 @@ 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.s_addr = sock_out.sin_addr.s_addr;
+ dgram->header.source_ip.s_addr = src_ip.s_addr;
fprintf(stderr, "Source IP = %0X\n", dgram->header.source_ip);
- dgram->header.source_port = ntohs(sock_out.sin_port);
+ dgram->header.source_port = ntohs(src_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;
@@ -157,11 +105,11 @@ int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len,
/*
* cli_get_response: Get a response ...
*/
-int cli_get_response(BOOL unique, char *mailslot, char *buf, int bufsiz)
+int cli_get_response(int dgram_sock, BOOL unique, char *mailslot, char *buf, int bufsiz)
{
struct packet_struct *packet;
- packet = receive_dgram_packet(dgram_sock, 2, mailslot);
+ packet = receive_dgram_packet(dgram_sock, 5, mailslot);
if (packet) { /* We got one, pull what we want out of the SMB data ... */
@@ -193,6 +141,9 @@ int cli_get_backup_list(const char *myname, const char *send_to_name)
char outbuf[15];
char *p;
struct in_addr sendto_ip, my_ip;
+ int dgram_sock;
+ struct sockaddr_in sock_out;
+ int name_size;
if (!resolve_name(send_to_name, &sendto_ip, 0x1d)) {
@@ -208,6 +159,57 @@ int cli_get_backup_list(const char *myname, const char *send_to_name)
}
+ if ((dgram_sock = open_socket_out(SOCK_DGRAM, &sendto_ip, 138, LONG_CONNECT_TIMEOUT)) < 0) {
+
+ DEBUG(4, ("open_sock_out failed ..."));
+ return False;
+
+ }
+
+ /* Make it a broadcast socket ... */
+
+ set_socket_options(dgram_sock, "SO_BROADCAST");
+
+ /* Make it non-blocking??? */
+
+ if (fcntl(dgram_sock, F_SETFL, O_NONBLOCK) < 0) {
+
+ fprintf(stderr, "Unable to set non blocking on dgram sock\n");
+
+ }
+
+ /* Now, bind a local addr to it ... Try port 138 first ... */
+
+ bzero((char *)&sock_out, sizeof(sock_out));
+ sock_out.sin_addr.s_addr = INADDR_ANY;
+ sock_out.sin_port = htons(138);
+ sock_out.sin_family = AF_INET;
+
+ if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) {
+
+ /* Try again on any port ... */
+
+ sock_out.sin_port = INADDR_ANY;
+
+ if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) {
+
+ DEBUG(4, ("failed to bind socket to address ...\n"));
+ return False;
+
+ }
+
+ }
+
+ /* 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));
+
+ /* Now, build the request */
+
bzero(cli_backup_list, sizeof(cli_backup_list));
bzero(outbuf, sizeof(outbuf));
@@ -222,17 +224,20 @@ int cli_get_backup_list(const char *myname, const char *send_to_name)
SIVAL(p, 0, 1); /* The sender's token ... */
p += 4;
- cli_send_mailslot(True, "\\MAILSLOT\\BROWSE", outbuf, PTR_DIFF(p, outbuf),
- myname, 0, send_to_name, 0x1d, sendto_ip, my_ip, 138);
+ cli_send_mailslot(dgram_sock, True, "\\MAILSLOT\\BROWSE", outbuf,
+ PTR_DIFF(p, outbuf), myname, 0, send_to_name,
+ 0x1d, sendto_ip, my_ip, 138, sock_out.sin_port);
/* We should check the error and return if we got one */
/* Now, get the response ... */
- cli_get_response(True, "\\MAILSLOT\\BROWSE", cli_backup_list, sizeof(cli_backup_list));
+ cli_get_response(dgram_sock, True, "\\MAILSLOT\\BROWSE", cli_backup_list, sizeof(cli_backup_list));
/* Should check the response here ... FIXME */
+ close(dgram_sock);
+
}
/*
@@ -246,6 +251,12 @@ int cli_get_backup_server(char *my_name, char *target, char *servername, int nam
cli_get_backup_list(my_name, target); /* FIXME: Check the response */
+ if (!cli_backup_list[0]) { /* Empty list ... try again */
+
+ cli_get_backup_list(my_name, target);
+
+ }
+
strncpy(servername, cli_backup_list, MIN(16, namesize));
}