s3: libsmb: Change cli_getattrE() and async versions to return a 32-bit attribute.
[vlendec/samba-autobuild/.git] / source3 / utils / nmblookup.c
index 5bbd06c99408c65e87312f110c7b813b607f11e6..c74b6497a3544453768c40fc04f4c0c37fe879a7 100644 (file)
@@ -21,6 +21,8 @@
 
 #include "includes.h"
 #include "popt_common.h"
+#include "libsmb/nmblib.h"
+#include "libsmb/namequery.h"
 
 static bool give_flags = false;
 static bool use_bcast = true;
@@ -39,7 +41,7 @@ static bool find_status = false;
 static bool open_sockets(void)
 {
        struct sockaddr_storage ss;
-       const char *sock_addr = lp_socket_address();
+       const char *sock_addr = lp_nbt_client_socket_address();
 
        if (!interpret_string_addr(&ss, sock_addr,
                                AI_NUMERICHOST|AI_PASSIVE)) {
@@ -106,8 +108,7 @@ static char *query_flags(int flags)
  Do a node status query.
 ****************************************************************************/
 
-static void do_node_status(int fd,
-               const char *name,
+static bool do_node_status(const char *name,
                int type,
                struct sockaddr_storage *pss)
 {
@@ -122,7 +123,7 @@ static void do_node_status(int fd,
        print_sockaddr(addr, sizeof(addr), pss);
        d_printf("Looking up status of %s\n",addr);
        make_nmb_name(&nname, name, type);
-       status = node_status_query(fd, &nname, pss, talloc_tos(),
+       status = node_status_query(talloc_tos(), &nname, pss,
                                   &addrs, &count, &extra);
        if (NT_STATUS_IS_OK(status)) {
                for (i=0;i<count;i++) {
@@ -142,8 +143,10 @@ static void do_node_status(int fd,
                                extra.mac_addr[4], extra.mac_addr[5]);
                d_printf("\n");
                TALLOC_FREE(addrs);
+               return true;
        } else {
                d_printf("No reply from %s\n\n",addr);
+               return false;
        }
 }
 
@@ -154,40 +157,26 @@ static void do_node_status(int fd,
 
 static bool query_one(const char *lookup, unsigned int lookup_type)
 {
-       int j, count, flags = 0;
+       int j, count;
+       uint8_t flags;
        struct sockaddr_storage *ip_list=NULL;
+       NTSTATUS status = NT_STATUS_NOT_FOUND;
 
        if (got_bcast) {
                char addr[INET6_ADDRSTRLEN];
                print_sockaddr(addr, sizeof(addr), &bcast_addr);
                d_printf("querying %s on %s\n", lookup, addr);
-               ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast,
-                                    use_bcast?true:recursion_desired,
-                                    &bcast_addr, &count, &flags, NULL);
+               status = name_query(lookup,lookup_type,use_bcast,
+                                   use_bcast?true:recursion_desired,
+                                   &bcast_addr, talloc_tos(),
+                                   &ip_list, &count, &flags);
        } else {
-               const struct in_addr *bcast;
-               for (j=iface_count() - 1;
-                    !ip_list && j >= 0;
-                    j--) {
-                       char addr[INET6_ADDRSTRLEN];
-                       struct sockaddr_storage bcast_ss;
-
-                       bcast = iface_n_bcast_v4(j);
-                       if (!bcast) {
-                               continue;
-                       }
-                       in_addr_to_sockaddr_storage(&bcast_ss, *bcast);
-                       print_sockaddr(addr, sizeof(addr), &bcast_ss);
-                       d_printf("querying %s on %s\n",
-                              lookup, addr);
-                       ip_list = name_query(ServerFD,lookup,lookup_type,
-                                            use_bcast,
-                                            use_bcast?True:recursion_desired,
-                                            &bcast_ss,&count, &flags, NULL);
-               }
+               status = name_resolve_bcast(
+                       lookup, lookup_type,
+                       talloc_tos(), &ip_list, &count);
        }
 
-       if (!ip_list) {
+       if (!NT_STATUS_IS_OK(status)) {
                return false;
        }
 
@@ -215,53 +204,119 @@ static bool query_one(const char *lookup, unsigned int lookup_type)
                   was valid - ie. name_query returned true.
                 */
                if (find_status) {
-                       do_node_status(ServerFD, lookup,
-                                       lookup_type, &ip_list[j]);
+                       if (!do_node_status(lookup, lookup_type, &ip_list[j])) {
+                               status = NT_STATUS_UNSUCCESSFUL;
+                       }
                }
        }
 
-       free(ip_list);
+       TALLOC_FREE(ip_list);
 
-       return (ip_list != NULL);
+       return NT_STATUS_IS_OK(status);
 }
 
 
 /****************************************************************************
   main program
 ****************************************************************************/
-int main(int argc,char *argv[])
+int main(int argc, const char *argv[])
 {
        int opt;
        unsigned int lookup_type = 0x0;
        fstring lookup;
        static bool find_master=False;
        static bool lookup_by_ip = False;
-       poptContext pc;
+       poptContext pc = NULL;
        TALLOC_CTX *frame = talloc_stackframe();
+       int rc = 0;
 
        struct poptOption long_options[] = {
                POPT_AUTOHELP
-               { "broadcast", 'B', POPT_ARG_STRING, NULL, 'B', "Specify address to use for broadcasts", "BROADCAST-ADDRESS" },
-               { "flags", 'f', POPT_ARG_NONE, NULL, 'f', "List the NMB flags returned" },
-               { "unicast", 'U', POPT_ARG_STRING, NULL, 'U', "Specify address to use for unicast" },
-               { "master-browser", 'M', POPT_ARG_NONE, NULL, 'M', "Search for a master browser" },
-               { "recursion", 'R', POPT_ARG_NONE, NULL, 'R', "Set recursion desired in package" },
-               { "status", 'S', POPT_ARG_NONE, NULL, 'S', "Lookup node status as well" },
-               { "translate", 'T', POPT_ARG_NONE, NULL, 'T', "Translate IP addresses into names" },
-               { "root-port", 'r', POPT_ARG_NONE, NULL, 'r', "Use root port 137 (Win95 only replies to this)" },
-               { "lookup-by-ip", 'A', POPT_ARG_NONE, NULL, 'A', "Do a node status on <name> as an IP Address" },
+               {
+                       .longName   = "broadcast",
+                       .shortName  = 'B',
+                       .argInfo    = POPT_ARG_STRING,
+                       .arg        = NULL,
+                       .val        = 'B',
+                       .descrip    = "Specify address to use for broadcasts",
+                       .argDescrip = "BROADCAST-ADDRESS",
+               },
+               {
+                       .longName   = "flags",
+                       .shortName  = 'f',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'f',
+                       .descrip    = "List the NMB flags returned",
+               },
+               {
+                       .longName   = "unicast",
+                       .shortName  = 'U',
+                       .argInfo    = POPT_ARG_STRING,
+                       .arg        = NULL,
+                       .val        = 'U',
+                       .descrip    = "Specify address to use for unicast",
+               },
+               {
+                       .longName   = "master-browser",
+                       .shortName  = 'M',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'M',
+                       .descrip    = "Search for a master browser",
+               },
+               {
+                       .longName   = "recursion",
+                       .shortName  = 'R',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'R',
+                       .descrip    = "Set recursion desired in package",
+               },
+               {
+                       .longName   = "status",
+                       .shortName  = 'S',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'S',
+                       .descrip    = "Lookup node status as well",
+               },
+               {
+                       .longName   = "translate",
+                       .shortName  = 'T',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'T',
+                       .descrip    = "Translate IP addresses into names",
+               },
+               {
+                       .longName   = "root-port",
+                       .shortName  = 'r',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'r',
+                       .descrip    = "Use root port 137 (Win95 only replies to this)",
+               },
+               {
+                       .longName   = "lookup-by-ip",
+                       .shortName  = 'A',
+                       .argInfo    = POPT_ARG_NONE,
+                       .arg        = NULL,
+                       .val        = 'A',
+                       .descrip    = "Do a node status on <name> as an IP Address",
+               },
                POPT_COMMON_SAMBA
                POPT_COMMON_CONNECTION
-               { 0, 0, 0, 0 }
+               POPT_TABLEEND
        };
 
        *lookup = 0;
 
-       load_case_tables();
+       smb_init_locale();
 
        setup_logging(argv[0], DEBUG_STDOUT);
 
-       pc = poptGetContext("nmblookup", argc, (const char **)argv,
+       pc = poptGetContext("nmblookup", argc, argv,
                        long_options, POPT_CONTEXT_KEEP_FIRST);
 
        poptSetOtherOptionHelp(pc, "<NODE> ...");
@@ -312,22 +367,25 @@ int main(int argc,char *argv[])
 
        if(!poptPeekArg(pc)) {
                poptPrintUsage(pc, stderr, 0);
-               exit(1);
+               rc = 1;
+               goto out;
        }
 
-       if (!lp_load(get_dyn_CONFIGFILE(),True,False,False,True)) {
+       if (!lp_load_global(get_dyn_CONFIGFILE())) {
                fprintf(stderr, "Can't load %s - run testparm to debug it\n",
                                get_dyn_CONFIGFILE());
        }
 
        load_interfaces();
        if (!open_sockets()) {
-               return(1);
+               rc = 1;
+               goto out;
        }
 
        while(poptPeekArg(pc)) {
                char *p;
                struct in_addr ip;
+               size_t nbt_len;
 
                fstrcpy(lookup,poptGetArg(pc));
 
@@ -336,7 +394,9 @@ int main(int argc,char *argv[])
                        ip = interpret_addr2(lookup);
                        in_addr_to_sockaddr_storage(&ss, ip);
                        fstrcpy(lookup,"*");
-                       do_node_status(ServerFD, lookup, lookup_type, &ss);
+                       if (!do_node_status(lookup, lookup_type, &ss)) {
+                               rc = 1;
+                       }
                        continue;
                }
 
@@ -355,7 +415,16 @@ int main(int argc,char *argv[])
                        sscanf(++p,"%x",&lookup_type);
                }
 
+               nbt_len = strlen(lookup);
+               if (nbt_len > MAX_NETBIOSNAME_LEN - 1) {
+                       d_printf("The specified netbios name [%s] is too long!\n",
+                                lookup);
+                       continue;
+               }
+
+
                if (!query_one(lookup, lookup_type)) {
+                       rc = 1;
                        d_printf( "name_query failed to find name %s", lookup );
                        if( 0 != lookup_type ) {
                                d_printf( "#%02x", lookup_type );
@@ -364,7 +433,8 @@ int main(int argc,char *argv[])
                }
        }
 
+out:
        poptFreeContext(pc);
        TALLOC_FREE(frame);
-       return(0);
+       return rc;
 }