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/>.
23 #include "nbt_server/nbt_server.h"
24 #include "samba/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
));
37 NDR_PRINT_DEBUG(nbt_name_packet
, packet
);
43 see if an incoming packet is a broadcast packet from one of our own
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
)) {
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
65 if (iface
->nbtsock
== nbtsock
&&
66 iface
!= iface
->nbtsrv
->bcast_interface
) {
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
)) {
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) {
97 struct nbt_name_packet
*nbtd_name_query_reply_packet(
102 const struct nbt_name
*name
,
103 const char **addresses
,
104 size_t num_addresses
)
106 struct nbt_name_packet
*packet
;
108 struct nbt_res_rec
*answer
;
109 struct nbt_rdata_netbios
*rdata
;
112 if (num_addresses
== 0) {
116 packet
= talloc_zero(mem_ctx
, struct nbt_name_packet
);
117 if (packet
== NULL
) {
121 packet
->name_trn_id
= trn_id
;
126 NBT_FLAG_AUTHORITATIVE
|
127 NBT_FLAG_RECURSION_DESIRED
|
128 NBT_FLAG_RECURSION_AVAIL
;
130 packet
->answers
= talloc_array(packet
, struct nbt_res_rec
, 1);
131 if (packet
->answers
== NULL
) {
134 answer
= packet
->answers
;
136 status
= nbt_name_dup(packet
->answers
, name
, &answer
->name
);
137 if (!NT_STATUS_IS_OK(status
)) {
140 answer
->rr_type
= NBT_QTYPE_NETBIOS
;
141 answer
->rr_class
= NBT_QCLASS_IP
;
144 rdata
= &answer
->rdata
.netbios
;
145 rdata
->length
= num_addresses
*6;
146 rdata
->addresses
= talloc_array(
148 struct nbt_rdata_address
,
150 if (rdata
->addresses
== NULL
) {
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
) {
171 send a name query reply
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
)
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
;
184 packet
= nbtd_name_query_reply_packet(
186 request_packet
->name_trn_id
,
191 str_list_length(addresses
));
192 if (packet
== NULL
) {
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
));
199 nbtsrv
->stats
.total_sent
++;
200 nbt_name_reply_send(nbtsock
, src
, packet
);
207 send a negative name query reply
209 void nbtd_negative_name_query_reply(struct nbt_name_socket
*nbtsock
,
210 struct nbt_name_packet
*request_packet
,
211 struct socket_address
*src
)
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
;
227 NBT_FLAG_AUTHORITATIVE
|
230 packet
->answers
= talloc_array(packet
, struct nbt_res_rec
, 1);
231 if (packet
->answers
== NULL
) goto failed
;
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
);
239 DEBUG(7,("Sending negative name query reply for %s to %s:%d\n",
240 nbt_name_string(packet
, name
), src
->addr
, src
->port
));
242 nbtsrv
->stats
.total_sent
++;
243 nbt_name_reply_send(nbtsock
, src
, packet
);
250 send a name registration reply
252 void nbtd_name_registration_reply(struct nbt_name_socket
*nbtsock
,
253 struct nbt_name_packet
*request_packet
,
254 struct socket_address
*src
,
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
;
263 packet
= talloc_zero(nbtsock
, struct nbt_name_packet
);
264 if (packet
== NULL
) return;
266 packet
->name_trn_id
= request_packet
->name_trn_id
;
270 NBT_OPCODE_REGISTER
|
271 NBT_FLAG_AUTHORITATIVE
|
272 NBT_FLAG_RECURSION_DESIRED
|
273 NBT_FLAG_RECURSION_AVAIL
|
276 packet
->answers
= talloc_array(packet
, struct nbt_res_rec
, 1);
277 if (packet
->answers
== NULL
) goto failed
;
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
;
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
));
289 nbtsrv
->stats
.total_sent
++;
290 nbt_name_reply_send(nbtsock
, src
, packet
);
298 send a name release reply
300 void nbtd_name_release_reply(struct nbt_name_socket
*nbtsock
,
301 struct nbt_name_packet
*request_packet
,
302 struct socket_address
*src
,
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
;
311 packet
= talloc_zero(nbtsock
, struct nbt_name_packet
);
312 if (packet
== NULL
) return;
314 packet
->name_trn_id
= request_packet
->name_trn_id
;
319 NBT_FLAG_AUTHORITATIVE
|
322 packet
->answers
= talloc_array(packet
, struct nbt_res_rec
, 1);
323 if (packet
->answers
== NULL
) goto failed
;
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
;
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
));
335 nbtsrv
->stats
.total_sent
++;
336 nbt_name_reply_send(nbtsock
, src
, packet
);
346 void nbtd_wack_reply(struct nbt_name_socket
*nbtsock
,
347 struct nbt_name_packet
*request_packet
,
348 struct socket_address
*src
,
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
;
357 packet
= talloc_zero(nbtsock
, struct nbt_name_packet
);
358 if (packet
== NULL
) return;
360 packet
->name_trn_id
= request_packet
->name_trn_id
;
365 NBT_FLAG_AUTHORITATIVE
;
367 packet
->answers
= talloc_array(packet
, struct nbt_res_rec
, 1);
368 if (packet
->answers
== NULL
) goto failed
;
370 packet
->answers
[0].name
= *name
;
371 packet
->answers
[0].rr_type
= NBT_QTYPE_WACK
;
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
);
379 DEBUG(7,("Sending WACK reply for %s to %s:%d\n",
380 nbt_name_string(packet
, name
), src
->addr
, src
->port
));
382 nbtsrv
->stats
.total_sent
++;
383 nbt_name_reply_send(nbtsock
, src
, packet
);