ctdb-tools-ctdb: Update LVS commands to use filter_nodemap_by_capabilities()
[Samba.git] / source4 / nbt_server / packet.c
blob2857f1aa9b49db28561c7af5feae842f625bc3fb
1 /*
2 Unix SMB/CIFS implementation.
4 packet utility functions
6 Copyright (C) Andrew Tridgell 2005
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.
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.
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/>.
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"
30 we received a badly formed packet - log it
32 void nbtd_bad_packet(struct nbt_name_packet *packet,
33 const struct socket_address *src, const char *reason)
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);
43 see if an incoming packet is a broadcast packet from one of our own
44 interfaces
46 bool nbtd_self_packet_and_bcast(struct nbt_name_socket *nbtsock,
47 struct nbt_name_packet *packet,
48 const struct socket_address *src)
50 struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
51 struct nbtd_interface);
53 /* if its not a broadcast then its not considered a self packet */
54 if (!(packet->operation & NBT_FLAG_BROADCAST)) {
55 return false;
58 /*
59 * this uses the fact that iface->nbtsock is the unicast listen address
60 * if the interface isn't the global bcast interface
62 * so if the request was directed to the unicast address it isn't a broadcast
63 * message
65 if (iface->nbtsock == nbtsock &&
66 iface != iface->nbtsrv->bcast_interface) {
67 return false;
70 return nbtd_self_packet(nbtsock, packet, src);
73 bool nbtd_self_packet(struct nbt_name_socket *nbtsock,
74 struct nbt_name_packet *packet,
75 const struct socket_address *src)
77 struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
78 struct nbtd_interface);
79 struct nbtd_server *nbtsrv = iface->nbtsrv;
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;
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;
94 return false;
99 send a name query reply
101 void nbtd_name_query_reply(struct nbt_name_socket *nbtsock,
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)
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;
114 if (num_addresses == 0) {
115 DEBUG(3,("No addresses in name query reply - failing\n"));
116 return;
119 packet = talloc_zero(nbtsock, struct nbt_name_packet);
120 if (packet == NULL) return;
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_AUTHORITATIVE |
128 NBT_FLAG_RECURSION_DESIRED |
129 NBT_FLAG_RECURSION_AVAIL;
131 packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
132 if (packet->answers == NULL) goto failed;
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;
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;
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));
154 nbtsrv->stats.total_sent++;
155 nbt_name_reply_send(nbtsock, src, packet);
157 failed:
158 talloc_free(packet);
163 send a negative name query reply
165 void nbtd_negative_name_query_reply(struct nbt_name_socket *nbtsock,
166 struct nbt_name_packet *request_packet,
167 struct socket_address *src)
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;
175 packet = talloc_zero(nbtsock, struct nbt_name_packet);
176 if (packet == NULL) return;
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_AUTHORITATIVE |
184 NBT_RCODE_NAM;
186 packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
187 if (packet->answers == NULL) goto failed;
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);
195 DEBUG(7,("Sending negative name query reply for %s to %s:%d\n",
196 nbt_name_string(packet, name), src->addr, src->port));
198 nbtsrv->stats.total_sent++;
199 nbt_name_reply_send(nbtsock, src, packet);
201 failed:
202 talloc_free(packet);
206 send a name registration reply
208 void nbtd_name_registration_reply(struct nbt_name_socket *nbtsock,
209 struct nbt_name_packet *request_packet,
210 struct socket_address *src,
211 uint8_t rcode)
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;
219 packet = talloc_zero(nbtsock, struct nbt_name_packet);
220 if (packet == NULL) return;
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_AUTHORITATIVE |
228 NBT_FLAG_RECURSION_DESIRED |
229 NBT_FLAG_RECURSION_AVAIL |
230 rcode;
232 packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
233 if (packet->answers == NULL) goto failed;
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;
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));
245 nbtsrv->stats.total_sent++;
246 nbt_name_reply_send(nbtsock, src, packet);
248 failed:
249 talloc_free(packet);
254 send a name release reply
256 void nbtd_name_release_reply(struct nbt_name_socket *nbtsock,
257 struct nbt_name_packet *request_packet,
258 struct socket_address *src,
259 uint8_t rcode)
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;
267 packet = talloc_zero(nbtsock, struct nbt_name_packet);
268 if (packet == NULL) return;
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_AUTHORITATIVE |
276 rcode;
278 packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
279 if (packet->answers == NULL) goto failed;
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;
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));
291 nbtsrv->stats.total_sent++;
292 nbt_name_reply_send(nbtsock, src, packet);
294 failed:
295 talloc_free(packet);
300 send a WACK reply
302 void nbtd_wack_reply(struct nbt_name_socket *nbtsock,
303 struct nbt_name_packet *request_packet,
304 struct socket_address *src,
305 uint32_t ttl)
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;
313 packet = talloc_zero(nbtsock, struct nbt_name_packet);
314 if (packet == NULL) return;
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_AUTHORITATIVE;
323 packet->answers = talloc_array(packet, struct nbt_res_rec, 1);
324 if (packet->answers == NULL) goto failed;
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);
335 DEBUG(7,("Sending WACK reply for %s to %s:%d\n",
336 nbt_name_string(packet, name), src->addr, src->port));
338 nbtsrv->stats.total_sent++;
339 nbt_name_reply_send(nbtsock, src, packet);
341 failed:
342 talloc_free(packet);