VirtualBox

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

最後變更 在這個檔案從21864是 21864,由 vboxsync 提交於 16 年 前

NAT: globals

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

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