s3:libsmb/unexpected: pass nmbd_socket_dir from the callers of nb_packet_{server_crea...
[asn/samba-autobuild/.git] / source3 / libsmb / unexpected.c
1 /*
2    Unix SMB/CIFS implementation.
3    handle unexpected packets
4    Copyright (C) Andrew Tridgell 2000
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 #include "includes.h"
22 #include "libsmb/unexpected.h"
23 #include "../lib/util/tevent_ntstatus.h"
24 #include "lib/util_tsock.h"
25 #include "libsmb/nmblib.h"
26 #include "lib/tsocket/tsocket.h"
27 #include "lib/util/sys_rw.h"
28
29 struct nb_packet_query {
30         enum packet_type type;
31         size_t mailslot_namelen;
32         int trn_id;
33 };
34
35 struct nb_packet_client;
36
37 struct nb_packet_server {
38         struct tevent_context *ev;
39         int listen_sock;
40         struct tevent_fd *listen_fde;
41         int max_clients;
42         int num_clients;
43         struct nb_packet_client *clients;
44 };
45
46 struct nb_packet_client {
47         struct nb_packet_client *prev, *next;
48         struct nb_packet_server *server;
49
50         enum packet_type type;
51         int trn_id;
52         char *mailslot_name;
53
54         struct {
55                 uint8_t byte;
56                 struct iovec iov[1];
57         } ack;
58
59         struct tstream_context *sock;
60         struct tevent_queue *out_queue;
61 };
62
63 static int nb_packet_server_destructor(struct nb_packet_server *s);
64 static void nb_packet_server_listener(struct tevent_context *ev,
65                                       struct tevent_fd *fde,
66                                       uint16_t flags,
67                                       void *private_data);
68
69 NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx,
70                                  struct tevent_context *ev,
71                                  const char *nmbd_socket_dir,
72                                  int max_clients,
73                                  struct nb_packet_server **presult)
74 {
75         struct nb_packet_server *result;
76         NTSTATUS status;
77         int rc;
78
79         result = talloc_zero(mem_ctx, struct nb_packet_server);
80         if (result == NULL) {
81                 status = NT_STATUS_NO_MEMORY;
82                 goto fail;
83         }
84         result->ev = ev;
85         result->max_clients = max_clients;
86
87         result->listen_sock = create_pipe_sock(
88                 nmbd_socket_dir, "unexpected", 0755);
89         if (result->listen_sock == -1) {
90                 status = map_nt_error_from_unix(errno);
91                 goto fail;
92         }
93         rc = listen(result->listen_sock, 5);
94         if (rc < 0) {
95                 status = map_nt_error_from_unix(errno);
96                 goto fail;
97         }
98         talloc_set_destructor(result, nb_packet_server_destructor);
99
100         result->listen_fde = tevent_add_fd(ev, result,
101                                            result->listen_sock,
102                                            TEVENT_FD_READ,
103                                            nb_packet_server_listener,
104                                            result);
105         if (result->listen_fde == NULL) {
106                 status = NT_STATUS_NO_MEMORY;
107                 goto fail;
108         }
109
110         *presult = result;
111         return NT_STATUS_OK;
112 fail:
113         TALLOC_FREE(result);
114         return status;
115 }
116
117 static int nb_packet_server_destructor(struct nb_packet_server *s)
118 {
119         TALLOC_FREE(s->listen_fde);
120
121         if (s->listen_sock != -1) {
122                 close(s->listen_sock);
123                 s->listen_sock = -1;
124         }
125         return 0;
126 }
127
128 static int nb_packet_client_destructor(struct nb_packet_client *c);
129 static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
130                                      void *private_data);
131 static void nb_packet_got_query(struct tevent_req *req);
132 static void nb_packet_client_ack_done(struct tevent_req *req);
133 static void nb_packet_client_read_done(struct tevent_req *req);
134
135 static void nb_packet_server_listener(struct tevent_context *ev,
136                                       struct tevent_fd *fde,
137                                       uint16_t flags,
138                                       void *private_data)
139 {
140         struct nb_packet_server *server = talloc_get_type_abort(
141                 private_data, struct nb_packet_server);
142         struct nb_packet_client *client;
143         struct tevent_req *req;
144         struct sockaddr_un sunaddr;
145         socklen_t len;
146         int sock;
147         int ret;
148
149         len = sizeof(sunaddr);
150
151         sock = accept(server->listen_sock, (struct sockaddr *)(void *)&sunaddr,
152                       &len);
153         if (sock == -1) {
154                 return;
155         }
156         smb_set_close_on_exec(sock);
157         DEBUG(6,("accepted socket %d\n", sock));
158
159         client = talloc_zero(server, struct nb_packet_client);
160         if (client == NULL) {
161                 DEBUG(10, ("talloc failed\n"));
162                 close(sock);
163                 return;
164         }
165         ret = tstream_bsd_existing_socket(client, sock, &client->sock);
166         if (ret != 0) {
167                 DEBUG(10, ("tstream_bsd_existing_socket failed\n"));
168                 TALLOC_FREE(client);
169                 close(sock);
170                 return;
171         }
172         /* as server we want to fail early */
173         tstream_bsd_fail_readv_first_error(client->sock, true);
174
175         client->server = server;
176
177         client->out_queue = tevent_queue_create(
178                 client, "unexpected packet output");
179         if (client->out_queue == NULL) {
180                 DEBUG(10, ("tevent_queue_create failed\n"));
181                 TALLOC_FREE(client);
182                 return;
183         }
184
185         req = tstream_read_packet_send(client, ev, client->sock,
186                                        sizeof(struct nb_packet_query),
187                                        nb_packet_client_more, NULL);
188         if (req == NULL) {
189                 DEBUG(10, ("tstream_read_packet_send failed\n"));
190                 TALLOC_FREE(client);
191                 return;
192         }
193         tevent_req_set_callback(req, nb_packet_got_query, client);
194
195         DLIST_ADD(server->clients, client);
196         server->num_clients += 1;
197
198         talloc_set_destructor(client, nb_packet_client_destructor);
199
200         if (server->num_clients > server->max_clients) {
201                 DEBUG(10, ("Too many clients, dropping oldest\n"));
202
203                 /*
204                  * no TALLOC_FREE here, don't mess with the list structs
205                  */
206                 talloc_free(server->clients->prev);
207         }
208 }
209
210 static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
211                                      void *private_data)
212 {
213         struct nb_packet_query q;
214         if (buflen > sizeof(struct nb_packet_query)) {
215                 return 0;
216         }
217         /* Take care of alignment */
218         memcpy(&q, buf, sizeof(q));
219         if (q.mailslot_namelen > 1024) {
220                 DEBUG(10, ("Got invalid mailslot namelen %d\n",
221                            (int)q.mailslot_namelen));
222                 return -1;
223         }
224         return q.mailslot_namelen;
225 }
226
227 static int nb_packet_client_destructor(struct nb_packet_client *c)
228 {
229         tevent_queue_stop(c->out_queue);
230         TALLOC_FREE(c->sock);
231
232         DLIST_REMOVE(c->server->clients, c);
233         c->server->num_clients -= 1;
234         return 0;
235 }
236
237 static void nb_packet_got_query(struct tevent_req *req)
238 {
239         struct nb_packet_client *client = tevent_req_callback_data(
240                 req, struct nb_packet_client);
241         struct nb_packet_query q;
242         uint8_t *buf;
243         ssize_t nread;
244         int err;
245
246         nread = tstream_read_packet_recv(req, client, &buf, &err);
247         TALLOC_FREE(req);
248         if (nread < (ssize_t)sizeof(struct nb_packet_query)) {
249                 DEBUG(10, ("read_packet_recv returned %d (%s)\n",
250                            (int)nread,
251                            (nread == -1) ? strerror(err) : "wrong length"));
252                 TALLOC_FREE(client);
253                 return;
254         }
255
256         /* Take care of alignment */
257         memcpy(&q, buf, sizeof(q));
258
259         if ((size_t)nread !=
260             sizeof(struct nb_packet_query) + q.mailslot_namelen) {
261                 DEBUG(10, ("nb_packet_got_query: Invalid mailslot namelength\n"));
262                 TALLOC_FREE(client);
263                 return;
264         }
265
266         client->trn_id = q.trn_id;
267         client->type = q.type;
268         if (q.mailslot_namelen > 0) {
269                 client->mailslot_name = talloc_strndup(
270                         client, (char *)buf + sizeof(q),
271                         q.mailslot_namelen);
272                 if (client->mailslot_name == NULL) {
273                         TALLOC_FREE(client);
274                         return;
275                 }
276         }
277
278         TALLOC_FREE(buf);
279
280         client->ack.byte = 0;
281         client->ack.iov[0].iov_base = &client->ack.byte;
282         client->ack.iov[0].iov_len = 1;
283         req = tstream_writev_queue_send(client, client->server->ev,
284                                         client->sock,
285                                         client->out_queue,
286                                         client->ack.iov, 1);
287         if (req == NULL) {
288                 DEBUG(10, ("tstream_writev_queue_send failed\n"));
289                 TALLOC_FREE(client);
290                 return;
291         }
292         tevent_req_set_callback(req, nb_packet_client_ack_done, client);
293
294         req = tstream_read_packet_send(client, client->server->ev,
295                                        client->sock, 1, NULL, NULL);
296         if (req == NULL) {
297                 DEBUG(10, ("Could not activate reader for client exit "
298                            "detection\n"));
299                 TALLOC_FREE(client);
300                 return;
301         }
302         tevent_req_set_callback(req, nb_packet_client_read_done,
303                                 client);
304 }
305
306 static void nb_packet_client_ack_done(struct tevent_req *req)
307 {
308         struct nb_packet_client *client = tevent_req_callback_data(
309                 req, struct nb_packet_client);
310         ssize_t nwritten;
311         int err;
312
313         nwritten = tstream_writev_queue_recv(req, &err);
314
315         TALLOC_FREE(req);
316
317         if (nwritten == -1) {
318                 DEBUG(10, ("tstream_writev_queue_recv failed: %s\n",
319                            strerror(err)));
320                 TALLOC_FREE(client);
321                 return;
322         }
323 }
324
325 static void nb_packet_client_read_done(struct tevent_req *req)
326 {
327         struct nb_packet_client *client = tevent_req_callback_data(
328                 req, struct nb_packet_client);
329         ssize_t nread;
330         uint8_t *buf;
331         int err;
332
333         nread = tstream_read_packet_recv(req, client, &buf, &err);
334         TALLOC_FREE(req);
335         if (nread == 1) {
336                 DEBUG(10, ("Protocol error, received data on write-only "
337                            "unexpected socket: 0x%2.2x\n", (*buf)));
338         }
339         TALLOC_FREE(client);
340 }
341
342 static void nb_packet_client_send(struct nb_packet_client *client,
343                                   struct packet_struct *p);
344
345 void nb_packet_dispatch(struct nb_packet_server *server,
346                         struct packet_struct *p)
347 {
348         struct nb_packet_client *c;
349         uint16_t trn_id;
350
351         switch (p->packet_type) {
352         case NMB_PACKET:
353                 trn_id = p->packet.nmb.header.name_trn_id;
354                 break;
355         case DGRAM_PACKET:
356                 trn_id = p->packet.dgram.header.dgm_id;
357                 break;
358         default:
359                 DEBUG(10, ("Got invalid packet type %d\n",
360                            (int)p->packet_type));
361                 return;
362         }
363         for (c = server->clients; c != NULL; c = c->next) {
364
365                 if (c->type != p->packet_type) {
366                         DEBUG(10, ("client expects packet %d, got %d\n",
367                                    c->type, p->packet_type));
368                         continue;
369                 }
370
371                 if (p->packet_type == NMB_PACKET) {
372                         /*
373                          * See if the client specified transaction
374                          * ID. Filter if it did.
375                          */
376                         if ((c->trn_id != -1) &&
377                             (c->trn_id != trn_id)) {
378                                 DEBUG(10, ("client expects trn %d, got %d\n",
379                                            c->trn_id, trn_id));
380                                 continue;
381                         }
382                 } else {
383                         /*
384                          * See if the client specified a mailslot
385                          * name. Filter if it did.
386                          */
387                         if ((c->mailslot_name != NULL) &&
388                             !match_mailslot_name(p, c->mailslot_name)) {
389                                 continue;
390                         }
391                 }
392                 nb_packet_client_send(c, p);
393         }
394 }
395
396 struct nb_packet_client_header {
397         size_t len;
398         enum packet_type type;
399         time_t timestamp;
400         struct in_addr ip;
401         int port;
402 };
403
404 struct nb_packet_client_state {
405         struct nb_packet_client *client;
406         struct iovec iov[2];
407         struct nb_packet_client_header hdr;
408         char buf[1024];
409 };
410
411 static void nb_packet_client_send_done(struct tevent_req *req);
412
413 static void nb_packet_client_send(struct nb_packet_client *client,
414                                   struct packet_struct *p)
415 {
416         struct nb_packet_client_state *state;
417         struct tevent_req *req;
418
419         if (tevent_queue_length(client->out_queue) > 10) {
420                 /*
421                  * Skip clients that don't listen anyway, some form of DoS
422                  * protection
423                  */
424                 return;
425         }
426
427         state = talloc_zero(client, struct nb_packet_client_state);
428         if (state == NULL) {
429                 DEBUG(10, ("talloc failed\n"));
430                 return;
431         }
432
433         state->client = client;
434
435         state->hdr.ip = p->ip;
436         state->hdr.port = p->port;
437         state->hdr.timestamp = p->timestamp;
438         state->hdr.type = p->packet_type;
439         state->hdr.len = build_packet(state->buf, sizeof(state->buf), p);
440
441         state->iov[0].iov_base = (char *)&state->hdr;
442         state->iov[0].iov_len = sizeof(state->hdr);
443         state->iov[1].iov_base = state->buf;
444         state->iov[1].iov_len = state->hdr.len;
445
446         req = tstream_writev_queue_send(state, client->server->ev,
447                                         client->sock,
448                                         client->out_queue,
449                                         state->iov, 2);
450         if (req == NULL) {
451                 DEBUG(10, ("tstream_writev_queue_send failed\n"));
452                 return;
453         }
454         tevent_req_set_callback(req, nb_packet_client_send_done, state);
455 }
456
457 static void nb_packet_client_send_done(struct tevent_req *req)
458 {
459         struct nb_packet_client_state *state = tevent_req_callback_data(
460                 req, struct nb_packet_client_state);
461         struct nb_packet_client *client = state->client;
462         ssize_t nwritten;
463         int err;
464
465         nwritten = tstream_writev_queue_recv(req, &err);
466
467         TALLOC_FREE(req);
468         TALLOC_FREE(state);
469
470         if (nwritten == -1) {
471                 DEBUG(10, ("tstream_writev_queue failed: %s\n", strerror(err)));
472                 TALLOC_FREE(client);
473                 return;
474         }
475 }
476
477 struct nb_packet_reader {
478         struct tstream_context *sock;
479 };
480
481 struct nb_packet_reader_state {
482         struct tevent_context *ev;
483         struct nb_packet_query query;
484         const char *mailslot_name;
485         struct iovec iov[2];
486         struct nb_packet_reader *reader;
487 };
488
489 static void nb_packet_reader_connected(struct tevent_req *subreq);
490 static void nb_packet_reader_sent_query(struct tevent_req *subreq);
491 static void nb_packet_reader_got_ack(struct tevent_req *subreq);
492
493 struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx,
494                                          struct tevent_context *ev,
495                                          const char *nmbd_socket_dir,
496                                          enum packet_type type,
497                                          int trn_id,
498                                          const char *mailslot_name)
499 {
500         struct tevent_req *req, *subreq;
501         struct nb_packet_reader_state *state;
502         struct tsocket_address *laddr;
503         char *rpath;
504         struct tsocket_address *raddr;
505         int ret;
506
507         req = tevent_req_create(mem_ctx, &state,
508                                 struct nb_packet_reader_state);
509         if (req == NULL) {
510                 return NULL;
511         }
512         state->ev = ev;
513         state->query.trn_id = trn_id;
514         state->query.type = type;
515         state->mailslot_name = mailslot_name;
516
517         if (mailslot_name != NULL) {
518                 state->query.mailslot_namelen = strlen(mailslot_name);
519         }
520
521         state->reader = talloc_zero(state, struct nb_packet_reader);
522         if (tevent_req_nomem(state->reader, req)) {
523                 return tevent_req_post(req, ev);
524         }
525
526         ret = tsocket_address_unix_from_path(state, NULL, &laddr);
527         if (ret != 0) {
528                 tevent_req_nterror(req, map_nt_error_from_unix(errno));
529                 return tevent_req_post(req, ev);
530         }
531         rpath = talloc_asprintf(state, "%s/%s", nmbd_socket_dir,
532                                "unexpected");
533         if (tevent_req_nomem(rpath, req)) {
534                 return tevent_req_post(req, ev);
535         }
536         ret = tsocket_address_unix_from_path(state, rpath, &raddr);
537         if (ret != 0) {
538                 tevent_req_nterror(req, map_nt_error_from_unix(errno));
539                 return tevent_req_post(req, ev);
540         }
541
542         subreq = tstream_unix_connect_send(state, ev, laddr, raddr);
543         if (tevent_req_nomem(subreq, req)) {
544                 return tevent_req_post(req, ev);
545         }
546         tevent_req_set_callback(subreq, nb_packet_reader_connected, req);
547         return req;
548 }
549
550 static void nb_packet_reader_connected(struct tevent_req *subreq)
551 {
552         struct tevent_req *req = tevent_req_callback_data(
553                 subreq, struct tevent_req);
554         struct nb_packet_reader_state *state = tevent_req_data(
555                 req, struct nb_packet_reader_state);
556         int res, err;
557         int num_iovecs = 1;
558
559         res = tstream_unix_connect_recv(subreq, &err, state->reader,
560                                         &state->reader->sock);
561         TALLOC_FREE(subreq);
562         if (res == -1) {
563                 DEBUG(10, ("tstream_unix_connect failed: %s\n", strerror(err)));
564                 tevent_req_nterror(req, map_nt_error_from_unix(err));
565                 return;
566         }
567
568         state->iov[0].iov_base = (char *)&state->query;
569         state->iov[0].iov_len = sizeof(state->query);
570
571         if (state->mailslot_name != NULL) {
572                 num_iovecs = 2;
573                 state->iov[1].iov_base = discard_const_p(
574                         char, state->mailslot_name);
575                 state->iov[1].iov_len = state->query.mailslot_namelen;
576         }
577
578         subreq = tstream_writev_send(state, state->ev, state->reader->sock,
579                                      state->iov, num_iovecs);
580         if (tevent_req_nomem(subreq, req)) {
581                 return;
582         }
583         tevent_req_set_callback(subreq, nb_packet_reader_sent_query, req);
584 }
585
586 static void nb_packet_reader_sent_query(struct tevent_req *subreq)
587 {
588         struct tevent_req *req = tevent_req_callback_data(
589                 subreq, struct tevent_req);
590         struct nb_packet_reader_state *state = tevent_req_data(
591                 req, struct nb_packet_reader_state);
592         ssize_t written;
593         int err;
594
595         written = tstream_writev_recv(subreq, &err);
596         TALLOC_FREE(subreq);
597         if (written == -1) {
598                 tevent_req_nterror(req, map_nt_error_from_unix(err));
599                 return;
600         }
601         if ((size_t)written !=
602             sizeof(state->query) + state->query.mailslot_namelen) {
603                 tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR);
604                 return;
605         }
606         subreq = tstream_read_packet_send(state, state->ev,
607                                           state->reader->sock,
608                                           1, NULL, NULL);
609         if (tevent_req_nomem(subreq, req)) {
610                 return;
611         }
612         tevent_req_set_callback(subreq, nb_packet_reader_got_ack, req);
613 }
614
615 static void nb_packet_reader_got_ack(struct tevent_req *subreq)
616 {
617         struct tevent_req *req = tevent_req_callback_data(
618                 subreq, struct tevent_req);
619         struct nb_packet_reader_state *state = tevent_req_data(
620                 req, struct nb_packet_reader_state);
621         ssize_t nread;
622         int err;
623         uint8_t *buf;
624
625         nread = tstream_read_packet_recv(subreq, state, &buf, &err);
626         TALLOC_FREE(subreq);
627         if (nread == -1) {
628                 DEBUG(10, ("read_packet_recv returned %s\n",
629                            strerror(err)));
630                 tevent_req_nterror(req, map_nt_error_from_unix(err));
631                 return;
632         }
633         if (nread != 1) {
634                 DBG_DEBUG("read = %zd, expected 1\n", nread);
635                 tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR);
636                 return;
637         }
638         tevent_req_done(req);
639 }
640
641 NTSTATUS nb_packet_reader_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
642                                struct nb_packet_reader **preader)
643 {
644         struct nb_packet_reader_state *state = tevent_req_data(
645                 req, struct nb_packet_reader_state);
646         NTSTATUS status;
647
648         if (tevent_req_is_nterror(req, &status)) {
649                 tevent_req_received(req);
650                 return status;
651         }
652         *preader = talloc_move(mem_ctx, &state->reader);
653         tevent_req_received(req);
654         return NT_STATUS_OK;
655 }
656
657 struct nb_packet_read_state {
658         struct nb_packet_client_header hdr;
659         uint8_t *buf;
660         size_t buflen;
661 };
662
663 static ssize_t nb_packet_read_more(uint8_t *buf, size_t buflen, void *p);
664 static void nb_packet_read_done(struct tevent_req *subreq);
665
666 struct tevent_req *nb_packet_read_send(TALLOC_CTX *mem_ctx,
667                                        struct tevent_context *ev,
668                                        struct nb_packet_reader *reader)
669 {
670         struct tevent_req *req, *subreq;
671         struct nb_packet_read_state *state;
672
673         req = tevent_req_create(mem_ctx, &state, struct nb_packet_read_state);
674         if (req == NULL) {
675                 return NULL;
676         }
677         subreq = tstream_read_packet_send(state, ev, reader->sock,
678                                           sizeof(struct nb_packet_client_header),
679                                           nb_packet_read_more, state);
680         if (tevent_req_nomem(subreq, req)) {
681                 return tevent_req_post(req, ev);
682         }
683         tevent_req_set_callback(subreq, nb_packet_read_done, req);
684         return req;
685 }
686
687 static ssize_t nb_packet_read_more(uint8_t *buf, size_t buflen, void *p)
688 {
689         struct nb_packet_read_state *state = talloc_get_type_abort(
690                 p, struct nb_packet_read_state);
691
692         if (buflen > sizeof(struct nb_packet_client_header)) {
693                 /*
694                  * Been here, done
695                  */
696                 return 0;
697         }
698         memcpy(&state->hdr, buf, sizeof(struct nb_packet_client_header));
699         return state->hdr.len;
700 }
701
702 static void nb_packet_read_done(struct tevent_req *subreq)
703 {
704         struct tevent_req *req = tevent_req_callback_data(
705                 subreq, struct tevent_req);
706         struct nb_packet_read_state *state = tevent_req_data(
707                 req, struct nb_packet_read_state);
708         ssize_t nread;
709         int err;
710
711         nread = tstream_read_packet_recv(subreq, state, &state->buf, &err);
712         if (nread == -1) {
713                 tevent_req_nterror(req, map_nt_error_from_unix(err));
714                 return;
715         }
716         state->buflen = nread;
717         tevent_req_done(req);
718 }
719
720 NTSTATUS nb_packet_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
721                              struct packet_struct **ppacket)
722 {
723         struct nb_packet_read_state *state = tevent_req_data(
724                 req, struct nb_packet_read_state);
725         struct nb_packet_client_header hdr;
726         struct packet_struct *packet;
727         NTSTATUS status;
728
729         if (tevent_req_is_nterror(req, &status)) {
730                 tevent_req_received(req);
731                 return status;
732         }
733
734         memcpy(&hdr, state->buf, sizeof(hdr));
735
736         packet = parse_packet_talloc(
737                 mem_ctx,
738                 (char *)state->buf + sizeof(struct nb_packet_client_header),
739                 state->buflen - sizeof(struct nb_packet_client_header),
740                 state->hdr.type, state->hdr.ip, state->hdr.port);
741         if (packet == NULL) {
742                 tevent_req_received(req);
743                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
744         }
745
746         *ppacket = packet;
747         tevent_req_received(req);
748         return NT_STATUS_OK;
749 }