root/source4/nbt_server/packet.c

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

DEFINITIONS

This source file includes following definitions.
  1. nbtd_bad_packet
  2. nbtd_self_packet_and_bcast
  3. nbtd_self_packet
  4. nbtd_name_query_reply
  5. nbtd_negative_name_query_reply
  6. nbtd_name_registration_reply
  7. nbtd_name_release_reply
  8. nbtd_wack_reply

   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 "smbd/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 void nbtd_bad_packet(struct nbt_name_packet *packet, 
     /* [<][>][^][v][top][bottom][index][help] */
  33                      const struct socket_address *src, const char *reason)
  34 {
  35         DEBUG(2,("nbtd: bad packet '%s' from %s:%d\n", reason, src->addr, src->port));
  36         if (DEBUGLVL(5)) {
  37                 NDR_PRINT_DEBUG(nbt_name_packet, packet);               
  38         }
  39 }
  40 
  41 
  42 /*
  43   see if an incoming packet is a broadcast packet from one of our own
  44   interfaces
  45 */
  46 bool nbtd_self_packet_and_bcast(struct nbt_name_socket *nbtsock, 
     /* [<][>][^][v][top][bottom][index][help] */
  47                                 struct nbt_name_packet *packet, 
  48                                 const struct socket_address *src)
  49 {
  50         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         if (!(packet->operation & NBT_FLAG_BROADCAST)) {
  55                 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         if (iface->nbtsock == nbtsock &&
  66             iface != iface->nbtsrv->bcast_interface) {
  67                 return false;
  68         }
  69 
  70         return nbtd_self_packet(nbtsock, packet, src);
  71 }
  72 
  73 bool nbtd_self_packet(struct nbt_name_socket *nbtsock, 
     /* [<][>][^][v][top][bottom][index][help] */
  74                       struct nbt_name_packet *packet, 
  75                       const struct socket_address *src)
  76 {
  77         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
  78                                                        struct nbtd_interface);
  79         struct nbtd_server *nbtsrv = iface->nbtsrv;
  80         
  81         /* if its not from the nbt port, then it wasn't a broadcast from us */
  82         if (src->port != lp_nbt_port(iface->nbtsrv->task->lp_ctx)) {
  83                 return false;
  84         }
  85 
  86         /* we have to loop over our interface list, seeing if its from
  87            one of our own interfaces */
  88         for (iface=nbtsrv->interfaces;iface;iface=iface->next) {
  89                 if (strcmp(src->addr, iface->ip_address) == 0) {
  90                         return true;
  91                 }
  92         }
  93 
  94         return false;
  95 }
  96 
  97 
  98 /*
  99   send a name query reply
 100 */
 101 void nbtd_name_query_reply(struct nbt_name_socket *nbtsock, 
     /* [<][>][^][v][top][bottom][index][help] */
 102                            struct nbt_name_packet *request_packet, 
 103                            struct socket_address *src,
 104                            struct nbt_name *name, uint32_t ttl,
 105                            uint16_t nb_flags, const char **addresses)
 106 {
 107         struct nbt_name_packet *packet;
 108         size_t num_addresses = str_list_length(addresses);
 109         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
 110                                                        struct nbtd_interface);
 111         struct nbtd_server *nbtsrv = iface->nbtsrv;
 112         int i;
 113 
 114         if (num_addresses == 0) {
 115                 DEBUG(3,("No addresses in name query reply - failing\n"));
 116                 return;
 117         }
 118 
 119         packet = talloc_zero(nbtsock, struct nbt_name_packet);
 120         if (packet == NULL) return;
 121 
 122         packet->name_trn_id = request_packet->name_trn_id;
 123         packet->ancount = 1;
 124         packet->operation = 
 125                 NBT_FLAG_REPLY | 
 126                 NBT_OPCODE_QUERY | 
 127                 NBT_FLAG_AUTHORITIVE |
 128                 NBT_FLAG_RECURSION_DESIRED |
 129                 NBT_FLAG_RECURSION_AVAIL;
 130 
 131         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
 132         if (packet->answers == NULL) goto failed;
 133 
 134         packet->answers[0].name     = *name;
 135         packet->answers[0].rr_type  = NBT_QTYPE_NETBIOS;
 136         packet->answers[0].rr_class = NBT_QCLASS_IP;
 137         packet->answers[0].ttl      = ttl;
 138         packet->answers[0].rdata.netbios.length = num_addresses*6;
 139         packet->answers[0].rdata.netbios.addresses = 
 140                 talloc_array(packet->answers, struct nbt_rdata_address, num_addresses);
 141         if (packet->answers[0].rdata.netbios.addresses == NULL) goto failed;
 142 
 143         for (i=0;i<num_addresses;i++) {
 144                 struct nbt_rdata_address *addr = 
 145                         &packet->answers[0].rdata.netbios.addresses[i];
 146                 addr->nb_flags = nb_flags;
 147                 addr->ipaddr = talloc_strdup(packet->answers, addresses[i]);
 148                 if (addr->ipaddr == NULL) goto failed;
 149         }
 150 
 151         DEBUG(7,("Sending name query reply for %s at %s to %s:%d\n", 
 152                  nbt_name_string(packet, name), addresses[0], src->addr, src->port));
 153         
 154         nbtsrv->stats.total_sent++;
 155         nbt_name_reply_send(nbtsock, src, packet);
 156 
 157 failed:
 158         talloc_free(packet);
 159 }
 160 
 161 
 162 /*
 163   send a negative name query reply
 164 */
 165 void nbtd_negative_name_query_reply(struct nbt_name_socket *nbtsock, 
     /* [<][>][^][v][top][bottom][index][help] */
 166                                     struct nbt_name_packet *request_packet, 
 167                                     struct socket_address *src)
 168 {
 169         struct nbt_name_packet *packet;
 170         struct nbt_name *name = &request_packet->questions[0].name;
 171         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
 172                                                        struct nbtd_interface);
 173         struct nbtd_server *nbtsrv = iface->nbtsrv;
 174 
 175         packet = talloc_zero(nbtsock, struct nbt_name_packet);
 176         if (packet == NULL) return;
 177 
 178         packet->name_trn_id = request_packet->name_trn_id;
 179         packet->ancount = 1;
 180         packet->operation = 
 181                 NBT_FLAG_REPLY | 
 182                 NBT_OPCODE_QUERY | 
 183                 NBT_FLAG_AUTHORITIVE |
 184                 NBT_RCODE_NAM;
 185 
 186         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
 187         if (packet->answers == NULL) goto failed;
 188 
 189         packet->answers[0].name      = *name;
 190         packet->answers[0].rr_type   = NBT_QTYPE_NULL;
 191         packet->answers[0].rr_class  = NBT_QCLASS_IP;
 192         packet->answers[0].ttl       = 0;
 193         ZERO_STRUCT(packet->answers[0].rdata);
 194 
 195         DEBUG(7,("Sending negative name query reply for %s to %s:%d\n", 
 196                  nbt_name_string(packet, name), src->addr, src->port));
 197         
 198         nbtsrv->stats.total_sent++;
 199         nbt_name_reply_send(nbtsock, src, packet);
 200 
 201 failed:
 202         talloc_free(packet);
 203 }
 204 
 205 /*
 206   send a name registration reply
 207 */
 208 void nbtd_name_registration_reply(struct nbt_name_socket *nbtsock, 
     /* [<][>][^][v][top][bottom][index][help] */
 209                                   struct nbt_name_packet *request_packet, 
 210                                   struct socket_address *src,
 211                                   uint8_t rcode)
 212 {
 213         struct nbt_name_packet *packet;
 214         struct nbt_name *name = &request_packet->questions[0].name;
 215         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
 216                                                        struct nbtd_interface);
 217         struct nbtd_server *nbtsrv = iface->nbtsrv;
 218 
 219         packet = talloc_zero(nbtsock, struct nbt_name_packet);
 220         if (packet == NULL) return;
 221 
 222         packet->name_trn_id = request_packet->name_trn_id;
 223         packet->ancount = 1;
 224         packet->operation = 
 225                 NBT_FLAG_REPLY | 
 226                 NBT_OPCODE_REGISTER |
 227                 NBT_FLAG_AUTHORITIVE |
 228                 NBT_FLAG_RECURSION_DESIRED |
 229                 NBT_FLAG_RECURSION_AVAIL |
 230                 rcode;
 231         
 232         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
 233         if (packet->answers == NULL) goto failed;
 234 
 235         packet->answers[0].name     = *name;
 236         packet->answers[0].rr_type  = NBT_QTYPE_NETBIOS;
 237         packet->answers[0].rr_class = NBT_QCLASS_IP;
 238         packet->answers[0].ttl      = request_packet->additional[0].ttl;
 239         packet->answers[0].rdata    = request_packet->additional[0].rdata;
 240 
 241         DEBUG(7,("Sending %s name registration reply for %s to %s:%d\n", 
 242                  rcode==0?"positive":"negative",
 243                  nbt_name_string(packet, name), src->addr, src->port));
 244         
 245         nbtsrv->stats.total_sent++;
 246         nbt_name_reply_send(nbtsock, src, packet);
 247 
 248 failed:
 249         talloc_free(packet);
 250 }
 251 
 252 
 253 /*
 254   send a name release reply
 255 */
 256 void nbtd_name_release_reply(struct nbt_name_socket *nbtsock, 
     /* [<][>][^][v][top][bottom][index][help] */
 257                              struct nbt_name_packet *request_packet, 
 258                              struct socket_address *src,
 259                              uint8_t rcode)
 260 {
 261         struct nbt_name_packet *packet;
 262         struct nbt_name *name = &request_packet->questions[0].name;
 263         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
 264                                                        struct nbtd_interface);
 265         struct nbtd_server *nbtsrv = iface->nbtsrv;
 266 
 267         packet = talloc_zero(nbtsock, struct nbt_name_packet);
 268         if (packet == NULL) return;
 269 
 270         packet->name_trn_id = request_packet->name_trn_id;
 271         packet->ancount = 1;
 272         packet->operation = 
 273                 NBT_FLAG_REPLY | 
 274                 NBT_OPCODE_RELEASE |
 275                 NBT_FLAG_AUTHORITIVE |
 276                 rcode;
 277         
 278         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
 279         if (packet->answers == NULL) goto failed;
 280 
 281         packet->answers[0].name     = *name;
 282         packet->answers[0].rr_type  = NBT_QTYPE_NETBIOS;
 283         packet->answers[0].rr_class = NBT_QCLASS_IP;
 284         packet->answers[0].ttl      = request_packet->additional[0].ttl;
 285         packet->answers[0].rdata    = request_packet->additional[0].rdata;
 286 
 287         DEBUG(7,("Sending %s name release reply for %s to %s:%d\n", 
 288                  rcode==0?"positive":"negative",
 289                  nbt_name_string(packet, name), src->addr, src->port));
 290         
 291         nbtsrv->stats.total_sent++;
 292         nbt_name_reply_send(nbtsock, src, packet);
 293 
 294 failed:
 295         talloc_free(packet);
 296 }
 297 
 298 
 299 /*
 300   send a WACK reply
 301 */
 302 void nbtd_wack_reply(struct nbt_name_socket *nbtsock, 
     /* [<][>][^][v][top][bottom][index][help] */
 303                      struct nbt_name_packet *request_packet, 
 304                      struct socket_address *src,
 305                      uint32_t ttl)
 306 {
 307         struct nbt_name_packet *packet;
 308         struct nbt_name *name = &request_packet->questions[0].name;
 309         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
 310                                                        struct nbtd_interface);
 311         struct nbtd_server *nbtsrv = iface->nbtsrv;
 312 
 313         packet = talloc_zero(nbtsock, struct nbt_name_packet);
 314         if (packet == NULL) return;
 315 
 316         packet->name_trn_id = request_packet->name_trn_id;
 317         packet->ancount = 1;
 318         packet->operation = 
 319                 NBT_FLAG_REPLY | 
 320                 NBT_OPCODE_WACK |
 321                 NBT_FLAG_AUTHORITIVE;
 322         
 323         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
 324         if (packet->answers == NULL) goto failed;
 325 
 326         packet->answers[0].name              = *name;
 327         packet->answers[0].rr_type           = NBT_QTYPE_NETBIOS;
 328         packet->answers[0].rr_class          = NBT_QCLASS_IP;
 329         packet->answers[0].ttl               = ttl;
 330         packet->answers[0].rdata.data.length = 2;
 331         packet->answers[0].rdata.data.data   = talloc_array(packet, uint8_t, 2);
 332         if (packet->answers[0].rdata.data.data == NULL) goto failed;
 333         RSSVAL(packet->answers[0].rdata.data.data, 0, request_packet->operation);
 334 
 335         DEBUG(7,("Sending WACK reply for %s to %s:%d\n", 
 336                  nbt_name_string(packet, name), src->addr, src->port));
 337         
 338         nbtsrv->stats.total_sent++;
 339         nbt_name_reply_send(nbtsock, src, packet);
 340 
 341 failed:
 342         talloc_free(packet);
 343 }

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