diff options
-rw-r--r-- | source/libsmb/clidgram.c | 43 | ||||
-rw-r--r-- | source/libsmb/libsmbclient.c | 4 | ||||
-rw-r--r-- | source/libsmb/namequery.c | 153 |
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], ®ister_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. *********************************************************/ |