kernel: Don't include <sys/mutex.h> in some drivers that don't need it.
[dragonfly.git] / sys / net / libalias / alias_nbt.c
blobbe49e05089ae3b535f8d60e1339f80a5f03080f7
1 /*-
2 * Written by Atsushi Murai <amurai@spec.co.jp>
3 * Copyright (c) 1998, System Planning and Engineering Co.
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 * TODO:
27 * oClean up.
28 * oConsidering for word alignment for other platform.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD: src/sys/netinet/libalias/alias_nbt.c,v 1.20.6.1 2008/11/25 02:59:29 kensmith Exp $");
35 alias_nbt.c performs special processing for NetBios over TCP/IP
36 sessions by UDP.
38 Initial version: May, 1998 (Atsushi Murai <amurai@spec.co.jp>)
40 See HISTORY file for record of revisions.
43 /* Includes */
44 #ifdef _KERNEL
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/module.h>
49 #else
50 #include <errno.h>
51 #include <sys/types.h>
52 #include <stdio.h>
53 #endif
55 #include <netinet/in_systm.h>
56 #include <netinet/in.h>
57 #include <netinet/ip.h>
58 #include <netinet/udp.h>
60 #ifdef _KERNEL
61 #include <netinet/libalias/alias_local.h>
62 #include <netinet/libalias/alias_mod.h>
63 #else
64 #include "alias_local.h"
65 #include "alias_mod.h"
66 #endif
68 #define NETBIOS_NS_PORT_NUMBER 137
69 #define NETBIOS_DGM_PORT_NUMBER 138
71 static int
72 AliasHandleUdpNbt(struct libalias *, struct ip *, struct alias_link *,
73 struct in_addr *, u_short);
75 static int
76 AliasHandleUdpNbtNS(struct libalias *, struct ip *, struct alias_link *,
77 struct in_addr *, u_short *, struct in_addr *, u_short *);
78 static int
79 fingerprint1(struct libalias *la, struct ip *pip, struct alias_data *ah)
82 if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
83 ah->aaddr == NULL || ah->aport == NULL)
84 return (-1);
85 if (ntohs(*ah->dport) == NETBIOS_DGM_PORT_NUMBER
86 || ntohs(*ah->sport) == NETBIOS_DGM_PORT_NUMBER)
87 return (0);
88 return (-1);
91 static int
92 protohandler1(struct libalias *la, struct ip *pip, struct alias_data *ah)
95 AliasHandleUdpNbt(la, pip, ah->lnk, ah->aaddr, *ah->aport);
96 return (0);
99 static int
100 fingerprint2(struct libalias *la, struct ip *pip, struct alias_data *ah)
103 if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL ||
104 ah->aaddr == NULL || ah->aport == NULL)
105 return (-1);
106 if (ntohs(*ah->dport) == NETBIOS_NS_PORT_NUMBER
107 || ntohs(*ah->sport) == NETBIOS_NS_PORT_NUMBER)
108 return (0);
109 return (-1);
112 static int
113 protohandler2in(struct libalias *la, struct ip *pip, struct alias_data *ah)
116 AliasHandleUdpNbtNS(la, pip, ah->lnk, ah->aaddr, ah->aport,
117 ah->oaddr, ah->dport);
118 return (0);
121 static int
122 protohandler2out(struct libalias *la, struct ip *pip, struct alias_data *ah)
125 AliasHandleUdpNbtNS(la, pip, ah->lnk, &pip->ip_src, ah->sport,
126 ah->aaddr, ah->aport);
127 return (0);
130 /* Kernel module definition. */
131 struct proto_handler handlers[] = {
133 .pri = 130,
134 .dir = IN|OUT,
135 .proto = UDP,
136 .fingerprint = &fingerprint1,
137 .protohandler = &protohandler1
140 .pri = 140,
141 .dir = IN,
142 .proto = UDP,
143 .fingerprint = &fingerprint2,
144 .protohandler = &protohandler2in
147 .pri = 140,
148 .dir = OUT,
149 .proto = UDP,
150 .fingerprint = &fingerprint2,
151 .protohandler = &protohandler2out
153 { EOH }
156 static int
157 mod_handler(module_t mod, int type, void *data)
159 int error;
161 switch (type) {
162 case MOD_LOAD:
163 error = 0;
164 LibAliasAttachHandlers(handlers);
165 break;
166 case MOD_UNLOAD:
167 error = 0;
168 LibAliasDetachHandlers(handlers);
169 break;
170 default:
171 error = EINVAL;
173 return (error);
176 #ifdef _KERNEL
177 static
178 #endif
179 moduledata_t alias_mod = {
180 "alias_nbt", mod_handler, NULL
183 #ifdef _KERNEL
184 DECLARE_MODULE(alias_nbt, alias_mod, SI_SUB_DRIVERS, SI_ORDER_SECOND);
185 MODULE_VERSION(alias_nbt, 1);
186 MODULE_DEPEND(alias_nbt, libalias, 1, 1, 1);
187 #endif
189 typedef struct {
190 struct in_addr oldaddr;
191 u_short oldport;
192 struct in_addr newaddr;
193 u_short newport;
194 u_short *uh_sum;
195 } NBTArguments;
197 typedef struct {
198 unsigned char type;
199 unsigned char flags;
200 u_short id;
201 struct in_addr source_ip;
202 u_short source_port;
203 u_short len;
204 u_short offset;
205 } NbtDataHeader;
207 #define OpQuery 0
208 #define OpUnknown 4
209 #define OpRegist 5
210 #define OpRelease 6
211 #define OpWACK 7
212 #define OpRefresh 8
213 typedef struct {
214 u_short nametrid;
215 u_short dir: 1, opcode:4, nmflags:7, rcode:4;
216 u_short qdcount;
217 u_short ancount;
218 u_short nscount;
219 u_short arcount;
220 } NbtNSHeader;
222 #define FMT_ERR 0x1
223 #define SRV_ERR 0x2
224 #define IMP_ERR 0x4
225 #define RFS_ERR 0x5
226 #define ACT_ERR 0x6
227 #define CFT_ERR 0x7
230 #ifdef LIBALIAS_DEBUG
231 static void
232 PrintRcode(u_char rcode)
235 switch (rcode) {
236 case FMT_ERR:
237 kprintf("\nFormat Error.");
238 case SRV_ERR:
239 kprintf("\nSever failure.");
240 case IMP_ERR:
241 kprintf("\nUnsupported request error.\n");
242 case RFS_ERR:
243 kprintf("\nRefused error.\n");
244 case ACT_ERR:
245 kprintf("\nActive error.\n");
246 case CFT_ERR:
247 kprintf("\nName in conflict error.\n");
248 default:
249 kprintf("\n?%c?=%0x\n", '?', rcode);
254 #endif
257 /* Handling Name field */
258 static u_char *
259 AliasHandleName(u_char * p, char *pmax)
262 u_char *s;
263 u_char c;
264 int compress;
266 /* Following length field */
268 if (p == NULL || (char *)p >= pmax)
269 return (NULL);
271 if (*p & 0xc0) {
272 p = p + 2;
273 if ((char *)p > pmax)
274 return (NULL);
275 return ((u_char *) p);
277 while ((*p & 0x3f) != 0x00) {
278 s = p + 1;
279 if (*p == 0x20)
280 compress = 1;
281 else
282 compress = 0;
284 /* Get next length field */
285 p = (u_char *) (p + (*p & 0x3f) + 1);
286 if ((char *)p > pmax) {
287 p = NULL;
288 break;
290 #ifdef LIBALIAS_DEBUG
291 kprintf(":");
292 #endif
293 while (s < p) {
294 if (compress == 1) {
295 c = (u_char) (((((*s & 0x0f) << 4) | (*(s + 1) & 0x0f)) - 0x11));
296 #ifdef LIBALIAS_DEBUG
297 if (isprint(c))
298 kprintf("%c", c);
299 else
300 kprintf("<0x%02x>", c);
301 #endif
302 s += 2;
303 } else {
304 #ifdef LIBALIAS_DEBUG
305 kprintf("%c", *s);
306 #endif
307 s++;
310 #ifdef LIBALIAS_DEBUG
311 kprintf(":");
312 fflush(stdout);
313 #endif
316 /* Set up to out of Name field */
317 if (p == NULL || (char *)p >= pmax)
318 p = NULL;
319 else
320 p++;
321 return ((u_char *) p);
325 * NetBios Datagram Handler (IP/UDP)
327 #define DGM_DIRECT_UNIQ 0x10
328 #define DGM_DIRECT_GROUP 0x11
329 #define DGM_BROADCAST 0x12
330 #define DGM_ERROR 0x13
331 #define DGM_QUERY 0x14
332 #define DGM_POSITIVE_RES 0x15
333 #define DGM_NEGATIVE_RES 0x16
335 static int
336 AliasHandleUdpNbt(
337 struct libalias *la,
338 struct ip *pip, /* IP packet to examine/patch */
339 struct alias_link *lnk,
340 struct in_addr *alias_address,
341 u_short alias_port
344 #ifdef LIBALIAS_DEBUG
345 char abuf[INET_ADDRSTRLEN];
346 #endif
347 struct udphdr *uh;
348 NbtDataHeader *ndh;
349 u_char *p = NULL;
350 char *pmax;
352 (void)la;
353 (void)lnk;
355 /* Calculate data length of UDP packet */
356 uh = (struct udphdr *)ip_next(pip);
357 pmax = (char *)uh + ntohs(uh->uh_ulen);
359 ndh = (NbtDataHeader *)udp_next(uh);
360 if ((char *)(ndh + 1) > pmax)
361 return (-1);
362 #ifdef LIBALIAS_DEBUG
363 kprintf("\nType=%02x,", ndh->type);
364 #endif
365 switch (ndh->type) {
366 case DGM_DIRECT_UNIQ:
367 case DGM_DIRECT_GROUP:
368 case DGM_BROADCAST:
369 p = (u_char *) ndh + 14;
370 p = AliasHandleName(p, pmax); /* Source Name */
371 p = AliasHandleName(p, pmax); /* Destination Name */
372 break;
373 case DGM_ERROR:
374 p = (u_char *) ndh + 11;
375 break;
376 case DGM_QUERY:
377 case DGM_POSITIVE_RES:
378 case DGM_NEGATIVE_RES:
379 p = (u_char *) ndh + 10;
380 p = AliasHandleName(p, pmax); /* Destination Name */
381 break;
383 if (p == NULL || (char *)p > pmax)
384 p = NULL;
385 #ifdef LIBALIAS_DEBUG
386 kprintf("%s:%d-->", kinet_ntoa(ndh->source_ip, abuf),
387 ntohs(ndh->source_port));
388 #endif
389 /* Doing an IP address and Port number Translation */
390 if (uh->uh_sum != 0) {
391 int acc;
392 u_short *sptr;
394 acc = ndh->source_port;
395 acc -= alias_port;
396 sptr = (u_short *) & (ndh->source_ip);
397 acc += *sptr++;
398 acc += *sptr;
399 sptr = (u_short *) alias_address;
400 acc -= *sptr++;
401 acc -= *sptr;
402 ADJUST_CHECKSUM(acc, uh->uh_sum);
404 ndh->source_ip = *alias_address;
405 ndh->source_port = alias_port;
406 #ifdef LIBALIAS_DEBUG
407 kprintf("%s:%d\n", kinet_ntoa(ndh->source_ip, abuf),
408 ntohs(ndh->source_port));
409 fflush(stdout);
410 #endif
411 return ((p == NULL) ? -1 : 0);
414 /* Question Section */
415 #define QS_TYPE_NB 0x0020
416 #define QS_TYPE_NBSTAT 0x0021
417 #define QS_CLAS_IN 0x0001
418 typedef struct {
419 u_short type; /* The type of Request */
420 u_short class; /* The class of Request */
421 } NBTNsQuestion;
423 static u_char *
424 AliasHandleQuestion(
425 u_short count,
426 NBTNsQuestion * q,
427 char *pmax,
428 NBTArguments * nbtarg)
431 (void)nbtarg;
433 while (count != 0) {
434 /* Name Filed */
435 q = (NBTNsQuestion *) AliasHandleName((u_char *) q, pmax);
437 if (q == NULL || (char *)(q + 1) > pmax) {
438 q = NULL;
439 break;
441 /* Type and Class filed */
442 switch (ntohs(q->type)) {
443 case QS_TYPE_NB:
444 case QS_TYPE_NBSTAT:
445 q = q + 1;
446 break;
447 default:
448 #ifdef LIBALIAS_DEBUG
449 kprintf("\nUnknown Type on Question %0x\n", ntohs(q->type));
450 #endif
451 break;
453 count--;
456 /* Set up to out of Question Section */
457 return ((u_char *) q);
460 /* Resource Record */
461 #define RR_TYPE_A 0x0001
462 #define RR_TYPE_NS 0x0002
463 #define RR_TYPE_NULL 0x000a
464 #define RR_TYPE_NB 0x0020
465 #define RR_TYPE_NBSTAT 0x0021
466 #define RR_CLAS_IN 0x0001
467 #define SizeOfNsResource 8
468 typedef struct {
469 u_short type;
470 u_short class;
471 unsigned int ttl;
472 u_short rdlen;
473 } NBTNsResource;
475 #define SizeOfNsRNB 6
476 typedef struct {
477 u_short g: 1 , ont:2, resv:13;
478 struct in_addr addr;
479 } NBTNsRNB;
481 static u_char *
482 AliasHandleResourceNB(
483 NBTNsResource * q,
484 char *pmax,
485 NBTArguments * nbtarg)
487 NBTNsRNB *nb;
488 u_short bcount;
489 #ifdef LIBALIAS_DEBUG
490 char abuf[INET_ADDRSTRLEN];
491 #endif
493 if (q == NULL || (char *)(q + 1) > pmax)
494 return (NULL);
495 /* Check out a length */
496 bcount = ntohs(q->rdlen);
498 /* Forward to Resource NB position */
499 nb = (NBTNsRNB *) ((u_char *) q + SizeOfNsResource);
501 /* Processing all in_addr array */
502 #ifdef LIBALIAS_DEBUG
503 kprintf("NB rec[%s", kinet_ntoa(nbtarg->oldaddr, abuf));
504 kprintf("->%s, %dbytes] ", kinet_ntoa(nbtarg->newaddr, abuf), bcount);
505 #endif
506 while (nb != NULL && bcount != 0) {
507 if ((char *)(nb + 1) > pmax) {
508 nb = NULL;
509 break;
511 #ifdef LIBALIAS_DEBUG
512 kprintf("<%s>", kinet_ntoa(nb->addr, abuf));
513 #endif
514 if (!bcmp(&nbtarg->oldaddr, &nb->addr, sizeof(struct in_addr))) {
515 if (*nbtarg->uh_sum != 0) {
516 int acc;
517 u_short *sptr;
519 sptr = (u_short *) & (nb->addr);
520 acc = *sptr++;
521 acc += *sptr;
522 sptr = (u_short *) & (nbtarg->newaddr);
523 acc -= *sptr++;
524 acc -= *sptr;
525 ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
527 nb->addr = nbtarg->newaddr;
528 #ifdef LIBALIAS_DEBUG
529 kprintf("O");
530 #endif
532 #ifdef LIBALIAS_DEBUG
533 else {
534 kprintf(".");
536 #endif
537 nb = (NBTNsRNB *) ((u_char *) nb + SizeOfNsRNB);
538 bcount -= SizeOfNsRNB;
540 if (nb == NULL || (char *)(nb + 1) > pmax) {
541 nb = NULL;
543 return ((u_char *) nb);
546 #define SizeOfResourceA 6
547 typedef struct {
548 struct in_addr addr;
549 } NBTNsResourceA;
551 static u_char *
552 AliasHandleResourceA(
553 NBTNsResource * q,
554 char *pmax,
555 NBTArguments * nbtarg)
557 NBTNsResourceA *a;
558 u_short bcount;
559 #ifdef LIBALIAS_DEBUG
560 char abuf[INET_ADDRSTRLEN];
561 #endif
563 if (q == NULL || (char *)(q + 1) > pmax)
564 return (NULL);
566 /* Forward to Resource A position */
567 a = (NBTNsResourceA *) ((u_char *) q + sizeof(NBTNsResource));
569 /* Check out of length */
570 bcount = ntohs(q->rdlen);
572 /* Processing all in_addr array */
573 #ifdef LIBALIAS_DEBUG
574 kprintf("Arec [%s", kinet_ntoa(nbtarg->oldaddr, abuf));
575 kprintf("->%s]", kinet_ntoa(nbtarg->newaddr, abuf));
576 #endif
577 while (bcount != 0) {
578 if (a == NULL || (char *)(a + 1) > pmax)
579 return (NULL);
580 #ifdef LIBALIAS_DEBUG
581 kprintf("..%s", kinet_ntoa(a->addr, abuf));
582 #endif
583 if (!bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr))) {
584 if (*nbtarg->uh_sum != 0) {
585 int acc;
586 u_short *sptr;
588 sptr = (u_short *) & (a->addr); /* Old */
589 acc = *sptr++;
590 acc += *sptr;
591 sptr = (u_short *) & nbtarg->newaddr; /* New */
592 acc -= *sptr++;
593 acc -= *sptr;
594 ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
596 a->addr = nbtarg->newaddr;
598 a++; /* XXXX */
599 bcount -= SizeOfResourceA;
601 if (a == NULL || (char *)(a + 1) > pmax)
602 a = NULL;
603 return ((u_char *) a);
606 typedef struct {
607 u_short opcode:4, flags:8, resv:4;
608 } NBTNsResourceNULL;
610 static u_char *
611 AliasHandleResourceNULL(
612 NBTNsResource * q,
613 char *pmax,
614 NBTArguments * nbtarg)
616 NBTNsResourceNULL *n;
617 u_short bcount;
619 (void)nbtarg;
621 if (q == NULL || (char *)(q + 1) > pmax)
622 return (NULL);
624 /* Forward to Resource NULL position */
625 n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource));
627 /* Check out of length */
628 bcount = ntohs(q->rdlen);
630 /* Processing all in_addr array */
631 while (bcount != 0) {
632 if ((char *)(n + 1) > pmax) {
633 n = NULL;
634 break;
636 n++;
637 bcount -= sizeof(NBTNsResourceNULL);
639 if ((char *)(n + 1) > pmax)
640 n = NULL;
642 return ((u_char *) n);
645 static u_char *
646 AliasHandleResourceNS(
647 NBTNsResource * q,
648 char *pmax,
649 NBTArguments * nbtarg)
651 NBTNsResourceNULL *n;
652 u_short bcount;
654 (void)nbtarg;
656 if (q == NULL || (char *)(q + 1) > pmax)
657 return (NULL);
659 /* Forward to Resource NULL position */
660 n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource));
662 /* Check out of length */
663 bcount = ntohs(q->rdlen);
665 /* Resource Record Name Filed */
666 q = (NBTNsResource *) AliasHandleName((u_char *) n, pmax); /* XXX */
668 if (q == NULL || (char *)((u_char *) n + bcount) > pmax)
669 return (NULL);
670 else
671 return ((u_char *) n + bcount);
674 typedef struct {
675 u_short numnames;
676 } NBTNsResourceNBSTAT;
678 static u_char *
679 AliasHandleResourceNBSTAT(
680 NBTNsResource * q,
681 char *pmax,
682 NBTArguments * nbtarg)
684 NBTNsResourceNBSTAT *n;
685 u_short bcount;
687 (void)nbtarg;
689 if (q == NULL || (char *)(q + 1) > pmax)
690 return (NULL);
692 /* Forward to Resource NBSTAT position */
693 n = (NBTNsResourceNBSTAT *) ((u_char *) q + sizeof(NBTNsResource));
695 /* Check out of length */
696 bcount = ntohs(q->rdlen);
698 if (q == NULL || (char *)((u_char *) n + bcount) > pmax)
699 return (NULL);
700 else
701 return ((u_char *) n + bcount);
704 static u_char *
705 AliasHandleResource(
706 u_short count,
707 NBTNsResource * q,
708 char *pmax,
709 NBTArguments
710 * nbtarg)
712 while (count != 0) {
713 /* Resource Record Name Filed */
714 q = (NBTNsResource *) AliasHandleName((u_char *) q, pmax);
716 if (q == NULL || (char *)(q + 1) > pmax)
717 break;
718 #ifdef LIBALIAS_DEBUG
719 kprintf("type=%02x, count=%d\n", ntohs(q->type), count);
720 #endif
722 /* Type and Class filed */
723 switch (ntohs(q->type)) {
724 case RR_TYPE_NB:
725 q = (NBTNsResource *) AliasHandleResourceNB(
727 pmax,
728 nbtarg
730 break;
731 case RR_TYPE_A:
732 q = (NBTNsResource *) AliasHandleResourceA(
734 pmax,
735 nbtarg
737 break;
738 case RR_TYPE_NS:
739 q = (NBTNsResource *) AliasHandleResourceNS(
741 pmax,
742 nbtarg
744 break;
745 case RR_TYPE_NULL:
746 q = (NBTNsResource *) AliasHandleResourceNULL(
748 pmax,
749 nbtarg
751 break;
752 case RR_TYPE_NBSTAT:
753 q = (NBTNsResource *) AliasHandleResourceNBSTAT(
755 pmax,
756 nbtarg
758 break;
759 default:
760 #ifdef LIBALIAS_DEBUG
761 kprintf(
762 "\nUnknown Type of Resource %0x\n",
763 ntohs(q->type)
765 fflush(stdout);
766 #endif
767 break;
769 count--;
771 return ((u_char *) q);
774 static int
775 AliasHandleUdpNbtNS(
776 struct libalias *la,
777 struct ip *pip, /* IP packet to examine/patch */
778 struct alias_link *lnk,
779 struct in_addr *alias_address,
780 u_short * alias_port,
781 struct in_addr *original_address,
782 u_short * original_port)
784 struct udphdr *uh;
785 NbtNSHeader *nsh;
786 u_char *p;
787 char *pmax;
788 NBTArguments nbtarg;
790 (void)la;
791 (void)lnk;
793 /* Set up Common Parameter */
794 nbtarg.oldaddr = *alias_address;
795 nbtarg.oldport = *alias_port;
796 nbtarg.newaddr = *original_address;
797 nbtarg.newport = *original_port;
799 /* Calculate data length of UDP packet */
800 uh = (struct udphdr *)ip_next(pip);
801 nbtarg.uh_sum = &(uh->uh_sum);
802 nsh = (NbtNSHeader *)udp_next(uh);
803 p = (u_char *) (nsh + 1);
804 pmax = (char *)uh + ntohs(uh->uh_ulen);
806 if ((char *)(nsh + 1) > pmax)
807 return (-1);
809 #ifdef LIBALIAS_DEBUG
810 kprintf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
811 ", an=%04x, ns=%04x, ar=%04x, [%d]-->",
812 nsh->dir ? "Response" : "Request",
813 nsh->nametrid,
814 nsh->opcode,
815 nsh->nmflags,
816 nsh->rcode,
817 ntohs(nsh->qdcount),
818 ntohs(nsh->ancount),
819 ntohs(nsh->nscount),
820 ntohs(nsh->arcount),
821 (u_char *) p - (u_char *) nsh
823 #endif
825 /* Question Entries */
826 if (ntohs(nsh->qdcount) != 0) {
827 p = AliasHandleQuestion(
828 ntohs(nsh->qdcount),
829 (NBTNsQuestion *) p,
830 pmax,
831 &nbtarg
834 /* Answer Resource Records */
835 if (ntohs(nsh->ancount) != 0) {
836 p = AliasHandleResource(
837 ntohs(nsh->ancount),
838 (NBTNsResource *) p,
839 pmax,
840 &nbtarg
843 /* Authority Resource Recodrs */
844 if (ntohs(nsh->nscount) != 0) {
845 p = AliasHandleResource(
846 ntohs(nsh->nscount),
847 (NBTNsResource *) p,
848 pmax,
849 &nbtarg
852 /* Additional Resource Recodrs */
853 if (ntohs(nsh->arcount) != 0) {
854 p = AliasHandleResource(
855 ntohs(nsh->arcount),
856 (NBTNsResource *) p,
857 pmax,
858 &nbtarg
861 #ifdef LIBALIAS_DEBUG
862 PrintRcode(nsh->rcode);
863 #endif
864 return ((p == NULL) ? -1 : 0);