VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/slirp/libalias/alias_nbt.c@ 39101

Last change on this file since 39101 was 39101, checked in by vboxsync, 14 years ago

NAT: warnings.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette