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