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