s3:utils: Use C99 initializer for poptOption in sharesec
[vlendec/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 static const char *nmbd_socket_dir(void)
30 {
31         return lp_parm_const_string(-1, "nmbd", "socket dir",
32                                     get_dyn_NMBDSOCKETDIR());
33 }
34
35 struct nb_packet_query {
36         enum packet_type type;
37         size_t mailslot_namelen;
38         int trn_id;
39 };
40
41 struct nb_packet_client;
42
43 struct nb_packet_server {
44         struct tevent_context *ev;
45         int listen_sock;
46         struct tevent_fd *listen_fde;
47         int max_clients;
48         int num_clients;
49         struct nb_packet_client *clients;
50 };
51
52 struct nb_packet_client {
53         struct nb_packet_client *prev, *next;
54         struct nb_packet_server *server;
55
56         enum packet_type type;
57         int trn_id;
58         char *mailslot_name;
59
60         struct {
61                 uint8_t byte;
62                 struct iovec iov[1];
63         } ack;
64
65         struct tstream_context *sock;
66         struct tevent_queue *out_queue;
67 };
68
69 static int nb_packet_server_destructor(struct nb_packet_server *s);
70 static void nb_packet_server_listener(struct tevent_context *ev,
71                                       struct tevent_fd *fde,
72                                       uint16_t flags,
73                                       void *private_data);
74
75 NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx,
76                                  struct tevent_context *ev,
77                                  int max_clients,
78                                  struct nb_packet_server **presult)
79 {
80         struct nb_packet_server *result;
81         NTSTATUS status;
82         int rc;
83
84         result = talloc_zero(mem_ctx, struct nb_packet_server);
85         if (result == NULL) {
86                 status = NT_STATUS_NO_MEMORY;
87                 goto fail;
88         }
89         result->ev = ev;
90         result->max_clients = max_clients;
91
92         result->listen_sock = create_pipe_sock(
93                 nmbd_socket_dir(), "unexpected", 0755);
94         if (result->listen_sock == -1) {
95                 status = map_nt_error_from_unix(errno);
96                 goto fail;
97         }
98         rc = listen(result->listen_sock, 5);
99         if (rc < 0) {
100                 status = map_nt_error_from_unix(errno);
101                 goto fail;
102         }
103         talloc_set_destructor(result, nb_packet_server_destructor);
104
105         result->listen_fde = tevent_add_fd(ev, result,
106                                            result->listen_sock,
107                                            TEVENT_FD_READ,
108                                            nb_packet_server_listener,
109                                            result);
110         if (result->listen_fde == NULL) {
111                 status = NT_STATUS_NO_MEMORY;
112                 goto fail;
113         }
114
115         *presult = result;
116         return NT_STATUS_OK;
117 fail:
118         TALLOC_FREE(result);
119         return status;
120 }
121
122 static int nb_packet_server_destructor(struct nb_packet_server *s)
123 {
124         TALLOC_FREE(s->listen_fde);
125
126         if (s->listen_sock != -1) {
127                 close(s->listen_sock);
128                 s->listen_sock = -1;
129         }
130         return 0;
131 }
132
133 static int nb_packet_client_destructor(struct nb_packet_client *c);
134 static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
135                                      void *private_data);
136 static void nb_packet_got_query(struct tevent_req *req);
137 static void nb_packet_client_ack_done(struct tevent_req *req);
138 static void nb_packet_client_read_done(struct tevent_req *req);
139
140 static void nb_packet_server_listener(struct tevent_context *ev,
141                                       struct tevent_fd *fde,
142                                       uint16_t flags,
143                                       void *private_data)
144 {
145         struct nb_packet_server *server = talloc_get_type_abort(
146                 private_data, struct nb_packet_server);
147         struct nb_packet_client *client;
148         struct tevent_req *req;
149         struct sockaddr_un sunaddr;
150         socklen_t len;
151         int sock;
152         int ret;
153
154         len = sizeof(sunaddr);
155
156         sock = accept(server->listen_sock, (struct sockaddr *)(void *)&sunaddr,
157                       &len);
158         if (sock == -1) {
159                 return;
160         }
161         smb_set_close_on_exec(sock);
162         DEBUG(6,("accepted socket %d\n", sock));
163
164         client = talloc_zero(server, struct nb_packet_client);
165         if (client == NULL) {
166                 DEBUG(10, ("talloc failed\n"));
167                 close(sock);
168                 return;
169         }
170         ret = tstream_bsd_existing_socket(client, sock, &client->sock);
171         if (ret != 0) {
172                 DEBUG(10, ("tstream_bsd_existing_socket failed\n"));
173                 TALLOC_FREE(client);
174                 close(sock);
175                 return;
176         }
177
178         client->server = server;
179
180         client->out_queue = tevent_queue_create(
181                 client, "unexpected packet output");
182         if (client->out_queue == NULL) {
183                 DEBUG(10, ("tevent_queue_create failed\n"));
184                 TALLOC_FREE(client);
185                 return;
186         }
187
188         req = tstream_read_packet_send(client, ev, client->sock,
189                                        sizeof(struct nb_packet_query),
190                                        nb_packet_client_more, NULL);
191         if (req == NULL) {
192                 DEBUG(10, ("tstream_read_packet_send failed\n"));
193                 TALLOC_FREE(client);
194                 return;
195         }
196         tevent_req_set_callback(req, nb_packet_got_query, client);
197
198         DLIST_ADD(server->clients, client);
199         server->num_clients += 1;
200
201         talloc_set_destructor(client, nb_packet_client_destructor);
202
203         if (server->num_clients > server->max_clients) {
204                 DEBUG(10, ("Too many clients, dropping oldest\n"));
205
206                 /*
207                  * no TALLOC_FREE here, don't mess with the list structs
208                  */
209                 talloc_free(server->clients->prev);
210         }
211 }
212
213 static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen,
214                                      void *private_data)
215 {
216         struct nb_packet_query q;
217         if (buflen > sizeof(struct nb_packet_query)) {
218                 return 0;
219         }
220         /* Take care of alignment */
221         memcpy(&q, buf, sizeof(q));
222         if (q.mailslot_namelen > 1024) {
223                 DEBUG(10, ("Got invalid mailslot namelen %d\n",
224                            (int)q.mailslot_namelen));
225                 return -1;
226         }
227         return q.mailslot_namelen;
228 }
229
230 static int nb_packet_client_destructor(struct nb_packet_client *c)
231 {
232         tevent_queue_stop(c->out_queue);
233         TALLOC_FREE(c->sock);
234
235         DLIST_REMOVE(c->server->clients, c);
236         c->server->num_clients -= 1;
237         return 0;
238 }
239
240 static void nb_packet_got_query(struct tevent_req *req)
241 {
242         struct nb_packet_client *client = tevent_req_callback_data(
243                 req, struct nb_packet_client);
244         struct nb_packet_query q;
245         uint8_t *buf;
246         ssize_t nread;
247         int err;
248
249         nread = tstream_read_packet_recv(req, talloc_tos(), &buf, &err);
250         TALLOC_FREE(req);
251         if (nread < (ssize_t)sizeof(struct nb_packet_query)) {
252                 DEBUG(10, ("read_packet_recv returned %d (%s)\n",
253                            (int)nread,
254                            (nread == -1) ? strerror(err) : "wrong length"));
255                 TALLOC_FREE(client);
256                 return;
257         }
258
259         /* Take care of alignment */
260         memcpy(&q, buf, sizeof(q));
261
262         if ((size_t)nread !=
263             sizeof(struct nb_packet_query) + q.mailslot_namelen) {
264                 DEBUG(10, ("nb_packet_got_query: Invalid mailslot namelength\n"));
265                 TALLOC_FREE(client);
266                 return;
267         }
268
269         client->trn_id = q.trn_id;
270         client->type = q.type;
271         if (q.mailslot_namelen > 0) {
272                 client->mailslot_name = talloc_strndup(
273                         client, (char *)buf + sizeof(q),
274                         q.mailslot_namelen);
275                 if (client->mailslot_name == NULL) {
276                         TALLOC_FREE(client);
277                         return;
278                 }
279         }
280
281         client->ack.byte = 0;
282         client->ack.iov[0].iov_base = &client->ack.byte;
283         client->ack.iov[0].iov_len = 1;
284         req = tstream_writev_queue_send(client, client->server->ev,
285                                         client->sock,
286                                         client->out_queue,
287                                         client->ack.iov, 1);
288         if (req == NULL) {
289                 DEBUG(10, ("tstream_writev_queue_send failed\n"));
290                 TALLOC_FREE(client);
291                 return;
292         }
293         tevent_req_set_callback(req, nb_packet_client_ack_done, client);
294
295         req = tstream_read_packet_send(client, client->server->ev,
296                                        client->sock, 1, NULL, NULL);
297         if (req == NULL) {
298                 DEBUG(10, ("Could not activate reader for client exit "
299                            "detection\n"));
300                 TALLOC_FREE(client);
301                 return;
302         }
303         tevent_req_set_callback(req, nb_packet_client_read_done,
304                                 client);
305 }
306
307 static void nb_packet_client_ack_done(struct tevent_req *req)
308 {
309         struct nb_packet_client *client = tevent_req_callback_data(
310                 req, struct nb_packet_client);
311         ssize_t nwritten;
312         int err;
313
314         nwritten = tstream_writev_queue_recv(req, &err);
315
316         TALLOC_FREE(req);
317
318         if (nwritten == -1) {
319                 DEBUG(10, ("tstream_writev_queue_recv failed: %s\n",
320                            strerror(err)));
321                 TALLOC_FREE(client);
322                 return;
323         }
324 }
325
326 static void nb_packet_client_read_done(struct tevent_req *req)
327 {
328         struct nb_packet_client *client = tevent_req_callback_data(
329                 req, struct nb_packet_client);
330         ssize_t nread;
331         uint8_t *buf;
332         int err;
333
334         nread = tstream_read_packet_recv(req, talloc_tos(), &buf, &err);
335         TALLOC_FREE(req);
336         if (nread == 1) {
337                 DEBUG(10, ("Protocol error, received data on write-only "
338                            "unexpected socket: 0x%2.2x\n", (*buf)));
339         }
340         TALLOC_FREE(client);
341 }
342
343 static void nb_packet_client_send(struct nb_packet_client *client,
344                                   struct packet_struct *p);
345
346 void nb_packet_dispatch(struct nb_packet_server *server,
347                         struct packet_struct *p)
348 {
349         struct nb_packet_client *c;
350         uint16_t trn_id;
351
352         switch (p->packet_type) {
353         case NMB_PACKET:
354                 trn_id = p->packet.nmb.header.name_trn_id;
355                 break;
356         case DGRAM_PACKET:
357                 trn_id = p->packet.dgram.header.dgm_id;
358                 break;
359         default:
360                 DEBUG(10, ("Got invalid packet type %d\n",
361                            (int)p->packet_type));
362                 return;
363         }
364         for (c = server->clients; c != NULL; c = c->next) {
365
366                 if (c->type != p->packet_type) {
367                         DEBUG(10, ("client expects packet %d, got %d\n",
368                                    c->type, p->packet_type));
369                         continue;
370                 }
371
372                 if (p->packet_type == NMB_PACKET) {
373                         /*
374                          * See if the client specified transaction
375                          * ID. Filter if it did.
376                          */
377                         if ((c->trn_id != -1) &&
378                             (c->trn_id != trn_id)) {
379                                 DEBUG(10, ("client expects trn %d, got %d\n",
380                                            c->trn_id, trn_id));
381                                 continue;
382                         }
383                 } else {
384                         /*
385                          * See if the client specified a mailslot
386                          * name. Filter if it did.
387                          */
388                         if ((c->mailslot_name != NULL) &&
389                             !match_mailslot_name(p, c->mailslot_name)) {
390                                 continue;
391                         }
392                 }
393                 nb_packet_client_send(c, p);
394         }
395 }
396
397 struct nb_packet_client_header {
398         size_t len;
399         enum packet_type type;
400         time_t timestamp;
401         struct in_addr ip;
402         int port;
403 };
404
405 struct nb_packet_client_state {
406         struct nb_packet_client *client;
407         struct iovec iov[2];
408         struct nb_packet_client_header hdr;
409         char buf[1024];
410 };
411
412 static void nb_packet_client_send_done(struct tevent_req *req);
413
414 static void nb_packet_client_send(struct nb_packet_client *client,
415                                   struct packet_struct *p)
416 {
417         struct nb_packet_client_state *state;
418         struct tevent_req *req;
419
420         if (tevent_queue_length(client->out_queue) > 10) {
421                 /*
422                  * Skip clients that don't listen anyway, some form of DoS
423                  * protection
424                  */
425                 return;
426         }
427
428         state = talloc_zero(client, struct nb_packet_client_state);
429         if (state == NULL) {
430                 DEBUG(10, ("talloc failed\n"));
431                 return;
432         }
433
434         state->client = client;
435
436         state->hdr.ip = p->ip;
437         state->hdr.port = p->port;
438         state->hdr.timestamp = p->timestamp;
439         state->hdr.type = p->packet_type;
440         state->hdr.len = build_packet(state->buf, sizeof(state->buf), p);
441
442         state->iov[0].iov_base = (char *)&state->hdr;
443         state->iov[0].iov_len = sizeof(state->hdr);
444         state->iov[1].iov_base = state->buf;
445         state->iov[1].iov_len = state->hdr.len;
446
447         req = tstream_writev_queue_send(state, client->server->ev,
448                                         client->sock,
449                                         client->out_queue,
450                                         state->iov, 2);
451         if (req == NULL) {
452                 DEBUG(10, ("tstream_writev_queue_send failed\n"));
453                 return;
454         }
455         tevent_req_set_callback(req, nb_packet_client_send_done, state);
456 }
457
458 static void nb_packet_client_send_done(struct tevent_req *req)
459 {
460         struct nb_packet_client_state *state = tevent_req_callback_data(
461                 req, struct nb_packet_client_state);
462         struct nb_packet_client *client = state->client;
463         ssize_t nwritten;
464         int err;
465
466         nwritten = tstream_writev_queue_recv(req, &err);
467
468         TALLOC_FREE(req);
469         TALLOC_FREE(state);
470
471         if (nwritten == -1) {
472                 DEBUG(10, ("tstream_writev_queue failed: %s\n", strerror(err)));
473                 TALLOC_FREE(client);
474                 return;
475         }
476 }
477
478 struct nb_packet_reader {
479         struct tstream_context *sock;
480 };
481
482 struct nb_packet_reader_state {
483         struct tevent_context *ev;
484         struct nb_packet_query query;
485         const char *mailslot_name;
486         struct iovec iov[2];
487         struct nb_packet_reader *reader;
488 };
489
490 static void nb_packet_reader_connected(struct tevent_req *subreq);
491 static void nb_packet_reader_sent_query(struct tevent_req *subreq);
492 static void nb_packet_reader_got_ack(struct tevent_req *subreq);
493
494 struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx,
495                                          struct tevent_context *ev,
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 }