VirtualBox

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

Last change on this file since 22452 was 22452, checked in by vboxsync, 15 years ago

NAT/libalias: don't alloc to much

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

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