root/libcli/nbt/namequery.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nbt_name_query_send
  2. nbt_name_query_recv
  3. nbt_name_query
  4. nbt_name_status_send
  5. nbt_name_status_recv
  6. nbt_name_status

   1 /*
   2    Unix SMB/CIFS implementation.
   3 
   4    make nbt name query requests
   5 
   6    Copyright (C) Andrew Tridgell 2005
   7 
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12 
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17 
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 #include "../libcli/nbt/libnbt.h"
  24 #include "../libcli/nbt/nbt_proto.h"
  25 #include "lib/socket/socket.h"
  26 
  27 /**
  28   send a nbt name query
  29 */
  30 _PUBLIC_ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock,
     /* [<][>][^][v][top][bottom][index][help] */
  31                                              struct nbt_name_query *io)
  32 {
  33         struct nbt_name_request *req;
  34         struct nbt_name_packet *packet;
  35         struct socket_address *dest;
  36 
  37         packet = talloc_zero(nbtsock, struct nbt_name_packet);
  38         if (packet == NULL) return NULL;
  39 
  40         packet->qdcount = 1;
  41         packet->operation = NBT_OPCODE_QUERY;
  42         if (io->in.broadcast) {
  43                 packet->operation |= NBT_FLAG_BROADCAST;
  44         }
  45         if (io->in.wins_lookup) {
  46                 packet->operation |= NBT_FLAG_RECURSION_DESIRED;
  47         }
  48 
  49         packet->questions = talloc_array(packet, struct nbt_name_question, 1);
  50         if (packet->questions == NULL) goto failed;
  51 
  52         packet->questions[0].name = io->in.name;
  53         packet->questions[0].question_type = NBT_QTYPE_NETBIOS;
  54         packet->questions[0].question_class = NBT_QCLASS_IP;
  55 
  56         dest = socket_address_from_strings(packet, nbtsock->sock->backend_name,
  57                                            io->in.dest_addr, io->in.dest_port);
  58         if (dest == NULL) goto failed;
  59         req = nbt_name_request_send(nbtsock, dest, packet,
  60                                     io->in.timeout, io->in.retries, false);
  61         if (req == NULL) goto failed;
  62 
  63         talloc_free(packet);
  64         return req;
  65 
  66 failed:
  67         talloc_free(packet);
  68         return NULL;
  69 }
  70 
  71 /**
  72   wait for a name query reply
  73 */
  74 _PUBLIC_ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req,
     /* [<][>][^][v][top][bottom][index][help] */
  75                              TALLOC_CTX *mem_ctx, struct nbt_name_query *io)
  76 {
  77         NTSTATUS status;
  78         struct nbt_name_packet *packet;
  79         int i;
  80 
  81         status = nbt_name_request_recv(req);
  82         if (!NT_STATUS_IS_OK(status) ||
  83             req->num_replies == 0) {
  84                 talloc_free(req);
  85                 return status;
  86         }
  87 
  88         packet = req->replies[0].packet;
  89         io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr);
  90 
  91         if ((packet->operation & NBT_RCODE) != 0) {
  92                 status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE);
  93                 talloc_free(req);
  94                 return status;
  95         }
  96 
  97         if (packet->ancount != 1 ||
  98             packet->answers[0].rr_type != NBT_QTYPE_NETBIOS ||
  99             packet->answers[0].rr_class != NBT_QCLASS_IP) {
 100                 talloc_free(req);
 101                 return status;
 102         }
 103 
 104         io->out.name = packet->answers[0].name;
 105         io->out.num_addrs = packet->answers[0].rdata.netbios.length / 6;
 106         io->out.reply_addrs = talloc_array(mem_ctx, const char *, io->out.num_addrs+1);
 107         if (io->out.reply_addrs == NULL) {
 108                 talloc_free(req);
 109                 return NT_STATUS_NO_MEMORY;
 110         }
 111 
 112         for (i=0;i<io->out.num_addrs;i++) {
 113                 io->out.reply_addrs[i] = talloc_steal(io->out.reply_addrs,
 114                                                       packet->answers[0].rdata.netbios.addresses[i].ipaddr);
 115         }
 116         io->out.reply_addrs[i] = NULL;
 117 
 118         talloc_steal(mem_ctx, io->out.name.name);
 119         talloc_steal(mem_ctx, io->out.name.scope);
 120 
 121         talloc_free(req);
 122 
 123         return NT_STATUS_OK;
 124 }
 125 
 126 /**
 127   wait for a name query reply
 128 */
 129 _PUBLIC_ NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock,
     /* [<][>][^][v][top][bottom][index][help] */
 130                         TALLOC_CTX *mem_ctx, struct nbt_name_query *io)
 131 {
 132         struct nbt_name_request *req = nbt_name_query_send(nbtsock, io);
 133         return nbt_name_query_recv(req, mem_ctx, io);
 134 }
 135 
 136 
 137 /**
 138   send a nbt name status
 139 */
 140 _PUBLIC_ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock,
     /* [<][>][^][v][top][bottom][index][help] */
 141                                               struct nbt_name_status *io)
 142 {
 143         struct nbt_name_request *req;
 144         struct nbt_name_packet *packet;
 145         struct socket_address *dest;
 146 
 147         packet = talloc_zero(nbtsock, struct nbt_name_packet);
 148         if (packet == NULL) return NULL;
 149 
 150         packet->qdcount = 1;
 151         packet->operation = NBT_OPCODE_QUERY;
 152 
 153         packet->questions = talloc_array(packet, struct nbt_name_question, 1);
 154         if (packet->questions == NULL) goto failed;
 155 
 156         packet->questions[0].name = io->in.name;
 157         packet->questions[0].question_type = NBT_QTYPE_STATUS;
 158         packet->questions[0].question_class = NBT_QCLASS_IP;
 159 
 160         dest = socket_address_from_strings(packet, nbtsock->sock->backend_name,
 161                                            io->in.dest_addr, io->in.dest_port);
 162         if (dest == NULL) goto failed;
 163         req = nbt_name_request_send(nbtsock, dest, packet,
 164                                     io->in.timeout, io->in.retries, false);
 165         if (req == NULL) goto failed;
 166 
 167         talloc_free(packet);
 168         return req;
 169 
 170 failed:
 171         talloc_free(packet);
 172         return NULL;
 173 }
 174 
 175 /**
 176   wait for a name status reply
 177 */
 178 _PUBLIC_ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req,
     /* [<][>][^][v][top][bottom][index][help] */
 179                              TALLOC_CTX *mem_ctx, struct nbt_name_status *io)
 180 {
 181         NTSTATUS status;
 182         struct nbt_name_packet *packet;
 183         int i;
 184 
 185         status = nbt_name_request_recv(req);
 186         if (!NT_STATUS_IS_OK(status) ||
 187             req->num_replies == 0) {
 188                 talloc_free(req);
 189                 return status;
 190         }
 191 
 192         packet = req->replies[0].packet;
 193         io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr);
 194 
 195         if ((packet->operation & NBT_RCODE) != 0) {
 196                 status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE);
 197                 talloc_free(req);
 198                 return status;
 199         }
 200 
 201         if (packet->ancount != 1 ||
 202             packet->answers[0].rr_type != NBT_QTYPE_STATUS ||
 203             packet->answers[0].rr_class != NBT_QCLASS_IP) {
 204                 talloc_free(req);
 205                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
 206         }
 207 
 208         io->out.name = packet->answers[0].name;
 209         talloc_steal(mem_ctx, io->out.name.name);
 210         talloc_steal(mem_ctx, io->out.name.scope);
 211 
 212         io->out.status = packet->answers[0].rdata.status;
 213         talloc_steal(mem_ctx, io->out.status.names);
 214         for (i=0;i<io->out.status.num_names;i++) {
 215                 talloc_steal(io->out.status.names, io->out.status.names[i].name);
 216         }
 217 
 218 
 219         talloc_free(req);
 220 
 221         return NT_STATUS_OK;
 222 }
 223 
 224 /**
 225   wait for a name status reply
 226 */
 227 _PUBLIC_ NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock,
     /* [<][>][^][v][top][bottom][index][help] */
 228                         TALLOC_CTX *mem_ctx, struct nbt_name_status *io)
 229 {
 230         struct nbt_name_request *req = nbt_name_status_send(nbtsock, io);
 231         return nbt_name_status_recv(req, mem_ctx, io);
 232 }
 233 
 234 

/* [<][>][^][v][top][bottom][index][help] */