/* setup our listening sockets on the configured network interfaces */ NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_context *lp_ctx, struct interface *ifaces) { int num_interfaces = iface_count(ifaces); int i; TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv); NTSTATUS status; /* if we are allowing incoming packets from any address, then we also need to bind to the wildcard address */ if (!lp_bind_interfaces_only(lp_ctx)) { const char *primary_address; /* the primary address is the address we will return for non-WINS queries not made on a specific interface */ if (num_interfaces > 0) { primary_address = iface_n_ip(ifaces, 0); } else { primary_address = inet_ntoa(interpret_addr2( lp_netbios_name(lp_ctx))); } primary_address = talloc_strdup(tmp_ctx, primary_address); NT_STATUS_HAVE_NO_MEMORY(primary_address); status = nbtd_add_socket(nbtsrv, lp_ctx, "0.0.0.0", primary_address, talloc_strdup(tmp_ctx, "255.255.255.255"), talloc_strdup(tmp_ctx, "0.0.0.0")); NT_STATUS_NOT_OK_RETURN(status); } for (i=0; i<num_interfaces; i++) { const char *bcast = iface_n_bcast(ifaces, i); const char *address, *netmask; /* we can't assume every interface is broadcast capable */ if (bcast == NULL) continue; address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i)); bcast = talloc_strdup(tmp_ctx, bcast); netmask = talloc_strdup(tmp_ctx, iface_n_netmask(ifaces, i)); status = nbtd_add_socket(nbtsrv, lp_ctx, address, address, bcast, netmask); NT_STATUS_NOT_OK_RETURN(status); } if (lp_wins_server_list(lp_ctx)) { status = nbtd_add_wins_socket(nbtsrv); NT_STATUS_NOT_OK_RETURN(status); } talloc_free(tmp_ctx); return NT_STATUS_OK; }
/**************************************************************************** send out one query ****************************************************************************/ static BOOL query_one(char *lookup, unsigned int lookup_type) { int j, count, flags; struct in_addr *ip_list=NULL; if (got_bcast) { printf("querying %s on %s\n", lookup, inet_ntoa(bcast_addr)); ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast, use_bcast?True:recursion_desired, bcast_addr,&count, &flags); } else { struct in_addr *bcast; for (j=iface_count() - 1; !ip_list && j >= 0; j--) { bcast = iface_n_bcast(j); printf("querying %s on %s\n", lookup, inet_ntoa(*bcast)); ip_list = name_query(ServerFD,lookup,lookup_type, use_bcast, use_bcast?True:recursion_desired, *bcast,&count, &flags); } } if (give_flags) printf("Flags: %s\n", query_flags(flags)); if (!ip_list) return False; for (j=0;j<count;j++) { if (translate_addresses) { struct hostent *host = gethostbyaddr((char *)&ip_list[j], sizeof(ip_list[j]), AF_INET); if (host) { printf("%s, ", host -> h_name); } } printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type); } /* We can only do find_status if the ip address returned was valid - ie. name_query returned true. */ if (find_status) { do_node_status(ServerFD, lookup, lookup_type, ip_list[0]); } safe_free(ip_list); return (ip_list != NULL); }
static struct sockaddr_storage *lookup_byname_backend(TALLOC_CTX *mem_ctx, const char *name, int *count) { struct ip_service *ret = NULL; struct sockaddr_storage *return_ss = NULL; int j, i; NTSTATUS status; *count = 0; /* always try with wins first */ if (NT_STATUS_IS_OK(resolve_wins(name,0x20,&ret,count))) { if ( *count == 0 ) return NULL; return_ss = TALLOC_ARRAY(mem_ctx, struct sockaddr_storage, *count); if (return_ss == NULL ) { free( ret ); return NULL; } /* copy the IP addresses */ for ( i=0; i<(*count); i++ ) return_ss[i] = ret[i].ss; free( ret ); return return_ss; } /* uggh, we have to broadcast to each interface in turn */ for (j=iface_count() - 1; j >= 0; j--) { const struct sockaddr_storage *bcast_ss = iface_n_bcast(j); if (!bcast_ss) { continue; } status = name_query(name, 0x20, True, True,bcast_ss, mem_ctx, &return_ss, count, NULL); if (NT_STATUS_IS_OK(status)) { break; } } return return_ss; }
static struct in_addr *lookup_byname_backend(const char *name, int *count) { int fd; struct ip_service *ret = NULL; struct in_addr *return_ip; int j, i, flags = 0; *count = 0; /* always try with wins first */ if (resolve_wins(name,0x20,&ret,count)) { if ( count == 0 ) return NULL; if ( (return_ip = (struct in_addr *)malloc((*count)*sizeof(struct in_addr))) == NULL ) { free( ret ); return NULL; } /* copy the IP addresses */ for ( i=0; i<(*count); i++ ) return_ip[i] = ret[i].ip; free( ret ); return return_ip; } fd = wins_lookup_open_socket_in(); if (fd == -1) { return NULL; } /* uggh, we have to broadcast to each interface in turn */ for (j=iface_count() - 1; j >= 0; j--) { struct in_addr *bcast = iface_n_bcast(j); return_ip = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL); if (return_ip) break; } close(fd); return return_ip; }
static struct in_addr *lookup_byname_backend(const char *name, int *count) { int fd; struct in_addr *ret = NULL; struct in_addr p; int j, flags; *count = 0; fd = wins_lookup_open_socket_in(); if (fd == -1) return NULL; p = wins_srv_ip(); if( !is_zero_ip(p) ) { ret = name_query(fd,name,0x20,False,True, p, count, &flags); goto out; } if (lp_wins_support()) { /* we are our own WINS server */ ret = name_query(fd,name,0x20,False,True, *interpret_addr2("127.0.0.1"), count, &flags); goto out; } /* uggh, we have to broadcast to each interface in turn */ for (j=iface_count() - 1; j >= 0; j--) { struct in_addr *bcast = iface_n_bcast(j); ret = name_query(fd,name,0x20,True,True,*bcast,count, &flags); if (ret) break; } out: close(fd); return ret; }
static bool process_one(struct loadparm_context *lp_ctx, struct tevent_context *ev, struct interface *ifaces, const char *name, int nbt_port) { TALLOC_CTX *tmp_ctx = talloc_new(NULL); enum nbt_name_type node_type = NBT_NAME_CLIENT; char *node_name, *p; struct socket_address *all_zero_addr; struct nbt_name_socket *nbtsock; NTSTATUS status = NT_STATUS_OK; bool ret = true; if (!options.case_sensitive) { name = strupper_talloc(tmp_ctx, name); } if (options.find_master) { node_type = NBT_NAME_MASTER; if (*name == '-' || *name == '_') { name = "\01\02__MSBROWSE__\02"; node_type = NBT_NAME_MS; } } p = strchr(name, '#'); if (p) { node_name = talloc_strndup(tmp_ctx, name, PTR_DIFF(p,name)); node_type = (enum nbt_name_type)strtol(p+1, NULL, 16); } else { node_name = talloc_strdup(tmp_ctx, name); } nbtsock = nbt_name_socket_init(tmp_ctx, ev, lp_iconv_convenience(lp_ctx)); if (options.root_port) { all_zero_addr = socket_address_from_strings(tmp_ctx, nbtsock->sock->backend_name, "0.0.0.0", NBT_NAME_SERVICE_PORT); if (!all_zero_addr) { talloc_free(tmp_ctx); return false; } status = socket_listen(nbtsock->sock, all_zero_addr, 0, 0); if (!NT_STATUS_IS_OK(status)) { printf("Failed to bind to local port 137 - %s\n", nt_errstr(status)); talloc_free(tmp_ctx); return false; } } if (options.lookup_by_ip) { ret = do_node_status(nbtsock, name, nbt_port); talloc_free(tmp_ctx); return ret; } if (options.broadcast_address) { status = do_node_query(nbtsock, options.broadcast_address, nbt_port, node_name, node_type, true); } else if (options.unicast_address) { status = do_node_query(nbtsock, options.unicast_address, nbt_port, node_name, node_type, false); } else { int i, num_interfaces; num_interfaces = iface_count(ifaces); for (i=0;i<num_interfaces;i++) { const char *bcast = iface_n_bcast(ifaces, i); if (bcast == NULL) continue; status = do_node_query(nbtsock, bcast, nbt_port, node_name, node_type, true); if (NT_STATUS_IS_OK(status)) break; } } if (!NT_STATUS_IS_OK(status)) { printf("Lookup failed - %s\n", nt_errstr(status)); ret = false; } talloc_free(tmp_ctx); return ret; }