LCOV - code coverage report
Current view: top level - source4/nbt_server - packet.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 147 166 88.6 %
Date: 2024-02-28 12:06:22 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    packet utility functions
       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 "nbt_server/nbt_server.h"
      24             : #include "samba/service_task.h"
      25             : #include "lib/socket/socket.h"
      26             : #include "librpc/gen_ndr/ndr_nbt.h"
      27             : #include "param/param.h"
      28             : 
      29             : /*
      30             :   we received a badly formed packet - log it
      31             : */
      32           0 : void nbtd_bad_packet(struct nbt_name_packet *packet, 
      33             :                      const struct socket_address *src, const char *reason)
      34             : {
      35           0 :         DEBUG(2,("nbtd: bad packet '%s' from %s:%d\n", reason, src->addr, src->port));
      36           0 :         if (DEBUGLVL(5)) {
      37           0 :                 NDR_PRINT_DEBUG(nbt_name_packet, packet);               
      38             :         }
      39           0 : }
      40             : 
      41             : 
      42             : /*
      43             :   see if an incoming packet is a broadcast packet from one of our own
      44             :   interfaces
      45             : */
      46       11713 : bool nbtd_self_packet_and_bcast(struct nbt_name_socket *nbtsock, 
      47             :                                 struct nbt_name_packet *packet, 
      48             :                                 const struct socket_address *src)
      49             : {
      50       11713 :         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
      51             :                                                        struct nbtd_interface);
      52             : 
      53             :         /* if its not a broadcast then its not considered a self packet */
      54       11713 :         if (!(packet->operation & NBT_FLAG_BROADCAST)) {
      55         986 :                 return false;
      56             :         }
      57             : 
      58             :         /* 
      59             :          * this uses the fact that iface->nbtsock is the unicast listen address
      60             :          * if the interface isn't the global bcast interface
      61             :          *
      62             :          * so if the request was directed to the unicast address it isn't a broadcast
      63             :          * message
      64             :          */
      65       10715 :         if (iface->nbtsock == nbtsock &&
      66       10715 :             iface != iface->nbtsrv->bcast_interface) {
      67       10621 :                 return false;
      68             :         }
      69             : 
      70           0 :         return nbtd_self_packet(nbtsock, packet, src);
      71             : }
      72             : 
      73        5507 : bool nbtd_self_packet(struct nbt_name_socket *nbtsock, 
      74             :                       struct nbt_name_packet *packet, 
      75             :                       const struct socket_address *src)
      76             : {
      77        5507 :         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
      78             :                                                        struct nbtd_interface);
      79        5507 :         struct nbtd_server *nbtsrv = iface->nbtsrv;
      80             :         
      81             :         /* if its not from the nbt port, then it wasn't a broadcast from us */
      82        5507 :         if (src->port != lpcfg_nbt_port(iface->nbtsrv->task->lp_ctx)) {
      83         119 :                 return false;
      84             :         }
      85             : 
      86             :         /* we have to loop over our interface list, seeing if its from
      87             :            one of our own interfaces */
      88        9269 :         for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
      89        5388 :                 if (strcmp(src->addr, iface->ip_address) == 0) {
      90        1462 :                         return true;
      91             :                 }
      92             :         }
      93             : 
      94        3860 :         return false;
      95             : }
      96             : 
      97        1075 : struct nbt_name_packet *nbtd_name_query_reply_packet(
      98             :         TALLOC_CTX *mem_ctx,
      99             :         uint16_t trn_id,
     100             :         uint32_t ttl,
     101             :         uint16_t nb_flags,
     102             :         const struct nbt_name *name,
     103             :         const char **addresses,
     104             :         size_t num_addresses)
     105             : {
     106          24 :         struct nbt_name_packet *packet;
     107          24 :         size_t i;
     108          24 :         struct nbt_res_rec *answer;
     109          24 :         struct nbt_rdata_netbios *rdata;
     110          24 :         NTSTATUS status;
     111             : 
     112        1075 :         if (num_addresses == 0) {
     113           0 :                 return NULL;
     114             :         }
     115             : 
     116        1075 :         packet = talloc_zero(mem_ctx, struct nbt_name_packet);
     117        1075 :         if (packet == NULL) {
     118           0 :                 return NULL;
     119             :         }
     120             : 
     121        1075 :         packet->name_trn_id = trn_id;
     122        1075 :         packet->ancount = 1;
     123        1075 :         packet->operation =
     124             :                 NBT_FLAG_REPLY |
     125             :                 NBT_OPCODE_QUERY |
     126             :                 NBT_FLAG_AUTHORITATIVE |
     127             :                 NBT_FLAG_RECURSION_DESIRED |
     128             :                 NBT_FLAG_RECURSION_AVAIL;
     129             : 
     130        1075 :         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
     131        1075 :         if (packet->answers == NULL) {
     132           0 :                 goto failed;
     133             :         }
     134        1075 :         answer = packet->answers;
     135             : 
     136        1075 :         status = nbt_name_dup(packet->answers, name, &answer->name);
     137        1075 :         if (!NT_STATUS_IS_OK(status)) {
     138           0 :                 goto failed;
     139             :         }
     140        1075 :         answer->rr_type  = NBT_QTYPE_NETBIOS;
     141        1075 :         answer->rr_class = NBT_QCLASS_IP;
     142        1075 :         answer->ttl      = ttl;
     143             : 
     144        1075 :         rdata = &answer->rdata.netbios;
     145        1075 :         rdata->length = num_addresses*6;
     146        1075 :         rdata->addresses = talloc_array(
     147             :                 packet->answers,
     148             :                 struct nbt_rdata_address,
     149             :                 num_addresses);
     150        1075 :         if (rdata->addresses == NULL) {
     151           0 :                 goto failed;
     152             :         }
     153             : 
     154        2150 :         for (i=0; i<num_addresses; i++) {
     155        1075 :                 struct nbt_rdata_address *addr = &rdata->addresses[i];
     156        1075 :                 addr->nb_flags = nb_flags;
     157        1075 :                 addr->ipaddr = talloc_strdup(packet->answers, addresses[i]);
     158        1075 :                 if (addr->ipaddr == NULL) {
     159           0 :                         goto failed;
     160             :                 }
     161             :         }
     162             : 
     163        1051 :         return packet;
     164             : 
     165           0 : failed:
     166           0 :         TALLOC_FREE(packet);
     167           0 :         return NULL;
     168             : }
     169             : 
     170             : /*
     171             :   send a name query reply
     172             : */
     173        1075 : void nbtd_name_query_reply(struct nbt_name_socket *nbtsock,
     174             :                            struct nbt_name_packet *request_packet,
     175             :                            struct socket_address *src,
     176             :                            struct nbt_name *name, uint32_t ttl,
     177             :                            uint16_t nb_flags, const char **addresses)
     178             : {
     179          24 :         struct nbt_name_packet *packet;
     180        1075 :         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
     181             :                                                        struct nbtd_interface);
     182        1075 :         struct nbtd_server *nbtsrv = iface->nbtsrv;
     183             : 
     184        1075 :         packet = nbtd_name_query_reply_packet(
     185             :                 nbtsock,
     186        1075 :                 request_packet->name_trn_id,
     187             :                 ttl,
     188             :                 nb_flags,
     189             :                 name,
     190             :                 addresses,
     191             :                 str_list_length(addresses));
     192        1075 :         if (packet == NULL) {
     193           0 :                 return;
     194             :         }
     195             : 
     196        1075 :         DEBUG(7,("Sending name query reply for %s at %s to %s:%d\n", 
     197             :                  nbt_name_string(packet, name), addresses[0], src->addr, src->port));
     198             :         
     199        1075 :         nbtsrv->stats.total_sent++;
     200        1075 :         nbt_name_reply_send(nbtsock, src, packet);
     201             : 
     202        1075 :         talloc_free(packet);
     203             : }
     204             : 
     205             : 
     206             : /*
     207             :   send a negative name query reply
     208             : */
     209          41 : void nbtd_negative_name_query_reply(struct nbt_name_socket *nbtsock, 
     210             :                                     struct nbt_name_packet *request_packet, 
     211             :                                     struct socket_address *src)
     212             : {
     213           0 :         struct nbt_name_packet *packet;
     214          41 :         struct nbt_name *name = &request_packet->questions[0].name;
     215          41 :         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
     216             :                                                        struct nbtd_interface);
     217          41 :         struct nbtd_server *nbtsrv = iface->nbtsrv;
     218             : 
     219          41 :         packet = talloc_zero(nbtsock, struct nbt_name_packet);
     220          41 :         if (packet == NULL) return;
     221             : 
     222          41 :         packet->name_trn_id = request_packet->name_trn_id;
     223          41 :         packet->ancount = 1;
     224          41 :         packet->operation =
     225             :                 NBT_FLAG_REPLY |
     226             :                 NBT_OPCODE_QUERY |
     227             :                 NBT_FLAG_AUTHORITATIVE |
     228             :                 NBT_RCODE_NAM;
     229             : 
     230          41 :         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
     231          41 :         if (packet->answers == NULL) goto failed;
     232             : 
     233          41 :         packet->answers[0].name      = *name;
     234          41 :         packet->answers[0].rr_type   = NBT_QTYPE_NULL;
     235          41 :         packet->answers[0].rr_class  = NBT_QCLASS_IP;
     236          41 :         packet->answers[0].ttl       = 0;
     237          41 :         ZERO_STRUCT(packet->answers[0].rdata);
     238             : 
     239          41 :         DEBUG(7,("Sending negative name query reply for %s to %s:%d\n", 
     240             :                  nbt_name_string(packet, name), src->addr, src->port));
     241             :         
     242          41 :         nbtsrv->stats.total_sent++;
     243          41 :         nbt_name_reply_send(nbtsock, src, packet);
     244             : 
     245          41 : failed:
     246          41 :         talloc_free(packet);
     247             : }
     248             : 
     249             : /*
     250             :   send a name registration reply
     251             : */
     252         247 : void nbtd_name_registration_reply(struct nbt_name_socket *nbtsock, 
     253             :                                   struct nbt_name_packet *request_packet, 
     254             :                                   struct socket_address *src,
     255             :                                   uint8_t rcode)
     256             : {
     257           1 :         struct nbt_name_packet *packet;
     258         247 :         struct nbt_name *name = &request_packet->questions[0].name;
     259         247 :         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
     260             :                                                        struct nbtd_interface);
     261         247 :         struct nbtd_server *nbtsrv = iface->nbtsrv;
     262             : 
     263         247 :         packet = talloc_zero(nbtsock, struct nbt_name_packet);
     264         247 :         if (packet == NULL) return;
     265             : 
     266         247 :         packet->name_trn_id = request_packet->name_trn_id;
     267         247 :         packet->ancount = 1;
     268         247 :         packet->operation =
     269             :                 NBT_FLAG_REPLY |
     270             :                 NBT_OPCODE_REGISTER |
     271             :                 NBT_FLAG_AUTHORITATIVE |
     272             :                 NBT_FLAG_RECURSION_DESIRED |
     273         247 :                 NBT_FLAG_RECURSION_AVAIL |
     274             :                 rcode;
     275             :         
     276         247 :         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
     277         247 :         if (packet->answers == NULL) goto failed;
     278             : 
     279         247 :         packet->answers[0].name     = *name;
     280         247 :         packet->answers[0].rr_type  = NBT_QTYPE_NETBIOS;
     281         247 :         packet->answers[0].rr_class = NBT_QCLASS_IP;
     282         247 :         packet->answers[0].ttl      = request_packet->additional[0].ttl;
     283         247 :         packet->answers[0].rdata    = request_packet->additional[0].rdata;
     284             : 
     285         247 :         DEBUG(7,("Sending %s name registration reply for %s to %s:%d\n", 
     286             :                  rcode==0?"positive":"negative",
     287             :                  nbt_name_string(packet, name), src->addr, src->port));
     288             :         
     289         247 :         nbtsrv->stats.total_sent++;
     290         247 :         nbt_name_reply_send(nbtsock, src, packet);
     291             : 
     292         247 : failed:
     293         247 :         talloc_free(packet);
     294             : }
     295             : 
     296             : 
     297             : /*
     298             :   send a name release reply
     299             : */
     300         210 : void nbtd_name_release_reply(struct nbt_name_socket *nbtsock, 
     301             :                              struct nbt_name_packet *request_packet, 
     302             :                              struct socket_address *src,
     303             :                              uint8_t rcode)
     304             : {
     305           0 :         struct nbt_name_packet *packet;
     306         210 :         struct nbt_name *name = &request_packet->questions[0].name;
     307         210 :         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
     308             :                                                        struct nbtd_interface);
     309         210 :         struct nbtd_server *nbtsrv = iface->nbtsrv;
     310             : 
     311         210 :         packet = talloc_zero(nbtsock, struct nbt_name_packet);
     312         210 :         if (packet == NULL) return;
     313             : 
     314         210 :         packet->name_trn_id = request_packet->name_trn_id;
     315         210 :         packet->ancount = 1;
     316         210 :         packet->operation =
     317             :                 NBT_FLAG_REPLY |
     318             :                 NBT_OPCODE_RELEASE |
     319         210 :                 NBT_FLAG_AUTHORITATIVE |
     320             :                 rcode;
     321             :         
     322         210 :         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
     323         210 :         if (packet->answers == NULL) goto failed;
     324             : 
     325         210 :         packet->answers[0].name     = *name;
     326         210 :         packet->answers[0].rr_type  = NBT_QTYPE_NETBIOS;
     327         210 :         packet->answers[0].rr_class = NBT_QCLASS_IP;
     328         210 :         packet->answers[0].ttl      = request_packet->additional[0].ttl;
     329         210 :         packet->answers[0].rdata    = request_packet->additional[0].rdata;
     330             : 
     331         210 :         DEBUG(7,("Sending %s name release reply for %s to %s:%d\n", 
     332             :                  rcode==0?"positive":"negative",
     333             :                  nbt_name_string(packet, name), src->addr, src->port));
     334             :         
     335         210 :         nbtsrv->stats.total_sent++;
     336         210 :         nbt_name_reply_send(nbtsock, src, packet);
     337             : 
     338         210 : failed:
     339         210 :         talloc_free(packet);
     340             : }
     341             : 
     342             : 
     343             : /*
     344             :   send a WACK reply
     345             : */
     346          18 : void nbtd_wack_reply(struct nbt_name_socket *nbtsock, 
     347             :                      struct nbt_name_packet *request_packet, 
     348             :                      struct socket_address *src,
     349             :                      uint32_t ttl)
     350             : {
     351           0 :         struct nbt_name_packet *packet;
     352          18 :         struct nbt_name *name = &request_packet->questions[0].name;
     353          18 :         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
     354             :                                                        struct nbtd_interface);
     355          18 :         struct nbtd_server *nbtsrv = iface->nbtsrv;
     356             : 
     357          18 :         packet = talloc_zero(nbtsock, struct nbt_name_packet);
     358          18 :         if (packet == NULL) return;
     359             : 
     360          18 :         packet->name_trn_id = request_packet->name_trn_id;
     361          18 :         packet->ancount = 1;
     362          18 :         packet->operation =
     363             :                 NBT_FLAG_REPLY |
     364             :                 NBT_OPCODE_WACK |
     365             :                 NBT_FLAG_AUTHORITATIVE;
     366             :         
     367          18 :         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
     368          18 :         if (packet->answers == NULL) goto failed;
     369             : 
     370          18 :         packet->answers[0].name              = *name;
     371          18 :         packet->answers[0].rr_type           = NBT_QTYPE_WACK;
     372          18 :         packet->answers[0].rr_class          = NBT_QCLASS_IP;
     373          18 :         packet->answers[0].ttl               = ttl;
     374          18 :         packet->answers[0].rdata.data.length = 2;
     375          18 :         packet->answers[0].rdata.data.data   = talloc_array(packet, uint8_t, 2);
     376          18 :         if (packet->answers[0].rdata.data.data == NULL) goto failed;
     377          18 :         RSSVAL(packet->answers[0].rdata.data.data, 0, request_packet->operation);
     378             : 
     379          18 :         DEBUG(7,("Sending WACK reply for %s to %s:%d\n", 
     380             :                  nbt_name_string(packet, name), src->addr, src->port));
     381             :         
     382          18 :         nbtsrv->stats.total_sent++;
     383          18 :         nbt_name_reply_send(nbtsock, src, packet);
     384             : 
     385          18 : failed:
     386          18 :         talloc_free(packet);
     387             : }

Generated by: LCOV version 1.14