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