LCOV - code coverage report
Current view: top level - libcli/nbt - namerelease.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 53 66 80.3 %
Date: 2024-04-21 15:09:00 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    send out a name release request
       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 release request
      29             : */
      30         220 : _PUBLIC_ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock,
      31             :                                                struct nbt_name_release *io)
      32             : {
      33           0 :         struct nbt_name_request *req;
      34           0 :         struct nbt_name_packet *packet;
      35           0 :         struct socket_address *dest;
      36             : 
      37         220 :         packet = talloc_zero(nbtsock, struct nbt_name_packet);
      38         220 :         if (packet == NULL) return NULL;
      39             : 
      40         220 :         packet->qdcount = 1;
      41         220 :         packet->arcount = 1;
      42         220 :         packet->operation = NBT_OPCODE_RELEASE;
      43         220 :         if (io->in.broadcast) {
      44           0 :                 packet->operation |= NBT_FLAG_BROADCAST;
      45             :         }
      46             : 
      47         220 :         packet->questions = talloc_array(packet, struct nbt_name_question, 1);
      48         220 :         if (packet->questions == NULL) goto failed;
      49             : 
      50         220 :         packet->questions[0].name           = io->in.name;
      51         220 :         packet->questions[0].question_type  = NBT_QTYPE_NETBIOS;
      52         220 :         packet->questions[0].question_class = NBT_QCLASS_IP;
      53             : 
      54         220 :         packet->additional = talloc_array(packet, struct nbt_res_rec, 1);
      55         220 :         if (packet->additional == NULL) goto failed;
      56             : 
      57         220 :         packet->additional[0].name                   = io->in.name;
      58         220 :         packet->additional[0].rr_type                = NBT_QTYPE_NETBIOS;
      59         220 :         packet->additional[0].rr_class               = NBT_QCLASS_IP;
      60         220 :         packet->additional[0].ttl                    = 0;
      61         220 :         packet->additional[0].rdata.netbios.length   = 6;
      62         220 :         packet->additional[0].rdata.netbios.addresses = talloc_array(packet->additional,
      63             :                                                                      struct nbt_rdata_address, 1);
      64         220 :         if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed;
      65         220 :         packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags;
      66         440 :         packet->additional[0].rdata.netbios.addresses[0].ipaddr =
      67         220 :                 talloc_strdup(packet->additional, io->in.address);
      68             : 
      69         220 :         dest = socket_address_from_strings(packet, nbtsock->sock->backend_name,
      70         220 :                                            io->in.dest_addr, io->in.dest_port);
      71         220 :         if (dest == NULL) goto failed;
      72         220 :         req = nbt_name_request_send(nbtsock, nbtsock, dest, packet,
      73             :                                     io->in.timeout, io->in.retries, false);
      74         220 :         if (req == NULL) goto failed;
      75             : 
      76         220 :         talloc_free(packet);
      77         220 :         return req;
      78             : 
      79           0 : failed:
      80           0 :         talloc_free(packet);
      81           0 :         return NULL;
      82             : }
      83             : 
      84             : /*
      85             :   wait for a release reply
      86             : */
      87         220 : _PUBLIC_ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req,
      88             :                                TALLOC_CTX *mem_ctx, struct nbt_name_release *io)
      89             : {
      90           0 :         NTSTATUS status;
      91           0 :         struct nbt_name_packet *packet;
      92             : 
      93         220 :         status = nbt_name_request_recv(req);
      94         220 :         if (!NT_STATUS_IS_OK(status) ||
      95         219 :             req->num_replies == 0) {
      96           1 :                 talloc_free(req);
      97           1 :                 return status;
      98             :         }
      99             : 
     100         219 :         packet = req->replies[0].packet;
     101         219 :         io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr);
     102             : 
     103         219 :         if (packet->ancount != 1 ||
     104         219 :             packet->answers[0].rr_type != NBT_QTYPE_NETBIOS ||
     105         219 :             packet->answers[0].rr_class != NBT_QCLASS_IP) {
     106           0 :                 talloc_free(req);
     107           0 :                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
     108             :         }
     109             : 
     110         219 :         io->out.rcode = packet->operation & NBT_RCODE;
     111         219 :         io->out.name = packet->answers[0].name;
     112         219 :         if (packet->answers[0].rdata.netbios.length < 6) {
     113           0 :                 talloc_free(req);
     114           0 :                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
     115             :         }
     116         219 :         io->out.reply_addr = talloc_steal(mem_ctx,
     117             :                                           packet->answers[0].rdata.netbios.addresses[0].ipaddr);
     118         219 :         talloc_steal(mem_ctx, io->out.name.name);
     119         219 :         talloc_steal(mem_ctx, io->out.name.scope);
     120             : 
     121         219 :         talloc_free(req);
     122             : 
     123         219 :         return NT_STATUS_OK;
     124             : }
     125             : 
     126             : /*
     127             :   synchronous name release request
     128             : */
     129         210 : _PUBLIC_ NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock,
     130             :                            TALLOC_CTX *mem_ctx, struct nbt_name_release *io)
     131             : {
     132         210 :         struct nbt_name_request *req = nbt_name_release_send(nbtsock, io);
     133         210 :         return nbt_name_release_recv(req, mem_ctx, io);
     134             : }

Generated by: LCOV version 1.14