nbt_server: Factor out nbtd_name_query_reply_packet
[garming/samba-autobuild/.git] / source4 / nbt_server / packet.c
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, 
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, 
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, 
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 != lpcfg_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 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         struct nbt_name_packet *packet;
107         size_t i;
108         struct nbt_res_rec *answer;
109         struct nbt_rdata_netbios *rdata;
110         NTSTATUS status;
111
112         if (num_addresses == 0) {
113                 return NULL;
114         }
115
116         packet = talloc_zero(mem_ctx, struct nbt_name_packet);
117         if (packet == NULL) {
118                 return NULL;
119         }
120
121         packet->name_trn_id = trn_id;
122         packet->ancount = 1;
123         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         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
131         if (packet->answers == NULL) {
132                 goto failed;
133         }
134         answer = packet->answers;
135
136         status = nbt_name_dup(packet->answers, name, &answer->name);
137         if (!NT_STATUS_IS_OK(status)) {
138                 goto failed;
139         }
140         answer->rr_type  = NBT_QTYPE_NETBIOS;
141         answer->rr_class = NBT_QCLASS_IP;
142         answer->ttl      = ttl;
143
144         rdata = &answer->rdata.netbios;
145         rdata->length = num_addresses*6;
146         rdata->addresses = talloc_array(
147                 packet->answers,
148                 struct nbt_rdata_address,
149                 num_addresses);
150         if (rdata->addresses == NULL) {
151                 goto failed;
152         }
153
154         for (i=0; i<num_addresses; i++) {
155                 struct nbt_rdata_address *addr = &rdata->addresses[i];
156                 addr->nb_flags = nb_flags;
157                 addr->ipaddr = talloc_strdup(packet->answers, addresses[i]);
158                 if (addr->ipaddr == NULL) {
159                         goto failed;
160                 }
161         }
162
163         return packet;
164
165 failed:
166         TALLOC_FREE(packet);
167         return NULL;
168 }
169
170 /*
171   send a name query reply
172 */
173 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         struct nbt_name_packet *packet;
180         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
181                                                        struct nbtd_interface);
182         struct nbtd_server *nbtsrv = iface->nbtsrv;
183
184         packet = nbtd_name_query_reply_packet(
185                 nbtsock,
186                 request_packet->name_trn_id,
187                 ttl,
188                 nb_flags,
189                 name,
190                 addresses,
191                 str_list_length(addresses));
192         if (packet == NULL) {
193                 return;
194         }
195
196         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         nbtsrv->stats.total_sent++;
200         nbt_name_reply_send(nbtsock, src, packet);
201
202         talloc_free(packet);
203 }
204
205
206 /*
207   send a negative name query reply
208 */
209 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         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_QUERY |
227                 NBT_FLAG_AUTHORITATIVE |
228                 NBT_RCODE_NAM;
229
230         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
231         if (packet->answers == NULL) goto failed;
232
233         packet->answers[0].name      = *name;
234         packet->answers[0].rr_type   = NBT_QTYPE_NULL;
235         packet->answers[0].rr_class  = NBT_QCLASS_IP;
236         packet->answers[0].ttl       = 0;
237         ZERO_STRUCT(packet->answers[0].rdata);
238
239         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         nbtsrv->stats.total_sent++;
243         nbt_name_reply_send(nbtsock, src, packet);
244
245 failed:
246         talloc_free(packet);
247 }
248
249 /*
250   send a name registration reply
251 */
252 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         struct nbt_name_packet *packet;
258         struct nbt_name *name = &request_packet->questions[0].name;
259         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
260                                                        struct nbtd_interface);
261         struct nbtd_server *nbtsrv = iface->nbtsrv;
262
263         packet = talloc_zero(nbtsock, struct nbt_name_packet);
264         if (packet == NULL) return;
265
266         packet->name_trn_id = request_packet->name_trn_id;
267         packet->ancount = 1;
268         packet->operation =
269                 NBT_FLAG_REPLY |
270                 NBT_OPCODE_REGISTER |
271                 NBT_FLAG_AUTHORITATIVE |
272                 NBT_FLAG_RECURSION_DESIRED |
273                 NBT_FLAG_RECURSION_AVAIL |
274                 rcode;
275         
276         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
277         if (packet->answers == NULL) goto failed;
278
279         packet->answers[0].name     = *name;
280         packet->answers[0].rr_type  = NBT_QTYPE_NETBIOS;
281         packet->answers[0].rr_class = NBT_QCLASS_IP;
282         packet->answers[0].ttl      = request_packet->additional[0].ttl;
283         packet->answers[0].rdata    = request_packet->additional[0].rdata;
284
285         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         nbtsrv->stats.total_sent++;
290         nbt_name_reply_send(nbtsock, src, packet);
291
292 failed:
293         talloc_free(packet);
294 }
295
296
297 /*
298   send a name release reply
299 */
300 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         struct nbt_name_packet *packet;
306         struct nbt_name *name = &request_packet->questions[0].name;
307         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
308                                                        struct nbtd_interface);
309         struct nbtd_server *nbtsrv = iface->nbtsrv;
310
311         packet = talloc_zero(nbtsock, struct nbt_name_packet);
312         if (packet == NULL) return;
313
314         packet->name_trn_id = request_packet->name_trn_id;
315         packet->ancount = 1;
316         packet->operation =
317                 NBT_FLAG_REPLY |
318                 NBT_OPCODE_RELEASE |
319                 NBT_FLAG_AUTHORITATIVE |
320                 rcode;
321         
322         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
323         if (packet->answers == NULL) goto failed;
324
325         packet->answers[0].name     = *name;
326         packet->answers[0].rr_type  = NBT_QTYPE_NETBIOS;
327         packet->answers[0].rr_class = NBT_QCLASS_IP;
328         packet->answers[0].ttl      = request_packet->additional[0].ttl;
329         packet->answers[0].rdata    = request_packet->additional[0].rdata;
330
331         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         nbtsrv->stats.total_sent++;
336         nbt_name_reply_send(nbtsock, src, packet);
337
338 failed:
339         talloc_free(packet);
340 }
341
342
343 /*
344   send a WACK reply
345 */
346 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         struct nbt_name_packet *packet;
352         struct nbt_name *name = &request_packet->questions[0].name;
353         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
354                                                        struct nbtd_interface);
355         struct nbtd_server *nbtsrv = iface->nbtsrv;
356
357         packet = talloc_zero(nbtsock, struct nbt_name_packet);
358         if (packet == NULL) return;
359
360         packet->name_trn_id = request_packet->name_trn_id;
361         packet->ancount = 1;
362         packet->operation =
363                 NBT_FLAG_REPLY |
364                 NBT_OPCODE_WACK |
365                 NBT_FLAG_AUTHORITATIVE;
366         
367         packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
368         if (packet->answers == NULL) goto failed;
369
370         packet->answers[0].name              = *name;
371         packet->answers[0].rr_type           = NBT_QTYPE_NETBIOS;
372         packet->answers[0].rr_class          = NBT_QCLASS_IP;
373         packet->answers[0].ttl               = ttl;
374         packet->answers[0].rdata.data.length = 2;
375         packet->answers[0].rdata.data.data   = talloc_array(packet, uint8_t, 2);
376         if (packet->answers[0].rdata.data.data == NULL) goto failed;
377         RSSVAL(packet->answers[0].rdata.data.data, 0, request_packet->operation);
378
379         DEBUG(7,("Sending WACK reply for %s to %s:%d\n", 
380                  nbt_name_string(packet, name), src->addr, src->port));
381         
382         nbtsrv->stats.total_sent++;
383         nbt_name_reply_send(nbtsock, src, packet);
384
385 failed:
386         talloc_free(packet);
387 }