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